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