OSDN Git Service

Add BT_HDR length check for received AVCTP packets
[android-x86/system-bt.git] / stack / avct / avct_bcb_act.cc
1 /******************************************************************************
2  *
3  *  Copyright (C) 2003-2016 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 *  Name:           avct_bcb_act.cc
22 *
23 *  Description:    This module contains action functions of the browsing control
24 *                  state machine.
25 *
26  *****************************************************************************/
27
28 #include <log/log.h>
29 #include <string.h>
30 #include "avct_api.h"
31 #include "avct_int.h"
32 #include "bt_target.h"
33 #include "bt_utils.h"
34 #include "btm_api.h"
35 #include "osi/include/osi.h"
36
37 /* action function list */
38 const tAVCT_BCB_ACTION avct_bcb_action[] = {
39     avct_bcb_chnl_open,   /* AVCT_LCB_CHNL_OPEN */
40     avct_bcb_chnl_disc,   /* AVCT_LCB_CHNL_DISC */
41     avct_bcb_send_msg,    /* AVCT_LCB_SEND_MSG */
42     avct_bcb_open_ind,    /* AVCT_LCB_OPEN_IND */
43     avct_bcb_open_fail,   /* AVCT_LCB_OPEN_FAIL */
44     avct_bcb_close_ind,   /* AVCT_LCB_CLOSE_IND */
45     avct_bcb_close_cfm,   /* AVCT_LCB_CLOSE_CFM */
46     avct_bcb_msg_ind,     /* AVCT_LCB_MSG_IND */
47     avct_bcb_cong_ind,    /* AVCT_LCB_CONG_IND */
48     avct_bcb_bind_conn,   /* AVCT_LCB_BIND_CONN */
49     avct_bcb_bind_fail,   /* AVCT_LCB_BIND_FAIL */
50     avct_bcb_unbind_disc, /* AVCT_LCB_UNBIND_DISC */
51     avct_bcb_chk_disc,    /* AVCT_LCB_CHK_DISC */
52     avct_bcb_discard_msg, /* AVCT_LCB_DISCARD_MSG */
53     avct_bcb_dealloc,     /* AVCT_LCB_DEALLOC */
54     avct_bcb_free_msg_ind /* AVCT_LCB_FREE_MSG_IND */
55 };
56
57 /*******************************************************************************
58  *
59  * Function         avct_bcb_msg_asmbl
60  *
61  * Description      Reassemble incoming message.
62  *
63  *
64  * Returns          Pointer to reassembled message;  NULL if no message
65  *                  available.
66  *
67  ******************************************************************************/
68 static BT_HDR* avct_bcb_msg_asmbl(UNUSED_ATTR tAVCT_BCB* p_bcb, BT_HDR* p_buf) {
69   uint8_t* p;
70   uint8_t pkt_type;
71
72   if (p_buf->len == 0) {
73     osi_free_and_reset((void**)&p_buf);
74     android_errorWriteLog(0x534e4554, "79944113");
75     return nullptr;
76   }
77
78   /* parse the message header */
79   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
80   pkt_type = AVCT_PKT_TYPE(p);
81
82   /* must be single packet - can not fragment */
83   if (pkt_type != AVCT_PKT_TYPE_SINGLE) {
84     osi_free_and_reset((void**)&p_buf);
85     AVCT_TRACE_WARNING("Pkt type=%d - fragmentation not allowed. drop it",
86                        pkt_type);
87   }
88   return p_buf;
89 }
90
91 /*******************************************************************************
92  *
93  * Function         avct_bcb_chnl_open
94  *
95  * Description      Open L2CAP channel to peer
96  *
97  *
98  * Returns          Nothing.
99  *
100  ******************************************************************************/
101 void avct_bcb_chnl_open(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
102   uint16_t result = AVCT_RESULT_FAIL;
103   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
104   tL2CAP_ERTM_INFO ertm_info;
105
106   BTM_SetOutService(p_lcb->peer_addr, BTM_SEC_SERVICE_AVCTP_BROWSE, 0);
107
108   /* Set the FCR options: Browsing channel mandates ERTM */
109   ertm_info.preferred_mode = avct_l2c_br_fcr_opts_def.mode;
110   ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_ERTM;
111   ertm_info.user_rx_buf_size = BT_DEFAULT_BUFFER_SIZE;
112   ertm_info.user_tx_buf_size = BT_DEFAULT_BUFFER_SIZE;
113   ertm_info.fcr_rx_buf_size = BT_DEFAULT_BUFFER_SIZE;
114   ertm_info.fcr_tx_buf_size = BT_DEFAULT_BUFFER_SIZE;
115
116   /* call l2cap connect req */
117   p_bcb->ch_state = AVCT_CH_CONN;
118   p_bcb->ch_lcid =
119       L2CA_ErtmConnectReq(AVCT_BR_PSM, p_lcb->peer_addr, &ertm_info);
120   if (p_bcb->ch_lcid == 0) {
121     /* if connect req failed, send ourselves close event */
122     tAVCT_LCB_EVT avct_lcb_evt;
123     avct_lcb_evt.result = result;
124     avct_bcb_event(p_bcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
125   }
126 }
127
128 /*******************************************************************************
129  *
130  * Function         avct_bcb_unbind_disc
131  *
132  * Description      call callback with disconnect event.
133  *
134  *
135  * Returns          Nothing.
136  *
137  ******************************************************************************/
138 void avct_bcb_unbind_disc(UNUSED_ATTR tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
139   p_data->p_ccb->p_bcb = NULL;
140   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
141                                     AVCT_BROWSE_DISCONN_CFM_EVT, 0, NULL);
142 }
143
144 /*******************************************************************************
145  *
146  * Function         avct_bcb_open_ind
147  *
148  * Description      Handle an LL_OPEN event.
149  *                  For the allocated ccb already bound to the bcb, send a
150  *                  connect event. For the unbound ccb with a new PID, bind that
151  *                  ccb to the bcb with the same bd_addr and send a connect
152  *                  event.
153  *
154  *
155  * Returns          Nothing.
156  *
157  ******************************************************************************/
158 void avct_bcb_open_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
159   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
160   tAVCT_CCB* p_ccb_bind = NULL;
161   bool bind = false;
162   tAVCT_UL_MSG ul_msg;
163
164   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
165     /* if ccb allocated and */
166     if (p_ccb->allocated) {
167       /* if bound to this bcb send connect confirm event */
168       if (p_ccb->p_bcb == p_bcb) {
169         bind = true;
170         p_ccb_bind = p_ccb;
171         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_CFM_EVT,
172                                0, &p_ccb->p_lcb->peer_addr);
173       }
174       /* if unbound acceptor and lcb allocated and bd_addr are the same for bcb
175          and lcb */
176       else if ((p_ccb->p_bcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
177                (p_ccb->p_lcb != NULL) &&
178                p_bcb->peer_addr == p_ccb->p_lcb->peer_addr) {
179         /* bind bcb to ccb and send connect ind event */
180         bind = true;
181         p_ccb_bind = p_ccb;
182         p_ccb->p_bcb = p_bcb;
183         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_IND_EVT,
184                                0, &p_ccb->p_lcb->peer_addr);
185       }
186     }
187   }
188
189   /* if no ccbs bound to this lcb, disconnect */
190   if (bind == false) {
191     avct_bcb_event(p_bcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
192     return;
193   }
194
195   if (!p_bcb->p_tx_msg || !p_ccb_bind) {
196     return;
197   }
198
199   ul_msg.p_buf = p_bcb->p_tx_msg;
200   ul_msg.p_ccb = p_ccb_bind;
201   ul_msg.label = (uint8_t)(p_bcb->p_tx_msg->layer_specific & 0xFF);
202   ul_msg.cr = (uint8_t)((p_bcb->p_tx_msg->layer_specific & 0xFF00) >> 8);
203   p_bcb->p_tx_msg->layer_specific = AVCT_DATA_BROWSE;
204   p_bcb->p_tx_msg = NULL;
205
206   /* send msg event to bcb */
207   tAVCT_LCB_EVT avct_lcb_evt;
208   avct_lcb_evt.ul_msg = ul_msg;
209   avct_bcb_event(p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
210 }
211
212 /*******************************************************************************
213  *
214  * Function         avct_bcb_open_fail
215  *
216  * Description      L2CAP channel open attempt failed.  Mark the ccbs
217  *                  as NULL bcb.
218  *
219  *
220  * Returns          Nothing.
221  *
222  ******************************************************************************/
223 void avct_bcb_open_fail(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
224   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
225
226   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
227     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
228       p_ccb->p_bcb = NULL;
229     }
230   }
231 }
232
233 /*******************************************************************************
234  *
235  * Function         avct_bcb_close_ind
236  *
237  * Description      L2CAP channel closed by peer.  Deallocate any initiator
238  *                  ccbs on this lcb and send disconnect ind event.
239  *
240  *
241  * Returns          Nothing.
242  *
243  ******************************************************************************/
244 void avct_bcb_close_ind(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
245   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
246   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
247
248   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
249     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
250       if (p_ccb->cc.role == AVCT_INT) {
251         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
252                                   AVCT_BROWSE_DISCONN_CFM_EVT, 0,
253                                   &p_lcb->peer_addr);
254       } else {
255         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
256                                   AVCT_BROWSE_DISCONN_IND_EVT, 0, NULL);
257       }
258       p_ccb->p_bcb = NULL;
259     }
260   }
261 }
262
263 /*******************************************************************************
264  *
265  * Function         avct_bcb_close_cfm
266  *
267  * Description      L2CAP channel closed by us.  Deallocate any initiator
268  *                  ccbs on this lcb and send disconnect ind or cfm event.
269  *
270  *
271  * Returns          Nothing.
272  *
273  ******************************************************************************/
274 void avct_bcb_close_cfm(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
275   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
276   uint8_t event = 0;
277   /* Whether BCB initiated channel close */
278   bool ch_close = p_bcb->ch_close;
279   tAVCT_CTRL_CBACK* p_cback;
280
281   p_bcb->ch_close = false;
282   p_bcb->allocated = 0;
283   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
284     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
285       /* if this ccb initiated close send disconnect cfm otherwise ind */
286       if (ch_close) {
287         event = AVCT_BROWSE_DISCONN_CFM_EVT;
288       } else {
289         event = AVCT_BROWSE_DISCONN_IND_EVT;
290       }
291
292       p_cback = p_ccb->cc.p_ctrl_cback;
293       p_ccb->p_bcb = NULL;
294       if (p_ccb->p_lcb == NULL) avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
295       (*p_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result,
296                  &p_bcb->peer_addr);
297     }
298   }
299 }
300
301 /*******************************************************************************
302  *
303  * Function         avct_bcb_bind_conn
304  *
305  * Description      Bind ccb to lcb and send connect cfm event.
306  *
307  *
308  * Returns          Nothing.
309  *
310  ******************************************************************************/
311 void avct_bcb_bind_conn(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
312   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
313   p_data->p_ccb->p_bcb = p_bcb;
314   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
315                                     AVCT_BROWSE_CONN_CFM_EVT, 0,
316                                     &p_lcb->peer_addr);
317 }
318
319 /*******************************************************************************
320  *
321  * Function         avct_bcb_chk_disc
322  *
323  * Description      A ccb wants to close; if it is the last ccb on this lcb,
324  *                  close channel.  Otherwise just deallocate and call
325  *                  callback.
326  *
327  *
328  * Returns          Nothing.
329  *
330  ******************************************************************************/
331 void avct_bcb_chk_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
332   p_bcb->ch_close = avct_bcb_get_last_ccb_index(p_bcb, p_data->p_ccb);
333   if (p_bcb->ch_close) {
334     avct_bcb_event(p_bcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
335     return;
336   }
337
338   avct_bcb_unbind_disc(p_bcb, p_data);
339 }
340
341 /*******************************************************************************
342  *
343  * Function         avct_bcb_chnl_disc
344  *
345  * Description      Disconnect L2CAP channel.
346  *
347  *
348  * Returns          Nothing.
349  *
350  ******************************************************************************/
351 void avct_bcb_chnl_disc(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
352   L2CA_DisconnectReq(p_bcb->ch_lcid);
353 }
354
355 /*******************************************************************************
356  *
357  * Function         avct_bcb_bind_fail
358  *
359  * Description      Deallocate ccb and call callback with connect event
360  *                  with failure result.
361  *
362  *
363  * Returns          Nothing.
364  *
365  ******************************************************************************/
366 void avct_bcb_bind_fail(UNUSED_ATTR tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
367   p_data->p_ccb->p_bcb = NULL;
368   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
369                                     AVCT_BROWSE_CONN_CFM_EVT, AVCT_RESULT_FAIL,
370                                     NULL);
371 }
372
373 /*******************************************************************************
374  *
375  * Function         avct_bcb_cong_ind
376  *
377  * Description      Handle congestion indication from L2CAP.
378  *
379  *
380  * Returns          Nothing.
381  *
382  ******************************************************************************/
383 void avct_bcb_cong_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
384   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
385   uint8_t event;
386   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
387
388   /* set event */
389   event =
390       (p_data->cong) ? AVCT_BROWSE_CONG_IND_EVT : AVCT_BROWSE_UNCONG_IND_EVT;
391
392   /* send event to all ccbs on this lcb */
393   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
394     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
395       (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0,
396                                 &p_lcb->peer_addr);
397     }
398   }
399 }
400
401 /*******************************************************************************
402  *
403  * Function         avct_bcb_discard_msg
404  *
405  * Description      Discard a message sent in from the API.
406  *
407  *
408  * Returns          Nothing.
409  *
410  ******************************************************************************/
411 void avct_bcb_discard_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
412   osi_free_and_reset((void**)&p_bcb->p_tx_msg);
413
414   /* if control channel is up, save the message and open the browsing channel */
415   if (p_data->ul_msg.p_ccb->p_lcb == NULL) {
416     osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
417     return;
418   }
419   p_bcb->p_tx_msg = p_data->ul_msg.p_buf;
420
421   if (p_bcb->p_tx_msg) {
422     p_bcb->p_tx_msg->layer_specific =
423         (p_data->ul_msg.cr << 8) + p_data->ul_msg.label;
424
425     /* the channel is closed, opening or closing - open it again */
426     AVCT_TRACE_DEBUG("ch_state: %d, allocated:%d->%d", p_bcb->ch_state,
427                      p_bcb->allocated, p_data->ul_msg.p_ccb->p_lcb->allocated);
428     p_bcb->allocated = p_data->ul_msg.p_ccb->p_lcb->allocated;
429     avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT,
430                    (tAVCT_LCB_EVT*)p_data->ul_msg.p_ccb);
431   }
432 }
433
434 /*******************************************************************************
435  *
436  * Function         avct_bcb_send_msg
437  *
438  * Description      Build and send an AVCTP message.
439  *
440  *
441  * Returns          Nothing.
442  *
443  ******************************************************************************/
444 void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
445   uint16_t curr_msg_len;
446   uint8_t pkt_type = AVCT_PKT_TYPE_SINGLE;
447   uint8_t hdr_len;
448   BT_HDR* p_buf;
449   uint8_t* p;
450
451   /* store msg len */
452   curr_msg_len = p_data->ul_msg.p_buf->len;
453
454   /* initialize packet type and other stuff */
455   if (curr_msg_len > (p_bcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) {
456     AVCT_TRACE_ERROR("%s msg len (%d) exceeds peer mtu(%d-%d)!!", __func__,
457                      curr_msg_len, p_bcb->peer_mtu, AVCT_HDR_LEN_SINGLE);
458     osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
459     return;
460   }
461
462   /* set header len */
463   hdr_len = avct_lcb_pkt_type_len[pkt_type];
464   p_buf = p_data->ul_msg.p_buf;
465
466   /* set up to build header */
467   p_buf->len += hdr_len;
468   p_buf->offset -= hdr_len;
469   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
470
471   /* build header */
472   AVCT_BUILD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr);
473   UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid);
474
475   p_buf->layer_specific = AVCT_DATA_BROWSE;
476
477   /* send message to L2CAP */
478   L2CA_DataWrite(p_bcb->ch_lcid, p_buf);
479 }
480
481 /*******************************************************************************
482  *
483  * Function         avct_bcb_free_msg_ind
484  *
485  * Description      Discard an incoming AVCTP message.
486  *
487  *
488  * Returns          Nothing.
489  *
490  ******************************************************************************/
491 void avct_bcb_free_msg_ind(UNUSED_ATTR tAVCT_BCB* p_bcb,
492                            tAVCT_LCB_EVT* p_data) {
493   if (p_data) osi_free_and_reset((void**)&p_data->p_buf);
494 }
495
496 /*******************************************************************************
497  *
498  * Function         avct_bcb_msg_ind
499  *
500  * Description      Handle an incoming AVCTP message.
501  *
502  *
503  * Returns          Nothing.
504  *
505  ******************************************************************************/
506 void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
507   uint8_t* p;
508   uint8_t label, type, cr_ipid;
509   uint16_t pid;
510   tAVCT_CCB* p_ccb;
511   tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
512
513   if ((p_data == NULL) || (p_data->p_buf == NULL)) {
514     AVCT_TRACE_WARNING("%s p_data is NULL, returning!", __func__);
515     return;
516   }
517
518   /* this p_buf is to be reported through p_msg_cback. The layer_specific
519    * needs to be set properly to indicate that it is received through
520    * browsing channel */
521   p_data->p_buf->layer_specific = AVCT_DATA_BROWSE;
522
523   /* reassemble message; if no message available (we received a fragment) return
524    */
525   p_data->p_buf = avct_bcb_msg_asmbl(p_bcb, p_data->p_buf);
526   if (p_data->p_buf == NULL) {
527     return;
528   }
529
530   if (p_data->p_buf->len < AVCT_HDR_LEN_SINGLE) {
531     AVCT_TRACE_WARNING("Invalid AVCTP packet length %d: must be at least %d",
532                        p_data->p_buf->len, AVCT_HDR_LEN_SINGLE);
533     osi_free_and_reset((void**)&p_data->p_buf);
534     android_errorWriteLog(0x534e4554, "79944113");
535     return;
536   }
537
538   p = (uint8_t*)(p_data->p_buf + 1) + p_data->p_buf->offset;
539
540   /* parse header byte */
541   AVCT_PARSE_HDR(p, label, type, cr_ipid);
542
543   /* check for invalid cr_ipid */
544   if (cr_ipid == AVCT_CR_IPID_INVALID) {
545     AVCT_TRACE_WARNING("Invalid cr_ipid", cr_ipid);
546     osi_free_and_reset((void**)&p_data->p_buf);
547     return;
548   }
549
550   /* parse and lookup PID */
551   BE_STREAM_TO_UINT16(pid, p);
552   p_ccb = avct_lcb_has_pid(p_lcb, pid);
553   if (p_ccb) {
554     /* PID found; send msg up, adjust bt hdr and call msg callback */
555     p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE;
556     p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE;
557     (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid,
558                              p_data->p_buf);
559     return;
560   }
561
562   /* PID not found; drop message */
563   AVCT_TRACE_WARNING("No ccb for PID=%x", pid);
564   osi_free_and_reset((void**)&p_data->p_buf);
565
566   /* if command send reject */
567   if (cr_ipid == AVCT_CMD) {
568     BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVRC_CMD_BUF_SIZE);
569     p_buf->len = AVCT_HDR_LEN_SINGLE;
570     p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE;
571     p = (uint8_t*)(p_buf + 1) + p_buf->offset;
572     AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ);
573     UINT16_TO_BE_STREAM(p, pid);
574     p_buf->layer_specific = AVCT_DATA_BROWSE;
575     L2CA_DataWrite(p_bcb->ch_lcid, p_buf);
576   }
577 }
578
579 /*******************************************************************************
580  *
581  * Function         avct_bcb_dealloc
582  *
583  * Description      Deallocate a browse control block.
584  *
585  *
586  * Returns          void.
587  *
588  ******************************************************************************/
589 void avct_bcb_dealloc(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) {
590   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
591
592   AVCT_TRACE_DEBUG("%s %d", __func__, p_bcb->allocated);
593
594   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
595     /* if ccb allocated and */
596     if ((p_ccb->allocated) && (p_ccb->p_bcb == p_bcb)) {
597       p_ccb->p_bcb = NULL;
598       AVCT_TRACE_DEBUG("%s used by ccb: %d", __func__, idx);
599       break;
600     }
601   }
602
603   /* the browsing channel is down. Check if we have pending messages */
604   osi_free_and_reset((void**)&p_bcb->p_tx_msg);
605   memset(p_bcb, 0, sizeof(tAVCT_BCB));
606 }
607
608 /*******************************************************************************
609  *
610  * Function         avct_close_bcb
611  *
612  * Description      this function is called right before LCB disconnects.
613  *
614  *
615  * Returns          Nothing.
616  *
617  ******************************************************************************/
618 void avct_close_bcb(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
619   tAVCT_BCB* p_bcb = avct_bcb_by_lcb(p_lcb);
620   if (p_bcb->allocated) {
621     avct_bcb_event(p_bcb, AVCT_LCB_UL_UNBIND_EVT, p_data);
622   }
623 }
624
625 /*******************************************************************************
626  *
627  * Function         avct_lcb_by_bcb
628  *
629  * Description      This lookup function finds the lcb for a bcb.
630  *
631  * Returns          pointer to the lcb.
632  *
633  ******************************************************************************/
634 tAVCT_LCB* avct_lcb_by_bcb(tAVCT_BCB* p_bcb) {
635   return &avct_cb.lcb[p_bcb->allocated - 1];
636 }
637
638 /*******************************************************************************
639  *
640  * Function         avct_bcb_by_lcb
641  *
642  * Description      This lookup function finds the bcb for a lcb.
643  *
644  * Returns          pointer to the lcb.
645  *
646  ******************************************************************************/
647 tAVCT_BCB* avct_bcb_by_lcb(tAVCT_LCB* p_lcb) {
648   return &avct_cb.bcb[p_lcb->allocated - 1];
649 }
650
651 /*******************************************************************************
652  *
653  * Function         avct_bcb_get_last_ccb_index
654  *
655  * Description      See if given ccb is only one on the bcb.
656  *
657  *
658  * Returns          0, if ccb is last,  (ccb index + 1) otherwise.
659  *
660  ******************************************************************************/
661 uint8_t avct_bcb_get_last_ccb_index(tAVCT_BCB* p_bcb, tAVCT_CCB* p_ccb_last) {
662   tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
663   uint8_t idx = 0;
664
665   for (int i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
666     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
667       if (p_ccb != p_ccb_last) return 0;
668       idx = (uint8_t)(i + 1);
669     }
670   }
671   return idx;
672 }
673
674 /*******************************************************************************
675  *
676  * Function         avct_bcb_by_lcid
677  *
678  * Description      Find the BCB associated with the L2CAP LCID
679  *
680  *
681  * Returns          pointer to the lcb, or NULL if none found.
682  *
683  ******************************************************************************/
684 tAVCT_BCB* avct_bcb_by_lcid(uint16_t lcid) {
685   tAVCT_BCB* p_bcb = &avct_cb.bcb[0];
686   int idx;
687
688   for (idx = 0; idx < AVCT_NUM_LINKS; idx++, p_bcb++) {
689     if (p_bcb->allocated && (p_bcb->ch_lcid == lcid)) {
690       return p_bcb;
691     }
692   }
693
694   /* out of lcbs */
695   AVCT_TRACE_WARNING("No bcb for lcid %x", lcid);
696   return NULL;
697 }