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