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