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