• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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