1 /****************************************************************************** 2 * 3 * Copyright (c) 2016 The Android Open Source Project 4 * Copyright 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 <base/logging.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 25 #include "bt_utils.h" 26 #include "bta_api.h" 27 #include "bta_hf_client_api.h" 28 #include "bta_hf_client_int.h" 29 #include "bta_sys.h" 30 #include "osi/include/osi.h" 31 #include "osi/include/properties.h" 32 #include "utl.h" 33 34 static const char* bta_hf_client_evt_str(uint16_t event); 35 static const char* bta_hf_client_state_str(uint8_t state); 36 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle); 37 38 /* state machine states */ 39 enum { 40 BTA_HF_CLIENT_INIT_ST, 41 BTA_HF_CLIENT_OPENING_ST, 42 BTA_HF_CLIENT_OPEN_ST, 43 BTA_HF_CLIENT_CLOSING_ST 44 }; 45 46 /* state machine action enumeration list */ 47 enum { 48 BTA_HF_CLIENT_RFC_DO_CLOSE, 49 BTA_HF_CLIENT_START_CLOSE, 50 BTA_HF_CLIENT_START_OPEN, 51 BTA_HF_CLIENT_RFC_ACP_OPEN, 52 BTA_HF_CLIENT_SCO_LISTEN, 53 BTA_HF_CLIENT_SCO_CONN_OPEN, 54 BTA_HF_CLIENT_SCO_CONN_CLOSE, 55 BTA_HF_CLIENT_SCO_OPEN, 56 BTA_HF_CLIENT_SCO_CLOSE, 57 BTA_HF_CLIENT_FREE_DB, 58 BTA_HF_CLIENT_OPEN_FAIL, 59 BTA_HF_CLIENT_RFC_OPEN, 60 BTA_HF_CLIENT_RFC_FAIL, 61 BTA_HF_CLIENT_DISC_INT_RES, 62 BTA_HF_CLIENT_RFC_DO_OPEN, 63 BTA_HF_CLIENT_DISC_FAIL, 64 BTA_HF_CLIENT_RFC_CLOSE, 65 BTA_HF_CLIENT_RFC_DATA, 66 BTA_HF_CLIENT_DISC_ACP_RES, 67 BTA_HF_CLIENT_SVC_CONN_OPEN, 68 BTA_HF_CLIENT_SEND_AT_CMD, 69 BTA_HF_CLIENT_NUM_ACTIONS, 70 }; 71 72 #define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS 73 74 /* type for action functions */ 75 typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA* p_data); 76 77 /* action functions table, indexed with action enum */ 78 const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = { 79 /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close, 80 /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close, 81 /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open, 82 /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open, 83 /* BTA_HF_CLIENT_SCO_LISTEN */ NULL, 84 /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open, 85 /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close, 86 /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open, 87 /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close, 88 /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db, 89 /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail, 90 /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open, 91 /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail, 92 /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res, 93 /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open, 94 /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail, 95 /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close, 96 /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data, 97 /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res, 98 /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open, 99 /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd, 100 }; 101 102 /* state table information */ 103 #define BTA_HF_CLIENT_ACTIONS 2 /* number of actions */ 104 #define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */ 105 #define BTA_HF_CLIENT_NUM_COLS 3 /* number of columns in state tables */ 106 107 /* state table for init state */ 108 const uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = { 109 /* Event Action 1 Action 2 110 Next state */ 111 /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE, 112 BTA_HF_CLIENT_OPENING_ST}, 113 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 114 BTA_HF_CLIENT_INIT_ST}, 115 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 116 BTA_HF_CLIENT_INIT_ST}, 117 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 118 BTA_HF_CLIENT_INIT_ST}, 119 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_IGNORE, 120 BTA_HF_CLIENT_OPEN_ST}, 121 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 122 BTA_HF_CLIENT_INIT_ST}, 123 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 124 BTA_HF_CLIENT_INIT_ST}, 125 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 126 BTA_HF_CLIENT_INIT_ST}, 127 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, 128 BTA_HF_CLIENT_INIT_ST}, 129 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 130 BTA_HF_CLIENT_INIT_ST}, 131 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 132 BTA_HF_CLIENT_INIT_ST}, 133 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 134 BTA_HF_CLIENT_INIT_ST}, 135 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 136 BTA_HF_CLIENT_INIT_ST}, 137 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 138 BTA_HF_CLIENT_INIT_ST}, 139 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 140 BTA_HF_CLIENT_INIT_ST}, 141 }; 142 143 /* state table for opening state */ 144 const uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = { 145 /* Event Action 1 Action 2 146 Next state */ 147 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, 148 BTA_HF_CLIENT_OPENING_ST}, 149 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE, 150 BTA_HF_CLIENT_CLOSING_ST}, 151 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 152 BTA_HF_CLIENT_OPENING_ST}, 153 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 154 BTA_HF_CLIENT_OPENING_ST}, 155 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_IGNORE, 156 BTA_HF_CLIENT_OPEN_ST}, 157 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE, 158 BTA_HF_CLIENT_INIT_ST}, 159 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 160 BTA_HF_CLIENT_OPENING_ST}, 161 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 162 BTA_HF_CLIENT_OPENING_ST}, 163 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 164 BTA_HF_CLIENT_OPENING_ST}, 165 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE, 166 BTA_HF_CLIENT_OPENING_ST}, 167 /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE, 168 BTA_HF_CLIENT_OPENING_ST}, 169 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE, 170 BTA_HF_CLIENT_INIT_ST}, 171 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 172 BTA_HF_CLIENT_OPENING_ST}, 173 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 174 BTA_HF_CLIENT_OPENING_ST}, 175 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 176 BTA_HF_CLIENT_OPENING_ST}, 177 }; 178 179 /* state table for open state */ 180 const uint8_t bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = { 181 /* Event Action 1 Action 2 182 Next state */ 183 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, 184 BTA_HF_CLIENT_OPEN_ST}, 185 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE, 186 BTA_HF_CLIENT_CLOSING_ST}, 187 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE, 188 BTA_HF_CLIENT_OPEN_ST}, 189 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE, 190 BTA_HF_CLIENT_OPEN_ST}, 191 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 192 BTA_HF_CLIENT_OPEN_ST}, 193 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE, 194 BTA_HF_CLIENT_INIT_ST}, 195 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 196 BTA_HF_CLIENT_OPEN_ST}, 197 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE, 198 BTA_HF_CLIENT_OPEN_ST}, 199 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE, 200 BTA_HF_CLIENT_OPEN_ST}, 201 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 202 BTA_HF_CLIENT_OPEN_ST}, 203 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 204 BTA_HF_CLIENT_OPEN_ST}, 205 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 206 BTA_HF_CLIENT_OPEN_ST}, 207 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE, 208 BTA_HF_CLIENT_OPEN_ST}, 209 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE, 210 BTA_HF_CLIENT_OPEN_ST}, 211 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE, 212 BTA_HF_CLIENT_OPEN_ST}, 213 }; 214 215 /* state table for closing state */ 216 const uint8_t bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = { 217 /* Event Action 1 Action 2 218 Next state */ 219 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, 220 BTA_HF_CLIENT_CLOSING_ST}, 221 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 222 BTA_HF_CLIENT_CLOSING_ST}, 223 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 224 BTA_HF_CLIENT_CLOSING_ST}, 225 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 226 BTA_HF_CLIENT_CLOSING_ST}, 227 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 228 BTA_HF_CLIENT_CLOSING_ST}, 229 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE, 230 BTA_HF_CLIENT_INIT_ST}, 231 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 232 BTA_HF_CLIENT_CLOSING_ST}, 233 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 234 BTA_HF_CLIENT_CLOSING_ST}, 235 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, 236 BTA_HF_CLIENT_CLOSING_ST}, 237 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, 238 BTA_HF_CLIENT_INIT_ST}, 239 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 240 BTA_HF_CLIENT_CLOSING_ST}, 241 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 242 BTA_HF_CLIENT_CLOSING_ST}, 243 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 244 BTA_HF_CLIENT_CLOSING_ST}, 245 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 246 BTA_HF_CLIENT_CLOSING_ST}, 247 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, 248 BTA_HF_CLIENT_CLOSING_ST}, 249 }; 250 251 /* type for state table */ 252 typedef const uint8_t (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS]; 253 254 /* state table */ 255 const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = { 256 bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open, 257 bta_hf_client_st_closing}; 258 259 /* HF Client control block */ 260 tBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr; 261 262 /* Event handler for the state machine */ 263 static const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event, 264 BTA_HfClientDisable}; 265 266 /******************************************************************************* 267 * 268 * Function bta_hf_client_cb_arr_init 269 * 270 * Description Initialize entire control block array set 271 * 272 * 273 * Returns void 274 * 275 ******************************************************************************/ 276 void bta_hf_client_cb_arr_init() { 277 memset(&bta_hf_client_cb_arr, 0, sizeof(tBTA_HF_CLIENT_CB_ARR)); 278 279 // reset the handles and make the CBs non-allocated 280 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 281 // Allocate the handles in increasing order of indices 282 bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i); 283 bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i; 284 } 285 } 286 287 /******************************************************************************* 288 * 289 * Function bta_hf_client_cb_init 290 * 291 * Description Initialize an HF_Client service control block. Assign the 292 * handle to cb->handle. 293 * 294 * 295 * 296 * Returns void 297 * 298 ******************************************************************************/ 299 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) { 300 APPL_TRACE_DEBUG("%s", __func__); 301 302 // Free any memory we need to explicity release 303 alarm_free(client_cb->collision_timer); 304 305 // Memset the rest of the block 306 memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB)); 307 308 // Re allocate any variables required 309 client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer"); 310 client_cb->handle = handle; 311 client_cb->sco_idx = BTM_INVALID_SCO_INDEX; 312 } 313 314 /******************************************************************************* 315 * 316 * Function bta_hf_client_resume_open 317 * 318 * Description Resume opening process. 319 * 320 * 321 * Returns void 322 * 323 ******************************************************************************/ 324 void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) { 325 APPL_TRACE_DEBUG("%s", __func__); 326 327 /* resume opening process. */ 328 if (client_cb->state == BTA_HF_CLIENT_INIT_ST) { 329 client_cb->state = BTA_HF_CLIENT_OPENING_ST; 330 tBTA_HF_CLIENT_DATA msg; 331 msg.hdr.layer_specific = client_cb->handle; 332 msg.api_open.bd_addr = client_cb->peer_addr; 333 msg.api_open.sec_mask = client_cb->cli_sec_mask; 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 const RawAddress& 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 osi_free_and_reset((void**)&client_cb->p_disc_db); 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_mloop(client_cb->collision_timer, 395 BTA_HF_CLIENT_COLLISION_TIMER_MS, 396 bta_hf_client_collision_timer_cback, (void*)client_cb); 397 } 398 } 399 400 /******************************************************************************* 401 * 402 * Function bta_hf_client_api_enable 403 * 404 * Description Handle an API enable event. 405 * 406 * 407 * Returns void 408 * 409 ******************************************************************************/ 410 tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback, 411 tBTA_SEC sec_mask, 412 tBTA_HF_CLIENT_FEAT features, 413 const char* p_service_name) { 414 /* If already registered then return error */ 415 if (bta_sys_is_register(BTA_ID_HS)) { 416 APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ..."); 417 return BTA_FAILURE; 418 } 419 420 /* register with BTA system manager */ 421 bta_sys_register(BTA_ID_HS, &bta_hf_client_reg); 422 423 /* reset the control blocks */ 424 bta_hf_client_cb_arr_init(); 425 426 bta_hf_client_cb_arr.p_cback = p_cback; 427 bta_hf_client_cb_arr.serv_sec_mask = sec_mask; 428 bta_hf_client_cb_arr.features = features; 429 430 /* create SDP records */ 431 bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name); 432 433 /* set same setting as AG does */ 434 BTM_WriteVoiceSettings(AG_VOICE_SETTINGS); 435 436 bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback); 437 438 /* Set the Audio service class bit */ 439 tBTA_UTL_COD cod; 440 cod.service = BTM_COD_SERVICE_AUDIO; 441 utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS); 442 443 /* start RFCOMM server */ 444 bta_hf_client_start_server(); 445 446 return BTA_SUCCESS; 447 } 448 449 /******************************************************************************* 450 * 451 * Function bta_hf_client_find_cb_by_handle 452 * 453 * Description Finds the control block by handle provided 454 * 455 * handle: Handle as obtained from BTA_HfClientOpen call 456 * 457 * 458 * Returns Control block corresponding to the handle and NULL if 459 * none exists 460 * 461 ******************************************************************************/ 462 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) { 463 // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES 464 if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) { 465 APPL_TRACE_ERROR("%s: handle out of range (%d, %d) %d", __func__, 1, 466 HF_CLIENT_MAX_DEVICES, handle); 467 return NULL; 468 } 469 470 // Check if the associated index is allocated. Index is (handle - 1). 471 if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated) 472 return &(bta_hf_client_cb_arr.cb[handle - 1]); 473 474 APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle); 475 return NULL; 476 } 477 478 /******************************************************************************* 479 * 480 * Function bta_hf_client_find_cb_by_bda 481 * 482 * Description Finds the control block by handle provided 483 * 484 * bda: address of the device to find the handle for. 485 * Since there can only be one HF connection for a device 486 * we should always find a unique block 487 * 488 * Returns Control block corresponding to the address and NULL if 489 * none exists 490 * 491 ******************************************************************************/ 492 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const RawAddress& peer_addr) { 493 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 494 // Check if the associated index is allocated and that BD ADDR matches 495 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 496 if (client_cb->is_allocated && peer_addr == client_cb->peer_addr) { 497 return client_cb; 498 } else { 499 APPL_TRACE_WARNING("%s: bdaddr mismatch for handle %d alloc %d", __func__, 500 i, client_cb->is_allocated); 501 } 502 } 503 APPL_TRACE_ERROR("%s: block not found", __func__); 504 return NULL; 505 } 506 507 /******************************************************************************* 508 * 509 * Function bta_hf_client_find_cb_by_rfc_handle 510 * 511 * Description Finds the control block by RFC handle provided. 512 * 513 * handle: RFC handle for the established connection 514 * 515 * 516 * Returns Control block corresponding to the handle and NULL if none 517 * exists 518 * 519 ******************************************************************************/ 520 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) { 521 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 522 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 523 bool is_allocated = client_cb->is_allocated; 524 uint16_t conn_handle = client_cb->conn_handle; 525 526 APPL_TRACE_DEBUG("%s: cb rfc_handle %d alloc %d conn_handle %d", __func__, 527 handle, is_allocated, conn_handle); 528 529 if (is_allocated && conn_handle == handle) { 530 return client_cb; 531 } 532 533 APPL_TRACE_WARNING("%s: no cb yet %d alloc %d conn_handle %d", __func__, 534 handle, is_allocated, conn_handle); 535 } 536 537 APPL_TRACE_ERROR("%s: no cb found for rfc handle %d", __func__, handle); 538 return NULL; 539 } 540 541 /******************************************************************************* 542 * 543 * Function bta_hf_client_find_cb_by_sco_handle 544 * 545 * Description Finds the control block by sco handle provided 546 * 547 * handle: sco handle 548 * 549 * 550 * Returns Control block corresponding to the sco handle and 551 * none if none exists 552 * 553 ******************************************************************************/ 554 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) { 555 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 556 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 557 if (client_cb->is_allocated && client_cb->sco_idx == handle) { 558 return client_cb; 559 } 560 } 561 APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle); 562 return NULL; 563 } 564 565 /******************************************************************************* 566 * 567 * Function bta_hf_client_allocate_handle 568 * 569 * Description Allocates a handle for the new BD ADDR that needs a new RF 570 * channel for HF connection. If the channel cannot be created 571 * for a reason then false is returned 572 * 573 * bd_addr: Address of the device for which this block is 574 * being created. Single device can only have one block. 575 * p_handle: OUT variable to store the outcome of allocate. If 576 * allocate failed then value is not valid 577 * 578 * 579 * Returns true if the creation of p_handle succeeded, false otherwise 580 * 581 ******************************************************************************/ 582 bool bta_hf_client_allocate_handle(const RawAddress& bd_addr, 583 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 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 VLOG(1) << __func__ << ": notifying state change to " << in_state << " -> " 748 << client_cb->state << " device " << client_cb->peer_addr; 749 tBTA_HF_CLIENT evt; 750 memset(&evt, 0, sizeof(evt)); 751 evt.bd_addr = client_cb->peer_addr; 752 if (client_cb->state == BTA_HF_CLIENT_INIT_ST) { 753 bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt); 754 APPL_TRACE_DEBUG("%s: marking CB handle %d to false", __func__, client_cb->handle); 755 client_cb->is_allocated = false; 756 } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) { 757 evt.open.handle = client_cb->handle; 758 bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt); 759 } 760 } 761 762 VLOG(2) << __func__ << ": device " << client_cb->peer_addr 763 << "state change: [" << bta_hf_client_state_str(in_state) << "] -> [" 764 << bta_hf_client_state_str(client_cb->state) << "] after Event [" 765 << bta_hf_client_evt_str(in_event) << "]"; 766 } 767 768 static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) { 769 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE; 770 771 tBTA_HF_CLIENT_DATA p_data; 772 p_data.hdr.layer_specific = client_cb->handle; 773 bta_hf_client_sco_listen(&p_data); 774 bta_hf_client_send_at_bia(client_cb); 775 bta_hf_client_send_at_ccwa(client_cb, true); 776 bta_hf_client_send_at_cmee(client_cb, true); 777 bta_hf_client_send_at_cops(client_cb, false); 778 bta_hf_client_send_at_btrh(client_cb, true, 0); 779 bta_hf_client_send_at_clip(client_cb, true); 780 } 781 782 /******************************************************************************* 783 * 784 * Function bta_hf_client_slc_seq 785 * 786 * Description Handles AT commands sequence required for SLC creation 787 * 788 * 789 * Returns void 790 * 791 ******************************************************************************/ 792 void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) { 793 APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u", 794 client_cb->at_cb.current_cmd); 795 796 if (error) { 797 /* SLC establishment error, sent close rfcomm event */ 798 APPL_TRACE_ERROR( 799 "HFPClient: Failed to create SLC due to AT error, disconnecting (%u)", 800 client_cb->at_cb.current_cmd); 801 802 tBTA_HF_CLIENT_DATA msg; 803 msg.hdr.layer_specific = client_cb->handle; 804 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg); 805 return; 806 } 807 808 if (client_cb->svc_conn) { 809 APPL_TRACE_WARNING("%s: SLC already connected for CB handle %d", __func__, 810 client_cb->handle); 811 return; 812 } 813 814 switch (client_cb->at_cb.current_cmd) { 815 case BTA_HF_CLIENT_AT_NONE: 816 bta_hf_client_send_at_brsf(client_cb, bta_hf_client_cb_arr.features); 817 break; 818 819 case BTA_HF_CLIENT_AT_BRSF: 820 if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_CODEC) && 821 (client_cb->peer_features & BTA_HF_CLIENT_PEER_CODEC)) { 822 bta_hf_client_send_at_bac(client_cb); 823 break; 824 } 825 826 bta_hf_client_send_at_cind(client_cb, false); 827 break; 828 829 case BTA_HF_CLIENT_AT_BAC: 830 bta_hf_client_send_at_cind(client_cb, false); 831 break; 832 833 case BTA_HF_CLIENT_AT_CIND: 834 bta_hf_client_send_at_cind(client_cb, true); 835 break; 836 837 case BTA_HF_CLIENT_AT_CIND_STATUS: 838 bta_hf_client_send_at_cmer(client_cb, true); 839 break; 840 841 case BTA_HF_CLIENT_AT_CMER: 842 if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY && 843 bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) { 844 bta_hf_client_send_at_chld(client_cb, '?', 0); 845 } else { 846 tBTA_HF_CLIENT_DATA msg; 847 msg.hdr.layer_specific = client_cb->handle; 848 bta_hf_client_svc_conn_open(&msg); 849 send_post_slc_cmd(client_cb); 850 } 851 break; 852 853 case BTA_HF_CLIENT_AT_CHLD: { 854 tBTA_HF_CLIENT_DATA msg; 855 msg.hdr.layer_specific = client_cb->handle; 856 bta_hf_client_svc_conn_open(&msg); 857 send_post_slc_cmd(client_cb); 858 break; 859 } 860 861 default: { 862 /* If happen there is a bug in SLC creation procedure... */ 863 APPL_TRACE_ERROR( 864 "HFPClient: Failed to create SLCdue to unexpected AT command, " 865 "disconnecting (%u)", 866 client_cb->at_cb.current_cmd); 867 868 tBTA_HF_CLIENT_DATA msg; 869 msg.hdr.layer_specific = client_cb->handle; 870 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg); 871 break; 872 } 873 } 874 } 875 876 #ifndef CASE_RETURN_STR 877 #define CASE_RETURN_STR(const) \ 878 case const: \ 879 return #const; 880 #endif 881 882 static const char* bta_hf_client_evt_str(uint16_t event) { 883 switch (event) { 884 CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT) 885 CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT) 886 CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT) 887 CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT) 888 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT) 889 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT) 890 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT) 891 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT) 892 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT) 893 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT) 894 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT) 895 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT) 896 CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT) 897 CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT) 898 CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT) 899 CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT) 900 CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT) 901 default: 902 return "Unknown HF Client Event"; 903 } 904 } 905 906 static const char* bta_hf_client_state_str(uint8_t state) { 907 switch (state) { 908 CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST) 909 CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST) 910 CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST) 911 CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST) 912 default: 913 return "Unknown HF Client State"; 914 } 915 } 916 917 void bta_hf_client_dump_statistics(int fd) { 918 dprintf(fd, "\nBluetooth HF Client BTA Statistics\n"); 919 920 // We dump statistics for all control blocks 921 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { 922 tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; 923 if (!client_cb->is_allocated) { 924 // Skip the blocks which are not allocated 925 continue; 926 } 927 928 dprintf(fd, " Control block #%d\n", i + 1); 929 930 uint8_t* a = client_cb->peer_addr.address; 931 // Device name 932 dprintf(fd, " Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n", a[0], a[1], 933 a[2], a[3], a[4], a[5]); 934 935 // State machine state 936 dprintf(fd, " State Machine State: %s\n", 937 bta_hf_client_state_str(client_cb->state)); 938 939 // Local RFC channelfor communication 940 dprintf(fd, " RFCOMM Channel (local) %d\n", client_cb->conn_handle); 941 942 // BTA Handle shared between BTA and client (ex BTIF) 943 dprintf(fd, " BTA Generated handle %d\n", client_cb->handle); 944 } 945 } 946