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