1 /****************************************************************************** 2 * 3 * Copyright (C) 2003-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This is the main implementation file for the BTA audio gateway. 22 * 23 ******************************************************************************/ 24 25 #include <string.h> 26 27 #include "bta_ag_co.h" 28 #include "bta_ag_int.h" 29 #include "bta_api.h" 30 #include "bta_sys.h" 31 #include "osi/include/osi.h" 32 #include "utl.h" 33 34 /***************************************************************************** 35 * Constants and types 36 ****************************************************************************/ 37 #ifndef BTA_AG_DEBUG 38 #define BTA_AG_DEBUG FALSE 39 #endif 40 41 extern fixed_queue_t* btu_bta_alarm_queue; 42 43 #if (BTA_AG_DEBUG == TRUE) 44 static char* bta_ag_evt_str(uint16_t event, tBTA_AG_RES result); 45 static char* bta_ag_state_str(uint8_t state); 46 #endif 47 48 /* state machine states */ 49 enum { BTA_AG_INIT_ST, BTA_AG_OPENING_ST, BTA_AG_OPEN_ST, BTA_AG_CLOSING_ST }; 50 51 /* state machine action enumeration list */ 52 enum { 53 BTA_AG_REGISTER, 54 BTA_AG_DEREGISTER, 55 BTA_AG_START_OPEN, 56 BTA_AG_RFC_DO_OPEN, 57 BTA_AG_RFC_DO_CLOSE, 58 BTA_AG_START_DEREG, 59 BTA_AG_START_CLOSE, 60 BTA_AG_RFC_OPEN, 61 BTA_AG_OPEN_FAIL, 62 BTA_AG_RFC_ACP_OPEN, 63 BTA_AG_RFC_CLOSE, 64 BTA_AG_RFC_FAIL, 65 BTA_AG_RFC_DATA, 66 BTA_AG_DISC_INT_RES, 67 BTA_AG_DISC_FAIL, 68 BTA_AG_DISC_ACP_RES, 69 BTA_AG_FREE_DB, 70 BTA_AG_SCO_CONN_OPEN, 71 BTA_AG_SCO_CONN_CLOSE, 72 BTA_AG_SCO_LISTEN, 73 BTA_AG_SCO_OPEN, 74 BTA_AG_SCO_CLOSE, 75 BTA_AG_SCO_SHUTDOWN, 76 BTA_AG_POST_SCO_OPEN, 77 BTA_AG_POST_SCO_CLOSE, 78 BTA_AG_SVC_CONN_OPEN, 79 BTA_AG_RESULT, 80 BTA_AG_SETCODEC, 81 BTA_AG_SEND_RING, 82 BTA_AG_CI_SCO_DATA, 83 BTA_AG_CI_RX_DATA, 84 BTA_AG_RCVD_SLC_READY, 85 BTA_AG_NUM_ACTIONS 86 }; 87 88 #define BTA_AG_IGNORE BTA_AG_NUM_ACTIONS 89 90 /* type for action functions */ 91 typedef void (*tBTA_AG_ACTION)(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data); 92 93 /* action functions */ 94 const tBTA_AG_ACTION bta_ag_action[] = { 95 bta_ag_register, bta_ag_deregister, bta_ag_start_open, 96 bta_ag_rfc_do_open, bta_ag_rfc_do_close, bta_ag_start_dereg, 97 bta_ag_start_close, bta_ag_rfc_open, bta_ag_open_fail, 98 bta_ag_rfc_acp_open, bta_ag_rfc_close, bta_ag_rfc_fail, 99 bta_ag_rfc_data, bta_ag_disc_int_res, bta_ag_disc_fail, 100 bta_ag_disc_acp_res, bta_ag_free_db, bta_ag_sco_conn_open, 101 bta_ag_sco_conn_close, bta_ag_sco_listen, bta_ag_sco_open, 102 bta_ag_sco_close, bta_ag_sco_shutdown, bta_ag_post_sco_open, 103 bta_ag_post_sco_close, bta_ag_svc_conn_open, bta_ag_result, 104 bta_ag_setcodec, bta_ag_send_ring, bta_ag_ci_sco_data, 105 bta_ag_ci_rx_data, bta_ag_rcvd_slc_ready}; 106 107 /* state table information */ 108 #define BTA_AG_ACTIONS 2 /* number of actions */ 109 #define BTA_AG_NEXT_STATE 2 /* position of next state */ 110 #define BTA_AG_NUM_COLS 3 /* number of columns in state tables */ 111 112 /* state table for init state */ 113 const uint8_t bta_ag_st_init[][BTA_AG_NUM_COLS] = { 114 /* Event Action 1 Action 2 Next state */ 115 /* API_REGISTER_EVT */ {BTA_AG_REGISTER, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 116 /* API_DEREGISTER_EVT */ {BTA_AG_DEREGISTER, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 117 /* API_OPEN_EVT */ {BTA_AG_START_OPEN, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 118 /* API_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 119 /* API_AUDIO_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 120 /* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 121 /* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 122 /* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 123 /* RFC_OPEN_EVT */ {BTA_AG_RFC_ACP_OPEN, BTA_AG_SCO_LISTEN, BTA_AG_OPEN_ST}, 124 /* RFC_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 125 /* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 126 /* RFC_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 127 /* SCO_OPEN_EVT */ {BTA_AG_SCO_CONN_OPEN, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 128 /* SCO_CLOSE_EVT */ {BTA_AG_SCO_CONN_CLOSE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 129 /* DISC_ACP_RES_EVT */ {BTA_AG_FREE_DB, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 130 /* DISC_INT_RES_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 131 /* DISC_OK_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 132 /* DISC_FAIL_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 133 /* CI_RX_WRITE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 134 /* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 135 /* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 136 /* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 137 /* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}}; 138 139 /* state table for opening state */ 140 const uint8_t bta_ag_st_opening[][BTA_AG_NUM_COLS] = { 141 /* Event Action 1 Action 2 Next state */ 142 /* API_REGISTER_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 143 /* API_DEREGISTER_EVT */ {BTA_AG_RFC_DO_CLOSE, BTA_AG_START_DEREG, 144 BTA_AG_CLOSING_ST}, 145 /* API_OPEN_EVT */ {BTA_AG_OPEN_FAIL, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 146 /* API_CLOSE_EVT */ {BTA_AG_RFC_DO_CLOSE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 147 /* API_AUDIO_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 148 /* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 149 /* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 150 /* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 151 /* RFC_OPEN_EVT */ {BTA_AG_RFC_OPEN, BTA_AG_SCO_LISTEN, BTA_AG_OPEN_ST}, 152 /* RFC_CLOSE_EVT */ {BTA_AG_RFC_FAIL, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 153 /* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 154 /* RFC_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 155 /* SCO_OPEN_EVT */ {BTA_AG_SCO_CONN_OPEN, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 156 /* SCO_CLOSE_EVT */ {BTA_AG_SCO_CONN_CLOSE, BTA_AG_IGNORE, 157 BTA_AG_OPENING_ST}, 158 /* DISC_ACP_RES_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 159 /* DISC_INT_RES_EVT */ {BTA_AG_DISC_INT_RES, BTA_AG_IGNORE, 160 BTA_AG_OPENING_ST}, 161 /* DISC_OK_EVT */ {BTA_AG_RFC_DO_OPEN, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 162 /* DISC_FAIL_EVT */ {BTA_AG_DISC_FAIL, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 163 /* CI_RX_WRITE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 164 /* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 165 /* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 166 /* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, 167 /* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}}; 168 169 /* state table for open state */ 170 const uint8_t bta_ag_st_open[][BTA_AG_NUM_COLS] = { 171 /* Event Action 1 Action 2 Next state */ 172 /* API_REGISTER_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 173 /* API_DEREGISTER_EVT */ {BTA_AG_START_CLOSE, BTA_AG_START_DEREG, 174 BTA_AG_CLOSING_ST}, 175 /* API_OPEN_EVT */ {BTA_AG_OPEN_FAIL, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 176 /* API_CLOSE_EVT */ {BTA_AG_START_CLOSE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 177 /* API_AUDIO_OPEN_EVT */ {BTA_AG_SCO_OPEN, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 178 /* API_AUDIO_CLOSE_EVT */ {BTA_AG_SCO_CLOSE, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 179 /* API_RESULT_EVT */ {BTA_AG_RESULT, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 180 /* API_SETCODEC_EVT */ {BTA_AG_SETCODEC, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 181 /* RFC_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 182 /* RFC_CLOSE_EVT */ {BTA_AG_RFC_CLOSE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 183 /* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 184 /* RFC_DATA_EVT */ {BTA_AG_RFC_DATA, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 185 /* SCO_OPEN_EVT */ {BTA_AG_SCO_CONN_OPEN, BTA_AG_POST_SCO_OPEN, 186 BTA_AG_OPEN_ST}, 187 /* SCO_CLOSE_EVT */ {BTA_AG_SCO_CONN_CLOSE, BTA_AG_POST_SCO_CLOSE, 188 BTA_AG_OPEN_ST}, 189 /* DISC_ACP_RES_EVT */ {BTA_AG_DISC_ACP_RES, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 190 /* DISC_INT_RES_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 191 /* DISC_OK_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 192 /* DISC_FAIL_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 193 /* CI_RX_WRITE_EVT */ {BTA_AG_CI_RX_DATA, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 194 /* RING_TOUT_EVT */ {BTA_AG_SEND_RING, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 195 /* SVC_TOUT_EVT */ {BTA_AG_START_CLOSE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 196 /* CI_SCO_DATA_EVT */ {BTA_AG_CI_SCO_DATA, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, 197 /* CI_SLC_READY_EVT */ 198 {BTA_AG_RCVD_SLC_READY, BTA_AG_IGNORE, BTA_AG_OPEN_ST}}; 199 200 /* state table for closing state */ 201 const uint8_t bta_ag_st_closing[][BTA_AG_NUM_COLS] = { 202 /* Event Action 1 Action 2 Next state */ 203 /* API_REGISTER_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 204 /* API_DEREGISTER_EVT */ {BTA_AG_START_DEREG, BTA_AG_IGNORE, 205 BTA_AG_CLOSING_ST}, 206 /* API_OPEN_EVT */ {BTA_AG_OPEN_FAIL, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 207 /* API_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 208 /* API_AUDIO_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 209 /* API_AUDIO_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 210 /* API_RESULT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 211 /* API_SETCODEC_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 212 /* RFC_OPEN_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 213 /* RFC_CLOSE_EVT */ {BTA_AG_RFC_CLOSE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 214 /* RFC_SRV_CLOSE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 215 /* RFC_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 216 /* SCO_OPEN_EVT */ {BTA_AG_SCO_CONN_OPEN, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 217 /* SCO_CLOSE_EVT */ {BTA_AG_SCO_CONN_CLOSE, BTA_AG_POST_SCO_CLOSE, 218 BTA_AG_CLOSING_ST}, 219 /* DISC_ACP_RES_EVT */ {BTA_AG_FREE_DB, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 220 /* DISC_INT_RES_EVT */ {BTA_AG_FREE_DB, BTA_AG_IGNORE, BTA_AG_INIT_ST}, 221 /* DISC_OK_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 222 /* DISC_FAIL_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 223 /* CI_RX_WRITE_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 224 /* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 225 /* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 226 /* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, 227 /* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}}; 228 229 /* type for state table */ 230 typedef const uint8_t (*tBTA_AG_ST_TBL)[BTA_AG_NUM_COLS]; 231 232 /* state table */ 233 const tBTA_AG_ST_TBL bta_ag_st_tbl[] = {bta_ag_st_init, bta_ag_st_opening, 234 bta_ag_st_open, bta_ag_st_closing}; 235 236 /***************************************************************************** 237 * Global data 238 ****************************************************************************/ 239 240 /* AG control block */ 241 tBTA_AG_CB bta_ag_cb; 242 243 /******************************************************************************* 244 * 245 * Function bta_ag_scb_alloc 246 * 247 * Description Allocate an AG service control block. 248 * 249 * 250 * Returns pointer to the scb, or NULL if none could be allocated. 251 * 252 ******************************************************************************/ 253 static tBTA_AG_SCB* bta_ag_scb_alloc(void) { 254 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0]; 255 int i; 256 257 for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) { 258 if (!p_scb->in_use) { 259 /* initialize variables */ 260 p_scb->in_use = true; 261 p_scb->sco_idx = BTM_INVALID_SCO_INDEX; 262 p_scb->codec_updated = false; 263 p_scb->codec_fallback = false; 264 p_scb->peer_codecs = BTA_AG_CODEC_CVSD; 265 p_scb->sco_codec = BTA_AG_CODEC_CVSD; 266 /* set up timers */ 267 p_scb->ring_timer = alarm_new("bta_ag.scb_ring_timer"); 268 p_scb->collision_timer = alarm_new("bta_ag.scb_collision_timer"); 269 p_scb->codec_negotiation_timer = 270 alarm_new("bta_ag.scb_codec_negotiation_timer"); 271 /* set eSCO mSBC setting to T2 as the preferred */ 272 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; 273 APPL_TRACE_DEBUG("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb)); 274 break; 275 } 276 } 277 278 if (i == BTA_AG_NUM_SCB) { 279 /* out of scbs */ 280 p_scb = NULL; 281 APPL_TRACE_WARNING("%s: Out of scbs", __func__); 282 } 283 return p_scb; 284 } 285 286 /******************************************************************************* 287 * 288 * Function bta_ag_scb_dealloc 289 * 290 * Description Deallocate a service control block. 291 * 292 * 293 * Returns void 294 * 295 ******************************************************************************/ 296 void bta_ag_scb_dealloc(tBTA_AG_SCB* p_scb) { 297 uint8_t idx; 298 bool allocated = false; 299 300 APPL_TRACE_DEBUG("bta_ag_scb_dealloc %d", bta_ag_scb_to_idx(p_scb)); 301 302 /* stop and free timers */ 303 alarm_free(p_scb->ring_timer); 304 alarm_free(p_scb->codec_negotiation_timer); 305 alarm_free(p_scb->collision_timer); 306 307 /* initialize control block */ 308 memset(p_scb, 0, sizeof(tBTA_AG_SCB)); 309 p_scb->sco_idx = BTM_INVALID_SCO_INDEX; 310 311 /* If all scbs are deallocated, callback with disable event */ 312 if (!bta_sys_is_register(BTA_ID_AG)) { 313 for (idx = 0; idx < BTA_AG_NUM_SCB; idx++) { 314 if (bta_ag_cb.scb[idx].in_use) { 315 allocated = true; 316 break; 317 } 318 } 319 320 if (!allocated) { 321 (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL); 322 } 323 } 324 } 325 326 /******************************************************************************* 327 * 328 * Function bta_ag_scb_to_idx 329 * 330 * Description Given a pointer to an scb, return its index. 331 * 332 * 333 * Returns Index of scb. 334 * 335 ******************************************************************************/ 336 uint16_t bta_ag_scb_to_idx(tBTA_AG_SCB* p_scb) { 337 /* use array arithmetic to determine index */ 338 return ((uint16_t)(p_scb - bta_ag_cb.scb)) + 1; 339 } 340 341 /******************************************************************************* 342 * 343 * Function bta_ag_scb_by_idx 344 * 345 * Description Given an scb index return pointer to scb. 346 * 347 * 348 * Returns Pointer to scb or NULL if not allocated. 349 * 350 ******************************************************************************/ 351 tBTA_AG_SCB* bta_ag_scb_by_idx(uint16_t idx) { 352 tBTA_AG_SCB* p_scb; 353 354 /* verify index */ 355 if (idx > 0 && idx <= BTA_AG_NUM_SCB) { 356 p_scb = &bta_ag_cb.scb[idx - 1]; 357 if (!p_scb->in_use) { 358 p_scb = NULL; 359 APPL_TRACE_WARNING("ag scb idx %d not allocated", idx); 360 } 361 } else { 362 p_scb = NULL; 363 APPL_TRACE_DEBUG("ag scb idx %d out of range", idx); 364 } 365 return p_scb; 366 } 367 368 /******************************************************************************* 369 * 370 * Function bta_ag_service_to_idx 371 * 372 * Description Given a BTA service mask convert to profile index. 373 * 374 * 375 * Returns Profile ndex of scb. 376 * 377 ******************************************************************************/ 378 uint8_t bta_ag_service_to_idx(tBTA_SERVICE_MASK services) { 379 if (services & BTA_HFP_SERVICE_MASK) { 380 return BTA_AG_HFP; 381 } else { 382 return BTA_AG_HSP; 383 } 384 } 385 386 /******************************************************************************* 387 * 388 * Function bta_ag_idx_by_bdaddr 389 * 390 * Description Find SCB associated with peer BD address. 391 * 392 * 393 * Returns Index of SCB or zero if none found. 394 * 395 ******************************************************************************/ 396 uint16_t bta_ag_idx_by_bdaddr(BD_ADDR peer_addr) { 397 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0]; 398 uint16_t i; 399 400 if (peer_addr != NULL) { 401 for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) { 402 if (p_scb->in_use && !bdcmp(peer_addr, p_scb->peer_addr)) { 403 return (i + 1); 404 } 405 } 406 } 407 408 /* no scb found */ 409 APPL_TRACE_WARNING("No ag scb for peer addr"); 410 return 0; 411 } 412 413 /******************************************************************************* 414 * 415 * Function bta_ag_other_scb_open 416 * 417 * Description Check whether any other scb is in open state. 418 * 419 * 420 * Returns true if another scb is in open state, false otherwise. 421 * 422 ******************************************************************************/ 423 bool bta_ag_other_scb_open(tBTA_AG_SCB* p_curr_scb) { 424 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0]; 425 int i; 426 427 for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) { 428 if (p_scb->in_use && p_scb != p_curr_scb && 429 p_scb->state == BTA_AG_OPEN_ST) { 430 return true; 431 } 432 } 433 434 /* no other scb found */ 435 APPL_TRACE_DEBUG("No other ag scb open"); 436 return false; 437 } 438 439 /******************************************************************************* 440 * 441 * Function bta_ag_scb_open 442 * 443 * Description Check whether given scb is in open state. 444 * 445 * 446 * Returns true if scb is in open state, false otherwise. 447 * 448 ******************************************************************************/ 449 bool bta_ag_scb_open(tBTA_AG_SCB* p_curr_scb) { 450 if (p_curr_scb && p_curr_scb->in_use && p_curr_scb->state == BTA_AG_OPEN_ST) { 451 return true; 452 } 453 454 return false; 455 } 456 457 /******************************************************************************* 458 * 459 * Function bta_ag_get_other_idle_scb 460 * 461 * Description Return other scb if it is in INIT st. 462 * 463 * 464 * Returns Pointer to other scb if INIT st, NULL otherwise. 465 * 466 ******************************************************************************/ 467 tBTA_AG_SCB* bta_ag_get_other_idle_scb(tBTA_AG_SCB* p_curr_scb) { 468 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0]; 469 uint8_t xx; 470 471 for (xx = 0; xx < BTA_AG_NUM_SCB; xx++, p_scb++) { 472 if (p_scb->in_use && (p_scb != p_curr_scb) && 473 (p_scb->state == BTA_AG_INIT_ST)) { 474 return p_scb; 475 } 476 } 477 478 /* no other scb found */ 479 APPL_TRACE_DEBUG("bta_ag_get_other_idle_scb: No idle AG scb"); 480 return NULL; 481 } 482 483 /******************************************************************************* 484 * 485 * Function bta_ag_collision_timer_cback 486 * 487 * Description AG connection collision timer callback 488 * 489 * 490 * Returns void 491 * 492 ******************************************************************************/ 493 static void bta_ag_collision_timer_cback(void* data) { 494 tBTA_AG_SCB* p_scb = (tBTA_AG_SCB*)data; 495 496 APPL_TRACE_DEBUG("%s", __func__); 497 498 /* If the peer haven't opened AG connection */ 499 /* we will restart opening process. */ 500 bta_ag_resume_open(p_scb); 501 } 502 503 /******************************************************************************* 504 * 505 * Function bta_ag_collision_cback 506 * 507 * Description Get notified about collision. 508 * 509 * 510 * Returns void 511 * 512 ******************************************************************************/ 513 void bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, uint8_t id, 514 UNUSED_ATTR uint8_t app_id, BD_ADDR peer_addr) { 515 uint16_t handle; 516 tBTA_AG_SCB* p_scb; 517 518 /* Check if we have opening scb for the peer device. */ 519 handle = bta_ag_idx_by_bdaddr(peer_addr); 520 p_scb = bta_ag_scb_by_idx(handle); 521 522 if (p_scb && (p_scb->state == BTA_AG_OPENING_ST)) { 523 if (id == BTA_ID_SYS) /* ACL collision */ 524 { 525 APPL_TRACE_WARNING("AG found collision (ACL) ..."); 526 } else if (id == BTA_ID_AG) /* RFCOMM collision */ 527 { 528 APPL_TRACE_WARNING("AG found collision (RFCOMM) ..."); 529 } else { 530 APPL_TRACE_WARNING("AG found collision (\?\?\?) ..."); 531 } 532 533 p_scb->state = BTA_AG_INIT_ST; 534 535 /* Cancel SDP if it had been started. */ 536 if (p_scb->p_disc_db) { 537 (void)SDP_CancelServiceSearch(p_scb->p_disc_db); 538 bta_ag_free_db(p_scb, NULL); 539 } 540 541 /* reopen registered servers */ 542 /* Collision may be detected before or after we close servers. */ 543 if (bta_ag_is_server_closed(p_scb)) 544 bta_ag_start_servers(p_scb, p_scb->reg_services); 545 546 /* Start timer to han */ 547 alarm_set_on_queue(p_scb->collision_timer, BTA_AG_COLLISION_TIMEOUT_MS, 548 bta_ag_collision_timer_cback, p_scb, 549 btu_bta_alarm_queue); 550 } 551 } 552 553 /******************************************************************************* 554 * 555 * Function bta_ag_resume_open 556 * 557 * Description Resume opening process. 558 * 559 * 560 * Returns void 561 * 562 ******************************************************************************/ 563 void bta_ag_resume_open(tBTA_AG_SCB* p_scb) { 564 if (p_scb) { 565 APPL_TRACE_DEBUG("bta_ag_resume_open, Handle(%d)", 566 bta_ag_scb_to_idx(p_scb)); 567 568 /* resume opening process. */ 569 if (p_scb->state == BTA_AG_INIT_ST) { 570 p_scb->state = BTA_AG_OPENING_ST; 571 bta_ag_start_open(p_scb, NULL); 572 } 573 } else { 574 APPL_TRACE_ERROR("bta_ag_resume_open, Null p_scb"); 575 } 576 } 577 578 /******************************************************************************* 579 * 580 * Function bta_ag_api_enable 581 * 582 * Description Handle an API enable event. 583 * 584 * 585 * Returns void 586 * 587 ******************************************************************************/ 588 static void bta_ag_api_enable(tBTA_AG_DATA* p_data) { 589 /* initialize control block */ 590 for (size_t i = 0; i < BTA_AG_NUM_SCB; i++) { 591 alarm_free(bta_ag_cb.scb[i].ring_timer); 592 alarm_free(bta_ag_cb.scb[i].codec_negotiation_timer); 593 alarm_free(bta_ag_cb.scb[i].collision_timer); 594 } 595 memset(&bta_ag_cb, 0, sizeof(tBTA_AG_CB)); 596 597 /* store callback function */ 598 bta_ag_cb.p_cback = p_data->api_enable.p_cback; 599 bta_ag_cb.parse_mode = p_data->api_enable.parse_mode; 600 601 /* call init call-out */ 602 bta_ag_co_init(); 603 604 bta_sys_collision_register(BTA_ID_AG, bta_ag_collision_cback); 605 606 /* call callback with enable event */ 607 (*bta_ag_cb.p_cback)(BTA_AG_ENABLE_EVT, NULL); 608 } 609 610 /******************************************************************************* 611 * 612 * Function bta_ag_api_disable 613 * 614 * Description Handle an API disable event. 615 * 616 * 617 * Returns void 618 * 619 ******************************************************************************/ 620 static void bta_ag_api_disable(tBTA_AG_DATA* p_data) { 621 /* deregister all scbs in use */ 622 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0]; 623 bool do_dereg = false; 624 int i; 625 626 if (!bta_sys_is_register(BTA_ID_AG)) { 627 APPL_TRACE_ERROR("BTA AG is already disabled, ignoring ..."); 628 return; 629 } 630 631 /* De-register with BTA system manager */ 632 bta_sys_deregister(BTA_ID_AG); 633 634 for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) { 635 if (p_scb->in_use) { 636 bta_ag_sm_execute(p_scb, BTA_AG_API_DEREGISTER_EVT, p_data); 637 do_dereg = true; 638 } 639 } 640 641 if (!do_dereg) { 642 /* Done, send callback evt to app */ 643 (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL); 644 } 645 646 bta_sys_collision_register(BTA_ID_AG, NULL); 647 } 648 649 /******************************************************************************* 650 * 651 * Function bta_ag_api_register 652 * 653 * Description Handle an API event registers a new service. 654 * 655 * 656 * Returns void 657 * 658 ******************************************************************************/ 659 static void bta_ag_api_register(tBTA_AG_DATA* p_data) { 660 tBTA_AG_SCB* p_scb; 661 tBTA_AG_REGISTER reg; 662 663 /* allocate an scb */ 664 p_scb = bta_ag_scb_alloc(); 665 if (p_scb != NULL) { 666 APPL_TRACE_DEBUG("bta_ag_api_register: p_scb 0x%08x ", p_scb); 667 bta_ag_sm_execute(p_scb, p_data->hdr.event, p_data); 668 } else { 669 reg.status = BTA_AG_FAIL_RESOURCES; 670 (*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, (tBTA_AG*)®); 671 } 672 } 673 674 /******************************************************************************* 675 * 676 * Function bta_ag_api_result 677 * 678 * Description Handle an API result event. 679 * 680 * 681 * Returns void 682 * 683 ******************************************************************************/ 684 static void bta_ag_api_result(tBTA_AG_DATA* p_data) { 685 tBTA_AG_SCB* p_scb; 686 int i; 687 688 if (p_data->hdr.layer_specific != BTA_AG_HANDLE_ALL) { 689 p_scb = bta_ag_scb_by_idx(p_data->hdr.layer_specific); 690 if (p_scb != NULL) { 691 APPL_TRACE_DEBUG("bta_ag_api_result: p_scb 0x%08x ", p_scb); 692 bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data); 693 } 694 } else { 695 for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, p_scb++) { 696 if (p_scb->in_use && p_scb->svc_conn) { 697 APPL_TRACE_DEBUG("bta_ag_api_result p_scb 0x%08x ", p_scb); 698 bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data); 699 } 700 } 701 } 702 } 703 704 /******************************************************************************* 705 * 706 * Function bta_ag_sm_execute 707 * 708 * Description State machine event handling function for AG 709 * 710 * 711 * Returns void 712 * 713 ******************************************************************************/ 714 void bta_ag_sm_execute(tBTA_AG_SCB* p_scb, uint16_t event, 715 tBTA_AG_DATA* p_data) { 716 tBTA_AG_ST_TBL state_table; 717 uint8_t action; 718 int i; 719 #if (BTA_AG_DEBUG == TRUE) 720 uint16_t previous_event = event; 721 uint8_t previous_state = p_scb->state; 722 723 /* Ignore displaying of AT results when not connected (Ignored in state 724 * machine) */ 725 if ((previous_event != BTA_AG_API_RESULT_EVT || 726 p_scb->state == BTA_AG_OPEN_ST) && 727 event != BTA_AG_CI_SCO_DATA_EVT) { 728 APPL_TRACE_EVENT("%s: Handle 0x%04x, State %d (%s), Event 0x%04x (%s)", 729 __func__, bta_ag_scb_to_idx(p_scb), p_scb->state, 730 bta_ag_state_str(p_scb->state), event, 731 bta_ag_evt_str(event, p_data->api_result.result)); 732 } 733 #else 734 if (event != BTA_AG_CI_SCO_DATA_EVT) { 735 APPL_TRACE_EVENT("%s: Handle 0x%04x, State %d, Event 0x%04x", __func__, 736 bta_ag_scb_to_idx(p_scb), p_scb->state, event); 737 } 738 #endif 739 740 event &= 0x00FF; 741 if (event >= (BTA_AG_MAX_EVT & 0x00FF)) { 742 APPL_TRACE_ERROR("%s: event out of range, ignored", __func__); 743 return; 744 } 745 746 /* look up the state table for the current state */ 747 state_table = bta_ag_st_tbl[p_scb->state]; 748 749 /* set next state */ 750 p_scb->state = state_table[event][BTA_AG_NEXT_STATE]; 751 752 /* execute action functions */ 753 for (i = 0; i < BTA_AG_ACTIONS; i++) { 754 action = state_table[event][i]; 755 if (action != BTA_AG_IGNORE) { 756 (*bta_ag_action[action])(p_scb, p_data); 757 } else { 758 break; 759 } 760 } 761 #if (BTA_AG_DEBUG == TRUE) 762 if (p_scb->state != previous_state) { 763 APPL_TRACE_EVENT("%s: State Change: [%s] -> [%s] after Event [%s]", 764 __func__, bta_ag_state_str(previous_state), 765 bta_ag_state_str(p_scb->state), 766 bta_ag_evt_str(previous_event, p_data->api_result.result)); 767 } 768 #endif 769 } 770 771 /******************************************************************************* 772 * 773 * Function bta_ag_hdl_event 774 * 775 * Description Data gateway main event handling function. 776 * 777 * 778 * Returns bool 779 * 780 ******************************************************************************/ 781 bool bta_ag_hdl_event(BT_HDR* p_msg) { 782 tBTA_AG_SCB* p_scb; 783 784 APPL_TRACE_DEBUG("bta_ag_hdl_event: Event 0x%04x ", p_msg->event); 785 switch (p_msg->event) { 786 case BTA_AG_API_ENABLE_EVT: 787 bta_ag_api_enable((tBTA_AG_DATA*)p_msg); 788 break; 789 790 case BTA_AG_API_DISABLE_EVT: 791 bta_ag_api_disable((tBTA_AG_DATA*)p_msg); 792 break; 793 794 case BTA_AG_API_REGISTER_EVT: 795 bta_ag_api_register((tBTA_AG_DATA*)p_msg); 796 break; 797 798 case BTA_AG_API_RESULT_EVT: 799 bta_ag_api_result((tBTA_AG_DATA*)p_msg); 800 break; 801 802 /* all others reference scb by handle */ 803 default: 804 p_scb = bta_ag_scb_by_idx(p_msg->layer_specific); 805 if (p_scb != NULL) { 806 APPL_TRACE_DEBUG("bta_ag_hdl_event: p_scb 0x%08x ", p_scb); 807 bta_ag_sm_execute(p_scb, p_msg->event, (tBTA_AG_DATA*)p_msg); 808 } 809 break; 810 } 811 return true; 812 } 813 814 #if (BTA_AG_DEBUG == TRUE) 815 static char* bta_ag_evt_str(uint16_t event, tBTA_AG_RES result) { 816 switch (event) { 817 case BTA_AG_API_REGISTER_EVT: 818 return "Register Request"; 819 case BTA_AG_API_DEREGISTER_EVT: 820 return "Deregister Request"; 821 case BTA_AG_API_OPEN_EVT: 822 return "Open SLC Request"; 823 case BTA_AG_API_CLOSE_EVT: 824 return "Close SLC Request"; 825 case BTA_AG_API_AUDIO_OPEN_EVT: 826 return "Open Audio Request"; 827 case BTA_AG_API_AUDIO_CLOSE_EVT: 828 return "Close Audio Request"; 829 case BTA_AG_API_RESULT_EVT: 830 switch (result) { 831 case BTA_AG_SPK_RES: 832 return ("AT Result BTA_AG_SPK_RES"); 833 case BTA_AG_MIC_RES: 834 return ("AT Result BTA_AG_MIC_RES"); 835 case BTA_AG_INBAND_RING_RES: 836 return ("AT Result BTA_AG_INBAND_RING_RES"); 837 case BTA_AG_CIND_RES: 838 return ("AT Result BTA_AG_CIND_RES"); 839 case BTA_AG_BINP_RES: 840 return ("AT Result BTA_AG_BINP_RES"); 841 case BTA_AG_IND_RES: 842 return ("AT Result BTA_AG_IND_RES"); 843 case BTA_AG_BVRA_RES: 844 return ("AT Result BTA_AG_BVRA_RES"); 845 case BTA_AG_CNUM_RES: 846 return ("AT Result BTA_AG_CNUM_RES"); 847 case BTA_AG_BTRH_RES: 848 return ("AT Result BTA_AG_BTRH_RES"); 849 case BTA_AG_CLCC_RES: 850 return ("AT Result BTA_AG_CLCC_RES"); 851 case BTA_AG_COPS_RES: 852 return ("AT Result BTA_AG_COPS_RES"); 853 case BTA_AG_IN_CALL_RES: 854 return ("AT Result BTA_AG_IN_CALL_RES"); 855 case BTA_AG_IN_CALL_CONN_RES: 856 return ("AT Result BTA_AG_IN_CALL_CONN_RES"); 857 case BTA_AG_CALL_WAIT_RES: 858 return ("AT Result BTA_AG_CALL_WAIT_RES"); 859 case BTA_AG_OUT_CALL_ORIG_RES: 860 return ("AT Result BTA_AG_OUT_CALL_ORIG_RES"); 861 case BTA_AG_OUT_CALL_ALERT_RES: 862 return ("AT Result BTA_AG_OUT_CALL_ALERT_RES"); 863 case BTA_AG_OUT_CALL_CONN_RES: 864 return ("AT Result BTA_AG_OUT_CALL_CONN_RES"); 865 case BTA_AG_CALL_CANCEL_RES: 866 return ("AT Result BTA_AG_CALL_CANCEL_RES"); 867 case BTA_AG_END_CALL_RES: 868 return ("AT Result BTA_AG_END_CALL_RES"); 869 case BTA_AG_UNAT_RES: 870 return ("AT Result BTA_AG_UNAT_RES"); 871 default: 872 return ("Unknown AG Result"); 873 } 874 case BTA_AG_API_SETCODEC_EVT: 875 return "Set Codec Request"; 876 case BTA_AG_RFC_OPEN_EVT: 877 return "RFC Opened"; 878 case BTA_AG_RFC_CLOSE_EVT: 879 return "RFC Closed"; 880 case BTA_AG_RFC_SRV_CLOSE_EVT: 881 return "RFC SRV Closed"; 882 case BTA_AG_RFC_DATA_EVT: 883 return "RFC Data"; 884 case BTA_AG_SCO_OPEN_EVT: 885 return "Audio Opened"; 886 case BTA_AG_SCO_CLOSE_EVT: 887 return "Audio Closed"; 888 case BTA_AG_DISC_ACP_RES_EVT: 889 return "Discovery ACP Result"; 890 case BTA_AG_DISC_INT_RES_EVT: 891 return "Discovery INT Result"; 892 case BTA_AG_DISC_OK_EVT: 893 return "Discovery OK"; 894 case BTA_AG_DISC_FAIL_EVT: 895 return "Discovery Failed"; 896 case BTA_AG_CI_RX_WRITE_EVT: 897 return "CI RX Write"; 898 case BTA_AG_RING_TIMEOUT_EVT: 899 return "Ring Timeout"; 900 case BTA_AG_SVC_TIMEOUT_EVT: 901 return "Service Timeout"; 902 case BTA_AG_API_ENABLE_EVT: 903 return "Enable AG"; 904 case BTA_AG_API_DISABLE_EVT: 905 return "Disable AG"; 906 case BTA_AG_CI_SCO_DATA_EVT: 907 return "SCO data Callin"; 908 case BTA_AG_CI_SLC_READY_EVT: 909 return "SLC Ready Callin"; 910 default: 911 return "Unknown AG Event"; 912 } 913 } 914 915 static char* bta_ag_state_str(uint8_t state) { 916 switch (state) { 917 case BTA_AG_INIT_ST: 918 return "Initial"; 919 case BTA_AG_OPENING_ST: 920 return "Opening"; 921 case BTA_AG_OPEN_ST: 922 return "Open"; 923 case BTA_AG_CLOSING_ST: 924 return "Closing"; 925 default: 926 return "Unknown AG State"; 927 } 928 } 929 930 #endif 931