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