Monitor the RW power notification.
To prevent any CLF lock, analyze the PROP_PWR_MON_RW notification and
recover if a timeout is detected.
A recovery is also done if several occurrences of duplicated
PROP_PWR_MON_RW_OFF_NTF are detected.
Bug: 136432213
Bug: 137352121
Bug: 137237286
Test: NFC R/W mode stress test
Merged-In: I8a5e00a139ad104a0336334359f17646d2cb6402
Change-Id: I8a5e00a139ad104a0336334359f17646d2cb6402
(cherry picked from commit a9ebe5e705601118b97049c547c48c23f7e29099)
diff --git a/1.1/hal_st21nfc.cc b/1.1/hal_st21nfc.cc
index 927e9a1..59823e6 100644
--- a/1.1/hal_st21nfc.cc
+++ b/1.1/hal_st21nfc.cc
@@ -43,7 +43,7 @@
nfc_stack_callback_t* p_cback_unwrap;
} st21nfc_dev_t;
-const char* halVersion = "ST21NFC HAL1.1 Version 3.1.15";
+const char* halVersion = "ST21NFC HAL1.1 Version 3.1.16";
uint8_t cmd_set_nfc_mode_enable[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
uint8_t hal_is_closed = 1;
diff --git a/1.2/hal_st21nfc.cc b/1.2/hal_st21nfc.cc
index dfac627..c7e8d16 100644
--- a/1.2/hal_st21nfc.cc
+++ b/1.2/hal_st21nfc.cc
@@ -43,7 +43,7 @@
nfc_stack_callback_t* p_cback_unwrap;
} st21nfc_dev_t;
-const char* halVersion = "ST21NFC HAL1.2 Version 3.2.4";
+const char* halVersion = "ST21NFC HAL1.2 Version 3.2.5";
uint8_t cmd_set_nfc_mode_enable[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
uint8_t hal_is_closed = 1;
diff --git a/st21nfc/hal/halcore.cc b/st21nfc/hal/halcore.cc
index 8f432f8..0828bf5 100644
--- a/st21nfc/hal/halcore.cc
+++ b/st21nfc/hal/halcore.cc
@@ -343,6 +343,18 @@
}
}
+bool HalSendDownstreamTimer(HALHANDLE hHAL, uint32_t duration) {
+ HalInstance* inst = (HalInstance*)hHAL;
+
+ ThreadMesssage msg;
+
+ msg.command = MSG_TIMER_START;
+ msg.payload = 0;
+ msg.length = duration;
+ msg.buffer = NULL;
+
+ return HalEnqueueThreadMessage(inst, &msg);
+}
/**
* Send an NCI message downstream to HAL protocol layer (DH->NFCC transfer).
* Block if more than NUM_BUFFERS (10) transfers are outstanding, otherwise will
@@ -745,6 +757,11 @@
msg.length);
break;
+ case MSG_TIMER_START:
+ // Start timer
+ HalStartTimer(inst, msg.length);
+ STLOG_HAL_D("MSG_TIMER_START \n");
+ break;
default:
STLOG_HAL_E("!received unkown thread message?\n");
break;
diff --git a/st21nfc/hal/halcore_private.h b/st21nfc/hal/halcore_private.h
index 2932706..27483db 100644
--- a/st21nfc/hal/halcore_private.h
+++ b/st21nfc/hal/halcore_private.h
@@ -50,6 +50,7 @@
// HAL _WRAPPER
#define MSG_TX_DATA_TIMER_START 3
+#define MSG_TIMER_START 4
/* number of buffers used for incoming & outgoing data */
#define NUM_BUFFERS 10
diff --git a/st21nfc/hal_wrapper.cc b/st21nfc/hal_wrapper.cc
index 7558521..1d42540 100644
--- a/st21nfc/hal_wrapper.cc
+++ b/st21nfc/hal_wrapper.cc
@@ -52,6 +52,8 @@
int mRetryFwDwl;
uint8_t mFwUpdateResMask = 0;
uint8_t* ConfigBuffer = NULL;
+uint8_t mError_count = 0;
+bool mIsActiveRW = false;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER;
@@ -68,6 +70,8 @@
bool mHciCreditLent = false;
bool mfactoryReset = false;
bool ready_flag = 0;
+bool mTimerStarted = false;
+bool forceRecover = false;
void wait_ready() {
pthread_mutex_lock(&mutex);
@@ -98,6 +102,7 @@
mHalWrapperState = HAL_WRAPPER_STATE_OPEN;
mHciCreditLent = false;
mReadFwConfigDone = false;
+ mError_count = 0;
mHalWrapperCallback = p_cback;
mHalWrapperDataCallback = p_data_cback;
@@ -414,8 +419,42 @@
}
}
}
+ } else if ((p_data[0] == 0x6f) && (p_data[1] == 0x05)) {
+ // start timer
+ mTimerStarted = true;
+ HalSendDownstreamTimer(mHalHandle, 1000);
+ mIsActiveRW = true;
+ } else if ((p_data[0] == 0x6f) && (p_data[1] == 0x06)) {
+ // stop timer
+ if (mTimerStarted) {
+ HalSendDownstreamStopTimer(mHalHandle);
+ mTimerStarted = false;
+ }
+ if(mIsActiveRW == true) {
+ mIsActiveRW = false;
+ } else {
+ mError_count ++;
+ STLOG_HAL_E("Error Act -> Act count=%d", mError_count);
+ if(mError_count > 20) {
+ mError_count = 0;
+ STLOG_HAL_E("NFC Recovery Start");
+ mTimerStarted = true;
+ HalSendDownstreamTimer(mHalHandle, 1);
+ }
+ }
+ } else if (((p_data[0] == 0x61) && (p_data[1] == 0x05)) ||
+ ((p_data[0] == 0x61) && (p_data[1] == 0x03))) {
+ mError_count = 0;
+ // stop timer
+ if (mTimerStarted) {
+ HalSendDownstreamStopTimer(mHalHandle);
+ mTimerStarted = false;
+ }
}
mHalWrapperDataCallback(data_len, p_data);
+ } else if (forceRecover == true) {
+ forceRecover = false;
+ mHalWrapperDataCallback(data_len, p_data);
} else {
STLOG_HAL_V("%s - Core reset notification - Nfc mode ", __func__);
}
@@ -454,6 +493,7 @@
static void halWrapperCallback(uint8_t event, uint8_t event_status) {
uint8_t coreInitCmd[] = {0x20, 0x01, 0x02, 0x00, 0x00};
+ uint8_t propNfcModeSetCmdOn[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
switch (mHalWrapperState) {
case HAL_WRAPPER_STATE_CLOSED:
@@ -496,6 +536,22 @@
}
break;
+ case HAL_WRAPPER_STATE_READY:
+ if (event == HAL_WRAPPER_TIMEOUT_EVT) {
+ if (mTimerStarted) {
+ STLOG_HAL_D("NFC-NCI HAL: %s Timeout.. Recover", __func__);
+ HalSendDownstreamStopTimer(mHalHandle);
+ mTimerStarted = false;
+ forceRecover = true;
+ if (!HalSendDownstream(mHalHandle, propNfcModeSetCmdOn,
+ sizeof(propNfcModeSetCmdOn))) {
+ STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
+ }
+ }
+ return;
+ }
+ break;
+
default:
break;
}
diff --git a/st21nfc/include/halcore.h b/st21nfc/include/halcore.h
index c700aec..a068803 100644
--- a/st21nfc/include/halcore.h
+++ b/st21nfc/include/halcore.h
@@ -74,6 +74,7 @@
// HAL WRAPPER
bool HalSendDownstreamTimer(HALHANDLE hHAL, const uint8_t* data, size_t size,
uint32_t duration);
+bool HalSendDownstreamTimer(HALHANDLE hHAL, uint32_t duration);
bool HalSendDownstreamStopTimer(HALHANDLE hHAL);
/* send a complete HDLC frame from the CLF to the HOST */