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