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 #include <hardware/bluetooth.h>
29 #include <hardware/bt_hf.h>
30 #include <stdlib.h>
31
32 #define LOG_TAG "BTIF_HF"
33 #include "btif_common.h"
34 #include "btif_util.h"
35 #include "btif_profile_queue.h"
36
37 #include "bd.h"
38 #include "bta_ag_api.h"
39
40 /************************************************************************************
41 ** Constants & Macros
42 ************************************************************************************/
43 #ifndef BTIF_HSAG_SERVICE_NAME
44 #define BTIF_HSAG_SERVICE_NAME ("Headset Gateway")
45 #endif
46
47 #ifndef BTIF_HFAG_SERVICE_NAME
48 #define BTIF_HFAG_SERVICE_NAME ("Handsfree Gateway")
49 #endif
50
51 #ifndef BTIF_HF_SERVICES
52 #define BTIF_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK )
53 #endif
54
55 #ifndef BTIF_HF_SERVICE_NAMES
56 #define BTIF_HF_SERVICE_NAMES {BTIF_HSAG_SERVICE_NAME , BTIF_HFAG_SERVICE_NAME}
57 #endif
58
59 #ifndef BTIF_HF_SECURITY
60 #define BTIF_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
61 #endif
62
63 #ifndef BTIF_HF_FEATURES
64 #define BTIF_HF_FEATURES ( BTA_AG_FEAT_3WAY | \
65 BTA_AG_FEAT_ECNR | \
66 BTA_AG_FEAT_REJECT | \
67 BTA_AG_FEAT_ECS | \
68 BTA_AG_FEAT_EXTERR | \
69 BTA_AG_FEAT_BTRH | \
70 BTA_AG_FEAT_VREC | \
71 BTA_AG_FEAT_UNAT)
72 #endif
73
74 #define BTIF_HF_ID_1 0
75
76 #define BTIF_HF_CALL_END_TIMEOUT 6
77
78 /************************************************************************************
79 ** Local type definitions
80 ************************************************************************************/
81
82 /************************************************************************************
83 ** Static variables
84 ************************************************************************************/
85 static bthf_callbacks_t *bt_hf_callbacks = NULL;
86
87 #define CHECK_BTHF_INIT() if (bt_hf_callbacks == NULL)\
88 {\
89 BTIF_TRACE_WARNING1("BTHF: %s: BTHF not initialized", __FUNCTION__);\
90 return BT_STATUS_NOT_READY;\
91 }\
92 else\
93 {\
94 BTIF_TRACE_EVENT1("BTHF: %s", __FUNCTION__);\
95 }
96
97 #define CHECK_BTHF_SLC_CONNECTED() if (bt_hf_callbacks == NULL)\
98 {\
99 BTIF_TRACE_WARNING1("BTHF: %s: BTHF not initialized", __FUNCTION__);\
100 return BT_STATUS_NOT_READY;\
101 }\
102 else if (btif_hf_cb.state != BTHF_CONNECTION_STATE_SLC_CONNECTED)\
103 {\
104 BTIF_TRACE_WARNING2("BTHF: %s: SLC connection not up. state=%s", __FUNCTION__, dump_hf_conn_state(btif_hf_cb.state));\
105 return BT_STATUS_NOT_READY;\
106 }\
107 else\
108 {\
109 BTIF_TRACE_EVENT1("BTHF: %s", __FUNCTION__);\
110 }
111
112 /* BTIF-HF control block to map bdaddr to BTA handle */
113 typedef struct _btif_hf_cb
114 {
115 UINT16 handle;
116 bt_bdaddr_t connected_bda;
117 bthf_connection_state_t state;
118 bthf_vr_state_t vr_state;
119 tBTA_AG_PEER_FEAT peer_feat;
120 int num_active;
121 int num_held;
122 struct timespec call_end_timestamp;
123 bthf_call_state_t call_setup_state;
124 } btif_hf_cb_t;
125
126 static btif_hf_cb_t btif_hf_cb;
127
128
129 /************************************************************************************
130 ** Static functions
131 ************************************************************************************/
132
133 /************************************************************************************
134 ** Externs
135 ************************************************************************************/
136
137 /************************************************************************************
138 ** Functions
139 ************************************************************************************/
140
141 /*******************************************************************************
142 **
143 ** Function is_connected
144 **
145 ** Description Internal function to check if HF is connected
146 **
147 ** Returns TRUE if connected
148 **
149 *******************************************************************************/
is_connected(bt_bdaddr_t * bd_addr)150 static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
151 {
152 if (((btif_hf_cb.state == BTHF_CONNECTION_STATE_CONNECTED) || (btif_hf_cb.state == BTHF_CONNECTION_STATE_SLC_CONNECTED))&&
153 ((bd_addr == NULL) || (bdcmp(bd_addr->address, btif_hf_cb.connected_bda.address) == 0)))
154 return TRUE;
155 else
156 return FALSE;
157 }
158
159 /*******************************************************************************
160 **
161 ** Function callstate_to_callsetup
162 **
163 ** Description Converts HAL call state to BTA call setup indicator value
164 **
165 ** Returns BTA call indicator value
166 **
167 *******************************************************************************/
callstate_to_callsetup(bthf_call_state_t call_state)168 static UINT8 callstate_to_callsetup(bthf_call_state_t call_state)
169 {
170 UINT8 call_setup = 0;
171 if (call_state == BTHF_CALL_STATE_INCOMING)
172 call_setup = 1;
173 if (call_state == BTHF_CALL_STATE_DIALING)
174 call_setup = 2;
175 if (call_state == BTHF_CALL_STATE_ALERTING)
176 call_setup = 3;
177
178 return call_setup;
179 }
180
181 /*******************************************************************************
182 **
183 ** Function send_at_result
184 **
185 ** Description Send AT result code (OK/ERROR)
186 **
187 ** Returns void
188 **
189 *******************************************************************************/
send_at_result(UINT8 ok_flag,UINT16 errcode)190 static void send_at_result(UINT8 ok_flag, UINT16 errcode)
191 {
192 tBTA_AG_RES_DATA ag_res;
193 memset (&ag_res, 0, sizeof (ag_res));
194
195 ag_res.ok_flag = ok_flag;
196 if (ok_flag == BTA_AG_OK_ERROR)
197 {
198 ag_res.errcode = errcode;
199 }
200
201 BTA_AgResult (btif_hf_cb.handle, BTA_AG_UNAT_RES, &ag_res);
202 }
203
204 /*******************************************************************************
205 **
206 ** Function send_indicator_update
207 **
208 ** Description Send indicator update (CIEV)
209 **
210 ** Returns void
211 **
212 *******************************************************************************/
send_indicator_update(UINT16 indicator,UINT16 value)213 static void send_indicator_update (UINT16 indicator, UINT16 value)
214 {
215 tBTA_AG_RES_DATA ag_res;
216
217 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
218 ag_res.ind.id = indicator;
219 ag_res.ind.value = value;
220
221 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res);
222 }
223
clear_phone_state()224 void clear_phone_state()
225 {
226 btif_hf_cb.call_setup_state = BTHF_CALL_STATE_IDLE;
227 btif_hf_cb.num_active = btif_hf_cb.num_held = 0;
228 }
229
230
231 /*****************************************************************************
232 ** Section name (Group of functions)
233 *****************************************************************************/
234
235 /*****************************************************************************
236 **
237 ** btif hf api functions (no context switch)
238 **
239 *****************************************************************************/
240
241
242 /*******************************************************************************
243 **
244 ** Function btif_hf_upstreams_evt
245 **
246 ** Description Executes HF UPSTREAMS events in btif context
247 **
248 ** Returns void
249 **
250 *******************************************************************************/
btif_hf_upstreams_evt(UINT16 event,char * p_param)251 static void btif_hf_upstreams_evt(UINT16 event, char* p_param)
252 {
253 tBTA_AG *p_data = (tBTA_AG *)p_param;
254 bdstr_t bdstr;
255
256 BTIF_TRACE_DEBUG2("%s: event=%s", __FUNCTION__, dump_hf_event(event));
257
258 switch (event)
259 {
260 case BTA_AG_ENABLE_EVT:
261 case BTA_AG_DISABLE_EVT:
262 break;
263
264 case BTA_AG_REGISTER_EVT:
265 btif_hf_cb.handle = p_data->reg.hdr.handle;
266 break;
267
268 case BTA_AG_OPEN_EVT:
269 if (p_data->open.status == BTA_AG_SUCCESS)
270 {
271 bdcpy(btif_hf_cb.connected_bda.address, p_data->open.bd_addr);
272 btif_hf_cb.state = BTHF_CONNECTION_STATE_CONNECTED;
273 btif_hf_cb.peer_feat = 0;
274 clear_phone_state();
275 }
276 else if (btif_hf_cb.state == BTHF_CONNECTION_STATE_CONNECTING)
277 {
278 btif_hf_cb.state = BTHF_CONNECTION_STATE_DISCONNECTED;
279 }
280 else
281 {
282 BTIF_TRACE_WARNING4("%s: AG open failed, but another device connected. status=%d state=%d connected device=%s",
283 __FUNCTION__, p_data->open.status, btif_hf_cb.state, bd2str(&btif_hf_cb.connected_bda, &bdstr));
284 break;
285 }
286
287 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb.state, &btif_hf_cb.connected_bda);
288
289 if (btif_hf_cb.state == BTHF_CONNECTION_STATE_DISCONNECTED)
290 bdsetany(btif_hf_cb.connected_bda.address);
291
292 if (p_data->open.status != BTA_AG_SUCCESS)
293 btif_queue_advance();
294 break;
295
296 case BTA_AG_CLOSE_EVT:
297 btif_hf_cb.state = BTHF_CONNECTION_STATE_DISCONNECTED;
298 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb.state, &btif_hf_cb.connected_bda);
299 bdsetany(btif_hf_cb.connected_bda.address);
300 btif_hf_cb.peer_feat = 0;
301 clear_phone_state();
302 /* If AG_OPEN was received but SLC was not setup in a specified time (10 seconds),
303 ** then AG_CLOSE may be received. We need to advance the queue here
304 */
305 btif_queue_advance();
306 break;
307
308 case BTA_AG_CONN_EVT:
309 btif_hf_cb.peer_feat = p_data->conn.peer_feat;
310 btif_hf_cb.state = BTHF_CONNECTION_STATE_SLC_CONNECTED;
311
312 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb.state,
313 &btif_hf_cb.connected_bda);
314 btif_queue_advance();
315 break;
316
317 case BTA_AG_AUDIO_OPEN_EVT:
318 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTED, &btif_hf_cb.connected_bda);
319 break;
320
321 case BTA_AG_AUDIO_CLOSE_EVT:
322 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_DISCONNECTED, &btif_hf_cb.connected_bda);
323 break;
324
325 /* BTA auto-responds, silently discard */
326 case BTA_AG_SPK_EVT:
327 case BTA_AG_MIC_EVT:
328 HAL_CBACK(bt_hf_callbacks, volume_cmd_cb,
329 (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK : BTHF_VOLUME_TYPE_MIC, p_data->val.num);
330 break;
331
332 case BTA_AG_AT_A_EVT:
333 HAL_CBACK(bt_hf_callbacks, answer_call_cmd_cb);
334 break;
335
336 /* Java needs to send OK/ERROR for these commands */
337 case BTA_AG_AT_BLDN_EVT:
338 case BTA_AG_AT_D_EVT:
339 HAL_CBACK(bt_hf_callbacks, dial_call_cmd_cb,
340 (event == BTA_AG_AT_D_EVT) ? p_data->val.str : NULL);
341 break;
342
343 case BTA_AG_AT_CHUP_EVT:
344 HAL_CBACK(bt_hf_callbacks, hangup_call_cmd_cb);
345 break;
346
347 case BTA_AG_AT_CIND_EVT:
348 HAL_CBACK(bt_hf_callbacks, cind_cmd_cb);
349 break;
350
351 case BTA_AG_AT_VTS_EVT:
352 HAL_CBACK(bt_hf_callbacks, dtmf_cmd_cb, p_data->val.str[0]);
353 break;
354
355 case BTA_AG_AT_BVRA_EVT:
356 HAL_CBACK(bt_hf_callbacks, vr_cmd_cb,
357 (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED : BTHF_VR_STATE_STOPPED);
358 break;
359
360 case BTA_AG_AT_NREC_EVT:
361 HAL_CBACK(bt_hf_callbacks, nrec_cmd_cb,
362 (p_data->val.num == 1) ? BTHF_NREC_START : BTHF_NREC_STOP);
363 break;
364
365 /* TODO: Add a callback for CBC */
366 case BTA_AG_AT_CBC_EVT:
367 break;
368
369 case BTA_AG_AT_CKPD_EVT:
370 HAL_CBACK(bt_hf_callbacks, key_pressed_cmd_cb);
371 break;
372
373 /* Java needs to send OK/ERROR for these commands */
374 case BTA_AG_AT_CHLD_EVT:
375 HAL_CBACK(bt_hf_callbacks, chld_cmd_cb, atoi(p_data->val.str));
376 break;
377
378 case BTA_AG_AT_CLCC_EVT:
379 HAL_CBACK(bt_hf_callbacks, clcc_cmd_cb, p_data->val.num);
380 break;
381
382 case BTA_AG_AT_COPS_EVT:
383 HAL_CBACK(bt_hf_callbacks, cops_cmd_cb);
384 break;
385
386 case BTA_AG_AT_UNAT_EVT:
387 HAL_CBACK(bt_hf_callbacks, unknown_at_cmd_cb,
388 p_data->val.str);
389 break;
390
391 case BTA_AG_AT_CNUM_EVT:
392 HAL_CBACK(bt_hf_callbacks, cnum_cmd_cb);
393 break;
394
395 /* TODO: Some of these commands may need to be sent to app. For now respond with error */
396 case BTA_AG_AT_BINP_EVT:
397 case BTA_AG_AT_BTRH_EVT:
398 send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED);
399 break;
400
401
402 default:
403 BTIF_TRACE_WARNING2("%s: Unhandled event: %d", __FUNCTION__, event);
404 break;
405 }
406 }
407
408 /*******************************************************************************
409 **
410 ** Function bte_hf_evt
411 **
412 ** Description Switches context from BTE to BTIF for all HF events
413 **
414 ** Returns void
415 **
416 *******************************************************************************/
417
bte_hf_evt(tBTA_AG_EVT event,tBTA_AG * p_data)418 static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *p_data)
419 {
420 bt_status_t status;
421 int param_len = 0;
422
423 /* TODO: BTA sends the union members and not tBTA_AG. If using param_len=sizeof(tBTA_AG), we get a crash on memcpy */
424 if (BTA_AG_REGISTER_EVT == event)
425 param_len = sizeof(tBTA_AG_REGISTER);
426 else if (BTA_AG_OPEN_EVT == event)
427 param_len = sizeof(tBTA_AG_OPEN);
428 else if (BTA_AG_CONN_EVT == event)
429 param_len = sizeof(tBTA_AG_CONN);
430 else if ( (BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event))
431 param_len = sizeof(tBTA_AG_HDR);
432 else if (p_data)
433 param_len = sizeof(tBTA_AG_VAL);
434
435 /* switch context to btif task context (copy full union size for convenience) */
436 status = btif_transfer_context(btif_hf_upstreams_evt, (uint16_t)event, (void*)p_data, param_len, NULL);
437
438 /* catch any failed context transfers */
439 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
440 }
441
442
443 /*******************************************************************************
444 **
445 ** Function btif_in_hf_generic_evt
446 **
447 ** Description Processes generic events to be sent to JNI that are not triggered from the BTA.
448 ** Always runs in BTIF context
449 **
450 ** Returns void
451 **
452 *******************************************************************************/
btif_in_hf_generic_evt(UINT16 event,char * p_param)453 static void btif_in_hf_generic_evt(UINT16 event, char *p_param)
454 {
455 BTIF_TRACE_EVENT2("%s: event=%d", __FUNCTION__, event);
456 switch (event) {
457 case BTIF_HFP_CB_AUDIO_CONNECTING:
458 {
459 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTING,
460 &btif_hf_cb.connected_bda);
461 } break;
462 default:
463 {
464 BTIF_TRACE_WARNING2("%s : Unknown event 0x%x", __FUNCTION__, event);
465 }
466 break;
467 }
468 }
469
470
471 /*******************************************************************************
472 **
473 ** Function btif_hf_init
474 **
475 ** Description initializes the hf interface
476 **
477 ** Returns bt_status_t
478 **
479 *******************************************************************************/
init(bthf_callbacks_t * callbacks)480 static bt_status_t init( bthf_callbacks_t* callbacks )
481 {
482 BTIF_TRACE_EVENT1("%s", __FUNCTION__);
483
484 bt_hf_callbacks = callbacks;
485
486 /* Invoke the enable service API to the core to set the appropriate service_id
487 * Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled (phone)
488 * othwerwise only HSP is enabled (tablet)
489 */
490 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
491 btif_enable_service(BTA_HFP_SERVICE_ID);
492 #else
493 btif_enable_service(BTA_HSP_SERVICE_ID);
494 #endif
495
496 memset(&btif_hf_cb, 0, sizeof(btif_hf_cb_t));
497 clear_phone_state();
498
499 return BT_STATUS_SUCCESS;
500 }
501
502 /*******************************************************************************
503 **
504 ** Function connect
505 **
506 ** Description connect to headset
507 **
508 ** Returns bt_status_t
509 **
510 *******************************************************************************/
connect_int(bt_bdaddr_t * bd_addr)511 static bt_status_t connect_int( bt_bdaddr_t *bd_addr )
512 {
513 if (!is_connected(bd_addr))
514 {
515 btif_hf_cb.state = BTHF_CONNECTION_STATE_CONNECTING;
516 bdcpy(btif_hf_cb.connected_bda.address, bd_addr->address);
517
518 BTA_AgOpen(btif_hf_cb.handle, btif_hf_cb.connected_bda.address,
519 BTIF_HF_SECURITY, BTIF_HF_SERVICES);
520 return BT_STATUS_SUCCESS;
521 }
522
523 return BT_STATUS_BUSY;
524 }
525
connect(bt_bdaddr_t * bd_addr)526 static bt_status_t connect( bt_bdaddr_t *bd_addr )
527 {
528 CHECK_BTHF_INIT();
529 return btif_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_int);
530 }
531
532 /*******************************************************************************
533 **
534 ** Function disconnect
535 **
536 ** Description disconnect from headset
537 **
538 ** Returns bt_status_t
539 **
540 *******************************************************************************/
disconnect(bt_bdaddr_t * bd_addr)541 static bt_status_t disconnect( bt_bdaddr_t *bd_addr )
542 {
543 CHECK_BTHF_INIT();
544
545 if (is_connected(bd_addr))
546 {
547 BTA_AgClose(btif_hf_cb.handle);
548 return BT_STATUS_SUCCESS;
549 }
550
551 return BT_STATUS_FAIL;
552 }
553
554 /*******************************************************************************
555 **
556 ** Function connect_audio
557 **
558 ** Description create an audio connection
559 **
560 ** Returns bt_status_t
561 **
562 *******************************************************************************/
connect_audio(bt_bdaddr_t * bd_addr)563 static bt_status_t connect_audio( bt_bdaddr_t *bd_addr )
564 {
565 CHECK_BTHF_INIT();
566
567 if (is_connected(bd_addr))
568 {
569 BTA_AgAudioOpen(btif_hf_cb.handle);
570
571 /* Inform the application that the audio connection has been initiated successfully */
572 btif_transfer_context(btif_in_hf_generic_evt, BTIF_HFP_CB_AUDIO_CONNECTING,
573 (char *)bd_addr, sizeof(bt_bdaddr_t), NULL);
574 return BT_STATUS_SUCCESS;
575 }
576
577 return BT_STATUS_FAIL;
578 }
579
580 /*******************************************************************************
581 **
582 ** Function disconnect_audio
583 **
584 ** Description close the audio connection
585 **
586 ** Returns bt_status_t
587 **
588 *******************************************************************************/
disconnect_audio(bt_bdaddr_t * bd_addr)589 static bt_status_t disconnect_audio( bt_bdaddr_t *bd_addr )
590 {
591 CHECK_BTHF_INIT();
592
593 if (is_connected(bd_addr))
594 {
595 BTA_AgAudioClose(btif_hf_cb.handle);
596 return BT_STATUS_SUCCESS;
597 }
598
599 return BT_STATUS_FAIL;
600 }
601
602 /*******************************************************************************
603 **
604 ** Function start_voice_recognition
605 **
606 ** Description start voice recognition
607 **
608 ** Returns bt_status_t
609 **
610 *******************************************************************************/
start_voice_recognition()611 static bt_status_t start_voice_recognition()
612 {
613 CHECK_BTHF_INIT();
614 if (is_connected(NULL))
615 {
616 if (btif_hf_cb.peer_feat & BTA_AG_PEER_FEAT_VREC)
617 {
618 tBTA_AG_RES_DATA ag_res;
619 memset(&ag_res, 0, sizeof(ag_res));
620 ag_res.state = 1;
621 BTA_AgResult (btif_hf_cb.handle, BTA_AG_BVRA_RES, &ag_res);
622
623 return BT_STATUS_SUCCESS;
624 }
625 else
626 {
627 return BT_STATUS_UNSUPPORTED;
628 }
629 }
630
631 return BT_STATUS_NOT_READY;
632 }
633
634 /*******************************************************************************
635 **
636 ** Function stop_voice_recognition
637 **
638 ** Description stop voice recognition
639 **
640 ** Returns bt_status_t
641 **
642 *******************************************************************************/
stop_voice_recognition()643 static bt_status_t stop_voice_recognition()
644 {
645 CHECK_BTHF_INIT();
646
647 if (is_connected(NULL))
648 {
649 if (btif_hf_cb.peer_feat & BTA_AG_PEER_FEAT_VREC)
650 {
651 tBTA_AG_RES_DATA ag_res;
652 memset(&ag_res, 0, sizeof(ag_res));
653 ag_res.state = 0;
654 BTA_AgResult (btif_hf_cb.handle, BTA_AG_BVRA_RES, &ag_res);
655
656 return BT_STATUS_SUCCESS;
657 }
658 else
659 {
660 return BT_STATUS_UNSUPPORTED;
661 }
662 }
663
664 return BT_STATUS_NOT_READY;
665 }
666
667 /*******************************************************************************
668 **
669 ** Function volume_control
670 **
671 ** Description volume control
672 **
673 ** Returns bt_status_t
674 **
675 *******************************************************************************/
volume_control(bthf_volume_type_t type,int volume)676 static bt_status_t volume_control(bthf_volume_type_t type, int volume)
677 {
678 CHECK_BTHF_INIT();
679
680 tBTA_AG_RES_DATA ag_res;
681 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
682 if (is_connected(NULL))
683 {
684 ag_res.num = volume;
685 BTA_AgResult(btif_hf_cb.handle,
686 (type == BTHF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES,
687 &ag_res);
688 return BT_STATUS_SUCCESS;
689 }
690
691 return BT_STATUS_FAIL;
692 }
693
694 /*******************************************************************************
695 **
696 ** Function device_status_notification
697 **
698 ** Description Combined device status change notification
699 **
700 ** Returns bt_status_t
701 **
702 *******************************************************************************/
device_status_notification(bthf_network_state_t ntk_state,bthf_service_type_t svc_type,int signal,int batt_chg)703 static bt_status_t device_status_notification(bthf_network_state_t ntk_state,
704 bthf_service_type_t svc_type, int signal, int batt_chg)
705 {
706 CHECK_BTHF_INIT();
707
708 if (is_connected(NULL))
709 {
710 /* send all indicators to BTA.
711 ** BTA will make sure no duplicates are sent out
712 */
713 send_indicator_update(BTA_AG_IND_SERVICE,
714 (ntk_state == BTHF_NETWORK_STATE_AVAILABLE) ? 1 : 0);
715 send_indicator_update(BTA_AG_IND_ROAM,
716 (svc_type == BTHF_SERVICE_TYPE_HOME) ? 0 : 1);
717 send_indicator_update(BTA_AG_IND_SIGNAL, signal);
718 send_indicator_update(BTA_AG_IND_BATTCHG, batt_chg);
719 return BT_STATUS_SUCCESS;
720 }
721
722 return BT_STATUS_SUCCESS;
723 }
724
725 /*******************************************************************************
726 **
727 ** Function cops_response
728 **
729 ** Description Response for COPS command
730 **
731 ** Returns bt_status_t
732 **
733 *******************************************************************************/
cops_response(const char * cops)734 static bt_status_t cops_response(const char *cops)
735 {
736 CHECK_BTHF_INIT();
737
738 if (is_connected(NULL))
739 {
740 tBTA_AG_RES_DATA ag_res;
741
742 /* Format the response */
743 sprintf (ag_res.str, "0,0,\"%s\"", cops);
744 ag_res.ok_flag = BTA_AG_OK_DONE;
745
746 BTA_AgResult (btif_hf_cb.handle, BTA_AG_COPS_RES, &ag_res);
747 return BT_STATUS_SUCCESS;
748 }
749 return BT_STATUS_FAIL;
750 }
751
752 /*******************************************************************************
753 **
754 ** Function cind_response
755 **
756 ** Description Response for CIND command
757 **
758 ** Returns bt_status_t
759 **
760 *******************************************************************************/
cind_response(int svc,int num_active,int num_held,bthf_call_state_t call_setup_state,int signal,int roam,int batt_chg)761 static bt_status_t cind_response(int svc, int num_active, int num_held,
762 bthf_call_state_t call_setup_state,
763 int signal, int roam, int batt_chg)
764 {
765 CHECK_BTHF_INIT();
766
767 if (is_connected(NULL))
768 {
769 tBTA_AG_RES_DATA ag_res;
770
771 memset (&ag_res, 0, sizeof (ag_res));
772 /* per the errata 2043, call=1 implies atleast one call is in progress (active/held)
773 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
774 **/
775 sprintf (ag_res.str, "%d,%d,%d,%d,%d,%d,%d",
776 (num_active + num_held) ? 1 : 0, /* Call state */
777 callstate_to_callsetup(call_setup_state), /* Callsetup state */
778 svc, /* network service */
779 signal, /* Signal strength */
780 roam, /* Roaming indicator */
781 batt_chg, /* Battery level */
782 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1))); /* Call held */
783
784 BTA_AgResult (btif_hf_cb.handle, BTA_AG_CIND_RES, &ag_res);
785
786 return BT_STATUS_SUCCESS;
787 }
788
789 return BT_STATUS_FAIL;
790 }
791
792 /*******************************************************************************
793 **
794 ** Function formatted_at_response
795 **
796 ** Description Pre-formatted AT response, typically in response to unknown AT cmd
797 **
798 ** Returns bt_status_t
799 **
800 *******************************************************************************/
formatted_at_response(const char * rsp)801 static bt_status_t formatted_at_response(const char *rsp)
802 {
803 CHECK_BTHF_INIT();
804 tBTA_AG_RES_DATA ag_res;
805
806 if (is_connected(NULL))
807 {
808 /* Format the response and send */
809 memset (&ag_res, 0, sizeof (ag_res));
810 strncpy(ag_res.str, rsp, BTA_AG_AT_MAX_LEN);
811 BTA_AgResult (btif_hf_cb.handle, BTA_AG_UNAT_RES, &ag_res);
812
813 return BT_STATUS_SUCCESS;
814 }
815
816 return BT_STATUS_FAIL;
817 }
818
819 /*******************************************************************************
820 **
821 ** Function at_response
822 **
823 ** Description ok/error response
824 **
825 ** Returns bt_status_t
826 **
827 *******************************************************************************/
at_response(bthf_at_response_t response_code,int error_code)828 static bt_status_t at_response(bthf_at_response_t response_code, int error_code)
829 {
830 CHECK_BTHF_INIT();
831
832 if (is_connected(NULL))
833 {
834 send_at_result((response_code == BTHF_AT_RESPONSE_OK) ? BTA_AG_OK_DONE
835 : BTA_AG_OK_ERROR, error_code);
836 return BT_STATUS_SUCCESS;
837 }
838
839
840 return BT_STATUS_FAIL;
841 }
842
843 /*******************************************************************************
844 **
845 ** Function clcc_response
846 **
847 ** Description response for CLCC command
848 ** Can be iteratively called for each call index. Call index
849 ** of 0 will be treated as NULL termination (Completes response)
850 **
851 ** Returns bt_status_t
852 **
853 *******************************************************************************/
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)854 static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
855 bthf_call_state_t state, bthf_call_mode_t mode,
856 bthf_call_mpty_type_t mpty, const char *number,
857 bthf_call_addrtype_t type)
858 {
859 CHECK_BTHF_INIT();
860
861 if (is_connected(NULL))
862 {
863 tBTA_AG_RES_DATA ag_res;
864 int xx;
865
866 memset (&ag_res, 0, sizeof (ag_res));
867
868 /* Format the response */
869 if (index == 0)
870 {
871 ag_res.ok_flag = BTA_AG_OK_DONE;
872 }
873 else
874 {
875 BTIF_TRACE_EVENT6("clcc_response: [%d] dir %d state %d mode %d number = %s type = %d",
876 index, dir, state, mode, number, type);
877 xx = sprintf (ag_res.str, "%d,%d,%d,%d,%d",
878 index, dir, state, mode, mpty);
879
880 if (number)
881 {
882 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
883 sprintf (&ag_res.str[xx], ",\"+%s\",%d", number, type);
884 else
885 sprintf (&ag_res.str[xx], ",\"%s\",%d", number, type);
886 }
887 }
888 BTA_AgResult (btif_hf_cb.handle, BTA_AG_CLCC_RES, &ag_res);
889
890 return BT_STATUS_SUCCESS;
891 }
892
893 return BT_STATUS_FAIL;
894 }
895
896 /*******************************************************************************
897 **
898 ** Function phone_state_change
899 **
900 ** Description notify of a call state change
901 ** number & type: valid only for incoming & waiting call
902 **
903 ** Returns bt_status_t
904 **
905 *******************************************************************************/
906
phone_state_change(int num_active,int num_held,bthf_call_state_t call_setup_state,const char * number,bthf_call_addrtype_t type)907 static bt_status_t phone_state_change(int num_active, int num_held, bthf_call_state_t call_setup_state,
908 const char *number, bthf_call_addrtype_t type)
909 {
910 tBTA_AG_RES res = 0xff;
911 tBTA_AG_RES_DATA ag_res;
912 bt_status_t status = BT_STATUS_SUCCESS;
913 BOOLEAN activeCallUpdated = FALSE;
914
915 CHECK_BTHF_SLC_CONNECTED();
916
917 BTIF_TRACE_DEBUG6("phone_state_change: num_active=%d [prev: %d] num_held=%d[prev: %d]"\
918 " call_setup=%s [prev: %s]", num_active, btif_hf_cb.num_active,
919 num_held, btif_hf_cb.num_held,
920 dump_hf_call_state(call_setup_state), dump_hf_call_state(btif_hf_cb.call_setup_state));
921
922 /* if all indicators are 0, send end call and return */
923 if (num_active == 0 && num_held == 0 && call_setup_state == BTHF_CALL_STATE_IDLE)
924 {
925 BTIF_TRACE_DEBUG1("%s: Phone on hook", __FUNCTION__);
926
927 /* record call termination timestamp if there was an active/held call or callsetup state > BTHF_CALL_STATE_IDLE */
928 if ((btif_hf_cb.call_setup_state != BTHF_CALL_STATE_IDLE ) || (btif_hf_cb.num_active) ||(btif_hf_cb.num_held))
929 {
930 BTIF_TRACE_DEBUG1("%s: Record call termination timestamp", __FUNCTION__);
931 clock_gettime(CLOCK_MONOTONIC, &btif_hf_cb.call_end_timestamp);
932 }
933 BTA_AgResult (BTA_AG_HANDLE_ALL, BTA_AG_END_CALL_RES, NULL);
934
935 /* if held call was present, reset that as well */
936 if (btif_hf_cb.num_held)
937 send_indicator_update(BTA_AG_IND_CALLHELD, 0);
938
939 goto update_call_states;
940 }
941
942 /* active state can change when:
943 ** 1. an outgoing/incoming call was answered
944 ** 2. an held was resumed
945 ** 3. without callsetup notifications, call became active
946 ** (3) can happen if call is active and a headset connects to us
947 **
948 ** In the case of (3), we will have to notify the stack of an active
949 ** call, instead of sending an indicator update. This will also
950 ** force the SCO to be setup. Handle this special case here prior to
951 ** call setup handling
952 */
953 if ( (num_active == 1) && (btif_hf_cb.num_active == 0) && (btif_hf_cb.num_held == 0) &&
954 (btif_hf_cb.call_setup_state == BTHF_CALL_STATE_IDLE) )
955 {
956 BTIF_TRACE_DEBUG1("%s: Active call notification received without call setup update",
957 __FUNCTION__);
958
959 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
960 ag_res.audio_handle = btif_hf_cb.handle;
961 res = BTA_AG_OUT_CALL_CONN_RES;
962 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
963 activeCallUpdated = TRUE;
964 }
965
966 /* Ringing call changed? */
967 if (call_setup_state != btif_hf_cb.call_setup_state)
968 {
969 BTIF_TRACE_DEBUG3("%s: Call setup states changed. old: %s new: %s",
970 __FUNCTION__, dump_hf_call_state(btif_hf_cb.call_setup_state),
971 dump_hf_call_state(call_setup_state));
972 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
973
974 switch (call_setup_state)
975 {
976 case BTHF_CALL_STATE_IDLE:
977 {
978 switch (btif_hf_cb.call_setup_state)
979 {
980 case BTHF_CALL_STATE_INCOMING:
981 if (num_active > btif_hf_cb.num_active)
982 {
983 res = BTA_AG_IN_CALL_CONN_RES;
984 ag_res.audio_handle = btif_hf_cb.handle;
985 }
986 else if (num_held > btif_hf_cb.num_held)
987 res = BTA_AG_IN_CALL_HELD_RES;
988 else
989 res = BTA_AG_CALL_CANCEL_RES;
990 break;
991 case BTHF_CALL_STATE_DIALING:
992 case BTHF_CALL_STATE_ALERTING:
993 if (num_active > btif_hf_cb.num_active)
994 {
995 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
996 res = BTA_AG_OUT_CALL_CONN_RES;
997 }
998 else
999 res = BTA_AG_CALL_CANCEL_RES;
1000 break;
1001 default:
1002 BTIF_TRACE_ERROR1("%s: Incorrect Call setup state transition", __FUNCTION__);
1003 status = BT_STATUS_PARM_INVALID;
1004 break;
1005 }
1006 } break;
1007
1008 case BTHF_CALL_STATE_INCOMING:
1009 if (num_active || num_held)
1010 res = BTA_AG_CALL_WAIT_RES;
1011 else
1012 res = BTA_AG_IN_CALL_RES;
1013 if (number)
1014 {
1015 int xx = 0;
1016 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
1017 xx = sprintf (ag_res.str, "\"+%s\"", number);
1018 else
1019 xx = sprintf (ag_res.str, "\"%s\"", number);
1020 ag_res.num = type;
1021
1022 if (res == BTA_AG_CALL_WAIT_RES)
1023 sprintf(&ag_res.str[xx], ",%d", type);
1024 }
1025 break;
1026 case BTHF_CALL_STATE_DIALING:
1027 ag_res.audio_handle = btif_hf_cb.handle;
1028 res = BTA_AG_OUT_CALL_ORIG_RES;
1029 break;
1030 case BTHF_CALL_STATE_ALERTING:
1031 /* if we went from idle->alert, force SCO setup here. dialing usually triggers it */
1032 if (btif_hf_cb.call_setup_state == BTHF_CALL_STATE_IDLE)
1033 ag_res.audio_handle = btif_hf_cb.handle;
1034 res = BTA_AG_OUT_CALL_ALERT_RES;
1035 break;
1036 default:
1037 BTIF_TRACE_ERROR1("%s: Incorrect new ringing call state", __FUNCTION__);
1038 status = BT_STATUS_PARM_INVALID;
1039 break;
1040 }
1041 BTIF_TRACE_DEBUG3("%s: Call setup state changed. res=%d, audio_handle=%d", __FUNCTION__, res, ag_res.audio_handle);
1042
1043 if (res)
1044 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1045
1046 /* if call setup is idle, we have already updated call indicator, jump out */
1047 if (call_setup_state == BTHF_CALL_STATE_IDLE)
1048 {
1049 /* check & update callheld */
1050 if ((num_held > 0) && (num_active > 0))
1051 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1052 goto update_call_states;
1053 }
1054 }
1055
1056 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1057
1058 /* per the errata 2043, call=1 implies atleast one call is in progress (active/held)
1059 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1060 ** Handle call indicator change
1061 **/
1062 if (!activeCallUpdated && ((num_active + num_held) != (btif_hf_cb.num_active + btif_hf_cb.num_held)) )
1063 {
1064 BTIF_TRACE_DEBUG3("%s: Active call states changed. old: %d new: %d", __FUNCTION__, btif_hf_cb.num_active, num_active);
1065 send_indicator_update(BTA_AG_IND_CALL, ((num_active + num_held) > 0) ? 1 : 0);
1066 }
1067
1068 /* Held Changed? */
1069 if (num_held != btif_hf_cb.num_held)
1070 {
1071 BTIF_TRACE_DEBUG3("%s: Held call states changed. old: %d new: %d", __FUNCTION__, btif_hf_cb.num_held, num_held);
1072 send_indicator_update(BTA_AG_IND_CALLHELD, ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1)));
1073 }
1074
1075 /* Calls Swapped? */
1076 if ( (call_setup_state == btif_hf_cb.call_setup_state) &&
1077 (num_active && num_held) &&
1078 (num_active == btif_hf_cb.num_active) &&
1079 (num_held == btif_hf_cb.num_held) )
1080 {
1081 BTIF_TRACE_DEBUG1("%s: Calls swapped", __FUNCTION__);
1082 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1083 }
1084
1085 update_call_states:
1086 btif_hf_cb.num_active = num_active;
1087 btif_hf_cb.num_held = num_held;
1088 btif_hf_cb.call_setup_state = call_setup_state;
1089
1090 return status;
1091 }
1092
1093
1094 /*******************************************************************************
1095 **
1096 ** Function btif_hf_call_terminated_recently
1097 **
1098 ** Description Checks if a call has been terminated
1099 **
1100 ** Returns bt_status_t
1101 **
1102 *******************************************************************************/
btif_hf_call_terminated_recently()1103 BOOLEAN btif_hf_call_terminated_recently()
1104 {
1105 struct timespec now;
1106
1107 clock_gettime(CLOCK_MONOTONIC, &now);
1108 if (now.tv_sec < btif_hf_cb.call_end_timestamp.tv_sec + BTIF_HF_CALL_END_TIMEOUT)
1109 {
1110 return TRUE;
1111 }
1112 else
1113 {
1114 btif_hf_cb.call_end_timestamp.tv_sec = 0;
1115 return FALSE;
1116 }
1117 }
1118
1119 /*******************************************************************************
1120 **
1121 ** Function cleanup
1122 **
1123 ** Description Closes the HF interface
1124 **
1125 ** Returns bt_status_t
1126 **
1127 *******************************************************************************/
cleanup(void)1128 static void cleanup( void )
1129 {
1130 BTIF_TRACE_EVENT1("%s", __FUNCTION__);
1131
1132 if (bt_hf_callbacks)
1133 {
1134 btif_disable_service(BTA_HFP_SERVICE_ID);
1135 bt_hf_callbacks = NULL;
1136 }
1137 }
1138
1139 static const bthf_interface_t bthfInterface = {
1140 sizeof(bt_interface_t),
1141 init,
1142 connect,
1143 disconnect,
1144 connect_audio,
1145 disconnect_audio,
1146 start_voice_recognition,
1147 stop_voice_recognition,
1148 volume_control,
1149 device_status_notification,
1150 cops_response,
1151 cind_response,
1152 formatted_at_response,
1153 at_response,
1154 clcc_response,
1155 phone_state_change,
1156 cleanup,
1157 };
1158
1159 /*******************************************************************************
1160 **
1161 ** Function btif_hf_execute_service
1162 **
1163 ** Description Initializes/Shuts down the service
1164 **
1165 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1166 **
1167 *******************************************************************************/
btif_hf_execute_service(BOOLEAN b_enable)1168 bt_status_t btif_hf_execute_service(BOOLEAN b_enable)
1169 {
1170 char * p_service_names[] = BTIF_HF_SERVICE_NAMES;
1171 if (b_enable)
1172 {
1173 /* Enable and register with BTA-AG */
1174 BTA_AgEnable (BTA_AG_PARSE, bte_hf_evt);
1175 BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY, BTIF_HF_FEATURES,
1176 p_service_names, BTIF_HF_ID_1);
1177 }
1178 else {
1179 /* De-register AG */
1180 BTA_AgDeregister(btif_hf_cb.handle);
1181 /* Disable AG */
1182 BTA_AgDisable();
1183 }
1184 return BT_STATUS_SUCCESS;
1185 }
1186
1187 /*******************************************************************************
1188 **
1189 ** Function btif_hf_get_interface
1190 **
1191 ** Description Get the hf callback interface
1192 **
1193 ** Returns bthf_interface_t
1194 **
1195 *******************************************************************************/
btif_hf_get_interface()1196 const bthf_interface_t *btif_hf_get_interface()
1197 {
1198 BTIF_TRACE_EVENT1("%s", __FUNCTION__);
1199 return &bthfInterface;
1200 }
1201