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