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