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