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