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