avct_lcb_act.c revision 0d65d4cdafc165484dfc8d1c5af4ac1cb7453fd7
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 */
35const 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*******************************************************************************/
53static 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*******************************************************************************/
189void 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*******************************************************************************/
214void 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*******************************************************************************/
234void 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*******************************************************************************/
285void 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*******************************************************************************/
311void 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*******************************************************************************/
347void 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*******************************************************************************/
392void 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*******************************************************************************/
411void 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*******************************************************************************/
440void 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*******************************************************************************/
458void 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*******************************************************************************/
475void 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*******************************************************************************/
516void 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*******************************************************************************/
535void 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", p_lcb->tx_q.count);
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*******************************************************************************/
653void 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*******************************************************************************/
672void 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
696    /* check for invalid cr_ipid */
697    if (cr_ipid == AVCT_CR_IPID_INVALID)
698    {
699        AVCT_TRACE_WARNING("Invalid cr_ipid", cr_ipid);
700        GKI_freebuf(p_data->p_buf);
701        return;
702    }
703
704    /* parse and lookup PID */
705    BE_STREAM_TO_UINT16(pid, p);
706    if ((p_ccb = avct_lcb_has_pid(p_lcb, pid)) != NULL)
707    {
708        /* PID found; send msg up, adjust bt hdr and call msg callback */
709        p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE;
710        p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE;
711        (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid, p_data->p_buf);
712    }
713    else
714    {
715        /* PID not found; drop message */
716        AVCT_TRACE_WARNING("No ccb for PID=%x", pid);
717        GKI_freebuf(p_data->p_buf);
718
719        /* if command send reject */
720        if (cr_ipid == AVCT_CMD)
721        {
722            if ((p_buf = (BT_HDR *) GKI_getpoolbuf(AVCT_CMD_POOL_ID)) != NULL)
723            {
724                p_buf->len = AVCT_HDR_LEN_SINGLE;
725                p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE;
726                p = (UINT8 *)(p_buf + 1) + p_buf->offset;
727                AVCT_BLD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ);
728                UINT16_TO_BE_STREAM(p, pid);
729                L2CA_DataWrite(p_lcb->ch_lcid, p_buf);
730            }
731        }
732    }
733}
734