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