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