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