avdt_ad.cc 20 KB

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