1 /****************************************************************************** 2 * 3 * Copyright (C) 2003-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file implements utility functions for the HeaLth device profile 22 * (HL). 23 * 24 ******************************************************************************/ 25 26 #include <stdio.h> 27 #include <string.h> 28 29 #include "bt_target.h" 30 #if defined(HL_INCLUDED) && (HL_INCLUDED == TRUE) 31 32 33 #include "bt_common.h" 34 #include "utl.h" 35 #include "bta_hl_int.h" 36 #include "bta_hl_co.h" 37 #include "mca_defs.h" 38 #include "mca_api.h" 39 40 41 /******************************************************************************* 42 ** 43 ** Function bta_hl_set_ctrl_psm_for_dch 44 ** 45 ** Description This function set the control PSM for the DCH setup 46 ** 47 ** Returns BOOLEAN - TRUE - control PSM setting is successful 48 *******************************************************************************/ 49 BOOLEAN bta_hl_set_ctrl_psm_for_dch(UINT8 app_idx, UINT8 mcl_idx, 50 UINT8 mdl_idx, UINT16 ctrl_psm) 51 { 52 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 53 BOOLEAN success = TRUE, update_ctrl_psm = FALSE; 54 UNUSED(mdl_idx); 55 56 if (p_mcb->sdp.num_recs) 57 { 58 if (p_mcb->ctrl_psm != ctrl_psm) 59 { 60 /* can not use a different ctrl PSM than the current one*/ 61 success = FALSE; 62 } 63 } 64 else 65 { 66 /* No SDP info control i.e. channel was opened by the peer */ 67 update_ctrl_psm = TRUE; 68 } 69 70 if (success && update_ctrl_psm) 71 { 72 p_mcb->ctrl_psm = ctrl_psm; 73 } 74 75 76 #if BTA_HL_DEBUG == TRUE 77 if (!success) 78 { 79 APPL_TRACE_DEBUG("bta_hl_set_ctrl_psm_for_dch num_recs=%d success=%d update_ctrl_psm=%d ctrl_psm=0x%x ", 80 p_mcb->sdp.num_recs, success, update_ctrl_psm, ctrl_psm ); 81 } 82 #endif 83 84 return success; 85 } 86 87 88 /******************************************************************************* 89 ** 90 ** Function bta_hl_find_sdp_idx_using_ctrl_psm 91 ** 92 ** Description 93 ** 94 ** Returns TRUE if found 95 ** 96 *******************************************************************************/ 97 BOOLEAN bta_hl_find_sdp_idx_using_ctrl_psm(tBTA_HL_SDP *p_sdp, 98 UINT16 ctrl_psm, 99 UINT8 *p_sdp_idx) 100 { 101 BOOLEAN found=FALSE; 102 tBTA_HL_SDP_REC *p_rec; 103 UINT8 i; 104 105 if (ctrl_psm != 0) 106 { 107 for (i=0; i<p_sdp->num_recs; i++) 108 { 109 p_rec = &p_sdp->sdp_rec[i]; 110 if (p_rec->ctrl_psm == ctrl_psm) 111 { 112 *p_sdp_idx = i; 113 found = TRUE; 114 break; 115 } 116 } 117 } 118 else 119 { 120 *p_sdp_idx = 0; 121 found = TRUE; 122 } 123 124 #if BTA_HL_DEBUG == TRUE 125 if (!found) 126 { 127 APPL_TRACE_DEBUG("bta_hl_find_sdp_idx_using_ctrl_psm found=%d sdp_idx=%d ctrl_psm=0x%x ", 128 found, *p_sdp_idx, ctrl_psm ); 129 } 130 #endif 131 return found; 132 } 133 134 /******************************************************************************* 135 ** 136 ** Function bta_hl_set_user_tx_buf_size 137 ** 138 ** Description This function sets the user tx buffer size 139 ** 140 ** Returns UINT16 buf_size 141 ** 142 *******************************************************************************/ 143 144 UINT16 bta_hl_set_user_tx_buf_size(UINT16 max_tx_size) 145 { 146 if (max_tx_size > BT_DEFAULT_BUFFER_SIZE) 147 return BTA_HL_LRG_DATA_BUF_SIZE; 148 return L2CAP_INVALID_ERM_BUF_SIZE; 149 } 150 151 /******************************************************************************* 152 ** 153 ** Function bta_hl_set_user_rx_buf_size 154 ** 155 ** Description This function sets the user rx buffer size 156 ** 157 ** Returns UINT16 buf_size 158 ** 159 *******************************************************************************/ 160 161 UINT16 bta_hl_set_user_rx_buf_size(UINT16 mtu) 162 { 163 if (mtu > BT_DEFAULT_BUFFER_SIZE) 164 return BTA_HL_LRG_DATA_BUF_SIZE; 165 return L2CAP_INVALID_ERM_BUF_SIZE; 166 } 167 168 169 170 /******************************************************************************* 171 ** 172 ** Function bta_hl_set_tx_win_size 173 ** 174 ** Description This function sets the tx window size 175 ** 176 ** Returns UINT8 tx_win_size 177 ** 178 *******************************************************************************/ 179 UINT8 bta_hl_set_tx_win_size(UINT16 mtu, UINT16 mps) 180 { 181 UINT8 tx_win_size; 182 183 if (mtu <= mps) 184 { 185 tx_win_size =1; 186 } 187 else 188 { 189 if (mps > 0) 190 { 191 tx_win_size = (mtu/mps)+1; 192 } 193 else 194 { 195 APPL_TRACE_ERROR("The MPS is zero"); 196 tx_win_size = 10; 197 } 198 } 199 200 #if BTA_HL_DEBUG == TRUE 201 APPL_TRACE_DEBUG("bta_hl_set_tx_win_size win_size=%d mtu=%d mps=%d", 202 tx_win_size, mtu, mps); 203 #endif 204 return tx_win_size; 205 } 206 207 /******************************************************************************* 208 ** 209 ** Function bta_hl_set_mps 210 ** 211 ** Description This function sets the MPS 212 ** 213 ** Returns UINT16 MPS 214 ** 215 *******************************************************************************/ 216 UINT16 bta_hl_set_mps(UINT16 mtu) 217 { 218 UINT16 mps; 219 if (mtu > BTA_HL_L2C_MPS) 220 { 221 mps = BTA_HL_L2C_MPS; 222 } 223 else 224 { 225 mps = mtu; 226 } 227 #if BTA_HL_DEBUG == TRUE 228 APPL_TRACE_DEBUG("bta_hl_set_mps mps=%d mtu=%d", 229 mps, mtu); 230 #endif 231 return mps; 232 } 233 234 235 /******************************************************************************* 236 ** 237 ** Function bta_hl_clean_mdl_cb 238 ** 239 ** Description This function clean up the specified MDL control block 240 ** 241 ** Returns void 242 ** 243 *******************************************************************************/ 244 void bta_hl_clean_mdl_cb(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx) 245 { 246 tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 247 #if BTA_HL_DEBUG == TRUE 248 APPL_TRACE_DEBUG("bta_hl_clean_mdl_cb app_idx=%d mcl_idx=%d mdl_idx=%d", 249 app_idx, mcl_idx, mdl_idx); 250 #endif 251 osi_free_and_reset((void **)&p_dcb->p_tx_pkt); 252 osi_free_and_reset((void **)&p_dcb->p_rx_pkt); 253 osi_free_and_reset((void **)&p_dcb->p_echo_tx_pkt); 254 osi_free_and_reset((void **)&p_dcb->p_echo_rx_pkt); 255 256 memset((void *)p_dcb, 0 , sizeof(tBTA_HL_MDL_CB)); 257 } 258 259 260 /******************************************************************************* 261 ** 262 ** Function bta_hl_get_buf 263 ** 264 ** Description This function allocate a buffer based on the specified data size 265 ** 266 ** Returns BT_HDR *. 267 ** 268 *******************************************************************************/ 269 BT_HDR * bta_hl_get_buf(UINT16 data_size, BOOLEAN fcs_use) 270 { 271 size_t size = data_size + L2CAP_MIN_OFFSET + BT_HDR_SIZE + L2CAP_FCS_LEN 272 + L2CAP_EXT_CONTROL_OVERHEAD; 273 274 if (fcs_use) 275 size += L2CAP_FCS_LEN; 276 277 BT_HDR *p_new = (BT_HDR *)osi_malloc(size); 278 p_new->len = data_size; 279 p_new->offset = L2CAP_MIN_OFFSET; 280 281 return p_new; 282 } 283 284 /******************************************************************************* 285 ** 286 ** Function bta_hl_find_service_in_db 287 ** 288 ** Description This function check the specified service class(es) can be find in 289 ** the received SDP database 290 ** 291 ** Returns BOOLEAN TRUE - found 292 ** FALSE - not found 293 ** 294 *******************************************************************************/ 295 BOOLEAN bta_hl_find_service_in_db( UINT8 app_idx, UINT8 mcl_idx, 296 UINT16 service_uuid, 297 tSDP_DISC_REC **pp_rec ) 298 { 299 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 300 BOOLEAN found = TRUE; 301 302 switch (service_uuid) 303 { 304 case UUID_SERVCLASS_HDP_SINK: 305 case UUID_SERVCLASS_HDP_SOURCE: 306 if ((*pp_rec = SDP_FindServiceInDb(p_mcb->p_db, service_uuid, 307 *pp_rec)) == NULL) 308 { 309 found = FALSE; 310 } 311 break; 312 default: 313 if (((*pp_rec = bta_hl_find_sink_or_src_srv_class_in_db(p_mcb->p_db, 314 *pp_rec)) == NULL)) 315 { 316 found = FALSE; 317 } 318 break; 319 } 320 return found; 321 } 322 323 /******************************************************************************* 324 ** 325 ** Function bta_hl_get_service_uuids 326 ** 327 ** 328 ** Description This function finds the service class(es) for both CCH and DCH oeprations 329 ** 330 ** Returns UINT16 - service_id 331 ** if service_uuid = 0xFFFF then it means service uuid 332 ** can be either Sink or Source 333 ** 334 *******************************************************************************/ 335 UINT16 bta_hl_get_service_uuids(UINT8 sdp_oper, UINT8 app_idx, UINT8 mcl_idx, 336 UINT8 mdl_idx ) 337 { 338 tBTA_HL_MDL_CB *p_dcb; 339 UINT16 service_uuid = 0xFFFF; /* both Sink and Source */ 340 341 switch (sdp_oper) 342 { 343 344 case BTA_HL_SDP_OP_DCH_OPEN_INIT: 345 case BTA_HL_SDP_OP_DCH_RECONNECT_INIT: 346 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 347 if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) 348 { 349 if (p_dcb->peer_mdep_role == BTA_HL_MDEP_ROLE_SINK) 350 { 351 service_uuid = UUID_SERVCLASS_HDP_SINK; 352 } 353 else 354 { 355 service_uuid = UUID_SERVCLASS_HDP_SOURCE; 356 } 357 } 358 break; 359 case BTA_HL_SDP_OP_CCH_INIT: 360 default: 361 /* use default that is both Sink and Source */ 362 break; 363 } 364 #if BTA_HL_DEBUG == TRUE 365 APPL_TRACE_DEBUG("bta_hl_get_service_uuids service_uuid=0x%x",service_uuid ); 366 #endif 367 return service_uuid; 368 } 369 370 /******************************************************************************* 371 ** 372 ** Function bta_hl_find_echo_cfg_rsp 373 ** 374 ** 375 ** Description This function finds the configuration response for the echo test 376 ** 377 ** Returns BOOLEAN - TRUE found 378 ** FALSE not found 379 ** 380 *******************************************************************************/ 381 BOOLEAN bta_hl_find_echo_cfg_rsp(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdep_idx, UINT8 cfg, 382 UINT8 *p_cfg_rsp) 383 { 384 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 385 tBTA_HL_MDEP *p_mdep= &p_acb->sup_feature.mdep[mdep_idx]; 386 BOOLEAN status =TRUE; 387 388 if (p_mdep->mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) 389 { 390 if ((cfg == BTA_HL_DCH_CFG_RELIABLE) || (cfg == BTA_HL_DCH_CFG_STREAMING)) 391 { 392 *p_cfg_rsp = cfg; 393 } 394 else if (cfg == BTA_HL_DCH_CFG_NO_PREF ) 395 { 396 *p_cfg_rsp = BTA_HL_DEFAULT_ECHO_TEST_SRC_DCH_CFG; 397 } 398 else 399 { 400 status = FALSE; 401 APPL_TRACE_ERROR("Inavlid echo cfg value"); 402 } 403 return status; 404 } 405 406 #if BTA_HL_DEBUG == TRUE 407 if (!status) 408 { 409 APPL_TRACE_DEBUG("bta_hl_find_echo_cfg_rsp status=failed app_idx=%d mcl_idx=%d mdep_idx=%d cfg=%d", 410 app_idx, mcl_idx, mdep_idx, cfg); 411 } 412 #endif 413 414 return status; 415 } 416 417 /******************************************************************************* 418 ** 419 ** Function bta_hl_validate_dch_cfg 420 ** 421 ** Description This function validate the DCH configuration 422 ** 423 ** Returns BOOLEAN - TRUE cfg is valid 424 ** FALSE not valid 425 ** 426 *******************************************************************************/ 427 BOOLEAN bta_hl_validate_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx, 428 UINT8 cfg) 429 { 430 tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 431 BOOLEAN is_valid =FALSE; 432 433 434 if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx) && 435 (cfg != BTA_HL_DCH_CFG_RELIABLE)) 436 { 437 APPL_TRACE_ERROR("the first DCH should be a reliable channel"); 438 return is_valid; 439 } 440 441 switch (p_dcb->local_cfg) 442 { 443 case BTA_HL_DCH_CFG_NO_PREF: 444 445 if ((cfg == BTA_HL_DCH_CFG_RELIABLE) || (cfg == BTA_HL_DCH_CFG_STREAMING)) 446 { 447 is_valid = TRUE; 448 } 449 break; 450 case BTA_HL_DCH_CFG_RELIABLE: 451 case BTA_HL_DCH_CFG_STREAMING: 452 if (p_dcb->local_cfg == cfg ) 453 { 454 is_valid = TRUE; 455 } 456 break; 457 default: 458 break; 459 } 460 461 #if BTA_HL_DEBUG == TRUE 462 if (!is_valid) 463 { 464 APPL_TRACE_DEBUG("bta_hl_validate_dch_open_cfg is_valid=%d, cfg=%d", is_valid, cfg ); 465 } 466 #endif 467 return is_valid; 468 } 469 470 /******************************************************************************* 471 ** 472 ** Function bta_hl_find_cch_cb_indexes 473 ** 474 ** Description This function finds the indexes needed for the CCH state machine 475 ** 476 ** Returns BOOLEAN - TRUE found 477 ** FALSE not found 478 ** 479 *******************************************************************************/ 480 BOOLEAN bta_hl_find_cch_cb_indexes(tBTA_HL_DATA *p_msg, 481 UINT8 *p_app_idx, 482 UINT8 *p_mcl_idx) 483 { 484 BOOLEAN found = FALSE; 485 tBTA_HL_MCL_CB *p_mcb; 486 UINT8 app_idx = 0, mcl_idx = 0; 487 488 switch (p_msg->hdr.event) 489 { 490 case BTA_HL_CCH_SDP_OK_EVT: 491 case BTA_HL_CCH_SDP_FAIL_EVT: 492 app_idx = p_msg->cch_sdp.app_idx; 493 mcl_idx = p_msg->cch_sdp.mcl_idx; 494 found = TRUE; 495 break; 496 497 case BTA_HL_MCA_CONNECT_IND_EVT: 498 499 if (bta_hl_find_app_idx_using_handle(p_msg->mca_evt.app_handle, &app_idx)) 500 { 501 if (bta_hl_find_mcl_idx(app_idx, p_msg->mca_evt.mca_data.connect_ind.bd_addr, &mcl_idx)) 502 { 503 /* local initiated */ 504 found = TRUE; 505 } 506 else if (!bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx)&& 507 bta_hl_find_avail_mcl_idx(app_idx, &mcl_idx)) 508 { 509 /* remote initiated */ 510 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 511 p_mcb->in_use = TRUE; 512 p_mcb->cch_oper = BTA_HL_CCH_OP_REMOTE_OPEN; 513 found = TRUE; 514 } 515 } 516 break; 517 518 case BTA_HL_MCA_DISCONNECT_IND_EVT: 519 520 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx)) 521 { 522 found = TRUE; 523 } 524 else if (bta_hl_find_app_idx_using_handle(p_msg->mca_evt.app_handle, &app_idx) && 525 bta_hl_find_mcl_idx(app_idx, p_msg->mca_evt.mca_data.disconnect_ind.bd_addr, &mcl_idx)) 526 { 527 found = TRUE; 528 } 529 530 if (found) 531 { 532 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 533 if ((p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE) && (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_OPEN) ) 534 { 535 p_mcb->cch_oper = BTA_HL_CCH_OP_REMOTE_CLOSE; 536 } 537 } 538 break; 539 540 case BTA_HL_MCA_RSP_TOUT_IND_EVT: 541 542 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx)) 543 { 544 found = TRUE; 545 } 546 547 if (found) 548 { 549 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 550 if ((p_mcb->cch_oper != BTA_HL_CCH_OP_REMOTE_CLOSE) && (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_OPEN)) 551 { 552 p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE; 553 } 554 } 555 break; 556 default: 557 break; 558 } 559 560 561 if (found) 562 { 563 *p_app_idx = app_idx; 564 *p_mcl_idx = mcl_idx; 565 } 566 567 #if BTA_HL_DEBUG == TRUE 568 if (!found) 569 { 570 APPL_TRACE_DEBUG("bta_hl_find_cch_cb_indexes event=%s found=%d app_idx=%d mcl_idx=%d", 571 bta_hl_evt_code(p_msg->hdr.event), found, app_idx, mcl_idx); 572 } 573 #endif 574 575 return found; 576 } 577 578 /******************************************************************************* 579 ** 580 ** Function bta_hl_find_dch_cb_indexes 581 ** 582 ** Description This function finds the indexes needed for the DCH state machine 583 ** 584 ** Returns BOOLEAN - TRUE found 585 ** FALSE not found 586 ** 587 *******************************************************************************/ 588 BOOLEAN bta_hl_find_dch_cb_indexes(tBTA_HL_DATA *p_msg, 589 UINT8 *p_app_idx, 590 UINT8 *p_mcl_idx, 591 UINT8 *p_mdl_idx) 592 { 593 BOOLEAN found = FALSE; 594 tBTA_HL_MCL_CB *p_mcb; 595 UINT8 app_idx = 0, mcl_idx = 0, mdl_idx = 0; 596 597 switch (p_msg->hdr.event) 598 { 599 case BTA_HL_MCA_CREATE_CFM_EVT: 600 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx) && 601 bta_hl_find_mdl_idx( app_idx, mcl_idx, p_msg->mca_evt.mca_data.create_cfm.mdl_id, &mdl_idx)) 602 { 603 found = TRUE; 604 } 605 break; 606 607 case BTA_HL_MCA_CREATE_IND_EVT: 608 case BTA_HL_MCA_RECONNECT_IND_EVT: 609 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx) && 610 bta_hl_find_avail_mdl_idx( app_idx, mcl_idx, &mdl_idx)) 611 { 612 found = TRUE; 613 } 614 break; 615 616 case BTA_HL_MCA_OPEN_CFM_EVT: 617 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx) && 618 bta_hl_find_mdl_idx( app_idx, mcl_idx, p_msg->mca_evt.mca_data.open_cfm.mdl_id, &mdl_idx)) 619 { 620 found = TRUE; 621 } 622 break; 623 624 case BTA_HL_MCA_OPEN_IND_EVT: 625 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx) && 626 bta_hl_find_mdl_idx( app_idx, mcl_idx, p_msg->mca_evt.mca_data.open_ind.mdl_id, &mdl_idx)) 627 { 628 found = TRUE; 629 } 630 break; 631 632 case BTA_HL_MCA_CLOSE_CFM_EVT: 633 634 if (bta_hl_find_mdl_idx_using_handle((tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.close_cfm.mdl, 635 &app_idx, &mcl_idx, &mdl_idx)) 636 { 637 found = TRUE; 638 } 639 break; 640 case BTA_HL_MCA_CLOSE_IND_EVT: 641 642 if (bta_hl_find_mdl_idx_using_handle((tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.close_ind.mdl, 643 &app_idx, &mcl_idx, &mdl_idx)) 644 { 645 found = TRUE; 646 } 647 break; 648 case BTA_HL_API_SEND_DATA_EVT: 649 650 if (bta_hl_find_mdl_idx_using_handle(p_msg->api_send_data.mdl_handle, 651 &app_idx, &mcl_idx, &mdl_idx )) 652 { 653 found = TRUE; 654 } 655 656 break; 657 658 case BTA_HL_MCA_CONG_CHG_EVT: 659 660 if (bta_hl_find_mdl_idx_using_handle((tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.cong_chg.mdl, 661 &app_idx, &mcl_idx, &mdl_idx )) 662 { 663 found = TRUE; 664 } 665 666 break; 667 668 case BTA_HL_MCA_RCV_DATA_EVT: 669 app_idx = p_msg->mca_rcv_data_evt.app_idx; 670 mcl_idx = p_msg->mca_rcv_data_evt.mcl_idx; 671 mdl_idx = p_msg->mca_rcv_data_evt.mdl_idx; 672 found = TRUE; 673 break; 674 case BTA_HL_DCH_RECONNECT_EVT: 675 case BTA_HL_DCH_OPEN_EVT: 676 case BTA_HL_DCH_ECHO_TEST_EVT: 677 case BTA_HL_DCH_SDP_FAIL_EVT: 678 app_idx = p_msg->dch_sdp.app_idx; 679 mcl_idx = p_msg->dch_sdp.mcl_idx; 680 mdl_idx = p_msg->dch_sdp.mdl_idx; 681 found = TRUE; 682 break; 683 case BTA_HL_MCA_RECONNECT_CFM_EVT: 684 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx) && 685 bta_hl_find_mdl_idx( app_idx, mcl_idx, p_msg->mca_evt.mca_data.reconnect_cfm.mdl_id, &mdl_idx)) 686 { 687 found = TRUE; 688 } 689 break; 690 691 692 case BTA_HL_API_DCH_CREATE_RSP_EVT: 693 if (bta_hl_find_mcl_idx_using_handle(p_msg->api_dch_create_rsp.mcl_handle, &app_idx, &mcl_idx)&& 694 bta_hl_find_mdl_idx( app_idx, mcl_idx,p_msg->api_dch_create_rsp.mdl_id, &mdl_idx)) 695 { 696 found = TRUE; 697 } 698 break; 699 case BTA_HL_MCA_ABORT_IND_EVT: 700 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx) && 701 bta_hl_find_mdl_idx( app_idx, mcl_idx,p_msg->mca_evt.mca_data.abort_ind.mdl_id, &mdl_idx)) 702 { 703 found = TRUE; 704 } 705 break; 706 case BTA_HL_MCA_ABORT_CFM_EVT: 707 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx, &mcl_idx) && 708 bta_hl_find_mdl_idx( app_idx, mcl_idx, p_msg->mca_evt.mca_data.abort_cfm.mdl_id, &mdl_idx)) 709 { 710 found = TRUE; 711 } 712 break; 713 case BTA_HL_CI_GET_TX_DATA_EVT: 714 case BTA_HL_CI_PUT_RX_DATA_EVT: 715 if (bta_hl_find_mdl_idx_using_handle(p_msg->ci_get_put_data.mdl_handle, &app_idx, &mcl_idx, &mdl_idx)) 716 { 717 found = TRUE; 718 } 719 break; 720 case BTA_HL_CI_GET_ECHO_DATA_EVT: 721 case BTA_HL_CI_PUT_ECHO_DATA_EVT: 722 if (bta_hl_find_mcl_idx_using_handle(p_msg->ci_get_put_echo_data.mcl_handle, &app_idx, &mcl_idx)) 723 { 724 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 725 mdl_idx = p_mcb->echo_mdl_idx; 726 found = TRUE; 727 } 728 break; 729 730 default: 731 break; 732 733 } 734 735 if (found) 736 { 737 *p_app_idx = app_idx; 738 *p_mcl_idx = mcl_idx; 739 *p_mdl_idx = mdl_idx; 740 } 741 #if BTA_HL_DEBUG == TRUE 742 if (!found) 743 { 744 APPL_TRACE_DEBUG("bta_hl_find_dch_cb_indexes event=%s found=%d app_idx=%d mcl_idx=%d mdl_idx=%d", 745 bta_hl_evt_code(p_msg->hdr.event), found, *p_app_idx, *p_mcl_idx, *p_mdl_idx ); 746 } 747 #endif 748 749 return found; 750 } 751 752 /******************************************************************************* 753 ** 754 ** Function bta_hl_allocate_mdl_id 755 ** 756 ** Description This function allocates a MDL ID 757 ** 758 ** Returns UINT16 - MDL ID 759 ** 760 *******************************************************************************/ 761 UINT16 bta_hl_allocate_mdl_id(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx ) 762 { 763 UINT16 mdl_id=0; 764 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 765 BOOLEAN duplicate_id; 766 UINT8 i, mdl_cfg_idx; 767 768 do 769 { 770 duplicate_id = FALSE; 771 mdl_id = ((mdl_id+1) & 0xFEFF); 772 /* check mdl_ids that are used for the current conenctions */ 773 for (i=0; i< BTA_HL_NUM_MDLS_PER_MCL; i++) 774 { 775 if (p_mcb->mdl[i].in_use && 776 (i != mdl_idx) && 777 (p_mcb->mdl[i].mdl_id == mdl_id) ) 778 { 779 duplicate_id = TRUE; 780 break; 781 } 782 } 783 784 if (duplicate_id) 785 { 786 /* start from the beginning to get another MDL value*/ 787 continue; 788 } 789 else 790 { 791 /* check mdl_ids that are stored in the persistent memory */ 792 if (bta_hl_find_mdl_cfg_idx(app_idx,mcl_idx, mdl_id, &mdl_cfg_idx)) 793 { 794 duplicate_id = TRUE; 795 } 796 else 797 { 798 /* found a new MDL value */ 799 break; 800 } 801 } 802 803 }while (TRUE); 804 805 #if BTA_HL_DEBUG == TRUE 806 APPL_TRACE_DEBUG("bta_hl_allocate_mdl OK mdl_id=%d", mdl_id); 807 #endif 808 return mdl_id; 809 } 810 /******************************************************************************* 811 ** 812 ** Function bta_hl_find_mdl_idx 813 ** 814 ** Description This function finds the MDL index based on mdl_id 815 ** 816 ** Returns BOOLEAN TRUE-found 817 ** 818 *******************************************************************************/ 819 BOOLEAN bta_hl_find_mdl_idx(UINT8 app_idx, UINT8 mcl_idx, UINT16 mdl_id, 820 UINT8 *p_mdl_idx) 821 { 822 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 823 BOOLEAN found=FALSE; 824 UINT8 i; 825 826 for (i=0; i < BTA_HL_NUM_MDLS_PER_MCL ; i ++) 827 { 828 if (p_mcb->mdl[i].in_use && 829 (mdl_id !=0) && 830 (p_mcb->mdl[i].mdl_id== mdl_id)) 831 { 832 found = TRUE; 833 *p_mdl_idx = i; 834 break; 835 } 836 } 837 838 #if BTA_HL_DEBUG == TRUE 839 if (!found) 840 { 841 APPL_TRACE_DEBUG("bta_hl_find_mdl_idx found=%d mdl_id=%d mdl_idx=%d ", 842 found, mdl_id, i); 843 } 844 #endif 845 846 return found; 847 } 848 849 /******************************************************************************* 850 ** 851 ** Function bta_hl_find_an_active_mdl_idx 852 ** 853 ** Description This function finds an active MDL 854 ** 855 ** Returns BOOLEAN TRUE-found 856 ** 857 *******************************************************************************/ 858 BOOLEAN bta_hl_find_an_active_mdl_idx(UINT8 app_idx, UINT8 mcl_idx, 859 UINT8 *p_mdl_idx) 860 { 861 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 862 BOOLEAN found=FALSE; 863 UINT8 i; 864 865 for (i=0; i < BTA_HL_NUM_MDLS_PER_MCL ; i ++) 866 { 867 if (p_mcb->mdl[i].in_use && 868 (p_mcb->mdl[i].dch_state == BTA_HL_DCH_OPEN_ST)) 869 { 870 found = TRUE; 871 *p_mdl_idx = i; 872 break; 873 } 874 } 875 876 #if BTA_HL_DEBUG == TRUE 877 if (found) 878 { 879 APPL_TRACE_DEBUG("bta_hl_find_an_opened_mdl_idx found=%d app_idx=%d mcl_idx=%d mdl_idx=%d", 880 found, app_idx, mcl_idx, i); 881 } 882 #endif 883 884 return found; 885 } 886 887 /******************************************************************************* 888 ** 889 ** Function bta_hl_find_dch_setup_mdl_idx 890 ** 891 ** Description This function finds a MDL which in the DCH setup state 892 ** 893 ** Returns BOOLEAN TRUE-found 894 ** 895 *******************************************************************************/ 896 BOOLEAN bta_hl_find_dch_setup_mdl_idx(UINT8 app_idx, UINT8 mcl_idx, 897 UINT8 *p_mdl_idx) 898 { 899 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 900 BOOLEAN found=FALSE; 901 UINT8 i; 902 903 for (i=0; i < BTA_HL_NUM_MDLS_PER_MCL ; i ++) 904 { 905 if (p_mcb->mdl[i].in_use && 906 (p_mcb->mdl[i].dch_state == BTA_HL_DCH_OPENING_ST)) 907 { 908 found = TRUE; 909 *p_mdl_idx = i; 910 break; 911 } 912 } 913 914 #if BTA_HL_DEBUG == TRUE 915 if (found) 916 { 917 APPL_TRACE_DEBUG("bta_hl_find_dch_setup_mdl_idx found=%d app_idx=%d mcl_idx=%d mdl_idx=%d", 918 found, app_idx, mcl_idx, i); 919 } 920 #endif 921 922 return found; 923 } 924 925 /******************************************************************************* 926 ** 927 ** Function bta_hl_find_an_in_use_mcl_idx 928 ** 929 ** Description This function finds an in-use MCL control block index 930 ** 931 ** Returns BOOLEAN TRUE-found 932 ** 933 *******************************************************************************/ 934 BOOLEAN bta_hl_find_an_in_use_mcl_idx(UINT8 app_idx, 935 UINT8 *p_mcl_idx) 936 { 937 tBTA_HL_MCL_CB *p_mcb; 938 BOOLEAN found=FALSE; 939 UINT8 i; 940 941 for (i=0; i < BTA_HL_NUM_MCLS ; i ++) 942 { 943 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, i); 944 if (p_mcb->in_use && 945 (p_mcb->cch_state != BTA_HL_CCH_IDLE_ST)) 946 { 947 found = TRUE; 948 *p_mcl_idx = i; 949 break; 950 } 951 } 952 953 #if BTA_HL_DEBUG == TRUE 954 if (found) 955 { 956 APPL_TRACE_DEBUG("bta_hl_find_an_in_use_mcl_idx found=%d app_idx=%d mcl_idx=%d ", 957 found, app_idx, i); 958 } 959 #endif 960 961 return found; 962 } 963 964 965 /******************************************************************************* 966 ** 967 ** Function bta_hl_find_an_in_use_app_idx 968 ** 969 ** Description This function finds an in-use application control block index 970 ** 971 ** Returns BOOLEAN TRUE-found 972 ** 973 *******************************************************************************/ 974 BOOLEAN bta_hl_find_an_in_use_app_idx(UINT8 *p_app_idx) 975 { 976 tBTA_HL_APP_CB *p_acb ; 977 BOOLEAN found=FALSE; 978 UINT8 i; 979 980 for (i=0; i < BTA_HL_NUM_APPS ; i ++) 981 { 982 p_acb = BTA_HL_GET_APP_CB_PTR(i); 983 if (p_acb->in_use) 984 { 985 found = TRUE; 986 *p_app_idx = i; 987 break; 988 } 989 } 990 991 #if BTA_HL_DEBUG == TRUE 992 if (found) 993 { 994 APPL_TRACE_DEBUG("bta_hl_find_an_in_use_app_idx found=%d app_idx=%d ", 995 found, i); 996 } 997 #endif 998 999 return found; 1000 } 1001 /******************************************************************************* 1002 ** 1003 ** Function bta_hl_find_app_idx 1004 ** 1005 ** Description This function finds the application control block index based on 1006 ** the application ID 1007 ** 1008 ** Returns BOOLEAN TRUE-found 1009 ** 1010 *******************************************************************************/ 1011 BOOLEAN bta_hl_find_app_idx(UINT8 app_id, UINT8 *p_app_idx) 1012 { 1013 BOOLEAN found=FALSE; 1014 UINT8 i; 1015 1016 for (i=0; i < BTA_HL_NUM_APPS ; i ++) 1017 { 1018 if (bta_hl_cb.acb[i].in_use && 1019 (bta_hl_cb.acb[i].app_id == app_id)) 1020 { 1021 found = TRUE; 1022 *p_app_idx = i; 1023 break; 1024 } 1025 } 1026 1027 #if BTA_HL_DEBUG == TRUE 1028 APPL_TRACE_DEBUG("bta_hl_find_app_idx found=%d app_id=%d idx=%d ", 1029 found, app_id, i); 1030 #endif 1031 1032 return found; 1033 } 1034 1035 1036 /******************************************************************************* 1037 ** 1038 ** Function bta_hl_find_app_idx_using_handle 1039 ** 1040 ** Description This function finds the application control block index based on 1041 ** the application handle 1042 ** 1043 ** Returns BOOLEAN TRUE-found 1044 ** 1045 *******************************************************************************/ 1046 BOOLEAN bta_hl_find_app_idx_using_handle(tBTA_HL_APP_HANDLE app_handle, 1047 UINT8 *p_app_idx) 1048 { 1049 BOOLEAN found=FALSE; 1050 UINT8 i; 1051 1052 for (i=0; i < BTA_HL_NUM_APPS ; i ++) 1053 { 1054 if (bta_hl_cb.acb[i].in_use && 1055 (bta_hl_cb.acb[i].app_handle == app_handle)) 1056 { 1057 found = TRUE; 1058 *p_app_idx = i; 1059 break; 1060 } 1061 } 1062 1063 #if BTA_HL_DEBUG == TRUE 1064 if (!found) 1065 { 1066 APPL_TRACE_DEBUG("bta_hl_find_app_idx_using_mca_handle status=%d handle=%d app_idx=%d ", 1067 found, app_handle , i); 1068 } 1069 #endif 1070 1071 return found; 1072 } 1073 1074 1075 /******************************************************************************* 1076 ** 1077 ** Function bta_hl_find_mcl_idx_using_handle 1078 ** 1079 ** Description This function finds the MCL control block index based on 1080 ** the MCL handle 1081 ** 1082 ** Returns BOOLEAN TRUE-found 1083 ** 1084 *******************************************************************************/ 1085 BOOLEAN bta_hl_find_mcl_idx_using_handle( tBTA_HL_MCL_HANDLE mcl_handle, 1086 UINT8 *p_app_idx, UINT8 *p_mcl_idx) 1087 { 1088 tBTA_HL_APP_CB *p_acb; 1089 BOOLEAN found=FALSE; 1090 UINT8 i = 0,j = 0; 1091 1092 for (i=0; i<BTA_HL_NUM_APPS; i++) 1093 { 1094 p_acb = BTA_HL_GET_APP_CB_PTR(i); 1095 if (p_acb->in_use) 1096 { 1097 for (j=0; j < BTA_HL_NUM_MCLS ; j++) 1098 { 1099 if ( p_acb->mcb[j].mcl_handle == mcl_handle ) 1100 { 1101 found = TRUE; 1102 *p_app_idx = i; 1103 *p_mcl_idx = j; 1104 break; 1105 } 1106 } 1107 } 1108 } 1109 1110 #if BTA_HL_DEBUG == TRUE 1111 if (!found) 1112 { 1113 APPL_TRACE_DEBUG("bta_hl_find_mcl_idx_using_handle found=%d app_idx=%d mcl_idx=%d", 1114 found, i, j); 1115 } 1116 #endif 1117 return found; 1118 } 1119 1120 /******************************************************************************* 1121 ** 1122 ** Function bta_hl_find_mcl_idx 1123 ** 1124 ** Description This function finds the MCL control block index based on 1125 ** the peer BD address 1126 ** 1127 ** Returns BOOLEAN TRUE-found 1128 ** 1129 *******************************************************************************/ 1130 BOOLEAN bta_hl_find_mcl_idx(UINT8 app_idx, BD_ADDR p_bd_addr, UINT8 *p_mcl_idx) 1131 { 1132 BOOLEAN found=FALSE; 1133 UINT8 i; 1134 1135 for (i=0; i < BTA_HL_NUM_MCLS ; i ++) 1136 { 1137 if (bta_hl_cb.acb[app_idx].mcb[i].in_use && 1138 (!memcmp (bta_hl_cb.acb[app_idx].mcb[i].bd_addr, p_bd_addr, BD_ADDR_LEN))) 1139 { 1140 found = TRUE; 1141 *p_mcl_idx = i; 1142 break; 1143 } 1144 } 1145 1146 #if BTA_HL_DEBUG == TRUE 1147 if (!found) 1148 { 1149 APPL_TRACE_DEBUG("bta_hl_find_mcl_idx found=%d idx=%d", 1150 found, i); 1151 } 1152 #endif 1153 return found; 1154 } 1155 1156 1157 1158 /******************************************************************************* 1159 ** 1160 ** Function bta_hl_find_mdl_idx_using_handle 1161 ** 1162 ** Description This function finds the MDL control block index based on 1163 ** the MDL handle 1164 ** 1165 ** Returns BOOLEAN TRUE-found 1166 ** 1167 *******************************************************************************/ 1168 BOOLEAN bta_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle, 1169 UINT8 *p_app_idx,UINT8 *p_mcl_idx, 1170 UINT8 *p_mdl_idx) 1171 { 1172 tBTA_HL_APP_CB *p_acb; 1173 tBTA_HL_MCL_CB *p_mcb; 1174 tBTA_HL_MDL_CB *p_dcb; 1175 BOOLEAN found=FALSE; 1176 UINT8 i,j,k; 1177 1178 for (i=0; i < BTA_HL_NUM_APPS ; i ++) 1179 { 1180 p_acb = BTA_HL_GET_APP_CB_PTR(i); 1181 if (p_acb->in_use) 1182 { 1183 for (j=0; j< BTA_HL_NUM_MCLS; j++) 1184 { 1185 p_mcb = BTA_HL_GET_MCL_CB_PTR(i,j); 1186 if (p_mcb->in_use) 1187 { 1188 for (k=0; k< BTA_HL_NUM_MDLS_PER_MCL; k++) 1189 { 1190 p_dcb = BTA_HL_GET_MDL_CB_PTR(i,j,k); 1191 if (p_dcb->in_use) 1192 { 1193 if (p_dcb->mdl_handle == mdl_handle) 1194 { 1195 found = TRUE; 1196 *p_app_idx = i; 1197 *p_mcl_idx =j; 1198 *p_mdl_idx = k; 1199 break; 1200 } 1201 } 1202 } 1203 } 1204 } 1205 } 1206 } 1207 1208 1209 #if BTA_HL_DEBUG == TRUE 1210 if (!found) 1211 { 1212 APPL_TRACE_DEBUG("bta_hl_find_mdl_idx_using_handle found=%d mdl_handle=%d ", 1213 found, mdl_handle); 1214 } 1215 #endif 1216 return found; 1217 } 1218 /******************************************************************************* 1219 ** 1220 ** Function bta_hl_is_the_first_reliable_existed 1221 ** 1222 ** Description This function checks whether the first reliable DCH channel 1223 ** has been setup on the MCL or not 1224 ** 1225 ** Returns BOOLEAN - TRUE exist 1226 ** FALSE does not exist 1227 ** 1228 *******************************************************************************/ 1229 BOOLEAN bta_hl_is_the_first_reliable_existed(UINT8 app_idx, UINT8 mcl_idx ) 1230 { 1231 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1232 BOOLEAN is_existed =FALSE; 1233 UINT8 i ; 1234 1235 for (i=0; i< BTA_HL_NUM_MDLS_PER_MCL; i++) 1236 { 1237 if (p_mcb->mdl[i].in_use && p_mcb->mdl[i].is_the_first_reliable) 1238 { 1239 is_existed = TRUE; 1240 break; 1241 } 1242 } 1243 1244 #if BTA_HL_DEBUG == TRUE 1245 APPL_TRACE_DEBUG("bta_hl_is_the_first_reliable_existed is_existed=%d ",is_existed ); 1246 #endif 1247 return is_existed; 1248 } 1249 1250 /******************************************************************************* 1251 ** 1252 ** Function bta_hl_find_non_active_mdl_cfg 1253 ** 1254 ** Description This function finds a valid MDL configiration index and this 1255 ** MDL ID is not active 1256 ** 1257 ** Returns BOOLEAN - TRUE found 1258 ** FALSE not found 1259 ** 1260 *******************************************************************************/ 1261 BOOLEAN bta_hl_find_non_active_mdl_cfg(UINT8 app_idx, UINT8 start_mdl_cfg_idx, 1262 UINT8 *p_mdl_cfg_idx) 1263 { 1264 1265 tBTA_HL_MCL_CB *p_mcb; 1266 tBTA_HL_MDL_CB *p_dcb; 1267 tBTA_HL_MDL_CFG *p_mdl; 1268 BOOLEAN mdl_in_use; 1269 BOOLEAN found = FALSE; 1270 UINT8 i,j,k; 1271 1272 for (i = start_mdl_cfg_idx; i< BTA_HL_NUM_MDL_CFGS; i++) 1273 { 1274 mdl_in_use = FALSE; 1275 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i); 1276 for (j=0; j< BTA_HL_NUM_MCLS; j++) 1277 { 1278 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, j); 1279 if (p_mcb->in_use && 1280 !memcmp(p_mdl->peer_bd_addr,p_mcb->bd_addr,BD_ADDR_LEN)) 1281 { 1282 1283 for (k=0; k<BTA_HL_NUM_MDLS_PER_MCL; k++) 1284 { 1285 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, j, k); 1286 1287 if (p_dcb->in_use && p_mdl->mdl_id == p_dcb->mdl_id) 1288 { 1289 mdl_in_use = TRUE; 1290 break; 1291 } 1292 } 1293 } 1294 1295 if (mdl_in_use) 1296 { 1297 break; 1298 } 1299 } 1300 1301 if (!mdl_in_use) 1302 { 1303 *p_mdl_cfg_idx = i; 1304 found = TRUE; 1305 break; 1306 } 1307 } 1308 1309 return found; 1310 } 1311 1312 /******************************************************************************* 1313 ** 1314 ** Function bta_hl_find_mdl_cfg_idx 1315 ** 1316 ** Description This function finds an available MDL configuration index 1317 ** 1318 ** Returns BOOLEAN - TRUE found 1319 ** FALSE not found 1320 ** 1321 *******************************************************************************/ 1322 BOOLEAN bta_hl_find_avail_mdl_cfg_idx(UINT8 app_idx, UINT8 mcl_idx, 1323 UINT8 *p_mdl_cfg_idx) 1324 { 1325 tBTA_HL_MDL_CFG *p_mdl, *p_mdl1, *p_mdl2; 1326 UINT8 i; 1327 BOOLEAN found=FALSE; 1328 UINT8 first_mdl_cfg_idx, second_mdl_cfg_idx, older_mdl_cfg_idx; 1329 BOOLEAN done; 1330 UNUSED(mcl_idx); 1331 1332 for (i=0; i< BTA_HL_NUM_MDL_CFGS; i++) 1333 { 1334 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i); 1335 if (!p_mdl->active ) 1336 { 1337 /* found an unused space to store mdl cfg*/ 1338 found=TRUE; 1339 *p_mdl_cfg_idx =i; 1340 break; 1341 } 1342 } 1343 1344 if (!found) 1345 { 1346 /* all available mdl cfg spaces are in use so we need to find the mdl cfg which is 1347 not currently in use and has the the oldest time stamp to remove*/ 1348 1349 found = TRUE; 1350 if (bta_hl_find_non_active_mdl_cfg(app_idx,0, &first_mdl_cfg_idx)) 1351 { 1352 if (bta_hl_find_non_active_mdl_cfg(app_idx,(UINT8) (first_mdl_cfg_idx+1), &second_mdl_cfg_idx)) 1353 { 1354 done = FALSE; 1355 while (!done) 1356 { 1357 p_mdl1 = BTA_HL_GET_MDL_CFG_PTR(app_idx, first_mdl_cfg_idx); 1358 p_mdl2 = BTA_HL_GET_MDL_CFG_PTR(app_idx, second_mdl_cfg_idx); 1359 1360 if (p_mdl1->time < p_mdl2->time) 1361 { 1362 older_mdl_cfg_idx = first_mdl_cfg_idx; 1363 } 1364 else 1365 { 1366 older_mdl_cfg_idx = second_mdl_cfg_idx; 1367 } 1368 1369 if (bta_hl_find_non_active_mdl_cfg(app_idx,(UINT8) (second_mdl_cfg_idx+1), &second_mdl_cfg_idx)) 1370 { 1371 first_mdl_cfg_idx = older_mdl_cfg_idx; 1372 } 1373 else 1374 { 1375 done = TRUE; 1376 } 1377 } 1378 1379 *p_mdl_cfg_idx = older_mdl_cfg_idx; 1380 1381 } 1382 else 1383 { 1384 *p_mdl_cfg_idx = first_mdl_cfg_idx; 1385 } 1386 1387 } 1388 else 1389 { 1390 found = FALSE; 1391 } 1392 } 1393 1394 #if BTA_HL_DEBUG == TRUE 1395 if (!found) 1396 { 1397 APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_cfg_idx found=%d mdl_cfg_idx=%d ",found, *p_mdl_cfg_idx ); 1398 } 1399 #endif 1400 1401 return found; 1402 1403 1404 } 1405 1406 /******************************************************************************* 1407 ** 1408 ** Function bta_hl_find_mdl_cfg_idx 1409 ** 1410 ** Description This function finds the MDL configuration index based on 1411 ** the MDL ID 1412 ** 1413 ** Returns BOOLEAN - TRUE found 1414 ** FALSE not found 1415 ** 1416 *******************************************************************************/ 1417 BOOLEAN bta_hl_find_mdl_cfg_idx(UINT8 app_idx, UINT8 mcl_idx, 1418 tBTA_HL_MDL_ID mdl_id, UINT8 *p_mdl_cfg_idx) 1419 { 1420 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1421 tBTA_HL_MDL_CFG *p_mdl; 1422 UINT8 i ; 1423 BOOLEAN found=FALSE; 1424 1425 *p_mdl_cfg_idx = 0; 1426 for (i=0; i< BTA_HL_NUM_MDL_CFGS; i++) 1427 { 1428 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i); 1429 if(p_mdl->active) 1430 APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx: mdl_id =%d, p_mdl->mdl_id=%d",mdl_id, 1431 p_mdl->mdl_id); 1432 if (p_mdl->active && 1433 (!memcmp (p_mcb->bd_addr, p_mdl->peer_bd_addr, BD_ADDR_LEN))&& 1434 (p_mdl->mdl_id == mdl_id)) 1435 { 1436 found=TRUE; 1437 *p_mdl_cfg_idx =i; 1438 break; 1439 } 1440 } 1441 1442 #if BTA_HL_DEBUG == TRUE 1443 if (!found) 1444 { 1445 APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx found=%d mdl_cfg_idx=%d ",found, i ); 1446 } 1447 #endif 1448 1449 return found; 1450 1451 1452 } 1453 1454 1455 /******************************************************************************* 1456 ** 1457 ** Function bta_hl_get_cur_time 1458 ** 1459 ** Description This function get the cuurent time value 1460 ** 1461 ** Returns BOOLEAN - TRUE found 1462 ** FALSE not found 1463 ** 1464 *******************************************************************************/ 1465 BOOLEAN bta_hl_get_cur_time(UINT8 app_idx, UINT8 *p_cur_time) 1466 { 1467 tBTA_HL_MDL_CFG *p_mdl; 1468 UINT8 i, j, time_latest, time; 1469 BOOLEAN found=FALSE, result=TRUE; 1470 1471 for (i=0; i< BTA_HL_NUM_MDL_CFGS; i++) 1472 { 1473 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i); 1474 if (p_mdl->active) 1475 { 1476 found=TRUE; 1477 time_latest = p_mdl->time; 1478 for (j=(i+1); j< BTA_HL_NUM_MDL_CFGS; j++ ) 1479 { 1480 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, j); 1481 if (p_mdl->active) 1482 { 1483 time = p_mdl->time; 1484 if (time > time_latest) 1485 { 1486 time_latest = time; 1487 } 1488 } 1489 } 1490 break; 1491 } 1492 } 1493 1494 1495 if (found) 1496 { 1497 if (time_latest < BTA_HL_MAX_TIME) 1498 { 1499 *p_cur_time = time_latest+1; 1500 } 1501 else 1502 { 1503 /* need to wrap around */ 1504 result = FALSE; 1505 } 1506 } 1507 else 1508 { 1509 *p_cur_time = BTA_HL_MIN_TIME; 1510 } 1511 1512 #if BTA_HL_DEBUG == TRUE 1513 if (!result) 1514 { 1515 APPL_TRACE_DEBUG("bta_hl_get_cur_time result=%s cur_time=%d", 1516 (result?"OK":"FAIL"), *p_cur_time); 1517 } 1518 #endif 1519 1520 return result; 1521 } 1522 1523 /******************************************************************************* 1524 ** 1525 ** Function bta_hl_sort_cfg_time_idx 1526 ** 1527 ** Description This function sort the mdl configuration idx stored in array a 1528 ** based on decending time value 1529 ** 1530 ** Returns BOOLEAN - TRUE found 1531 ** FALSE not found 1532 ** 1533 *******************************************************************************/ 1534 void bta_hl_sort_cfg_time_idx(UINT8 app_idx, UINT8 *a, UINT8 n) 1535 { 1536 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1537 UINT8 temp_time, temp_idx; 1538 INT16 i, j; 1539 for (i = 1; i < n; ++i) 1540 { 1541 temp_idx = a[i]; 1542 temp_time = p_acb->mdl_cfg[temp_idx].time; 1543 j = i - 1; 1544 while ((j >= 0) && (temp_time < p_acb->mdl_cfg[a[j]].time)) 1545 { 1546 a[j + 1] = a[j]; 1547 --j; 1548 } 1549 a[j + 1] = temp_idx; 1550 } 1551 } 1552 1553 /******************************************************************************* 1554 ** 1555 ** Function bta_hl_compact_mdl_cfg_time 1556 ** 1557 ** Description This function finds the MDL configuration index based on 1558 ** the MDL ID 1559 ** 1560 ** Returns BOOLEAN - TRUE found 1561 ** FALSE not found 1562 ** 1563 *******************************************************************************/ 1564 void bta_hl_compact_mdl_cfg_time(UINT8 app_idx, UINT8 mdep_id) 1565 { 1566 tBTA_HL_MDL_CFG *p_mdl; 1567 UINT8 i, time_min, cnt=0; 1568 UINT8 s_arr[BTA_HL_NUM_MDL_CFGS]; 1569 1570 1571 for (i=0; i< BTA_HL_NUM_MDL_CFGS; i++) 1572 { 1573 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i); 1574 if (p_mdl->active ) 1575 { 1576 s_arr[cnt]= i; 1577 cnt++; 1578 } 1579 } 1580 1581 1582 1583 #if BTA_HL_DEBUG == TRUE 1584 APPL_TRACE_DEBUG("bta_hl_compact_mdl_cfg_time cnt=%d ",cnt ); 1585 #endif 1586 1587 1588 if (cnt) 1589 { 1590 bta_hl_sort_cfg_time_idx(app_idx, s_arr, cnt); 1591 time_min = BTA_HL_MIN_TIME; 1592 for (i=0;i<cnt; i++) 1593 { 1594 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, s_arr[i]); 1595 p_mdl->time = time_min + i; 1596 bta_hl_co_save_mdl(mdep_id, s_arr[i], p_mdl); 1597 } 1598 } 1599 1600 1601 } 1602 1603 1604 1605 /******************************************************************************* 1606 ** 1607 ** Function bta_hl_is_mdl_exsit_in_mcl 1608 ** 1609 ** Description This function checks whether the MDL ID 1610 ** has already existed in teh MCL or not 1611 ** 1612 ** Returns BOOLEAN - TRUE exist 1613 ** FALSE does not exist 1614 ** 1615 *******************************************************************************/ 1616 BOOLEAN bta_hl_is_mdl_exsit_in_mcl(UINT8 app_idx, BD_ADDR bd_addr, 1617 tBTA_HL_MDL_ID mdl_id) 1618 { 1619 tBTA_HL_MDL_CFG *p_mdl; 1620 BOOLEAN found = FALSE; 1621 UINT8 i; 1622 1623 for (i = 0; i< BTA_HL_NUM_MDL_CFGS; i++) 1624 { 1625 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i); 1626 if (p_mdl->active && 1627 !memcmp(p_mdl->peer_bd_addr, bd_addr,BD_ADDR_LEN)) 1628 { 1629 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) 1630 { 1631 if (p_mdl->mdl_id == mdl_id) 1632 { 1633 found = TRUE; 1634 break; 1635 } 1636 } 1637 else 1638 { 1639 found = TRUE; 1640 break; 1641 } 1642 } 1643 } 1644 1645 return found; 1646 } 1647 1648 /******************************************************************************* 1649 ** 1650 ** Function bta_hl_delete_mdl_cfg 1651 ** 1652 ** Description This function delete the specified MDL ID 1653 ** 1654 ** Returns BOOLEAN - TRUE Success 1655 ** FALSE Failed 1656 ** 1657 *******************************************************************************/ 1658 BOOLEAN bta_hl_delete_mdl_cfg(UINT8 app_idx, BD_ADDR bd_addr, 1659 tBTA_HL_MDL_ID mdl_id) 1660 { 1661 tBTA_HL_MDL_CFG *p_mdl; 1662 BOOLEAN success = FALSE; 1663 UINT8 i; 1664 1665 for (i = 0; i< BTA_HL_NUM_MDL_CFGS; i++) 1666 { 1667 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i); 1668 if (p_mdl->active && 1669 !memcmp(p_mdl->peer_bd_addr, bd_addr,BD_ADDR_LEN)) 1670 { 1671 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) 1672 { 1673 if (p_mdl->mdl_id == mdl_id) 1674 { 1675 bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i); 1676 memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG)); 1677 success = TRUE; 1678 break; 1679 } 1680 } 1681 else 1682 { 1683 bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i); 1684 memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG)); 1685 success = TRUE; 1686 } 1687 } 1688 } 1689 1690 return success; 1691 } 1692 1693 1694 /******************************************************************************* 1695 ** 1696 ** Function bta_hl_is_mdl_value_valid 1697 ** 1698 ** 1699 ** Description This function checks the specified MDL ID is in valid range or not 1700 ** 1701 ** Returns BOOLEAN - TRUE Success 1702 ** FALSE Failed 1703 ** 1704 ** note: mdl_id range 0x0000 reserved, 1705 ** 0x0001-oxFEFF dynamic range, 1706 ** 0xFF00-0xFFFE reserved, 1707 ** 0xFFFF indicates all MDLs (for delete operation only) 1708 ** 1709 *******************************************************************************/ 1710 BOOLEAN bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id) 1711 { 1712 BOOLEAN status = TRUE; 1713 1714 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) 1715 { 1716 if (mdl_id != 0) 1717 { 1718 if (mdl_id > BTA_HL_MAX_MDL_VAL ) 1719 { 1720 status = FALSE; 1721 } 1722 } 1723 else 1724 { 1725 status = FALSE; 1726 } 1727 } 1728 1729 return status; 1730 } 1731 1732 /******************************************************************************* 1733 ** 1734 ** Function bta_hl_find_mdep_cfg_idx 1735 ** 1736 ** Description This function finds the MDEP configuration index based 1737 ** on the local MDEP ID 1738 ** 1739 ** Returns BOOLEAN - TRUE found 1740 ** FALSE not found 1741 ** 1742 *******************************************************************************/ 1743 BOOLEAN bta_hl_find_mdep_cfg_idx(UINT8 app_idx, tBTA_HL_MDEP_ID local_mdep_id, 1744 UINT8 *p_mdep_cfg_idx) 1745 { 1746 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1747 tBTA_HL_SUP_FEATURE *p_sup_feature= &p_acb->sup_feature; 1748 BOOLEAN found =FALSE; 1749 UINT8 i; 1750 1751 for (i=0; i< p_sup_feature->num_of_mdeps; i++) 1752 { 1753 if ( p_sup_feature->mdep[i].mdep_id == local_mdep_id) 1754 { 1755 found = TRUE; 1756 *p_mdep_cfg_idx = i; 1757 break; 1758 } 1759 } 1760 1761 #if BTA_HL_DEBUG == TRUE 1762 if (!found) 1763 { 1764 APPL_TRACE_DEBUG("bta_hl_find_mdep_cfg_idx found=%d mdep_idx=%d local_mdep_id=%d ", 1765 found,i, local_mdep_id ); 1766 } 1767 #endif 1768 return found; 1769 } 1770 1771 1772 /******************************************************************************* 1773 ** 1774 ** Function bta_hl_find_rxtx_apdu_size 1775 ** 1776 ** Description This function finds the maximum APDU rx and tx sizes based on 1777 ** the MDEP configuration data 1778 ** 1779 ** Returns void 1780 ** 1781 *******************************************************************************/ 1782 void bta_hl_find_rxtx_apdu_size(UINT8 app_idx, UINT8 mdep_cfg_idx, 1783 UINT16 *p_rx_apu_size, 1784 UINT16 *p_tx_apu_size) 1785 { 1786 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1787 tBTA_HL_MDEP_CFG *p_mdep_cfg; 1788 UINT8 i; 1789 UINT16 max_rx_apdu_size=0, max_tx_apdu_size=0; 1790 1791 p_mdep_cfg = &p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg; 1792 1793 1794 for (i=0; i< p_mdep_cfg->num_of_mdep_data_types ; i++) 1795 { 1796 1797 if (max_rx_apdu_size < p_mdep_cfg->data_cfg[i].max_rx_apdu_size) 1798 { 1799 max_rx_apdu_size = p_mdep_cfg->data_cfg[i].max_rx_apdu_size; 1800 } 1801 1802 if (max_tx_apdu_size < p_mdep_cfg->data_cfg[i].max_tx_apdu_size) 1803 { 1804 max_tx_apdu_size = p_mdep_cfg->data_cfg[i].max_tx_apdu_size; 1805 } 1806 } 1807 1808 1809 *p_rx_apu_size = max_rx_apdu_size; 1810 *p_tx_apu_size = max_tx_apdu_size; 1811 1812 #if BTA_HL_DEBUG == TRUE 1813 APPL_TRACE_DEBUG("bta_hl_find_rxtx_apdu_size max_rx_apdu_size=%d max_tx_apdu_size=%d ", 1814 max_rx_apdu_size, max_tx_apdu_size ); 1815 #endif 1816 1817 1818 } 1819 1820 /******************************************************************************* 1821 ** 1822 ** Function bta_hl_validate_peer_cfg 1823 ** 1824 ** Description This function validates the peer DCH configuration 1825 ** 1826 ** Returns BOOLEAN - TRUE validation is successful 1827 ** FALSE validation failed 1828 ** 1829 *******************************************************************************/ 1830 BOOLEAN bta_hl_validate_peer_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx, 1831 tBTA_HL_MDEP_ID peer_mdep_id, 1832 tBTA_HL_MDEP_ROLE peer_mdep_role, 1833 UINT8 sdp_idx) 1834 { 1835 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1836 tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1837 tBTA_HL_SDP_REC *p_rec; 1838 BOOLEAN peer_found =FALSE; 1839 UINT8 i; 1840 1841 APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg sdp_idx=%d app_idx %d", sdp_idx, app_idx); 1842 1843 1844 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) 1845 { 1846 return TRUE; 1847 } 1848 1849 p_rec = &p_mcb->sdp.sdp_rec[sdp_idx]; 1850 for (i=0; i< p_rec->num_mdeps; i++) 1851 { 1852 APPL_TRACE_DEBUG("mdep_id %d peer_mdep_id %d",p_rec->mdep_cfg[i].mdep_id , peer_mdep_id); 1853 APPL_TRACE_DEBUG("mdep_role %d peer_mdep_role %d",p_rec->mdep_cfg[i].mdep_role, 1854 peer_mdep_role) 1855 if ( (p_rec->mdep_cfg[i].mdep_id == peer_mdep_id) && 1856 (p_rec->mdep_cfg[i].mdep_role == peer_mdep_role)) 1857 { 1858 peer_found = TRUE; 1859 1860 break; 1861 } 1862 } 1863 1864 #if BTA_HL_DEBUG == TRUE 1865 if (!peer_found) 1866 { 1867 APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg failed num_mdeps=%d",p_rec->num_mdeps); 1868 } 1869 #endif 1870 return peer_found; 1871 } 1872 1873 /******************************************************************************* 1874 ** 1875 ** Function bta_hl_chk_local_cfg 1876 ** 1877 ** Description This function check whether the local DCH configuration is OK or not 1878 ** 1879 ** Returns tBTA_HL_STATUS - OK - local DCH configuration is OK 1880 ** NO_FIRST_RELIABLE - the streaming DCH configuration 1881 ** is not OK and it needs to use 1882 ** reliable DCH configuration 1883 ** 1884 *******************************************************************************/ 1885 tBTA_HL_STATUS bta_hl_chk_local_cfg(UINT8 app_idx, UINT8 mcl_idx, 1886 UINT8 mdep_cfg_idx, 1887 tBTA_HL_DCH_CFG local_cfg) 1888 { 1889 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1890 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 1891 1892 if ( mdep_cfg_idx && 1893 (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SOURCE) && 1894 (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) && 1895 (local_cfg != BTA_HL_DCH_CFG_RELIABLE)) 1896 { 1897 status = BTA_HL_STATUS_NO_FIRST_RELIABLE; 1898 APPL_TRACE_ERROR("BTA_HL_STATUS_INVALID_DCH_CFG"); 1899 } 1900 1901 return status; 1902 } 1903 1904 1905 /******************************************************************************* 1906 ** 1907 ** Function bta_hl_validate_reconnect_params 1908 ** 1909 ** Description This function validates the reconnect parameters 1910 ** 1911 ** Returns BOOLEAN - TRUE validation is successful 1912 ** FALSE validation failed 1913 *******************************************************************************/ 1914 BOOLEAN bta_hl_validate_reconnect_params(UINT8 app_idx, UINT8 mcl_idx, 1915 tBTA_HL_API_DCH_RECONNECT *p_reconnect, 1916 UINT8 *p_mdep_cfg_idx, UINT8 *p_mdl_cfg_idx) 1917 { 1918 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1919 tBTA_HL_SUP_FEATURE *p_sup_feature = &p_acb->sup_feature; 1920 UINT8 num_mdeps; 1921 UINT8 mdl_cfg_idx; 1922 BOOLEAN local_mdep_id_found =FALSE; 1923 BOOLEAN mdl_cfg_found =FALSE; 1924 BOOLEAN status=FALSE; 1925 UINT8 i, in_use_mdl_idx = 0; 1926 1927 #if BTA_HL_DEBUG == TRUE 1928 APPL_TRACE_DEBUG("bta_hl_validate_reconnect_params mdl_id=%d app_idx=%d", p_reconnect->mdl_id, app_idx); 1929 #endif 1930 if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect->mdl_id, &mdl_cfg_idx)) 1931 { 1932 mdl_cfg_found = TRUE; 1933 } 1934 1935 #if BTA_HL_DEBUG == TRUE 1936 if (!mdl_cfg_found) 1937 { 1938 APPL_TRACE_DEBUG("mdl_cfg_found not found"); 1939 } 1940 #endif 1941 1942 1943 if (mdl_cfg_found) 1944 { 1945 num_mdeps = p_sup_feature->num_of_mdeps; 1946 for (i=0; i< num_mdeps ; i++) 1947 { 1948 if ( p_sup_feature->mdep[i].mdep_id == p_acb->mdl_cfg[mdl_cfg_idx].local_mdep_id) 1949 { 1950 local_mdep_id_found = TRUE; 1951 *p_mdep_cfg_idx =i; 1952 *p_mdl_cfg_idx = mdl_cfg_idx; 1953 break; 1954 } 1955 } 1956 } 1957 1958 #if BTA_HL_DEBUG == TRUE 1959 if (!local_mdep_id_found) 1960 { 1961 APPL_TRACE_DEBUG("local_mdep_id not found"); 1962 } 1963 #endif 1964 1965 1966 if (local_mdep_id_found) 1967 { 1968 if (!bta_hl_find_mdl_idx(app_idx,mcl_idx, p_reconnect->mdl_id, &in_use_mdl_idx)) 1969 { 1970 status= TRUE; 1971 } 1972 else 1973 { 1974 APPL_TRACE_ERROR("mdl_id=%d is curreltly in use",p_reconnect->mdl_id); 1975 } 1976 } 1977 1978 #if BTA_HL_DEBUG == TRUE 1979 if (!status) 1980 { 1981 APPL_TRACE_DEBUG("Reconnect validation failed local_mdep_id found=%d mdl_cfg_idx found=%d in_use_mdl_idx=%d ", 1982 local_mdep_id_found, mdl_cfg_found, in_use_mdl_idx); 1983 } 1984 #endif 1985 return status; 1986 } 1987 1988 /******************************************************************************* 1989 ** 1990 ** Function bta_hl_find_avail_mcl_idx 1991 ** 1992 ** Returns BOOLEAN - TRUE found 1993 ** FALSE not found 1994 ** 1995 *******************************************************************************/ 1996 BOOLEAN bta_hl_find_avail_mcl_idx(UINT8 app_idx, UINT8 *p_mcl_idx) 1997 { 1998 BOOLEAN found=FALSE; 1999 UINT8 i; 2000 2001 for (i=0; i < BTA_HL_NUM_MCLS ; i ++) 2002 { 2003 if (!bta_hl_cb.acb[app_idx].mcb[i].in_use) 2004 { 2005 found = TRUE; 2006 *p_mcl_idx = i; 2007 break; 2008 } 2009 } 2010 2011 #if BTA_HL_DEBUG == TRUE 2012 if (!found) 2013 { 2014 APPL_TRACE_DEBUG("bta_hl_find_avail_mcl_idx found=%d idx=%d", 2015 found, i); 2016 } 2017 #endif 2018 return found; 2019 } 2020 2021 2022 2023 /******************************************************************************* 2024 ** 2025 ** Function bta_hl_find_avail_mdl_idx 2026 ** 2027 ** Description This function finds an available MDL control block index 2028 ** 2029 ** Returns BOOLEAN - TRUE found 2030 ** FALSE not found 2031 ** 2032 *******************************************************************************/ 2033 BOOLEAN bta_hl_find_avail_mdl_idx(UINT8 app_idx, UINT8 mcl_idx, 2034 UINT8 *p_mdl_idx) 2035 { 2036 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2037 BOOLEAN found=FALSE; 2038 UINT8 i; 2039 2040 for (i=0; i < BTA_HL_NUM_MDLS_PER_MCL ; i ++) 2041 { 2042 if (!p_mcb->mdl[i].in_use) 2043 { 2044 memset((void *)&p_mcb->mdl[i],0, sizeof(tBTA_HL_MDL_CB)); 2045 found = TRUE; 2046 *p_mdl_idx = i; 2047 break; 2048 } 2049 } 2050 2051 #if BTA_HL_DEBUG == TRUE 2052 if (!found) 2053 { 2054 APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_idx found=%d idx=%d", 2055 found, i); 2056 } 2057 #endif 2058 return found; 2059 } 2060 2061 /******************************************************************************* 2062 ** 2063 ** Function bta_hl_is_a_duplicate_id 2064 ** 2065 ** Description This function finds the application has been used or not 2066 ** 2067 ** Returns BOOLEAN - TRUE the app_id is a duplicate ID 2068 ** FALSE not a duplicate ID 2069 *******************************************************************************/ 2070 BOOLEAN bta_hl_is_a_duplicate_id(UINT8 app_id) 2071 { 2072 BOOLEAN is_duplicate=FALSE; 2073 UINT8 i; 2074 2075 for (i=0; i < BTA_HL_NUM_APPS ; i ++) 2076 { 2077 if (bta_hl_cb.acb[i].in_use && 2078 (bta_hl_cb.acb[i].app_id == app_id)) 2079 { 2080 is_duplicate = TRUE; 2081 2082 break; 2083 } 2084 } 2085 2086 #if BTA_HL_DEBUG == TRUE 2087 if (is_duplicate) 2088 { 2089 2090 APPL_TRACE_DEBUG("bta_hl_is_a_duplicate_id app_id=%d is_duplicate=%d", 2091 app_id, is_duplicate); 2092 } 2093 #endif 2094 2095 return is_duplicate; 2096 } 2097 2098 2099 /******************************************************************************* 2100 ** 2101 ** Function bta_hl_find_avail_app_idx 2102 ** 2103 ** Description This function finds an available application control block index 2104 ** 2105 ** Returns BOOLEAN - TRUE found 2106 ** FALSE not found 2107 ** 2108 *******************************************************************************/ 2109 BOOLEAN bta_hl_find_avail_app_idx(UINT8 *p_idx) 2110 { 2111 BOOLEAN found=FALSE; 2112 UINT8 i; 2113 2114 for (i=0; i < BTA_HL_NUM_APPS ; i ++) 2115 { 2116 if (!bta_hl_cb.acb[i].in_use) 2117 { 2118 found = TRUE; 2119 *p_idx = i; 2120 break; 2121 } 2122 } 2123 2124 #if BTA_HL_DEBUG == TRUE 2125 if (!found) 2126 { 2127 APPL_TRACE_DEBUG("bta_hl_find_avail_app_idx found=%d app_idx=%d", 2128 found, i); 2129 } 2130 #endif 2131 return found; 2132 } 2133 2134 /******************************************************************************* 2135 ** 2136 ** Function bta_hl_app_update 2137 ** 2138 ** Description This function registers an HDP application MCAP and DP 2139 ** 2140 ** Returns tBTA_HL_STATUS -registration status 2141 ** 2142 *******************************************************************************/ 2143 tBTA_HL_STATUS bta_hl_app_update(UINT8 app_id, BOOLEAN is_register) 2144 { 2145 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 2146 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(0); 2147 tMCA_CS mca_cs; 2148 UINT8 i, mdep_idx, num_of_mdeps; 2149 UINT8 mdep_counter = 0; 2150 2151 2152 #if BTA_HL_DEBUG == TRUE 2153 APPL_TRACE_DEBUG("bta_hl_app_update app_id=%d", app_id); 2154 #endif 2155 2156 if (is_register) 2157 { 2158 if ((status == BTA_HL_STATUS_OK) && 2159 bta_hl_co_get_num_of_mdep(app_id, &num_of_mdeps)) 2160 { 2161 for (i=0; i < num_of_mdeps; i++) 2162 { 2163 mca_cs.type = MCA_TDEP_DATA; 2164 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP; 2165 mca_cs.p_data_cback = bta_hl_mcap_data_cback; 2166 /* Find the first available mdep index, and create a MDL Endpoint */ 2167 // make a function later if needed 2168 for (mdep_idx = 1; mdep_idx < BTA_HL_NUM_MDEPS; mdep_idx++) 2169 { 2170 if ( p_acb->sup_feature.mdep[mdep_idx].mdep_id == 0) 2171 { 2172 break; /* We found an available index */ 2173 } 2174 else 2175 { 2176 mdep_counter++; 2177 } 2178 } 2179 /* If no available MDEPs, return error */ 2180 if (mdep_idx == BTA_HL_NUM_MDEPS) 2181 { 2182 APPL_TRACE_ERROR("bta_hl_app_update: Out of MDEP IDs"); 2183 status = BTA_HL_STATUS_MCAP_REG_FAIL; 2184 break; 2185 } 2186 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle, 2187 &(p_acb->sup_feature.mdep[mdep_idx].mdep_id), &mca_cs) == MCA_SUCCESS) 2188 { 2189 if (bta_hl_co_get_mdep_config(app_id, 2190 mdep_idx, 2191 mdep_counter, 2192 p_acb->sup_feature.mdep[mdep_idx].mdep_id, 2193 &p_acb->sup_feature.mdep[mdep_idx].mdep_cfg)) 2194 { 2195 p_acb->sup_feature.mdep[mdep_idx].ori_app_id = app_id; 2196 APPL_TRACE_DEBUG("mdep idx %d id %d ori_app_id %d num data type %d",mdep_idx, 2197 p_acb->sup_feature.mdep[mdep_idx].mdep_id, 2198 p_acb->sup_feature.mdep[mdep_idx].ori_app_id, 2199 p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.num_of_mdep_data_types); 2200 if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role == 2201 BTA_HL_MDEP_ROLE_SOURCE) 2202 { 2203 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE; 2204 } 2205 else if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role == 2206 BTA_HL_MDEP_ROLE_SINK) 2207 { 2208 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK; 2209 } 2210 else 2211 { 2212 APPL_TRACE_ERROR("bta_hl_app_registration: Invalid Role %d", 2213 p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role); 2214 status = BTA_HL_STATUS_MDEP_CO_FAIL; 2215 break; 2216 } 2217 } 2218 else 2219 { 2220 APPL_TRACE_ERROR("bta_hl_app_registration: Cfg callout failed"); 2221 status = BTA_HL_STATUS_MDEP_CO_FAIL; 2222 break; 2223 } 2224 } 2225 else 2226 { 2227 APPL_TRACE_ERROR("bta_hl_app_registration: MCA_CreateDep failed"); 2228 status = BTA_HL_STATUS_MCAP_REG_FAIL; 2229 break; 2230 } 2231 2232 } 2233 p_acb->sup_feature.num_of_mdeps += num_of_mdeps; 2234 APPL_TRACE_DEBUG("num_of_mdeps %d", p_acb->sup_feature.num_of_mdeps); 2235 2236 if ((status == BTA_HL_STATUS_OK) && 2237 (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) 2238 { 2239 p_acb->sup_feature.advertize_source_sdp = 2240 bta_hl_co_advrtise_source_sdp(app_id); 2241 } 2242 2243 if ((status == BTA_HL_STATUS_OK)&& 2244 (!bta_hl_co_get_echo_config(app_id, &p_acb->sup_feature.echo_cfg))) 2245 { 2246 status = BTA_HL_STATUS_ECHO_CO_FAIL; 2247 } 2248 2249 if ((status == BTA_HL_STATUS_OK)&& 2250 (!bta_hl_co_load_mdl_config(app_id, BTA_HL_NUM_MDL_CFGS, &p_acb->mdl_cfg[0]))) 2251 { 2252 status = BTA_HL_STATUS_MDL_CFG_CO_FAIL; 2253 } 2254 } 2255 else 2256 { 2257 status = BTA_HL_STATUS_MDEP_CO_FAIL; 2258 } 2259 } 2260 else 2261 { 2262 for (i=1; i<BTA_HL_NUM_MDEPS; i++) 2263 { 2264 if (p_acb->sup_feature.mdep[i].ori_app_id == app_id) 2265 { 2266 APPL_TRACE_DEBUG("Found index %", i); 2267 2268 2269 if (MCA_DeleteDep((tMCA_HANDLE)p_acb->app_handle, 2270 (p_acb->sup_feature.mdep[i].mdep_id)) != MCA_SUCCESS) 2271 { 2272 APPL_TRACE_ERROR("Error deregistering"); 2273 status = BTA_HL_STATUS_MCAP_REG_FAIL; 2274 return status; 2275 } 2276 memset(&p_acb->sup_feature.mdep[i], 0, sizeof(tBTA_HL_MDEP)); 2277 } 2278 } 2279 2280 2281 } 2282 2283 if (status == BTA_HL_STATUS_OK) 2284 { 2285 /* Register/Update MDEP(s) in SDP Record */ 2286 status = bta_hl_sdp_update(app_id); 2287 } 2288 /* else do cleanup */ 2289 2290 2291 return status; 2292 } 2293 2294 2295 /******************************************************************************* 2296 ** 2297 ** Function bta_hl_app_registration 2298 ** 2299 ** Description This function registers an HDP application MCAP and DP 2300 ** 2301 ** Returns tBTA_HL_STATUS -registration status 2302 ** 2303 *******************************************************************************/ 2304 tBTA_HL_STATUS bta_hl_app_registration(UINT8 app_idx) 2305 { 2306 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 2307 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 2308 tMCA_REG reg; 2309 tMCA_CS mca_cs; 2310 UINT8 i, num_of_mdeps; 2311 UINT8 mdep_counter = 0; 2312 2313 #if BTA_HL_DEBUG == TRUE 2314 APPL_TRACE_DEBUG("bta_hl_app_registration app_idx=%d", app_idx); 2315 #endif 2316 2317 reg.ctrl_psm = p_acb->ctrl_psm; 2318 reg.data_psm = p_acb->data_psm; 2319 reg.sec_mask = p_acb->sec_mask; 2320 reg.rsp_tout = BTA_HL_MCAP_RSP_TOUT; 2321 2322 if ( (p_acb->app_handle = (tBTA_HL_APP_HANDLE) MCA_Register(®, bta_hl_mcap_ctrl_cback))!=0) 2323 { 2324 mca_cs.type = MCA_TDEP_ECHO; 2325 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP; 2326 mca_cs.p_data_cback = bta_hl_mcap_data_cback; 2327 2328 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle, 2329 &(p_acb->sup_feature.mdep[0].mdep_id), 2330 &mca_cs) == MCA_SUCCESS) 2331 { 2332 if (p_acb->sup_feature.mdep[0].mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) 2333 { 2334 status = BTA_HL_STATUS_MCAP_REG_FAIL; 2335 APPL_TRACE_ERROR("BAD MDEP ID for echo test mdep_id=%d", 2336 p_acb->sup_feature.mdep[0].mdep_id ); 2337 } 2338 } 2339 else 2340 { 2341 status = BTA_HL_STATUS_MCAP_REG_FAIL; 2342 APPL_TRACE_ERROR("MCA_CreateDep for echo test(mdep_id=0) failed"); 2343 } 2344 2345 2346 if ((status == BTA_HL_STATUS_OK) && 2347 bta_hl_co_get_num_of_mdep(p_acb->app_id, &num_of_mdeps)) 2348 { 2349 p_acb->sup_feature.num_of_mdeps = num_of_mdeps+1; 2350 2351 for (i=1; i<p_acb->sup_feature.num_of_mdeps; i++) 2352 { 2353 mca_cs.type = MCA_TDEP_DATA; 2354 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP; 2355 mca_cs.p_data_cback = bta_hl_mcap_data_cback; 2356 2357 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle, 2358 &(p_acb->sup_feature.mdep[i].mdep_id), &mca_cs) == MCA_SUCCESS) 2359 { 2360 if (bta_hl_co_get_mdep_config(p_acb->app_id, 2361 i,mdep_counter, 2362 p_acb->sup_feature.mdep[i].mdep_id, 2363 &p_acb->sup_feature.mdep[i].mdep_cfg)) 2364 { 2365 if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SOURCE) 2366 { 2367 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE; 2368 } 2369 else if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SINK) 2370 { 2371 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK; 2372 } 2373 else 2374 { 2375 status = BTA_HL_STATUS_MDEP_CO_FAIL; 2376 break; 2377 } 2378 p_acb->sup_feature.mdep[i].ori_app_id = p_acb->app_id; 2379 APPL_TRACE_DEBUG("index %d ori_app_id %d", i, 2380 p_acb->sup_feature.mdep[i].ori_app_id); 2381 } 2382 else 2383 { 2384 status = BTA_HL_STATUS_MDEP_CO_FAIL; 2385 break; 2386 } 2387 } 2388 else 2389 { 2390 status = BTA_HL_STATUS_MCAP_REG_FAIL; 2391 break; 2392 } 2393 } 2394 2395 2396 2397 if ((status == BTA_HL_STATUS_OK) && 2398 (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) 2399 { 2400 /* this is a source only applciation */ 2401 p_acb->sup_feature.advertize_source_sdp = 2402 bta_hl_co_advrtise_source_sdp(p_acb->app_id); 2403 } 2404 2405 if ((status == BTA_HL_STATUS_OK)&& 2406 (!bta_hl_co_get_echo_config(p_acb->app_id, &p_acb->sup_feature.echo_cfg))) 2407 { 2408 status = BTA_HL_STATUS_ECHO_CO_FAIL; 2409 } 2410 2411 if ((status == BTA_HL_STATUS_OK)&& 2412 (!bta_hl_co_load_mdl_config(p_acb->app_id, BTA_HL_NUM_MDL_CFGS, &p_acb->mdl_cfg[0]))) 2413 { 2414 status = BTA_HL_STATUS_MDL_CFG_CO_FAIL; 2415 } 2416 } 2417 else 2418 { 2419 status = BTA_HL_STATUS_MDEP_CO_FAIL; 2420 } 2421 } 2422 else 2423 { 2424 status = BTA_HL_STATUS_MCAP_REG_FAIL; 2425 } 2426 2427 if (status == BTA_HL_STATUS_OK) 2428 { 2429 status = bta_hl_sdp_register(app_idx); 2430 } 2431 2432 return status; 2433 } 2434 2435 2436 /******************************************************************************* 2437 ** 2438 ** Function bta_hl_discard_data 2439 ** 2440 ** Description This function discard an HDP event 2441 ** 2442 ** Returns void 2443 ** 2444 *******************************************************************************/ 2445 void bta_hl_discard_data(UINT16 event, tBTA_HL_DATA *p_data) 2446 { 2447 2448 #if BTA_HL_DEBUG == TRUE 2449 APPL_TRACE_ERROR("BTA HL Discard event=%s",bta_hl_evt_code(event)); 2450 2451 #endif 2452 2453 switch (event) 2454 { 2455 case BTA_HL_API_SEND_DATA_EVT: 2456 break; 2457 2458 case BTA_HL_MCA_RCV_DATA_EVT: 2459 osi_free_and_reset((void **)&p_data->mca_rcv_data_evt.p_pkt); 2460 break; 2461 2462 default: 2463 /*Nothing to free*/ 2464 break; 2465 } 2466 } 2467 2468 /******************************************************************************* 2469 ** 2470 ** Function bta_hl_save_mdl_cfg 2471 ** 2472 ** Description This function saves the MDL configuration 2473 ** 2474 ** Returns void 2475 ** 2476 *******************************************************************************/ 2477 void bta_hl_save_mdl_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx ) 2478 { 2479 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 2480 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2481 tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2482 UINT8 mdl_cfg_idx; 2483 tBTA_HL_MDL_ID mdl_id; 2484 BOOLEAN found=TRUE; 2485 tBTA_HL_MDL_CFG mdl_cfg; 2486 tBTA_HL_MDEP *p_mdep_cfg; 2487 tBTA_HL_L2CAP_CFG_INFO l2cap_cfg; 2488 UINT8 time_val = 0; 2489 mdl_id = p_dcb->mdl_id; 2490 if (!bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, mdl_id, &mdl_cfg_idx)) 2491 { 2492 if (!bta_hl_find_avail_mdl_cfg_idx(app_idx, mcl_idx, &mdl_cfg_idx)) 2493 { 2494 APPL_TRACE_ERROR("No space to save the MDL config"); 2495 found= FALSE; /*no space available*/ 2496 } 2497 } 2498 2499 if (found) 2500 { 2501 bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg); 2502 if (!bta_hl_get_cur_time(app_idx, &time_val )) 2503 { 2504 bta_hl_compact_mdl_cfg_time(app_idx,p_dcb->local_mdep_id); 2505 bta_hl_get_cur_time(app_idx, &time_val); 2506 } 2507 mdl_cfg.active = TRUE; 2508 mdl_cfg.time = time_val; 2509 mdl_cfg.mdl_id = p_dcb->mdl_id; 2510 mdl_cfg.dch_mode = p_dcb->dch_mode; 2511 mdl_cfg.mtu = l2cap_cfg.mtu; 2512 mdl_cfg.fcs = l2cap_cfg.fcs; 2513 2514 bdcpy(mdl_cfg.peer_bd_addr, p_mcb->bd_addr); 2515 mdl_cfg.local_mdep_id= p_dcb->local_mdep_id; 2516 p_mdep_cfg = &p_acb->sup_feature.mdep[p_dcb->local_mdep_cfg_idx]; 2517 mdl_cfg.local_mdep_role= p_mdep_cfg->mdep_cfg.mdep_role; 2518 memcpy(&p_acb->mdl_cfg[mdl_cfg_idx], &mdl_cfg, sizeof(tBTA_HL_MDL_CFG)); 2519 bta_hl_co_save_mdl(mdl_cfg.local_mdep_id, mdl_cfg_idx, &mdl_cfg); 2520 } 2521 2522 #if BTA_HL_DEBUG == TRUE 2523 if (found) 2524 { 2525 if (p_dcb->mtu != l2cap_cfg.mtu) 2526 { 2527 APPL_TRACE_WARNING("MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from l2cap mtu=%d", 2528 p_dcb->mtu, l2cap_cfg.mtu); 2529 } 2530 APPL_TRACE_DEBUG("bta_hl_save_mdl_cfg saved=%d", found); 2531 APPL_TRACE_DEBUG("Saved. L2cap cfg mdl_id=%d mtu=%d fcs=%d dch_mode=%d", 2532 mdl_cfg.mdl_id, mdl_cfg.mtu, mdl_cfg.fcs, mdl_cfg.dch_mode); 2533 } 2534 #endif 2535 2536 2537 2538 } 2539 2540 /******************************************************************************* 2541 ** 2542 ** Function bta_hl_set_dch_chan_cfg 2543 ** 2544 ** Description This function setups the L2CAP DCH channel configuration 2545 ** 2546 ** Returns void 2547 *******************************************************************************/ 2548 void bta_hl_set_dch_chan_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,tBTA_HL_DATA *p_data) 2549 { 2550 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 2551 tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2552 UINT8 l2cap_mode = L2CAP_FCR_ERTM_MODE; 2553 tBTA_HL_SUP_FEATURE *p_sup_feature= &p_acb->sup_feature; 2554 UINT8 local_mdep_cfg_idx = p_dcb->local_mdep_cfg_idx; 2555 2556 switch (p_dcb->dch_oper) 2557 { 2558 case BTA_HL_DCH_OP_LOCAL_RECONNECT: 2559 case BTA_HL_DCH_OP_REMOTE_RECONNECT: 2560 if (p_dcb->dch_mode == BTA_HL_DCH_MODE_STREAMING) 2561 l2cap_mode = L2CAP_FCR_STREAM_MODE; 2562 break; 2563 case BTA_HL_DCH_OP_LOCAL_OPEN: 2564 if (p_data->mca_evt.mca_data.create_cfm.cfg == BTA_HL_DCH_CFG_STREAMING) 2565 l2cap_mode = L2CAP_FCR_STREAM_MODE; 2566 break; 2567 case BTA_HL_DCH_OP_REMOTE_OPEN: 2568 if (p_dcb->local_cfg == BTA_HL_DCH_CFG_STREAMING ) 2569 l2cap_mode = L2CAP_FCR_STREAM_MODE; 2570 break; 2571 default: 2572 APPL_TRACE_ERROR("Invalid dch oper=%d for set dch chan cfg", p_dcb->dch_oper); 2573 break; 2574 } 2575 p_dcb->chnl_cfg.fcr_opt.mode = l2cap_mode; 2576 p_dcb->chnl_cfg.fcr_opt.mps = bta_hl_set_mps(p_dcb->max_rx_apdu_size); 2577 p_dcb->chnl_cfg.fcr_opt.tx_win_sz = bta_hl_set_tx_win_size(p_dcb->max_rx_apdu_size, 2578 p_dcb->chnl_cfg.fcr_opt.mps); 2579 p_dcb->chnl_cfg.fcr_opt.max_transmit= BTA_HL_L2C_MAX_TRANSMIT; 2580 p_dcb->chnl_cfg.fcr_opt.rtrans_tout = BTA_HL_L2C_RTRANS_TOUT; 2581 p_dcb->chnl_cfg.fcr_opt.mon_tout = BTA_HL_L2C_MON_TOUT; 2582 2583 p_dcb->chnl_cfg.user_rx_buf_size = bta_hl_set_user_rx_buf_size(p_dcb->max_rx_apdu_size); 2584 p_dcb->chnl_cfg.user_tx_buf_size = bta_hl_set_user_tx_buf_size(p_dcb->max_tx_apdu_size); 2585 p_dcb->chnl_cfg.fcr_rx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE; 2586 p_dcb->chnl_cfg.fcr_tx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE; 2587 p_dcb->chnl_cfg.data_mtu = p_dcb->max_rx_apdu_size; 2588 2589 p_dcb->chnl_cfg.fcs = BTA_HL_MCA_NO_FCS; 2590 if (local_mdep_cfg_idx != BTA_HL_ECHO_TEST_MDEP_CFG_IDX) 2591 { 2592 if (p_sup_feature->mdep[local_mdep_cfg_idx].mdep_cfg.mdep_role == 2593 BTA_HL_MDEP_ROLE_SOURCE) 2594 { 2595 p_dcb->chnl_cfg.fcs = BTA_HL_DEFAULT_SOURCE_FCS; 2596 } 2597 } 2598 else 2599 { 2600 p_dcb->chnl_cfg.fcs = BTA_HL_MCA_USE_FCS; 2601 } 2602 2603 #if BTA_HL_DEBUG == TRUE 2604 APPL_TRACE_DEBUG("L2CAP Params l2cap_mode[3-ERTM 4-STREAM]=%d", l2cap_mode); 2605 APPL_TRACE_DEBUG("Use FCS =%s mtu=%d", ((p_dcb->chnl_cfg.fcs & 1)?"YES":"NO"), 2606 p_dcb->chnl_cfg.data_mtu); 2607 APPL_TRACE_DEBUG("tx_win_sz=%d, max_transmit=%d, rtrans_tout=%d, mon_tout=%d, mps=%d", 2608 p_dcb->chnl_cfg.fcr_opt.tx_win_sz, 2609 p_dcb->chnl_cfg.fcr_opt.max_transmit, 2610 p_dcb->chnl_cfg.fcr_opt.rtrans_tout, 2611 p_dcb->chnl_cfg.fcr_opt.mon_tout, 2612 p_dcb->chnl_cfg.fcr_opt.mps); 2613 2614 APPL_TRACE_DEBUG("USER rx_buf_size=%d, tx_buf_size=%d, FCR rx_buf_size=%d, tx_buf_size=%d", 2615 p_dcb->chnl_cfg.user_rx_buf_size, 2616 p_dcb->chnl_cfg.user_tx_buf_size, 2617 p_dcb->chnl_cfg.fcr_rx_buf_size, 2618 p_dcb->chnl_cfg.fcr_tx_buf_size); 2619 2620 #endif 2621 2622 2623 2624 2625 2626 2627 2628 2629 } 2630 2631 /******************************************************************************* 2632 ** 2633 ** Function bta_hl_get_l2cap_cfg 2634 ** 2635 ** Description This function get the current L2CAP channel configuration 2636 ** 2637 ** Returns BOOLEAN - TRUE - operation is successful 2638 *******************************************************************************/ 2639 BOOLEAN bta_hl_get_l2cap_cfg(tBTA_HL_MDL_HANDLE mdl_hnd, tBTA_HL_L2CAP_CFG_INFO *p_cfg) 2640 { 2641 BOOLEAN success = FALSE; 2642 UINT16 lcid; 2643 tL2CAP_CFG_INFO *p_our_cfg; 2644 tL2CAP_CH_CFG_BITS our_cfg_bits; 2645 tL2CAP_CFG_INFO *p_peer_cfg; 2646 tL2CAP_CH_CFG_BITS peer_cfg_bits; 2647 2648 lcid = MCA_GetL2CapChannel((tMCA_DL) mdl_hnd); 2649 if ( lcid && 2650 L2CA_GetCurrentConfig(lcid, &p_our_cfg, &our_cfg_bits, &p_peer_cfg, 2651 &peer_cfg_bits)) 2652 { 2653 p_cfg->fcs = BTA_HL_MCA_NO_FCS; 2654 if (our_cfg_bits & L2CAP_CH_CFG_MASK_FCS) 2655 { 2656 p_cfg->fcs |= p_our_cfg->fcs; 2657 } 2658 else 2659 { 2660 p_cfg->fcs = BTA_HL_MCA_USE_FCS; 2661 } 2662 2663 if (p_cfg->fcs != BTA_HL_MCA_USE_FCS ) 2664 { 2665 if (peer_cfg_bits & L2CAP_CH_CFG_MASK_FCS) 2666 { 2667 p_cfg->fcs |= p_peer_cfg->fcs; 2668 } 2669 else 2670 { 2671 p_cfg->fcs = BTA_HL_MCA_USE_FCS; 2672 } 2673 } 2674 2675 p_cfg->mtu =0; 2676 if (peer_cfg_bits & L2CAP_CH_CFG_MASK_MTU) 2677 { 2678 p_cfg->mtu = p_peer_cfg->mtu; 2679 } 2680 else 2681 { 2682 p_cfg->mtu = L2CAP_DEFAULT_MTU; 2683 } 2684 success = TRUE; 2685 } 2686 else 2687 { 2688 p_cfg->mtu = L2CAP_DEFAULT_MTU; 2689 p_cfg->fcs = BTA_HL_L2C_NO_FCS; 2690 } 2691 2692 #if BTA_HL_DEBUG == TRUE 2693 if (!success) 2694 { 2695 APPL_TRACE_DEBUG("bta_hl_get_l2cap_cfg success=%d mdl=%d lcid=%d", success, mdl_hnd, lcid); 2696 APPL_TRACE_DEBUG("l2cap mtu=%d fcs=%d", p_cfg->mtu, p_cfg->fcs); 2697 } 2698 #endif 2699 2700 return success; 2701 } 2702 2703 /******************************************************************************* 2704 ** 2705 ** Function bta_hl_validate_chan_cfg 2706 ** 2707 ** Description This function validates the L2CAP channel configuration 2708 ** 2709 ** Returns BOOLEAN - TRUE - validation is successful 2710 *******************************************************************************/ 2711 BOOLEAN bta_hl_validate_chan_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx) 2712 { 2713 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 2714 tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2715 BOOLEAN success = FALSE; 2716 UINT8 mdl_cfg_idx = 0; 2717 tBTA_HL_L2CAP_CFG_INFO l2cap_cfg; 2718 BOOLEAN get_l2cap_result, get_mdl_result; 2719 2720 get_l2cap_result = bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg); 2721 get_mdl_result = bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_dcb->mdl_id, &mdl_cfg_idx); 2722 2723 if (get_l2cap_result && get_mdl_result) 2724 { 2725 if ((p_acb->mdl_cfg[mdl_cfg_idx].mtu <= l2cap_cfg.mtu) && 2726 (p_acb->mdl_cfg[mdl_cfg_idx].fcs == l2cap_cfg.fcs) && 2727 (p_acb->mdl_cfg[mdl_cfg_idx].dch_mode == p_dcb->dch_mode)) 2728 { 2729 success = TRUE; 2730 } 2731 } 2732 2733 2734 #if BTA_HL_DEBUG == TRUE 2735 2736 if (p_dcb->mtu != l2cap_cfg.mtu) 2737 { 2738 APPL_TRACE_WARNING("MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from l2cap mtu=%d", 2739 p_dcb->mtu, l2cap_cfg.mtu); 2740 } 2741 2742 if (!success) 2743 { 2744 APPL_TRACE_DEBUG("bta_hl_validate_chan_cfg success=%d app_idx=%d mcl_idx=%d mdl_idx=%d",success, app_idx, mcl_idx, mdl_idx); 2745 APPL_TRACE_DEBUG("Cur. L2cap cfg mtu=%d fcs=%d dch_mode=%d", l2cap_cfg.mtu, l2cap_cfg.fcs, p_dcb->dch_mode); 2746 APPL_TRACE_DEBUG("From saved: L2cap cfg mtu=%d fcs=%d dch_mode=%d", p_acb->mdl_cfg[mdl_cfg_idx].mtu, 2747 p_acb->mdl_cfg[mdl_cfg_idx].fcs , p_acb->mdl_cfg[mdl_cfg_idx].dch_mode); 2748 } 2749 #endif 2750 2751 return success; 2752 } 2753 2754 2755 /******************************************************************************* 2756 ** 2757 ** Function bta_hl_is_cong_on 2758 ** 2759 ** Description This function checks whether the congestion condition is on or not 2760 ** 2761 ** Returns BOOLEAN - TRUE DCH is congested 2762 ** FALSE not congested 2763 ** 2764 *******************************************************************************/ 2765 BOOLEAN bta_hl_is_cong_on(UINT8 app_id, BD_ADDR bd_addr, tBTA_HL_MDL_ID mdl_id) 2766 2767 { 2768 tBTA_HL_MDL_CB *p_dcb; 2769 UINT8 app_idx = 0, mcl_idx, mdl_idx; 2770 BOOLEAN cong_status = TRUE; 2771 2772 if (bta_hl_find_app_idx(app_id, &app_idx)) 2773 { 2774 if (bta_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx )) 2775 { 2776 if (bta_hl_find_mdl_idx(app_idx, mcl_idx, mdl_id, &mdl_idx )) 2777 { 2778 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2779 cong_status = p_dcb->cong; 2780 } 2781 } 2782 } 2783 2784 return cong_status; 2785 } 2786 2787 /******************************************************************************* 2788 ** 2789 ** Function bta_hl_check_cch_close 2790 ** 2791 ** Description This function checks whether there is a pending CCH close request 2792 ** or not 2793 ** 2794 ** Returns void 2795 *******************************************************************************/ 2796 void bta_hl_check_cch_close(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data, BOOLEAN check_dch_setup ) 2797 { 2798 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2799 tBTA_HL_MDL_CB *p_dcb; 2800 UINT8 mdl_idx; 2801 2802 #if (BTA_HL_DEBUG == TRUE) 2803 APPL_TRACE_DEBUG("bta_hl_check_cch_close cch_close_dch_oper=%d",p_mcb->cch_close_dch_oper ); 2804 #endif 2805 2806 if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE) 2807 { 2808 if (check_dch_setup && bta_hl_find_dch_setup_mdl_idx(app_idx, mcl_idx, &mdl_idx)) 2809 { 2810 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2811 if (!p_mcb->rsp_tout) 2812 { 2813 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_ABORT; 2814 2815 if (!p_dcb->abort_oper) 2816 { 2817 p_dcb->abort_oper |= BTA_HL_ABORT_CCH_CLOSE_MASK; 2818 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, p_data); 2819 } 2820 } 2821 else 2822 { 2823 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE; 2824 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 2825 } 2826 } 2827 else if (bta_hl_find_an_active_mdl_idx(app_idx, mcl_idx,&mdl_idx)) 2828 { 2829 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE; 2830 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, p_data); 2831 } 2832 else 2833 { 2834 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_NONE; 2835 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_EVT, p_data); 2836 } 2837 } 2838 } 2839 2840 /******************************************************************************* 2841 ** 2842 ** Function bta_hl_clean_app 2843 ** 2844 ** Description Cleans up the HDP application resources and control block 2845 ** 2846 ** Returns void 2847 ** 2848 *******************************************************************************/ 2849 void bta_hl_clean_app(UINT8 app_idx) 2850 { 2851 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 2852 int i, num_act_apps=0; 2853 2854 #if BTA_HL_DEBUG == TRUE 2855 APPL_TRACE_DEBUG("bta_hl_clean_app"); 2856 #endif 2857 MCA_Deregister((tMCA_HANDLE)p_acb->app_handle); 2858 2859 if (p_acb->sdp_handle) SDP_DeleteRecord(p_acb->sdp_handle); 2860 2861 memset((void *) p_acb, 0, sizeof(tBTA_HL_APP_CB)); 2862 2863 /* check any application is still active */ 2864 for (i=0; i < BTA_HL_NUM_APPS ; i ++) 2865 { 2866 p_acb = BTA_HL_GET_APP_CB_PTR(i); 2867 if (p_acb->in_use) num_act_apps++; 2868 } 2869 2870 if (!num_act_apps) 2871 { 2872 bta_sys_remove_uuid(UUID_SERVCLASS_HDP_PROFILE); 2873 } 2874 } 2875 2876 /******************************************************************************* 2877 ** 2878 ** Function bta_hl_check_deregistration 2879 ** 2880 ** Description This function checks whether there is a pending deregistration 2881 ** request or not 2882 ** 2883 ** Returns void 2884 *******************************************************************************/ 2885 void bta_hl_check_deregistration(UINT8 app_idx, tBTA_HL_DATA *p_data ) 2886 { 2887 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 2888 tBTA_HL_MCL_CB *p_mcb; 2889 UINT8 mcl_idx; 2890 tBTA_HL evt_data; 2891 2892 #if (BTA_HL_DEBUG == TRUE) 2893 APPL_TRACE_DEBUG("bta_hl_check_deregistration"); 2894 #endif 2895 2896 if (p_acb->deregistering) 2897 { 2898 if (bta_hl_find_an_in_use_mcl_idx(app_idx, &mcl_idx)) 2899 { 2900 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2901 if (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE) 2902 { 2903 if (p_mcb->cch_state == BTA_HL_CCH_OPENING_ST) 2904 p_mcb->force_close_local_cch_opening = TRUE; 2905 p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE; 2906 APPL_TRACE_DEBUG("p_mcb->force_close_local_cch_opening=%d", p_mcb->force_close_local_cch_opening ); 2907 bta_hl_check_cch_close(app_idx,mcl_idx,p_data, TRUE); 2908 } 2909 } 2910 else 2911 { 2912 /* all cchs are closed */ 2913 evt_data.dereg_cfm.app_handle = p_acb->app_handle; 2914 evt_data.dereg_cfm.app_id = p_data->api_dereg.app_id; 2915 evt_data.dereg_cfm.status = BTA_HL_STATUS_OK; 2916 p_acb->p_cback(BTA_HL_DEREGISTER_CFM_EVT, (tBTA_HL *) &evt_data ); 2917 bta_hl_clean_app(app_idx); 2918 bta_hl_check_disable(p_data); 2919 } 2920 } 2921 } 2922 2923 2924 /******************************************************************************* 2925 ** 2926 ** Function bta_hl_check_disable 2927 ** 2928 ** Description This function checks whether there is a pending disable 2929 ** request or not 2930 ** 2931 ** Returns void 2932 ** 2933 *******************************************************************************/ 2934 void bta_hl_check_disable(tBTA_HL_DATA *p_data ) 2935 { 2936 tBTA_HL_CB *p_cb= &bta_hl_cb; 2937 tBTA_HL_APP_CB *p_acb; 2938 UINT8 app_idx; 2939 tBTA_HL_CTRL evt_data; 2940 2941 #if (BTA_HL_DEBUG == TRUE) 2942 APPL_TRACE_DEBUG("bta_hl_check_disable"); 2943 #endif 2944 2945 if (bta_hl_cb.disabling) 2946 { 2947 if (bta_hl_find_an_in_use_app_idx(&app_idx)) 2948 { 2949 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 2950 if (!p_acb->deregistering) 2951 { 2952 p_acb->deregistering = TRUE; 2953 bta_hl_check_deregistration(app_idx, p_data); 2954 } 2955 } 2956 else 2957 { 2958 /* all apps are deregistered */ 2959 bta_sys_deregister(BTA_ID_HL); 2960 evt_data.disable_cfm.status = BTA_HL_STATUS_OK; 2961 if (p_cb->p_ctrl_cback) p_cb->p_ctrl_cback(BTA_HL_CTRL_DISABLE_CFM_EVT, (tBTA_HL_CTRL *) &evt_data); 2962 memset((void *) p_cb, 0, sizeof(tBTA_HL_CB)); 2963 } 2964 } 2965 } 2966 2967 /******************************************************************************* 2968 ** 2969 ** Function bta_hl_build_abort_cfm 2970 ** 2971 ** Description This function builds the abort confirmation event data 2972 ** 2973 ** Returns None 2974 ** 2975 *******************************************************************************/ 2976 void bta_hl_build_abort_cfm(tBTA_HL *p_evt_data, 2977 tBTA_HL_APP_HANDLE app_handle, 2978 tBTA_HL_MCL_HANDLE mcl_handle, 2979 tBTA_HL_STATUS status) 2980 { 2981 p_evt_data->dch_abort_cfm.status = status; 2982 p_evt_data->dch_abort_cfm.mcl_handle = mcl_handle; 2983 p_evt_data->dch_abort_cfm.app_handle = app_handle; 2984 } 2985 2986 /******************************************************************************* 2987 ** 2988 ** Function bta_hl_build_abort_ind 2989 ** 2990 ** Description This function builds the abort indication event data 2991 ** 2992 ** Returns None 2993 ** 2994 *******************************************************************************/ 2995 void bta_hl_build_abort_ind(tBTA_HL *p_evt_data, 2996 tBTA_HL_APP_HANDLE app_handle, 2997 tBTA_HL_MCL_HANDLE mcl_handle) 2998 { 2999 p_evt_data->dch_abort_ind.mcl_handle = mcl_handle; 3000 p_evt_data->dch_abort_ind.app_handle = app_handle; 3001 } 3002 /******************************************************************************* 3003 ** 3004 ** Function bta_hl_build_close_cfm 3005 ** 3006 ** Description This function builds the close confirmation event data 3007 ** 3008 ** Returns None 3009 ** 3010 *******************************************************************************/ 3011 void bta_hl_build_dch_close_cfm(tBTA_HL *p_evt_data, 3012 tBTA_HL_APP_HANDLE app_handle, 3013 tBTA_HL_MCL_HANDLE mcl_handle, 3014 tBTA_HL_MDL_HANDLE mdl_handle, 3015 tBTA_HL_STATUS status) 3016 { 3017 p_evt_data->dch_close_cfm.status = status; 3018 p_evt_data->dch_close_cfm.mdl_handle = mdl_handle; 3019 p_evt_data->dch_close_cfm.mcl_handle = mcl_handle; 3020 p_evt_data->dch_close_cfm.app_handle = app_handle; 3021 } 3022 3023 /******************************************************************************* 3024 ** 3025 ** Function bta_hl_build_dch_close_ind 3026 ** 3027 ** Description This function builds the close indication event data 3028 ** 3029 ** Returns None 3030 ** 3031 *******************************************************************************/ 3032 void bta_hl_build_dch_close_ind(tBTA_HL *p_evt_data, 3033 tBTA_HL_APP_HANDLE app_handle, 3034 tBTA_HL_MCL_HANDLE mcl_handle, 3035 tBTA_HL_MDL_HANDLE mdl_handle, 3036 BOOLEAN intentional) 3037 { 3038 p_evt_data->dch_close_ind.mdl_handle = mdl_handle; 3039 p_evt_data->dch_close_ind.mcl_handle = mcl_handle; 3040 p_evt_data->dch_close_ind.app_handle = app_handle; 3041 p_evt_data->dch_close_ind.intentional = intentional; 3042 } 3043 3044 /******************************************************************************* 3045 ** 3046 ** Function bta_hl_build_send_data_cfm 3047 ** 3048 ** Description This function builds the send data confirmation event data 3049 ** 3050 ** Returns None 3051 ** 3052 *******************************************************************************/ 3053 void bta_hl_build_send_data_cfm(tBTA_HL *p_evt_data, 3054 tBTA_HL_APP_HANDLE app_handle, 3055 tBTA_HL_MCL_HANDLE mcl_handle, 3056 tBTA_HL_MDL_HANDLE mdl_handle, 3057 tBTA_HL_STATUS status ) 3058 { 3059 3060 p_evt_data->dch_send_data_cfm.mdl_handle = mdl_handle; 3061 p_evt_data->dch_send_data_cfm.mcl_handle = mcl_handle; 3062 p_evt_data->dch_send_data_cfm.app_handle = app_handle; 3063 p_evt_data->dch_send_data_cfm.status = status; 3064 } 3065 3066 /******************************************************************************* 3067 ** 3068 ** Function bta_hl_build_rcv_data_ind 3069 ** 3070 ** Description This function builds the received data indication event data 3071 ** 3072 ** Returns None 3073 ** 3074 *******************************************************************************/ 3075 void bta_hl_build_rcv_data_ind(tBTA_HL *p_evt_data, 3076 tBTA_HL_APP_HANDLE app_handle, 3077 tBTA_HL_MCL_HANDLE mcl_handle, 3078 tBTA_HL_MDL_HANDLE mdl_handle) 3079 { 3080 p_evt_data->dch_rcv_data_ind.mdl_handle = mdl_handle; 3081 p_evt_data->dch_rcv_data_ind.mcl_handle = mcl_handle; 3082 p_evt_data->dch_rcv_data_ind.app_handle = app_handle; 3083 } 3084 3085 3086 /******************************************************************************* 3087 ** 3088 ** Function bta_hl_build_cch_open_cfm 3089 ** 3090 ** Description This function builds the CCH open confirmation event data 3091 ** 3092 ** Returns None 3093 ** 3094 *******************************************************************************/ 3095 void bta_hl_build_cch_open_cfm(tBTA_HL *p_evt_data, 3096 UINT8 app_id, 3097 tBTA_HL_APP_HANDLE app_handle, 3098 tBTA_HL_MCL_HANDLE mcl_handle, 3099 BD_ADDR bd_addr, 3100 tBTA_HL_STATUS status ) 3101 { 3102 p_evt_data->cch_open_cfm.app_id = app_id; 3103 p_evt_data->cch_open_cfm.app_handle = app_handle; 3104 p_evt_data->cch_open_cfm.mcl_handle = mcl_handle; 3105 bdcpy(p_evt_data->cch_open_cfm.bd_addr, bd_addr); 3106 p_evt_data->cch_open_cfm.status = status; 3107 APPL_TRACE_DEBUG("bta_hl_build_cch_open_cfm: status=%d",status); 3108 } 3109 3110 /******************************************************************************* 3111 ** 3112 ** Function bta_hl_build_cch_open_ind 3113 ** 3114 ** Description This function builds the CCH open indication event data 3115 ** 3116 ** Returns None 3117 ** 3118 *******************************************************************************/ 3119 void bta_hl_build_cch_open_ind(tBTA_HL *p_evt_data, tBTA_HL_APP_HANDLE app_handle, 3120 tBTA_HL_MCL_HANDLE mcl_handle, 3121 BD_ADDR bd_addr ) 3122 { 3123 3124 p_evt_data->cch_open_ind.app_handle = app_handle; 3125 p_evt_data->cch_open_ind.mcl_handle = mcl_handle; 3126 bdcpy(p_evt_data->cch_open_ind.bd_addr, bd_addr); 3127 } 3128 3129 /******************************************************************************* 3130 ** 3131 ** Function bta_hl_build_cch_close_cfm 3132 ** 3133 ** Description This function builds the CCH close confirmation event data 3134 ** 3135 ** Returns None 3136 ** 3137 *******************************************************************************/ 3138 void bta_hl_build_cch_close_cfm(tBTA_HL *p_evt_data, 3139 tBTA_HL_APP_HANDLE app_handle, 3140 tBTA_HL_MCL_HANDLE mcl_handle, 3141 tBTA_HL_STATUS status ) 3142 { 3143 p_evt_data->cch_close_cfm.mcl_handle = mcl_handle; 3144 p_evt_data->cch_close_cfm.app_handle = app_handle; 3145 p_evt_data->cch_close_cfm.status = status; 3146 } 3147 3148 3149 /******************************************************************************* 3150 ** 3151 ** Function bta_hl_build_cch_close_ind 3152 ** 3153 ** Description This function builds the CCH colse indication event data 3154 ** 3155 ** Returns None 3156 ** 3157 *******************************************************************************/ 3158 void bta_hl_build_cch_close_ind(tBTA_HL *p_evt_data, 3159 tBTA_HL_APP_HANDLE app_handle, 3160 tBTA_HL_MCL_HANDLE mcl_handle, 3161 BOOLEAN intentional) 3162 { 3163 p_evt_data->cch_close_ind.mcl_handle = mcl_handle; 3164 p_evt_data->cch_close_ind.app_handle = app_handle; 3165 p_evt_data->cch_close_ind.intentional = intentional; 3166 } 3167 3168 /******************************************************************************* 3169 ** 3170 ** Function bta_hl_build_dch_open_cfm 3171 ** 3172 ** Description This function builds the DCH open confirmation event data 3173 ** 3174 ** Returns None 3175 ** 3176 *******************************************************************************/ 3177 void bta_hl_build_dch_open_cfm(tBTA_HL *p_evt_data, 3178 tBTA_HL_APP_HANDLE app_handle, 3179 tBTA_HL_MCL_HANDLE mcl_handle, 3180 tBTA_HL_MDL_HANDLE mdl_handle, 3181 tBTA_HL_MDEP_ID local_mdep_id, 3182 tBTA_HL_MDL_ID mdl_id, 3183 tBTA_HL_DCH_MODE dch_mode, 3184 BOOLEAN first_reliable, 3185 UINT16 mtu, 3186 tBTA_HL_STATUS status) 3187 3188 { 3189 p_evt_data->dch_open_cfm.mdl_handle = mdl_handle; 3190 p_evt_data->dch_open_cfm.mcl_handle = mcl_handle; 3191 p_evt_data->dch_open_cfm.app_handle = app_handle; 3192 p_evt_data->dch_open_cfm.local_mdep_id = local_mdep_id; 3193 p_evt_data->dch_open_cfm.mdl_id = mdl_id; 3194 p_evt_data->dch_open_cfm.dch_mode = dch_mode; 3195 p_evt_data->dch_open_cfm.first_reliable = first_reliable; 3196 p_evt_data->dch_open_cfm.mtu = mtu; 3197 p_evt_data->dch_open_cfm.status = status; 3198 } 3199 3200 3201 /******************************************************************************* 3202 ** 3203 ** Function bta_hl_build_sdp_query_cfm 3204 ** 3205 ** Description This function builds the SDP query indication event data 3206 ** 3207 ** Returns None 3208 ** 3209 *******************************************************************************/ 3210 void bta_hl_build_sdp_query_cfm(tBTA_HL *p_evt_data, 3211 UINT8 app_id, 3212 tBTA_HL_APP_HANDLE app_handle, 3213 BD_ADDR bd_addr, 3214 tBTA_HL_SDP *p_sdp, 3215 tBTA_HL_STATUS status) 3216 3217 { 3218 APPL_TRACE_DEBUG("bta_hl_build_sdp_query_cfm: app_id = %d, app_handle=%d", 3219 app_id,app_handle); 3220 p_evt_data->sdp_query_cfm.app_id = app_id; 3221 p_evt_data->sdp_query_cfm.app_handle = app_handle; 3222 bdcpy(p_evt_data->sdp_query_cfm.bd_addr, bd_addr); 3223 p_evt_data->sdp_query_cfm.p_sdp = p_sdp; 3224 p_evt_data->sdp_query_cfm.status = status; 3225 } 3226 3227 3228 /******************************************************************************* 3229 ** 3230 ** Function bta_hl_build_delete_mdl_cfm 3231 ** 3232 ** Description This function builds the delete MDL confirmation event data 3233 ** 3234 ** Returns None 3235 ** 3236 *******************************************************************************/ 3237 void bta_hl_build_delete_mdl_cfm(tBTA_HL *p_evt_data, 3238 tBTA_HL_APP_HANDLE app_handle, 3239 tBTA_HL_MCL_HANDLE mcl_handle, 3240 tBTA_HL_MDL_ID mdl_id, 3241 tBTA_HL_STATUS status) 3242 3243 { 3244 p_evt_data->delete_mdl_cfm.mcl_handle = mcl_handle; 3245 p_evt_data->delete_mdl_cfm.app_handle = app_handle; 3246 p_evt_data->delete_mdl_cfm.mdl_id = mdl_id; 3247 p_evt_data->delete_mdl_cfm.status = status; 3248 } 3249 3250 /******************************************************************************* 3251 ** 3252 ** Function bta_hl_build_echo_test_cfm 3253 ** 3254 ** Description This function builds the echo test confirmation event data 3255 ** 3256 ** Returns None 3257 ** 3258 *******************************************************************************/ 3259 void bta_hl_build_echo_test_cfm(tBTA_HL *p_evt_data, 3260 tBTA_HL_APP_HANDLE app_handle, 3261 tBTA_HL_MCL_HANDLE mcl_handle, 3262 tBTA_HL_STATUS status ) 3263 { 3264 p_evt_data->echo_test_cfm.mcl_handle = mcl_handle; 3265 p_evt_data->echo_test_cfm.app_handle = app_handle; 3266 p_evt_data->echo_test_cfm.status = status; 3267 } 3268 3269 3270 /***************************************************************************** 3271 ** Debug Functions 3272 *****************************************************************************/ 3273 #if (BTA_HL_DEBUG == TRUE) 3274 3275 /******************************************************************************* 3276 ** 3277 ** Function bta_hl_status_code 3278 ** 3279 ** Description get the status string pointer 3280 ** 3281 ** Returns char * - status string pointer 3282 ** 3283 *******************************************************************************/ 3284 char *bta_hl_status_code(tBTA_HL_STATUS status) 3285 { 3286 switch (status) 3287 { 3288 case BTA_HL_STATUS_OK: 3289 return "BTA_HL_STATUS_OK"; 3290 case BTA_HL_STATUS_FAIL: 3291 return "BTA_HL_STATUS_FAIL"; 3292 case BTA_HL_STATUS_ABORTED: 3293 return "BTA_HL_STATUS_ABORTED"; 3294 case BTA_HL_STATUS_NO_RESOURCE: 3295 return "BTA_HL_STATUS_NO_RESOURCE"; 3296 case BTA_HL_STATUS_LAST_ITEM: 3297 return "BTA_HL_STATUS_LAST_ITEM"; 3298 case BTA_HL_STATUS_DUPLICATE_APP_ID: 3299 return "BTA_HL_STATUS_DUPLICATE_APP_ID"; 3300 case BTA_HL_STATUS_INVALID_APP_HANDLE: 3301 return "BTA_HL_STATUS_INVALID_APP_HANDLE"; 3302 case BTA_HL_STATUS_INVALID_MCL_HANDLE: 3303 return "BTA_HL_STATUS_INVALID_MCL_HANDLE"; 3304 case BTA_HL_STATUS_MCAP_REG_FAIL: 3305 return "BTA_HL_STATUS_MCAP_REG_FAIL"; 3306 case BTA_HL_STATUS_MDEP_CO_FAIL: 3307 return "BTA_HL_STATUS_MDEP_CO_FAIL"; 3308 case BTA_HL_STATUS_ECHO_CO_FAIL: 3309 return "BTA_HL_STATUS_ECHO_CO_FAIL"; 3310 case BTA_HL_STATUS_MDL_CFG_CO_FAIL: 3311 return "BTA_HL_STATUS_MDL_CFG_CO_FAIL"; 3312 case BTA_HL_STATUS_SDP_NO_RESOURCE: 3313 return "BTA_HL_STATUS_SDP_NO_RESOURCE"; 3314 case BTA_HL_STATUS_SDP_FAIL: 3315 return "BTA_HL_STATUS_SDP_FAIL"; 3316 case BTA_HL_STATUS_NO_CCH: 3317 return "BTA_HL_STATUS_NO_CCH"; 3318 case BTA_HL_STATUS_NO_MCL: 3319 return "BTA_HL_STATUS_NO_MCL"; 3320 3321 case BTA_HL_STATUS_NO_FIRST_RELIABLE: 3322 return "BTA_HL_STATUS_NO_FIRST_RELIABLE"; 3323 case BTA_HL_STATUS_INVALID_DCH_CFG: 3324 return "BTA_HL_STATUS_INVALID_DCH_CFG"; 3325 case BTA_HL_STATUS_INVALID_BD_ADDR: 3326 return "BTA_HL_STATUS_INVALID_BD_ADDR"; 3327 case BTA_HL_STATUS_INVALID_RECONNECT_CFG: 3328 return "BTA_HL_STATUS_INVALID_RECONNECT_CFG"; 3329 case BTA_HL_STATUS_ECHO_TEST_BUSY: 3330 return "BTA_HL_STATUS_ECHO_TEST_BUSY"; 3331 case BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID: 3332 return "BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID"; 3333 case BTA_HL_STATUS_INVALID_MDL_ID: 3334 return "BTA_HL_STATUS_INVALID_MDL_ID"; 3335 case BTA_HL_STATUS_NO_MDL_ID_FOUND: 3336 return "BTA_HL_STATUS_NO_MDL_ID_FOUND"; 3337 case BTA_HL_STATUS_DCH_BUSY: 3338 return "BTA_HL_STATUS_DCH_BUSY"; 3339 default: 3340 return "Unknown status code"; 3341 } 3342 } 3343 /******************************************************************************* 3344 ** 3345 ** Function bta_hl_evt_code 3346 ** 3347 ** Description Maps HL event code to the corresponding event string 3348 ** 3349 ** Returns string pointer for the associated event name 3350 ** 3351 *******************************************************************************/ 3352 char *bta_hl_evt_code(tBTA_HL_INT_EVT evt_code) 3353 { 3354 switch (evt_code) 3355 { 3356 case BTA_HL_CCH_OPEN_EVT: 3357 return "BTA_HL_CCH_OPEN_EVT"; 3358 case BTA_HL_CCH_SDP_OK_EVT: 3359 return "BTA_HL_CCH_SDP_OK_EVT"; 3360 case BTA_HL_CCH_SDP_FAIL_EVT: 3361 return "BTA_HL_CCH_SDP_FAIL_EVT"; 3362 case BTA_HL_MCA_CONNECT_IND_EVT: 3363 return "BTA_HL_MCA_CONNECT_IND_EVT"; 3364 case BTA_HL_MCA_DISCONNECT_IND_EVT: 3365 return "BTA_HL_MCA_DISCONNECT_IND_EVT"; 3366 3367 case BTA_HL_CCH_CLOSE_EVT: 3368 return "BTA_HL_CCH_CLOSE_EVT"; 3369 case BTA_HL_CCH_CLOSE_CMPL_EVT: 3370 return "BTA_HL_CCH_CLOSE_CMPL_EVT"; 3371 case BTA_HL_DCH_OPEN_EVT: 3372 return "BTA_HL_DCH_OPEN_EVT"; 3373 case BTA_HL_MCA_CREATE_IND_EVT: 3374 return "BTA_HL_MCA_CREATE_IND_EVT"; 3375 case BTA_HL_MCA_CREATE_CFM_EVT: 3376 return "BTA_HL_MCA_CREATE_CFM_EVT"; 3377 case BTA_HL_MCA_OPEN_IND_EVT: 3378 return "BTA_HL_MCA_OPEN_IND_EVT"; 3379 case BTA_HL_MCA_OPEN_CFM_EVT: 3380 return "BTA_HL_MCA_OPEN_CFM_EVT"; 3381 case BTA_HL_DCH_CLOSE_EVT: 3382 return "BTA_HL_DCH_CLOSE_EVT"; 3383 case BTA_HL_MCA_CLOSE_IND_EVT: 3384 return "BTA_HL_MCA_CLOSE_IND_EVT"; 3385 case BTA_HL_MCA_CLOSE_CFM_EVT: 3386 return "BTA_HL_MCA_CLOSE_CFM_EVT"; 3387 case BTA_HL_API_SEND_DATA_EVT: 3388 return "BTA_HL_API_SEND_DATA_EVT"; 3389 case BTA_HL_MCA_RCV_DATA_EVT: 3390 return "BTA_HL_MCA_RCV_DATA_EVT"; 3391 case BTA_HL_DCH_CLOSE_CMPL_EVT: 3392 return "BTA_HL_DCH_CLOSE_CMPL_EVT"; 3393 3394 case BTA_HL_API_ENABLE_EVT: 3395 return "BTA_HL_API_ENABLE_EVT"; 3396 case BTA_HL_API_DISABLE_EVT: 3397 return "BTA_HL_API_DISABLE_EVT"; 3398 case BTA_HL_API_UPDATE_EVT: 3399 return "BTA_HL_API_UPDATE_EVT"; 3400 case BTA_HL_API_REGISTER_EVT: 3401 return "BTA_HL_API_REGISTER_EVT"; 3402 case BTA_HL_API_DEREGISTER_EVT: 3403 return "BTA_HL_API_DEREGISTER_EVT"; 3404 3405 case BTA_HL_API_CCH_OPEN_EVT: 3406 return "BTA_HL_API_CCH_OPEN_EVT"; 3407 3408 case BTA_HL_API_CCH_CLOSE_EVT: 3409 return "BTA_HL_API_CCH_CLOSE_EVT"; 3410 case BTA_HL_API_DCH_OPEN_EVT: 3411 return "BTA_HL_API_DCH_OPEN_EVT"; 3412 3413 case BTA_HL_API_DCH_RECONNECT_EVT: 3414 return "BTA_HL_API_DCH_RECONNECT_EVT"; 3415 case BTA_HL_API_DCH_CLOSE_EVT: 3416 return "BTA_HL_API_DCH_CLOSE_EVT"; 3417 case BTA_HL_API_DELETE_MDL_EVT: 3418 return "BTA_HL_API_DELETE_MDL_EVT"; 3419 case BTA_HL_API_DCH_ABORT_EVT: 3420 return "BTA_HL_API_DCH_ABORT_EVT"; 3421 3422 case BTA_HL_DCH_RECONNECT_EVT: 3423 return "BTA_HL_DCH_RECONNECT_EVT"; 3424 case BTA_HL_DCH_SDP_INIT_EVT: 3425 return "BTA_HL_DCH_SDP_INIT_EVT"; 3426 case BTA_HL_DCH_SDP_FAIL_EVT: 3427 return "BTA_HL_DCH_SDP_FAIL_EVT"; 3428 case BTA_HL_API_DCH_ECHO_TEST_EVT: 3429 return "BTA_HL_API_DCH_ECHO_TEST_EVT"; 3430 case BTA_HL_DCH_CLOSE_ECHO_TEST_EVT: 3431 return "BTA_HL_DCH_CLOSE_ECHO_TEST_EVT"; 3432 case BTA_HL_MCA_RECONNECT_IND_EVT: 3433 return "BTA_HL_MCA_RECONNECT_IND_EVT"; 3434 case BTA_HL_MCA_RECONNECT_CFM_EVT: 3435 return "BTA_HL_MCA_RECONNECT_CFM_EVT"; 3436 case BTA_HL_API_DCH_CREATE_RSP_EVT: 3437 return "BTA_HL_API_DCH_CREATE_RSP_EVT"; 3438 case BTA_HL_DCH_ABORT_EVT: 3439 return "BTA_HL_DCH_ABORT_EVT"; 3440 case BTA_HL_MCA_ABORT_IND_EVT: 3441 return "BTA_HL_MCA_ABORT_IND_EVT"; 3442 case BTA_HL_MCA_ABORT_CFM_EVT: 3443 return "BTA_HL_MCA_ABORT_CFM_EVT"; 3444 case BTA_HL_MCA_DELETE_IND_EVT: 3445 return "BTA_HL_MCA_DELETE_IND_EVT"; 3446 case BTA_HL_MCA_DELETE_CFM_EVT: 3447 return "BTA_HL_MCA_DELETE_CFM_EVT"; 3448 case BTA_HL_MCA_CONG_CHG_EVT: 3449 return "BTA_HL_MCA_CONG_CHG_EVT"; 3450 case BTA_HL_CI_GET_TX_DATA_EVT: 3451 return "BTA_HL_CI_GET_TX_DATA_EVT"; 3452 case BTA_HL_CI_PUT_RX_DATA_EVT: 3453 return "BTA_HL_CI_PUT_RX_DATA_EVT"; 3454 case BTA_HL_CI_GET_ECHO_DATA_EVT: 3455 return "BTA_HL_CI_GET_ECHO_DATA_EVT"; 3456 case BTA_HL_DCH_ECHO_TEST_EVT: 3457 return "BTA_HL_DCH_ECHO_TEST_EVT"; 3458 case BTA_HL_CI_PUT_ECHO_DATA_EVT: 3459 return "BTA_HL_CI_PUT_ECHO_DATA_EVT"; 3460 case BTA_HL_API_SDP_QUERY_EVT: 3461 return "BTA_HL_API_SDP_QUERY_EVT"; 3462 case BTA_HL_SDP_QUERY_OK_EVT: 3463 return "BTA_HL_SDP_QUERY_OK_EVT"; 3464 case BTA_HL_SDP_QUERY_FAIL_EVT: 3465 return "BTA_HL_SDP_QUERY_FAIL_EVT"; 3466 case BTA_HL_MCA_RSP_TOUT_IND_EVT: 3467 return "BTA_HL_MCA_RSP_TOUT_IND_EVT"; 3468 3469 default: 3470 return "Unknown HL event code"; 3471 } 3472 } 3473 3474 #endif /* Debug Functions */ 3475 #endif // HL_INCLUDED 3476 3477 3478 3479 3480 3481 3482 3483 3484