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