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