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