bta_ag_main.c revision 5b675bc41986a159023c51b561e81939f0632f95
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
40static char *bta_ag_evt_str(UINT16 event, tBTA_AG_RES result);
41static char *bta_ag_state_str(UINT8 state);
42#endif
43
44/* state machine states */
45enum
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 */
54enum
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 */
94typedef void (*tBTA_AG_ACTION)(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data);
95
96/* action functions */
97const 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 */
139const 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 */
168const 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 */
197const 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 */
226const 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 */
255typedef const UINT8 (*tBTA_AG_ST_TBL)[BTA_AG_NUM_COLS];
256
257/* state table */
258const 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
272tBTA_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*******************************************************************************/
285static 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*******************************************************************************/
308static 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*******************************************************************************/
354void 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
367    /* initialize control block */
368    memset(p_scb, 0, sizeof(tBTA_AG_SCB));
369    p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
370
371    /* If all scbs are deallocated, callback with disable event */
372    if (!bta_sys_is_register (BTA_ID_AG))
373    {
374        for (idx = 0; idx < BTA_AG_NUM_SCB; idx++)
375        {
376            if (bta_ag_cb.scb[idx].in_use)
377            {
378                allocated = TRUE;
379                break;
380            }
381        }
382
383        if (!allocated)
384        {
385            (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL);
386        }
387    }
388
389}
390
391/*******************************************************************************
392**
393** Function         bta_ag_scb_to_idx
394**
395** Description      Given a pointer to an scb, return its index.
396**
397**
398** Returns          Index of scb.
399**
400*******************************************************************************/
401UINT16 bta_ag_scb_to_idx(tBTA_AG_SCB *p_scb)
402{
403    /* use array arithmetic to determine index */
404    return ((UINT16) (p_scb - bta_ag_cb.scb)) + 1;
405}
406
407/*******************************************************************************
408**
409** Function         bta_ag_scb_by_idx
410**
411** Description      Given an scb index return pointer to scb.
412**
413**
414** Returns          Pointer to scb or NULL if not allocated.
415**
416*******************************************************************************/
417tBTA_AG_SCB *bta_ag_scb_by_idx(UINT16 idx)
418{
419    tBTA_AG_SCB     *p_scb;
420
421    /* verify index */
422    if (idx > 0 && idx <= BTA_AG_NUM_SCB)
423    {
424        p_scb = &bta_ag_cb.scb[idx - 1];
425        if (!p_scb->in_use)
426        {
427            p_scb = NULL;
428            APPL_TRACE_WARNING("ag scb idx %d not allocated", idx);
429        }
430    }
431    else
432    {
433        p_scb = NULL;
434        APPL_TRACE_DEBUG("ag scb idx %d out of range", idx);
435    }
436    return p_scb;
437}
438
439/*******************************************************************************
440**
441** Function         bta_ag_service_to_idx
442**
443** Description      Given a BTA service mask convert to profile index.
444**
445**
446** Returns          Profile ndex of scb.
447**
448*******************************************************************************/
449UINT8 bta_ag_service_to_idx(tBTA_SERVICE_MASK services)
450{
451    if (services & BTA_HFP_SERVICE_MASK)
452    {
453        return BTA_AG_HFP;
454    }
455    else
456    {
457        return BTA_AG_HSP;
458    }
459}
460
461/*******************************************************************************
462**
463** Function         bta_ag_idx_by_bdaddr
464**
465** Description      Find SCB associated with peer BD address.
466**
467**
468** Returns          Index of SCB or zero if none found.
469**
470*******************************************************************************/
471UINT16 bta_ag_idx_by_bdaddr(BD_ADDR peer_addr)
472{
473    tBTA_AG_SCB     *p_scb = &bta_ag_cb.scb[0];
474    UINT16          i;
475
476    if (peer_addr != NULL)
477    {
478        for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++)
479        {
480            if (p_scb->in_use && !bdcmp(peer_addr, p_scb->peer_addr))
481            {
482                return (i + 1);
483            }
484        }
485    }
486
487    /* no scb found */
488    APPL_TRACE_WARNING("No ag scb for peer addr");
489    return 0;
490}
491
492/*******************************************************************************
493**
494** Function         bta_ag_other_scb_open
495**
496** Description      Check whether any other scb is in open state.
497**
498**
499** Returns          TRUE if another scb is in open state, FALSE otherwise.
500**
501*******************************************************************************/
502BOOLEAN bta_ag_other_scb_open(tBTA_AG_SCB *p_curr_scb)
503{
504    tBTA_AG_SCB     *p_scb = &bta_ag_cb.scb[0];
505    int             i;
506
507    for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++)
508    {
509        if (p_scb->in_use && p_scb != p_curr_scb && p_scb->state == BTA_AG_OPEN_ST)
510        {
511            return TRUE;
512        }
513    }
514
515    /* no other scb found */
516    APPL_TRACE_DEBUG("No other ag scb open");
517    return FALSE;
518}
519
520/*******************************************************************************
521**
522** Function         bta_ag_scb_open
523**
524** Description      Check whether given scb is in open state.
525**
526**
527** Returns          TRUE if scb is in open state, FALSE otherwise.
528**
529*******************************************************************************/
530BOOLEAN bta_ag_scb_open(tBTA_AG_SCB *p_curr_scb)
531{
532    if (p_curr_scb && p_curr_scb->in_use && p_curr_scb->state == BTA_AG_OPEN_ST)
533    {
534        return TRUE;
535    }
536
537    return FALSE;
538}
539
540/*******************************************************************************
541**
542** Function         bta_ag_get_other_idle_scb
543**
544** Description      Return other scb if it is in INIT st.
545**
546**
547** Returns          Pointer to other scb if INIT st, NULL otherwise.
548**
549*******************************************************************************/
550tBTA_AG_SCB *bta_ag_get_other_idle_scb (tBTA_AG_SCB *p_curr_scb)
551{
552    tBTA_AG_SCB     *p_scb = &bta_ag_cb.scb[0];
553    UINT8   xx;
554
555    for (xx = 0; xx < BTA_AG_NUM_SCB; xx++, p_scb++)
556    {
557        if (p_scb->in_use && (p_scb != p_curr_scb) && (p_scb->state == BTA_AG_INIT_ST))
558        {
559            return p_scb;
560        }
561    }
562
563    /* no other scb found */
564    APPL_TRACE_DEBUG("bta_ag_get_other_idle_scb: No idle AG scb");
565    return NULL;
566}
567
568/*******************************************************************************
569**
570** Function         bta_ag_colli_timer_cback
571**
572** Description      AG connection collision timer callback
573**
574**
575** Returns          void
576**
577*******************************************************************************/
578static void bta_ag_colli_timer_cback (TIMER_LIST_ENT *p_tle)
579{
580    tBTA_AG_SCB *p_scb;
581
582    APPL_TRACE_DEBUG ("bta_ag_colli_timer_cback");
583
584    if (p_tle)
585    {
586        p_scb = (tBTA_AG_SCB *)p_tle->param;
587
588        if (p_scb)
589        {
590            p_scb->colli_tmr_on = FALSE;
591
592            /* If the peer haven't opened AG connection     */
593            /* we will restart opening process.             */
594            bta_ag_resume_open (p_scb);
595        }
596    }
597}
598
599/*******************************************************************************
600**
601** Function         bta_ag_collision_cback
602**
603** Description      Get notified about collision.
604**
605**
606** Returns          void
607**
608*******************************************************************************/
609void bta_ag_collision_cback (tBTA_SYS_CONN_STATUS status, UINT8 id,
610                                    UINT8 app_id, BD_ADDR peer_addr)
611{
612    UINT16  handle;
613    tBTA_AG_SCB *p_scb;
614    UNUSED(status);
615    UNUSED(app_id);
616
617    /* Check if we have opening scb for the peer device. */
618    handle = bta_ag_idx_by_bdaddr (peer_addr);
619    p_scb = bta_ag_scb_by_idx (handle);
620
621    if (p_scb && (p_scb->state == BTA_AG_OPENING_ST))
622    {
623        if (id == BTA_ID_SYS)   /* ACL collision */
624        {
625            APPL_TRACE_WARNING ("AG found collision (ACL) ...");
626        }
627        else if (id == BTA_ID_AG)   /* RFCOMM collision */
628        {
629            APPL_TRACE_WARNING ("AG found collision (RFCOMM) ...");
630        }
631        else
632        {
633            APPL_TRACE_WARNING ("AG found collision (\?\?\?) ...");
634        }
635
636        p_scb->state = BTA_AG_INIT_ST;
637
638        /* Cancel SDP if it had been started. */
639        if(p_scb->p_disc_db)
640        {
641            (void)SDP_CancelServiceSearch (p_scb->p_disc_db);
642            bta_ag_free_db(p_scb, NULL);
643        }
644
645        /* reopen registered servers */
646        /* Collision may be detected before or after we close servers. */
647        if (bta_ag_is_server_closed (p_scb))
648            bta_ag_start_servers(p_scb, p_scb->reg_services);
649
650        /* Start timer to han */
651        p_scb->colli_timer.p_cback = (TIMER_CBACK*)&bta_ag_colli_timer_cback;
652        p_scb->colli_timer.param = (INT32)p_scb;
653        bta_sys_start_timer(&p_scb->colli_timer, 0, BTA_AG_COLLISION_TIMER);
654        p_scb->colli_tmr_on = TRUE;
655    }
656
657}
658
659/*******************************************************************************
660**
661** Function         bta_ag_resume_open
662**
663** Description      Resume opening process.
664**
665**
666** Returns          void
667**
668*******************************************************************************/
669void bta_ag_resume_open (tBTA_AG_SCB *p_scb)
670{
671    if (p_scb)
672    {
673        APPL_TRACE_DEBUG ("bta_ag_resume_open, Handle(%d)", bta_ag_scb_to_idx(p_scb));
674
675        /* resume opening process.  */
676        if (p_scb->state == BTA_AG_INIT_ST)
677        {
678            p_scb->state = BTA_AG_OPENING_ST;
679            bta_ag_start_open (p_scb, NULL);
680        }
681    }
682    else
683    {
684        APPL_TRACE_ERROR ("bta_ag_resume_open, Null p_scb");
685    }
686}
687
688/*******************************************************************************
689**
690** Function         bta_ag_api_enable
691**
692** Description      Handle an API enable event.
693**
694**
695** Returns          void
696**
697*******************************************************************************/
698static void bta_ag_api_enable(tBTA_AG_DATA *p_data)
699{
700    /* initialize control block */
701    memset(&bta_ag_cb, 0, sizeof(tBTA_AG_CB));
702
703    /* store callback function */
704    bta_ag_cb.p_cback = p_data->api_enable.p_cback;
705    bta_ag_cb.parse_mode = p_data->api_enable.parse_mode;
706
707    /* call init call-out */
708    bta_ag_co_init();
709
710    bta_sys_collision_register (BTA_ID_AG, bta_ag_collision_cback);
711
712    /* call callback with enable event */
713    (*bta_ag_cb.p_cback)(BTA_AG_ENABLE_EVT, NULL);
714}
715
716/*******************************************************************************
717**
718** Function         bta_ag_api_disable
719**
720** Description      Handle an API disable event.
721**
722**
723** Returns          void
724**
725*******************************************************************************/
726static void bta_ag_api_disable(tBTA_AG_DATA *p_data)
727{
728    /* deregister all scbs in use */
729    tBTA_AG_SCB     *p_scb = &bta_ag_cb.scb[0];
730    BOOLEAN         do_dereg = FALSE;
731    int             i;
732
733    if (!bta_sys_is_register (BTA_ID_AG))
734    {
735        APPL_TRACE_ERROR("BTA AG is already disabled, ignoring ...");
736        return;
737    }
738
739    /* De-register with BTA system manager */
740    bta_sys_deregister(BTA_ID_AG);
741
742    for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++)
743    {
744        if (p_scb->in_use)
745        {
746            bta_ag_sm_execute(p_scb, BTA_AG_API_DEREGISTER_EVT, p_data);
747            do_dereg = TRUE;
748        }
749    }
750
751    if (!do_dereg)
752    {
753        /* Done, send callback evt to app */
754        (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL);
755    }
756
757    bta_sys_collision_register (BTA_ID_AG, NULL);
758}
759
760/*******************************************************************************
761**
762** Function         bta_ag_api_register
763**
764** Description      Handle an API event registers a new service.
765**
766**
767** Returns          void
768**
769*******************************************************************************/
770static void bta_ag_api_register(tBTA_AG_DATA *p_data)
771{
772    tBTA_AG_SCB     *p_scb;
773    tBTA_AG_REGISTER reg;
774
775    /* allocate an scb */
776    if ((p_scb = bta_ag_scb_alloc()) != NULL)
777    {
778        APPL_TRACE_DEBUG("bta_ag_api_register: p_scb 0x%08x ", p_scb);
779        bta_ag_sm_execute(p_scb, p_data->hdr.event, p_data);
780    }
781    else
782    {
783        reg.status = BTA_AG_FAIL_RESOURCES;
784        (*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, (tBTA_AG *) &reg);
785    }
786}
787
788/*******************************************************************************
789**
790** Function         bta_ag_api_result
791**
792** Description      Handle an API result event.
793**
794**
795** Returns          void
796**
797*******************************************************************************/
798static void bta_ag_api_result(tBTA_AG_DATA *p_data)
799{
800    tBTA_AG_SCB     *p_scb;
801    int             i;
802
803    if (p_data->hdr.layer_specific != BTA_AG_HANDLE_ALL)
804    {
805        if ((p_scb = bta_ag_scb_by_idx(p_data->hdr.layer_specific)) != NULL)
806        {
807            APPL_TRACE_DEBUG("bta_ag_api_result: p_scb 0x%08x ", p_scb);
808            bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data);
809        }
810    }
811    else
812    {
813        for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, p_scb++)
814        {
815            if (p_scb->in_use && p_scb->svc_conn)
816            {
817                APPL_TRACE_DEBUG("bta_ag_api_result p_scb 0x%08x ", p_scb);
818                bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data);
819            }
820        }
821    }
822}
823
824/*******************************************************************************
825**
826** Function         bta_ag_sm_execute
827**
828** Description      State machine event handling function for AG
829**
830**
831** Returns          void
832**
833*******************************************************************************/
834void bta_ag_sm_execute(tBTA_AG_SCB *p_scb, UINT16 event, tBTA_AG_DATA *p_data)
835{
836    tBTA_AG_ST_TBL      state_table;
837    UINT8               action;
838    int                 i;
839
840#if BTA_AG_DEBUG == TRUE
841    UINT16  in_event = event;
842    UINT8   in_state = p_scb->state;
843
844    /* Ignore displaying of AT results when not connected (Ignored in state machine) */
845    if (in_event != BTA_AG_API_RESULT_EVT || p_scb->state == BTA_AG_OPEN_ST)
846    {
847        APPL_TRACE_EVENT("AG evt (hdl 0x%04x): State %d (%s), Event 0x%04x (%s)",
848                           bta_ag_scb_to_idx(p_scb),
849                           p_scb->state, bta_ag_state_str(p_scb->state),
850                           event, bta_ag_evt_str(event, p_data->api_result.result));
851    }
852#else
853    APPL_TRACE_EVENT("AG evt (hdl 0x%04x): State %d, Event 0x%04x",
854                      bta_ag_scb_to_idx(p_scb), p_scb->state, event);
855#endif
856
857    event &= 0x00FF;
858    if (event >= (BTA_AG_MAX_EVT & 0x00FF))
859    {
860        APPL_TRACE_ERROR("AG evt out of range, ignoring...");
861        return;
862    }
863
864    /* look up the state table for the current state */
865    state_table = bta_ag_st_tbl[p_scb->state];
866
867    /* set next state */
868    p_scb->state = state_table[event][BTA_AG_NEXT_STATE];
869
870    /* execute action functions */
871    for (i = 0; i < BTA_AG_ACTIONS; i++)
872    {
873        if ((action = state_table[event][i]) != BTA_AG_IGNORE)
874        {
875            (*bta_ag_action[action])(p_scb, p_data);
876        }
877        else
878        {
879            break;
880        }
881    }
882#if BTA_AG_DEBUG == TRUE
883    if (p_scb->state != in_state)
884    {
885        APPL_TRACE_EVENT("BTA AG State Change: [%s] -> [%s] after Event [%s]",
886                      bta_ag_state_str(in_state),
887                      bta_ag_state_str(p_scb->state),
888                      bta_ag_evt_str(in_event, p_data->api_result.result));
889    }
890#endif
891}
892
893/*******************************************************************************
894**
895** Function         bta_ag_hdl_event
896**
897** Description      Data gateway main event handling function.
898**
899**
900** Returns          BOOLEAN
901**
902*******************************************************************************/
903BOOLEAN bta_ag_hdl_event(BT_HDR *p_msg)
904{
905    tBTA_AG_SCB *p_scb;
906
907    APPL_TRACE_DEBUG("bta_ag_hdl_event: Event 0x%04x ", p_msg->event);
908    switch (p_msg->event)
909    {
910        /* handle enable event */
911        case BTA_AG_API_ENABLE_EVT:
912            bta_ag_api_enable((tBTA_AG_DATA *) p_msg);
913            break;
914
915        /* handle disable event */
916        case BTA_AG_API_DISABLE_EVT:
917            bta_ag_api_disable((tBTA_AG_DATA *) p_msg);
918            break;
919
920        /* handle register event */
921        case BTA_AG_API_REGISTER_EVT:
922            bta_ag_api_register((tBTA_AG_DATA *) p_msg);
923            break;
924
925        /* handle result event */
926        case BTA_AG_API_RESULT_EVT:
927            bta_ag_api_result((tBTA_AG_DATA *) p_msg);
928            break;
929
930        /* all others reference scb by handle */
931        default:
932            if ((p_scb = bta_ag_scb_by_idx(p_msg->layer_specific)) != NULL)
933            {
934                APPL_TRACE_DEBUG("bta_ag_hdl_event: p_scb 0x%08x ", p_scb);
935                bta_ag_sm_execute(p_scb, p_msg->event, (tBTA_AG_DATA *) p_msg);
936            }
937            break;
938    }
939    return TRUE;
940}
941
942#if BTA_AG_DEBUG == TRUE
943static char *bta_ag_evt_str(UINT16 event, tBTA_AG_RES result)
944{
945    switch (event)
946    {
947    case BTA_AG_API_REGISTER_EVT:
948        return "Register Request";
949    case BTA_AG_API_DEREGISTER_EVT:
950        return "Deregister Request";
951    case BTA_AG_API_OPEN_EVT:
952        return "Open SLC Request";
953    case BTA_AG_API_CLOSE_EVT:
954        return "Close SLC Request";
955    case BTA_AG_API_AUDIO_OPEN_EVT:
956        return "Open Audio Request";
957    case BTA_AG_API_AUDIO_CLOSE_EVT:
958        return "Close Audio Request";
959    case BTA_AG_API_RESULT_EVT:
960        switch (result)
961        {
962        case BTA_AG_SPK_RES:            return ("AT Result  BTA_AG_SPK_RES");
963        case BTA_AG_MIC_RES:            return ("AT Result  BTA_AG_MIC_RES");
964        case BTA_AG_INBAND_RING_RES:    return ("AT Result  BTA_AG_INBAND_RING_RES");
965        case BTA_AG_CIND_RES:           return ("AT Result  BTA_AG_CIND_RES");
966        case BTA_AG_BINP_RES:           return ("AT Result  BTA_AG_BINP_RES");
967        case BTA_AG_IND_RES:            return ("AT Result  BTA_AG_IND_RES");
968        case BTA_AG_BVRA_RES:           return ("AT Result  BTA_AG_BVRA_RES");
969        case BTA_AG_CNUM_RES:           return ("AT Result  BTA_AG_CNUM_RES");
970        case BTA_AG_BTRH_RES:           return ("AT Result  BTA_AG_BTRH_RES");
971        case BTA_AG_CLCC_RES:           return ("AT Result  BTA_AG_CLCC_RES");
972        case BTA_AG_COPS_RES:           return ("AT Result  BTA_AG_COPS_RES");
973        case BTA_AG_IN_CALL_RES:        return ("AT Result  BTA_AG_IN_CALL_RES");
974        case BTA_AG_IN_CALL_CONN_RES:   return ("AT Result  BTA_AG_IN_CALL_CONN_RES");
975        case BTA_AG_CALL_WAIT_RES:      return ("AT Result  BTA_AG_CALL_WAIT_RES");
976        case BTA_AG_OUT_CALL_ORIG_RES:  return ("AT Result  BTA_AG_OUT_CALL_ORIG_RES");
977        case BTA_AG_OUT_CALL_ALERT_RES: return ("AT Result  BTA_AG_OUT_CALL_ALERT_RES");
978        case BTA_AG_OUT_CALL_CONN_RES:  return ("AT Result  BTA_AG_OUT_CALL_CONN_RES");
979        case BTA_AG_CALL_CANCEL_RES:    return ("AT Result  BTA_AG_CALL_CANCEL_RES");
980        case BTA_AG_END_CALL_RES:       return ("AT Result  BTA_AG_END_CALL_RES");
981        case BTA_AG_UNAT_RES:           return ("AT Result  BTA_AG_UNAT_RES");
982        default:                        return ("Unknown AG Result");
983        }
984    case BTA_AG_API_SETCODEC_EVT:
985        return "Set Codec Request";
986    case BTA_AG_RFC_OPEN_EVT:
987        return "RFC Opened";
988    case BTA_AG_RFC_CLOSE_EVT:
989        return "RFC Closed";
990    case BTA_AG_RFC_SRV_CLOSE_EVT:
991        return "RFC SRV Closed";
992    case BTA_AG_RFC_DATA_EVT:
993        return "RFC Data";
994    case BTA_AG_SCO_OPEN_EVT:
995        return "Audio Opened";
996    case BTA_AG_SCO_CLOSE_EVT:
997        return "Audio Closed";
998    case BTA_AG_DISC_ACP_RES_EVT:
999        return "Discovery ACP Result";
1000    case BTA_AG_DISC_INT_RES_EVT:
1001        return "Discovery INT Result";
1002    case BTA_AG_DISC_OK_EVT:
1003        return "Discovery OK";
1004    case BTA_AG_DISC_FAIL_EVT:
1005        return "Discovery Failed";
1006    case BTA_AG_CI_RX_WRITE_EVT:
1007        return "CI RX Write";
1008    case BTA_AG_RING_TOUT_EVT:
1009        return "Ring Timeout";
1010    case BTA_AG_SVC_TOUT_EVT:
1011        return "Service Timeout";
1012    case BTA_AG_API_ENABLE_EVT:
1013        return "Enable AG";
1014    case BTA_AG_API_DISABLE_EVT:
1015        return "Disable AG";
1016    case BTA_AG_CI_SCO_DATA_EVT:
1017        return "SCO data Callin";
1018    case BTA_AG_CI_SLC_READY_EVT:
1019        return "SLC Ready Callin";
1020    default:
1021        return "Unknown AG Event";
1022    }
1023}
1024
1025static char *bta_ag_state_str(UINT8 state)
1026{
1027    switch (state)
1028    {
1029    case BTA_AG_INIT_ST:
1030        return "Initial";
1031    case BTA_AG_OPENING_ST:
1032        return "Opening";
1033    case BTA_AG_OPEN_ST:
1034        return "Open";
1035    case BTA_AG_CLOSING_ST:
1036        return "Closing";
1037    default:
1038        return "Unknown AG State";
1039    }
1040}
1041
1042#endif
1043