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