Merge "NfCC power state tracker implementation" into qt-dev
diff --git a/Android.bp b/Android.bp
index a6cfc1f..7d5d199 100755
--- a/Android.bp
+++ b/Android.bp
@@ -46,6 +46,7 @@
         "halimpl/utils/phNxpConfig.cpp",
         "halimpl/utils/phNxpNciHal_utils.cc",
         "halimpl/utils/sparse_crc32.cc",
+        "halimpl/utils/NfccPowerTracker.cpp",
     ],
 
     local_include_dirs: [
diff --git a/halimpl/hal/phNxpNciHal.cc b/halimpl/hal/phNxpNciHal.cc
index f9d7d2a..7d3264d 100755
--- a/halimpl/hal/phNxpNciHal.cc
+++ b/halimpl/hal/phNxpNciHal.cc
@@ -13,13 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#include "NfccPowerTracker.h"
+#include "hal_nxpese.h"
+#include "hal_nxpnfc.h"
+#include "spi_spm.h"
+#include <EseAdaptation.h>
+#include <cutils/properties.h>
 #include <log/log.h>
 #include <phDal4Nfc_messageQueueLib.h>
 #include <phDnldNfc.h>
 #include <phNxpConfig.h>
 #include <phNxpLog.h>
-#include <cutils/properties.h>
 #include <phNxpNciHal.h>
 #include <phNxpNciHal_Adaptation.h>
 #include <phNxpNciHal_Dnld.h>
@@ -27,10 +31,6 @@
 #include <phNxpNciHal_ext.h>
 #include <phTmlNfc.h>
 #include <sys/stat.h>
-#include <EseAdaptation.h>
-#include "hal_nxpnfc.h"
-#include "hal_nxpese.h"
-#include "spi_spm.h"
 
 using namespace android::hardware::nfc::V1_1;
 using namespace android::hardware::nfc::V1_2;
@@ -729,7 +729,7 @@
       NXPLOG_NCIHAL_D("FW download Success");
     }
   }
-
+  NfccPowerTracker::getInstance().Initialize();
   /* Call open complete */
   phNxpNciHal_MinOpen_complete(wConfigStatus);
   NXPLOG_NCIHAL_D("phNxpNciHal_MinOpen(): exit");
@@ -975,6 +975,9 @@
     goto clean_and_return;
   }
 
+  NfccPowerTracker::getInstance().ProcessCmd(
+      (uint8_t *)nxpncihal_ctrl.p_cmd_data, (uint16_t)nxpncihal_ctrl.cmd_len);
+
 retry:
 
   data_len = nxpncihal_ctrl.cmd_len;
@@ -1108,6 +1111,10 @@
 
     phNxpNciHal_print_res_status(pInfo->pBuff, &pInfo->wLength);
 
