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