diff --git a/system/bta/dm/bta_dm_act.c b/system/bta/dm/bta_dm_act.c
index da76bebe4a831a9fce56485f4ca0bd6de02cad49..1fb47dfd0d07dfe79816356468ef06a7f490613e 100644
--- a/system/bta/dm/bta_dm_act.c
+++ b/system/bta/dm/bta_dm_act.c
@@ -121,6 +121,7 @@ static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
 
 extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8* p_uuid128);
+extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
 
 const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] =
 {
@@ -5503,7 +5504,7 @@ static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_
 
 /*******************************************************************************
 **
-** Function         bta_ble_enable_scan_cmpl
+** Function         bta_ble_status_cmpl
 **
 ** Description      ADV payload filtering enable / disable complete callback
 **
@@ -5522,6 +5523,51 @@ static void bta_ble_status_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_REF_VALUE re
        bta_dm_cb.p_scan_filt_status_cback(action, ref_value, st);
 }
 
+/*******************************************************************************
+**
+** Function         bta_ble_enable_scan_cmpl
+**
+** Description      ADV payload filtering enable / disable complete callback
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
+                                        tBTM_BLE_RX_TIME_MS rx_time,
+                                        tBTM_BLE_IDLE_TIME_MS idle_time,
+                                        tBTM_BLE_ENERGY_USED  energy_used,
+                                        tBTM_STATUS status)
+{
+    tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
+    tBTA_DM_CONTRL_STATE ctrl_state = 0;
+
+    if (BTA_SUCCESS == st)
+       ctrl_state = bta_dm_pm_obtain_controller_state();
+
+    if (bta_dm_cb.p_energy_info_cback)
+        bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_ble_get_energy_info
+**
+** Description      This function obtains the energy info
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+
+    bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
+    btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
+    if (BTM_CMD_STARTED != btm_status)
+        bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
+}
+
 /*******************************************************************************
 **
 ** Function         bta_dm_cfg_filter_cond
@@ -5593,6 +5639,7 @@ void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
                                             p_data->ble_enable_scan_filt.ref_value, status);
 
 }
+
 /*******************************************************************************
 **
 ** Function         bta_dm_scan_filter_param_setup
diff --git a/system/bta/dm/bta_dm_api.c b/system/bta/dm/bta_dm_api.c
index f80fda838c4007d62afa68747975de58192a97a3..d8fb93448b6a1d5c06013f6c2893d40b79b123fc 100644
--- a/system/bta/dm/bta_dm_api.c
+++ b/system/bta/dm/bta_dm_api.c
@@ -2329,6 +2329,33 @@ void BTA_DmBleScanFilterSetup(UINT8 action, tBTA_DM_BLE_PF_FILT_INDEX filt_index
 #endif
 }
 
+/*******************************************************************************
+**
+** Function         BTA_DmBleGetEnergyInfo
+**
+** Description      This function is called to obtain the energy info
+**
+** Parameters       p_cmpl_cback - Command complete callback
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback)
+{
+    tBTA_DM_API_ENERGY_INFO *p_msg;
+    APPL_TRACE_API ("BTA_DmBleGetEnergyInfo");
+
+    UINT16  len = sizeof(tBTA_DM_API_ENERGY_INFO) + sizeof(tBLE_BD_ADDR);
+
+    if ((p_msg = (tBTA_DM_API_ENERGY_INFO *) GKI_getbuf(len)) != NULL)
+    {
+        memset (p_msg, 0, len);
+        p_msg->hdr.event        = BTA_DM_API_BLE_ENERGY_INFO_EVT;
+        p_msg->p_energy_info_cback = p_cmpl_cback;
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
 /*******************************************************************************
 **
 ** Function         BTA_DmEnableScanFilter
diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h
index a1b935b61e200adc9e3acb21b8d29f10ad7198cf..8b8689bd26e6deabc7a9c9766811d2040caad22b 100644
--- a/system/bta/dm/bta_dm_int.h
+++ b/system/bta/dm/bta_dm_int.h
@@ -124,6 +124,7 @@ enum
     BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT,
     BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT,
     BTA_DM_API_BLE_TRACK_ADVERTISER_EVT,
+    BTA_DM_API_BLE_ENERGY_INFO_EVT,
 #endif
 
 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
@@ -641,6 +642,12 @@ typedef struct
     tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback;
 } tBTA_DM_API_TRACK_ADVERTISER;
 
+typedef struct
+{
+    BT_HDR                  hdr;
+    tBTA_BLE_ENERGY_INFO_CBACK *p_energy_info_cback;
+} tBTA_DM_API_ENERGY_INFO;
+
 #endif /* BLE_INCLUDED */
 
 typedef struct
@@ -810,6 +817,7 @@ typedef union
     tBTA_DM_API_READ_SCAN_REPORTS       ble_read_reports;
     tBTA_DM_API_DISABLE_SCAN            ble_disable_scan;
     tBTA_DM_API_TRACK_ADVERTISER        ble_track_advert;
+    tBTA_DM_API_ENERGY_INFO             ble_energy_info;
 #endif
 
     tBTA_DM_API_SET_AFH_CHANNEL_ASSESSMENT set_afh_channel_assessment;
@@ -918,6 +926,7 @@ typedef struct
     tBTA_DM_BLE_PF_CFG_CBACK     *p_scan_filt_cfg_cback;
     tBTA_DM_BLE_PF_STATUS_CBACK  *p_scan_filt_status_cback;
     tBTA_DM_BLE_PF_PARAM_CBACK   *p_scan_filt_param_cback;
+    tBTA_BLE_ENERGY_INFO_CBACK   *p_energy_info_cback;
     TIMER_LIST_ENT              signal_strength_timer;
     tBTA_SIG_STRENGTH_MASK      signal_strength_mask;
     UINT16                      state;
@@ -1198,6 +1207,7 @@ extern void bta_dm_ble_enable_batch_scan(tBTA_DM_MSG * p_data);
 extern void bta_dm_ble_disable_batch_scan(tBTA_DM_MSG * p_data);
 extern void bta_dm_ble_read_scan_reports(tBTA_DM_MSG * p_data);
 extern void bta_dm_ble_track_advertiser(tBTA_DM_MSG * p_data);
+extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data);
 
 #endif
 extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
