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