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