l2c_main.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 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. * This file contains the main L2CAP entry points
  21. *
  22. ******************************************************************************/
  23. #include <stdlib.h>
  24. #include <string.h>
  25. //#include <stdio.h>
  26. #include "device/controller.h"
  27. //#include "btcore/include/counter.h"
  28. #include "common/bt_target.h"
  29. #include "btm_int.h"
  30. #include "stack/btu.h"
  31. #include "stack/hcimsgs.h"
  32. #include "stack/l2c_api.h"
  33. #include "l2c_int.h"
  34. #include "stack/l2cdefs.h"
  35. //#include "osi/include/log.h"
  36. /********************************************************************************/
  37. /* L O C A L F U N C T I O N P R O T O T Y P E S */
  38. /********************************************************************************/
  39. #if (CLASSIC_BT_INCLUDED == TRUE)
  40. static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len);
  41. #endif ///CLASSIC_BT_INCLUDED == TRUE
  42. /********************************************************************************/
  43. /* G L O B A L L 2 C A P D A T A */
  44. /********************************************************************************/
  45. #if L2C_DYNAMIC_MEMORY == FALSE
  46. tL2C_CB l2cb;
  47. #else
  48. tL2C_CB *l2c_cb_ptr;
  49. #endif
  50. #if BT_CLASSIC_BQB_INCLUDED
  51. static BOOLEAN s_l2cap_bqb_bad_cmd_len_rej_flag = FALSE;
  52. #endif /* BT_CLASSIC_BQB_INCLUDED */
  53. #if 0 //Unused
  54. /*******************************************************************************
  55. **
  56. ** Function l2c_bcst_msg
  57. **
  58. ** Description
  59. **
  60. ** Returns void
  61. **
  62. *******************************************************************************/
  63. void l2c_bcst_msg( BT_HDR *p_buf, UINT16 psm )
  64. {
  65. UINT8 *p;
  66. /* Ensure we have enough space in the buffer for the L2CAP and HCI headers */
  67. if (p_buf->offset < L2CAP_BCST_MIN_OFFSET) {
  68. L2CAP_TRACE_ERROR ("L2CAP - cannot send buffer, offset: %d", p_buf->offset);
  69. osi_free (p_buf);
  70. return;
  71. }
  72. /* Step back some bytes to add the headers */
  73. p_buf->offset -= (HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_BCST_OVERHEAD);
  74. p_buf->len += L2CAP_PKT_OVERHEAD + L2CAP_BCST_OVERHEAD;
  75. /* Set the pointer to the beginning of the data */
  76. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  77. /* First, the HCI transport header */
  78. UINT16_TO_STREAM (p, 0x0050 | (L2CAP_PKT_START << 12) | (2 << 14));
  79. uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_classic();
  80. /* The HCI transport will segment the buffers. */
  81. if (p_buf->len > acl_data_size) {
  82. UINT16_TO_STREAM (p, acl_data_size);
  83. } else {
  84. UINT16_TO_STREAM (p, p_buf->len);
  85. }
  86. /* Now the L2CAP header */
  87. UINT16_TO_STREAM (p, p_buf->len - L2CAP_PKT_OVERHEAD);
  88. UINT16_TO_STREAM (p, L2CAP_CONNECTIONLESS_CID);
  89. UINT16_TO_STREAM (p, psm);
  90. p_buf->len += HCI_DATA_PREAMBLE_SIZE;
  91. if (p_buf->len <= controller_get_interface()->get_acl_packet_size_classic()) {
  92. //counter_add("l2cap.ch2.tx.bytes", p_buf->len);
  93. //counter_add("l2cap.ch2.tx.pkts", 1);
  94. bte_main_hci_send(p_buf, BT_EVT_TO_LM_HCI_ACL);
  95. }
  96. }
  97. #endif
  98. /*******************************************************************************
  99. **
  100. ** Function l2cap_bqb_bad_cmd_len_rej_ctrl
  101. **
  102. ** Description Control rejecting L2CAP signaling PDUs with incorrect length
  103. ** for BQB test.
  104. **
  105. ** Returns void
  106. **
  107. *******************************************************************************/
  108. #if BT_CLASSIC_BQB_INCLUDED
  109. void l2cap_bqb_bad_cmd_len_rej_ctrl(BOOLEAN enable)
  110. {
  111. s_l2cap_bqb_bad_cmd_len_rej_flag = enable;
  112. }
  113. #endif /* BT_CLASSIC_BQB_INCLUDED */
  114. /*******************************************************************************
  115. **
  116. ** Function l2c_rcv_acl_data
  117. **
  118. ** Description This function is called from the HCI Interface when an ACL
  119. ** data packet is received.
  120. **
  121. ** Returns void
  122. **
  123. *******************************************************************************/
  124. void l2c_rcv_acl_data (BT_HDR *p_msg)
  125. {
  126. UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset;
  127. UINT16 handle, hci_len;
  128. UINT8 pkt_type;
  129. tL2C_LCB *p_lcb;
  130. tL2C_CCB *p_ccb = NULL;
  131. UINT16 l2cap_len, rcv_cid;
  132. #if (!CONFIG_BT_STACK_NO_LOG)
  133. UINT16 psm;
  134. #endif
  135. UINT16 credit;
  136. /* Extract the handle */
  137. STREAM_TO_UINT16 (handle, p);
  138. pkt_type = HCID_GET_EVENT (handle);
  139. handle = HCID_GET_HANDLE (handle);
  140. /* Since the HCI Transport is putting segmented packets back together, we */
  141. /* should never get a valid packet with the type set to "continuation" */
  142. if (pkt_type != L2CAP_PKT_CONTINUE) {
  143. /* Find the LCB based on the handle */
  144. if ((p_lcb = l2cu_find_lcb_by_handle (handle)) == NULL) {
  145. UINT8 cmd_code;
  146. /* There is a slight possibility (specifically with USB) that we get an */
  147. /* L2CAP connection request before we get the HCI connection complete. */
  148. /* So for these types of messages, hold them for up to 2 seconds. */
  149. STREAM_TO_UINT16 (hci_len, p);
  150. STREAM_TO_UINT16 (l2cap_len, p);
  151. STREAM_TO_UINT16 (rcv_cid, p);
  152. STREAM_TO_UINT8 (cmd_code, p);
  153. if ((p_msg->layer_specific == 0) && (rcv_cid == L2CAP_SIGNALLING_CID)
  154. && (cmd_code == L2CAP_CMD_INFO_REQ || cmd_code == L2CAP_CMD_CONN_REQ)) {
  155. L2CAP_TRACE_WARNING ("L2CAP - holding ACL for unknown handle:%d ls:%d"
  156. " cid:%d opcode:%d cur count:%d", handle, p_msg->layer_specific,
  157. rcv_cid, cmd_code, list_length(l2cb.rcv_pending_q));
  158. p_msg->layer_specific = 2;
  159. list_append(l2cb.rcv_pending_q, p_msg);
  160. if (list_length(l2cb.rcv_pending_q) == 1) {
  161. btu_start_timer (&l2cb.rcv_hold_tle, BTU_TTYPE_L2CAP_HOLD, BT_1SEC_TIMEOUT);
  162. }
  163. return;
  164. } else {
  165. L2CAP_TRACE_ERROR ("L2CAP - rcvd ACL for unknown handle:%d ls:%d cid:%d"
  166. " opcode:%d cur count:%d", handle, p_msg->layer_specific, rcv_cid,
  167. cmd_code, list_length(l2cb.rcv_pending_q));
  168. }
  169. osi_free (p_msg);
  170. return;
  171. }
  172. } else {
  173. L2CAP_TRACE_WARNING ("L2CAP - expected pkt start or complete, got: %d", pkt_type);
  174. osi_free (p_msg);
  175. return;
  176. }
  177. /* Extract the length and update the buffer header */
  178. STREAM_TO_UINT16 (hci_len, p);
  179. p_msg->offset += 4;
  180. /* Extract the length and CID */
  181. STREAM_TO_UINT16 (l2cap_len, p);
  182. STREAM_TO_UINT16 (rcv_cid, p);
  183. #if BLE_INCLUDED == TRUE
  184. /* for BLE channel, always notify connection when ACL data received on the link */
  185. if (p_lcb && p_lcb->transport == BT_TRANSPORT_LE && p_lcb->link_state != LST_DISCONNECTING)
  186. /* only process fixed channel data as channel open indication when link is not in disconnecting mode */
  187. {
  188. l2cble_notify_le_connection(p_lcb->remote_bd_addr);
  189. }
  190. #endif
  191. L2CAP_TRACE_DEBUG ("L2CAP - rcv_cid CID: 0x%04x\n", rcv_cid);
  192. /* Find the CCB for this CID */
  193. if (rcv_cid >= L2CAP_BASE_APPL_CID) {
  194. if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, rcv_cid)) == NULL) {
  195. L2CAP_TRACE_WARNING ("L2CAP - unknown CID: 0x%04x", rcv_cid);
  196. osi_free (p_msg);
  197. return;
  198. }
  199. }
  200. if (hci_len >= L2CAP_PKT_OVERHEAD) { /* Must receive at least the L2CAP length and CID.*/
  201. p_msg->len = hci_len - L2CAP_PKT_OVERHEAD;
  202. p_msg->offset += L2CAP_PKT_OVERHEAD;
  203. } else {
  204. L2CAP_TRACE_WARNING ("L2CAP - got incorrect hci header" );
  205. osi_free (p_msg);
  206. return;
  207. }
  208. if (l2cap_len != p_msg->len) {
  209. L2CAP_TRACE_WARNING ("L2CAP - bad length in pkt. Exp: %d Act: %d",
  210. l2cap_len, p_msg->len);
  211. osi_free (p_msg);
  212. return;
  213. }
  214. /* Send the data through the channel state machine */
  215. if (rcv_cid == L2CAP_SIGNALLING_CID) {
  216. //counter_add("l2cap.sig.rx.bytes", l2cap_len);
  217. //counter_add("l2cap.sig.rx.pkts", 1);
  218. #if (CLASSIC_BT_INCLUDED == TRUE)
  219. process_l2cap_cmd (p_lcb, p, l2cap_len);
  220. #endif ///CLASSIC_BT_INCLUDED == TRUE
  221. osi_free (p_msg);
  222. } else if (rcv_cid == L2CAP_CONNECTIONLESS_CID) {
  223. //counter_add("l2cap.ch2.rx.bytes", l2cap_len);
  224. //counter_add("l2cap.ch2.rx.pkts", 1);
  225. /* process_connectionless_data (p_lcb); */
  226. #if !CONFIG_BT_STACK_NO_LOG
  227. STREAM_TO_UINT16 (psm, p);
  228. #endif
  229. L2CAP_TRACE_DEBUG( "GOT CONNECTIONLESS DATA PSM:%d", psm ) ;
  230. #if (L2CAP_UCD_INCLUDED == TRUE)
  231. /* if it is not broadcast, check UCD registration */
  232. if ( l2c_ucd_check_rx_pkts( p_lcb, p_msg ) ) {
  233. /* nothing to do */
  234. } else
  235. #endif
  236. {
  237. osi_free (p_msg);
  238. }
  239. }
  240. #if (BLE_INCLUDED == TRUE)
  241. else if (rcv_cid == L2CAP_BLE_SIGNALLING_CID) {
  242. //counter_add("l2cap.ble.rx.bytes", l2cap_len);
  243. //counter_add("l2cap.ble.rx.pkts", 1);
  244. l2cble_process_sig_cmd (p_lcb, p, l2cap_len);
  245. osi_free (p_msg);
  246. }
  247. #endif
  248. #if (L2CAP_NUM_FIXED_CHNLS > 0)
  249. else if ((rcv_cid >= L2CAP_FIRST_FIXED_CHNL) && (rcv_cid <= L2CAP_LAST_FIXED_CHNL) &&
  250. (l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb != NULL) ) {
  251. //counter_add("l2cap.fix.rx.bytes", l2cap_len);
  252. //counter_add("l2cap.fix.rx.pkts", 1);
  253. /* If no CCB for this channel, allocate one */
  254. if (p_lcb &&
  255. /* only process fixed channel data when link is open or wait for data indication */
  256. (p_lcb->link_state != LST_DISCONNECTING) &&
  257. l2cu_initialize_fixed_ccb (p_lcb, rcv_cid, &l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) {
  258. p_ccb = p_lcb->p_fixed_ccbs[rcv_cid - L2CAP_FIRST_FIXED_CHNL];
  259. if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE) {
  260. #if (CLASSIC_BT_INCLUDED == TRUE)
  261. l2c_fcr_proc_pdu (p_ccb, p_msg);
  262. #endif ///CLASSIC_BT_INCLUDED == TRUE
  263. } else {
  264. (*l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)
  265. (rcv_cid, p_lcb->remote_bd_addr, p_msg);
  266. }
  267. } else {
  268. osi_free (p_msg);
  269. }
  270. }
  271. #endif
  272. else {
  273. //counter_add("l2cap.dyn.rx.bytes", l2cap_len);
  274. //counter_add("l2cap.dyn.rx.pkts", 1);
  275. if (p_ccb == NULL) {
  276. osi_free (p_msg);
  277. } else {
  278. if (p_lcb->transport == BT_TRANSPORT_LE) {
  279. // Got a pkt, valid send out credits to the peer device
  280. credit = L2CAP_LE_DEFAULT_CREDIT;
  281. L2CAP_TRACE_DEBUG("%s Credits received %d",__func__, credit);
  282. if((p_ccb->peer_conn_cfg.credits + credit) > L2CAP_LE_MAX_CREDIT) {
  283. /* we have received credits more than max coc credits,
  284. * so disconnecting the Le Coc Channel
  285. */
  286. #if (BLE_INCLUDED == TRUE)
  287. l2cble_send_peer_disc_req (p_ccb);
  288. #endif ///BLE_INCLUDED == TRUE
  289. } else {
  290. p_ccb->peer_conn_cfg.credits += credit;
  291. l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, NULL);
  292. }
  293. }
  294. /* Basic mode packets go straight to the state machine */
  295. if (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_BASIC_MODE) {
  296. #if (CLASSIC_BT_INCLUDED == TRUE)
  297. l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DATA, p_msg);
  298. #endif ///CLASSIC_BT_INCLUDED == TRUE
  299. } else {
  300. /* eRTM or streaming mode, so we need to validate states first */
  301. if ((p_ccb->chnl_state == CST_OPEN) || (p_ccb->chnl_state == CST_CONFIG)) {
  302. #if (CLASSIC_BT_INCLUDED == TRUE)
  303. l2c_fcr_proc_pdu (p_ccb, p_msg);
  304. #endif ///CLASSIC_BT_INCLUDED == TRUE
  305. } else {
  306. osi_free (p_msg);
  307. }
  308. }
  309. }
  310. }
  311. }
  312. /*******************************************************************************
  313. **
  314. ** Function process_l2cap_cmd
  315. **
  316. ** Description This function is called when a packet is received on the
  317. ** L2CAP signalling CID
  318. **
  319. ** Returns void
  320. **
  321. *******************************************************************************/
  322. #if (CLASSIC_BT_INCLUDED == TRUE)
  323. static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
  324. {
  325. UINT8 *p_pkt_end, *p_next_cmd, *p_cfg_end, *p_cfg_start;
  326. UINT8 cmd_code, cfg_code, cfg_len, id;
  327. tL2C_CONN_INFO con_info;
  328. tL2CAP_CFG_INFO cfg_info;
  329. UINT16 rej_reason, rej_mtu, lcid, rcid, info_type;
  330. tL2C_CCB *p_ccb;
  331. tL2C_RCB *p_rcb;
  332. BOOLEAN cfg_rej, pkt_size_rej = FALSE;
  333. UINT16 cfg_rej_len, cmd_len;
  334. UINT16 result;
  335. tL2C_CONN_INFO ci;
  336. #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
  337. /* if l2cap command received in CID 1 on top of an LE link, ignore this command */
  338. if (p_lcb->transport == BT_TRANSPORT_LE) {
  339. return;
  340. }
  341. #endif
  342. /* Reject the packet if it exceeds the default Signalling Channel MTU */
  343. if (pkt_len > L2CAP_DEFAULT_MTU) {
  344. /* Core Spec requires a single response to the first command found in a multi-command
  345. ** L2cap packet. If only responses in the packet, then it will be ignored.
  346. ** Here we simply mark the bad packet and decide which cmd ID to reject later
  347. */
  348. pkt_size_rej = TRUE;
  349. L2CAP_TRACE_ERROR ("L2CAP SIG MTU Pkt Len Exceeded (672) -> pkt_len: %d", pkt_len);
  350. }
  351. p_next_cmd = p;
  352. p_pkt_end = p + pkt_len;
  353. memset (&cfg_info, 0, sizeof(cfg_info));
  354. /* An L2CAP packet may contain multiple commands */
  355. while (TRUE) {
  356. /* Smallest command is 4 bytes */
  357. if ((p = p_next_cmd) > (p_pkt_end - 4)) {
  358. break;
  359. }
  360. STREAM_TO_UINT8 (cmd_code, p);
  361. STREAM_TO_UINT8 (id, p);
  362. STREAM_TO_UINT16 (cmd_len, p);
  363. /* Check command length does not exceed packet length */
  364. if ((p_next_cmd = p + cmd_len) > p_pkt_end) {
  365. L2CAP_TRACE_WARNING ("Command len bad pkt_len: %d cmd_len: %d code: %d",
  366. pkt_len, cmd_len, cmd_code);
  367. break;
  368. }
  369. L2CAP_TRACE_DEBUG ("cmd_code: %d, id:%d, cmd_len:%d", cmd_code, id, cmd_len);
  370. /* Bad L2CAP packet length, look or cmd to reject */
  371. if (pkt_size_rej) {
  372. /* If command found rejected it and we're done, otherwise keep looking */
  373. if (l2c_is_cmd_rejected(cmd_code, id, p_lcb)) {
  374. return;
  375. } else {
  376. continue; /* Look for next cmd/response in current packet */
  377. }
  378. }
  379. switch (cmd_code) {
  380. case L2CAP_CMD_REJECT:
  381. STREAM_TO_UINT16 (rej_reason, p);
  382. if (rej_reason == L2CAP_CMD_REJ_MTU_EXCEEDED) {
  383. STREAM_TO_UINT16 (rej_mtu, p);
  384. /* What to do with the MTU reject ? We have negotiated an MTU. For now */
  385. /* we will ignore it and let a higher protocol timeout take care of it */
  386. L2CAP_TRACE_WARNING ("L2CAP - MTU rej Handle: %d MTU: %d", p_lcb->handle, rej_mtu);
  387. }
  388. if (rej_reason == L2CAP_CMD_REJ_INVALID_CID) {
  389. STREAM_TO_UINT16 (rcid, p);
  390. STREAM_TO_UINT16 (lcid, p);
  391. L2CAP_TRACE_WARNING ("L2CAP - rej with CID invalid, LCID: 0x%04x RCID: 0x%04x", lcid, rcid);
  392. /* Remote CID invalid. Treat as a disconnect */
  393. if (((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL)
  394. && (p_ccb->remote_cid == rcid)) {
  395. /* Fake link disconnect - no reply is generated */
  396. l2c_csm_execute (p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL);
  397. }
  398. }
  399. /* SonyEricsson Info request Bug workaround (Continue connection) */
  400. else if (rej_reason == L2CAP_CMD_REJ_NOT_UNDERSTOOD && p_lcb->w4_info_rsp) {
  401. btu_stop_timer (&p_lcb->info_timer_entry);
  402. p_lcb->w4_info_rsp = FALSE;
  403. ci.status = HCI_SUCCESS;
  404. memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
  405. /* For all channels, send the event through their FSMs */
  406. for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
  407. l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
  408. }
  409. }
  410. break;
  411. case L2CAP_CMD_CONN_REQ:
  412. STREAM_TO_UINT16 (con_info.psm, p);
  413. STREAM_TO_UINT16 (rcid, p);
  414. if ((p_rcb = l2cu_find_rcb_by_psm (con_info.psm)) == NULL) {
  415. L2CAP_TRACE_WARNING ("L2CAP - rcvd conn req for unknown PSM: %d", con_info.psm);
  416. l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_PSM);
  417. break;
  418. } else {
  419. if (!p_rcb->api.pL2CA_ConnectInd_Cb) {
  420. L2CAP_TRACE_WARNING ("L2CAP - rcvd conn req for outgoing-only connection PSM: %d", con_info.psm);
  421. l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_PSM);
  422. break;
  423. }
  424. }
  425. if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) {
  426. L2CAP_TRACE_ERROR ("L2CAP - unable to allocate CCB");
  427. l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_RESOURCES);
  428. break;
  429. }
  430. p_ccb->remote_id = id;
  431. p_ccb->p_rcb = p_rcb;
  432. p_ccb->remote_cid = rcid;
  433. l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info);
  434. #if BT_CLASSIC_BQB_INCLUDED
  435. // L2CAP/COS/CED/BI-02-C
  436. if (s_l2cap_bqb_bad_cmd_len_rej_flag) {
  437. l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
  438. }
  439. #endif /* BT_CLASSIC_BQB_INCLUDED */
  440. break;
  441. case L2CAP_CMD_CONN_RSP:
  442. STREAM_TO_UINT16 (con_info.remote_cid, p);
  443. STREAM_TO_UINT16 (lcid, p);
  444. STREAM_TO_UINT16 (con_info.l2cap_result, p);
  445. STREAM_TO_UINT16 (con_info.l2cap_status, p);
  446. if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) == NULL) {
  447. L2CAP_TRACE_WARNING ("L2CAP - no CCB for conn rsp, LCID: %d RCID: %d",
  448. lcid, con_info.remote_cid);
  449. break;
  450. }
  451. if (p_ccb->local_id != id) {
  452. L2CAP_TRACE_WARNING ("L2CAP - con rsp - bad ID. Exp: %d Got: %d",
  453. p_ccb->local_id, id);
  454. break;
  455. }
  456. if (con_info.l2cap_result == L2CAP_CONN_OK) {
  457. l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP, &con_info);
  458. } else if (con_info.l2cap_result == L2CAP_CONN_PENDING) {
  459. l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_PND, &con_info);
  460. } else {
  461. l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
  462. }
  463. break;
  464. case L2CAP_CMD_CONFIG_REQ:
  465. p_cfg_end = p + cmd_len;
  466. cfg_rej = FALSE;
  467. cfg_rej_len = 0;
  468. STREAM_TO_UINT16 (lcid, p);
  469. STREAM_TO_UINT16 (cfg_info.flags, p);
  470. p_cfg_start = p;
  471. cfg_info.flush_to_present = cfg_info.mtu_present = cfg_info.qos_present =
  472. cfg_info.fcr_present = cfg_info.fcs_present = FALSE;
  473. while (p < p_cfg_end) {
  474. STREAM_TO_UINT8 (cfg_code, p);
  475. STREAM_TO_UINT8 (cfg_len, p);
  476. switch (cfg_code & 0x7F) {
  477. case L2CAP_CFG_TYPE_MTU:
  478. cfg_info.mtu_present = TRUE;
  479. STREAM_TO_UINT16 (cfg_info.mtu, p);
  480. break;
  481. case L2CAP_CFG_TYPE_FLUSH_TOUT:
  482. cfg_info.flush_to_present = TRUE;
  483. STREAM_TO_UINT16 (cfg_info.flush_to, p);
  484. break;
  485. case L2CAP_CFG_TYPE_QOS:
  486. cfg_info.qos_present = TRUE;
  487. STREAM_TO_UINT8 (cfg_info.qos.qos_flags, p);
  488. STREAM_TO_UINT8 (cfg_info.qos.service_type, p);
  489. STREAM_TO_UINT32 (cfg_info.qos.token_rate, p);
  490. STREAM_TO_UINT32 (cfg_info.qos.token_bucket_size, p);
  491. STREAM_TO_UINT32 (cfg_info.qos.peak_bandwidth, p);
  492. STREAM_TO_UINT32 (cfg_info.qos.latency, p);
  493. STREAM_TO_UINT32 (cfg_info.qos.delay_variation, p);
  494. break;
  495. case L2CAP_CFG_TYPE_FCR:
  496. cfg_info.fcr_present = TRUE;
  497. STREAM_TO_UINT8 (cfg_info.fcr.mode, p);
  498. STREAM_TO_UINT8 (cfg_info.fcr.tx_win_sz, p);
  499. STREAM_TO_UINT8 (cfg_info.fcr.max_transmit, p);
  500. STREAM_TO_UINT16 (cfg_info.fcr.rtrans_tout, p);
  501. STREAM_TO_UINT16 (cfg_info.fcr.mon_tout, p);
  502. STREAM_TO_UINT16 (cfg_info.fcr.mps, p);
  503. break;
  504. case L2CAP_CFG_TYPE_FCS:
  505. cfg_info.fcs_present = TRUE;
  506. STREAM_TO_UINT8 (cfg_info.fcs, p);
  507. break;
  508. case L2CAP_CFG_TYPE_EXT_FLOW:
  509. cfg_info.ext_flow_spec_present = TRUE;
  510. STREAM_TO_UINT8 (cfg_info.ext_flow_spec.id, p);
  511. STREAM_TO_UINT8 (cfg_info.ext_flow_spec.stype, p);
  512. STREAM_TO_UINT16 (cfg_info.ext_flow_spec.max_sdu_size, p);
  513. STREAM_TO_UINT32 (cfg_info.ext_flow_spec.sdu_inter_time, p);
  514. STREAM_TO_UINT32 (cfg_info.ext_flow_spec.access_latency, p);
  515. STREAM_TO_UINT32 (cfg_info.ext_flow_spec.flush_timeout, p);
  516. break;
  517. default:
  518. /* sanity check option length */
  519. if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= cmd_len) {
  520. p += cfg_len;
  521. if ((cfg_code & 0x80) == 0) {
  522. cfg_rej_len += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
  523. cfg_rej = TRUE;
  524. }
  525. }
  526. /* bad length; force loop exit */
  527. else {
  528. p = p_cfg_end;
  529. cfg_rej = TRUE;
  530. }
  531. break;
  532. }
  533. }
  534. if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) {
  535. p_ccb->remote_id = id;
  536. if (cfg_rej) {
  537. l2cu_send_peer_config_rej (p_ccb, p_cfg_start, (UINT16) (cmd_len - L2CAP_CONFIG_REQ_LEN), cfg_rej_len);
  538. } else {
  539. l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_REQ, &cfg_info);
  540. }
  541. } else {
  542. /* updated spec says send command reject on invalid cid */
  543. l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, 0, 0);
  544. }
  545. break;
  546. case L2CAP_CMD_CONFIG_RSP:
  547. p_cfg_end = p + cmd_len;
  548. STREAM_TO_UINT16 (lcid, p);
  549. STREAM_TO_UINT16 (cfg_info.flags, p);
  550. STREAM_TO_UINT16 (cfg_info.result, p);
  551. cfg_info.flush_to_present = cfg_info.mtu_present = cfg_info.qos_present =
  552. cfg_info.fcr_present = cfg_info.fcs_present = FALSE;
  553. while (p < p_cfg_end) {
  554. STREAM_TO_UINT8 (cfg_code, p);
  555. STREAM_TO_UINT8 (cfg_len, p);
  556. switch (cfg_code & 0x7F) {
  557. case L2CAP_CFG_TYPE_MTU:
  558. cfg_info.mtu_present = TRUE;
  559. STREAM_TO_UINT16 (cfg_info.mtu, p);
  560. break;
  561. case L2CAP_CFG_TYPE_FLUSH_TOUT:
  562. cfg_info.flush_to_present = TRUE;
  563. STREAM_TO_UINT16 (cfg_info.flush_to, p);
  564. break;
  565. case L2CAP_CFG_TYPE_QOS:
  566. cfg_info.qos_present = TRUE;
  567. STREAM_TO_UINT8 (cfg_info.qos.qos_flags, p);
  568. STREAM_TO_UINT8 (cfg_info.qos.service_type, p);
  569. STREAM_TO_UINT32 (cfg_info.qos.token_rate, p);
  570. STREAM_TO_UINT32 (cfg_info.qos.token_bucket_size, p);
  571. STREAM_TO_UINT32 (cfg_info.qos.peak_bandwidth, p);
  572. STREAM_TO_UINT32 (cfg_info.qos.latency, p);
  573. STREAM_TO_UINT32 (cfg_info.qos.delay_variation, p);
  574. break;
  575. case L2CAP_CFG_TYPE_FCR:
  576. cfg_info.fcr_present = TRUE;
  577. STREAM_TO_UINT8 (cfg_info.fcr.mode, p);
  578. STREAM_TO_UINT8 (cfg_info.fcr.tx_win_sz, p);
  579. STREAM_TO_UINT8 (cfg_info.fcr.max_transmit, p);
  580. STREAM_TO_UINT16 (cfg_info.fcr.rtrans_tout, p);
  581. STREAM_TO_UINT16 (cfg_info.fcr.mon_tout, p);
  582. STREAM_TO_UINT16 (cfg_info.fcr.mps, p);
  583. break;
  584. case L2CAP_CFG_TYPE_FCS:
  585. cfg_info.fcs_present = TRUE;
  586. STREAM_TO_UINT8 (cfg_info.fcs, p);
  587. break;
  588. case L2CAP_CFG_TYPE_EXT_FLOW:
  589. cfg_info.ext_flow_spec_present = TRUE;
  590. STREAM_TO_UINT8 (cfg_info.ext_flow_spec.id, p);
  591. STREAM_TO_UINT8 (cfg_info.ext_flow_spec.stype, p);
  592. STREAM_TO_UINT16 (cfg_info.ext_flow_spec.max_sdu_size, p);
  593. STREAM_TO_UINT32 (cfg_info.ext_flow_spec.sdu_inter_time, p);
  594. STREAM_TO_UINT32 (cfg_info.ext_flow_spec.access_latency, p);
  595. STREAM_TO_UINT32 (cfg_info.ext_flow_spec.flush_timeout, p);
  596. break;
  597. }
  598. }
  599. if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) {
  600. if (p_ccb->local_id != id) {
  601. L2CAP_TRACE_WARNING ("L2CAP - cfg rsp - bad ID. Exp: %d Got: %d",
  602. p_ccb->local_id, id);
  603. break;
  604. }
  605. if ( (cfg_info.result == L2CAP_CFG_OK) || (cfg_info.result == L2CAP_CFG_PENDING) ) {
  606. l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_RSP, &cfg_info);
  607. } else {
  608. l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_RSP_NEG, &cfg_info);
  609. }
  610. } else {
  611. L2CAP_TRACE_WARNING ("L2CAP - rcvd cfg rsp for unknown CID: 0x%04x", lcid);
  612. }
  613. break;
  614. case L2CAP_CMD_DISC_REQ:
  615. STREAM_TO_UINT16 (lcid, p);
  616. STREAM_TO_UINT16 (rcid, p);
  617. if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) {
  618. if (p_ccb->remote_cid == rcid) {
  619. p_ccb->remote_id = id;
  620. l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, &con_info);
  621. }
  622. } else {
  623. l2cu_send_peer_disc_rsp (p_lcb, id, lcid, rcid);
  624. }
  625. break;
  626. case L2CAP_CMD_DISC_RSP:
  627. STREAM_TO_UINT16 (rcid, p);
  628. STREAM_TO_UINT16 (lcid, p);
  629. if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) {
  630. if ((p_ccb->remote_cid == rcid) && (p_ccb->local_id == id)) {
  631. l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, &con_info);
  632. }
  633. }
  634. break;
  635. case L2CAP_CMD_ECHO_REQ:
  636. l2cu_send_peer_echo_rsp (p_lcb, id, NULL, 0);
  637. break;
  638. case L2CAP_CMD_ECHO_RSP:
  639. if (p_lcb->p_echo_rsp_cb) {
  640. tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb;
  641. /* Zero out the callback in case app immediately calls us again */
  642. p_lcb->p_echo_rsp_cb = NULL;
  643. (*p_cb) (L2CAP_PING_RESULT_OK);
  644. }
  645. break;
  646. case L2CAP_CMD_INFO_REQ:
  647. STREAM_TO_UINT16 (info_type, p);
  648. l2cu_send_peer_info_rsp (p_lcb, id, info_type);
  649. break;
  650. case L2CAP_CMD_INFO_RSP:
  651. /* Stop the link connect timer if sent before L2CAP connection is up */
  652. if (p_lcb->w4_info_rsp) {
  653. btu_stop_timer (&p_lcb->info_timer_entry);
  654. p_lcb->w4_info_rsp = FALSE;
  655. }
  656. STREAM_TO_UINT16 (info_type, p);
  657. STREAM_TO_UINT16 (result, p);
  658. p_lcb->info_rx_bits |= (1 << info_type);
  659. if ( (info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE)
  660. && (result == L2CAP_INFO_RESP_RESULT_SUCCESS) ) {
  661. STREAM_TO_UINT32( p_lcb->peer_ext_fea, p );
  662. #if (L2CAP_NUM_FIXED_CHNLS > 0)
  663. if (p_lcb->peer_ext_fea & L2CAP_EXTFEA_FIXED_CHNLS) {
  664. l2cu_send_peer_info_req (p_lcb, L2CAP_FIXED_CHANNELS_INFO_TYPE);
  665. break;
  666. } else {
  667. l2cu_process_fixed_chnl_resp (p_lcb);
  668. }
  669. #endif
  670. }
  671. #if (L2CAP_NUM_FIXED_CHNLS > 0)
  672. if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) {
  673. if (result == L2CAP_INFO_RESP_RESULT_SUCCESS) {
  674. memcpy (p_lcb->peer_chnl_mask, p, L2CAP_FIXED_CHNL_ARRAY_SIZE);
  675. }
  676. l2cu_process_fixed_chnl_resp (p_lcb);
  677. }
  678. #endif
  679. #if (L2CAP_UCD_INCLUDED == TRUE)
  680. else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) {
  681. if (result == L2CAP_INFO_RESP_RESULT_SUCCESS) {
  682. STREAM_TO_UINT16 (p_lcb->ucd_mtu, p);
  683. }
  684. }
  685. #endif
  686. ci.status = HCI_SUCCESS;
  687. memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
  688. for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) {
  689. l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
  690. }
  691. break;
  692. default:
  693. L2CAP_TRACE_WARNING ("L2CAP - bad cmd code: %d", cmd_code);
  694. l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0);
  695. return;
  696. }
  697. }
  698. UNUSED(rej_mtu);
  699. }
  700. #endif ///CLASSIC_BT_INCLUDED == TRUE
  701. /*******************************************************************************
  702. **
  703. ** Function l2c_process_held_packets
  704. **
  705. ** Description This function processes any L2CAP packets that arrived before
  706. ** the HCI connection complete arrived. It is a work around for
  707. ** badly behaved controllers.
  708. **
  709. ** Returns void
  710. **
  711. *******************************************************************************/
  712. void l2c_process_held_packets(BOOLEAN timed_out)
  713. {
  714. if (list_is_empty(l2cb.rcv_pending_q)) {
  715. return;
  716. }
  717. if (!timed_out) {
  718. btu_stop_timer(&l2cb.rcv_hold_tle);
  719. L2CAP_TRACE_WARNING("L2CAP HOLD CONTINUE");
  720. } else {
  721. L2CAP_TRACE_WARNING("L2CAP HOLD TIMEOUT");
  722. }
  723. for (const list_node_t *node = list_begin(l2cb.rcv_pending_q);
  724. node != list_end(l2cb.rcv_pending_q);) {
  725. BT_HDR *p_buf = list_node(node);
  726. node = list_next(node);
  727. if (!timed_out || (!p_buf->layer_specific) || (--p_buf->layer_specific == 0)) {
  728. list_remove(l2cb.rcv_pending_q, p_buf);
  729. p_buf->layer_specific = 0xFFFF;
  730. l2c_rcv_acl_data(p_buf);
  731. }
  732. }
  733. /* If anyone still in the queue, restart the timeout */
  734. if (!list_is_empty(l2cb.rcv_pending_q)) {
  735. btu_start_timer (&l2cb.rcv_hold_tle, BTU_TTYPE_L2CAP_HOLD, BT_1SEC_TIMEOUT);
  736. }
  737. }
  738. /*******************************************************************************
  739. **
  740. ** Function l2c_init
  741. **
  742. ** Description This function is called once at startup to initialize
  743. ** all the L2CAP structures
  744. **
  745. ** Returns void
  746. **
  747. *******************************************************************************/
  748. void l2c_init (void)
  749. {
  750. #if L2C_DYNAMIC_MEMORY
  751. l2c_cb_ptr = (tL2C_CB *)osi_malloc(sizeof(tL2C_CB));
  752. #endif /* #if L2C_DYNAMIC_MEMORY */
  753. memset (&l2cb, 0, sizeof (tL2C_CB));
  754. /* the psm is increased by 2 before being used */
  755. l2cb.dyn_psm = 0xFFF;
  756. l2cb.p_ccb_pool = list_new(osi_free_func);
  757. if (l2cb.p_ccb_pool == NULL) {
  758. L2CAP_TRACE_ERROR("%s unable to allocate memory for L2CAP channel control block", __func__);
  759. }
  760. l2cb.p_lcb_pool = list_new(osi_free_func);
  761. if (l2cb.p_lcb_pool == NULL) {
  762. L2CAP_TRACE_ERROR("%s unable to allocate memory for L2CAP Link control block", __func__);
  763. }
  764. #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
  765. /* it will be set to L2CAP_PKT_START_NON_FLUSHABLE if controller supports */
  766. l2cb.non_flushable_pbf = L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT;
  767. #endif
  768. #ifdef L2CAP_DESIRED_LINK_ROLE
  769. l2cb.desire_role = L2CAP_DESIRED_LINK_ROLE;
  770. #else
  771. l2cb.desire_role = HCI_ROLE_SLAVE;
  772. #endif
  773. /* Set the default idle timeout */
  774. l2cb.idle_timeout = L2CAP_LINK_INACTIVITY_TOUT;
  775. #if defined(L2CAP_INITIAL_TRACE_LEVEL)
  776. l2cb.l2cap_trace_level = L2CAP_INITIAL_TRACE_LEVEL;
  777. #else
  778. l2cb.l2cap_trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
  779. #endif
  780. #if L2CAP_CONFORMANCE_TESTING == TRUE
  781. /* Conformance testing needs a dynamic response */
  782. l2cb.test_info_resp = L2CAP_EXTFEA_SUPPORTED_MASK;
  783. #endif
  784. /* Number of ACL buffers to use for high priority channel */
  785. #if (defined(L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE) && (L2CAP_HIGH_PRI_CHAN_QUOTA_IS_CONFIGURABLE == TRUE))
  786. l2cb.high_pri_min_xmit_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA;
  787. #endif
  788. #if BLE_INCLUDED == TRUE
  789. l2cb.l2c_ble_fixed_chnls_mask =
  790. L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
  791. #endif
  792. l2cb.rcv_pending_q = list_new(NULL);
  793. if (l2cb.rcv_pending_q == NULL) {
  794. L2CAP_TRACE_ERROR("%s unable to allocate memory for link layer control block", __func__);
  795. }
  796. #if BLE_INCLUDED == TRUE
  797. l2ble_update_att_acl_pkt_num(L2CA_BUFF_INI, NULL);
  798. #endif
  799. }
  800. void l2c_free_p_lcb_pool(void)
  801. {
  802. list_node_t *p_node = NULL;
  803. tL2C_LCB *p_lcb = NULL;
  804. for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) {
  805. p_lcb = list_node(p_node);
  806. if (p_lcb) {
  807. l2cu_release_lcb (p_lcb);
  808. }
  809. }
  810. list_free(l2cb.p_lcb_pool);
  811. }
  812. void l2c_free_p_ccb_pool(void)
  813. {
  814. list_node_t *p_node = NULL;
  815. tL2C_CCB *p_ccb = NULL;
  816. for (p_node = list_begin(l2cb.p_ccb_pool); p_node; p_node = list_next(p_node)) {
  817. p_ccb = list_node(p_node);
  818. if (p_ccb) {
  819. l2cu_release_ccb (p_ccb);
  820. }
  821. }
  822. list_free(l2cb.p_ccb_pool);
  823. }
  824. void l2c_free(void)
  825. {
  826. list_free(l2cb.rcv_pending_q);
  827. l2cb.rcv_pending_q = NULL;
  828. l2c_free_p_lcb_pool();
  829. l2c_free_p_ccb_pool();
  830. #if L2C_DYNAMIC_MEMORY
  831. FREE_AND_RESET(l2c_cb_ptr);
  832. #endif
  833. #if BLE_INCLUDED == TRUE
  834. l2ble_update_att_acl_pkt_num(L2CA_BUFF_DEINIT, NULL);
  835. #endif
  836. }
  837. /*******************************************************************************
  838. **
  839. ** Function l2c_process_timeout
  840. **
  841. ** Description This function is called when an L2CAP-related timeout occurs
  842. **
  843. ** Returns void
  844. **
  845. *******************************************************************************/
  846. void l2c_process_timeout (TIMER_LIST_ENT *p_tle)
  847. {
  848. /* What type of timeout ? */
  849. switch (p_tle->event) {
  850. case BTU_TTYPE_L2CAP_LINK:
  851. l2c_link_timeout ((tL2C_LCB *)p_tle->param);
  852. break;
  853. #if (CLASSIC_BT_INCLUDED == TRUE)
  854. case BTU_TTYPE_L2CAP_CHNL:
  855. l2c_csm_execute (((tL2C_CCB *)p_tle->param), L2CEVT_TIMEOUT, NULL);
  856. break;
  857. case BTU_TTYPE_L2CAP_FCR_ACK:
  858. l2c_csm_execute (((tL2C_CCB *)p_tle->param), L2CEVT_ACK_TIMEOUT, NULL);
  859. break;
  860. #endif ///CLASSIC_BT_INCLUDED == TRUE
  861. case BTU_TTYPE_L2CAP_HOLD:
  862. /* Update the timeouts in the hold queue */
  863. l2c_process_held_packets(TRUE);
  864. break;
  865. case BTU_TTYPE_L2CAP_INFO:
  866. l2c_info_timeout((tL2C_LCB *)p_tle->param);
  867. break;
  868. case BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS: {
  869. #if (BLE_INCLUDED == TRUE)
  870. UINT8 status = HCI_ERR_HOST_TIMEOUT;
  871. tL2C_LCB *p_lcb = (tL2C_LCB *)p_tle->param;
  872. if (p_lcb){
  873. p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING;
  874. p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL;
  875. l2c_send_update_conn_params_cb(p_lcb, status);
  876. }
  877. #endif ///BLE_INCLUDED == TRUE
  878. break;
  879. }
  880. }
  881. }
  882. /*******************************************************************************
  883. **
  884. ** Function l2c_data_write
  885. **
  886. ** Description API functions call this function to write data.
  887. **
  888. ** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE
  889. ** L2CAP_DW_CONGESTED, if data accepted and the channel is congested
  890. ** L2CAP_DW_FAILED, if error
  891. **
  892. *******************************************************************************/
  893. #if (CLASSIC_BT_INCLUDED == TRUE)
  894. UINT8 l2c_data_write (UINT16 cid, BT_HDR *p_data, UINT16 flags)
  895. {
  896. tL2C_CCB *p_ccb;
  897. /* Find the channel control block. We don't know the link it is on. */
  898. if ((p_ccb = l2cu_find_ccb_by_cid (NULL, cid)) == NULL) {
  899. L2CAP_TRACE_WARNING ("L2CAP - no CCB for L2CA_DataWrite, CID: %d", cid);
  900. osi_free (p_data);
  901. return (L2CAP_DW_FAILED);
  902. }
  903. #ifndef TESTER /* Tester may send any amount of data. otherwise sending message
  904. bigger than mtu size of peer is a violation of protocol */
  905. if (p_data->len > p_ccb->peer_cfg.mtu) {
  906. L2CAP_TRACE_WARNING ("L2CAP - CID: 0x%04x cannot send message bigger than peer's mtu size", cid);
  907. osi_free (p_data);
  908. return (L2CAP_DW_FAILED);
  909. }
  910. #endif
  911. /* channel based, packet based flushable or non-flushable */
  912. p_data->layer_specific = flags;
  913. /* If already congested, do not accept any more packets */
  914. if (p_ccb->cong_sent) {
  915. L2CAP_TRACE_DEBUG ("L2CAP - CID: 0x%04x cannot send, already congested xmit_hold_q.count: %u buff_quota: %u",
  916. p_ccb->local_cid,
  917. fixed_queue_length(p_ccb->xmit_hold_q),
  918. p_ccb->buff_quota);
  919. osi_free (p_data);
  920. return (L2CAP_DW_FAILED);
  921. }
  922. //counter_add("l2cap.dyn.tx.bytes", p_data->len);
  923. //counter_add("l2cap.dyn.tx.pkts", 1);
  924. l2c_csm_execute (p_ccb, L2CEVT_L2CA_DATA_WRITE, p_data);
  925. if (p_ccb->cong_sent) {
  926. return (L2CAP_DW_CONGESTED);
  927. }
  928. return (L2CAP_DW_SUCCESS);
  929. }
  930. #endif ///CLASSIC_BT_INCLUDED == TRUE