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************************************************************************************/
72static bthf_client_callbacks_t *bt_hf_client_callbacks = NULL;
73char   btif_hf_client_version[PROPERTY_VALUE_MAX];
74static 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 */
105typedef 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
115static 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*******************************************************************************/
132static 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
159static void clear_state(void)
160{
161    memset(&btif_hf_client_cb, 0, sizeof(btif_hf_client_cb_t));
162}
163
164static 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*******************************************************************************/
192static 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*******************************************************************************/
214static 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
228static 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*******************************************************************************/
245static 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*******************************************************************************/
267static 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*******************************************************************************/
300static 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*******************************************************************************/
322static 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*******************************************************************************/
345static 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*******************************************************************************/
368static 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*******************************************************************************/
398static 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*******************************************************************************/
423static 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*******************************************************************************/
441static 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*******************************************************************************/
538static 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*******************************************************************************/
561static 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*******************************************************************************/
579static 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*******************************************************************************/
597static 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*******************************************************************************/
615static 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*******************************************************************************/
638static 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*******************************************************************************/
658static 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
668static 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
690static 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*******************************************************************************/
735static 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
917static 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*******************************************************************************/
937bt_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*******************************************************************************/
981const bthf_client_interface_t *btif_hf_client_get_interface(void)
982{
983    BTIF_TRACE_EVENT("%s", __FUNCTION__);
984    return &bthfClientInterface;
985}
986