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