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