1 /******************************************************************************
2 *
3 * Copyright (c) 2014 The Android Open Source Project
4 * Copyright 2009-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 /*******************************************************************************
21 *
22 * Filename: btif_hf_client.c
23 *
24 * Description: Handsfree Profile (HF role) Bluetooth Interface
25 *
26 * Notes:
27 * a) Lifecycle of a control block
28 * Control block handles the lifecycle for a particular remote device's
29 * connection. The connection can go via the classic phases but more
30 * importantly there's only two messages from BTA that affect this.
31 * BTA_HF_CLIENT_OPEN_EVT and BTA_HF_CLIENT_CLOSE_EVT. Since the API between
32 * BTIF and BTA is controlled entirely by handles it's important to know where
33 * the handles are created and destroyed. Handles can be created at two
34 * locations:
35 * -- While connect() is called from BTIF. This is an outgoing connection
36 * -- While accepting an incoming connection (see BTA_HF_CLIENT_OPEN_EVT
37 * handling).
38 *
39 * The destruction or rather reuse of handles can be done when
40 * BTA_HF_CLIENT_CLOSE_EVT is called. Refer to the event handling for details
41 * of this.
42 *
43 ******************************************************************************/
44
45 #define LOG_TAG "bt_btif_hfc"
46
47 #include <stdlib.h>
48 #include <string.h>
49
50 #include <hardware/bluetooth.h>
51 #include <hardware/bt_hf_client.h>
52
53 #include "bt_utils.h"
54 #include "bta_hf_client_api.h"
55 #include "btif_common.h"
56 #include "btif_profile_queue.h"
57 #include "btif_util.h"
58 #include "osi/include/osi.h"
59 #include "osi/include/properties.h"
60
61 /*******************************************************************************
62 * Constants & Macros
63 ******************************************************************************/
64
65 #ifndef BTIF_HF_CLIENT_SERVICE_NAME
66 #define BTIF_HF_CLIENT_SERVICE_NAME ("Handsfree")
67 #endif
68
69 #ifndef BTIF_HF_CLIENT_SECURITY
70 #define BTIF_HF_CLIENT_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
71 #endif
72
73 #ifndef BTIF_HF_CLIENT_FEATURES
74 #define BTIF_HF_CLIENT_FEATURES \
75 (BTA_HF_CLIENT_FEAT_ECNR | BTA_HF_CLIENT_FEAT_3WAY | \
76 BTA_HF_CLIENT_FEAT_CLI | BTA_HF_CLIENT_FEAT_VREC | BTA_HF_CLIENT_FEAT_VOL | \
77 BTA_HF_CLIENT_FEAT_ECS | BTA_HF_CLIENT_FEAT_ECC | BTA_HF_CLIENT_FEAT_CODEC)
78 #endif
79
80 /*******************************************************************************
81 * Local type definitions
82 ******************************************************************************/
83 /* BTIF-HF control block to map bdaddr to BTA handle */
84 typedef struct {
85 uint16_t handle; // Handle obtained frm the BTA
86 RawAddress peer_bda; // Device corresponding to handle
87 bthf_client_connection_state_t state; // State of current connection
88 tBTA_HF_CLIENT_PEER_FEAT peer_feat; // HF features
89 tBTA_HF_CLIENT_CHLD_FEAT chld_feat; // AT+CHLD=<> command features
90 } btif_hf_client_cb_t;
91
92 /* Max devices supported by BTIF (useful to match the value in BTA) */
93 #define HF_CLIENT_MAX_DEVICES 10
94 typedef struct {
95 btif_hf_client_cb_t cb[HF_CLIENT_MAX_DEVICES];
96 } btif_hf_client_cb_arr_t;
97
98 /******************************************************************************
99 * Local function declarations
100 ******************************************************************************/
101 btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle);
102 btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& addr);
103 bool is_connected(const btif_hf_client_cb_t* cb);
104
105 /*******************************************************************************
106 * Static variables
107 ******************************************************************************/
108 static bthf_client_callbacks_t* bt_hf_client_callbacks = NULL;
109
110 char btif_hf_client_version[PROPERTY_VALUE_MAX];
111
dump_hf_client_conn_state(uint16_t event)112 static const char* dump_hf_client_conn_state(uint16_t event) {
113 switch (event) {
114 CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
115 CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_CONNECTING)
116 CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_CONNECTED)
117 CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED)
118 CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING)
119 default:
120 return "UNKNOWN MSG ID";
121 }
122 }
123
124 #define CHECK_BTHF_CLIENT_INIT() \
125 do { \
126 if (bt_hf_client_callbacks == NULL) { \
127 BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __func__); \
128 return BT_STATUS_NOT_READY; \
129 } else { \
130 BTIF_TRACE_EVENT("BTHF CLIENT: %s", __func__); \
131 } \
132 } while (0)
133
134 #define CHECK_BTHF_CLIENT_SLC_CONNECTED(cb) \
135 do { \
136 if (bt_hf_client_callbacks == NULL) { \
137 BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __func__); \
138 return BT_STATUS_NOT_READY; \
139 } else if ((cb)->state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) { \
140 BTIF_TRACE_WARNING("BTHF CLIENT: %s: SLC connection not up. state=%s", \
141 __func__, dump_hf_client_conn_state((cb)->state)); \
142 return BT_STATUS_NOT_READY; \
143 } else { \
144 BTIF_TRACE_EVENT("BTHF CLIENT: %s", __func__); \
145 } \
146 } while (0)
147
148 static btif_hf_client_cb_arr_t btif_hf_client_cb_arr;
149
150 /*******************************************************************************
151 * Static functions
152 ******************************************************************************/
153
154 /*******************************************************************************
155 *
156 * Function btif_in_hf_client_generic_evt
157 *
158 * Description Processes generic events to be sent to JNI that are not
159 * triggered from the BTA.
160 * Always runs in BTIF context
161 *
162 * Returns void
163 *
164 ******************************************************************************/
btif_in_hf_client_generic_evt(uint16_t event,char * p_param)165 static void btif_in_hf_client_generic_evt(uint16_t event, char* p_param) {
166 BTIF_TRACE_DEBUG("%s", __func__);
167 RawAddress* bd_addr = (RawAddress*)p_param;
168 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
169 if (cb == NULL || !is_connected(cb)) {
170 BTIF_TRACE_ERROR("%s: failed to find block for bda", __func__);
171 }
172
173 BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
174 switch (event) {
175 case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING: {
176 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
177 (bthf_client_audio_state_t)BTHF_CLIENT_AUDIO_STATE_CONNECTING);
178 } break;
179 default: {
180 BTIF_TRACE_WARNING("%s: : Unknown event 0x%x", __func__, event);
181 } break;
182 }
183 }
184
185 /*******************************************************************************
186 * Functions
187 ******************************************************************************/
is_connected(const btif_hf_client_cb_t * cb)188 bool is_connected(const btif_hf_client_cb_t* cb) {
189 if ((cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTED) ||
190 (cb->state == BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED))
191 return true;
192
193 BTIF_TRACE_ERROR("%s: not connected!", __func__);
194 return false;
195 }
196
197 /*******************************************************************************
198 *
199 * Function btif_hf_client_get_cb_by_handle
200 *
201 * Description Get control block by handle
202 *
203 * Returns btif_hf_client_cb_t pointer if available NULL otherwise
204 *
205 ******************************************************************************/
btif_hf_client_get_cb_by_handle(uint16_t handle)206 btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle) {
207 BTIF_TRACE_DEBUG("%s: cb by handle %d", __func__, handle);
208 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
209 // Block is valid only if it is allocated i.e. state is not DISCONNECTED
210 if (btif_hf_client_cb_arr.cb[i].state !=
211 BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
212 btif_hf_client_cb_arr.cb[i].handle == handle) {
213 return &btif_hf_client_cb_arr.cb[i];
214 }
215 }
216 BTIF_TRACE_ERROR("%s: could not find block for handle %d", __func__, handle);
217 return NULL;
218 }
219
220 /*******************************************************************************
221 *
222 * Function btif_hf_client_get_cb_by_bda
223 *
224 * Description Get control block by bda
225 *
226 * Returns btif_hf_client_cb_t pointer if available NULL otherwise
227 *
228 ******************************************************************************/
btif_hf_client_get_cb_by_bda(const RawAddress & bd_addr)229 btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& bd_addr) {
230 VLOG(1) << __func__ << " incoming addr " << bd_addr;
231
232 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
233 // Block is valid only if it is allocated i.e. state is not DISCONNECTED
234 if (btif_hf_client_cb_arr.cb[i].state !=
235 BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
236 btif_hf_client_cb_arr.cb[i].peer_bda == bd_addr) {
237 return &btif_hf_client_cb_arr.cb[i];
238 }
239 }
240 BTIF_TRACE_ERROR("%s: could not find block for bdaddr", __func__);
241 return NULL;
242 }
243
244 /*******************************************************************************
245 *
246 * Function btif_hf_client_allocate_cb
247 *
248 * Description Get control block by bda
249 *
250 * Returns btif_hf_client_cb_t pointer if available NULL otherwise
251 *
252 ******************************************************************************/
btif_hf_client_allocate_cb()253 btif_hf_client_cb_t* btif_hf_client_allocate_cb() {
254 for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
255 btif_hf_client_cb_t* cb = &btif_hf_client_cb_arr.cb[i];
256 if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED) {
257 return cb;
258 }
259 }
260 BTIF_TRACE_ERROR("%s: unable to allocate control block", __func__);
261 return NULL;
262 }
263
264 /*****************************************************************************
265 *
266 * btif hf api functions (no context switch)
267 *
268 ****************************************************************************/
269
270 /*******************************************************************************
271 *
272 * Function btif_hf_client_init
273 *
274 * Description initializes the hf interface
275 *
276 * Returns bt_status_t
277 *
278 ******************************************************************************/
init(bthf_client_callbacks_t * callbacks)279 static bt_status_t init(bthf_client_callbacks_t* callbacks) {
280 BTIF_TRACE_EVENT("%s", __func__);
281
282 bt_hf_client_callbacks = callbacks;
283
284 btif_enable_service(BTA_HFP_HS_SERVICE_ID);
285
286 memset(&btif_hf_client_cb_arr, 0, sizeof(btif_hf_client_cb_arr_t));
287
288 return BT_STATUS_SUCCESS;
289 }
290
291 /*******************************************************************************
292 *
293 * Function connect
294 *
295 * Description connect to audio gateway
296 *
297 * Returns bt_status_t
298 *
299 ******************************************************************************/
connect_int(RawAddress * bd_addr,uint16_t uuid)300 static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) {
301 btif_hf_client_cb_t* cb = btif_hf_client_allocate_cb();
302 if (cb == NULL) {
303 BTIF_TRACE_ERROR("%s: could not allocate block!", __func__);
304 return BT_STATUS_BUSY;
305 }
306
307 cb->peer_bda = *bd_addr;
308 if (is_connected(cb)) return BT_STATUS_BUSY;
309
310 cb->state = BTHF_CLIENT_CONNECTION_STATE_CONNECTING;
311 cb->peer_bda = *bd_addr;
312
313 /* Open HF connection to remote device and get the relevant handle.
314 * The handle is valid until we have called BTA_HfClientClose or the LL
315 * has notified us of channel close due to remote closing, error etc.
316 */
317 BTA_HfClientOpen(cb->peer_bda, BTIF_HF_CLIENT_SECURITY, &cb->handle);
318
319 return BT_STATUS_SUCCESS;
320 }
321
connect(RawAddress * bd_addr)322 static bt_status_t connect(RawAddress* bd_addr) {
323 BTIF_TRACE_EVENT("HFP Client version is %s", btif_hf_client_version);
324 CHECK_BTHF_CLIENT_INIT();
325 return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
326 }
327
328 /*******************************************************************************
329 *
330 * Function disconnect
331 *
332 * Description disconnect from audio gateway
333 *
334 * Returns bt_status_t
335 *
336 ******************************************************************************/
disconnect(const RawAddress * bd_addr)337 static bt_status_t disconnect(const RawAddress* bd_addr) {
338 CHECK_BTHF_CLIENT_INIT();
339
340 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
341 if (cb != NULL) {
342 BTA_HfClientClose(cb->handle);
343 return BT_STATUS_SUCCESS;
344 } else {
345 return BT_STATUS_BUSY;
346 }
347 }
348
349 /*******************************************************************************
350 *
351 * Function connect_audio
352 *
353 * Description create an audio connection
354 *
355 * Returns bt_status_t
356 *
357 ******************************************************************************/
connect_audio(const RawAddress * bd_addr)358 static bt_status_t connect_audio(const RawAddress* bd_addr) {
359 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
360 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
361
362 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
363
364 if ((BTIF_HF_CLIENT_FEATURES & BTA_HF_CLIENT_FEAT_CODEC) &&
365 (cb->peer_feat & BTA_HF_CLIENT_PEER_CODEC)) {
366 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BCC, 0, 0, NULL);
367 } else {
368 BTA_HfClientAudioOpen(cb->handle);
369 }
370
371 /* Inform the application that the audio connection has been initiated
372 * successfully */
373 btif_transfer_context(btif_in_hf_client_generic_evt,
374 BTIF_HF_CLIENT_CB_AUDIO_CONNECTING, (char*)bd_addr,
375 sizeof(RawAddress), NULL);
376 return BT_STATUS_SUCCESS;
377 }
378
379 /*******************************************************************************
380 *
381 * Function disconnect_audio
382 *
383 * Description close the audio connection
384 *
385 * Returns bt_status_t
386 *
387 ******************************************************************************/
disconnect_audio(const RawAddress * bd_addr)388 static bt_status_t disconnect_audio(const RawAddress* bd_addr) {
389 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
390 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
391
392 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
393
394 BTA_HfClientAudioClose(cb->handle);
395 return BT_STATUS_SUCCESS;
396 }
397
398 /*******************************************************************************
399 *
400 * Function start_voice_recognition
401 *
402 * Description start voice recognition
403 *
404 * Returns bt_status_t
405 *
406 ******************************************************************************/
start_voice_recognition(const RawAddress * bd_addr)407 static bt_status_t start_voice_recognition(const RawAddress* bd_addr) {
408 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
409 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
410
411 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
412
413 if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) {
414 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BVRA, 1, 0, NULL);
415 return BT_STATUS_SUCCESS;
416 }
417 return BT_STATUS_UNSUPPORTED;
418 }
419
420 /*******************************************************************************
421 *
422 * Function stop_voice_recognition
423 *
424 * Description stop voice recognition
425 *
426 * Returns bt_status_t
427 *
428 ******************************************************************************/
stop_voice_recognition(const RawAddress * bd_addr)429 static bt_status_t stop_voice_recognition(const RawAddress* bd_addr) {
430 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
431 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
432
433 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
434
435 if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) {
436 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BVRA, 0, 0, NULL);
437 return BT_STATUS_SUCCESS;
438 }
439 return BT_STATUS_UNSUPPORTED;
440 }
441
442 /*******************************************************************************
443 *
444 * Function volume_control
445 *
446 * Description volume control
447 *
448 * Returns bt_status_t
449 *
450 ******************************************************************************/
volume_control(const RawAddress * bd_addr,bthf_client_volume_type_t type,int volume)451 static bt_status_t volume_control(const RawAddress* bd_addr,
452 bthf_client_volume_type_t type, int volume) {
453 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
454 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
455
456 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
457
458 switch (type) {
459 case BTHF_CLIENT_VOLUME_TYPE_SPK:
460 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VGS, volume, 0, NULL);
461 break;
462 case BTHF_CLIENT_VOLUME_TYPE_MIC:
463 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VGM, volume, 0, NULL);
464 break;
465 default:
466 return BT_STATUS_UNSUPPORTED;
467 }
468
469 return BT_STATUS_SUCCESS;
470 }
471
472 /*******************************************************************************
473 *
474 * Function dial
475 *
476 * Description place a call
477 *
478 * Returns bt_status_t
479 *
480 ******************************************************************************/
dial(UNUSED_ATTR const RawAddress * bd_addr,const char * number)481 static bt_status_t dial(UNUSED_ATTR const RawAddress* bd_addr,
482 const char* number) {
483 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
484 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
485
486 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
487
488 if (number) {
489 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATD, 0, 0, number);
490 } else {
491 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BLDN, 0, 0, NULL);
492 }
493 return BT_STATUS_SUCCESS;
494 }
495
496 /*******************************************************************************
497 *
498 * Function dial_memory
499 *
500 * Description place a call with number specified by location (speed dial)
501 *
502 * Returns bt_status_t
503 *
504 ******************************************************************************/
dial_memory(const RawAddress * bd_addr,int location)505 static bt_status_t dial_memory(const RawAddress* bd_addr, int location) {
506 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
507 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
508
509 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
510
511 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATD, location, 0, NULL);
512 return BT_STATUS_SUCCESS;
513 }
514
515 /*******************************************************************************
516 *
517 * Function handle_call_action
518 *
519 * Description handle specified call related action
520 *
521 * Returns bt_status_t
522 *
523 ******************************************************************************/
handle_call_action(const RawAddress * bd_addr,bthf_client_call_action_t action,int idx)524 static bt_status_t handle_call_action(const RawAddress* bd_addr,
525 bthf_client_call_action_t action,
526 int idx) {
527 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
528 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
529
530 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
531
532 switch (action) {
533 case BTHF_CLIENT_CALL_ACTION_CHLD_0:
534 if (cb->chld_feat & BTA_HF_CLIENT_CHLD_REL) {
535 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 0, 0, NULL);
536 break;
537 }
538 return BT_STATUS_UNSUPPORTED;
539 case BTHF_CLIENT_CALL_ACTION_CHLD_1:
540 // CHLD 1 is mandatory for 3 way calling
541 if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) {
542 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, 0, NULL);
543 break;
544 }
545 return BT_STATUS_UNSUPPORTED;
546 case BTHF_CLIENT_CALL_ACTION_CHLD_2:
547 // CHLD 2 is mandatory for 3 way calling
548 if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) {
549 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, 0, NULL);
550 break;
551 }
552 return BT_STATUS_UNSUPPORTED;
553 case BTHF_CLIENT_CALL_ACTION_CHLD_3:
554 if (cb->chld_feat & BTA_HF_CLIENT_CHLD_MERGE) {
555 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 3, 0, NULL);
556 break;
557 }
558 return BT_STATUS_UNSUPPORTED;
559 case BTHF_CLIENT_CALL_ACTION_CHLD_4:
560 if (cb->chld_feat & BTA_HF_CLIENT_CHLD_MERGE_DETACH) {
561 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 4, 0, NULL);
562 break;
563 }
564 return BT_STATUS_UNSUPPORTED;
565 case BTHF_CLIENT_CALL_ACTION_CHLD_1x:
566 if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECC) {
567 if (idx < 1) {
568 return BT_STATUS_FAIL;
569 }
570 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, idx, NULL);
571 break;
572 }
573 return BT_STATUS_UNSUPPORTED;
574 case BTHF_CLIENT_CALL_ACTION_CHLD_2x:
575 if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECC) {
576 if (idx < 1) {
577 return BT_STATUS_FAIL;
578 }
579 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, idx, NULL);
580 break;
581 }
582 return BT_STATUS_UNSUPPORTED;
583 case BTHF_CLIENT_CALL_ACTION_ATA:
584 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATA, 0, 0, NULL);
585 break;
586 case BTHF_CLIENT_CALL_ACTION_CHUP:
587 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHUP, 0, 0, NULL);
588 break;
589 case BTHF_CLIENT_CALL_ACTION_BTRH_0:
590 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 0, 0, NULL);
591 break;
592 case BTHF_CLIENT_CALL_ACTION_BTRH_1:
593 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 1, 0, NULL);
594 break;
595 case BTHF_CLIENT_CALL_ACTION_BTRH_2:
596 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 2, 0, NULL);
597 break;
598 default:
599 return BT_STATUS_FAIL;
600 }
601
602 return BT_STATUS_SUCCESS;
603 }
604
605 /*******************************************************************************
606 *
607 * Function query_current_calls
608 *
609 * Description query list of current calls
610 *
611 * Returns bt_status_t
612 *
613 ******************************************************************************/
query_current_calls(UNUSED_ATTR const RawAddress * bd_addr)614 static bt_status_t query_current_calls(UNUSED_ATTR const RawAddress* bd_addr) {
615 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
616 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
617
618 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
619
620 if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECS) {
621 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CLCC, 0, 0, NULL);
622 return BT_STATUS_SUCCESS;
623 }
624
625 return BT_STATUS_UNSUPPORTED;
626 }
627
628 /*******************************************************************************
629 *
630 * Function query_current_operator_name
631 *
632 * Description query current selected operator name
633 *
634 * Returns bt_status_t
635 *
636 ******************************************************************************/
query_current_operator_name(const RawAddress * bd_addr)637 static bt_status_t query_current_operator_name(const RawAddress* bd_addr) {
638 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
639 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
640
641 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
642
643 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_COPS, 0, 0, NULL);
644 return BT_STATUS_SUCCESS;
645 }
646
647 /*******************************************************************************
648 *
649 * Function retieve_subscriber_info
650 *
651 * Description retrieve subscriber number information
652 *
653 * Returns bt_status_t
654 *
655 ******************************************************************************/
retrieve_subscriber_info(const RawAddress * bd_addr)656 static bt_status_t retrieve_subscriber_info(const RawAddress* bd_addr) {
657 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
658 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
659
660 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
661
662 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CNUM, 0, 0, NULL);
663 return BT_STATUS_SUCCESS;
664 }
665
666 /*******************************************************************************
667 *
668 * Function send_dtmf
669 *
670 * Description send dtmf
671 *
672 * Returns bt_status_t
673 *
674 ******************************************************************************/
send_dtmf(const RawAddress * bd_addr,char code)675 static bt_status_t send_dtmf(const RawAddress* bd_addr, char code) {
676 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
677 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
678
679 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
680
681 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VTS, code, 0, NULL);
682 return BT_STATUS_SUCCESS;
683 }
684
685 /*******************************************************************************
686 *
687 * Function request_last_voice_tag_number
688 *
689 * Description Request number from AG for VR purposes
690 *
691 * Returns bt_status_t
692 *
693 ******************************************************************************/
request_last_voice_tag_number(const RawAddress * bd_addr)694 static bt_status_t request_last_voice_tag_number(const RawAddress* bd_addr) {
695 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
696 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
697
698 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
699
700 if (cb->peer_feat & BTA_HF_CLIENT_PEER_VTAG) {
701 BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BINP, 1, 0, NULL);
702 return BT_STATUS_SUCCESS;
703 }
704 return BT_STATUS_UNSUPPORTED;
705 }
706
707 /*******************************************************************************
708 *
709 * Function cleanup
710 *
711 * Description Closes the HF interface
712 *
713 * Returns bt_status_t
714 *
715 ******************************************************************************/
cleanup(void)716 static void cleanup(void) {
717 BTIF_TRACE_EVENT("%s", __func__);
718
719 btif_queue_cleanup(UUID_SERVCLASS_HF_HANDSFREE);
720 if (bt_hf_client_callbacks) {
721 btif_disable_service(BTA_HFP_HS_SERVICE_ID);
722 bt_hf_client_callbacks = NULL;
723 }
724 }
725
726 /*******************************************************************************
727 *
728 * Function send_at_cmd
729 *
730 * Description Send requested AT command to rempte device.
731 *
732 * Returns bt_status_t
733 *
734 ******************************************************************************/
send_at_cmd(const RawAddress * bd_addr,int cmd,int val1,int val2,const char * arg)735 static bt_status_t send_at_cmd(const RawAddress* bd_addr, int cmd, int val1,
736 int val2, const char* arg) {
737 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
738 if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
739
740 CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
741
742 BTIF_TRACE_EVENT("%s: Cmd %d val1 %d val2 %d arg %s", __func__, cmd, val1,
743 val2, (arg != NULL) ? arg : "<null>");
744 BTA_HfClientSendAT(cb->handle, cmd, val1, val2, arg);
745
746 return BT_STATUS_SUCCESS;
747 }
748
749 static const bthf_client_interface_t bthfClientInterface = {
750 .size = sizeof(bthf_client_interface_t),
751 .init = init,
752 .connect = connect,
753 .disconnect = disconnect,
754 .connect_audio = connect_audio,
755 .disconnect_audio = disconnect_audio,
756 .start_voice_recognition = start_voice_recognition,
757 .stop_voice_recognition = stop_voice_recognition,
758 .volume_control = volume_control,
759 .dial = dial,
760 .dial_memory = dial_memory,
761 .handle_call_action = handle_call_action,
762 .query_current_calls = query_current_calls,
763 .query_current_operator_name = query_current_operator_name,
764 .retrieve_subscriber_info = retrieve_subscriber_info,
765 .send_dtmf = send_dtmf,
766 .request_last_voice_tag_number = request_last_voice_tag_number,
767 .cleanup = cleanup,
768 .send_at_cmd = send_at_cmd,
769 };
770
process_ind_evt(tBTA_HF_CLIENT_IND * ind)771 static void process_ind_evt(tBTA_HF_CLIENT_IND* ind) {
772 BTIF_TRACE_DEBUG("%s", __func__);
773
774 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(ind->bd_addr);
775 if (cb == NULL || !is_connected(cb)) return;
776
777 switch (ind->type) {
778 case BTA_HF_CLIENT_IND_CALL:
779 HAL_CBACK(bt_hf_client_callbacks, call_cb, &cb->peer_bda,
780 (bthf_client_call_t)ind->value);
781 break;
782
783 case BTA_HF_CLIENT_IND_CALLSETUP:
784 HAL_CBACK(bt_hf_client_callbacks, callsetup_cb, &cb->peer_bda,
785 (bthf_client_callsetup_t)ind->value);
786 break;
787 case BTA_HF_CLIENT_IND_CALLHELD:
788 HAL_CBACK(bt_hf_client_callbacks, callheld_cb, &cb->peer_bda,
789 (bthf_client_callheld_t)ind->value);
790 break;
791
792 case BTA_HF_CLIENT_IND_SERVICE:
793 HAL_CBACK(bt_hf_client_callbacks, network_state_cb, &cb->peer_bda,
794 (bthf_client_network_state_t)ind->value);
795 break;
796
797 case BTA_HF_CLIENT_IND_SIGNAL:
798 HAL_CBACK(bt_hf_client_callbacks, network_signal_cb, &cb->peer_bda,
799 ind->value);
800 break;
801
802 case BTA_HF_CLIENT_IND_ROAM:
803 HAL_CBACK(bt_hf_client_callbacks, network_roaming_cb, &cb->peer_bda,
804 (bthf_client_service_type_t)ind->value);
805 break;
806
807 case BTA_HF_CLIENT_IND_BATTCH:
808 HAL_CBACK(bt_hf_client_callbacks, battery_level_cb, &cb->peer_bda,
809 ind->value);
810 break;
811
812 default:
813 break;
814 }
815 }
816
817 /*******************************************************************************
818 *
819 * Function btif_hf_client_upstreams_evt
820 *
821 * Description Executes HF CLIENT UPSTREAMS events in btif context
822 *
823 * Returns void
824 *
825 ******************************************************************************/
btif_hf_client_upstreams_evt(uint16_t event,char * p_param)826 static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) {
827 tBTA_HF_CLIENT* p_data = (tBTA_HF_CLIENT*)p_param;
828
829 btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(p_data->bd_addr);
830 if (cb == NULL && event == BTA_HF_CLIENT_OPEN_EVT) {
831 BTIF_TRACE_DEBUG("%s: event BTA_HF_CLIENT_OPEN_EVT allocating block",
832 __func__);
833 cb = btif_hf_client_allocate_cb();
834 cb->handle = p_data->open.handle;
835 cb->peer_bda = p_data->open.bd_addr;
836 } else if (cb == NULL) {
837 BTIF_TRACE_ERROR("%s: event %d but not allocating block: cb not found",
838 __func__, event);
839 return;
840 }
841
842 BTIF_TRACE_DEBUG("%s: event=%s (%u)", __func__, dump_hf_client_event(event),
843 event);
844
845 switch (event) {
846 case BTA_HF_CLIENT_OPEN_EVT:
847 if (p_data->open.status == BTA_HF_CLIENT_SUCCESS) {
848 cb->state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED;
849 cb->peer_feat = 0;
850 cb->chld_feat = 0;
851 } else if (cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING) {
852 cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
853 } else {
854 BTIF_TRACE_WARNING(
855 "%s: HF CLient open failed, but another device connected. "
856 "status=%d state=%d connected device=%s",
857 __func__, p_data->open.status, cb->state,
858 cb->peer_bda.ToString().c_str());
859 break;
860 }
861
862 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
863 cb->state, 0, /* peer feat */
864 0 /* AT+CHLD feat */);
865
866 if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
867 cb->peer_bda = RawAddress::kAny;
868
869 if (p_data->open.status != BTA_HF_CLIENT_SUCCESS) btif_queue_advance();
870 break;
871
872 case BTA_HF_CLIENT_CONN_EVT:
873 cb->peer_feat = p_data->conn.peer_feat;
874 cb->chld_feat = p_data->conn.chld_feat;
875 cb->state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED;
876
877 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
878 cb->state, cb->peer_feat, cb->chld_feat);
879
880 /* Inform the application about in-band ringtone */
881 if (cb->peer_feat & BTA_HF_CLIENT_PEER_INBAND) {
882 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
883 BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
884 }
885
886 btif_queue_advance();
887 break;
888
889 case BTA_HF_CLIENT_CLOSE_EVT:
890 cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
891 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
892 cb->state, 0, 0);
893 cb->peer_bda = RawAddress::kAny;
894 cb->peer_feat = 0;
895 cb->chld_feat = 0;
896 btif_queue_advance();
897 break;
898
899 case BTA_HF_CLIENT_IND_EVT:
900 process_ind_evt(&p_data->ind);
901 break;
902
903 case BTA_HF_CLIENT_MIC_EVT:
904 HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, &cb->peer_bda,
905 BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value);
906 break;
907
908 case BTA_HF_CLIENT_SPK_EVT:
909 HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, &cb->peer_bda,
910 BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value);
911 break;
912
913 case BTA_HF_CLIENT_VOICE_REC_EVT:
914 HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, &cb->peer_bda,
915 (bthf_client_vr_state_t)p_data->val.value);
916 break;
917
918 case BTA_HF_CLIENT_OPERATOR_NAME_EVT:
919 HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, &cb->peer_bda,
920 p_data->operator_name.name);
921 break;
922
923 case BTA_HF_CLIENT_CLIP_EVT:
924 HAL_CBACK(bt_hf_client_callbacks, clip_cb, &cb->peer_bda,
925 p_data->number.number);
926 break;
927
928 case BTA_HF_CLIENT_BINP_EVT:
929 HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback,
930 &cb->peer_bda, p_data->number.number);
931 break;
932
933 case BTA_HF_CLIENT_CCWA_EVT:
934 HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, &cb->peer_bda,
935 p_data->number.number);
936 break;
937
938 case BTA_HF_CLIENT_AT_RESULT_EVT:
939 HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, &cb->peer_bda,
940 (bthf_client_cmd_complete_t)p_data->result.type,
941 p_data->result.cme);
942 break;
943
944 case BTA_HF_CLIENT_CLCC_EVT:
945 HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, &cb->peer_bda,
946 p_data->clcc.idx,
947 p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING
948 : BTHF_CLIENT_CALL_DIRECTION_OUTGOING,
949 (bthf_client_call_state_t)p_data->clcc.status,
950 p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI
951 : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE,
952 p_data->clcc.number_present ? p_data->clcc.number : "");
953 break;
954
955 case BTA_HF_CLIENT_CNUM_EVT:
956 if (p_data->cnum.service == 4) {
957 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
958 p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE);
959 } else if (p_data->cnum.service == 5) {
960 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
961 p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX);
962 } else {
963 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
964 p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN);
965 }
966 break;
967
968 case BTA_HF_CLIENT_BTRH_EVT:
969 if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT) {
970 HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, &cb->peer_bda,
971 (bthf_client_resp_and_hold_t)p_data->val.value);
972 }
973 break;
974
975 case BTA_HF_CLIENT_BSIR_EVT:
976 if (p_data->val.value != 0) {
977 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
978 BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
979 } else {
980 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
981 BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED);
982 }
983 break;
984
985 case BTA_HF_CLIENT_AUDIO_OPEN_EVT:
986 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
987 BTHF_CLIENT_AUDIO_STATE_CONNECTED);
988 break;
989
990 case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT:
991 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
992 BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC);
993 break;
994
995 case BTA_HF_CLIENT_AUDIO_CLOSE_EVT:
996 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
997 BTHF_CLIENT_AUDIO_STATE_DISCONNECTED);
998 break;
999 case BTA_HF_CLIENT_RING_INDICATION:
1000 HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb, &cb->peer_bda);
1001 break;
1002 case BTA_HF_CLIENT_UNKNOWN_EVT:
1003 HAL_CBACK(bt_hf_client_callbacks, unknown_event_cb, &cb->peer_bda,
1004 p_data->unknown.event_string);
1005 break;
1006 default:
1007 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
1008 break;
1009 }
1010 }
1011
1012 /*******************************************************************************
1013 *
1014 * Function bta_hf_client_evt
1015 *
1016 * Description Switches context from BTA to BTIF for all HF Client events
1017 *
1018 * Returns void
1019 *
1020 ******************************************************************************/
1021
bta_hf_client_evt(tBTA_HF_CLIENT_EVT event,tBTA_HF_CLIENT * p_data)1022 static void bta_hf_client_evt(tBTA_HF_CLIENT_EVT event,
1023 tBTA_HF_CLIENT* p_data) {
1024 bt_status_t status;
1025
1026 /* switch context to btif task context (copy full union size for convenience)
1027 */
1028 status = btif_transfer_context(btif_hf_client_upstreams_evt, (uint16_t)event,
1029 (char*)p_data, sizeof(*p_data), NULL);
1030
1031 /* catch any failed context transfers */
1032 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
1033 }
1034
1035 /*******************************************************************************
1036 *
1037 * Function btif_hf_client_execute_service
1038 *
1039 * Description Initializes/Shuts down the service
1040 *
1041 * Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1042 *
1043 ******************************************************************************/
btif_hf_client_execute_service(bool b_enable)1044 bt_status_t btif_hf_client_execute_service(bool b_enable) {
1045 BTIF_TRACE_EVENT("%s: enable: %d", __func__, b_enable);
1046
1047 tBTA_HF_CLIENT_FEAT features = BTIF_HF_CLIENT_FEATURES;
1048 if (osi_property_get_bool("persist.bluetooth.hfpclient.sco_s4_supported", false))
1049 features |= BTA_HF_CLIENT_FEAT_S4;
1050
1051 if (b_enable) {
1052 /* Enable and register with BTA-HFClient */
1053 BTIF_TRACE_EVENT("%s: support codec negotiation %d ", __func__,
1054 features);
1055 BTA_HfClientEnable(bta_hf_client_evt, BTIF_HF_CLIENT_SECURITY,
1056 features, BTIF_HF_CLIENT_SERVICE_NAME);
1057 } else {
1058 BTA_HfClientDisable();
1059 }
1060 return BT_STATUS_SUCCESS;
1061 }
1062
1063 /*******************************************************************************
1064 *
1065 * Function btif_hf_get_interface
1066 *
1067 * Description Get the hf callback interface
1068 *
1069 * Returns bthf_interface_t
1070 *
1071 ******************************************************************************/
btif_hf_client_get_interface(void)1072 const bthf_client_interface_t* btif_hf_client_get_interface(void) {
1073 BTIF_TRACE_EVENT("%s", __func__);
1074 return &bthfClientInterface;
1075 }
1076