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