diff --git a/system/bta/dm/bta_dm_main.c b/system/bta/dm/bta_dm_main.c
index d378744ec2d9d068b02dbf576d8e3a2ee8b42082..35835c7c7514063eb3dc04b76a5897bc8d65d8d9 100644
--- a/system/bta/dm/bta_dm_main.c
+++ b/system/bta/dm/bta_dm_main.c
@@ -118,6 +118,7 @@ const tBTA_DM_ACTION bta_dm_action[] =
     bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */
     bta_dm_ble_read_scan_reports,  /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */
     bta_dm_ble_track_advertiser,   /* BTA_DM_API_BLE_TRACK_ADVERTISER_EVT */
+    bta_dm_ble_get_energy_info,    /* BTA_DM_API_BLE_ENERGY_INFO_EVT */
 #endif
 
 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
diff --git a/system/bta/dm/bta_dm_pm.c b/system/bta/dm/bta_dm_pm.c
index b89688050ee2cfff5155d8e58f6f1a4ff66ff306..2038605ab955eff843a8c195f4cccbc4fefcf78f 100644
--- a/system/bta/dm/bta_dm_pm.c
+++ b/system/bta/dm/bta_dm_pm.c
@@ -970,3 +970,24 @@ static void bta_dm_pm_set_sniff_policy(tBTA_DM_PEER_DEVICE *p_dev, BOOLEAN bDisa
     BTM_SetLinkPolicy(p_dev->peer_bdaddr, &policy_setting);
 
 }
+
+/*******************************************************************************
+**
+** Function         bta_dm_pm_obtain_controller_state
+**
+** Description      This function obtains the consolidated controller power state
+**
+** Parameters:
+**
+*******************************************************************************/
+tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void)
+{
+    /*   Did not use counts as it is not sure, how accurate the count values are in
+     **  bta_dm_cb.device_list.count > 0 || bta_dm_cb.device_list.le_count > 0 */
+
+    tBTA_DM_CONTRL_STATE cur_state = BTA_DM_CONTRL_UNKNOWN;
+    cur_state = BTM_PM_ReadControllerState();
+
+    APPL_TRACE_DEBUG("bta_dm_pm_obtain_controller_state: %d", cur_state);
+    return cur_state;
+}
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index e43b23bf52d8e794f9b93f2a23fc6b7efc228793..8636ea431b87344f73a930e5920617ccdd170d97 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -637,6 +637,7 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK;
 #define BTA_DM_DEV_UNPAIRED_EVT         23
 #define BTA_DM_HW_ERROR_EVT             24      /* BT Chip H/W error */
 #define BTA_DM_LE_FEATURES_READ         25      /* Cotroller specific LE features are read */
+#define BTA_DM_ENER_INFO_READ           26      /* Energy info read */
 typedef UINT8 tBTA_DM_SEC_EVT;
 
 /* Structure associated with BTA_DM_ENABLE_EVT */
