Home | History | Annotate | Download | only in avct
      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 *******************************************************************************/
     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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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