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