1 /****************************************************************************** 2 * 3 * Copyright (c) 2016 The Android Open Source Project 4 * Copyright (C) 2003-2012 Broadcom Corporation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 ******************************************************************************/ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include "bt_utils.h" 25 #include "bta_api.h" 26 #include "bta_hf_client_api.h" 27 #include "bta_hf_client_int.h" 28 #include "bta_sys.h" 29 #include "btcore/include/bdaddr.h" 30 #include "osi/include/osi.h" 31 #include "osi/include/properties.h" 32 #include "utl.h" 33 34 extern fixed_queue_t* btu_bta_alarm_queue; 35 36 static const char* bta_hf_client_evt_str(uint16_t event); 37 static const char* bta_hf_client_state_str(uint8_t state); 38 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle); 39 40 /* state machine states */ 41 enum { 42 BTA_HF_CLIENT_INIT_ST, 43 BTA_HF_CLIENT_OPENING_ST, 44 BTA_HF_CLIENT_OPEN_ST, 45 BTA_HF_CLIENT_CLOSING_ST 46 }; 47 48 /* state machine action enumeration list */ 49 enum { 50 BTA_HF_CLIENT_RFC_DO_CLOSE, 51 BTA_HF_CLIENT_START_CLOSE, 52 BTA_HF_CLIENT_START_OPEN, 53 BTA_HF_CLIENT_RFC_ACP_OPEN, 54 BTA_HF_CLIENT_SCO_LISTEN, 55 BTA_HF_CLIENT_SCO_CONN_OPEN, 56 BTA_HF_CLIENT_SCO_CONN_CLOSE, 57 BTA_HF_CLIENT_SCO_OPEN, 58 BTA_HF_CLIENT_SCO_CLOSE, 59 BTA_HF_CLIENT_FREE_DB, 60 BTA_HF_CLIENT_OPEN_FAIL, 61 BTA_HF_CLIENT_RFC_OPEN, 62 BTA_HF_CLIENT_RFC_FAIL, 63 BTA_HF_CLIENT_DISC_INT_RES, 64 BTA_HF_CLIENT_RFC_DO_OPEN, 65 BTA_HF_CLIENT_DISC_FAIL, 66 BTA_HF_CLIENT_RFC_CLOSE, 67 BTA_HF_CLIENT_RFC_DATA, 68 BTA_HF_CLIENT_DISC_ACP_RES, 69 BTA_HF_CLIENT_SVC_CONN_OPEN, 70 BTA_HF_CLIENT_SEND_AT_CMD, 71 BTA_HF_CLIENT_NUM_ACTIONS, 72 }; 73 74 #define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS 75 76 /* type for action functions */ 77 typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA* p_data); 78 79 /* action functions table, indexed with action enum */ 80 const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = { 81 /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close, 82 /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close, 83 /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open, 84 /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open, 85 /* BTA_HF_CLIENT_SCO_LISTEN */ NULL, 86 /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open, 87 /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close, 88 /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open, 89 /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close, 90 /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db, 91 /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail, 92 /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open, 93 /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail, 94 /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res, 95 /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open, 96 /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail, 97 /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close, 98 /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data, 99 /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res, 100 /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open, 101 /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd, 102 }; 103 104 /* state table information */ 105 #define BTA_HF_CLIENT_ACTIONS 2 /* number of actions */ 106 #define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */ 107 #define BTA_HF_CLIENT_NUM_COLS 3 /* number of columns in state tables */ 108 109 /* state table for init state */ 110 const uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = { 111 /* Event Action 1 Action 2 112 Next state */ 113 /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE, 114 BTA_HF_CLIENT_OPENING_ST}, 115 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 116 BTA_HF_CLIENT_INIT_ST}, 117 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 118 BTA_HF_CLIENT_INIT_ST}, 119 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 120 BTA_HF_CLIENT_INIT_ST}, 121 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_IGNORE, 122 BTA_HF_CLIENT_OPEN_ST}, 123 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 124 BTA_HF_CLIENT_INIT_ST}, 125 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 126 BTA_HF_CLIENT_INIT_ST}, 127 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 128 BTA_HF_CLIENT_INIT_ST}, 129 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, 130 BTA_HF_CLIENT_INIT_ST}, 131 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 132 BTA_HF_CLIENT_INIT_ST}, 133 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 134 BTA_HF_CLIENT_INIT_ST}, 135 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 136 BTA_HF_CLIENT_INIT_ST}, 137 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 138 BTA_HF_CLIENT_INIT_ST}, 139 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 140 BTA_HF_CLIENT_INIT_ST}, 141 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 142 BTA_HF_CLIENT_INIT_ST}, 143 }; 144 145 /* state table for opening state */ 146 const uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = { 147 /* Event Action 1 Action 2 148 Next state */ 149 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, 150 BTA_HF_CLIENT_OPENING_ST}, 151 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE, 152 BTA_HF_CLIENT_CLOSING_ST}, 153 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 154 BTA_HF_CLIENT_OPENING_ST}, 155 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 156 BTA_HF_CLIENT_OPENING_ST}, 157 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_IGNORE, 158 BTA_HF_CLIENT_OPEN_ST}, 159 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE, 160 BTA_HF_CLIENT_INIT_ST}, 161 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 162 BTA_HF_CLIENT_OPENING_ST}, 163 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 164 BTA_HF_CLIENT_OPENING_ST}, 165 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 166 BTA_HF_CLIENT_OPENING_ST}, 167 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE, 168 BTA_HF_CLIENT_OPENING_ST}, 169 /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE, 170 BTA_HF_CLIENT_OPENING_ST}, 171 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE, 172 BTA_HF_CLIENT_INIT_ST}, 173 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 174 BTA_HF_CLIENT_OPENING_ST}, 175 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 176 BTA_HF_CLIENT_OPENING_ST}, 177 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 178 BTA_HF_CLIENT_OPENING_ST}, 179 }; 180 181 /* state table for open state */ 182 const uint8_t bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = { 183 /* Event Action 1 Action 2 184 Next state */ 185 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, 186 BTA_HF_CLIENT_OPEN_ST}, 187 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE, 188 BTA_HF_CLIENT_CLOSING_ST}, 189 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE, 190 BTA_HF_CLIENT_OPEN_ST}, 191 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE, 192 BTA_HF_CLIENT_OPEN_ST}, 193 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 194 BTA_HF_CLIENT_OPEN_ST}, 195 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE, 196 BTA_HF_CLIENT_INIT_ST}, 197 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 198 BTA_HF_CLIENT_OPEN_ST}, 199 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE, 200 BTA_HF_CLIENT_OPEN_ST}, 201 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE, 202 BTA_HF_CLIENT_OPEN_ST}, 203 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 204 BTA_HF_CLIENT_OPEN_ST}, 205 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 206 BTA_HF_CLIENT_OPEN_ST}, 207 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 208 BTA_HF_CLIENT_OPEN_ST}, 209 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE, 210 BTA_HF_CLIENT_OPEN_ST}, 211 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE, 212 BTA_HF_CLIENT_OPEN_ST}, 213 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE, 214 BTA_HF_CLIENT_OPEN_ST}, 215 }; 216 217 /* state table for closing state */ 218 const uint8_t bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = { 219 /* Event Action 1 Action 2 220 Next state */ 221 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, 222 BTA_HF_CLIENT_CLOSING_ST}, 223 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 224 BTA_HF_CLIENT_CLOSING_ST}, 225 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 226 BTA_HF_CLIENT_CLOSING_ST}, 227 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 228 BTA_HF_CLIENT_CLOSING_ST}, 229 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 230 BTA_HF_CLIENT_CLOSING_ST}, 231 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE, 232 BTA_HF_CLIENT_INIT_ST}, 233 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 234 BTA_HF_CLIENT_CLOSING_ST}, 235 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 236 BTA_HF_CLIENT_CLOSING_ST}, 237 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, 238 BTA_HF_CLIENT_CLOSING_ST}, 239 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, 240 BTA_HF_CLIENT_INIT_ST}, 241 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 242 BTA_HF_CLIENT_CLOSING_ST}, 243 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 244 BTA_HF_CLIENT_CLOSING_ST}, 245 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 246 BTA_HF_CLIENT_CLOSING_ST}, 247 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 248 BTA_HF_CLIENT_CLOSING_ST}, 249 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 250 BTA_HF_CLIENT_CLOSING_ST}, 251 }; 252 253 /* type for state table */ 254 typedef const uint8_t (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS]; 255 256 /* state table */ 257 const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = { 258 bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open, 259 bta_hf_client_st_closing}; 260 261 /* HF Client control block */ 262 tBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr; 263 264 /* Event handler for the state machine */ 265 static const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event, 266 BTA_HfClientDisable}; 267 268 /******************************************************************************* 269 * 270 * Function bta_hf_client_cb_arr_init 271 * 272 * Description Initialize entire control block array set 273 * 274 * 275 * Returns void 276 * 277 ******************************************************************************/ 278 void bta_hf_client_cb_arr_init() { 279 memset(&bta_hf_client_cb_arr, 0, sizeof(tBTA_HF_CLIENT_CB_ARR)); 280 281 // reset the handles and make the CBs non-allocated 282 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 283 // Allocate the handles in increasing order of indices 284 bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i); 285 bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i; 286 } 287 } 288 289 /******************************************************************************* 290 * 291 * Function bta_hf_client_cb_init 292 * 293 * Description Initialize an HF_Client service control block. Assign the 294 * handle to cb->handle. 295 * 296 * 297 * 298 * Returns void 299 * 300 ******************************************************************************/ 301 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) { 302 APPL_TRACE_DEBUG("%s", __func__); 303 304 // Free any memory we need to explicity release 305 alarm_free(client_cb->collision_timer); 306 307 // Memset the rest of the block 308 memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB)); 309 310 // Re allocate any variables required 311 client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer"); 312 client_cb->handle = handle; 313 client_cb->sco_idx = BTM_INVALID_SCO_INDEX; 314 } 315 316 /******************************************************************************* 317 * 318 * Function bta_hf_client_resume_open 319 * 320 * Description Resume opening process. 321 * 322 * 323 * Returns void 324 * 325 ******************************************************************************/ 326 void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) { 327 APPL_TRACE_DEBUG("%s", __func__); 328 329 /* resume opening process. */ 330 if (client_cb->state == BTA_HF_CLIENT_INIT_ST) { 331 client_cb->state = BTA_HF_CLIENT_OPENING_ST; 332 tBTA_HF_CLIENT_DATA msg; 333 msg.hdr.layer_specific = client_cb->handle; 334 bta_hf_client_start_open(&msg); 335 } 336 } 337 338 /******************************************************************************* 339 * 340 * Function bta_hf_client_collision_timer_cback 341 * 342 * Description HF Client connection collision timer callback 343 * 344 * 345 * Returns void 346 * 347 ******************************************************************************/ 348 static void bta_hf_client_collision_timer_cback(void* data) { 349 APPL_TRACE_DEBUG("%s", __func__); 350 tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data; 351 352 /* If the peer haven't opened connection, restart opening process */ 353 bta_hf_client_resume_open(client_cb); 354 } 355 356 /******************************************************************************* 357 * 358 * Function bta_hf_client_collision_cback 359 * 360 * Description Get notified about collision. 361 * 362 * 363 * Returns void 364 * 365 ******************************************************************************/ 366 void bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, 367 uint8_t id, UNUSED_ATTR uint8_t app_id, 368 BD_ADDR peer_addr) { 369 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(peer_addr); 370 if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) { 371 if (id == BTA_ID_SYS) /* ACL collision */ 372 { 373 APPL_TRACE_WARNING("HF Client found collision (ACL) ..."); 374 } else if (id == BTA_ID_HS) /* RFCOMM collision */ 375 { 376 APPL_TRACE_WARNING("HF Client found collision (RFCOMM) ..."); 377 } else { 378 APPL_TRACE_WARNING("HF Client found collision (\?\?\?) ..."); 379 } 380 381 client_cb->state = BTA_HF_CLIENT_INIT_ST; 382 383 /* Cancel SDP if it had been started. */ 384 if (client_cb->p_disc_db) { 385 (void)SDP_CancelServiceSearch(client_cb->p_disc_db); 386 bta_hf_client_free_db(NULL); 387 } 388 389 /* reopen registered server */ 390 /* Collision may be detected before or after we close servers. */ 391 // bta_hf_client_start_server(); 392 393 /* Start timer to handle connection opening restart */ 394 alarm_set_on_queue(client_cb->collision_timer, 395 BTA_HF_CLIENT_COLLISION_TIMER_MS, 396 bta_hf_client_collision_timer_cback, (void*)client_cb, 397 btu_bta_alarm_queue); 398 } 399 } 400 401 /******************************************************************************* 402 * 403 * Function bta_hf_client_api_enable 404 * 405 * Description Handle an API enable event. 406 * 407 * 408 * Returns void 409 * 410 ******************************************************************************/ 411 tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback, 412 tBTA_SEC sec_mask, 413 tBTA_HF_CLIENT_FEAT features, 414 const char* p_service_name) { 415 /* If already registered then return error */ 416 if (bta_sys_is_register(BTA_ID_HS)) { 417 APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ..."); 418 return BTA_FAILURE; 419 } 420 421 /* register with BTA system manager */ 422 bta_sys_register(BTA_ID_HS, &bta_hf_client_reg); 423 424 /* reset the control blocks */ 425 bta_hf_client_cb_arr_init(); 426 427 bta_hf_client_cb_arr.p_cback = p_cback; 428 bta_hf_client_cb_arr.serv_sec_mask = sec_mask; 429 bta_hf_client_cb_arr.features = features; 430 431 /* create SDP records */ 432 bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name); 433 434 /* set same setting as AG does */ 435 BTM_WriteVoiceSettings(AG_VOICE_SETTINGS); 436 437 bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback); 438 439 /* Set the Audio service class bit */ 440 tBTA_UTL_COD cod; 441 cod.service = BTM_COD_SERVICE_AUDIO; 442 utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS); 443 444 /* start RFCOMM server */ 445 bta_hf_client_start_server(); 446 447 return BTA_SUCCESS; 448 } 449 450 /******************************************************************************* 451 * 452 * Function bta_hf_client_find_cb_by_handle 453 * 454 * Description Finds the control block by handle provided 455 * 456 * handle: Handle as obtained from BTA_HfClientOpen call 457 * 458 * 459 * Returns Control block corresponding to the handle and NULL if 460 * none exists 461 * 462 ******************************************************************************/ 463 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) { 464 // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES 465 if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) { 466 APPL_TRACE_ERROR("%s: handle out of range (%d, %d) %d", __func__, 1, 467 HF_CLIENT_MAX_DEVICES, handle); 468 return NULL; 469 } 470 471 // Check if the associated index is allocated. Index is (handle - 1). 472 if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated) 473 return &(bta_hf_client_cb_arr.cb[handle - 1]); 474 475 APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle); 476 return NULL; 477 } 478 479 /******************************************************************************* 480 * 481 * Function bta_hf_client_find_cb_by_bda 482 * 483 * Description Finds the control block by handle provided 484 * 485 * bda: BD_ADDR of the device to find the handle for. 486 * Since there can only be one HF connection for a device 487 * we should always find a unique block 488 * 489 * Returns Control block corresponding to the BD_ADDR and NULL if 490 * none exists 491 * 492 ******************************************************************************/ 493 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const BD_ADDR peer_addr) { 494 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 495 // Check if the associated index is allocated and that BD ADDR matches 496 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 497 if (client_cb->is_allocated && !bdcmp(peer_addr, client_cb->peer_addr)) { 498 return client_cb; 499 } else { 500 APPL_TRACE_WARNING("%s: bdaddr mismatch for handle %d alloc %d", __func__, 501 i, client_cb->is_allocated); 502 } 503 } 504 APPL_TRACE_ERROR("%s: block not found", __func__); 505 return NULL; 506 } 507 508 /******************************************************************************* 509 * 510 * Function bta_hf_client_find_cb_by_rfc_handle 511 * 512 * Description Finds the control block by RFC handle provided. 513 * 514 * handle: RFC handle for the established connection 515 * 516 * 517 * Returns Control block corresponding to the handle and NULL if none 518 * exists 519 * 520 ******************************************************************************/ 521 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) { 522 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 523 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 524 bool is_allocated = client_cb->is_allocated; 525 uint16_t conn_handle = client_cb->conn_handle; 526 527 APPL_TRACE_DEBUG("%s: cb rfc_handle %d alloc %d conn_handle %d", __func__, 528 handle, is_allocated, conn_handle); 529 530 if (is_allocated && conn_handle == handle) { 531 return client_cb; 532 } 533 534 APPL_TRACE_WARNING("%s: no cb yet %d alloc %d conn_handle %d", __func__, 535 handle, is_allocated, conn_handle); 536 } 537 538 APPL_TRACE_ERROR("%s: no cb found for rfc handle %d", __func__, handle); 539 return NULL; 540 } 541 542 /******************************************************************************* 543 * 544 * Function bta_hf_client_find_cb_by_sco_handle 545 * 546 * Description Finds the control block by sco handle provided 547 * 548 * handle: sco handle 549 * 550 * 551 * Returns Control block corresponding to the sco handle and 552 * none if none exists 553 * 554 ******************************************************************************/ 555 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) { 556 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 557 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 558 if (client_cb->is_allocated && client_cb->sco_idx == handle) { 559 return client_cb; 560 } 561 } 562 APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle); 563 return NULL; 564 } 565 566 /******************************************************************************* 567 * 568 * Function bta_hf_client_allocate_handle 569 * 570 * Description Allocates a handle for the new BD ADDR that needs a new RF 571 * channel for HF connection. If the channel cannot be created 572 * for a reason then false is returned 573 * 574 * bd_addr: Address of the device for which this block is 575 * being created. Single device can only have one block. 576 * p_handle: OUT variable to store the outcome of allocate. If 577 * allocate failed then value is not valid 578 * 579 * 580 * Returns true if the creation of p_handle succeeded, false otherwise 581 * 582 ******************************************************************************/ 583 bool bta_hf_client_allocate_handle(const BD_ADDR bd_addr, uint16_t* p_handle) { 584 tBTA_HF_CLIENT_CB* existing_cb = bta_hf_client_find_cb_by_bda(bd_addr); 585 if (existing_cb != NULL) { 586 BTIF_TRACE_ERROR("%s: cannot allocate handle since BDADDR already exists", 587 __func__); 588 return false; 589 } 590 /* Check that we do not have a request to for same device in the control 591 * blocks */ 592 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 593 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 594 if (client_cb->is_allocated) { 595 APPL_TRACE_WARNING("%s: control block already used index %d", __func__, 596 i); 597 continue; 598 } 599 600 // Reset the client control block 601 bta_hf_client_cb_init(client_cb, client_cb->handle); 602 603 *p_handle = client_cb->handle; 604 APPL_TRACE_DEBUG("%s: marking CB handle %d to true", __func__, 605 client_cb->handle); 606 607 client_cb->is_allocated = true; 608 bdcpy(client_cb->peer_addr, bd_addr); 609 bta_hf_client_at_init(client_cb); 610 return true; 611 } 612 613 return false; 614 APPL_TRACE_ERROR("%s: all control blocks in use!", __func__); 615 } 616 617 /******************************************************************************* 618 * 619 * Function bta_hf_client_app_callback 620 * 621 * Description Calls the application callback 622 * 623 * 624 * Returns Void 625 * 626 ******************************************************************************/ 627 void bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data) { 628 if (bta_hf_client_cb_arr.p_cback != NULL) { 629 bta_hf_client_cb_arr.p_cback(event, data); 630 } 631 } 632 633 /******************************************************************************* 634 * 635 * Function bta_hf_client_api_disable 636 * 637 * Description Handle an API disable event. 638 * 639 * 640 * Returns void 641 * 642 ******************************************************************************/ 643 void bta_hf_client_api_disable() { 644 if (!bta_sys_is_register(BTA_ID_HS)) { 645 APPL_TRACE_WARNING("BTA HF Client is already disabled, ignoring ..."); 646 return; 647 } 648 649 /* Remove the collision handler */ 650 bta_sys_collision_register(BTA_ID_HS, NULL); 651 652 bta_hf_client_cb_arr.deregister = true; 653 654 /* remove sdp record */ 655 bta_hf_client_del_record(&bta_hf_client_cb_arr); 656 657 /* remove rfcomm server */ 658 bta_hf_client_close_server(); 659 660 /* reinit the control block */ 661 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 662 if (bta_hf_client_cb_arr.cb[i].is_allocated) { 663 bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i); 664 } 665 } 666 667 /* De-register with BTA system manager */ 668 bta_sys_deregister(BTA_ID_HS); 669 } 670 671 /******************************************************************************* 672 * 673 * Function bta_hf_client_hdl_event 674 * 675 * Description Data HF Client main event handling function. 676 * 677 * 678 * Returns bool 679 * 680 ******************************************************************************/ 681 bool bta_hf_client_hdl_event(BT_HDR* p_msg) { 682 APPL_TRACE_DEBUG("%s: %s (0x%x)", __func__, 683 bta_hf_client_evt_str(p_msg->event), p_msg->event); 684 bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg); 685 return true; 686 } 687 688 /******************************************************************************* 689 * 690 * Function bta_hf_client_sm_execute 691 * 692 * Description State machine event handling function for HF Client 693 * 694 * 695 * Returns void 696 * 697 ******************************************************************************/ 698 void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) { 699 tBTA_HF_CLIENT_CB* client_cb = 700 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); 701 if (client_cb == NULL) { 702 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__, 703 p_data->hdr.layer_specific); 704 return; 705 } 706 707 tBTA_HF_CLIENT_ST_TBL state_table; 708 uint8_t action; 709 int i; 710 711 uint16_t in_event = event; 712 uint8_t in_state = client_cb->state; 713 714 /* Ignore displaying of AT results when not connected (Ignored in state 715 * machine) */ 716 if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) { 717 APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)", 718 client_cb->state, 719 bta_hf_client_state_str(client_cb->state), event, 720 bta_hf_client_evt_str(event)); 721 } 722 723 event &= 0x00FF; 724 if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) { 725 APPL_TRACE_ERROR("HF Client evt out of range, ignoring..."); 726 return; 727 } 728 729 /* look up the state table for the current state */ 730 state_table = bta_hf_client_st_tbl[client_cb->state]; 731 732 /* set next state */ 733 client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE]; 734 735 /* execute action functions */ 736 for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) { 737 action = state_table[event][i]; 738 if (action != BTA_HF_CLIENT_IGNORE) { 739 (*bta_hf_client_action[action])(p_data); 740 } else { 741 break; 742 } 743 } 744 745 /* If the state has changed then notify the app of the corresponding change */ 746 if (in_state != client_cb->state) { 747 APPL_TRACE_DEBUG( 748 "%s: notifying state change to %d -> %d " 749 "device %02x:%02x:%02x:%02x:%02x:%02x", 750 __func__, in_state, client_cb->state, client_cb->peer_addr[0], 751 client_cb->peer_addr[1], client_cb->peer_addr[2], 752 client_cb->peer_addr[3], client_cb->peer_addr[4], 753 client_cb->peer_addr[5]); 754 tBTA_HF_CLIENT evt; 755 memset(&evt, 0, sizeof(evt)); 756 bdcpy(evt.bd_addr, client_cb->peer_addr); 757 if (client_cb->state == BTA_HF_CLIENT_INIT_ST) { 758 bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt); 759 } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) { 760 evt.open.handle = client_cb->handle; 761 bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt); 762 } 763 } 764 765 /* if the next state is INIT then release the cb for future use */ 766 if (client_cb->state == BTA_HF_CLIENT_INIT_ST) { 767 APPL_TRACE_DEBUG("%s: marking CB handle %d to false", __func__, 768 client_cb->handle); 769 client_cb->is_allocated = false; 770 } 771 772 APPL_TRACE_EVENT( 773 "%s: device %02x:%02x:%02x:%02x:%02x:%02x " 774 "state change: [%s] -> [%s] after Event [%s]", 775 __func__, client_cb->peer_addr[0], client_cb->peer_addr[1], 776 client_cb->peer_addr[2], client_cb->peer_addr[3], client_cb->peer_addr[4], 777 client_cb->peer_addr[5], bta_hf_client_state_str(in_state), 778 bta_hf_client_state_str(client_cb->state), 779 bta_hf_client_evt_str(in_event)); 780 } 781 782 static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) { 783 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE; 784 785 bta_hf_client_send_at_bia(client_cb); 786 bta_hf_client_send_at_ccwa(client_cb, true); 787 bta_hf_client_send_at_cmee(client_cb, true); 788 bta_hf_client_send_at_cops(client_cb, false); 789 bta_hf_client_send_at_btrh(client_cb, true, 0); 790 bta_hf_client_send_at_clip(client_cb, true); 791 } 792 793 /******************************************************************************* 794 * 795 * Function bta_hf_client_slc_seq 796 * 797 * Description Handles AT commands sequence required for SLC creation 798 * 799 * 800 * Returns void 801 * 802 ******************************************************************************/ 803 void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) { 804 APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u", 805 client_cb->at_cb.current_cmd); 806 807 if (error) { 808 /* SLC establishment error, sent close rfcomm event */ 809 APPL_TRACE_ERROR( 810 "HFPClient: Failed to create SLC due to AT error, disconnecting (%u)", 811 client_cb->at_cb.current_cmd); 812 813 tBTA_HF_CLIENT_DATA msg; 814 msg.hdr.layer_specific = client_cb->handle; 815 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg); 816 return; 817 } 818 819 if (client_cb->svc_conn) { 820 APPL_TRACE_WARNING("%s: SLC already connected for CB handle %d", __func__, 821 client_cb->handle); 822 return; 823 } 824 825 switch (client_cb->at_cb.current_cmd) { 826 case BTA_HF_CLIENT_AT_NONE: 827 bta_hf_client_send_at_brsf(client_cb, bta_hf_client_cb_arr.features); 828 break; 829 830 case BTA_HF_CLIENT_AT_BRSF: 831 if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_CODEC) && 832 (client_cb->peer_features & BTA_HF_CLIENT_PEER_CODEC)) { 833 bta_hf_client_send_at_bac(client_cb); 834 break; 835 } 836 837 bta_hf_client_send_at_cind(client_cb, false); 838 break; 839 840 case BTA_HF_CLIENT_AT_BAC: 841 bta_hf_client_send_at_cind(client_cb, false); 842 break; 843 844 case BTA_HF_CLIENT_AT_CIND: 845 bta_hf_client_send_at_cind(client_cb, true); 846 break; 847 848 case BTA_HF_CLIENT_AT_CIND_STATUS: 849 bta_hf_client_send_at_cmer(client_cb, true); 850 break; 851 852 case BTA_HF_CLIENT_AT_CMER: 853 if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY && 854 bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) { 855 bta_hf_client_send_at_chld(client_cb, '?', 0); 856 } else { 857 tBTA_HF_CLIENT_DATA msg; 858 msg.hdr.layer_specific = client_cb->handle; 859 bta_hf_client_svc_conn_open(&msg); 860 send_post_slc_cmd(client_cb); 861 } 862 break; 863 864 case BTA_HF_CLIENT_AT_CHLD: { 865 tBTA_HF_CLIENT_DATA msg; 866 msg.hdr.layer_specific = client_cb->handle; 867 bta_hf_client_svc_conn_open(&msg); 868 send_post_slc_cmd(client_cb); 869 break; 870 } 871 872 default: { 873 /* If happen there is a bug in SLC creation procedure... */ 874 APPL_TRACE_ERROR( 875 "HFPClient: Failed to create SLCdue to unexpected AT command, " 876 "disconnecting (%u)", 877 client_cb->at_cb.current_cmd); 878 879 tBTA_HF_CLIENT_DATA msg; 880 msg.hdr.layer_specific = client_cb->handle; 881 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg); 882 break; 883 } 884 } 885 } 886 887 #ifndef CASE_RETURN_STR 888 #define CASE_RETURN_STR(const) \ 889 case const: \ 890 return #const; 891 #endif 892 893 static const char* bta_hf_client_evt_str(uint16_t event) { 894 switch (event) { 895 CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT) 896 CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT) 897 CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT) 898 CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT) 899 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT) 900 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT) 901 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT) 902 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT) 903 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT) 904 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT) 905 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT) 906 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT) 907 CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT) 908 CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT) 909 CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT) 910 CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT) 911 CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT) 912 default: 913 return "Unknown HF Client Event"; 914 } 915 } 916 917 static const char* bta_hf_client_state_str(uint8_t state) { 918 switch (state) { 919 CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST) 920 CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST) 921 CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST) 922 CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST) 923 default: 924 return "Unknown HF Client State"; 925 } 926 } 927 928 void bta_hf_client_dump_statistics(int fd) { 929 dprintf(fd, "\nBluetooth HF Client BTA Statistics\n"); 930 931 // We dump statistics for all control blocks 932 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 933 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 934 if (!client_cb->is_allocated) { 935 // Skip the blocks which are not allocated 936 continue; 937 } 938 939 dprintf(fd, " Control block #%d\n", i + 1); 940 941 // Device name 942 dprintf(fd, " Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n", 943 client_cb->peer_addr[0], client_cb->peer_addr[1], 944 client_cb->peer_addr[2], client_cb->peer_addr[3], 945 client_cb->peer_addr[4], client_cb->peer_addr[5]); 946 947 // State machine state 948 dprintf(fd, " State Machine State: %s\n", 949 bta_hf_client_state_str(client_cb->state)); 950 951 // Local RFC channelfor communication 952 dprintf(fd, " RFCOMM Channel (local) %d\n", client_cb->conn_handle); 953 954 // BTA Handle shared between BTA and client (ex BTIF) 955 dprintf(fd, " BTA Generated handle %d\n", client_cb->handle); 956 } 957 } 958