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