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