Add a timer to prevent NFCC got stuck in ActiveRW

When screen off, the power state should switch back to active.
Start a 5 seconds timer to check if chip can swich back from A_RW
to Active mode.
If NFCC got stuck in Active RW mode, reset the chip.

Bug: 194675064
Bug: 189064168
Test: manual
Change-Id: Ia15e000f7ba6a482e5ca69f23cb644eaf0d7b01c
diff --git a/st21nfc/adaptation/i2clayer.cc b/st21nfc/adaptation/i2clayer.cc
index 33b54eb..f0500f6 100644
--- a/st21nfc/adaptation/i2clayer.cc
+++ b/st21nfc/adaptation/i2clayer.cc
@@ -59,6 +59,7 @@
 pthread_mutex_t i2ctransport_mtx = PTHREAD_MUTEX_INITIALIZER;
 
 unsigned long hal_ctrl_clk = 0;
+unsigned long hal_activerw_timer = 0;
 
 /**************************************************************************************************
  *
@@ -290,6 +291,8 @@
   }
 
   GetNumValue(NAME_STNFC_CONTROL_CLK, &hal_ctrl_clk, sizeof(hal_ctrl_clk));
+  GetNumValue(NAME_STNFC_ACTIVERW_TIMER, &hal_activerw_timer,
+              sizeof(hal_activerw_timer));
 
   if (hal_ctrl_clk) {
     if (ioctl(fidI2c, ST21NFC_CLK_DISABLE, NULL) < 0) {
@@ -423,9 +426,13 @@
   int clk_state = -1;
   char msg[LINUX_DBGBUFFER_SIZE];
 
-  if (hal_ctrl_clk && length >= 4 && pvBuffer[0] == 0x20 &&
-      pvBuffer[1] == 0x09) {
-    if (0 > (clk_state = ioctl(fid, ST21NFC_CLK_STATE, NULL))) {
+  if ((hal_ctrl_clk || hal_activerw_timer) && length >= 4 &&
+      pvBuffer[0] == 0x20 && pvBuffer[1] == 0x09) {
+    if (hal_activerw_timer && (pvBuffer[3] == 0x01 || pvBuffer[3] == 0x03)) {
+      // screen off cases
+      hal_wrapper_set_state(HAL_WRAPPER_STATE_SET_ACTIVERW_TIMER);
+    }
+    if (hal_ctrl_clk && 0 > (clk_state = ioctl(fid, ST21NFC_CLK_STATE, NULL))) {
       strerror_r(errno, msg, LINUX_DBGBUFFER_SIZE);
       STLOG_HAL_E("ST21NFC_CLK_STATE failed errno %d(%s)", errno, msg);
       clk_state = -1;
diff --git a/st21nfc/hal_wrapper.cc b/st21nfc/hal_wrapper.cc
index 67e9eca..faf1800 100644
--- a/st21nfc/hal_wrapper.cc
+++ b/st21nfc/hal_wrapper.cc
@@ -529,6 +529,21 @@
                   __func__);
       ApplyUwbParamHandler(mHalHandle, data_len, p_data);
       break;
+    case HAL_WRAPPER_STATE_SET_ACTIVERW_TIMER:  // 10
+      if (mIsActiveRW == true) {
+        STLOG_HAL_V(
+            "%s - mHalWrapperState = "
+            "HAL_WRAPPER_STATE_SET_ACTIVERW_TIMER",
+            __func__);
+        // start timer
+        mTimerStarted = true;
+        HalSendDownstreamTimer(mHalHandle, 5000);
+        // Chip state should back to Active
+        // at screen off state.
+      }
+      mHalWrapperState = HAL_WRAPPER_STATE_READY;
+      mHalWrapperDataCallback(data_len, p_data);
+      break;
   }
 }
 
@@ -589,7 +604,8 @@
     case HAL_WRAPPER_STATE_READY:
       if (event == HAL_WRAPPER_TIMEOUT_EVT) {
         if (mTimerStarted) {
-          STLOG_HAL_D("NFC-NCI HAL: %s  Timeout.. Recover", __func__);
+          STLOG_HAL_E("NFC-NCI HAL: %s  Timeout.. Recover", __func__);
+          STLOG_HAL_E("%s mIsActiveRW = %d", __func__, mIsActiveRW);
           HalSendDownstreamStopTimer(mHalHandle);
           mTimerStarted = false;
           forceRecover = true;
diff --git a/st21nfc/include/android_logmsg.h b/st21nfc/include/android_logmsg.h
index 6648a37..fcb0462 100644
--- a/st21nfc/include/android_logmsg.h
+++ b/st21nfc/include/android_logmsg.h
@@ -51,6 +51,7 @@
 #define NAME_CORE_CONF_PROP "CORE_CONF_PROP"
 #define NAME_STNFC_CONTROL_CLK "STNFC_CONTROL_CLK"
 #define NAME_STNFC_UWB_LIB_NAME "STNFC_UWB_LIB_NAME"
+#define NAME_STNFC_ACTIVERW_TIMER "STNFC_ACTIVERW_TIMER"
 
 /* #######################
  * Set the logging level
diff --git a/st21nfc/include/halcore.h b/st21nfc/include/halcore.h
index fd5b41e..96ba779 100644
--- a/st21nfc/include/halcore.h
+++ b/st21nfc/include/halcore.h
@@ -55,6 +55,7 @@
   HAL_WRAPPER_STATE_UPDATE,
   HAL_WRAPPER_STATE_APPLY_CUSTOM_PARAM,
   HAL_WRAPPER_STATE_APPLY_UWB_PARAM,
+  HAL_WRAPPER_STATE_SET_ACTIVERW_TIMER,
 } hal_wrapper_state_e;
 
 /* callback function to communicate from HAL Core with the outside world */