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