@@ -957,7 +958,7 @@ typedef UINT8 tBTA_BLE_MULTI_ADV_EVT;
 /* multi adv callback */
 typedef void (tBTA_BLE_MULTI_ADV_CBACK)(tBTA_BLE_MULTI_ADV_EVT event,
                                         UINT8 inst_id, void *p_ref, tBTA_STATUS status);
-typedef UINT8 tBTA_DM_BLE_REF_VALUE;
+typedef UINT32 tBTA_DM_BLE_REF_VALUE;
 
 #define BTA_DM_BLE_PF_ENABLE_EVT       BTM_BLE_PF_ENABLE
 #define BTA_DM_BLE_PF_CONFIG_EVT       BTM_BLE_PF_CONFIG
@@ -987,8 +988,8 @@ typedef void (tBTA_DM_BLE_PF_PARAM_CBACK) (UINT8 action_type, tBTA_DM_BLE_PF_AVB
                                            tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status);
 
 /* Status callback */
-typedef void (tBTA_DM_BLE_PF_STATUS_CBACK) (UINT8 action, tBTA_DM_BLE_REF_VALUE ref_value,
-                                            tBTA_STATUS status);
+typedef void (tBTA_DM_BLE_PF_STATUS_CBACK) (UINT8 action, tBTA_STATUS status,
+                                            tBTA_DM_BLE_REF_VALUE ref_value);
 
 
 #define BTA_DM_BLE_PF_BRDCAST_ADDR_FILT  1
@@ -1128,20 +1129,43 @@ typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport,
 #define BTA_DM_BLE_SEC_MITM         BTM_BLE_SEC_ENCRYPT_MITM
 typedef tBTM_BLE_SEC_ACT            tBTA_DM_BLE_SEC_ACT;
 
+typedef tBTM_BLE_TX_TIME_MS         tBTA_DM_BLE_TX_TIME_MS;
+typedef tBTM_BLE_RX_TIME_MS         tBTA_DM_BLE_RX_TIME_MS;
+typedef tBTM_BLE_IDLE_TIME_MS       tBTA_DM_BLE_IDLE_TIME_MS;
+typedef tBTM_BLE_ENERGY_USED        tBTA_DM_BLE_ENERGY_USED;
+
+#define BTA_DM_CONTRL_UNKNOWN 0       /* Unknown state */
+#define BTA_DM_CONTRL_ACTIVE  1       /* ACL link on, SCO link ongoing, sniff mode */
+#define BTA_DM_CONTRL_SCAN    2       /* Scan state - paging/inquiry/trying to connect*/
+#define BTA_DM_CONTRL_IDLE    3       /* Idle state - page scan, LE advt, inquiry scan */
+
+typedef UINT8 tBTA_DM_CONTRL_STATE;
+
+
 typedef void (tBTA_BLE_SCAN_THRESHOLD_CBACK)(tBTA_DM_BLE_REF_VALUE ref_value);
+
 typedef void (tBTA_BLE_SCAN_REP_CBACK) (tBTA_DM_BLE_REF_VALUE ref_value, UINT8 report_format,
                                         UINT8 num_records, UINT16 data_len,
                                         UINT8* p_rep_data, tBTA_STATUS status);
 
-typedef void (tBTA_BLE_SCAN_SETUP_CBACK) (tBTA_BLE_BATCH_SCAN_EVT evt, tBTA_DM_BLE_REF_VALUE ref_value,
+typedef void (tBTA_BLE_SCAN_SETUP_CBACK) (tBTA_BLE_BATCH_SCAN_EVT evt,
+                                          tBTA_DM_BLE_REF_VALUE ref_value,
                                           tBTA_STATUS status);
 
 typedef void (tBTA_BLE_TRACK_ADV_CMPL_CBACK)(int action, tBTA_STATUS status,
-                                tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_DM_BLE_REF_VALUE ref_value);
+                                             tBTA_DM_BLE_PF_AVBL_SPACE avbl_space,
+                                             tBTA_DM_BLE_REF_VALUE ref_value);
 
 typedef void (tBTA_BLE_TRACK_ADV_CBACK)(int filt_index, tBLE_ADDR_TYPE addr_type, BD_ADDR bda,
                                         int adv_state, tBTA_DM_BLE_REF_VALUE ref_value);
 
+typedef void (tBTA_BLE_ENERGY_INFO_CBACK)(tBTA_DM_BLE_TX_TIME_MS tx_time,
+                                          tBTA_DM_BLE_RX_TIME_MS rx_time,
+                                          tBTA_DM_BLE_IDLE_TIME_MS idle_time,
+                                          tBTA_DM_BLE_ENERGY_USED  energy_used,
+                                          tBTA_DM_CONTRL_STATE ctrl_state,
+                                          tBTA_STATUS status);
+
 #else
 typedef UINT8                       tBTA_DM_BLE_SEC_ACT;
 #endif
