1 /******************************************************************************
2 *
3 * Copyright (C) 2001-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains BNEP utility functions
22 *
23 ******************************************************************************/
24
25 #include <stdio.h>
26 #include <string.h>
27 #include "bnep_int.h"
28 #include "bt_common.h"
29 #include "bt_types.h"
30 #include "bt_utils.h"
31 #include "btm_int.h"
32 #include "btu.h"
33 #include "device/include/controller.h"
34 #include "osi/include/osi.h"
35
36 extern fixed_queue_t* btu_general_alarm_queue;
37
38 /******************************************************************************/
39 /* L O C A L F U N C T I O N P R O T O T Y P E S */
40 /******************************************************************************/
41 static uint8_t* bnepu_init_hdr(BT_HDR* p_buf, uint16_t hdr_len,
42 uint8_t pkt_type);
43
44 void bnepu_process_peer_multicast_filter_set(tBNEP_CONN* p_bcb,
45 uint8_t* p_filters, uint16_t len);
46 void bnepu_send_peer_multicast_filter_rsp(tBNEP_CONN* p_bcb,
47 uint16_t response_code);
48
49 /*******************************************************************************
50 *
51 * Function bnepu_find_bcb_by_cid
52 *
53 * Description This function searches the bcb table for an entry with the
54 * passed CID.
55 *
56 * Returns the BCB address, or NULL if not found.
57 *
58 ******************************************************************************/
bnepu_find_bcb_by_cid(uint16_t cid)59 tBNEP_CONN* bnepu_find_bcb_by_cid(uint16_t cid) {
60 uint16_t xx;
61 tBNEP_CONN* p_bcb;
62
63 /* Look through each connection control block */
64 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) {
65 if ((p_bcb->con_state != BNEP_STATE_IDLE) && (p_bcb->l2cap_cid == cid))
66 return (p_bcb);
67 }
68
69 /* If here, not found */
70 return (NULL);
71 }
72
73 /*******************************************************************************
74 *
75 * Function bnepu_find_bcb_by_bd_addr
76 *
77 * Description This function searches the BCB table for an entry with the
78 * passed Bluetooth Address.
79 *
80 * Returns the BCB address, or NULL if not found.
81 *
82 ******************************************************************************/
bnepu_find_bcb_by_bd_addr(uint8_t * p_bda)83 tBNEP_CONN* bnepu_find_bcb_by_bd_addr(uint8_t* p_bda) {
84 uint16_t xx;
85 tBNEP_CONN* p_bcb;
86
87 /* Look through each connection control block */
88 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) {
89 if (p_bcb->con_state != BNEP_STATE_IDLE) {
90 if (!memcmp((uint8_t*)(p_bcb->rem_bda), p_bda, BD_ADDR_LEN))
91 return (p_bcb);
92 }
93 }
94
95 /* If here, not found */
96 return (NULL);
97 }
98
99 /*******************************************************************************
100 *
101 * Function bnepu_allocate_bcb
102 *
103 * Description This function allocates a new BCB.
104 *
105 * Returns BCB address, or NULL if none available.
106 *
107 ******************************************************************************/
bnepu_allocate_bcb(BD_ADDR p_rem_bda)108 tBNEP_CONN* bnepu_allocate_bcb(BD_ADDR p_rem_bda) {
109 uint16_t xx;
110 tBNEP_CONN* p_bcb;
111
112 /* Look through each connection control block for a free one */
113 for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) {
114 if (p_bcb->con_state == BNEP_STATE_IDLE) {
115 alarm_free(p_bcb->conn_timer);
116 memset((uint8_t*)p_bcb, 0, sizeof(tBNEP_CONN));
117 p_bcb->conn_timer = alarm_new("bnep.conn_timer");
118
119 memcpy((uint8_t*)(p_bcb->rem_bda), (uint8_t*)p_rem_bda, BD_ADDR_LEN);
120 p_bcb->handle = xx + 1;
121 p_bcb->xmit_q = fixed_queue_new(SIZE_MAX);
122
123 return (p_bcb);
124 }
125 }
126
127 /* If here, no free BCB found */
128 return (NULL);
129 }
130
131 /*******************************************************************************
132 *
133 * Function bnepu_release_bcb
134 *
135 * Description This function releases a BCB.
136 *
137 * Returns void
138 *
139 ******************************************************************************/
bnepu_release_bcb(tBNEP_CONN * p_bcb)140 void bnepu_release_bcb(tBNEP_CONN* p_bcb) {
141 /* Ensure timer is stopped */
142 alarm_free(p_bcb->conn_timer);
143 p_bcb->conn_timer = NULL;
144
145 /* Drop any response pointer we may be holding */
146 p_bcb->con_state = BNEP_STATE_IDLE;
147 osi_free_and_reset((void**)&p_bcb->p_pending_data);
148
149 /* Free transmit queue */
150 while (!fixed_queue_is_empty(p_bcb->xmit_q)) {
151 osi_free(fixed_queue_try_dequeue(p_bcb->xmit_q));
152 }
153 fixed_queue_free(p_bcb->xmit_q, NULL);
154 p_bcb->xmit_q = NULL;
155 }
156
157 /*******************************************************************************
158 *
159 * Function bnep_send_conn_req
160 *
161 * Description This function sends a BNEP connection request to peer
162 *
163 * Returns void
164 *
165 ******************************************************************************/
bnep_send_conn_req(tBNEP_CONN * p_bcb)166 void bnep_send_conn_req(tBNEP_CONN* p_bcb) {
167 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
168 uint8_t *p, *p_start;
169
170 BNEP_TRACE_DEBUG("%s: sending setup req with dst uuid %x", __func__,
171 p_bcb->dst_uuid.uu.uuid16);
172
173 p_buf->offset = L2CAP_MIN_OFFSET;
174 p = p_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
175
176 /* Put in BNEP frame type - filter control */
177 UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
178
179 /* Put in filter message type - set filters */
180 UINT8_TO_BE_STREAM(p, BNEP_SETUP_CONNECTION_REQUEST_MSG);
181
182 UINT8_TO_BE_STREAM(p, p_bcb->dst_uuid.len);
183
184 if (p_bcb->dst_uuid.len == 2) {
185 UINT16_TO_BE_STREAM(p, p_bcb->dst_uuid.uu.uuid16);
186 UINT16_TO_BE_STREAM(p, p_bcb->src_uuid.uu.uuid16);
187 } else if (p_bcb->dst_uuid.len == 4) {
188 UINT32_TO_BE_STREAM(p, p_bcb->dst_uuid.uu.uuid32);
189 UINT32_TO_BE_STREAM(p, p_bcb->src_uuid.uu.uuid32);
190 } else if (p_bcb->dst_uuid.len == 16) {
191 memcpy(p, p_bcb->dst_uuid.uu.uuid128, p_bcb->dst_uuid.len);
192 p += p_bcb->dst_uuid.len;
193 memcpy(p, p_bcb->src_uuid.uu.uuid128, p_bcb->dst_uuid.len);
194 p += p_bcb->dst_uuid.len;
195 } else {
196 BNEP_TRACE_ERROR("%s: uuid: %x, invalid length: %x", __func__,
197 p_bcb->dst_uuid.uu.uuid16, p_bcb->dst_uuid.len);
198 }
199
200 p_buf->len = (uint16_t)(p - p_start);
201
202 bnepu_check_send_packet(p_bcb, p_buf);
203 }
204
205 /*******************************************************************************
206 *
207 * Function bnep_send_conn_responce
208 *
209 * Description This function sends a BNEP setup response to peer
210 *
211 * Returns void
212 *
213 ******************************************************************************/
bnep_send_conn_responce(tBNEP_CONN * p_bcb,uint16_t resp_code)214 void bnep_send_conn_responce(tBNEP_CONN* p_bcb, uint16_t resp_code) {
215 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
216 uint8_t* p;
217
218 BNEP_TRACE_EVENT("BNEP - bnep_send_conn_responce for CID: 0x%x",
219 p_bcb->l2cap_cid);
220
221 p_buf->offset = L2CAP_MIN_OFFSET;
222 p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
223
224 /* Put in BNEP frame type - filter control */
225 UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
226
227 /* Put in filter message type - set filters */
228 UINT8_TO_BE_STREAM(p, BNEP_SETUP_CONNECTION_RESPONSE_MSG);
229
230 UINT16_TO_BE_STREAM(p, resp_code);
231
232 p_buf->len = 4;
233
234 bnepu_check_send_packet(p_bcb, p_buf);
235 }
236
237 /*******************************************************************************
238 *
239 * Function bnepu_send_peer_our_filters
240 *
241 * Description This function sends our filters to a peer
242 *
243 * Returns void
244 *
245 ******************************************************************************/
bnepu_send_peer_our_filters(tBNEP_CONN * p_bcb)246 void bnepu_send_peer_our_filters(tBNEP_CONN* p_bcb) {
247 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
248 uint8_t* p;
249 uint16_t xx;
250
251 BNEP_TRACE_DEBUG("BNEP sending peer our filters");
252
253 p_buf->offset = L2CAP_MIN_OFFSET;
254 p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
255
256 /* Put in BNEP frame type - filter control */
257 UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
258
259 /* Put in filter message type - set filters */
260 UINT8_TO_BE_STREAM(p, BNEP_FILTER_NET_TYPE_SET_MSG);
261
262 UINT16_TO_BE_STREAM(p, (4 * p_bcb->sent_num_filters));
263 for (xx = 0; xx < p_bcb->sent_num_filters; xx++) {
264 UINT16_TO_BE_STREAM(p, p_bcb->sent_prot_filter_start[xx]);
265 UINT16_TO_BE_STREAM(p, p_bcb->sent_prot_filter_end[xx]);
266 }
267
268 p_buf->len = 4 + (4 * p_bcb->sent_num_filters);
269
270 bnepu_check_send_packet(p_bcb, p_buf);
271
272 p_bcb->con_flags |= BNEP_FLAGS_FILTER_RESP_PEND;
273
274 /* Start timer waiting for setup response */
275 alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
276 bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
277 }
278
279 /*******************************************************************************
280 *
281 * Function bnepu_send_peer_our_multi_filters
282 *
283 * Description This function sends our multicast filters to a peer
284 *
285 * Returns void
286 *
287 ******************************************************************************/
bnepu_send_peer_our_multi_filters(tBNEP_CONN * p_bcb)288 void bnepu_send_peer_our_multi_filters(tBNEP_CONN* p_bcb) {
289 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
290 uint8_t* p;
291 uint16_t xx;
292
293 BNEP_TRACE_DEBUG("BNEP sending peer our multicast filters");
294
295 p_buf->offset = L2CAP_MIN_OFFSET;
296 p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
297
298 /* Put in BNEP frame type - filter control */
299 UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
300
301 /* Put in filter message type - set filters */
302 UINT8_TO_BE_STREAM(p, BNEP_FILTER_MULTI_ADDR_SET_MSG);
303
304 UINT16_TO_BE_STREAM(p, (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters));
305 for (xx = 0; xx < p_bcb->sent_mcast_filters; xx++) {
306 memcpy(p, p_bcb->sent_mcast_filter_start[xx], BD_ADDR_LEN);
307 p += BD_ADDR_LEN;
308 memcpy(p, p_bcb->sent_mcast_filter_end[xx], BD_ADDR_LEN);
309 p += BD_ADDR_LEN;
310 }
311
312 p_buf->len = 4 + (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters);
313
314 bnepu_check_send_packet(p_bcb, p_buf);
315
316 p_bcb->con_flags |= BNEP_FLAGS_MULTI_RESP_PEND;
317
318 /* Start timer waiting for setup response */
319 alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
320 bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
321 }
322
323 /*******************************************************************************
324 *
325 * Function bnepu_send_peer_filter_rsp
326 *
327 * Description This function sends a filter response to a peer
328 *
329 * Returns void
330 *
331 ******************************************************************************/
bnepu_send_peer_filter_rsp(tBNEP_CONN * p_bcb,uint16_t response_code)332 void bnepu_send_peer_filter_rsp(tBNEP_CONN* p_bcb, uint16_t response_code) {
333 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
334 uint8_t* p;
335
336 BNEP_TRACE_DEBUG("BNEP sending filter response");
337
338 p_buf->offset = L2CAP_MIN_OFFSET;
339 p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
340
341 /* Put in BNEP frame type - filter control */
342 UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
343
344 /* Put in filter message type - set filters */
345 UINT8_TO_BE_STREAM(p, BNEP_FILTER_NET_TYPE_RESPONSE_MSG);
346
347 UINT16_TO_BE_STREAM(p, response_code);
348
349 p_buf->len = 4;
350
351 bnepu_check_send_packet(p_bcb, p_buf);
352 }
353
354 /*******************************************************************************
355 *
356 * Function bnep_send_command_not_understood
357 *
358 * Description This function sends a BNEP command not understood message
359 *
360 * Returns void
361 *
362 ******************************************************************************/
bnep_send_command_not_understood(tBNEP_CONN * p_bcb,uint8_t cmd_code)363 void bnep_send_command_not_understood(tBNEP_CONN* p_bcb, uint8_t cmd_code) {
364 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
365 uint8_t* p;
366
367 BNEP_TRACE_EVENT(
368 "BNEP - bnep_send_command_not_understood for CID: 0x%x, cmd 0x%x",
369 p_bcb->l2cap_cid, cmd_code);
370
371 p_buf->offset = L2CAP_MIN_OFFSET;
372 p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
373
374 /* Put in BNEP frame type - filter control */
375 UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
376
377 /* Put in filter message type - set filters */
378 UINT8_TO_BE_STREAM(p, BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD);
379
380 UINT8_TO_BE_STREAM(p, cmd_code);
381
382 p_buf->len = 3;
383
384 bnepu_check_send_packet(p_bcb, p_buf);
385 }
386
387 /*******************************************************************************
388 *
389 * Function bnepu_check_send_packet
390 *
391 * Description This function tries to send a packet to L2CAP.
392 * If L2CAP is flow controlled, it enqueues the
393 * packet to the transmit queue
394 *
395 * Returns void
396 *
397 ******************************************************************************/
bnepu_check_send_packet(tBNEP_CONN * p_bcb,BT_HDR * p_buf)398 void bnepu_check_send_packet(tBNEP_CONN* p_bcb, BT_HDR* p_buf) {
399 BNEP_TRACE_EVENT("BNEP - bnepu_check_send_packet for CID: 0x%x",
400 p_bcb->l2cap_cid);
401 if (p_bcb->con_flags & BNEP_FLAGS_L2CAP_CONGESTED) {
402 if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) {
403 BNEP_TRACE_EVENT("BNEP - congested, dropping buf, CID: 0x%x",
404 p_bcb->l2cap_cid);
405
406 osi_free(p_buf);
407 } else {
408 fixed_queue_enqueue(p_bcb->xmit_q, p_buf);
409 }
410 } else {
411 L2CA_DataWrite(p_bcb->l2cap_cid, p_buf);
412 }
413 }
414
415 /*******************************************************************************
416 *
417 * Function bnepu_build_bnep_hdr
418 *
419 * Description This function builds the BNEP header for a packet
420 * Extension headers are not sent yet, so there is no
421 * check for that.
422 *
423 * Returns void
424 *
425 ******************************************************************************/
bnepu_build_bnep_hdr(tBNEP_CONN * p_bcb,BT_HDR * p_buf,uint16_t protocol,uint8_t * p_src_addr,uint8_t * p_dest_addr,bool fw_ext_present)426 void bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf, uint16_t protocol,
427 uint8_t* p_src_addr, uint8_t* p_dest_addr,
428 bool fw_ext_present) {
429 const controller_t* controller = controller_get_interface();
430 uint8_t ext_bit, *p = (uint8_t *)NULL;
431 uint8_t type = BNEP_FRAME_COMPRESSED_ETHERNET;
432
433 ext_bit = fw_ext_present ? 0x80 : 0x00;
434
435 if ((p_src_addr) &&
436 (memcmp(p_src_addr, &controller->get_address()->address, BD_ADDR_LEN)))
437 type = BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY;
438
439 if (memcmp(p_dest_addr, p_bcb->rem_bda, BD_ADDR_LEN))
440 type = (type == BNEP_FRAME_COMPRESSED_ETHERNET)
441 ? BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY
442 : BNEP_FRAME_GENERAL_ETHERNET;
443
444 if (!p_src_addr) p_src_addr = (uint8_t*)controller->get_address();
445
446 switch (type) {
447 case BNEP_FRAME_GENERAL_ETHERNET:
448 p = bnepu_init_hdr(p_buf, 15,
449 (uint8_t)(ext_bit | BNEP_FRAME_GENERAL_ETHERNET));
450
451 memcpy(p, p_dest_addr, BD_ADDR_LEN);
452 p += BD_ADDR_LEN;
453
454 memcpy(p, p_src_addr, BD_ADDR_LEN);
455 p += BD_ADDR_LEN;
456 break;
457
458 case BNEP_FRAME_COMPRESSED_ETHERNET:
459 p = bnepu_init_hdr(p_buf, 3,
460 (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET));
461 break;
462
463 case BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY:
464 p = bnepu_init_hdr(
465 p_buf, 9,
466 (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY));
467
468 memcpy(p, p_src_addr, BD_ADDR_LEN);
469 p += BD_ADDR_LEN;
470 break;
471
472 case BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY:
473 p = bnepu_init_hdr(
474 p_buf, 9,
475 (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY));
476
477 memcpy(p, p_dest_addr, BD_ADDR_LEN);
478 p += BD_ADDR_LEN;
479 break;
480 }
481
482 UINT16_TO_BE_STREAM(p, protocol);
483 }
484
485 /*******************************************************************************
486 *
487 * Function bnepu_init_hdr
488 *
489 * Description This function initializes the BNEP header
490 *
491 * Returns pointer to header in buffer
492 *
493 ******************************************************************************/
bnepu_init_hdr(BT_HDR * p_buf,uint16_t hdr_len,uint8_t pkt_type)494 static uint8_t* bnepu_init_hdr(BT_HDR* p_buf, uint16_t hdr_len,
495 uint8_t pkt_type) {
496 uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
497
498 /* See if we need to make space in the buffer */
499 if (p_buf->offset < (hdr_len + L2CAP_MIN_OFFSET)) {
500 uint16_t xx, diff = BNEP_MINIMUM_OFFSET - p_buf->offset;
501 p = p + p_buf->len - 1;
502 for (xx = 0; xx < p_buf->len; xx++, p--) p[diff] = *p;
503
504 p_buf->offset = BNEP_MINIMUM_OFFSET;
505 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
506 }
507
508 p_buf->len += hdr_len;
509 p_buf->offset -= hdr_len;
510 p -= hdr_len;
511
512 *p++ = pkt_type;
513
514 return (p);
515 }
516
517 /*******************************************************************************
518 *
519 * Function bnep_process_setup_conn_req
520 *
521 * Description This function processes a peer's setup connection request
522 * message. The destination UUID is verified and response sent
523 * Connection open indication will be given to PAN profile
524 *
525 * Returns void
526 *
527 ******************************************************************************/
bnep_process_setup_conn_req(tBNEP_CONN * p_bcb,uint8_t * p_setup,uint8_t len)528 void bnep_process_setup_conn_req(tBNEP_CONN* p_bcb, uint8_t* p_setup,
529 uint8_t len) {
530 BNEP_TRACE_EVENT("BNEP - bnep_process_setup_conn_req for CID: 0x%x",
531 p_bcb->l2cap_cid);
532
533 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP &&
534 p_bcb->con_state != BNEP_STATE_SEC_CHECKING &&
535 p_bcb->con_state != BNEP_STATE_CONNECTED) {
536 BNEP_TRACE_ERROR("BNEP - setup request in bad state %d", p_bcb->con_state);
537 bnep_send_conn_responce(p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
538 return;
539 }
540
541 /* Check if we already initiated security check or if waiting for user
542 * responce */
543 if (p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD) {
544 BNEP_TRACE_EVENT(
545 "BNEP - Duplicate Setup message received while doing security check");
546 return;
547 }
548
549 /* Check if peer is the originator */
550 if (p_bcb->con_state != BNEP_STATE_CONNECTED &&
551 (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) &&
552 (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) {
553 BNEP_TRACE_ERROR("BNEP - setup request when we are originator",
554 p_bcb->con_state);
555 bnep_send_conn_responce(p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
556 return;
557 }
558
559 if (p_bcb->con_state == BNEP_STATE_CONNECTED) {
560 memcpy((uint8_t*)&(p_bcb->prv_src_uuid), (uint8_t*)&(p_bcb->src_uuid),
561 sizeof(tBT_UUID));
562 memcpy((uint8_t*)&(p_bcb->prv_dst_uuid), (uint8_t*)&(p_bcb->dst_uuid),
563 sizeof(tBT_UUID));
564 }
565
566 p_bcb->dst_uuid.len = p_bcb->src_uuid.len = len;
567
568 if (p_bcb->dst_uuid.len == 2) {
569 /* because peer initiated connection keep src uuid as dst uuid */
570 BE_STREAM_TO_UINT16(p_bcb->src_uuid.uu.uuid16, p_setup);
571 BE_STREAM_TO_UINT16(p_bcb->dst_uuid.uu.uuid16, p_setup);
572
573 /* If nothing has changed don't bother the profile */
574 if (p_bcb->con_state == BNEP_STATE_CONNECTED &&
575 p_bcb->src_uuid.uu.uuid16 == p_bcb->prv_src_uuid.uu.uuid16 &&
576 p_bcb->dst_uuid.uu.uuid16 == p_bcb->prv_dst_uuid.uu.uuid16) {
577 bnep_send_conn_responce(p_bcb, BNEP_SETUP_CONN_OK);
578 return;
579 }
580 } else if (p_bcb->dst_uuid.len == 4) {
581 BE_STREAM_TO_UINT32(p_bcb->src_uuid.uu.uuid32, p_setup);
582 BE_STREAM_TO_UINT32(p_bcb->dst_uuid.uu.uuid32, p_setup);
583 } else if (p_bcb->dst_uuid.len == 16) {
584 memcpy(p_bcb->src_uuid.uu.uuid128, p_setup, p_bcb->src_uuid.len);
585 p_setup += p_bcb->src_uuid.len;
586 memcpy(p_bcb->dst_uuid.uu.uuid128, p_setup, p_bcb->dst_uuid.len);
587 p_setup += p_bcb->dst_uuid.len;
588 } else {
589 BNEP_TRACE_ERROR("BNEP - Bad UID len %d in ConnReq", p_bcb->dst_uuid.len);
590 bnep_send_conn_responce(p_bcb, BNEP_SETUP_INVALID_UUID_SIZE);
591 return;
592 }
593
594 p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
595 p_bcb->con_flags |= BNEP_FLAGS_SETUP_RCVD;
596
597 BNEP_TRACE_EVENT(
598 "BNEP initiating security check for incoming call for uuid 0x%x",
599 p_bcb->src_uuid.uu.uuid16);
600 #if (BNEP_DO_AUTH_FOR_ROLE_SWITCH == FALSE)
601 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
602 bnep_sec_check_complete(p_bcb->rem_bda, p_bcb, BTM_SUCCESS);
603 else
604 #endif
605 btm_sec_mx_access_request(
606 p_bcb->rem_bda, BT_PSM_BNEP, false, BTM_SEC_PROTO_BNEP,
607 bnep_get_uuid32(&(p_bcb->src_uuid)), &bnep_sec_check_complete, p_bcb);
608
609 return;
610 }
611
612 /*******************************************************************************
613 *
614 * Function bnep_process_setup_conn_responce
615 *
616 * Description This function processes a peer's setup connection response
617 * message. The response code is verified and
618 * Connection open indication will be given to PAN profile
619 *
620 * Returns void
621 *
622 ******************************************************************************/
bnep_process_setup_conn_responce(tBNEP_CONN * p_bcb,uint8_t * p_setup)623 void bnep_process_setup_conn_responce(tBNEP_CONN* p_bcb, uint8_t* p_setup) {
624 tBNEP_RESULT resp;
625 uint16_t resp_code;
626
627 BNEP_TRACE_DEBUG("BNEP received setup responce");
628 /* The state should be either SETUP or CONNECTED */
629 if (p_bcb->con_state != BNEP_STATE_CONN_SETUP) {
630 /* Should we disconnect ? */
631 BNEP_TRACE_ERROR("BNEP - setup response in bad state %d", p_bcb->con_state);
632 return;
633 }
634
635 /* Check if we are the originator */
636 if (!(p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) {
637 BNEP_TRACE_ERROR("BNEP - setup response when we are not originator",
638 p_bcb->con_state);
639 return;
640 }
641
642 BE_STREAM_TO_UINT16(resp_code, p_setup);
643
644 switch (resp_code) {
645 case BNEP_SETUP_INVALID_SRC_UUID:
646 resp = BNEP_CONN_FAILED_SRC_UUID;
647 break;
648
649 case BNEP_SETUP_INVALID_DEST_UUID:
650 resp = BNEP_CONN_FAILED_DST_UUID;
651 break;
652
653 case BNEP_SETUP_INVALID_UUID_SIZE:
654 resp = BNEP_CONN_FAILED_UUID_SIZE;
655 break;
656
657 case BNEP_SETUP_CONN_NOT_ALLOWED:
658 default:
659 resp = BNEP_CONN_FAILED;
660 break;
661 }
662
663 /* Check the responce code */
664 if (resp_code != BNEP_SETUP_CONN_OK) {
665 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) {
666 BNEP_TRACE_EVENT("BNEP - role change response is %d", resp_code);
667
668 /* Restore the earlier BNEP status */
669 p_bcb->con_state = BNEP_STATE_CONNECTED;
670 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
671 memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)&(p_bcb->prv_src_uuid),
672 sizeof(tBT_UUID));
673 memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)&(p_bcb->prv_dst_uuid),
674 sizeof(tBT_UUID));
675
676 /* Ensure timer is stopped */
677 alarm_cancel(p_bcb->conn_timer);
678 p_bcb->re_transmits = 0;
679
680 /* Tell the user if he has a callback */
681 if (bnep_cb.p_conn_state_cb)
682 (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda, resp, true);
683
684 return;
685 } else {
686 BNEP_TRACE_ERROR("BNEP - setup response %d is not OK", resp_code);
687
688 L2CA_DisconnectReq(p_bcb->l2cap_cid);
689
690 /* Tell the user if he has a callback */
691 if ((p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) && (bnep_cb.p_conn_state_cb))
692 (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda, resp, false);
693
694 bnepu_release_bcb(p_bcb);
695 return;
696 }
697 }
698
699 /* Received successful responce */
700 bnep_connected(p_bcb);
701 }
702
703 /*******************************************************************************
704 *
705 * Function bnep_process_control_packet
706 *
707 * Description This function processes a peer's setup connection request
708 * message. The destination UUID is verified and response sent
709 * Connection open indication will be given to PAN profile
710 *
711 * Returns void
712 *
713 ******************************************************************************/
bnep_process_control_packet(tBNEP_CONN * p_bcb,uint8_t * p,uint16_t * rem_len,bool is_ext)714 uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
715 uint16_t* rem_len, bool is_ext) {
716 uint8_t control_type;
717 uint16_t len, ext_len = 0;
718
719 if (p == NULL || rem_len == NULL) {
720 if (rem_len != NULL) *rem_len = 0;
721 BNEP_TRACE_DEBUG("%s: invalid packet: p = %p rem_len = %p", __func__, p,
722 rem_len);
723 return NULL;
724 }
725 uint16_t rem_len_orig = *rem_len;
726
727 if (is_ext) {
728 if (*rem_len < 1) goto bad_packet_length;
729 ext_len = *p++;
730 *rem_len = *rem_len - 1;
731 }
732
733 if (*rem_len < 1) goto bad_packet_length;
734 control_type = *p++;
735 *rem_len = *rem_len - 1;
736
737 BNEP_TRACE_EVENT(
738 "%s: BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d",
739 __func__, *rem_len, is_ext, control_type);
740
741 switch (control_type) {
742 case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
743 if (*rem_len < 1) {
744 BNEP_TRACE_ERROR(
745 "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD with bad length",
746 __func__);
747 goto bad_packet_length;
748 }
749 BNEP_TRACE_ERROR(
750 "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD for pkt type: %d",
751 __func__, *p);
752 p++;
753 *rem_len = *rem_len - 1;
754 break;
755
756 case BNEP_SETUP_CONNECTION_REQUEST_MSG:
757 len = *p++;
758 if (*rem_len < ((2 * len) + 1)) {
759 BNEP_TRACE_ERROR(
760 "%s: Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length",
761 __func__);
762 goto bad_packet_length;
763 }
764 if (!is_ext) bnep_process_setup_conn_req(p_bcb, p, (uint8_t)len);
765 p += (2 * len);
766 *rem_len = *rem_len - (2 * len) - 1;
767 break;
768
769 case BNEP_SETUP_CONNECTION_RESPONSE_MSG:
770 if (*rem_len < 2) {
771 BNEP_TRACE_ERROR(
772 "%s: Received BNEP_SETUP_CONNECTION_RESPONSE_MSG with bad length",
773 __func__);
774 goto bad_packet_length;
775 }
776 if (!is_ext) bnep_process_setup_conn_responce(p_bcb, p);
777 p += 2;
778 *rem_len = *rem_len - 2;
779 break;
780
781 case BNEP_FILTER_NET_TYPE_SET_MSG:
782 BE_STREAM_TO_UINT16(len, p);
783 if (*rem_len < (len + 2)) {
784 BNEP_TRACE_ERROR(
785 "%s: Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length",
786 __func__);
787 goto bad_packet_length;
788 }
789 bnepu_process_peer_filter_set(p_bcb, p, len);
790 p += len;
791 *rem_len = *rem_len - len - 2;
792 break;
793
794 case BNEP_FILTER_NET_TYPE_RESPONSE_MSG:
795 if (*rem_len < 2) {
796 BNEP_TRACE_ERROR(
797 "%s: Received BNEP_FILTER_NET_TYPE_RESPONSE_MSG with bad length",
798 __func__);
799 goto bad_packet_length;
800 }
801 bnepu_process_peer_filter_rsp(p_bcb, p);
802 p += 2;
803 *rem_len = *rem_len - 2;
804 break;
805
806 case BNEP_FILTER_MULTI_ADDR_SET_MSG:
807 BE_STREAM_TO_UINT16(len, p);
808 if (*rem_len < (len + 2)) {
809 BNEP_TRACE_ERROR(
810 "%s: Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length",
811 __func__);
812 goto bad_packet_length;
813 }
814 bnepu_process_peer_multicast_filter_set(p_bcb, p, len);
815 p += len;
816 *rem_len = *rem_len - len - 2;
817 break;
818
819 case BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG:
820 if (*rem_len < 2) {
821 BNEP_TRACE_ERROR(
822 "%s: Received BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG with bad length",
823 __func__);
824 goto bad_packet_length;
825 }
826 bnepu_process_multicast_filter_rsp(p_bcb, p);
827 p += 2;
828 *rem_len = *rem_len - 2;
829 break;
830
831 default:
832 BNEP_TRACE_ERROR("%s: BNEP - bad ctl pkt type: %d", __func__,
833 control_type);
834 bnep_send_command_not_understood(p_bcb, control_type);
835 if (is_ext && (ext_len > 0)) {
836 if (*rem_len < (ext_len - 1)) {
837 goto bad_packet_length;
838 }
839 p += (ext_len - 1);
840 *rem_len -= (ext_len - 1);
841 }
842 break;
843 }
844 return p;
845
846 bad_packet_length:
847 BNEP_TRACE_ERROR("%s: bad control packet length: original=%d remaining=%d",
848 __func__, rem_len_orig, *rem_len);
849 *rem_len = 0;
850 return NULL;
851 }
852
853 /*******************************************************************************
854 *
855 * Function bnepu_process_peer_filter_set
856 *
857 * Description This function processes a peer's filter control
858 * 'set' message. The filters are stored in the BCB,
859 * and an appropriate filter response message sent.
860 *
861 * Returns void
862 *
863 ******************************************************************************/
bnepu_process_peer_filter_set(tBNEP_CONN * p_bcb,uint8_t * p_filters,uint16_t len)864 void bnepu_process_peer_filter_set(tBNEP_CONN* p_bcb, uint8_t* p_filters,
865 uint16_t len) {
866 uint16_t num_filters = 0;
867 uint16_t xx, resp_code = BNEP_FILTER_CRL_OK;
868 uint16_t start, end;
869 uint8_t* p_temp_filters;
870
871 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
872 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) {
873 BNEP_TRACE_DEBUG(
874 "BNEP received filter set from peer when there is no connection");
875 return;
876 }
877
878 BNEP_TRACE_DEBUG("BNEP received filter set from peer");
879 /* Check for length not a multiple of 4 */
880 if (len & 3) {
881 BNEP_TRACE_EVENT("BNEP - bad filter len: %d", len);
882 bnepu_send_peer_filter_rsp(p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
883 return;
884 }
885
886 if (len) num_filters = (uint16_t)(len >> 2);
887
888 /* Validate filter values */
889 if (num_filters <= BNEP_MAX_PROT_FILTERS) {
890 p_temp_filters = p_filters;
891 for (xx = 0; xx < num_filters; xx++) {
892 BE_STREAM_TO_UINT16(start, p_temp_filters);
893 BE_STREAM_TO_UINT16(end, p_temp_filters);
894
895 if (start > end) {
896 resp_code = BNEP_FILTER_CRL_BAD_RANGE;
897 break;
898 }
899 }
900 } else
901 resp_code = BNEP_FILTER_CRL_MAX_REACHED;
902
903 if (resp_code != BNEP_FILTER_CRL_OK) {
904 bnepu_send_peer_filter_rsp(p_bcb, resp_code);
905 return;
906 }
907
908 if (bnep_cb.p_filter_ind_cb)
909 (*bnep_cb.p_filter_ind_cb)(p_bcb->handle, true, 0, len, p_filters);
910
911 p_bcb->rcvd_num_filters = num_filters;
912 for (xx = 0; xx < num_filters; xx++) {
913 BE_STREAM_TO_UINT16(start, p_filters);
914 BE_STREAM_TO_UINT16(end, p_filters);
915
916 p_bcb->rcvd_prot_filter_start[xx] = start;
917 p_bcb->rcvd_prot_filter_end[xx] = end;
918 }
919
920 bnepu_send_peer_filter_rsp(p_bcb, resp_code);
921 }
922
923 /*******************************************************************************
924 *
925 * Function bnepu_process_peer_filter_rsp
926 *
927 * Description This function processes a peer's filter control
928 * 'response' message.
929 *
930 * Returns void
931 *
932 ******************************************************************************/
bnepu_process_peer_filter_rsp(tBNEP_CONN * p_bcb,uint8_t * p_data)933 void bnepu_process_peer_filter_rsp(tBNEP_CONN* p_bcb, uint8_t* p_data) {
934 uint16_t resp_code;
935 tBNEP_RESULT result;
936
937 BNEP_TRACE_DEBUG("BNEP received filter responce");
938 /* The state should be CONNECTED */
939 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
940 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) {
941 BNEP_TRACE_ERROR("BNEP - filter response in bad state %d",
942 p_bcb->con_state);
943 return;
944 }
945
946 /* Check if we are the originator */
947 if (!(p_bcb->con_flags & BNEP_FLAGS_FILTER_RESP_PEND)) {
948 BNEP_TRACE_ERROR("BNEP - filter response when not expecting");
949 return;
950 }
951
952 /* Ensure timer is stopped */
953 alarm_cancel(p_bcb->conn_timer);
954 p_bcb->con_flags &= ~BNEP_FLAGS_FILTER_RESP_PEND;
955 p_bcb->re_transmits = 0;
956
957 BE_STREAM_TO_UINT16(resp_code, p_data);
958
959 result = BNEP_SUCCESS;
960 if (resp_code != BNEP_FILTER_CRL_OK) result = BNEP_SET_FILTER_FAIL;
961
962 if (bnep_cb.p_filter_ind_cb)
963 (*bnep_cb.p_filter_ind_cb)(p_bcb->handle, false, result, 0, NULL);
964 }
965
966 /*******************************************************************************
967 *
968 * Function bnepu_process_multicast_filter_rsp
969 *
970 * Description This function processes multicast filter control
971 * 'response' message.
972 *
973 * Returns void
974 *
975 ******************************************************************************/
bnepu_process_multicast_filter_rsp(tBNEP_CONN * p_bcb,uint8_t * p_data)976 void bnepu_process_multicast_filter_rsp(tBNEP_CONN* p_bcb, uint8_t* p_data) {
977 uint16_t resp_code;
978 tBNEP_RESULT result;
979
980 BNEP_TRACE_DEBUG("BNEP received multicast filter responce");
981 /* The state should be CONNECTED */
982 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
983 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) {
984 BNEP_TRACE_ERROR("BNEP - multicast filter response in bad state %d",
985 p_bcb->con_state);
986 return;
987 }
988
989 /* Check if we are the originator */
990 if (!(p_bcb->con_flags & BNEP_FLAGS_MULTI_RESP_PEND)) {
991 BNEP_TRACE_ERROR("BNEP - multicast filter response when not expecting");
992 return;
993 }
994
995 /* Ensure timer is stopped */
996 alarm_cancel(p_bcb->conn_timer);
997 p_bcb->con_flags &= ~BNEP_FLAGS_MULTI_RESP_PEND;
998 p_bcb->re_transmits = 0;
999
1000 BE_STREAM_TO_UINT16(resp_code, p_data);
1001
1002 result = BNEP_SUCCESS;
1003 if (resp_code != BNEP_FILTER_CRL_OK) result = BNEP_SET_FILTER_FAIL;
1004
1005 if (bnep_cb.p_mfilter_ind_cb)
1006 (*bnep_cb.p_mfilter_ind_cb)(p_bcb->handle, false, result, 0, NULL);
1007 }
1008
1009 /*******************************************************************************
1010 *
1011 * Function bnepu_process_peer_multicast_filter_set
1012 *
1013 * Description This function processes a peer's filter control
1014 * 'set' message. The filters are stored in the BCB,
1015 * and an appropriate filter response message sent.
1016 *
1017 * Returns void
1018 *
1019 ******************************************************************************/
bnepu_process_peer_multicast_filter_set(tBNEP_CONN * p_bcb,uint8_t * p_filters,uint16_t len)1020 void bnepu_process_peer_multicast_filter_set(tBNEP_CONN* p_bcb,
1021 uint8_t* p_filters, uint16_t len) {
1022 uint16_t resp_code = BNEP_FILTER_CRL_OK;
1023 uint16_t num_filters, xx;
1024 uint8_t *p_temp_filters, null_bda[BD_ADDR_LEN] = {0, 0, 0, 0, 0, 0};
1025
1026 if ((p_bcb->con_state != BNEP_STATE_CONNECTED) &&
1027 (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) {
1028 BNEP_TRACE_DEBUG(
1029 "BNEP received multicast filter set from peer when there is no "
1030 "connection");
1031 return;
1032 }
1033
1034 if (len % 12) {
1035 BNEP_TRACE_EVENT("BNEP - bad filter len: %d", len);
1036 bnepu_send_peer_multicast_filter_rsp(p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
1037 return;
1038 }
1039
1040 if (len > (BNEP_MAX_MULTI_FILTERS * 2 * BD_ADDR_LEN)) {
1041 BNEP_TRACE_EVENT("BNEP - Too many filters");
1042 bnepu_send_peer_multicast_filter_rsp(p_bcb, BNEP_FILTER_CRL_MAX_REACHED);
1043 return;
1044 }
1045
1046 num_filters = 0;
1047 if (len) num_filters = (uint16_t)(len / 12);
1048
1049 /* Validate filter values */
1050 if (num_filters <= BNEP_MAX_MULTI_FILTERS) {
1051 p_temp_filters = p_filters;
1052 for (xx = 0; xx < num_filters; xx++) {
1053 if (memcmp(p_temp_filters, p_temp_filters + BD_ADDR_LEN, BD_ADDR_LEN) >
1054 0) {
1055 bnepu_send_peer_multicast_filter_rsp(p_bcb, BNEP_FILTER_CRL_BAD_RANGE);
1056 return;
1057 }
1058
1059 p_temp_filters += (BD_ADDR_LEN * 2);
1060 }
1061 }
1062
1063 p_bcb->rcvd_mcast_filters = num_filters;
1064 for (xx = 0; xx < num_filters; xx++) {
1065 memcpy(p_bcb->rcvd_mcast_filter_start[xx], p_filters, BD_ADDR_LEN);
1066 memcpy(p_bcb->rcvd_mcast_filter_end[xx], p_filters + BD_ADDR_LEN,
1067 BD_ADDR_LEN);
1068 p_filters += (BD_ADDR_LEN * 2);
1069
1070 /* Check if any of the ranges have all zeros as both starting and ending
1071 * addresses */
1072 if ((memcmp(null_bda, p_bcb->rcvd_mcast_filter_start[xx], BD_ADDR_LEN) ==
1073 0) &&
1074 (memcmp(null_bda, p_bcb->rcvd_mcast_filter_end[xx], BD_ADDR_LEN) ==
1075 0)) {
1076 p_bcb->rcvd_mcast_filters = 0xFFFF;
1077 break;
1078 }
1079 }
1080
1081 BNEP_TRACE_EVENT("BNEP multicast filters %d", p_bcb->rcvd_mcast_filters);
1082 bnepu_send_peer_multicast_filter_rsp(p_bcb, resp_code);
1083
1084 if (bnep_cb.p_mfilter_ind_cb)
1085 (*bnep_cb.p_mfilter_ind_cb)(p_bcb->handle, true, 0, len, p_filters);
1086 }
1087
1088 /*******************************************************************************
1089 *
1090 * Function bnepu_send_peer_multicast_filter_rsp
1091 *
1092 * Description This function sends a filter response to a peer
1093 *
1094 * Returns void
1095 *
1096 ******************************************************************************/
bnepu_send_peer_multicast_filter_rsp(tBNEP_CONN * p_bcb,uint16_t response_code)1097 void bnepu_send_peer_multicast_filter_rsp(tBNEP_CONN* p_bcb,
1098 uint16_t response_code) {
1099 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE);
1100 uint8_t* p;
1101
1102 BNEP_TRACE_DEBUG("BNEP sending multicast filter response %d", response_code);
1103
1104 p_buf->offset = L2CAP_MIN_OFFSET;
1105 p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
1106
1107 /* Put in BNEP frame type - filter control */
1108 UINT8_TO_BE_STREAM(p, BNEP_FRAME_CONTROL);
1109
1110 /* Put in filter message type - set filters */
1111 UINT8_TO_BE_STREAM(p, BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG);
1112
1113 UINT16_TO_BE_STREAM(p, response_code);
1114
1115 p_buf->len = 4;
1116
1117 bnepu_check_send_packet(p_bcb, p_buf);
1118 }
1119
1120 /*******************************************************************************
1121 *
1122 * Function bnep_sec_check_complete
1123 *
1124 * Description This function is registered with BTM and will be called
1125 * after completing the security procedures
1126 *
1127 * Returns void
1128 *
1129 ******************************************************************************/
bnep_sec_check_complete(UNUSED_ATTR BD_ADDR bd_addr,UNUSED_ATTR tBT_TRANSPORT trasnport,void * p_ref_data,uint8_t result)1130 void bnep_sec_check_complete(UNUSED_ATTR BD_ADDR bd_addr,
1131 UNUSED_ATTR tBT_TRANSPORT trasnport,
1132 void* p_ref_data, uint8_t result) {
1133 tBNEP_CONN* p_bcb = (tBNEP_CONN*)p_ref_data;
1134 uint16_t resp_code = BNEP_SETUP_CONN_OK;
1135 bool is_role_change;
1136
1137 BNEP_TRACE_EVENT("BNEP security callback returned result %d", result);
1138 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
1139 is_role_change = true;
1140 else
1141 is_role_change = false;
1142
1143 /* check if the port is still waiting for security to complete */
1144 if (p_bcb->con_state != BNEP_STATE_SEC_CHECKING) {
1145 BNEP_TRACE_ERROR(
1146 "BNEP Connection in wrong state %d when security is completed",
1147 p_bcb->con_state);
1148 return;
1149 }
1150
1151 /* if it is outgoing call and result is FAILURE return security fail error */
1152 if (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) {
1153 if (result != BTM_SUCCESS) {
1154 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) {
1155 /* Tell the user that role change is failed because of security */
1156 if (bnep_cb.p_conn_state_cb)
1157 (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
1158 BNEP_SECURITY_FAIL, is_role_change);
1159
1160 p_bcb->con_state = BNEP_STATE_CONNECTED;
1161 memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)&(p_bcb->prv_src_uuid),
1162 sizeof(tBT_UUID));
1163 memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)&(p_bcb->prv_dst_uuid),
1164 sizeof(tBT_UUID));
1165 return;
1166 }
1167
1168 L2CA_DisconnectReq(p_bcb->l2cap_cid);
1169
1170 /* Tell the user if he has a callback */
1171 if (bnep_cb.p_conn_state_cb)
1172 (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda,
1173 BNEP_SECURITY_FAIL, is_role_change);
1174
1175 bnepu_release_bcb(p_bcb);
1176 return;
1177 }
1178
1179 /* Transition to the next appropriate state, waiting for connection confirm.
1180 */
1181 p_bcb->con_state = BNEP_STATE_CONN_SETUP;
1182
1183 bnep_send_conn_req(p_bcb);
1184 alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
1185 bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
1186 return;
1187 }
1188
1189 /* it is an incoming call respond appropriately */
1190 if (result != BTM_SUCCESS) {
1191 bnep_send_conn_responce(p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED);
1192 if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) {
1193 /* Role change is failed because of security. Revert back to connected
1194 * state */
1195 p_bcb->con_state = BNEP_STATE_CONNECTED;
1196 p_bcb->con_flags &= (~BNEP_FLAGS_SETUP_RCVD);
1197 memcpy((uint8_t*)&(p_bcb->src_uuid), (uint8_t*)&(p_bcb->prv_src_uuid),
1198 sizeof(tBT_UUID));
1199 memcpy((uint8_t*)&(p_bcb->dst_uuid), (uint8_t*)&(p_bcb->prv_dst_uuid),
1200 sizeof(tBT_UUID));
1201 return;
1202 }
1203
1204 L2CA_DisconnectReq(p_bcb->l2cap_cid);
1205
1206 bnepu_release_bcb(p_bcb);
1207 return;
1208 }
1209
1210 if (bnep_cb.p_conn_ind_cb) {
1211 p_bcb->con_state = BNEP_STATE_CONN_SETUP;
1212 (*bnep_cb.p_conn_ind_cb)(p_bcb->handle, p_bcb->rem_bda, &p_bcb->dst_uuid,
1213 &p_bcb->src_uuid, is_role_change);
1214 } else {
1215 /* Profile didn't register connection indication call back */
1216 bnep_send_conn_responce(p_bcb, resp_code);
1217 bnep_connected(p_bcb);
1218 }
1219
1220 return;
1221 }
1222
1223 /*******************************************************************************
1224 *
1225 * Function bnep_is_packet_allowed
1226 *
1227 * Description This function verifies whether the protocol passes through
1228 * the protocol filters set by the peer
1229 *
1230 * Returns BNEP_SUCCESS - if the protocol is allowed
1231 * BNEP_IGNORE_CMD - if the protocol is filtered out
1232 *
1233 ******************************************************************************/
bnep_is_packet_allowed(tBNEP_CONN * p_bcb,BD_ADDR p_dest_addr,uint16_t protocol,bool fw_ext_present,uint8_t * p_data)1234 tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb, BD_ADDR p_dest_addr,
1235 uint16_t protocol, bool fw_ext_present,
1236 uint8_t* p_data) {
1237 if (p_bcb->rcvd_num_filters) {
1238 uint16_t i, proto;
1239
1240 /* Findout the actual protocol to check for the filtering */
1241 proto = protocol;
1242 if (proto == BNEP_802_1_P_PROTOCOL) {
1243 if (fw_ext_present) {
1244 uint8_t len, ext;
1245 /* parse the extension headers and findout actual protocol */
1246 do {
1247 ext = *p_data++;
1248 len = *p_data++;
1249 p_data += len;
1250
1251 } while (ext & 0x80);
1252 }
1253 p_data += 2;
1254 BE_STREAM_TO_UINT16(proto, p_data);
1255 }
1256
1257 for (i = 0; i < p_bcb->rcvd_num_filters; i++) {
1258 if ((p_bcb->rcvd_prot_filter_start[i] <= proto) &&
1259 (proto <= p_bcb->rcvd_prot_filter_end[i]))
1260 break;
1261 }
1262
1263 if (i == p_bcb->rcvd_num_filters) {
1264 BNEP_TRACE_DEBUG("Ignoring protocol 0x%x in BNEP data write", proto);
1265 return BNEP_IGNORE_CMD;
1266 }
1267 }
1268
1269 /* Ckeck for multicast address filtering */
1270 if ((p_dest_addr[0] & 0x01) && p_bcb->rcvd_mcast_filters) {
1271 uint16_t i;
1272
1273 /* Check if every multicast should be filtered */
1274 if (p_bcb->rcvd_mcast_filters != 0xFFFF) {
1275 /* Check if the address is mentioned in the filter range */
1276 for (i = 0; i < p_bcb->rcvd_mcast_filters; i++) {
1277 if ((memcmp(p_bcb->rcvd_mcast_filter_start[i], p_dest_addr,
1278 BD_ADDR_LEN) <= 0) &&
1279 (memcmp(p_bcb->rcvd_mcast_filter_end[i], p_dest_addr,
1280 BD_ADDR_LEN) >= 0))
1281 break;
1282 }
1283 }
1284
1285 /*
1286 ** If every multicast should be filtered or the address is not in the filter
1287 *range
1288 ** drop the packet
1289 */
1290 if ((p_bcb->rcvd_mcast_filters == 0xFFFF) ||
1291 (i == p_bcb->rcvd_mcast_filters)) {
1292 BNEP_TRACE_DEBUG(
1293 "Ignoring multicast address %x.%x.%x.%x.%x.%x in BNEP data write",
1294 p_dest_addr[0], p_dest_addr[1], p_dest_addr[2], p_dest_addr[3],
1295 p_dest_addr[4], p_dest_addr[5]);
1296 return BNEP_IGNORE_CMD;
1297 }
1298 }
1299
1300 return BNEP_SUCCESS;
1301 }
1302
1303 /*******************************************************************************
1304 *
1305 * Function bnep_get_uuid32
1306 *
1307 * Description This function returns the 32-bit equivalent of the UUID
1308 *
1309 * Returns uint32_t - 32-bit equivalent of the UUID
1310 *
1311 ******************************************************************************/
bnep_get_uuid32(tBT_UUID * src_uuid)1312 uint32_t bnep_get_uuid32(tBT_UUID* src_uuid) {
1313 uint32_t result;
1314
1315 if (src_uuid->len == 2)
1316 return ((uint32_t)src_uuid->uu.uuid16);
1317 else if (src_uuid->len == 4)
1318 return (src_uuid->uu.uuid32 & 0x0000FFFF);
1319 else {
1320 result = src_uuid->uu.uuid128[2];
1321 result = (result << 8) | (src_uuid->uu.uuid128[3]);
1322 return result;
1323 }
1324 }
1325