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