@@ -2563,6 +2587,19 @@ BTA_API extern void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action,
 BTA_API extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value,
                             tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback);
 
+/*******************************************************************************
+**
+** Function         BTA_DmBleGetEnergyInfo
+**
+** Description      This function is called to obtain the energy info
+**
+** Parameters       p_cmpl_cback - Command complete callback
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback);
+
 #endif
 
 #ifdef __cplusplus
diff --git a/system/btif/include/btif_api.h b/system/btif/include/btif_api.h
index 80a74d0515f86f314261b0bdb3cf24a77d4df8a9..2369b13d0232a52fd840a0baa46c61cc20d41b7f 100644
--- a/system/btif/include/btif_api.h
+++ b/system/btif/include/btif_api.h
@@ -347,6 +347,17 @@ bt_status_t btif_dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len);
 *******************************************************************************/
 bt_status_t btif_le_test_mode(uint16_t opcode, uint8_t *buf, uint8_t len);
 
+/*******************************************************************************
+**
+** Function         btif_dm_read_energy_info
+**
+** Description     Reads the energy info from controller
+**
+** Returns          void
+**
+*******************************************************************************/
+void btif_dm_read_energy_info();
+
 /*******************************************************************************
 **
 ** Function         btif_config_hci_snoop_log
diff --git a/system/btif/src/bluetooth.c b/system/btif/src/bluetooth.c
index 21b6f246a2f8713dce0b1c1e75e12a7742f51f11..7020ffac1ca4c6d955681bdac0c870afd56ca80a 100644
--- a/system/btif/src/bluetooth.c
+++ b/system/btif/src/bluetooth.c
@@ -321,6 +321,14 @@ static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
     return btif_dm_ssp_reply(bd_addr, variant, accept, passkey);
 }
 
+static int read_energy_info()
+{
+    if (interface_ready() == FALSE)
+        return BT_STATUS_NOT_READY;
+    btif_dm_read_energy_info();
+    return BT_STATUS_SUCCESS;
+}
+
 static const void* get_profile_interface (const char *profile_id)
 {
     ALOGI("get_profile_interface %s", profile_id);
@@ -454,6 +462,7 @@ static const bt_interface_t bluetoothInterface = {
 #endif
     config_hci_snoop_log,
     set_os_callouts,
+    read_energy_info,
 };
 
 const bt_interface_t* bluetooth__get_bluetooth_interface ()
diff --git a/system/btif/src/btif_core.c b/system/btif/src/btif_core.c
index c168e6c682540d872af789d9a596540d59f65081..426580830667dc87476ee6bf61749532a0473473 100644
--- a/system/btif/src/btif_core.c
+++ b/system/btif/src/btif_core.c
@@ -1043,6 +1043,7 @@ static void execute_storage_request(UINT16 event, char *p_param)
                 local_le_features.max_irk_list_size = cmn_vsc_cb.max_irk_list_sz;
                 local_le_features.rpa_offload_supported = cmn_vsc_cb.rpa_offloading;
                 local_le_features.scan_result_storage_size = cmn_vsc_cb.tot_scan_results_strg;
+                local_le_features.activity_energy_info_supported = cmn_vsc_cb.energy_support;
                 memcpy(prop.val, &local_le_features, prop.len);
                 #endif
             }
diff --git a/system/btif/src/btif_dm.c b/system/btif/src/btif_dm.c
index 7ec5948089d1709cc6734463fba6edb72149e900..c3dbe950a7099ee679955a373caab937d95e5d79 100644
--- a/system/btif/src/btif_dm.c
+++ b/system/btif/src/btif_dm.c
@@ -124,6 +124,17 @@ typedef struct
     BT_OCTET16 sp_r;
     BD_ADDR  oob_bdaddr;  /* peer bdaddr*/
 } btif_dm_oob_cb_t;
+
+typedef struct
+{
+    uint8_t  status;
+    uint8_t  ctrl_state;
+    uint64_t tx_time;
+    uint64_t rx_time;
+    uint64_t idle_time;
+    uint64_t energy_used;
+} btif_activity_energy_info_cb_t;
+
 #define BTA_SERVICE_ID_TO_SERVICE_MASK(id)       (1 << (id))
 
 /* This flag will be true if HCI_Inquiry is in progress */
@@ -1671,6 +1682,20 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
             HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1, &prop);
             break;
          }
