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