avct_lcb_act.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2003-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 action functions of the link control state machine.
  21. *
  22. ******************************************************************************/
  23. #include <string.h>
  24. #include "stack/bt_types.h"
  25. #include "common/bt_target.h"
  26. #include "common/bt_defs.h"
  27. #include "stack/avct_api.h"
  28. #include "avct_int.h"
  29. #include "stack/btm_api.h"
  30. #include "osi/allocator.h"
  31. #if (defined(AVCT_INCLUDED) && AVCT_INCLUDED == TRUE)
  32. /* packet header length lookup table */
  33. const UINT8 avct_lcb_pkt_type_len[] = {
  34. AVCT_HDR_LEN_SINGLE,
  35. AVCT_HDR_LEN_START,
  36. AVCT_HDR_LEN_CONT,
  37. AVCT_HDR_LEN_END
  38. };
  39. /*******************************************************************************
  40. **
  41. ** Function avct_lcb_msg_asmbl
  42. **
  43. ** Description Reassemble incoming message.
  44. **
  45. **
  46. ** Returns Pointer to reassembled message; NULL if no message
  47. ** available.
  48. **
  49. *******************************************************************************/
  50. static BT_HDR *avct_lcb_msg_asmbl(tAVCT_LCB *p_lcb, BT_HDR *p_buf)
  51. {
  52. UINT8 *p;
  53. UINT8 pkt_type;
  54. BT_HDR *p_ret;
  55. UINT16 buf_len;
  56. /* parse the message header */
  57. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  58. AVCT_PRS_PKT_TYPE(p, pkt_type);
  59. /* quick sanity check on length */
  60. if (p_buf->len < avct_lcb_pkt_type_len[pkt_type]) {
  61. osi_free(p_buf);
  62. AVCT_TRACE_WARNING("Bad length during reassembly");
  63. p_ret = NULL;
  64. }
  65. /* single packet */
  66. else if (pkt_type == AVCT_PKT_TYPE_SINGLE) {
  67. /* if reassembly in progress drop message and process new single */
  68. if (p_lcb->p_rx_msg != NULL) {
  69. AVCT_TRACE_WARNING("Got single during reassembly");
  70. }
  71. osi_free(p_lcb->p_rx_msg);
  72. p_lcb->p_rx_msg = NULL;
  73. p_ret = p_buf;
  74. }
  75. /* start packet */
  76. else if (pkt_type == AVCT_PKT_TYPE_START) {
  77. /* if reassembly in progress drop message and process new start */
  78. if (p_lcb->p_rx_msg != NULL) {
  79. AVCT_TRACE_WARNING("Got start during reassembly");
  80. }
  81. osi_free(p_lcb->p_rx_msg);
  82. /* Allocate bigger buffer for reassembly. As lower layers are
  83. * not aware of possible packet size after reassembly they
  84. * would have allocated smaller buffer.
  85. */
  86. p_lcb->p_rx_msg = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
  87. if (p_lcb->p_rx_msg == NULL) {
  88. AVCT_TRACE_ERROR ("Cannot alloc buffer for reassembly !!");
  89. osi_free(p_buf);
  90. } else {
  91. memcpy (p_lcb->p_rx_msg, p_buf,
  92. sizeof(BT_HDR) + p_buf->offset + p_buf->len);
  93. /* Free original buffer */
  94. osi_free(p_buf);
  95. /* update p to point to new buffer */
  96. p = (UINT8 *)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset;
  97. /* copy first header byte over nosp */
  98. *(p + 1) = *p;
  99. /* set offset to point to where to copy next */
  100. p_lcb->p_rx_msg->offset += p_lcb->p_rx_msg->len;
  101. /* adjust length for packet header */
  102. p_lcb->p_rx_msg->len -= 1;
  103. }
  104. p_ret = NULL;
  105. }
  106. /* continue or end */
  107. else {
  108. /* if no reassembly in progress drop message */
  109. if (p_lcb->p_rx_msg == NULL) {
  110. osi_free(p_buf);
  111. AVCT_TRACE_WARNING("Pkt type=%d out of order", pkt_type);
  112. p_ret = NULL;
  113. } else {
  114. /* get size of buffer holding assembled message */
  115. /*
  116. * NOTE: The buffer is allocated above at the beginning of the
  117. * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE.
  118. */
  119. buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR);
  120. /* adjust offset and len of fragment for header byte */
  121. p_buf->offset += AVCT_HDR_LEN_CONT;
  122. p_buf->len -= AVCT_HDR_LEN_CONT;
  123. /* verify length */
  124. if ((p_lcb->p_rx_msg->offset + p_buf->len) > buf_len) {
  125. /* won't fit; free everything */
  126. AVCT_TRACE_WARNING("%s: Fragmented message too big!", __func__);
  127. osi_free(p_lcb->p_rx_msg);
  128. p_lcb->p_rx_msg = NULL;
  129. osi_free(p_buf);
  130. p_ret = NULL;
  131. } else {
  132. /* copy contents of p_buf to p_rx_msg */
  133. memcpy((UINT8 *)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset,
  134. (UINT8 *)(p_buf + 1) + p_buf->offset, p_buf->len);
  135. if (pkt_type == AVCT_PKT_TYPE_END) {
  136. p_lcb->p_rx_msg->offset -= p_lcb->p_rx_msg->len;
  137. p_lcb->p_rx_msg->len += p_buf->len;
  138. p_ret = p_lcb->p_rx_msg;
  139. p_lcb->p_rx_msg = NULL;
  140. } else {
  141. p_lcb->p_rx_msg->offset += p_buf->len;
  142. p_lcb->p_rx_msg->len += p_buf->len;
  143. p_ret = NULL;
  144. }
  145. osi_free(p_buf);
  146. }
  147. }
  148. }
  149. return p_ret;
  150. }
  151. /*******************************************************************************
  152. **
  153. ** Function avct_lcb_chnl_open
  154. **
  155. ** Description Open L2CAP channel to peer
  156. **
  157. **
  158. ** Returns Nothing.
  159. **
  160. *******************************************************************************/
  161. void avct_lcb_chnl_open(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  162. {
  163. UINT16 result = AVCT_RESULT_FAIL;
  164. UNUSED(p_data);
  165. BTM_SetOutService(p_lcb->peer_addr, BTM_SEC_SERVICE_AVCTP, 0);
  166. /* call l2cap connect req */
  167. p_lcb->ch_state = AVCT_CH_CONN;
  168. if ((p_lcb->ch_lcid = L2CA_ConnectReq(AVCT_PSM, p_lcb->peer_addr)) == 0) {
  169. /* if connect req failed, send ourselves close event */
  170. avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT *) &result);
  171. }
  172. }
  173. /*******************************************************************************
  174. **
  175. ** Function avct_lcb_unbind_disc
  176. **
  177. ** Description Deallocate ccb and call callback with disconnect event.
  178. **
  179. **
  180. ** Returns Nothing.
  181. **
  182. *******************************************************************************/
  183. void avct_lcb_unbind_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  184. {
  185. UNUSED(p_lcb);
  186. avct_ccb_dealloc(p_data->p_ccb, AVCT_DISCONNECT_CFM_EVT, 0, NULL);
  187. }
  188. /*******************************************************************************
  189. **
  190. ** Function avct_lcb_open_ind
  191. **
  192. ** Description Handle an LL_OPEN event. For each allocated ccb already
  193. ** bound to this lcb, send a connect event. For each
  194. ** unbound ccb with a new PID, bind that ccb to this lcb and
  195. ** send a connect event.
  196. **
  197. **
  198. ** Returns Nothing.
  199. **
  200. *******************************************************************************/
  201. void avct_lcb_open_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  202. {
  203. tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
  204. int i;
  205. BOOLEAN bind = FALSE;
  206. for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
  207. /* if ccb allocated and */
  208. if (p_ccb->allocated) {
  209. /* if bound to this lcb send connect confirm event */
  210. if (p_ccb->p_lcb == p_lcb) {
  211. bind = TRUE;
  212. L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH);
  213. p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_CFM_EVT,
  214. 0, p_lcb->peer_addr);
  215. }
  216. /* if unbound acceptor and lcb doesn't already have a ccb for this PID */
  217. else if ((p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
  218. (avct_lcb_has_pid(p_lcb, p_ccb->cc.pid) == NULL)) {
  219. /* bind ccb to lcb and send connect ind event */
  220. bind = TRUE;
  221. p_ccb->p_lcb = p_lcb;
  222. L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH);
  223. p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_IND_EVT,
  224. 0, p_lcb->peer_addr);
  225. }
  226. }
  227. }
  228. /* if no ccbs bound to this lcb, disconnect */
  229. if (bind == FALSE) {
  230. avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
  231. }
  232. }
  233. /*******************************************************************************
  234. **
  235. ** Function avct_lcb_open_fail
  236. **
  237. ** Description L2CAP channel open attempt failed. Deallocate any ccbs
  238. ** on this lcb and send connect confirm event with failure.
  239. **
  240. **
  241. ** Returns Nothing.
  242. **
  243. *******************************************************************************/
  244. void avct_lcb_open_fail(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  245. {
  246. tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
  247. int i;
  248. for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
  249. if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
  250. avct_ccb_dealloc(p_ccb, AVCT_CONNECT_CFM_EVT,
  251. p_data->result, p_lcb->peer_addr);
  252. }
  253. }
  254. }
  255. /*******************************************************************************
  256. **
  257. ** Function avct_lcb_close_ind
  258. **
  259. ** Description L2CAP channel closed by peer. Deallocate any initiator
  260. ** ccbs on this lcb and send disconnect ind event.
  261. **
  262. **
  263. ** Returns Nothing.
  264. **
  265. *******************************************************************************/
  266. void avct_lcb_close_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  267. {
  268. tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
  269. int i;
  270. UNUSED(p_data);
  271. for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
  272. if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
  273. if (p_ccb->cc.role == AVCT_INT) {
  274. avct_ccb_dealloc(p_ccb, AVCT_DISCONNECT_IND_EVT,
  275. 0, p_lcb->peer_addr);
  276. } else {
  277. p_ccb->p_lcb = NULL;
  278. (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), AVCT_DISCONNECT_IND_EVT,
  279. 0, p_lcb->peer_addr);
  280. }
  281. }
  282. }
  283. }
  284. /*******************************************************************************
  285. **
  286. ** Function avct_lcb_close_cfm
  287. **
  288. ** Description L2CAP channel closed by us. Deallocate any initiator
  289. ** ccbs on this lcb and send disconnect ind or cfm event.
  290. **
  291. **
  292. ** Returns Nothing.
  293. **
  294. *******************************************************************************/
  295. void avct_lcb_close_cfm(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  296. {
  297. tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
  298. int i;
  299. UINT8 event;
  300. for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
  301. if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
  302. /* if this ccb initiated close send disconnect cfm otherwise ind */
  303. if (p_ccb->ch_close) {
  304. p_ccb->ch_close = FALSE;
  305. event = AVCT_DISCONNECT_CFM_EVT;
  306. } else {
  307. event = AVCT_DISCONNECT_IND_EVT;
  308. }
  309. if (p_ccb->cc.role == AVCT_INT) {
  310. avct_ccb_dealloc(p_ccb, event, p_data->result, p_lcb->peer_addr);
  311. } else {
  312. p_ccb->p_lcb = NULL;
  313. (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event,
  314. p_data->result, p_lcb->peer_addr);
  315. }
  316. }
  317. }
  318. }
  319. /*******************************************************************************
  320. **
  321. ** Function avct_lcb_bind_conn
  322. **
  323. ** Description Bind ccb to lcb and send connect cfm event.
  324. **
  325. **
  326. ** Returns Nothing.
  327. **
  328. *******************************************************************************/
  329. void avct_lcb_bind_conn(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  330. {
  331. p_data->p_ccb->p_lcb = p_lcb;
  332. (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
  333. AVCT_CONNECT_CFM_EVT, 0, p_lcb->peer_addr);
  334. }
  335. /*******************************************************************************
  336. **
  337. ** Function avct_lcb_chk_disc
  338. **
  339. ** Description A ccb wants to close; if it is the last ccb on this lcb,
  340. ** close channel. Otherwise just deallocate and call
  341. ** callback.
  342. **
  343. **
  344. ** Returns Nothing.
  345. **
  346. *******************************************************************************/
  347. void avct_lcb_chk_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  348. {
  349. AVCT_TRACE_EVENT("avct_lcb_chk_disc");
  350. #if (AVCT_BROWSE_INCLUDED == TRUE)
  351. avct_close_bcb(p_lcb, p_data);
  352. #endif
  353. if (avct_lcb_last_ccb(p_lcb, p_data->p_ccb)) {
  354. AVCT_TRACE_EVENT("closing");
  355. p_data->p_ccb->ch_close = TRUE;
  356. avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
  357. } else {
  358. AVCT_TRACE_EVENT("dealloc ccb");
  359. avct_lcb_unbind_disc(p_lcb, p_data);
  360. }
  361. }
  362. /*******************************************************************************
  363. **
  364. ** Function avct_lcb_chnl_disc
  365. **
  366. ** Description Disconnect L2CAP channel.
  367. **
  368. **
  369. ** Returns Nothing.
  370. **
  371. *******************************************************************************/
  372. void avct_lcb_chnl_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  373. {
  374. UNUSED(p_data);
  375. L2CA_DisconnectReq(p_lcb->ch_lcid);
  376. }
  377. /*******************************************************************************
  378. **
  379. ** Function avct_lcb_bind_fail
  380. **
  381. ** Description Deallocate ccb and call callback with connect event
  382. ** with failure result.
  383. **
  384. **
  385. ** Returns Nothing.
  386. **
  387. *******************************************************************************/
  388. void avct_lcb_bind_fail(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  389. {
  390. UNUSED(p_lcb);
  391. avct_ccb_dealloc(p_data->p_ccb, AVCT_CONNECT_CFM_EVT, AVCT_RESULT_FAIL, NULL);
  392. }
  393. /*******************************************************************************
  394. **
  395. ** Function avct_lcb_cong_ind
  396. **
  397. ** Description Handle congestion indication from L2CAP.
  398. **
  399. **
  400. ** Returns Nothing.
  401. **
  402. *******************************************************************************/
  403. void avct_lcb_cong_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  404. {
  405. tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
  406. int i;
  407. UINT8 event;
  408. BT_HDR *p_buf;
  409. /* set event */
  410. event = (p_data->cong) ? AVCT_CONG_IND_EVT : AVCT_UNCONG_IND_EVT;
  411. p_lcb->cong = p_data->cong;
  412. if (p_lcb->cong == FALSE && !fixed_queue_is_empty(p_lcb->tx_q))
  413. {
  414. while (!p_lcb->cong &&
  415. (p_buf = (BT_HDR *)fixed_queue_dequeue(p_lcb->tx_q, 0)) != NULL)
  416. {
  417. if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED)
  418. {
  419. p_lcb->cong = TRUE;
  420. }
  421. }
  422. }
  423. /* send event to all ccbs on this lcb */
  424. for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
  425. if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
  426. (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0, p_lcb->peer_addr);
  427. }
  428. }
  429. }
  430. /*******************************************************************************
  431. **
  432. ** Function avct_lcb_discard_msg
  433. **
  434. ** Description Discard a message sent in from the API.
  435. **
  436. **
  437. ** Returns Nothing.
  438. **
  439. *******************************************************************************/
  440. void avct_lcb_discard_msg(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  441. {
  442. UNUSED(p_lcb);
  443. AVCT_TRACE_WARNING("Dropping msg");
  444. osi_free(p_data->ul_msg.p_buf);
  445. p_data->ul_msg.p_buf = NULL;
  446. }
  447. /*******************************************************************************
  448. **
  449. ** Function avct_lcb_send_msg
  450. **
  451. ** Description Build and send an AVCTP message.
  452. **
  453. **
  454. ** Returns Nothing.
  455. **
  456. *******************************************************************************/
  457. void avct_lcb_send_msg(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  458. {
  459. UINT16 curr_msg_len;
  460. UINT8 pkt_type;
  461. UINT8 hdr_len;
  462. UINT8 *p;
  463. UINT8 nosp = 0; /* number of subsequent packets */
  464. UINT16 temp;
  465. UINT16 buf_size = p_lcb->peer_mtu + L2CAP_MIN_OFFSET + BT_HDR_SIZE;
  466. /* store msg len */
  467. curr_msg_len = p_data->ul_msg.p_buf->len;
  468. /* initialize packet type and other stuff */
  469. if (curr_msg_len <= (p_lcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) {
  470. pkt_type = AVCT_PKT_TYPE_SINGLE;
  471. } else {
  472. pkt_type = AVCT_PKT_TYPE_START;
  473. temp = (curr_msg_len + AVCT_HDR_LEN_START - p_lcb->peer_mtu);
  474. nosp = temp / (p_lcb->peer_mtu - 1) + 1;
  475. if ( (temp % (p_lcb->peer_mtu - 1)) != 0) {
  476. nosp++;
  477. }
  478. }
  479. /* while we haven't sent all packets */
  480. while (curr_msg_len != 0) {
  481. BT_HDR *p_buf;
  482. /* set header len */
  483. hdr_len = avct_lcb_pkt_type_len[pkt_type];
  484. /* if remaining msg must be fragmented */
  485. if (p_data->ul_msg.p_buf->len > (p_lcb->peer_mtu - hdr_len)) {
  486. /* get a new buffer for fragment we are sending */
  487. if ((p_buf = (BT_HDR *) osi_malloc(buf_size)) == NULL) {
  488. /* whoops; free original msg buf and bail */
  489. AVCT_TRACE_ERROR ("avct_lcb_send_msg cannot alloc buffer!!");
  490. osi_free(p_data->ul_msg.p_buf);
  491. break;
  492. }
  493. /* copy portion of data from current message to new buffer */
  494. p_buf->offset = L2CAP_MIN_OFFSET + hdr_len;
  495. p_buf->len = p_lcb->peer_mtu - hdr_len;
  496. memcpy((UINT8 *)(p_buf + 1) + p_buf->offset,
  497. (UINT8 *)(p_data->ul_msg.p_buf + 1) + p_data->ul_msg.p_buf->offset, p_buf->len);
  498. p_data->ul_msg.p_buf->offset += p_buf->len;
  499. p_data->ul_msg.p_buf->len -= p_buf->len;
  500. } else {
  501. p_buf = p_data->ul_msg.p_buf;
  502. }
  503. curr_msg_len -= p_buf->len;
  504. /* set up to build header */
  505. p_buf->len += hdr_len;
  506. p_buf->offset -= hdr_len;
  507. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  508. /* build header */
  509. AVCT_BLD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr);
  510. if (pkt_type == AVCT_PKT_TYPE_START) {
  511. UINT8_TO_STREAM(p, nosp);
  512. }
  513. if ((pkt_type == AVCT_PKT_TYPE_START) || (pkt_type == AVCT_PKT_TYPE_SINGLE)) {
  514. UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid);
  515. }
  516. if (p_lcb->cong == TRUE) {
  517. fixed_queue_enqueue(p_lcb->tx_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
  518. }
  519. /* send message to L2CAP */
  520. else {
  521. if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) {
  522. p_lcb->cong = TRUE;
  523. }
  524. }
  525. /* update pkt type for next packet */
  526. if (curr_msg_len > (p_lcb->peer_mtu - AVCT_HDR_LEN_END)) {
  527. pkt_type = AVCT_PKT_TYPE_CONT;
  528. } else {
  529. pkt_type = AVCT_PKT_TYPE_END;
  530. }
  531. }
  532. AVCT_TRACE_DEBUG ("avct_lcb_send_msg tx_q_count:%d",
  533. fixed_queue_length(p_lcb->tx_q));
  534. return;
  535. }
  536. /*******************************************************************************
  537. **
  538. ** Function avct_lcb_free_msg_ind
  539. **
  540. ** Description Discard an incoming AVCTP message.
  541. **
  542. **
  543. ** Returns Nothing.
  544. **
  545. *******************************************************************************/
  546. void avct_lcb_free_msg_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  547. {
  548. UNUSED(p_lcb);
  549. if (p_data == NULL) {
  550. return;
  551. }
  552. osi_free(p_data->p_buf);
  553. p_data->p_buf = NULL;
  554. }
  555. /*******************************************************************************
  556. **
  557. ** Function avct_lcb_msg_ind
  558. **
  559. ** Description Handle an incoming AVCTP message.
  560. **
  561. **
  562. ** Returns Nothing.
  563. **
  564. *******************************************************************************/
  565. void avct_lcb_msg_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
  566. {
  567. UINT8 *p;
  568. UINT8 label, type, cr_ipid;
  569. UINT16 pid;
  570. tAVCT_CCB *p_ccb;
  571. BT_HDR *p_buf;
  572. /* this p_buf is to be reported through p_msg_cback. The layer_specific
  573. * needs to be set properly to indicate that it is received through
  574. * control channel */
  575. p_data->p_buf->layer_specific = AVCT_DATA_CTRL;
  576. /* reassemble message; if no message available (we received a fragment) return */
  577. if ((p_data->p_buf = avct_lcb_msg_asmbl(p_lcb, p_data->p_buf)) == NULL) {
  578. return;
  579. }
  580. p = (UINT8 *)(p_data->p_buf + 1) + p_data->p_buf->offset;
  581. /* parse header byte */
  582. AVCT_PRS_HDR(p, label, type, cr_ipid);
  583. UNUSED(type);
  584. /* check for invalid cr_ipid */
  585. if (cr_ipid == AVCT_CR_IPID_INVALID) {
  586. AVCT_TRACE_WARNING("Invalid cr_ipid %d", cr_ipid);
  587. osi_free(p_data->p_buf);
  588. p_data->p_buf = NULL;
  589. return;
  590. }
  591. /* parse and lookup PID */
  592. BE_STREAM_TO_UINT16(pid, p);
  593. if ((p_ccb = avct_lcb_has_pid(p_lcb, pid)) != NULL) {
  594. /* PID found; send msg up, adjust bt hdr and call msg callback */
  595. p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE;
  596. p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE;
  597. (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid, p_data->p_buf);
  598. } else {
  599. /* PID not found; drop message */
  600. AVCT_TRACE_WARNING("No ccb for PID=%x", pid);
  601. osi_free(p_data->p_buf);
  602. p_data->p_buf = NULL;
  603. /* if command send reject */
  604. if (cr_ipid == AVCT_CMD) {
  605. if ((p_buf = (BT_HDR *) osi_malloc(AVCT_CMD_BUF_SIZE)) != NULL) {
  606. p_buf->len = AVCT_HDR_LEN_SINGLE;
  607. p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE;
  608. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  609. AVCT_BLD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ);
  610. UINT16_TO_BE_STREAM(p, pid);
  611. L2CA_DataWrite(p_lcb->ch_lcid, p_buf);
  612. }
  613. }
  614. }
  615. }
  616. #endif /* #if (defined(AVCT_INCLUDED) && AVCT_INCLUDED == TRUE) */