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*)®);
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