+
+        case BTA_DM_ENER_INFO_READ:
+        {
+            btif_activity_energy_info_cb_t *p_ener_data = (btif_activity_energy_info_cb_t*) p_param;
+            bt_activity_energy_info energy_info;
+            energy_info.status = p_ener_data->status;
+            energy_info.ctrl_state = p_ener_data->ctrl_state;
+            energy_info.rx_time = p_ener_data->rx_time;
+            energy_info.tx_time = p_ener_data->tx_time;
+            energy_info.idle_time = p_ener_data->idle_time;
+            energy_info.energy_used = p_ener_data->energy_used;
+            HAL_CBACK(bt_hal_cbacks, energy_info_cb, &energy_info);
+            break;
+        }
 #endif
 
         case BTA_DM_AUTHORIZE_EVT:
@@ -1866,6 +1891,34 @@ static void bte_dm_remote_service_record_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_S
    btif_transfer_context(btif_dm_remote_service_record_evt, event, (char*)p_data, sizeof(tBTA_DM_SEARCH), NULL);
 }
 
+/*******************************************************************************
+**
+** Function         bta_energy_info_cb
+**
+** Description      Switches context from BTE to BTIF for DM energy info event
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_energy_info_cb(tBTA_DM_BLE_TX_TIME_MS tx_time, tBTA_DM_BLE_RX_TIME_MS rx_time,
+                                    tBTA_DM_BLE_IDLE_TIME_MS idle_time,
+                                    tBTA_DM_BLE_ENERGY_USED energy_used,
+                                    tBTA_DM_CONTRL_STATE ctrl_state, tBTA_STATUS status)
+{
+    BTIF_TRACE_DEBUG("energy_info_cb-Status:%d,state=%d,tx_t=%ld, rx_t=%ld, idle_time=%ld,used=%ld",
+        status, ctrl_state, tx_time, rx_time, idle_time, energy_used);
+
+    btif_activity_energy_info_cb_t btif_cb;
+    btif_cb.status = status;
+    btif_cb.ctrl_state = ctrl_state;
+    btif_cb.tx_time = (uint64_t) tx_time;
+    btif_cb.rx_time = (uint64_t) rx_time;
+    btif_cb.idle_time =(uint64_t) idle_time;
+    btif_cb.energy_used =(uint64_t) energy_used;
+    btif_transfer_context(btif_dm_upstreams_evt, BTA_DM_ENER_INFO_READ,
+                          (char*) &btif_cb, sizeof(btif_activity_energy_info_cb_t), NULL);
+}
+
 /*****************************************************************************
 **
 **   btif api functions (no context switch)
@@ -2790,6 +2843,20 @@ void btif_dm_on_disable()
     }
 }
 
+/*******************************************************************************
+**
+** Function         btif_dm_read_energy_info
+**
+** Description     Reads the energy info from controller
+**
+** Returns         void
+**
+*******************************************************************************/
+void btif_dm_read_energy_info()
+{
+    BTA_DmBleGetEnergyInfo(bta_energy_info_cb);
+}
+
 static char* btif_get_default_local_name() {
     if (btif_default_local_name[0] == '\0')
     {
diff --git a/system/btif/src/btif_util.c b/system/btif/src/btif_util.c
index 693e76857622a8579bd37c587f4b10998569a31e..bd376a6d1d2547c58eeb3070ebc203457511af0f 100644
--- a/system/btif/src/btif_util.c
+++ b/system/btif/src/btif_util.c
@@ -282,6 +282,7 @@ const char* dump_dm_event(UINT16 event)
         CASE_RETURN_STR(BTA_DM_BLE_AUTH_CMPL_EVT)
         CASE_RETURN_STR(BTA_DM_DEV_UNPAIRED_EVT)
         CASE_RETURN_STR(BTA_DM_HW_ERROR_EVT)
+        CASE_RETURN_STR(BTA_DM_ENER_INFO_READ)
 
         default:
             return "UNKNOWN DM EVENT";
diff --git a/system/stack/Android.mk b/system/stack/Android.mk
index c4b17ef0e0c66b3d635d6c3231ce9cb385147dbd..f1159a6e455618cfbdc2870463396729f58a3626 100644
--- a/system/stack/Android.mk
+++ b/system/stack/Android.mk
@@ -68,6 +68,7 @@ LOCAL_SRC_FILES:= \
     ./btm/btm_ble_adv_filter.c \
     ./btm/btm_ble_multi_adv.c \
     ./btm/btm_ble_batchscan.c \
+    ./btm/btm_ble_cont_energy.c \
     ./btm/btm_acl.c \
     ./btm/btm_sco.c \
     ./btm/btm_pm.c \
diff --git a/system/stack/btm/btm_ble_cont_energy.c b/system/stack/btm/btm_ble_cont_energy.c
new file mode 100644
index 0000000000000000000000000000000000000000..0da6cf0d3a052e8fed9705acc263c2dd8ac03d85
--- /dev/null
+++ b/system/stack/btm/btm_ble_cont_energy.c
@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014  Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "bt_target.h"
+
+#if (BLE_INCLUDED == TRUE)
+#include "bt_types.h"
+#include "hcimsgs.h"
+#include "btu.h"
+#include "btm_int.h"
+#include "bt_utils.h"
+#include "hcidefs.h"
+#include "btm_ble_api.h"
+
+tBTM_BLE_ENERGY_INFO_CB ble_energy_info_cb;
+
+/*******************************************************************************
+**
+** Function         btm_ble_cont_energy_cmpl_cback
+**
+** Description      Controller VSC complete callback
+**
+** Parameters
+**
+** Returns          void
+**
+*******************************************************************************/
+void btm_ble_cont_energy_cmpl_cback (tBTM_VSC_CMPL *p_params)
+{
+    UINT8  *p = p_params->p_param_buf;
+    UINT16  len = p_params->param_len;
+    UINT8  status = 0;
+    UINT32 total_tx_time = 0, total_rx_time = 0, total_idle_time = 0, total_energy_used = 0;
+
+    if (len < 17)
+    {
+        BTM_TRACE_ERROR("wrong length for btm_ble_cont_energy_cmpl_cback");
+        return;
+    }
+
+    STREAM_TO_UINT8(status, p);
+    STREAM_TO_UINT32(total_tx_time, p);
+    STREAM_TO_UINT32(total_rx_time, p);
+    STREAM_TO_UINT32(total_idle_time, p);
+    STREAM_TO_UINT32(total_energy_used, p);
+
+    BTM_TRACE_DEBUG("energy_info status=%d,tx_t=%ld, rx_t=%ld, ener_used=%ld, idle_t=%ld",
+        status, total_tx_time, total_rx_time, total_energy_used, total_idle_time);
+
+    if (NULL != ble_energy_info_cb.p_ener_cback)
+        ble_energy_info_cb.p_ener_cback(total_tx_time, total_rx_time, total_idle_time,
+                          total_energy_used, status);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         BTM_BleGetEnergyInfo
+**
+** Description      This function obtains the energy info
+**
+** Parameters      p_ener_cback - Callback pointer
+**
+** Returns          status
+**
+*******************************************************************************/
+tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback)
+{
+    tBTM_STATUS status = BTM_ILLEGAL_VALUE;
+    tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+
+    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
+
+    BTM_TRACE_EVENT("BTM_BleGetEnergyInfo");
+
+    if (0 == cmn_ble_vsc_cb.energy_support)
+    {
+        BTM_TRACE_ERROR("Controller does not support get energy info");
+        return BTM_ERR_PROCESSING;
+    }
+
+    ble_energy_info_cb.p_ener_cback = p_ener_cback;
+    if ((status = BTM_VendorSpecificCommand (HCI_BLE_ENERGY_INFO_OCF, 0, NULL,
+                   btm_ble_cont_energy_cmpl_cback)) != BTM_CMD_STARTED)
+    {
+        BTM_TRACE_ERROR("BTM_BleGetEnergyInfo status: %d", status);
+        return BTM_ILLEGAL_VALUE;
+    }
+
+    return status;
+}
+
+#endif
+
diff --git a/system/stack/btm/btm_ble_gap.c b/system/stack/btm/btm_ble_gap.c
index d00236fc8e4492147b83f20327d611e0ec9b734a..f5179b6f84ed1e8a056991b19ac0f994226137a9 100644
--- a/system/stack/btm/btm_ble_gap.c
+++ b/system/stack/btm/btm_ble_gap.c
@@ -458,6 +458,7 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_
         STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, p);
         STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.filter_support, p);
         STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.max_filter, p);
