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