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