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