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 ******************************************************************************/ 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 ******************************************************************************/ 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 = avct_l2c_br_fcr_opts_def.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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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