1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-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 * Filename: btif_hl.c 22 * 23 * Description: Health Device Profile Bluetooth Interface 24 * 25 * 26 ******************************************************************************/ 27 #define LOG_TAG "bt_btif_hl" 28 29 #include "btif_hl.h" 30 31 #include <base/logging.h> 32 #include <ctype.h> 33 #include <errno.h> 34 #include <fcntl.h> 35 #include <pthread.h> 36 #include <signal.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <sys/poll.h> 41 #include <sys/prctl.h> 42 #include <sys/select.h> 43 #include <sys/socket.h> 44 #include <sys/types.h> 45 #include <sys/un.h> 46 #include <time.h> 47 #include <unistd.h> 48 49 #include <hardware/bt_hl.h> 50 51 #include "bta_api.h" 52 #include "btif_common.h" 53 #include "btif_storage.h" 54 #include "btif_util.h" 55 #include "btu.h" 56 #include "mca_api.h" 57 #include "osi/include/list.h" 58 #include "osi/include/log.h" 59 #include "osi/include/osi.h" 60 61 #define MAX_DATATYPE_SUPPORTED 8 62 63 extern int btif_hl_update_maxfd(int max_org_s); 64 extern void btif_hl_select_monitor_callback(fd_set* p_cur_set, 65 UNUSED_ATTR fd_set* p_org_set); 66 extern void btif_hl_select_wakeup_callback(fd_set* p_org_set, 67 int wakeup_signal); 68 extern int btif_hl_update_maxfd(int max_org_s); 69 extern void btif_hl_select_monitor_callback(fd_set* p_cur_set, 70 UNUSED_ATTR fd_set* p_org_set); 71 extern void btif_hl_select_wakeup_callback(fd_set* p_org_set, 72 int wakeup_signal); 73 extern void btif_hl_soc_thread_init(void); 74 extern void btif_hl_release_mcl_sockets(uint8_t app_idx, uint8_t mcl_idx); 75 extern bool btif_hl_create_socket(uint8_t app_idx, uint8_t mcl_idx, 76 uint8_t mdl_idx); 77 extern void btif_hl_release_socket(uint8_t app_idx, uint8_t mcl_idx, 78 uint8_t mdl_idx); 79 80 btif_hl_cb_t btif_hl_cb; 81 btif_hl_cb_t* p_btif_hl_cb = &btif_hl_cb; 82 83 /******************************************************************************* 84 * Static variables 85 ******************************************************************************/ 86 static bthl_callbacks_t bt_hl_callbacks_cb; 87 static bthl_callbacks_t* bt_hl_callbacks = NULL; 88 89 /* signal socketpair to wake up select loop */ 90 91 const int btif_hl_signal_select_wakeup = 1; 92 const int btif_hl_signal_select_exit = 2; 93 const int btif_hl_signal_select_close_connected = 3; 94 95 static int listen_s = -1; 96 static int connected_s = -1; 97 static pthread_t select_thread_id = -1; 98 static int signal_fds[2] = {-1, -1}; 99 static list_t* soc_queue; 100 static int reg_counter; 101 102 static inline int btif_hl_select_wakeup(void); 103 static inline int btif_hl_select_close_connected(void); 104 static inline int btif_hl_close_select_thread(void); 105 static uint8_t btif_hl_get_next_app_id(void); 106 static int btif_hl_get_next_channel_id(uint8_t app_id); 107 static void btif_hl_init_next_app_id(void); 108 static void btif_hl_init_next_channel_id(void); 109 static void btif_hl_ctrl_cback(tBTA_HL_CTRL_EVT event, tBTA_HL_CTRL* p_data); 110 static void btif_hl_set_state(btif_hl_state_t state); 111 static btif_hl_state_t btif_hl_get_state(void); 112 static void btif_hl_cback(tBTA_HL_EVT event, tBTA_HL* p_data); 113 static void btif_hl_proc_cb_evt(uint16_t event, char* p_param); 114 115 #define CHECK_CALL_CBACK(P_CB, P_CBACK, ...) \ 116 do { \ 117 if ((P_CB) && (P_CB)->P_CBACK) { \ 118 (P_CB)->P_CBACK(__VA_ARGS__); \ 119 } else { \ 120 ASSERTC(0, "Callback is NULL", 0); \ 121 } \ 122 } while (0) 123 124 #define BTIF_HL_CALL_CBACK(P_CB, P_CBACK, ...) \ 125 do { \ 126 if ((p_btif_hl_cb->state != BTIF_HL_STATE_DISABLING) && \ 127 (p_btif_hl_cb->state != BTIF_HL_STATE_DISABLED)) { \ 128 if ((P_CB) && (P_CB)->P_CBACK) { \ 129 (P_CB)->P_CBACK(__VA_ARGS__); \ 130 } else { \ 131 ASSERTC(0, "Callback is NULL", 0); \ 132 } \ 133 } \ 134 } while (0) 135 136 #define CHECK_BTHL_INIT() \ 137 do { \ 138 if (bt_hl_callbacks == NULL) { \ 139 BTIF_TRACE_WARNING("BTHL: %s: BTHL not initialized", __func__); \ 140 return BT_STATUS_NOT_READY; \ 141 } \ 142 } while (0) 143 144 static const btif_hl_data_type_cfg_t data_type_table[] = { 145 /* Data Specilization Ntx Nrx (from Bluetooth SIG's 146 HDP whitepaper)*/ 147 {BTIF_HL_DATA_TYPE_PULSE_OXIMETER, 9216, 256}, 148 {BTIF_HL_DATA_TYPE_BLOOD_PRESSURE_MON, 896, 224}, 149 {BTIF_HL_DATA_TYPE_BODY_THERMOMETER, 896, 224}, 150 {BTIF_HL_DATA_TYPE_BODY_WEIGHT_SCALE, 896, 224}, 151 {BTIF_HL_DATA_TYPE_GLUCOSE_METER, 896, 224}, 152 {BTIF_HL_DATA_TYPE_STEP_COUNTER, 6624, 224}, 153 {BTIF_HL_DATA_TYPE_BCA, 7730, 1230}, 154 {BTIF_HL_DATA_TYPE_PEAK_FLOW, 2030, 224}, 155 {BTIF_HL_DATA_TYPE_ACTIVITY_HUB, 5120, 224}, 156 {BTIF_HL_DATA_TYPE_AMM, 1024, 64}}; 157 158 #define BTIF_HL_DATA_TABLE_SIZE \ 159 (sizeof(data_type_table) / sizeof(btif_hl_data_type_cfg_t)) 160 #define BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE \ 161 10240 /* use this size if the data type is not \ 162 defined in the table; for future proof */ 163 #define BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE \ 164 512 /* use this size if the data type is not \ 165 defined in the table; for future proof */ 166 167 #define BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE 1024 168 169 /******************************************************************************* 170 * Static utility functions 171 ******************************************************************************/ 172 173 #define BTIF_IF_GET_NAME 16 174 void btif_hl_display_calling_process_name(void) { 175 char name[16]; 176 prctl(BTIF_IF_GET_NAME, name, 0, 0, 0); 177 BTIF_TRACE_DEBUG("Process name (%s)", name); 178 } 179 #define BTIF_TIMEOUT_CCH_NO_DCH_MS (30 * 1000) 180 181 /******************************************************************************* 182 * 183 * Function btif_hl_if_channel_setup_pending 184 * 185 * Description check whether channel id is in setup pending state or not 186 * 187 * Returns bool 188 * 189 ******************************************************************************/ 190 bool btif_hl_if_channel_setup_pending(int channel_id, uint8_t* p_app_idx, 191 uint8_t* p_mcl_idx) { 192 btif_hl_app_cb_t* p_acb; 193 btif_hl_mcl_cb_t* p_mcb; 194 uint8_t i, j; 195 bool found = false; 196 197 *p_app_idx = 0; 198 *p_mcl_idx = 0; 199 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 200 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 201 if (p_acb->in_use) { 202 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 203 p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, j); 204 if (p_mcb->in_use && p_mcb->is_connected && 205 p_mcb->pcb.channel_id == channel_id) { 206 found = true; 207 *p_app_idx = i; 208 *p_mcl_idx = j; 209 break; 210 } 211 } 212 } 213 if (found) break; 214 } 215 BTIF_TRACE_DEBUG("%s found=%d channel_id=0x%08x", __func__, found, channel_id, 216 *p_app_idx, *p_mcl_idx); 217 return found; 218 } 219 /******************************************************************************* 220 * 221 * Function btif_hl_num_dchs_in_use 222 * 223 * Description find number of DCHs in use 224 * 225 * Returns uint8_t 226 ******************************************************************************/ 227 uint8_t btif_hl_num_dchs_in_use(uint8_t mcl_handle) { 228 btif_hl_app_cb_t* p_acb; 229 btif_hl_mcl_cb_t* p_mcb; 230 uint8_t i, j, x; 231 uint8_t cnt = 0; 232 233 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 234 BTIF_TRACE_DEBUG("btif_hl_num_dchs:i = %d", i); 235 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 236 if (p_acb && p_acb->in_use) { 237 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 238 if (p_acb->mcb[j].in_use) 239 BTIF_TRACE_DEBUG( 240 "btif_hl_num_dchs:mcb in use j=%d, mcl_handle=%d,mcb handle=%d", 241 j, mcl_handle, p_acb->mcb[j].mcl_handle); 242 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) { 243 p_mcb = &p_acb->mcb[j]; 244 BTIF_TRACE_DEBUG("btif_hl_num_dchs: mcl handle found j =%d", j); 245 for (x = 0; x < BTA_HL_NUM_MDLS_PER_MCL; x++) { 246 if (p_mcb->mdl[x].in_use) { 247 BTIF_TRACE_DEBUG("btif_hl_num_dchs_in_use:found x =%d", x); 248 cnt++; 249 } 250 } 251 } 252 } 253 } 254 } 255 256 BTIF_TRACE_DEBUG("%s dch in use count=%d", __func__, cnt); 257 return cnt; 258 } 259 /******************************************************************************* 260 * 261 * Function btif_hl_timer_timeout 262 * 263 * Description Process timer timeout 264 * 265 * Returns void 266 ******************************************************************************/ 267 void btif_hl_timer_timeout(void* data) { 268 btif_hl_mcl_cb_t* p_mcb = (btif_hl_mcl_cb_t*)data; 269 270 BTIF_TRACE_DEBUG("%s", __func__); 271 if (p_mcb->is_connected) { 272 BTIF_TRACE_DEBUG("Idle timeout Close CCH mcl_handle=%d", p_mcb->mcl_handle); 273 BTA_HlCchClose(p_mcb->mcl_handle); 274 } else { 275 BTIF_TRACE_DEBUG("CCH idle timeout But CCH not connected"); 276 } 277 } 278 279 /******************************************************************************* 280 * 281 * Function btif_hl_stop_cch_timer 282 * 283 * Description stop CCH timer 284 * 285 * Returns void 286 ******************************************************************************/ 287 void btif_hl_stop_cch_timer(uint8_t app_idx, uint8_t mcl_idx) { 288 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 289 290 BTIF_TRACE_DEBUG("%s app_idx=%d, mcl_idx=%d", __func__, app_idx, mcl_idx); 291 alarm_cancel(p_mcb->cch_timer); 292 } 293 294 /******************************************************************************* 295 * 296 * Function btif_hl_start_cch_timer 297 * 298 * Description start CCH timer 299 * 300 * Returns void 301 ******************************************************************************/ 302 void btif_hl_start_cch_timer(uint8_t app_idx, uint8_t mcl_idx) { 303 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 304 BTIF_TRACE_DEBUG("%s app_idx=%d, mcl_idx=%d", __func__, app_idx, mcl_idx); 305 306 alarm_free(p_mcb->cch_timer); 307 p_mcb->cch_timer = alarm_new("btif_hl.mcl_cch_timer"); 308 alarm_set_on_mloop(p_mcb->cch_timer, BTIF_TIMEOUT_CCH_NO_DCH_MS, 309 btif_hl_timer_timeout, p_mcb); 310 } 311 312 /******************************************************************************* 313 * 314 * Function btif_hl_find_mdl_idx 315 * 316 * Description Find the MDL index using MDL ID 317 * 318 * Returns bool 319 * 320 ******************************************************************************/ 321 static bool btif_hl_find_mdl_idx(uint8_t app_idx, uint8_t mcl_idx, 322 uint16_t mdl_id, uint8_t* p_mdl_idx) { 323 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 324 bool found = false; 325 uint8_t i; 326 327 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) { 328 if (p_mcb->mdl[i].in_use && (mdl_id != 0) && 329 (p_mcb->mdl[i].mdl_id == mdl_id)) { 330 found = true; 331 *p_mdl_idx = i; 332 break; 333 } 334 } 335 336 BTIF_TRACE_DEBUG("%s found=%d mdl_id=%d mdl_idx=%d ", __func__, found, mdl_id, 337 i); 338 339 return found; 340 } 341 342 /******************************************************************************* 343 * 344 * Function btif_hl_is_the_first_reliable_existed 345 * 346 * Description This function checks whether the first reliable DCH channel 347 * has been setup on the MCL or not 348 * 349 * Returns bool - true exist 350 * false does not exist 351 * 352 ******************************************************************************/ 353 bool btif_hl_is_the_first_reliable_existed(uint8_t app_idx, uint8_t mcl_idx) { 354 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 355 bool is_existed = false; 356 uint8_t i; 357 358 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) { 359 if (p_mcb->mdl[i].in_use && p_mcb->mdl[i].is_the_first_reliable) { 360 is_existed = true; 361 break; 362 } 363 } 364 365 BTIF_TRACE_DEBUG("bta_hl_is_the_first_reliable_existed is_existed=%d ", 366 is_existed); 367 return is_existed; 368 } 369 /******************************************************************************* 370 * 371 * Function btif_hl_clean_delete_mdl 372 * 373 * Description Cleanup the delete mdl control block 374 * 375 * Returns Nothing 376 * 377 ******************************************************************************/ 378 static void btif_hl_clean_delete_mdl(btif_hl_delete_mdl_t* p_cb) { 379 BTIF_TRACE_DEBUG("%s", __func__); 380 memset(p_cb, 0, sizeof(btif_hl_delete_mdl_t)); 381 } 382 383 /******************************************************************************* 384 * 385 * Function btif_hl_clean_pcb 386 * 387 * Description Cleanup the pending chan control block 388 * 389 * Returns Nothing 390 * 391 ******************************************************************************/ 392 static void btif_hl_clean_pcb(btif_hl_pending_chan_cb_t* p_pcb) { 393 BTIF_TRACE_DEBUG("%s", __func__); 394 memset(p_pcb, 0, sizeof(btif_hl_pending_chan_cb_t)); 395 } 396 397 /******************************************************************************* 398 * 399 * Function btif_hl_clean_mdl_cb 400 * 401 * Description Cleanup the MDL control block 402 * 403 * Returns Nothing 404 * 405 ******************************************************************************/ 406 static void btif_hl_clean_mdl_cb(btif_hl_mdl_cb_t* p_dcb) { 407 BTIF_TRACE_DEBUG("%s", __func__); 408 osi_free_and_reset((void**)&p_dcb->p_rx_pkt); 409 osi_free_and_reset((void**)&p_dcb->p_tx_pkt); 410 memset(p_dcb, 0, sizeof(btif_hl_mdl_cb_t)); 411 } 412 413 /******************************************************************************* 414 * 415 * Function btif_hl_reset_mcb 416 * 417 * Description Reset MCL control block 418 * 419 * Returns bool 420 * 421 ******************************************************************************/ 422 static void btif_hl_clean_mcl_cb(uint8_t app_idx, uint8_t mcl_idx) { 423 btif_hl_mcl_cb_t* p_mcb; 424 BTIF_TRACE_DEBUG("%s app_idx=%d, mcl_idx=%d", __func__, app_idx, mcl_idx); 425 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 426 alarm_free(p_mcb->cch_timer); 427 memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t)); 428 } 429 430 /******************************************************************************* 431 * 432 * Function btif_hl_find_sdp_idx_using_mdep_filter 433 * 434 * Description This function finds the SDP record index using MDEP filter 435 * parameters 436 * 437 * Returns bool 438 * 439 ******************************************************************************/ 440 static void btif_hl_reset_mdep_filter(uint8_t app_idx) { 441 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 442 p_acb->filter.num_elems = 0; 443 } 444 445 /******************************************************************************* 446 * 447 * Function btif_hl_find_sdp_idx_using_mdep_filter 448 * 449 * Description This function finds the SDP record index using MDEP filter 450 * parameters 451 * 452 * Returns bool 453 * 454 ******************************************************************************/ 455 static bool btif_hl_find_sdp_idx_using_mdep_filter(uint8_t app_idx, 456 uint8_t mcl_idx, 457 uint8_t* p_sdp_idx) { 458 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 459 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 460 uint8_t i, j, num_recs, num_elems, num_mdeps, mdep_idx; 461 tBTA_HL_MDEP_ROLE peer_mdep_role; 462 uint16_t data_type; 463 tBTA_HL_SDP_MDEP_CFG* p_mdep; 464 bool found = false; 465 bool elem_found; 466 467 BTIF_TRACE_DEBUG("btif_hl_find_sdp_idx_using_mdep_filter"); 468 num_recs = p_mcb->sdp.num_recs; 469 num_elems = p_acb->filter.num_elems; 470 if (!num_elems) { 471 BTIF_TRACE_DEBUG("btif_hl_find_sdp_idx_using_mdep_filter num_elem=0"); 472 *p_sdp_idx = 0; 473 found = true; 474 return found; 475 } 476 477 for (i = 0; i < num_recs; i++) { 478 num_mdeps = p_mcb->sdp.sdp_rec[i].num_mdeps; 479 for (j = 0; j < num_elems; j++) { 480 data_type = p_acb->filter.elem[j].data_type; 481 peer_mdep_role = p_acb->filter.elem[j].peer_mdep_role; 482 elem_found = false; 483 mdep_idx = 0; 484 while (!elem_found && mdep_idx < num_mdeps) { 485 p_mdep = &(p_mcb->sdp.sdp_rec[i].mdep_cfg[mdep_idx]); 486 if ((p_mdep->data_type == data_type) && 487 (p_mdep->mdep_role == peer_mdep_role)) { 488 elem_found = true; 489 } else { 490 mdep_idx++; 491 } 492 } 493 494 if (!elem_found) { 495 found = false; 496 break; 497 } else { 498 found = true; 499 } 500 } 501 502 if (found) { 503 BTIF_TRACE_DEBUG("btif_hl_find_sdp_idx_using_mdep_filter found idx=%d", 504 i); 505 *p_sdp_idx = i; 506 break; 507 } 508 } 509 510 BTIF_TRACE_DEBUG("%s found=%d sdp_idx=%d", __func__, found, *p_sdp_idx); 511 512 btif_hl_reset_mdep_filter(app_idx); 513 514 return found; 515 } 516 /******************************************************************************* 517 * 518 * Function btif_hl_is_reconnect_possible 519 * 520 * Description check reconnect is possible or not 521 * 522 * Returns bool 523 * 524 ******************************************************************************/ 525 bool btif_hl_is_reconnect_possible(uint8_t app_idx, uint8_t mcl_idx, 526 int mdep_cfg_idx, 527 tBTA_HL_DCH_OPEN_PARAM* p_dch_open_api, 528 tBTA_HL_MDL_ID* p_mdl_id) { 529 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 530 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 531 tBTA_HL_DCH_CFG local_cfg = p_dch_open_api->local_cfg; 532 tBTA_HL_DCH_MODE dch_mode = BTA_HL_DCH_MODE_RELIABLE; 533 bool use_mdl_dch_mode = false; 534 btif_hl_mdl_cfg_t* p_mdl; 535 btif_hl_mdl_cfg_t* p_mdl1; 536 uint8_t i, j; 537 bool is_reconnect_ok = false; 538 bool stream_mode_avail = false; 539 uint16_t data_type = 540 p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.data_cfg[0].data_type; 541 tBTA_HL_MDEP_ID peer_mdep_id = p_dch_open_api->peer_mdep_id; 542 uint8_t mdl_idx; 543 544 BTIF_TRACE_DEBUG("%s app_idx=%d mcl_idx=%d mdep_cfg_idx=%d", __func__, 545 app_idx, mcl_idx, mdep_cfg_idx); 546 switch (local_cfg) { 547 case BTA_HL_DCH_CFG_NO_PREF: 548 if (!btif_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) { 549 dch_mode = BTA_HL_DCH_MODE_RELIABLE; 550 } else { 551 use_mdl_dch_mode = true; 552 } 553 break; 554 case BTA_HL_DCH_CFG_RELIABLE: 555 dch_mode = BTA_HL_DCH_MODE_RELIABLE; 556 break; 557 case BTA_HL_DCH_CFG_STREAMING: 558 dch_mode = BTA_HL_DCH_MODE_STREAMING; 559 break; 560 default: 561 BTIF_TRACE_ERROR("Invalid local_cfg=%d", local_cfg); 562 return is_reconnect_ok; 563 break; 564 } 565 566 BTIF_TRACE_DEBUG("local_cfg=%d use_mdl_dch_mode=%d dch_mode=%d ", local_cfg, 567 use_mdl_dch_mode, dch_mode); 568 569 for (i = 0, p_mdl = &p_acb->mdl_cfg[0]; i < BTA_HL_NUM_MDL_CFGS; 570 i++, p_mdl++) { 571 if (p_mdl->base.active && p_mdl->extra.data_type == data_type && 572 (p_mdl->extra.peer_mdep_id != BTA_HL_INVALID_MDEP_ID && 573 p_mdl->extra.peer_mdep_id == peer_mdep_id) && 574 p_mdl->base.peer_bd_addr != p_mcb->bd_addr && p_mdl->base.mdl_id && 575 !btif_hl_find_mdl_idx(app_idx, mcl_idx, p_mdl->base.mdl_id, &mdl_idx)) { 576 BTIF_TRACE_DEBUG("i=%d Matched active=%d mdl_id =%d, mdl_dch_mode=%d", 577 i, p_mdl->base.active, p_mdl->base.mdl_id, 578 p_mdl->base.dch_mode); 579 if (!use_mdl_dch_mode) { 580 if (p_mdl->base.dch_mode == dch_mode) { 581 is_reconnect_ok = true; 582 *p_mdl_id = p_mdl->base.mdl_id; 583 BTIF_TRACE_DEBUG("reconnect is possible dch_mode=%d mdl_id=%d", 584 dch_mode, p_mdl->base.mdl_id); 585 break; 586 } 587 } else { 588 is_reconnect_ok = true; 589 for (j = i, p_mdl1 = &p_acb->mdl_cfg[i]; j < BTA_HL_NUM_MDL_CFGS; 590 j++, p_mdl1++) { 591 if (p_mdl1->base.active && p_mdl1->extra.data_type == data_type && 592 (p_mdl1->extra.peer_mdep_id != BTA_HL_INVALID_MDEP_ID && 593 p_mdl1->extra.peer_mdep_id == peer_mdep_id) && 594 p_mdl1->base.peer_bd_addr != p_mcb->bd_addr && 595 p_mdl1->base.dch_mode == BTA_HL_DCH_MODE_STREAMING) { 596 stream_mode_avail = true; 597 BTIF_TRACE_DEBUG("found streaming mode mdl index=%d", j); 598 break; 599 } 600 } 601 602 if (stream_mode_avail) { 603 dch_mode = BTA_HL_DCH_MODE_STREAMING; 604 *p_mdl_id = p_mdl1->base.mdl_id; 605 BTIF_TRACE_DEBUG( 606 "reconnect is ok index=%d dch_mode=streaming mdl_id=%d", j, 607 *p_mdl_id); 608 break; 609 } else { 610 dch_mode = p_mdl->base.dch_mode; 611 *p_mdl_id = p_mdl->base.mdl_id; 612 BTIF_TRACE_DEBUG("reconnect is ok index=%d dch_mode=%d mdl_id=%d", i, 613 p_mdl->base.dch_mode, *p_mdl_id); 614 break; 615 } 616 } 617 } 618 } 619 620 BTIF_TRACE_DEBUG("is_reconnect_ok dch_mode=%d mdl_id=%d", is_reconnect_ok, 621 dch_mode, *p_mdl_id); 622 return is_reconnect_ok; 623 } 624 625 /******************************************************************************* 626 * 627 * Function btif_hl_dch_open 628 * 629 * Description Process DCH open request using the DCH Open API parameters 630 * 631 * Returns bool 632 * 633 ******************************************************************************/ 634 bool btif_hl_dch_open(uint8_t app_id, const RawAddress& bd_addr, 635 tBTA_HL_DCH_OPEN_PARAM* p_dch_open_api, int mdep_cfg_idx, 636 btif_hl_pend_dch_op_t op, int* channel_id) { 637 btif_hl_app_cb_t* p_acb; 638 btif_hl_mcl_cb_t* p_mcb; 639 btif_hl_pending_chan_cb_t* p_pcb; 640 uint8_t app_idx, mcl_idx; 641 bool status = false; 642 tBTA_HL_MDL_ID mdl_id; 643 tBTA_HL_DCH_RECONNECT_PARAM reconnect_param; 644 645 BTIF_TRACE_DEBUG("%s app_id=%d ", __func__, app_id); 646 VLOG(0) << "DB " << bd_addr; 647 648 if (btif_hl_find_app_idx(app_id, &app_idx)) { 649 if (btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) { 650 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 651 652 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 653 if (!p_pcb->in_use) { 654 p_mcb->req_ctrl_psm = p_dch_open_api->ctrl_psm; 655 656 p_pcb->in_use = true; 657 *channel_id = p_pcb->channel_id = 658 (int)btif_hl_get_next_channel_id(app_id); 659 p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING; 660 p_pcb->mdep_cfg_idx = mdep_cfg_idx; 661 p_pcb->bd_addr = bd_addr; 662 p_pcb->op = op; 663 664 if (p_mcb->sdp.num_recs) { 665 if (p_mcb->valid_sdp_idx) { 666 p_dch_open_api->ctrl_psm = p_mcb->ctrl_psm; 667 } 668 669 if (!btif_hl_is_reconnect_possible(app_idx, mcl_idx, mdep_cfg_idx, 670 p_dch_open_api, &mdl_id)) { 671 BTIF_TRACE_DEBUG("Issue DCH open"); 672 BTA_HlDchOpen(p_mcb->mcl_handle, p_dch_open_api); 673 } else { 674 reconnect_param.ctrl_psm = p_mcb->ctrl_psm; 675 reconnect_param.mdl_id = mdl_id; 676 ; 677 BTIF_TRACE_DEBUG("Issue Reconnect ctrl_psm=0x%x mdl_id=0x%x", 678 reconnect_param.ctrl_psm, reconnect_param.mdl_id); 679 BTA_HlDchReconnect(p_mcb->mcl_handle, &reconnect_param); 680 } 681 682 status = true; 683 } else { 684 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 685 p_mcb->cch_oper = BTIF_HL_CCH_OP_DCH_OPEN; 686 BTA_HlSdpQuery(app_id, p_acb->app_handle, bd_addr); 687 status = true; 688 } 689 } 690 } 691 } 692 693 BTIF_TRACE_DEBUG("status=%d ", status); 694 return status; 695 } 696 697 /******************************************************************************* 698 * 699 * Function btif_hl_dch_abort 700 * 701 * Description Process DCH abort request 702 * 703 * Returns Nothing 704 * 705 ******************************************************************************/ 706 void btif_hl_dch_abort(uint8_t app_idx, uint8_t mcl_idx) { 707 btif_hl_mcl_cb_t* p_mcb; 708 709 BTIF_TRACE_DEBUG("%s app_idx=%d mcl_idx=%d", __func__, app_idx, mcl_idx); 710 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 711 if (p_mcb->is_connected) { 712 BTA_HlDchAbort(p_mcb->mcl_handle); 713 } else { 714 p_mcb->pcb.abort_pending = true; 715 } 716 } 717 /******************************************************************************* 718 * 719 * Function btif_hl_cch_open 720 * 721 * Description Process CCH open request 722 * 723 * Returns Nothing 724 * 725 ******************************************************************************/ 726 bool btif_hl_cch_open(uint8_t app_id, const RawAddress& bd_addr, 727 uint16_t ctrl_psm, int mdep_cfg_idx, 728 btif_hl_pend_dch_op_t op, int* channel_id) { 729 btif_hl_app_cb_t* p_acb; 730 btif_hl_mcl_cb_t* p_mcb; 731 btif_hl_pending_chan_cb_t* p_pcb; 732 uint8_t app_idx, mcl_idx; 733 bool status = true; 734 735 BTIF_TRACE_DEBUG("%s app_id=%d ctrl_psm=%d mdep_cfg_idx=%d op=%d", __func__, 736 app_id, ctrl_psm, mdep_cfg_idx, op); 737 VLOG(1) << "DB " << bd_addr; 738 739 if (btif_hl_find_app_idx(app_id, &app_idx)) { 740 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 741 742 if (!btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) { 743 if (btif_hl_find_avail_mcl_idx(app_idx, &mcl_idx)) { 744 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 745 alarm_free(p_mcb->cch_timer); 746 memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t)); 747 p_mcb->in_use = true; 748 p_mcb->bd_addr = bd_addr; 749 750 if (!ctrl_psm) { 751 p_mcb->cch_oper = BTIF_HL_CCH_OP_MDEP_FILTERING; 752 } else { 753 p_mcb->cch_oper = BTIF_HL_CCH_OP_MATCHED_CTRL_PSM; 754 p_mcb->req_ctrl_psm = ctrl_psm; 755 } 756 757 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 758 p_pcb->in_use = true; 759 p_pcb->mdep_cfg_idx = mdep_cfg_idx; 760 p_pcb->bd_addr = bd_addr; 761 p_pcb->op = op; 762 763 switch (op) { 764 case BTIF_HL_PEND_DCH_OP_OPEN: 765 *channel_id = p_pcb->channel_id = 766 (int)btif_hl_get_next_channel_id(app_id); 767 p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING; 768 break; 769 case BTIF_HL_PEND_DCH_OP_DELETE_MDL: 770 p_pcb->channel_id = p_acb->delete_mdl.channel_id; 771 p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_DESTROYED_PENDING; 772 break; 773 default: 774 break; 775 } 776 BTA_HlSdpQuery(app_id, p_acb->app_handle, bd_addr); 777 } else { 778 status = false; 779 BTIF_TRACE_ERROR("Open CCH request discarded- No mcl cb"); 780 } 781 } else { 782 status = false; 783 BTIF_TRACE_ERROR("Open CCH request discarded- already in USE"); 784 } 785 } else { 786 status = false; 787 BTIF_TRACE_ERROR("Invalid app_id=%d", app_id); 788 } 789 790 if (channel_id) { 791 BTIF_TRACE_DEBUG("status=%d channel_id=0x%08x", status, *channel_id); 792 } else { 793 BTIF_TRACE_DEBUG("status=%d ", status); 794 } 795 return status; 796 } 797 798 /******************************************************************************* 799 * 800 * Function btif_hl_find_mdl_idx_using_handle 801 * 802 * Description Find the MDL index using channel id 803 * 804 * Returns bool 805 * 806 ******************************************************************************/ 807 bool btif_hl_find_mdl_cfg_idx_using_channel_id(int channel_id, 808 uint8_t* p_app_idx, 809 uint8_t* p_mdl_cfg_idx) { 810 btif_hl_app_cb_t* p_acb; 811 btif_hl_mdl_cfg_t* p_mdl; 812 bool found = false; 813 uint8_t i, j; 814 int mdl_cfg_channel_id; 815 816 *p_app_idx = 0; 817 *p_mdl_cfg_idx = 0; 818 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 819 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 820 for (j = 0; j < BTA_HL_NUM_MDL_CFGS; j++) { 821 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(i, j); 822 mdl_cfg_channel_id = *(BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(i, j)); 823 if (p_acb->in_use && p_mdl->base.active && 824 (mdl_cfg_channel_id == channel_id)) { 825 found = true; 826 *p_app_idx = i; 827 *p_mdl_cfg_idx = j; 828 break; 829 } 830 } 831 } 832 833 BTIF_TRACE_EVENT("%s found=%d channel_id=0x%08x, app_idx=%d mdl_cfg_idx=%d ", 834 __func__, found, channel_id, i, j); 835 return found; 836 } 837 /******************************************************************************* 838 * 839 * Function btif_hl_find_mdl_idx_using_handle 840 * 841 * Description Find the MDL index using channel id 842 * 843 * Returns bool 844 * 845 ******************************************************************************/ 846 bool btif_hl_find_mdl_idx_using_channel_id(int channel_id, uint8_t* p_app_idx, 847 uint8_t* p_mcl_idx, 848 uint8_t* p_mdl_idx) { 849 btif_hl_app_cb_t* p_acb; 850 btif_hl_mcl_cb_t* p_mcb; 851 btif_hl_mdl_cb_t* p_dcb; 852 bool found = false; 853 uint8_t i, j, k; 854 855 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 856 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 857 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 858 p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, j); 859 for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) { 860 p_dcb = BTIF_HL_GET_MDL_CB_PTR(i, j, k); 861 if (p_acb->in_use && p_mcb->in_use && p_dcb->in_use && 862 (p_dcb->channel_id == channel_id)) { 863 found = true; 864 *p_app_idx = i; 865 *p_mcl_idx = j; 866 *p_mdl_idx = k; 867 break; 868 } 869 } 870 } 871 } 872 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d mcl_idx=%d mdl_idx=%d ", __func__, 873 found, i, j, k); 874 return found; 875 } 876 877 /******************************************************************************* 878 * 879 * Function btif_hl_find_channel_id_using_mdl_id 880 * 881 * Description Find channel id using mdl_id' 882 * 883 * Returns bool 884 ******************************************************************************/ 885 bool btif_hl_find_channel_id_using_mdl_id(uint8_t app_idx, 886 tBTA_HL_MDL_ID mdl_id, 887 int* p_channel_id) { 888 btif_hl_app_cb_t* p_acb; 889 btif_hl_mdl_cfg_t* p_mdl; 890 bool found = false; 891 uint8_t j = 0; 892 int mdl_cfg_channel_id; 893 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 894 if (p_acb && p_acb->in_use) { 895 for (j = 0; j < BTA_HL_NUM_MDL_CFGS; j++) { 896 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, j); 897 mdl_cfg_channel_id = *(BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(app_idx, j)); 898 if (p_mdl->base.active && (p_mdl->base.mdl_id == mdl_id)) { 899 found = true; 900 *p_channel_id = mdl_cfg_channel_id; 901 break; 902 } 903 } 904 } 905 BTIF_TRACE_EVENT( 906 "%s found=%d channel_id=0x%08x, mdl_id=0x%x app_idx=%d mdl_cfg_idx=%d ", 907 __func__, found, *p_channel_id, mdl_id, app_idx, j); 908 return found; 909 } 910 911 /******************************************************************************* 912 * 913 * Function btif_hl_find_mdl_idx_using_handle 914 * 915 * Description Find the MDL index using handle 916 * 917 * Returns bool 918 * 919 ******************************************************************************/ 920 bool btif_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle, 921 uint8_t* p_app_idx, uint8_t* p_mcl_idx, 922 uint8_t* p_mdl_idx) { 923 btif_hl_app_cb_t* p_acb; 924 btif_hl_mcl_cb_t* p_mcb; 925 btif_hl_mdl_cb_t* p_dcb; 926 bool found = false; 927 uint8_t i, j, k; 928 929 *p_app_idx = 0; 930 *p_mcl_idx = 0; 931 *p_mdl_idx = 0; 932 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 933 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 934 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 935 p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, j); 936 for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) { 937 p_dcb = BTIF_HL_GET_MDL_CB_PTR(i, j, k); 938 if (p_acb->in_use && p_mcb->in_use && p_dcb->in_use && 939 (p_dcb->mdl_handle == mdl_handle)) { 940 found = true; 941 *p_app_idx = i; 942 *p_mcl_idx = j; 943 *p_mdl_idx = k; 944 break; 945 } 946 } 947 } 948 } 949 950 BTIF_TRACE_EVENT("%s found=%d app_idx=%d mcl_idx=%d mdl_idx=%d ", __func__, 951 found, i, j, k); 952 return found; 953 } 954 /******************************************************************************* 955 * 956 * Function btif_hl_find_peer_mdep_id 957 * 958 * Description Find the peer MDEP ID from the received SPD records 959 * 960 * Returns bool 961 * 962 ******************************************************************************/ 963 static bool btif_hl_find_peer_mdep_id(uint8_t app_id, const RawAddress& bd_addr, 964 tBTA_HL_MDEP_ROLE local_mdep_role, 965 uint16_t data_type, 966 tBTA_HL_MDEP_ID* p_peer_mdep_id) { 967 uint8_t app_idx, mcl_idx; 968 btif_hl_mcl_cb_t* p_mcb; 969 tBTA_HL_SDP_REC* p_rec; 970 uint8_t i, num_mdeps; 971 bool found = false; 972 tBTA_HL_MDEP_ROLE peer_mdep_role; 973 974 BTIF_TRACE_DEBUG("%s app_id=%d local_mdep_role=%d, data_type=%d", __func__, 975 app_id, local_mdep_role, data_type); 976 VLOG(1) << "DB " << bd_addr; 977 978 BTIF_TRACE_DEBUG("local_mdep_role=%d", local_mdep_role); 979 BTIF_TRACE_DEBUG("data_type=%d", data_type); 980 981 if (local_mdep_role == BTA_HL_MDEP_ROLE_SINK) 982 peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE; 983 else 984 peer_mdep_role = BTA_HL_MDEP_ROLE_SINK; 985 986 if (btif_hl_find_app_idx(app_id, &app_idx)) { 987 if (btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) { 988 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 989 990 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d", app_idx, mcl_idx); 991 BTIF_TRACE_DEBUG("valid_spd_idx=%d sdp_idx=%d", p_mcb->valid_sdp_idx, 992 p_mcb->sdp_idx); 993 if (p_mcb->valid_sdp_idx) { 994 p_rec = &p_mcb->sdp.sdp_rec[p_mcb->sdp_idx]; 995 num_mdeps = p_rec->num_mdeps; 996 BTIF_TRACE_DEBUG("num_mdeps=%d", num_mdeps); 997 998 for (i = 0; i < num_mdeps; i++) { 999 BTIF_TRACE_DEBUG("p_rec->mdep_cfg[%d].mdep_role=%d", i, 1000 p_rec->mdep_cfg[i].mdep_role); 1001 BTIF_TRACE_DEBUG("p_rec->mdep_cfg[%d].data_type =%d", i, 1002 p_rec->mdep_cfg[i].data_type); 1003 if ((p_rec->mdep_cfg[i].mdep_role == peer_mdep_role) && 1004 (p_rec->mdep_cfg[i].data_type == data_type)) { 1005 found = true; 1006 *p_peer_mdep_id = p_rec->mdep_cfg[i].mdep_id; 1007 break; 1008 } 1009 } 1010 } 1011 } 1012 } 1013 1014 BTIF_TRACE_DEBUG("found =%d *p_peer_mdep_id=%d", found, *p_peer_mdep_id); 1015 1016 return found; 1017 } 1018 1019 /******************************************************************************* 1020 * 1021 * Function btif_hl_find_mdep_cfg_idx 1022 * 1023 * Description Find the MDEP configuration index using local MDEP_ID 1024 * 1025 * Returns bool 1026 * 1027 ******************************************************************************/ 1028 static bool btif_hl_find_mdep_cfg_idx(uint8_t app_idx, 1029 tBTA_HL_MDEP_ID local_mdep_id, 1030 uint8_t* p_mdep_cfg_idx) { 1031 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 1032 tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature; 1033 bool found = false; 1034 uint8_t i; 1035 1036 for (i = 0; i < p_sup_feature->num_of_mdeps; i++) { 1037 BTIF_TRACE_DEBUG("btif_hl_find_mdep_cfg_idx: mdep_id=%d app_idx = %d", 1038 p_sup_feature->mdep[i].mdep_id, app_idx); 1039 if (p_sup_feature->mdep[i].mdep_id == local_mdep_id) { 1040 found = true; 1041 *p_mdep_cfg_idx = i; 1042 break; 1043 } 1044 } 1045 1046 BTIF_TRACE_DEBUG("%s found=%d mdep_idx=%d local_mdep_id=%d app_idx=%d ", 1047 __func__, found, i, local_mdep_id, app_idx); 1048 return found; 1049 } 1050 1051 /******************************************************************************* 1052 * 1053 * Function btif_hl_find_mcl_idx 1054 * 1055 * Description Find the MCL index using BD address 1056 * 1057 * Returns bool 1058 * 1059 ******************************************************************************/ 1060 bool btif_hl_find_mcl_idx(uint8_t app_idx, const RawAddress& p_bd_addr, 1061 uint8_t* p_mcl_idx) { 1062 bool found = false; 1063 uint8_t i; 1064 btif_hl_mcl_cb_t* p_mcb; 1065 1066 *p_mcl_idx = 0; 1067 for (i = 0; i < BTA_HL_NUM_MCLS; i++) { 1068 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, i); 1069 if (p_mcb->in_use && p_mcb->bd_addr == p_bd_addr) { 1070 found = true; 1071 *p_mcl_idx = i; 1072 break; 1073 } 1074 } 1075 1076 BTIF_TRACE_DEBUG("%s found=%d idx=%d", __func__, found, i); 1077 return found; 1078 } 1079 /******************************************************************************* 1080 * 1081 * Function btif_hl_init 1082 * 1083 * Description HL initialization function. 1084 * 1085 * Returns void 1086 * 1087 ******************************************************************************/ 1088 static void btif_hl_init(void) { 1089 BTIF_TRACE_DEBUG("%s", __func__); 1090 memset(p_btif_hl_cb, 0, sizeof(btif_hl_cb_t)); 1091 btif_hl_init_next_app_id(); 1092 btif_hl_init_next_channel_id(); 1093 } 1094 /******************************************************************************* 1095 * 1096 * Function btif_hl_disable 1097 * 1098 * Description Disable initialization function. 1099 * 1100 * Returns void 1101 * 1102 ******************************************************************************/ 1103 static void btif_hl_disable(void) { 1104 BTIF_TRACE_DEBUG("%s", __func__); 1105 1106 if ((p_btif_hl_cb->state != BTIF_HL_STATE_DISABLING) && 1107 (p_btif_hl_cb->state != BTIF_HL_STATE_DISABLED)) { 1108 btif_hl_set_state(BTIF_HL_STATE_DISABLING); 1109 BTA_HlDisable(); 1110 } 1111 } 1112 /******************************************************************************* 1113 * 1114 * Function btif_hl_is_no_active_app 1115 * 1116 * Description Find whether or not any APP is still in use 1117 * 1118 * Returns bool 1119 * 1120 ******************************************************************************/ 1121 static bool btif_hl_is_no_active_app(void) { 1122 bool no_active_app = true; 1123 uint8_t i; 1124 1125 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1126 if (btif_hl_cb.acb[i].in_use) { 1127 no_active_app = false; 1128 break; 1129 } 1130 } 1131 1132 BTIF_TRACE_DEBUG("%s no_active_app=%d ", __func__, no_active_app); 1133 return no_active_app; 1134 } 1135 1136 /******************************************************************************* 1137 * 1138 * Function btif_hl_free_app_idx 1139 * 1140 * Description free an application control block 1141 * 1142 * Returns void 1143 * 1144 ******************************************************************************/ 1145 static void btif_hl_free_app_idx(uint8_t app_idx) { 1146 if ((app_idx < BTA_HL_NUM_APPS) && btif_hl_cb.acb[app_idx].in_use) { 1147 btif_hl_cb.acb[app_idx].in_use = false; 1148 for (size_t i = 0; i < BTA_HL_NUM_MCLS; i++) 1149 alarm_free(btif_hl_cb.acb[app_idx].mcb[i].cch_timer); 1150 memset(&btif_hl_cb.acb[app_idx], 0, sizeof(btif_hl_app_cb_t)); 1151 } 1152 } 1153 /******************************************************************************* 1154 * 1155 * Function btif_hl_set_state 1156 * 1157 * Description set HL state 1158 * 1159 * Returns void 1160 * 1161 ******************************************************************************/ 1162 static void btif_hl_set_state(btif_hl_state_t state) { 1163 BTIF_TRACE_DEBUG("btif_hl_set_state: %d ---> %d ", p_btif_hl_cb->state, 1164 state); 1165 p_btif_hl_cb->state = state; 1166 } 1167 1168 /******************************************************************************* 1169 * 1170 * Function btif_hl_set_state 1171 * 1172 * Description get HL state 1173 * 1174 * Returns btif_hl_state_t 1175 * 1176 ******************************************************************************/ 1177 1178 static btif_hl_state_t btif_hl_get_state(void) { 1179 BTIF_TRACE_DEBUG("btif_hl_get_state: %d ", p_btif_hl_cb->state); 1180 return p_btif_hl_cb->state; 1181 } 1182 1183 /******************************************************************************* 1184 * 1185 * Function btif_hl_find_data_type_idx 1186 * 1187 * Description Find the index in the data type table 1188 * 1189 * Returns bool 1190 * 1191 ******************************************************************************/ 1192 static bool btif_hl_find_data_type_idx(uint16_t data_type, uint8_t* p_idx) { 1193 bool found = false; 1194 uint8_t i; 1195 1196 for (i = 0; i < BTIF_HL_DATA_TABLE_SIZE; i++) { 1197 if (data_type_table[i].data_type == data_type) { 1198 found = true; 1199 *p_idx = i; 1200 break; 1201 } 1202 } 1203 1204 BTIF_TRACE_DEBUG("%s found=%d, data_type=0x%x idx=%d", __func__, found, 1205 data_type, i); 1206 return found; 1207 } 1208 1209 /******************************************************************************* 1210 * 1211 * Function btif_hl_get_max_tx_apdu_size 1212 * 1213 * Description Find the maximum TX APDU size for the specified data type and 1214 * MDEP role 1215 * 1216 * Returns uint16_t 1217 * 1218 ******************************************************************************/ 1219 uint16_t btif_hl_get_max_tx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role, 1220 uint16_t data_type) { 1221 uint8_t idx; 1222 uint16_t max_tx_apdu_size = 0; 1223 1224 if (btif_hl_find_data_type_idx(data_type, &idx)) { 1225 if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE) { 1226 max_tx_apdu_size = data_type_table[idx].max_tx_apdu_size; 1227 } else { 1228 max_tx_apdu_size = data_type_table[idx].max_rx_apdu_size; 1229 } 1230 } else { 1231 if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE) { 1232 max_tx_apdu_size = BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE; 1233 } else { 1234 max_tx_apdu_size = BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE; 1235 } 1236 } 1237 1238 BTIF_TRACE_DEBUG("%s mdep_role=%d data_type=0x%4x size=%d", __func__, 1239 mdep_role, data_type, max_tx_apdu_size); 1240 return max_tx_apdu_size; 1241 } 1242 1243 /******************************************************************************* 1244 * 1245 * Function btif_hl_get_max_rx_apdu_size 1246 * 1247 * Description Find the maximum RX APDU size for the specified data type and 1248 * MDEP role 1249 * 1250 * Returns uint16_t 1251 * 1252 ******************************************************************************/ 1253 uint16_t btif_hl_get_max_rx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role, 1254 uint16_t data_type) { 1255 uint8_t idx; 1256 uint16_t max_rx_apdu_size = 0; 1257 1258 if (btif_hl_find_data_type_idx(data_type, &idx)) { 1259 if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE) { 1260 max_rx_apdu_size = data_type_table[idx].max_rx_apdu_size; 1261 } else { 1262 max_rx_apdu_size = data_type_table[idx].max_tx_apdu_size; 1263 } 1264 } else { 1265 if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE) { 1266 max_rx_apdu_size = BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE; 1267 } else { 1268 max_rx_apdu_size = BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE; 1269 } 1270 } 1271 1272 BTIF_TRACE_DEBUG("%s mdep_role=%d data_type=0x%4x size=%d", __func__, 1273 mdep_role, data_type, max_rx_apdu_size); 1274 1275 return max_rx_apdu_size; 1276 } 1277 1278 /******************************************************************************* 1279 * 1280 * Function btif_hl_if_channel_setup_pending 1281 * 1282 * Description 1283 * 1284 * Returns bool 1285 * 1286 ******************************************************************************/ 1287 1288 static bool btif_hl_get_bta_mdep_role(bthl_mdep_role_t mdep, 1289 tBTA_HL_MDEP_ROLE* p) { 1290 bool status = true; 1291 switch (mdep) { 1292 case BTHL_MDEP_ROLE_SOURCE: 1293 *p = BTA_HL_MDEP_ROLE_SOURCE; 1294 break; 1295 case BTHL_MDEP_ROLE_SINK: 1296 *p = BTA_HL_MDEP_ROLE_SINK; 1297 break; 1298 default: 1299 *p = BTA_HL_MDEP_ROLE_SOURCE; 1300 status = false; 1301 break; 1302 } 1303 1304 BTIF_TRACE_DEBUG("%s status=%d bta_mdep_role=%d (%d:btif)", __func__, status, 1305 *p, mdep); 1306 return status; 1307 } 1308 /******************************************************************************* 1309 * 1310 * Function btif_hl_get_bta_channel_type 1311 * 1312 * Description convert bthl channel type to BTA DCH channel type 1313 * 1314 * Returns bool 1315 * 1316 ******************************************************************************/ 1317 1318 static bool btif_hl_get_bta_channel_type(bthl_channel_type_t channel_type, 1319 tBTA_HL_DCH_CFG* p) { 1320 bool status = true; 1321 switch (channel_type) { 1322 case BTHL_CHANNEL_TYPE_RELIABLE: 1323 *p = BTA_HL_DCH_CFG_RELIABLE; 1324 break; 1325 case BTHL_CHANNEL_TYPE_STREAMING: 1326 *p = BTA_HL_DCH_CFG_STREAMING; 1327 break; 1328 case BTHL_CHANNEL_TYPE_ANY: 1329 *p = BTA_HL_DCH_CFG_NO_PREF; 1330 break; 1331 default: 1332 status = false; 1333 break; 1334 } 1335 BTIF_TRACE_DEBUG("%s status = %d BTA DCH CFG=%d (1-rel 2-strm", __func__, 1336 status, *p); 1337 return status; 1338 } 1339 /******************************************************************************* 1340 * 1341 * Function btif_hl_get_next_app_id 1342 * 1343 * Description get next applcation id 1344 * 1345 * Returns uint8_t 1346 * 1347 ******************************************************************************/ 1348 1349 static uint8_t btif_hl_get_next_app_id() { 1350 uint8_t next_app_id = btif_hl_cb.next_app_id; 1351 1352 btif_hl_cb.next_app_id++; 1353 return next_app_id; 1354 } 1355 /******************************************************************************* 1356 * 1357 * Function btif_hl_get_next_channel_id 1358 * 1359 * Description get next channel id 1360 * 1361 * Returns int 1362 * 1363 ******************************************************************************/ 1364 static int btif_hl_get_next_channel_id(uint8_t app_id) { 1365 uint16_t next_channel_id = btif_hl_cb.next_channel_id; 1366 int channel_id; 1367 btif_hl_cb.next_channel_id++; 1368 channel_id = (app_id << 16) + next_channel_id; 1369 BTIF_TRACE_DEBUG("%s channel_id=0x%08x, app_id=0x%02x next_channel_id=0x%04x", 1370 __func__, channel_id, app_id, next_channel_id); 1371 return channel_id; 1372 } 1373 /******************************************************************************* 1374 * 1375 * Function btif_hl_get_app_id 1376 * 1377 * Description get the applicaiton id associated with the channel id 1378 * 1379 * Returns uint8_t 1380 * 1381 ******************************************************************************/ 1382 1383 static uint8_t btif_hl_get_app_id(int channel_id) { 1384 uint8_t app_id = (uint8_t)(channel_id >> 16); 1385 BTIF_TRACE_DEBUG("%s channel_id=0x%08x, app_id=0x%02x ", __func__, channel_id, 1386 app_id); 1387 return app_id; 1388 } 1389 /******************************************************************************* 1390 * 1391 * Function btif_hl_init_next_app_id 1392 * 1393 * Description initialize the application id 1394 * 1395 * Returns void 1396 * 1397 ******************************************************************************/ 1398 static void btif_hl_init_next_app_id(void) { btif_hl_cb.next_app_id = 1; } 1399 /******************************************************************************* 1400 * 1401 * Function btif_hl_init_next_channel_id 1402 * 1403 * Description initialize the channel id 1404 * 1405 * Returns void 1406 * 1407 ******************************************************************************/ 1408 static void btif_hl_init_next_channel_id(void) { 1409 btif_hl_cb.next_channel_id = 1; 1410 } 1411 1412 /******************************************************************************* 1413 * 1414 * Function btif_hl_find_app_idx_using_handle 1415 * 1416 * Description Find the applicaiton index using handle 1417 * 1418 * Returns bool 1419 * 1420 ******************************************************************************/ 1421 bool btif_hl_find_app_idx_using_handle(tBTA_HL_APP_HANDLE app_handle, 1422 uint8_t* p_app_idx) { 1423 bool found = false; 1424 uint8_t i; 1425 1426 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1427 if (btif_hl_cb.acb[i].in_use && 1428 (btif_hl_cb.acb[i].app_handle == app_handle)) { 1429 found = true; 1430 *p_app_idx = i; 1431 break; 1432 } 1433 } 1434 1435 BTIF_TRACE_EVENT("%s status=%d handle=%d app_idx=%d ", __func__, found, 1436 app_handle, i); 1437 1438 return found; 1439 } 1440 1441 /******************************************************************************* 1442 * 1443 * Function btif_hl_find_app_idx_using_app_id 1444 * 1445 * Description Find the applicaiton index using app_id 1446 * 1447 * Returns bool 1448 * 1449 ******************************************************************************/ 1450 bool btif_hl_find_app_idx_using_app_id(uint8_t app_id, uint8_t* p_app_idx) { 1451 bool found = false; 1452 uint8_t i; 1453 1454 *p_app_idx = 0; 1455 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1456 if (btif_hl_cb.acb[i].in_use && (btif_hl_cb.acb[i].app_id == app_id)) { 1457 found = true; 1458 *p_app_idx = i; 1459 break; 1460 } 1461 } 1462 1463 BTIF_TRACE_EVENT("%s found=%d app_id=%d app_idx=%d ", __func__, found, app_id, 1464 i); 1465 1466 return found; 1467 } 1468 1469 /******************************************************************************* 1470 * 1471 * Function btif_hl_find_mcl_idx_using_handle 1472 * 1473 * Description Find the MCL index using handle 1474 * 1475 * Returns bool 1476 * 1477 ******************************************************************************/ 1478 bool btif_hl_find_mcl_idx_using_handle(tBTA_HL_MCL_HANDLE mcl_handle, 1479 uint8_t* p_app_idx, uint8_t* p_mcl_idx) { 1480 btif_hl_app_cb_t* p_acb; 1481 bool found = false; 1482 uint8_t i, j; 1483 1484 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1485 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 1486 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 1487 if (p_acb->mcb[j].in_use) 1488 BTIF_TRACE_DEBUG( 1489 "btif_hl_find_mcl_idx_using_handle:app_idx=%d," 1490 "mcl_idx =%d mcl_handle=%d", 1491 i, j, p_acb->mcb[j].mcl_handle); 1492 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) { 1493 found = true; 1494 *p_app_idx = i; 1495 *p_mcl_idx = j; 1496 break; 1497 } 1498 } 1499 } 1500 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d mcl_idx=%d", __func__, found, i, j); 1501 return found; 1502 } 1503 1504 /******************************************************************************* 1505 * 1506 * Function btif_hl_find_mdl_idx_using_mdl_id 1507 * 1508 * Description Find the mdl index using mdl_id 1509 * 1510 * Returns bool 1511 * 1512 ******************************************************************************/ 1513 bool btif_hl_find_mcl_idx_using_mdl_id(uint8_t mdl_id, uint8_t mcl_handle, 1514 uint8_t* p_app_idx, uint8_t* p_mcl_idx) { 1515 btif_hl_app_cb_t* p_acb; 1516 btif_hl_mcl_cb_t* p_mcb; 1517 bool found = false; 1518 uint8_t i, j, x; 1519 1520 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1521 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 1522 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 1523 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) { 1524 p_mcb = &p_acb->mcb[j]; 1525 BTIF_TRACE_DEBUG( 1526 "btif_hl_find_mcl_idx_using_mdl_id: mcl handle found j =%d", j); 1527 for (x = 0; x < BTA_HL_NUM_MDLS_PER_MCL; x++) { 1528 if (p_mcb->mdl[x].in_use && p_mcb->mdl[x].mdl_id == mdl_id) { 1529 BTIF_TRACE_DEBUG("btif_hl_find_mcl_idx_using_mdl_id:found x =%d", 1530 x); 1531 found = true; 1532 *p_app_idx = i; 1533 *p_mcl_idx = j; 1534 break; 1535 } 1536 } 1537 } 1538 } 1539 } 1540 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d mcl_idx=%d", __func__, found, i, j); 1541 return found; 1542 } 1543 1544 /******************************************************************************* 1545 * 1546 * Function btif_hl_find_mcl_idx_using_deleted_mdl_id 1547 * 1548 * Description Find the app index deleted_mdl_id 1549 * 1550 * Returns bool 1551 * 1552 ******************************************************************************/ 1553 bool btif_hl_find_app_idx_using_deleted_mdl_id(uint8_t mdl_id, 1554 uint8_t* p_app_idx) { 1555 btif_hl_app_cb_t* p_acb; 1556 bool found = false; 1557 uint8_t i; 1558 1559 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1560 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 1561 if (p_acb->delete_mdl.active) { 1562 BTIF_TRACE_DEBUG("%s: app_idx=%d, mdl_id=%d", __func__, i, mdl_id); 1563 } 1564 if (p_acb->delete_mdl.active && (p_acb->delete_mdl.mdl_id == mdl_id)) { 1565 found = true; 1566 *p_app_idx = i; 1567 break; 1568 } 1569 } 1570 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d", __func__, found, i); 1571 return found; 1572 } 1573 1574 /******************************************************************************* 1575 * 1576 * Function btif_hl_stop_timer_using_handle 1577 * 1578 * Description clean control channel cb using handle 1579 * 1580 * Returns void 1581 * 1582 ******************************************************************************/ 1583 static void btif_hl_stop_timer_using_handle(tBTA_HL_MCL_HANDLE mcl_handle) { 1584 btif_hl_app_cb_t* p_acb; 1585 uint8_t i, j; 1586 1587 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1588 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 1589 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 1590 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) { 1591 btif_hl_stop_cch_timer(i, j); 1592 } 1593 } 1594 } 1595 } 1596 1597 /******************************************************************************* 1598 * 1599 * Function btif_hl_find_mcl_idx_using_app_idx 1600 * 1601 * Description Find the MCL index using handle 1602 * 1603 * Returns bool 1604 * 1605 ******************************************************************************/ 1606 bool btif_hl_find_mcl_idx_using_app_idx(tBTA_HL_MCL_HANDLE mcl_handle, 1607 uint8_t p_app_idx, uint8_t* p_mcl_idx) { 1608 btif_hl_app_cb_t* p_acb; 1609 bool found = false; 1610 uint8_t j; 1611 1612 p_acb = BTIF_HL_GET_APP_CB_PTR(p_app_idx); 1613 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 1614 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) { 1615 found = true; 1616 *p_mcl_idx = j; 1617 break; 1618 } 1619 } 1620 BTIF_TRACE_DEBUG("%s found=%dmcl_idx=%d", __func__, found, j); 1621 return found; 1622 } 1623 1624 /******************************************************************************* 1625 * 1626 * Function btif_hl_clean_mdls_using_app_idx 1627 * 1628 * Description clean dch cpntrol bloack using app_idx 1629 * 1630 * Returns void 1631 * 1632 ******************************************************************************/ 1633 void btif_hl_clean_mdls_using_app_idx(uint8_t app_idx) { 1634 btif_hl_app_cb_t* p_acb; 1635 btif_hl_mcl_cb_t* p_mcb; 1636 btif_hl_mdl_cb_t* p_dcb; 1637 uint8_t j, x; 1638 RawAddress bd_addr; 1639 1640 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 1641 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 1642 if (p_acb->mcb[j].in_use) { 1643 p_mcb = &p_acb->mcb[j]; 1644 BTIF_TRACE_DEBUG( 1645 "btif_hl_find_mcl_idx_using_mdl_id: mcl handle found j =%d", j); 1646 for (x = 0; x < BTA_HL_NUM_MDLS_PER_MCL; x++) { 1647 if (p_mcb->mdl[x].in_use) { 1648 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, j, x); 1649 btif_hl_release_socket(app_idx, j, x); 1650 bd_addr = p_mcb->bd_addr; 1651 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, p_acb->app_id, 1652 &bd_addr, p_dcb->local_mdep_cfg_idx, 1653 p_dcb->channel_id, BTHL_CONN_STATE_DISCONNECTED, 1654 0); 1655 btif_hl_clean_mdl_cb(p_dcb); 1656 if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle)) 1657 BTA_HlCchClose(p_mcb->mcl_handle); 1658 BTIF_TRACE_DEBUG("remote DCH close success mdl_idx=%d", x); 1659 } 1660 } 1661 } 1662 } 1663 } 1664 1665 /******************************************************************************* 1666 * 1667 * Function btif_hl_find_app_idx 1668 * 1669 * Description Find the application index using application ID 1670 * 1671 * Returns bool 1672 * 1673 ******************************************************************************/ 1674 bool btif_hl_find_app_idx(uint8_t app_id, uint8_t* p_app_idx) { 1675 bool found = false; 1676 uint8_t i; 1677 1678 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1679 if (btif_hl_cb.acb[i].in_use && (btif_hl_cb.acb[i].app_id == app_id)) { 1680 found = true; 1681 *p_app_idx = i; 1682 break; 1683 } 1684 } 1685 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d", __func__, found, i); 1686 1687 return found; 1688 } 1689 1690 /******************************************************************************* 1691 * 1692 * Function btif_hl_find_app_idx 1693 * 1694 * Description Find the application index using application ID 1695 * 1696 * Returns bool 1697 * 1698 ******************************************************************************/ 1699 bool btif_hl_find_app_idx_using_mdepId(uint8_t mdep_id, uint8_t* p_app_idx) { 1700 bool found = false; 1701 uint8_t i; 1702 1703 *p_app_idx = 0; 1704 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1705 BTIF_TRACE_DEBUG("btif_hl_find_app_idx_using_mdepId: MDEP-ID = %d", 1706 btif_hl_cb.acb[i].sup_feature.mdep[0].mdep_id); 1707 if (btif_hl_cb.acb[i].in_use && 1708 (btif_hl_cb.acb[i].sup_feature.mdep[0].mdep_id == mdep_id)) { 1709 found = true; 1710 *p_app_idx = i; 1711 break; 1712 } 1713 } 1714 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d", __func__, found, i); 1715 1716 return found; 1717 } 1718 1719 /******************************************************************************* 1720 * 1721 * Function btif_hl_find_avail_mdl_idx 1722 * 1723 * Description Find a not in-use MDL index 1724 * 1725 * Returns bool 1726 * 1727 ******************************************************************************/ 1728 bool btif_hl_find_avail_mdl_idx(uint8_t app_idx, uint8_t mcl_idx, 1729 uint8_t* p_mdl_idx) { 1730 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1731 bool found = false; 1732 uint8_t i; 1733 1734 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) { 1735 if (!p_mcb->mdl[i].in_use) { 1736 btif_hl_clean_mdl_cb(&p_mcb->mdl[i]); 1737 found = true; 1738 *p_mdl_idx = i; 1739 break; 1740 } 1741 } 1742 1743 BTIF_TRACE_DEBUG("%s found=%d idx=%d", __func__, found, i); 1744 return found; 1745 } 1746 1747 /******************************************************************************* 1748 * 1749 * Function btif_hl_find_avail_mcl_idx 1750 * 1751 * Description Find a not in-use MDL index 1752 * 1753 * Returns bool 1754 * 1755 ******************************************************************************/ 1756 bool btif_hl_find_avail_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx) { 1757 bool found = false; 1758 uint8_t i; 1759 1760 for (i = 0; i < BTA_HL_NUM_MCLS; i++) { 1761 if (!btif_hl_cb.acb[app_idx].mcb[i].in_use) { 1762 found = true; 1763 *p_mcl_idx = i; 1764 break; 1765 } 1766 } 1767 BTIF_TRACE_DEBUG("%s found=%d mcl_idx=%d", __func__, found, i); 1768 return found; 1769 } 1770 1771 /******************************************************************************* 1772 * 1773 * Function btif_hl_find_avail_app_idx 1774 * 1775 * Description Find a not in-use APP index 1776 * 1777 * Returns bool 1778 * 1779 ******************************************************************************/ 1780 static bool btif_hl_find_avail_app_idx(uint8_t* p_idx) { 1781 bool found = false; 1782 uint8_t i; 1783 1784 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 1785 if (!btif_hl_cb.acb[i].in_use) { 1786 found = true; 1787 *p_idx = i; 1788 break; 1789 } 1790 } 1791 1792 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d", __func__, found, i); 1793 return found; 1794 } 1795 1796 /******************************************************************************* 1797 * 1798 * Function btif_hl_proc_dereg_cfm 1799 * 1800 * Description Process the de-registration confirmation 1801 * 1802 * Returns Nothing 1803 * 1804 ******************************************************************************/ 1805 static void btif_hl_proc_dereg_cfm(tBTA_HL* p_data) 1806 1807 { 1808 btif_hl_app_cb_t* p_acb; 1809 uint8_t app_idx; 1810 int app_id = 0; 1811 bthl_app_reg_state_t state = BTHL_APP_REG_STATE_DEREG_SUCCESS; 1812 1813 BTIF_TRACE_DEBUG("%s de-reg status=%d app_handle=%d", __func__, 1814 p_data->dereg_cfm.status, p_data->dereg_cfm.app_handle); 1815 1816 if (btif_hl_find_app_idx_using_app_id(p_data->dereg_cfm.app_id, &app_idx)) { 1817 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 1818 app_id = (int)p_acb->app_id; 1819 if (p_data->dereg_cfm.status == BTA_HL_STATUS_OK) { 1820 btif_hl_clean_mdls_using_app_idx(app_idx); 1821 for (size_t i = 0; i < BTA_HL_NUM_MCLS; i++) 1822 alarm_free(p_acb->mcb[i].cch_timer); 1823 memset(p_acb, 0, sizeof(btif_hl_app_cb_t)); 1824 } else 1825 state = BTHL_APP_REG_STATE_DEREG_FAILED; 1826 1827 BTIF_TRACE_DEBUG("call reg state callback app_id=%d state=%d", app_id, 1828 state); 1829 BTIF_HL_CALL_CBACK(bt_hl_callbacks, app_reg_state_cb, app_id, state); 1830 1831 if (btif_hl_is_no_active_app()) { 1832 btif_hl_disable(); 1833 } 1834 } 1835 } 1836 1837 /******************************************************************************* 1838 * 1839 * Function btif_hl_proc_reg_cfm 1840 * 1841 * Description Process the registration confirmation 1842 * 1843 * Returns Nothing 1844 * 1845 ******************************************************************************/ 1846 static void btif_hl_proc_reg_cfm(tBTA_HL* p_data) { 1847 btif_hl_app_cb_t* p_acb; 1848 uint8_t app_idx; 1849 bthl_app_reg_state_t state = BTHL_APP_REG_STATE_REG_SUCCESS; 1850 1851 BTIF_TRACE_DEBUG("%s reg status=%d app_handle=%d", __func__, 1852 p_data->reg_cfm.status, p_data->reg_cfm.app_handle); 1853 1854 if (btif_hl_find_app_idx(p_data->reg_cfm.app_id, &app_idx)) { 1855 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 1856 if (p_data->reg_cfm.status == BTA_HL_STATUS_OK) { 1857 p_acb->app_handle = p_data->reg_cfm.app_handle; 1858 } else { 1859 btif_hl_free_app_idx(app_idx); 1860 state = BTHL_APP_REG_STATE_REG_FAILED; 1861 } 1862 1863 BTIF_TRACE_DEBUG("%s call reg state callback app_id=%d reg state=%d", 1864 __func__, p_data->reg_cfm.app_id, state); 1865 BTIF_HL_CALL_CBACK(bt_hl_callbacks, app_reg_state_cb, 1866 ((int)p_data->reg_cfm.app_id), state); 1867 } 1868 } 1869 1870 /******************************************************************************* 1871 * 1872 * Function btif_hl_set_chan_cb_state 1873 * 1874 * Description set the channel callback state 1875 * 1876 * Returns void 1877 * 1878 ******************************************************************************/ 1879 void btif_hl_set_chan_cb_state(uint8_t app_idx, uint8_t mcl_idx, 1880 btif_hl_chan_cb_state_t state) { 1881 btif_hl_pending_chan_cb_t* p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 1882 btif_hl_chan_cb_state_t cur_state = p_pcb->cb_state; 1883 1884 if (cur_state != state) { 1885 p_pcb->cb_state = state; 1886 BTIF_TRACE_DEBUG("%s state %d--->%d", __func__, cur_state, state); 1887 } 1888 } 1889 /******************************************************************************* 1890 * 1891 * Function btif_hl_send_destroyed_cb 1892 * 1893 * Description send the channel destroyed callback 1894 * 1895 * Returns void 1896 * 1897 ******************************************************************************/ 1898 void btif_hl_send_destroyed_cb(btif_hl_app_cb_t* p_acb) { 1899 int app_id = (int)btif_hl_get_app_id(p_acb->delete_mdl.channel_id); 1900 1901 RawAddress bd_addr = p_acb->delete_mdl.bd_addr; 1902 BTIF_TRACE_DEBUG("%s", __func__); 1903 BTIF_TRACE_DEBUG( 1904 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d, state=%d " 1905 "fd=%d", 1906 p_acb->delete_mdl.channel_id, p_acb->delete_mdl.mdep_cfg_idx, 1907 BTHL_CONN_STATE_DESTROYED, 0); 1908 VLOG(1) << "BD " << bd_addr; 1909 1910 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr, 1911 p_acb->delete_mdl.mdep_cfg_idx, 1912 p_acb->delete_mdl.channel_id, BTHL_CONN_STATE_DESTROYED, 1913 0); 1914 } 1915 /******************************************************************************* 1916 * 1917 * Function btif_hl_send_disconnecting_cb 1918 * 1919 * Description send a channel disconnecting callback 1920 * 1921 * Returns void 1922 * 1923 ******************************************************************************/ 1924 void btif_hl_send_disconnecting_cb(uint8_t app_idx, uint8_t mcl_idx, 1925 uint8_t mdl_idx) { 1926 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1927 btif_hl_soc_cb_t* p_scb = p_dcb->p_scb; 1928 int app_id = (int)btif_hl_get_app_id(p_scb->channel_id); 1929 1930 RawAddress bd_addr = p_scb->bd_addr; 1931 1932 BTIF_TRACE_DEBUG("%s", __func__); 1933 BTIF_TRACE_DEBUG( 1934 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d, " 1935 "state=%d fd=%d", 1936 p_scb->channel_id, p_scb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTING, 1937 p_scb->socket_id[0]); 1938 VLOG(1) << "BD " << bd_addr; 1939 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr, 1940 p_scb->mdep_cfg_idx, p_scb->channel_id, 1941 BTHL_CONN_STATE_DISCONNECTING, p_scb->socket_id[0]); 1942 } 1943 /******************************************************************************* 1944 * 1945 * Function btif_hl_send_setup_connecting_cb 1946 * 1947 * Description send a channel connecting callback 1948 * 1949 * Returns void 1950 * 1951 ******************************************************************************/ 1952 void btif_hl_send_setup_connecting_cb(uint8_t app_idx, uint8_t mcl_idx) { 1953 btif_hl_pending_chan_cb_t* p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 1954 int app_id = (int)btif_hl_get_app_id(p_pcb->channel_id); 1955 1956 RawAddress bd_addr = p_pcb->bd_addr; 1957 1958 if (p_pcb->in_use && 1959 p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING) { 1960 BTIF_TRACE_DEBUG("%s", __func__); 1961 BTIF_TRACE_DEBUG( 1962 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d " 1963 "state=%d fd=%d", 1964 p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_CONNECTING, 0); 1965 VLOG(1) << "BD " << bd_addr; 1966 1967 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr, 1968 p_pcb->mdep_cfg_idx, p_pcb->channel_id, 1969 BTHL_CONN_STATE_CONNECTING, 0); 1970 btif_hl_set_chan_cb_state(app_idx, mcl_idx, 1971 BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING); 1972 } 1973 } 1974 /******************************************************************************* 1975 * 1976 * Function btif_hl_send_setup_disconnected_cb 1977 * 1978 * Description send a channel disconnected callback 1979 * 1980 * Returns void 1981 * 1982 ******************************************************************************/ 1983 void btif_hl_send_setup_disconnected_cb(uint8_t app_idx, uint8_t mcl_idx) { 1984 btif_hl_pending_chan_cb_t* p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 1985 int app_id = (int)btif_hl_get_app_id(p_pcb->channel_id); 1986 1987 RawAddress bd_addr = p_pcb->bd_addr; 1988 1989 BTIF_TRACE_DEBUG("%s p_pcb->in_use=%d", __func__, p_pcb->in_use); 1990 if (p_pcb->in_use) { 1991 BTIF_TRACE_DEBUG("%p_pcb->cb_state=%d", p_pcb->cb_state); 1992 if (p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING) { 1993 BTIF_TRACE_DEBUG( 1994 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d " 1995 "state=%d fd=%d", 1996 p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_CONNECTING, 1997 0); 1998 VLOG(1) << "BD " << bd_addr; 1999 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr, 2000 p_pcb->mdep_cfg_idx, p_pcb->channel_id, 2001 BTHL_CONN_STATE_CONNECTING, 0); 2002 2003 BTIF_TRACE_DEBUG( 2004 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d " 2005 "state=%d fd=%d", 2006 p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTED, 2007 0); 2008 VLOG(1) << "BD " << bd_addr; 2009 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr, 2010 p_pcb->mdep_cfg_idx, p_pcb->channel_id, 2011 BTHL_CONN_STATE_DISCONNECTED, 0); 2012 } else if (p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING) { 2013 BTIF_TRACE_DEBUG( 2014 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d " 2015 "state=%d fd=%d", 2016 p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTED, 2017 0); 2018 VLOG(1) << "BD " << bd_addr; 2019 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr, 2020 p_pcb->mdep_cfg_idx, p_pcb->channel_id, 2021 BTHL_CONN_STATE_DISCONNECTED, 0); 2022 } 2023 btif_hl_clean_pcb(p_pcb); 2024 } 2025 } 2026 /******************************************************************************* 2027 * 2028 * Function btif_hl_proc_sdp_query_cfm 2029 * 2030 * Description Process the SDP query confirmation 2031 * 2032 * Returns Nothing 2033 * 2034 ******************************************************************************/ 2035 static bool btif_hl_proc_sdp_query_cfm(tBTA_HL* p_data) { 2036 btif_hl_app_cb_t* p_acb; 2037 btif_hl_mcl_cb_t* p_mcb; 2038 tBTA_HL_SDP* p_sdp; 2039 tBTA_HL_CCH_OPEN_PARAM open_param; 2040 uint8_t app_idx, mcl_idx, sdp_idx = 0; 2041 uint8_t num_recs, i, num_mdeps, j; 2042 btif_hl_cch_op_t old_cch_oper; 2043 bool status = false; 2044 btif_hl_pending_chan_cb_t* p_pcb; 2045 2046 BTIF_TRACE_DEBUG("%s", __func__); 2047 2048 p_sdp = p_data->sdp_query_cfm.p_sdp; 2049 num_recs = p_sdp->num_recs; 2050 2051 BTIF_TRACE_DEBUG("num of SDP records=%d", num_recs); 2052 for (i = 0; i < num_recs; i++) { 2053 BTIF_TRACE_DEBUG("rec_idx=%d ctrl_psm=0x%x data_psm=0x%x", (i + 1), 2054 p_sdp->sdp_rec[i].ctrl_psm, p_sdp->sdp_rec[i].data_psm); 2055 BTIF_TRACE_DEBUG("MCAP supported procedures=0x%x", 2056 p_sdp->sdp_rec[i].mcap_sup_proc); 2057 num_mdeps = p_sdp->sdp_rec[i].num_mdeps; 2058 BTIF_TRACE_DEBUG("num of mdeps =%d", num_mdeps); 2059 for (j = 0; j < num_mdeps; j++) { 2060 BTIF_TRACE_DEBUG("mdep_idx=%d mdep_id=0x%x data_type=0x%x mdep_role=0x%x", 2061 (j + 1), p_sdp->sdp_rec[i].mdep_cfg[j].mdep_id, 2062 p_sdp->sdp_rec[i].mdep_cfg[j].data_type, 2063 p_sdp->sdp_rec[i].mdep_cfg[j].mdep_role); 2064 } 2065 } 2066 2067 if (btif_hl_find_app_idx_using_app_id(p_data->sdp_query_cfm.app_id, 2068 &app_idx)) { 2069 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 2070 2071 if (btif_hl_find_mcl_idx(app_idx, p_data->sdp_query_cfm.bd_addr, 2072 &mcl_idx)) { 2073 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2074 if (p_mcb->cch_oper != BTIF_HL_CCH_OP_NONE) { 2075 memcpy(&p_mcb->sdp, p_sdp, sizeof(tBTA_HL_SDP)); 2076 old_cch_oper = p_mcb->cch_oper; 2077 p_mcb->cch_oper = BTIF_HL_CCH_OP_NONE; 2078 2079 switch (old_cch_oper) { 2080 case BTIF_HL_CCH_OP_MDEP_FILTERING: 2081 status = btif_hl_find_sdp_idx_using_mdep_filter(app_idx, mcl_idx, 2082 &sdp_idx); 2083 break; 2084 default: 2085 break; 2086 } 2087 2088 if (status) { 2089 p_mcb->sdp_idx = sdp_idx; 2090 p_mcb->valid_sdp_idx = true; 2091 p_mcb->ctrl_psm = p_mcb->sdp.sdp_rec[sdp_idx].ctrl_psm; 2092 2093 switch (old_cch_oper) { 2094 case BTIF_HL_CCH_OP_MDEP_FILTERING: 2095 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 2096 if (p_pcb->in_use) { 2097 if (!p_pcb->abort_pending) { 2098 switch (p_pcb->op) { 2099 case BTIF_HL_PEND_DCH_OP_OPEN: 2100 btif_hl_send_setup_connecting_cb(app_idx, mcl_idx); 2101 break; 2102 case BTIF_HL_PEND_DCH_OP_DELETE_MDL: 2103 default: 2104 break; 2105 } 2106 open_param.ctrl_psm = p_mcb->ctrl_psm; 2107 open_param.bd_addr = p_mcb->bd_addr; 2108 open_param.sec_mask = 2109 (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); 2110 BTA_HlCchOpen(p_acb->app_id, p_acb->app_handle, &open_param); 2111 } else { 2112 BTIF_TRACE_DEBUG("channel abort pending"); 2113 } 2114 } 2115 break; 2116 2117 case BTIF_HL_CCH_OP_DCH_OPEN: 2118 status = btif_hl_proc_pending_op(app_idx, mcl_idx); 2119 break; 2120 2121 default: 2122 BTIF_TRACE_ERROR("Invalid CCH oper %d", old_cch_oper); 2123 break; 2124 } 2125 } else { 2126 BTIF_TRACE_ERROR("Can not find SDP idx discard CCH Open request"); 2127 } 2128 } 2129 } 2130 } 2131 return status; 2132 } 2133 2134 /******************************************************************************* 2135 * 2136 * Function btif_hl_proc_cch_open_ind 2137 * 2138 * Description Process the CCH open indication 2139 * 2140 * Returns Nothing 2141 * 2142 ******************************************************************************/ 2143 static void btif_hl_proc_cch_open_ind(tBTA_HL* p_data) 2144 2145 { 2146 btif_hl_mcl_cb_t* p_mcb; 2147 uint8_t mcl_idx; 2148 int i; 2149 2150 BTIF_TRACE_DEBUG("%s", __func__); 2151 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 2152 if (btif_hl_cb.acb[i].in_use) { 2153 if (!btif_hl_find_mcl_idx(i, p_data->cch_open_ind.bd_addr, &mcl_idx)) { 2154 if (btif_hl_find_avail_mcl_idx(i, &mcl_idx)) { 2155 p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, mcl_idx); 2156 alarm_free(p_mcb->cch_timer); 2157 memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t)); 2158 p_mcb->in_use = true; 2159 p_mcb->is_connected = true; 2160 p_mcb->mcl_handle = p_data->cch_open_ind.mcl_handle; 2161 p_mcb->bd_addr = p_data->cch_open_ind.bd_addr; 2162 btif_hl_start_cch_timer(i, mcl_idx); 2163 } 2164 } else { 2165 BTIF_TRACE_ERROR("The MCL already exist for cch_open_ind"); 2166 } 2167 } 2168 } 2169 } 2170 2171 /******************************************************************************* 2172 * 2173 * Function btif_hl_proc_pending_op 2174 * 2175 * Description Process the pending dch operation. 2176 * 2177 * Returns Nothing 2178 * 2179 ******************************************************************************/ 2180 bool btif_hl_proc_pending_op(uint8_t app_idx, uint8_t mcl_idx) 2181 2182 { 2183 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 2184 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2185 btif_hl_pending_chan_cb_t* p_pcb; 2186 bool status = false; 2187 tBTA_HL_DCH_OPEN_PARAM dch_open; 2188 tBTA_HL_MDL_ID mdl_id; 2189 tBTA_HL_DCH_RECONNECT_PARAM reconnect_param; 2190 2191 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 2192 if (p_pcb->in_use) { 2193 switch (p_pcb->op) { 2194 case BTIF_HL_PEND_DCH_OP_OPEN: 2195 if (!p_pcb->abort_pending) { 2196 BTIF_TRACE_DEBUG("op BTIF_HL_PEND_DCH_OP_OPEN"); 2197 dch_open.ctrl_psm = p_mcb->ctrl_psm; 2198 dch_open.local_mdep_id = 2199 p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx].mdep_id; 2200 if (btif_hl_find_peer_mdep_id( 2201 p_acb->app_id, p_mcb->bd_addr, 2202 p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx] 2203 .mdep_cfg.mdep_role, 2204 p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx] 2205 .mdep_cfg.data_cfg[0] 2206 .data_type, 2207 &dch_open.peer_mdep_id)) { 2208 dch_open.local_cfg = p_acb->channel_type[p_pcb->mdep_cfg_idx]; 2209 if ((p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx] 2210 .mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SOURCE) && 2211 !btif_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) { 2212 dch_open.local_cfg = BTA_HL_DCH_CFG_RELIABLE; 2213 } 2214 dch_open.sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); 2215 BTIF_TRACE_DEBUG("dch_open.local_cfg=%d ", dch_open.local_cfg); 2216 btif_hl_send_setup_connecting_cb(app_idx, mcl_idx); 2217 2218 if (!btif_hl_is_reconnect_possible(app_idx, mcl_idx, 2219 p_pcb->mdep_cfg_idx, &dch_open, 2220 &mdl_id)) { 2221 BTIF_TRACE_DEBUG("Issue DCH open, mcl_handle=%d", 2222 p_mcb->mcl_handle); 2223 BTA_HlDchOpen(p_mcb->mcl_handle, &dch_open); 2224 } else { 2225 reconnect_param.ctrl_psm = p_mcb->ctrl_psm; 2226 reconnect_param.mdl_id = mdl_id; 2227 ; 2228 BTIF_TRACE_DEBUG("Issue Reconnect ctrl_psm=0x%x mdl_id=0x%x", 2229 reconnect_param.ctrl_psm, 2230 reconnect_param.mdl_id); 2231 BTA_HlDchReconnect(p_mcb->mcl_handle, &reconnect_param); 2232 } 2233 status = true; 2234 } 2235 } else { 2236 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx); 2237 status = true; 2238 } 2239 break; 2240 case BTIF_HL_PEND_DCH_OP_DELETE_MDL: 2241 BTA_HlDeleteMdl(p_mcb->mcl_handle, p_acb->delete_mdl.mdl_id); 2242 status = true; 2243 break; 2244 2245 default: 2246 break; 2247 } 2248 } 2249 return status; 2250 } 2251 2252 /******************************************************************************* 2253 * 2254 * Function btif_hl_proc_cch_open_cfm 2255 * 2256 * Description Process the CCH open confirmation 2257 * 2258 * Returns Nothing 2259 * 2260 ******************************************************************************/ 2261 static bool btif_hl_proc_cch_open_cfm(tBTA_HL* p_data) 2262 2263 { 2264 btif_hl_mcl_cb_t* p_mcb; 2265 uint8_t app_idx, mcl_idx; 2266 bool status = false; 2267 2268 BTIF_TRACE_DEBUG("%s", __func__); 2269 2270 if (btif_hl_find_app_idx_using_app_id(p_data->cch_open_cfm.app_id, 2271 &app_idx)) { 2272 BTIF_TRACE_DEBUG("app_idx=%d", app_idx); 2273 if (btif_hl_find_mcl_idx(app_idx, p_data->cch_open_cfm.bd_addr, &mcl_idx)) { 2274 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2275 BTIF_TRACE_DEBUG("mcl_idx=%d, mcl_handle=%d", mcl_idx, 2276 p_data->cch_open_cfm.mcl_handle); 2277 p_mcb->mcl_handle = p_data->cch_open_cfm.mcl_handle; 2278 p_mcb->is_connected = true; 2279 status = btif_hl_proc_pending_op(app_idx, mcl_idx); 2280 if (status) btif_hl_start_cch_timer(app_idx, mcl_idx); 2281 } 2282 } 2283 2284 return status; 2285 } 2286 2287 /******************************************************************************* 2288 * 2289 * Function btif_hl_clean_mcb_using_handle 2290 * 2291 * Description clean control channel cb using handle 2292 * 2293 * Returns void 2294 * 2295 ******************************************************************************/ 2296 static void btif_hl_clean_mcb_using_handle(tBTA_HL_MCL_HANDLE mcl_handle) { 2297 btif_hl_app_cb_t* p_acb; 2298 uint8_t i, j; 2299 2300 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 2301 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 2302 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 2303 if (p_acb->mcb[j].in_use) 2304 BTIF_TRACE_DEBUG( 2305 "btif_hl_find_mcl_idx_using_handle: app_idx=%d," 2306 "mcl_idx =%d mcl_handle=%d", 2307 i, j, p_acb->mcb[j].mcl_handle); 2308 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) { 2309 btif_hl_stop_cch_timer(i, j); 2310 btif_hl_release_mcl_sockets(i, j); 2311 btif_hl_send_setup_disconnected_cb(i, j); 2312 btif_hl_clean_mcl_cb(i, j); 2313 } 2314 } 2315 } 2316 } 2317 2318 /******************************************************************************* 2319 * 2320 * Function btif_hl_proc_cch_close_ind 2321 * 2322 * Description Process the CCH close indication 2323 * 2324 * Returns Nothing 2325 * 2326 ******************************************************************************/ 2327 static void btif_hl_proc_cch_close_ind(tBTA_HL* p_data) 2328 2329 { 2330 BTIF_TRACE_DEBUG("%s", __func__); 2331 2332 btif_hl_clean_mcb_using_handle(p_data->cch_close_ind.mcl_handle); 2333 } 2334 2335 /******************************************************************************* 2336 * 2337 * Function btif_hl_proc_cch_close_cfm 2338 * 2339 * Description Process the CCH close confirmation 2340 * 2341 * Returns Nothing 2342 * 2343 ******************************************************************************/ 2344 static void btif_hl_proc_cch_close_cfm(tBTA_HL* p_data) { 2345 BTIF_TRACE_DEBUG("%s", __func__); 2346 2347 btif_hl_clean_mcb_using_handle(p_data->cch_close_ind.mcl_handle); 2348 } 2349 2350 /******************************************************************************* 2351 * 2352 * Function btif_hl_proc_create_ind 2353 * 2354 * Description Process the MDL create indication 2355 * 2356 * Returns Nothing 2357 * 2358 ******************************************************************************/ 2359 static void btif_hl_proc_create_ind(tBTA_HL* p_data) { 2360 btif_hl_app_cb_t* p_acb; 2361 btif_hl_mcl_cb_t* p_mcb; 2362 tBTA_HL_MDEP* p_mdep; 2363 uint8_t orig_app_idx, mcl_idx, mdep_cfg_idx; 2364 bool first_reliable_exist; 2365 bool success = true; 2366 tBTA_HL_DCH_CFG rsp_cfg = BTA_HL_DCH_CFG_UNKNOWN; 2367 tBTA_HL_DCH_CREATE_RSP rsp_code = BTA_HL_DCH_CREATE_RSP_CFG_REJ; 2368 tBTA_HL_DCH_CREATE_RSP_PARAM create_rsp_param; 2369 2370 BTIF_TRACE_DEBUG("%s", __func__); 2371 2372 // Find the correct app_idx based on the mdep_id; 2373 btif_hl_find_app_idx_using_mdepId(p_data->dch_create_ind.local_mdep_id, 2374 &orig_app_idx); 2375 if (btif_hl_find_mcl_idx(orig_app_idx, p_data->dch_create_ind.bd_addr, 2376 &mcl_idx)) { 2377 p_acb = BTIF_HL_GET_APP_CB_PTR(orig_app_idx); 2378 p_mcb = BTIF_HL_GET_MCL_CB_PTR(orig_app_idx, mcl_idx); 2379 2380 if (btif_hl_find_mdep_cfg_idx(orig_app_idx, 2381 p_data->dch_create_ind.local_mdep_id, 2382 &mdep_cfg_idx)) { 2383 p_mdep = &(p_acb->sup_feature.mdep[mdep_cfg_idx]); 2384 first_reliable_exist = 2385 btif_hl_is_the_first_reliable_existed(orig_app_idx, mcl_idx); 2386 switch (p_mdep->mdep_cfg.mdep_role) { 2387 case BTA_HL_MDEP_ROLE_SOURCE: 2388 if (p_data->dch_create_ind.cfg == BTA_HL_DCH_CFG_NO_PREF) { 2389 if (first_reliable_exist) { 2390 rsp_cfg = p_acb->channel_type[mdep_cfg_idx]; 2391 } else { 2392 rsp_cfg = BTA_HL_DCH_CFG_RELIABLE; 2393 } 2394 rsp_code = BTA_HL_DCH_CREATE_RSP_SUCCESS; 2395 } 2396 2397 break; 2398 case BTA_HL_MDEP_ROLE_SINK: 2399 2400 BTIF_TRACE_DEBUG("btif_hl_proc_create_ind:BTA_HL_MDEP_ROLE_SINK"); 2401 if ((p_data->dch_create_ind.cfg == BTA_HL_DCH_CFG_RELIABLE) || 2402 (first_reliable_exist && 2403 (p_data->dch_create_ind.cfg == BTA_HL_DCH_CFG_STREAMING))) { 2404 rsp_code = BTA_HL_DCH_CREATE_RSP_SUCCESS; 2405 rsp_cfg = p_data->dch_create_ind.cfg; 2406 BTIF_TRACE_DEBUG( 2407 "btif_hl_proc_create_ind:BTA_HL_MDEP_ROLE_SINK cfg = %d", 2408 rsp_cfg); 2409 } 2410 break; 2411 default: 2412 break; 2413 } 2414 } 2415 } else { 2416 success = false; 2417 } 2418 2419 if (success) { 2420 BTIF_TRACE_DEBUG("create response rsp_code=%d rsp_cfg=%d", rsp_code, 2421 rsp_cfg); 2422 create_rsp_param.local_mdep_id = p_data->dch_create_ind.local_mdep_id; 2423 create_rsp_param.mdl_id = p_data->dch_create_ind.mdl_id; 2424 create_rsp_param.rsp_code = rsp_code; 2425 create_rsp_param.cfg_rsp = rsp_cfg; 2426 BTA_HlDchCreateRsp(p_mcb->mcl_handle, &create_rsp_param); 2427 } 2428 } 2429 2430 /******************************************************************************* 2431 * 2432 * Function btif_hl_proc_dch_open_ind 2433 * 2434 * Description Process the DCH open indication 2435 * 2436 * Returns Nothing 2437 * 2438 ******************************************************************************/ 2439 static void btif_hl_proc_dch_open_ind(tBTA_HL* p_data) 2440 2441 { 2442 btif_hl_mdl_cb_t* p_dcb; 2443 uint8_t orig_app_idx, mcl_idx, mdl_idx, mdep_cfg_idx; 2444 bool close_dch = false; 2445 2446 BTIF_TRACE_DEBUG("%s", __func__); 2447 2448 // Find the correct app_idx based on the mdep_id; 2449 btif_hl_find_app_idx_using_mdepId(p_data->dch_open_ind.local_mdep_id, 2450 &orig_app_idx); 2451 2452 if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_open_ind.mcl_handle, 2453 orig_app_idx, &mcl_idx)) { 2454 if (btif_hl_find_avail_mdl_idx(orig_app_idx, mcl_idx, &mdl_idx)) { 2455 p_dcb = BTIF_HL_GET_MDL_CB_PTR(orig_app_idx, mcl_idx, mdl_idx); 2456 2457 if (btif_hl_find_mdep_cfg_idx(orig_app_idx, 2458 p_data->dch_open_ind.local_mdep_id, 2459 &mdep_cfg_idx)) { 2460 p_dcb->in_use = true; 2461 p_dcb->mdl_handle = p_data->dch_open_ind.mdl_handle; 2462 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 2463 p_dcb->local_mdep_id = p_data->dch_open_ind.local_mdep_id; 2464 p_dcb->mdl_id = p_data->dch_open_ind.mdl_id; 2465 p_dcb->dch_mode = p_data->dch_open_ind.dch_mode; 2466 p_dcb->dch_mode = p_data->dch_open_ind.dch_mode; 2467 p_dcb->is_the_first_reliable = p_data->dch_open_ind.first_reliable; 2468 p_dcb->mtu = p_data->dch_open_ind.mtu; 2469 2470 if (btif_hl_find_channel_id_using_mdl_id(orig_app_idx, p_dcb->mdl_id, 2471 &p_dcb->channel_id)) { 2472 BTIF_TRACE_DEBUG(" app_idx=%d mcl_idx=%d mdl_idx=%d channel_id=%d", 2473 orig_app_idx, mcl_idx, mdl_idx, p_dcb->channel_id); 2474 if (!btif_hl_create_socket(orig_app_idx, mcl_idx, mdl_idx)) { 2475 BTIF_TRACE_ERROR("Unable to create socket"); 2476 close_dch = true; 2477 } 2478 } else { 2479 BTIF_TRACE_ERROR("Unable find channel id for mdl_id=0x%x", 2480 p_dcb->mdl_id); 2481 close_dch = true; 2482 } 2483 } else { 2484 BTIF_TRACE_ERROR("INVALID_LOCAL_MDEP_ID mdep_id=%d", 2485 p_data->dch_open_cfm.local_mdep_id); 2486 close_dch = true; 2487 } 2488 2489 if (close_dch) btif_hl_clean_mdl_cb(p_dcb); 2490 } else 2491 close_dch = true; 2492 } else 2493 close_dch = true; 2494 2495 if (close_dch) BTA_HlDchClose(p_data->dch_open_cfm.mdl_handle); 2496 } 2497 2498 /******************************************************************************* 2499 * 2500 * Function btif_hl_proc_dch_open_cfm 2501 * 2502 * Description Process the DCH close confirmation 2503 * 2504 * Returns Nothing 2505 * 2506 ******************************************************************************/ 2507 static bool btif_hl_proc_dch_open_cfm(tBTA_HL* p_data) 2508 2509 { 2510 btif_hl_mdl_cb_t* p_dcb; 2511 btif_hl_pending_chan_cb_t* p_pcb; 2512 uint8_t app_idx, mcl_idx, mdl_idx, mdep_cfg_idx; 2513 bool status = false; 2514 bool close_dch = false; 2515 2516 BTIF_TRACE_DEBUG("%s", __func__); 2517 2518 // Find the correct app_idx based on the mdep_id; 2519 btif_hl_find_app_idx_using_mdepId(p_data->dch_open_cfm.local_mdep_id, 2520 &app_idx); 2521 2522 if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_open_cfm.mcl_handle, 2523 app_idx, &mcl_idx)) { 2524 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 2525 2526 if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) { 2527 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2528 2529 if (btif_hl_find_mdep_cfg_idx(app_idx, p_data->dch_open_cfm.local_mdep_id, 2530 &mdep_cfg_idx)) { 2531 p_dcb->in_use = true; 2532 p_dcb->mdl_handle = p_data->dch_open_cfm.mdl_handle; 2533 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 2534 p_dcb->local_mdep_id = p_data->dch_open_cfm.local_mdep_id; 2535 p_dcb->mdl_id = p_data->dch_open_cfm.mdl_id; 2536 p_dcb->dch_mode = p_data->dch_open_cfm.dch_mode; 2537 p_dcb->is_the_first_reliable = p_data->dch_open_cfm.first_reliable; 2538 p_dcb->mtu = p_data->dch_open_cfm.mtu; 2539 p_dcb->channel_id = p_pcb->channel_id; 2540 2541 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d mdl_idx=%d", app_idx, mcl_idx, 2542 mdl_idx); 2543 btif_hl_send_setup_connecting_cb(app_idx, mcl_idx); 2544 if (btif_hl_create_socket(app_idx, mcl_idx, mdl_idx)) { 2545 status = true; 2546 BTIF_TRACE_DEBUG( 2547 "app_idx=%d mcl_idx=%d mdl_idx=%d p_dcb->channel_id=0x%08x", 2548 app_idx, mcl_idx, mdl_idx, p_dcb->channel_id); 2549 btif_hl_clean_pcb(p_pcb); 2550 } else { 2551 BTIF_TRACE_ERROR("Unable to create socket"); 2552 close_dch = true; 2553 } 2554 } else { 2555 BTIF_TRACE_ERROR("INVALID_LOCAL_MDEP_ID mdep_id=%d", 2556 p_data->dch_open_cfm.local_mdep_id); 2557 close_dch = true; 2558 } 2559 2560 if (close_dch) { 2561 btif_hl_clean_mdl_cb(p_dcb); 2562 BTA_HlDchClose(p_data->dch_open_cfm.mdl_handle); 2563 } 2564 } 2565 } 2566 2567 return status; 2568 } 2569 /******************************************************************************* 2570 * 2571 * Function btif_hl_proc_dch_reconnect_cfm 2572 * 2573 * Description Process the DCH reconnect indication 2574 * 2575 * Returns Nothing 2576 * 2577 ******************************************************************************/ 2578 static bool btif_hl_proc_dch_reconnect_cfm(tBTA_HL* p_data) { 2579 btif_hl_mdl_cb_t* p_dcb; 2580 btif_hl_pending_chan_cb_t* p_pcb; 2581 uint8_t app_idx, mcl_idx, mdl_idx, mdep_cfg_idx; 2582 bool status = false; 2583 bool close_dch = false; 2584 2585 BTIF_TRACE_DEBUG("%s", __func__); 2586 2587 btif_hl_find_app_idx_using_mdepId(p_data->dch_reconnect_cfm.local_mdep_id, 2588 &app_idx); 2589 2590 if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_reconnect_cfm.mcl_handle, 2591 app_idx, &mcl_idx)) { 2592 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 2593 2594 if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) { 2595 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2596 2597 if (btif_hl_find_mdep_cfg_idx(app_idx, 2598 p_data->dch_reconnect_cfm.local_mdep_id, 2599 &mdep_cfg_idx)) { 2600 p_dcb->in_use = true; 2601 p_dcb->mdl_handle = p_data->dch_reconnect_cfm.mdl_handle; 2602 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 2603 p_dcb->local_mdep_id = p_data->dch_reconnect_cfm.local_mdep_id; 2604 p_dcb->mdl_id = p_data->dch_reconnect_cfm.mdl_id; 2605 p_dcb->dch_mode = p_data->dch_reconnect_cfm.dch_mode; 2606 p_dcb->is_the_first_reliable = p_data->dch_reconnect_cfm.first_reliable; 2607 p_dcb->mtu = p_data->dch_reconnect_cfm.mtu; 2608 p_dcb->channel_id = p_pcb->channel_id; 2609 2610 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d mdl_idx=%d", app_idx, mcl_idx, 2611 mdl_idx); 2612 btif_hl_send_setup_connecting_cb(app_idx, mcl_idx); 2613 if (btif_hl_create_socket(app_idx, mcl_idx, mdl_idx)) { 2614 status = true; 2615 BTIF_TRACE_DEBUG( 2616 "app_idx=%d mcl_idx=%d mdl_idx=%d p_dcb->channel_id=0x%08x", 2617 app_idx, mcl_idx, mdl_idx, p_dcb->channel_id); 2618 btif_hl_clean_pcb(p_pcb); 2619 } else { 2620 BTIF_TRACE_ERROR("Unable to create socket"); 2621 close_dch = true; 2622 } 2623 } else { 2624 BTIF_TRACE_ERROR("INVALID_LOCAL_MDEP_ID mdep_id=%d", 2625 p_data->dch_open_cfm.local_mdep_id); 2626 close_dch = true; 2627 } 2628 2629 if (close_dch) { 2630 btif_hl_clean_mdl_cb(p_dcb); 2631 BTA_HlDchClose(p_data->dch_reconnect_cfm.mdl_handle); 2632 } 2633 } 2634 } 2635 2636 return status; 2637 } 2638 /******************************************************************************* 2639 * 2640 * Function btif_hl_proc_dch_reconnect_ind 2641 * 2642 * Description Process the DCH reconnect indication 2643 * 2644 * Returns Nothing 2645 * 2646 ******************************************************************************/ 2647 static void btif_hl_proc_dch_reconnect_ind(tBTA_HL* p_data) 2648 2649 { 2650 btif_hl_app_cb_t* p_acb; 2651 btif_hl_mdl_cb_t* p_dcb; 2652 uint8_t app_idx, mcl_idx, mdl_idx, mdep_cfg_idx; 2653 bool close_dch = false; 2654 2655 BTIF_TRACE_DEBUG("%s", __func__); 2656 2657 // Find the correct app_idx based on the mdep_id; 2658 btif_hl_find_app_idx_using_mdepId(p_data->dch_reconnect_ind.local_mdep_id, 2659 &app_idx); 2660 2661 if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_reconnect_ind.mcl_handle, 2662 app_idx, &mcl_idx)) { 2663 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 2664 BTIF_TRACE_DEBUG( 2665 "btif_hl_proc_dch_reconnect_ind: app_idx = %d, mcl_idx = %d", app_idx, 2666 mcl_idx); 2667 2668 if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) { 2669 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2670 2671 if (btif_hl_find_mdep_cfg_idx(app_idx, 2672 p_data->dch_reconnect_ind.local_mdep_id, 2673 &mdep_cfg_idx)) { 2674 p_dcb->in_use = true; 2675 p_dcb->mdl_handle = p_data->dch_reconnect_ind.mdl_handle; 2676 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 2677 p_dcb->local_mdep_id = p_data->dch_reconnect_ind.local_mdep_id; 2678 p_dcb->mdl_id = p_data->dch_reconnect_ind.mdl_id; 2679 p_dcb->dch_mode = p_data->dch_reconnect_ind.dch_mode; 2680 p_dcb->dch_mode = p_data->dch_reconnect_ind.dch_mode; 2681 p_dcb->is_the_first_reliable = p_data->dch_reconnect_ind.first_reliable; 2682 p_dcb->mtu = p_data->dch_reconnect_ind.mtu; 2683 p_dcb->channel_id = btif_hl_get_next_channel_id(p_acb->app_id); 2684 2685 BTIF_TRACE_DEBUG(" app_idx=%d mcl_idx=%d mdl_idx=%d channel_id=%d", 2686 app_idx, mcl_idx, mdl_idx, p_dcb->channel_id); 2687 if (!btif_hl_create_socket(app_idx, mcl_idx, mdl_idx)) { 2688 BTIF_TRACE_ERROR("Unable to create socket"); 2689 close_dch = true; 2690 } 2691 } else { 2692 BTIF_TRACE_ERROR("INVALID_LOCAL_MDEP_ID mdep_id=%d", 2693 p_data->dch_open_cfm.local_mdep_id); 2694 close_dch = true; 2695 } 2696 2697 if (close_dch) btif_hl_clean_mdl_cb(p_dcb); 2698 } else 2699 close_dch = true; 2700 } else 2701 close_dch = true; 2702 2703 if (close_dch) BTA_HlDchClose(p_data->dch_reconnect_ind.mdl_handle); 2704 } 2705 2706 /******************************************************************************* 2707 * 2708 * Function btif_hl_proc_dch_close_ind 2709 * 2710 * Description Process the DCH close indication 2711 * 2712 * Returns Nothing 2713 * 2714 ******************************************************************************/ 2715 static void btif_hl_proc_dch_close_ind(tBTA_HL* p_data) 2716 2717 { 2718 btif_hl_mdl_cb_t* p_dcb; 2719 btif_hl_mcl_cb_t* p_mcb; 2720 uint8_t app_idx, mcl_idx, mdl_idx; 2721 2722 BTIF_TRACE_DEBUG("%s", __func__); 2723 if (btif_hl_find_mdl_idx_using_handle(p_data->dch_close_ind.mdl_handle, 2724 &app_idx, &mcl_idx, &mdl_idx)) { 2725 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2726 btif_hl_release_socket(app_idx, mcl_idx, mdl_idx); 2727 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx); 2728 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2729 btif_hl_clean_mdl_cb(p_dcb); 2730 if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle)) 2731 btif_hl_start_cch_timer(app_idx, mcl_idx); 2732 BTIF_TRACE_DEBUG("remote DCH close success mdl_idx=%d", mdl_idx); 2733 } 2734 } 2735 2736 /******************************************************************************* 2737 * 2738 * Function btif_hl_proc_dch_close_cfm 2739 * 2740 * Description Process the DCH reconnect confirmation 2741 * 2742 * Returns Nothing 2743 * 2744 ******************************************************************************/ 2745 static void btif_hl_proc_dch_close_cfm(tBTA_HL* p_data) 2746 2747 { 2748 btif_hl_mdl_cb_t* p_dcb; 2749 btif_hl_mcl_cb_t* p_mcb; 2750 uint8_t app_idx, mcl_idx, mdl_idx; 2751 2752 BTIF_TRACE_DEBUG("%s", __func__); 2753 if (btif_hl_find_mdl_idx_using_handle(p_data->dch_close_cfm.mdl_handle, 2754 &app_idx, &mcl_idx, &mdl_idx)) { 2755 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2756 btif_hl_release_socket(app_idx, mcl_idx, mdl_idx); 2757 btif_hl_clean_mdl_cb(p_dcb); 2758 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2759 if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle)) 2760 btif_hl_start_cch_timer(app_idx, mcl_idx); 2761 BTIF_TRACE_DEBUG(" local DCH close success mdl_idx=%d", mdl_idx); 2762 } 2763 } 2764 2765 /******************************************************************************* 2766 * 2767 * Function btif_hl_proc_abort_ind 2768 * 2769 * Description Process the abort indicaiton 2770 * 2771 * Returns Nothing 2772 * 2773 ******************************************************************************/ 2774 static void btif_hl_proc_abort_ind(tBTA_HL_MCL_HANDLE mcl_handle) { 2775 BTIF_TRACE_DEBUG("%s", __func__); 2776 btif_hl_app_cb_t* p_acb; 2777 uint8_t i, j; 2778 2779 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 2780 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 2781 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 2782 if (p_acb->mcb[j].in_use) 2783 BTIF_TRACE_DEBUG( 2784 "btif_hl_find_mcl_idx_using_handle: app_idx=%d,mcl_idx =%d " 2785 "mcl_handle=%d", 2786 i, j, p_acb->mcb[j].mcl_handle); 2787 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) { 2788 btif_hl_stop_cch_timer(i, j); 2789 btif_hl_send_setup_disconnected_cb(i, j); 2790 btif_hl_clean_mcl_cb(i, j); 2791 } 2792 } 2793 } 2794 } 2795 2796 /******************************************************************************* 2797 * 2798 * Function btif_hl_proc_abort_cfm 2799 * 2800 * Description Process the abort confirmation 2801 * 2802 * Returns Nothing 2803 * 2804 ******************************************************************************/ 2805 static void btif_hl_proc_abort_cfm(tBTA_HL_MCL_HANDLE mcl_handle) { 2806 BTIF_TRACE_DEBUG("%s", __func__); 2807 btif_hl_app_cb_t* p_acb; 2808 uint8_t i, j; 2809 2810 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 2811 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 2812 for (j = 0; j < BTA_HL_NUM_MCLS; j++) { 2813 if (p_acb->mcb[j].in_use) 2814 BTIF_TRACE_DEBUG( 2815 "btif_hl_find_mcl_idx_using_handle: app_idx=%d,mcl_idx =%d " 2816 "mcl_handle=%d", 2817 i, j, p_acb->mcb[j].mcl_handle); 2818 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) { 2819 btif_hl_stop_cch_timer(i, j); 2820 btif_hl_send_setup_disconnected_cb(i, j); 2821 btif_hl_clean_mcl_cb(i, j); 2822 } 2823 } 2824 } 2825 } 2826 2827 /******************************************************************************* 2828 * 2829 * Function btif_hl_proc_send_data_cfm 2830 * 2831 * Description Process the send data confirmation 2832 * 2833 * Returns Nothing 2834 * 2835 ******************************************************************************/ 2836 static void btif_hl_proc_send_data_cfm(tBTA_HL_MDL_HANDLE mdl_handle, 2837 UNUSED_ATTR tBTA_HL_STATUS status) { 2838 uint8_t app_idx, mcl_idx, mdl_idx; 2839 btif_hl_mdl_cb_t* p_dcb; 2840 2841 BTIF_TRACE_DEBUG("%s", __func__); 2842 if (btif_hl_find_mdl_idx_using_handle(mdl_handle, &app_idx, &mcl_idx, 2843 &mdl_idx)) { 2844 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2845 osi_free_and_reset((void**)&p_dcb->p_tx_pkt); 2846 BTIF_TRACE_DEBUG("send success free p_tx_pkt tx_size=%d", p_dcb->tx_size); 2847 p_dcb->tx_size = 0; 2848 } 2849 } 2850 2851 /******************************************************************************* 2852 * 2853 * Function btif_hl_proc_dch_cong_ind 2854 * 2855 * Description Process the DCH congestion change indication 2856 * 2857 * Returns Nothing 2858 * 2859 ******************************************************************************/ 2860 static void btif_hl_proc_dch_cong_ind(tBTA_HL* p_data) 2861 2862 { 2863 btif_hl_mdl_cb_t* p_dcb; 2864 uint8_t app_idx, mcl_idx, mdl_idx; 2865 2866 BTIF_TRACE_DEBUG("btif_hl_proc_dch_cong_ind"); 2867 2868 if (btif_hl_find_mdl_idx_using_handle(p_data->dch_cong_ind.mdl_handle, 2869 &app_idx, &mcl_idx, &mdl_idx)) { 2870 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 2871 p_dcb->cong = p_data->dch_cong_ind.cong; 2872 } 2873 } 2874 2875 /******************************************************************************* 2876 * 2877 * Function btif_hl_proc_reg_request 2878 * 2879 * Description Process registration request 2880 * 2881 * Returns void 2882 * 2883 ******************************************************************************/ 2884 static void btif_hl_proc_reg_request(uint8_t app_idx, uint8_t app_id, 2885 tBTA_HL_REG_PARAM* p_reg_param, 2886 UNUSED_ATTR tBTA_HL_CBACK* p_cback) { 2887 BTIF_TRACE_DEBUG("%s app_idx=%d app_id=%d", __func__, app_idx, app_id); 2888 2889 if (reg_counter > 1) { 2890 BTIF_TRACE_DEBUG("btif_hl_proc_reg_request: calling uPDATE"); 2891 BTA_HlUpdate(app_id, p_reg_param, true, btif_hl_cback); 2892 } else 2893 BTA_HlRegister(app_id, p_reg_param, btif_hl_cback); 2894 } 2895 2896 /******************************************************************************* 2897 * 2898 * Function btif_hl_proc_cb_evt 2899 * 2900 * Description Process HL callback events 2901 * 2902 * Returns void 2903 * 2904 ******************************************************************************/ 2905 static void btif_hl_proc_cb_evt(uint16_t event, char* p_param) { 2906 btif_hl_evt_cb_t* p_data = (btif_hl_evt_cb_t*)p_param; 2907 bthl_channel_state_t state = BTHL_CONN_STATE_DISCONNECTED; 2908 bool send_chan_cb = true; 2909 tBTA_HL_REG_PARAM reg_param; 2910 btif_hl_app_cb_t* p_acb; 2911 2912 BTIF_TRACE_DEBUG("%s event %d", __func__, event); 2913 btif_hl_display_calling_process_name(); 2914 2915 switch (event) { 2916 case BTIF_HL_SEND_CONNECTED_CB: 2917 case BTIF_HL_SEND_DISCONNECTED_CB: 2918 if (p_data->chan_cb.cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING) 2919 state = BTHL_CONN_STATE_CONNECTED; 2920 else if (p_data->chan_cb.cb_state == 2921 BTIF_HL_CHAN_CB_STATE_DISCONNECTED_PENDING) 2922 state = BTHL_CONN_STATE_DISCONNECTED; 2923 else 2924 send_chan_cb = false; 2925 2926 if (send_chan_cb) { 2927 RawAddress bd_addr = p_data->chan_cb.bd_addr; 2928 BTIF_TRACE_DEBUG( 2929 "state callbk: ch_id=0x%08x cb_state=%d state=%d fd=%d", 2930 p_data->chan_cb.channel_id, p_data->chan_cb.cb_state, state, 2931 p_data->chan_cb.fd); 2932 VLOG(1) << "BD " << bd_addr; 2933 BTIF_HL_CALL_CBACK( 2934 bt_hl_callbacks, channel_state_cb, p_data->chan_cb.app_id, &bd_addr, 2935 p_data->chan_cb.mdep_cfg_index, p_data->chan_cb.channel_id, state, 2936 p_data->chan_cb.fd); 2937 } 2938 2939 break; 2940 2941 case BTIF_HL_REG_APP: 2942 reg_counter++; 2943 p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->reg.app_idx); 2944 BTIF_TRACE_DEBUG("Rcv BTIF_HL_REG_APP app_idx=%d reg_pending=%d", 2945 p_data->reg.app_idx, p_acb->reg_pending); 2946 if (btif_hl_get_state() == BTIF_HL_STATE_ENABLED && p_acb->reg_pending) { 2947 BTIF_TRACE_DEBUG("Rcv BTIF_HL_REG_APP reg_counter=%d", reg_counter); 2948 p_acb->reg_pending = false; 2949 reg_param.dev_type = p_acb->dev_type; 2950 reg_param.sec_mask = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT; 2951 reg_param.p_srv_name = p_acb->srv_name; 2952 reg_param.p_srv_desp = p_acb->srv_desp; 2953 reg_param.p_provider_name = p_acb->provider_name; 2954 btif_hl_proc_reg_request(p_data->reg.app_idx, p_acb->app_id, ®_param, 2955 btif_hl_cback); 2956 } else { 2957 BTIF_TRACE_DEBUG("reg request is processed state=%d reg_pending=%d", 2958 btif_hl_get_state(), p_acb->reg_pending); 2959 } 2960 break; 2961 2962 case BTIF_HL_UNREG_APP: 2963 reg_counter--; 2964 BTIF_TRACE_DEBUG("Rcv BTIF_HL_UNREG_APP app_idx=%d", 2965 p_data->unreg.app_idx); 2966 p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->unreg.app_idx); 2967 if (btif_hl_get_state() == BTIF_HL_STATE_ENABLED) { 2968 if (reg_counter >= 1) 2969 BTA_HlUpdate(p_acb->app_id, NULL, false, NULL); 2970 else 2971 BTA_HlDeregister(p_acb->app_id, p_acb->app_handle); 2972 } 2973 break; 2974 2975 case BTIF_HL_UPDATE_MDL: 2976 BTIF_TRACE_DEBUG("Rcv BTIF_HL_UPDATE_MDL app_idx=%d", 2977 p_data->update_mdl.app_idx); 2978 p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->update_mdl.app_idx); 2979 break; 2980 2981 default: 2982 BTIF_TRACE_ERROR("Unknown event %d", event); 2983 break; 2984 } 2985 } 2986 2987 /******************************************************************************* 2988 * 2989 * Function btif_hl_upstreams_evt 2990 * 2991 * Description Process HL events 2992 * 2993 * Returns void 2994 * 2995 ******************************************************************************/ 2996 static void btif_hl_upstreams_evt(uint16_t event, char* p_param) { 2997 tBTA_HL* p_data = (tBTA_HL*)p_param; 2998 uint8_t app_idx, mcl_idx; 2999 btif_hl_app_cb_t* p_acb; 3000 btif_hl_mcl_cb_t* p_mcb = NULL; 3001 btif_hl_pend_dch_op_t pending_op; 3002 bool status; 3003 3004 BTIF_TRACE_DEBUG("%s event %d", __func__, event); 3005 btif_hl_display_calling_process_name(); 3006 switch (event) { 3007 case BTA_HL_REGISTER_CFM_EVT: 3008 BTIF_TRACE_DEBUG("Rcv BTA_HL_REGISTER_CFM_EVT"); 3009 BTIF_TRACE_DEBUG("app_id=%d app_handle=%d status=%d ", 3010 p_data->reg_cfm.app_id, p_data->reg_cfm.app_handle, 3011 p_data->reg_cfm.status); 3012 3013 btif_hl_proc_reg_cfm(p_data); 3014 break; 3015 case BTA_HL_SDP_INFO_IND_EVT: 3016 BTIF_TRACE_DEBUG("Rcv BTA_HL_SDP_INFO_IND_EVT"); 3017 BTIF_TRACE_DEBUG( 3018 "app_handle=%d ctrl_psm=0x%04x data_psm=0x%04x x_spec=%d " 3019 "mcap_sup_procs=0x%02x", 3020 p_data->sdp_info_ind.app_handle, p_data->sdp_info_ind.ctrl_psm, 3021 p_data->sdp_info_ind.data_psm, p_data->sdp_info_ind.data_x_spec, 3022 p_data->sdp_info_ind.mcap_sup_procs); 3023 // btif_hl_proc_sdp_info_ind(p_data); 3024 break; 3025 3026 case BTA_HL_DEREGISTER_CFM_EVT: 3027 BTIF_TRACE_DEBUG("Rcv BTA_HL_DEREGISTER_CFM_EVT"); 3028 BTIF_TRACE_DEBUG("app_handle=%d status=%d ", p_data->dereg_cfm.app_handle, 3029 p_data->dereg_cfm.status); 3030 btif_hl_proc_dereg_cfm(p_data); 3031 break; 3032 3033 case BTA_HL_SDP_QUERY_CFM_EVT: 3034 BTIF_TRACE_DEBUG("Rcv BTA_HL_SDP_QUERY_CFM_EVT"); 3035 BTIF_TRACE_DEBUG("app_handle=%d app_id =%d,status =%d", 3036 p_data->sdp_query_cfm.app_handle, 3037 p_data->sdp_query_cfm.app_id, 3038 p_data->sdp_query_cfm.status); 3039 VLOG(0) << "DB " << p_data->sdp_query_cfm.bd_addr; 3040 3041 if (p_data->sdp_query_cfm.status == BTA_HL_STATUS_OK) 3042 status = btif_hl_proc_sdp_query_cfm(p_data); 3043 else 3044 status = false; 3045 3046 if (!status) { 3047 BTIF_TRACE_DEBUG("BTA_HL_SDP_QUERY_CFM_EVT Status = %d", 3048 p_data->sdp_query_cfm.status); 3049 if (btif_hl_find_app_idx_using_app_id(p_data->sdp_query_cfm.app_id, 3050 &app_idx)) { 3051 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 3052 if (btif_hl_find_mcl_idx(app_idx, p_data->sdp_query_cfm.bd_addr, 3053 &mcl_idx)) { 3054 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 3055 if ((p_mcb->cch_oper == BTIF_HL_CCH_OP_MDEP_FILTERING) || 3056 (p_mcb->cch_oper == BTIF_HL_CCH_OP_DCH_OPEN)) { 3057 pending_op = p_mcb->pcb.op; 3058 switch (pending_op) { 3059 case BTIF_HL_PEND_DCH_OP_OPEN: 3060 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx); 3061 break; 3062 case BTIF_HL_PEND_DCH_OP_RECONNECT: 3063 case BTIF_HL_PEND_DCH_OP_DELETE_MDL: 3064 default: 3065 break; 3066 } 3067 if (!p_mcb->is_connected) btif_hl_clean_mcl_cb(app_idx, mcl_idx); 3068 } 3069 } 3070 } 3071 } 3072 3073 break; 3074 3075 case BTA_HL_CCH_OPEN_CFM_EVT: 3076 BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_OPEN_CFM_EVT"); 3077 BTIF_TRACE_DEBUG( 3078 "app_id=%d,app_handle=%d mcl_handle=%d status =%d", 3079 p_data->cch_open_cfm.app_id, p_data->cch_open_cfm.app_handle, 3080 p_data->cch_open_cfm.mcl_handle, p_data->cch_open_cfm.status); 3081 VLOG(1) << "BD " << p_data->cch_open_cfm.bd_addr; 3082 3083 if (p_data->cch_open_cfm.status == BTA_HL_STATUS_OK || 3084 p_data->cch_open_cfm.status == BTA_HL_STATUS_DUPLICATE_CCH_OPEN) { 3085 status = btif_hl_proc_cch_open_cfm(p_data); 3086 } else { 3087 status = false; 3088 } 3089 3090 if (!status) { 3091 if (btif_hl_find_app_idx_using_app_id(p_data->cch_open_cfm.app_id, 3092 &app_idx)) { 3093 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 3094 if (btif_hl_find_mcl_idx(app_idx, p_data->cch_open_cfm.bd_addr, 3095 &mcl_idx)) { 3096 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 3097 pending_op = p_mcb->pcb.op; 3098 switch (pending_op) { 3099 case BTIF_HL_PEND_DCH_OP_OPEN: 3100 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx); 3101 break; 3102 case BTIF_HL_PEND_DCH_OP_RECONNECT: 3103 case BTIF_HL_PEND_DCH_OP_DELETE_MDL: 3104 default: 3105 break; 3106 } 3107 btif_hl_clean_mcl_cb(app_idx, mcl_idx); 3108 } 3109 } 3110 } 3111 break; 3112 3113 case BTA_HL_DCH_OPEN_CFM_EVT: 3114 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_OPEN_CFM_EVT"); 3115 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_handle=0x%x status=%d ", 3116 p_data->dch_open_cfm.mcl_handle, 3117 p_data->dch_open_cfm.mdl_handle, 3118 p_data->dch_open_cfm.status); 3119 BTIF_TRACE_DEBUG( 3120 "first_reliable =%d dch_mode=%d local_mdep_id=%d mdl_id=%d mtu=%d", 3121 p_data->dch_open_cfm.first_reliable, p_data->dch_open_cfm.dch_mode, 3122 p_data->dch_open_cfm.local_mdep_id, p_data->dch_open_cfm.mdl_id, 3123 p_data->dch_open_cfm.mtu); 3124 if (p_data->dch_open_cfm.status == BTA_HL_STATUS_OK) { 3125 status = btif_hl_proc_dch_open_cfm(p_data); 3126 } else { 3127 status = false; 3128 } 3129 3130 if (!status) { 3131 if (btif_hl_find_mcl_idx_using_handle(p_data->dch_open_cfm.mcl_handle, 3132 &app_idx, &mcl_idx)) { 3133 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 3134 pending_op = p_mcb->pcb.op; 3135 switch (pending_op) { 3136 case BTIF_HL_PEND_DCH_OP_OPEN: 3137 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx); 3138 break; 3139 case BTIF_HL_PEND_DCH_OP_RECONNECT: 3140 case BTIF_HL_PEND_DCH_OP_DELETE_MDL: 3141 default: 3142 break; 3143 } 3144 } 3145 } 3146 break; 3147 3148 case BTA_HL_CCH_OPEN_IND_EVT: 3149 BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_OPEN_IND_EVT"); 3150 BTIF_TRACE_DEBUG("app_handle=%d mcl_handle=%d", 3151 p_data->cch_open_ind.app_handle, 3152 p_data->cch_open_ind.mcl_handle); 3153 VLOG(0) << "DB " << p_data->cch_open_ind.bd_addr; 3154 3155 btif_hl_proc_cch_open_ind(p_data); 3156 break; 3157 3158 case BTA_HL_DCH_CREATE_IND_EVT: 3159 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_CREATE_IND_EVT"); 3160 BTIF_TRACE_DEBUG("mcl_handle=%d", p_data->dch_create_ind.mcl_handle); 3161 BTIF_TRACE_DEBUG("local_mdep_id =%d mdl_id=%d cfg=%d", 3162 p_data->dch_create_ind.local_mdep_id, 3163 p_data->dch_create_ind.mdl_id, 3164 p_data->dch_create_ind.cfg); 3165 btif_hl_proc_create_ind(p_data); 3166 break; 3167 3168 case BTA_HL_DCH_OPEN_IND_EVT: 3169 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_OPEN_IND_EVT"); 3170 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_handle=0x%x", 3171 p_data->dch_open_ind.mcl_handle, 3172 p_data->dch_open_ind.mdl_handle); 3173 BTIF_TRACE_DEBUG( 3174 "first_reliable =%d dch_mode=%d local_mdep_id=%d mdl_id=%d mtu=%d", 3175 p_data->dch_open_ind.first_reliable, p_data->dch_open_ind.dch_mode, 3176 p_data->dch_open_ind.local_mdep_id, p_data->dch_open_ind.mdl_id, 3177 p_data->dch_open_ind.mtu); 3178 3179 btif_hl_proc_dch_open_ind(p_data); 3180 break; 3181 3182 case BTA_HL_DELETE_MDL_IND_EVT: 3183 BTIF_TRACE_DEBUG("Rcv BTA_HL_DELETE_MDL_IND_EVT"); 3184 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_id=0x%x", 3185 p_data->delete_mdl_ind.mcl_handle, 3186 p_data->delete_mdl_ind.mdl_id); 3187 break; 3188 3189 case BTA_HL_DELETE_MDL_CFM_EVT: 3190 BTIF_TRACE_DEBUG("Rcv BTA_HL_DELETE_MDL_CFM_EVT"); 3191 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_id=0x%x status=%d", 3192 p_data->delete_mdl_cfm.mcl_handle, 3193 p_data->delete_mdl_cfm.mdl_id, 3194 p_data->delete_mdl_cfm.status); 3195 3196 if (btif_hl_find_app_idx_using_deleted_mdl_id( 3197 p_data->delete_mdl_cfm.mdl_id, &app_idx)) { 3198 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 3199 btif_hl_send_destroyed_cb(p_acb); 3200 btif_hl_clean_delete_mdl(&p_acb->delete_mdl); 3201 } 3202 break; 3203 3204 case BTA_HL_DCH_RECONNECT_CFM_EVT: 3205 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_RECONNECT_CFM_EVT"); 3206 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_handle=%d status=%d ", 3207 p_data->dch_reconnect_cfm.mcl_handle, 3208 p_data->dch_reconnect_cfm.mdl_handle, 3209 p_data->dch_reconnect_cfm.status); 3210 BTIF_TRACE_DEBUG("first_reliable =%d dch_mode=%d mdl_id=%d mtu=%d", 3211 p_data->dch_reconnect_cfm.first_reliable, 3212 p_data->dch_reconnect_cfm.dch_mode, 3213 p_data->dch_reconnect_cfm.mdl_id, 3214 p_data->dch_reconnect_cfm.mtu); 3215 3216 if (p_data->dch_reconnect_cfm.status == BTA_HL_STATUS_OK) { 3217 status = btif_hl_proc_dch_reconnect_cfm(p_data); 3218 } else { 3219 status = false; 3220 } 3221 3222 if (!status) { 3223 if (btif_hl_find_mcl_idx_using_handle(p_data->dch_open_cfm.mcl_handle, 3224 &app_idx, &mcl_idx)) { 3225 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 3226 pending_op = p_mcb->pcb.op; 3227 switch (pending_op) { 3228 case BTIF_HL_PEND_DCH_OP_OPEN: 3229 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx); 3230 break; 3231 case BTIF_HL_PEND_DCH_OP_RECONNECT: 3232 case BTIF_HL_PEND_DCH_OP_DELETE_MDL: 3233 default: 3234 break; 3235 } 3236 } 3237 } 3238 3239 break; 3240 3241 case BTA_HL_CCH_CLOSE_CFM_EVT: 3242 BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_CLOSE_CFM_EVT"); 3243 BTIF_TRACE_DEBUG("mcl_handle=%d status =%d", 3244 p_data->cch_close_cfm.mcl_handle, 3245 p_data->cch_close_cfm.status); 3246 if (p_data->cch_close_cfm.status == BTA_HL_STATUS_OK) { 3247 btif_hl_proc_cch_close_cfm(p_data); 3248 } 3249 break; 3250 3251 case BTA_HL_CCH_CLOSE_IND_EVT: 3252 BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_CLOSE_IND_EVT"); 3253 BTIF_TRACE_DEBUG("mcl_handle =%d intentional_close=%s", 3254 p_data->cch_close_ind.mcl_handle, 3255 (p_data->cch_close_ind.intentional ? "Yes" : "No")); 3256 3257 btif_hl_proc_cch_close_ind(p_data); 3258 break; 3259 3260 case BTA_HL_DCH_CLOSE_IND_EVT: 3261 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_CLOSE_IND_EVT"); 3262 BTIF_TRACE_DEBUG("mdl_handle=%d intentional_close=%s", 3263 p_data->dch_close_ind.mdl_handle, 3264 (p_data->dch_close_ind.intentional ? "Yes" : "No")); 3265 3266 btif_hl_proc_dch_close_ind(p_data); 3267 break; 3268 3269 case BTA_HL_DCH_CLOSE_CFM_EVT: 3270 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_CLOSE_CFM_EVT"); 3271 BTIF_TRACE_DEBUG("mdl_handle=%d status=%d ", 3272 p_data->dch_close_cfm.mdl_handle, 3273 p_data->dch_close_cfm.status); 3274 3275 if (p_data->dch_close_cfm.status == BTA_HL_STATUS_OK) { 3276 btif_hl_proc_dch_close_cfm(p_data); 3277 } 3278 break; 3279 3280 case BTA_HL_DCH_ECHO_TEST_CFM_EVT: 3281 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_ECHO_TEST_CFM_EVT"); 3282 BTIF_TRACE_DEBUG("mcl_handle=%d status=%d", 3283 p_data->echo_test_cfm.mcl_handle, 3284 p_data->echo_test_cfm.status); 3285 /* not supported */ 3286 break; 3287 3288 case BTA_HL_DCH_RECONNECT_IND_EVT: 3289 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_RECONNECT_IND_EVT"); 3290 3291 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_handle=5d", 3292 p_data->dch_reconnect_ind.mcl_handle, 3293 p_data->dch_reconnect_ind.mdl_handle); 3294 BTIF_TRACE_DEBUG("first_reliable =%d dch_mode=%d mdl_id=%d mtu=%d", 3295 p_data->dch_reconnect_ind.first_reliable, 3296 p_data->dch_reconnect_ind.dch_mode, 3297 p_data->dch_reconnect_ind.mdl_id, 3298 p_data->dch_reconnect_ind.mtu); 3299 3300 btif_hl_proc_dch_reconnect_ind(p_data); 3301 break; 3302 3303 case BTA_HL_CONG_CHG_IND_EVT: 3304 BTIF_TRACE_DEBUG("Rcv BTA_HL_CONG_CHG_IND_EVT"); 3305 BTIF_TRACE_DEBUG("mdl_handle=%d cong =%d", 3306 p_data->dch_cong_ind.mdl_handle, 3307 p_data->dch_cong_ind.cong); 3308 btif_hl_proc_dch_cong_ind(p_data); 3309 break; 3310 3311 case BTA_HL_DCH_ABORT_IND_EVT: 3312 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_ABORT_IND_EVT"); 3313 BTIF_TRACE_DEBUG("mcl_handle=%d", p_data->dch_abort_ind.mcl_handle); 3314 btif_hl_proc_abort_ind(p_data->dch_abort_ind.mcl_handle); 3315 break; 3316 case BTA_HL_DCH_ABORT_CFM_EVT: 3317 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_ABORT_CFM_EVT"); 3318 BTIF_TRACE_DEBUG("mcl_handle=%d status =%d", 3319 p_data->dch_abort_cfm.mcl_handle, 3320 p_data->dch_abort_cfm.status); 3321 if (p_data->dch_abort_cfm.status == BTA_HL_STATUS_OK) { 3322 btif_hl_proc_abort_cfm(p_data->dch_abort_ind.mcl_handle); 3323 } 3324 break; 3325 3326 case BTA_HL_DCH_SEND_DATA_CFM_EVT: 3327 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_SEND_DATA_CFM_EVT"); 3328 BTIF_TRACE_DEBUG("mdl_handle=0x%x status =%d", 3329 p_data->dch_send_data_cfm.mdl_handle, 3330 p_data->dch_send_data_cfm.status); 3331 btif_hl_proc_send_data_cfm(p_data->dch_send_data_cfm.mdl_handle, 3332 p_data->dch_send_data_cfm.status); 3333 break; 3334 3335 case BTA_HL_DCH_RCV_DATA_IND_EVT: 3336 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_RCV_DATA_IND_EVT"); 3337 BTIF_TRACE_DEBUG("mdl_handle=0x%x ", p_data->dch_rcv_data_ind.mdl_handle); 3338 /* do nothing here */ 3339 break; 3340 3341 default: 3342 BTIF_TRACE_DEBUG("Unknown Event (0x%02x)...", event); 3343 break; 3344 } 3345 } 3346 3347 /******************************************************************************* 3348 * 3349 * Function btif_hl_cback 3350 * 3351 * Description Callback function for HL events 3352 * 3353 * Returns void 3354 * 3355 ******************************************************************************/ 3356 static void btif_hl_cback(tBTA_HL_EVT event, tBTA_HL* p_data) { 3357 bt_status_t status; 3358 int param_len = 0; 3359 BTIF_TRACE_DEBUG("%s event %d", __func__, event); 3360 btif_hl_display_calling_process_name(); 3361 switch (event) { 3362 case BTA_HL_REGISTER_CFM_EVT: 3363 param_len = sizeof(tBTA_HL_REGISTER_CFM); 3364 break; 3365 case BTA_HL_SDP_INFO_IND_EVT: 3366 param_len = sizeof(tBTA_HL_SDP_INFO_IND); 3367 break; 3368 case BTA_HL_DEREGISTER_CFM_EVT: 3369 param_len = sizeof(tBTA_HL_DEREGISTER_CFM); 3370 break; 3371 case BTA_HL_SDP_QUERY_CFM_EVT: 3372 param_len = sizeof(tBTA_HL_SDP_QUERY_CFM); 3373 break; 3374 case BTA_HL_CCH_OPEN_CFM_EVT: 3375 param_len = sizeof(tBTA_HL_CCH_OPEN_CFM); 3376 break; 3377 case BTA_HL_DCH_OPEN_CFM_EVT: 3378 param_len = sizeof(tBTA_HL_DCH_OPEN_CFM); 3379 break; 3380 case BTA_HL_CCH_OPEN_IND_EVT: 3381 param_len = sizeof(tBTA_HL_CCH_OPEN_IND); 3382 break; 3383 case BTA_HL_DCH_CREATE_IND_EVT: 3384 param_len = sizeof(tBTA_HL_DCH_CREATE_IND); 3385 break; 3386 case BTA_HL_DCH_OPEN_IND_EVT: 3387 param_len = sizeof(tBTA_HL_DCH_OPEN_IND); 3388 break; 3389 case BTA_HL_DELETE_MDL_IND_EVT: 3390 param_len = sizeof(tBTA_HL_MDL_IND); 3391 break; 3392 case BTA_HL_DELETE_MDL_CFM_EVT: 3393 param_len = sizeof(tBTA_HL_MDL_CFM); 3394 break; 3395 case BTA_HL_DCH_RECONNECT_CFM_EVT: 3396 param_len = sizeof(tBTA_HL_DCH_OPEN_CFM); 3397 break; 3398 case BTA_HL_CCH_CLOSE_CFM_EVT: 3399 param_len = sizeof(tBTA_HL_MCL_CFM); 3400 break; 3401 case BTA_HL_CCH_CLOSE_IND_EVT: 3402 param_len = sizeof(tBTA_HL_CCH_CLOSE_IND); 3403 break; 3404 case BTA_HL_DCH_CLOSE_IND_EVT: 3405 param_len = sizeof(tBTA_HL_DCH_CLOSE_IND); 3406 break; 3407 case BTA_HL_DCH_CLOSE_CFM_EVT: 3408 param_len = sizeof(tBTA_HL_MDL_CFM); 3409 break; 3410 case BTA_HL_DCH_ECHO_TEST_CFM_EVT: 3411 param_len = sizeof(tBTA_HL_MCL_CFM); 3412 break; 3413 case BTA_HL_DCH_RECONNECT_IND_EVT: 3414 param_len = sizeof(tBTA_HL_DCH_OPEN_IND); 3415 break; 3416 case BTA_HL_CONG_CHG_IND_EVT: 3417 param_len = sizeof(tBTA_HL_DCH_CONG_IND); 3418 break; 3419 case BTA_HL_DCH_ABORT_IND_EVT: 3420 param_len = sizeof(tBTA_HL_MCL_IND); 3421 break; 3422 case BTA_HL_DCH_ABORT_CFM_EVT: 3423 param_len = sizeof(tBTA_HL_MCL_CFM); 3424 break; 3425 case BTA_HL_DCH_SEND_DATA_CFM_EVT: 3426 param_len = sizeof(tBTA_HL_MDL_CFM); 3427 break; 3428 case BTA_HL_DCH_RCV_DATA_IND_EVT: 3429 param_len = sizeof(tBTA_HL_MDL_IND); 3430 break; 3431 default: 3432 param_len = sizeof(tBTA_HL_MDL_IND); 3433 break; 3434 } 3435 status = btif_transfer_context(btif_hl_upstreams_evt, (uint16_t)event, 3436 (char*)p_data, param_len, NULL); 3437 3438 /* catch any failed context transfers */ 3439 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 3440 } 3441 3442 /******************************************************************************* 3443 * 3444 * Function btif_hl_upstreams_ctrl_evt 3445 * 3446 * Description Callback function for HL control events in the BTIF task 3447 * context 3448 * 3449 * Returns void 3450 * 3451 ******************************************************************************/ 3452 static void btif_hl_upstreams_ctrl_evt(uint16_t event, char* p_param) { 3453 tBTA_HL_CTRL* p_data = (tBTA_HL_CTRL*)p_param; 3454 uint8_t i; 3455 tBTA_HL_REG_PARAM reg_param; 3456 btif_hl_app_cb_t* p_acb; 3457 3458 BTIF_TRACE_DEBUG("%s event %d", __func__, event); 3459 btif_hl_display_calling_process_name(); 3460 3461 switch (event) { 3462 case BTA_HL_CTRL_ENABLE_CFM_EVT: 3463 BTIF_TRACE_DEBUG("Rcv BTA_HL_CTRL_ENABLE_CFM_EVT"); 3464 BTIF_TRACE_DEBUG("status=%d", p_data->enable_cfm.status); 3465 3466 if (p_data->enable_cfm.status == BTA_HL_STATUS_OK) { 3467 btif_hl_set_state(BTIF_HL_STATE_ENABLED); 3468 3469 for (i = 0; i < BTA_HL_NUM_APPS; i++) { 3470 p_acb = BTIF_HL_GET_APP_CB_PTR(i); 3471 if (p_acb->in_use && p_acb->reg_pending) { 3472 p_acb->reg_pending = false; 3473 reg_param.dev_type = p_acb->dev_type; 3474 reg_param.sec_mask = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT; 3475 reg_param.p_srv_name = p_acb->srv_name; 3476 reg_param.p_srv_desp = p_acb->srv_desp; 3477 reg_param.p_provider_name = p_acb->provider_name; 3478 3479 BTIF_TRACE_DEBUG("Register pending app_id=%d", p_acb->app_id); 3480 btif_hl_proc_reg_request(i, p_acb->app_id, ®_param, 3481 btif_hl_cback); 3482 } 3483 } 3484 } 3485 3486 break; 3487 case BTA_HL_CTRL_DISABLE_CFM_EVT: 3488 BTIF_TRACE_DEBUG("Rcv BTA_HL_CTRL_DISABLE_CFM_EVT"); 3489 BTIF_TRACE_DEBUG("status=%d", p_data->disable_cfm.status); 3490 3491 if (p_data->disable_cfm.status == BTA_HL_STATUS_OK) { 3492 for (size_t i = 0; i < BTA_HL_NUM_APPS; i++) { 3493 for (size_t j = 0; j < BTA_HL_NUM_MCLS; j++) { 3494 alarm_free(p_btif_hl_cb->acb[i].mcb[j].cch_timer); 3495 } 3496 } 3497 memset(p_btif_hl_cb, 0, sizeof(btif_hl_cb_t)); 3498 btif_hl_set_state(BTIF_HL_STATE_DISABLED); 3499 } 3500 3501 break; 3502 default: 3503 break; 3504 } 3505 } 3506 3507 /******************************************************************************* 3508 * 3509 * Function btif_hl_ctrl_cback 3510 * 3511 * Description Callback function for HL control events 3512 * 3513 * Returns void 3514 * 3515 ******************************************************************************/ 3516 static void btif_hl_ctrl_cback(tBTA_HL_CTRL_EVT event, tBTA_HL_CTRL* p_data) { 3517 bt_status_t status; 3518 int param_len = 0; 3519 3520 BTIF_TRACE_DEBUG("%s event %d", __func__, event); 3521 btif_hl_display_calling_process_name(); 3522 3523 switch (event) { 3524 case BTA_HL_CTRL_ENABLE_CFM_EVT: 3525 case BTA_HL_CTRL_DISABLE_CFM_EVT: 3526 param_len = sizeof(tBTA_HL_CTRL_ENABLE_DISABLE); 3527 break; 3528 default: 3529 break; 3530 } 3531 3532 status = btif_transfer_context(btif_hl_upstreams_ctrl_evt, (uint16_t)event, 3533 (char*)p_data, param_len, NULL); 3534 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 3535 } 3536 /******************************************************************************* 3537 * 3538 * Function connect_channel 3539 * 3540 * Description connect a data channel 3541 * 3542 * Returns bt_status_t 3543 * 3544 ******************************************************************************/ 3545 static bt_status_t connect_channel(int app_id, RawAddress* bd_addr, 3546 int mdep_cfg_index, int* channel_id) { 3547 uint8_t app_idx, mcl_idx; 3548 btif_hl_app_cb_t* p_acb = NULL; 3549 btif_hl_pending_chan_cb_t* p_pcb = NULL; 3550 btif_hl_mcl_cb_t* p_mcb = NULL; 3551 bt_status_t status = BT_STATUS_SUCCESS; 3552 tBTA_HL_DCH_OPEN_PARAM dch_open; 3553 3554 CHECK_BTHL_INIT(); 3555 BTIF_TRACE_EVENT("%s", __func__); 3556 btif_hl_display_calling_process_name(); 3557 3558 if (btif_hl_find_app_idx(((uint8_t)app_id), &app_idx)) { 3559 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 3560 if (btif_hl_find_mcl_idx(app_idx, *bd_addr, &mcl_idx)) { 3561 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 3562 if (p_mcb->is_connected) { 3563 dch_open.ctrl_psm = p_mcb->ctrl_psm; 3564 dch_open.local_mdep_id = 3565 p_acb->sup_feature.mdep[mdep_cfg_index].mdep_id; 3566 BTIF_TRACE_DEBUG( 3567 "connect_channel: app_idx =%d, mdep_cfg_indx =%d, mdep_id =%d " 3568 "app_id= %d", 3569 app_idx, mdep_cfg_index, dch_open.local_mdep_id, app_id); 3570 if (btif_hl_find_peer_mdep_id( 3571 p_acb->app_id, p_mcb->bd_addr, 3572 p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role, 3573 p_acb->sup_feature.mdep[mdep_cfg_index] 3574 .mdep_cfg.data_cfg[0] 3575 .data_type, 3576 &dch_open.peer_mdep_id)) { 3577 dch_open.local_cfg = p_acb->channel_type[mdep_cfg_index]; 3578 if ((p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role == 3579 BTA_HL_MDEP_ROLE_SOURCE) && 3580 !btif_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) { 3581 dch_open.local_cfg = BTA_HL_DCH_CFG_RELIABLE; 3582 } 3583 dch_open.sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); 3584 3585 if (!btif_hl_dch_open(p_acb->app_id, *bd_addr, &dch_open, 3586 mdep_cfg_index, BTIF_HL_PEND_DCH_OP_OPEN, 3587 channel_id)) { 3588 status = BT_STATUS_FAIL; 3589 BTIF_TRACE_EVENT("%s loc0 status = BT_STATUS_FAIL", __func__); 3590 } 3591 } else { 3592 p_mcb->cch_oper = BTIF_HL_CCH_OP_MDEP_FILTERING; 3593 3594 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx); 3595 p_pcb->in_use = true; 3596 p_pcb->mdep_cfg_idx = mdep_cfg_index; 3597 p_pcb->bd_addr = *bd_addr; 3598 p_pcb->op = BTIF_HL_PEND_DCH_OP_OPEN; 3599 BTA_HlSdpQuery(app_id, p_acb->app_handle, *bd_addr); 3600 } 3601 } else { 3602 status = BT_STATUS_FAIL; 3603 } 3604 } else { 3605 p_acb->filter.num_elems = 1; 3606 p_acb->filter.elem[0].data_type = p_acb->sup_feature.mdep[mdep_cfg_index] 3607 .mdep_cfg.data_cfg[mdep_cfg_index] 3608 .data_type; 3609 if (p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role == 3610 BTA_HL_MDEP_ROLE_SINK) 3611 p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE; 3612 else 3613 p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SINK; 3614 3615 if (!btif_hl_cch_open(p_acb->app_id, *bd_addr, 0, mdep_cfg_index, 3616 BTIF_HL_PEND_DCH_OP_OPEN, channel_id)) { 3617 status = BT_STATUS_FAIL; 3618 } 3619 } 3620 } else { 3621 status = BT_STATUS_FAIL; 3622 } 3623 3624 BTIF_TRACE_DEBUG("%s status=%d channel_id=0x%08x", __func__, status, 3625 *channel_id); 3626 3627 return status; 3628 } 3629 /******************************************************************************* 3630 * 3631 * Function destroy_channel 3632 * 3633 * Description destroy a data channel 3634 * 3635 * Returns bt_status_t 3636 * 3637 ******************************************************************************/ 3638 static bt_status_t destroy_channel(int channel_id) { 3639 uint8_t app_idx, mcl_idx, mdl_cfg_idx, mdep_cfg_idx = 0; 3640 bt_status_t status = BT_STATUS_SUCCESS; 3641 btif_hl_mdl_cfg_t* p_mdl; 3642 btif_hl_mcl_cb_t* p_mcb; 3643 btif_hl_app_cb_t* p_acb; 3644 3645 CHECK_BTHL_INIT(); 3646 BTIF_TRACE_EVENT("%s channel_id=0x%08x", __func__, channel_id); 3647 btif_hl_display_calling_process_name(); 3648 3649 if (btif_hl_if_channel_setup_pending(channel_id, &app_idx, &mcl_idx)) { 3650 btif_hl_dch_abort(app_idx, mcl_idx); 3651 } else { 3652 if (btif_hl_find_mdl_cfg_idx_using_channel_id(channel_id, &app_idx, 3653 &mdl_cfg_idx)) 3654 // if(btif_hl_find_mdl_idx_using_channel_id(channel_id, 3655 // &app_idx,&mcl_idx, &mdl_idx)) 3656 { 3657 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 3658 if (!p_acb->delete_mdl.active) { 3659 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, mdl_cfg_idx); 3660 p_acb->delete_mdl.active = true; 3661 p_acb->delete_mdl.mdl_id = p_mdl->base.mdl_id; 3662 p_acb->delete_mdl.channel_id = channel_id; 3663 p_acb->delete_mdl.mdep_cfg_idx = p_mdl->extra.mdep_cfg_idx; 3664 p_acb->delete_mdl.bd_addr = p_mdl->base.peer_bd_addr; 3665 3666 if (btif_hl_find_mcl_idx(app_idx, p_mdl->base.peer_bd_addr, &mcl_idx)) { 3667 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 3668 if (p_mcb->is_connected) { 3669 BTIF_TRACE_DEBUG("calling BTA_HlDeleteMdl mdl_id=%d", 3670 p_acb->delete_mdl.mdl_id); 3671 BTA_HlDeleteMdl(p_mcb->mcl_handle, p_acb->delete_mdl.mdl_id); 3672 } else { 3673 status = BT_STATUS_FAIL; 3674 } 3675 } else { 3676 BTIF_TRACE_DEBUG("btif_hl_delete_mdl calling btif_hl_cch_open"); 3677 mdep_cfg_idx = p_mdl->extra.mdep_cfg_idx; 3678 p_acb->filter.num_elems = 1; 3679 p_acb->filter.elem[0].data_type = 3680 p_acb->sup_feature.mdep[mdep_cfg_idx] 3681 .mdep_cfg.data_cfg[mdep_cfg_idx] 3682 .data_type; 3683 if (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role == 3684 BTA_HL_MDEP_ROLE_SINK) 3685 p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE; 3686 else 3687 p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SINK; 3688 if (btif_hl_cch_open(p_acb->app_id, p_acb->delete_mdl.bd_addr, 0, 3689 mdep_cfg_idx, BTIF_HL_PEND_DCH_OP_DELETE_MDL, 3690 NULL)) { 3691 status = BT_STATUS_FAIL; 3692 } 3693 } 3694 3695 if (status == BT_STATUS_FAIL) { 3696 /* fail for now */ 3697 btif_hl_clean_delete_mdl(&p_acb->delete_mdl); 3698 } 3699 } else { 3700 status = BT_STATUS_BUSY; 3701 } 3702 } else { 3703 status = BT_STATUS_FAIL; 3704 } 3705 } 3706 return status; 3707 } 3708 /******************************************************************************* 3709 * 3710 * Function unregister_application 3711 * 3712 * Description unregister an HDP application 3713 * 3714 * Returns bt_status_t 3715 * 3716 ******************************************************************************/ 3717 static bt_status_t unregister_application(int app_id) { 3718 uint8_t app_idx; 3719 int len; 3720 bt_status_t status = BT_STATUS_SUCCESS; 3721 btif_hl_evt_cb_t evt_param; 3722 3723 CHECK_BTHL_INIT(); 3724 BTIF_TRACE_EVENT("%s app_id=%d", __func__, app_id); 3725 btif_hl_display_calling_process_name(); 3726 3727 if (btif_hl_find_app_idx(((uint8_t)app_id), &app_idx)) { 3728 evt_param.unreg.app_idx = app_idx; 3729 reg_counter--; 3730 len = sizeof(btif_hl_unreg_t); 3731 status = btif_transfer_context(btif_hl_proc_cb_evt, BTIF_HL_UNREG_APP, 3732 (char*)&evt_param, len, NULL); 3733 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 3734 } else { 3735 status = BT_STATUS_FAIL; 3736 } 3737 3738 BTIF_TRACE_DEBUG("de-reg return status=%d", status); 3739 return status; 3740 } 3741 /******************************************************************************* 3742 * 3743 * Function register_application 3744 * 3745 * Description register an HDP application 3746 * 3747 * Returns bt_status_t 3748 * 3749 ******************************************************************************/ 3750 static bt_status_t register_application(bthl_reg_param_t* p_reg_param, 3751 int* app_id) { 3752 btif_hl_app_cb_t* p_acb; 3753 tBTA_HL_SUP_FEATURE* p_sup; 3754 tBTA_HL_MDEP_CFG* p_cfg; 3755 tBTA_HL_MDEP_DATA_TYPE_CFG* p_data; 3756 uint8_t app_idx = 0, i = 0; 3757 bthl_mdep_cfg_t* p_mdep_cfg; 3758 bt_status_t status = BT_STATUS_SUCCESS; 3759 btif_hl_evt_cb_t evt_param; 3760 int len; 3761 3762 CHECK_BTHL_INIT(); 3763 BTIF_TRACE_EVENT("%s", __func__); 3764 btif_hl_display_calling_process_name(); 3765 3766 if (btif_hl_get_state() == BTIF_HL_STATE_DISABLED) { 3767 btif_hl_init(); 3768 btif_hl_set_state(BTIF_HL_STATE_ENABLING); 3769 BTA_HlEnable(btif_hl_ctrl_cback); 3770 } 3771 3772 if (!btif_hl_find_avail_app_idx(&app_idx)) { 3773 BTIF_TRACE_ERROR("Unable to allocate a new application control block"); 3774 return BT_STATUS_FAIL; 3775 } 3776 3777 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 3778 p_acb->in_use = true; 3779 3780 p_acb->app_id = btif_hl_get_next_app_id(); 3781 3782 if (p_reg_param->application_name != NULL) 3783 strncpy(p_acb->application_name, p_reg_param->application_name, 3784 BTIF_HL_APPLICATION_NAME_LEN); 3785 3786 if (p_reg_param->provider_name != NULL) 3787 strncpy(p_acb->provider_name, p_reg_param->provider_name, 3788 BTA_PROVIDER_NAME_LEN); 3789 3790 if (p_reg_param->srv_name != NULL) 3791 strncpy(p_acb->srv_name, p_reg_param->srv_name, BTA_SERVICE_NAME_LEN); 3792 3793 if (p_reg_param->srv_desp != NULL) 3794 strncpy(p_acb->srv_desp, p_reg_param->srv_desp, BTA_SERVICE_DESP_LEN); 3795 3796 p_sup = &p_acb->sup_feature; 3797 p_sup->advertize_source_sdp = true; 3798 p_sup->echo_cfg.max_rx_apdu_size = BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE; 3799 p_sup->echo_cfg.max_tx_apdu_size = BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE; 3800 p_sup->num_of_mdeps = p_reg_param->number_of_mdeps; 3801 3802 for (i = 0, p_mdep_cfg = p_reg_param->mdep_cfg; i < p_sup->num_of_mdeps; 3803 i++, p_mdep_cfg++) { 3804 p_cfg = &p_sup->mdep[i].mdep_cfg; 3805 p_cfg->num_of_mdep_data_types = 1; 3806 p_data = &p_cfg->data_cfg[0]; 3807 3808 if (!btif_hl_get_bta_mdep_role(p_mdep_cfg->mdep_role, 3809 &(p_cfg->mdep_role))) { 3810 BTIF_TRACE_ERROR("Invalid mdep_role=%d", p_mdep_cfg->mdep_role); 3811 status = BT_STATUS_FAIL; 3812 break; 3813 } else { 3814 if (p_cfg->mdep_role == BTA_HL_MDEP_ROLE_SINK) 3815 p_sup->app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK; 3816 else 3817 p_sup->app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE; 3818 3819 if ((p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SINK) && 3820 (p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SOURCE)) { 3821 p_acb->dev_type = BTA_HL_DEVICE_TYPE_DUAL; 3822 } else if (p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SINK) { 3823 p_acb->dev_type = BTA_HL_DEVICE_TYPE_SINK; 3824 } else { 3825 p_acb->dev_type = BTA_HL_DEVICE_TYPE_SOURCE; 3826 } 3827 3828 p_data->data_type = (uint16_t)p_mdep_cfg->data_type; 3829 p_data->max_rx_apdu_size = 3830 btif_hl_get_max_rx_apdu_size(p_cfg->mdep_role, p_data->data_type); 3831 p_data->max_tx_apdu_size = 3832 btif_hl_get_max_tx_apdu_size(p_cfg->mdep_role, p_data->data_type); 3833 3834 if (p_mdep_cfg->mdep_description != NULL) 3835 strncpy(p_data->desp, p_mdep_cfg->mdep_description, 3836 BTA_SERVICE_DESP_LEN); 3837 3838 if (!btif_hl_get_bta_channel_type(p_mdep_cfg->channel_type, 3839 &(p_acb->channel_type[i]))) { 3840 BTIF_TRACE_ERROR("Invalid channel_type=%d", p_mdep_cfg->channel_type); 3841 status = BT_STATUS_FAIL; 3842 break; 3843 } 3844 } 3845 } 3846 3847 if (status == BT_STATUS_SUCCESS) { 3848 *app_id = (int)p_acb->app_id; 3849 evt_param.reg.app_idx = app_idx; 3850 len = sizeof(btif_hl_reg_t); 3851 p_acb->reg_pending = true; 3852 BTIF_TRACE_DEBUG("calling btif_transfer_context status=%d app_id=%d", 3853 status, *app_id); 3854 status = btif_transfer_context(btif_hl_proc_cb_evt, BTIF_HL_REG_APP, 3855 (char*)&evt_param, len, NULL); 3856 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 3857 3858 } else { 3859 btif_hl_free_app_idx(app_idx); 3860 } 3861 3862 BTIF_TRACE_DEBUG("register_application status=%d app_id=%d", status, *app_id); 3863 return status; 3864 } 3865 3866 /******************************************************************************* 3867 * 3868 * Function btif_hl_save_mdl_cfg 3869 * 3870 * Description Save the MDL configuration 3871 * 3872 * Returns bool 3873 * 3874 ******************************************************************************/ 3875 bool btif_hl_save_mdl_cfg(uint8_t mdep_id, uint8_t item_idx, 3876 tBTA_HL_MDL_CFG* p_mdl_cfg) { 3877 btif_hl_mdl_cfg_t* p_mdl = NULL; 3878 bool success = false; 3879 btif_hl_app_cb_t* p_acb; 3880 btif_hl_mcl_cb_t* p_mcb; 3881 uint8_t app_idx, mcl_idx, len; 3882 bt_status_t bt_status; 3883 btif_hl_evt_cb_t evt_param; 3884 int* p_channel_id; 3885 3886 BTIF_TRACE_DEBUG( 3887 "%s mdep_id=%d item_idx=%d, local_mdep_id=%d mdl_id=0x%x dch_mode=%d", 3888 __func__, mdep_id, item_idx, p_mdl_cfg->local_mdep_id, p_mdl_cfg->mdl_id, 3889 p_mdl_cfg->dch_mode); 3890 3891 if (btif_hl_find_app_idx_using_mdepId(mdep_id, &app_idx)) { 3892 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 3893 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, item_idx); 3894 p_channel_id = BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(app_idx, item_idx); 3895 if (p_mdl) { 3896 memcpy(&p_mdl->base, p_mdl_cfg, sizeof(tBTA_HL_MDL_CFG)); 3897 if (btif_hl_find_mcl_idx(app_idx, p_mdl->base.peer_bd_addr, &mcl_idx)) { 3898 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 3899 if (p_mcb->pcb.in_use) 3900 *p_channel_id = p_mcb->pcb.channel_id; 3901 else 3902 *p_channel_id = btif_hl_get_next_channel_id(p_acb->app_id); 3903 p_mdl->extra.mdep_cfg_idx = p_mcb->pcb.mdep_cfg_idx; 3904 p_mdl->extra.data_type = 3905 p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx] 3906 .mdep_cfg.data_cfg[0] 3907 .data_type; 3908 3909 if (!btif_hl_find_peer_mdep_id( 3910 p_acb->app_id, p_mcb->bd_addr, 3911 p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx] 3912 .mdep_cfg.mdep_role, 3913 p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx] 3914 .mdep_cfg.data_cfg[0] 3915 .data_type, 3916 &p_mdl->extra.peer_mdep_id)) { 3917 p_mdl->extra.peer_mdep_id = BTA_HL_INVALID_MDEP_ID; 3918 } 3919 BTIF_TRACE_DEBUG("%s app_idx=%d item_idx=%d mld_id=0x%x", __func__, 3920 app_idx, item_idx, p_mdl->base.mdl_id); 3921 evt_param.update_mdl.app_idx = app_idx; 3922 len = sizeof(btif_hl_update_mdl_t); 3923 BTIF_TRACE_DEBUG("send BTIF_HL_UPDATE_MDL event app_idx=%d ", app_idx); 3924 bt_status = 3925 btif_transfer_context(btif_hl_proc_cb_evt, BTIF_HL_UPDATE_MDL, 3926 (char*)&evt_param, len, NULL); 3927 if (bt_status == BT_STATUS_SUCCESS) { 3928 success = true; 3929 } 3930 ASSERTC(bt_status == BT_STATUS_SUCCESS, "context transfer failed", 3931 bt_status); 3932 } 3933 } 3934 } 3935 BTIF_TRACE_DEBUG("%s success=%d ", __func__, success); 3936 3937 return success; 3938 } 3939 3940 /******************************************************************************* 3941 * 3942 * Function btif_hl_delete_mdl_cfg 3943 * 3944 * Description Delete the MDL configuration 3945 * 3946 * Returns bool 3947 * 3948 ******************************************************************************/ 3949 bool btif_hl_delete_mdl_cfg(uint8_t mdep_id, uint8_t item_idx) { 3950 btif_hl_mdl_cfg_t* p_mdl = NULL; 3951 bool success = false; 3952 uint8_t app_idx, len; 3953 bt_status_t bt_status; 3954 btif_hl_evt_cb_t evt_param; 3955 3956 if (btif_hl_find_app_idx_using_mdepId(mdep_id, &app_idx)) { 3957 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, item_idx); 3958 if (p_mdl) { 3959 memset(p_mdl, 0, sizeof(btif_hl_mdl_cfg_t)); 3960 evt_param.update_mdl.app_idx = app_idx; 3961 len = sizeof(btif_hl_update_mdl_t); 3962 BTIF_TRACE_DEBUG("send BTIF_HL_UPDATE_MDL event app_idx=%d ", app_idx); 3963 bt_status = btif_transfer_context(btif_hl_proc_cb_evt, BTIF_HL_UPDATE_MDL, 3964 (char*)&evt_param, len, NULL); 3965 if (bt_status == BT_STATUS_SUCCESS) { 3966 success = true; 3967 } 3968 ASSERTC(bt_status == BT_STATUS_SUCCESS, "context transfer failed", 3969 bt_status); 3970 } 3971 } 3972 3973 BTIF_TRACE_DEBUG("%s success=%d ", __func__, success); 3974 return success; 3975 } 3976 3977 /******************************************************************************* 3978 * 3979 * Function init 3980 * 3981 * Description initializes the hl interface 3982 * 3983 * Returns bt_status_t 3984 * 3985 ******************************************************************************/ 3986 static bt_status_t init(bthl_callbacks_t* callbacks) { 3987 bt_status_t status = BT_STATUS_SUCCESS; 3988 3989 BTIF_TRACE_EVENT("%s", __func__); 3990 btif_hl_display_calling_process_name(); 3991 bt_hl_callbacks_cb = *callbacks; 3992 bt_hl_callbacks = &bt_hl_callbacks_cb; 3993 btif_hl_soc_thread_init(); 3994 reg_counter = 0; 3995 return status; 3996 } 3997 /******************************************************************************* 3998 * 3999 * Function cleanup 4000 * 4001 * Description Closes the HL interface 4002 * 4003 * Returns void 4004 * 4005 ******************************************************************************/ 4006 static void cleanup(void) { 4007 BTIF_TRACE_EVENT("%s", __func__); 4008 btif_hl_display_calling_process_name(); 4009 if (bt_hl_callbacks) { 4010 btif_disable_service(BTA_HDP_SERVICE_ID); 4011 bt_hl_callbacks = NULL; 4012 reg_counter = 0; 4013 } 4014 4015 btif_hl_disable(); 4016 btif_hl_close_select_thread(); 4017 } 4018 4019 static const bthl_interface_t bthlInterface = { 4020 sizeof(bthl_interface_t), 4021 init, 4022 register_application, 4023 unregister_application, 4024 connect_channel, 4025 destroy_channel, 4026 cleanup, 4027 }; 4028 4029 /******************************************************************************* 4030 * 4031 * Function btif_hl_get_interface 4032 * 4033 * Description Get the hl callback interface 4034 * 4035 * Returns bthf_interface_t 4036 * 4037 ******************************************************************************/ 4038 const bthl_interface_t* btif_hl_get_interface() { 4039 BTIF_TRACE_EVENT("%s", __func__); 4040 return &bthlInterface; 4041 } 4042 4043 /******************************************************************************* 4044 * 4045 * Function btif_hl_update_maxfd 4046 * 4047 * Description Update the max fd if the input fd is greater than the current max 4048 * fd 4049 * 4050 * Returns int 4051 * 4052 ******************************************************************************/ 4053 int btif_hl_update_maxfd(int max_org_s) { 4054 int maxfd = max_org_s; 4055 4056 BTIF_TRACE_DEBUG("btif_hl_update_maxfd max_org_s= %d", max_org_s); 4057 for (const list_node_t* node = list_begin(soc_queue); 4058 node != list_end(soc_queue); node = list_next(node)) { 4059 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node); 4060 if (maxfd < p_scb->max_s) { 4061 maxfd = p_scb->max_s; 4062 BTIF_TRACE_DEBUG("btif_hl_update_maxfd maxfd=%d", maxfd); 4063 } 4064 } 4065 4066 BTIF_TRACE_DEBUG("btif_hl_update_maxfd final *p_max_s=%d", maxfd); 4067 return maxfd; 4068 } 4069 /******************************************************************************* 4070 * 4071 * Function btif_hl_get_socket_state 4072 * 4073 * Description get socket state 4074 * 4075 * Returns btif_hl_soc_state_t 4076 * 4077 ******************************************************************************/ 4078 btif_hl_soc_state_t btif_hl_get_socket_state(btif_hl_soc_cb_t* p_scb) { 4079 BTIF_TRACE_DEBUG("btif_hl_get_socket_state state=%d", p_scb->state); 4080 return p_scb->state; 4081 } 4082 /******************************************************************************* 4083 * 4084 * Function btif_hl_set_socket_state 4085 * 4086 * Description set socket state 4087 * 4088 * Returns void 4089 * 4090 ******************************************************************************/ 4091 void btif_hl_set_socket_state(btif_hl_soc_cb_t* p_scb, 4092 btif_hl_soc_state_t new_state) { 4093 BTIF_TRACE_DEBUG("btif_hl_set_socket_state %d---->%d", p_scb->state, 4094 new_state); 4095 p_scb->state = new_state; 4096 } 4097 /******************************************************************************* 4098 * 4099 * Function btif_hl_release_mcl_sockets 4100 * 4101 * Description Release all sockets on the MCL 4102 * 4103 * Returns void 4104 * 4105 ******************************************************************************/ 4106 void btif_hl_release_mcl_sockets(uint8_t app_idx, uint8_t mcl_idx) { 4107 uint8_t i; 4108 btif_hl_mdl_cb_t* p_dcb; 4109 bool found = false; 4110 BTIF_TRACE_DEBUG("%s", __func__); 4111 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) { 4112 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, i); 4113 if (p_dcb && p_dcb->in_use && p_dcb->p_scb) { 4114 BTIF_TRACE_DEBUG("found socket for app_idx=%d mcl_id=%d, mdl_idx=%d", 4115 app_idx, mcl_idx, i); 4116 btif_hl_set_socket_state(p_dcb->p_scb, BTIF_HL_SOC_STATE_W4_REL); 4117 p_dcb->p_scb = NULL; 4118 found = true; 4119 } 4120 } 4121 if (found) btif_hl_select_close_connected(); 4122 } 4123 /******************************************************************************* 4124 * 4125 * Function btif_hl_release_socket 4126 * 4127 * Description release a specified socket 4128 * 4129 * Returns void 4130 * 4131 ******************************************************************************/ 4132 void btif_hl_release_socket(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) { 4133 btif_hl_soc_cb_t* p_scb = NULL; 4134 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 4135 4136 BTIF_TRACE_DEBUG("%s", __func__); 4137 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d mdl_idx=%d", app_idx, mcl_idx, 4138 mdl_idx); 4139 4140 if (p_dcb && p_dcb->p_scb) { 4141 p_scb = p_dcb->p_scb; 4142 btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_REL); 4143 p_dcb->p_scb = NULL; 4144 btif_hl_select_close_connected(); 4145 } 4146 } 4147 /******************************************************************************* 4148 * 4149 * Function btif_hl_create_socket 4150 * 4151 * Description create a socket 4152 * 4153 * Returns bool 4154 * 4155 ******************************************************************************/ 4156 bool btif_hl_create_socket(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) { 4157 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 4158 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 4159 bool status = false; 4160 4161 BTIF_TRACE_DEBUG("%s", __func__); 4162 4163 if (p_dcb) { 4164 btif_hl_soc_cb_t* p_scb = 4165 (btif_hl_soc_cb_t*)osi_malloc(sizeof(btif_hl_soc_cb_t)); 4166 if (socketpair(AF_UNIX, SOCK_STREAM, 0, p_scb->socket_id) >= 0) { 4167 BTIF_TRACE_DEBUG("socket id[0]=%d id[1]=%d", p_scb->socket_id[0], 4168 p_scb->socket_id[1]); 4169 p_dcb->p_scb = p_scb; 4170 p_scb->app_idx = app_idx; 4171 p_scb->mcl_idx = mcl_idx; 4172 p_scb->mdl_idx = mdl_idx; 4173 p_scb->channel_id = p_dcb->channel_id; 4174 p_scb->mdep_cfg_idx = p_dcb->local_mdep_cfg_idx; 4175 p_scb->bd_addr = p_mcb->bd_addr; 4176 btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_ADD); 4177 p_scb->max_s = p_scb->socket_id[1]; 4178 list_append(soc_queue, (void*)p_scb); 4179 btif_hl_select_wakeup(); 4180 status = true; 4181 } else { 4182 osi_free_and_reset((void**)&p_scb); 4183 } 4184 } 4185 4186 BTIF_TRACE_DEBUG("%s status=%d", __func__, status); 4187 return status; 4188 } 4189 /******************************************************************************* 4190 * 4191 * Function btif_hl_add_socket_to_set 4192 * 4193 * Description Add a socket 4194 * 4195 * Returns void 4196 * 4197 ******************************************************************************/ 4198 void btif_hl_add_socket_to_set(fd_set* p_org_set) { 4199 btif_hl_mdl_cb_t* p_dcb = NULL; 4200 btif_hl_mcl_cb_t* p_mcb = NULL; 4201 btif_hl_app_cb_t* p_acb = NULL; 4202 btif_hl_evt_cb_t evt_param; 4203 bt_status_t status; 4204 int len; 4205 4206 BTIF_TRACE_DEBUG("entering %s", __func__); 4207 4208 for (const list_node_t* node = list_begin(soc_queue); 4209 node != list_end(soc_queue); node = list_next(node)) { 4210 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node); 4211 4212 BTIF_TRACE_DEBUG("btif_hl_add_socket_to_set first p_scb=0x%x", p_scb); 4213 if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_ADD) { 4214 btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_READ); 4215 FD_SET(p_scb->socket_id[1], p_org_set); 4216 BTIF_TRACE_DEBUG("found and set socket_id=%d is_set=%d", 4217 p_scb->socket_id[1], 4218 FD_ISSET(p_scb->socket_id[1], p_org_set)); 4219 p_mcb = BTIF_HL_GET_MCL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx); 4220 p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx, 4221 p_scb->mdl_idx); 4222 p_acb = BTIF_HL_GET_APP_CB_PTR(p_scb->app_idx); 4223 if (p_mcb && p_dcb) { 4224 btif_hl_stop_timer_using_handle(p_mcb->mcl_handle); 4225 evt_param.chan_cb.app_id = p_acb->app_id; 4226 evt_param.chan_cb.bd_addr = p_mcb->bd_addr; 4227 evt_param.chan_cb.channel_id = p_dcb->channel_id; 4228 evt_param.chan_cb.fd = p_scb->socket_id[0]; 4229 evt_param.chan_cb.mdep_cfg_index = (int)p_dcb->local_mdep_cfg_idx; 4230 evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING; 4231 len = sizeof(btif_hl_send_chan_state_cb_t); 4232 status = btif_transfer_context(btif_hl_proc_cb_evt, 4233 BTIF_HL_SEND_CONNECTED_CB, 4234 (char*)&evt_param, len, NULL); 4235 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 4236 } 4237 } 4238 } 4239 BTIF_TRACE_DEBUG("leaving %s", __func__); 4240 } 4241 4242 /******************************************************************************* 4243 * 4244 * Function btif_hl_close_socket 4245 * 4246 * Description close a socket 4247 * 4248 * Returns void 4249 * 4250 ******************************************************************************/ 4251 void btif_hl_close_socket(fd_set* p_org_set) { 4252 BTIF_TRACE_DEBUG("entering %s", __func__); 4253 for (const list_node_t* node = list_begin(soc_queue); 4254 node != list_end(soc_queue); node = list_next(node)) { 4255 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node); 4256 if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_REL) { 4257 BTIF_TRACE_DEBUG("app_idx=%d mcl_id=%d, mdl_idx=%d", p_scb->app_idx, 4258 p_scb->mcl_idx, p_scb->mdl_idx); 4259 btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_IDLE); 4260 if (p_scb->socket_id[1] != -1) { 4261 FD_CLR(p_scb->socket_id[1], p_org_set); 4262 shutdown(p_scb->socket_id[1], SHUT_RDWR); 4263 close(p_scb->socket_id[1]); 4264 4265 btif_hl_evt_cb_t evt_param; 4266 evt_param.chan_cb.app_id = (int)btif_hl_get_app_id(p_scb->channel_id); 4267 evt_param.chan_cb.bd_addr = p_scb->bd_addr; 4268 evt_param.chan_cb.channel_id = p_scb->channel_id; 4269 evt_param.chan_cb.fd = p_scb->socket_id[0]; 4270 evt_param.chan_cb.mdep_cfg_index = (int)p_scb->mdep_cfg_idx; 4271 evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_DISCONNECTED_PENDING; 4272 int len = sizeof(btif_hl_send_chan_state_cb_t); 4273 bt_status_t status = btif_transfer_context( 4274 btif_hl_proc_cb_evt, BTIF_HL_SEND_DISCONNECTED_CB, 4275 (char*)&evt_param, len, NULL); 4276 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status); 4277 } 4278 } 4279 } 4280 4281 for (const list_node_t* node = list_begin(soc_queue); 4282 node != list_end(soc_queue);) { 4283 // We may mutate this list so we need keep track of 4284 // the current node and only remove items behind. 4285 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node); 4286 BTIF_TRACE_DEBUG("p_scb=0x%x", p_scb); 4287 node = list_next(node); 4288 if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_IDLE) { 4289 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR( 4290 p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx); 4291 BTIF_TRACE_DEBUG( 4292 "idle socket app_idx=%d mcl_id=%d, mdl_idx=%d p_dcb->in_use=%d", 4293 p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx, p_dcb->in_use); 4294 list_remove(soc_queue, p_scb); 4295 osi_free(p_scb); 4296 p_dcb->p_scb = NULL; 4297 } 4298 } 4299 BTIF_TRACE_DEBUG("leaving %s", __func__); 4300 } 4301 4302 /******************************************************************************* 4303 * 4304 * Function btif_hl_select_wakeup_callback 4305 * 4306 * Description Select wakup callback to add or close a socket 4307 * 4308 * Returns void 4309 * 4310 ******************************************************************************/ 4311 4312 void btif_hl_select_wakeup_callback(fd_set* p_org_set, int wakeup_signal) { 4313 BTIF_TRACE_DEBUG("entering %s wakeup_signal=0x%04x", __func__, wakeup_signal); 4314 4315 if (wakeup_signal == btif_hl_signal_select_wakeup) { 4316 btif_hl_add_socket_to_set(p_org_set); 4317 } else if (wakeup_signal == btif_hl_signal_select_close_connected) { 4318 btif_hl_close_socket(p_org_set); 4319 } 4320 BTIF_TRACE_DEBUG("leaving %s", __func__); 4321 } 4322 4323 /******************************************************************************* 4324 * 4325 * Function btif_hl_select_monitor_callback 4326 * 4327 * Description Select monitor callback to check pending socket actions 4328 * 4329 * Returns void 4330 * 4331 ******************************************************************************/ 4332 void btif_hl_select_monitor_callback(fd_set* p_cur_set, 4333 UNUSED_ATTR fd_set* p_org_set) { 4334 BTIF_TRACE_DEBUG("entering %s", __func__); 4335 4336 for (const list_node_t* node = list_begin(soc_queue); 4337 node != list_end(soc_queue); node = list_next(node)) { 4338 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node); 4339 if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_READ) { 4340 if (FD_ISSET(p_scb->socket_id[1], p_cur_set)) { 4341 BTIF_TRACE_DEBUG("read data state= BTIF_HL_SOC_STATE_W4_READ"); 4342 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR( 4343 p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx); 4344 CHECK(p_dcb != NULL); 4345 if (p_dcb->p_tx_pkt) { 4346 BTIF_TRACE_ERROR( 4347 "Rcv new pkt but the last pkt is still not been" 4348 " sent tx_size=%d", 4349 p_dcb->tx_size); 4350 osi_free_and_reset((void**)&p_dcb->p_tx_pkt); 4351 } 4352 p_dcb->p_tx_pkt = (uint8_t*)osi_malloc(p_dcb->mtu); 4353 ssize_t r; 4354 OSI_NO_INTR(r = recv(p_scb->socket_id[1], p_dcb->p_tx_pkt, p_dcb->mtu, 4355 MSG_DONTWAIT)); 4356 if (r > 0) { 4357 BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data r =%d", 4358 r); 4359 p_dcb->tx_size = r; 4360 BTIF_TRACE_DEBUG( 4361 "btif_hl_select_monitor_callback send data tx_size=%d", 4362 p_dcb->tx_size); 4363 BTA_HlSendData(p_dcb->mdl_handle, p_dcb->tx_size); 4364 } else { 4365 BTIF_TRACE_DEBUG( 4366 "btif_hl_select_monitor_callback receive failed r=%d", r); 4367 BTA_HlDchClose(p_dcb->mdl_handle); 4368 } 4369 } 4370 } 4371 } 4372 4373 if (list_is_empty(soc_queue)) 4374 BTIF_TRACE_DEBUG("btif_hl_select_monitor_queue is empty"); 4375 4376 BTIF_TRACE_DEBUG("leaving %s", __func__); 4377 } 4378 4379 /******************************************************************************* 4380 * 4381 * Function btif_hl_select_wakeup_init 4382 * 4383 * Description select loop wakup init 4384 * 4385 * Returns int 4386 * 4387 ******************************************************************************/ 4388 static inline int btif_hl_select_wakeup_init(fd_set* set) { 4389 BTIF_TRACE_DEBUG("%s", __func__); 4390 if (signal_fds[0] == -1 && 4391 socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0) { 4392 BTIF_TRACE_ERROR("socketpair failed: %s", strerror(errno)); 4393 return -1; 4394 } 4395 4396 BTIF_TRACE_DEBUG( 4397 "btif_hl_select_wakeup_init signal_fds[0]=%d signal_fds[1]=%d", 4398 signal_fds[0], signal_fds[1]); 4399 FD_SET(signal_fds[0], set); 4400 4401 return signal_fds[0]; 4402 } 4403 4404 /******************************************************************************* 4405 * 4406 * Function btif_hl_select_wakeup 4407 * 4408 * Description send a signal to wakupo the select loop 4409 * 4410 * Returns int 4411 * 4412 ******************************************************************************/ 4413 static inline int btif_hl_select_wakeup(void) { 4414 char sig_on = btif_hl_signal_select_wakeup; 4415 4416 BTIF_TRACE_DEBUG("%s", __func__); 4417 4418 ssize_t ret; 4419 OSI_NO_INTR(ret = send(signal_fds[1], &sig_on, sizeof(sig_on), 0)); 4420 4421 return (int)ret; 4422 } 4423 4424 /******************************************************************************* 4425 * 4426 * Function btif_hl_select_close_connected 4427 * 4428 * Description send a signal to close a socket 4429 * 4430 * Returns int 4431 * 4432 ******************************************************************************/ 4433 static inline int btif_hl_select_close_connected(void) { 4434 char sig_on = btif_hl_signal_select_close_connected; 4435 4436 BTIF_TRACE_DEBUG("%s", __func__); 4437 4438 ssize_t ret; 4439 OSI_NO_INTR(ret = send(signal_fds[1], &sig_on, sizeof(sig_on), 0)); 4440 4441 return (int)ret; 4442 } 4443 4444 /******************************************************************************* 4445 * 4446 * Function btif_hl_close_select_thread 4447 * 4448 * Description send signal to close the thread and then close all signal FDs 4449 * 4450 * Returns int 4451 * 4452 ******************************************************************************/ 4453 static inline int btif_hl_close_select_thread(void) { 4454 ssize_t result = 0; 4455 char sig_on = btif_hl_signal_select_exit; 4456 4457 BTIF_TRACE_DEBUG("%", __func__); 4458 4459 OSI_NO_INTR(result = send(signal_fds[1], &sig_on, sizeof(sig_on), 0)); 4460 4461 if (btif_is_enabled()) { 4462 /* Wait for the select_thread_id to exit if BT is still enabled 4463 and only this profile getting cleaned up*/ 4464 if (select_thread_id != -1) { 4465 pthread_join(select_thread_id, NULL); 4466 select_thread_id = -1; 4467 } 4468 } 4469 list_free(soc_queue); 4470 soc_queue = NULL; 4471 4472 return (int)result; 4473 } 4474 4475 /******************************************************************************* 4476 * 4477 * Function btif_hl_select_wake_reset 4478 * 4479 * Description clear the received signal for the select loop 4480 * 4481 * Returns int 4482 * 4483 ******************************************************************************/ 4484 static inline int btif_hl_select_wake_reset(void) { 4485 char sig_recv = 0; 4486 4487 BTIF_TRACE_DEBUG("%s", __func__); 4488 4489 ssize_t r; 4490 OSI_NO_INTR( 4491 r = recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL)); 4492 4493 return (int)sig_recv; 4494 } 4495 /******************************************************************************* 4496 * 4497 * Function btif_hl_select_wake_signaled 4498 * 4499 * Description check whether a fd is set or not 4500 * 4501 * Returns int 4502 * 4503 ******************************************************************************/ 4504 static inline int btif_hl_select_wake_signaled(fd_set* set) { 4505 BTIF_TRACE_DEBUG("btif_hl_select_wake_signaled"); 4506 return FD_ISSET(signal_fds[0], set); 4507 } 4508 /******************************************************************************* 4509 * 4510 * Function btif_hl_thread_cleanup 4511 * 4512 * Description shut down and clean up the select loop 4513 * 4514 * Returns void 4515 * 4516 ******************************************************************************/ 4517 static void btif_hl_thread_cleanup() { 4518 if (listen_s != -1) close(listen_s); 4519 if (connected_s != -1) { 4520 shutdown(connected_s, SHUT_RDWR); 4521 close(connected_s); 4522 } 4523 listen_s = connected_s = -1; 4524 BTIF_TRACE_DEBUG("hl thread cleanup"); 4525 } 4526 /******************************************************************************* 4527 * 4528 * Function btif_hl_select_thread 4529 * 4530 * Description the select loop 4531 * 4532 * Returns void 4533 * 4534 ******************************************************************************/ 4535 static void* btif_hl_select_thread(UNUSED_ATTR void* arg) { 4536 fd_set org_set, curr_set; 4537 int r, max_curr_s, max_org_s; 4538 4539 BTIF_TRACE_DEBUG("entered btif_hl_select_thread"); 4540 FD_ZERO(&org_set); 4541 max_org_s = btif_hl_select_wakeup_init(&org_set); 4542 BTIF_TRACE_DEBUG("max_s=%d ", max_org_s); 4543 4544 for (;;) { 4545 r = 0; 4546 BTIF_TRACE_DEBUG("set curr_set = org_set "); 4547 curr_set = org_set; 4548 max_curr_s = max_org_s; 4549 int ret = select((max_curr_s + 1), &curr_set, NULL, NULL, NULL); 4550 BTIF_TRACE_DEBUG("select unblocked ret=%d", ret); 4551 if (ret == -1) { 4552 if (errno == EINTR) continue; 4553 BTIF_TRACE_DEBUG("select() ret -1, exit the thread"); 4554 btif_hl_thread_cleanup(); 4555 select_thread_id = -1; 4556 return 0; 4557 } else if (ret) { 4558 BTIF_TRACE_DEBUG("btif_hl_select_wake_signaled, signal ret=%d", ret); 4559 if (btif_hl_select_wake_signaled(&curr_set)) { 4560 r = btif_hl_select_wake_reset(); 4561 BTIF_TRACE_DEBUG("btif_hl_select_wake_signaled, signal:%d", r); 4562 if (r == btif_hl_signal_select_wakeup || 4563 r == btif_hl_signal_select_close_connected) { 4564 btif_hl_select_wakeup_callback(&org_set, r); 4565 } else if (r == btif_hl_signal_select_exit) { 4566 btif_hl_thread_cleanup(); 4567 BTIF_TRACE_DEBUG( 4568 "Exit hl_select_thread for btif_hl_signal_select_exit"); 4569 return 0; 4570 } 4571 } 4572 4573 btif_hl_select_monitor_callback(&curr_set, &org_set); 4574 max_org_s = btif_hl_update_maxfd(max_org_s); 4575 } else 4576 BTIF_TRACE_DEBUG("no data, select ret: %d\n", ret); 4577 } 4578 BTIF_TRACE_DEBUG("leaving hl_select_thread"); 4579 return 0; 4580 } 4581 4582 /******************************************************************************* 4583 * 4584 * Function create_thread 4585 * 4586 * Description creat a select loop 4587 * 4588 * Returns pthread_t 4589 * 4590 ******************************************************************************/ 4591 static inline pthread_t create_thread(void* (*start_routine)(void*), 4592 void* arg) { 4593 BTIF_TRACE_DEBUG("create_thread: entered"); 4594 pthread_attr_t thread_attr; 4595 4596 pthread_attr_init(&thread_attr); 4597 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); 4598 pthread_t thread_id = -1; 4599 if (pthread_create(&thread_id, &thread_attr, start_routine, arg) != 0) { 4600 BTIF_TRACE_ERROR("pthread_create : %s", strerror(errno)); 4601 return -1; 4602 } 4603 BTIF_TRACE_DEBUG("create_thread: thread created successfully"); 4604 return thread_id; 4605 } 4606 4607 /******************************************************************************* 4608 * 4609 * Function btif_hl_soc_thread_init 4610 * 4611 * Description HL select loop init function. 4612 * 4613 * Returns void 4614 * 4615 ******************************************************************************/ 4616 void btif_hl_soc_thread_init(void) { 4617 BTIF_TRACE_DEBUG("%s", __func__); 4618 soc_queue = list_new(NULL); 4619 if (soc_queue == NULL) 4620 LOG_ERROR(LOG_TAG, "%s unable to allocate resources for thread", __func__); 4621 select_thread_id = create_thread(btif_hl_select_thread, NULL); 4622 } 4623 /******************************************************************************* 4624 * 4625 * Function btif_hl_load_mdl_config 4626 * 4627 * Description load the MDL configuation from the application control block 4628 * 4629 * Returns bool 4630 * 4631 ******************************************************************************/ 4632 bool btif_hl_load_mdl_config(uint8_t app_id, uint8_t buffer_size, 4633 tBTA_HL_MDL_CFG* p_mdl_buf) { 4634 uint8_t app_idx; 4635 bool result = false; 4636 btif_hl_app_cb_t* p_acb; 4637 tBTA_HL_MDL_CFG* p; 4638 int i; 4639 BTIF_TRACE_DEBUG("%s", __func__); 4640 4641 if (btif_hl_find_app_idx(app_id, &app_idx)) { 4642 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); 4643 for (i = 0, p = p_mdl_buf; i < buffer_size; i++, p++) { 4644 memcpy(p, &p_acb->mdl_cfg[i].base, sizeof(tBTA_HL_MDL_CFG)); 4645 } 4646 result = true; 4647 } 4648 4649 BTIF_TRACE_DEBUG("result=%d", result); 4650 return result; 4651 } 4652