1 /******************************************************************************
2 *
3 * Copyright 2009-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /*******************************************************************************
20 *
21 * Filename: btif_hf.c
22 *
23 * Description: Handsfree Profile Bluetooth Interface
24 *
25 *
26 ******************************************************************************/
27
28 #define LOG_TAG "bt_btif_hf"
29
30 #include "btif/include/btif_hf.h"
31
32 #include <android_bluetooth_sysprop.h>
33 #include <base/functional/bind.h>
34 #include <base/functional/callback.h>
35 #include <bluetooth/log.h>
36 #include <com_android_bluetooth_flags.h>
37 #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h>
38
39 #include <cstddef>
40 #include <cstdint>
41 #include <cstdio>
42 #include <cstdlib>
43 #include <cstring>
44 #include <sstream>
45 #include <string>
46 #include <vector>
47
48 #include "bta/ag/bta_ag_int.h"
49 #include "bta/include/bta_ag_api.h"
50 #include "bta/include/bta_api.h"
51 #include "bta/include/utl.h"
52 #include "bta_ag_swb_aptx.h"
53 #include "btif/include/btif_common.h"
54 #include "btif/include/btif_metrics_logging.h"
55 #include "btif/include/btif_profile_queue.h"
56 #include "btif/include/btif_util.h"
57 #include "btm_api_types.h"
58 #include "common/metrics.h"
59 #include "device/include/device_iot_conf_defs.h"
60 #include "device/include/device_iot_config.h"
61 #include "hardware/bluetooth.h"
62 #include "include/hardware/bluetooth_headset_callbacks.h"
63 #include "include/hardware/bluetooth_headset_interface.h"
64 #include "include/hardware/bt_hf.h"
65 #include "internal_include/bt_target.h"
66 #include "os/logging/log_adapter.h"
67 #include "stack/btm/btm_sco_hfp_hal.h"
68 #include "stack/include/bt_uuid16.h"
69 #include "stack/include/btm_client_interface.h"
70 #include "stack/include/btm_log_history.h"
71 #include "types/raw_address.h"
72
73 namespace {
74 constexpr char kBtmLogTag[] = "HFP";
75 }
76
77 namespace bluetooth::headset {
78
79 /*******************************************************************************
80 * Constants & Macros
81 ******************************************************************************/
82 #ifndef BTIF_HSAG_SERVICE_NAME
83 #define BTIF_HSAG_SERVICE_NAME ("Headset Gateway")
84 #endif
85
86 #ifndef BTIF_HFAG_SERVICE_NAME
87 #define BTIF_HFAG_SERVICE_NAME ("Handsfree Gateway")
88 #endif
89
90 #ifndef BTIF_HF_SERVICE_NAMES
91 #define BTIF_HF_SERVICE_NAMES \
92 { BTIF_HSAG_SERVICE_NAME, BTIF_HFAG_SERVICE_NAME }
93 #endif
94
95 static uint32_t get_hf_features();
96 /* HF features supported at runtime */
97 static uint32_t btif_hf_features = get_hf_features();
98
99 #define BTIF_HF_INVALID_IDX (-1)
100
101 /* Max HF clients supported from App */
102 static int btif_max_hf_clients = 1;
103 static RawAddress active_bda = {};
104
105 /*******************************************************************************
106 * Static variables
107 ******************************************************************************/
108 static Callbacks* bt_hf_callbacks = nullptr;
109
110 #define CHECK_BTHF_INIT() \
111 do { \
112 if (!bt_hf_callbacks) { \
113 log::warn("BTHF not initialized"); \
114 return BT_STATUS_NOT_READY; \
115 } else { \
116 log::verbose("BTHF ok"); \
117 } \
118 } while (false)
119
120 /* BTIF-HF control block to map bdaddr to BTA handle */
121 struct btif_hf_cb_t {
122 uint16_t handle;
123 bool is_initiator;
124 RawAddress connected_bda;
125 bthf_connection_state_t state;
126 tBTA_AG_PEER_FEAT peer_feat;
127 int num_active;
128 int num_held;
129 bool is_during_voice_recognition;
130 bthf_call_state_t call_setup_state;
131 };
132
133 static btif_hf_cb_t btif_hf_cb[BTA_AG_MAX_NUM_CLIENTS];
134
dump_hf_call_state(bthf_call_state_t call_state)135 static const char* dump_hf_call_state(bthf_call_state_t call_state) {
136 switch (call_state) {
137 CASE_RETURN_STR(BTHF_CALL_STATE_IDLE)
138 CASE_RETURN_STR(BTHF_CALL_STATE_HELD)
139 CASE_RETURN_STR(BTHF_CALL_STATE_DIALING)
140 CASE_RETURN_STR(BTHF_CALL_STATE_ALERTING)
141 CASE_RETURN_STR(BTHF_CALL_STATE_INCOMING)
142 CASE_RETURN_STR(BTHF_CALL_STATE_WAITING)
143 CASE_RETURN_STR(BTHF_CALL_STATE_ACTIVE)
144 CASE_RETURN_STR(BTHF_CALL_STATE_DISCONNECTED)
145 default:
146 return "UNKNOWN CALL STATE";
147 }
148 }
149
150 static int btif_hf_idx_by_bdaddr(RawAddress* bd_addr);
151
152 /**
153 * Check if bd_addr is the current active device.
154 *
155 * @param bd_addr target device address
156 * @return True if bd_addr is the current active device, False otherwise or if
157 * no active device is set (i.e. active_device_addr is empty)
158 */
is_active_device(const RawAddress & bd_addr)159 static bool is_active_device(const RawAddress& bd_addr) {
160 return !active_bda.IsEmpty() && active_bda == bd_addr;
161 }
162
get_BTIF_HF_SERVICES()163 static tBTA_SERVICE_MASK get_BTIF_HF_SERVICES() {
164 return android::sysprop::bluetooth::Hfp::hf_services().value_or(BTA_HSP_SERVICE_MASK |
165 BTA_HFP_SERVICE_MASK);
166 }
167
168 /* HF features supported at runtime */
get_hf_features()169 static uint32_t get_hf_features() {
170 #if TARGET_FLOSS
171 #define DEFAULT_BTIF_HF_FEATURES \
172 (BTA_AG_FEAT_ECS | BTA_AG_FEAT_CODEC | BTA_AG_FEAT_UNAT | BTA_AG_FEAT_HF_IND | \
173 BTA_AG_FEAT_ESCO_S4 | BTA_AG_FEAT_NOSCO)
174 #else
175 #define DEFAULT_BTIF_HF_FEATURES \
176 (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | BTA_AG_FEAT_REJECT | BTA_AG_FEAT_ECS | \
177 BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_VREC | BTA_AG_FEAT_CODEC | BTA_AG_FEAT_HF_IND | \
178 BTA_AG_FEAT_ESCO_S4 | BTA_AG_FEAT_UNAT)
179 #endif
180
181 return android::sysprop::bluetooth::Hfp::hf_features().value_or(DEFAULT_BTIF_HF_FEATURES);
182 }
183
184 /*******************************************************************************
185 *
186 * Function is_connected
187 *
188 * Description Internal function to check if HF is connected
189 * is_connected(nullptr) returns TRUE if one of the control
190 * blocks is connected
191 *
192 * Returns true if connected
193 *
194 ******************************************************************************/
is_connected(RawAddress * bd_addr)195 static bool is_connected(RawAddress* bd_addr) {
196 for (int i = 0; i < btif_max_hf_clients; ++i) {
197 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
198 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)) &&
199 (!bd_addr || *bd_addr == btif_hf_cb[i].connected_bda)) {
200 return true;
201 }
202 }
203 return false;
204 }
205
206 /*******************************************************************************
207 *
208 * Function btif_hf_idx_by_bdaddr
209 *
210 * Description Internal function to get idx by bdaddr
211 *
212 * Returns idx
213 *
214 ******************************************************************************/
btif_hf_idx_by_bdaddr(RawAddress * bd_addr)215 static int btif_hf_idx_by_bdaddr(RawAddress* bd_addr) {
216 for (int i = 0; i < btif_max_hf_clients; ++i) {
217 if (*bd_addr == btif_hf_cb[i].connected_bda) {
218 return i;
219 }
220 }
221 return BTIF_HF_INVALID_IDX;
222 }
223
224 /*******************************************************************************
225 *
226 * Function callstate_to_callsetup
227 *
228 * Description Converts HAL call state to BTA call setup indicator value
229 *
230 * Returns BTA call indicator value
231 *
232 ******************************************************************************/
callstate_to_callsetup(bthf_call_state_t call_state)233 static uint8_t callstate_to_callsetup(bthf_call_state_t call_state) {
234 switch (call_state) {
235 case BTHF_CALL_STATE_INCOMING:
236 return 1;
237 case BTHF_CALL_STATE_DIALING:
238 return 2;
239 case BTHF_CALL_STATE_ALERTING:
240 return 3;
241 default:
242 return 0;
243 }
244 }
245
246 /*******************************************************************************
247 *
248 * Function send_at_result
249 *
250 * Description Send AT result code (OK/ERROR)
251 *
252 * Returns void
253 *
254 ******************************************************************************/
send_at_result(uint8_t ok_flag,uint16_t errcode,int idx)255 static void send_at_result(uint8_t ok_flag, uint16_t errcode, int idx) {
256 tBTA_AG_RES_DATA ag_res = {};
257 ag_res.ok_flag = ok_flag;
258 if (ok_flag == BTA_AG_OK_ERROR) {
259 ag_res.errcode = errcode;
260 }
261 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, ag_res);
262 }
263
264 /*******************************************************************************
265 *
266 * Function send_indicator_update
267 *
268 * Description Send indicator update (CIEV)
269 *
270 * Returns void
271 *
272 ******************************************************************************/
send_indicator_update(const btif_hf_cb_t & control_block,uint16_t indicator,uint16_t value)273 static void send_indicator_update(const btif_hf_cb_t& control_block, uint16_t indicator,
274 uint16_t value) {
275 tBTA_AG_RES_DATA ag_res = {};
276 ag_res.ind.id = indicator;
277 ag_res.ind.value = value;
278 BTA_AgResult(control_block.handle, BTA_AG_IND_RES, ag_res);
279 }
280
is_nth_bit_enabled(uint32_t value,int n)281 static bool is_nth_bit_enabled(uint32_t value, int n) {
282 return (value & (static_cast<uint32_t>(1) << n)) != 0;
283 }
284
clear_phone_state_multihf(btif_hf_cb_t * hf_cb)285 static void clear_phone_state_multihf(btif_hf_cb_t* hf_cb) {
286 hf_cb->call_setup_state = BTHF_CALL_STATE_IDLE;
287 hf_cb->num_active = 0;
288 hf_cb->num_held = 0;
289 }
290
reset_control_block(btif_hf_cb_t * hf_cb)291 static void reset_control_block(btif_hf_cb_t* hf_cb) {
292 hf_cb->state = BTHF_CONNECTION_STATE_DISCONNECTED;
293 hf_cb->is_initiator = false;
294 hf_cb->connected_bda = RawAddress::kEmpty;
295 hf_cb->peer_feat = 0;
296 clear_phone_state_multihf(hf_cb);
297 }
298
299 /**
300 * Check if Service Level Connection (SLC) is established for bd_addr
301 *
302 * @param bd_addr remote device address
303 * @return true if SLC is established for bd_addr
304 */
IsSlcConnected(RawAddress * bd_addr)305 static bool IsSlcConnected(RawAddress* bd_addr) {
306 if (!bd_addr) {
307 log::warn("bd_addr is null");
308 return false;
309 }
310 int idx = btif_hf_idx_by_bdaddr(bd_addr);
311 if (idx < 0 || idx > BTA_AG_MAX_NUM_CLIENTS) {
312 log::warn("invalid index {} for {}", idx, *bd_addr);
313 return false;
314 }
315 return btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_SLC_CONNECTED;
316 }
317
318 /*******************************************************************************
319 *
320 * Function btif_hf_upstreams_evt
321 *
322 * Description Executes HF UPSTREAMS events in btif context
323 *
324 * Returns void
325 *
326 ******************************************************************************/
btif_hf_upstreams_evt(uint16_t event,char * p_param)327 static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
328 if (event == BTA_AG_ENABLE_EVT || event == BTA_AG_DISABLE_EVT) {
329 log::info("AG enable/disable event {}", event);
330 return;
331 }
332 if (p_param == nullptr) {
333 log::error("parameter is null");
334 return;
335 }
336 tBTA_AG* p_data = (tBTA_AG*)p_param;
337 int idx = p_data->hdr.handle - 1;
338
339 log::debug("HF Upstream event:{}", dump_hf_event(event));
340
341 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
342 log::error("{} Invalid client index:{}", dump_hf_event(event), idx);
343 return;
344 }
345 if (!bt_hf_callbacks) {
346 log::error("{} Headset callback is not set", dump_hf_event(event));
347 return;
348 }
349
350 switch (event) {
351 case BTA_AG_REGISTER_EVT:
352 btif_hf_cb[idx].handle = p_data->reg.hdr.handle;
353 log::debug("{} idx:{} btif_hf_cb.handle = {}", dump_hf_event(event), idx,
354 btif_hf_cb[idx].handle);
355 break;
356 // RFCOMM connected or failed to connect
357 case BTA_AG_OPEN_EVT:
358 bt_hf_callbacks->ConnectionStateCallback(BTHF_CONNECTION_STATE_CONNECTING,
359 &(p_data->open.bd_addr));
360 // Check if an outgoing connection is pending
361 if (btif_hf_cb[idx].is_initiator) {
362 // There is an outgoing connection.
363 // Check the incoming open event status and the outgoing connection
364 // state.
365 if ((p_data->open.status != BTA_AG_SUCCESS) &&
366 btif_hf_cb[idx].state != BTHF_CONNECTION_STATE_CONNECTING) {
367 // Check if the incoming open event and the outgoing connection are
368 // for the same device.
369 if (p_data->open.bd_addr == btif_hf_cb[idx].connected_bda) {
370 log::warn(
371 "btif_hf_cb state[{}] is not expected, possible connection "
372 "collision, ignoring AG open failure event for the same device "
373 "{}",
374 p_data->open.status, p_data->open.bd_addr);
375 } else {
376 log::warn(
377 "btif_hf_cb state[{}] is not expected, possible connection "
378 "collision, ignoring AG open failure event for the different "
379 "devices btif_hf_cb bda: {}, p_data bda: {}, report disconnect "
380 "state for p_data bda.",
381 p_data->open.status, btif_hf_cb[idx].connected_bda, p_data->open.bd_addr);
382 bt_hf_callbacks->ConnectionStateCallback(BTHF_CONNECTION_STATE_DISCONNECTED,
383 &(p_data->open.bd_addr));
384 log_counter_metrics_btif(
385 android::bluetooth::CodePathCounterKeyEnum::HFP_COLLISON_AT_AG_OPEN, 1);
386 }
387 break;
388 }
389
390 // There is an outgoing connection.
391 // Check the outgoing connection state and address.
392 log::assert_that(btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_CONNECTING,
393 "Control block must be in connecting state when initiating");
394 log::assert_that(!btif_hf_cb[idx].connected_bda.IsEmpty(),
395 "Remote device address must not be empty when initiating");
396 // Check if the incoming open event and the outgoing connection are
397 // for the same device.
398 if (btif_hf_cb[idx].connected_bda != p_data->open.bd_addr) {
399 log::warn(
400 "possible connection collision, ignore the outgoing connection "
401 "for the different devices btif_hf_cb bda: {}, p_data bda: {}, "
402 "report disconnect state for btif_hf_cb bda.",
403 btif_hf_cb[idx].connected_bda, p_data->open.bd_addr);
404 bt_hf_callbacks->ConnectionStateCallback(BTHF_CONNECTION_STATE_DISCONNECTED,
405 &(btif_hf_cb[idx].connected_bda));
406 log_counter_metrics_btif(
407 android::bluetooth::CodePathCounterKeyEnum::HFP_COLLISON_AT_CONNECTING, 1);
408 reset_control_block(&btif_hf_cb[idx]);
409 btif_queue_advance();
410 }
411 }
412
413 // There is no pending outgoing connection.
414 if (p_data->open.status == BTA_AG_SUCCESS) {
415 // In case this is an incoming connection
416 btif_hf_cb[idx].connected_bda = p_data->open.bd_addr;
417 if (btif_hf_cb[idx].state != BTHF_CONNECTION_STATE_CONNECTING) {
418 DEVICE_IOT_CONFIG_ADDR_SET_INT(btif_hf_cb[idx].connected_bda, IOT_CONF_KEY_HFP_ROLE,
419 IOT_CONF_VAL_HFP_ROLE_CLIENT);
420 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(btif_hf_cb[idx].connected_bda,
421 IOT_CONF_KEY_HFP_SLC_CONN_COUNT);
422 }
423
424 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_CONNECTED;
425 btif_hf_cb[idx].peer_feat = 0;
426 clear_phone_state_multihf(&btif_hf_cb[idx]);
427 bluetooth::common::BluetoothMetricsLogger::GetInstance()->LogHeadsetProfileRfcConnection(
428 p_data->open.service_id);
429 bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state,
430 &btif_hf_cb[idx].connected_bda);
431 } else {
432 if (!btif_hf_cb[idx].is_initiator) {
433 // Ignore remote initiated open failures
434 log::warn("Unexpected AG open failure {} for {} is ignored", p_data->open.status,
435 p_data->open.bd_addr);
436 break;
437 }
438 log::error("self initiated AG open failed for {}, status {}", btif_hf_cb[idx].connected_bda,
439 p_data->open.status);
440 RawAddress connected_bda = btif_hf_cb[idx].connected_bda;
441 reset_control_block(&btif_hf_cb[idx]);
442
443 if (com::android::bluetooth::flags::ignore_notify_when_already_connected()) {
444 bool notify_required = true;
445
446 for (int i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++) {
447 if ((i != idx) && (BTHF_CONNECTION_STATE_CONNECTED == btif_hf_cb[i].state) &&
448 (connected_bda == btif_hf_cb[i].connected_bda)) {
449 // There is already an active cnnection on this device
450 // skip upper layer notification
451 notify_required = false;
452 log::info(
453 "AG open failure for {} is ignored because there's an "
454 "active connection on the same device",
455 connected_bda);
456 break;
457 }
458 }
459
460 if (notify_required) {
461 bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, &connected_bda);
462 }
463 } else {
464 bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, &connected_bda);
465 }
466
467 log_counter_metrics_btif(
468 android::bluetooth::CodePathCounterKeyEnum::HFP_SELF_INITIATED_AG_FAILED, 1);
469 btif_queue_advance();
470 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(connected_bda, IOT_CONF_KEY_HFP_SLC_CONN_FAIL_COUNT);
471 }
472 break;
473 case BTA_AG_CLOSE_EVT: {
474 log::debug(
475 "SLC and RFCOMM both disconnected event:{} idx:{} "
476 "btif_hf_cb.handle:{}",
477 dump_hf_event(event), idx, btif_hf_cb[idx].handle);
478 RawAddress connected_bda = btif_hf_cb[idx].connected_bda;
479 bt_hf_callbacks->ConnectionStateCallback(BTHF_CONNECTION_STATE_DISCONNECTING, &connected_bda);
480 // If AG_OPEN was received but SLC was not connected in time, then
481 // AG_CLOSE may be received. We need to advance the queue here.
482 bool failed_to_setup_slc = (btif_hf_cb[idx].state != BTHF_CONNECTION_STATE_SLC_CONNECTED) &&
483 btif_hf_cb[idx].is_initiator;
484
485 reset_control_block(&btif_hf_cb[idx]);
486 bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, &connected_bda);
487 if (failed_to_setup_slc) {
488 log::error("failed to setup SLC for {}", connected_bda);
489 log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum::HFP_SLC_SETUP_FAILED,
490 1);
491 btif_queue_advance();
492 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(btif_hf_cb[idx].connected_bda,
493 IOT_CONF_KEY_HFP_SLC_CONN_FAIL_COUNT);
494 }
495 break;
496 }
497 case BTA_AG_CONN_EVT:
498 DEVICE_IOT_CONFIG_ADDR_SET_HEX(btif_hf_cb[idx].connected_bda, IOT_CONF_KEY_HFP_CODECTYPE,
499 p_data->conn.peer_codec == 0x03
500 ? IOT_CONF_VAL_HFP_CODECTYPE_CVSDMSBC
501 : IOT_CONF_VAL_HFP_CODECTYPE_CVSD,
502 IOT_CONF_BYTE_NUM_1);
503 DEVICE_IOT_CONFIG_ADDR_SET_HEX(btif_hf_cb[idx].connected_bda, IOT_CONF_KEY_HFP_FEATURES,
504 p_data->conn.peer_feat, IOT_CONF_BYTE_NUM_2);
505
506 log::debug("SLC connected event:{} idx:{}", dump_hf_event(event), idx);
507 btif_hf_cb[idx].peer_feat = p_data->conn.peer_feat;
508 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_SLC_CONNECTED;
509 bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state,
510 &btif_hf_cb[idx].connected_bda);
511 if (btif_hf_cb[idx].is_initiator) {
512 btif_queue_advance();
513 }
514 break;
515
516 case BTA_AG_AUDIO_OPEN_EVT:
517 log::debug("Audio open event:{}", dump_hf_event(event));
518 bt_hf_callbacks->AudioStateCallback(BTHF_AUDIO_STATE_CONNECTED,
519 &btif_hf_cb[idx].connected_bda);
520 break;
521
522 case BTA_AG_AUDIO_CLOSE_EVT:
523 log::debug("Audio close event:{}", dump_hf_event(event));
524
525 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(btif_hf_cb[idx].connected_bda,
526 IOT_CONF_KEY_HFP_SCO_CONN_FAIL_COUNT);
527
528 bt_hf_callbacks->AudioStateCallback(BTHF_AUDIO_STATE_DISCONNECTED,
529 &btif_hf_cb[idx].connected_bda);
530 break;
531
532 case BTA_AG_SPK_EVT:
533 case BTA_AG_MIC_EVT:
534 log::debug("BTA auto-responds, silently discard event:{}", dump_hf_event(event));
535 bt_hf_callbacks->VolumeControlCallback(
536 (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK : BTHF_VOLUME_TYPE_MIC,
537 p_data->val.num, &btif_hf_cb[idx].connected_bda);
538 break;
539
540 case BTA_AG_AT_A_EVT:
541 bt_hf_callbacks->AnswerCallCallback(&btif_hf_cb[idx].connected_bda);
542 break;
543
544 /* Java needs to send OK/ERROR for these commands */
545 case BTA_AG_AT_BLDN_EVT:
546 case BTA_AG_AT_D_EVT:
547 bt_hf_callbacks->DialCallCallback((event == BTA_AG_AT_D_EVT) ? p_data->val.str : (char*)"",
548 &btif_hf_cb[idx].connected_bda);
549 break;
550
551 case BTA_AG_AT_CHUP_EVT:
552 bt_hf_callbacks->HangupCallCallback(&btif_hf_cb[idx].connected_bda);
553 break;
554
555 case BTA_AG_AT_CIND_EVT:
556 bt_hf_callbacks->AtCindCallback(&btif_hf_cb[idx].connected_bda);
557 break;
558
559 case BTA_AG_AT_VTS_EVT:
560 bt_hf_callbacks->DtmfCmdCallback(p_data->val.str[0], &btif_hf_cb[idx].connected_bda);
561 break;
562
563 case BTA_AG_AT_BVRA_EVT:
564 bt_hf_callbacks->VoiceRecognitionCallback(
565 (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED : BTHF_VR_STATE_STOPPED,
566 &btif_hf_cb[idx].connected_bda);
567 break;
568
569 case BTA_AG_AT_NREC_EVT:
570 bt_hf_callbacks->NoiseReductionCallback(
571 (p_data->val.num == 1) ? BTHF_NREC_START : BTHF_NREC_STOP,
572 &btif_hf_cb[idx].connected_bda);
573 break;
574
575 /* TODO: Add a callback for CBC */
576 case BTA_AG_AT_CBC_EVT:
577 break;
578
579 case BTA_AG_AT_CKPD_EVT:
580 bt_hf_callbacks->KeyPressedCallback(&btif_hf_cb[idx].connected_bda);
581 break;
582
583 case BTA_AG_CODEC_EVT:
584 log::verbose("BTA_AG_CODEC_EVT Set codec status {} codec {} 1=CVSD 2=MSBC 4=LC3",
585 p_data->val.hdr.status, p_data->val.num);
586 if (p_data->val.num == BTM_SCO_CODEC_CVSD) {
587 bt_hf_callbacks->WbsCallback(BTHF_WBS_NO, &btif_hf_cb[idx].connected_bda);
588 bt_hf_callbacks->SwbCallback(BTHF_SWB_CODEC_LC3, BTHF_SWB_NO,
589 &btif_hf_cb[idx].connected_bda);
590 } else if (p_data->val.num == BTM_SCO_CODEC_MSBC) {
591 bt_hf_callbacks->WbsCallback(BTHF_WBS_YES, &btif_hf_cb[idx].connected_bda);
592 bt_hf_callbacks->SwbCallback(BTHF_SWB_CODEC_LC3, BTHF_SWB_NO,
593 &btif_hf_cb[idx].connected_bda);
594 } else if (p_data->val.num == BTM_SCO_CODEC_LC3) {
595 bt_hf_callbacks->WbsCallback(BTHF_WBS_NO, &btif_hf_cb[idx].connected_bda);
596 bt_hf_callbacks->SwbCallback(BTHF_SWB_CODEC_LC3, BTHF_SWB_YES,
597 &btif_hf_cb[idx].connected_bda);
598 } else {
599 bt_hf_callbacks->WbsCallback(BTHF_WBS_NONE, &btif_hf_cb[idx].connected_bda);
600
601 bthf_swb_codec_t codec = BTHF_SWB_CODEC_LC3;
602 bthf_swb_config_t config = BTHF_SWB_NONE;
603
604 if (is_hfp_aptx_voice_enabled()) {
605 codec = BTHF_SWB_CODEC_VENDOR_APTX;
606
607 log::verbose("AG final selected SWB codec is 0x{:02x} 0=Q0 4=Q1 6=Q2 7=Q3",
608 p_data->val.num);
609 if (p_data->val.num == BTA_AG_SCO_APTX_SWB_SETTINGS_Q0 ||
610 p_data->val.num == BTA_AG_SCO_APTX_SWB_SETTINGS_Q1 ||
611 p_data->val.num == BTA_AG_SCO_APTX_SWB_SETTINGS_Q2 ||
612 p_data->val.num == BTA_AG_SCO_APTX_SWB_SETTINGS_Q3) {
613 config = BTHF_SWB_YES;
614 } else {
615 config = BTHF_SWB_NO;
616 }
617 }
618 bt_hf_callbacks->SwbCallback(codec, config, &btif_hf_cb[idx].connected_bda);
619 }
620 break;
621
622 /* Java needs to send OK/ERROR for these commands */
623 case BTA_AG_AT_CHLD_EVT:
624 bt_hf_callbacks->AtChldCallback((bthf_chld_type_t)atoi(p_data->val.str),
625 &btif_hf_cb[idx].connected_bda);
626 break;
627
628 case BTA_AG_AT_CLCC_EVT:
629 bt_hf_callbacks->AtClccCallback(&btif_hf_cb[idx].connected_bda);
630 break;
631
632 case BTA_AG_AT_COPS_EVT:
633 bt_hf_callbacks->AtCopsCallback(&btif_hf_cb[idx].connected_bda);
634 break;
635
636 case BTA_AG_AT_UNAT_EVT:
637 bt_hf_callbacks->UnknownAtCallback(p_data->val.str, &btif_hf_cb[idx].connected_bda);
638 break;
639
640 case BTA_AG_AT_CNUM_EVT:
641 bt_hf_callbacks->AtCnumCallback(&btif_hf_cb[idx].connected_bda);
642 break;
643
644 /* TODO: Some of these commands may need to be sent to app. For now respond
645 * with error */
646 case BTA_AG_AT_BINP_EVT:
647 case BTA_AG_AT_BTRH_EVT:
648 send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED, idx);
649 break;
650 case BTA_AG_AT_BAC_EVT:
651 log::verbose("AG Bitmap of peer-codecs {}", p_data->val.num);
652 /* If the peer supports mSBC and the BTIF preferred codec is also mSBC,
653 * then we should set the BTA AG Codec to mSBC. This would trigger a +BCS
654 * to mSBC at the time of SCO connection establishment */
655 if (hfp_hal_interface::get_swb_supported() && (p_data->val.num & BTM_SCO_CODEC_LC3)) {
656 log::verbose("btif_hf override-Preferred Codec to LC3");
657 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTM_SCO_CODEC_LC3);
658 } else if (hfp_hal_interface::get_wbs_supported() && (p_data->val.num & BTM_SCO_CODEC_MSBC)) {
659 log::verbose("btif_hf override-Preferred Codec to mSBC");
660 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTM_SCO_CODEC_MSBC);
661 } else {
662 log::verbose("btif_hf override-Preferred Codec to CVSD");
663 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTM_SCO_CODEC_CVSD);
664 }
665 break;
666
667 case BTA_AG_AT_BCS_EVT:
668 log::verbose("AG final selected codec is 0x{:02x} 1=CVSD 2=MSBC", p_data->val.num);
669 /* No BTHF_WBS_NONE case, because HF1.6 supported device can send BCS */
670 /* Only CVSD is considered narrow band speech */
671 bt_hf_callbacks->WbsCallback(
672 (p_data->val.num == BTM_SCO_CODEC_MSBC) ? BTHF_WBS_YES : BTHF_WBS_NO,
673 &btif_hf_cb[idx].connected_bda);
674 bt_hf_callbacks->SwbCallback(
675 BTHF_SWB_CODEC_LC3,
676 (p_data->val.num == BTM_SCO_CODEC_LC3) ? BTHF_SWB_YES : BTHF_SWB_NO,
677 &btif_hf_cb[idx].connected_bda);
678 break;
679
680 case BTA_AG_AT_BIND_EVT:
681 if (p_data->val.hdr.status == BTA_AG_SUCCESS) {
682 bt_hf_callbacks->AtBindCallback(p_data->val.str, &btif_hf_cb[idx].connected_bda);
683 }
684 break;
685
686 case BTA_AG_AT_BIEV_EVT:
687 if (p_data->val.hdr.status == BTA_AG_SUCCESS) {
688 bt_hf_callbacks->AtBievCallback((bthf_hf_ind_type_t)p_data->val.lidx, (int)p_data->val.num,
689 &btif_hf_cb[idx].connected_bda);
690 }
691 break;
692 case BTA_AG_AT_BIA_EVT:
693 if (p_data->val.hdr.status == BTA_AG_SUCCESS) {
694 uint32_t bia_mask_out = p_data->val.num;
695 bool service = !is_nth_bit_enabled(bia_mask_out, BTA_AG_IND_SERVICE);
696 bool roam = !is_nth_bit_enabled(bia_mask_out, BTA_AG_IND_ROAM);
697 bool signal = !is_nth_bit_enabled(bia_mask_out, BTA_AG_IND_SIGNAL);
698 bool battery = !is_nth_bit_enabled(bia_mask_out, BTA_AG_IND_BATTCHG);
699 bt_hf_callbacks->AtBiaCallback(service, roam, signal, battery,
700 &btif_hf_cb[idx].connected_bda);
701 }
702 break;
703
704 case BTA_AG_AT_QCS_EVT:
705 if (!is_hfp_aptx_voice_enabled()) {
706 log::warn("unhandled event {}. Aptx codec is not enabled", event);
707 break;
708 }
709
710 log::info("AG final selected SWB codec is {:#02x} 0=Q0 4=Q1 6=Q2 7=Q3", p_data->val.num);
711 bt_hf_callbacks->SwbCallback(
712 BTHF_SWB_CODEC_VENDOR_APTX,
713 p_data->val.num <= BTA_AG_SCO_APTX_SWB_SETTINGS_Q3 ? BTHF_SWB_YES : BTHF_SWB_NO,
714 &btif_hf_cb[idx].connected_bda);
715 break;
716
717 default:
718 log::warn("unhandled event {}", event);
719 break;
720 }
721 }
722
723 /*******************************************************************************
724 *
725 * Function bte_hf_evt
726 *
727 * Description Switches context from BTE to BTIF for all HF events
728 *
729 * Returns void
730 *
731 ******************************************************************************/
732
bte_hf_evt(tBTA_AG_EVT event,tBTA_AG * p_data)733 static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG* p_data) {
734 bt_status_t status;
735 int param_len = 0;
736
737 /* TODO: BTA sends the union members and not tBTA_AG. If using
738 * param_len=sizeof(tBTA_AG), we get a crash on memcpy */
739 if (BTA_AG_REGISTER_EVT == event) {
740 param_len = sizeof(tBTA_AG_REGISTER);
741 } else if (BTA_AG_OPEN_EVT == event) {
742 param_len = sizeof(tBTA_AG_OPEN);
743 } else if (BTA_AG_CONN_EVT == event) {
744 param_len = sizeof(tBTA_AG_CONN);
745 } else if ((BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) ||
746 (BTA_AG_AUDIO_CLOSE_EVT == event)) {
747 param_len = sizeof(tBTA_AG_HDR);
748 } else if (p_data) {
749 param_len = sizeof(tBTA_AG_VAL);
750 }
751
752 /* switch context to btif task context (copy full union size for convenience)
753 */
754 status = btif_transfer_context(btif_hf_upstreams_evt, (uint16_t)event, (char*)p_data, param_len,
755 nullptr);
756
757 /* catch any failed context transfers */
758 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
759 }
760
761 /*******************************************************************************
762 *
763 * Function connect
764 *
765 * Description connect to headset
766 *
767 * Returns bt_status_t
768 *
769 ******************************************************************************/
connect_int(RawAddress * bd_addr,uint16_t)770 static bt_status_t connect_int(RawAddress* bd_addr, uint16_t /*uuid*/) {
771 CHECK_BTHF_INIT();
772 if (is_connected(bd_addr)) {
773 log::warn("device {} is already connected", *bd_addr);
774 return BT_STATUS_DONE;
775 }
776 btif_hf_cb_t* hf_cb = nullptr;
777 for (int i = 0; i < btif_max_hf_clients; i++) {
778 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_DISCONNECTED) {
779 hf_cb = &btif_hf_cb[i];
780 break;
781 }
782 // Due to btif queue implementation, when connect_int is called, no btif
783 // control block should be in connecting state
784 // Crash here to prevent future code changes from breaking this mechanism
785 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTING) {
786 log::fatal("{}, handle {}, is still in connecting state {}", btif_hf_cb[i].connected_bda,
787 btif_hf_cb[i].handle, btif_hf_cb[i].state);
788 }
789 }
790 if (hf_cb == nullptr) {
791 log::warn("Cannot connect {}: maximum {} clients already connected", *bd_addr,
792 btif_max_hf_clients);
793 return BT_STATUS_BUSY;
794 }
795 hf_cb->state = BTHF_CONNECTION_STATE_CONNECTING;
796 hf_cb->connected_bda = *bd_addr;
797 hf_cb->is_initiator = true;
798 hf_cb->peer_feat = 0;
799 BTA_AgOpen(hf_cb->handle, hf_cb->connected_bda);
800
801 DEVICE_IOT_CONFIG_ADDR_SET_INT(hf_cb->connected_bda, IOT_CONF_KEY_HFP_ROLE,
802 IOT_CONF_VAL_HFP_ROLE_CLIENT);
803 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(hf_cb->connected_bda, IOT_CONF_KEY_HFP_SLC_CONN_COUNT);
804 return BT_STATUS_SUCCESS;
805 }
806
UpdateCallStates(btif_hf_cb_t * control_block,int num_active,int num_held,bthf_call_state_t call_setup_state)807 static void UpdateCallStates(btif_hf_cb_t* control_block, int num_active, int num_held,
808 bthf_call_state_t call_setup_state) {
809 control_block->num_active = num_active;
810 control_block->num_held = num_held;
811 control_block->call_setup_state = call_setup_state;
812 }
813
814 /*******************************************************************************
815 *
816 * Function btif_hf_is_call_idle
817 *
818 * Description returns true if no call is in progress
819 *
820 * Returns bt_status_t
821 *
822 ******************************************************************************/
IsCallIdle()823 bool IsCallIdle() {
824 if (!bt_hf_callbacks) {
825 return true;
826 }
827
828 for (int i = 0; i < btif_max_hf_clients; ++i) {
829 if ((btif_hf_cb[i].call_setup_state != BTHF_CALL_STATE_IDLE) ||
830 ((btif_hf_cb[i].num_held + btif_hf_cb[i].num_active) > 0)) {
831 return false;
832 }
833 }
834
835 return true;
836 }
837
IsDuringVoiceRecognition(RawAddress * bd_addr)838 bool IsDuringVoiceRecognition(RawAddress* bd_addr) {
839 if (!bt_hf_callbacks) {
840 return false;
841 }
842 if (bd_addr == nullptr) {
843 log::error("null address");
844 return false;
845 }
846 int idx = btif_hf_idx_by_bdaddr(bd_addr);
847 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
848 log::error("Invalid index {}", idx);
849 return false;
850 }
851 if (!is_connected(bd_addr)) {
852 log::error("{} is not connected", *bd_addr);
853 return false;
854 }
855 bool in_vr = btif_hf_cb[idx].is_during_voice_recognition;
856 log::debug("IsDuringVoiceRecognition={}", in_vr);
857 return in_vr;
858 }
859
860 class HeadsetInterface : Interface {
861 public:
GetInstance()862 static Interface* GetInstance() {
863 static Interface* instance = new HeadsetInterface();
864 return instance;
865 }
866 bt_status_t Init(Callbacks* callbacks, int max_hf_clients, bool inband_ringing_enabled) override;
867 bt_status_t Connect(RawAddress* bd_addr) override;
868 bt_status_t Disconnect(RawAddress* bd_addr) override;
869 bt_status_t ConnectAudio(RawAddress* bd_addr, int disabled_codecs) override;
870 bt_status_t DisconnectAudio(RawAddress* bd_addr) override;
871 bt_status_t isNoiseReductionSupported(RawAddress* bd_addr) override;
872 bt_status_t isVoiceRecognitionSupported(RawAddress* bd_addr) override;
873 bt_status_t StartVoiceRecognition(RawAddress* bd_addr) override;
874 bt_status_t StopVoiceRecognition(RawAddress* bd_addr) override;
875 bt_status_t VolumeControl(bthf_volume_type_t type, int volume, RawAddress* bd_addr) override;
876 bt_status_t DeviceStatusNotification(bthf_network_state_t ntk_state, bthf_service_type_t svc_type,
877 int signal, int batt_chg, RawAddress* bd_addr) override;
878 bt_status_t CopsResponse(const char* cops, RawAddress* bd_addr) override;
879 bt_status_t CindResponse(int svc, int num_active, int num_held,
880 bthf_call_state_t call_setup_state, int signal, int roam, int batt_chg,
881 RawAddress* bd_addr) override;
882 bt_status_t FormattedAtResponse(const char* rsp, RawAddress* bd_addr) override;
883 bt_status_t AtResponse(bthf_at_response_t response_code, int error_code,
884 RawAddress* bd_addr) override;
885 bt_status_t ClccResponse(int index, bthf_call_direction_t dir, bthf_call_state_t state,
886 bthf_call_mode_t mode, bthf_call_mpty_type_t mpty, const char* number,
887 bthf_call_addrtype_t type, RawAddress* bd_addr) override;
888 bt_status_t PhoneStateChange(int num_active, int num_held, bthf_call_state_t call_setup_state,
889 const char* number, bthf_call_addrtype_t type, const char* name,
890 RawAddress* bd_addr) override;
891
892 bt_status_t EnableSwb(bthf_swb_codec_t swbCodec, bool enable, RawAddress* bd_addr) override;
893
894 void Cleanup() override;
895 bt_status_t SetScoOffloadEnabled(bool value) override;
896 bt_status_t SetScoAllowed(bool value) override;
897 bt_status_t SendBsir(bool value, RawAddress* bd_addr) override;
898 bt_status_t SetActiveDevice(RawAddress* active_device_addr) override;
899 bt_status_t DebugDump() override;
900 };
901
Init(Callbacks * callbacks,int max_hf_clients,bool inband_ringing_enabled)902 bt_status_t HeadsetInterface::Init(Callbacks* callbacks, int max_hf_clients,
903 bool inband_ringing_enabled) {
904 if (inband_ringing_enabled) {
905 btif_hf_features |= BTA_AG_FEAT_INBAND;
906 } else {
907 btif_hf_features &= ~BTA_AG_FEAT_INBAND;
908 }
909 log::assert_that(max_hf_clients <= BTA_AG_MAX_NUM_CLIENTS,
910 "Too many HF clients, maximum is {}, was given {}", BTA_AG_MAX_NUM_CLIENTS,
911 max_hf_clients);
912 btif_max_hf_clients = max_hf_clients;
913 log::verbose("btif_hf_features={}, max_hf_clients={}, inband_ringing_enabled={}",
914 btif_hf_features, btif_max_hf_clients, inband_ringing_enabled);
915 bt_hf_callbacks = callbacks;
916 for (btif_hf_cb_t& hf_cb : btif_hf_cb) {
917 reset_control_block(&hf_cb);
918 }
919
920 // Invoke the enable service API to the core to set the appropriate service_id
921 // Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled
922 // (phone) otherwise only HSP is enabled (tablet)
923 if (get_BTIF_HF_SERVICES() & BTA_HFP_SERVICE_MASK) {
924 btif_enable_service(BTA_HFP_SERVICE_ID);
925 } else {
926 btif_enable_service(BTA_HSP_SERVICE_ID);
927 }
928
929 return BT_STATUS_SUCCESS;
930 }
931
Connect(RawAddress * bd_addr)932 bt_status_t HeadsetInterface::Connect(RawAddress* bd_addr) {
933 CHECK_BTHF_INIT();
934 return btif_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_int);
935 }
936
Disconnect(RawAddress * bd_addr)937 bt_status_t HeadsetInterface::Disconnect(RawAddress* bd_addr) {
938 CHECK_BTHF_INIT();
939 int idx = btif_hf_idx_by_bdaddr(bd_addr);
940 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
941 log::error("Invalid index {}", idx);
942 return BT_STATUS_PARM_INVALID;
943 }
944 if (!is_connected(bd_addr)) {
945 log::error("{} is not connected", *bd_addr);
946 return BT_STATUS_DEVICE_NOT_FOUND;
947 }
948 BTA_AgClose(btif_hf_cb[idx].handle);
949 return BT_STATUS_SUCCESS;
950 }
951
ConnectAudio(RawAddress * bd_addr,int disabled_codecs)952 bt_status_t HeadsetInterface::ConnectAudio(RawAddress* bd_addr, int disabled_codecs) {
953 CHECK_BTHF_INIT();
954 int idx = btif_hf_idx_by_bdaddr(bd_addr);
955 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
956 log::error("Invalid index {}", idx);
957 return BT_STATUS_PARM_INVALID;
958 }
959 /* Check if SLC is connected */
960 if (!IsSlcConnected(bd_addr)) {
961 log::error("SLC not connected for {}", *bd_addr);
962 return BT_STATUS_NOT_READY;
963 }
964 do_in_jni_thread(base::BindOnce(&Callbacks::AudioStateCallback,
965 // Manual pointer management for now
966 base::Unretained(bt_hf_callbacks), BTHF_AUDIO_STATE_CONNECTING,
967 &btif_hf_cb[idx].connected_bda));
968 BTA_AgAudioOpen(btif_hf_cb[idx].handle, disabled_codecs);
969
970 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(*bd_addr, IOT_CONF_KEY_HFP_SCO_CONN_COUNT);
971
972 return BT_STATUS_SUCCESS;
973 }
974
DisconnectAudio(RawAddress * bd_addr)975 bt_status_t HeadsetInterface::DisconnectAudio(RawAddress* bd_addr) {
976 CHECK_BTHF_INIT();
977 int idx = btif_hf_idx_by_bdaddr(bd_addr);
978 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
979 log::error("Invalid index {}", idx);
980 return BT_STATUS_PARM_INVALID;
981 }
982 if (!is_connected(bd_addr)) {
983 log::error("{} is not connected", *bd_addr);
984 return BT_STATUS_DEVICE_NOT_FOUND;
985 }
986 BTA_AgAudioClose(btif_hf_cb[idx].handle);
987 return BT_STATUS_SUCCESS;
988 }
989
isNoiseReductionSupported(RawAddress * bd_addr)990 bt_status_t HeadsetInterface::isNoiseReductionSupported(RawAddress* bd_addr) {
991 CHECK_BTHF_INIT();
992 int idx = btif_hf_idx_by_bdaddr(bd_addr);
993 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
994 log::error("Invalid index {}", idx);
995 return BT_STATUS_PARM_INVALID;
996 }
997 if (!(btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_ECNR)) {
998 return BT_STATUS_UNSUPPORTED;
999 }
1000 return BT_STATUS_SUCCESS;
1001 }
1002
isVoiceRecognitionSupported(RawAddress * bd_addr)1003 bt_status_t HeadsetInterface::isVoiceRecognitionSupported(RawAddress* bd_addr) {
1004 CHECK_BTHF_INIT();
1005 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1006 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1007 log::error("Invalid index {}", idx);
1008 return BT_STATUS_PARM_INVALID;
1009 }
1010 if (!(btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC)) {
1011 return BT_STATUS_UNSUPPORTED;
1012 }
1013 return BT_STATUS_SUCCESS;
1014 }
1015
StartVoiceRecognition(RawAddress * bd_addr)1016 bt_status_t HeadsetInterface::StartVoiceRecognition(RawAddress* bd_addr) {
1017 CHECK_BTHF_INIT();
1018 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1019 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1020 log::error("Invalid index {}", idx);
1021 return BT_STATUS_PARM_INVALID;
1022 }
1023 if (!is_connected(bd_addr)) {
1024 log::error("{} is not connected", *bd_addr);
1025 return BT_STATUS_NOT_READY;
1026 }
1027 if (!(btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC)) {
1028 log::error("voice recognition not supported, features=0x{:x}", btif_hf_cb[idx].peer_feat);
1029 return BT_STATUS_UNSUPPORTED;
1030 }
1031 btif_hf_cb[idx].is_during_voice_recognition = true;
1032 tBTA_AG_RES_DATA ag_res = {};
1033 ag_res.state = true;
1034 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, ag_res);
1035 return BT_STATUS_SUCCESS;
1036 }
1037
StopVoiceRecognition(RawAddress * bd_addr)1038 bt_status_t HeadsetInterface::StopVoiceRecognition(RawAddress* bd_addr) {
1039 CHECK_BTHF_INIT();
1040 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1041
1042 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1043 log::error("Invalid index {}", idx);
1044 return BT_STATUS_PARM_INVALID;
1045 }
1046 if (!is_connected(bd_addr)) {
1047 log::error("{} is not connected", *bd_addr);
1048 return BT_STATUS_NOT_READY;
1049 }
1050 if (!(btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC)) {
1051 log::error("voice recognition not supported, features=0x{:x}", btif_hf_cb[idx].peer_feat);
1052 return BT_STATUS_UNSUPPORTED;
1053 }
1054 btif_hf_cb[idx].is_during_voice_recognition = false;
1055 tBTA_AG_RES_DATA ag_res = {};
1056 ag_res.state = false;
1057 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, ag_res);
1058 return BT_STATUS_SUCCESS;
1059 }
1060
VolumeControl(bthf_volume_type_t type,int volume,RawAddress * bd_addr)1061 bt_status_t HeadsetInterface::VolumeControl(bthf_volume_type_t type, int volume,
1062 RawAddress* bd_addr) {
1063 CHECK_BTHF_INIT();
1064 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1065 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1066 log::error("Invalid index {}", idx);
1067 return BT_STATUS_PARM_INVALID;
1068 }
1069 if (!is_connected(bd_addr)) {
1070 log::error("{} is not connected", *bd_addr);
1071 return BT_STATUS_DEVICE_NOT_FOUND;
1072 }
1073 tBTA_AG_RES_DATA ag_res = {};
1074 ag_res.num = static_cast<uint16_t>(volume);
1075 BTA_AgResult(btif_hf_cb[idx].handle,
1076 (type == BTHF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES, ag_res);
1077 return BT_STATUS_SUCCESS;
1078 }
1079
DeviceStatusNotification(bthf_network_state_t ntk_state,bthf_service_type_t svc_type,int signal,int batt_chg,RawAddress * bd_addr)1080 bt_status_t HeadsetInterface::DeviceStatusNotification(bthf_network_state_t ntk_state,
1081 bthf_service_type_t svc_type, int signal,
1082 int batt_chg, RawAddress* bd_addr) {
1083 CHECK_BTHF_INIT();
1084 if (!bd_addr) {
1085 log::warn("bd_addr is null");
1086 return BT_STATUS_PARM_INVALID;
1087 }
1088 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1089 if (idx < 0 || idx > BTA_AG_MAX_NUM_CLIENTS) {
1090 log::warn("invalid index {} for {}", idx, *bd_addr);
1091 return BT_STATUS_PARM_INVALID;
1092 }
1093 const btif_hf_cb_t& control_block = btif_hf_cb[idx];
1094 // ok if no device is connected
1095 if (is_connected(nullptr)) {
1096 // send all indicators to BTA.
1097 // BTA will make sure no duplicates are sent out
1098 send_indicator_update(control_block, BTA_AG_IND_SERVICE,
1099 (ntk_state == BTHF_NETWORK_STATE_AVAILABLE) ? 1 : 0);
1100 send_indicator_update(control_block, BTA_AG_IND_ROAM,
1101 (svc_type == BTHF_SERVICE_TYPE_HOME) ? 0 : 1);
1102 send_indicator_update(control_block, BTA_AG_IND_SIGNAL, signal);
1103 send_indicator_update(control_block, BTA_AG_IND_BATTCHG, batt_chg);
1104 }
1105 return BT_STATUS_SUCCESS;
1106 }
1107
CopsResponse(const char * cops,RawAddress * bd_addr)1108 bt_status_t HeadsetInterface::CopsResponse(const char* cops, RawAddress* bd_addr) {
1109 CHECK_BTHF_INIT();
1110 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1111 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1112 log::error("Invalid index {}", idx);
1113 return BT_STATUS_PARM_INVALID;
1114 }
1115 if (!is_connected(bd_addr)) {
1116 log::error("{} is not connected", *bd_addr);
1117 return BT_STATUS_DEVICE_NOT_FOUND;
1118 }
1119 tBTA_AG_RES_DATA ag_res = {};
1120 /* Format the response */
1121 snprintf(ag_res.str, sizeof(ag_res.str), "0,0,\"%.16s\"", cops);
1122 ag_res.ok_flag = BTA_AG_OK_DONE;
1123 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_COPS_RES, ag_res);
1124 return BT_STATUS_SUCCESS;
1125 }
1126
CindResponse(int svc,int num_active,int num_held,bthf_call_state_t call_setup_state,int signal,int roam,int batt_chg,RawAddress * bd_addr)1127 bt_status_t HeadsetInterface::CindResponse(int svc, int num_active, int num_held,
1128 bthf_call_state_t call_setup_state, int signal, int roam,
1129 int batt_chg, RawAddress* bd_addr) {
1130 CHECK_BTHF_INIT();
1131 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1132 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1133 log::error("Invalid index {}", idx);
1134 return BT_STATUS_PARM_INVALID;
1135 }
1136 if (!is_connected(bd_addr)) {
1137 log::error("{} is not connected", *bd_addr);
1138 return BT_STATUS_DEVICE_NOT_FOUND;
1139 }
1140 tBTA_AG_RES_DATA ag_res = {};
1141 // per the errata 2043, call=1 implies atleast one call is in progress
1142 // (active/held), see:
1143 // https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1144 snprintf(ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d,%d,%d",
1145 (num_active + num_held) ? 1 : 0, /* Call state */
1146 callstate_to_callsetup(call_setup_state), /* Callsetup state */
1147 svc, /* network service */
1148 signal, /* Signal strength */
1149 roam, /* Roaming indicator */
1150 batt_chg, /* Battery level */
1151 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1))); /* Call held */
1152 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CIND_RES, ag_res);
1153 return BT_STATUS_SUCCESS;
1154 }
1155
FormattedAtResponse(const char * rsp,RawAddress * bd_addr)1156 bt_status_t HeadsetInterface::FormattedAtResponse(const char* rsp, RawAddress* bd_addr) {
1157 CHECK_BTHF_INIT();
1158 tBTA_AG_RES_DATA ag_res = {};
1159 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1160 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1161 log::error("Invalid index {}", idx);
1162 return BT_STATUS_PARM_INVALID;
1163 }
1164 if (!is_connected(bd_addr)) {
1165 log::error("{} is not connected", *bd_addr);
1166 return BT_STATUS_DEVICE_NOT_FOUND;
1167 }
1168 /* Format the response and send */
1169 strncpy(ag_res.str, rsp, BTA_AG_AT_MAX_LEN);
1170 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, ag_res);
1171 return BT_STATUS_SUCCESS;
1172 }
1173
AtResponse(bthf_at_response_t response_code,int error_code,RawAddress * bd_addr)1174 bt_status_t HeadsetInterface::AtResponse(bthf_at_response_t response_code, int error_code,
1175 RawAddress* bd_addr) {
1176 CHECK_BTHF_INIT();
1177 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1178 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1179 log::error("Invalid index {}", idx);
1180 return BT_STATUS_PARM_INVALID;
1181 }
1182 if (!is_connected(bd_addr)) {
1183 log::error("{} is not connected", *bd_addr);
1184 return BT_STATUS_DEVICE_NOT_FOUND;
1185 }
1186 send_at_result((response_code == BTHF_AT_RESPONSE_OK) ? BTA_AG_OK_DONE : BTA_AG_OK_ERROR,
1187 static_cast<uint16_t>(error_code), idx);
1188 return BT_STATUS_SUCCESS;
1189 }
1190
ClccResponse(int index,bthf_call_direction_t dir,bthf_call_state_t state,bthf_call_mode_t mode,bthf_call_mpty_type_t mpty,const char * number,bthf_call_addrtype_t type,RawAddress * bd_addr)1191 bt_status_t HeadsetInterface::ClccResponse(int index, bthf_call_direction_t dir,
1192 bthf_call_state_t state, bthf_call_mode_t mode,
1193 bthf_call_mpty_type_t mpty, const char* number,
1194 bthf_call_addrtype_t type, RawAddress* bd_addr) {
1195 CHECK_BTHF_INIT();
1196 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1197 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1198 log::error("Invalid index {}", idx);
1199 return BT_STATUS_PARM_INVALID;
1200 }
1201 if (!is_connected(bd_addr)) {
1202 log::error("{} is not connected", *bd_addr);
1203 return BT_STATUS_DEVICE_NOT_FOUND;
1204 }
1205 tBTA_AG_RES_DATA ag_res = {};
1206 /* Format the response */
1207 if (index == 0) {
1208 ag_res.ok_flag = BTA_AG_OK_DONE;
1209 } else {
1210 std::string cell_number(number ? number : "");
1211 log::verbose("clcc_response: [{}] dir {} state {} mode {} number = {} type = {}", index, dir,
1212 state, mode, PRIVATE_CELL(cell_number), type);
1213 int res_strlen = snprintf(ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d", index, dir, state,
1214 mode, mpty);
1215 if (number) {
1216 size_t rem_bytes = sizeof(ag_res.str) - res_strlen;
1217 char dialnum[sizeof(ag_res.str)];
1218 size_t newidx = 0;
1219 if (type == BTHF_CALL_ADDRTYPE_INTERNATIONAL && *number != '+') {
1220 dialnum[newidx++] = '+';
1221 }
1222 for (size_t i = 0; number[i] != 0; i++) {
1223 if (newidx >= (sizeof(dialnum) - res_strlen - 1)) {
1224 break;
1225 }
1226 if (utl_isdialchar(number[i])) {
1227 dialnum[newidx++] = number[i];
1228 }
1229 }
1230 dialnum[newidx] = 0;
1231 // Reserve 5 bytes for ["][,][3_digit_type]
1232 snprintf(&ag_res.str[res_strlen], rem_bytes - 5, ",\"%s", dialnum);
1233 std::stringstream remaining_string;
1234 remaining_string << "\"," << type;
1235 strncat(&ag_res.str[res_strlen], remaining_string.str().c_str(), 5);
1236 }
1237 }
1238 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, ag_res);
1239 return BT_STATUS_SUCCESS;
1240 }
1241
PhoneStateChange(int num_active,int num_held,bthf_call_state_t call_setup_state,const char * number,bthf_call_addrtype_t type,const char * name,RawAddress * bd_addr)1242 bt_status_t HeadsetInterface::PhoneStateChange(int num_active, int num_held,
1243 bthf_call_state_t call_setup_state,
1244 const char* number, bthf_call_addrtype_t type,
1245 const char* name, RawAddress* bd_addr) {
1246 CHECK_BTHF_INIT();
1247 if (bd_addr == nullptr) {
1248 log::warn("bd_addr is null");
1249 return BT_STATUS_PARM_INVALID;
1250 }
1251
1252 const RawAddress raw_address(*bd_addr);
1253 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1254 if (idx < 0 || idx >= BTA_AG_MAX_NUM_CLIENTS) {
1255 log::warn("Invalid index {} for {}", idx, raw_address);
1256 return BT_STATUS_PARM_INVALID;
1257 }
1258
1259 const btif_hf_cb_t& control_block = btif_hf_cb[idx];
1260 if (!IsSlcConnected(bd_addr)) {
1261 log::warn("SLC not connected for {}", *bd_addr);
1262 return BT_STATUS_NOT_READY;
1263 }
1264 if (call_setup_state == BTHF_CALL_STATE_DISCONNECTED) {
1265 // HFP spec does not handle cases when a call is being disconnected.
1266 // Since DISCONNECTED state must lead to IDLE state, ignoring it here.s
1267 log::info(
1268 "Ignore call state change to DISCONNECTED, idx={}, addr={}, "
1269 "num_active={}, num_held={}",
1270 idx, *bd_addr, num_active, num_held);
1271 return BT_STATUS_SUCCESS;
1272 }
1273 log::debug(
1274 "bd_addr:{} active_bda:{} num_active:{} prev_num_active:{} num_held:{} "
1275 "prev_num_held:{} call_state:{} prev_call_state:{}",
1276 *bd_addr, active_bda, num_active, control_block.num_active, num_held,
1277 control_block.num_held, dump_hf_call_state(call_setup_state),
1278 dump_hf_call_state(control_block.call_setup_state));
1279 tBTA_AG_RES res = BTA_AG_UNKNOWN;
1280 bt_status_t status = BT_STATUS_SUCCESS;
1281 bool active_call_updated = false;
1282
1283 /* if all indicators are 0, send end call and return */
1284 if (num_active == 0 && num_held == 0 && call_setup_state == BTHF_CALL_STATE_IDLE) {
1285 if (control_block.num_active > 0) {
1286 BTM_LogHistory(kBtmLogTag, raw_address, "Call Ended");
1287 }
1288 BTA_AgResult(control_block.handle, BTA_AG_END_CALL_RES, tBTA_AG_RES_DATA::kEmpty);
1289 /* if held call was present, reset that as well */
1290 if (control_block.num_held) {
1291 send_indicator_update(control_block, BTA_AG_IND_CALLHELD, 0);
1292 }
1293 UpdateCallStates(&btif_hf_cb[idx], num_active, num_held, call_setup_state);
1294 return status;
1295 }
1296
1297 /* active state can change when:
1298 ** 1. an outgoing/incoming call was answered
1299 ** 2. an held was resumed
1300 ** 3. without callsetup notifications, call became active
1301 ** (3) can happen if call is active and a headset connects to us
1302 **
1303 ** In the case of (3), we will have to notify the stack of an active
1304 ** call, instead of sending an indicator update. This will also
1305 ** force the SCO to be setup. Handle this special case here prior to
1306 ** call setup handling
1307 */
1308 if (((num_active + num_held) > 0) && (control_block.num_active == 0) &&
1309 (control_block.num_held == 0) && (control_block.call_setup_state == BTHF_CALL_STATE_IDLE)) {
1310 tBTA_AG_RES_DATA ag_res = {};
1311 log::verbose("Active/Held call notification received without call setup update");
1312
1313 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
1314 // Addition call setup with the Active call
1315 // CIND response should have been updated.
1316 // just open SCO connection.
1317 if (call_setup_state != BTHF_CALL_STATE_IDLE) {
1318 res = BTA_AG_MULTI_CALL_RES;
1319 } else {
1320 res = BTA_AG_OUT_CALL_CONN_RES;
1321 }
1322 BTA_AgResult(control_block.handle, res, ag_res);
1323 active_call_updated = true;
1324 }
1325
1326 /* Ringing call changed? */
1327 if (call_setup_state != control_block.call_setup_state) {
1328 tBTA_AG_RES_DATA ag_res = {};
1329 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
1330 log::verbose("Call setup states changed. old: {} new: {}",
1331 dump_hf_call_state(control_block.call_setup_state),
1332 dump_hf_call_state(call_setup_state));
1333 switch (call_setup_state) {
1334 case BTHF_CALL_STATE_IDLE: {
1335 switch (control_block.call_setup_state) {
1336 case BTHF_CALL_STATE_INCOMING:
1337 if (num_active > control_block.num_active) {
1338 res = BTA_AG_IN_CALL_CONN_RES;
1339 if (is_active_device(*bd_addr)) {
1340 ag_res.audio_handle = control_block.handle;
1341 }
1342 } else if (num_held > control_block.num_held) {
1343 res = BTA_AG_IN_CALL_HELD_RES;
1344 } else {
1345 res = BTA_AG_CALL_CANCEL_RES;
1346 }
1347 break;
1348 case BTHF_CALL_STATE_DIALING:
1349 case BTHF_CALL_STATE_ALERTING:
1350 if (num_active > control_block.num_active) {
1351 res = BTA_AG_OUT_CALL_CONN_RES;
1352 } else {
1353 res = BTA_AG_CALL_CANCEL_RES;
1354 }
1355 break;
1356 default:
1357 log::error("Incorrect call state prev={}, now={}", control_block.call_setup_state,
1358 call_setup_state);
1359 status = BT_STATUS_PARM_INVALID;
1360 break;
1361 }
1362 } break;
1363
1364 case BTHF_CALL_STATE_INCOMING:
1365 if (num_active || num_held) {
1366 res = BTA_AG_CALL_WAIT_RES;
1367 } else {
1368 res = BTA_AG_IN_CALL_RES;
1369 if (is_active_device(*bd_addr)) {
1370 ag_res.audio_handle = control_block.handle;
1371 }
1372 }
1373 if (number) {
1374 std::ostringstream call_number_stream;
1375 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+')) {
1376 call_number_stream << "\"+";
1377 } else {
1378 call_number_stream << "\"";
1379 }
1380
1381 std::string name_str;
1382 if (name) {
1383 name_str.append(name);
1384 }
1385 std::string number_str(number);
1386 // 13 = ["][+]["][,][3_digit_type][,,,]["]["][null_terminator]
1387 int overflow_size = 13 + static_cast<int>(number_str.length() + name_str.length()) -
1388 static_cast<int>(sizeof(ag_res.str));
1389 if (overflow_size > 0) {
1390 int extra_overflow_size = overflow_size - static_cast<int>(name_str.length());
1391 if (extra_overflow_size > 0) {
1392 number_str.resize(number_str.length() - extra_overflow_size);
1393 name_str.clear();
1394 } else {
1395 name_str.resize(name_str.length() - overflow_size);
1396 }
1397 }
1398 call_number_stream << number_str << "\"";
1399
1400 // Store caller id string and append type info.
1401 // Make sure type info is valid, otherwise add 129 as default type
1402 ag_res.num = static_cast<uint16_t>(type);
1403 if ((ag_res.num < BTA_AG_CLIP_TYPE_MIN) || (ag_res.num > BTA_AG_CLIP_TYPE_MAX)) {
1404 if (ag_res.num != BTA_AG_CLIP_TYPE_VOIP) {
1405 ag_res.num = BTA_AG_CLIP_TYPE_DEFAULT;
1406 }
1407 }
1408
1409 if (res == BTA_AG_CALL_WAIT_RES || name_str.empty()) {
1410 call_number_stream << "," << std::to_string(ag_res.num);
1411 } else {
1412 call_number_stream << "," << std::to_string(ag_res.num) << ",,,\"" << name_str << "\"";
1413 }
1414 snprintf(ag_res.str, sizeof(ag_res.str), "%s", call_number_stream.str().c_str());
1415 }
1416 {
1417 std::string cell_number(number);
1418 BTM_LogHistory(kBtmLogTag, raw_address, "Call Incoming",
1419 base::StringPrintf("number:%s", PRIVATE_CELL(cell_number)));
1420 }
1421 // base::StringPrintf("number:%s", PRIVATE_CELL(number)));
1422 break;
1423 case BTHF_CALL_STATE_DIALING:
1424 if (!(num_active + num_held) && is_active_device(*bd_addr)) {
1425 ag_res.audio_handle = control_block.handle;
1426 }
1427 res = BTA_AG_OUT_CALL_ORIG_RES;
1428 break;
1429 case BTHF_CALL_STATE_ALERTING:
1430 /* if we went from idle->alert, force SCO setup here. dialing usually
1431 * triggers it */
1432 if ((control_block.call_setup_state == BTHF_CALL_STATE_IDLE) && !(num_active + num_held) &&
1433 is_active_device(*bd_addr)) {
1434 ag_res.audio_handle = control_block.handle;
1435 }
1436 res = BTA_AG_OUT_CALL_ALERT_RES;
1437 break;
1438 default:
1439 log::error("Incorrect call state prev={}, now={}", control_block.call_setup_state,
1440 call_setup_state);
1441 status = BT_STATUS_PARM_INVALID;
1442 break;
1443 }
1444 log::verbose("Call setup state changed. res={}, audio_handle={}", res, ag_res.audio_handle);
1445
1446 if (res != 0xFF) {
1447 BTA_AgResult(control_block.handle, res, ag_res);
1448 }
1449
1450 /* if call setup is idle, we have already updated call indicator, jump out
1451 */
1452 if (call_setup_state == BTHF_CALL_STATE_IDLE) {
1453 /* check & update callheld */
1454 if ((num_held > 0) && (num_active > 0)) {
1455 send_indicator_update(control_block, BTA_AG_IND_CALLHELD, 1);
1456 }
1457 UpdateCallStates(&btif_hf_cb[idx], num_active, num_held, call_setup_state);
1458 return status;
1459 }
1460 }
1461
1462 /**
1463 * Handle call indicator change
1464 *
1465 * Per the errata 2043, call=1 implies at least one call is in progress
1466 * (active or held)
1467 * See: https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1468 *
1469 **/
1470 if (!active_call_updated &&
1471 ((num_active + num_held) != (control_block.num_active + control_block.num_held))) {
1472 log::verbose("in progress call states changed, active=[{}->{}], held=[{}->{}]",
1473 control_block.num_active, num_active, control_block.num_held, num_held);
1474 send_indicator_update(
1475 control_block, BTA_AG_IND_CALL,
1476 ((num_active + num_held) > 0) ? BTA_AG_CALL_ACTIVE : BTA_AG_CALL_INACTIVE);
1477 }
1478
1479 /* Held Changed? */
1480 if (num_held != control_block.num_held ||
1481 ((num_active == 0) && ((num_held + control_block.num_held) > 1))) {
1482 log::verbose("Held call states changed. old: {} new: {}", control_block.num_held, num_held);
1483 send_indicator_update(control_block, BTA_AG_IND_CALLHELD,
1484 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1)));
1485 }
1486
1487 /* Calls Swapped? */
1488 if ((call_setup_state == control_block.call_setup_state) && (num_active && num_held) &&
1489 (num_active == control_block.num_active) && (num_held == control_block.num_held)) {
1490 log::verbose("Calls swapped");
1491 send_indicator_update(control_block, BTA_AG_IND_CALLHELD, 1);
1492 }
1493
1494 /* When call is hung up and still there is another call is in active,
1495 * some of the HF cannot acquire the call states by its own. If HF try
1496 * to terminate a call, it may not send the command AT+CHUP because the
1497 * call states are not updated properly. HF should get informed the call
1498 * status forcibly.
1499 */
1500 if ((control_block.num_active == num_active && num_active != 0) &&
1501 (control_block.num_held != num_held && num_held == 0)) {
1502 tBTA_AG_RES_DATA ag_res = {};
1503 ag_res.ind.id = BTA_AG_IND_CALL;
1504 ag_res.ind.value = num_active;
1505 BTA_AgResult(control_block.handle, BTA_AG_IND_RES_ON_DEMAND, ag_res);
1506 }
1507
1508 UpdateCallStates(&btif_hf_cb[idx], num_active, num_held, call_setup_state);
1509
1510 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(btif_hf_cb[idx].connected_bda,
1511 IOT_CONF_KEY_HFP_SCO_CONN_COUNT);
1512
1513 return status;
1514 }
1515
EnableSwb(bthf_swb_codec_t,bool enable,RawAddress * bd_addr)1516 bt_status_t HeadsetInterface::EnableSwb(bthf_swb_codec_t /*swb_codec*/, bool enable,
1517 RawAddress* bd_addr) {
1518 return enable_aptx_swb_codec(enable, bd_addr);
1519 }
1520
Cleanup()1521 void HeadsetInterface::Cleanup() {
1522 log::verbose("");
1523
1524 btif_queue_cleanup(UUID_SERVCLASS_AG_HANDSFREE);
1525
1526 tBTA_SERVICE_MASK mask = btif_get_enabled_services_mask();
1527 if (get_BTIF_HF_SERVICES() & BTA_HFP_SERVICE_MASK) {
1528 if ((mask & (1 << BTA_HFP_SERVICE_ID)) != 0) {
1529 btif_disable_service(BTA_HFP_SERVICE_ID);
1530 }
1531 } else {
1532 if ((mask & (1 << BTA_HSP_SERVICE_ID)) != 0) {
1533 btif_disable_service(BTA_HSP_SERVICE_ID);
1534 }
1535 }
1536
1537 do_in_jni_thread(base::BindOnce([]() { bt_hf_callbacks = nullptr; }));
1538 }
1539
SetScoOffloadEnabled(bool value)1540 bt_status_t HeadsetInterface::SetScoOffloadEnabled(bool value) {
1541 CHECK_BTHF_INIT();
1542 BTA_AgSetScoOffloadEnabled(value);
1543 return BT_STATUS_SUCCESS;
1544 }
1545
SetScoAllowed(bool value)1546 bt_status_t HeadsetInterface::SetScoAllowed(bool value) {
1547 CHECK_BTHF_INIT();
1548 BTA_AgSetScoAllowed(value);
1549 return BT_STATUS_SUCCESS;
1550 }
1551
SendBsir(bool value,RawAddress * bd_addr)1552 bt_status_t HeadsetInterface::SendBsir(bool value, RawAddress* bd_addr) {
1553 CHECK_BTHF_INIT();
1554 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1555 if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) {
1556 log::error("Invalid index {} for {}", idx, *bd_addr);
1557 return BT_STATUS_PARM_INVALID;
1558 }
1559 if (!is_connected(bd_addr)) {
1560 log::error("{} not connected", *bd_addr);
1561 return BT_STATUS_DEVICE_NOT_FOUND;
1562 }
1563 tBTA_AG_RES_DATA ag_result = {};
1564 ag_result.state = value;
1565 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_INBAND_RING_RES, ag_result);
1566 return BT_STATUS_SUCCESS;
1567 }
1568
SetActiveDevice(RawAddress * active_device_addr)1569 bt_status_t HeadsetInterface::SetActiveDevice(RawAddress* active_device_addr) {
1570 CHECK_BTHF_INIT();
1571 active_bda = *active_device_addr;
1572 BTA_AgSetActiveDevice(*active_device_addr);
1573 return BT_STATUS_SUCCESS;
1574 }
1575
DebugDump()1576 bt_status_t HeadsetInterface::DebugDump() {
1577 CHECK_BTHF_INIT();
1578 tBTM_SCO_DEBUG_DUMP debug_dump = get_btm_client_interface().sco.BTM_GetScoDebugDump();
1579 bt_hf_callbacks->DebugDumpCallback(
1580 debug_dump.is_active, debug_dump.codec_id, debug_dump.total_num_decoded_frames,
1581 debug_dump.pkt_loss_ratio, debug_dump.latest_data.begin_ts_raw_us,
1582 debug_dump.latest_data.end_ts_raw_us, debug_dump.latest_data.status_in_hex.c_str(),
1583 debug_dump.latest_data.status_in_binary.c_str());
1584 return BT_STATUS_SUCCESS;
1585 }
1586
1587 /*******************************************************************************
1588 *
1589 * Function btif_hf_execute_service
1590 *
1591 * Description Initializes/Shuts down the service
1592 *
1593 * Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1594 *
1595 ******************************************************************************/
ExecuteService(bool b_enable)1596 bt_status_t ExecuteService(bool b_enable) {
1597 log::info("service starts to: {}", b_enable ? "Initialize" : "Shutdown");
1598 const char* service_names_raw[] = BTIF_HF_SERVICE_NAMES;
1599 std::vector<std::string> service_names;
1600 for (const char* service_name_raw : service_names_raw) {
1601 if (service_name_raw) {
1602 service_names.emplace_back(service_name_raw);
1603 }
1604 }
1605 if (b_enable) {
1606 /* Enable and register with BTA-AG */
1607 BTA_AgEnable(bte_hf_evt);
1608 for (uint8_t app_id = 0; app_id < btif_max_hf_clients; app_id++) {
1609 BTA_AgRegister(get_BTIF_HF_SERVICES(), btif_hf_features, service_names, app_id);
1610 }
1611 } else {
1612 /* De-register AG */
1613 for (int i = 0; i < btif_max_hf_clients; i++) {
1614 BTA_AgDeregister(btif_hf_cb[i].handle);
1615 }
1616 /* Disable AG */
1617 BTA_AgDisable();
1618 }
1619 return BT_STATUS_SUCCESS;
1620 }
1621
1622 /*******************************************************************************
1623 *
1624 * Function btif_hf_get_interface
1625 *
1626 * Description Get the hf callback interface
1627 *
1628 * Returns bthf_interface_t
1629 *
1630 ******************************************************************************/
GetInterface()1631 Interface* GetInterface() {
1632 log::verbose("");
1633 return HeadsetInterface::GetInstance();
1634 }
1635
1636 } // namespace bluetooth::headset
1637