1 /******************************************************************************
2 *
3 * Copyright 1999-2012 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 /******************************************************************************
20 *
21 * This file contains the L2CAP API code
22 *
23 ******************************************************************************/
24
25 #define LOG_TAG "bt_l2cap"
26
27 #include "stack/include/l2c_api.h"
28
29 #include <base/location.h>
30 #include <base/strings/stringprintf.h>
31 #include <bluetooth/log.h>
32
33 #include <cstdint>
34 #include <string>
35
36 #include "common/init_flags.h"
37 #include "hal/snoop_logger.h"
38 #include "hci/controller_interface.h"
39 #include "internal_include/bt_target.h"
40 #include "internal_include/bt_trace.h"
41 #include "main/shim/dumpsys.h"
42 #include "main/shim/entry.h"
43 #include "os/log.h"
44 #include "os/system_properties.h"
45 #include "osi/include/allocator.h"
46 #include "stack/include/bt_hdr.h"
47 #include "stack/include/bt_psm_types.h"
48 #include "stack/include/btm_api.h"
49 #include "stack/include/btm_client_interface.h"
50 #include "stack/include/l2c_api.h"
51 #include "stack/include/main_thread.h"
52 #include "stack/l2cap/l2c_int.h"
53 #include "types/raw_address.h"
54
55 using namespace bluetooth;
56
57 using base::StringPrintf;
58
59 extern fixed_queue_t* btu_general_alarm_queue;
60 tL2C_AVDT_CHANNEL_INFO av_media_channels[MAX_ACTIVE_AVDT_CONN];
61
l2c_get_transport_from_fixed_cid(uint16_t fixed_cid)62 tBT_TRANSPORT l2c_get_transport_from_fixed_cid(uint16_t fixed_cid) {
63 if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
64 return BT_TRANSPORT_LE;
65 return BT_TRANSPORT_BR_EDR;
66 }
67
L2CA_RegisterWithSecurity(uint16_t psm,const tL2CAP_APPL_INFO & p_cb_info,bool enable_snoop,tL2CAP_ERTM_INFO * p_ertm_info,uint16_t my_mtu,uint16_t required_remote_mtu,uint16_t sec_level)68 uint16_t L2CA_RegisterWithSecurity(
69 uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop,
70 tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu,
71 uint16_t required_remote_mtu, uint16_t sec_level) {
72 auto ret = L2CA_Register(psm, p_cb_info, enable_snoop, p_ertm_info, my_mtu,
73 required_remote_mtu, sec_level);
74 get_btm_client_interface().security.BTM_SetSecurityLevel(
75 false, "", 0, sec_level, psm, 0, 0);
76 return ret;
77 }
78
L2CA_LeCreditDefault()79 uint16_t L2CA_LeCreditDefault() {
80 static const uint16_t sL2CAP_LE_CREDIT_DEFAULT =
81 bluetooth::os::GetSystemPropertyUint32Base(
82 "bluetooth.l2cap.le.credit_default.value", 0xffff);
83 return sL2CAP_LE_CREDIT_DEFAULT;
84 }
85
L2CA_LeCreditThreshold()86 uint16_t L2CA_LeCreditThreshold() {
87 static const uint16_t sL2CAP_LE_CREDIT_THRESHOLD =
88 bluetooth::os::GetSystemPropertyUint32Base(
89 "bluetooth.l2cap.le.credit_threshold.value", 0x0040);
90 return sL2CAP_LE_CREDIT_THRESHOLD;
91 }
92
check_l2cap_credit()93 static bool check_l2cap_credit() {
94 log::assert_that(L2CA_LeCreditThreshold() < L2CA_LeCreditDefault(),
95 "Threshold must be smaller than default credits");
96 return true;
97 }
98
99 // Replace static assert with startup assert depending of the config
100 static const bool enforce_assert = check_l2cap_credit();
101
102 /*******************************************************************************
103 *
104 * Function L2CA_Register
105 *
106 * Description Other layers call this function to register for L2CAP
107 * services.
108 *
109 * Returns PSM to use or zero if error. Typically, the PSM returned
110 * is the same as was passed in, but for an outgoing-only
111 * connection to a dynamic PSM, a "virtual" PSM is returned
112 * and should be used in the calls to L2CA_ConnectReq(),
113 * L2CA_ErtmConnectReq() and L2CA_Deregister()
114 *
115 ******************************************************************************/
L2CA_Register(uint16_t psm,const tL2CAP_APPL_INFO & p_cb_info,bool enable_snoop,tL2CAP_ERTM_INFO * p_ertm_info,uint16_t my_mtu,uint16_t required_remote_mtu,uint16_t)116 uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
117 bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
118 uint16_t my_mtu, uint16_t required_remote_mtu,
119 uint16_t /* sec_level */) {
120 const bool config_cfm_cb = (p_cb_info.pL2CA_ConfigCfm_Cb != nullptr);
121 const bool config_ind_cb = (p_cb_info.pL2CA_ConfigInd_Cb != nullptr);
122 const bool data_ind_cb = (p_cb_info.pL2CA_DataInd_Cb != nullptr);
123 const bool disconnect_ind_cb = (p_cb_info.pL2CA_DisconnectInd_Cb != nullptr);
124
125 tL2C_RCB* p_rcb;
126 uint16_t vpsm = psm;
127
128 /* Verify that the required callback info has been filled in
129 ** Note: Connection callbacks are required but not checked
130 ** for here because it is possible to be only a client
131 ** or only a server.
132 */
133 if (!config_cfm_cb || !data_ind_cb || !disconnect_ind_cb) {
134 log::error(
135 "L2CAP - no cb registering PSM: 0x{:04x} cfg_cfm:{} cfg_ind:{} "
136 "data_ind:{} discon_int:{}",
137 psm, config_cfm_cb, config_ind_cb, data_ind_cb, disconnect_ind_cb);
138 return (0);
139 }
140
141 /* Verify PSM is valid */
142 if (L2C_INVALID_PSM(psm)) {
143 log::error("L2CAP - invalid PSM value, PSM: 0x{:04x}", psm);
144 return (0);
145 }
146
147 /* Check if this is a registration for an outgoing-only connection to */
148 /* a dynamic PSM. If so, allocate a "virtual" PSM for the app to use. */
149 if ((psm >= 0x1001) && (p_cb_info.pL2CA_ConnectInd_Cb == NULL)) {
150 for (vpsm = 0x1002; vpsm < 0x8000; vpsm += 2) {
151 p_rcb = l2cu_find_rcb_by_psm(vpsm);
152 if (p_rcb == NULL) break;
153 }
154
155 log::debug("L2CAP - Real PSM: 0x{:04x} Virtual PSM: 0x{:04x}", psm, vpsm);
156 }
157
158 /* If registration block already there, just overwrite it */
159 p_rcb = l2cu_find_rcb_by_psm(vpsm);
160 if (p_rcb == NULL) {
161 p_rcb = l2cu_allocate_rcb(vpsm);
162 if (p_rcb == NULL) {
163 log::warn("L2CAP - no RCB available, PSM: 0x{:04x} vPSM: 0x{:04x}", psm,
164 vpsm);
165 return (0);
166 }
167 }
168
169 log::info("L2CAP Registered service classic PSM: 0x{:04x}", psm);
170 p_rcb->log_packets = enable_snoop;
171 p_rcb->api = p_cb_info;
172 p_rcb->real_psm = psm;
173 p_rcb->ertm_info = p_ertm_info == nullptr
174 ? tL2CAP_ERTM_INFO{L2CAP_FCR_BASIC_MODE}
175 : *p_ertm_info;
176 p_rcb->my_mtu = my_mtu;
177 p_rcb->required_remote_mtu =
178 std::max<uint16_t>(required_remote_mtu, L2CAP_MIN_MTU);
179
180 return (vpsm);
181 }
182
183 /*******************************************************************************
184 *
185 * Function L2CA_Deregister
186 *
187 * Description Other layers call this function to de-register for L2CAP
188 * services.
189 *
190 * Returns void
191 *
192 ******************************************************************************/
L2CA_Deregister(uint16_t psm)193 void L2CA_Deregister(uint16_t psm) {
194 tL2C_RCB* p_rcb;
195 tL2C_CCB* p_ccb;
196 tL2C_LCB* p_lcb;
197 int ii;
198
199 log::verbose("L2CAP - L2CA_Deregister() called for PSM: 0x{:04x}", psm);
200
201 p_rcb = l2cu_find_rcb_by_psm(psm);
202 if (p_rcb != NULL) {
203 p_lcb = &l2cb.lcb_pool[0];
204 for (ii = 0; ii < MAX_L2CAP_LINKS; ii++, p_lcb++) {
205 if (p_lcb->in_use) {
206 p_ccb = p_lcb->ccb_queue.p_first_ccb;
207 if ((p_ccb == NULL) || (p_lcb->link_state == LST_DISCONNECTING)) {
208 continue;
209 }
210
211 if ((p_ccb->in_use) &&
212 ((p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP) ||
213 (p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))) {
214 continue;
215 }
216
217 if (p_ccb->p_rcb == p_rcb) {
218 l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL);
219 }
220 }
221 }
222 l2cu_release_rcb(p_rcb);
223 } else {
224 log::warn("L2CAP - PSM: 0x{:04x} not found for deregistration", psm);
225 }
226 }
227
228 /*******************************************************************************
229 *
230 * Function L2CA_AllocateLePSM
231 *
232 * Description To find an unused LE PSM for L2CAP services.
233 *
234 * Returns LE_PSM to use if success. Otherwise returns 0.
235 *
236 ******************************************************************************/
L2CA_AllocateLePSM(void)237 uint16_t L2CA_AllocateLePSM(void) {
238 bool done = false;
239 uint16_t psm = l2cb.le_dyn_psm;
240 uint16_t count = 0;
241
242 log::verbose("last psm={}", psm);
243 while (!done) {
244 count++;
245 if (count > LE_DYNAMIC_PSM_RANGE) {
246 log::error("Out of free BLE PSM");
247 return 0;
248 }
249
250 psm++;
251 if (psm > LE_DYNAMIC_PSM_END) {
252 psm = LE_DYNAMIC_PSM_START;
253 }
254
255 if (!l2cb.le_dyn_psm_assigned[psm - LE_DYNAMIC_PSM_START]) {
256 /* make sure the newly allocated psm is not used right now */
257 if (l2cu_find_ble_rcb_by_psm(psm)) {
258 log::warn("supposedly-free PSM={} have allocated rcb!", psm);
259 continue;
260 }
261
262 l2cb.le_dyn_psm_assigned[psm - LE_DYNAMIC_PSM_START] = true;
263 log::verbose("assigned PSM={}", psm);
264 done = true;
265 break;
266 }
267 }
268 l2cb.le_dyn_psm = psm;
269
270 return (psm);
271 }
272
273 /*******************************************************************************
274 *
275 * Function L2CA_FreeLePSM
276 *
277 * Description Free an assigned LE PSM.
278 *
279 * Returns void
280 *
281 ******************************************************************************/
L2CA_FreeLePSM(uint16_t psm)282 void L2CA_FreeLePSM(uint16_t psm) {
283 log::verbose("to free psm={}", psm);
284
285 if ((psm < LE_DYNAMIC_PSM_START) || (psm > LE_DYNAMIC_PSM_END)) {
286 log::error("Invalid PSM={} value!", psm);
287 return;
288 }
289
290 if (!l2cb.le_dyn_psm_assigned[psm - LE_DYNAMIC_PSM_START]) {
291 log::warn("PSM={} was not allocated!", psm);
292 }
293 l2cb.le_dyn_psm_assigned[psm - LE_DYNAMIC_PSM_START] = false;
294 }
295
L2CA_ConnectReqWithSecurity(uint16_t psm,const RawAddress & p_bd_addr,uint16_t sec_level)296 uint16_t L2CA_ConnectReqWithSecurity(uint16_t psm, const RawAddress& p_bd_addr,
297 uint16_t sec_level) {
298 get_btm_client_interface().security.BTM_SetSecurityLevel(
299 true, "", 0, sec_level, psm, 0, 0);
300 return L2CA_ConnectReq(psm, p_bd_addr);
301 }
302
303 /*******************************************************************************
304 *
305 * Function L2CA_ConnectReq
306 *
307 * Description Higher layers call this function to create an L2CAP
308 * connection.
309 * Note that the connection is not established at this time,
310 * but connection establishment gets started. The callback
311 * will be invoked when connection establishes or fails.
312 *
313 * Returns the CID of the connection, or 0 if it failed to start
314 *
315 ******************************************************************************/
L2CA_ConnectReq(uint16_t psm,const RawAddress & p_bd_addr)316 uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) {
317 log::verbose("BDA {} PSM: 0x{:04x}", p_bd_addr, psm);
318
319 /* Fail if we have not established communications with the controller */
320 if (!BTM_IsDeviceUp()) {
321 log::warn("BTU not ready");
322 return 0;
323 }
324 /* Fail if the PSM is not registered */
325 tL2C_RCB* p_rcb = l2cu_find_rcb_by_psm(psm);
326 if (p_rcb == nullptr) {
327 log::warn("no RCB, PSM=0x{:x}", psm);
328 return 0;
329 }
330
331 /* First, see if we already have a link to the remote */
332 /* assume all ERTM l2cap connection is going over BR/EDR for now */
333 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR);
334 if (p_lcb == nullptr) {
335 /* No link. Get an LCB and start link establishment */
336 p_lcb = l2cu_allocate_lcb(p_bd_addr, false, BT_TRANSPORT_BR_EDR);
337 /* currently use BR/EDR for ERTM mode l2cap connection */
338 if (p_lcb == nullptr) {
339 log::warn("connection not started for PSM=0x{:x}, p_lcb={}", psm,
340 fmt::ptr(p_lcb));
341 return 0;
342 }
343 l2cu_create_conn_br_edr(p_lcb);
344 }
345
346 /* Allocate a channel control block */
347 tL2C_CCB* p_ccb = l2cu_allocate_ccb(p_lcb, 0);
348 if (p_ccb == nullptr) {
349 log::warn("no CCB, PSM=0x{:x}", psm);
350 return 0;
351 }
352
353 /* Save registration info */
354 p_ccb->p_rcb = p_rcb;
355
356 p_ccb->connection_initiator = L2CAP_INITIATOR_LOCAL;
357
358 /* If link is up, start the L2CAP connection */
359 if (p_lcb->link_state == LST_CONNECTED) {
360 l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_REQ, nullptr);
361 } else if (p_lcb->link_state == LST_DISCONNECTING) {
362 /* If link is disconnecting, save link info to retry after disconnect
363 * Possible Race condition when a reconnect occurs
364 * on the channel during a disconnect of link. This
365 * ccb will be automatically retried after link disconnect
366 * arrives
367 */
368 log::verbose("L2CAP API - link disconnecting: RETRY LATER");
369
370 /* Save ccb so it can be started after disconnect is finished */
371 p_lcb->p_pending_ccb = p_ccb;
372 }
373
374 log::verbose("L2CAP - L2CA_conn_req(psm: 0x{:04x}) returned CID: 0x{:04x}",
375 psm, p_ccb->local_cid);
376
377 /* Return the local CID as our handle */
378 return p_ccb->local_cid;
379 }
380
381 /*******************************************************************************
382 *
383 * Function L2CA_RegisterLECoc
384 *
385 * Description Other layers call this function to register for L2CAP
386 * Connection Oriented Channel.
387 *
388 * Returns PSM to use or zero if error. Typically, the PSM returned
389 * is the same as was passed in, but for an outgoing-only
390 * connection to a dynamic PSM, a "virtual" PSM is returned
391 * and should be used in the calls to L2CA_ConnectLECocReq()
392 * and L2CA_DeregisterLECoc()
393 *
394 ******************************************************************************/
L2CA_RegisterLECoc(uint16_t psm,const tL2CAP_APPL_INFO & p_cb_info,uint16_t sec_level,tL2CAP_LE_CFG_INFO cfg)395 uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
396 uint16_t sec_level, tL2CAP_LE_CFG_INFO cfg) {
397 if (p_cb_info.pL2CA_ConnectInd_Cb != nullptr || psm < LE_DYNAMIC_PSM_START) {
398 // If we register LE COC for outgoing connection only, don't register with
399 // BTM_Sec, because it's handled by L2CA_ConnectLECocReq.
400 get_btm_client_interface().security.BTM_SetSecurityLevel(
401 false, "", 0, sec_level, psm, 0, 0);
402 }
403
404 /* Verify that the required callback info has been filled in
405 ** Note: Connection callbacks are required but not checked
406 ** for here because it is possible to be only a client
407 ** or only a server.
408 */
409 if ((!p_cb_info.pL2CA_DataInd_Cb) || (!p_cb_info.pL2CA_DisconnectInd_Cb)) {
410 log::error("No cb registering BLE PSM: 0x{:04x}", psm);
411 return 0;
412 }
413
414 /* Verify PSM is valid */
415 if (!L2C_IS_VALID_LE_PSM(psm)) {
416 log::error("Invalid BLE PSM value, PSM: 0x{:04x}", psm);
417 return 0;
418 }
419
420 tL2C_RCB* p_rcb;
421 uint16_t vpsm = psm;
422
423 /* Check if this is a registration for an outgoing-only connection to */
424 /* a dynamic PSM. If so, allocate a "virtual" PSM for the app to use. */
425 if ((psm >= LE_DYNAMIC_PSM_START) &&
426 (p_cb_info.pL2CA_ConnectInd_Cb == NULL)) {
427 vpsm = L2CA_AllocateLePSM();
428 if (vpsm == 0) {
429 log::error("Out of free BLE PSM");
430 return 0;
431 }
432
433 log::debug("Real PSM: 0x{:04x} Virtual PSM: 0x{:04x}", psm, vpsm);
434 }
435
436 /* If registration block already there, just overwrite it */
437 p_rcb = l2cu_find_ble_rcb_by_psm(vpsm);
438 if (p_rcb == NULL) {
439 log::debug("Allocate rcp for Virtual PSM: 0x{:04x}", vpsm);
440 p_rcb = l2cu_allocate_ble_rcb(vpsm);
441 if (p_rcb == NULL) {
442 log::warn("No BLE RCB available, PSM: 0x{:04x} vPSM: 0x{:04x}", psm,
443 vpsm);
444 return 0;
445 }
446 }
447
448 log::info("Registered service LE COC PSM: 0x{:04x}", psm);
449 p_rcb->api = p_cb_info;
450 p_rcb->real_psm = psm;
451 p_rcb->coc_cfg = cfg;
452
453 return vpsm;
454 }
455
456 /*******************************************************************************
457 *
458 * Function L2CA_DeregisterLECoc
459 *
460 * Description Other layers call this function to de-register for L2CAP
461 * Connection Oriented Channel.
462 *
463 * Returns void
464 *
465 ******************************************************************************/
L2CA_DeregisterLECoc(uint16_t psm)466 void L2CA_DeregisterLECoc(uint16_t psm) {
467 log::verbose("called for PSM: 0x{:04x}", psm);
468
469 tL2C_RCB* p_rcb = l2cu_find_ble_rcb_by_psm(psm);
470 if (p_rcb == NULL) {
471 log::warn("PSM: 0x{:04x} not found for deregistration", psm);
472 return;
473 }
474
475 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
476 for (int i = 0; i < MAX_L2CAP_LINKS; i++, p_lcb++) {
477 if (!p_lcb->in_use || p_lcb->transport != BT_TRANSPORT_LE) continue;
478
479 tL2C_CCB* p_ccb = p_lcb->ccb_queue.p_first_ccb;
480 if ((p_ccb == NULL) || (p_lcb->link_state == LST_DISCONNECTING)) continue;
481
482 if (p_ccb->in_use && (p_ccb->chnl_state == CST_W4_L2CAP_DISCONNECT_RSP ||
483 p_ccb->chnl_state == CST_W4_L2CA_DISCONNECT_RSP))
484 continue;
485
486 if (p_ccb->p_rcb == p_rcb)
487 l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL);
488 }
489
490 l2cu_release_ble_rcb(p_rcb);
491 }
492
493 /*******************************************************************************
494 *
495 * Function L2CA_ConnectLECocReq
496 *
497 * Description Higher layers call this function to create an L2CAP
498 * connection. Note that the connection is not established at
499 * this time, but connection establishment gets started. The
500 * callback function will be invoked when connection
501 * establishes or fails.
502 *
503 * Parameters: PSM: L2CAP PSM for the connection
504 * BD address of the peer
505 * Local Coc configurations
506
507 * Returns the CID of the connection, or 0 if it failed to start
508 *
509 ******************************************************************************/
L2CA_ConnectLECocReq(uint16_t psm,const RawAddress & p_bd_addr,tL2CAP_LE_CFG_INFO * p_cfg,uint16_t sec_level)510 uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr,
511 tL2CAP_LE_CFG_INFO* p_cfg, uint16_t sec_level) {
512 get_btm_client_interface().security.BTM_SetSecurityLevel(
513 true, "", 0, sec_level, psm, 0, 0);
514
515 log::verbose("BDA: {} PSM: 0x{:04x}", p_bd_addr, psm);
516
517 /* Fail if we have not established communications with the controller */
518 if (!BTM_IsDeviceUp()) {
519 log::warn("BTU not ready");
520 return 0;
521 }
522
523 /* Fail if the PSM is not registered */
524 tL2C_RCB* p_rcb = l2cu_find_ble_rcb_by_psm(psm);
525 if (p_rcb == NULL) {
526 log::warn("No BLE RCB, PSM: 0x{:04x}", psm);
527 return 0;
528 }
529
530 /* First, see if we already have a le link to the remote */
531 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE);
532 if (p_lcb == NULL) {
533 /* No link. Get an LCB and start link establishment */
534 p_lcb = l2cu_allocate_lcb(p_bd_addr, false, BT_TRANSPORT_LE);
535 if ((p_lcb == NULL)
536 /* currently use BR/EDR for ERTM mode l2cap connection */
537 || (!l2cu_create_conn_le(p_lcb))) {
538 log::warn("conn not started for PSM: 0x{:04x} p_lcb: 0x{}", psm,
539 fmt::ptr(p_lcb));
540 return 0;
541 }
542 }
543
544 /* Allocate a channel control block */
545 tL2C_CCB* p_ccb = l2cu_allocate_ccb(p_lcb, 0);
546 if (p_ccb == NULL) {
547 log::warn("no CCB, PSM: 0x{:04x}", psm);
548 return 0;
549 }
550
551 /* Save registration info */
552 p_ccb->p_rcb = p_rcb;
553
554 p_ccb->connection_initiator = L2CAP_INITIATOR_LOCAL;
555
556 /* Save the configuration */
557 if (p_cfg) {
558 p_ccb->local_conn_cfg = *p_cfg;
559 p_ccb->remote_credit_count = p_cfg->credits;
560 }
561
562 /* If link is up, start the L2CAP connection */
563 if (p_lcb->link_state == LST_CONNECTED) {
564 if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
565 log::verbose("LE Link is up");
566 // post this asynchronously to avoid out-of-order callback invocation
567 // should this operation fail
568 do_in_main_thread(
569 FROM_HERE, base::BindOnce(&l2c_csm_execute, base::Unretained(p_ccb),
570 L2CEVT_L2CA_CONNECT_REQ, nullptr));
571 }
572 }
573
574 /* If link is disconnecting, save link info to retry after disconnect
575 * Possible Race condition when a reconnect occurs
576 * on the channel during a disconnect of link. This
577 * ccb will be automatically retried after link disconnect
578 * arrives
579 */
580 else if (p_lcb->link_state == LST_DISCONNECTING) {
581 log::verbose("link disconnecting: RETRY LATER");
582
583 /* Save ccb so it can be started after disconnect is finished */
584 p_lcb->p_pending_ccb = p_ccb;
585 }
586
587 log::verbose("(psm: 0x{:04x}) returned CID: 0x{:04x}", psm, p_ccb->local_cid);
588
589 /* Return the local CID as our handle */
590 return p_ccb->local_cid;
591 }
592
593 /*******************************************************************************
594 *
595 * Function L2CA_GetPeerLECocConfig
596 *
597 * Description Get a peers configuration for LE Connection Oriented
598 * Channel.
599 *
600 * Parameters: local channel id
601 * Pointers to peers configuration storage area
602 *
603 * Return value: true if peer is connected
604 *
605 ******************************************************************************/
L2CA_GetPeerLECocConfig(uint16_t lcid,tL2CAP_LE_CFG_INFO * peer_cfg)606 bool L2CA_GetPeerLECocConfig(uint16_t lcid, tL2CAP_LE_CFG_INFO* peer_cfg) {
607 log::verbose("CID: 0x{:04x}", lcid);
608
609 tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
610 if (p_ccb == NULL) {
611 log::error("No CCB for CID:0x{:04x}", lcid);
612 return false;
613 }
614
615 if (peer_cfg != NULL)
616 memcpy(peer_cfg, &p_ccb->peer_conn_cfg, sizeof(tL2CAP_LE_CFG_INFO));
617
618 return true;
619 }
620
621 /*******************************************************************************
622 *
623 * Function L2CA_GetPeerLECocCredit
624 *
625 * Description Get peers current credit for LE Connection Oriented
626 * Channel.
627 *
628 * Return value: Number of the peer current credit
629 *
630 ******************************************************************************/
L2CA_GetPeerLECocCredit(const RawAddress & bd_addr,uint16_t lcid)631 uint16_t L2CA_GetPeerLECocCredit(const RawAddress& bd_addr, uint16_t lcid) {
632 /* First, find the link control block */
633 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
634 if (p_lcb == NULL) {
635 /* No link. Get an LCB and start link establishment */
636 log::warn("no LCB");
637 return L2CAP_LE_CREDIT_MAX;
638 }
639
640 tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
641 if (p_ccb == NULL) {
642 log::error("No CCB for CID:0x{:04x}", lcid);
643 return L2CAP_LE_CREDIT_MAX;
644 }
645
646 return p_ccb->peer_conn_cfg.credits;
647 }
648
649 /*******************************************************************************
650 *
651 * Function L2CA_ConnectCreditBasedRsp
652 *
653 * Description Response for the pL2CA_CreditBasedConnectInd_Cb which is the
654 * indication for peer requesting credit based connection.
655 *
656 * Parameters: BD address of the peer
657 * Identifier of the transaction
658 * Vector of accepted lcids by upper layer
659 * L2CAP result
660 * Local channel configuration
661 *
662 * Returns true for success, false for failure
663 *
664 ******************************************************************************/
L2CA_ConnectCreditBasedRsp(const RawAddress & p_bd_addr,uint8_t id,std::vector<uint16_t> & accepted_lcids,uint16_t result,tL2CAP_LE_CFG_INFO * p_cfg)665 bool L2CA_ConnectCreditBasedRsp(const RawAddress& p_bd_addr, uint8_t id,
666 std::vector<uint16_t>& accepted_lcids,
667 uint16_t result, tL2CAP_LE_CFG_INFO* p_cfg) {
668 log::verbose("BDA: {} num of cids: {} Result: {}", p_bd_addr,
669 int(accepted_lcids.size()), result);
670
671 /* First, find the link control block */
672 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE);
673 if (p_lcb == NULL) {
674 /* No link. Get an LCB and start link establishment */
675 log::warn("no LCB");
676 return false;
677 }
678
679 /* Now, find the channel control block. We kept lead cid.
680 */
681 tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, p_lcb->pending_lead_cid);
682
683 if (!p_ccb) {
684 log::error("No CCB for CID:0x{:04x}", p_lcb->pending_lead_cid);
685 return false;
686 }
687
688 for (uint16_t cid : accepted_lcids) {
689 tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid);
690 if (temp_p_ccb == NULL) {
691 log::warn("no CCB");
692 return false;
693 }
694
695 if (p_cfg) {
696 temp_p_ccb->local_conn_cfg = *p_cfg;
697 temp_p_ccb->remote_credit_count = p_cfg->credits;
698 }
699 }
700
701 /* The IDs must match */
702 if (p_ccb->remote_id != id) {
703 log::warn("bad id. Expected: {} Got: {}", p_ccb->remote_id, id);
704 return false;
705 }
706
707 tL2C_CONN_INFO conn_info;
708 conn_info.lcids = accepted_lcids;
709 conn_info.bd_addr = p_bd_addr;
710 conn_info.l2cap_result = result;
711
712 if (accepted_lcids.size() > 0) {
713 l2c_csm_execute(p_ccb, L2CEVT_L2CA_CREDIT_BASED_CONNECT_RSP, &conn_info);
714 } else {
715 l2c_csm_execute(p_ccb, L2CEVT_L2CA_CREDIT_BASED_CONNECT_RSP_NEG,
716 &conn_info);
717 }
718
719 return true;
720 }
721 /*******************************************************************************
722 *
723 * Function L2CA_ConnectCreditBasedReq
724 *
725 * Description Initiate Create Credit Based connections.
726 *
727 * Parameters: PSM for the L2CAP channel
728 * BD address of the peer
729 * Local channel configuration
730 *
731 * Return value: Vector of allocated local cids.
732 *
733 ******************************************************************************/
734
L2CA_ConnectCreditBasedReq(uint16_t psm,const RawAddress & p_bd_addr,tL2CAP_LE_CFG_INFO * p_cfg)735 std::vector<uint16_t> L2CA_ConnectCreditBasedReq(uint16_t psm,
736 const RawAddress& p_bd_addr,
737 tL2CAP_LE_CFG_INFO* p_cfg) {
738 log::verbose("BDA: {} PSM: 0x{:04x}", p_bd_addr, psm);
739
740 std::vector<uint16_t> allocated_cids;
741
742 /* Fail if we have not established communications with the controller */
743 if (!BTM_IsDeviceUp()) {
744 log::warn("BTU not ready");
745 return allocated_cids;
746 }
747
748 if (!p_cfg) {
749 log::warn("p_cfg is NULL");
750 return allocated_cids;
751 }
752
753 /* Fail if the PSM is not registered */
754 tL2C_RCB* p_rcb = l2cu_find_ble_rcb_by_psm(psm);
755 if (p_rcb == NULL) {
756 log::warn("No BLE RCB, PSM: 0x{:04x}", psm);
757 return allocated_cids;
758 }
759
760 /* First, see if we already have a le link to the remote */
761 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE);
762 if (p_lcb == NULL) {
763 log::warn("No link available");
764 return allocated_cids;
765 }
766
767 if (p_lcb->link_state != LST_CONNECTED) {
768 log::warn("incorrect link state: {}", p_lcb->link_state);
769 return allocated_cids;
770 }
771
772 log::verbose("LE Link is up");
773
774 /* Check if there is no ongoing connection request */
775 if (p_lcb->pending_ecoc_conn_cnt > 0) {
776 log::warn("There is ongoing connection request, PSM: 0x{:04x}", psm);
777 return allocated_cids;
778 }
779
780 tL2C_CCB* p_ccb_primary;
781
782 /* Make sure user set proper value for number of cids */
783 if (p_cfg->number_of_channels > L2CAP_CREDIT_BASED_MAX_CIDS ||
784 p_cfg->number_of_channels == 0) {
785 p_cfg->number_of_channels = L2CAP_CREDIT_BASED_MAX_CIDS;
786 }
787
788 for (int i = 0; i < p_cfg->number_of_channels; i++) {
789 /* Allocate a channel control block */
790 tL2C_CCB* p_ccb =
791 l2cu_allocate_ccb(p_lcb, 0, psm == BT_PSM_EATT /* is_eatt */);
792 if (p_ccb == NULL) {
793 if (i == 0) {
794 log::warn("no CCB, PSM: 0x{:04x}", psm);
795 return allocated_cids;
796 } else {
797 break;
798 }
799 }
800
801 p_ccb->ecoc = true;
802 p_ccb->local_conn_cfg = *p_cfg;
803 p_ccb->remote_credit_count = p_cfg->credits;
804 /* Save registration info */
805 p_ccb->p_rcb = p_rcb;
806 if (i == 0) {
807 p_ccb_primary = p_ccb;
808 } else {
809 /* Only primary channel we keep in closed state, as in that
810 * context we will run state machine where security is checked etc.
811 * Others we can directly put into waiting for connect
812 * response, so those are not confused by system as incomming connections
813 */
814 p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP;
815 }
816
817 allocated_cids.push_back(p_ccb->local_cid);
818 }
819
820 for (int i = 0; i < (int)(allocated_cids.size()); i++)
821 p_lcb->pending_ecoc_connection_cids[i] = allocated_cids[i];
822
823 p_lcb->pending_ecoc_conn_cnt = (uint16_t)(allocated_cids.size());
824 l2c_csm_execute(p_ccb_primary, L2CEVT_L2CA_CREDIT_BASED_CONNECT_REQ, NULL);
825
826 log::verbose("(psm: 0x{:04x}) returned CID: 0x{:04x}", psm,
827 p_ccb_primary->local_cid);
828
829 return allocated_cids;
830 }
831
832 /*******************************************************************************
833 *
834 * Function L2CA_ReconfigCreditBasedConnsReq
835 *
836 * Description Start reconfigure procedure on Connection Oriented Channel.
837 *
838 * Parameters: Vector of channels for which configuration should be
839 * changed to new local channel configuration
840 *
841 * Return value: true if peer is connected
842 *
843 ******************************************************************************/
844
L2CA_ReconfigCreditBasedConnsReq(const RawAddress &,std::vector<uint16_t> & lcids,tL2CAP_LE_CFG_INFO * p_cfg)845 bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& /* bda */,
846 std::vector<uint16_t>& lcids,
847 tL2CAP_LE_CFG_INFO* p_cfg) {
848 tL2C_CCB* p_ccb;
849
850 log::verbose("L2CA_ReconfigCreditBasedConnsReq()");
851
852 if (lcids.empty()) {
853 log::warn("L2CAP - empty lcids");
854 return (false);
855 }
856
857 for (uint16_t cid : lcids) {
858 p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
859
860 if (!p_ccb) {
861 log::warn("L2CAP - no CCB for L2CA_cfg_req, CID: {}", cid);
862 return (false);
863 }
864
865 if ((p_ccb->local_conn_cfg.mtu > p_cfg->mtu) ||
866 (p_ccb->local_conn_cfg.mps > p_cfg->mps)) {
867 log::warn("L2CAP - MPS or MTU reduction, CID: {}", cid);
868 return (false);
869 }
870 }
871
872 if (p_cfg->mtu > L2CAP_MTU_SIZE) {
873 log::warn("L2CAP - adjust MTU: {} too large", p_cfg->mtu);
874 p_cfg->mtu = L2CAP_MTU_SIZE;
875 }
876
877 /* Mark all the p_ccbs which going to be reconfigured */
878 for (uint16_t cid : lcids) {
879 log::verbose("cid: {}", cid);
880 p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
881 if (!p_ccb) {
882 log::error("Missing cid? {}", int(cid));
883 return (false);
884 }
885 p_ccb->reconfig_started = true;
886 }
887
888 tL2C_LCB* p_lcb = p_ccb->p_lcb;
889
890 /* Hack warning - the whole reconfig we are doing in the context of the first
891 * p_ccb. In the p_lcp we store configuration and cid in which context we are
892 * doing reconfiguration.
893 */
894 for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb)
895 if ((p_ccb->in_use) && (p_ccb->ecoc) && (p_ccb->reconfig_started)) {
896 p_ccb->p_lcb->pending_ecoc_reconfig_cfg = *p_cfg;
897 p_ccb->p_lcb->pending_ecoc_reconfig_cnt = lcids.size();
898 break;
899 }
900
901 l2c_csm_execute(p_ccb, L2CEVT_L2CA_CREDIT_BASED_RECONFIG_REQ, p_cfg);
902
903 return (true);
904 }
905
906 /*******************************************************************************
907 *
908 * Function L2CA_DisconnectReq
909 *
910 * Description Higher layers call this function to disconnect a channel.
911 *
912 * Returns true if disconnect sent, else false
913 *
914 ******************************************************************************/
L2CA_DisconnectReq(uint16_t cid)915 bool L2CA_DisconnectReq(uint16_t cid) {
916 tL2C_CCB* p_ccb;
917
918 /* Find the channel control block. We don't know the link it is on. */
919 p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
920 if (p_ccb == NULL) {
921 log::warn("L2CAP - no CCB for L2CA_disc_req, CID: {}", cid);
922 return (false);
923 }
924
925 log::debug("L2CAP Local disconnect request CID: 0x{:04x}", cid);
926
927 l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL);
928
929 return (true);
930 }
931
L2CA_DisconnectLECocReq(uint16_t cid)932 bool L2CA_DisconnectLECocReq(uint16_t cid) { return L2CA_DisconnectReq(cid); }
933
934 /*******************************************************************************
935 *
936 * Function L2CA_GetRemoteChannelId
937 *
938 * Description Get remote channel ID for Connection Oriented Channel.
939 *
940 * Parameters: lcid: Local CID
941 * rcid: Pointer to remote CID
942 *
943 * Return value: true if peer is connected
944 *
945 ******************************************************************************/
L2CA_GetRemoteChannelId(uint16_t lcid,uint16_t * rcid)946 bool L2CA_GetRemoteChannelId(uint16_t lcid, uint16_t* rcid) {
947 log::assert_that(rcid != nullptr, "assert failed: rcid != nullptr");
948
949 log::verbose("LCID: 0x{:04x}", lcid);
950 tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(nullptr, lcid);
951 if (p_ccb == nullptr) {
952 log::error("No CCB for CID:0x{:04x}", lcid);
953 return false;
954 }
955
956 *rcid = p_ccb->remote_cid;
957 return true;
958 }
959
960 /*******************************************************************************
961 *
962 * Function L2CA_SetIdleTimeoutByBdAddr
963 *
964 * Description Higher layers call this function to set the idle timeout for
965 * a connection. The "idle timeout" is the amount of time that
966 * a connection can remain up with no L2CAP channels on it.
967 * A timeout of zero means that the connection will be torn
968 * down immediately when the last channel is removed.
969 * A timeout of 0xFFFF means no timeout. Values are in seconds.
970 * A bd_addr is the remote BD address. If bd_addr =
971 * RawAddress::kAny, then the idle timeouts for all active
972 * l2cap links will be changed.
973 *
974 * Returns true if command succeeded, false if failed
975 *
976 * NOTE This timeout applies to all logical channels active on the
977 * ACL link.
978 ******************************************************************************/
L2CA_SetIdleTimeoutByBdAddr(const RawAddress & bd_addr,uint16_t timeout,tBT_TRANSPORT transport)979 bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout,
980 tBT_TRANSPORT transport) {
981 tL2C_LCB* p_lcb;
982
983 if (RawAddress::kAny != bd_addr) {
984 p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, transport);
985 if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
986 p_lcb->idle_timeout = timeout;
987
988 if (!p_lcb->ccb_queue.p_first_ccb) l2cu_no_dynamic_ccbs(p_lcb);
989 } else
990 return false;
991 } else {
992 int xx;
993 tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
994
995 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
996 if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
997 p_lcb->idle_timeout = timeout;
998
999 if (!p_lcb->ccb_queue.p_first_ccb) l2cu_no_dynamic_ccbs(p_lcb);
1000 }
1001 }
1002 }
1003
1004 return true;
1005 }
1006
1007 /*******************************************************************************
1008 *
1009 * Function L2CA_UseLatencyMode
1010 *
1011 * Description Sets acl use latency mode.
1012 *
1013 * Returns true if a valid channel, else false
1014 *
1015 ******************************************************************************/
L2CA_UseLatencyMode(const RawAddress & bd_addr,bool use_latency_mode)1016 bool L2CA_UseLatencyMode(const RawAddress& bd_addr, bool use_latency_mode) {
1017 /* Find the link control block for the acl channel */
1018 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
1019 if (p_lcb == nullptr) {
1020 log::warn("L2CAP - no LCB for L2CA_SetUseLatencyMode, BDA: {}", bd_addr);
1021 return false;
1022 }
1023 log::info("BDA: {}, use_latency_mode: {}", bd_addr, use_latency_mode);
1024 p_lcb->use_latency_mode = use_latency_mode;
1025 return true;
1026 }
1027
1028 /*******************************************************************************
1029 *
1030 * Function L2CA_SetAclPriority
1031 *
1032 * Description Sets the transmission priority for a channel.
1033 * (For initial implementation only two values are valid.
1034 * L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
1035 *
1036 * Returns true if a valid channel, else false
1037 *
1038 ******************************************************************************/
L2CA_SetAclPriority(const RawAddress & bd_addr,tL2CAP_PRIORITY priority)1039 bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority) {
1040 log::verbose("BDA: {}, priority: {}", bd_addr, priority);
1041 return (l2cu_set_acl_priority(bd_addr, priority, false));
1042 }
1043
1044 /*******************************************************************************
1045 *
1046 * Function L2CA_SetAclLatency
1047 *
1048 * Description Sets the transmission latency for a channel.
1049 *
1050 * Returns true if a valid channel, else false
1051 *
1052 ******************************************************************************/
L2CA_SetAclLatency(const RawAddress & bd_addr,tL2CAP_LATENCY latency)1053 bool L2CA_SetAclLatency(const RawAddress& bd_addr, tL2CAP_LATENCY latency) {
1054 log::info("BDA: {}, latency: {}", bd_addr, latency);
1055 return l2cu_set_acl_latency(bd_addr, latency);
1056 }
1057
1058 /*******************************************************************************
1059 *
1060 * Function L2CA_SetTxPriority
1061 *
1062 * Description Sets the transmission priority for a channel.
1063 *
1064 * Returns true if a valid channel, else false
1065 *
1066 ******************************************************************************/
L2CA_SetTxPriority(uint16_t cid,tL2CAP_CHNL_PRIORITY priority)1067 bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) {
1068 tL2C_CCB* p_ccb;
1069
1070 log::verbose("L2CA_SetTxPriority() CID: 0x{:04x}, priority:{}", cid,
1071 priority);
1072
1073 /* Find the channel control block. We don't know the link it is on. */
1074 p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
1075 if (p_ccb == NULL) {
1076 log::warn("L2CAP - no CCB for L2CA_SetTxPriority, CID: {}", cid);
1077 return (false);
1078 }
1079
1080 /* it will update the order of CCB in LCB by priority and update round robin
1081 * service variables */
1082 l2cu_change_pri_ccb(p_ccb, priority);
1083
1084 return (true);
1085 }
1086
1087 /*******************************************************************************
1088 *
1089 * Function L2CA_GetPeerFeatures
1090 *
1091 * Description Get a peers features and fixed channel map
1092 *
1093 * Parameters: BD address of the peer
1094 * Pointers to features and channel mask storage area
1095 *
1096 * Return value: true if peer is connected
1097 *
1098 ******************************************************************************/
L2CA_GetPeerFeatures(const RawAddress & bd_addr,uint32_t * p_ext_feat,uint8_t * p_chnl_mask)1099 bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat,
1100 uint8_t* p_chnl_mask) {
1101 tL2C_LCB* p_lcb;
1102
1103 /* We must already have a link to the remote */
1104 p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
1105 if (p_lcb == NULL) {
1106 log::warn("No BDA: {}", bd_addr);
1107 return false;
1108 }
1109
1110 log::verbose("BDA: {} ExtFea: 0x{:08x} Chnl_Mask[0]: 0x{:02x}", bd_addr,
1111 p_lcb->peer_ext_fea, p_lcb->peer_chnl_mask[0]);
1112
1113 *p_ext_feat = p_lcb->peer_ext_fea;
1114
1115 memcpy(p_chnl_mask, p_lcb->peer_chnl_mask, L2CAP_FIXED_CHNL_ARRAY_SIZE);
1116
1117 return true;
1118 }
1119
1120 /*******************************************************************************
1121 *
1122 * Function L2CA_RegisterFixedChannel
1123 *
1124 * Description Register a fixed channel.
1125 *
1126 * Parameters: Fixed Channel #
1127 * Channel Callbacks and config
1128 *
1129 * Return value: -
1130 *
1131 ******************************************************************************/
fixed_channel_text(const uint16_t & fixed_cid)1132 static std::string fixed_channel_text(const uint16_t& fixed_cid) {
1133 switch (fixed_cid) {
1134 case L2CAP_SIGNALLING_CID:
1135 return std::string("br_edr signalling");
1136 case L2CAP_CONNECTIONLESS_CID:
1137 return std::string("connectionless");
1138 case L2CAP_AMP_CID:
1139 return std::string("amp");
1140 case L2CAP_ATT_CID:
1141 return std::string("att");
1142 case L2CAP_BLE_SIGNALLING_CID:
1143 return std::string("ble signalling");
1144 case L2CAP_SMP_CID:
1145 return std::string("smp");
1146 case L2CAP_SMP_BR_CID:
1147 return std::string("br_edr smp");
1148 default:
1149 return std::string("unknown");
1150 }
1151 }
1152
L2CA_RegisterFixedChannel(uint16_t fixed_cid,tL2CAP_FIXED_CHNL_REG * p_freg)1153 bool L2CA_RegisterFixedChannel(uint16_t fixed_cid,
1154 tL2CAP_FIXED_CHNL_REG* p_freg) {
1155 if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
1156 (fixed_cid > L2CAP_LAST_FIXED_CHNL)) {
1157 log::error("Invalid fixed CID: 0x{:04x}", fixed_cid);
1158 return false;
1159 }
1160
1161 l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = *p_freg;
1162 log::debug("Registered fixed channel:{}", fixed_channel_text(fixed_cid));
1163 return true;
1164 }
1165
1166 /*******************************************************************************
1167 *
1168 * Function L2CA_ConnectFixedChnl
1169 *
1170 * Description Connect an fixed signalling channel to a remote device.
1171 *
1172 * Parameters: Fixed CID
1173 * BD Address of remote
1174 *
1175 * Return value: true if connection started
1176 *
1177 ******************************************************************************/
L2CA_ConnectFixedChnl(uint16_t fixed_cid,const RawAddress & rem_bda)1178 bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
1179 tL2C_LCB* p_lcb;
1180 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1181
1182 log::debug("fixed_cid:0x{:04x}", fixed_cid);
1183
1184 // Check CID is valid and registered
1185 if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
1186 (fixed_cid > L2CAP_LAST_FIXED_CHNL) ||
1187 (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb ==
1188 NULL)) {
1189 log::error("Invalid fixed_cid:0x{:04x}", fixed_cid);
1190 return (false);
1191 }
1192
1193 // Fail if BT is not yet up
1194 if (!BTM_IsDeviceUp()) {
1195 log::warn("Bt controller is not ready fixed_cid:0x{:04x}", fixed_cid);
1196 return (false);
1197 }
1198
1199 if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
1200 transport = BT_TRANSPORT_LE;
1201
1202 tL2C_BLE_FIXED_CHNLS_MASK peer_channel_mask;
1203
1204 // If we already have a link to the remote, check if it supports that CID
1205 p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport);
1206 if (p_lcb != NULL) {
1207 // Fixed channels are mandatory on LE transports so ignore the received
1208 // channel mask and use the locally cached LE channel mask.
1209
1210 if (transport == BT_TRANSPORT_LE)
1211 peer_channel_mask = l2cb.l2c_ble_fixed_chnls_mask;
1212 else
1213 peer_channel_mask = p_lcb->peer_chnl_mask[0];
1214
1215 // Check for supported channel
1216 if (!(peer_channel_mask & (1 << fixed_cid))) {
1217 log::info("Peer device does not support fixed_cid:0x{:04x}", fixed_cid);
1218 return false;
1219 }
1220
1221 // Get a CCB and link the lcb to it
1222 if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) {
1223 log::warn("Unable to allocate fixed channel resource fixed_cid:0x{:04x}",
1224 fixed_cid);
1225 return false;
1226 }
1227
1228 // racing with disconnecting, queue the connection request
1229 if (p_lcb->link_state == LST_DISCONNECTING) {
1230 log::debug(
1231 "Link is disconnecting so deferring connection fixed_cid:0x{:04x}",
1232 fixed_cid);
1233 /* Save ccb so it can be started after disconnect is finished */
1234 p_lcb->p_pending_ccb =
1235 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
1236 return true;
1237 }
1238
1239 (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(
1240 fixed_cid, p_lcb->remote_bd_addr, true, 0, p_lcb->transport);
1241 return true;
1242 }
1243
1244 // No link. Get an LCB and start link establishment
1245 p_lcb = l2cu_allocate_lcb(rem_bda, false, transport);
1246 if (p_lcb == NULL) {
1247 log::warn(
1248 "Unable to allocate link resource for connection fixed_cid:0x{:04x}",
1249 fixed_cid);
1250 return false;
1251 }
1252
1253 // Get a CCB and link the lcb to it
1254 if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) {
1255 log::warn("Unable to allocate fixed channel resource fixed_cid:0x{:04x}",
1256 fixed_cid);
1257 l2cu_release_lcb(p_lcb);
1258 return false;
1259 }
1260
1261 if (transport == BT_TRANSPORT_LE) {
1262 bool ret = l2cu_create_conn_le(p_lcb);
1263 if (!ret) {
1264 log::warn(
1265 "Unable to create fixed channel le connection fixed_cid:0x{:04x}",
1266 fixed_cid);
1267 l2cu_release_lcb(p_lcb);
1268 return false;
1269 }
1270 } else {
1271 l2cu_create_conn_br_edr(p_lcb);
1272 }
1273 return true;
1274 }
1275
1276 /*******************************************************************************
1277 *
1278 * Function L2CA_SendFixedChnlData
1279 *
1280 * Description Write data on a fixed channel.
1281 *
1282 * Parameters: Fixed CID
1283 * BD Address of remote
1284 * Pointer to buffer of type BT_HDR
1285 *
1286 * Return value L2CAP_DW_SUCCESS, if data accepted
1287 * L2CAP_DW_FAILED, if error
1288 *
1289 ******************************************************************************/
L2CA_SendFixedChnlData(uint16_t fixed_cid,const RawAddress & rem_bda,BT_HDR * p_buf)1290 uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda,
1291 BT_HDR* p_buf) {
1292 tL2C_LCB* p_lcb;
1293 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1294
1295 if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
1296 transport = BT_TRANSPORT_LE;
1297
1298 if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
1299 (fixed_cid > L2CAP_LAST_FIXED_CHNL) ||
1300 (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb ==
1301 NULL)) {
1302 log::warn("No service registered or invalid CID: 0x{:04x}", fixed_cid);
1303 osi_free(p_buf);
1304 return (L2CAP_DW_FAILED);
1305 }
1306
1307 if (!BTM_IsDeviceUp()) {
1308 log::warn("Controller is not ready CID: 0x{:04x}", fixed_cid);
1309 osi_free(p_buf);
1310 return (L2CAP_DW_FAILED);
1311 }
1312
1313 p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport);
1314 if (p_lcb == NULL || p_lcb->link_state == LST_DISCONNECTING) {
1315 /* if link is disconnecting, also report data sending failure */
1316 log::warn("Link is disconnecting or does not exist CID: 0x{:04x}",
1317 fixed_cid);
1318 osi_free(p_buf);
1319 return (L2CAP_DW_FAILED);
1320 }
1321
1322 tL2C_BLE_FIXED_CHNLS_MASK peer_channel_mask;
1323
1324 // Select peer channels mask to use depending on transport
1325 if (transport == BT_TRANSPORT_LE)
1326 peer_channel_mask = l2cb.l2c_ble_fixed_chnls_mask;
1327 else
1328 peer_channel_mask = p_lcb->peer_chnl_mask[0];
1329
1330 if ((peer_channel_mask & (1 << fixed_cid)) == 0) {
1331 log::warn("Peer does not support fixed channel CID: 0x{:04x}", fixed_cid);
1332 osi_free(p_buf);
1333 return (L2CAP_DW_FAILED);
1334 }
1335
1336 p_buf->event = 0;
1337 p_buf->layer_specific = L2CAP_FLUSHABLE_CH_BASED;
1338
1339 if (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) {
1340 if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) {
1341 log::warn("No channel control block found for CID: 0x{:4x}", fixed_cid);
1342 osi_free(p_buf);
1343 return (L2CAP_DW_FAILED);
1344 }
1345 }
1346
1347 if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
1348 log::warn(
1349 "Unable to send data due to congestion CID: 0x{:04x} "
1350 "xmit_hold_q.count: {} buff_quota: {}",
1351 fixed_cid,
1352 fixed_queue_length(
1353 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]
1354 ->xmit_hold_q),
1355 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->buff_quota);
1356 osi_free(p_buf);
1357 return (L2CAP_DW_FAILED);
1358 }
1359
1360 log::debug("Enqueued data for CID: 0x{:04x} len:{}", fixed_cid, p_buf->len);
1361 l2c_enqueue_peer_data(p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL],
1362 p_buf);
1363
1364 l2c_link_check_send_pkts(p_lcb, 0, NULL);
1365
1366 // If there is no dynamic CCB on the link, restart the idle timer each time
1367 // something is sent
1368 if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED &&
1369 !p_lcb->ccb_queue.p_first_ccb) {
1370 l2cu_no_dynamic_ccbs(p_lcb);
1371 }
1372
1373 if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) {
1374 log::debug("Link congested for CID: 0x{:04x}", fixed_cid);
1375 return (L2CAP_DW_CONGESTED);
1376 }
1377
1378 return (L2CAP_DW_SUCCESS);
1379 }
1380
1381 /*******************************************************************************
1382 *
1383 * Function L2CA_RemoveFixedChnl
1384 *
1385 * Description Remove a fixed channel to a remote device.
1386 *
1387 * Parameters: Fixed CID
1388 * BD Address of remote
1389 * Idle timeout to use (or 0xFFFF if don't care)
1390 *
1391 * Return value: true if channel removed
1392 *
1393 ******************************************************************************/
L2CA_RemoveFixedChnl(uint16_t fixed_cid,const RawAddress & rem_bda)1394 bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
1395 tL2C_LCB* p_lcb;
1396 tL2C_CCB* p_ccb;
1397 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1398
1399 /* Check CID is valid and registered */
1400 if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
1401 (fixed_cid > L2CAP_LAST_FIXED_CHNL) ||
1402 (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb ==
1403 NULL)) {
1404 log::error("L2CA_RemoveFixedChnl() Invalid CID: 0x{:04x}", fixed_cid);
1405 return (false);
1406 }
1407
1408 if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
1409 transport = BT_TRANSPORT_LE;
1410
1411 /* Is a fixed channel connected to the remote BDA ?*/
1412 p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport);
1413
1414 if (((p_lcb) == NULL) ||
1415 (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL])) {
1416 log::warn("BDA: {} CID: 0x{:04x} not connected", rem_bda, fixed_cid);
1417 return (false);
1418 }
1419
1420 log::verbose("BDA: {} CID: 0x{:04x}", rem_bda, fixed_cid);
1421
1422 /* Release the CCB, starting an inactivity timeout on the LCB if no other CCBs
1423 * exist */
1424 p_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
1425
1426 p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = NULL;
1427 p_lcb->SetDisconnectReason(HCI_ERR_CONN_CAUSE_LOCAL_HOST);
1428
1429 // Retain the link for a few more seconds after SMP pairing is done, since
1430 // the Android platform always does service discovery after pairing is
1431 // complete. This will avoid the link down (pairing is complete) and an
1432 // immediate re-connection for service discovery.
1433 // Some devices do not do auto advertising when link is dropped, thus fail
1434 // the second connection and service discovery.
1435 if ((fixed_cid == L2CAP_ATT_CID) && !p_lcb->ccb_queue.p_first_ccb)
1436 p_lcb->idle_timeout = 0;
1437
1438 l2cu_release_ccb(p_ccb);
1439
1440 return (true);
1441 }
1442
1443 /*******************************************************************************
1444 *
1445 * Function L2CA_SetLeGattTimeout
1446 *
1447 * Description Higher layers call this function to set the idle timeout for
1448 * a fixed channel. The "idle timeout" is the amount of time
1449 * that a connection can remain up with no L2CAP channels on
1450 * it. A timeout of zero means that the connection will be torn
1451 * down immediately when the last channel is removed.
1452 * A timeout of 0xFFFF means no timeout. Values are in seconds.
1453 * A bd_addr is the remote BD address.
1454 *
1455 * Returns true if command succeeded, false if failed
1456 *
1457 ******************************************************************************/
L2CA_SetLeGattTimeout(const RawAddress & rem_bda,uint16_t idle_tout)1458 bool L2CA_SetLeGattTimeout(const RawAddress& rem_bda, uint16_t idle_tout) {
1459 constexpr uint16_t kAttCid = 4;
1460
1461 /* Is a fixed channel connected to the remote BDA ?*/
1462 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
1463 if (((p_lcb) == NULL) ||
1464 (!p_lcb->p_fixed_ccbs[kAttCid - L2CAP_FIRST_FIXED_CHNL])) {
1465 log::warn("BDA: {} CID: 0x{:04x} not connected", rem_bda, kAttCid);
1466 return (false);
1467 }
1468
1469 p_lcb->p_fixed_ccbs[kAttCid - L2CAP_FIRST_FIXED_CHNL]->fixed_chnl_idle_tout =
1470 idle_tout;
1471
1472 if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED &&
1473 !p_lcb->ccb_queue.p_first_ccb) {
1474 /* If there are no dynamic CCBs, (re)start the idle timer in case we changed
1475 * it */
1476 l2cu_no_dynamic_ccbs(p_lcb);
1477 }
1478
1479 return true;
1480 }
1481
L2CA_MarkLeLinkAsActive(const RawAddress & rem_bda)1482 bool L2CA_MarkLeLinkAsActive(const RawAddress& rem_bda) {
1483 tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
1484 if (p_lcb == NULL) {
1485 return false;
1486 }
1487 log::info("setting link to {} as active", rem_bda);
1488 p_lcb->with_active_local_clients = true;
1489 return true;
1490 }
1491
1492 /*******************************************************************************
1493 *
1494 * Function L2CA_DataWrite
1495 *
1496 * Description Higher layers call this function to write data.
1497 *
1498 * Returns L2CAP_DW_SUCCESS, if data accepted, else false
1499 * L2CAP_DW_CONGESTED, if data accepted and the channel is
1500 * congested
1501 * L2CAP_DW_FAILED, if error
1502 *
1503 ******************************************************************************/
L2CA_DataWrite(uint16_t cid,BT_HDR * p_data)1504 uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
1505 log::verbose("L2CA_DataWrite() CID: 0x{:04x} Len: {}", cid, p_data->len);
1506 return l2c_data_write(cid, p_data, L2CAP_FLUSHABLE_CH_BASED);
1507 }
1508
L2CA_LECocDataWrite(uint16_t cid,BT_HDR * p_data)1509 uint8_t L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) {
1510 return L2CA_DataWrite(cid, p_data);
1511 }
1512
1513 /*******************************************************************************
1514 *
1515 * Function L2CA_SetChnlFlushability
1516 *
1517 * Description Higher layers call this function to set a channels
1518 * flushability flags
1519 *
1520 * Returns true if CID found, else false
1521 *
1522 ******************************************************************************/
L2CA_SetChnlFlushability(uint16_t cid,bool is_flushable)1523 bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) {
1524 tL2C_CCB* p_ccb;
1525
1526 /* Find the channel control block. We don't know the link it is on. */
1527 p_ccb = l2cu_find_ccb_by_cid(NULL, cid);
1528 if (p_ccb == NULL) {
1529 log::warn("L2CAP - no CCB for L2CA_SetChnlFlushability, CID: {}", cid);
1530 return (false);
1531 }
1532
1533 p_ccb->is_flushable = is_flushable;
1534
1535 log::verbose("L2CA_SetChnlFlushability() CID: 0x{:04x} is_flushable: {}",
1536 cid, is_flushable);
1537
1538 return (true);
1539 }
1540
1541 /*******************************************************************************
1542 *
1543 * Function L2CA_FlushChannel
1544 *
1545 * Description This function flushes none, some or all buffers queued up
1546 * for xmission for a particular CID. If called with
1547 * L2CAP_FLUSH_CHANS_GET (0), it simply returns the number
1548 * of buffers queued for that CID L2CAP_FLUSH_CHANS_ALL (0xffff)
1549 * flushes all buffers. All other values specifies the maximum
1550 * buffers to flush.
1551 *
1552 * Returns Number of buffers left queued for that CID
1553 *
1554 ******************************************************************************/
L2CA_FlushChannel(uint16_t lcid,uint16_t num_to_flush)1555 uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) {
1556 tL2C_CCB* p_ccb;
1557 tL2C_LCB* p_lcb;
1558 uint16_t num_left = 0, num_flushed1 = 0, num_flushed2 = 0;
1559
1560 p_ccb = l2cu_find_ccb_by_cid(NULL, lcid);
1561
1562 if (!p_ccb || (p_ccb->p_lcb == NULL)) {
1563 log::warn("L2CA_FlushChannel() abnormally returning 0 CID: 0x{:04x}",
1564 lcid);
1565 return (0);
1566 }
1567 p_lcb = p_ccb->p_lcb;
1568
1569 if (num_to_flush != L2CAP_FLUSH_CHANS_GET) {
1570 log::verbose(
1571 "L2CA_FlushChannel (FLUSH) CID: 0x{:04x} NumToFlush: {} QC: {} "
1572 "pFirst: 0x{}",
1573 lcid, num_to_flush, fixed_queue_length(p_ccb->xmit_hold_q),
1574 fmt::ptr(fixed_queue_try_peek_first(p_ccb->xmit_hold_q)));
1575 } else {
1576 log::verbose("L2CA_FlushChannel (QUERY) CID: 0x{:04x}", lcid);
1577 }
1578
1579 /* Cannot flush eRTM buffers once they have a sequence number */
1580 if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) {
1581 // Don't need send enhanced_flush to controller if it is LE transport.
1582 if (p_lcb->transport != BT_TRANSPORT_LE &&
1583 num_to_flush != L2CAP_FLUSH_CHANS_GET) {
1584 /* If the controller supports enhanced flush, flush the data queued at the
1585 * controller */
1586 if (bluetooth::shim::GetController()->SupportsNonFlushablePb() &&
1587 (BTM_GetNumScoLinks() == 0)) {
1588 /* The only packet type defined - 0 - Automatically-Flushable Only */
1589 l2c_acl_flush(p_lcb->Handle());
1590 }
1591 }
1592
1593 // Iterate though list and flush the amount requested from
1594 // the transmit data queue that satisfy the layer and event conditions.
1595 for (const list_node_t* node = list_begin(p_lcb->link_xmit_data_q);
1596 (num_to_flush > 0) && node != list_end(p_lcb->link_xmit_data_q);) {
1597 BT_HDR* p_buf = (BT_HDR*)list_node(node);
1598 node = list_next(node);
1599 if ((p_buf->layer_specific == 0) && (p_buf->event == lcid)) {
1600 num_to_flush--;
1601 num_flushed1++;
1602
1603 list_remove(p_lcb->link_xmit_data_q, p_buf);
1604 osi_free(p_buf);
1605 }
1606 }
1607 }
1608
1609 /* If needed, flush buffers in the CCB xmit hold queue */
1610 while ((num_to_flush != 0) && (!fixed_queue_is_empty(p_ccb->xmit_hold_q))) {
1611 BT_HDR* p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q);
1612 osi_free(p_buf);
1613 num_to_flush--;
1614 num_flushed2++;
1615 }
1616
1617 /* If app needs to track all packets, call it */
1618 if ((p_ccb->p_rcb) && (p_ccb->p_rcb->api.pL2CA_TxComplete_Cb) &&
1619 (num_flushed2))
1620 (*p_ccb->p_rcb->api.pL2CA_TxComplete_Cb)(p_ccb->local_cid, num_flushed2);
1621
1622 /* Now count how many are left */
1623 for (const list_node_t* node = list_begin(p_lcb->link_xmit_data_q);
1624 node != list_end(p_lcb->link_xmit_data_q); node = list_next(node)) {
1625 BT_HDR* p_buf = (BT_HDR*)list_node(node);
1626 if (p_buf->event == lcid) num_left++;
1627 }
1628
1629 /* Add in the number in the CCB xmit queue */
1630 num_left += fixed_queue_length(p_ccb->xmit_hold_q);
1631
1632 /* Return the local number of buffers left for the CID */
1633 log::verbose("L2CA_FlushChannel() flushed: {} + {}, num_left: {}",
1634 num_flushed1, num_flushed2, num_left);
1635
1636 /* If we were congested, and now we are not, tell the app */
1637 l2cu_check_channel_congestion(p_ccb);
1638
1639 return (num_left);
1640 }
1641
L2CA_IsLinkEstablished(const RawAddress & bd_addr,tBT_TRANSPORT transport)1642 bool L2CA_IsLinkEstablished(const RawAddress& bd_addr,
1643 tBT_TRANSPORT transport) {
1644 return l2cu_find_lcb_by_bd_addr(bd_addr, transport) != nullptr;
1645 }
1646
1647 /*******************************************************************************
1648 **
1649 ** Function L2CA_SetMediaStreamChannel
1650 **
1651 ** Description This function is called to set/reset the ccb of active media
1652 ** streaming channel
1653 **
1654 ** Parameters: local_media_cid: The local cid provided to A2DP to be used
1655 ** for streaming
1656 ** status: The status of media streaming on this channel
1657 **
1658 ** Returns void
1659 **
1660 *******************************************************************************/
L2CA_SetMediaStreamChannel(uint16_t local_media_cid,bool status)1661 void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) {
1662 uint16_t i;
1663 int set_channel = -1;
1664 bluetooth::hal::SnoopLogger* snoop_logger = bluetooth::shim::GetSnoopLogger();
1665
1666 if (snoop_logger == nullptr) {
1667 log::error("bluetooth::shim::GetSnoopLogger() is nullptr");
1668 return;
1669 }
1670
1671 if (snoop_logger->GetBtSnoopMode() != snoop_logger->kBtSnoopLogModeFiltered) {
1672 return;
1673 }
1674
1675 log::debug("local_media_cid={}, status={}", local_media_cid,
1676 status ? "add" : "remove");
1677
1678 if (status) {
1679 for (i = 0; i < MAX_ACTIVE_AVDT_CONN; i++) {
1680 if (!(av_media_channels[i].is_active)) {
1681 set_channel = i;
1682 break;
1683 }
1684 }
1685
1686 if (set_channel < 0) {
1687 log::error("No empty slot found to set media channel");
1688 return;
1689 }
1690
1691 av_media_channels[set_channel].p_ccb =
1692 l2cu_find_ccb_by_cid(NULL, local_media_cid);
1693
1694 if (!av_media_channels[set_channel].p_ccb ||
1695 !av_media_channels[set_channel].p_ccb->p_lcb) {
1696 return;
1697 }
1698 av_media_channels[set_channel].local_cid = local_media_cid;
1699
1700 snoop_logger->AddA2dpMediaChannel(
1701 av_media_channels[set_channel].p_ccb->p_lcb->Handle(),
1702 av_media_channels[set_channel].local_cid,
1703 av_media_channels[set_channel].p_ccb->remote_cid);
1704
1705 log::verbose(
1706 "Set A2DP media snoop filtering for local_cid: {}, remote_cid: {}",
1707 local_media_cid, av_media_channels[set_channel].p_ccb->remote_cid);
1708 } else {
1709 for (i = 0; i < MAX_ACTIVE_AVDT_CONN; i++) {
1710 if (av_media_channels[i].is_active &&
1711 av_media_channels[i].local_cid == local_media_cid) {
1712 set_channel = i;
1713 break;
1714 }
1715 }
1716
1717 if (set_channel < 0) {
1718 log::error("The channel {} not found in active media channels",
1719 local_media_cid);
1720 return;
1721 }
1722
1723 if (!av_media_channels[set_channel].p_ccb ||
1724 !av_media_channels[set_channel].p_ccb->p_lcb) {
1725 return;
1726 }
1727
1728 snoop_logger->RemoveA2dpMediaChannel(
1729 av_media_channels[set_channel].p_ccb->p_lcb->Handle(),
1730 av_media_channels[set_channel].local_cid);
1731
1732 log::verbose("Reset A2DP media snoop filtering for local_cid: {}",
1733 local_media_cid);
1734 }
1735
1736 av_media_channels[set_channel].is_active = status;
1737 }
1738
1739 /*******************************************************************************
1740 **
1741 ** Function L2CA_isMediaChannel
1742 **
1743 ** Description This function returns if the channel id passed as parameter
1744 ** is an A2DP streaming channel
1745 **
1746 ** Parameters: handle: Connection handle with the remote device
1747 ** channel_id: Channel ID
1748 ** is_local_cid: Signifies if the channel id passed is local
1749 ** cid or remote cid (true if local, remote otherwise)
1750 **
1751 ** Returns bool
1752 **
1753 *******************************************************************************/
L2CA_isMediaChannel(uint16_t handle,uint16_t channel_id,bool is_local_cid)1754 bool L2CA_isMediaChannel(uint16_t handle, uint16_t channel_id,
1755 bool is_local_cid) {
1756 int i;
1757 bool ret = false;
1758
1759 for (i = 0; i < MAX_ACTIVE_AVDT_CONN; i++) {
1760 if (av_media_channels[i].is_active) {
1761 if (!av_media_channels[i].p_ccb || !av_media_channels[i].p_ccb->p_lcb) {
1762 continue;
1763 }
1764 if (((!is_local_cid &&
1765 channel_id == av_media_channels[i].p_ccb->remote_cid) ||
1766 (is_local_cid &&
1767 channel_id == av_media_channels[i].p_ccb->local_cid)) &&
1768 handle == av_media_channels[i].p_ccb->p_lcb->Handle()) {
1769 ret = true;
1770 break;
1771 }
1772 }
1773 }
1774
1775 return ret;
1776 }
1777
1778 using namespace bluetooth;
1779
1780 #define DUMPSYS_TAG "shim::legacy::l2cap"
1781
L2CA_Dumpsys(int fd)1782 void L2CA_Dumpsys(int fd) {
1783 LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
1784 for (int i = 0; i < MAX_L2CAP_LINKS; i++) {
1785 const tL2C_LCB& lcb = l2cb.lcb_pool[i];
1786 if (!lcb.in_use) continue;
1787 LOG_DUMPSYS(fd, "link_state:%s", link_state_text(lcb.link_state).c_str());
1788 LOG_DUMPSYS(fd, "handle:0x%04x", lcb.Handle());
1789
1790 const tL2C_CCB* ccb = lcb.ccb_queue.p_first_ccb;
1791 while (ccb != nullptr) {
1792 LOG_DUMPSYS(
1793 fd, " active channel lcid:0x%04x rcid:0x%04x is_ecoc:%s in_use:%s",
1794 ccb->local_cid, ccb->remote_cid,
1795 ccb->ecoc ? "true" : "false",
1796 ccb->in_use ? "true" : "false");
1797 ccb = ccb->p_next_ccb;
1798 }
1799 }
1800 }
1801 #undef DUMPSYS_TAG
1802