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  ******************************************************************************/
gap_conn_init(void)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  ******************************************************************************/
GAP_ConnOpen(const char * p_serv_name,uint8_t service_id,bool is_server,const RawAddress * p_rem_bda,uint16_t psm,uint16_t le_mps,tL2CAP_CFG_INFO * p_cfg,tL2CAP_ERTM_INFO * ertm_info,uint16_t security,uint8_t chan_mode_mask,tGAP_CONN_CALLBACK * p_cb,tBT_TRANSPORT transport)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  ******************************************************************************/
GAP_ConnClose(uint16_t gap_handle)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  ******************************************************************************/
GAP_ConnReadData(uint16_t gap_handle,uint8_t * p_data,uint16_t max_len,uint16_t * p_len)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  ******************************************************************************/
GAP_GetRxQueueCnt(uint16_t handle,uint32_t * p_rx_queue_count)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  ******************************************************************************/
GAP_ConnBTRead(uint16_t gap_handle,BT_HDR ** pp_buf)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. */
gap_try_write_queued_data(tGAP_CCB * p_ccb)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  ******************************************************************************/
GAP_ConnWriteData(uint16_t gap_handle,BT_HDR * msg)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  ******************************************************************************/
GAP_ConnReconfig(uint16_t gap_handle,tL2CAP_CFG_INFO * p_cfg)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  ******************************************************************************/
GAP_ConnSetIdleTimeout(uint16_t gap_handle,uint16_t timeout)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  ******************************************************************************/
GAP_ConnGetRemoteAddr(uint16_t gap_handle)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  ******************************************************************************/
GAP_ConnGetRemMtuSize(uint16_t gap_handle)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  ******************************************************************************/
GAP_ConnGetL2CAPCid(uint16_t gap_handle)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  ******************************************************************************/
gap_tx_complete_ind(uint16_t l2cap_cid,uint16_t sdu_sent)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 
gap_credits_received_cb(uint16_t l2cap_cid,uint16_t credits_received,uint16_t credit_count)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  ******************************************************************************/
gap_connect_ind(const RawAddress & bd_addr,uint16_t l2cap_cid,uint16_t psm,uint8_t l2cap_id)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  ******************************************************************************/
gap_checks_con_flags(tGAP_CCB * p_ccb)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  ******************************************************************************/
gap_sec_check_complete(const RawAddress *,tBT_TRANSPORT,void * p_ref_data,uint8_t res)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  ******************************************************************************/
gap_connect_cfm(uint16_t l2cap_cid,uint16_t result)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  ******************************************************************************/
gap_config_ind(uint16_t l2cap_cid,tL2CAP_CFG_INFO * p_cfg)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  ******************************************************************************/
gap_config_cfm(uint16_t l2cap_cid,tL2CAP_CFG_INFO * p_cfg)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  ******************************************************************************/
gap_disconnect_ind(uint16_t l2cap_cid,bool ack_needed)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  ******************************************************************************/
gap_data_ind(uint16_t l2cap_cid,BT_HDR * p_msg)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  ******************************************************************************/
gap_congestion_ind(uint16_t lcid,bool is_congested)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  ******************************************************************************/
gap_find_ccb_by_cid(uint16_t cid)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  ******************************************************************************/
gap_find_ccb_by_handle(uint16_t handle)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  ******************************************************************************/
gap_allocate_ccb(void)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  ******************************************************************************/
gap_release_ccb(tGAP_CCB * p_ccb)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  */
GAP_Init(void)1167 void GAP_Init(void) {
1168   gap_conn_init();
1169   gap_attr_db_init();
1170 }
1171