1 /******************************************************************************
2 *
3 * Copyright (C) 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 <stdlib.h>
31 #include <string.h>
32 #include <time.h>
33
34 #include <hardware/bluetooth.h>
35 #include <hardware/bt_hf.h>
36
37 #include "bta/include/utl.h"
38 #include "bta_ag_api.h"
39 #include "btcore/include/bdaddr.h"
40 #include "btif_common.h"
41 #include "btif_hf.h"
42 #include "btif_profile_queue.h"
43 #include "btif_util.h"
44 #include "osi/include/properties.h"
45
46 /*******************************************************************************
47 * Constants & Macros
48 ******************************************************************************/
49 #ifndef BTIF_HSAG_SERVICE_NAME
50 #define BTIF_HSAG_SERVICE_NAME ("Headset Gateway")
51 #endif
52
53 #ifndef BTIF_HFAG_SERVICE_NAME
54 #define BTIF_HFAG_SERVICE_NAME ("Handsfree Gateway")
55 #endif
56
57 #ifndef BTIF_HF_SERVICES
58 #define BTIF_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK)
59 #endif
60
61 #ifndef BTIF_HF_SERVICE_NAMES
62 #define BTIF_HF_SERVICE_NAMES \
63 { BTIF_HSAG_SERVICE_NAME, BTIF_HFAG_SERVICE_NAME }
64 #endif
65
66 #ifndef BTIF_HF_SECURITY
67 #define BTIF_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
68 #endif
69
70 #ifndef BTIF_HF_FEATURES
71 #define BTIF_HF_FEATURES \
72 (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | BTA_AG_FEAT_REJECT | \
73 BTA_AG_FEAT_ECS | BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_VREC | \
74 BTA_AG_FEAT_CODEC | BTA_AG_FEAT_HF_IND | BTA_AG_FEAT_ESCO | \
75 BTA_AG_FEAT_UNAT)
76 #endif
77
78 /* HF features supported at runtime */
79 static uint32_t btif_hf_features = BTIF_HF_FEATURES;
80
81 #define BTIF_HF_CALL_END_TIMEOUT 6
82
83 #define BTIF_HF_INVALID_IDX (-1)
84
85 /* Number of BTIF-HF control blocks */
86 #define BTIF_HF_NUM_CB 2
87
88 /* Max HF clients supported from App */
89 uint16_t btif_max_hf_clients = 1;
90
91 /* HF app ids for service registration */
92 typedef enum {
93 BTIF_HF_ID_1 = 0,
94 BTIF_HF_ID_2,
95 #if (BTIF_HF_NUM_CB == 3)
96 BTIF_HF_ID_3
97 #endif
98 } bthf_hf_id_t;
99
100 uint16_t bthf_hf_id[BTIF_HF_NUM_CB] = {BTIF_HF_ID_1, BTIF_HF_ID_2,
101 #if (BTIF_HF_NUM_CB == 3)
102 BTIF_HF_ID_3
103 #endif
104 };
105
106 /*******************************************************************************
107 * Local type definitions
108 ******************************************************************************/
109
110 /*******************************************************************************
111 * Static variables
112 ******************************************************************************/
113 static bthf_callbacks_t* bt_hf_callbacks = NULL;
114 static int hf_idx = BTIF_HF_INVALID_IDX;
115
116 #define CHECK_BTHF_INIT() \
117 do { \
118 if (bt_hf_callbacks == NULL) { \
119 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __func__); \
120 return BT_STATUS_NOT_READY; \
121 } else { \
122 BTIF_TRACE_EVENT("BTHF: %s", __func__); \
123 } \
124 } while (0)
125
126 /* BTIF-HF control block to map bdaddr to BTA handle */
127 typedef struct _btif_hf_cb {
128 uint16_t handle;
129 bt_bdaddr_t connected_bda;
130 bthf_connection_state_t state;
131 bthf_vr_state_t vr_state;
132 tBTA_AG_PEER_FEAT peer_feat;
133 int num_active;
134 int num_held;
135 struct timespec call_end_timestamp;
136 struct timespec connected_timestamp;
137 bthf_call_state_t call_setup_state;
138 } btif_hf_cb_t;
139
140 static btif_hf_cb_t btif_hf_cb[BTIF_HF_NUM_CB];
141
142 /*******************************************************************************
143 * Static functions
144 ******************************************************************************/
145
146 /*******************************************************************************
147 * Externs
148 ******************************************************************************/
149 /* By default, even though codec negotiation is enabled, we will not use WBS as
150 * the default
151 * codec unless this variable is set to true.
152 */
153 #ifndef BTIF_HF_WBS_PREFERRED
154 #define BTIF_HF_WBS_PREFERRED false
155 #endif
156
157 bool btif_conf_hf_force_wbs = BTIF_HF_WBS_PREFERRED;
158
159 /*******************************************************************************
160 * Functions
161 ******************************************************************************/
162
163 /*******************************************************************************
164 *
165 * Function is_connected
166 *
167 * Description Internal function to check if HF is connected
168 *
169 * Returns true if connected
170 *
171 ******************************************************************************/
is_connected(bt_bdaddr_t * bd_addr)172 static bool is_connected(bt_bdaddr_t* bd_addr) {
173 int i;
174 for (i = 0; i < btif_max_hf_clients; ++i) {
175 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
176 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)) &&
177 ((bd_addr == NULL) ||
178 (bdcmp(bd_addr->address, btif_hf_cb[i].connected_bda.address) == 0)))
179 return true;
180 }
181 return false;
182 }
183
184 /*******************************************************************************
185 *
186 * Function btif_hf_idx_by_bdaddr
187 *
188 * Description Internal function to get idx by bdaddr
189 *
190 * Returns idx
191 *
192 ******************************************************************************/
btif_hf_idx_by_bdaddr(bt_bdaddr_t * bd_addr)193 static int btif_hf_idx_by_bdaddr(bt_bdaddr_t* bd_addr) {
194 int i;
195 for (i = 0; i < btif_max_hf_clients; ++i) {
196 if ((bdcmp(bd_addr->address, btif_hf_cb[i].connected_bda.address) == 0))
197 return i;
198 }
199 return BTIF_HF_INVALID_IDX;
200 }
201
202 /*******************************************************************************
203 *
204 * Function callstate_to_callsetup
205 *
206 * Description Converts HAL call state to BTA call setup indicator value
207 *
208 * Returns BTA call indicator value
209 *
210 ******************************************************************************/
callstate_to_callsetup(bthf_call_state_t call_state)211 static uint8_t callstate_to_callsetup(bthf_call_state_t call_state) {
212 uint8_t call_setup = 0;
213 if (call_state == BTHF_CALL_STATE_INCOMING) call_setup = 1;
214 if (call_state == BTHF_CALL_STATE_DIALING) call_setup = 2;
215 if (call_state == BTHF_CALL_STATE_ALERTING) call_setup = 3;
216
217 return call_setup;
218 }
219
220 /*******************************************************************************
221 *
222 * Function send_at_result
223 *
224 * Description Send AT result code (OK/ERROR)
225 *
226 * Returns void
227 *
228 ******************************************************************************/
send_at_result(uint8_t ok_flag,uint16_t errcode,int idx)229 static void send_at_result(uint8_t ok_flag, uint16_t errcode, int idx) {
230 tBTA_AG_RES_DATA ag_res;
231 memset(&ag_res, 0, sizeof(ag_res));
232
233 ag_res.ok_flag = ok_flag;
234 if (ok_flag == BTA_AG_OK_ERROR) {
235 ag_res.errcode = errcode;
236 }
237
238 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res);
239 }
240
241 /*******************************************************************************
242 *
243 * Function send_indicator_update
244 *
245 * Description Send indicator update (CIEV)
246 *
247 * Returns void
248 *
249 ******************************************************************************/
send_indicator_update(uint16_t indicator,uint16_t value)250 static void send_indicator_update(uint16_t indicator, uint16_t value) {
251 tBTA_AG_RES_DATA ag_res;
252
253 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
254 ag_res.ind.id = indicator;
255 ag_res.ind.value = value;
256
257 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res);
258 }
259
clear_phone_state_multihf(int idx)260 void clear_phone_state_multihf(int idx) {
261 btif_hf_cb[idx].call_setup_state = BTHF_CALL_STATE_IDLE;
262 btif_hf_cb[idx].num_active = btif_hf_cb[idx].num_held = 0;
263 }
264
265 /*******************************************************************************
266 *
267 * Function btif_hf_latest_connected_idx
268 *
269 * Description Returns idx for latest connected HF
270 *
271 * Returns int
272 *
273 ******************************************************************************/
btif_hf_latest_connected_idx()274 static int btif_hf_latest_connected_idx() {
275 struct timespec now, conn_time_delta;
276 int latest_conn_idx = BTIF_HF_INVALID_IDX, i;
277
278 clock_gettime(CLOCK_MONOTONIC, &now);
279 conn_time_delta.tv_sec = now.tv_sec;
280
281 for (i = 0; i < btif_max_hf_clients; i++) {
282 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED) {
283 if ((now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec) <
284 conn_time_delta.tv_sec) {
285 conn_time_delta.tv_sec =
286 now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec;
287 latest_conn_idx = i;
288 }
289 }
290 }
291 return latest_conn_idx;
292 }
293
294 /*******************************************************************************
295 *
296 * Function btif_hf_check_if_slc_connected
297 *
298 * Description Returns BT_STATUS_SUCCESS if SLC is up for any HF
299 *
300 * Returns bt_status_t
301 *
302 ******************************************************************************/
btif_hf_check_if_slc_connected()303 static bt_status_t btif_hf_check_if_slc_connected() {
304 if (bt_hf_callbacks == NULL) {
305 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __func__);
306 return BT_STATUS_NOT_READY;
307 } else {
308 int i;
309 for (i = 0; i < btif_max_hf_clients; i++) {
310 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED) {
311 BTIF_TRACE_EVENT("BTHF: %s: slc connected for idx = %d", __func__, i);
312 return BT_STATUS_SUCCESS;
313 }
314 }
315 BTIF_TRACE_WARNING("BTHF: %s: No SLC connection up", __func__);
316 return BT_STATUS_NOT_READY;
317 }
318 }
319
320 /*****************************************************************************
321 * Section name (Group of functions)
322 ****************************************************************************/
323
324 /*****************************************************************************
325 *
326 * btif hf api functions (no context switch)
327 *
328 ****************************************************************************/
329
330 /*******************************************************************************
331 *
332 * Function btif_hf_upstreams_evt
333 *
334 * Description Executes HF UPSTREAMS events in btif context
335 *
336 * Returns void
337 *
338 ******************************************************************************/
btif_hf_upstreams_evt(uint16_t event,char * p_param)339 static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
340 tBTA_AG* p_data = (tBTA_AG*)p_param;
341 bdstr_t bdstr;
342 int idx = p_data->hdr.handle - 1;
343
344 BTIF_TRACE_DEBUG("%s: event=%s", __func__, dump_hf_event(event));
345
346 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
347 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
348 return;
349 }
350
351 switch (event) {
352 case BTA_AG_ENABLE_EVT:
353 case BTA_AG_DISABLE_EVT:
354 break;
355
356 case BTA_AG_REGISTER_EVT:
357 btif_hf_cb[idx].handle = p_data->reg.hdr.handle;
358 BTIF_TRACE_DEBUG(
359 "%s: BTA_AG_REGISTER_EVT,"
360 "btif_hf_cb.handle = %d",
361 __func__, btif_hf_cb[idx].handle);
362 break;
363
364 case BTA_AG_OPEN_EVT:
365 if (p_data->open.status == BTA_AG_SUCCESS) {
366 bdcpy(btif_hf_cb[idx].connected_bda.address, p_data->open.bd_addr);
367 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_CONNECTED;
368 btif_hf_cb[idx].peer_feat = 0;
369 clear_phone_state_multihf(idx);
370 } else if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_CONNECTING) {
371 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED;
372 } else {
373 BTIF_TRACE_WARNING(
374 "%s: AG open failed, but another device connected. status=%d "
375 "state=%d connected device=%s",
376 __func__, p_data->open.status, btif_hf_cb[idx].state,
377 bdaddr_to_string(&btif_hf_cb[idx].connected_bda, bdstr,
378 sizeof(bdstr)));
379 break;
380 }
381
382 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
383 &btif_hf_cb[idx].connected_bda);
384
385 if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_DISCONNECTED)
386 bdsetany(btif_hf_cb[idx].connected_bda.address);
387
388 if (p_data->open.status != BTA_AG_SUCCESS) btif_queue_advance();
389 break;
390
391 case BTA_AG_CLOSE_EVT:
392 btif_hf_cb[idx].connected_timestamp.tv_sec = 0;
393 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED;
394 BTIF_TRACE_DEBUG(
395 "%s: BTA_AG_CLOSE_EVT,"
396 "idx = %d, btif_hf_cb.handle = %d",
397 __func__, idx, btif_hf_cb[idx].handle);
398 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
399 &btif_hf_cb[idx].connected_bda);
400 bdsetany(btif_hf_cb[idx].connected_bda.address);
401 btif_hf_cb[idx].peer_feat = 0;
402 clear_phone_state_multihf(idx);
403 hf_idx = btif_hf_latest_connected_idx();
404 /* If AG_OPEN was received but SLC was not setup in a specified time (10
405 *seconds),
406 ** then AG_CLOSE may be received. We need to advance the queue here
407 */
408 btif_queue_advance();
409 break;
410
411 case BTA_AG_CONN_EVT:
412 clock_gettime(CLOCK_MONOTONIC, &btif_hf_cb[idx].connected_timestamp);
413 BTIF_TRACE_DEBUG("%s: BTA_AG_CONN_EVT, idx = %d ", __func__, idx);
414 btif_hf_cb[idx].peer_feat = p_data->conn.peer_feat;
415 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_SLC_CONNECTED;
416 hf_idx = btif_hf_latest_connected_idx();
417
418 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
419 &btif_hf_cb[idx].connected_bda);
420 btif_queue_advance();
421 break;
422
423 case BTA_AG_AUDIO_OPEN_EVT:
424 hf_idx = idx;
425 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTED,
426 &btif_hf_cb[idx].connected_bda);
427 break;
428
429 case BTA_AG_AUDIO_CLOSE_EVT:
430 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_DISCONNECTED,
431 &btif_hf_cb[idx].connected_bda);
432 break;
433
434 /* BTA auto-responds, silently discard */
435 case BTA_AG_SPK_EVT:
436 case BTA_AG_MIC_EVT:
437 HAL_CBACK(bt_hf_callbacks, volume_cmd_cb,
438 (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK
439 : BTHF_VOLUME_TYPE_MIC,
440 p_data->val.num, &btif_hf_cb[idx].connected_bda);
441 break;
442
443 case BTA_AG_AT_A_EVT:
444 if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0)
445 hf_idx = idx;
446 else
447 BTIF_TRACE_DEBUG("Donot set hf_idx for ATA since already in a call");
448
449 HAL_CBACK(bt_hf_callbacks, answer_call_cmd_cb,
450 &btif_hf_cb[idx].connected_bda);
451 break;
452
453 /* Java needs to send OK/ERROR for these commands */
454 case BTA_AG_AT_BLDN_EVT:
455 case BTA_AG_AT_D_EVT:
456 if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0)
457 hf_idx = idx;
458 else
459 BTIF_TRACE_DEBUG("Donot set hf_idx for BLDN/D since already in a call");
460
461 HAL_CBACK(bt_hf_callbacks, dial_call_cmd_cb,
462 (event == BTA_AG_AT_D_EVT) ? p_data->val.str : NULL,
463 &btif_hf_cb[idx].connected_bda);
464 break;
465
466 case BTA_AG_AT_CHUP_EVT:
467 HAL_CBACK(bt_hf_callbacks, hangup_call_cmd_cb,
468 &btif_hf_cb[idx].connected_bda);
469 break;
470
471 case BTA_AG_AT_CIND_EVT:
472 HAL_CBACK(bt_hf_callbacks, cind_cmd_cb, &btif_hf_cb[idx].connected_bda);
473 break;
474
475 case BTA_AG_AT_VTS_EVT:
476 HAL_CBACK(bt_hf_callbacks, dtmf_cmd_cb, p_data->val.str[0],
477 &btif_hf_cb[idx].connected_bda);
478 break;
479
480 case BTA_AG_AT_BVRA_EVT:
481 HAL_CBACK(bt_hf_callbacks, vr_cmd_cb,
482 (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED
483 : BTHF_VR_STATE_STOPPED,
484 &btif_hf_cb[idx].connected_bda);
485 break;
486
487 case BTA_AG_AT_NREC_EVT:
488 HAL_CBACK(bt_hf_callbacks, nrec_cmd_cb,
489 (p_data->val.num == 1) ? BTHF_NREC_START : BTHF_NREC_STOP,
490 &btif_hf_cb[idx].connected_bda);
491 break;
492
493 /* TODO: Add a callback for CBC */
494 case BTA_AG_AT_CBC_EVT:
495 break;
496
497 case BTA_AG_AT_CKPD_EVT:
498 HAL_CBACK(bt_hf_callbacks, key_pressed_cmd_cb,
499 &btif_hf_cb[idx].connected_bda);
500 break;
501
502 case BTA_AG_WBS_EVT:
503 BTIF_TRACE_DEBUG(
504 "BTA_AG_WBS_EVT Set codec status %d codec %d 1=CVSD 2=MSBC",
505 p_data->val.hdr.status, p_data->val.num);
506 if (p_data->val.num == BTA_AG_CODEC_CVSD) {
507 HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NO,
508 &btif_hf_cb[idx].connected_bda);
509 } else if (p_data->val.num == BTA_AG_CODEC_MSBC) {
510 HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_YES,
511 &btif_hf_cb[idx].connected_bda);
512 } else {
513 HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NONE,
514 &btif_hf_cb[idx].connected_bda);
515 }
516 break;
517
518 /* Java needs to send OK/ERROR for these commands */
519 case BTA_AG_AT_CHLD_EVT:
520 HAL_CBACK(bt_hf_callbacks, chld_cmd_cb,
521 (bthf_chld_type_t)atoi(p_data->val.str),
522 &btif_hf_cb[idx].connected_bda);
523 break;
524
525 case BTA_AG_AT_CLCC_EVT:
526 HAL_CBACK(bt_hf_callbacks, clcc_cmd_cb, &btif_hf_cb[idx].connected_bda);
527 break;
528
529 case BTA_AG_AT_COPS_EVT:
530 HAL_CBACK(bt_hf_callbacks, cops_cmd_cb, &btif_hf_cb[idx].connected_bda);
531 break;
532
533 case BTA_AG_AT_UNAT_EVT:
534 HAL_CBACK(bt_hf_callbacks, unknown_at_cmd_cb, p_data->val.str,
535 &btif_hf_cb[idx].connected_bda);
536 break;
537
538 case BTA_AG_AT_CNUM_EVT:
539 HAL_CBACK(bt_hf_callbacks, cnum_cmd_cb, &btif_hf_cb[idx].connected_bda);
540 break;
541
542 /* TODO: Some of these commands may need to be sent to app. For now respond
543 * with error */
544 case BTA_AG_AT_BINP_EVT:
545 case BTA_AG_AT_BTRH_EVT:
546 send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED, idx);
547 break;
548 case BTA_AG_AT_BAC_EVT:
549 BTIF_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num);
550 /* If the peer supports mSBC and the BTIF preferred codec is also mSBC,
551 then
552 we should set the BTA AG Codec to mSBC. This would trigger a +BCS to mSBC
553 at the time
554 of SCO connection establishment */
555 if ((btif_conf_hf_force_wbs == true) &&
556 (p_data->val.num & BTA_AG_CODEC_MSBC)) {
557 BTIF_TRACE_EVENT("%s: btif_hf override-Preferred Codec to MSBC",
558 __func__);
559 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_MSBC);
560 } else {
561 BTIF_TRACE_EVENT("%s btif_hf override-Preferred Codec to CVSD",
562 __func__);
563 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_CVSD);
564 }
565 break;
566 case BTA_AG_AT_BCS_EVT:
567 BTIF_TRACE_DEBUG("%s: AG final selected codec is 0x%02x 1=CVSD 2=MSBC",
568 __func__, p_data->val.num);
569 /* No BTHF_WBS_NONE case, because HF1.6 supported device can send BCS */
570 /* Only CVSD is considered narrow band speech */
571 HAL_CBACK(
572 bt_hf_callbacks, wbs_cb,
573 (p_data->val.num == BTA_AG_CODEC_CVSD) ? BTHF_WBS_NO : BTHF_WBS_YES,
574 &btif_hf_cb[idx].connected_bda);
575 break;
576
577 case BTA_AG_AT_BIND_EVT:
578 if (p_data->val.hdr.status == BTA_AG_SUCCESS) {
579 HAL_CBACK(bt_hf_callbacks, bind_cb, p_data->val.str,
580 &btif_hf_cb[idx].connected_bda);
581 }
582 break;
583
584 case BTA_AG_AT_BIEV_EVT:
585 if (p_data->val.hdr.status == BTA_AG_SUCCESS) {
586 HAL_CBACK(bt_hf_callbacks, biev_cb,
587 (bthf_hf_ind_type_t)p_data->val.lidx, (int)p_data->val.num,
588 &btif_hf_cb[idx].connected_bda);
589 }
590 break;
591 default:
592 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
593 break;
594 }
595 }
596
597 /*******************************************************************************
598 *
599 * Function bte_hf_evt
600 *
601 * Description Switches context from BTE to BTIF for all HF events
602 *
603 * Returns void
604 *
605 ******************************************************************************/
606
bte_hf_evt(tBTA_AG_EVT event,tBTA_AG * p_data)607 static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG* p_data) {
608 bt_status_t status;
609 int param_len = 0;
610
611 /* TODO: BTA sends the union members and not tBTA_AG. If using
612 * param_len=sizeof(tBTA_AG), we get a crash on memcpy */
613 if (BTA_AG_REGISTER_EVT == event)
614 param_len = sizeof(tBTA_AG_REGISTER);
615 else if (BTA_AG_OPEN_EVT == event)
616 param_len = sizeof(tBTA_AG_OPEN);
617 else if (BTA_AG_CONN_EVT == event)
618 param_len = sizeof(tBTA_AG_CONN);
619 else if ((BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) ||
620 (BTA_AG_AUDIO_CLOSE_EVT == event))
621 param_len = sizeof(tBTA_AG_HDR);
622 else if (p_data)
623 param_len = sizeof(tBTA_AG_VAL);
624
625 /* switch context to btif task context (copy full union size for convenience)
626 */
627 status = btif_transfer_context(btif_hf_upstreams_evt, (uint16_t)event,
628 (char*)p_data, param_len, NULL);
629
630 /* catch any failed context transfers */
631 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
632 }
633
634 /*******************************************************************************
635 *
636 * Function btif_in_hf_generic_evt
637 *
638 * Description Processes generic events to be sent to JNI that are not
639 * triggered from the BTA.
640 * Always runs in BTIF context
641 *
642 * Returns void
643 *
644 ******************************************************************************/
btif_in_hf_generic_evt(uint16_t event,char * p_param)645 static void btif_in_hf_generic_evt(uint16_t event, char* p_param) {
646 int idx = btif_hf_idx_by_bdaddr((bt_bdaddr_t*)p_param);
647
648 BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
649
650 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
651 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
652 return;
653 }
654
655 switch (event) {
656 case BTIF_HFP_CB_AUDIO_CONNECTING: {
657 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTING,
658 &btif_hf_cb[idx].connected_bda);
659 } break;
660 default: {
661 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __func__, event);
662 } break;
663 }
664 }
665
inband_ringing_property_enabled()666 static bool inband_ringing_property_enabled() {
667 char inband_ringing_flag[PROPERTY_VALUE_MAX] = {0};
668 osi_property_get("persist.bluetooth.enableinbandringing", inband_ringing_flag,
669 "false");
670 if (strncmp(inband_ringing_flag, "true", 4) == 0) {
671 BTIF_TRACE_DEBUG("%s: In-band ringing enabled by property", __func__);
672 return true;
673 }
674 return false;
675 }
676
677 /*******************************************************************************
678 *
679 * Function btif_hf_init
680 *
681 * Description initializes the hf interface
682 *
683 * Returns bt_status_t
684 *
685 ******************************************************************************/
init(bthf_callbacks_t * callbacks,int max_hf_clients,bool inband_ringing_supported)686 static bt_status_t init(bthf_callbacks_t* callbacks, int max_hf_clients,
687 bool inband_ringing_supported) {
688 bool inband_ringing_property_enable = inband_ringing_property_enabled();
689 if (inband_ringing_supported && inband_ringing_property_enable) {
690 btif_hf_features |= BTA_AG_FEAT_INBAND;
691 } else {
692 btif_hf_features &= ~BTA_AG_FEAT_INBAND;
693 }
694 btif_max_hf_clients = max_hf_clients;
695 BTIF_TRACE_DEBUG(
696 "%s: btif_hf_features=%zu, max_hf_clients=%d, "
697 "inband_ringing=[supported=%d, enabled=%d]",
698 __func__, btif_hf_features, btif_max_hf_clients, inband_ringing_supported,
699 inband_ringing_property_enable);
700 bt_hf_callbacks = callbacks;
701 memset(&btif_hf_cb, 0, sizeof(btif_hf_cb));
702
703 /* Invoke the enable service API to the core to set the appropriate service_id
704 * Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled
705 * (phone)
706 * othwerwise only HSP is enabled (tablet)
707 */
708 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
709 btif_enable_service(BTA_HFP_SERVICE_ID);
710 #else
711 btif_enable_service(BTA_HSP_SERVICE_ID);
712 #endif
713
714 for (int i = 0; i < btif_max_hf_clients; i++) clear_phone_state_multihf(i);
715
716 return BT_STATUS_SUCCESS;
717 }
718
719 /*******************************************************************************
720 *
721 * Function connect
722 *
723 * Description connect to headset
724 *
725 * Returns bt_status_t
726 *
727 ******************************************************************************/
connect_int(bt_bdaddr_t * bd_addr,uint16_t uuid)728 static bt_status_t connect_int(bt_bdaddr_t* bd_addr, uint16_t uuid) {
729 CHECK_BTHF_INIT();
730 int i;
731 for (i = 0; i < btif_max_hf_clients;) {
732 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
733 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)))
734 i++;
735 else
736 break;
737 }
738
739 if (i == btif_max_hf_clients) return BT_STATUS_BUSY;
740
741 if (!is_connected(bd_addr)) {
742 btif_hf_cb[i].state = BTHF_CONNECTION_STATE_CONNECTING;
743 bdcpy(btif_hf_cb[i].connected_bda.address, bd_addr->address);
744
745 BTA_AgOpen(btif_hf_cb[i].handle, btif_hf_cb[i].connected_bda.address,
746 BTIF_HF_SECURITY, BTIF_HF_SERVICES);
747 return BT_STATUS_SUCCESS;
748 }
749
750 return BT_STATUS_BUSY;
751 }
752
connect(bt_bdaddr_t * bd_addr)753 static bt_status_t connect(bt_bdaddr_t* bd_addr) {
754 CHECK_BTHF_INIT();
755 return btif_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_int);
756 }
757
758 /*******************************************************************************
759 *
760 * Function disconnect
761 *
762 * Description disconnect from headset
763 *
764 * Returns bt_status_t
765 *
766 ******************************************************************************/
disconnect(bt_bdaddr_t * bd_addr)767 static bt_status_t disconnect(bt_bdaddr_t* bd_addr) {
768 CHECK_BTHF_INIT();
769
770 int idx = btif_hf_idx_by_bdaddr(bd_addr);
771
772 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
773 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
774 return BT_STATUS_FAIL;
775 }
776
777 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
778 BTA_AgClose(btif_hf_cb[idx].handle);
779 return BT_STATUS_SUCCESS;
780 }
781
782 return BT_STATUS_FAIL;
783 }
784
785 /*******************************************************************************
786 *
787 * Function connect_audio
788 *
789 * Description create an audio connection
790 *
791 * Returns bt_status_t
792 *
793 ******************************************************************************/
connect_audio(bt_bdaddr_t * bd_addr)794 static bt_status_t connect_audio(bt_bdaddr_t* bd_addr) {
795 CHECK_BTHF_INIT();
796
797 int idx = btif_hf_idx_by_bdaddr(bd_addr);
798
799 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
800 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
801 return BT_STATUS_FAIL;
802 }
803
804 /* Check if SLC is connected */
805 if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS)
806 return BT_STATUS_NOT_READY;
807
808 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
809 BTA_AgAudioOpen(btif_hf_cb[idx].handle);
810
811 /* Inform the application that the audio connection has been initiated
812 * successfully */
813 btif_transfer_context(btif_in_hf_generic_evt, BTIF_HFP_CB_AUDIO_CONNECTING,
814 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
815 return BT_STATUS_SUCCESS;
816 }
817
818 return BT_STATUS_FAIL;
819 }
820
821 /*******************************************************************************
822 *
823 * Function disconnect_audio
824 *
825 * Description close the audio connection
826 *
827 * Returns bt_status_t
828 *
829 ******************************************************************************/
disconnect_audio(bt_bdaddr_t * bd_addr)830 static bt_status_t disconnect_audio(bt_bdaddr_t* bd_addr) {
831 CHECK_BTHF_INIT();
832
833 int idx = btif_hf_idx_by_bdaddr(bd_addr);
834
835 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
836 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
837 return BT_STATUS_FAIL;
838 }
839
840 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
841 BTA_AgAudioClose(btif_hf_cb[idx].handle);
842 return BT_STATUS_SUCCESS;
843 }
844
845 return BT_STATUS_FAIL;
846 }
847
848 /*******************************************************************************
849 *
850 * Function start_voice_recognition
851 *
852 * Description start voice recognition
853 *
854 * Returns bt_status_t
855 *
856 ******************************************************************************/
start_voice_recognition(bt_bdaddr_t * bd_addr)857 static bt_status_t start_voice_recognition(bt_bdaddr_t* bd_addr) {
858 CHECK_BTHF_INIT();
859
860 int idx = btif_hf_idx_by_bdaddr(bd_addr);
861
862 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
863 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
864 return BT_STATUS_FAIL;
865 }
866
867 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
868 if (btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC) {
869 tBTA_AG_RES_DATA ag_res;
870 memset(&ag_res, 0, sizeof(ag_res));
871 ag_res.state = 1;
872 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, &ag_res);
873
874 return BT_STATUS_SUCCESS;
875 } else {
876 return BT_STATUS_UNSUPPORTED;
877 }
878 }
879
880 return BT_STATUS_NOT_READY;
881 }
882
883 /*******************************************************************************
884 *
885 * Function stop_voice_recognition
886 *
887 * Description stop voice recognition
888 *
889 * Returns bt_status_t
890 *
891 ******************************************************************************/
stop_voice_recognition(bt_bdaddr_t * bd_addr)892 static bt_status_t stop_voice_recognition(bt_bdaddr_t* bd_addr) {
893 CHECK_BTHF_INIT();
894
895 int idx = btif_hf_idx_by_bdaddr(bd_addr);
896
897 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
898 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
899 return BT_STATUS_FAIL;
900 }
901
902 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
903 if (btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC) {
904 tBTA_AG_RES_DATA ag_res;
905 memset(&ag_res, 0, sizeof(ag_res));
906 ag_res.state = 0;
907 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, &ag_res);
908
909 return BT_STATUS_SUCCESS;
910 } else {
911 return BT_STATUS_UNSUPPORTED;
912 }
913 }
914
915 return BT_STATUS_NOT_READY;
916 }
917
918 /*******************************************************************************
919 *
920 * Function volume_control
921 *
922 * Description volume control
923 *
924 * Returns bt_status_t
925 *
926 ******************************************************************************/
volume_control(bthf_volume_type_t type,int volume,bt_bdaddr_t * bd_addr)927 static bt_status_t volume_control(bthf_volume_type_t type, int volume,
928 bt_bdaddr_t* bd_addr) {
929 CHECK_BTHF_INIT();
930
931 int idx = btif_hf_idx_by_bdaddr(bd_addr);
932
933 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
934 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
935 return BT_STATUS_FAIL;
936 }
937
938 tBTA_AG_RES_DATA ag_res;
939 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
940 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
941 ag_res.num = volume;
942 BTA_AgResult(
943 btif_hf_cb[idx].handle,
944 (type == BTHF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES,
945 &ag_res);
946 return BT_STATUS_SUCCESS;
947 }
948
949 return BT_STATUS_FAIL;
950 }
951
952 /*******************************************************************************
953 *
954 * Function device_status_notification
955 *
956 * Description Combined device status change notification
957 *
958 * Returns bt_status_t
959 *
960 ******************************************************************************/
device_status_notification(bthf_network_state_t ntk_state,bthf_service_type_t svc_type,int signal,int batt_chg)961 static bt_status_t device_status_notification(bthf_network_state_t ntk_state,
962 bthf_service_type_t svc_type,
963 int signal, int batt_chg) {
964 CHECK_BTHF_INIT();
965
966 if (is_connected(NULL)) {
967 /* send all indicators to BTA.
968 ** BTA will make sure no duplicates are sent out
969 */
970 send_indicator_update(BTA_AG_IND_SERVICE,
971 (ntk_state == BTHF_NETWORK_STATE_AVAILABLE) ? 1 : 0);
972 send_indicator_update(BTA_AG_IND_ROAM,
973 (svc_type == BTHF_SERVICE_TYPE_HOME) ? 0 : 1);
974 send_indicator_update(BTA_AG_IND_SIGNAL, signal);
975 send_indicator_update(BTA_AG_IND_BATTCHG, batt_chg);
976 return BT_STATUS_SUCCESS;
977 }
978
979 return BT_STATUS_SUCCESS;
980 }
981
982 /*******************************************************************************
983 *
984 * Function cops_response
985 *
986 * Description Response for COPS command
987 *
988 * Returns bt_status_t
989 *
990 ******************************************************************************/
cops_response(const char * cops,bt_bdaddr_t * bd_addr)991 static bt_status_t cops_response(const char* cops, bt_bdaddr_t* bd_addr) {
992 CHECK_BTHF_INIT();
993
994 int idx = btif_hf_idx_by_bdaddr(bd_addr);
995
996 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
997 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
998 return BT_STATUS_FAIL;
999 }
1000
1001 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
1002 tBTA_AG_RES_DATA ag_res;
1003
1004 /* Format the response */
1005 snprintf(ag_res.str, sizeof(ag_res.str), "0,0,\"%.16s\"", cops);
1006 ag_res.ok_flag = BTA_AG_OK_DONE;
1007
1008 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_COPS_RES, &ag_res);
1009 return BT_STATUS_SUCCESS;
1010 }
1011 return BT_STATUS_FAIL;
1012 }
1013
1014 /*******************************************************************************
1015 *
1016 * Function cind_response
1017 *
1018 * Description Response for CIND command
1019 *
1020 * Returns bt_status_t
1021 *
1022 ******************************************************************************/
cind_response(int svc,int num_active,int num_held,bthf_call_state_t call_setup_state,int signal,int roam,int batt_chg,bt_bdaddr_t * bd_addr)1023 static bt_status_t cind_response(int svc, int num_active, int num_held,
1024 bthf_call_state_t call_setup_state, int signal,
1025 int roam, int batt_chg, bt_bdaddr_t* bd_addr) {
1026 CHECK_BTHF_INIT();
1027
1028 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1029
1030 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
1031 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
1032 return BT_STATUS_FAIL;
1033 }
1034
1035 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
1036 tBTA_AG_RES_DATA ag_res;
1037
1038 memset(&ag_res, 0, sizeof(ag_res));
1039 /* per the errata 2043, call=1 implies atleast one call is in progress
1040 *(active/held)
1041 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1042 **/
1043 snprintf(
1044 ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d,%d,%d",
1045 (num_active + num_held) ? 1 : 0, /* Call state */
1046 callstate_to_callsetup(call_setup_state), /* Callsetup state */
1047 svc, /* network service */
1048 signal, /* Signal strength */
1049 roam, /* Roaming indicator */
1050 batt_chg, /* Battery level */
1051 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1))); /* Call held */
1052
1053 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CIND_RES, &ag_res);
1054
1055 return BT_STATUS_SUCCESS;
1056 }
1057
1058 return BT_STATUS_FAIL;
1059 }
1060
1061 /*******************************************************************************
1062 *
1063 * Function bind_response
1064 *
1065 * Description Send +BIND response
1066 *
1067 * Returns bt_status_t
1068 *
1069 ******************************************************************************/
bind_response(bthf_hf_ind_type_t ind_id,bthf_hf_ind_status_t ind_status,bt_bdaddr_t * bd_addr)1070 static bt_status_t bind_response(bthf_hf_ind_type_t ind_id,
1071 bthf_hf_ind_status_t ind_status,
1072 bt_bdaddr_t* bd_addr) {
1073 CHECK_BTHF_INIT();
1074
1075 int index = btif_hf_idx_by_bdaddr(bd_addr);
1076 if (!is_connected(bd_addr) || index == BTIF_HF_INVALID_IDX)
1077 return BT_STATUS_FAIL;
1078
1079 tBTA_AG_RES_DATA ag_res;
1080 memset(&ag_res, 0, sizeof(ag_res));
1081 ag_res.ind.id = ind_id;
1082 ag_res.ind.on_demand = (ind_status == BTHF_HF_IND_ENABLED);
1083
1084 BTA_AgResult(btif_hf_cb[index].handle, BTA_AG_BIND_RES, &ag_res);
1085 return BT_STATUS_SUCCESS;
1086 }
1087
1088 /*******************************************************************************
1089 *
1090 * Function formatted_at_response
1091 *
1092 * Description Pre-formatted AT response, typically in response to unknown
1093 * AT cmd
1094 *
1095 * Returns bt_status_t
1096 *
1097 ******************************************************************************/
formatted_at_response(const char * rsp,bt_bdaddr_t * bd_addr)1098 static bt_status_t formatted_at_response(const char* rsp,
1099 bt_bdaddr_t* bd_addr) {
1100 CHECK_BTHF_INIT();
1101 tBTA_AG_RES_DATA ag_res;
1102 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1103
1104 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
1105 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
1106 return BT_STATUS_FAIL;
1107 }
1108
1109 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
1110 /* Format the response and send */
1111 memset(&ag_res, 0, sizeof(ag_res));
1112 strncpy(ag_res.str, rsp, BTA_AG_AT_MAX_LEN);
1113 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res);
1114
1115 return BT_STATUS_SUCCESS;
1116 }
1117
1118 return BT_STATUS_FAIL;
1119 }
1120
1121 /*******************************************************************************
1122 *
1123 * Function at_response
1124 *
1125 * Description ok/error response
1126 *
1127 * Returns bt_status_t
1128 *
1129 ******************************************************************************/
at_response(bthf_at_response_t response_code,int error_code,bt_bdaddr_t * bd_addr)1130 static bt_status_t at_response(bthf_at_response_t response_code, int error_code,
1131 bt_bdaddr_t* bd_addr) {
1132 CHECK_BTHF_INIT();
1133
1134 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1135
1136 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
1137 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
1138 return BT_STATUS_FAIL;
1139 }
1140
1141 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
1142 send_at_result((response_code == BTHF_AT_RESPONSE_OK) ? BTA_AG_OK_DONE
1143 : BTA_AG_OK_ERROR,
1144 error_code, idx);
1145 return BT_STATUS_SUCCESS;
1146 }
1147
1148 return BT_STATUS_FAIL;
1149 }
1150
1151 /*******************************************************************************
1152 *
1153 * Function clcc_response
1154 *
1155 * Description response for CLCC command
1156 * Can be iteratively called for each call index. Call index
1157 * of 0 will be treated as NULL termination (Completes
1158 * response)
1159 *
1160 * Returns bt_status_t
1161 *
1162 ******************************************************************************/
clcc_response(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,bt_bdaddr_t * bd_addr)1163 static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
1164 bthf_call_state_t state, bthf_call_mode_t mode,
1165 bthf_call_mpty_type_t mpty, const char* number,
1166 bthf_call_addrtype_t type,
1167 bt_bdaddr_t* bd_addr) {
1168 CHECK_BTHF_INIT();
1169
1170 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1171
1172 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
1173 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
1174 return BT_STATUS_FAIL;
1175 }
1176
1177 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
1178 tBTA_AG_RES_DATA ag_res;
1179 memset(&ag_res, 0, sizeof(ag_res));
1180
1181 /* Format the response */
1182 if (index == 0) {
1183 ag_res.ok_flag = BTA_AG_OK_DONE;
1184 } else {
1185 BTIF_TRACE_EVENT(
1186 "clcc_response: [%d] dir %d state %d mode %d number = %s type = %d",
1187 index, dir, state, mode, number, type);
1188 int res_strlen =
1189 snprintf(ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d", index, dir,
1190 state, mode, mpty);
1191
1192 if (number) {
1193 size_t rem_bytes = sizeof(ag_res.str) - res_strlen;
1194 char dialnum[sizeof(ag_res.str)];
1195 size_t newidx = 0;
1196 if (type == BTHF_CALL_ADDRTYPE_INTERNATIONAL && *number != '+') {
1197 dialnum[newidx++] = '+';
1198 }
1199 for (size_t i = 0; number[i] != 0; i++) {
1200 if (utl_isdialchar(number[i])) {
1201 dialnum[newidx++] = number[i];
1202 }
1203 }
1204 dialnum[newidx] = 0;
1205 snprintf(&ag_res.str[res_strlen], rem_bytes, ",\"%s\",%d", dialnum,
1206 type);
1207 }
1208 }
1209 BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, &ag_res);
1210
1211 return BT_STATUS_SUCCESS;
1212 }
1213
1214 return BT_STATUS_FAIL;
1215 }
1216
1217 /*******************************************************************************
1218 *
1219 * Function phone_state_change
1220 *
1221 * Description notify of a call state change
1222 * number & type: valid only for incoming & waiting call
1223 *
1224 * Returns bt_status_t
1225 *
1226 ******************************************************************************/
1227
phone_state_change(int num_active,int num_held,bthf_call_state_t call_setup_state,const char * number,bthf_call_addrtype_t type)1228 static bt_status_t phone_state_change(int num_active, int num_held,
1229 bthf_call_state_t call_setup_state,
1230 const char* number,
1231 bthf_call_addrtype_t type) {
1232 tBTA_AG_RES res = 0xff;
1233 tBTA_AG_RES_DATA ag_res;
1234 bt_status_t status = BT_STATUS_SUCCESS;
1235 bool activeCallUpdated = false;
1236 int idx, i;
1237
1238 /* hf_idx is index of connected HS that sent ATA/BLDN,
1239 otherwise index of latest connected HS */
1240 if (hf_idx != BTIF_HF_INVALID_IDX)
1241 idx = hf_idx;
1242 else
1243 idx = btif_hf_latest_connected_idx();
1244
1245 BTIF_TRACE_DEBUG("phone_state_change: idx = %d", idx);
1246
1247 /* Check if SLC is connected */
1248 if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS)
1249 return BT_STATUS_NOT_READY;
1250
1251 BTIF_TRACE_DEBUG(
1252 "phone_state_change: num_active=%d [prev: %d] num_held=%d[prev: %d]"
1253 " call_setup=%s [prev: %s]",
1254 num_active, btif_hf_cb[idx].num_active, num_held,
1255 btif_hf_cb[idx].num_held, dump_hf_call_state(call_setup_state),
1256 dump_hf_call_state(btif_hf_cb[idx].call_setup_state));
1257
1258 /* if all indicators are 0, send end call and return */
1259 if (num_active == 0 && num_held == 0 &&
1260 call_setup_state == BTHF_CALL_STATE_IDLE) {
1261 BTIF_TRACE_DEBUG("%s: Phone on hook", __func__);
1262
1263 /* record call termination timestamp if there was an active/held call or
1264 callsetup state > BTHF_CALL_STATE_IDLE */
1265 if ((btif_hf_cb[idx].call_setup_state != BTHF_CALL_STATE_IDLE) ||
1266 (btif_hf_cb[idx].num_active) || (btif_hf_cb[idx].num_held)) {
1267 BTIF_TRACE_DEBUG("%s: Record call termination timestamp", __func__);
1268 clock_gettime(CLOCK_MONOTONIC, &btif_hf_cb[0].call_end_timestamp);
1269 }
1270 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_END_CALL_RES, NULL);
1271 hf_idx = BTIF_HF_INVALID_IDX;
1272
1273 /* if held call was present, reset that as well */
1274 if (btif_hf_cb[idx].num_held) send_indicator_update(BTA_AG_IND_CALLHELD, 0);
1275
1276 goto update_call_states;
1277 }
1278
1279 /* active state can change when:
1280 ** 1. an outgoing/incoming call was answered
1281 ** 2. an held was resumed
1282 ** 3. without callsetup notifications, call became active
1283 ** (3) can happen if call is active and a headset connects to us
1284 **
1285 ** In the case of (3), we will have to notify the stack of an active
1286 ** call, instead of sending an indicator update. This will also
1287 ** force the SCO to be setup. Handle this special case here prior to
1288 ** call setup handling
1289 */
1290 if (((num_active + num_held) > 0) && (btif_hf_cb[idx].num_active == 0) &&
1291 (btif_hf_cb[idx].num_held == 0) &&
1292 (btif_hf_cb[idx].call_setup_state == BTHF_CALL_STATE_IDLE)) {
1293 BTIF_TRACE_DEBUG(
1294 "%s: Active/Held call notification received without call setup update",
1295 __func__);
1296
1297 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1298 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
1299 /* Addition call setup with the Active call
1300 ** CIND response should have been updated.
1301 ** just open SCO connection.
1302 */
1303 if (call_setup_state != BTHF_CALL_STATE_IDLE)
1304 res = BTA_AG_MULTI_CALL_RES;
1305 else
1306 res = BTA_AG_OUT_CALL_CONN_RES;
1307 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1308 activeCallUpdated = true;
1309 }
1310
1311 /* Ringing call changed? */
1312 if (call_setup_state != btif_hf_cb[idx].call_setup_state) {
1313 BTIF_TRACE_DEBUG("%s: Call setup states changed. old: %s new: %s", __func__,
1314 dump_hf_call_state(btif_hf_cb[idx].call_setup_state),
1315 dump_hf_call_state(call_setup_state));
1316 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1317
1318 switch (call_setup_state) {
1319 case BTHF_CALL_STATE_IDLE: {
1320 switch (btif_hf_cb[idx].call_setup_state) {
1321 case BTHF_CALL_STATE_INCOMING:
1322 if (num_active > btif_hf_cb[idx].num_active) {
1323 res = BTA_AG_IN_CALL_CONN_RES;
1324 ag_res.audio_handle = btif_hf_cb[idx].handle;
1325 } else if (num_held > btif_hf_cb[idx].num_held)
1326 res = BTA_AG_IN_CALL_HELD_RES;
1327 else
1328 res = BTA_AG_CALL_CANCEL_RES;
1329 break;
1330 case BTHF_CALL_STATE_DIALING:
1331 case BTHF_CALL_STATE_ALERTING:
1332 if (num_active > btif_hf_cb[idx].num_active) {
1333 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
1334 res = BTA_AG_OUT_CALL_CONN_RES;
1335 } else
1336 res = BTA_AG_CALL_CANCEL_RES;
1337 break;
1338 default:
1339 BTIF_TRACE_ERROR("%s: Incorrect Call setup state transition",
1340 __func__);
1341 status = BT_STATUS_PARM_INVALID;
1342 break;
1343 }
1344 } break;
1345
1346 case BTHF_CALL_STATE_INCOMING:
1347 if (num_active || num_held) {
1348 res = BTA_AG_CALL_WAIT_RES;
1349 } else {
1350 res = BTA_AG_IN_CALL_RES;
1351 }
1352 if (number) {
1353 int xx = 0;
1354 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
1355 xx = snprintf(ag_res.str, sizeof(ag_res.str), "\"+%s\"", number);
1356 else
1357 xx = snprintf(ag_res.str, sizeof(ag_res.str), "\"%s\"", number);
1358 ag_res.num = type;
1359
1360 if (res == BTA_AG_CALL_WAIT_RES)
1361 snprintf(&ag_res.str[xx], sizeof(ag_res.str) - xx, ",%d", type);
1362 }
1363 break;
1364 case BTHF_CALL_STATE_DIALING:
1365 if (!(num_active + num_held))
1366 ag_res.audio_handle = btif_hf_cb[idx].handle;
1367 res = BTA_AG_OUT_CALL_ORIG_RES;
1368 break;
1369 case BTHF_CALL_STATE_ALERTING:
1370 /* if we went from idle->alert, force SCO setup here. dialing usually
1371 * triggers it */
1372 if ((btif_hf_cb[idx].call_setup_state == BTHF_CALL_STATE_IDLE) &&
1373 !(num_active + num_held))
1374 ag_res.audio_handle = btif_hf_cb[idx].handle;
1375 res = BTA_AG_OUT_CALL_ALERT_RES;
1376 break;
1377 default:
1378 BTIF_TRACE_ERROR("%s: Incorrect new ringing call state", __func__);
1379 status = BT_STATUS_PARM_INVALID;
1380 break;
1381 }
1382 BTIF_TRACE_DEBUG("%s: Call setup state changed. res=%d, audio_handle=%d",
1383 __func__, res, ag_res.audio_handle);
1384
1385 if (res) BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1386
1387 /* if call setup is idle, we have already updated call indicator, jump out
1388 */
1389 if (call_setup_state == BTHF_CALL_STATE_IDLE) {
1390 /* check & update callheld */
1391 if ((num_held > 0) && (num_active > 0))
1392 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1393 goto update_call_states;
1394 }
1395 }
1396
1397 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1398
1399 /* per the errata 2043, call=1 implies atleast one call is in progress
1400 *(active/held)
1401 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1402 ** Handle call indicator change
1403 **/
1404 if (!activeCallUpdated &&
1405 ((num_active + num_held) !=
1406 (btif_hf_cb[idx].num_active + btif_hf_cb[idx].num_held))) {
1407 BTIF_TRACE_DEBUG("%s: Active call states changed. old: %d new: %d",
1408 __func__, btif_hf_cb[idx].num_active, num_active);
1409 send_indicator_update(BTA_AG_IND_CALL,
1410 ((num_active + num_held) > 0) ? 1 : 0);
1411 }
1412
1413 /* Held Changed? */
1414 if (num_held != btif_hf_cb[idx].num_held ||
1415 ((num_active == 0) && ((num_held + btif_hf_cb[idx].num_held) > 1))) {
1416 BTIF_TRACE_DEBUG("%s: Held call states changed. old: %d new: %d", __func__,
1417 btif_hf_cb[idx].num_held, num_held);
1418 send_indicator_update(BTA_AG_IND_CALLHELD,
1419 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1)));
1420 }
1421
1422 /* Calls Swapped? */
1423 if ((call_setup_state == btif_hf_cb[idx].call_setup_state) &&
1424 (num_active && num_held) && (num_active == btif_hf_cb[idx].num_active) &&
1425 (num_held == btif_hf_cb[idx].num_held)) {
1426 BTIF_TRACE_DEBUG("%s: Calls swapped", __func__);
1427 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1428 }
1429
1430 update_call_states:
1431 for (i = 0; i < btif_max_hf_clients; i++) {
1432 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED) {
1433 btif_hf_cb[i].num_active = num_active;
1434 btif_hf_cb[i].num_held = num_held;
1435 btif_hf_cb[i].call_setup_state = call_setup_state;
1436 }
1437 }
1438 return status;
1439 }
1440
1441 /*******************************************************************************
1442 *
1443 * Function btif_hf_is_call_idle
1444 *
1445 * Description returns true if no call is in progress
1446 *
1447 * Returns bt_status_t
1448 *
1449 ******************************************************************************/
btif_hf_is_call_idle(void)1450 bool btif_hf_is_call_idle(void) {
1451 if (bt_hf_callbacks == NULL) return true;
1452
1453 for (int i = 0; i < btif_max_hf_clients; ++i) {
1454 if ((btif_hf_cb[i].call_setup_state != BTHF_CALL_STATE_IDLE) ||
1455 ((btif_hf_cb[i].num_held + btif_hf_cb[i].num_active) > 0))
1456 return false;
1457 }
1458
1459 return true;
1460 }
1461
1462 /*******************************************************************************
1463 *
1464 * Function btif_hf_call_terminated_recently
1465 *
1466 * Description Checks if a call has been terminated
1467 *
1468 * Returns bt_status_t
1469 *
1470 ******************************************************************************/
btif_hf_call_terminated_recently()1471 bool btif_hf_call_terminated_recently() {
1472 struct timespec now;
1473
1474 clock_gettime(CLOCK_MONOTONIC, &now);
1475 if (now.tv_sec <
1476 btif_hf_cb[0].call_end_timestamp.tv_sec + BTIF_HF_CALL_END_TIMEOUT) {
1477 return true;
1478 } else {
1479 btif_hf_cb[0].call_end_timestamp.tv_sec = 0;
1480 return false;
1481 }
1482 }
1483
1484 /*******************************************************************************
1485 *
1486 * Function cleanup
1487 *
1488 * Description Closes the HF interface
1489 *
1490 * Returns bt_status_t
1491 *
1492 ******************************************************************************/
cleanup(void)1493 static void cleanup(void) {
1494 BTIF_TRACE_EVENT("%s", __func__);
1495
1496 if (bt_hf_callbacks) {
1497 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
1498 btif_disable_service(BTA_HFP_SERVICE_ID);
1499 #else
1500 btif_disable_service(BTA_HSP_SERVICE_ID);
1501 #endif
1502 bt_hf_callbacks = NULL;
1503 }
1504 }
1505
1506 /*******************************************************************************
1507 *
1508 * Function configure_wbs
1509 *
1510 * Description set to over-ride the current WBS configuration.
1511 * It will not send codec setting cmd to the controller now.
1512 * It just change the configure.
1513 *
1514 * Returns bt_status_t
1515 *
1516 ******************************************************************************/
configure_wbs(bt_bdaddr_t * bd_addr,bthf_wbs_config_t config)1517 static bt_status_t configure_wbs(bt_bdaddr_t* bd_addr,
1518 bthf_wbs_config_t config) {
1519 CHECK_BTHF_INIT();
1520
1521 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1522
1523 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB)) {
1524 BTIF_TRACE_ERROR("%s: Invalid index %d", __func__, idx);
1525 return BT_STATUS_FAIL;
1526 }
1527
1528 BTIF_TRACE_EVENT("%s config is %d", __func__, config);
1529 if (config == BTHF_WBS_YES)
1530 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_MSBC);
1531 else if (config == BTHF_WBS_NO)
1532 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_CVSD);
1533 else
1534 BTA_AgSetCodec(btif_hf_cb[idx].handle, BTA_AG_CODEC_NONE);
1535
1536 return BT_STATUS_SUCCESS;
1537 }
1538
1539 static const bthf_interface_t bthfInterface = {
1540 sizeof(bthfInterface),
1541 init,
1542 connect,
1543 disconnect,
1544 connect_audio,
1545 disconnect_audio,
1546 start_voice_recognition,
1547 stop_voice_recognition,
1548 volume_control,
1549 device_status_notification,
1550 cops_response,
1551 cind_response,
1552 formatted_at_response,
1553 at_response,
1554 clcc_response,
1555 phone_state_change,
1556 cleanup,
1557 configure_wbs,
1558 bind_response,
1559 };
1560
1561 /*******************************************************************************
1562 *
1563 * Function btif_hf_execute_service
1564 *
1565 * Description Initializes/Shuts down the service
1566 *
1567 * Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1568 *
1569 ******************************************************************************/
btif_hf_execute_service(bool b_enable)1570 bt_status_t btif_hf_execute_service(bool b_enable) {
1571 const char* p_service_names[] = BTIF_HF_SERVICE_NAMES;
1572 int i;
1573 if (b_enable) {
1574 /* Enable and register with BTA-AG */
1575 BTA_AgEnable(BTA_AG_PARSE, bte_hf_evt);
1576 for (i = 0; i < btif_max_hf_clients; i++) {
1577 BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY, btif_hf_features,
1578 p_service_names, bthf_hf_id[i]);
1579 }
1580 } else {
1581 /* De-register AG */
1582 for (i = 0; i < btif_max_hf_clients; i++) {
1583 BTA_AgDeregister(btif_hf_cb[i].handle);
1584 }
1585 /* Disable AG */
1586 BTA_AgDisable();
1587 }
1588 return BT_STATUS_SUCCESS;
1589 }
1590
1591 /*******************************************************************************
1592 *
1593 * Function btif_hf_get_interface
1594 *
1595 * Description Get the hf callback interface
1596 *
1597 * Returns bthf_interface_t
1598 *
1599 ******************************************************************************/
btif_hf_get_interface()1600 const bthf_interface_t* btif_hf_get_interface() {
1601 BTIF_TRACE_EVENT("%s", __func__);
1602 return &bthfInterface;
1603 }
1604