NfCC power state tracker implementation

Calculate and log amount of time spent by NFCC
in following power states
1. Active mode.
2. Standby mode.

This log information can be read from
/data/vendor/nfc/nfc_power_state.txt

Bug:68656882
Test: NFC Enable, Disable & VTS Test.
Change-Id: I0692add33bd877e8425acb8b57bd84766ee6358b
diff --git a/Android.bp b/Android.bp
index 9b018fe..6f12e84 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 15ebac9..f579f0c 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 android::hardware::nfc::V1_1::NfcEvent;
@@ -728,7 +728,7 @@
       NXPLOG_NCIHAL_D("FW download Success");
     }
   }
-
+  NfccPowerTracker::getInstance().Initialize();
   /* Call open complete */
   phNxpNciHal_MinOpen_complete(wConfigStatus);
   NXPLOG_NCIHAL_D("phNxpNciHal_MinOpen(): exit");
@@ -974,6 +974,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;
@@ -1107,6 +1110,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) {
@@ -2153,7 +2160,7 @@
 
     NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
   }
-
+  NfccPowerTracker::getInstance().Pause();
   CONCURRENCY_UNLOCK();
 
   phNxpNciHal_cleanup_monitor();
@@ -2197,6 +2204,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: ";
+};