• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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