+        STREAM_TO_UINT8  (btm_cb.cmn_ble_vsc_cb.energy_support, p);
     }
 
     p_vcb->irk_avail_size = max_irk_list_sz;
diff --git a/system/stack/btm/btm_pm.c b/system/stack/btm/btm_pm.c
index 93e55ee97ac3bcb397b956c96a180f389e8d8a07..a74b24db2d84b99a5beb448611416bea5ba2f06a 100644
--- a/system/stack/btm/btm_pm.c
+++ b/system/stack/btm/btm_pm.c
@@ -1008,4 +1008,85 @@ BOOLEAN BTM_IsPowerManagerOn (void)
     return BTM_PWR_MGR_INCLUDED;
 }
 
+/*******************************************************************************
+**
+** Function         btm_pm_device_in_active_or_sniff_mode
+**
+** Description      This function is called to check if in active or sniff mode
+**
+** Returns          TRUE, if in active or sniff mode
+**
+*******************************************************************************/
+BOOLEAN btm_pm_device_in_active_or_sniff_mode(void)
+{
+    /* The active state is the highest state-includes connected device and sniff mode*/
+
+    /* Covers active and sniff modes */
+    if (btm_cb.num_acl > 0)
+    {
+        BTM_TRACE_DEBUG("btm_pm_device_in_active_or_sniff_mode-acl:%d", btm_cb.num_acl);
+        return TRUE;
+    }
+
+    /* Check BLE states */
+    if (btm_ble_get_conn_st() != BLE_CONN_IDLE)
+    {
+        BTM_TRACE_DEBUG("btm_pm_device_in_active_or_sniff_mode- BLE state: %x",
+                        btm_ble_get_conn_st());
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         btm_pm_device_in_scan_state
+**
+** Description      This function is called to check if in paging, inquiry or connecting mode
+**
+** Returns          TRUE, if in paging, inquiry or connecting mode
+**
+*******************************************************************************/
+BOOLEAN btm_pm_device_in_scan_state(void)
+{
+    /* Scan state-paging, inquiry, and trying to connect */
+
+    /* Check for paging */
+    if (btm_cb.is_paging || btm_cb.page_queue.count > 0 ||
+       BTM_BL_PAGING_STARTED == btm_cb.busy_level)
+    {
+       BTM_TRACE_DEBUG("btm_pm_device_in_scan_state- paging");
+       return TRUE;
+    }
+
+    /* Check for inquiry */
+    if ((btm_cb.btm_inq_vars.inq_active & (BTM_BR_INQ_ACTIVE_MASK | BTM_BLE_INQ_ACTIVE_MASK)) != 0)
+    {
+        BTM_TRACE_DEBUG("btm_pm_device_in_scan_state- Inq active");
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         BTM_PM_ReadControllerState
+**
+** Description      This function is called to obtain the controller state
+**
+** Returns          Controller State-BTM_CONTRL_ACTIVE, BTM_CONTRL_SCAN, and BTM_CONTRL_IDLE
+**
+*******************************************************************************/
+tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void)
+{
+    if (TRUE == btm_pm_device_in_active_or_sniff_mode())
+       return BTM_CONTRL_ACTIVE;
+    else
+    if (TRUE == btm_pm_device_in_scan_state())
+       return BTM_CONTRL_SCAN;
+    else
+       return BTM_CONTRL_IDLE;
+}
 
diff --git a/system/stack/include/btm_api.h b/system/stack/include/btm_api.h
index 368e70db81dbc29f6e6b6a942204ce7f4d66cef3..dbd0fb2fb04e1bbf204e6d2f7eb6c4ca8fe5d976 100644
--- a/system/stack/include/btm_api.h
+++ b/system/stack/include/btm_api.h
@@ -1976,6 +1976,12 @@ typedef void (tBTM_MIP_EVENTS_CB) (tBTM_MIP_EVT event, tBTM_MIP_EVENT_DATA data)
 /* MIP Device query callback function  */
 typedef BOOLEAN (tBTM_MIP_QUERY_CB) (BD_ADDR dev_addr, UINT8 *p_mode, LINK_KEY link_key);
 
+#define BTM_CONTRL_ACTIVE  1       /* ACL link on, SCO link ongoing, sniff mode */
+#define BTM_CONTRL_SCAN    2       /* Scan state - paging/inquiry/trying to connect*/
+#define BTM_CONTRL_IDLE    3       /* Idle state - page scan, LE advt, inquiry scan */
+
+typedef UINT8 tBTM_CONTRL_STATE;
+
 /*****************************************************************************
 **  EXTERNAL FUNCTION DECLARATIONS
 *****************************************************************************/
@@ -4496,6 +4502,18 @@ BTM_API extern void BTM_SetARCMode (UINT8 iface, UINT8 arc_mode, tBTM_VSC_CMPL_C
 *******************************************************************************/
 BTM_API extern void BTM_PCM2Setup_Write (BOOLEAN clk_master, tBTM_VSC_CMPL_CB *p_arc_cb);
 
+
+/*******************************************************************************
+**
+** Function         BTM_PM_ReadControllerState
+**
+** Description      This function is called to obtain the controller state
+**
+** Returns          Controller state (BTM_CONTRL_ACTIVE, BTM_CONTRL_SCAN, and BTM_CONTRL_IDLE)
+**
+*******************************************************************************/
+BTM_API extern tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/system/stack/include/btm_ble_api.h b/system/stack/include/btm_ble_api.h
index 956801efcee20a58a5bd60c223bf26b13c2886a4..f408b8721305e5e33907cf7261565d938b4e2aa1 100644
--- a/system/stack/include/btm_ble_api.h
+++ b/system/stack/include/btm_ble_api.h
@@ -46,7 +46,7 @@ typedef UINT8 tBTM_BLE_CHNL_MAP[CHNL_MAP_LEN];
 
 #define BTM_BLE_UNKNOWN_EVT     0xff
 
-typedef UINT8 tBTM_BLE_REF_VALUE;
+typedef UINT32 tBTM_BLE_REF_VALUE;
 
 #define BTM_BLE_SCAN_MODE_PASS      0
 #define BTM_BLE_SCAN_MODE_ACTI      1
@@ -334,6 +334,7 @@ typedef struct
     UINT8 max_irk_list_sz;
     UINT8 filter_support;
     UINT8 max_filter;
+    UINT8 energy_support;
 }tBTM_BLE_VSC_CB;
 
 /* slave preferred connection interval range */
@@ -758,6 +759,21 @@ typedef UINT8 tBTM_BLE_TRACK_ADV_ACTION;
 
 typedef UINT8 tBTM_BLE_BATCH_SCAN_EVT;
 
+typedef UINT32 tBTM_BLE_TX_TIME_MS;
+typedef UINT32 tBTM_BLE_RX_TIME_MS;
+typedef UINT32 tBTM_BLE_IDLE_TIME_MS;
+typedef UINT32 tBTM_BLE_ENERGY_USED;
+
+typedef void (tBTM_BLE_ENERGY_INFO_CBACK)(tBTM_BLE_TX_TIME_MS tx_time, tBTM_BLE_RX_TIME_MS rx_time,
+                                          tBTM_BLE_IDLE_TIME_MS idle_time,
+                                          tBTM_BLE_ENERGY_USED  energy_used,
+                                          tBTM_STATUS status);
+
+typedef struct
+{
+    tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback;
+}tBTM_BLE_ENERGY_INFO_CB;
+
 typedef BOOLEAN (tBTM_BLE_SEL_CBACK)(BD_ADDR random_bda,     UINT8 *p_remote_name);
 typedef void (tBTM_BLE_CTRL_FEATURES_CBACK)(tBTM_STATUS status);
 
@@ -1610,6 +1626,18 @@ BTM_API extern tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable,
                                                tBTM_BLE_PF_STATUS_CBACK *p_stat_cback,
                                                tBTM_BLE_REF_VALUE ref_value);
 
+/*******************************************************************************
+**
+** Function         BTM_BleGetEnergyInfo
+**
+** Description      This function obtains the energy info
+**
+** Parameters       p_ener_cback - Callback pointer
+**
+** Returns          status
+**
+*******************************************************************************/
+BTM_API extern tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback);
 
 #ifdef __cplusplus
 }
