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