Home | History | Annotate | Download | only in gap
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2009-2013 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 #include "bt_target.h"
     21 #include "btu.h"
     22 #include "gap_int.h"
     23 #include "l2cdefs.h"
     24 #include "l2c_int.h"
     25 #include <string.h>
     26 #if GAP_CONN_INCLUDED == TRUE
     27 #include "btm_int.h"
     28 
     29 /********************************************************************************/
     30 /*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
     31 /********************************************************************************/
     32 static void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id);
     33 static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result);
     34 static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
     35 static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
     36 static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed);
     37 static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg);
     38 static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested);
     39 
     40 static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid);
     41 static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle);
     42 static tGAP_CCB *gap_allocate_ccb (void);
     43 static void      gap_release_ccb (tGAP_CCB *p_ccb);
     44 
     45 /*******************************************************************************
     46 **
     47 ** Function         gap_conn_init
     48 **
     49 ** Description      This function is called to initialize GAP connection management
     50 **
     51 ** Returns          void
     52 **
     53 *******************************************************************************/
     54 void gap_conn_init (void)
     55 {
     56 #if AMP_INCLUDED == TRUE
     57     gap_cb.conn.reg_info.pAMP_ConnectInd_Cb         = gap_connect_ind;
     58     gap_cb.conn.reg_info.pAMP_ConnectCfm_Cb         = gap_connect_cfm;
     59     gap_cb.conn.reg_info.pAMP_ConnectPnd_Cb         = NULL;
     60     gap_cb.conn.reg_info.pAMP_ConfigInd_Cb          = gap_config_ind;
     61     gap_cb.conn.reg_info.pAMP_ConfigCfm_Cb          = gap_config_cfm;
     62     gap_cb.conn.reg_info.pAMP_DisconnectInd_Cb      = gap_disconnect_ind;
     63     gap_cb.conn.reg_info.pAMP_DisconnectCfm_Cb      = NULL;
     64     gap_cb.conn.reg_info.pAMP_QoSViolationInd_Cb    = NULL;
     65     gap_cb.conn.reg_info.pAMP_DataInd_Cb            = gap_data_ind;
     66     gap_cb.conn.reg_info.pAMP_CongestionStatus_Cb   = gap_congestion_ind;
     67     gap_cb.conn.reg_info.pAMP_TxComplete_Cb         = NULL;
     68     gap_cb.conn.reg_info.pAMP_MoveInd_Cb            = NULL;
     69     gap_cb.conn.reg_info.pAMP_MoveRsp_Cb            = NULL;
     70     gap_cb.conn.reg_info.pAMP_MoveCfm_Cb            = NULL; //gap_move_cfm
     71     gap_cb.conn.reg_info.pAMP_MoveCfmRsp_Cb         = NULL; //gap_move_cfm_rsp
     72 
     73 #else
     74     gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb       = gap_connect_ind;
     75     gap_cb.conn.reg_info.pL2CA_ConnectCfm_Cb       = gap_connect_cfm;
     76     gap_cb.conn.reg_info.pL2CA_ConnectPnd_Cb       = NULL;
     77     gap_cb.conn.reg_info.pL2CA_ConfigInd_Cb        = gap_config_ind;
     78     gap_cb.conn.reg_info.pL2CA_ConfigCfm_Cb        = gap_config_cfm;
     79     gap_cb.conn.reg_info.pL2CA_DisconnectInd_Cb    = gap_disconnect_ind;
     80     gap_cb.conn.reg_info.pL2CA_DisconnectCfm_Cb    = NULL;
     81     gap_cb.conn.reg_info.pL2CA_QoSViolationInd_Cb  = NULL;
     82     gap_cb.conn.reg_info.pL2CA_DataInd_Cb          = gap_data_ind;
     83     gap_cb.conn.reg_info.pL2CA_CongestionStatus_Cb = gap_congestion_ind;
     84     gap_cb.conn.reg_info.pL2CA_TxComplete_Cb       = NULL;
     85 #endif
     86 }
     87 
     88 
     89 /*******************************************************************************
     90 **
     91 ** Function         GAP_ConnOpen
     92 **
     93 ** Description      This function is called to open an L2CAP connection.
     94 **
     95 ** Parameters:      is_server   - If TRUE, the connection is not created
     96 **                                but put into a "listen" mode waiting for
     97 **                                the remote side to connect.
     98 **
     99 **                  service_id  - Unique service ID from
    100 **                                BTM_SEC_SERVICE_FIRST_EMPTY (6)
    101 **                                to BTM_SEC_MAX_SERVICE_RECORDS (32)
    102 **
    103 **                  p_rem_bda   - Pointer to remote BD Address.
    104 **                                If a server, and we don't care about the
    105 **                                remote BD Address, then NULL should be passed.
    106 **
    107 **                  psm         - the PSM used for the connection
    108 **
    109 **                  p_config    - Optional pointer to configuration structure.
    110 **                                If NULL, the default GAP configuration will
    111 **                                be used.
    112 **
    113 **                  security    - security flags
    114 **                  chan_mode_mask - (GAP_FCR_CHAN_OPT_BASIC, GAP_FCR_CHAN_OPT_ERTM, GAP_FCR_CHAN_OPT_STREAM)
    115 **
    116 **                  p_cb        - Pointer to callback function for events.
    117 **
    118 ** Returns          handle of the connection if successful, else GAP_INVALID_HANDLE
    119 **
    120 *******************************************************************************/
    121 UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
    122                      BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg,
    123                      UINT16 security, UINT8 chan_mode_mask, tGAP_CONN_CALLBACK *p_cb)
    124 {
    125     tGAP_CCB    *p_ccb;
    126     UINT16       cid;
    127     tBT_UUID    bt_uuid = {2, {GAP_PROTOCOL_ID}};
    128 
    129     GAP_TRACE_EVENT0 ("GAP_CONN - Open Request");
    130 
    131     /* Allocate a new CCB. Return if none available. */
    132     if ((p_ccb = gap_allocate_ccb()) == NULL)
    133         return (GAP_INVALID_HANDLE);
    134 
    135     /* If caller specified a BD address, save it */
    136     if (p_rem_bda)
    137     {
    138         /* the bd addr is not BT_BD_ANY, then a bd address was specified */
    139         if (memcmp (p_rem_bda, BT_BD_ANY, BD_ADDR_LEN))
    140             p_ccb->rem_addr_specified = TRUE;
    141 
    142         memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
    143     }
    144     else if (!is_server)
    145     {
    146         /* remore addr is not specified and is not a server -> bad */
    147         return (GAP_INVALID_HANDLE);
    148     }
    149 
    150     /* A client MUST have specified a bd addr to connect with */
    151     if (!p_ccb->rem_addr_specified && !is_server)
    152     {
    153         gap_release_ccb (p_ccb);
    154         GAP_TRACE_ERROR0 ("GAP ERROR: Client must specify a remote BD ADDR to connect to!");
    155         return (GAP_INVALID_HANDLE);
    156     }
    157 
    158     /* Check if configuration was specified */
    159     if (p_cfg)
    160         p_ccb->cfg = *p_cfg;
    161 
    162     p_ccb->p_callback     = p_cb;
    163 
    164     /* If originator, use a dynamic PSM */
    165 #if AMP_INCLUDED == TRUE
    166     if (!is_server)
    167         gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = NULL;
    168     else
    169         gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = gap_connect_ind;
    170 #else
    171     if (!is_server)
    172         gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = NULL;
    173     else
    174         gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind;
    175 #endif
    176 
    177     /* Register the PSM with L2CAP */
    178     if ((p_ccb->psm = L2CA_REGISTER (psm, &gap_cb.conn.reg_info, AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE)) == 0)
    179     {
    180         GAP_TRACE_ERROR1 ("GAP_ConnOpen: Failure registering PSM 0x%04x", psm);
    181         gap_release_ccb (p_ccb);
    182         return (GAP_INVALID_HANDLE);
    183     }
    184 
    185     /* Register with Security Manager for the specific security level */
    186     p_ccb->service_id = service_id;
    187     if (!BTM_SetSecurityLevel ((UINT8)!is_server, p_serv_name, p_ccb->service_id, security, p_ccb->psm, 0, 0))
    188     {
    189         GAP_TRACE_ERROR0 ("GAP_CONN - Security Error");
    190         gap_release_ccb (p_ccb);
    191         return (GAP_INVALID_HANDLE);
    192     }
    193 
    194     /* Fill in eL2CAP parameter data */
    195     if( p_ccb->cfg.fcr_present )
    196     {
    197         p_ccb->ertm_info.preferred_mode = p_ccb->cfg.fcr.mode;
    198         p_ccb->ertm_info.user_rx_pool_id = GAP_DATA_POOL_ID;
    199         p_ccb->ertm_info.user_tx_pool_id = GAP_DATA_POOL_ID;
    200         p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
    201         p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
    202     }
    203 
    204     /* optional FCR channel modes */
    205     p_ccb->ertm_info.allowed_modes = (chan_mode_mask) ? chan_mode_mask : (UINT8)L2CAP_FCR_CHAN_OPT_BASIC;
    206 
    207     if (is_server)
    208     {
    209         p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; /* assume btm/l2cap would handle it */
    210         p_ccb->con_state = GAP_CCB_STATE_LISTENING;
    211         return (p_ccb->gap_handle);
    212     }
    213     else
    214     {
    215         /* We are the originator of this connection */
    216         p_ccb->con_flags = GAP_CCB_FLAGS_IS_ORIG;
    217 
    218         /* Transition to the next appropriate state, waiting for connection confirm. */
    219         p_ccb->con_state = GAP_CCB_STATE_CONN_SETUP;
    220 
    221         /* mark security done flag, when security is not required */
    222         if ((security & (BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT) ) == 0)
    223             p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
    224 
    225         /* Check if L2CAP started the connection process */
    226         if (p_rem_bda && ((cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info, &bt_uuid)) != 0))
    227         {
    228             p_ccb->connection_id = cid;
    229             return (p_ccb->gap_handle);
    230         }
    231         else
    232         {
    233             gap_release_ccb (p_ccb);
    234             return (GAP_INVALID_HANDLE);
    235         }
    236     }
    237 }
    238 
    239 
    240 /*******************************************************************************
    241 **
    242 ** Function         GAP_ConnClose
    243 **
    244 ** Description      This function is called to close a connection.
    245 **
    246 ** Parameters:      handle      - Handle of the connection returned by GAP_ConnOpen
    247 **
    248 ** Returns          BT_PASS             - closed OK
    249 **                  GAP_ERR_BAD_HANDLE  - invalid handle
    250 **
    251 *******************************************************************************/
    252 UINT16 GAP_ConnClose (UINT16 gap_handle)
    253 {
    254     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
    255 
    256     GAP_TRACE_EVENT1 ("GAP_CONN - close  handle: 0x%x", gap_handle);
    257 
    258     if (p_ccb)
    259     {
    260         /* Check if we have a connection ID */
    261         if (p_ccb->con_state != GAP_CCB_STATE_LISTENING)
    262             L2CA_DISCONNECT_REQ (p_ccb->connection_id);
    263 
    264         gap_release_ccb (p_ccb);
    265 
    266         return (BT_PASS);
    267     }
    268 
    269     return (GAP_ERR_BAD_HANDLE);
    270 }
    271 
    272 
    273 
    274 /*******************************************************************************
    275 **
    276 ** Function         GAP_ConnReadData
    277 **
    278 ** Description      Normally not GKI aware application will call this function
    279 **                  after receiving GAP_EVT_RXDATA event.
    280 **
    281 ** Parameters:      handle      - Handle of the connection returned in the Open
    282 **                  p_data      - Data area
    283 **                  max_len     - Byte count requested
    284 **                  p_len       - Byte count received
    285 **
    286 ** Returns          BT_PASS             - data read
    287 **                  GAP_ERR_BAD_HANDLE  - invalid handle
    288 **                  GAP_NO_DATA_AVAIL   - no data available
    289 **
    290 *******************************************************************************/
    291 UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
    292 {
    293     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
    294     BT_HDR     *p_buf;
    295     UINT16      copy_len;
    296 
    297     if (!p_ccb)
    298         return (GAP_ERR_BAD_HANDLE);
    299 
    300     *p_len = 0;
    301 
    302     p_buf = (BT_HDR *)GKI_getfirst (&p_ccb->rx_queue);
    303     if (!p_buf)
    304         return (GAP_NO_DATA_AVAIL);
    305 
    306     GKI_disable();
    307 
    308     while (max_len && p_buf)
    309     {
    310         copy_len = (p_buf->len > max_len)?max_len:p_buf->len;
    311         max_len -= copy_len;
    312         *p_len  += copy_len;
    313         if (p_data)
    314         {
    315             memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, copy_len);
    316             p_data += copy_len;
    317         }
    318 
    319         if (p_buf->len > copy_len)
    320         {
    321             p_buf->offset += copy_len;
    322             p_buf->len    -= copy_len;
    323             break;
    324         }
    325         else
    326         {
    327             if (max_len)
    328             {
    329                 p_buf = (BT_HDR *)GKI_getnext (p_buf);
    330             }
    331             GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));
    332         }
    333     }
    334 
    335     p_ccb->rx_queue_size -= *p_len;
    336 
    337     GKI_enable();
    338 
    339     GAP_TRACE_EVENT2 ("GAP_ConnReadData - rx_queue_size left=%d, *p_len=%d",
    340                                        p_ccb->rx_queue_size, *p_len);
    341 
    342     return (BT_PASS);
    343 }
    344 
    345 /*******************************************************************************
    346 **
    347 ** Function         GAP_GetRxQueueCnt
    348 **
    349 ** Description      This function return number of bytes on the rx queue.
    350 **
    351 ** Parameters:      handle     - Handle returned in the GAP_ConnOpen
    352 **                  p_rx_queue_count - Pointer to return queue count in.
    353 **
    354 **
    355 *******************************************************************************/
    356 int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
    357 {
    358     tGAP_CCB    *p_ccb;
    359     int         rc = BT_PASS;
    360 
    361     /* Check that handle is valid */
    362     if (handle < GAP_MAX_CONNECTIONS)
    363     {
    364         p_ccb = &gap_cb.conn.ccb_pool[handle];
    365 
    366         if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
    367         {
    368             *p_rx_queue_count = p_ccb->rx_queue_size;
    369         }
    370         else
    371             rc = GAP_INVALID_HANDLE;
    372     }
    373     else
    374         rc = GAP_INVALID_HANDLE;
    375 
    376     GAP_TRACE_EVENT2 ("GAP_GetRxQueueCnt - rc = 0x%04x, rx_queue_count=%d",
    377                                        rc , *p_rx_queue_count);
    378 
    379     return (rc);
    380 }
    381 
    382 /*******************************************************************************
    383 **
    384 ** Function         GAP_ConnBTRead
    385 **
    386 ** Description      Bluetooth aware applications will call this function after receiving
    387 **                  GAP_EVT_RXDATA event.
    388 **
    389 ** Parameters:      handle      - Handle of the connection returned in the Open
    390 **                  pp_buf      - pointer to address of buffer with data,
    391 **
    392 ** Returns          BT_PASS             - data read
    393 **                  GAP_ERR_BAD_HANDLE  - invalid handle
    394 **                  GAP_NO_DATA_AVAIL   - no data available
    395 **
    396 *******************************************************************************/
    397 UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf)
    398 {
    399     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
    400     BT_HDR      *p_buf;
    401 
    402     if (!p_ccb)
    403         return (GAP_ERR_BAD_HANDLE);
    404 
    405     p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->rx_queue);
    406 
    407     if (p_buf)
    408     {
    409         *pp_buf = p_buf;
    410 
    411         p_ccb->rx_queue_size -= p_buf->len;
    412         return (BT_PASS);
    413     }
    414     else
    415     {
    416         *pp_buf = NULL;
    417         return (GAP_NO_DATA_AVAIL);
    418     }
    419 }
    420 
    421 
    422 /*******************************************************************************
    423 **
    424 ** Function         GAP_ConnBTWrite
    425 **
    426 ** Description      Bluetooth Aware applications can call this function to write data.
    427 **
    428 ** Parameters:      handle      - Handle of the connection returned in the Open
    429 **                  p_buf      - pointer to address of buffer with data,
    430 **
    431 ** Returns          BT_PASS                 - data read
    432 **                  GAP_ERR_BAD_HANDLE      - invalid handle
    433 **                  GAP_ERR_BAD_STATE       - connection not established
    434 **                  GAP_INVALID_BUF_OFFSET  - buffer offset is invalid
    435 *******************************************************************************/
    436 UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
    437 {
    438     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
    439 
    440     if (!p_ccb)
    441     {
    442         GKI_freebuf (p_buf);
    443         return (GAP_ERR_BAD_HANDLE);
    444     }
    445 
    446     if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
    447     {
    448         GKI_freebuf (p_buf);
    449         return (GAP_ERR_BAD_STATE);
    450     }
    451 
    452     if (p_buf->offset < L2CAP_MIN_OFFSET)
    453     {
    454         GKI_freebuf (p_buf);
    455         return (GAP_ERR_BUF_OFFSET);
    456     }
    457 
    458     GKI_enqueue (&p_ccb->tx_queue, p_buf);
    459 
    460     if (p_ccb->is_congested)
    461     {
    462         return (BT_PASS);
    463     }
    464 
    465     /* Send the buffer through L2CAP */
    466 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
    467     gap_send_event (gap_handle);
    468 #else
    469     while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
    470     {
    471         UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
    472 
    473         if (status == L2CAP_DW_CONGESTED)
    474         {
    475             p_ccb->is_congested = TRUE;
    476             break;
    477         }
    478         else if (status != L2CAP_DW_SUCCESS)
    479             return (GAP_ERR_BAD_STATE);
    480     }
    481 #endif
    482     return (BT_PASS);
    483 }
    484 
    485 
    486 /*******************************************************************************
    487 **
    488 ** Function         GAP_ConnWriteData
    489 **
    490 ** Description      Normally not GKI aware application will call this function
    491 **                  to send data to the connection.
    492 **
    493 ** Parameters:      handle      - Handle of the connection returned in the Open
    494 **                  p_data      - Data area
    495 **                  max_len     - Byte count requested
    496 **                  p_len       - Byte count received
    497 **
    498 ** Returns          BT_PASS                 - data read
    499 **                  GAP_ERR_BAD_HANDLE      - invalid handle
    500 **                  GAP_ERR_BAD_STATE       - connection not established
    501 **                  GAP_CONGESTION          - system is congested
    502 **
    503 *******************************************************************************/
    504 UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
    505 {
    506     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
    507     BT_HDR     *p_buf;
    508 
    509     *p_len = 0;
    510 
    511     if (!p_ccb)
    512         return (GAP_ERR_BAD_HANDLE);
    513 
    514     if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
    515         return (GAP_ERR_BAD_STATE);
    516 
    517     while (max_len)
    518     {
    519         if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
    520         {
    521             if ((p_buf = (BT_HDR *)GKI_getpoolbuf (p_ccb->ertm_info.user_tx_pool_id)) == NULL)
    522                 return (GAP_ERR_CONGESTED);
    523         }
    524         else
    525         {
    526             if ((p_buf = (BT_HDR *)GKI_getpoolbuf (GAP_DATA_POOL_ID)) == NULL)
    527                 return (GAP_ERR_CONGESTED);
    528         }
    529 
    530         p_buf->offset = L2CAP_MIN_OFFSET;
    531         p_buf->len = (p_ccb->rem_mtu_size < max_len) ? p_ccb->rem_mtu_size : max_len;
    532         p_buf->event = BT_EVT_TO_BTU_SP_DATA;
    533 
    534         memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
    535 
    536         *p_len  += p_buf->len;
    537         max_len -= p_buf->len;
    538         p_data  += p_buf->len;
    539 
    540         GAP_TRACE_EVENT1 ("GAP_WriteData %d bytes", p_buf->len);
    541 
    542         GKI_enqueue (&p_ccb->tx_queue, p_buf);
    543     }
    544 
    545     if (p_ccb->is_congested)
    546     {
    547         return (BT_PASS);
    548     }
    549 
    550     /* Send the buffer through L2CAP */
    551 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
    552     gap_send_event (gap_handle);
    553 #else
    554     while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
    555     {
    556         UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
    557 
    558         if (status == L2CAP_DW_CONGESTED)
    559         {
    560             p_ccb->is_congested = TRUE;
    561             break;
    562         }
    563         else if (status != L2CAP_DW_SUCCESS)
    564             return (GAP_ERR_BAD_STATE);
    565     }
    566 #endif
    567     return (BT_PASS);
    568 }
    569 
    570 
    571 /*******************************************************************************
    572 **
    573 ** Function         GAP_ConnReconfig
    574 **
    575 ** Description      Applications can call this function to reconfigure the connection.
    576 **
    577 ** Parameters:      handle      - Handle of the connection
    578 **                  p_cfg       - Pointer to new configuration
    579 **
    580 ** Returns          BT_PASS                 - config process started
    581 **                  GAP_ERR_BAD_HANDLE      - invalid handle
    582 **
    583 *******************************************************************************/
    584 UINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg)
    585 {
    586     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
    587 
    588     if (!p_ccb)
    589         return (GAP_ERR_BAD_HANDLE);
    590 
    591     p_ccb->cfg = *p_cfg;
    592 
    593     if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
    594         L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg);
    595 
    596     return (BT_PASS);
    597 }
    598 
    599 
    600 
    601 /*******************************************************************************
    602 **
    603 ** Function         GAP_ConnSetIdleTimeout
    604 **
    605 ** Description      Higher layers call this function to set the idle timeout for
    606 **                  a connection, or for all future connections. The "idle timeout"
    607 **                  is the amount of time that a connection can remain up with
    608 **                  no L2CAP channels on it. A timeout of zero means that the
    609 **                  connection will be torn down immediately when the last channel
    610 **                  is removed. A timeout of 0xFFFF means no timeout. Values are
    611 **                  in seconds.
    612 **
    613 ** Parameters:      handle      - Handle of the connection
    614 **                  timeout     - in secs
    615 **                                0 = immediate disconnect when last channel is removed
    616 **                                0xFFFF = no idle timeout
    617 **
    618 ** Returns          BT_PASS                 - config process started
    619 **                  GAP_ERR_BAD_HANDLE      - invalid handle
    620 **
    621 *******************************************************************************/
    622 UINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout)
    623 {
    624     tGAP_CCB    *p_ccb;
    625 
    626     if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
    627         return (GAP_ERR_BAD_HANDLE);
    628 
    629     if (L2CA_SetIdleTimeout (p_ccb->connection_id, timeout, FALSE))
    630         return (BT_PASS);
    631     else
    632         return (GAP_ERR_BAD_HANDLE);
    633 }
    634 
    635 
    636 
    637 /*******************************************************************************
    638 **
    639 ** Function         GAP_ConnGetRemoteAddr
    640 **
    641 ** Description      This function is called to get the remote BD address
    642 **                  of a connection.
    643 **
    644 ** Parameters:      handle      - Handle of the connection returned by GAP_ConnOpen
    645 **
    646 ** Returns          BT_PASS             - closed OK
    647 **                  GAP_ERR_BAD_HANDLE  - invalid handle
    648 **
    649 *******************************************************************************/
    650 UINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle)
    651 {
    652     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
    653 
    654     GAP_TRACE_EVENT1 ("GAP_ConnGetRemoteAddr gap_handle = %d", gap_handle);
    655 
    656     if ((p_ccb) && (p_ccb->con_state > GAP_CCB_STATE_LISTENING))
    657     {
    658         GAP_TRACE_EVENT6("GAP_ConnGetRemoteAddr bda :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
    659                          p_ccb->rem_dev_address[0],p_ccb->rem_dev_address[1],p_ccb->rem_dev_address[2],
    660                          p_ccb->rem_dev_address[3],p_ccb->rem_dev_address[4],p_ccb->rem_dev_address[5]);
    661         return (p_ccb->rem_dev_address);
    662     }
    663     else
    664     {
    665         GAP_TRACE_EVENT0 ("GAP_ConnGetRemoteAddr return Error ");
    666         return (NULL);
    667     }
    668 }
    669 
    670 
    671 /*******************************************************************************
    672 **
    673 ** Function         GAP_ConnGetRemMtuSize
    674 **
    675 ** Description      Returns the remote device's MTU size
    676 **
    677 ** Parameters:      handle      - Handle of the connection
    678 **
    679 ** Returns          UINT16      - maximum size buffer that can be transmitted to the peer
    680 **
    681 *******************************************************************************/
    682 UINT16 GAP_ConnGetRemMtuSize (UINT16 gap_handle)
    683 {
    684     tGAP_CCB    *p_ccb;
    685 
    686     if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
    687         return (0);
    688 
    689     return (p_ccb->rem_mtu_size);
    690 }
    691 
    692 /*******************************************************************************
    693 **
    694 ** Function         GAP_ConnGetL2CAPCid
    695 **
    696 ** Description      Returns the L2CAP channel id
    697 **
    698 ** Parameters:      handle      - Handle of the connection
    699 **
    700 ** Returns          UINT16      - The L2CAP channel id
    701 **                  0, if error
    702 **
    703 *******************************************************************************/
    704 UINT16 GAP_ConnGetL2CAPCid (UINT16 gap_handle)
    705 {
    706     tGAP_CCB    *p_ccb;
    707 
    708     if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
    709         return (0);
    710 
    711     return (p_ccb->connection_id);
    712 }
    713 
    714 
    715 /*******************************************************************************
    716 **
    717 ** Function         gap_connect_ind
    718 **
    719 ** Description      This function handles an inbound connection indication
    720 **                  from L2CAP. This is the case where we are acting as a
    721 **                  server.
    722 **
    723 ** Returns          void
    724 **
    725 *******************************************************************************/
    726 static void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id)
    727 {
    728     UINT16       xx;
    729     tGAP_CCB     *p_ccb;
    730     tBT_UUID    bt_uuid = {2, {GAP_PROTOCOL_ID}};
    731 
    732     /* See if we have a CCB listening for the connection */
    733     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
    734     {
    735         if ((p_ccb->con_state == GAP_CCB_STATE_LISTENING)
    736          && (p_ccb->psm == psm)
    737          && ((p_ccb->rem_addr_specified == FALSE)
    738            || (!memcmp (bd_addr, p_ccb->rem_dev_address, BD_ADDR_LEN))))
    739             break;
    740     }
    741 
    742     if (xx == GAP_MAX_CONNECTIONS)
    743     {
    744         GAP_TRACE_WARNING0("*******");
    745         GAP_TRACE_WARNING0("WARNING: GAP Conn Indication for Unexpected Bd Addr...Disconnecting");
    746         GAP_TRACE_WARNING0("*******");
    747 
    748         /* Disconnect because it is an unexpected connection */
    749         L2CA_DISCONNECT_REQ (l2cap_cid);
    750         return;
    751     }
    752 
    753     /* Transition to the next appropriate state, waiting for config setup. */
    754     p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
    755 
    756     /* Save the BD Address and Channel ID. */
    757     memcpy (&p_ccb->rem_dev_address[0], bd_addr, BD_ADDR_LEN);
    758     p_ccb->connection_id = l2cap_cid;
    759 
    760     /* Send response to the L2CAP layer. */
    761     L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->ertm_info, &bt_uuid);
    762 
    763     GAP_TRACE_EVENT1("GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x", p_ccb->connection_id);
    764 
    765     /* Send a Configuration Request. */
    766     L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
    767 }
    768 
    769 /*******************************************************************************
    770 **
    771 ** Function         gap_checks_con_flags
    772 **
    773 ** Description      This function processes the L2CAP configuration indication
    774 **                  event.
    775 **
    776 ** Returns          void
    777 **
    778 *******************************************************************************/
    779 static void gap_checks_con_flags (tGAP_CCB    *p_ccb)
    780 {
    781     GAP_TRACE_EVENT1 ("gap_checks_con_flags conn_flags:0x%x, ", p_ccb->con_flags);
    782     /* if all the required con_flags are set, report the OPEN event now */
    783     if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE)
    784     {
    785         p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
    786 
    787         p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
    788     }
    789 }
    790 
    791 /*******************************************************************************
    792 **
    793 ** Function         gap_sec_check_complete
    794 **
    795 ** Description      The function called when Security Manager finishes
    796 **                  verification of the service side connection
    797 **
    798 ** Returns          void
    799 **
    800 *******************************************************************************/
    801 static void gap_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
    802 {
    803     tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data;
    804 
    805     GAP_TRACE_EVENT3 ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d",
    806         p_ccb->con_state, p_ccb->con_flags, res);
    807     if (p_ccb->con_state == GAP_CCB_STATE_IDLE)
    808         return;
    809 
    810     if (res == BTM_SUCCESS)
    811     {
    812         p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
    813         gap_checks_con_flags (p_ccb);
    814     }
    815     else
    816     {
    817         /* security failed - disconnect the channel */
    818         L2CA_DISCONNECT_REQ (p_ccb->connection_id);
    819     }
    820 }
    821 
    822 /*******************************************************************************
    823 **
    824 ** Function         gap_connect_cfm
    825 **
    826 ** Description      This function handles the connect confirm events
    827 **                  from L2CAP. This is the case when we are acting as a
    828 **                  client and have sent a connect request.
    829 **
    830 ** Returns          void
    831 **
    832 *******************************************************************************/
    833 static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result)
    834 {
    835     tGAP_CCB    *p_ccb;
    836 
    837     /* Find CCB based on CID */
    838     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
    839         return;
    840 
    841     /* initiate security process, if needed */
    842     if ( (p_ccb->con_flags & GAP_CCB_FLAGS_SEC_DONE) == 0)
    843     {
    844         btm_sec_mx_access_request (p_ccb->rem_dev_address, p_ccb->psm, TRUE,
    845                                    0, 0, &gap_sec_check_complete, p_ccb);
    846     }
    847 
    848     /* If the connection response contains success status, then */
    849     /* Transition to the next state and startup the timer.      */
    850     if ((result == L2CAP_CONN_OK) && (p_ccb->con_state == GAP_CCB_STATE_CONN_SETUP))
    851     {
    852         p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
    853 
    854         /* Send a Configuration Request. */
    855         L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
    856     }
    857     else
    858     {
    859         /* Tell the user if he has a callback */
    860         if (p_ccb->p_callback)
    861             (*p_ccb->p_callback) (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
    862 
    863         gap_release_ccb (p_ccb);
    864     }
    865 }
    866 
    867 /*******************************************************************************
    868 **
    869 ** Function         gap_config_ind
    870 **
    871 ** Description      This function processes the L2CAP configuration indication
    872 **                  event.
    873 **
    874 ** Returns          void
    875 **
    876 *******************************************************************************/
    877 static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
    878 {
    879     tGAP_CCB    *p_ccb;
    880     UINT16      local_mtu_size;
    881 
    882     /* Find CCB based on CID */
    883     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
    884         return;
    885 
    886     /* Remember the remote MTU size */
    887 
    888     if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
    889     {
    890         local_mtu_size = GKI_get_pool_bufsize (p_ccb->ertm_info.user_tx_pool_id)
    891                        - sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
    892     }
    893     else
    894         local_mtu_size = L2CAP_MTU_SIZE;
    895 
    896     if ((!p_cfg->mtu_present)||(p_cfg->mtu > local_mtu_size))
    897     {
    898         p_ccb->rem_mtu_size = local_mtu_size;
    899     }
    900     else
    901         p_ccb->rem_mtu_size = p_cfg->mtu;
    902 
    903     /* For now, always accept configuration from the other side */
    904     p_cfg->flush_to_present = FALSE;
    905     p_cfg->mtu_present      = FALSE;
    906     p_cfg->result           = L2CAP_CFG_OK;
    907     p_cfg->fcs_present      = FALSE;
    908 
    909     L2CA_CONFIG_RSP (l2cap_cid, p_cfg);
    910 
    911     p_ccb->con_flags |= GAP_CCB_FLAGS_HIS_CFG_DONE;
    912 
    913     gap_checks_con_flags (p_ccb);
    914 }
    915 
    916 
    917 /*******************************************************************************
    918 **
    919 ** Function         gap_config_cfm
    920 **
    921 ** Description      This function processes the L2CAP configuration confirmation
    922 **                  event.
    923 **
    924 ** Returns          void
    925 **
    926 *******************************************************************************/
    927 static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
    928 {
    929     tGAP_CCB    *p_ccb;
    930 
    931     /* Find CCB based on CID */
    932     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
    933         return;
    934 
    935     if (p_cfg->result == L2CAP_CFG_OK)
    936     {
    937         p_ccb->con_flags |= GAP_CCB_FLAGS_MY_CFG_DONE;
    938 
    939 
    940         if (p_ccb->cfg.fcr_present)
    941             p_ccb->cfg.fcr.mode = p_cfg->fcr.mode;
    942         else
    943             p_ccb->cfg.fcr.mode = L2CAP_FCR_BASIC_MODE;
    944 
    945         gap_checks_con_flags (p_ccb);
    946     }
    947     else
    948     {
    949         p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
    950         gap_release_ccb (p_ccb);
    951     }
    952 }
    953 
    954 
    955 /*******************************************************************************
    956 **
    957 ** Function         gap_disconnect_ind
    958 **
    959 ** Description      This function handles a disconnect event from L2CAP. If
    960 **                  requested to, we ack the disconnect before dropping the CCB
    961 **
    962 ** Returns          void
    963 **
    964 *******************************************************************************/
    965 static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
    966 {
    967     tGAP_CCB    *p_ccb;
    968 
    969     GAP_TRACE_EVENT1 ("GAP_CONN - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
    970 
    971     /* Find CCB based on CID */
    972     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
    973         return;
    974 
    975     if (ack_needed)
    976         L2CA_DISCONNECT_RSP (l2cap_cid);
    977 
    978     p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
    979     gap_release_ccb (p_ccb);
    980 }
    981 
    982 
    983 /*******************************************************************************
    984 **
    985 ** Function         gap_data_ind
    986 **
    987 ** Description      This function is called when data is received from L2CAP.
    988 **
    989 ** Returns          void
    990 **
    991 *******************************************************************************/
    992 static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
    993 {
    994     tGAP_CCB    *p_ccb;
    995 
    996     /* Find CCB based on CID */
    997     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
    998     {
    999         GKI_freebuf (p_msg);
   1000         return;
   1001     }
   1002 
   1003     if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
   1004     {
   1005         GKI_enqueue (&p_ccb->rx_queue, p_msg);
   1006 
   1007         p_ccb->rx_queue_size += p_msg->len;
   1008         /*
   1009         GAP_TRACE_EVENT2 ("gap_data_ind - rx_queue_size=%d, msg len=%d",
   1010                                        p_ccb->rx_queue_size, p_msg->len);
   1011          */
   1012 
   1013         p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
   1014     }
   1015     else
   1016     {
   1017         GKI_freebuf (p_msg);
   1018     }
   1019 }
   1020 
   1021 
   1022 /*******************************************************************************
   1023 **
   1024 ** Function         gap_congestion_ind
   1025 **
   1026 ** Description      This is a callback function called by L2CAP when
   1027 **                  data L2CAP congestion status changes
   1028 **
   1029 *******************************************************************************/
   1030 static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested)
   1031 {
   1032     tGAP_CCB    *p_ccb;
   1033     UINT16       event;
   1034     BT_HDR      *p_buf;
   1035     UINT8        status;
   1036 
   1037     GAP_TRACE_EVENT2 ("GAP_CONN - Rcvd L2CAP Is Congested (%d), CID: 0x%x",
   1038                       is_congested, lcid);
   1039 
   1040     /* Find CCB based on CID */
   1041     if ((p_ccb = gap_find_ccb_by_cid (lcid)) == NULL)
   1042         return;
   1043 
   1044     p_ccb->is_congested = is_congested;
   1045 
   1046     event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED;
   1047     p_ccb->p_callback (p_ccb->gap_handle, event);
   1048 
   1049     if (!is_congested)
   1050     {
   1051         while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
   1052         {
   1053             status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
   1054 
   1055             if (status == L2CAP_DW_CONGESTED)
   1056             {
   1057                 p_ccb->is_congested = TRUE;
   1058                 break;
   1059             }
   1060             else if (status != L2CAP_DW_SUCCESS)
   1061                 break;
   1062         }
   1063     }
   1064 }
   1065 
   1066 
   1067 /*******************************************************************************
   1068 **
   1069 ** Function         gap_find_ccb_by_cid
   1070 **
   1071 ** Description      This function searches the CCB table for an entry with the
   1072 **                  passed CID.
   1073 **
   1074 ** Returns          the CCB address, or NULL if not found.
   1075 **
   1076 *******************************************************************************/
   1077 static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid)
   1078 {
   1079     UINT16       xx;
   1080     tGAP_CCB     *p_ccb;
   1081 
   1082     /* Look through each connection control block */
   1083     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
   1084     {
   1085         if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->connection_id == cid))
   1086             return (p_ccb);
   1087     }
   1088 
   1089     /* If here, not found */
   1090     return (NULL);
   1091 }
   1092 
   1093 
   1094 /*******************************************************************************
   1095 **
   1096 ** Function         gap_find_ccb_by_handle
   1097 **
   1098 ** Description      This function searches the CCB table for an entry with the
   1099 **                  passed handle.
   1100 **
   1101 ** Returns          the CCB address, or NULL if not found.
   1102 **
   1103 *******************************************************************************/
   1104 static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle)
   1105 {
   1106     tGAP_CCB     *p_ccb;
   1107 
   1108     /* Check that handle is valid */
   1109     if (handle < GAP_MAX_CONNECTIONS)
   1110     {
   1111         p_ccb = &gap_cb.conn.ccb_pool[handle];
   1112 
   1113         if (p_ccb->con_state != GAP_CCB_STATE_IDLE)
   1114             return (p_ccb);
   1115     }
   1116 
   1117     /* If here, handle points to invalid connection */
   1118     return (NULL);
   1119 }
   1120 
   1121 
   1122 /*******************************************************************************
   1123 **
   1124 ** Function         gap_allocate_ccb
   1125 **
   1126 ** Description      This function allocates a new CCB.
   1127 **
   1128 ** Returns          CCB address, or NULL if none available.
   1129 **
   1130 *******************************************************************************/
   1131 static tGAP_CCB *gap_allocate_ccb (void)
   1132 {
   1133     UINT16       xx;
   1134     tGAP_CCB     *p_ccb;
   1135 
   1136     /* Look through each connection control block for a free one */
   1137     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
   1138     {
   1139         if (p_ccb->con_state == GAP_CCB_STATE_IDLE)
   1140         {
   1141             memset (p_ccb, 0, sizeof (tGAP_CCB));
   1142 
   1143             p_ccb->gap_handle   = xx;
   1144             p_ccb->rem_mtu_size = L2CAP_MTU_SIZE;
   1145 
   1146             return (p_ccb);
   1147         }
   1148     }
   1149 
   1150     /* If here, no free CCB found */
   1151     return (NULL);
   1152 }
   1153 
   1154 
   1155 /*******************************************************************************
   1156 **
   1157 ** Function         gap_release_ccb
   1158 **
   1159 ** Description      This function releases a CCB.
   1160 **
   1161 ** Returns          void
   1162 **
   1163 *******************************************************************************/
   1164 static void gap_release_ccb (tGAP_CCB *p_ccb)
   1165 {
   1166     UINT16       xx;
   1167     UINT16      psm = p_ccb->psm;
   1168     UINT8       service_id = p_ccb->service_id;
   1169 
   1170     /* Drop any buffers we may be holding */
   1171     p_ccb->rx_queue_size = 0;
   1172 
   1173     while (p_ccb->rx_queue.p_first)
   1174         GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));
   1175 
   1176     while (p_ccb->tx_queue.p_first)
   1177         GKI_freebuf (GKI_dequeue (&p_ccb->tx_queue));
   1178 
   1179     p_ccb->con_state = GAP_CCB_STATE_IDLE;
   1180 
   1181     /* If no-one else is using the PSM, deregister from L2CAP */
   1182     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
   1183     {
   1184         if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->psm == psm))
   1185             return;
   1186     }
   1187 
   1188     /* Free the security record for this PSM */
   1189     BTM_SecClrService(service_id);
   1190     L2CA_DEREGISTER (psm);
   1191 }
   1192 
   1193 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
   1194 
   1195 /*******************************************************************************
   1196 **
   1197 ** Function     gap_send_event
   1198 **
   1199 ** Description  Send BT_EVT_TO_GAP_MSG event to BTU task
   1200 **
   1201 ** Returns      None
   1202 **
   1203 *******************************************************************************/
   1204 void gap_send_event (UINT16 gap_handle)
   1205 {
   1206     BT_HDR  *p_msg;
   1207 
   1208     if ((p_msg = (BT_HDR*)GKI_getbuf(BT_HDR_SIZE)) != NULL)
   1209     {
   1210         p_msg->event  = BT_EVT_TO_GAP_MSG;
   1211         p_msg->len    = 0;
   1212         p_msg->offset = 0;
   1213         p_msg->layer_specific = gap_handle;
   1214 
   1215         GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
   1216     }
   1217     else
   1218     {
   1219         GAP_TRACE_ERROR0("Unable to allocate message buffer for event.");
   1220     }
   1221 }
   1222 
   1223 /*******************************************************************************
   1224 **
   1225 ** Function     gap_proc_btu_event
   1226 **
   1227 ** Description  Event handler for BT_EVT_TO_GAP_MSG event from BTU task
   1228 **
   1229 ** Returns      None
   1230 **
   1231 *******************************************************************************/
   1232 void gap_proc_btu_event(BT_HDR *p_msg)
   1233 {
   1234     tGAP_CCB   *p_ccb = gap_find_ccb_by_handle (p_msg->layer_specific);
   1235     UINT8       status;
   1236     BT_HDR     *p_buf;
   1237 
   1238     if (!p_ccb)
   1239     {
   1240         return;
   1241     }
   1242 
   1243     if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
   1244     {
   1245         return;
   1246     }
   1247 
   1248     if (p_ccb->is_congested)
   1249     {
   1250         return;
   1251     }
   1252 
   1253     /* Send the buffer through L2CAP */
   1254 
   1255     while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
   1256     {
   1257         status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
   1258 
   1259         if (status == L2CAP_DW_CONGESTED)
   1260         {
   1261             p_ccb->is_congested = TRUE;
   1262             break;
   1263         }
   1264         else if (status != L2CAP_DW_SUCCESS)
   1265             break;
   1266     }
   1267 
   1268 }
   1269 #endif /* (GAP_CONN_POST_EVT_INCLUDED == TRUE) */
   1270 #endif  /* GAP_CONN_INCLUDED */
   1271