Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (c) 2014 The Android Open Source Project
      4  *  Copyright 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  *  Notes:
     27  *  a) Lifecycle of a control block
     28  *  Control block handles the lifecycle for a particular remote device's
     29  *  connection. The connection can go via the classic phases but more
     30  *  importantly there's only two messages from BTA that affect this.
     31  *  BTA_HF_CLIENT_OPEN_EVT and BTA_HF_CLIENT_CLOSE_EVT. Since the API between
     32  *  BTIF and BTA is controlled entirely by handles it's important to know where
     33  *  the handles are created and destroyed. Handles can be created at two
     34  *  locations:
     35  *  -- While connect() is called from BTIF. This is an outgoing connection
     36  *  -- While accepting an incoming connection (see BTA_HF_CLIENT_OPEN_EVT
     37  *  handling).
     38  *
     39  *  The destruction or rather reuse of handles can be done when
     40  *  BTA_HF_CLIENT_CLOSE_EVT is called. Refer to the event handling for details
     41  *  of this.
     42  *
     43  ******************************************************************************/
     44 
     45 #define LOG_TAG "bt_btif_hfc"
     46 
     47 #include <stdlib.h>
     48 #include <string.h>
     49 
     50 #include <hardware/bluetooth.h>
     51 #include <hardware/bt_hf_client.h>
     52 
     53 #include "bt_utils.h"
     54 #include "bta_hf_client_api.h"
     55 #include "btif_common.h"
     56 #include "btif_profile_queue.h"
     57 #include "btif_util.h"
     58 #include "osi/include/osi.h"
     59 #include "osi/include/properties.h"
     60 
     61 /*******************************************************************************
     62  *  Constants & Macros
     63  ******************************************************************************/
     64 
     65 #ifndef BTIF_HF_CLIENT_SERVICE_NAME
     66 #define BTIF_HF_CLIENT_SERVICE_NAME ("Handsfree")
     67 #endif
     68 
     69 #ifndef BTIF_HF_CLIENT_SECURITY
     70 #define BTIF_HF_CLIENT_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
     71 #endif
     72 
     73 #ifndef BTIF_HF_CLIENT_FEATURES
     74 #define BTIF_HF_CLIENT_FEATURES                                                \
     75   (BTA_HF_CLIENT_FEAT_ECNR | BTA_HF_CLIENT_FEAT_3WAY |                         \
     76    BTA_HF_CLIENT_FEAT_CLI | BTA_HF_CLIENT_FEAT_VREC | BTA_HF_CLIENT_FEAT_VOL | \
     77    BTA_HF_CLIENT_FEAT_ECS | BTA_HF_CLIENT_FEAT_ECC | BTA_HF_CLIENT_FEAT_CODEC)
     78 #endif
     79 
     80 /*******************************************************************************
     81  *  Local type definitions
     82  ******************************************************************************/
     83 /* BTIF-HF control block to map bdaddr to BTA handle */
     84 typedef struct {
     85   uint16_t handle;                       // Handle obtained frm the BTA
     86   RawAddress peer_bda;                   // Device corresponding to handle
     87   bthf_client_connection_state_t state;  // State of current connection
     88   tBTA_HF_CLIENT_PEER_FEAT peer_feat;    // HF features
     89   tBTA_HF_CLIENT_CHLD_FEAT chld_feat;    // AT+CHLD=<> command features
     90 } btif_hf_client_cb_t;
     91 
     92 /* Max devices supported by BTIF (useful to match the value in BTA) */
     93 #define HF_CLIENT_MAX_DEVICES 10
     94 typedef struct {
     95   btif_hf_client_cb_t cb[HF_CLIENT_MAX_DEVICES];
     96 } btif_hf_client_cb_arr_t;
     97 
     98 /******************************************************************************
     99  * Local function declarations
    100  ******************************************************************************/
    101 btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle);
    102 btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& addr);
    103 bool is_connected(const btif_hf_client_cb_t* cb);
    104 
    105 /*******************************************************************************
    106  *  Static variables
    107  ******************************************************************************/
    108 static bthf_client_callbacks_t* bt_hf_client_callbacks = NULL;
    109 
    110 char btif_hf_client_version[PROPERTY_VALUE_MAX];
    111 
    112 static const char* dump_hf_client_conn_state(uint16_t event) {
    113   switch (event) {
    114     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
    115     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_CONNECTING)
    116     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_CONNECTED)
    117     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED)
    118     CASE_RETURN_STR(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING)
    119     default:
    120       return "UNKNOWN MSG ID";
    121   }
    122 }
    123 
    124 #define CHECK_BTHF_CLIENT_INIT()                                        \
    125   do {                                                                  \
    126     if (bt_hf_client_callbacks == NULL) {                               \
    127       BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __func__); \
    128       return BT_STATUS_NOT_READY;                                       \
    129     } else {                                                            \
    130       BTIF_TRACE_EVENT("BTHF CLIENT: %s", __func__);                    \
    131     }                                                                   \
    132   } while (0)
    133 
    134 #define CHECK_BTHF_CLIENT_SLC_CONNECTED(cb)                                  \
    135   do {                                                                       \
    136     if (bt_hf_client_callbacks == NULL) {                                    \
    137       BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __func__);      \
    138       return BT_STATUS_NOT_READY;                                            \
    139     } else if ((cb)->state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) {  \
    140       BTIF_TRACE_WARNING("BTHF CLIENT: %s: SLC connection not up. state=%s", \
    141                          __func__, dump_hf_client_conn_state((cb)->state));  \
    142       return BT_STATUS_NOT_READY;                                            \
    143     } else {                                                                 \
    144       BTIF_TRACE_EVENT("BTHF CLIENT: %s", __func__);                         \
    145     }                                                                        \
    146   } while (0)
    147 
    148 static btif_hf_client_cb_arr_t btif_hf_client_cb_arr;
    149 
    150 /*******************************************************************************
    151  *  Static functions
    152  ******************************************************************************/
    153 
    154 /*******************************************************************************
    155  *
    156  * Function        btif_in_hf_client_generic_evt
    157  *
    158  * Description     Processes generic events to be sent to JNI that are not
    159  *                 triggered from the BTA.
    160  *                 Always runs in BTIF context
    161  *
    162  * Returns          void
    163  *
    164  ******************************************************************************/
    165 static void btif_in_hf_client_generic_evt(uint16_t event, char* p_param) {
    166   BTIF_TRACE_DEBUG("%s", __func__);
    167   RawAddress* bd_addr = (RawAddress*)p_param;
    168   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    169   if (cb == NULL || !is_connected(cb)) {
    170     BTIF_TRACE_ERROR("%s: failed to find block for bda", __func__);
    171   }
    172 
    173   BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
    174   switch (event) {
    175     case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING: {
    176       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
    177                 (bthf_client_audio_state_t)BTHF_CLIENT_AUDIO_STATE_CONNECTING);
    178     } break;
    179     default: {
    180       BTIF_TRACE_WARNING("%s: : Unknown event 0x%x", __func__, event);
    181     } break;
    182   }
    183 }
    184 
    185 /*******************************************************************************
    186  *  Functions
    187  ******************************************************************************/
    188 bool is_connected(const btif_hf_client_cb_t* cb) {
    189   if ((cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTED) ||
    190       (cb->state == BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED))
    191     return true;
    192 
    193   BTIF_TRACE_ERROR("%s: not connected!", __func__);
    194   return false;
    195 }
    196 
    197 /*******************************************************************************
    198  *
    199  * Function        btif_hf_client_get_cb_by_handle
    200  *
    201  * Description     Get control block by handle
    202  *
    203  * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
    204  *
    205  ******************************************************************************/
    206 btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle) {
    207   BTIF_TRACE_DEBUG("%s: cb by handle %d", __func__, handle);
    208   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    209     // Block is valid only if it is allocated i.e. state is not DISCONNECTED
    210     if (btif_hf_client_cb_arr.cb[i].state !=
    211             BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
    212         btif_hf_client_cb_arr.cb[i].handle == handle) {
    213       return &btif_hf_client_cb_arr.cb[i];
    214     }
    215   }
    216   BTIF_TRACE_ERROR("%s: could not find block for handle %d", __func__, handle);
    217   return NULL;
    218 }
    219 
    220 /*******************************************************************************
    221  *
    222  * Function        btif_hf_client_get_cb_by_bda
    223  *
    224  * Description     Get control block by bda
    225  *
    226  * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
    227  *
    228  ******************************************************************************/
    229 btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& bd_addr) {
    230   VLOG(1) << __func__ << " incoming addr " << bd_addr;
    231 
    232   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    233     // Block is valid only if it is allocated i.e. state is not DISCONNECTED
    234     if (btif_hf_client_cb_arr.cb[i].state !=
    235             BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
    236         btif_hf_client_cb_arr.cb[i].peer_bda == bd_addr) {
    237       return &btif_hf_client_cb_arr.cb[i];
    238     }
    239   }
    240   BTIF_TRACE_ERROR("%s: could not find block for bdaddr", __func__);
    241   return NULL;
    242 }
    243 
    244 /*******************************************************************************
    245  *
    246  * Function        btif_hf_client_allocate_cb
    247  *
    248  * Description     Get control block by bda
    249  *
    250  * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
    251  *
    252  ******************************************************************************/
    253 btif_hf_client_cb_t* btif_hf_client_allocate_cb() {
    254   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    255     btif_hf_client_cb_t* cb = &btif_hf_client_cb_arr.cb[i];
    256     if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED) {
    257       return cb;
    258     }
    259   }
    260   BTIF_TRACE_ERROR("%s: unable to allocate control block", __func__);
    261   return NULL;
    262 }
    263 
    264 /*****************************************************************************
    265  *
    266  *   btif hf api functions (no context switch)
    267  *
    268  ****************************************************************************/
    269 
    270 /*******************************************************************************
    271  *
    272  * Function         btif_hf_client_init
    273  *
    274  * Description     initializes the hf interface
    275  *
    276  * Returns         bt_status_t
    277  *
    278  ******************************************************************************/
    279 static bt_status_t init(bthf_client_callbacks_t* callbacks) {
    280   BTIF_TRACE_EVENT("%s", __func__);
    281 
    282   bt_hf_client_callbacks = callbacks;
    283 
    284   btif_enable_service(BTA_HFP_HS_SERVICE_ID);
    285 
    286   memset(&btif_hf_client_cb_arr, 0, sizeof(btif_hf_client_cb_arr_t));
    287 
    288   return BT_STATUS_SUCCESS;
    289 }
    290 
    291 /*******************************************************************************
    292  *
    293  * Function         connect
    294  *
    295  * Description     connect to audio gateway
    296  *
    297  * Returns         bt_status_t
    298  *
    299  ******************************************************************************/
    300 static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) {
    301   btif_hf_client_cb_t* cb = btif_hf_client_allocate_cb();
    302   if (cb == NULL) {
    303     BTIF_TRACE_ERROR("%s: could not allocate block!", __func__);
    304     return BT_STATUS_BUSY;
    305   }
    306 
    307   cb->peer_bda = *bd_addr;
    308   if (is_connected(cb)) return BT_STATUS_BUSY;
    309 
    310   cb->state = BTHF_CLIENT_CONNECTION_STATE_CONNECTING;
    311   cb->peer_bda = *bd_addr;
    312 
    313   /* Open HF connection to remote device and get the relevant handle.
    314    * The handle is valid until we have called BTA_HfClientClose or the LL
    315    * has notified us of channel close due to remote closing, error etc.
    316    */
    317   BTA_HfClientOpen(cb->peer_bda, BTIF_HF_CLIENT_SECURITY, &cb->handle);
    318 
    319   return BT_STATUS_SUCCESS;
    320 }
    321 
    322 static bt_status_t connect(RawAddress* bd_addr) {
    323   BTIF_TRACE_EVENT("HFP Client version is  %s", btif_hf_client_version);
    324   CHECK_BTHF_CLIENT_INIT();
    325   return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
    326 }
    327 
    328 /*******************************************************************************
    329  *
    330  * Function         disconnect
    331  *
    332  * Description      disconnect from audio gateway
    333  *
    334  * Returns         bt_status_t
    335  *
    336  ******************************************************************************/
    337 static bt_status_t disconnect(const RawAddress* bd_addr) {
    338   CHECK_BTHF_CLIENT_INIT();
    339 
    340   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    341   if (cb != NULL) {
    342     BTA_HfClientClose(cb->handle);
    343     return BT_STATUS_SUCCESS;
    344   } else {
    345     return BT_STATUS_BUSY;
    346   }
    347 }
    348 
    349 /*******************************************************************************
    350  *
    351  * Function         connect_audio
    352  *
    353  * Description     create an audio connection
    354  *
    355  * Returns         bt_status_t
    356  *
    357  ******************************************************************************/
    358 static bt_status_t connect_audio(const RawAddress* bd_addr) {
    359   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    360   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    361 
    362   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    363 
    364   if ((BTIF_HF_CLIENT_FEATURES & BTA_HF_CLIENT_FEAT_CODEC) &&
    365       (cb->peer_feat & BTA_HF_CLIENT_PEER_CODEC)) {
    366     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BCC, 0, 0, NULL);
    367   } else {
    368     BTA_HfClientAudioOpen(cb->handle);
    369   }
    370 
    371   /* Inform the application that the audio connection has been initiated
    372    * successfully */
    373   btif_transfer_context(btif_in_hf_client_generic_evt,
    374                         BTIF_HF_CLIENT_CB_AUDIO_CONNECTING, (char*)bd_addr,
    375                         sizeof(RawAddress), NULL);
    376   return BT_STATUS_SUCCESS;
    377 }
    378 
    379 /*******************************************************************************
    380  *
    381  * Function         disconnect_audio
    382  *
    383  * Description      close the audio connection
    384  *
    385  * Returns         bt_status_t
    386  *
    387  ******************************************************************************/
    388 static bt_status_t disconnect_audio(const RawAddress* bd_addr) {
    389   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    390   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    391 
    392   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    393 
    394   BTA_HfClientAudioClose(cb->handle);
    395   return BT_STATUS_SUCCESS;
    396 }
    397 
    398 /*******************************************************************************
    399  *
    400  * Function         start_voice_recognition
    401  *
    402  * Description      start voice recognition
    403  *
    404  * Returns          bt_status_t
    405  *
    406  ******************************************************************************/
    407 static bt_status_t start_voice_recognition(const RawAddress* bd_addr) {
    408   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    409   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    410 
    411   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    412 
    413   if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) {
    414     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BVRA, 1, 0, NULL);
    415     return BT_STATUS_SUCCESS;
    416   }
    417   return BT_STATUS_UNSUPPORTED;
    418 }
    419 
    420 /*******************************************************************************
    421  *
    422  * Function         stop_voice_recognition
    423  *
    424  * Description      stop voice recognition
    425  *
    426  * Returns          bt_status_t
    427  *
    428  ******************************************************************************/
    429 static bt_status_t stop_voice_recognition(const RawAddress* bd_addr) {
    430   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    431   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    432 
    433   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    434 
    435   if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC) {
    436     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BVRA, 0, 0, NULL);
    437     return BT_STATUS_SUCCESS;
    438   }
    439   return BT_STATUS_UNSUPPORTED;
    440 }
    441 
    442 /*******************************************************************************
    443  *
    444  * Function         volume_control
    445  *
    446  * Description      volume control
    447  *
    448  * Returns          bt_status_t
    449  *
    450  ******************************************************************************/
    451 static bt_status_t volume_control(const RawAddress* bd_addr,
    452                                   bthf_client_volume_type_t type, int volume) {
    453   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    454   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    455 
    456   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    457 
    458   switch (type) {
    459     case BTHF_CLIENT_VOLUME_TYPE_SPK:
    460       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VGS, volume, 0, NULL);
    461       break;
    462     case BTHF_CLIENT_VOLUME_TYPE_MIC:
    463       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VGM, volume, 0, NULL);
    464       break;
    465     default:
    466       return BT_STATUS_UNSUPPORTED;
    467   }
    468 
    469   return BT_STATUS_SUCCESS;
    470 }
    471 
    472 /*******************************************************************************
    473  *
    474  * Function         dial
    475  *
    476  * Description      place a call
    477  *
    478  * Returns          bt_status_t
    479  *
    480  ******************************************************************************/
    481 static bt_status_t dial(UNUSED_ATTR const RawAddress* bd_addr,
    482                         const char* number) {
    483   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    484   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    485 
    486   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    487 
    488   if (number) {
    489     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATD, 0, 0, number);
    490   } else {
    491     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BLDN, 0, 0, NULL);
    492   }
    493   return BT_STATUS_SUCCESS;
    494 }
    495 
    496 /*******************************************************************************
    497  *
    498  * Function         dial_memory
    499  *
    500  * Description      place a call with number specified by location (speed dial)
    501  *
    502  * Returns          bt_status_t
    503  *
    504  ******************************************************************************/
    505 static bt_status_t dial_memory(const RawAddress* bd_addr, int location) {
    506   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    507   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    508 
    509   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    510 
    511   BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATD, location, 0, NULL);
    512   return BT_STATUS_SUCCESS;
    513 }
    514 
    515 /*******************************************************************************
    516  *
    517  * Function         handle_call_action
    518  *
    519  * Description      handle specified call related action
    520  *
    521  * Returns          bt_status_t
    522  *
    523  ******************************************************************************/
    524 static bt_status_t handle_call_action(const RawAddress* bd_addr,
    525                                       bthf_client_call_action_t action,
    526                                       int idx) {
    527   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    528   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    529 
    530   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    531 
    532   switch (action) {
    533     case BTHF_CLIENT_CALL_ACTION_CHLD_0:
    534       if (cb->chld_feat & BTA_HF_CLIENT_CHLD_REL) {
    535         BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 0, 0, NULL);
    536         break;
    537       }
    538       return BT_STATUS_UNSUPPORTED;
    539     case BTHF_CLIENT_CALL_ACTION_CHLD_1:
    540       // CHLD 1 is mandatory for 3 way calling
    541       if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) {
    542         BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, 0, NULL);
    543         break;
    544       }
    545       return BT_STATUS_UNSUPPORTED;
    546     case BTHF_CLIENT_CALL_ACTION_CHLD_2:
    547       // CHLD 2 is mandatory for 3 way calling
    548       if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) {
    549         BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, 0, NULL);
    550         break;
    551       }
    552       return BT_STATUS_UNSUPPORTED;
    553     case BTHF_CLIENT_CALL_ACTION_CHLD_3:
    554       if (cb->chld_feat & BTA_HF_CLIENT_CHLD_MERGE) {
    555         BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 3, 0, NULL);
    556         break;
    557       }
    558       return BT_STATUS_UNSUPPORTED;
    559     case BTHF_CLIENT_CALL_ACTION_CHLD_4:
    560       if (cb->chld_feat & BTA_HF_CLIENT_CHLD_MERGE_DETACH) {
    561         BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 4, 0, NULL);
    562         break;
    563       }
    564       return BT_STATUS_UNSUPPORTED;
    565     case BTHF_CLIENT_CALL_ACTION_CHLD_1x:
    566       if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECC) {
    567         if (idx < 1) {
    568           return BT_STATUS_FAIL;
    569         }
    570         BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, idx, NULL);
    571         break;
    572       }
    573       return BT_STATUS_UNSUPPORTED;
    574     case BTHF_CLIENT_CALL_ACTION_CHLD_2x:
    575       if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECC) {
    576         if (idx < 1) {
    577           return BT_STATUS_FAIL;
    578         }
    579         BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, idx, NULL);
    580         break;
    581       }
    582       return BT_STATUS_UNSUPPORTED;
    583     case BTHF_CLIENT_CALL_ACTION_ATA:
    584       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATA, 0, 0, NULL);
    585       break;
    586     case BTHF_CLIENT_CALL_ACTION_CHUP:
    587       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHUP, 0, 0, NULL);
    588       break;
    589     case BTHF_CLIENT_CALL_ACTION_BTRH_0:
    590       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 0, 0, NULL);
    591       break;
    592     case BTHF_CLIENT_CALL_ACTION_BTRH_1:
    593       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 1, 0, NULL);
    594       break;
    595     case BTHF_CLIENT_CALL_ACTION_BTRH_2:
    596       BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 2, 0, NULL);
    597       break;
    598     default:
    599       return BT_STATUS_FAIL;
    600   }
    601 
    602   return BT_STATUS_SUCCESS;
    603 }
    604 
    605 /*******************************************************************************
    606  *
    607  * Function         query_current_calls
    608  *
    609  * Description      query list of current calls
    610  *
    611  * Returns          bt_status_t
    612  *
    613  ******************************************************************************/
    614 static bt_status_t query_current_calls(UNUSED_ATTR const RawAddress* bd_addr) {
    615   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    616   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    617 
    618   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    619 
    620   if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECS) {
    621     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CLCC, 0, 0, NULL);
    622     return BT_STATUS_SUCCESS;
    623   }
    624 
    625   return BT_STATUS_UNSUPPORTED;
    626 }
    627 
    628 /*******************************************************************************
    629  *
    630  * Function         query_current_operator_name
    631  *
    632  * Description      query current selected operator name
    633  *
    634  * Returns          bt_status_t
    635  *
    636  ******************************************************************************/
    637 static bt_status_t query_current_operator_name(const RawAddress* bd_addr) {
    638   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    639   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    640 
    641   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    642 
    643   BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_COPS, 0, 0, NULL);
    644   return BT_STATUS_SUCCESS;
    645 }
    646 
    647 /*******************************************************************************
    648  *
    649  * Function         retieve_subscriber_info
    650  *
    651  * Description      retrieve subscriber number information
    652  *
    653  * Returns          bt_status_t
    654  *
    655  ******************************************************************************/
    656 static bt_status_t retrieve_subscriber_info(const RawAddress* bd_addr) {
    657   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    658   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    659 
    660   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    661 
    662   BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CNUM, 0, 0, NULL);
    663   return BT_STATUS_SUCCESS;
    664 }
    665 
    666 /*******************************************************************************
    667  *
    668  * Function         send_dtmf
    669  *
    670  * Description      send dtmf
    671  *
    672  * Returns          bt_status_t
    673  *
    674  ******************************************************************************/
    675 static bt_status_t send_dtmf(const RawAddress* bd_addr, char code) {
    676   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    677   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    678 
    679   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    680 
    681   BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_VTS, code, 0, NULL);
    682   return BT_STATUS_SUCCESS;
    683 }
    684 
    685 /*******************************************************************************
    686  *
    687  * Function         request_last_voice_tag_number
    688  *
    689  * Description      Request number from AG for VR purposes
    690  *
    691  * Returns          bt_status_t
    692  *
    693  ******************************************************************************/
    694 static bt_status_t request_last_voice_tag_number(const RawAddress* bd_addr) {
    695   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    696   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    697 
    698   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    699 
    700   if (cb->peer_feat & BTA_HF_CLIENT_PEER_VTAG) {
    701     BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BINP, 1, 0, NULL);
    702     return BT_STATUS_SUCCESS;
    703   }
    704   return BT_STATUS_UNSUPPORTED;
    705 }
    706 
    707 /*******************************************************************************
    708  *
    709  * Function         cleanup
    710  *
    711  * Description      Closes the HF interface
    712  *
    713  * Returns          bt_status_t
    714  *
    715  ******************************************************************************/
    716 static void cleanup(void) {
    717   BTIF_TRACE_EVENT("%s", __func__);
    718 
    719   btif_queue_cleanup(UUID_SERVCLASS_HF_HANDSFREE);
    720   if (bt_hf_client_callbacks) {
    721     btif_disable_service(BTA_HFP_HS_SERVICE_ID);
    722     bt_hf_client_callbacks = NULL;
    723   }
    724 }
    725 
    726 /*******************************************************************************
    727  *
    728  * Function         send_at_cmd
    729  *
    730  * Description      Send requested AT command to rempte device.
    731  *
    732  * Returns          bt_status_t
    733  *
    734  ******************************************************************************/
    735 static bt_status_t send_at_cmd(const RawAddress* bd_addr, int cmd, int val1,
    736                                int val2, const char* arg) {
    737   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
    738   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
    739 
    740   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
    741 
    742   BTIF_TRACE_EVENT("%s: Cmd %d val1 %d val2 %d arg %s", __func__, cmd, val1,
    743                    val2, (arg != NULL) ? arg : "<null>");
    744   BTA_HfClientSendAT(cb->handle, cmd, val1, val2, arg);
    745 
    746   return BT_STATUS_SUCCESS;
    747 }
    748 
    749 static const bthf_client_interface_t bthfClientInterface = {
    750     sizeof(bthf_client_interface_t),
    751     .init = init,
    752     .connect = connect,
    753     .disconnect = disconnect,
    754     .connect_audio = connect_audio,
    755     .disconnect_audio = disconnect_audio,
    756     .start_voice_recognition = start_voice_recognition,
    757     .stop_voice_recognition = stop_voice_recognition,
    758     .volume_control = volume_control,
    759     .dial = dial,
    760     .dial_memory = dial_memory,
    761     .handle_call_action = handle_call_action,
    762     .query_current_calls = query_current_calls,
    763     .query_current_operator_name = query_current_operator_name,
    764     .retrieve_subscriber_info = retrieve_subscriber_info,
    765     .send_dtmf = send_dtmf,
    766     .request_last_voice_tag_number = request_last_voice_tag_number,
    767     .cleanup = cleanup,
    768     .send_at_cmd = send_at_cmd,
    769 };
    770 
    771 static void process_ind_evt(tBTA_HF_CLIENT_IND* ind) {
    772   BTIF_TRACE_DEBUG("%s", __func__);
    773 
    774   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(ind->bd_addr);
    775   if (cb == NULL || !is_connected(cb)) return;
    776 
    777   switch (ind->type) {
    778     case BTA_HF_CLIENT_IND_CALL:
    779       HAL_CBACK(bt_hf_client_callbacks, call_cb, &cb->peer_bda,
    780                 (bthf_client_call_t)ind->value);
    781       break;
    782 
    783     case BTA_HF_CLIENT_IND_CALLSETUP:
    784       HAL_CBACK(bt_hf_client_callbacks, callsetup_cb, &cb->peer_bda,
    785                 (bthf_client_callsetup_t)ind->value);
    786       break;
    787     case BTA_HF_CLIENT_IND_CALLHELD:
    788       HAL_CBACK(bt_hf_client_callbacks, callheld_cb, &cb->peer_bda,
    789                 (bthf_client_callheld_t)ind->value);
    790       break;
    791 
    792     case BTA_HF_CLIENT_IND_SERVICE:
    793       HAL_CBACK(bt_hf_client_callbacks, network_state_cb, &cb->peer_bda,
    794                 (bthf_client_network_state_t)ind->value);
    795       break;
    796 
    797     case BTA_HF_CLIENT_IND_SIGNAL:
    798       HAL_CBACK(bt_hf_client_callbacks, network_signal_cb, &cb->peer_bda,
    799                 ind->value);
    800       break;
    801 
    802     case BTA_HF_CLIENT_IND_ROAM:
    803       HAL_CBACK(bt_hf_client_callbacks, network_roaming_cb, &cb->peer_bda,
    804                 (bthf_client_service_type_t)ind->value);
    805       break;
    806 
    807     case BTA_HF_CLIENT_IND_BATTCH:
    808       HAL_CBACK(bt_hf_client_callbacks, battery_level_cb, &cb->peer_bda,
    809                 ind->value);
    810       break;
    811 
    812     default:
    813       break;
    814   }
    815 }
    816 
    817 /*******************************************************************************
    818  *
    819  * Function         btif_hf_client_upstreams_evt
    820  *
    821  * Description      Executes HF CLIENT UPSTREAMS events in btif context
    822  *
    823  * Returns          void
    824  *
    825  ******************************************************************************/
    826 static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) {
    827   tBTA_HF_CLIENT* p_data = (tBTA_HF_CLIENT*)p_param;
    828 
    829   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(p_data->bd_addr);
    830   if (cb == NULL && event == BTA_HF_CLIENT_OPEN_EVT) {
    831     BTIF_TRACE_DEBUG("%s: event BTA_HF_CLIENT_OPEN_EVT allocating block",
    832                      __func__);
    833     cb = btif_hf_client_allocate_cb();
    834     cb->handle = p_data->open.handle;
    835     cb->peer_bda = p_data->open.bd_addr;
    836   } else if (cb == NULL) {
    837     BTIF_TRACE_ERROR("%s: event %d but not allocating block: cb not found",
    838                      __func__, event);
    839     return;
    840   }
    841 
    842   BTIF_TRACE_DEBUG("%s: event=%s (%u)", __func__, dump_hf_client_event(event),
    843                    event);
    844 
    845   switch (event) {
    846     case BTA_HF_CLIENT_OPEN_EVT:
    847       if (p_data->open.status == BTA_HF_CLIENT_SUCCESS) {
    848         cb->state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED;
    849         cb->peer_feat = 0;
    850         cb->chld_feat = 0;
    851       } else if (cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING) {
    852         cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
    853       } else {
    854         BTIF_TRACE_WARNING(
    855             "%s: HF CLient open failed, but another device connected. "
    856             "status=%d state=%d connected device=%s",
    857             __func__, p_data->open.status, cb->state,
    858             cb->peer_bda.ToString().c_str());
    859         break;
    860       }
    861 
    862       HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
    863                 cb->state, 0, /* peer feat */
    864                 0 /* AT+CHLD feat */);
    865 
    866       if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
    867         cb->peer_bda = RawAddress::kAny;
    868 
    869       if (p_data->open.status != BTA_HF_CLIENT_SUCCESS) btif_queue_advance();
    870       break;
    871 
    872     case BTA_HF_CLIENT_CONN_EVT:
    873       cb->peer_feat = p_data->conn.peer_feat;
    874       cb->chld_feat = p_data->conn.chld_feat;
    875       cb->state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED;
    876 
    877       HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
    878                 cb->state, cb->peer_feat, cb->chld_feat);
    879 
    880       /* Inform the application about in-band ringtone */
    881       if (cb->peer_feat & BTA_HF_CLIENT_PEER_INBAND) {
    882         HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
    883                   BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
    884       }
    885 
    886       btif_queue_advance();
    887       break;
    888 
    889     case BTA_HF_CLIENT_CLOSE_EVT:
    890       cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
    891       HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
    892                 cb->state, 0, 0);
    893       cb->peer_bda = RawAddress::kAny;
    894       cb->peer_feat = 0;
    895       cb->chld_feat = 0;
    896       btif_queue_advance();
    897       break;
    898 
    899     case BTA_HF_CLIENT_IND_EVT:
    900       process_ind_evt(&p_data->ind);
    901       break;
    902 
    903     case BTA_HF_CLIENT_MIC_EVT:
    904       HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, &cb->peer_bda,
    905                 BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value);
    906       break;
    907 
    908     case BTA_HF_CLIENT_SPK_EVT:
    909       HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, &cb->peer_bda,
    910                 BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value);
    911       break;
    912 
    913     case BTA_HF_CLIENT_VOICE_REC_EVT:
    914       HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, &cb->peer_bda,
    915                 (bthf_client_vr_state_t)p_data->val.value);
    916       break;
    917 
    918     case BTA_HF_CLIENT_OPERATOR_NAME_EVT:
    919       HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, &cb->peer_bda,
    920                 p_data->operator_name.name);
    921       break;
    922 
    923     case BTA_HF_CLIENT_CLIP_EVT:
    924       HAL_CBACK(bt_hf_client_callbacks, clip_cb, &cb->peer_bda,
    925                 p_data->number.number);
    926       break;
    927 
    928     case BTA_HF_CLIENT_BINP_EVT:
    929       HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback,
    930                 &cb->peer_bda, p_data->number.number);
    931       break;
    932 
    933     case BTA_HF_CLIENT_CCWA_EVT:
    934       HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, &cb->peer_bda,
    935                 p_data->number.number);
    936       break;
    937 
    938     case BTA_HF_CLIENT_AT_RESULT_EVT:
    939       HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, &cb->peer_bda,
    940                 (bthf_client_cmd_complete_t)p_data->result.type,
    941                 p_data->result.cme);
    942       break;
    943 
    944     case BTA_HF_CLIENT_CLCC_EVT:
    945       HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, &cb->peer_bda,
    946                 p_data->clcc.idx,
    947                 p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING
    948                                  : BTHF_CLIENT_CALL_DIRECTION_OUTGOING,
    949                 (bthf_client_call_state_t)p_data->clcc.status,
    950                 p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI
    951                                   : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE,
    952                 p_data->clcc.number_present ? p_data->clcc.number : NULL);
    953       break;
    954 
    955     case BTA_HF_CLIENT_CNUM_EVT:
    956       if (p_data->cnum.service == 4) {
    957         HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
    958                   p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE);
    959       } else if (p_data->cnum.service == 5) {
    960         HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
    961                   p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX);
    962       } else {
    963         HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, &cb->peer_bda,
    964                   p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN);
    965       }
    966       break;
    967 
    968     case BTA_HF_CLIENT_BTRH_EVT:
    969       if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT) {
    970         HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, &cb->peer_bda,
    971                   (bthf_client_resp_and_hold_t)p_data->val.value);
    972       }
    973       break;
    974 
    975     case BTA_HF_CLIENT_BSIR_EVT:
    976       if (p_data->val.value != 0) {
    977         HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
    978                   BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
    979       } else {
    980         HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, &cb->peer_bda,
    981                   BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED);
    982       }
    983       break;
    984 
    985     case BTA_HF_CLIENT_AUDIO_OPEN_EVT:
    986       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
    987                 BTHF_CLIENT_AUDIO_STATE_CONNECTED);
    988       break;
    989 
    990     case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT:
    991       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
    992                 BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC);
    993       break;
    994 
    995     case BTA_HF_CLIENT_AUDIO_CLOSE_EVT:
    996       HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda,
    997                 BTHF_CLIENT_AUDIO_STATE_DISCONNECTED);
    998       break;
    999     case BTA_HF_CLIENT_RING_INDICATION:
   1000       HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb, &cb->peer_bda);
   1001       break;
   1002     default:
   1003       BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
   1004       break;
   1005   }
   1006 }
   1007 
   1008 /*******************************************************************************
   1009  *
   1010  * Function         bta_hf_client_evt
   1011  *
   1012  * Description      Switches context from BTA to BTIF for all HF Client events
   1013  *
   1014  * Returns          void
   1015  *
   1016  ******************************************************************************/
   1017 
   1018 static void bta_hf_client_evt(tBTA_HF_CLIENT_EVT event,
   1019                               tBTA_HF_CLIENT* p_data) {
   1020   bt_status_t status;
   1021 
   1022   /* switch context to btif task context (copy full union size for convenience)
   1023    */
   1024   status = btif_transfer_context(btif_hf_client_upstreams_evt, (uint16_t)event,
   1025                                  (char*)p_data, sizeof(*p_data), NULL);
   1026 
   1027   /* catch any failed context transfers */
   1028   ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
   1029 }
   1030 
   1031 /*******************************************************************************
   1032  *
   1033  * Function         btif_hf_client_execute_service
   1034  *
   1035  * Description      Initializes/Shuts down the service
   1036  *
   1037  * Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
   1038  *
   1039  ******************************************************************************/
   1040 bt_status_t btif_hf_client_execute_service(bool b_enable) {
   1041   BTIF_TRACE_EVENT("%s: enable: %d", __func__, b_enable);
   1042 
   1043   if (b_enable) {
   1044     /* Enable and register with BTA-HFClient */
   1045     BTIF_TRACE_EVENT("%s: support codec negotiation %d ", __func__,
   1046                      BTIF_HF_CLIENT_FEATURES);
   1047     BTA_HfClientEnable(bta_hf_client_evt, BTIF_HF_CLIENT_SECURITY,
   1048                        BTIF_HF_CLIENT_FEATURES, BTIF_HF_CLIENT_SERVICE_NAME);
   1049   } else {
   1050     BTA_HfClientDisable();
   1051   }
   1052   return BT_STATUS_SUCCESS;
   1053 }
   1054 
   1055 /*******************************************************************************
   1056  *
   1057  * Function         btif_hf_get_interface
   1058  *
   1059  * Description      Get the hf callback interface
   1060  *
   1061  * Returns          bthf_interface_t
   1062  *
   1063  ******************************************************************************/
   1064 const bthf_client_interface_t* btif_hf_client_get_interface(void) {
   1065   BTIF_TRACE_EVENT("%s", __func__);
   1066   return &bthfClientInterface;
   1067 }
   1068