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 "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 seid; 274 UINT8 err_code; 275 276 /* verify all streams in the right state */ 277 if ((seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_START, p_data->msg.multi.seid_list, 278 p_data->msg.multi.num_seps, &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 } 283 else 284 { 285 /* not ok, send reject */ 286 p_data->msg.hdr.err_code = err_code; 287 p_data->msg.hdr.err_param = seid; 288 avdt_msg_send_rej(p_ccb, AVDT_SIG_START, &p_data->msg); 289 } 290 } 291 292 /******************************************************************************* 293 ** 294 ** Function avdt_ccb_hdl_start_rsp 295 ** 296 ** Description This function is called when a start response or reject 297 ** is received from the peer. Using the SEIDs stored in the 298 ** current command message, it sends a start response or start 299 ** reject event to each SCB associated with the command. 300 ** 301 ** 302 ** Returns void. 303 ** 304 *******************************************************************************/ 305 void avdt_ccb_hdl_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 306 { 307 UINT8 event; 308 int i; 309 UINT8 *p; 310 tAVDT_SCB *p_scb; 311 312 /* determine rsp or rej event */ 313 event = (p_data->msg.hdr.err_code == 0) ? 314 AVDT_SCB_MSG_START_RSP_EVT : AVDT_SCB_MSG_START_REJ_EVT; 315 316 /* get to where seid's are stashed in current cmd */ 317 p = (UINT8 *)(p_ccb->p_curr_cmd + 1); 318 319 /* little trick here; length of current command equals number of streams */ 320 for (i = 0; i < p_ccb->p_curr_cmd->len; i++) 321 { 322 if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL) 323 { 324 avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg); 325 } 326 } 327 } 328 329 /******************************************************************************* 330 ** 331 ** Function avdt_ccb_hdl_suspend_cmd 332 ** 333 ** Description This function is called when a suspend command is received 334 ** from the peer. It verifies that all requested streams are 335 ** in the proper state. If so, it initiates sending of a 336 ** suspend response. Otherwise it sends a suspend reject. 337 338 ** 339 ** 340 ** Returns void. 341 ** 342 *******************************************************************************/ 343 void avdt_ccb_hdl_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 344 { 345 UINT8 seid; 346 UINT8 err_code; 347 348 /* verify all streams in the right state */ 349 if ((seid = avdt_scb_verify(p_ccb, AVDT_VERIFY_SUSPEND, p_data->msg.multi.seid_list, 350 p_data->msg.multi.num_seps, &err_code)) == 0) 351 { 352 /* we're ok, send response */ 353 avdt_ccb_event(p_ccb, AVDT_CCB_API_SUSPEND_RSP_EVT, p_data); 354 } 355 else 356 { 357 /* not ok, send reject */ 358 p_data->msg.hdr.err_code = err_code; 359 p_data->msg.hdr.err_param = seid; 360 avdt_msg_send_rej(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg); 361 } 362 } 363 364 /******************************************************************************* 365 ** 366 ** Function avdt_ccb_hdl_suspend_rsp 367 ** 368 ** Description This function is called when a suspend response or reject 369 ** is received from the peer. Using the SEIDs stored in the 370 ** current command message, it sends a suspend response or 371 ** suspend reject event to each SCB associated with the command. 372 ** 373 ** 374 ** 375 ** Returns void. 376 ** 377 *******************************************************************************/ 378 void avdt_ccb_hdl_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 379 { 380 UINT8 event; 381 int i; 382 UINT8 *p; 383 tAVDT_SCB *p_scb; 384 385 /* determine rsp or rej event */ 386 event = (p_data->msg.hdr.err_code == 0) ? 387 AVDT_SCB_MSG_SUSPEND_RSP_EVT : AVDT_SCB_MSG_SUSPEND_REJ_EVT; 388 389 /* get to where seid's are stashed in current cmd */ 390 p = (UINT8 *)(p_ccb->p_curr_cmd + 1); 391 392 /* little trick here; length of current command equals number of streams */ 393 for (i = 0; i < p_ccb->p_curr_cmd->len; i++) 394 { 395 if ((p_scb = avdt_scb_by_hdl(p[i])) != NULL) 396 { 397 avdt_scb_event(p_scb, event, (tAVDT_SCB_EVT *) &p_data->msg); 398 } 399 } 400 } 401 402 /******************************************************************************* 403 ** 404 ** Function avdt_ccb_snd_discover_cmd 405 ** 406 ** Description This function is called to send a discover command to the 407 ** peer. It copies variables needed for the procedure from 408 ** the event to the CCB. It marks the CCB as busy and then 409 ** sends a discover command. 410 ** 411 ** 412 ** Returns void. 413 ** 414 *******************************************************************************/ 415 void avdt_ccb_snd_discover_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 416 { 417 /* store info in ccb struct */ 418 p_ccb->p_proc_data = p_data->discover.p_sep_info; 419 p_ccb->proc_cback = p_data->discover.p_cback; 420 p_ccb->proc_param = p_data->discover.num_seps; 421 422 /* we're busy */ 423 p_ccb->proc_busy = TRUE; 424 425 /* build and queue discover req */ 426 avdt_msg_send_cmd(p_ccb, NULL, AVDT_SIG_DISCOVER, NULL); 427 } 428 429 /******************************************************************************* 430 ** 431 ** Function avdt_ccb_snd_discover_rsp 432 ** 433 ** Description This function is called to send a discover response to 434 ** the peer. It takes the stream information passed in the 435 ** event and sends a discover response. 436 ** 437 ** 438 ** Returns void. 439 ** 440 *******************************************************************************/ 441 void avdt_ccb_snd_discover_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 442 { 443 /* send response */ 444 avdt_msg_send_rsp(p_ccb, AVDT_SIG_DISCOVER, &p_data->msg); 445 } 446 447 /******************************************************************************* 448 ** 449 ** Function avdt_ccb_snd_getcap_cmd 450 ** 451 ** Description This function is called to send a get capabilities command 452 ** to the peer. It copies variables needed for the procedure 453 ** from the event to the CCB. It marks the CCB as busy and 454 ** then sends a get capabilities command. 455 ** 456 ** 457 ** Returns void. 458 ** 459 *******************************************************************************/ 460 void avdt_ccb_snd_getcap_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 461 { 462 UINT8 sig_id = AVDT_SIG_GETCAP; 463 464 /* store info in ccb struct */ 465 p_ccb->p_proc_data = p_data->getcap.p_cfg; 466 p_ccb->proc_cback = p_data->getcap.p_cback; 467 468 /* we're busy */ 469 p_ccb->proc_busy = TRUE; 470 471 /* build and queue discover req */ 472 if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP) 473 sig_id = AVDT_SIG_GET_ALLCAP; 474 475 avdt_msg_send_cmd(p_ccb, NULL, sig_id, (tAVDT_MSG *) &p_data->getcap.single); 476 } 477 478 /******************************************************************************* 479 ** 480 ** Function avdt_ccb_snd_getcap_rsp 481 ** 482 ** Description This function is called to send a get capabilities response 483 ** to the peer. It takes the stream information passed in the 484 ** event and sends a get capabilities response. 485 ** 486 ** 487 ** Returns void. 488 ** 489 *******************************************************************************/ 490 void avdt_ccb_snd_getcap_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 491 { 492 UINT8 sig_id = AVDT_SIG_GETCAP; 493 494 if (p_data->msg.hdr.sig_id == AVDT_SIG_GET_ALLCAP) 495 sig_id = AVDT_SIG_GET_ALLCAP; 496 497 /* send response */ 498 avdt_msg_send_rsp(p_ccb, sig_id, &p_data->msg); 499 } 500 501 /******************************************************************************* 502 ** 503 ** Function avdt_ccb_snd_start_cmd 504 ** 505 ** Description This function is called to send a start command to the 506 ** peer. It verifies that all requested streams are in the 507 ** proper state. If so, it sends a start command. Otherwise 508 ** send ourselves back a start reject. 509 ** 510 ** 511 ** Returns void. 512 ** 513 *******************************************************************************/ 514 void avdt_ccb_snd_start_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 515 { 516 int i; 517 tAVDT_SCB *p_scb; 518 tAVDT_MSG avdt_msg; 519 UINT8 seid_list[AVDT_NUM_SEPS]; 520 521 /* make copy of our seid list */ 522 memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps); 523 524 /* verify all streams in the right state */ 525 if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_OPEN, p_data->msg.multi.seid_list, 526 p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0) 527 { 528 /* set peer seid list in messsage */ 529 avdt_scb_peer_seid_list(&p_data->msg.multi); 530 531 /* send command */ 532 avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_START, &p_data->msg); 533 } 534 else 535 { 536 /* failed; send ourselves a reject for each stream */ 537 for (i = 0; i < p_data->msg.multi.num_seps; i++) 538 { 539 if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL) 540 { 541 avdt_scb_event(p_scb, AVDT_SCB_MSG_START_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr); 542 } 543 } 544 } 545 } 546 547 /******************************************************************************* 548 ** 549 ** Function avdt_ccb_snd_start_rsp 550 ** 551 ** Description This function is called to send a start response to the 552 ** peer. It takes the stream information passed in the event 553 ** and sends a start response. Then it sends a start event 554 ** to the SCB for each stream. 555 ** 556 ** 557 ** Returns void. 558 ** 559 *******************************************************************************/ 560 void avdt_ccb_snd_start_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 561 { 562 tAVDT_SCB *p_scb; 563 int i; 564 565 /* send response message */ 566 avdt_msg_send_rsp(p_ccb, AVDT_SIG_START, &p_data->msg); 567 568 /* send start event to each scb */ 569 for (i = 0; i < p_data->msg.multi.num_seps; i++) 570 { 571 if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL) 572 { 573 avdt_scb_event(p_scb, AVDT_SCB_MSG_START_CMD_EVT, NULL); 574 } 575 } 576 } 577 578 /******************************************************************************* 579 ** 580 ** Function avdt_ccb_snd_suspend_cmd 581 ** 582 ** Description This function is called to send a suspend command to the 583 ** peer. It verifies that all requested streams are in the 584 ** proper state. If so, it sends a suspend command. 585 ** Otherwise it calls the callback function for each requested 586 ** stream and sends a suspend confirmation with failure. 587 ** 588 ** 589 ** Returns void. 590 ** 591 *******************************************************************************/ 592 void avdt_ccb_snd_suspend_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 593 { 594 int i; 595 tAVDT_SCB *p_scb; 596 tAVDT_MSG avdt_msg; 597 UINT8 seid_list[AVDT_NUM_SEPS]; 598 599 /* make copy of our seid list */ 600 memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps); 601 602 /* verify all streams in the right state */ 603 if ((avdt_msg.hdr.err_param = avdt_scb_verify(p_ccb, AVDT_VERIFY_STREAMING, p_data->msg.multi.seid_list, 604 p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code)) == 0) 605 { 606 /* set peer seid list in messsage */ 607 avdt_scb_peer_seid_list(&p_data->msg.multi); 608 609 /* send command */ 610 avdt_msg_send_cmd(p_ccb, seid_list, AVDT_SIG_SUSPEND, &p_data->msg); 611 } 612 else 613 { 614 /* failed; send ourselves a reject for each stream */ 615 for (i = 0; i < p_data->msg.multi.num_seps; i++) 616 { 617 if ((p_scb = avdt_scb_by_hdl(seid_list[i])) != NULL) 618 { 619 avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_REJ_EVT, (tAVDT_SCB_EVT *) &avdt_msg.hdr); 620 } 621 } 622 } 623 } 624 625 /******************************************************************************* 626 ** 627 ** Function avdt_ccb_snd_suspend_rsp 628 ** 629 ** Description This function is called to send a suspend response to the 630 ** peer. It takes the stream information passed in the event 631 ** and sends a suspend response. Then it sends a suspend event 632 ** to the SCB for each stream. 633 ** 634 ** 635 ** Returns void. 636 ** 637 *******************************************************************************/ 638 void avdt_ccb_snd_suspend_rsp(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 639 { 640 tAVDT_SCB *p_scb; 641 int i; 642 643 /* send response message */ 644 avdt_msg_send_rsp(p_ccb, AVDT_SIG_SUSPEND, &p_data->msg); 645 646 /* send start event to each scb */ 647 for (i = 0; i < p_data->msg.multi.num_seps; i++) 648 { 649 if ((p_scb = avdt_scb_by_hdl(p_data->msg.multi.seid_list[i])) != NULL) 650 { 651 avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_CMD_EVT, NULL); 652 } 653 } 654 } 655 656 /******************************************************************************* 657 ** 658 ** Function avdt_ccb_clear_cmds 659 ** 660 ** Description This function is called when the signaling channel is 661 ** closed to clean up any pending commands. For each pending 662 ** command in the command queue, it frees the command and 663 ** calls the application callback function indicating failure. 664 ** Certain CCB variables are also initialized. 665 ** 666 ** 667 ** Returns void. 668 ** 669 *******************************************************************************/ 670 void avdt_ccb_clear_cmds(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 671 { 672 int i; 673 tAVDT_SCB *p_scb = &avdt_cb.scb[0]; 674 UINT8 err_code = AVDT_ERR_CONNECT; 675 UNUSED(p_data); 676 677 /* clear the ccb */ 678 avdt_ccb_clear_ccb(p_ccb); 679 680 /* clear out command queue; this is a little tricky here; we need 681 ** to handle the case where there is a command on deck in p_curr_cmd, 682 ** plus we need to clear out the queue 683 */ 684 do 685 { 686 /* we know p_curr_cmd = NULL after this */ 687 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code); 688 689 /* set up next message */ 690 p_ccb->p_curr_cmd = (BT_HDR *) GKI_dequeue(&p_ccb->cmd_q); 691 692 } while (p_ccb->p_curr_cmd != NULL); 693 694 /* send a CC_CLOSE_EVT any active scbs associated with this ccb */ 695 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) 696 { 697 if ((p_scb->allocated) && (p_scb->p_ccb == p_ccb)) 698 { 699 avdt_scb_event(p_scb, AVDT_SCB_CC_CLOSE_EVT, NULL); 700 } 701 } 702 } 703 704 /******************************************************************************* 705 ** 706 ** Function avdt_ccb_cmd_fail 707 ** 708 ** Description This function is called when there is a response timeout. 709 ** The currently pending command is freed and we fake a 710 ** reject message back to ourselves. 711 ** 712 ** 713 ** Returns void. 714 ** 715 *******************************************************************************/ 716 void avdt_ccb_cmd_fail(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 717 { 718 tAVDT_MSG msg; 719 UINT8 evt; 720 tAVDT_SCB *p_scb; 721 722 if (p_ccb->p_curr_cmd != NULL) 723 { 724 /* set up data */ 725 msg.hdr.err_code = p_data->err_code; 726 msg.hdr.err_param = 0; 727 msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb); 728 729 /* pretend that we received a rej message */ 730 evt = avdt_msg_rej_2_evt[p_ccb->p_curr_cmd->event - 1]; 731 732 if (evt & AVDT_CCB_MKR) 733 { 734 avdt_ccb_event(p_ccb, (UINT8) (evt & ~AVDT_CCB_MKR), (tAVDT_CCB_EVT *) &msg); 735 } 736 else 737 { 738 /* we get the scb out of the current cmd */ 739 p_scb = avdt_scb_by_hdl(*((UINT8 *)(p_ccb->p_curr_cmd + 1))); 740 if (p_scb != NULL) 741 { 742 avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT *) &msg); 743 } 744 } 745 746 GKI_freebuf(p_ccb->p_curr_cmd); 747 p_ccb->p_curr_cmd = NULL; 748 } 749 } 750 751 /******************************************************************************* 752 ** 753 ** Function avdt_ccb_free_cmd 754 ** 755 ** Description This function is called when a response is received for a 756 ** currently pending command. The command is freed. 757 ** 758 ** 759 ** Returns void. 760 ** 761 *******************************************************************************/ 762 void avdt_ccb_free_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 763 { 764 UNUSED(p_data); 765 766 if (p_ccb->p_curr_cmd != NULL) 767 { 768 GKI_freebuf(p_ccb->p_curr_cmd); 769 p_ccb->p_curr_cmd = NULL; 770 } 771 } 772 773 /******************************************************************************* 774 ** 775 ** Function avdt_ccb_cong_state 776 ** 777 ** Description This function is called to set the congestion state for 778 ** the CCB. 779 ** 780 ** 781 ** Returns void. 782 ** 783 *******************************************************************************/ 784 void avdt_ccb_cong_state(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 785 { 786 p_ccb->cong = p_data->llcong; 787 } 788 789 /******************************************************************************* 790 ** 791 ** Function avdt_ccb_ret_cmd 792 ** 793 ** Description This function is called to retransmit the currently 794 ** pending command. The retransmission count is incremented. 795 ** If the count reaches the maximum number of retransmissions, 796 ** the event is treated as a response timeout. 797 ** 798 ** 799 ** Returns void. 800 ** 801 *******************************************************************************/ 802 void avdt_ccb_ret_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 803 { 804 UINT8 err_code = AVDT_ERR_TIMEOUT; 805 BT_HDR *p_msg; 806 807 p_ccb->ret_count++; 808 if (p_ccb->ret_count == AVDT_RET_MAX) 809 { 810 /* command failed */ 811 p_ccb->ret_count = 0; 812 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code); 813 814 /* go to next queued command */ 815 avdt_ccb_snd_cmd(p_ccb, p_data); 816 } 817 else 818 { 819 /* if command pending and we're not congested and not sending a fragment */ 820 if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd != NULL)) 821 { 822 /* make copy of message in p_curr_cmd and send it */ 823 if ((p_msg = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) != NULL) 824 { 825 memcpy(p_msg, p_ccb->p_curr_cmd, 826 (sizeof(BT_HDR) + p_ccb->p_curr_cmd->offset + p_ccb->p_curr_cmd->len)); 827 avdt_msg_send(p_ccb, p_msg); 828 } 829 } 830 831 /* restart timer */ 832 btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_AVDT_CCB_RET, avdt_cb.rcb.ret_tout); 833 } 834 } 835 836 /******************************************************************************* 837 ** 838 ** Function avdt_ccb_snd_cmd 839 ** 840 ** Description This function is called the send the next command, 841 ** if any, in the command queue. 842 ** 843 ** 844 ** Returns void. 845 ** 846 *******************************************************************************/ 847 void avdt_ccb_snd_cmd(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 848 { 849 BT_HDR *p_msg; 850 UNUSED(p_data); 851 852 /* do we have commands to send? send next command; make sure we're clear; 853 ** not congested, not sending fragment, not waiting for response 854 */ 855 if ((!p_ccb->cong) && (p_ccb->p_curr_msg == NULL) && (p_ccb->p_curr_cmd == NULL)) 856 { 857 if ((p_msg = (BT_HDR *) GKI_dequeue(&p_ccb->cmd_q)) != NULL) 858 { 859 /* make a copy of buffer in p_curr_cmd */ 860 if ((p_ccb->p_curr_cmd = (BT_HDR *) GKI_getpoolbuf(AVDT_CMD_POOL_ID)) != NULL) 861 { 862 memcpy(p_ccb->p_curr_cmd, p_msg, (sizeof(BT_HDR) + p_msg->offset + p_msg->len)); 863 864 avdt_msg_send(p_ccb, p_msg); 865 } 866 } 867 } 868 } 869 870 /******************************************************************************* 871 ** 872 ** Function avdt_ccb_snd_msg 873 ** 874 ** Description 875 ** 876 ** 877 ** Returns void. 878 ** 879 *******************************************************************************/ 880 void avdt_ccb_snd_msg(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 881 { 882 BT_HDR *p_msg; 883 UNUSED(p_data); 884 885 /* if not congested */ 886 if (!p_ccb->cong) 887 { 888 /* are we sending a fragmented message? continue sending fragment */ 889 if (p_ccb->p_curr_msg != NULL) 890 { 891 avdt_msg_send(p_ccb, NULL); 892 } 893 /* do we have responses to send? send them */ 894 else if (!GKI_queue_is_empty(&p_ccb->rsp_q)) 895 { 896 while ((p_msg = (BT_HDR *) GKI_dequeue(&p_ccb->rsp_q)) != NULL) 897 { 898 if (avdt_msg_send(p_ccb, p_msg) == TRUE) 899 { 900 /* break out if congested */ 901 break; 902 } 903 } 904 } 905 906 /* do we have commands to send? send next command */ 907 avdt_ccb_snd_cmd(p_ccb, NULL); 908 } 909 } 910 911 /******************************************************************************* 912 ** 913 ** Function avdt_ccb_set_reconn 914 ** 915 ** Description This function is called to enable a reconnect attempt when 916 ** a channel transitions from closing to idle state. It sets 917 ** the reconn variable to TRUE. 918 ** 919 ** 920 ** Returns void. 921 ** 922 *******************************************************************************/ 923 void avdt_ccb_set_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 924 { 925 UNUSED(p_data); 926 927 p_ccb->reconn = TRUE; 928 } 929 930 /******************************************************************************* 931 ** 932 ** Function avdt_ccb_clr_reconn 933 ** 934 ** Description This function is called to clear the reconn variable. 935 ** 936 ** 937 ** Returns void. 938 ** 939 *******************************************************************************/ 940 void avdt_ccb_clr_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 941 { 942 UNUSED(p_data); 943 944 p_ccb->reconn = FALSE; 945 } 946 947 /******************************************************************************* 948 ** 949 ** Function avdt_ccb_chk_reconn 950 ** 951 ** Description This function is called to check if a reconnect attempt 952 ** is enabled. If enabled, it sends an AVDT_CCB_UL_OPEN_EVT 953 ** to the CCB. If disabled, the CCB is deallocated. 954 ** 955 ** 956 ** Returns void. 957 ** 958 *******************************************************************************/ 959 void avdt_ccb_chk_reconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 960 { 961 UINT8 err_code = AVDT_ERR_CONNECT; 962 UNUSED(p_data); 963 964 if (p_ccb->reconn) 965 { 966 p_ccb->reconn = FALSE; 967 968 /* clear out ccb */ 969 avdt_ccb_clear_ccb(p_ccb); 970 971 /* clear out current command, if any */ 972 avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT *) &err_code); 973 974 /* reopen the signaling channel */ 975 avdt_ccb_event(p_ccb, AVDT_CCB_UL_OPEN_EVT, NULL); 976 } 977 else 978 { 979 avdt_ccb_ll_closed(p_ccb, NULL); 980 } 981 } 982 983 /******************************************************************************* 984 ** 985 ** Function avdt_ccb_chk_timer 986 ** 987 ** Description This function stops the CCB timer if the idle timer is 988 ** running. 989 ** 990 ** 991 ** Returns void. 992 ** 993 *******************************************************************************/ 994 void avdt_ccb_chk_timer(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 995 { 996 UNUSED(p_data); 997 998 if (p_ccb->timer_entry.event == BTU_TTYPE_AVDT_CCB_IDLE) 999 { 1000 btu_stop_timer(&p_ccb->timer_entry); 1001 } 1002 } 1003 1004 /******************************************************************************* 1005 ** 1006 ** Function avdt_ccb_set_conn 1007 ** 1008 ** Description Set CCB variables associated with AVDT_ConnectReq(). 1009 ** 1010 ** 1011 ** Returns void. 1012 ** 1013 *******************************************************************************/ 1014 void avdt_ccb_set_conn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1015 { 1016 /* save callback */ 1017 p_ccb->p_conn_cback = p_data->connect.p_cback; 1018 1019 /* set security level */ 1020 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_data->connect.sec_mask, 1021 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG); 1022 } 1023 1024 /******************************************************************************* 1025 ** 1026 ** Function avdt_ccb_set_disconn 1027 ** 1028 ** Description Set CCB variables associated with AVDT_DisconnectReq(). 1029 ** 1030 ** 1031 ** Returns void. 1032 ** 1033 *******************************************************************************/ 1034 void avdt_ccb_set_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1035 { 1036 /* 1037 AVDT_TRACE_EVENT("avdt_ccb_set_disconn:conn:x%x, api:x%x", 1038 p_ccb->p_conn_cback, p_data->disconnect.p_cback); 1039 */ 1040 /* save callback */ 1041 if (p_data->disconnect.p_cback) 1042 p_ccb->p_conn_cback = p_data->disconnect.p_cback; 1043 } 1044 1045 /******************************************************************************* 1046 ** 1047 ** Function avdt_ccb_do_disconn 1048 ** 1049 ** Description Do action associated with AVDT_DisconnectReq(). 1050 ** 1051 ** 1052 ** Returns void. 1053 ** 1054 *******************************************************************************/ 1055 void avdt_ccb_do_disconn(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1056 { 1057 UNUSED(p_data); 1058 1059 /* clear any pending commands */ 1060 avdt_ccb_clear_cmds(p_ccb, NULL); 1061 1062 /* close channel */ 1063 avdt_ccb_chan_close(p_ccb, NULL); 1064 } 1065 1066 /******************************************************************************* 1067 ** 1068 ** Function avdt_ccb_ll_closed 1069 ** 1070 ** Description Clear commands from and deallocate CCB. 1071 ** 1072 ** 1073 ** Returns void. 1074 ** 1075 *******************************************************************************/ 1076 void avdt_ccb_ll_closed(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1077 { 1078 tAVDT_CTRL_CBACK *p_cback; 1079 BD_ADDR bd_addr; 1080 tAVDT_CTRL avdt_ctrl; 1081 UNUSED(p_data); 1082 1083 /* clear any pending commands */ 1084 avdt_ccb_clear_cmds(p_ccb, NULL); 1085 1086 /* save callback pointer, bd addr */ 1087 p_cback = p_ccb->p_conn_cback; 1088 if (!p_cback) 1089 p_cback = avdt_cb.p_conn_cback; 1090 memcpy(bd_addr, p_ccb->peer_addr, BD_ADDR_LEN); 1091 1092 /* dealloc ccb */ 1093 avdt_ccb_dealloc(p_ccb, NULL); 1094 1095 /* call callback */ 1096 if (p_cback) 1097 { 1098 avdt_ctrl.hdr.err_code = 0; 1099 (*p_cback)(0, bd_addr, AVDT_DISCONNECT_IND_EVT, &avdt_ctrl); 1100 } 1101 } 1102 1103 /******************************************************************************* 1104 ** 1105 ** Function avdt_ccb_ll_opened 1106 ** 1107 ** Description Call callback on open. 1108 ** 1109 ** 1110 ** Returns void. 1111 ** 1112 *******************************************************************************/ 1113 void avdt_ccb_ll_opened(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data) 1114 { 1115 tAVDT_CTRL avdt_ctrl; 1116 1117 p_ccb->ll_opened = TRUE; 1118 1119 if (!p_ccb->p_conn_cback) 1120 p_ccb->p_conn_cback = avdt_cb.p_conn_cback; 1121 1122 /* call callback */ 1123 if (p_ccb->p_conn_cback) 1124 { 1125 avdt_ctrl.hdr.err_code = 0; 1126 avdt_ctrl.hdr.err_param = p_data->msg.hdr.err_param; 1127 (*p_ccb->p_conn_cback)(0, p_ccb->peer_addr, AVDT_CONNECT_IND_EVT, &avdt_ctrl); 1128 } 1129 } 1130