bta_ag_main.c revision e6f4ed85b19c49a3577b2c2842bb6ca20452ceb8
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    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*******************************************************************************/
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_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*******************************************************************************/
531BOOLEAN 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*******************************************************************************/
551tBTA_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*******************************************************************************/
579static 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*******************************************************************************/
610void 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*******************************************************************************/
670void 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*******************************************************************************/
699static 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*******************************************************************************/
727static 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*******************************************************************************/
771static 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 *) &reg);
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*******************************************************************************/
799static 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*******************************************************************************/
835void 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*******************************************************************************/
904BOOLEAN 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
944static 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
1026static 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