• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (c) 2014 The Android Open Source Project
4  *  Copyright (C) 2009-2012 Broadcom Corporation
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at:
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  ******************************************************************************/
19 
20 /************************************************************************************
21  *
22  *  Filename:      btif_hf_client.c
23  *
24  *  Description:   Handsfree Profile (HF role) Bluetooth Interface
25  *
26  *
27  ***********************************************************************************/
28 
29 #include <hardware/bluetooth.h>
30 #include <hardware/bt_hf_client.h>
31 #include <stdlib.h>
32 #include <cutils/properties.h>
33 
34 #define LOG_TAG "BTIF_HF_CLIENT"
35 #include "btif_common.h"
36 #include "btif_util.h"
37 #include "btif_profile_queue.h"
38 #include "bt_utils.h"
39 #include "bd.h"
40 #include "bta_hf_client_api.h"
41 
42 /************************************************************************************
43 **  Constants & Macros
44 ************************************************************************************/
45 
46 #ifndef BTIF_HF_CLIENT_SERVICE_NAME
47 #define BTIF_HF_CLIENT_SERVICE_NAME ("Handsfree")
48 #endif
49 
50 #ifndef BTIF_HF_CLIENT_SECURITY
51 #define BTIF_HF_CLIENT_SECURITY    (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
52 #endif
53 
54 #ifndef BTIF_HF_CLIENT_FEATURES
55 #define BTIF_HF_CLIENT_FEATURES   ( BTA_HF_CLIENT_FEAT_ECNR  | \
56                                     BTA_HF_CLIENT_FEAT_3WAY  | \
57                                     BTA_HF_CLIENT_FEAT_CLI   | \
58                                     BTA_HF_CLIENT_FEAT_VREC  | \
59                                     BTA_HF_CLIENT_FEAT_VOL   | \
60                                     BTA_HF_CLIENT_FEAT_ECS   | \
61                                     BTA_HF_CLIENT_FEAT_ECC   | \
62                                     BTA_HF_CLIENT_FEAT_CODEC)
63 #endif
64 
65 /************************************************************************************
66 **  Local type definitions
67 ************************************************************************************/
68 
69 /************************************************************************************
70 **  Static variables
71 ************************************************************************************/
72 static bthf_client_callbacks_t *bt_hf_client_callbacks = NULL;
73 char   btif_hf_client_version[PROPERTY_VALUE_MAX];
74 static UINT32 btif_hf_client_features = 0;
75 
76 
77 #define CHECK_BTHF_CLIENT_INIT() if (bt_hf_client_callbacks == NULL)\
78     {\
79         BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __FUNCTION__);\
80         return BT_STATUS_NOT_READY;\
81     }\
82     else\
83     {\
84         BTIF_TRACE_EVENT("BTHF CLIENT: %s", __FUNCTION__);\
85     }
86 
87 #define CHECK_BTHF_CLIENT_SLC_CONNECTED() if (bt_hf_client_callbacks == NULL)\
88     {\
89         BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __FUNCTION__);\
90         return BT_STATUS_NOT_READY;\
91     }\
92     else if (btif_hf_client_cb.state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED)\
93     {\
94         BTIF_TRACE_WARNING("BTHF CLIENT: %s: SLC connection not up. state=%s",\
95                            __FUNCTION__, \
96                            dump_hf_conn_state(btif_hf_client_cb.state));\
97         return BT_STATUS_NOT_READY;\
98     }\
99     else\
100     {\
101         BTIF_TRACE_EVENT("BTHF CLIENT: %s", __FUNCTION__);\
102     }
103 
104 /* BTIF-HF control block to map bdaddr to BTA handle */
105 typedef struct
106 {
107     UINT16                          handle;
108     bt_bdaddr_t                     connected_bda;
109     bthf_client_connection_state_t  state;
110     bthf_client_vr_state_t          vr_state;
111     tBTA_HF_CLIENT_PEER_FEAT        peer_feat;
112     tBTA_HF_CLIENT_CHLD_FEAT        chld_feat;
113 } btif_hf_client_cb_t;
114 
115 static btif_hf_client_cb_t btif_hf_client_cb;
116 
117 
118 /************************************************************************************
119 **  Static functions
120 ************************************************************************************/
121 
122 /*******************************************************************************
123 **
124 ** Function        btif_in_hf_client_generic_evt
125 **
126 ** Description     Processes generic events to be sent to JNI that are not triggered from the BTA.
127 **                 Always runs in BTIF context
128 **
129 ** Returns          void
130 **
131 *******************************************************************************/
btif_in_hf_client_generic_evt(UINT16 event,char * p_param)132 static void btif_in_hf_client_generic_evt(UINT16 event, char *p_param)
133 {
134     UNUSED(p_param);
135 
136     BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event);
137     switch (event) {
138         case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING:
139         {
140             HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTING,
141                       &btif_hf_client_cb.connected_bda);
142         } break;
143         default:
144         {
145             BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
146         }
147         break;
148     }
149 }
150 
151 /************************************************************************************
152 **  Externs
153 ************************************************************************************/
154 
155 /************************************************************************************
156 **  Functions
157 ************************************************************************************/
158 
clear_state(void)159 static void clear_state(void)
160 {
161     memset(&btif_hf_client_cb, 0, sizeof(btif_hf_client_cb_t));
162 }
163 
is_connected(bt_bdaddr_t * bd_addr)164 static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
165 {
166     if (((btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_CONNECTED) ||
167             (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED))&&
168         ((bd_addr == NULL) || (bdcmp(bd_addr->address, btif_hf_client_cb.connected_bda.address) == 0)))
169         return TRUE;
170     return FALSE;
171 }
172 
173 /*****************************************************************************
174 **   Section name (Group of functions)
175 *****************************************************************************/
176 
177 /*****************************************************************************
178 **
179 **   btif hf api functions (no context switch)
180 **
181 *****************************************************************************/
182 
183 /*******************************************************************************
184 **
185 ** Function         btif_hf_client_init
186 **
187 ** Description     initializes the hf interface
188 **
189 ** Returns         bt_status_t
190 **
191 *******************************************************************************/
init(bthf_client_callbacks_t * callbacks)192 static bt_status_t init( bthf_client_callbacks_t* callbacks )
193 {
194     BTIF_TRACE_EVENT("%s", __FUNCTION__);
195 
196     bt_hf_client_callbacks = callbacks;
197 
198     btif_enable_service(BTA_HFP_HS_SERVICE_ID);
199 
200     clear_state();
201 
202     return BT_STATUS_SUCCESS;
203 }
204 
205 /*******************************************************************************
206 **
207 ** Function         connect
208 **
209 ** Description     connect to audio gateway
210 **
211 ** Returns         bt_status_t
212 **
213 *******************************************************************************/
connect_int(bt_bdaddr_t * bd_addr,uint16_t uuid)214 static bt_status_t connect_int( bt_bdaddr_t *bd_addr, uint16_t uuid )
215 {
216     if (is_connected(bd_addr))
217         return BT_STATUS_BUSY;
218 
219     btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_CONNECTING;
220     bdcpy(btif_hf_client_cb.connected_bda.address, bd_addr->address);
221 
222     BTA_HfClientOpen(btif_hf_client_cb.handle, btif_hf_client_cb.connected_bda.address,
223                BTIF_HF_CLIENT_SECURITY);
224 
225     return BT_STATUS_SUCCESS;
226 }
227 
connect(bt_bdaddr_t * bd_addr)228 static bt_status_t connect( bt_bdaddr_t *bd_addr )
229 {
230     BTIF_TRACE_EVENT("HFP Client version is  %s", btif_hf_client_version);
231     CHECK_BTHF_CLIENT_INIT();
232     return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
233 
234 }
235 
236 /*******************************************************************************
237 **
238 ** Function         disconnect
239 **
240 ** Description      disconnect from audio gateway
241 **
242 ** Returns         bt_status_t
243 **
244 *******************************************************************************/
disconnect(bt_bdaddr_t * bd_addr)245 static bt_status_t disconnect( bt_bdaddr_t *bd_addr )
246 {
247     CHECK_BTHF_CLIENT_INIT();
248 
249     if (is_connected(bd_addr))
250     {
251         BTA_HfClientClose(btif_hf_client_cb.handle);
252         return BT_STATUS_SUCCESS;
253     }
254 
255     return BT_STATUS_FAIL;
256 }
257 
258 /*******************************************************************************
259 **
260 ** Function         connect_audio
261 **
262 ** Description     create an audio connection
263 **
264 ** Returns         bt_status_t
265 **
266 *******************************************************************************/
connect_audio(bt_bdaddr_t * bd_addr)267 static bt_status_t connect_audio( bt_bdaddr_t *bd_addr )
268 {
269     CHECK_BTHF_CLIENT_SLC_CONNECTED();
270 
271     if (is_connected(bd_addr))
272     {
273         if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_CODEC)
274         {
275             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BCC, 0, 0, NULL);
276         }
277         else
278         {
279             BTA_HfClientAudioOpen(btif_hf_client_cb.handle);
280         }
281 
282         /* Inform the application that the audio connection has been initiated successfully */
283         btif_transfer_context(btif_in_hf_client_generic_evt, BTIF_HF_CLIENT_CB_AUDIO_CONNECTING,
284                               (char *)bd_addr, sizeof(bt_bdaddr_t), NULL);
285         return BT_STATUS_SUCCESS;
286     }
287 
288     return BT_STATUS_FAIL;
289 }
290 
291 /*******************************************************************************
292 **
293 ** Function         disconnect_audio
294 **
295 ** Description      close the audio connection
296 **
297 ** Returns         bt_status_t
298 **
299 *******************************************************************************/
disconnect_audio(bt_bdaddr_t * bd_addr)300 static bt_status_t disconnect_audio( bt_bdaddr_t *bd_addr )
301 {
302     CHECK_BTHF_CLIENT_SLC_CONNECTED();
303 
304     if (is_connected(bd_addr))
305     {
306         BTA_HfClientAudioClose(btif_hf_client_cb.handle);
307         return BT_STATUS_SUCCESS;
308     }
309 
310     return BT_STATUS_FAIL;
311 }
312 
313 /*******************************************************************************
314 **
315 ** Function         start_voice_recognition
316 **
317 ** Description      start voice recognition
318 **
319 ** Returns          bt_status_t
320 **
321 *******************************************************************************/
start_voice_recognition()322 static bt_status_t start_voice_recognition()
323 {
324     CHECK_BTHF_CLIENT_SLC_CONNECTED();
325 
326     if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC)
327     {
328         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BVRA, 1, 0, NULL);
329 
330         return BT_STATUS_SUCCESS;
331     }
332 
333     return BT_STATUS_UNSUPPORTED;
334 }
335 
336 /*******************************************************************************
337 **
338 ** Function         stop_voice_recognition
339 **
340 ** Description      stop voice recognition
341 **
342 ** Returns          bt_status_t
343 **
344 *******************************************************************************/
stop_voice_recognition()345 static bt_status_t stop_voice_recognition()
346 {
347     CHECK_BTHF_CLIENT_SLC_CONNECTED();
348 
349     if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC)
350     {
351         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BVRA, 0, 0, NULL);
352 
353         return BT_STATUS_SUCCESS;
354     }
355 
356     return BT_STATUS_UNSUPPORTED;
357 }
358 
359 /*******************************************************************************
360 **
361 ** Function         volume_control
362 **
363 ** Description      volume control
364 **
365 ** Returns          bt_status_t
366 **
367 *******************************************************************************/
volume_control(bthf_client_volume_type_t type,int volume)368 static bt_status_t volume_control(bthf_client_volume_type_t type, int volume)
369 {
370     BOOLEAN speaker;
371 
372     CHECK_BTHF_CLIENT_SLC_CONNECTED();
373 
374     switch (type)
375     {
376         case BTHF_CLIENT_VOLUME_TYPE_SPK:
377             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VGS, volume, 0, NULL);
378             break;
379         case BTHF_CLIENT_VOLUME_TYPE_MIC:
380             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VGM, volume, 0, NULL);
381             break;
382         default:
383             return BT_STATUS_UNSUPPORTED;
384     }
385 
386     return BT_STATUS_SUCCESS;
387 }
388 
389 /*******************************************************************************
390 **
391 ** Function         dial
392 **
393 ** Description      place a call
394 **
395 ** Returns          bt_status_t
396 **
397 *******************************************************************************/
dial(const char * number)398 static bt_status_t dial(const char *number)
399 {
400     CHECK_BTHF_CLIENT_SLC_CONNECTED();
401 
402     if (number)
403     {
404         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATD, 0, 0, number);
405     }
406     else
407     {
408         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BLDN, 0, 0, NULL);
409     }
410 
411     return BT_STATUS_SUCCESS;
412 }
413 
414 /*******************************************************************************
415 **
416 ** Function         dial_memory
417 **
418 ** Description      place a call with number specified by location (speed dial)
419 **
420 ** Returns          bt_status_t
421 **
422 *******************************************************************************/
dial_memory(int location)423 static bt_status_t dial_memory(int location)
424 {
425     CHECK_BTHF_CLIENT_SLC_CONNECTED();
426 
427     BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATD, location, 0, NULL);
428 
429     return BT_STATUS_SUCCESS;
430 }
431 
432 /*******************************************************************************
433 **
434 ** Function         handle_call_action
435 **
436 ** Description      handle specified call related action
437 **
438 ** Returns          bt_status_t
439 **
440 *******************************************************************************/
handle_call_action(bthf_client_call_action_t action,int idx)441 static bt_status_t handle_call_action(bthf_client_call_action_t action, int idx)
442 {
443     CHECK_BTHF_CLIENT_SLC_CONNECTED();
444 
445     switch (action)
446     {
447     case BTHF_CLIENT_CALL_ACTION_CHLD_0:
448         if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_REL)
449         {
450             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 0, 0, NULL);
451             break;
452         }
453         return BT_STATUS_UNSUPPORTED;
454     case BTHF_CLIENT_CALL_ACTION_CHLD_1:
455         // CHLD 1 is mandatory for 3 way calling
456         if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY)
457         {
458             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, 0, NULL);
459             break;
460         }
461         return BT_STATUS_UNSUPPORTED;
462     case BTHF_CLIENT_CALL_ACTION_CHLD_2:
463         // CHLD 2 is mandatory for 3 way calling
464         if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY)
465         {
466             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, 0, NULL);
467             break;
468         }
469         return BT_STATUS_UNSUPPORTED;
470     case BTHF_CLIENT_CALL_ACTION_CHLD_3:
471         if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_MERGE)
472         {
473             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 3, 0, NULL);
474             break;
475         }
476         return BT_STATUS_UNSUPPORTED;
477     case BTHF_CLIENT_CALL_ACTION_CHLD_4:
478         if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_MERGE_DETACH)
479         {
480             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 4, 0, NULL);
481             break;
482         }
483         return BT_STATUS_UNSUPPORTED;
484     case BTHF_CLIENT_CALL_ACTION_CHLD_1x:
485         if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECC)
486         {
487             if (idx < 1)
488             {
489                 return BT_STATUS_FAIL;
490             }
491             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, idx, NULL);
492             break;
493         }
494         return BT_STATUS_UNSUPPORTED;
495     case BTHF_CLIENT_CALL_ACTION_CHLD_2x:
496         if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECC)
497         {
498             if (idx < 1)
499             {
500                 return BT_STATUS_FAIL;
501             }
502             BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, idx, NULL);
503             break;
504         }
505         return BT_STATUS_UNSUPPORTED;
506     case BTHF_CLIENT_CALL_ACTION_ATA:
507         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATA, 0, 0, NULL);
508         break;
509     case BTHF_CLIENT_CALL_ACTION_CHUP:
510         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHUP, 0, 0, NULL);
511         break;
512     case BTHF_CLIENT_CALL_ACTION_BTRH_0:
513         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 0, 0, NULL);
514         break;
515     case BTHF_CLIENT_CALL_ACTION_BTRH_1:
516         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 1, 0, NULL);
517         break;
518     case BTHF_CLIENT_CALL_ACTION_BTRH_2:
519         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 2, 0, NULL);
520         break;
521     default:
522         return BT_STATUS_FAIL;
523 
524     }
525 
526     return BT_STATUS_SUCCESS;
527 }
528 
529 /*******************************************************************************
530 **
531 ** Function         query_current_calls
532 **
533 ** Description      query list of current calls
534 **
535 ** Returns          bt_status_t
536 **
537 *******************************************************************************/
query_current_calls(void)538 static bt_status_t query_current_calls(void)
539 {
540     CHECK_BTHF_CLIENT_SLC_CONNECTED();
541 
542     if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECS)
543     {
544         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CLCC, 0, 0, NULL);
545 
546         return BT_STATUS_SUCCESS;
547     }
548 
549     return BT_STATUS_UNSUPPORTED;
550 }
551 
552 /*******************************************************************************
553 **
554 ** Function         query_current_operator_name
555 **
556 ** Description      query current selected operator name
557 **
558 ** Returns          bt_status_t
559 **
560 *******************************************************************************/
query_current_operator_name(void)561 static bt_status_t query_current_operator_name(void)
562 {
563     CHECK_BTHF_CLIENT_SLC_CONNECTED();
564 
565     BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_COPS, 0, 0, NULL);
566 
567     return BT_STATUS_SUCCESS;
568 }
569 
570 /*******************************************************************************
571 **
572 ** Function         retieve_subscriber_info
573 **
574 ** Description      retrieve subscriber number information
575 **
576 ** Returns          bt_status_t
577 **
578 *******************************************************************************/
retrieve_subscriber_info(void)579 static bt_status_t retrieve_subscriber_info(void)
580 {
581     CHECK_BTHF_CLIENT_SLC_CONNECTED();
582 
583     BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CNUM, 0, 0, NULL);
584 
585     return BT_STATUS_SUCCESS;
586 }
587 
588 /*******************************************************************************
589 **
590 ** Function         send_dtmf
591 **
592 ** Description      send dtmf
593 **
594 ** Returns          bt_status_t
595 **
596 *******************************************************************************/
send_dtmf(char code)597 static bt_status_t send_dtmf(char code)
598 {
599     CHECK_BTHF_CLIENT_SLC_CONNECTED();
600 
601     BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VTS, code, 0, NULL);
602 
603     return BT_STATUS_SUCCESS;
604 }
605 
606 /*******************************************************************************
607 **
608 ** Function         request_last_voice_tag_number
609 **
610 ** Description      Request number from AG for VR purposes
611 **
612 ** Returns          bt_status_t
613 **
614 *******************************************************************************/
request_last_voice_tag_number(void)615 static bt_status_t request_last_voice_tag_number(void)
616 {
617     CHECK_BTHF_CLIENT_SLC_CONNECTED();
618 
619     if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_VTAG)
620     {
621         BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BINP, 1, 0, NULL);
622 
623         return BT_STATUS_SUCCESS;
624     }
625 
626     return BT_STATUS_UNSUPPORTED;
627 }
628 
629 /*******************************************************************************
630 **
631 ** Function         cleanup
632 **
633 ** Description      Closes the HF interface
634 **
635 ** Returns          bt_status_t
636 **
637 *******************************************************************************/
cleanup(void)638 static void  cleanup( void )
639 {
640     BTIF_TRACE_EVENT("%s", __FUNCTION__);
641 
642     if (bt_hf_client_callbacks)
643     {
644         btif_disable_service(BTA_HFP_HS_SERVICE_ID);
645         bt_hf_client_callbacks = NULL;
646     }
647 }
648 
649 /*******************************************************************************
650 **
651 ** Function         send_at_cmd
652 **
653 ** Description      Send requested AT command to rempte device.
654 **
655 ** Returns          bt_status_t
656 **
657 *******************************************************************************/
send_at_cmd(int cmd,int val1,int val2,const char * arg)658 static bt_status_t send_at_cmd(int cmd,int val1,int val2,const char *arg)
659 {
660     CHECK_BTHF_CLIENT_SLC_CONNECTED();
661     BTIF_TRACE_EVENT("%s Cmd %d val1 %d val2 %d arg %s",
662             __FUNCTION__,cmd,val1,val2,arg);
663     BTA_HfClientSendAT(btif_hf_client_cb.handle, cmd, val1, val2, arg);
664 
665     return BT_STATUS_SUCCESS;
666 }
667 
668 static const bthf_client_interface_t bthfClientInterface = {
669     sizeof(bthf_client_interface_t),
670     .init = init,
671     .connect = connect,
672     .disconnect = disconnect,
673     .connect_audio = connect_audio,
674     .disconnect_audio = disconnect_audio,
675     .start_voice_recognition = start_voice_recognition,
676     .stop_voice_recognition = stop_voice_recognition,
677     .volume_control = volume_control,
678     .dial = dial,
679     .dial_memory = dial_memory,
680     .handle_call_action = handle_call_action,
681     .query_current_calls = query_current_calls,
682     .query_current_operator_name = query_current_operator_name,
683     .retrieve_subscriber_info = retrieve_subscriber_info,
684     .send_dtmf = send_dtmf,
685     .request_last_voice_tag_number = request_last_voice_tag_number,
686     .cleanup = cleanup,
687     .send_at_cmd = send_at_cmd,
688 };
689 
process_ind_evt(tBTA_HF_CLIENT_IND * ind)690 static void process_ind_evt(tBTA_HF_CLIENT_IND *ind)
691 {
692     switch (ind->type)
693     {
694         case BTA_HF_CLIENT_IND_CALL:
695             HAL_CBACK(bt_hf_client_callbacks, call_cb, ind->value);
696             break;
697 
698         case BTA_HF_CLIENT_IND_CALLSETUP:
699             HAL_CBACK(bt_hf_client_callbacks, callsetup_cb, ind->value);
700             break;
701         case BTA_HF_CLIENT_IND_CALLHELD:
702             HAL_CBACK(bt_hf_client_callbacks, callheld_cb, ind->value);
703             break;
704 
705         case BTA_HF_CLIENT_IND_SERVICE:
706             HAL_CBACK(bt_hf_client_callbacks, network_state_cb, ind->value);
707             break;
708 
709         case BTA_HF_CLIENT_IND_SIGNAL:
710             HAL_CBACK(bt_hf_client_callbacks, network_signal_cb, ind->value);
711             break;
712 
713         case BTA_HF_CLIENT_IND_ROAM:
714             HAL_CBACK(bt_hf_client_callbacks, network_roaming_cb, ind->value);
715             break;
716 
717         case BTA_HF_CLIENT_IND_BATTCH:
718             HAL_CBACK(bt_hf_client_callbacks, battery_level_cb, ind->value);
719             break;
720 
721         default:
722             break;
723     }
724 }
725 
726 /*******************************************************************************
727 **
728 ** Function         btif_hf_client_upstreams_evt
729 **
730 ** Description      Executes HF CLIENT UPSTREAMS events in btif context
731 **
732 ** Returns          void
733 **
734 *******************************************************************************/
btif_hf_client_upstreams_evt(UINT16 event,char * p_param)735 static void btif_hf_client_upstreams_evt(UINT16 event, char* p_param)
736 {
737     tBTA_HF_CLIENT *p_data = (tBTA_HF_CLIENT *)p_param;
738     bdstr_t bdstr;
739 
740     BTIF_TRACE_DEBUG("%s: event=%s (%u)", __FUNCTION__, dump_hf_client_event(event), event);
741 
742     switch (event)
743     {
744         case BTA_HF_CLIENT_ENABLE_EVT:
745         case BTA_HF_CLIENT_DISABLE_EVT:
746             break;
747 
748         case BTA_HF_CLIENT_REGISTER_EVT:
749             btif_hf_client_cb.handle = p_data->reg.handle;
750             break;
751 
752         case BTA_HF_CLIENT_OPEN_EVT:
753             if (p_data->open.status == BTA_HF_CLIENT_SUCCESS)
754             {
755                 bdcpy(btif_hf_client_cb.connected_bda.address, p_data->open.bd_addr);
756                 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED;
757                 btif_hf_client_cb.peer_feat = 0;
758                 btif_hf_client_cb.chld_feat = 0;
759                 //clear_phone_state();
760             }
761             else if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING)
762             {
763                 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
764             }
765             else
766             {
767                 BTIF_TRACE_WARNING("%s: HF CLient open failed, but another device connected. status=%d state=%d connected device=%s",
768                         __FUNCTION__, p_data->open.status, btif_hf_client_cb.state, bd2str(&btif_hf_client_cb.connected_bda, &bdstr));
769                 break;
770             }
771 
772             HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state,
773                         0, 0, &btif_hf_client_cb.connected_bda);
774 
775             if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
776                 bdsetany(btif_hf_client_cb.connected_bda.address);
777 
778             if (p_data->open.status != BTA_HF_CLIENT_SUCCESS)
779                 btif_queue_advance();
780             break;
781 
782         case BTA_HF_CLIENT_CONN_EVT:
783             btif_hf_client_cb.peer_feat = p_data->conn.peer_feat;
784             btif_hf_client_cb.chld_feat = p_data->conn.chld_feat;
785             btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED;
786 
787             HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state,
788                         btif_hf_client_cb.peer_feat, btif_hf_client_cb.chld_feat,
789                         &btif_hf_client_cb.connected_bda);
790 
791             /* Inform the application about in-band ringtone */
792             if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_INBAND)
793             {
794                 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
795             }
796 
797             btif_queue_advance();
798             break;
799 
800         case BTA_HF_CLIENT_CLOSE_EVT:
801             btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
802             HAL_CBACK(bt_hf_client_callbacks, connection_state_cb,  btif_hf_client_cb.state,
803                         0, 0, &btif_hf_client_cb.connected_bda);
804             bdsetany(btif_hf_client_cb.connected_bda.address);
805             btif_hf_client_cb.peer_feat = 0;
806             btif_hf_client_cb.chld_feat = 0;
807             btif_queue_advance();
808             break;
809 
810         case BTA_HF_CLIENT_IND_EVT:
811             process_ind_evt(&p_data->ind);
812             break;
813 
814         case BTA_HF_CLIENT_MIC_EVT:
815             HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value);
816             break;
817 
818         case BTA_HF_CLIENT_SPK_EVT:
819             HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value);
820             break;
821 
822         case BTA_HF_CLIENT_VOICE_REC_EVT:
823             HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, p_data->val.value);
824             break;
825 
826         case BTA_HF_CLIENT_OPERATOR_NAME_EVT:
827             HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, p_data->operator.name);
828             break;
829 
830         case BTA_HF_CLIENT_CLIP_EVT:
831             HAL_CBACK(bt_hf_client_callbacks, clip_cb, p_data->number.number);
832             break;
833 
834         case BTA_HF_CLIENT_BINP_EVT:
835             HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback, p_data->number.number);
836             break;
837 
838         case BTA_HF_CLIENT_CCWA_EVT:
839             HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, p_data->number.number);
840             break;
841 
842         case BTA_HF_CLIENT_AT_RESULT_EVT:
843             HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, p_data->result.type, p_data->result.cme);
844             break;
845 
846         case BTA_HF_CLIENT_CLCC_EVT:
847             HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, p_data->clcc.idx,
848                         p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING : BTHF_CLIENT_CALL_DIRECTION_OUTGOING,
849                         p_data->clcc.status,
850                         p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE,
851                         p_data->clcc.number_present ? p_data->clcc.number : NULL);
852             break;
853 
854         case BTA_HF_CLIENT_CNUM_EVT:
855             if (p_data->cnum.service == 4)
856             {
857                 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE);
858             }
859             else if (p_data->cnum.service == 5)
860             {
861                 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX);
862             }
863             else
864             {
865                 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN);
866             }
867             break;
868 
869         case BTA_HF_CLIENT_BTRH_EVT:
870             if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT)
871             {
872                 HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, p_data->val.value);
873             }
874             break;
875 
876         case BTA_HF_CLIENT_BSIR_EVT:
877             if (p_data->val.value != 0)
878             {
879                 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
880             }
881             else
882             {
883                 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED);
884             }
885             break;
886 
887         case BTA_HF_CLIENT_AUDIO_OPEN_EVT:
888             HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED, &btif_hf_client_cb.connected_bda);
889             break;
890 
891         case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT:
892             HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, &btif_hf_client_cb.connected_bda);
893             break;
894 
895         case BTA_HF_CLIENT_AUDIO_CLOSE_EVT:
896             HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_DISCONNECTED, &btif_hf_client_cb.connected_bda);
897             break;
898         case BTA_HF_CLIENT_RING_INDICATION:
899             HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb);
900             break;
901         default:
902             BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
903             break;
904     }
905 }
906 
907 /*******************************************************************************
908 **
909 ** Function         bte_hf_client_evt
910 **
911 ** Description      Switches context from BTE to BTIF for all HF Client events
912 **
913 ** Returns          void
914 **
915 *******************************************************************************/
916 
bte_hf_client_evt(tBTA_HF_CLIENT_EVT event,tBTA_HF_CLIENT * p_data)917 static void bte_hf_client_evt(tBTA_HF_CLIENT_EVT event, tBTA_HF_CLIENT *p_data)
918 {
919     bt_status_t status;
920 
921     /* switch context to btif task context (copy full union size for convenience) */
922     status = btif_transfer_context(btif_hf_client_upstreams_evt, (uint16_t)event, (void*)p_data, sizeof(*p_data), NULL);
923 
924     /* catch any failed context transfers */
925     ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
926 }
927 
928 /*******************************************************************************
929 **
930 ** Function         btif_hf_client_execute_service
931 **
932 ** Description      Initializes/Shuts down the service
933 **
934 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
935 **
936 *******************************************************************************/
btif_hf_client_execute_service(BOOLEAN b_enable)937 bt_status_t btif_hf_client_execute_service(BOOLEAN b_enable)
938 {
939     BTIF_TRACE_EVENT("%s enable:%d", __FUNCTION__, b_enable);
940 
941     property_get("ro.bluetooth.hfp.ver", btif_hf_client_version, "1.5");
942 
943      if (b_enable)
944      {
945           /* Enable and register with BTA-HFClient */
946           BTA_HfClientEnable(bte_hf_client_evt);
947           if (strcmp(btif_hf_client_version, "1.6") == 0)
948           {
949               BTIF_TRACE_EVENT("Support Codec Nego. %d ", BTIF_HF_CLIENT_FEATURES);
950               BTA_HfClientRegister(BTIF_HF_CLIENT_SECURITY, BTIF_HF_CLIENT_FEATURES,
951                       BTIF_HF_CLIENT_SERVICE_NAME);
952           }
953           else
954           {
955               BTIF_TRACE_EVENT("No Codec Nego Supported");
956               btif_hf_client_features = BTIF_HF_CLIENT_FEATURES;
957               btif_hf_client_features = btif_hf_client_features & (~BTA_HF_CLIENT_FEAT_CODEC);
958               BTIF_TRACE_EVENT("btif_hf_client_features is   %d", btif_hf_client_features);
959               BTA_HfClientRegister(BTIF_HF_CLIENT_SECURITY, btif_hf_client_features,
960                       BTIF_HF_CLIENT_SERVICE_NAME);
961           }
962 
963      }
964      else
965      {
966          BTA_HfClientDeregister(btif_hf_client_cb.handle);
967          BTA_HfClientDisable();
968      }
969      return BT_STATUS_SUCCESS;
970 }
971 
972 /*******************************************************************************
973 **
974 ** Function         btif_hf_get_interface
975 **
976 ** Description      Get the hf callback interface
977 **
978 ** Returns          bthf_interface_t
979 **
980 *******************************************************************************/
btif_hf_client_get_interface(void)981 const bthf_client_interface_t *btif_hf_client_get_interface(void)
982 {
983     BTIF_TRACE_EVENT("%s", __FUNCTION__);
984     return &bthfClientInterface;
985 }
986