1 /****************************************************************************** 2 * 3 * Copyright (c) 2014 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 <string.h> 21 #include <stdlib.h> 22 23 #include "osi/include/osi.h" 24 #include "osi/include/properties.h" 25 #include "bt_utils.h" 26 #include "bta_api.h" 27 #include "bta_sys.h" 28 #include "bta_hf_client_api.h" 29 #include "bta_hf_client_int.h" 30 31 /* uncomment to enable extra debug */ 32 /* #define BTA_HF_CLIENT_DEBUG TRUE */ 33 34 #ifndef BTA_HF_CLIENT_DEBUG 35 #define BTA_HF_CLIENT_DEBUG FALSE 36 #endif 37 38 extern fixed_queue_t *btu_bta_alarm_queue; 39 40 #if BTA_HF_CLIENT_DEBUG == TRUE 41 static char *bta_hf_client_evt_str(UINT16 event); 42 static char *bta_hf_client_state_str(UINT8 state); 43 #endif 44 45 /* state machine states */ 46 enum 47 { 48 BTA_HF_CLIENT_INIT_ST, 49 BTA_HF_CLIENT_OPENING_ST, 50 BTA_HF_CLIENT_OPEN_ST, 51 BTA_HF_CLIENT_CLOSING_ST 52 }; 53 54 /* state machine action enumeration list */ 55 enum 56 { 57 BTA_HF_CLIENT_REGISTER, 58 BTA_HF_CLIENT_DEREGISTER, 59 BTA_HF_CLIENT_START_DEREG, 60 BTA_HF_CLIENT_RFC_DO_CLOSE, 61 BTA_HF_CLIENT_START_CLOSE, 62 BTA_HF_CLIENT_START_OPEN, 63 BTA_HF_CLIENT_RFC_ACP_OPEN, 64 BTA_HF_CLIENT_SCO_LISTEN, 65 BTA_HF_CLIENT_SCO_CONN_OPEN, 66 BTA_HF_CLIENT_SCO_CONN_CLOSE, 67 BTA_HF_CLIENT_SCO_OPEN, 68 BTA_HF_CLIENT_SCO_CLOSE, 69 BTA_HF_CLIENT_SCO_SHUTDOWN, 70 BTA_HF_CLIENT_FREE_DB, 71 BTA_HF_CLIENT_OPEN_FAIL, 72 BTA_HF_CLIENT_RFC_OPEN, 73 BTA_HF_CLIENT_RFC_FAIL, 74 BTA_HF_CLIENT_DISC_INT_RES, 75 BTA_HF_CLIENT_RFC_DO_OPEN, 76 BTA_HF_CLIENT_DISC_FAIL, 77 BTA_HF_CLIENT_RFC_CLOSE, 78 BTA_HF_CLIENT_RFC_DATA, 79 BTA_HF_CLIENT_DISC_ACP_RES, 80 BTA_HF_CLIENT_SVC_CONN_OPEN, 81 BTA_HF_CLIENT_SEND_AT_CMD, 82 BTA_HF_CLIENT_NUM_ACTIONS, 83 }; 84 85 #define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS 86 87 /* type for action functions */ 88 typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA *p_data); 89 90 /* action functions table, indexed with action enum */ 91 const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = 92 { 93 /* BTA_HF_CLIENT_REGISTER */ bta_hf_client_register, 94 /* BTA_HF_CLIENT_DEREGISTER */ bta_hf_client_deregister, 95 /* BTA_HF_CLIENT_START_DEREG */ bta_hf_client_start_dereg, 96 /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close, 97 /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close, 98 /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open, 99 /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open, 100 /* BTA_HF_CLIENT_SCO_LISTEN */ bta_hf_client_sco_listen, 101 /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open, 102 /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close, 103 /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open, 104 /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close, 105 /* BTA_HF_CLIENT_SCO_SHUTDOWN */ bta_hf_client_sco_shutdown, 106 /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db, 107 /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail, 108 /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open, 109 /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail, 110 /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res, 111 /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open, 112 /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail, 113 /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close, 114 /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data, 115 /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res, 116 /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open, 117 /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd, 118 }; 119 120 /* state table information */ 121 #define BTA_HF_CLIENT_ACTIONS 2 /* number of actions */ 122 #define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */ 123 #define BTA_HF_CLIENT_NUM_COLS 3 /* number of columns in state tables */ 124 125 /* state table for init state */ 126 const UINT8 bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = 127 { 128 /* Event Action 1 Action 2 Next state */ 129 /* API_REGISTER_EVT */ {BTA_HF_CLIENT_REGISTER, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 130 /* API_DEREGISTER_EVT */ {BTA_HF_CLIENT_DEREGISTER, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 131 /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 132 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 133 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 134 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 135 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_SCO_LISTEN, BTA_HF_CLIENT_OPEN_ST}, 136 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 137 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 138 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 139 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 140 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 141 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 142 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 143 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 144 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 145 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 146 }; 147 148 /* state table for opening state */ 149 const UINT8 bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = 150 { 151 /* Event Action 1 Action 2 Next state */ 152 /* API_REGISTER_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 153 /* API_DEREGISTER_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_START_DEREG, BTA_HF_CLIENT_CLOSING_ST}, 154 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 155 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 156 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 157 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 158 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_SCO_LISTEN, BTA_HF_CLIENT_OPEN_ST}, 159 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 160 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 161 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 162 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 163 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 164 /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 165 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 166 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 167 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 168 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, 169 }; 170 171 /* state table for open state */ 172 const UINT8 bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = 173 { 174 /* Event Action 1 Action 2 Next state */ 175 /* API_REGISTER_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 176 /* API_DEREGISTER_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_START_DEREG, BTA_HF_CLIENT_CLOSING_ST}, 177 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 178 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 179 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 180 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 181 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 182 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 183 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 184 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 185 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 186 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 187 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 188 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 189 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 190 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 191 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, 192 }; 193 194 /* state table for closing state */ 195 const UINT8 bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = 196 { 197 /* Event Action 1 Action 2 Next state */ 198 /* API_REGISTER_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 199 /* API_DEREGISTER_EVT */ {BTA_HF_CLIENT_START_DEREG, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 200 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 201 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 202 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 203 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 204 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 205 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 206 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 207 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 208 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 209 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, 210 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 211 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 212 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 213 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 214 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, 215 }; 216 217 /* type for state table */ 218 typedef const UINT8 (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS]; 219 220 /* state table */ 221 const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = 222 { 223 bta_hf_client_st_init, 224 bta_hf_client_st_opening, 225 bta_hf_client_st_open, 226 bta_hf_client_st_closing 227 }; 228 229 /* HF Client control block */ 230 tBTA_HF_CLIENT_CB bta_hf_client_cb; 231 232 /******************************************************************************* 233 ** 234 ** Function bta_hf_client_scb_init 235 ** 236 ** Description Initialize an HF_Client service control block. 237 ** 238 ** 239 ** Returns void 240 ** 241 *******************************************************************************/ 242 void bta_hf_client_scb_init(void) 243 { 244 APPL_TRACE_DEBUG("%s", __FUNCTION__); 245 246 alarm_free(bta_hf_client_cb.scb.collision_timer); 247 alarm_free(bta_hf_client_cb.scb.at_cb.resp_timer); 248 alarm_free(bta_hf_client_cb.scb.at_cb.hold_timer); 249 memset(&bta_hf_client_cb.scb, 0, sizeof(tBTA_HF_CLIENT_SCB)); 250 bta_hf_client_cb.scb.collision_timer = 251 alarm_new("bta_hf_client.scb_collision_timer"); 252 bta_hf_client_cb.scb.sco_idx = BTM_INVALID_SCO_INDEX; 253 bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD; 254 } 255 256 /******************************************************************************* 257 ** 258 ** Function bta_hf_client_scb_disable 259 ** 260 ** Description Disable a service control block. 261 ** 262 ** 263 ** Returns void 264 ** 265 *******************************************************************************/ 266 void bta_hf_client_scb_disable(void) 267 { 268 APPL_TRACE_DEBUG("%s", __FUNCTION__); 269 270 bta_hf_client_scb_init(); 271 272 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_DISABLE_EVT, NULL); 273 } 274 275 /******************************************************************************* 276 ** 277 ** Function bta_hf_client_resume_open 278 ** 279 ** Description Resume opening process. 280 ** 281 ** 282 ** Returns void 283 ** 284 *******************************************************************************/ 285 void bta_hf_client_resume_open (void) 286 { 287 APPL_TRACE_DEBUG ("%s", __FUNCTION__); 288 289 /* resume opening process. */ 290 if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_INIT_ST) 291 { 292 bta_hf_client_cb.scb.state = BTA_HF_CLIENT_OPENING_ST; 293 bta_hf_client_start_open (NULL); 294 } 295 } 296 297 /******************************************************************************* 298 ** 299 ** Function bta_hf_client_collision_timer_cback 300 ** 301 ** Description HF Client connection collision timer callback 302 ** 303 ** 304 ** Returns void 305 ** 306 *******************************************************************************/ 307 static void bta_hf_client_collision_timer_cback(UNUSED_ATTR void *data) 308 { 309 APPL_TRACE_DEBUG("%s", __FUNCTION__); 310 311 /* If the peer haven't opened connection, restart opening process */ 312 bta_hf_client_resume_open(); 313 } 314 315 /******************************************************************************* 316 ** 317 ** Function bta_hf_client_collision_cback 318 ** 319 ** Description Get notified about collision. 320 ** 321 ** 322 ** Returns void 323 ** 324 *******************************************************************************/ 325 void bta_hf_client_collision_cback (tBTA_SYS_CONN_STATUS status, UINT8 id, 326 UINT8 app_id, BD_ADDR peer_addr) 327 { 328 UNUSED(status); 329 UNUSED(app_id); 330 UNUSED(peer_addr); 331 332 if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_OPENING_ST) 333 { 334 if (id == BTA_ID_SYS) /* ACL collision */ 335 { 336 APPL_TRACE_WARNING ("HF Client found collision (ACL) ..."); 337 } 338 else if (id == BTA_ID_HS) /* RFCOMM collision */ 339 { 340 APPL_TRACE_WARNING ("HF Client found collision (RFCOMM) ..."); 341 } 342 else 343 { 344 APPL_TRACE_WARNING ("HF Client found collision (\?\?\?) ..."); 345 } 346 347 bta_hf_client_cb.scb.state = BTA_HF_CLIENT_INIT_ST; 348 349 /* Cancel SDP if it had been started. */ 350 if(bta_hf_client_cb.scb.p_disc_db) 351 { 352 (void)SDP_CancelServiceSearch (bta_hf_client_cb.scb.p_disc_db); 353 bta_hf_client_free_db(NULL); 354 } 355 356 /* reopen registered server */ 357 /* Collision may be detected before or after we close servers. */ 358 bta_hf_client_start_server(); 359 360 /* Start timer to handle connection opening restart */ 361 alarm_set_on_queue(bta_hf_client_cb.scb.collision_timer, 362 BTA_HF_CLIENT_COLLISION_TIMER_MS, 363 bta_hf_client_collision_timer_cback, 364 NULL, 365 btu_bta_alarm_queue); 366 } 367 } 368 369 /******************************************************************************* 370 ** 371 ** Function bta_hf_client_api_enable 372 ** 373 ** Description Handle an API enable event. 374 ** 375 ** 376 ** Returns void 377 ** 378 *******************************************************************************/ 379 static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data) 380 { 381 char value[PROPERTY_VALUE_MAX]; 382 383 /* initialize control block */ 384 memset(&bta_hf_client_cb, 0, sizeof(tBTA_HF_CLIENT_CB)); 385 386 /* store callback function */ 387 bta_hf_client_cb.p_cback = p_data->api_enable.p_cback; 388 389 /* check if mSBC support enabled */ 390 osi_property_get("ro.bluetooth.hfp.ver", value, "0"); 391 if (strcmp(value,"1.6") == 0) 392 { 393 bta_hf_client_cb.msbc_enabled = TRUE; 394 } 395 396 bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD; 397 398 /* set same setting as AG does */ 399 BTM_WriteVoiceSettings(AG_VOICE_SETTINGS); 400 401 bta_sys_collision_register (BTA_ID_HS, bta_hf_client_collision_cback); 402 403 /* call callback with enable event */ 404 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_ENABLE_EVT, NULL); 405 } 406 407 /******************************************************************************* 408 ** 409 ** Function bta_hf_client_api_disable 410 ** 411 ** Description Handle an API disable event. 412 ** 413 ** 414 ** Returns void 415 ** 416 *******************************************************************************/ 417 static void bta_hf_client_api_disable(tBTA_HF_CLIENT_DATA *p_data) 418 { 419 if (!bta_sys_is_register (BTA_ID_HS)) 420 { 421 APPL_TRACE_ERROR("BTA HF Client is already disabled, ignoring ..."); 422 return; 423 } 424 425 /* De-register with BTA system manager */ 426 bta_sys_deregister(BTA_ID_HS); 427 428 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_DEREGISTER_EVT, p_data); 429 430 bta_sys_collision_register (BTA_ID_HS, NULL); 431 } 432 433 /******************************************************************************* 434 ** 435 ** Function bta_hf_client_hdl_event 436 ** 437 ** Description Data HF Client main event handling function. 438 ** 439 ** 440 ** Returns BOOLEAN 441 ** 442 *******************************************************************************/ 443 BOOLEAN bta_hf_client_hdl_event(BT_HDR *p_msg) 444 { 445 #if BTA_HF_CLIENT_DEBUG == TRUE 446 APPL_TRACE_DEBUG("bta_hf_client_hdl_event %s (0x%x)", bta_hf_client_evt_str(p_msg->event), p_msg->event); 447 #endif 448 449 switch (p_msg->event) 450 { 451 /* handle enable event */ 452 case BTA_HF_CLIENT_API_ENABLE_EVT: 453 bta_hf_client_api_enable((tBTA_HF_CLIENT_DATA *) p_msg); 454 break; 455 456 /* handle disable event */ 457 case BTA_HF_CLIENT_API_DISABLE_EVT: 458 bta_hf_client_api_disable((tBTA_HF_CLIENT_DATA *) p_msg); 459 break; 460 461 default: 462 bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA *) p_msg); 463 break; 464 } 465 return TRUE; 466 } 467 468 /******************************************************************************* 469 ** 470 ** Function bta_hf_client_sm_execute 471 ** 472 ** Description State machine event handling function for HF Client 473 ** 474 ** 475 ** Returns void 476 ** 477 *******************************************************************************/ 478 void bta_hf_client_sm_execute(UINT16 event, tBTA_HF_CLIENT_DATA *p_data) 479 { 480 tBTA_HF_CLIENT_ST_TBL state_table; 481 UINT8 action; 482 int i; 483 484 #if BTA_HF_CLIENT_DEBUG == TRUE 485 UINT16 in_event = event; 486 UINT8 in_state = bta_hf_client_cb.scb.state; 487 488 /* Ignore displaying of AT results when not connected (Ignored in state machine) */ 489 if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_OPEN_ST) 490 { 491 APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)", 492 bta_hf_client_cb.scb.state, 493 bta_hf_client_state_str(bta_hf_client_cb.scb.state), 494 event, bta_hf_client_evt_str(event)); 495 } 496 #endif 497 498 event &= 0x00FF; 499 if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) 500 { 501 APPL_TRACE_ERROR("HF Client evt out of range, ignoring..."); 502 return; 503 } 504 505 /* look up the state table for the current state */ 506 state_table = bta_hf_client_st_tbl[bta_hf_client_cb.scb.state]; 507 508 /* set next state */ 509 bta_hf_client_cb.scb.state = state_table[event][BTA_HF_CLIENT_NEXT_STATE]; 510 511 /* execute action functions */ 512 for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) 513 { 514 if ((action = state_table[event][i]) != BTA_HF_CLIENT_IGNORE) 515 { 516 (*bta_hf_client_action[action])(p_data); 517 } 518 else 519 { 520 break; 521 } 522 } 523 524 #if BTA_HF_CLIENT_DEBUG == TRUE 525 if (bta_hf_client_cb.scb.state != in_state) 526 { 527 APPL_TRACE_EVENT("BTA HF Client State Change: [%s] -> [%s] after Event [%s]", 528 bta_hf_client_state_str(in_state), 529 bta_hf_client_state_str(bta_hf_client_cb.scb.state), 530 bta_hf_client_evt_str(in_event)); 531 } 532 #endif 533 } 534 535 static void send_post_slc_cmd(void) 536 { 537 bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE; 538 539 bta_hf_client_send_at_bia(); 540 bta_hf_client_send_at_ccwa(TRUE); 541 bta_hf_client_send_at_cmee(TRUE); 542 bta_hf_client_send_at_cops(FALSE); 543 bta_hf_client_send_at_btrh(TRUE, 0); 544 bta_hf_client_send_at_clip(TRUE); 545 } 546 547 /******************************************************************************* 548 ** 549 ** Function bta_hf_client_slc_seq 550 ** 551 ** Description Handles AT commands sequence required for SLC creation 552 ** 553 ** 554 ** Returns void 555 ** 556 *******************************************************************************/ 557 void bta_hf_client_slc_seq(BOOLEAN error) 558 { 559 APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u", bta_hf_client_cb.scb.at_cb.current_cmd); 560 561 if (error) { 562 /* SLC establishment error, sent close rfcomm event */ 563 APPL_TRACE_ERROR("HFPClient: Failed to create SLC due to AT error, disconnecting (%u)", 564 bta_hf_client_cb.scb.at_cb.current_cmd); 565 566 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL); 567 return; 568 } 569 570 if (bta_hf_client_cb.scb.svc_conn) 571 return; 572 573 switch (bta_hf_client_cb.scb.at_cb.current_cmd) 574 { 575 case BTA_HF_CLIENT_AT_NONE: 576 bta_hf_client_send_at_brsf(); 577 break; 578 579 case BTA_HF_CLIENT_AT_BRSF: 580 if ((bta_hf_client_cb.scb.features & BTA_HF_CLIENT_FEAT_CODEC) 581 && (bta_hf_client_cb.scb.peer_features & BTA_HF_CLIENT_PEER_CODEC)) 582 { 583 bta_hf_client_send_at_bac(); 584 break; 585 } 586 587 bta_hf_client_send_at_cind(FALSE); 588 break; 589 590 case BTA_HF_CLIENT_AT_BAC: 591 bta_hf_client_send_at_cind(FALSE); 592 break; 593 594 case BTA_HF_CLIENT_AT_CIND: 595 bta_hf_client_send_at_cind(TRUE); 596 break; 597 598 case BTA_HF_CLIENT_AT_CIND_STATUS: 599 bta_hf_client_send_at_cmer(TRUE); 600 break; 601 602 case BTA_HF_CLIENT_AT_CMER: 603 if (bta_hf_client_cb.scb.peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY 604 && bta_hf_client_cb.scb.features & BTA_HF_CLIENT_FEAT_3WAY) 605 { 606 bta_hf_client_send_at_chld('?', 0); 607 } 608 else 609 { 610 bta_hf_client_svc_conn_open(NULL); 611 send_post_slc_cmd(); 612 } 613 break; 614 615 case BTA_HF_CLIENT_AT_CHLD: 616 bta_hf_client_svc_conn_open(NULL); 617 send_post_slc_cmd(); 618 break; 619 620 default: 621 /* If happen there is a bug in SLC creation procedure... */ 622 APPL_TRACE_ERROR("HFPClient: Failed to create SLCdue to unexpected AT command, disconnecting (%u)", 623 bta_hf_client_cb.scb.at_cb.current_cmd); 624 625 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL); 626 break; 627 } 628 } 629 630 #if BTA_HF_CLIENT_DEBUG == TRUE 631 632 #ifndef CASE_RETURN_STR 633 #define CASE_RETURN_STR(const) case const: return #const; 634 #endif 635 636 static char *bta_hf_client_evt_str(UINT16 event) 637 { 638 switch (event) 639 { 640 CASE_RETURN_STR(BTA_HF_CLIENT_API_REGISTER_EVT) 641 CASE_RETURN_STR(BTA_HF_CLIENT_API_DEREGISTER_EVT) 642 CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT) 643 CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT) 644 CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT) 645 CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT) 646 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT) 647 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT) 648 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT) 649 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT) 650 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT) 651 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT) 652 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT) 653 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT) 654 CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT) 655 CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT) 656 CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT) 657 CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT) 658 CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT) 659 default: 660 return "Unknown HF Client Event"; 661 } 662 } 663 664 static char *bta_hf_client_state_str(UINT8 state) 665 { 666 switch (state) 667 { 668 CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST) 669 CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST) 670 CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST) 671 CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST) 672 default: 673 return "Unknown HF Client State"; 674 } 675 } 676 #endif 677