1 /******************************************************************************
2  *
3  *  Copyright 2002-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 module contains the AVDTP adaptation layer.
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "bluetooth-a2dp"
26 
27 #include <bluetooth/log.h>
28 #include <com_android_bluetooth_flags.h>
29 #include <string.h>
30 
31 #include <cstdint>
32 
33 #include "avdt_api.h"
34 #include "avdt_int.h"
35 #include "internal_include/bt_target.h"
36 #include "l2cap_types.h"
37 #include "l2cdefs.h"
38 #include "osi/include/allocator.h"
39 #include "stack/include/bt_hdr.h"
40 #include "stack/include/btm_sec_api_types.h"
41 #include "stack/include/l2cap_interface.h"
42 
43 using namespace bluetooth;
44 
LookupAvdtpScb(const AvdtpTransportChannel & tc)45 AvdtpScb* AvdtpAdaptationLayer::LookupAvdtpScb(const AvdtpTransportChannel& tc) {
46   if (tc.ccb_idx >= AVDT_NUM_LINKS) {
47     log::error("AvdtpScb entry not found: invalid ccb_idx: {}", tc.ccb_idx);
48     return nullptr;
49   }
50   if (tc.tcid >= AVDT_NUM_RT_TBL) {
51     log::error("AvdtpScb entry not found: invalid tcid: {}", tc.tcid);
52     return nullptr;
53   }
54   const AvdtpRoutingEntry& re = rt_tbl[tc.ccb_idx][tc.tcid];
55   log::verbose("ccb_idx: {} tcid: {} scb_hdl: {}", tc.ccb_idx, tc.tcid, re.scb_hdl);
56   return avdt_scb_by_hdl(re.scb_hdl);
57 }
58 
59 /*******************************************************************************
60  *
61  * Function         avdt_ad_type_to_tcid
62  *
63  * Description      Derives the TCID from the channel type and SCB.
64  *
65  *
66  * Returns          TCID value.
67  *
68  ******************************************************************************/
avdt_ad_type_to_tcid(uint8_t type,AvdtpScb * p_scb)69 uint8_t avdt_ad_type_to_tcid(uint8_t type, AvdtpScb* p_scb) {
70   if (type == AVDT_CHAN_SIG) {
71     return 0;
72   }
73   // The SCB Handle is unique in the [1, AVDT_NUM_LINKS * AVDT_NUM_SEPS]
74   // range. The scb_idx computed here is the SCB index for the corresponding
75   // SEP, and it is in the range [0, AVDT_NUM_SEPS) for a particular link.
76   uint8_t scb_idx = (avdt_scb_to_hdl(p_scb) - 1) % AVDT_NUM_LINKS;
77   // There are AVDT_CHAN_NUM_TYPES channel types per SEP. Here we compute
78   // the type index (TCID) from the SEP index and the type itself.
79   return (scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type;
80 }
81 
82 /*******************************************************************************
83  *
84  * Function         avdt_ad_tcid_to_type
85  *
86  * Description      Derives the channel type from the TCID.
87  *
88  *
89  * Returns          Channel type value.
90  *
91  ******************************************************************************/
avdt_ad_tcid_to_type(uint8_t tcid)92 static uint8_t avdt_ad_tcid_to_type(uint8_t tcid) {
93   if (tcid == 0) {
94     return AVDT_CHAN_SIG;
95   }
96   /* tcid translates to type based on number of channels, as follows:
97   ** only media channel   :  tcid=1,2,3,4,5,6...  type=1,1,1,1,1,1...
98   ** media and report     :  tcid=1,2,3,4,5,6...  type=1,2,1,2,1,2...
99   ** media, report, recov :  tcid=1,2,3,4,5,6...  type=1,2,3,1,2,3...
100   */
101   return ((tcid + AVDT_CHAN_NUM_TYPES - 2) % (AVDT_CHAN_NUM_TYPES - 1)) + 1;
102 }
103 
104 /*******************************************************************************
105  *
106  * Function         avdt_ad_init
107  *
108  * Description      Initialize adaptation layer.
109  *
110  *
111  * Returns          Nothing.
112  *
113  ******************************************************************************/
avdt_ad_init(void)114 void avdt_ad_init(void) {
115   int i;
116   AvdtpTransportChannel* p_tbl = avdtp_cb.ad.tc_tbl;
117   avdtp_cb.ad.Reset();
118 
119   /* make sure the peer_mtu is a valid value */
120   for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
121     p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
122   }
123 }
124 
125 /*******************************************************************************
126  *
127  * Function         avdt_ad_tc_tbl_by_st
128  *
129  * Description      Find adaptation layer transport channel table entry matching
130  *                  the given state.
131  *
132  *
133  * Returns          Pointer to matching entry.  For control channel it returns
134  *                  the matching entry.  For media or other it returns the
135  *                  first matching entry (there could be more than one).
136  *
137  ******************************************************************************/
avdt_ad_tc_tbl_by_st(uint8_t type,AvdtpCcb * p_ccb,uint8_t state)138 AvdtpTransportChannel* avdt_ad_tc_tbl_by_st(uint8_t type, AvdtpCcb* p_ccb, uint8_t state) {
139   int i;
140   AvdtpTransportChannel* p_tbl = avdtp_cb.ad.tc_tbl;
141   uint8_t ccb_idx;
142 
143   if (p_ccb == NULL) {
144     /* resending security req */
145     for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
146       /* must be AVDT_CHAN_SIG - tcid always zero */
147       if ((p_tbl->tcid == 0) && (p_tbl->state == state)) {
148         break;
149       }
150     }
151   } else {
152     ccb_idx = avdt_ccb_to_idx(p_ccb);
153 
154     for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
155       if (type == AVDT_CHAN_SIG) {
156         /* if control channel, tcid always zero */
157         if ((p_tbl->tcid == 0) && (p_tbl->ccb_idx == ccb_idx) && (p_tbl->state == state)) {
158           break;
159         }
160       } else {
161         /* if other channel, tcid is always > zero */
162         if ((p_tbl->tcid > 0) && (p_tbl->ccb_idx == ccb_idx) && (p_tbl->state == state)) {
163           break;
164         }
165       }
166     }
167   }
168 
169   /* if nothing found return null */
170   if (i == AVDT_NUM_TC_TBL) {
171     p_tbl = NULL;
172   }
173 
174   return p_tbl;
175 }
176 
177 /*******************************************************************************
178  *
179  * Function         avdt_ad_tc_tbl_by_lcid
180  *
181  * Description      Find adaptation layer transport channel table entry by LCID.
182  *
183  *
184  * Returns          Pointer to entry.
185  *
186  ******************************************************************************/
avdt_ad_tc_tbl_by_lcid(uint16_t lcid)187 AvdtpTransportChannel* avdt_ad_tc_tbl_by_lcid(uint16_t lcid) {
188   if (avdtp_cb.ad.lcid_tbl.count(lcid) != 0) {
189     uint8_t idx = avdtp_cb.ad.lcid_tbl[lcid];
190     return &avdtp_cb.ad.tc_tbl[idx];
191   } else {
192     return nullptr;
193   }
194 }
195 
196 /*******************************************************************************
197  *
198  * Function         avdt_ad_tc_tbl_by_type
199  *
200  * Description      This function retrieves the transport channel table entry
201  *                  for a particular channel.
202  *
203  *
204  * Returns          Pointer to transport channel table entry.
205  *
206  ******************************************************************************/
avdt_ad_tc_tbl_by_type(uint8_t type,AvdtpCcb * p_ccb,AvdtpScb * p_scb)207 AvdtpTransportChannel* avdt_ad_tc_tbl_by_type(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb) {
208   uint8_t tcid;
209   int i;
210   AvdtpTransportChannel* p_tbl = avdtp_cb.ad.tc_tbl;
211   uint8_t ccb_idx = avdt_ccb_to_idx(p_ccb);
212 
213   /* get tcid from type, scb */
214   tcid = avdt_ad_type_to_tcid(type, p_scb);
215 
216   for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
217     if ((p_tbl->tcid == tcid) && (p_tbl->ccb_idx == ccb_idx)) {
218       break;
219     }
220   }
221 
222   log::assert_that(i != AVDT_NUM_TC_TBL, "assert failed: i != AVDT_NUM_TC_TBL");
223 
224   return p_tbl;
225 }
226 
227 /*******************************************************************************
228  *
229  * Function         avdt_ad_tc_tbl_alloc
230  *
231  * Description      Allocate an entry in the traffic channel table.
232  *
233  *
234  * Returns          Pointer to entry.
235  *
236  ******************************************************************************/
avdt_ad_tc_tbl_alloc(AvdtpCcb * p_ccb)237 AvdtpTransportChannel* avdt_ad_tc_tbl_alloc(AvdtpCcb* p_ccb) {
238   int i;
239   AvdtpTransportChannel* p_tbl = avdtp_cb.ad.tc_tbl;
240 
241   /* find next free entry in tc table */
242   for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) {
243     if (p_tbl->state == AVDT_AD_ST_UNUSED) {
244       break;
245     }
246   }
247 
248   /* sanity check */
249   log::assert_that(i != AVDT_NUM_TC_TBL, "assert failed: i != AVDT_NUM_TC_TBL");
250 
251   /* initialize entry */
252   p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
253   p_tbl->role = tAVDT_ROLE::AVDT_UNKNOWN;
254   p_tbl->ccb_idx = avdt_ccb_to_idx(p_ccb);
255   p_tbl->state = AVDT_AD_ST_IDLE;
256   return p_tbl;
257 }
258 
259 /*******************************************************************************
260  *
261  * Function         avdt_ad_tc_tbl_to_idx
262  *
263  * Description      Convert a transport channel table entry to an index.
264  *
265  *
266  * Returns          Index value.
267  *
268  ******************************************************************************/
avdt_ad_tc_tbl_to_idx(AvdtpTransportChannel * p_tbl)269 uint8_t avdt_ad_tc_tbl_to_idx(AvdtpTransportChannel* p_tbl) {
270   return (uint8_t)(p_tbl - avdtp_cb.ad.tc_tbl);
271 }
272 
273 /*******************************************************************************
274  *
275  * Function         avdt_ad_tc_close_ind
276  *
277  * Description      This function is called by the L2CAP interface when the
278  *                  L2CAP channel is closed.  It looks up the CCB or SCB for
279  *                  the channel and sends it a close event.  The reason
280  *                  parameter is the same value passed by the L2CAP
281  *                  callback function.
282  *
283  *
284  * Returns          Nothing.
285  *
286  ******************************************************************************/
avdt_ad_tc_close_ind(AvdtpTransportChannel * p_tbl)287 void avdt_ad_tc_close_ind(AvdtpTransportChannel* p_tbl) {
288   AvdtpCcb* p_ccb;
289   AvdtpScb* p_scb;
290   tAVDT_SCB_TC_CLOSE close;
291 
292   log::verbose("p_tbl: {} state: {} tcid: {} type: {} ccb_idx: {} scb_hdl: {}",
293                std::format_ptr(p_tbl), tc_state_text(p_tbl->state), p_tbl->tcid,
294                tc_type_text(avdt_ad_tcid_to_type(p_tbl->tcid)), p_tbl->ccb_idx,
295                avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
296 
297   close.old_tc_state = p_tbl->state;
298   /* clear avdt_ad_tc_tbl entry */
299   p_tbl->state = AVDT_AD_ST_UNUSED;
300   p_tbl->role = tAVDT_ROLE::AVDT_UNKNOWN;
301   p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
302 
303   /* if signaling channel, notify ccb that channel close */
304   if (p_tbl->tcid == 0) {
305     p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
306     avdt_ccb_event(p_ccb, AVDT_CCB_LL_CLOSE_EVT, NULL);
307     return;
308   }
309   /* if media or other channel, notify scb that channel close */
310   /* look up scb in stream routing table by ccb, tcid */
311   p_scb = avdtp_cb.ad.LookupAvdtpScb(*p_tbl);
312   if (p_scb == nullptr) {
313     log::error("Cannot find AvdtScb entry: ccb_idx: {} tcid: {}", p_tbl->ccb_idx, p_tbl->tcid);
314     return;
315   }
316   close.tcid = p_tbl->tcid;
317   close.type = avdt_ad_tcid_to_type(p_tbl->tcid);
318   tAVDT_SCB_EVT avdt_scb_evt;
319   avdt_scb_evt.close = close;
320   avdt_scb_event(p_scb, AVDT_SCB_TC_CLOSE_EVT, &avdt_scb_evt);
321 }
322 
323 /*******************************************************************************
324  *
325  * Function         avdt_ad_tc_open_ind
326  *
327  * Description      This function is called by the L2CAP interface when
328  *                  the L2CAP channel is opened.  It looks up the CCB or SCB
329  *                  for the channel and sends it an open event.
330  *
331  *
332  * Returns          Nothing.
333  *
334  ******************************************************************************/
avdt_ad_tc_open_ind(AvdtpTransportChannel * p_tbl)335 void avdt_ad_tc_open_ind(AvdtpTransportChannel* p_tbl) {
336   AvdtpCcb* p_ccb;
337   AvdtpScb* p_scb;
338   tAVDT_OPEN open;
339   tAVDT_EVT_HDR evt;
340 
341   log::verbose("p_tbl: {} state: {} tcid: {} type: {} ccb_idx: {} scb_hdl: {}",
342                std::format_ptr(p_tbl), tc_state_text(p_tbl->state), p_tbl->tcid,
343                tc_type_text(avdt_ad_tcid_to_type(p_tbl->tcid)), p_tbl->ccb_idx,
344                avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
345 
346   p_tbl->state = AVDT_AD_ST_OPEN;
347 
348   /* if signaling channel, notify ccb that channel open */
349   if (p_tbl->tcid == 0) {
350     /* set the signal channel to use high priority within the ACL link */
351     if (!stack::l2cap::get_interface().L2CA_SetTxPriority(
352                 avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][AVDT_CHAN_SIG].lcid, L2CAP_CHNL_PRIORITY_HIGH)) {
353       log::warn("Unable to set L2CAP transmit high priority cid: 0x{:x}",
354                 avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][AVDT_CHAN_SIG].lcid);
355     }
356 
357     p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
358     /* use err_param to indicate the role of connection */
359     evt.err_param = static_cast<uint8_t>(p_tbl->role);
360     tAVDT_CCB_EVT avdt_ccb_evt;
361     avdt_ccb_evt.msg.hdr = evt;
362     avdt_ccb_event(p_ccb, AVDT_CCB_LL_OPEN_EVT, &avdt_ccb_evt);
363     return;
364   }
365   /* if media or other channel, notify scb that channel open */
366   /* look up scb in stream routing table by ccb, tcid */
367   p_scb = avdtp_cb.ad.LookupAvdtpScb(*p_tbl);
368   if (p_scb == nullptr) {
369     log::error("Cannot find AvdtScb entry: ccb_idx: {} tcid: {}", p_tbl->ccb_idx, p_tbl->tcid);
370     return;
371   }
372   /* put lcid in event data */
373   open.peer_mtu = p_tbl->peer_mtu;
374   open.lcid = avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].lcid;
375   open.hdr.err_code = avdt_ad_tcid_to_type(p_tbl->tcid);
376   tAVDT_SCB_EVT avdt_scb_evt;
377   avdt_scb_evt.open = open;
378   avdt_scb_event(p_scb, AVDT_SCB_TC_OPEN_EVT, &avdt_scb_evt);
379 }
380 
381 /*******************************************************************************
382  *
383  * Function         avdt_ad_tc_cong_ind
384  *
385  * Description      This function is called by the L2CAP interface layer when
386  *                  L2CAP calls the congestion callback.  It looks up the CCB
387  *                  or SCB for the channel and sends it a congestion event.
388  *                  The is_congested parameter is the same value passed by
389  *                  the L2CAP callback function.
390  *
391  *
392  * Returns          Nothing.
393  *
394  ******************************************************************************/
avdt_ad_tc_cong_ind(AvdtpTransportChannel * p_tbl,bool is_congested)395 void avdt_ad_tc_cong_ind(AvdtpTransportChannel* p_tbl, bool is_congested) {
396   AvdtpCcb* p_ccb;
397   AvdtpScb* p_scb;
398 
399   log::verbose("p_tbl: {} state: {} tcid: {} type: {} ccb_idx: {} scb_hdl: {} is_congested: {}",
400                std::format_ptr(p_tbl), tc_state_text(p_tbl->state), p_tbl->tcid,
401                tc_type_text(avdt_ad_tcid_to_type(p_tbl->tcid)), p_tbl->ccb_idx,
402                avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl, is_congested);
403 
404   /* if signaling channel, notify ccb of congestion */
405   if (p_tbl->tcid == 0) {
406     p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
407     tAVDT_CCB_EVT avdt_ccb_evt;
408     avdt_ccb_evt.llcong = is_congested;
409     avdt_ccb_event(p_ccb, AVDT_CCB_LL_CONG_EVT, &avdt_ccb_evt);
410     return;
411   }
412   /* if media or other channel, notify scb that channel open */
413   /* look up scb in stream routing table by ccb, tcid */
414   p_scb = avdtp_cb.ad.LookupAvdtpScb(*p_tbl);
415   if (p_scb == nullptr) {
416     log::error("Cannot find AvdtScb entry: ccb_idx: {} tcid: {}", p_tbl->ccb_idx, p_tbl->tcid);
417     return;
418   }
419   tAVDT_SCB_EVT avdt_scb_evt;
420   avdt_scb_evt.llcong = is_congested;
421   avdt_scb_event(p_scb, AVDT_SCB_TC_CONG_EVT, &avdt_scb_evt);
422 }
423 
424 /*******************************************************************************
425  *
426  * Function         avdt_ad_tc_data_ind
427  *
428  * Description      This function is called by the L2CAP interface layer when
429  *                  incoming data is received from L2CAP.  It looks up the CCB
430  *                  or SCB for the channel and routes the data accordingly.
431  *
432  *
433  * Returns          Nothing.
434  *
435  ******************************************************************************/
avdt_ad_tc_data_ind(AvdtpTransportChannel * p_tbl,BT_HDR * p_buf)436 void avdt_ad_tc_data_ind(AvdtpTransportChannel* p_tbl, BT_HDR* p_buf) {
437   AvdtpCcb* p_ccb;
438   AvdtpScb* p_scb;
439 
440   /* store type (media, recovery, reporting) */
441   p_buf->layer_specific = avdt_ad_tcid_to_type(p_tbl->tcid);
442 
443   /* if signaling channel, handle control message */
444   if (p_tbl->tcid == 0) {
445     p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
446     avdt_msg_ind(p_ccb, p_buf);
447     return;
448   }
449   /* if media or other channel, send event to scb */
450   p_scb = avdtp_cb.ad.LookupAvdtpScb(*p_tbl);
451   if (p_scb == nullptr) {
452     log::error("Cannot find AvdtScb entry: ccb_idx: {} tcid: {}", p_tbl->ccb_idx, p_tbl->tcid);
453     osi_free(p_buf);
454     log::error("buffer freed");
455     return;
456   }
457   avdt_scb_event(p_scb, AVDT_SCB_TC_DATA_EVT, (tAVDT_SCB_EVT*)&p_buf);
458 }
459 
460 /*******************************************************************************
461  *
462  * Function         avdt_ad_write_req
463  *
464  * Description      This function is called by a CCB or SCB to send data to a
465  *                  transport channel.  It looks up the LCID of the channel
466  *                  based on the type, CCB, and SCB (if present).  Then it
467  *                  passes the data to L2CA_DataWrite().
468  *
469  *
470  * Returns          AVDT_AD_SUCCESS, if data accepted
471  *                  AVDT_AD_CONGESTED, if data accepted and the channel is
472  *                                     congested
473  *                  AVDT_AD_FAILED, if error
474  *
475  ******************************************************************************/
avdt_ad_write_req(uint8_t type,AvdtpCcb * p_ccb,AvdtpScb * p_scb,BT_HDR * p_buf)476 tL2CAP_DW_RESULT avdt_ad_write_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, BT_HDR* p_buf) {
477   uint8_t tcid;
478 
479   /* get tcid from type, scb */
480   tcid = avdt_ad_type_to_tcid(type, p_scb);
481 
482   return stack::l2cap::get_interface().L2CA_DataWrite(
483           avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid, p_buf);
484 }
485 
486 /*******************************************************************************
487  *
488  * Function         avdt_ad_open_req
489  *
490  * Description      This function is called by a CCB or SCB to open a transport
491  *                  channel.  This function allocates and initializes a
492  *                  transport channel table entry.  The channel can be opened
493  *                  in two roles:  as an initiator or acceptor.  When opened
494  *                  as an initiator the function will start an L2CAP connection.
495  *                  When opened as an acceptor the function simply configures
496  *                  the table entry to listen for an incoming channel.
497  *
498  *
499  * Returns          Nothing.
500  *
501  ******************************************************************************/
avdt_ad_open_req(uint8_t type,AvdtpCcb * p_ccb,AvdtpScb * p_scb,tAVDT_ROLE role)502 void avdt_ad_open_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, tAVDT_ROLE role) {
503   AvdtpTransportChannel* p_tbl;
504   uint16_t lcid;
505 
506   p_tbl = avdt_ad_tc_tbl_alloc(p_ccb);
507   if (p_tbl == NULL) {
508     log::error("Cannot allocate p_tbl");
509     return;
510   }
511 
512   p_tbl->tcid = avdt_ad_type_to_tcid(type, p_scb);
513   p_tbl->my_mtu = kAvdtpMtu;
514   log::verbose("p_tbl: {} state: {} tcid: {} type: {} role: {} my_mtu: {}", std::format_ptr(p_tbl),
515                tc_state_text(p_tbl->state), p_tbl->tcid, tc_type_text(type), avdt_role_text(role),
516                p_tbl->my_mtu);
517 
518   if (type != AVDT_CHAN_SIG) {
519     /* also set scb_hdl in rt_tbl */
520     avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].scb_hdl = avdt_scb_to_hdl(p_scb);
521     log::verbose("For ccb index: {}, tcid: {} store scb_hdl: {}", avdt_ccb_to_idx(p_ccb),
522                  p_tbl->tcid, avdt_scb_to_hdl(p_scb));
523   }
524 
525   if (role == tAVDT_ROLE::AVDT_ACP) {
526     /* if we're acceptor, we're done; just sit back and listen */
527     p_tbl->state = AVDT_AD_ST_ACP;
528   } else {
529     /* else we're inititator, start the L2CAP connection */
530     p_tbl->state = AVDT_AD_ST_CONN;
531 
532     /* call l2cap connect req */
533     lcid = stack::l2cap::get_interface().L2CA_ConnectReqWithSecurity(
534       AVDT_PSM, p_ccb->peer_addr, BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT);
535 
536     if (lcid == 0) {
537       /* if connect req failed, call avdt_ad_tc_close_ind() */
538       avdt_ad_tc_close_ind(p_tbl);
539       return;
540     }
541 
542     /* if connect req ok, store tcid in lcid table  */
543     avdtp_cb.ad.lcid_tbl[lcid] = avdt_ad_tc_tbl_to_idx(p_tbl);
544     log::verbose("For lcid: 0x{:x} store table index: {}", lcid, avdt_ad_tc_tbl_to_idx(p_tbl));
545 
546     avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = lcid;
547     log::verbose("For ccb index: {} and tcid: {} store lcid 0x{:x}", avdt_ccb_to_idx(p_ccb),
548                  p_tbl->tcid, lcid);
549   }
550 }
551 
552 /*******************************************************************************
553  *
554  * Function         avdt_ad_close_req
555  *
556  * Description      This function is called by a CCB or SCB to close a
557  *                  transport channel.  The function looks up the LCID for the
558  *                  channel and calls L2CA_DisconnectReq().
559  *
560  *
561  * Returns          Nothing.
562  *
563  ******************************************************************************/
avdt_ad_close_req(uint8_t type,AvdtpCcb * p_ccb,AvdtpScb * p_scb)564 void avdt_ad_close_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb) {
565   uint16_t lcid;
566   AvdtpTransportChannel* p_tbl;
567 
568   p_tbl = avdt_ad_tc_tbl_by_type(type, p_ccb, p_scb);
569   log::verbose("p_tbl: {} state: {} tcid: {} type: {} ccb_idx: {} scb_hdl: {}",
570                std::format_ptr(p_tbl), tc_state_text(p_tbl->state), p_tbl->tcid, tc_type_text(type),
571                p_tbl->ccb_idx, avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
572 
573   switch (p_tbl->state) {
574     case AVDT_AD_ST_UNUSED:
575       /* probably for reporting */
576       break;
577     case AVDT_AD_ST_ACP:
578       /* if we're listening on this channel, send ourselves a close ind */
579       avdt_ad_tc_close_ind(p_tbl);
580       break;
581     default:
582       lcid = p_tbl->lcid;
583       /* call l2cap disconnect req */
584       if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
585         log::warn("Unable to disconnect L2CAP lcid: 0x{:04x}", lcid);
586       }
587       avdt_ad_tc_close_ind(p_tbl);
588   }
589 }
590