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