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