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