1 /******************************************************************************
2 *
3 * Copyright (c) 2014 The Android Open Source Project
4 * Copyright (C) 2003-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include "osi/include/osi.h"
24 #include "osi/include/properties.h"
25 #include "bt_utils.h"
26 #include "bta_api.h"
27 #include "bta_sys.h"
28 #include "bta_hf_client_api.h"
29 #include "bta_hf_client_int.h"
30
31 /* uncomment to enable extra debug */
32 /* #define BTA_HF_CLIENT_DEBUG TRUE */
33
34 #ifndef BTA_HF_CLIENT_DEBUG
35 #define BTA_HF_CLIENT_DEBUG FALSE
36 #endif
37
38 extern fixed_queue_t *btu_bta_alarm_queue;
39
40 #if BTA_HF_CLIENT_DEBUG == TRUE
41 static char *bta_hf_client_evt_str(UINT16 event);
42 static char *bta_hf_client_state_str(UINT8 state);
43 #endif
44
45 /* state machine states */
46 enum
47 {
48 BTA_HF_CLIENT_INIT_ST,
49 BTA_HF_CLIENT_OPENING_ST,
50 BTA_HF_CLIENT_OPEN_ST,
51 BTA_HF_CLIENT_CLOSING_ST
52 };
53
54 /* state machine action enumeration list */
55 enum
56 {
57 BTA_HF_CLIENT_REGISTER,
58 BTA_HF_CLIENT_DEREGISTER,
59 BTA_HF_CLIENT_START_DEREG,
60 BTA_HF_CLIENT_RFC_DO_CLOSE,
61 BTA_HF_CLIENT_START_CLOSE,
62 BTA_HF_CLIENT_START_OPEN,
63 BTA_HF_CLIENT_RFC_ACP_OPEN,
64 BTA_HF_CLIENT_SCO_LISTEN,
65 BTA_HF_CLIENT_SCO_CONN_OPEN,
66 BTA_HF_CLIENT_SCO_CONN_CLOSE,
67 BTA_HF_CLIENT_SCO_OPEN,
68 BTA_HF_CLIENT_SCO_CLOSE,
69 BTA_HF_CLIENT_SCO_SHUTDOWN,
70 BTA_HF_CLIENT_FREE_DB,
71 BTA_HF_CLIENT_OPEN_FAIL,
72 BTA_HF_CLIENT_RFC_OPEN,
73 BTA_HF_CLIENT_RFC_FAIL,
74 BTA_HF_CLIENT_DISC_INT_RES,
75 BTA_HF_CLIENT_RFC_DO_OPEN,
76 BTA_HF_CLIENT_DISC_FAIL,
77 BTA_HF_CLIENT_RFC_CLOSE,
78 BTA_HF_CLIENT_RFC_DATA,
79 BTA_HF_CLIENT_DISC_ACP_RES,
80 BTA_HF_CLIENT_SVC_CONN_OPEN,
81 BTA_HF_CLIENT_SEND_AT_CMD,
82 BTA_HF_CLIENT_NUM_ACTIONS,
83 };
84
85 #define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS
86
87 /* type for action functions */
88 typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA *p_data);
89
90 /* action functions table, indexed with action enum */
91 const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] =
92 {
93 /* BTA_HF_CLIENT_REGISTER */ bta_hf_client_register,
94 /* BTA_HF_CLIENT_DEREGISTER */ bta_hf_client_deregister,
95 /* BTA_HF_CLIENT_START_DEREG */ bta_hf_client_start_dereg,
96 /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close,
97 /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close,
98 /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open,
99 /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open,
100 /* BTA_HF_CLIENT_SCO_LISTEN */ bta_hf_client_sco_listen,
101 /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
102 /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
103 /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open,
104 /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close,
105 /* BTA_HF_CLIENT_SCO_SHUTDOWN */ bta_hf_client_sco_shutdown,
106 /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db,
107 /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail,
108 /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open,
109 /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail,
110 /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res,
111 /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open,
112 /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail,
113 /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close,
114 /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data,
115 /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res,
116 /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
117 /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
118 };
119
120 /* state table information */
121 #define BTA_HF_CLIENT_ACTIONS 2 /* number of actions */
122 #define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */
123 #define BTA_HF_CLIENT_NUM_COLS 3 /* number of columns in state tables */
124
125 /* state table for init state */
126 const UINT8 bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] =
127 {
128 /* Event Action 1 Action 2 Next state */
129 /* API_REGISTER_EVT */ {BTA_HF_CLIENT_REGISTER, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
130 /* API_DEREGISTER_EVT */ {BTA_HF_CLIENT_DEREGISTER, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
131 /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
132 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
133 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
134 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
135 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_SCO_LISTEN, BTA_HF_CLIENT_OPEN_ST},
136 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
137 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
138 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
139 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
140 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
141 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
142 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
143 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
144 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
145 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
146 };
147
148 /* state table for opening state */
149 const UINT8 bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] =
150 {
151 /* Event Action 1 Action 2 Next state */
152 /* API_REGISTER_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
153 /* API_DEREGISTER_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_START_DEREG, BTA_HF_CLIENT_CLOSING_ST},
154 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
155 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
156 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
157 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
158 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_SCO_LISTEN, BTA_HF_CLIENT_OPEN_ST},
159 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
160 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
161 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
162 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
163 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
164 /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
165 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
166 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
167 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
168 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST},
169 };
170
171 /* state table for open state */
172 const UINT8 bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] =
173 {
174 /* Event Action 1 Action 2 Next state */
175 /* API_REGISTER_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
176 /* API_DEREGISTER_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_START_DEREG, BTA_HF_CLIENT_CLOSING_ST},
177 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
178 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
179 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
180 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
181 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
182 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
183 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
184 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
185 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
186 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
187 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
188 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
189 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
190 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
191 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST},
192 };
193
194 /* state table for closing state */
195 const UINT8 bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] =
196 {
197 /* Event Action 1 Action 2 Next state */
198 /* API_REGISTER_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
199 /* API_DEREGISTER_EVT */ {BTA_HF_CLIENT_START_DEREG, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
200 /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
201 /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
202 /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
203 /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
204 /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
205 /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
206 /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
207 /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
208 /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
209 /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST},
210 /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
211 /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
212 /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
213 /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
214 /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST},
215 };
216
217 /* type for state table */
218 typedef const UINT8 (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS];
219
220 /* state table */
221 const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] =
222 {
223 bta_hf_client_st_init,
224 bta_hf_client_st_opening,
225 bta_hf_client_st_open,
226 bta_hf_client_st_closing
227 };
228
229 /* HF Client control block */
230 tBTA_HF_CLIENT_CB bta_hf_client_cb;
231
232 /*******************************************************************************
233 **
234 ** Function bta_hf_client_scb_init
235 **
236 ** Description Initialize an HF_Client service control block.
237 **
238 **
239 ** Returns void
240 **
241 *******************************************************************************/
bta_hf_client_scb_init(void)242 void bta_hf_client_scb_init(void)
243 {
244 APPL_TRACE_DEBUG("%s", __FUNCTION__);
245
246 alarm_free(bta_hf_client_cb.scb.collision_timer);
247 alarm_free(bta_hf_client_cb.scb.at_cb.resp_timer);
248 alarm_free(bta_hf_client_cb.scb.at_cb.hold_timer);
249 memset(&bta_hf_client_cb.scb, 0, sizeof(tBTA_HF_CLIENT_SCB));
250 bta_hf_client_cb.scb.collision_timer =
251 alarm_new("bta_hf_client.scb_collision_timer");
252 bta_hf_client_cb.scb.sco_idx = BTM_INVALID_SCO_INDEX;
253 bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
254 }
255
256 /*******************************************************************************
257 **
258 ** Function bta_hf_client_scb_disable
259 **
260 ** Description Disable a service control block.
261 **
262 **
263 ** Returns void
264 **
265 *******************************************************************************/
bta_hf_client_scb_disable(void)266 void bta_hf_client_scb_disable(void)
267 {
268 APPL_TRACE_DEBUG("%s", __FUNCTION__);
269
270 bta_hf_client_scb_init();
271
272 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_DISABLE_EVT, NULL);
273 }
274
275 /*******************************************************************************
276 **
277 ** Function bta_hf_client_resume_open
278 **
279 ** Description Resume opening process.
280 **
281 **
282 ** Returns void
283 **
284 *******************************************************************************/
bta_hf_client_resume_open(void)285 void bta_hf_client_resume_open (void)
286 {
287 APPL_TRACE_DEBUG ("%s", __FUNCTION__);
288
289 /* resume opening process. */
290 if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_INIT_ST)
291 {
292 bta_hf_client_cb.scb.state = BTA_HF_CLIENT_OPENING_ST;
293 bta_hf_client_start_open (NULL);
294 }
295 }
296
297 /*******************************************************************************
298 **
299 ** Function bta_hf_client_collision_timer_cback
300 **
301 ** Description HF Client connection collision timer callback
302 **
303 **
304 ** Returns void
305 **
306 *******************************************************************************/
bta_hf_client_collision_timer_cback(UNUSED_ATTR void * data)307 static void bta_hf_client_collision_timer_cback(UNUSED_ATTR void *data)
308 {
309 APPL_TRACE_DEBUG("%s", __FUNCTION__);
310
311 /* If the peer haven't opened connection, restart opening process */
312 bta_hf_client_resume_open();
313 }
314
315 /*******************************************************************************
316 **
317 ** Function bta_hf_client_collision_cback
318 **
319 ** Description Get notified about collision.
320 **
321 **
322 ** Returns void
323 **
324 *******************************************************************************/
bta_hf_client_collision_cback(tBTA_SYS_CONN_STATUS status,UINT8 id,UINT8 app_id,BD_ADDR peer_addr)325 void bta_hf_client_collision_cback (tBTA_SYS_CONN_STATUS status, UINT8 id,
326 UINT8 app_id, BD_ADDR peer_addr)
327 {
328 UNUSED(status);
329 UNUSED(app_id);
330 UNUSED(peer_addr);
331
332 if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_OPENING_ST)
333 {
334 if (id == BTA_ID_SYS) /* ACL collision */
335 {
336 APPL_TRACE_WARNING ("HF Client found collision (ACL) ...");
337 }
338 else if (id == BTA_ID_HS) /* RFCOMM collision */
339 {
340 APPL_TRACE_WARNING ("HF Client found collision (RFCOMM) ...");
341 }
342 else
343 {
344 APPL_TRACE_WARNING ("HF Client found collision (\?\?\?) ...");
345 }
346
347 bta_hf_client_cb.scb.state = BTA_HF_CLIENT_INIT_ST;
348
349 /* Cancel SDP if it had been started. */
350 if(bta_hf_client_cb.scb.p_disc_db)
351 {
352 (void)SDP_CancelServiceSearch (bta_hf_client_cb.scb.p_disc_db);
353 bta_hf_client_free_db(NULL);
354 }
355
356 /* reopen registered server */
357 /* Collision may be detected before or after we close servers. */
358 bta_hf_client_start_server();
359
360 /* Start timer to handle connection opening restart */
361 alarm_set_on_queue(bta_hf_client_cb.scb.collision_timer,
362 BTA_HF_CLIENT_COLLISION_TIMER_MS,
363 bta_hf_client_collision_timer_cback,
364 NULL,
365 btu_bta_alarm_queue);
366 }
367 }
368
369 /*******************************************************************************
370 **
371 ** Function bta_hf_client_api_enable
372 **
373 ** Description Handle an API enable event.
374 **
375 **
376 ** Returns void
377 **
378 *******************************************************************************/
bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA * p_data)379 static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
380 {
381 char value[PROPERTY_VALUE_MAX];
382
383 /* initialize control block */
384 memset(&bta_hf_client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
385
386 /* store callback function */
387 bta_hf_client_cb.p_cback = p_data->api_enable.p_cback;
388
389 /* check if mSBC support enabled */
390 osi_property_get("ro.bluetooth.hfp.ver", value, "0");
391 if (strcmp(value,"1.6") == 0)
392 {
393 bta_hf_client_cb.msbc_enabled = TRUE;
394 }
395
396 bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
397
398 /* set same setting as AG does */
399 BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
400
401 bta_sys_collision_register (BTA_ID_HS, bta_hf_client_collision_cback);
402
403 /* call callback with enable event */
404 (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_ENABLE_EVT, NULL);
405 }
406
407 /*******************************************************************************
408 **
409 ** Function bta_hf_client_api_disable
410 **
411 ** Description Handle an API disable event.
412 **
413 **
414 ** Returns void
415 **
416 *******************************************************************************/
bta_hf_client_api_disable(tBTA_HF_CLIENT_DATA * p_data)417 static void bta_hf_client_api_disable(tBTA_HF_CLIENT_DATA *p_data)
418 {
419 if (!bta_sys_is_register (BTA_ID_HS))
420 {
421 APPL_TRACE_ERROR("BTA HF Client is already disabled, ignoring ...");
422 return;
423 }
424
425 /* De-register with BTA system manager */
426 bta_sys_deregister(BTA_ID_HS);
427
428 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_DEREGISTER_EVT, p_data);
429
430 bta_sys_collision_register (BTA_ID_HS, NULL);
431 }
432
433 /*******************************************************************************
434 **
435 ** Function bta_hf_client_hdl_event
436 **
437 ** Description Data HF Client main event handling function.
438 **
439 **
440 ** Returns BOOLEAN
441 **
442 *******************************************************************************/
bta_hf_client_hdl_event(BT_HDR * p_msg)443 BOOLEAN bta_hf_client_hdl_event(BT_HDR *p_msg)
444 {
445 #if BTA_HF_CLIENT_DEBUG == TRUE
446 APPL_TRACE_DEBUG("bta_hf_client_hdl_event %s (0x%x)", bta_hf_client_evt_str(p_msg->event), p_msg->event);
447 #endif
448
449 switch (p_msg->event)
450 {
451 /* handle enable event */
452 case BTA_HF_CLIENT_API_ENABLE_EVT:
453 bta_hf_client_api_enable((tBTA_HF_CLIENT_DATA *) p_msg);
454 break;
455
456 /* handle disable event */
457 case BTA_HF_CLIENT_API_DISABLE_EVT:
458 bta_hf_client_api_disable((tBTA_HF_CLIENT_DATA *) p_msg);
459 break;
460
461 default:
462 bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA *) p_msg);
463 break;
464 }
465 return TRUE;
466 }
467
468 /*******************************************************************************
469 **
470 ** Function bta_hf_client_sm_execute
471 **
472 ** Description State machine event handling function for HF Client
473 **
474 **
475 ** Returns void
476 **
477 *******************************************************************************/
bta_hf_client_sm_execute(UINT16 event,tBTA_HF_CLIENT_DATA * p_data)478 void bta_hf_client_sm_execute(UINT16 event, tBTA_HF_CLIENT_DATA *p_data)
479 {
480 tBTA_HF_CLIENT_ST_TBL state_table;
481 UINT8 action;
482 int i;
483
484 #if BTA_HF_CLIENT_DEBUG == TRUE
485 UINT16 in_event = event;
486 UINT8 in_state = bta_hf_client_cb.scb.state;
487
488 /* Ignore displaying of AT results when not connected (Ignored in state machine) */
489 if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_OPEN_ST)
490 {
491 APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)",
492 bta_hf_client_cb.scb.state,
493 bta_hf_client_state_str(bta_hf_client_cb.scb.state),
494 event, bta_hf_client_evt_str(event));
495 }
496 #endif
497
498 event &= 0x00FF;
499 if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF))
500 {
501 APPL_TRACE_ERROR("HF Client evt out of range, ignoring...");
502 return;
503 }
504
505 /* look up the state table for the current state */
506 state_table = bta_hf_client_st_tbl[bta_hf_client_cb.scb.state];
507
508 /* set next state */
509 bta_hf_client_cb.scb.state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
510
511 /* execute action functions */
512 for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++)
513 {
514 if ((action = state_table[event][i]) != BTA_HF_CLIENT_IGNORE)
515 {
516 (*bta_hf_client_action[action])(p_data);
517 }
518 else
519 {
520 break;
521 }
522 }
523
524 #if BTA_HF_CLIENT_DEBUG == TRUE
525 if (bta_hf_client_cb.scb.state != in_state)
526 {
527 APPL_TRACE_EVENT("BTA HF Client State Change: [%s] -> [%s] after Event [%s]",
528 bta_hf_client_state_str(in_state),
529 bta_hf_client_state_str(bta_hf_client_cb.scb.state),
530 bta_hf_client_evt_str(in_event));
531 }
532 #endif
533 }
534
send_post_slc_cmd(void)535 static void send_post_slc_cmd(void)
536 {
537 bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
538
539 bta_hf_client_send_at_bia();
540 bta_hf_client_send_at_ccwa(TRUE);
541 bta_hf_client_send_at_cmee(TRUE);
542 bta_hf_client_send_at_cops(FALSE);
543 bta_hf_client_send_at_btrh(TRUE, 0);
544 bta_hf_client_send_at_clip(TRUE);
545 }
546
547 /*******************************************************************************
548 **
549 ** Function bta_hf_client_slc_seq
550 **
551 ** Description Handles AT commands sequence required for SLC creation
552 **
553 **
554 ** Returns void
555 **
556 *******************************************************************************/
bta_hf_client_slc_seq(BOOLEAN error)557 void bta_hf_client_slc_seq(BOOLEAN error)
558 {
559 APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u", bta_hf_client_cb.scb.at_cb.current_cmd);
560
561 if (error) {
562 /* SLC establishment error, sent close rfcomm event */
563 APPL_TRACE_ERROR("HFPClient: Failed to create SLC due to AT error, disconnecting (%u)",
564 bta_hf_client_cb.scb.at_cb.current_cmd);
565
566 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
567 return;
568 }
569
570 if (bta_hf_client_cb.scb.svc_conn)
571 return;
572
573 switch (bta_hf_client_cb.scb.at_cb.current_cmd)
574 {
575 case BTA_HF_CLIENT_AT_NONE:
576 bta_hf_client_send_at_brsf();
577 break;
578
579 case BTA_HF_CLIENT_AT_BRSF:
580 if ((bta_hf_client_cb.scb.features & BTA_HF_CLIENT_FEAT_CODEC)
581 && (bta_hf_client_cb.scb.peer_features & BTA_HF_CLIENT_PEER_CODEC))
582 {
583 bta_hf_client_send_at_bac();
584 break;
585 }
586
587 bta_hf_client_send_at_cind(FALSE);
588 break;
589
590 case BTA_HF_CLIENT_AT_BAC:
591 bta_hf_client_send_at_cind(FALSE);
592 break;
593
594 case BTA_HF_CLIENT_AT_CIND:
595 bta_hf_client_send_at_cind(TRUE);
596 break;
597
598 case BTA_HF_CLIENT_AT_CIND_STATUS:
599 bta_hf_client_send_at_cmer(TRUE);
600 break;
601
602 case BTA_HF_CLIENT_AT_CMER:
603 if (bta_hf_client_cb.scb.peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY
604 && bta_hf_client_cb.scb.features & BTA_HF_CLIENT_FEAT_3WAY)
605 {
606 bta_hf_client_send_at_chld('?', 0);
607 }
608 else
609 {
610 bta_hf_client_svc_conn_open(NULL);
611 send_post_slc_cmd();
612 }
613 break;
614
615 case BTA_HF_CLIENT_AT_CHLD:
616 bta_hf_client_svc_conn_open(NULL);
617 send_post_slc_cmd();
618 break;
619
620 default:
621 /* If happen there is a bug in SLC creation procedure... */
622 APPL_TRACE_ERROR("HFPClient: Failed to create SLCdue to unexpected AT command, disconnecting (%u)",
623 bta_hf_client_cb.scb.at_cb.current_cmd);
624
625 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
626 break;
627 }
628 }
629
630 #if BTA_HF_CLIENT_DEBUG == TRUE
631
632 #ifndef CASE_RETURN_STR
633 #define CASE_RETURN_STR(const) case const: return #const;
634 #endif
635
bta_hf_client_evt_str(UINT16 event)636 static char *bta_hf_client_evt_str(UINT16 event)
637 {
638 switch (event)
639 {
640 CASE_RETURN_STR(BTA_HF_CLIENT_API_REGISTER_EVT)
641 CASE_RETURN_STR(BTA_HF_CLIENT_API_DEREGISTER_EVT)
642 CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT)
643 CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT)
644 CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT)
645 CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT)
646 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT)
647 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT)
648 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT)
649 CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT)
650 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT)
651 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT)
652 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT)
653 CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT)
654 CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT)
655 CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT)
656 CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT)
657 CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT)
658 CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT)
659 default:
660 return "Unknown HF Client Event";
661 }
662 }
663
bta_hf_client_state_str(UINT8 state)664 static char *bta_hf_client_state_str(UINT8 state)
665 {
666 switch (state)
667 {
668 CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST)
669 CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST)
670 CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST)
671 CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST)
672 default:
673 return "Unknown HF Client State";
674 }
675 }
676 #endif
677