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