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