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