1 /****************************************************************************** 2 * 3 * Copyright 2003-2012 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 * This module contains action functions of the link control state machine. 22 * 23 ******************************************************************************/ 24 25 #include <string.h> 26 #include "avct_api.h" 27 #include "avct_int.h" 28 #include "bt_common.h" 29 #include "bt_target.h" 30 #include "bt_types.h" 31 #include "bt_utils.h" 32 #include "btm_api.h" 33 #include "osi/include/osi.h" 34 35 /* packet header length lookup table */ 36 const uint8_t avct_lcb_pkt_type_len[] = {AVCT_HDR_LEN_SINGLE, 37 AVCT_HDR_LEN_START, AVCT_HDR_LEN_CONT, 38 AVCT_HDR_LEN_END}; 39 40 /******************************************************************************* 41 * 42 * Function avct_lcb_msg_asmbl 43 * 44 * Description Reassemble incoming message. 45 * 46 * 47 * Returns Pointer to reassembled message; NULL if no message 48 * available. 49 * 50 ******************************************************************************/ 51 static BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) { 52 uint8_t* p; 53 uint8_t pkt_type; 54 BT_HDR* p_ret; 55 56 /* parse the message header */ 57 p = (uint8_t*)(p_buf + 1) + p_buf->offset; 58 pkt_type = AVCT_PKT_TYPE(p); 59 60 /* quick sanity check on length */ 61 if (p_buf->len < avct_lcb_pkt_type_len[pkt_type]) { 62 osi_free(p_buf); 63 AVCT_TRACE_WARNING("Bad length during reassembly"); 64 p_ret = NULL; 65 } 66 /* single packet */ 67 else if (pkt_type == AVCT_PKT_TYPE_SINGLE) { 68 /* if reassembly in progress drop message and process new single */ 69 if (p_lcb->p_rx_msg != NULL) 70 AVCT_TRACE_WARNING("Got single during reassembly"); 71 72 osi_free_and_reset((void**)&p_lcb->p_rx_msg); 73 74 p_ret = p_buf; 75 } 76 /* start packet */ 77 else if (pkt_type == AVCT_PKT_TYPE_START) { 78 /* if reassembly in progress drop message and process new start */ 79 if (p_lcb->p_rx_msg != NULL) 80 AVCT_TRACE_WARNING("Got start during reassembly"); 81 82 osi_free(p_lcb->p_rx_msg); 83 84 /* 85 * Allocate bigger buffer for reassembly. As lower layers are 86 * not aware of possible packet size after reassembly, they 87 * would have allocated smaller buffer. 88 */ 89 p_lcb->p_rx_msg = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE); 90 memcpy(p_lcb->p_rx_msg, p_buf, sizeof(BT_HDR) + p_buf->offset + p_buf->len); 91 92 /* Free original buffer */ 93 osi_free(p_buf); 94 95 /* update p to point to new buffer */ 96 p = (uint8_t*)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset; 97 98 /* copy first header byte over nosp */ 99 *(p + 1) = *p; 100 101 /* set offset to point to where to copy next */ 102 p_lcb->p_rx_msg->offset += p_lcb->p_rx_msg->len; 103 104 /* adjust length for packet header */ 105 p_lcb->p_rx_msg->len -= 1; 106 107 p_ret = NULL; 108 } 109 /* continue or end */ 110 else { 111 /* if no reassembly in progress drop message */ 112 if (p_lcb->p_rx_msg == NULL) { 113 osi_free(p_buf); 114 AVCT_TRACE_WARNING("Pkt type=%d out of order", pkt_type); 115 p_ret = NULL; 116 } else { 117 /* get size of buffer holding assembled message */ 118 /* 119 * NOTE: The buffer is allocated above at the beginning of the 120 * reassembly, and is always of size BT_DEFAULT_BUFFER_SIZE. 121 */ 122 uint16_t buf_len = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR); 123 124 /* adjust offset and len of fragment for header byte */ 125 p_buf->offset += AVCT_HDR_LEN_CONT; 126 p_buf->len -= AVCT_HDR_LEN_CONT; 127 128 /* verify length */ 129 if ((p_lcb->p_rx_msg->offset + p_buf->len) > buf_len) { 130 /* won't fit; free everything */ 131 AVCT_TRACE_WARNING("%s: Fragmented message too big!", __func__); 132 osi_free_and_reset((void**)&p_lcb->p_rx_msg); 133 osi_free(p_buf); 134 p_ret = NULL; 135 } else { 136 /* copy contents of p_buf to p_rx_msg */ 137 memcpy((uint8_t*)(p_lcb->p_rx_msg + 1) + p_lcb->p_rx_msg->offset, 138 (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len); 139 140 if (pkt_type == AVCT_PKT_TYPE_END) { 141 p_lcb->p_rx_msg->offset -= p_lcb->p_rx_msg->len; 142 p_lcb->p_rx_msg->len += p_buf->len; 143 p_ret = p_lcb->p_rx_msg; 144 p_lcb->p_rx_msg = NULL; 145 } else { 146 p_lcb->p_rx_msg->offset += p_buf->len; 147 p_lcb->p_rx_msg->len += p_buf->len; 148 p_ret = NULL; 149 } 150 osi_free(p_buf); 151 } 152 } 153 } 154 return p_ret; 155 } 156 157 /******************************************************************************* 158 * 159 * Function avct_lcb_chnl_open 160 * 161 * Description Open L2CAP channel to peer 162 * 163 * 164 * Returns Nothing. 165 * 166 ******************************************************************************/ 167 void avct_lcb_chnl_open(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { 168 uint16_t result = AVCT_RESULT_FAIL; 169 170 BTM_SetOutService(p_lcb->peer_addr, BTM_SEC_SERVICE_AVCTP, 0); 171 /* call l2cap connect req */ 172 p_lcb->ch_state = AVCT_CH_CONN; 173 p_lcb->ch_lcid = L2CA_ConnectReq(AVCT_PSM, p_lcb->peer_addr); 174 if (p_lcb->ch_lcid == 0) { 175 /* if connect req failed, send ourselves close event */ 176 tAVCT_LCB_EVT avct_lcb_evt; 177 avct_lcb_evt.result = result; 178 avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt); 179 } 180 } 181 182 /******************************************************************************* 183 * 184 * Function avct_lcb_unbind_disc 185 * 186 * Description Deallocate ccb and call callback with disconnect event. 187 * 188 * 189 * Returns Nothing. 190 * 191 ******************************************************************************/ 192 void avct_lcb_unbind_disc(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 193 avct_ccb_dealloc(p_data->p_ccb, AVCT_DISCONNECT_CFM_EVT, 0, NULL); 194 } 195 196 /******************************************************************************* 197 * 198 * Function avct_lcb_open_ind 199 * 200 * Description Handle an LL_OPEN event. For each allocated ccb already 201 * bound to this lcb, send a connect event. For each 202 * unbound ccb with a new PID, bind that ccb to this lcb and 203 * send a connect event. 204 * 205 * 206 * Returns Nothing. 207 * 208 ******************************************************************************/ 209 void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 210 tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 211 int i; 212 bool bind = false; 213 214 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 215 /* if ccb allocated and */ 216 if (p_ccb->allocated) { 217 /* if bound to this lcb send connect confirm event */ 218 if (p_ccb->p_lcb == p_lcb) { 219 bind = true; 220 L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH); 221 p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_CFM_EVT, 0, 222 &p_lcb->peer_addr); 223 } 224 /* if unbound acceptor and lcb doesn't already have a ccb for this PID */ 225 else if ((p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP) && 226 (avct_lcb_has_pid(p_lcb, p_ccb->cc.pid) == NULL)) { 227 /* bind ccb to lcb and send connect ind event */ 228 bind = true; 229 p_ccb->p_lcb = p_lcb; 230 L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH); 231 p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_IND_EVT, 0, 232 &p_lcb->peer_addr); 233 } 234 } 235 } 236 237 /* if no ccbs bound to this lcb, disconnect */ 238 if (!bind) { 239 avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data); 240 } 241 } 242 243 /******************************************************************************* 244 * 245 * Function avct_lcb_open_fail 246 * 247 * Description L2CAP channel open attempt failed. Deallocate any ccbs 248 * on this lcb and send connect confirm event with failure. 249 * 250 * 251 * Returns Nothing. 252 * 253 ******************************************************************************/ 254 void avct_lcb_open_fail(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 255 tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 256 int i; 257 258 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 259 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { 260 avct_ccb_dealloc(p_ccb, AVCT_CONNECT_CFM_EVT, p_data->result, 261 &p_lcb->peer_addr); 262 } 263 } 264 } 265 266 /******************************************************************************* 267 * 268 * Function avct_lcb_close_ind 269 * 270 * Description L2CAP channel closed by peer. Deallocate any initiator 271 * ccbs on this lcb and send disconnect ind event. 272 * 273 * 274 * Returns Nothing. 275 * 276 ******************************************************************************/ 277 void avct_lcb_close_ind(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { 278 tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 279 int i; 280 281 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 282 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { 283 if (p_ccb->cc.role == AVCT_INT) { 284 avct_ccb_dealloc(p_ccb, AVCT_DISCONNECT_IND_EVT, 0, &p_lcb->peer_addr); 285 } else { 286 p_ccb->p_lcb = NULL; 287 (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), 288 AVCT_DISCONNECT_IND_EVT, 0, 289 &p_lcb->peer_addr); 290 } 291 } 292 } 293 } 294 295 /******************************************************************************* 296 * 297 * Function avct_lcb_close_cfm 298 * 299 * Description L2CAP channel closed by us. Deallocate any initiator 300 * ccbs on this lcb and send disconnect ind or cfm event. 301 * 302 * 303 * Returns Nothing. 304 * 305 ******************************************************************************/ 306 void avct_lcb_close_cfm(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 307 tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 308 int i; 309 uint8_t event; 310 311 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 312 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { 313 /* if this ccb initiated close send disconnect cfm otherwise ind */ 314 if (p_ccb->ch_close) { 315 p_ccb->ch_close = false; 316 event = AVCT_DISCONNECT_CFM_EVT; 317 } else { 318 event = AVCT_DISCONNECT_IND_EVT; 319 } 320 321 if (p_ccb->cc.role == AVCT_INT) { 322 avct_ccb_dealloc(p_ccb, event, p_data->result, &p_lcb->peer_addr); 323 } else { 324 p_ccb->p_lcb = NULL; 325 (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result, 326 &p_lcb->peer_addr); 327 } 328 } 329 } 330 } 331 332 /******************************************************************************* 333 * 334 * Function avct_lcb_bind_conn 335 * 336 * Description Bind ccb to lcb and send connect cfm event. 337 * 338 * 339 * Returns Nothing. 340 * 341 ******************************************************************************/ 342 void avct_lcb_bind_conn(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 343 p_data->p_ccb->p_lcb = p_lcb; 344 (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb), 345 AVCT_CONNECT_CFM_EVT, 0, &p_lcb->peer_addr); 346 } 347 348 /******************************************************************************* 349 * 350 * Function avct_lcb_chk_disc 351 * 352 * Description A ccb wants to close; if it is the last ccb on this lcb, 353 * close channel. Otherwise just deallocate and call 354 * callback. 355 * 356 * 357 * Returns Nothing. 358 * 359 ******************************************************************************/ 360 void avct_lcb_chk_disc(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 361 AVCT_TRACE_WARNING("%s", __func__); 362 363 avct_close_bcb(p_lcb, p_data); 364 if (avct_lcb_last_ccb(p_lcb, p_data->p_ccb)) { 365 AVCT_TRACE_WARNING("%s: closing", __func__); 366 p_data->p_ccb->ch_close = true; 367 avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data); 368 } else { 369 AVCT_TRACE_WARNING("%s: dealloc ccb", __func__); 370 avct_lcb_unbind_disc(p_lcb, p_data); 371 } 372 } 373 374 /******************************************************************************* 375 * 376 * Function avct_lcb_chnl_disc 377 * 378 * Description Disconnect L2CAP channel. 379 * 380 * 381 * Returns Nothing. 382 * 383 ******************************************************************************/ 384 void avct_lcb_chnl_disc(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { 385 L2CA_DisconnectReq(p_lcb->ch_lcid); 386 } 387 388 /******************************************************************************* 389 * 390 * Function avct_lcb_bind_fail 391 * 392 * Description Deallocate ccb and call callback with connect event 393 * with failure result. 394 * 395 * 396 * Returns Nothing. 397 * 398 ******************************************************************************/ 399 void avct_lcb_bind_fail(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 400 avct_ccb_dealloc(p_data->p_ccb, AVCT_CONNECT_CFM_EVT, AVCT_RESULT_FAIL, NULL); 401 } 402 403 /******************************************************************************* 404 * 405 * Function avct_lcb_cong_ind 406 * 407 * Description Handle congestion indication from L2CAP. 408 * 409 * 410 * Returns Nothing. 411 * 412 ******************************************************************************/ 413 void avct_lcb_cong_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 414 tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; 415 int i; 416 uint8_t event; 417 BT_HDR* p_buf; 418 419 /* set event */ 420 event = (p_data->cong) ? AVCT_CONG_IND_EVT : AVCT_UNCONG_IND_EVT; 421 p_lcb->cong = p_data->cong; 422 if (!p_lcb->cong && !fixed_queue_is_empty(p_lcb->tx_q)) { 423 while (!p_lcb->cong && 424 (p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_lcb->tx_q)) != NULL) { 425 if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) { 426 p_lcb->cong = true; 427 } 428 } 429 } 430 431 /* send event to all ccbs on this lcb */ 432 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { 433 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { 434 (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0, 435 &p_lcb->peer_addr); 436 } 437 } 438 } 439 440 /******************************************************************************* 441 * 442 * Function avct_lcb_discard_msg 443 * 444 * Description Discard a message sent in from the API. 445 * 446 * 447 * Returns Nothing. 448 * 449 ******************************************************************************/ 450 void avct_lcb_discard_msg(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 451 AVCT_TRACE_WARNING("%s Dropping message", __func__); 452 osi_free_and_reset((void**)&p_data->ul_msg.p_buf); 453 } 454 455 /******************************************************************************* 456 * 457 * Function avct_lcb_send_msg 458 * 459 * Description Build and send an AVCTP message. 460 * 461 * 462 * Returns Nothing. 463 * 464 ******************************************************************************/ 465 void avct_lcb_send_msg(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 466 uint16_t curr_msg_len; 467 uint8_t pkt_type; 468 uint8_t hdr_len; 469 uint8_t* p; 470 uint8_t nosp = 0; /* number of subsequent packets */ 471 uint16_t temp; 472 uint16_t buf_size = p_lcb->peer_mtu + L2CAP_MIN_OFFSET + BT_HDR_SIZE; 473 474 /* store msg len */ 475 curr_msg_len = p_data->ul_msg.p_buf->len; 476 477 /* initialize packet type and other stuff */ 478 if (curr_msg_len <= (p_lcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) { 479 pkt_type = AVCT_PKT_TYPE_SINGLE; 480 } else { 481 pkt_type = AVCT_PKT_TYPE_START; 482 temp = (curr_msg_len + AVCT_HDR_LEN_START - p_lcb->peer_mtu); 483 nosp = temp / (p_lcb->peer_mtu - 1) + 1; 484 if ((temp % (p_lcb->peer_mtu - 1)) != 0) nosp++; 485 } 486 487 /* while we haven't sent all packets */ 488 while (curr_msg_len != 0) { 489 BT_HDR* p_buf; 490 491 /* set header len */ 492 hdr_len = avct_lcb_pkt_type_len[pkt_type]; 493 494 /* if remaining msg must be fragmented */ 495 if (p_data->ul_msg.p_buf->len > (p_lcb->peer_mtu - hdr_len)) { 496 /* get a new buffer for fragment we are sending */ 497 p_buf = (BT_HDR*)osi_malloc(buf_size); 498 499 /* copy portion of data from current message to new buffer */ 500 p_buf->offset = L2CAP_MIN_OFFSET + hdr_len; 501 p_buf->len = p_lcb->peer_mtu - hdr_len; 502 503 memcpy( 504 (uint8_t*)(p_buf + 1) + p_buf->offset, 505 (uint8_t*)(p_data->ul_msg.p_buf + 1) + p_data->ul_msg.p_buf->offset, 506 p_buf->len); 507 508 p_data->ul_msg.p_buf->offset += p_buf->len; 509 p_data->ul_msg.p_buf->len -= p_buf->len; 510 } else { 511 p_buf = p_data->ul_msg.p_buf; 512 } 513 514 curr_msg_len -= p_buf->len; 515 516 /* set up to build header */ 517 p_buf->len += hdr_len; 518 p_buf->offset -= hdr_len; 519 p = (uint8_t*)(p_buf + 1) + p_buf->offset; 520 521 /* build header */ 522 AVCT_BUILD_HDR(p, p_data->ul_msg.label, pkt_type, p_data->ul_msg.cr); 523 if (pkt_type == AVCT_PKT_TYPE_START) { 524 UINT8_TO_STREAM(p, nosp); 525 } 526 if ((pkt_type == AVCT_PKT_TYPE_START) || 527 (pkt_type == AVCT_PKT_TYPE_SINGLE)) { 528 UINT16_TO_BE_STREAM(p, p_data->ul_msg.p_ccb->cc.pid); 529 } 530 531 if (p_lcb->cong) { 532 fixed_queue_enqueue(p_lcb->tx_q, p_buf); 533 } 534 535 /* send message to L2CAP */ 536 else { 537 if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) { 538 p_lcb->cong = true; 539 } 540 } 541 542 /* update pkt type for next packet */ 543 if (curr_msg_len > (p_lcb->peer_mtu - AVCT_HDR_LEN_END)) { 544 pkt_type = AVCT_PKT_TYPE_CONT; 545 } else { 546 pkt_type = AVCT_PKT_TYPE_END; 547 } 548 } 549 AVCT_TRACE_DEBUG("%s tx_q_count:%d", __func__, 550 fixed_queue_length(p_lcb->tx_q)); 551 return; 552 } 553 554 /******************************************************************************* 555 * 556 * Function avct_lcb_free_msg_ind 557 * 558 * Description Discard an incoming AVCTP message. 559 * 560 * 561 * Returns Nothing. 562 * 563 ******************************************************************************/ 564 void avct_lcb_free_msg_ind(UNUSED_ATTR tAVCT_LCB* p_lcb, 565 tAVCT_LCB_EVT* p_data) { 566 if (p_data == NULL) return; 567 568 osi_free_and_reset((void**)&p_data->p_buf); 569 } 570 571 /******************************************************************************* 572 * 573 * Function avct_lcb_msg_ind 574 * 575 * Description Handle an incoming AVCTP message. 576 * 577 * 578 * Returns Nothing. 579 * 580 ******************************************************************************/ 581 void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { 582 uint8_t* p; 583 uint8_t label, type, cr_ipid; 584 uint16_t pid; 585 tAVCT_CCB* p_ccb; 586 587 /* this p_buf is to be reported through p_msg_cback. The layer_specific 588 * needs to be set properly to indicate that it is received through 589 * control channel */ 590 p_data->p_buf->layer_specific = AVCT_DATA_CTRL; 591 592 /* reassemble message; if no message available (we received a fragment) return 593 */ 594 p_data->p_buf = avct_lcb_msg_asmbl(p_lcb, p_data->p_buf); 595 if (p_data->p_buf == NULL) { 596 return; 597 } 598 599 p = (uint8_t*)(p_data->p_buf + 1) + p_data->p_buf->offset; 600 601 /* parse header byte */ 602 AVCT_PARSE_HDR(p, label, type, cr_ipid); 603 604 /* check for invalid cr_ipid */ 605 if (cr_ipid == AVCT_CR_IPID_INVALID) { 606 AVCT_TRACE_WARNING("Invalid cr_ipid", cr_ipid); 607 osi_free_and_reset((void**)&p_data->p_buf); 608 return; 609 } 610 611 /* parse and lookup PID */ 612 BE_STREAM_TO_UINT16(pid, p); 613 p_ccb = avct_lcb_has_pid(p_lcb, pid); 614 if (p_ccb) { 615 /* PID found; send msg up, adjust bt hdr and call msg callback */ 616 p_data->p_buf->offset += AVCT_HDR_LEN_SINGLE; 617 p_data->p_buf->len -= AVCT_HDR_LEN_SINGLE; 618 (*p_ccb->cc.p_msg_cback)(avct_ccb_to_idx(p_ccb), label, cr_ipid, 619 p_data->p_buf); 620 return; 621 } 622 623 /* PID not found; drop message */ 624 AVCT_TRACE_WARNING("No ccb for PID=%x", pid); 625 osi_free_and_reset((void**)&p_data->p_buf); 626 627 /* if command send reject */ 628 if (cr_ipid == AVCT_CMD) { 629 BT_HDR* p_buf = (BT_HDR*)osi_malloc(AVCT_CMD_BUF_SIZE); 630 p_buf->len = AVCT_HDR_LEN_SINGLE; 631 p_buf->offset = AVCT_MSG_OFFSET - AVCT_HDR_LEN_SINGLE; 632 p = (uint8_t*)(p_buf + 1) + p_buf->offset; 633 AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ); 634 UINT16_TO_BE_STREAM(p, pid); 635 L2CA_DataWrite(p_lcb->ch_lcid, p_buf); 636 } 637 } 638