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