+    if ((nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_NTF) {
+      NfccPowerTracker::getInstance().ProcessNtf(nxpncihal_ctrl.p_rx_data,
+                                                 nxpncihal_ctrl.rx_data_len);
+    }
     /* Check if response should go to hal module only */
     if (nxpncihal_ctrl.hal_ext_enabled == TRUE &&
         (nxpncihal_ctrl.p_rx_data[0x00] & NCI_MT_MASK) == NCI_MT_RSP) {
@@ -2154,7 +2161,7 @@
 
     NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
   }
-
+  NfccPowerTracker::getInstance().Pause();
   CONCURRENCY_UNLOCK();
 
   phNxpNciHal_cleanup_monitor();
@@ -2198,6 +2205,7 @@
  ******************************************************************************/
 int phNxpNciHal_configDiscShutdown(void) {
   NFCSTATUS status;
+  NfccPowerTracker::getInstance().Reset();
 
   status = phNxpNciHal_close(true);
   if(status != NFCSTATUS_SUCCESS) {
diff --git a/halimpl/libnfc-nxp-PN81B_example_NCI2_0.conf b/halimpl/libnfc-nxp-PN81B_example_NCI2_0.conf
index 03bcb20..d3fbec9 100755
--- a/halimpl/libnfc-nxp-PN81B_example_NCI2_0.conf
+++ b/halimpl/libnfc-nxp-PN81B_example_NCI2_0.conf
@@ -127,7 +127,8 @@
 # DWP intf behavior config, SVDD Load activated by default if set to 0x31 A037
 # SPI CL Sync enable  A098
 # EVT END OF Operation delay A0B2
-NXP_CORE_CONF_EXTN={20, 02, 31, 0C,
+# Power tracker command  A091
+NXP_CORE_CONF_EXTN={20, 02, 35, 0D,
     A0, EC, 01, 01,
     A0, ED, 01, 01,
     A0, 5E, 01, 01,
@@ -139,7 +140,8 @@
     A0, D8, 01, 02,
     A0, D5, 01, 0A,
     A0, 98, 01, 03,
-    A0, B2, 01, 19
+    A0, B2, 01, 19,
+    A0, 91, 01, 01
 }
 
 ###############################################################################
diff --git a/halimpl/libnfc-nxp-PN81T_example_NCI2_0.conf b/halimpl/libnfc-nxp-PN81T_example_NCI2_0.conf
index c6d81f9..1286368 100755
--- a/halimpl/libnfc-nxp-PN81T_example_NCI2_0.conf
+++ b/halimpl/libnfc-nxp-PN81T_example_NCI2_0.conf
@@ -127,7 +127,7 @@
 # DWP intf behavior config, SVDD Load activated by default if set to 0x31 A037
 # SPI CL Sync enable  A098
 # EVT END OF Operation delay A0B2
-NXP_CORE_CONF_EXTN={20, 02, 31, 0C,
+NXP_CORE_CONF_EXTN={20, 02, 35, 0D,
     A0, EC, 01, 01,
     A0, ED, 01, 01,
     A0, 5E, 01, 01,
@@ -139,7 +139,8 @@
     A0, D8, 01, 02,
     A0, D5, 01, 0A,
     A0, 98, 01, 03,
-    A0, B2, 01, 19
+    A0, B2, 01, 19,
+    A0, 91, 01, 01
 }
 
 ###############################################################################
diff --git a/halimpl/utils/NfccPowerTracker.cpp b/halimpl/utils/NfccPowerTracker.cpp
new file mode 100644
index 0000000..99f2b8a
--- /dev/null
+++ b/halimpl/utils/NfccPowerTracker.cpp
@@ -0,0 +1,438 @@
+/******************************************************************************
+ *
+ *  Copyright 2018 NXP
+ *
+ *  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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NfccPowerTracker"
+#include "NfccPowerTracker.h"
+#include "phNxpNciHal_ext.h"
+#include <assert.h>
+#include <fstream>
+#include <iostream>
+#include <log/log.h>
+#include <sstream>
+#include <stdio.h>
+#include <sys/file.h>
+#include <sys/time.h>
+using namespace std;
+
+extern bool nfc_debug_enabled;
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+static const uint64_t PWR_TRK_ERROR_MARGIN_IN_MILLISEC = 60000;
+static const std::string POWER_TRACKER_LOG_FILE =
+    "/data/vendor/nfc/nfc_power_state.txt";
+static const uint16_t TIMER_COUNT_MASK = 0x7FFF;
+
+NfccPowerTracker::NfccPowerTracker() {
+  mIsFirstPwrTrkNtfRecvd = false;
+  mLastPowerTrackAborted = false;
+  /*Default standby time*/
+  mStandbyTimePerDiscLoopInMillisec = 1000;
+}
+NfccPowerTracker::~NfccPowerTracker() {}
+
+/*******************************************************************************
+**
+** Function         NfccPowerTracker::getInstance
+**
+** Description      access class singleton
+**
+** Returns          pointer to the singleton object
+**
+*******************************************************************************/
+NfccPowerTracker &NfccPowerTracker::getInstance() {
+  static NfccPowerTracker sPwrInstance;
+  return sPwrInstance;
+}
+/*******************************************************************************
+**
+** Function         Initialize
+**
+** Description      get all prerequisite information from NFCC needed for
+**                  Power tracker calculations.
+**
+** Returns          void
+**
+*******************************************************************************/
+void NfccPowerTracker::Initialize() {
+  /*get total duration of discovery loop from NFCC using GET CONFIG command*/
+  uint8_t cmdGetConfigDiscLoopDuration[] = {0x20, 0x03, 0x02, 0x01, 0x00};
+  int status = phNxpNciHal_send_ext_cmd(sizeof(cmdGetConfigDiscLoopDuration),
+                                        cmdGetConfigDiscLoopDuration);
+  if (status != 0) {
+    ALOGD_IF(nfc_debug_enabled, "NfccPowerTracker::Initialize: failed");
+    return;
+  }
+  /*Check for valid get config response and update stanby time*/
+  if (nxpncihal_ctrl.p_rx_data[0] == 0x40 &&
+      nxpncihal_ctrl.p_rx_data[1] == 0x03 &&
+      nxpncihal_ctrl.p_rx_data[2] == 0x06 &&
+      nxpncihal_ctrl.p_rx_data[3] == 0x00 &&
+      nxpncihal_ctrl.p_rx_data[4] == 0x01 &&
+      nxpncihal_ctrl.p_rx_data[5] == 0x00 &&
+      nxpncihal_ctrl.p_rx_data[6] == 0x02) {
+    mStandbyTimePerDiscLoopInMillisec = (uint32_t)(
+        (nxpncihal_ctrl.p_rx_data[8] << 8) | nxpncihal_ctrl.p_rx_data[7]);
+    ALOGD_IF(nfc_debug_enabled, "mStandbyTimePerDiscLoopInMillisec value : %d",
+             mStandbyTimePerDiscLoopInMillisec);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         TimeDiff
+**
+** Description      Computes time difference in milliseconds.
+**
+** Returns          Time difference in milliseconds
+**
+*******************************************************************************/
+uint64_t NfccPowerTracker::TimeDiff(struct timespec start,
+                                    struct timespec end) {
+  uint64_t startTimeInMillisec =
+      start.tv_sec * 1000 + (start.tv_nsec / 1000000);
+  uint64_t endTimeInMillisec = end.tv_sec * 1000 + (end.tv_nsec / 1000000);
+
+  assert(startTimeInMillisec > endTimeInMillisec);
+  return (endTimeInMillisec - startTimeInMillisec);
+}
+
+/*******************************************************************************
+**
+** Function         NfccPowerTracker::ProcessCmd
+**
+** Description      Parse the commands going to NFCC,
+**                  get the time at which power relevant commands are sent
+**                  (ex:Screen state/OMAPI session)is sent and
+**                  log/cache the timestamp to file
+**
+** Returns          void
+**
+*******************************************************************************/
+void NfccPowerTracker::ProcessCmd(uint8_t *cmd, uint16_t len) {
+  ALOGD_IF(nfc_debug_enabled,
+           "NfccPowerTracker::ProcessCmd: Enter,Recieved len :%d", len);
+  bool screenStateCommand;
+  if (cmd[0] == 0x20 && cmd[1] == 0x09) {
+    screenStateCommand = true;
+  } else {
+    screenStateCommand = false;
+  }
+
+  if (screenStateCommand && (cmd[3] == 0x00 || cmd[3] == 0x02)) {
+    /* Command for Screen State On-Locked or Unlocked */
+    clock_gettime(CLOCK_BOOTTIME, &mLastScreenOnTimeStamp);
+    mIsLastUpdateScreenOn = true;
+  } else if (screenStateCommand && (cmd[3] == 0x01 || cmd[3] == 0x03)) {
+    /* Command for Screen State OFF-locked or Unlocked */
+    clock_gettime(CLOCK_BOOTTIME, &mLastScreenOffTimeStamp);
+    mIsLastUpdateScreenOn = false;
+  } else if (cmd[0] == 0x20 && cmd[1] == 0x02 && cmd[2] == 0x05 &&
+             cmd[3] == 0x01 && cmd[4] == 0x00 && cmd[5] == 0x02) {
+    /* Command to update duration of discovery loop */
+    mStandbyTimePerDiscLoopInMillisec = (cmd[7] << 8 | cmd[6]);
+    ALOGD_IF(nfc_debug_enabled, "mStandbyTimePerDiscLoopInMillisec value : %d",
+             mStandbyTimePerDiscLoopInMillisec);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         NfccPowerTracker::ProcessNtf
+**
+** Description      Parse the Notifications coming from NFCC,
+**                  get the time at which power relevant notifications are
+**                  received
+**                  (ex:RF ON-OFF/ACTIVATE-DEACTIVATE NTF/PROP_PWR_TRACKINFO)
+**                  calculate error in standby time by comparing the
+**                  expectated value from NFC HAL and received value from NFCC.
+**                  Cache relevant info (timestamps) to file
+**
+** Returns          void
+**
+*******************************************************************************/
+void NfccPowerTracker::ProcessNtf(uint8_t *rsp, uint16_t rsp_len) {
+  ALOGD_IF(nfc_debug_enabled, "NfccPowerTracker::ProcessNtf: Enter");
+
+  /* Screen State Notification recieved */
+  if ((rsp[0] == 0x6F && rsp[1] == 0x05)) {
+    ProcessPowerTrackNtf(rsp, rsp_len);
+  } else if (rsp[0] == 0x61 && rsp[1] == 0x05) {
+    /*Activation notification received. Calculate the time NFCC is
+    active in Reader/P2P/CE duration */
+    clock_gettime(CLOCK_BOOTTIME, &mActiveTimeStart);
+    if (!mIsLastUpdateScreenOn) {
+      mActiveInfo.totalTransitions++;
+    }
+  } else if (rsp[0] == 0x61 && rsp[1] == 0x06) {
+    /* Deactivation notification received Calculate the time NFCC is
+    active in Reader/P2P/CE duration.Time between Activation and
+    Deacivation gives the active time*/
+    clock_gettime(CLOCK_BOOTTIME, &mActiveTimeEnd);
+    mActiveDurationFromLastScreenUpdate +=
+        TimeDiff(mActiveTimeStart, mActiveTimeEnd);
+    if (!mIsLastUpdateScreenOn) {
+      mStandbyInfo.totalTransitions++;
+    }
+    ALOGD_IF(nfc_debug_enabled, "mActiveDurationFromLastScreenUpdate: %llu",
+             (unsigned long long)mActiveDurationFromLastScreenUpdate);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ProcessPowerTrackNtf
+**
+** Description      Process Power Tracker notification and update timingInfo to
+**                  Log File.
+**
+** Returns          void
+**
+*******************************************************************************/
+void NfccPowerTracker::ProcessPowerTrackNtf(uint8_t *rsp, uint16_t rsp_len) {
+  /* Enable Power Tracking computations after 1st Power tracker notification
+   * is received. */
+  if (!mIsFirstPwrTrkNtfRecvd) {
+    mIsFirstPwrTrkNtfRecvd = true;
+    ifstream ifile(POWER_TRACKER_LOG_FILE.c_str());
+    if ((bool)ifile == true) {
+      mLastPowerTrackAborted = true;
+    }
+    return;
+  }
+
+  /*Duration between screen state change is taken as reference for calculating
+  active and standby time*/
+  uint64_t totalDuration = 0;
+  totalDuration =
+      mIsLastUpdateScreenOn
+          ? TimeDiff(mLastScreenOffTimeStamp, mLastScreenOnTimeStamp)
+          : TimeDiff(mLastScreenOnTimeStamp, mLastScreenOffTimeStamp);
+  if (totalDuration == 0)
+    return;
+
+  /*Calculate Active and Standby time based on the pollCount provided in the
+  Power tracker Notification from NFCC*/
+  uint16_t sPollCount = (TIMER_COUNT_MASK & ((rsp[5] << 8) | rsp[4]));
+  ALOGD_IF(nfc_debug_enabled,
+           "Poll/Timer count recived from FW is %d and rsp_len :%d", sPollCount,
+           rsp_len);
+  uint64_t standbyTime = 0, activeTime = 0;
+  if (mIsLastUpdateScreenOn) {
+    activeTime = sPollCount * ACTIVE_TIME_PER_TIMER_COUNT_IN_MILLISEC;
+    /*Check for errors in count provided by NFCC*/
+    uint64_t error = (activeTime > mActiveDurationFromLastScreenUpdate)
+                         ? (activeTime - mActiveDurationFromLastScreenUpdate)
+                         : (mActiveDurationFromLastScreenUpdate - activeTime);
+    if (error > PWR_TRK_ERROR_MARGIN_IN_MILLISEC) {
+      ALOGD_IF(nfc_debug_enabled,
+               "Active Time Error observed with value is %llu",
+               (unsigned long long)error);
+      mErrorInStandbyInfo.residencyInMsecSinceBoot += error;
+    }
+    standbyTime = (totalDuration > activeTime) ? (totalDuration - activeTime)
+                                               : (activeTime - totalDuration);
+    if (rsp[3]) {
+      /*If notification trigger is counter overflow, update the screen on
+      timestamp as there is no screen state change*/
+      clock_gettime(CLOCK_BOOTTIME, &mLastScreenOnTimeStamp);
+    }
+    mActiveInfo.totalTransitions++;
+  } else {
+    standbyTime = (sPollCount * mStandbyTimePerDiscLoopInMillisec);
+    activeTime = totalDuration > standbyTime ? (totalDuration - standbyTime)
+                                             : (standbyTime - totalDuration);
+    if (rsp[3]) {
+      /*If notification trigger is counter overflow, update the screen off
+      timestamp as there is no screen state change*/
+      clock_gettime(CLOCK_BOOTTIME, &mLastScreenOffTimeStamp);
+    }
+    /*Total transitions in screen on -> Screen Off window is same as poll count
+    provided by NFCC, as, there is transition in each discovery loop*/
+    mActiveInfo.totalTransitions += sPollCount;
+    /*1 additional transition for screen state update*/
+    mStandbyInfo.totalTransitions += (sPollCount + 1);
+  }
+
+  ALOGD_IF(nfc_debug_enabled,
+           "activeTime: %llu, standbyTime: %llu, totalDuration :%llu",
+           (unsigned long long)activeTime, (unsigned long long)standbyTime,
+           (unsigned long long)totalDuration);
+  if (mLastPowerTrackAborted) {
+    ALOGD_IF(nfc_debug_enabled,
+             "Last Hal service aborted,so retrive the power info data and "
+             "continue\n");
+    /*Read the file content and store in mActiveInfo.residencyInMsecSinceBoot
+    and mStandbyInfo.residencyInMsecSinceBoot*/
+    if (ReadPowerStateLog()) {
+      mLastPowerTrackAborted = false;
+    }
+  }
+  mStandbyInfo.residencyInMsecSinceBoot += standbyTime;
+  mActiveInfo.residencyInMsecSinceBoot += activeTime;
+  UpdatePowerStateLog(mStandbyInfo, mActiveInfo);
+  mActiveDurationFromLastScreenUpdate = 0;
+}
+/*******************************************************************************
+**
+** Function         NfccPowerTracker::UpdatePowerStateLog
+**
+** Description      update the powerstate related information in log file
+**
+** Returns          void
+**
+*******************************************************************************/
+void NfccPowerTracker::UpdatePowerStateLog(NfccPowerStateInfo_t mStandbyInfo,
+                                           NfccPowerStateInfo_t mActiveInfo) {
+  FILE *fp;
+  const string PWR_TRK_LOG_FILE_VERSION = "1.0";
+  /*Write the Active and standby timestamp into the file*/
+  fp = fopen(POWER_TRACKER_LOG_FILE.c_str(), "w");
+  if (fp == NULL) {
+    ALOGD_IF(nfc_debug_enabled, "Failed to Open Pwr Tracker Info File\n");
+    return;
+  }
+  ostringstream PwrTrackerInfo;
+  PwrTrackerInfo << "Version: " << PWR_TRK_LOG_FILE_VERSION.c_str() << endl;
+  PwrTrackerInfo << "NFC {" << endl;
+  PwrTrackerInfo << " { " << STR_ACTIVE
+                 << std::to_string(mActiveInfo.residencyInMsecSinceBoot) << " }"
+                 << endl;
+  PwrTrackerInfo << " { " << STR_STANDBY
+                 << std::to_string(mStandbyInfo.residencyInMsecSinceBoot)
+                 << " }" << endl;
+  PwrTrackerInfo << "}";
+  ALOGD_IF(nfc_debug_enabled,
+           "mActiveInfo.residencyInMsecSinceBoot: %llu, "
+           "mActiveInfo.totalTransitions: %llu,"
+           "mStandbyInfo.residencyInMsecSinceBoot "
+           ":%llu,mStandbyInfo.totalTransitions: %llu"
+           "mErrorInStandbyInfo.residencyInMsecSinceBoot: %llu",
+           (unsigned long long)mActiveInfo.residencyInMsecSinceBoot,
+           (unsigned long long)mActiveInfo.totalTransitions,
+           (unsigned long long)mStandbyInfo.residencyInMsecSinceBoot,
+           (unsigned long long)mStandbyInfo.totalTransitions,
+           (unsigned long long)mErrorInStandbyInfo.residencyInMsecSinceBoot);
+  string PwrInfo = PwrTrackerInfo.str();
+  if (!TryLockFile(fp)) {
+    ALOGD_IF(nfc_debug_enabled,
+             "Failed to Lock PwrTracker File.Skipping update\n");
+    fclose(fp);
+    return;
+  }
+  fwrite(PwrInfo.c_str(), sizeof(char), PwrInfo.length(), fp);
+  fflush(fp);
+  UnlockFile(fp);
+  fclose(fp);
+}
+/*******************************************************************************
+ **
+ ** Function         ReadPowerStateLog
+ **
+ ** Description      Retrieve powerstate related information from log file.
+ **
+ ** Returns          true if read successful, false otherwise.
+ **
+ *******************************************************************************/
+bool NfccPowerTracker::ReadPowerStateLog() {
+  ifstream pwrStateFileStream;
+  string itemName;
+  ALOGD_IF(nfc_debug_enabled, "NfccPowerTracker::ReadPowerStateLog: Enter \n");
+  pwrStateFileStream.open(POWER_TRACKER_LOG_FILE.c_str());
+  if (pwrStateFileStream.fail()) {
+    ALOGE("Error: %s", strerror(errno));
+    return false;
+  }
+
+  /*Check for required string(time in millisec) in the log file and convert it
+    to integer*/
+  while (pwrStateFileStream >> itemName) {
+    if (STR_ACTIVE.compare(itemName) == 0) {
+      pwrStateFileStream >> itemName;
+      mActiveInfo.residencyInMsecSinceBoot = stoull(itemName.c_str(), nullptr);
+    } else if (STR_STANDBY.compare(itemName) == 0) {
+      pwrStateFileStream >> itemName;
+      mStandbyInfo.residencyInMsecSinceBoot = stoull(itemName.c_str(), nullptr);
+    }
+  }
+
+  ALOGD_IF(nfc_debug_enabled,
+           "Value retrieved from Powertracker file is"
+           "activeTime: %llu and standbyTime: %llu\n",
+           (unsigned long long)mActiveInfo.residencyInMsecSinceBoot,
+           (unsigned long long)mStandbyInfo.residencyInMsecSinceBoot);
+  pwrStateFileStream.close();
+  return true;
+}
+/*******************************************************************************
+**
+** Function         Pause
+**
+** Description      Pause Power state Information Tracking,Tracking will resume
+**                  once next power tracker notification is recieved as part of
+**                  ProcessNtf.
+**
+** Returns          void
+**
+*******************************************************************************/
+void NfccPowerTracker::Pause() { mIsFirstPwrTrkNtfRecvd = false; }
+
+/*******************************************************************************
+**
+** Function         Reset
+**
+** Description      Stop power track information processing and delete
+**                  power tracker log file.
+**
+** Returns          void
+**
+*******************************************************************************/
+void NfccPowerTracker::Reset() {
+  ALOGD_IF(nfc_debug_enabled, "NfccPowerTracker::Reset enter");
+  if (remove(POWER_TRACKER_LOG_FILE.c_str()) != 0) {
+    ALOGD_IF(nfc_debug_enabled, "Error deleting Power tracker file");
+  }
+}
+/*******************************************************************************
+**
+** Function         TryLockFile
+**
+** Description      Lock PowerTracker log file. Any application trying to read
+**                  from PowerTracker log file shall acquire lock before reading
+**                  to avoid inconsistent data.
+**
+** Returns          true if locking was successful
+**                  false if there was a failure to lock PowerTracker log file.
+*******************************************************************************/
+bool NfccPowerTracker::TryLockFile(FILE *fp) {
+  uint8_t retryCount = 5;
+  do {
+    if (!flock(fileno(fp), LOCK_EX | LOCK_NB))
+      return true;
+    usleep(10000); /*10 millisec*/
+  } while (retryCount--);
+
+  return false;
+}
+/*******************************************************************************
+**
+** Function         UnlockFile
+**
+** Description      Unlock previously locked PowerTracker log file.
+**
+** Returns          void
+**
+*******************************************************************************/
+void NfccPowerTracker::UnlockFile(FILE *fp) { flock(fileno(fp), LOCK_UN); }
diff --git a/halimpl/utils/NfccPowerTracker.h b/halimpl/utils/NfccPowerTracker.h
new file mode 100644
index 0000000..3b3e8c0
--- /dev/null
+++ b/halimpl/utils/NfccPowerTracker.h
@@ -0,0 +1,195 @@
+/******************************************************************************
+ *
+ *  Copyright 2018 NXP
+ *
+ *  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.
+ *
+ ******************************************************************************/
+#pragma once
+
+#include <string>
+#include <time.h>
+#include <vector>
+
+/*Time spent in Active mode per count provided by NFCC*/
+static const uint32_t ACTIVE_TIME_PER_TIMER_COUNT_IN_MILLISEC = 20;
+/*Types of  Power states supported by NFCC */
+typedef struct NfccPowerStateInfo {
+  /* state name: Active/Standby */
+  std::string name;
+  /* Time spent in msec at this  power state since boot */
+  uint64_t residencyInMsecSinceBoot;
+  /* Total number of times Nfcc entered this state */
+  uint64_t totalTransitions;
+} NfccPowerStateInfo_t;
+
+/*Class to track the time spent in Standby mode by NFCC*/
+class NfccPowerTracker {
+public:
+  static NfccPowerTracker &getInstance();
+
+  /*******************************************************************************
+  **
+  ** Function         Initialize
+  **
+  ** Description      get all prerequisite information from NFCC needed for
+  **                  Power tracker calculations.
+  **
+  ** Returns          void
+  **
+  *******************************************************************************/
+  void Initialize();
+
+  /*******************************************************************************
+  **
+  ** Function         ProcessCmd
+  **
+  ** Description      Parse the commands going to NFCC,
+  **                  get the time at which power relevant commands are sent
+  **                  (ex:Screen state/OMAPI session)is sent and
+  **                  log/cache the timestamp to file.
+  **
+  ** Returns          void
+  **
+  *******************************************************************************/
+  void ProcessCmd(uint8_t *, uint16_t len);
+
+  /*******************************************************************************
+  **
+  ** Function         ProcessNtf
+  **
+  ** Description      Parse the Notifications coming from NFCC,
+  **                  get the time at which power relevant notifications are
+  **                  received (ex:RF ON-OFF/ACTIVATE-DEACTIVATE NTF/
+  **                  PROP_PWR_TRACKINFO). Calculate error in standby time by
+  **                  comparing the expectated value from NFC HAL and received
+  **                  value from NFCC. Update power state duration info
+  **                  to file.
+  **
+  ** Returns          void
+  **
+  *******************************************************************************/
+  void ProcessNtf(uint8_t *cmd, uint16_t len);
+
+  /*******************************************************************************
+  **
+  ** Function         Pause
+  **
+  ** Description      Pause Power state Information Tracking,Tracking will
+  **                  resume once next power tracker notification is recieved as
+  **                  part of ProcessNtf.
+  **
+  ** Returns          void
+  **
+  *******************************************************************************/
+  void Pause();
+
+  /*******************************************************************************
+  **
+  ** Function         Reset
+  **
+  ** Description      Stop power tracker information processing and delete
+  **                  power track log file.
+  **
+  ** Returns          void
+  **
+  *******************************************************************************/
+  void Reset();
+
+private:
+  NfccPowerTracker();
+  ~NfccPowerTracker();
+
+  /*******************************************************************************
+  **
+  ** Function         UpdatePowerStateLog
+  **
+  ** Description      update the powerstate related information in log file
+  **
+  ** Returns          void
+  **
+  *******************************************************************************/
+  void UpdatePowerStateLog(NfccPowerStateInfo_t standbyTime,
+                           NfccPowerStateInfo_t activeTime);
+
+  /*******************************************************************************
+   **
+   ** Function         ReadPowerStateLog
+   **
+   ** Description      Retrieve powerstate related information from log file.
+   **
+   ** Returns          true if read successful, false otherwise.
+   **
+   *******************************************************************************/
+  bool ReadPowerStateLog();
+
+  /*******************************************************************************
+   **
+   ** Function         ProcessPowerTrackNtf
+   **
+   ** Description      Process Power Tracker notification.
+   **
+   ** Returns          void
+   **
+   *******************************************************************************/
+  void ProcessPowerTrackNtf(uint8_t *rsp, uint16_t rsp_len);
+
+  /*******************************************************************************
+  **
+  ** Function         TimeDiff
+  **
+  ** Description      Computes time difference in milliseconds.
+  **
+  ** Returns          Time difference in milliseconds
+  **
+  *******************************************************************************/
+  uint64_t TimeDiff(timespec start, timespec end);
+  /*******************************************************************************
+  **
+  ** Function         TryLockFile
+  **
+  ** Description      Lock PowerTracker log file. Any application trying to read
+  **                  from PowerTracker log file shall acquire lock before
+  **                  reading to avoid inconsistent data.
+  **
+  ** Returns          true if locking was successful
+  **                  false if there was a failure to lock file.
+  *******************************************************************************/
+  bool TryLockFile(FILE *fp);
+  /*******************************************************************************
+  **
+  ** Function         UnlockFile
+  **
+  ** Description      Unlock previously locked PowerTracker log file.
+  **
+  ** Returns          void
+  *******************************************************************************/
+  void UnlockFile(FILE *fp);
+  struct timespec mLastScreenOffTimeStamp = {0, 0},
+                  mLastScreenOnTimeStamp = {0, 0};
+  /*Used to calculate time NFCC is active during Card emulation/P2P/Reader
+   * modes*/
+  struct timespec mActiveTimeStart = {0, 0}, mActiveTimeEnd = {0, 0};
+
+  bool mIsLastUpdateScreenOn;
+  bool mIsFirstPwrTrkNtfRecvd;
+
+  uint64_t mActiveDurationFromLastScreenUpdate = 0;
+  NfccPowerStateInfo_t mActiveInfo, mStandbyInfo, mErrorInStandbyInfo;
+
+  /*Last powertracker processing aborted due to NFC HAL Service abort*/
+  bool mLastPowerTrackAborted = false;
+  /* Time spent in standby mode in one discovery loop containing poll */
+  uint32_t mStandbyTimePerDiscLoopInMillisec;
+  const std::string STR_ACTIVE = "Active: ", STR_STANDBY = "StandBy: ";
+};