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 <bluetooth/log.h>
31 #include <string.h>
32
33 #include "avct_api.h"
34 #include "avct_int.h"
35 #include "bta/include/bta_sec_api.h"
36 #include "btif/include/btif_av.h"
37 #include "internal_include/bt_target.h"
38 #include "osi/include/allocator.h"
39 #include "osi/include/osi.h"
40 #include "stack/avct/avct_defs.h"
41 #include "stack/include/bt_hdr.h"
42 #include "stack/include/bt_types.h"
43
44 using namespace bluetooth;
45
46 /* action function list */
47 const tAVCT_BCB_ACTION avct_bcb_action[] = {
48 avct_bcb_chnl_open, /* AVCT_LCB_CHNL_OPEN */
49 avct_bcb_chnl_disc, /* AVCT_LCB_CHNL_DISC */
50 avct_bcb_send_msg, /* AVCT_LCB_SEND_MSG */
51 avct_bcb_open_ind, /* AVCT_LCB_OPEN_IND */
52 avct_bcb_open_fail, /* AVCT_LCB_OPEN_FAIL */
53 avct_bcb_close_ind, /* AVCT_LCB_CLOSE_IND */
54 avct_bcb_close_cfm, /* AVCT_LCB_CLOSE_CFM */
55 avct_bcb_msg_ind, /* AVCT_LCB_MSG_IND */
56 avct_bcb_cong_ind, /* AVCT_LCB_CONG_IND */
57 avct_bcb_bind_conn, /* AVCT_LCB_BIND_CONN */
58 avct_bcb_bind_fail, /* AVCT_LCB_BIND_FAIL */
59 avct_bcb_unbind_disc, /* AVCT_LCB_UNBIND_DISC */
60 avct_bcb_chk_disc, /* AVCT_LCB_CHK_DISC */
61 avct_bcb_discard_msg, /* AVCT_LCB_DISCARD_MSG */
62 avct_bcb_dealloc, /* AVCT_LCB_DEALLOC */
63 avct_bcb_free_msg_ind /* AVCT_LCB_FREE_MSG_IND */
64 };
65
66 /*******************************************************************************
67 *
68 * Function avct_bcb_msg_asmbl
69 *
70 * Description Reassemble incoming message.
71 *
72 *
73 * Returns Pointer to reassembled message; NULL if no message
74 * available.
75 *
76 ******************************************************************************/
avct_bcb_msg_asmbl(tAVCT_BCB *,BT_HDR * p_buf)77 static BT_HDR* avct_bcb_msg_asmbl(tAVCT_BCB* /* p_bcb */, BT_HDR* p_buf) {
78 uint8_t* p;
79 uint8_t pkt_type;
80
81 if (p_buf->len == 0) {
82 osi_free_and_reset((void**)&p_buf);
83 return nullptr;
84 }
85
86 /* parse the message header */
87 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
88 pkt_type = AVCT_PKT_TYPE(p);
89
90 /* must be single packet - can not fragment */
91 if (pkt_type != AVCT_PKT_TYPE_SINGLE) {
92 osi_free_and_reset((void**)&p_buf);
93 log::warn("Pkt type={} - fragmentation not allowed. drop it", pkt_type);
94 }
95 return p_buf;
96 }
97
98 /*******************************************************************************
99 *
100 * Function avct_bcb_chnl_open
101 *
102 * Description Open L2CAP channel to peer
103 *
104 *
105 * Returns Nothing.
106 *
107 ******************************************************************************/
avct_bcb_chnl_open(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT *)108 void avct_bcb_chnl_open(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* /* p_data */) {
109 uint16_t result = AVCT_RESULT_FAIL;
110 tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
111 tL2CAP_ERTM_INFO ertm_info;
112
113 /* Set the FCR options: Browsing channel mandates ERTM */
114 ertm_info.preferred_mode = L2CAP_FCR_ERTM_MODE;
115
116 /* call l2cap connect req */
117 p_bcb->ch_state = AVCT_CH_CONN;
118 p_bcb->ch_lcid = L2CA_ConnectReqWithSecurity(AVCT_BR_PSM, p_lcb->peer_addr,
119 BTA_SEC_AUTHENTICATE);
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 ******************************************************************************/
avct_bcb_unbind_disc(tAVCT_BCB *,tAVCT_LCB_EVT * p_data)138 void avct_bcb_unbind_disc(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 ******************************************************************************/
avct_bcb_open_ind(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT * p_data)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) {
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 ******************************************************************************/
avct_bcb_open_fail(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT *)223 void avct_bcb_open_fail(tAVCT_BCB* p_bcb, 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 ******************************************************************************/
avct_bcb_close_ind(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT *)244 void avct_bcb_close_ind(tAVCT_BCB* p_bcb, 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,
257 &p_lcb->peer_addr);
258 }
259 p_ccb->p_bcb = NULL;
260 }
261 }
262 }
263
264 /*******************************************************************************
265 *
266 * Function avct_bcb_close_cfm
267 *
268 * Description L2CAP channel closed by us. Deallocate any initiator
269 * ccbs on this lcb and send disconnect ind or cfm event.
270 *
271 *
272 * Returns Nothing.
273 *
274 ******************************************************************************/
avct_bcb_close_cfm(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT * p_data)275 void avct_bcb_close_cfm(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
276 tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
277 uint8_t event = 0;
278 /* Whether BCB initiated channel close */
279 bool ch_close = p_bcb->ch_close;
280 tAVCT_CTRL_CBACK* p_cback;
281
282 p_bcb->ch_close = false;
283 p_bcb->allocated = 0;
284 for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
285 if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
286 /* if this ccb initiated close send disconnect cfm otherwise ind */
287 if (ch_close) {
288 event = AVCT_BROWSE_DISCONN_CFM_EVT;
289 } else {
290 event = AVCT_BROWSE_DISCONN_IND_EVT;
291 }
292
293 p_cback = p_ccb->cc.p_ctrl_cback;
294 p_ccb->p_bcb = NULL;
295 if (p_ccb->p_lcb == NULL) avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
296 (*p_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result,
297 &p_bcb->peer_addr);
298 }
299 }
300 }
301
302 /*******************************************************************************
303 *
304 * Function avct_bcb_bind_conn
305 *
306 * Description Bind ccb to lcb and send connect cfm event.
307 *
308 *
309 * Returns Nothing.
310 *
311 ******************************************************************************/
avct_bcb_bind_conn(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT * p_data)312 void avct_bcb_bind_conn(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
313 tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
314 p_data->p_ccb->p_bcb = p_bcb;
315 (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
316 AVCT_BROWSE_CONN_CFM_EVT, 0,
317 &p_lcb->peer_addr);
318 }
319
320 /*******************************************************************************
321 *
322 * Function avct_bcb_chk_disc
323 *
324 * Description A ccb wants to close; if it is the last ccb on this lcb,
325 * close channel. Otherwise just deallocate and call
326 * callback.
327 *
328 *
329 * Returns Nothing.
330 *
331 ******************************************************************************/
avct_bcb_chk_disc(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT * p_data)332 void avct_bcb_chk_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
333 p_bcb->ch_close = avct_bcb_get_last_ccb_index(p_bcb, p_data->p_ccb);
334 if (p_bcb->ch_close) {
335 avct_bcb_event(p_bcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
336 return;
337 }
338
339 avct_bcb_unbind_disc(p_bcb, p_data);
340 }
341
342 /*******************************************************************************
343 *
344 * Function avct_bcb_chnl_disc
345 *
346 * Description Disconnect L2CAP channel.
347 *
348 *
349 * Returns Nothing.
350 *
351 ******************************************************************************/
avct_bcb_chnl_disc(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT *)352 void avct_bcb_chnl_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* /* p_data */) {
353 avct_l2c_br_disconnect(p_bcb->ch_lcid, 0);
354 }
355
356 /*******************************************************************************
357 *
358 * Function avct_bcb_bind_fail
359 *
360 * Description Deallocate ccb and call callback with connect event
361 * with failure result.
362 *
363 *
364 * Returns Nothing.
365 *
366 ******************************************************************************/
avct_bcb_bind_fail(tAVCT_BCB *,tAVCT_LCB_EVT * p_data)367 void avct_bcb_bind_fail(tAVCT_BCB* /* p_bcb */, tAVCT_LCB_EVT* p_data) {
368 p_data->p_ccb->p_bcb = NULL;
369 (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
370 AVCT_BROWSE_CONN_CFM_EVT, AVCT_RESULT_FAIL,
371 NULL);
372 }
373
374 /*******************************************************************************
375 *
376 * Function avct_bcb_cong_ind
377 *
378 * Description Handle congestion indication from L2CAP.
379 *
380 *
381 * Returns Nothing.
382 *
383 ******************************************************************************/
avct_bcb_cong_ind(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT * p_data)384 void avct_bcb_cong_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
385 tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
386 uint8_t event;
387 tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
388
389 /* set event */
390 event =
391 (p_data->cong) ? AVCT_BROWSE_CONG_IND_EVT : AVCT_BROWSE_UNCONG_IND_EVT;
392
393 /* send event to all ccbs on this lcb */
394 for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
395 if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
396 (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0,
397 &p_lcb->peer_addr);
398 }
399 }
400 }
401
402 /*******************************************************************************
403 *
404 * Function avct_bcb_discard_msg
405 *
406 * Description Discard a message sent in from the API.
407 *
408 *
409 * Returns Nothing.
410 *
411 ******************************************************************************/
avct_bcb_discard_msg(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT * p_data)412 void avct_bcb_discard_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
413 osi_free_and_reset((void**)&p_bcb->p_tx_msg);
414
415 /* if control channel is up, save the message and open the browsing channel */
416 if (p_data->ul_msg.p_ccb->p_lcb == NULL) {
417 osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
418 return;
419 }
420 p_bcb->p_tx_msg = p_data->ul_msg.p_buf;
421
422 if (p_bcb->p_tx_msg) {
423 p_bcb->p_tx_msg->layer_specific =
424 (p_data->ul_msg.cr << 8) + p_data->ul_msg.label;
425
426 /* the channel is closed, opening or closing - open it again */
427 log::verbose("ch_state: {}, allocated:{}->{}", p_bcb->ch_state,
428 p_bcb->allocated, p_data->ul_msg.p_ccb->p_lcb->allocated);
429 p_bcb->allocated = p_data->ul_msg.p_ccb->p_lcb->allocated;
430 avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT,
431 (tAVCT_LCB_EVT*)p_data->ul_msg.p_ccb);
432 }
433 }
434
435 /*******************************************************************************
436 *
437 * Function avct_bcb_send_msg
438 *
439 * Description Build and send an AVCTP message.
440 *
441 *
442 * Returns Nothing.
443 *
444 ******************************************************************************/
avct_bcb_send_msg(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT * p_data)445 void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
446 uint16_t curr_msg_len;
447 uint8_t pkt_type = AVCT_PKT_TYPE_SINGLE;
448 uint8_t hdr_len;
449 BT_HDR* p_buf;
450 uint8_t* p;
451
452 /* store msg len */
453 curr_msg_len = p_data->ul_msg.p_buf->len;
454
455 /* initialize packet type and other stuff */
456 if (curr_msg_len > (p_bcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) {
457 log::error("msg len ({}) exceeds peer mtu({}-{})!!", curr_msg_len,
458 p_bcb->peer_mtu, AVCT_HDR_LEN_SINGLE);
459 osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
460 return;
461 }
462
463 /* set header len */
464 hdr_len = avct_lcb_pkt_type_len[pkt_type];
465 p_buf = p_data->ul_msg.p_buf;
466
467 /* set up to build header */
468 p_buf->len += hdr_len;
469 p_buf->offset -= hdr_len;
470 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
471
472 /* build header */
473 AVCT_BUILD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr);
474 UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid);
475
476 p_buf->layer_specific = AVCT_DATA_BROWSE;
477
478 /* send message to L2CAP */
479 if (L2CA_DataWrite(p_bcb->ch_lcid, p_buf) != L2CAP_DW_SUCCESS) {
480 log::warn("Unable to write L2CAP data peer:{} cid:{}", p_bcb->peer_addr,
481 p_bcb->ch_lcid);
482 }
483 }
484
485 /*******************************************************************************
486 *
487 * Function avct_bcb_free_msg_ind
488 *
489 * Description Discard an incoming AVCTP message.
490 *
491 *
492 * Returns Nothing.
493 *
494 ******************************************************************************/
avct_bcb_free_msg_ind(tAVCT_BCB *,tAVCT_LCB_EVT * p_data)495 void avct_bcb_free_msg_ind(tAVCT_BCB* /* p_bcb */, tAVCT_LCB_EVT* p_data) {
496 if (p_data) osi_free_and_reset((void**)&p_data->p_buf);
497 }
498
499 /*******************************************************************************
500 *
501 * Function avct_bcb_msg_ind
502 *
503 * Description Handle an incoming AVCTP message.
504 *
505 *
506 * Returns Nothing.
507 *
508 ******************************************************************************/
avct_bcb_msg_ind(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT * p_data)509 void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
510 uint8_t* p;
511 uint8_t label, type, cr_ipid;
512 uint16_t pid;
513 tAVCT_CCB* p_ccb;
514 tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
515
516 if ((p_data == NULL) || (p_data->p_buf == NULL)) {
517 log::warn("p_data is NULL, returning!");
518 return;
519 }
520
521 /* this p_buf is to be reported through p_msg_cback. The layer_specific
522 * needs to be set properly to indicate that it is received through
523 * browsing channel */
524 p_data->p_buf->layer_specific = AVCT_DATA_BROWSE;
525
526 /* reassemble message; if no message available (we received a fragment) return
527 */
528 p_data->p_buf = avct_bcb_msg_asmbl(p_bcb, p_data->p_buf);
529 if (p_data->p_buf == NULL) {
530 return;
531 }
532
533 if (p_data->p_buf->len < AVCT_HDR_LEN_SINGLE) {
534 log::warn("Invalid AVCTP packet length {}: must be at least {}",
535 p_data->p_buf->len, AVCT_HDR_LEN_SINGLE);
536 osi_free_and_reset((void**)&p_data->p_buf);
537 return;
538 }
539
540 p = (uint8_t*)(p_data->p_buf + 1) + p_data->p_buf->offset;
541
542 /* parse header byte */
543 AVCT_PARSE_HDR(p, label, type, cr_ipid);
544 /* parse PID */
545 BE_STREAM_TO_UINT16(pid, p);
546
547 /* check for invalid cr_ipid */
548 if (cr_ipid == AVCT_CR_IPID_INVALID) {
549 log::warn("Invalid cr_ipid {}", cr_ipid);
550 osi_free_and_reset((void**)&p_data->p_buf);
551 return;
552 }
553
554 bool bind = false;
555 if (btif_av_src_sink_coexist_enabled()) {
556 bind = avct_msg_ind_for_src_sink_coexist(p_lcb, p_data, label, cr_ipid);
557 osi_free_and_reset((void**)&p_data->p_buf);
558 if (bind) return;
559 } else {
560 /* lookup PID */
561 p_ccb = avct_lcb_has_pid(p_lcb, pid);
562 if (p_ccb) {
563 /* PID found; send msg up, adjust bt hdr and call msg callback */
564 p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE;
565 p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE;
566 (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid,
567 p_data->p_buf);
568 return;
569 }
570 }
571
572 /* PID not found; drop message */
573 log::warn("No ccb for PID={:x}", pid);
574 osi_free_and_reset((void**)&p_data->p_buf);
575
576 /* if command send reject */
577 if (cr_ipid == AVCT_CMD) {
578 BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVRC_CMD_BUF_SIZE);
579 p_buf->len = AVCT_HDR_LEN_SINGLE;
580 p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE;
581 p = (uint8_t*)(p_buf + 1) + p_buf->offset;
582 AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ);
583 UINT16_TO_BE_STREAM(p, pid);
584 p_buf->layer_specific = AVCT_DATA_BROWSE;
585 if (L2CA_DataWrite(p_bcb->ch_lcid, p_buf) != L2CAP_DW_SUCCESS) {
586 log::warn("Unable to write L2CAP data peer:{} cid:{}", p_bcb->peer_addr,
587 p_bcb->ch_lcid);
588 }
589 }
590 }
591
592 /*******************************************************************************
593 *
594 * Function avct_bcb_dealloc
595 *
596 * Description Deallocate a browse control block.
597 *
598 *
599 * Returns void.
600 *
601 ******************************************************************************/
avct_bcb_dealloc(tAVCT_BCB * p_bcb,tAVCT_LCB_EVT *)602 void avct_bcb_dealloc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* /* p_data */) {
603 tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
604
605 log::verbose("{}", p_bcb->allocated);
606
607 for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
608 /* if ccb allocated and */
609 if ((p_ccb->allocated) && (p_ccb->p_bcb == p_bcb)) {
610 p_ccb->p_bcb = NULL;
611 log::verbose("used by ccb: {}", idx);
612 break;
613 }
614 }
615
616 /* the browsing channel is down. Check if we have pending messages */
617 osi_free_and_reset((void**)&p_bcb->p_tx_msg);
618 memset(p_bcb, 0, sizeof(tAVCT_BCB));
619 }
620
621 /*******************************************************************************
622 *
623 * Function avct_close_bcb
624 *
625 * Description this function is called right before LCB disconnects.
626 *
627 *
628 * Returns Nothing.
629 *
630 ******************************************************************************/
avct_close_bcb(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)631 void avct_close_bcb(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
632 tAVCT_BCB* p_bcb = avct_bcb_by_lcb(p_lcb);
633 if (p_bcb->allocated) {
634 avct_bcb_event(p_bcb, AVCT_LCB_UL_UNBIND_EVT, p_data);
635 }
636 }
637
638 /*******************************************************************************
639 *
640 * Function avct_lcb_by_bcb
641 *
642 * Description This lookup function finds the lcb for a bcb.
643 *
644 * Returns pointer to the lcb.
645 *
646 ******************************************************************************/
avct_lcb_by_bcb(tAVCT_BCB * p_bcb)647 tAVCT_LCB* avct_lcb_by_bcb(tAVCT_BCB* p_bcb) {
648 return &avct_cb.lcb[p_bcb->allocated - 1];
649 }
650
651 /*******************************************************************************
652 *
653 * Function avct_bcb_by_lcb
654 *
655 * Description This lookup function finds the bcb for a lcb.
656 *
657 * Returns pointer to the lcb.
658 *
659 ******************************************************************************/
avct_bcb_by_lcb(tAVCT_LCB * p_lcb)660 tAVCT_BCB* avct_bcb_by_lcb(tAVCT_LCB* p_lcb) {
661 return &avct_cb.bcb[p_lcb->allocated - 1];
662 }
663
664 /*******************************************************************************
665 *
666 * Function avct_bcb_get_last_ccb_index
667 *
668 * Description See if given ccb is only one on the bcb.
669 *
670 *
671 * Returns 0, if ccb is last, (ccb index + 1) otherwise.
672 *
673 ******************************************************************************/
avct_bcb_get_last_ccb_index(tAVCT_BCB * p_bcb,tAVCT_CCB * p_ccb_last)674 uint8_t avct_bcb_get_last_ccb_index(tAVCT_BCB* p_bcb, tAVCT_CCB* p_ccb_last) {
675 tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
676 uint8_t idx = 0;
677
678 for (int i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
679 if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
680 if (p_ccb != p_ccb_last) return 0;
681 idx = (uint8_t)(i + 1);
682 }
683 }
684 return idx;
685 }
686
687 /*******************************************************************************
688 *
689 * Function avct_bcb_by_lcid
690 *
691 * Description Find the BCB associated with the L2CAP LCID
692 *
693 *
694 * Returns pointer to the lcb, or NULL if none found.
695 *
696 ******************************************************************************/
avct_bcb_by_lcid(uint16_t lcid)697 tAVCT_BCB* avct_bcb_by_lcid(uint16_t lcid) {
698 tAVCT_BCB* p_bcb = &avct_cb.bcb[0];
699 int idx;
700
701 for (idx = 0; idx < AVCT_NUM_LINKS; idx++, p_bcb++) {
702 if (p_bcb->allocated &&
703 ((p_bcb->ch_lcid == lcid) || (p_bcb->conflict_lcid == lcid))) {
704 return p_bcb;
705 }
706 }
707
708 /* out of lcbs */
709 log::warn("No bcb for lcid {:x}", lcid);
710 return NULL;
711 }
712