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