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 ******************************************************************************/
bta_ag_scb_alloc(void)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 ******************************************************************************/
bta_ag_scb_dealloc(tBTA_AG_SCB * p_scb)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 ******************************************************************************/
bta_ag_scb_to_idx(tBTA_AG_SCB * p_scb)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 ******************************************************************************/
bta_ag_scb_by_idx(uint16_t idx)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 ******************************************************************************/
bta_ag_service_to_idx(tBTA_SERVICE_MASK services)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 ******************************************************************************/
bta_ag_idx_by_bdaddr(BD_ADDR peer_addr)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 ******************************************************************************/
bta_ag_other_scb_open(tBTA_AG_SCB * p_curr_scb)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 ******************************************************************************/
bta_ag_scb_open(tBTA_AG_SCB * p_curr_scb)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 ******************************************************************************/
bta_ag_get_other_idle_scb(tBTA_AG_SCB * p_curr_scb)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 ******************************************************************************/
bta_ag_collision_timer_cback(void * data)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 ******************************************************************************/
bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,uint8_t id,UNUSED_ATTR uint8_t app_id,BD_ADDR peer_addr)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 ******************************************************************************/
bta_ag_resume_open(tBTA_AG_SCB * p_scb)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 ******************************************************************************/
bta_ag_api_enable(tBTA_AG_DATA * p_data)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 ******************************************************************************/
bta_ag_api_disable(tBTA_AG_DATA * p_data)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 ******************************************************************************/
bta_ag_api_register(tBTA_AG_DATA * p_data)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 ******************************************************************************/
bta_ag_api_result(tBTA_AG_DATA * p_data)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 ******************************************************************************/
bta_ag_sm_execute(tBTA_AG_SCB * p_scb,uint16_t event,tBTA_AG_DATA * p_data)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 ******************************************************************************/
bta_ag_hdl_event(BT_HDR * p_msg)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)
bta_ag_evt_str(uint16_t event,tBTA_AG_RES result)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
bta_ag_state_str(uint8_t state)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