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