OSDN Git Service

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