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