• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (c) 2016 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 <base/logging.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "bt_utils.h"
26 #include "bta_api.h"
27 #include "bta_hf_client_api.h"
28 #include "bta_hf_client_int.h"
29 #include "bta_sys.h"
30 #include "osi/include/osi.h"
31 #include "osi/include/properties.h"
32 #include "utl.h"
33 
34 static const char* bta_hf_client_evt_str(uint16_t event);
35 static const char* bta_hf_client_state_str(uint8_t state);
36 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle);
37 
38 /* state machine states */
39 enum {
40   BTA_HF_CLIENT_INIT_ST,
41   BTA_HF_CLIENT_OPENING_ST,
42   BTA_HF_CLIENT_OPEN_ST,
43   BTA_HF_CLIENT_CLOSING_ST
44 };
45 
46 /* state machine action enumeration list */
47 enum {
48   BTA_HF_CLIENT_RFC_DO_CLOSE,
49   BTA_HF_CLIENT_START_CLOSE,
50   BTA_HF_CLIENT_START_OPEN,
51   BTA_HF_CLIENT_RFC_ACP_OPEN,
52   BTA_HF_CLIENT_SCO_LISTEN,
53   BTA_HF_CLIENT_SCO_CONN_OPEN,
54   BTA_HF_CLIENT_SCO_CONN_CLOSE,
55   BTA_HF_CLIENT_SCO_OPEN,
56   BTA_HF_CLIENT_SCO_CLOSE,
57   BTA_HF_CLIENT_FREE_DB,
58   BTA_HF_CLIENT_OPEN_FAIL,
59   BTA_HF_CLIENT_RFC_OPEN,
60   BTA_HF_CLIENT_RFC_FAIL,
61   BTA_HF_CLIENT_DISC_INT_RES,
62   BTA_HF_CLIENT_RFC_DO_OPEN,
63   BTA_HF_CLIENT_DISC_FAIL,
64   BTA_HF_CLIENT_RFC_CLOSE,
65   BTA_HF_CLIENT_RFC_DATA,
66   BTA_HF_CLIENT_DISC_ACP_RES,
67   BTA_HF_CLIENT_SVC_CONN_OPEN,
68   BTA_HF_CLIENT_SEND_AT_CMD,
69   BTA_HF_CLIENT_NUM_ACTIONS,
70 };
71 
72 #define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS
73 
74 /* type for action functions */
75 typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA* p_data);
76 
77 /* action functions table, indexed with action enum */
78 const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = {
79     /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close,
80     /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close,
81     /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open,
82     /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open,
83     /* BTA_HF_CLIENT_SCO_LISTEN */ NULL,
84     /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
85     /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
86     /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open,
87     /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close,
88     /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db,
89     /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail,
90     /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open,
91     /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail,
92     /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res,
93     /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open,
94     /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail,
95     /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close,
96     /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data,
97     /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res,
98     /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
99     /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
100 };
101 
102 /* state table information */
103 #define BTA_HF_CLIENT_ACTIONS 2    /* number of actions */
104 #define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */
105 #define BTA_HF_CLIENT_NUM_COLS 3   /* number of columns in state tables */
106 
107 /* state table for init state */
108 const uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = {
109     /* Event                    Action 1                       Action 2
110        Next state */
111     /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE,
112                         BTA_HF_CLIENT_OPENING_ST},
113     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
114                          BTA_HF_CLIENT_INIT_ST},
115     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
116                               BTA_HF_CLIENT_INIT_ST},
117     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
118                                BTA_HF_CLIENT_INIT_ST},
119     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_IGNORE,
120                         BTA_HF_CLIENT_OPEN_ST},
121     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
122                          BTA_HF_CLIENT_INIT_ST},
123     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
124                              BTA_HF_CLIENT_INIT_ST},
125     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
126                         BTA_HF_CLIENT_INIT_ST},
127     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
128                             BTA_HF_CLIENT_INIT_ST},
129     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
130                             BTA_HF_CLIENT_INIT_ST},
131     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
132                        BTA_HF_CLIENT_INIT_ST},
133     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
134                          BTA_HF_CLIENT_INIT_ST},
135     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
136                         BTA_HF_CLIENT_INIT_ST},
137     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
138                          BTA_HF_CLIENT_INIT_ST},
139     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
140                            BTA_HF_CLIENT_INIT_ST},
141 };
142 
143 /* state table for opening state */
144 const uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = {
145     /* Event                    Action 1                       Action 2
146        Next state */
147     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
148                         BTA_HF_CLIENT_OPENING_ST},
149     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE,
150                          BTA_HF_CLIENT_CLOSING_ST},
151     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
152                               BTA_HF_CLIENT_OPENING_ST},
153     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
154                                BTA_HF_CLIENT_OPENING_ST},
155     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_IGNORE,
156                         BTA_HF_CLIENT_OPEN_ST},
157     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE,
158                          BTA_HF_CLIENT_INIT_ST},
159     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
160                              BTA_HF_CLIENT_OPENING_ST},
161     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
162                         BTA_HF_CLIENT_OPENING_ST},
163     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
164                             BTA_HF_CLIENT_OPENING_ST},
165     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE,
166                             BTA_HF_CLIENT_OPENING_ST},
167     /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE,
168                        BTA_HF_CLIENT_OPENING_ST},
169     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE,
170                          BTA_HF_CLIENT_INIT_ST},
171     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
172                         BTA_HF_CLIENT_OPENING_ST},
173     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
174                          BTA_HF_CLIENT_OPENING_ST},
175     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
176                            BTA_HF_CLIENT_OPENING_ST},
177 };
178 
179 /* state table for open state */
180 const uint8_t bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = {
181     /* Event                    Action 1                       Action 2
182        Next state */
183     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
184                         BTA_HF_CLIENT_OPEN_ST},
185     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE,
186                          BTA_HF_CLIENT_CLOSING_ST},
187     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE,
188                               BTA_HF_CLIENT_OPEN_ST},
189     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE,
190                                BTA_HF_CLIENT_OPEN_ST},
191     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
192                         BTA_HF_CLIENT_OPEN_ST},
193     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
194                          BTA_HF_CLIENT_INIT_ST},
195     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
196                              BTA_HF_CLIENT_OPEN_ST},
197     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE,
198                         BTA_HF_CLIENT_OPEN_ST},
199     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE,
200                             BTA_HF_CLIENT_OPEN_ST},
201     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
202                             BTA_HF_CLIENT_OPEN_ST},
203     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
204                        BTA_HF_CLIENT_OPEN_ST},
205     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
206                          BTA_HF_CLIENT_OPEN_ST},
207     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE,
208                         BTA_HF_CLIENT_OPEN_ST},
209     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE,
210                          BTA_HF_CLIENT_OPEN_ST},
211     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE,
212                            BTA_HF_CLIENT_OPEN_ST},
213 };
214 
215 /* state table for closing state */
216 const uint8_t bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = {
217     /* Event                    Action 1                       Action 2
218        Next state */
219     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
220                         BTA_HF_CLIENT_CLOSING_ST},
221     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
222                          BTA_HF_CLIENT_CLOSING_ST},
223     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
224                               BTA_HF_CLIENT_CLOSING_ST},
225     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
226                                BTA_HF_CLIENT_CLOSING_ST},
227     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
228                         BTA_HF_CLIENT_CLOSING_ST},
229     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
230                          BTA_HF_CLIENT_INIT_ST},
231     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
232                              BTA_HF_CLIENT_CLOSING_ST},
233     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
234                         BTA_HF_CLIENT_CLOSING_ST},
235     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
236                             BTA_HF_CLIENT_CLOSING_ST},
237     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
238                             BTA_HF_CLIENT_INIT_ST},
239     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
240                        BTA_HF_CLIENT_CLOSING_ST},
241     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
242                          BTA_HF_CLIENT_CLOSING_ST},
243     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
244                         BTA_HF_CLIENT_CLOSING_ST},
245     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
246                          BTA_HF_CLIENT_CLOSING_ST},
247     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
248                            BTA_HF_CLIENT_CLOSING_ST},
249 };
250 
251 /* type for state table */
252 typedef const uint8_t (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS];
253 
254 /* state table */
255 const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
256     bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open,
257     bta_hf_client_st_closing};
258 
259 /* HF Client control block */
260 tBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr;
261 
262 /* Event handler for the state machine */
263 static const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event,
264                                                BTA_HfClientDisable};
265 
266 /*******************************************************************************
267  *
268  * Function         bta_hf_client_cb_arr_init
269  *
270  * Description      Initialize entire control block array set
271  *
272  *
273  * Returns          void
274  *
275  ******************************************************************************/
bta_hf_client_cb_arr_init()276 void bta_hf_client_cb_arr_init() {
277   memset(&bta_hf_client_cb_arr, 0, sizeof(tBTA_HF_CLIENT_CB_ARR));
278 
279   // reset the handles and make the CBs non-allocated
280   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
281     // Allocate the handles in increasing order of indices
282     bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
283     bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i;
284   }
285 }
286 
287 /*******************************************************************************
288  *
289  * Function         bta_hf_client_cb_init
290  *
291  * Description      Initialize an HF_Client service control block. Assign the
292  *                  handle to cb->handle.
293  *
294  *
295  *
296  * Returns          void
297  *
298  ******************************************************************************/
bta_hf_client_cb_init(tBTA_HF_CLIENT_CB * client_cb,uint16_t handle)299 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) {
300   APPL_TRACE_DEBUG("%s", __func__);
301 
302   // Free any memory we need to explicity release
303   alarm_free(client_cb->collision_timer);
304 
305   // Memset the rest of the block
306   memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
307 
308   // Re allocate any variables required
309   client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer");
310   client_cb->handle = handle;
311   client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
312 }
313 
314 /*******************************************************************************
315  *
316  * Function         bta_hf_client_resume_open
317  *
318  * Description      Resume opening process.
319  *
320  *
321  * Returns          void
322  *
323  ******************************************************************************/
bta_hf_client_resume_open(tBTA_HF_CLIENT_CB * client_cb)324 void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) {
325   APPL_TRACE_DEBUG("%s", __func__);
326 
327   /* resume opening process.  */
328   if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
329     client_cb->state = BTA_HF_CLIENT_OPENING_ST;
330     tBTA_HF_CLIENT_DATA msg;
331     msg.hdr.layer_specific = client_cb->handle;
332     bta_hf_client_start_open(&msg);
333   }
334 }
335 
336 /*******************************************************************************
337  *
338  * Function         bta_hf_client_collision_timer_cback
339  *
340  * Description      HF Client connection collision timer callback
341  *
342  *
343  * Returns          void
344  *
345  ******************************************************************************/
bta_hf_client_collision_timer_cback(void * data)346 static void bta_hf_client_collision_timer_cback(void* data) {
347   APPL_TRACE_DEBUG("%s", __func__);
348   tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
349 
350   /* If the peer haven't opened connection, restart opening process */
351   bta_hf_client_resume_open(client_cb);
352 }
353 
354 /*******************************************************************************
355  *
356  * Function         bta_hf_client_collision_cback
357  *
358  * Description      Get notified about collision.
359  *
360  *
361  * Returns          void
362  *
363  ******************************************************************************/
bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,uint8_t id,UNUSED_ATTR uint8_t app_id,const RawAddress * peer_addr)364 void bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,
365                                    uint8_t id, UNUSED_ATTR uint8_t app_id,
366                                    const RawAddress* peer_addr) {
367   tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(*peer_addr);
368   if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) {
369     if (id == BTA_ID_SYS) /* ACL collision */
370     {
371       APPL_TRACE_WARNING("HF Client found collision (ACL) ...");
372     } else if (id == BTA_ID_HS) /* RFCOMM collision */
373     {
374       APPL_TRACE_WARNING("HF Client found collision (RFCOMM) ...");
375     } else {
376       APPL_TRACE_WARNING("HF Client found collision (\?\?\?) ...");
377     }
378 
379     client_cb->state = BTA_HF_CLIENT_INIT_ST;
380 
381     /* Cancel SDP if it had been started. */
382     if (client_cb->p_disc_db) {
383       (void)SDP_CancelServiceSearch(client_cb->p_disc_db);
384       bta_hf_client_free_db(NULL);
385     }
386 
387     /* reopen registered server */
388     /* Collision may be detected before or after we close servers. */
389     // bta_hf_client_start_server();
390 
391     /* Start timer to handle connection opening restart */
392     alarm_set_on_mloop(client_cb->collision_timer,
393                        BTA_HF_CLIENT_COLLISION_TIMER_MS,
394                        bta_hf_client_collision_timer_cback, (void*)client_cb);
395   }
396 }
397 
398 /*******************************************************************************
399  *
400  * Function         bta_hf_client_api_enable
401  *
402  * Description      Handle an API enable event.
403  *
404  *
405  * Returns          void
406  *
407  ******************************************************************************/
bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK * p_cback,tBTA_SEC sec_mask,tBTA_HF_CLIENT_FEAT features,const char * p_service_name)408 tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
409                                      tBTA_SEC sec_mask,
410                                      tBTA_HF_CLIENT_FEAT features,
411                                      const char* p_service_name) {
412   /* If already registered then return error */
413   if (bta_sys_is_register(BTA_ID_HS)) {
414     APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ...");
415     return BTA_FAILURE;
416   }
417 
418   /* register with BTA system manager */
419   bta_sys_register(BTA_ID_HS, &bta_hf_client_reg);
420 
421   /* reset the control blocks */
422   bta_hf_client_cb_arr_init();
423 
424   bta_hf_client_cb_arr.p_cback = p_cback;
425   bta_hf_client_cb_arr.serv_sec_mask = sec_mask;
426   bta_hf_client_cb_arr.features = features;
427 
428   /* create SDP records */
429   bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name);
430 
431   /* set same setting as AG does */
432   BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
433 
434   bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback);
435 
436   /* Set the Audio service class bit */
437   tBTA_UTL_COD cod;
438   cod.service = BTM_COD_SERVICE_AUDIO;
439   utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
440 
441   /* start RFCOMM server */
442   bta_hf_client_start_server();
443 
444   return BTA_SUCCESS;
445 }
446 
447 /*******************************************************************************
448  *
449  * Function         bta_hf_client_find_cb_by_handle
450  *
451  * Description      Finds the control block by handle provided
452  *
453  *                  handle: Handle as obtained from BTA_HfClientOpen call
454  *
455  *
456  * Returns          Control block corresponding to the handle and NULL if
457  *                  none exists
458  *
459  ******************************************************************************/
bta_hf_client_find_cb_by_handle(uint16_t handle)460 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) {
461   // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES
462   if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) {
463     APPL_TRACE_ERROR("%s: handle out of range (%d, %d) %d", __func__, 1,
464                      HF_CLIENT_MAX_DEVICES, handle);
465     return NULL;
466   }
467 
468   // Check if the associated index is allocated. Index is (handle - 1).
469   if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated)
470     return &(bta_hf_client_cb_arr.cb[handle - 1]);
471 
472   APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
473   return NULL;
474 }
475 
476 /*******************************************************************************
477  *
478  * Function         bta_hf_client_find_cb_by_bda
479  *
480  * Description      Finds the control block by handle provided
481  *
482  *                  bda: address of the device to find the handle for.
483  *                  Since there can only be one HF connection for a device
484  *                  we should always find a unique block
485  *
486  * Returns          Control block corresponding to the address and NULL if
487  *                  none exists
488  *
489  ******************************************************************************/
bta_hf_client_find_cb_by_bda(const RawAddress & peer_addr)490 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const RawAddress& peer_addr) {
491   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
492     // Check if the associated index is allocated and that BD ADDR matches
493     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
494     if (client_cb->is_allocated && peer_addr == client_cb->peer_addr) {
495       return client_cb;
496     } else {
497       APPL_TRACE_WARNING("%s: bdaddr mismatch for handle %d alloc %d", __func__,
498                          i, client_cb->is_allocated);
499     }
500   }
501   APPL_TRACE_ERROR("%s: block not found", __func__);
502   return NULL;
503 }
504 
505 /*******************************************************************************
506  *
507  * Function         bta_hf_client_find_cb_by_rfc_handle
508  *
509  * Description      Finds the control block by RFC handle provided.
510  *
511  *                  handle: RFC handle for the established connection
512  *
513  *
514  * Returns          Control block corresponding to the handle and NULL if none
515  *                  exists
516  *
517  ******************************************************************************/
bta_hf_client_find_cb_by_rfc_handle(uint16_t handle)518 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) {
519   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
520     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
521     bool is_allocated = client_cb->is_allocated;
522     uint16_t conn_handle = client_cb->conn_handle;
523 
524     APPL_TRACE_DEBUG("%s: cb rfc_handle %d alloc %d conn_handle %d", __func__,
525                      handle, is_allocated, conn_handle);
526 
527     if (is_allocated && conn_handle == handle) {
528       return client_cb;
529     }
530 
531     APPL_TRACE_WARNING("%s: no cb yet %d alloc %d conn_handle %d", __func__,
532                        handle, is_allocated, conn_handle);
533   }
534 
535   APPL_TRACE_ERROR("%s: no cb found for rfc handle %d", __func__, handle);
536   return NULL;
537 }
538 
539 /*******************************************************************************
540  *
541  * Function         bta_hf_client_find_cb_by_sco_handle
542  *
543  * Description      Finds the control block by sco handle provided
544  *
545  *                  handle: sco handle
546  *
547  *
548  * Returns          Control block corresponding to the sco handle and
549  *                  none if none exists
550  *
551  ******************************************************************************/
bta_hf_client_find_cb_by_sco_handle(uint16_t handle)552 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) {
553   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
554     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
555     if (client_cb->is_allocated && client_cb->sco_idx == handle) {
556       return client_cb;
557     }
558   }
559   APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
560   return NULL;
561 }
562 
563 /*******************************************************************************
564  *
565  * Function         bta_hf_client_allocate_handle
566  *
567  * Description      Allocates a handle for the new BD ADDR that needs a new RF
568  *                  channel for HF connection. If the channel cannot be created
569  *                  for a reason then false is returned
570  *
571  *                  bd_addr: Address of the device for which this block is
572  *                  being created. Single device can only have one block.
573  *                  p_handle: OUT variable to store the outcome of allocate. If
574  *                  allocate failed then value is not valid
575  *
576  *
577  * Returns          true if the creation of p_handle succeeded, false otherwise
578  *
579  ******************************************************************************/
bta_hf_client_allocate_handle(const RawAddress & bd_addr,uint16_t * p_handle)580 bool bta_hf_client_allocate_handle(const RawAddress& bd_addr,
581                                    uint16_t* p_handle) {
582   tBTA_HF_CLIENT_CB* existing_cb = bta_hf_client_find_cb_by_bda(bd_addr);
583   if (existing_cb != NULL) {
584     BTIF_TRACE_ERROR("%s: cannot allocate handle since BDADDR already exists",
585                      __func__);
586     return false;
587   }
588   /* Check that we do not have a request to for same device in the control
589    * blocks */
590   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
591     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
592     if (client_cb->is_allocated) {
593       APPL_TRACE_WARNING("%s: control block already used index %d", __func__,
594                          i);
595       continue;
596     }
597 
598     // Reset the client control block
599     bta_hf_client_cb_init(client_cb, client_cb->handle);
600 
601     *p_handle = client_cb->handle;
602     APPL_TRACE_DEBUG("%s: marking CB handle %d to true", __func__,
603                      client_cb->handle);
604 
605     client_cb->is_allocated = true;
606     client_cb->peer_addr = bd_addr;
607     bta_hf_client_at_init(client_cb);
608     return true;
609   }
610 
611   return false;
612   APPL_TRACE_ERROR("%s: all control blocks in use!", __func__);
613 }
614 
615 /*******************************************************************************
616  *
617  * Function         bta_hf_client_app_callback
618  *
619  * Description      Calls the application callback
620  *
621  *
622  * Returns          Void
623  *
624  ******************************************************************************/
bta_hf_client_app_callback(uint16_t event,tBTA_HF_CLIENT * data)625 void bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data) {
626   if (bta_hf_client_cb_arr.p_cback != NULL) {
627     bta_hf_client_cb_arr.p_cback(event, data);
628   }
629 }
630 
631 /*******************************************************************************
632  *
633  * Function         bta_hf_client_api_disable
634  *
635  * Description      Handle an API disable event.
636  *
637  *
638  * Returns          void
639  *
640  ******************************************************************************/
bta_hf_client_api_disable()641 void bta_hf_client_api_disable() {
642   if (!bta_sys_is_register(BTA_ID_HS)) {
643     APPL_TRACE_WARNING("BTA HF Client is already disabled, ignoring ...");
644     return;
645   }
646 
647   /* Remove the collision handler */
648   bta_sys_collision_register(BTA_ID_HS, NULL);
649 
650   bta_hf_client_cb_arr.deregister = true;
651 
652   /* remove sdp record */
653   bta_hf_client_del_record(&bta_hf_client_cb_arr);
654 
655   /* remove rfcomm server */
656   bta_hf_client_close_server();
657 
658   /* reinit the control block */
659   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
660     if (bta_hf_client_cb_arr.cb[i].is_allocated) {
661       bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
662     }
663   }
664 
665   /* De-register with BTA system manager */
666   bta_sys_deregister(BTA_ID_HS);
667 }
668 
669 /*******************************************************************************
670  *
671  * Function         bta_hf_client_hdl_event
672  *
673  * Description      Data HF Client main event handling function.
674  *
675  *
676  * Returns          bool
677  *
678  ******************************************************************************/
bta_hf_client_hdl_event(BT_HDR * p_msg)679 bool bta_hf_client_hdl_event(BT_HDR* p_msg) {
680   APPL_TRACE_DEBUG("%s: %s (0x%x)", __func__,
681                    bta_hf_client_evt_str(p_msg->event), p_msg->event);
682   bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg);
683   return true;
684 }
685 
686 /*******************************************************************************
687  *
688  * Function         bta_hf_client_sm_execute
689  *
690  * Description      State machine event handling function for HF Client
691  *
692  *
693  * Returns          void
694  *
695  ******************************************************************************/
bta_hf_client_sm_execute(uint16_t event,tBTA_HF_CLIENT_DATA * p_data)696 void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) {
697   tBTA_HF_CLIENT_CB* client_cb =
698       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
699   if (client_cb == NULL) {
700     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
701                      p_data->hdr.layer_specific);
702     return;
703   }
704 
705   tBTA_HF_CLIENT_ST_TBL state_table;
706   uint8_t action;
707   int i;
708 
709   uint16_t in_event = event;
710   uint8_t in_state = client_cb->state;
711 
712   /* Ignore displaying of AT results when not connected (Ignored in state
713    * machine) */
714   if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
715     APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)",
716                      client_cb->state,
717                      bta_hf_client_state_str(client_cb->state), event,
718                      bta_hf_client_evt_str(event));
719   }
720 
721   event &= 0x00FF;
722   if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) {
723     APPL_TRACE_ERROR("HF Client evt out of range, ignoring...");
724     return;
725   }
726 
727   /* look up the state table for the current state */
728   state_table = bta_hf_client_st_tbl[client_cb->state];
729 
730   /* set next state */
731   client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
732 
733   /* execute action functions */
734   for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) {
735     action = state_table[event][i];
736     if (action != BTA_HF_CLIENT_IGNORE) {
737       (*bta_hf_client_action[action])(p_data);
738     } else {
739       break;
740     }
741   }
742 
743   /* If the state has changed then notify the app of the corresponding change */
744   if (in_state != client_cb->state) {
745     VLOG(1) << __func__ << ": notifying state change to " << in_state << " -> "
746             << client_cb->state << " device " << client_cb->peer_addr;
747     tBTA_HF_CLIENT evt;
748     memset(&evt, 0, sizeof(evt));
749     evt.bd_addr = client_cb->peer_addr;
750     if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
751       bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);
752     } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
753       evt.open.handle = client_cb->handle;
754       bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt);
755     }
756   }
757 
758   /* if the next state is INIT then release the cb for future use */
759   if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
760     APPL_TRACE_DEBUG("%s: marking CB handle %d to false", __func__,
761                      client_cb->handle);
762     client_cb->is_allocated = false;
763   }
764 
765   VLOG(2) << __func__ << ": device " << client_cb->peer_addr
766           << "state change: [" << bta_hf_client_state_str(in_state) << "] -> ["
767           << bta_hf_client_state_str(client_cb->state) << "] after Event ["
768           << bta_hf_client_evt_str(in_event) << "]";
769 }
770 
send_post_slc_cmd(tBTA_HF_CLIENT_CB * client_cb)771 static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) {
772   client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
773 
774   tBTA_HF_CLIENT_DATA p_data;
775   p_data.hdr.layer_specific = client_cb->handle;
776   bta_hf_client_sco_listen(&p_data);
777   bta_hf_client_send_at_bia(client_cb);
778   bta_hf_client_send_at_ccwa(client_cb, true);
779   bta_hf_client_send_at_cmee(client_cb, true);
780   bta_hf_client_send_at_cops(client_cb, false);
781   bta_hf_client_send_at_btrh(client_cb, true, 0);
782   bta_hf_client_send_at_clip(client_cb, true);
783 }
784 
785 /*******************************************************************************
786  *
787  * Function         bta_hf_client_slc_seq
788  *
789  * Description      Handles AT commands sequence required for SLC creation
790  *
791  *
792  * Returns          void
793  *
794  ******************************************************************************/
bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB * client_cb,bool error)795 void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
796   APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u",
797                    client_cb->at_cb.current_cmd);
798 
799   if (error) {
800     /* SLC establishment error, sent close rfcomm event */
801     APPL_TRACE_ERROR(
802         "HFPClient: Failed to create SLC due to AT error, disconnecting (%u)",
803         client_cb->at_cb.current_cmd);
804 
805     tBTA_HF_CLIENT_DATA msg;
806     msg.hdr.layer_specific = client_cb->handle;
807     bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
808     return;
809   }
810 
811   if (client_cb->svc_conn) {
812     APPL_TRACE_WARNING("%s: SLC already connected for CB handle %d", __func__,
813                        client_cb->handle);
814     return;
815   }
816 
817   switch (client_cb->at_cb.current_cmd) {
818     case BTA_HF_CLIENT_AT_NONE:
819       bta_hf_client_send_at_brsf(client_cb, bta_hf_client_cb_arr.features);
820       break;
821 
822     case BTA_HF_CLIENT_AT_BRSF:
823       if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_CODEC) &&
824           (client_cb->peer_features & BTA_HF_CLIENT_PEER_CODEC)) {
825         bta_hf_client_send_at_bac(client_cb);
826         break;
827       }
828 
829       bta_hf_client_send_at_cind(client_cb, false);
830       break;
831 
832     case BTA_HF_CLIENT_AT_BAC:
833       bta_hf_client_send_at_cind(client_cb, false);
834       break;
835 
836     case BTA_HF_CLIENT_AT_CIND:
837       bta_hf_client_send_at_cind(client_cb, true);
838       break;
839 
840     case BTA_HF_CLIENT_AT_CIND_STATUS:
841       bta_hf_client_send_at_cmer(client_cb, true);
842       break;
843 
844     case BTA_HF_CLIENT_AT_CMER:
845       if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY &&
846           bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) {
847         bta_hf_client_send_at_chld(client_cb, '?', 0);
848       } else {
849         tBTA_HF_CLIENT_DATA msg;
850         msg.hdr.layer_specific = client_cb->handle;
851         bta_hf_client_svc_conn_open(&msg);
852         send_post_slc_cmd(client_cb);
853       }
854       break;
855 
856     case BTA_HF_CLIENT_AT_CHLD: {
857       tBTA_HF_CLIENT_DATA msg;
858       msg.hdr.layer_specific = client_cb->handle;
859       bta_hf_client_svc_conn_open(&msg);
860       send_post_slc_cmd(client_cb);
861       break;
862     }
863 
864     default: {
865       /* If happen there is a bug in SLC creation procedure... */
866       APPL_TRACE_ERROR(
867           "HFPClient: Failed to create SLCdue to unexpected AT command, "
868           "disconnecting (%u)",
869           client_cb->at_cb.current_cmd);
870 
871       tBTA_HF_CLIENT_DATA msg;
872       msg.hdr.layer_specific = client_cb->handle;
873       bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
874       break;
875     }
876   }
877 }
878 
879 #ifndef CASE_RETURN_STR
880 #define CASE_RETURN_STR(const) \
881   case const:                  \
882     return #const;
883 #endif
884 
bta_hf_client_evt_str(uint16_t event)885 static const char* bta_hf_client_evt_str(uint16_t event) {
886   switch (event) {
887     CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT)
888     CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT)
889     CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT)
890     CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT)
891     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT)
892     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT)
893     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT)
894     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT)
895     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT)
896     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT)
897     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT)
898     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT)
899     CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT)
900     CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT)
901     CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT)
902     CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT)
903     CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT)
904     default:
905       return "Unknown HF Client Event";
906   }
907 }
908 
bta_hf_client_state_str(uint8_t state)909 static const char* bta_hf_client_state_str(uint8_t state) {
910   switch (state) {
911     CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST)
912     CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST)
913     CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST)
914     CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST)
915     default:
916       return "Unknown HF Client State";
917   }
918 }
919 
bta_hf_client_dump_statistics(int fd)920 void bta_hf_client_dump_statistics(int fd) {
921   dprintf(fd, "\nBluetooth HF Client BTA Statistics\n");
922 
923   // We dump statistics for all control blocks
924   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
925     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
926     if (!client_cb->is_allocated) {
927       // Skip the blocks which are not allocated
928       continue;
929     }
930 
931     dprintf(fd, "  Control block #%d\n", i + 1);
932 
933     uint8_t* a = client_cb->peer_addr.address;
934     // Device name
935     dprintf(fd, "    Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n", a[0], a[1],
936             a[2], a[3], a[4], a[5]);
937 
938     // State machine state
939     dprintf(fd, "    State Machine State: %s\n",
940             bta_hf_client_state_str(client_cb->state));
941 
942     // Local RFC channelfor communication
943     dprintf(fd, "    RFCOMM Channel (local) %d\n", client_cb->conn_handle);
944 
945     // BTA Handle shared between BTA and client (ex BTIF)
946     dprintf(fd, "    BTA Generated handle %d\n", client_cb->handle);
947   }
948 }
949