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