Home | History | Annotate | Download | only in src
      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 *******************************************************************************/
    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 
    159 static void clear_state(void)
    160 {
    161     memset(&btif_hf_client_cb, 0, sizeof(btif_hf_client_cb_t));
    162 }
    163 
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 
    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 *******************************************************************************/
    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 
    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 *******************************************************************************/
    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 *******************************************************************************/
    981 const bthf_client_interface_t *btif_hf_client_get_interface(void)
    982 {
    983     BTIF_TRACE_EVENT("%s", __FUNCTION__);
    984     return &bthfClientInterface;
    985 }
    986