1 /****************************************************************************** 2 * 3 * Copyright (C) 2006-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 the action functions associated with the channel 22 * control block state machine. 23 * 24 ******************************************************************************/ 25 26 #include <string.h> 27 #include "bt_types.h" 28 #include "bt_target.h" 29 #include "bt_utils.h" 30 #include "avdt_api.h" 31 #include "avdtc_api.h" 32 #include "avdt_int.h" 33 #include "gki.h" 34 #include "btu.h" 35 #include "btm_api.h" 36 37 /******************************************************************************* 38 ** 39 ** Function avdt_ccb_clear_ccb 40 ** 41 ** Description This function clears out certain buffers, queues, and 42 ** other data elements of a ccb. 43 ** 44 ** 45 ** Returns void. 46 ** 47 *******************************************************************************/ 48 static void avdt_ccb_clear_ccb(tAVDT_CCB *p_ccb) 49 { 50 BT_HDR *p_buf; 51 52 /* clear certain ccb variables */ 53 p_ccb->cong = FALSE; 54 p_ccb->ret_count = 0; 55 56 /* free message being fragmented */ 57 if (p_ccb->p_curr_msg != NULL) 58 { 59 GKI_freebuf(p_ccb->p_curr_msg); 60 p_ccb->p_curr_msg = NULL; 61 } 62 63 /* free message being reassembled */ 64 if (p_ccb->p_rx_msg != NULL) 65 { 66 GKI_freebuf(p_ccb->p_rx_msg); 67 p_ccb->p_rx_msg = NULL; 68 } 69 70 /* clear out response queue */ 71 while ((p_buf = (BT_HDR *) GKI_dequeue(&p_ccb->rsp_q)) != NULL) 72 { 73 GKI_freebuf(p_buf); 74 } 75 } 76 77 /******************************************************************************* 78 ** 79 ** Function avdt_ccb_chan_open 80 ** 81 ** Description This function calls avdt_ad_open_req() to 82 ** initiate a signaling channel connection. 83 ** 84 ** 85 ** Returns void. 86 ** 87 *******************************************************************************/ 88 void avdt_ccb_chan_open(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 89 { 90 UNUSED(p_data); 91 92 BTM_SetOutService(p_ccb->peer_addr, BTM_SEC_SERVICE_AVDTP, AVDT_CHAN_SIG); 93 avdt_ad_open_req(AVDT_CHAN_SIG, p_ccb, NULL, AVDT_INT); 94 } 95 96 /******************************************************************************* 97 ** 98 ** Function avdt_ccb_chan_close 99 ** 100 ** Description This function calls avdt_ad_close_req() to close a 101 ** signaling channel connection. 102 ** 103 ** 104 ** Returns void. 105 ** 106 *******************************************************************************/ 107 void avdt_ccb_chan_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 108 { 109 UNUSED(p_data); 110 111 /* close the transport channel used by this CCB */ 112 avdt_ad_close_req(AVDT_CHAN_SIG, p_ccb, NULL); 113 } 114 115 /******************************************************************************* 116 ** 117 ** Function avdt_ccb_chk_close 118 ** 119 ** Description This function checks for active streams on this CCB. 120 ** If there are none, it starts an idle timer. 121 ** 122 ** 123 ** Returns void. 124 ** 125 *******************************************************************************/ 126 void avdt_ccb_chk_close(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 127 { 128 int i; 129 tAVDT_SCB *p_scb = &avdt_cb.scb[0]; 130 UNUSED(p_data); 131 132 /* see if there are any active scbs associated with this ccb */ 133 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) 134 { 135 if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb)) 136 { 137 break; 138 } 139 } 140 141 /* if no active scbs start idle timer */ 142 if (i == AVDT_NUM_SEPS) 143 { 144 btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_AVDT_CCB_IDLE, avdt_cb.rcb.idle_tout); 145 } 146 } 147 148 /******************************************************************************* 149 ** 150 ** Function avdt_ccb_hdl_discover_cmd 151 ** 152 ** Description This function is called when a discover command is 153 ** received from the peer. It gathers up the stream 154 ** information for all allocated streams and initiates 155 ** sending of a discover response. 156 ** 157 ** 158 ** Returns void. 159 ** 160 *******************************************************************************/ 161 void avdt_ccb_hdl_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 162 { 163 tAVDT_SEP_INFO sep_info[AVDT_NUM_SEPS]; 164 tAVDT_SCB *p_scb = &avdt_cb.scb[0]; 165 int i; 166 167 p_data->msg.discover_rsp.p_sep_info = sep_info; 168 p_data->msg.discover_rsp.num_seps = 0; 169 170 /* for all allocated scbs */ 171 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) 172 { 173 if (p_scb->allocated) 174 { 175 /* copy sep info */ 176 sep_info[p_data->msg.discover_rsp.num_seps].in_use = p_scb->in_use; 177 sep_info[p_data->msg.discover_rsp.num_seps].seid = i + 1; 178 sep_info[p_data->msg.discover_rsp.num_seps].media_type = p_scb->cs.media_type; 179 sep_info[p_data->msg.discover_rsp.num_seps].tsep = p_scb->cs.tsep; 180 181 p_data->msg.discover_rsp.num_seps++; 182 } 183 } 184 185 /* send response */ 186 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_RSP_EVT, p_data); 187 } 188 189 /******************************************************************************* 190 ** 191 ** Function avdt_ccb_hdl_discover_rsp 192 ** 193 ** Description This function is called when a discover response or 194 ** reject is received from the peer. It calls the application 195 ** callback function with the results. 196 ** 197 ** 198 ** Returns void. 199 ** 200 *******************************************************************************/ 201 void avdt_ccb_hdl_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 202 { 203 /* we're done with procedure */ 204 p_ccb->proc_busy = FALSE; 205 206 /* call app callback with results */ 207 (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_DISCOVER_CFM_EVT, 208 (tAVDT_CTRL *)(&p_data->msg.discover_rsp)); 209 } 210 211 /******************************************************************************* 212 ** 213 ** Function avdt_ccb_hdl_getcap_cmd 214 ** 215 ** Description This function is called when a get capabilities command 216 ** is received from the peer. It retrieves the stream 217 ** configuration for the requested stream and initiates 218 ** sending of a get capabilities response. 219 ** 220 ** 221 ** Returns void. 222 ** 223 *******************************************************************************/ 224 void avdt_ccb_hdl_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 225 { 226 tAVDT_SCB *p_scb; 227 228 /* look up scb for seid sent to us */ 229 p_scb = avdt_scb_by_hdl(p_data->msg.single.seid); 230 231 p_data->msg.svccap.p_cfg = &p_scb->cs.cfg; 232 233 avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_RSP_EVT, p_data); 234 } 235 236 /******************************************************************************* 237 ** 238 ** Function avdt_ccb_hdl_getcap_rsp 239 ** 240 ** Description This function is called with a get capabilities response 241 ** or reject is received from the peer. It calls the 242 ** application callback function with the results. 243 ** 244 ** 245 ** Returns void. 246 ** 247 *******************************************************************************/ 248 void avdt_ccb_hdl_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 249 { 250 /* we're done with procedure */ 251 p_ccb->proc_busy = FALSE; 252 253 /* call app callback with results */ 254 (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_GETCAP_CFM_EVT, 255 (tAVDT_CTRL *)(&p_data->msg.svccap)); 256 } 257 258 /******************************************************************************* 259 ** 260 ** Function avdt_ccb_hdl_start_cmd 261 ** 262 ** Description This function is called when a start command is received 263 ** from the peer. It verifies that all requested streams 264 ** are in the proper state. If so, it initiates sending of 265 ** a start response. Otherwise it sends a start reject. 266 ** 267 ** 268 ** Returns void. 269 ** 270 *******************************************************************************/ 271 void avdt_ccb_hdl_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 272 { 273 UINT8 err_code = 0; 274 275 /* verify all streams in the right state */ 276 UINT8 seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_START, p_data->msg.multi.seid_list, 277 p_data->msg.multi.num_seps, &err_code); 278 if (seid == 0 && err_code == 0) 279 { 280 /* we're ok, send response */ 281 avdt_ccb_event(p_ccb, AVDT_CCB_API_START_RSP_EVT, p_data); 282 } else { 283 /* not ok, send reject */ 284 p_data->msg.hdr.err_code = err_code; 285 p_data->msg.hdr.err_param = seid; 286 avdt_msg_send_rej(p_ccb, AVDT_SIG_START, &p_data->msg); 287 } 288 } 289 290 /******************************************************************************* 291 ** 292 ** Function avdt_ccb_hdl_start_rsp 293 ** 294 ** Description This function is called when a start response or reject 295 ** is received from the peer. Using the SEIDs stored in the 296 ** current command message, it sends a start response or start 297 ** reject event to each SCB associated with the command. 298 ** 299 ** 300 ** Returns void. 301 ** 302 *******************************************************************************/ 303 void avdt_ccb_hdl_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 304 { 305 UINT8 event; 306 int i; 307 UINT8 *p; 308 tAVDT_SCB *p_scb; 309 310 /* determine rsp or rej event */ 311 event = (p_data->msg.hdr.err_code == 0) ? 312 AVDT_SCB_MSG_START_RSP_EVT : AVDT_SCB_MSG_START_REJ_EVT; 313 314 /* get to where seid's are stashed in current cmd */ 315 p = (UINT8 *)(p_ccb->p_curr_cmd + 1); 316 317 /* little trick here; length of current command equals number of streams */ 318 for (i = 0; i < p_ccb->p_curr_cmd->len; i++) 319 { 320 if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL) 321 { 322 avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg); 323 } 324 } 325 } 326 327 /******************************************************************************* 328 ** 329 ** Function avdt_ccb_hdl_suspend_cmd 330 ** 331 ** Description This function is called when a suspend command is received 332 ** from the peer. It verifies that all requested streams are 333 ** in the proper state. If so, it initiates sending of a 334 ** suspend response. Otherwise it sends a suspend reject. 335 336 ** 337 ** 338 ** Returns void. 339 ** 340 *******************************************************************************/ 341 void avdt_ccb_hdl_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 342 { 343 UINT8 seid; 344 UINT8 err_code = 0; 345 346 /* verify all streams in the right state */ 347 if ((seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_SUSPEND, p_data->msg.multi.seid_list, 348 p_data->msg.multi.num_seps, &err_code)) == 0 && 349 err_code == 0) 350 { 351 /* we're ok, send response */ 352 avdt_ccb_event(p_ccb, AVDT_CCB_API_SUSPEND_RSP_EVT, p_data); 353 } 354 else 355 { 356 /* not ok, send reject */ 357 p_data->msg.hdr.err_code = err_code; 358 p_data->msg.hdr.err_param = seid; 359 avdt_msg_send_rej(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg); 360 } 361 } 362 363 /******************************************************************************* 364 ** 365 ** Function avdt_ccb_hdl_suspend_rsp 366 ** 367 ** Description This function is called when a suspend response or reject 368 ** is received from the peer. Using the SEIDs stored in the 369 ** current command message, it sends a suspend response or 370 ** suspend reject event to each SCB associated with the command. 371 ** 372 ** 373 ** 374 ** Returns void. 375 ** 376 *******************************************************************************/ 377 void avdt_ccb_hdl_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 378 { 379 UINT8 event; 380 int i; 381 UINT8 *p; 382 tAVDT_SCB *p_scb; 383 384 /* determine rsp or rej event */ 385 event = (p_data->msg.hdr.err_code == 0) ? 386 AVDT_SCB_MSG_SUSPEND_RSP_EVT : AVDT_SCB_MSG_SUSPEND_REJ_EVT; 387 388 /* get to where seid's are stashed in current cmd */ 389 p = (UINT8 *)(p_ccb->p_curr_cmd + 1); 390 391 /* little trick here; length of current command equals number of streams */ 392 for (i = 0; i < p_ccb->p_curr_cmd->len; i++) 393 { 394 if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL) 395 { 396 avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg); 397 } 398 } 399 } 400 401 /******************************************************************************* 402 ** 403 ** Function avdt_ccb_snd_discover_cmd 404 ** 405 ** Description This function is called to send a discover command to the 406 ** peer. It copies variables needed for the procedure from 407 ** the event to the CCB. It marks the CCB as busy and then 408 ** sends a discover command. 409 ** 410 ** 411 ** Returns void. 412 ** 413 *******************************************************************************/ 414 void avdt_ccb_snd_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 415 { 416 /* store info in ccb struct */ 417 p_ccb->p_proc_data = p_data->discover.p_sep_info; 418 p_ccb->proc_cback = p_data->discover.p_cback; 419 p_ccb->proc_param = p_data->discover.num_seps; 420 421 /* we're busy */ 422 p_ccb->proc_busy = TRUE; 423 424 /* build and queue discover req */ 425 avdt_msg_send_cmd(p_ccb, NULL, AVDT_SIG_DISCOVER, NULL); 426 } 427 428 /******************************************************************************* 429 ** 430 ** Function avdt_ccb_snd_discover_rsp 431 ** 432 ** Description This function is called to send a discover response to 433 ** the peer. It takes the stream information passed in the 434 ** event and sends a discover response. 435 ** 436 ** 437 ** Returns void. 438 ** 439 *******************************************************************************/ 440 void avdt_ccb_snd_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 441 { 442 /* send response */ 443 avdt_msg_send_rsp(p_ccb, AVDT_SIG_DISCOVER, &p_data->msg); 444 } 445 446 /******************************************************************************* 447 ** 448 ** Function avdt_ccb_snd_getcap_cmd 449 ** 450 ** Description This function is called to send a get capabilities command 451 ** to the peer. It copies variables needed for the procedure 452 ** from the event to the CCB. It marks the CCB as busy and 453 ** then sends a get capabilities command. 454 ** 455 ** 456 ** Returns void. 457 ** 458 *******************************************************************************/ 459 void avdt_ccb_snd_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 460 { 461 UINT8 sig_id = AVDT_SIG_GETCAP; 462 463 /* store info in ccb struct */ 464 p_ccb->p_proc_data = p_data->getcap.p_cfg; 465 p_ccb->proc_cback = p_data->getcap.p_cback; 466 467 /* we're busy */ 468 p_ccb->proc_busy = TRUE; 469 470 /* build and queue discover req */ 471 if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP) 472 sig_id = AVDT_SIG_GET_ALLCAP; 473 474 avdt_msg_send_cmd(p_ccb, NULL, sig_id, (tAVDT_MSG *) &p_data->getcap.single); 475 } 476 477 /******************************************************************************* 478 ** 479 ** Function avdt_ccb_snd_getcap_rsp 480 ** 481 ** Description This function is called to send a get capabilities response 482 ** to the peer. It takes the stream information passed in the 483 ** event and sends a get capabilities response. 484 ** 485 ** 486 ** Returns void. 487 ** 488 *******************************************************************************/ 489 void avdt_ccb_snd_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 490 { 491 UINT8 sig_id = AVDT_SIG_GETCAP; 492 493 if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP) 494 sig_id = AVDT_SIG_GET_ALLCAP; 495 496 /* send response */ 497 avdt_msg_send_rsp(p_ccb, sig_id, &p_data->msg); 498 } 499 500 /******************************************************************************* 501 ** 502 ** Function avdt_ccb_snd_start_cmd 503 ** 504 ** Description This function is called to send a start command to the 505 ** peer. It verifies that all requested streams are in the 506 ** proper state. If so, it sends a start command. Otherwise 507 ** send ourselves back a start reject. 508 ** 509 ** 510 ** Returns void. 511 ** 512 *******************************************************************************/ 513 void avdt_ccb_snd_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 514 { 515 int i; 516 tAVDT_SCB *p_scb; 517 tAVDT_MSG avdt_msg; 518 UINT8 seid_list[AVDT_NUM_SEPS]; 519 520 /* make copy of our seid list */ 521 memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps); 522 523 /* verify all streams in the right state */ 524 if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_OPEN, p_data->msg.multi.seid_list, 525 p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0) 526 { 527 /* set peer seid list in messsage */ 528 avdt_scb_peer_seid_list(&p_data->msg.multi); 529 530 /* send command */ 531 avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_START, &p_data->msg); 532 } 533 else 534 { 535 /* failed; send ourselves a reject for each stream */ 536 for (i = 0; i < p_data->msg.multi.num_seps; i++) 537 { 538 if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL) 539 { 540 avdt_scb_event(p_scb, AVDT_SCB_MSG_START_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr); 541 } 542 } 543 } 544 } 545 546 /******************************************************************************* 547 ** 548 ** Function avdt_ccb_snd_start_rsp 549 ** 550 ** Description This function is called to send a start response to the 551 ** peer. It takes the stream information passed in the event 552 ** and sends a start response. Then it sends a start event 553 ** to the SCB for each stream. 554 ** 555 ** 556 ** Returns void. 557 ** 558 *******************************************************************************/ 559 void avdt_ccb_snd_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 560 { 561 tAVDT_SCB *p_scb; 562 int i; 563 564 /* send response message */ 565 avdt_msg_send_rsp(p_ccb, AVDT_SIG_START, &p_data->msg); 566 567 /* send start event to each scb */ 568 for (i = 0; i < p_data->msg.multi.num_seps; i++) 569 { 570 if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL) 571 { 572 avdt_scb_event(p_scb, AVDT_SCB_MSG_START_CMD_EVT, NULL); 573 } 574 } 575 } 576 577 /******************************************************************************* 578 ** 579 ** Function avdt_ccb_snd_suspend_cmd 580 ** 581 ** Description This function is called to send a suspend command to the 582 ** peer. It verifies that all requested streams are in the 583 ** proper state. If so, it sends a suspend command. 584 ** Otherwise it calls the callback function for each requested 585 ** stream and sends a suspend confirmation with failure. 586 ** 587 ** 588 ** Returns void. 589 ** 590 *******************************************************************************/ 591 void avdt_ccb_snd_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 592 { 593 int i; 594 tAVDT_SCB *p_scb; 595 tAVDT_MSG avdt_msg; 596 UINT8 seid_list[AVDT_NUM_SEPS]; 597 598 /* make copy of our seid list */ 599 memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps); 600 601 /* verify all streams in the right state */ 602 if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_STREAMING, p_data->msg.multi.seid_list, 603 p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0) 604 { 605 /* set peer seid list in messsage */ 606 avdt_scb_peer_seid_list(&p_data->msg.multi); 607 608 /* send command */ 609 avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_SUSPEND, &p_data->msg); 610 } 611 else 612 { 613 /* failed; send ourselves a reject for each stream */ 614 for (i = 0; i < p_data->msg.multi.num_seps; i++) 615 { 616 if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL) 617 { 618 avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr); 619 } 620 } 621 } 622 } 623 624 /******************************************************************************* 625 ** 626 ** Function avdt_ccb_snd_suspend_rsp 627 ** 628 ** Description This function is called to send a suspend response to the 629 ** peer. It takes the stream information passed in the event 630 ** and sends a suspend response. Then it sends a suspend event 631 ** to the SCB for each stream. 632 ** 633 ** 634 ** Returns void. 635 ** 636 *******************************************************************************/ 637 void avdt_ccb_snd_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 638 { 639 tAVDT_SCB *p_scb; 640 int i; 641 642 /* send response message */ 643 avdt_msg_send_rsp(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg); 644 645 /* send start event to each scb */ 646 for (i = 0; i < p_data->msg.multi.num_seps; i++) 647 { 648 if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL) 649 { 650 avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_CMD_EVT, NULL); 651 } 652 } 653 } 654 655 /******************************************************************************* 656 ** 657 ** Function avdt_ccb_clear_cmds 658 ** 659 ** Description This function is called when the signaling channel is 660 ** closed to clean up any pending commands. For each pending 661 ** command in the command queue, it frees the command and 662 ** calls the application callback function indicating failure. 663 ** Certain CCB variables are also initialized. 664 ** 665 ** 666 ** Returns void. 667 ** 668 *******************************************************************************/ 669 void avdt_ccb_clear_cmds(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 670 { 671 int i; 672 tAVDT_SCB *p_scb = &avdt_cb.scb[0]; 673 UINT8 err_code = AVDT_ERR_CONNECT; 674 UNUSED(p_data); 675 676 /* clear the ccb */ 677 avdt_ccb_clear_ccb(p_ccb); 678 679 /* clear out command queue; this is a little tricky here; we need 680 ** to handle the case where there is a command on deck in p_curr_cmd, 681 ** plus we need to clear out the queue 682 */ 683 do 684 { 685 /* we know p_curr_cmd = NULL after this */ 686 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code); 687 688 /* set up next message */ 689 p_ccb->p_curr_cmd = (BT_HDR *) GKI_dequeue(&p_ccb->cmd_q); 690 691 } while (p_ccb->p_curr_cmd != NULL); 692 693 /* send a CC_CLOSE_EVT any active scbs associated with this ccb */ 694 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) 695 { 696 if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb)) 697 { 698 avdt_scb_event(p_scb, AVDT_SCB_CC_CLOSE_EVT, NULL); 699 } 700 } 701 } 702 703 /******************************************************************************* 704 ** 705 ** Function avdt_ccb_cmd_fail 706 ** 707 ** Description This function is called when there is a response timeout. 708 ** The currently pending command is freed and we fake a 709 ** reject message back to ourselves. 710 ** 711 ** 712 ** Returns void. 713 ** 714 *******************************************************************************/ 715 void avdt_ccb_cmd_fail(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 716 { 717 tAVDT_MSG msg; 718 UINT8 evt; 719 tAVDT_SCB *p_scb; 720 721 if (p_ccb->p_curr_cmd != NULL) 722 { 723 /* set up data */ 724 msg.hdr.err_code = p_data->err_code; 725 msg.hdr.err_param = 0; 726 msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb); 727 728 /* pretend that we received a rej message */ 729 evt = avdt_msg_rej_2_evt[p_ccb->p_curr_cmd->event - 1]; 730 731 if (evt & AVDT_CCB_MKR) 732 { 733 avdt_ccb_event(p_ccb, (UINT8) (evt & ~AVDT_CCB_MKR), (tAVDT_CCB_EVT *) &msg); 734 } 735 else 736 { 737 /* we get the scb out of the current cmd */ 738 p_scb = avdt_scb_by_hdl(*((UINT8 *)(p_ccb->p_curr_cmd + 1))); 739 if (p_scb != NULL) 740 { 741 avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT *) &msg); 742 } 743 } 744 745 GKI_freebuf(p_ccb->p_curr_cmd); 746 p_ccb->p_curr_cmd = NULL; 747 } 748 } 749 750 /******************************************************************************* 751 ** 752 ** Function avdt_ccb_free_cmd 753 ** 754 ** Description This function is called when a response is received for a 755 ** currently pending command. The command is freed. 756 ** 757 ** 758 ** Returns void. 759 ** 760 *******************************************************************************/ 761 void avdt_ccb_free_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 762 { 763 UNUSED(p_data); 764 765 if (p_ccb->p_curr_cmd != NULL) 766 { 767 GKI_freebuf(p_ccb->p_curr_cmd); 768 p_ccb->p_curr_cmd = NULL; 769 } 770 } 771 772 /******************************************************************************* 773 ** 774 ** Function avdt_ccb_cong_state 775 ** 776 ** Description This function is called to set the congestion state for 777 ** the CCB. 778 ** 779 ** 780 ** Returns void. 781 ** 782 *******************************************************************************/ 783 void avdt_ccb_cong_state(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 784 { 785 p_ccb->cong = p_data->llcong; 786 } 787 788 /******************************************************************************* 789 ** 790 ** Function avdt_ccb_ret_cmd 791 ** 792 ** Description This function is called to retransmit the currently 793 ** pending command. The retransmission count is incremented. 794 ** If the count reaches the maximum number of retransmissions, 795 ** the event is treated as a response timeout. 796 ** 797 ** 798 ** Returns void. 799 ** 800 *******************************************************************************/ 801 void avdt_ccb_ret_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 802 { 803 UINT8 err_code = AVDT_ERR_TIMEOUT; 804 BT_HDR *p_msg; 805 806 p_ccb->ret_count++; 807 if (p_ccb->ret_count == AVDT_RET_MAX) 808 { 809 /* command failed */ 810 p_ccb->ret_count = 0; 811 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code); 812 813 /* go to next queued command */ 814 avdt_ccb_snd_cmd(p_ccb, p_data); 815 } 816 else 817 { 818 /* if command pending and we're not congested and not sending a fragment */ 819 if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd != NULL)) 820 { 821 /* make copy of message in p_curr_cmd and send it */ 822 if ((p_msg = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) != NULL) 823 { 824 memcpy(p_msg, p_ccb->p_curr_cmd, 825 (sizeof(BT_HDR) + p_ccb->p_curr_cmd->offset + p_ccb->p_curr_cmd->len)); 826 avdt_msg_send(p_ccb, p_msg); 827 } 828 } 829 830 /* restart timer */ 831 btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_AVDT_CCB_RET, avdt_cb.rcb.ret_tout); 832 } 833 } 834 835 /******************************************************************************* 836 ** 837 ** Function avdt_ccb_snd_cmd 838 ** 839 ** Description This function is called the send the next command, 840 ** if any, in the command queue. 841 ** 842 ** 843 ** Returns void. 844 ** 845 *******************************************************************************/ 846 void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 847 { 848 BT_HDR *p_msg; 849 UNUSED(p_data); 850 851 /* do we have commands to send? send next command; make sure we're clear; 852 ** not congested, not sending fragment, not waiting for response 853 */ 854 if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd == NULL)) 855 { 856 if ((p_msg = (BT_HDR *) GKI_dequeue(&p_ccb->cmd_q)) != NULL) 857 { 858 /* make a copy of buffer in p_curr_cmd */ 859 if ((p_ccb->p_curr_cmd = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) != NULL) 860 { 861 memcpy(p_ccb->p_curr_cmd, p_msg, (sizeof(BT_HDR) + p_msg->offset + p_msg->len)); 862 863 avdt_msg_send(p_ccb, p_msg); 864 } 865 } 866 } 867 } 868 869 /******************************************************************************* 870 ** 871 ** Function avdt_ccb_snd_msg 872 ** 873 ** Description 874 ** 875 ** 876 ** Returns void. 877 ** 878 *******************************************************************************/ 879 void avdt_ccb_snd_msg(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 880 { 881 BT_HDR *p_msg; 882 UNUSED(p_data); 883 884 /* if not congested */ 885 if (!p_ccb->cong) 886 { 887 /* are we sending a fragmented message? continue sending fragment */ 888 if (p_ccb->p_curr_msg != NULL) 889 { 890 avdt_msg_send(p_ccb, NULL); 891 } 892 /* do we have responses to send? send them */ 893 else if (!GKI_queue_is_empty(&p_ccb->rsp_q)) 894 { 895 while ((p_msg = (BT_HDR *) GKI_dequeue(&p_ccb->rsp_q)) != NULL) 896 { 897 if (avdt_msg_send(p_ccb, p_msg) == TRUE) 898 { 899 /* break out if congested */ 900 break; 901 } 902 } 903 } 904 905 /* do we have commands to send? send next command */ 906 avdt_ccb_snd_cmd(p_ccb, NULL); 907 } 908 } 909 910 /******************************************************************************* 911 ** 912 ** Function avdt_ccb_set_reconn 913 ** 914 ** Description This function is called to enable a reconnect attempt when 915 ** a channel transitions from closing to idle state. It sets 916 ** the reconn variable to TRUE. 917 ** 918 ** 919 ** Returns void. 920 ** 921 *******************************************************************************/ 922 void avdt_ccb_set_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 923 { 924 UNUSED(p_data); 925 926 p_ccb->reconn = TRUE; 927 } 928 929 /******************************************************************************* 930 ** 931 ** Function avdt_ccb_clr_reconn 932 ** 933 ** Description This function is called to clear the reconn variable. 934 ** 935 ** 936 ** Returns void. 937 ** 938 *******************************************************************************/ 939 void avdt_ccb_clr_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 940 { 941 UNUSED(p_data); 942 943 p_ccb->reconn = FALSE; 944 } 945 946 /******************************************************************************* 947 ** 948 ** Function avdt_ccb_chk_reconn 949 ** 950 ** Description This function is called to check if a reconnect attempt 951 ** is enabled. If enabled, it sends an AVDT_CCB_UL_OPEN_EVT 952 ** to the CCB. If disabled, the CCB is deallocated. 953 ** 954 ** 955 ** Returns void. 956 ** 957 *******************************************************************************/ 958 void avdt_ccb_chk_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 959 { 960 UINT8 err_code = AVDT_ERR_CONNECT; 961 UNUSED(p_data); 962 963 if (p_ccb->reconn) 964 { 965 p_ccb->reconn = FALSE; 966 967 /* clear out ccb */ 968 avdt_ccb_clear_ccb(p_ccb); 969 970 /* clear out current command, if any */ 971 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code); 972 973 /* reopen the signaling channel */ 974 avdt_ccb_event(p_ccb, AVDT_CCB_UL_OPEN_EVT, NULL); 975 } 976 else 977 { 978 avdt_ccb_ll_closed(p_ccb, NULL); 979 } 980 } 981 982 /******************************************************************************* 983 ** 984 ** Function avdt_ccb_chk_timer 985 ** 986 ** Description This function stops the CCB timer if the idle timer is 987 ** running. 988 ** 989 ** 990 ** Returns void. 991 ** 992 *******************************************************************************/ 993 void avdt_ccb_chk_timer(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 994 { 995 UNUSED(p_data); 996 997 if (p_ccb->timer_entry.event == BTU_TTYPE_AVDT_CCB_IDLE) 998 { 999 btu_stop_timer(&p_ccb->timer_entry); 1000 } 1001 } 1002 1003 /******************************************************************************* 1004 ** 1005 ** Function avdt_ccb_set_conn 1006 ** 1007 ** Description Set CCB variables associated with AVDT_ConnectReq(). 1008 ** 1009 ** 1010 ** Returns void. 1011 ** 1012 *******************************************************************************/ 1013 void avdt_ccb_set_conn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1014 { 1015 /* save callback */ 1016 p_ccb->p_conn_cback = p_data->connect.p_cback; 1017 1018 /* set security level */ 1019 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_data->connect.sec_mask, 1020 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG); 1021 } 1022 1023 /******************************************************************************* 1024 ** 1025 ** Function avdt_ccb_set_disconn 1026 ** 1027 ** Description Set CCB variables associated with AVDT_DisconnectReq(). 1028 ** 1029 ** 1030 ** Returns void. 1031 ** 1032 *******************************************************************************/ 1033 void avdt_ccb_set_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1034 { 1035 /* 1036 AVDT_TRACE_EVENT("avdt_ccb_set_disconn:conn:x%x, api:x%x", 1037 p_ccb->p_conn_cback, p_data->disconnect.p_cback); 1038 */ 1039 /* save callback */ 1040 if (p_data->disconnect.p_cback) 1041 p_ccb->p_conn_cback = p_data->disconnect.p_cback; 1042 } 1043 1044 /******************************************************************************* 1045 ** 1046 ** Function avdt_ccb_do_disconn 1047 ** 1048 ** Description Do action associated with AVDT_DisconnectReq(). 1049 ** 1050 ** 1051 ** Returns void. 1052 ** 1053 *******************************************************************************/ 1054 void avdt_ccb_do_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1055 { 1056 UNUSED(p_data); 1057 1058 /* clear any pending commands */ 1059 avdt_ccb_clear_cmds(p_ccb, NULL); 1060 1061 /* close channel */ 1062 avdt_ccb_chan_close(p_ccb, NULL); 1063 } 1064 1065 /******************************************************************************* 1066 ** 1067 ** Function avdt_ccb_ll_closed 1068 ** 1069 ** Description Clear commands from and deallocate CCB. 1070 ** 1071 ** 1072 ** Returns void. 1073 ** 1074 *******************************************************************************/ 1075 void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1076 { 1077 tAVDT_CTRL_CBACK *p_cback; 1078 BD_ADDR bd_addr; 1079 tAVDT_CTRL avdt_ctrl; 1080 UNUSED(p_data); 1081 1082 /* clear any pending commands */ 1083 avdt_ccb_clear_cmds(p_ccb, NULL); 1084 1085 /* save callback pointer, bd addr */ 1086 p_cback = p_ccb->p_conn_cback; 1087 if (!p_cback) 1088 p_cback = avdt_cb.p_conn_cback; 1089 memcpy(bd_addr, p_ccb->peer_addr, BD_ADDR_LEN); 1090 1091 /* dealloc ccb */ 1092 avdt_ccb_dealloc(p_ccb, NULL); 1093 1094 /* call callback */ 1095 if (p_cback) 1096 { 1097 avdt_ctrl.hdr.err_code = 0; 1098 (*p_cback)(0, bd_addr, AVDT_DISCONNECT_IND_EVT, &avdt_ctrl); 1099 } 1100 } 1101 1102 /******************************************************************************* 1103 ** 1104 ** Function avdt_ccb_ll_opened 1105 ** 1106 ** Description Call callback on open. 1107 ** 1108 ** 1109 ** Returns void. 1110 ** 1111 *******************************************************************************/ 1112 void avdt_ccb_ll_opened(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1113 { 1114 tAVDT_CTRL avdt_ctrl; 1115 1116 p_ccb->ll_opened = TRUE; 1117 1118 if (!p_ccb->p_conn_cback) 1119 p_ccb->p_conn_cback = avdt_cb.p_conn_cback; 1120 1121 /* call callback */ 1122 if (p_ccb->p_conn_cback) 1123 { 1124 avdt_ctrl.hdr.err_code = 0; 1125 avdt_ctrl.hdr.err_param = p_data->msg.hdr.err_param; 1126 (*p_ccb->p_conn_cback)(0, p_ccb->peer_addr, AVDT_CONNECT_IND_EVT, &avdt_ctrl); 1127 } 1128 } 1129