OSDN Git Service

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