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