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