Snap for 13256841 from 9c724f616856051759648ede513c208d3e2f4d3d to 25Q2-release
Change-Id: Ibb8d3f26fc7c7e1294b50a8768903c5d85f565db
diff --git a/aidl/StNfc_hal_api.h b/aidl/StNfc_hal_api.h
index 8f00964..1df55b6 100644
--- a/aidl/StNfc_hal_api.h
+++ b/aidl/StNfc_hal_api.h
@@ -66,5 +66,7 @@
bool StNfc_hal_isLoggingEnabled();
void StNfc_hal_dump(int fd);
+uint16_t
+iso14443_crc(const uint8_t *data, size_t szLen, int type);
#endif /* _STNFC_HAL_API_H_ */
diff --git a/aidl/hal_st21nfc.cc b/aidl/hal_st21nfc.cc
index 3b5082e..fddbfa3 100644
--- a/aidl/hal_st21nfc.cc
+++ b/aidl/hal_st21nfc.cc
@@ -39,6 +39,13 @@
#endif
#define VENDOR_LIB_EXT ".so"
+
+#define CRC_PRESET_A 0x6363
+#define CRC_PRESET_B 0xFFFF
+#define Type_A 0
+#define Type_B 1
+
+
bool dbg_logging = false;
extern void HalCoreCallback(void* context, uint32_t event, const void* d,
@@ -393,12 +400,95 @@
return 0;
}
} else if (!memcmp(p_data, NCI_ANDROID_PREFIX, sizeof(NCI_ANDROID_PREFIX)) &&
+ p_data[3] == 0x6) {
+ DispHal("TX DATA", (p_data), data_len);
+
+ memcpy(nci_cmd+3, p_data+4, 4);
+ nci_cmd[0] = 0x2f;
+ nci_cmd[1] = 0x19;
+
+ int index = 8;
+ int ll_index = 7;
+ uint8_t nci_length = 0;
+ uint16_t crc = 0;
+ bool prefix_match = false;
+ bool exact_match = true;
+
+ while (index < data_len) {
+ // Read the Type field (1 byte)
+ uint8_t type_field = p_data[index];
+ int tlv_len = p_data[index + 1];
+ prefix_match = false;
+ exact_match = true;
+ if (p_data[index] == 0x01) {
+ crc = iso14443_crc(p_data + index + 3, (uint8_t)((tlv_len - 1) / 2),
+ Type_B);
+ } else if ((p_data[index] & 0xF0) == 0x00) {
+ crc = iso14443_crc(p_data + index + 3, (uint8_t)((tlv_len - 1) / 2),
+ Type_A);
+ } else {
+ prefix_match = true;
+ }
+
+ nci_cmd[ll_index++] = p_data[index++];
+ nci_cmd[ll_index++] =
+ (!prefix_match) ? p_data[index++] + 4 : p_data[index++];
+ nci_cmd[ll_index++] = p_data[index++];
+
+ memcpy(nci_cmd + ll_index, p_data + index, (uint8_t)((tlv_len - 1) / 2));
+ ll_index += (tlv_len - 1) / 2;
+ index += (tlv_len - 1) / 2;
+ int crc_index = 0;
+ if (!prefix_match) {
+ crc_index = ll_index;
+ nci_cmd[ll_index++] = (uint8_t)crc;
+ nci_cmd[ll_index++] = (uint8_t)(crc >> 8);
+ }
+
+ memcpy(nci_cmd + ll_index, p_data + index, (tlv_len - 1) / 2);
+ for (int i = 0; i < (tlv_len - 1) / 2; ++i) {
+ if (p_data[index + i] != 0xFF) {
+ exact_match = false;
+ break;
+ }
+ }
+ ll_index += (tlv_len - 1) / 2;
+ index += (tlv_len - 1) / 2;
+ uint8_t crc_mask = exact_match ? 0xFF : 0x00;
+ if (!prefix_match) {
+ nci_cmd[ll_index++] = crc_mask;
+ nci_cmd[ll_index++] = crc_mask;
+
+ if (!exact_match) {
+ nci_cmd[crc_index] = crc_mask;
+ nci_cmd[crc_index +1] = crc_mask;
+ }
+
+ }
+ }
+ nci_length = ll_index;
+ nci_cmd[2] = ll_index -3;
+
+ if (!HalSendDownstream(dev.hHAL, nci_cmd, nci_length)) {
+ STLOG_HAL_E("HAL st21nfc %s SendDownstream failed", __func__);
+ (void)pthread_mutex_unlock(&hal_mtx);
+ return 0;
+ }
+ } else if (!memcmp(p_data, NCI_ANDROID_PREFIX, sizeof(NCI_ANDROID_PREFIX)) &&
p_data[3] == 0x9) {
DispHal("TX DATA", (p_data), data_len);
memcpy(nci_cmd + 3, p_data + 4, data_len - 4);
+
+ uint16_t crc = iso14443_crc(nci_cmd + 7, nci_cmd[5] - 1, Type_A);
+
+ uint8_t len = p_data[2];
nci_cmd[0] = 0x2f;
nci_cmd[1] = 0x1d;
- nci_cmd[2] = p_data[2] - 1;
+ nci_cmd[5] = nci_cmd[5] + 2;
+ nci_cmd[data_len - 1] = (uint8_t)crc;
+ nci_cmd[data_len] = (uint8_t)(crc >> 8);
+
+ nci_cmd[2] = p_data[2] + 1;
if (!HalSendDownstream(dev.hHAL, nci_cmd, nci_cmd[2] + 3)) {
STLOG_HAL_E("HAL st21nfc %s SendDownstream failed", __func__);
(void)pthread_mutex_unlock(&hal_mtx);
@@ -627,3 +717,22 @@
bool StNfc_hal_isLoggingEnabled() { return dbg_logging; }
void StNfc_hal_dump(int fd) { hal_wrapper_dumplog(fd); }
+
+uint16_t iso14443_crc(const uint8_t* data, size_t szLen, int type) {
+ uint16_t tempCrc;
+ if (type == Type_A) {
+ tempCrc = (unsigned short)CRC_PRESET_A;
+ } else {
+ tempCrc = (unsigned short)CRC_PRESET_B;
+ }
+ do {
+ uint8_t bt;
+ bt = *data++;
+ bt = (bt ^ (uint8_t)(tempCrc & 0x00FF));
+ bt = (bt ^ (bt << 4));
+ tempCrc = (tempCrc >> 8) ^ ((uint32_t)bt << 8) ^ ((uint32_t)bt << 3) ^
+ ((uint32_t)bt >> 4);
+ } while (--szLen);
+
+ return tempCrc;
+}
diff --git a/st21nfc/hal/hal_event_logger.cc b/st21nfc/hal/hal_event_logger.cc
index 5e6264b..8774a9a 100644
--- a/st21nfc/hal/hal_event_logger.cc
+++ b/st21nfc/hal/hal_event_logger.cc
@@ -127,8 +127,8 @@
oss << ss.str();
}
- dprintf(fd, "===== Nfc HAL Event Log =====\n");
+ dprintf(fd, "===== Nfc HAL Event Log v1 =====\n");
::android::base::WriteStringToFd(oss.str(), fd);
- dprintf(fd, "===== Nfc HAL Event Log =====\n");
+ dprintf(fd, "===== Nfc HAL Event Log v1 =====\n");
fsync(fd);
}
\ No newline at end of file
diff --git a/st21nfc/hal/hal_fd.cc b/st21nfc/hal/hal_fd.cc
index e92fc22..4b73b91 100644
--- a/st21nfc/hal/hal_fd.cc
+++ b/st21nfc/hal/hal_fd.cc
@@ -433,7 +433,9 @@
(mFWInfo->chipHwVersion == HW_ST54L)) {
if ((mFwFileBin != NULL) &&
(mFWInfo->fileFwVersion != mFWInfo->chipFwVersion)) {
- STLOG_HAL_D("---> Firmware update needed\n");
+ STLOG_HAL_D("---> Firmware update needed from 0x%08X to 0x%08X\n",
+ mFWInfo->chipFwVersion, mFWInfo->fileFwVersion);
+
result |= FW_UPDATE_NEEDED;
} else {
STLOG_HAL_D("---> No Firmware update needed\n");
@@ -442,8 +444,9 @@
if ((mFWInfo->fileCustVersion != 0) &&
(mFWInfo->chipCustVersion != mFWInfo->fileCustVersion)) {
STLOG_HAL_D(
- "%s - Need to apply new st21nfc custom configuration settings\n",
- __func__);
+ "%s - Need to apply new st21nfc custom configuration settings from "
+ "0x%04X to 0x%04X\n",
+ __func__, mFWInfo->chipCustVersion, mFWInfo->fileCustVersion);
if (!mCustomParamFailed) result |= CONF_UPDATE_NEEDED;
} else {
STLOG_HAL_D("%s - No need to apply custom configuration settings\n",
@@ -467,6 +470,12 @@
} else {
mFWCap->ObserveMode = 0x1;
}
+ if (hal_fd_getFwInfo()->chipHwVersion == HW_ST54L &&
+ (FWVersionMajor >= 0x2) && (FWVersionMinor >= 0x6)) {
+ mFWCap->ExitFrameSupport = 0x1;
+ } else {
+ mFWCap->ExitFrameSupport = 0x0;
+ }
return result;
} /* ft_cmd_HwReset */
diff --git a/st21nfc/hal/halcore.cc b/st21nfc/hal/halcore.cc
index 1d8fc7c..da5d043 100644
--- a/st21nfc/hal/halcore.cc
+++ b/st21nfc/hal/halcore.cc
@@ -42,11 +42,14 @@
struct timespec start_tx_data;
uint8_t NCI_ANDROID_GET_CAPS[] = {0x2f, 0x0c, 0x01, 0x0};
uint8_t NCI_ANDROID_GET_CAPS_RSP[] = {
- 0x4f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x04, // Number of capabilities
+ 0x4f, 0x0c,
+ 0x14, // Command length
+ 0x00, 0x00, 0x00, 0x00,
+ 0x05, // Nb of capabilities
0x00, 0x01, 0x01, // Passive Observe mode
0x01, 0x01, 0x01, // Polling frame ntf
0x03, 0x01, 0x00, // Autotransact polling loop filter
+ 0x04, 0x01, 0x05, // Nb of max exit frame entries
0x05, 0x01, 0x01 // Polling loop annotations
};
@@ -118,15 +121,16 @@
!memcmp(data, NCI_ANDROID_GET_CAPS, sizeof(NCI_ANDROID_GET_CAPS))) {
NCI_ANDROID_GET_CAPS_RSP[2] = sizeof(NCI_ANDROID_GET_CAPS_RSP) - 3;
NCI_ANDROID_GET_CAPS_RSP[10] = hal_fd_getFwCap()->ObserveMode;
+ NCI_ANDROID_GET_CAPS_RSP[16] = hal_fd_getFwCap()->ExitFrameSupport;
uint8_t FWVersionMajor = (uint8_t)(hal_fd_getFwInfo()->chipFwVersion >> 24);
uint8_t FWVersionMinor =
(uint8_t)((hal_fd_getFwInfo()->chipFwVersion & 0x00FF0000) >> 16);
// Declare support for reader mode annotation only if fw version >= 2.06.
if (hal_fd_getFwInfo()->chipHwVersion == HW_ST54L &&
(FWVersionMajor >= 0x2) && (FWVersionMinor >= 0x6)) {
- NCI_ANDROID_GET_CAPS_RSP[19] = 1;
+ NCI_ANDROID_GET_CAPS_RSP[22] = 1;
} else {
- NCI_ANDROID_GET_CAPS_RSP[19] = 0;
+ NCI_ANDROID_GET_CAPS_RSP[22] = 0;
}
dev->p_data_cback(sizeof(NCI_ANDROID_GET_CAPS_RSP),
diff --git a/st21nfc/hal_wrapper.cc b/st21nfc/hal_wrapper.cc
index 6848327..c86238d 100644
--- a/st21nfc/hal_wrapper.cc
+++ b/st21nfc/hal_wrapper.cc
@@ -83,6 +83,7 @@
bool mObserverRsp = false;
bool mPerTechCmdRsp = false;
bool storedLog = false;
+bool mObserveModeSuspended = false;
void wait_ready() {
pthread_mutex_lock(&mutex);
@@ -117,6 +118,7 @@
mObserverMode = 0;
mObserverRsp = false;
+ mObserveModeSuspended = false;
mHalWrapperCallback = p_cback;
mHalWrapperDataCallback = p_data_cback;
@@ -215,6 +217,7 @@
mObserverMode = enable;
mObserverRsp = true;
mPerTechCmdRsp = per_tech_cmd;
+ mObserveModeSuspended = false;
}
void hal_wrapper_get_observer_mode() { mObserverRsp = true; }
@@ -559,7 +562,11 @@
STLOG_HAL_E("mObserverMode got out of sync");
mObserverMode = p_data[4];
}
+ if (!mObserveModeSuspended) {
p_data[5] = p_data[4];
+ } else {
+ p_data[5] = 0x00;
+ }
} else {
if (p_data[7] != mObserverMode) {
STLOG_HAL_E("mObserverMode got out of sync");
@@ -573,6 +580,7 @@
p_data[3] = 0x04;
p_data[4] = rsp_status;
data_len = 0x6;
+ DispHal("RX DATA", (p_data), data_len);
}
}
@@ -586,7 +594,13 @@
DispHal("RX DATA", (p_data), data_len);
} else if ((p_data[0] == 0x6f) && (p_data[1] == 0x1b)) {
// PROP_RF_OBSERVE_MODE_SUSPENDED_NTF
+ mObserveModeSuspended = true;
+ // Remove two byte CRC at end of frame.
+ data_len -= 2;
+ p_data[2] -= 2;
+ p_data[4] -= 2;
memcpy(nciAndroidPassiveObserver, p_data + 3, data_len - 3);
+
p_data[0] = 0x6f;
p_data[1] = 0x0c;
p_data[2] = p_data[2] + 1;
@@ -596,6 +610,8 @@
DispHal("RX DATA", (p_data), data_len);
} else if ((p_data[0] == 0x6f) && (p_data[1] == 0x1c)) {
// PROP_RF_OBSERVE_MODE_RESUMED_NTF
+ mObserveModeSuspended = false;
+
p_data[0] = 0x6f;
p_data[1] = 0x0c;
p_data[2] = p_data[2] + 1;
@@ -803,6 +819,8 @@
}
break;
case HAL_WRAPPER_STATE_RECOVERY:
+ STLOG_HAL_W("%s - mHalWrapperState = HAL_WRAPPER_STATE_RECOVERY",
+ __func__);
break;
}
}
@@ -929,6 +947,31 @@
}
break;
+ case HAL_WRAPPER_STATE_EXIT_HIBERNATE_INTERNAL:
+ if (event == HAL_WRAPPER_TIMEOUT_EVT) {
+ STLOG_HAL_E("NFC-NCI HAL: %s Timeout at state: %s", __func__,
+ hal_wrapper_state_to_str(mHalWrapperState).c_str());
+ HalEventLogger::getInstance().log()
+ << __func__ << " Timer when sending conf parameters, retry"
+ << " mHalWrapperState="
+ << hal_wrapper_state_to_str(mHalWrapperState)
+ << " mIsActiveRW=" << mIsActiveRW
+ << " mTimerStarted=" << mTimerStarted << std::endl;
+ HalEventLogger::getInstance().store_log();
+ HalSendDownstreamStopTimer(mHalHandle);
+ p_data[0] = 0x60;
+ p_data[1] = 0x00;
+ p_data[2] = 0x03;
+ p_data[3] = 0xAB;
+ p_data[4] = 0x00;
+ p_data[5] = 0x00;
+ data_len = 0x6;
+ mHalWrapperDataCallback(data_len, p_data);
+ mHalWrapperState = HAL_WRAPPER_STATE_OPEN;
+ return;
+ }
+ break;
+
default:
if (event == HAL_WRAPPER_TIMEOUT_EVT) {
STLOG_HAL_E("NFC-NCI HAL: %s Timeout at state: %s", __func__,
diff --git a/st21nfc/include/hal_fd.h b/st21nfc/include/hal_fd.h
index affc06b..56a6ac9 100644
--- a/st21nfc/include/hal_fd.h
+++ b/st21nfc/include/hal_fd.h
@@ -47,7 +47,7 @@
*/
typedef struct FWCap {
uint8_t ObserveMode;
-
+ uint8_t ExitFrameSupport;
} FWCap;
typedef enum {