diff --git a/system/stack/include/hcidefs.h b/system/stack/include/hcidefs.h
index d2ff6e8e389af4efa655cea19d2e71bafb824218..0349d6aa7bdd835c5b87ad0acf9317a0d9190b3d 100644
--- a/system/stack/include/hcidefs.h
+++ b/system/stack/include/hcidefs.h
@@ -349,6 +349,9 @@
 /* Tracking OCF */
 #define HCI_BLE_TRACK_ADV_OCF     (0x0158 | HCI_GRP_VENDOR_SPECIFIC)
 
+/* Energy info OCF */
+#define HCI_BLE_ENERGY_INFO_OCF   (0x0159 | HCI_GRP_VENDOR_SPECIFIC)
+
 /* subcode for multi adv feature */
 #define BTM_BLE_MULTI_ADV_SET_PARAM                     0x01
 #define BTM_BLE_MULTI_ADV_WRITE_ADV_DATA                0x02
diff --git a/system/test/suite/support/callbacks.c b/system/test/suite/support/callbacks.c
index 2ad12cfb85113e8cac0146e9da1f81203c3343c2..08a69a5f900f1734fc4ee41d809e1f87828afcb0 100644
--- a/system/test/suite/support/callbacks.c
+++ b/system/test/suite/support/callbacks.c
@@ -76,6 +76,7 @@ static bt_callbacks_t bt_callbacks = {
   thread_evt,                // callback_thread_event
   NULL,                      // dut_mode_recv_callback
   NULL,                      // le_test_mode_callback
+  NULL,
 };
 
 static btpan_callbacks_t pan_callbacks = {