Snap for 10453563 from e0d57d01366dbc0a7188ad3b9ec80fb1ce19815d to mainline-art-release Change-Id: Ibe3619f312050cda547aa69704ccaa2b987b9e3e
diff --git a/aidl/hal_st21nfc.cc b/aidl/hal_st21nfc.cc index 755ece1..d3903c7 100644 --- a/aidl/hal_st21nfc.cc +++ b/aidl/hal_st21nfc.cc
@@ -345,6 +345,7 @@ } int StNfc_hal_close(int nfc_mode_value) { + void* stdll = nullptr; STLOG_HAL_D("HAL st21nfc: %s nfc_mode = %d", __func__, nfc_mode_value); /* check if HAL is closed */ @@ -371,8 +372,11 @@ std::string valueStr = android::base::GetProperty("persist.vendor.nfc.streset", ""); if (valueStr.length() > 0) { - valueStr = VENDOR_LIB_PATH + valueStr + VENDOR_LIB_EXT; - void* stdll = dlopen(valueStr.c_str(), RTLD_NOW); + stdll = dlopen(valueStr.c_str(), RTLD_NOW); + if (!stdll) { + valueStr = VENDOR_LIB_PATH + valueStr + VENDOR_LIB_EXT; + stdll = dlopen(valueStr.c_str(), RTLD_NOW); + } if (stdll) { STLOG_HAL_D("STReset Cold reset"); STEseReset fn = (STEseReset)dlsym(stdll, "cold_reset"); @@ -524,10 +528,10 @@ void StNfc_hal_setLogging(bool enable) { dbg_logging = enable; - if (dbg_logging) { + if (dbg_logging && hal_conf_trace_level < STNFC_TRACE_LEVEL_VERBOSE) { hal_trace_level = STNFC_TRACE_LEVEL_VERBOSE; } else { - hal_trace_level = STNFC_TRACE_LEVEL_ERROR; + hal_trace_level = hal_conf_trace_level; } }
diff --git a/aidl/main.cpp b/aidl/main.cpp index e596386..a9d7275 100644 --- a/aidl/main.cpp +++ b/aidl/main.cpp
@@ -30,13 +30,17 @@ typedef int (*STEseReset)(void); int main() { + void* stdll = nullptr; LOG(INFO) << "NFC AIDL HAL Service is starting up"; std::string valueStr = android::base::GetProperty("persist.vendor.nfc.streset", ""); if (valueStr.length() > 0) { - valueStr = VENDOR_LIB_PATH + valueStr + VENDOR_LIB_EXT; - void* stdll = dlopen(valueStr.c_str(), RTLD_NOW); + stdll = dlopen(valueStr.c_str(), RTLD_NOW); + if (!stdll) { + valueStr = VENDOR_LIB_PATH + valueStr + VENDOR_LIB_EXT; + stdll = dlopen(valueStr.c_str(), RTLD_NOW); + } if (stdll) { LOG(INFO) << "ST NFC HAL STReset starting."; STEseReset fn = (STEseReset)dlsym(stdll, "boot_reset");
diff --git a/st21nfc/adaptation/android_logmsg.cpp b/st21nfc/adaptation/android_logmsg.cpp index 341309a..72e5b6a 100644 --- a/st21nfc/adaptation/android_logmsg.cpp +++ b/st21nfc/adaptation/android_logmsg.cpp
@@ -22,6 +22,7 @@ void DispHal(const char* title, const void* data, size_t length); unsigned char hal_trace_level = STNFC_TRACE_LEVEL_DEBUG; +unsigned char hal_conf_trace_level = STNFC_TRACE_LEVEL_DEBUG; uint16_t hal_log_cnt = 0; pthread_mutex_t halLogMutex; @@ -49,8 +50,10 @@ int ret; num = 1; - if (GetNumValue(NAME_STNFC_HAL_LOGLEVEL, &num, sizeof(num))) - hal_trace_level = (unsigned char)num; + if (GetNumValue(NAME_STNFC_HAL_LOGLEVEL, &num, sizeof(num))) { + hal_conf_trace_level = (unsigned char)num; + hal_trace_level = hal_conf_trace_level; + } STLOG_HAL_D("%s: HAL log level=%u, hal_log_cnt (before reset): #%04X", __func__, hal_trace_level, hal_log_cnt); @@ -123,13 +126,15 @@ STLOG_HAL_D("%s\n", line); } } - line[k] = 0; + if (k < 100) { + line[k] = 0; + } } - sprintf(&line[k * 3], "%02x ", d[i]); + snprintf(&line[k * 3], sizeof(line) - (k * 3), "%02x ", d[i]); } if (privacy) { - sprintf(&line[k * 3], "(hidden)"); + snprintf(&line[k * 3], sizeof(line) - (k * 3), "(hidden)"); } if (first_line == true) {
diff --git a/st21nfc/adaptation/i2clayer.cc b/st21nfc/adaptation/i2clayer.cc index 4cad4db..4cbff2e 100644 --- a/st21nfc/adaptation/i2clayer.cc +++ b/st21nfc/adaptation/i2clayer.cc
@@ -113,7 +113,12 @@ int poll_status = poll(event_table, eventNum, -1); if (-1 == poll_status) { - STLOG_HAL_E("error in poll call\n"); + poll_status = errno; + STLOG_HAL_E("error in poll call : %d - %s\n", poll_status, + strerror(poll_status)); + if ((poll_status == EINTR) || (poll_status == EAGAIN)) continue; + + // other errors, we stop. break; } @@ -235,6 +240,9 @@ } } while (!closeThread); + // Stop here if we got a serious error above. + assert(closeThread); + close(fidI2c); close(cmdPipe[0]); close(cmdPipe[1]);
diff --git a/st21nfc/hal/hal_fd.cc b/st21nfc/hal/hal_fd.cc index 2e8fab0..810aca3 100644 --- a/st21nfc/hal/hal_fd.cc +++ b/st21nfc/hal/hal_fd.cc
@@ -55,6 +55,51 @@ static const uint8_t ApduExitLoadMode[] = {0x2F, 0x04, 0x06, 0x80, 0xA0, 0x00, 0x00, 0x01, 0x01}; + +// APDUs for ST54L +const int UK_NB = 2; +const int UK_SIZE = 12; +static uint8_t UserKeys[UK_NB][UK_SIZE] = { + {0x00, 0x00, 0xFD, 0x0F, 0x87, 0x7D, 0x31, 0xE3, 0xCF, 0x0C, 0xD3, + 0x68}, // Test + {0x00, 0x00, 0xFD, 0x00, 0x87, 0x7D, 0x31, 0xE3, 0xCF, 0x0C, 0xD3, + 0x68}}; // Production + +static uint8_t ApduPutKeyUser1[UK_NB][50] = { + {0x2F, 0x04, 0x2F, 0x84, 0x11, 0x00, 0x00, 0x2A, 0x01, 0xB3, + 0x56, 0x01, // Test + 0x00, 0x00, 0xFD, 0x20, 0x20, 0xEC, 0x7D, 0x47, 0xAE, 0xF3, + 0x23, 0x2E, 0x00, 0x00, 0x34, 0x78, 0x82, 0xEC, 0x6b, 0xA5, + 0x83, 0xAF, 0x68, 0xC7, 0x1F, 0x9F, 0xB0, 0xD7, 0x9D, 0x33, + 0xB0, 0xDA, 0xC6, 0x2C, 0xAB, 0x8A, 0x10, 0xEA}, + {0x2F, 0x04, 0x2F, 0x84, 0x11, 0x00, 0x00, 0x2A, 0x01, 0xB3, + 0x56, 0x01, // Production + 0x00, 0x00, 0xFD, 0x20, 0x20, 0xEC, 0x7D, 0x47, 0xAE, 0xF3, + 0x23, 0x2E, 0x00, 0x00, 0xE1, 0xA2, 0x78, 0xA9, 0x71, 0x14, + 0x46, 0x6D, 0x73, 0x86, 0x4C, 0x3B, 0x0F, 0x51, 0x71, 0x8E, + 0xE4, 0x1D, 0x54, 0x02, 0x3A, 0xE3, 0x18, 0x55}}; + +static uint8_t ApduEraseUpgradeStart[] = { + 0x2F, 0x04, 0x12, 0x84, 0x35, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xB2, 0x51, 0x42, 0xB0, 0x27, 0x92, 0xAA, 0xAB}; + +static uint8_t ApduEraseNfcArea[] = {0x2F, 0x04, 0x17, 0x84, 0x36, 0x00, 0x00, + 0x12, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x04, 0x5E, 0x00, 0x4D, 0x83, 0xE1, + 0x59, 0x62, 0xDC, 0x14, 0x64}; + +static uint8_t ApduEraseUpgradeStop[] = {0x2F, 0x04, 0x0F, 0x80, 0x33, 0x00, + 0x00, 0x0A, 0x00, 0x02, 0x97, 0x22, + 0xC2, 0x5A, 0x2D, 0xA4, 0x09, 0x1A}; + +static uint8_t ApduSetVariousConfig[] = { + 0x2F, 0x04, 0x11, 0x84, 0x74, 0x00, 0x00, 0x0C, 0x06, 0x02, + 0x80, 0x80, 0xD4, 0x29, 0xEC, 0x9A, 0xFB, 0xC8, 0x4B, 0x2A}; + +static uint8_t ApduSwitchToUser[] = {0x2F, 0x04, 0x0F, 0x84, 0xA0, 0x00, + 0x00, 0x0A, 0x20, 0x01, 0xFC, 0x63, + 0x2A, 0xE1, 0xFD, 0xAA, 0xD1, 0x9B}; + static const uint8_t nciHeaderPropSetUwbConfig[9] = { 0x2F, 0x02, 0x00, 0x04, 0x00, 0x16, 0x01, 0x00, 0x00}; static const uint8_t nciGetPropConfig[8] = {0x2F, 0x02, 0x05, 0x03, @@ -64,12 +109,44 @@ static uint8_t nciPropSetUwbConfig[128]; static uint8_t nciPropSetConfig_CustomField[64]; hal_fd_state_e mHalFDState = HAL_FD_STATE_AUTHENTICATE; +hal_fd_st54l_state_e mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER; void SendExitLoadMode(HALHANDLE mmHalHandle); +void SendSwitchToUserMode(HALHANDLE mmHalHandle); extern void hal_wrapper_update_complete(); typedef size_t (*STLoadUwbParams)(void *out_buff, size_t buf_size); +/*********************************************************************** + * Determine UserKey + * + * @return mode: -1 : not supported + * 0 : Test sample + * 1 : Product sample + ***********************************************************************/ +static int GetProdType(uint8_t* UserKey) { + int i, j; + int status; + + for (i = 0; i < UK_NB; i++) { + status = 1; + for (j = 0; j < UK_SIZE; j++) { + if (UserKey[j] != UserKeys[i][j]) { + STLOG_HAL_D( + " No match between UserKey[%d]=0x%02X and \ + UserKeys[%d][%d]=0x%02X", + j, UserKey[j], i, j, UserKeys[i][j]); + status = 0; + break; + } + } + if (1 == status) { + return i; + } + } + return (-1); +} + /** * Send a HW reset and decode NCI_CORE_RESET_NTF information * @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF @@ -90,6 +167,7 @@ char ConfPath[256]; char fwBinName[256]; char fwConfName[256]; + int ret; STLOG_HAL_D(" %s - enter", __func__); @@ -142,19 +220,56 @@ STLOG_HAL_D("%s - %s not detected", __func__, fwBinName); } else { STLOG_HAL_D("%s - %s file detected\n", __func__, fwBinName); - result |= FW_PATCH_AVAILABLE; - fread(mBinData, sizeof(uint8_t), 4, mFwFileBin); - mFWInfo->patchVersion = + + ret = fread(mBinData, sizeof(uint8_t), 4, mFwFileBin); + if (ret != 4) { + STLOG_HAL_E("%s did not read 4 bytes \n", __func__); + } + mFWInfo->fileFwVersion = mBinData[0] << 24 | mBinData[1] << 16 | mBinData[2] << 8 | mBinData[3]; - fread(mApduAuthent, sizeof(uint8_t), 24, mFwFileBin); - fgetpos(mFwFileBin, &mPosInit); + ret = fread(mBinData, sizeof(uint8_t), 5, mFwFileBin); + if (ret != 5) { + STLOG_HAL_E("%s did not read 5 bytes \n", __func__); + } + fsetpos(mFwFileBin, &mPosInit); // reset pos in stream - STLOG_HAL_D( - "%s --> st21nfc_fw integrates patch NFC FW version 0x%08X (%s)\n", - __func__, mFWInfo->patchVersion, FwType); + if (mBinData[4] == 0x35) { + mFWInfo->fileHwVersion = HW_ST54L; + } else { + ret = fread(mApduAuthent, sizeof(uint8_t), 24, mFwFileBin); + if (ret != 24) { + STLOG_HAL_E("%s Wrong read nb \n", __func__); + } + + // We use the last byte of the auth command to discriminate at the moment. + // it can be extended in case of conflict later. + switch (mApduAuthent[23]) { + case 0x43: + case 0xC7: + mFWInfo->fileHwVersion = HW_NFCD; + break; + + case 0xE9: + mFWInfo->fileHwVersion = HW_ST54J; + break; + } + } + + if (mFWInfo->fileHwVersion == 0) { + STLOG_HAL_E("%s --> %s integrates unknown patch NFC FW -- rejected\n", + __func__, FwPath); + fclose(mFwFileBin); + mFwFileBin = NULL; + } else { + fgetpos(mFwFileBin, &mPosInit); + + STLOG_HAL_D("%s --> %s integrates patch NFC FW version 0x%08X (r:%d)\n", + __func__, FwPath, mFWInfo->fileFwVersion, + mFWInfo->fileHwVersion); + } } if ((mCustomFileBin = fopen((char *)ConfPath, "r")) == NULL) { @@ -162,9 +277,9 @@ } else { STLOG_HAL_D("%s - %s file detected\n", __func__, ConfPath); fread(mBinData, sizeof(uint8_t), 2, mCustomFileBin); - mFWInfo->confVersion = mBinData[0] << 8 | mBinData[1]; + mFWInfo->fileCustVersion = mBinData[0] << 8 | mBinData[1]; STLOG_HAL_D("%s --> st21nfc_custom configuration version 0x%04X \n", - __func__, mFWInfo->confVersion); + __func__, mFWInfo->fileCustVersion); result |= FW_CUSTOM_PARAM_AVAILABLE; } @@ -215,25 +330,26 @@ STLOG_HAL_D("-> Router Mode NCI_CORE_RESET_NTF received after HW Reset"); /* retrieve HW Version from NCI_CORE_RESET_NTF */ - mFWInfo->hwVersion = pdata[8]; - STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->hwVersion); + mFWInfo->chipHwVersion = pdata[8]; + STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->chipHwVersion); /* retrieve FW Version from NCI_CORE_RESET_NTF */ - mFWInfo->fwVersion = + mFWInfo->chipFwVersion = (pdata[10] << 24) | (pdata[11] << 16) | (pdata[12] << 8) | pdata[13]; - STLOG_HAL_D(" FwVersion = 0x%08X", mFWInfo->fwVersion); + STLOG_HAL_D(" FwVersion = 0x%08X", mFWInfo->chipFwVersion); /* retrieve Loader Version from NCI_CORE_RESET_NTF */ - mFWInfo->loaderVersion = (pdata[14] << 16) | (pdata[15] << 8) | pdata[16]; - STLOG_HAL_D(" LoaderVersion = 0x%06X", mFWInfo->loaderVersion); + mFWInfo->chipLoaderVersion = + (pdata[14] << 16) | (pdata[15] << 8) | pdata[16]; + STLOG_HAL_D(" LoaderVersion = 0x%06X", mFWInfo->chipLoaderVersion); /* retrieve Customer Version from NCI_CORE_RESET_NTF */ - mFWInfo->custVersion = (pdata[31] << 8) | pdata[32]; - STLOG_HAL_D(" CustomerVersion = 0x%04X", mFWInfo->custVersion); + mFWInfo->chipCustVersion = (pdata[31] << 8) | pdata[32]; + STLOG_HAL_D(" CustomerVersion = 0x%04X", mFWInfo->chipCustVersion); /* retrieve Uwb param Version from NCI_CORE_RESET_NTF */ - mFWInfo->uwbFwVersion = (pdata[29] << 8) | pdata[30]; - STLOG_HAL_D(" uwbVersion = 0x%04X", mFWInfo->uwbFwVersion); + mFWInfo->chipUwbVersion = (pdata[29] << 8) | pdata[30]; + STLOG_HAL_D(" uwbVersion = 0x%04X", mFWInfo->chipUwbVersion); *clf_mode = FT_CLF_MODE_ROUTER; } else if ((pdata[2] == 0x39) && (pdata[3] == 0xA1)) { @@ -241,32 +357,43 @@ /* deduce HW Version from Factory Loader version */ if (pdata[16] == 0x01) { - mFWInfo->hwVersion = 0x05; // ST54J + mFWInfo->chipHwVersion = 0x05; // ST54J } else if (pdata[16] == 0x02) { - mFWInfo->hwVersion = 0x04; // ST21NFCD + mFWInfo->chipHwVersion = 0x04; // ST21NFCD } else { - mFWInfo->hwVersion = 0x03; // ST21NFCD + mFWInfo->chipHwVersion = 0x03; // ST21NFCD } - STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->hwVersion); + STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->chipHwVersion); /* Identify the Active loader. Normally only one should be detected*/ if (pdata[11] == 0xA0) { - mFWInfo->loaderVersion = (pdata[8] << 16) | (pdata[9] << 8) | pdata[10]; + mFWInfo->chipLoaderVersion = + (pdata[8] << 16) | (pdata[9] << 8) | pdata[10]; STLOG_HAL_D(" - Most recent loader activated, revision 0x%06X", - mFWInfo->loaderVersion); + mFWInfo->chipLoaderVersion); } if (pdata[15] == 0xA0) { - mFWInfo->loaderVersion = (pdata[12] << 16) | (pdata[13] << 8) | pdata[14]; + mFWInfo->chipLoaderVersion = + (pdata[12] << 16) | (pdata[13] << 8) | pdata[14]; STLOG_HAL_D(" - Least recent loader activated, revision 0x%06X", - mFWInfo->loaderVersion); + mFWInfo->chipLoaderVersion); } if (pdata[19] == 0xA0) { - mFWInfo->loaderVersion = (pdata[16] << 16) | (pdata[17] << 8) | pdata[18]; + mFWInfo->chipLoaderVersion = + (pdata[16] << 16) | (pdata[17] << 8) | pdata[18]; STLOG_HAL_D(" - Factory loader activated, revision 0x%06X", - mFWInfo->loaderVersion); + mFWInfo->chipLoaderVersion); } *clf_mode = FT_CLF_MODE_LOADER; + } else if ((pdata[2] == 0x41) && (pdata[3] == 0xA2)) { + STLOG_HAL_D("-> Loader V3 Mode NCI_CORE_RESET_NTF received after HW Reset"); + mFWInfo->chipHwVersion = HW_ST54L; + STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->chipHwVersion); + mFWInfo->chipFwVersion = 0; // make sure FW will be updated. + /* retrieve Production type* from NCI_CORE_RESET_NTF */ + mFWInfo->chipProdType = GetProdType(&pdata[44]); + *clf_mode = FT_CLF_MODE_LOADER; } else { STLOG_HAL_E( "%s --> ERROR: wrong NCI_CORE_RESET_NTF received after HW Reset", @@ -274,17 +401,18 @@ *clf_mode = FT_CLF_MODE_ERROR; } - // Allow update only for ST54J - if (mFWInfo->hwVersion == 0x05) { - if ((mFwFileBin != NULL) && (mFWInfo->patchVersion != mFWInfo->fwVersion)) { + if ((mFWInfo->chipHwVersion == HW_ST54J) || + (mFWInfo->chipHwVersion == HW_ST54L)) { + if ((mFwFileBin != NULL) && + (mFWInfo->fileFwVersion != mFWInfo->chipFwVersion)) { STLOG_HAL_D("---> Firmware update needed\n"); result |= FW_UPDATE_NEEDED; } else { STLOG_HAL_D("---> No Firmware update needed\n"); } - if ((mFWInfo->confVersion != 0) && - (mFWInfo->custVersion != mFWInfo->confVersion)) { + if ((mFWInfo->fileCustVersion != 0) && + (mFWInfo->chipCustVersion != mFWInfo->fileCustVersion)) { STLOG_HAL_D( "%s - Need to apply new st21nfc custom configuration settings\n", __func__); @@ -294,8 +422,8 @@ __func__); } } - if ((mFWInfo->uwbVersion != 0) && - (mFWInfo->uwbVersion != mFWInfo->uwbFwVersion)) { + if ((mFWInfo->fileUwbVersion != 0) && + (mFWInfo->fileUwbVersion != mFWInfo->chipUwbVersion)) { result |= UWB_CONF_UPDATE_NEEDED; STLOG_HAL_D("%s - Need to apply new uwb param configuration \n", __func__); mUwbConfigNeeded = true; @@ -401,10 +529,10 @@ memcpy(nciPropSetUwbConfig, nciHeaderPropSetUwbConfig, 9); nciPropSetUwbConfig[2] = lengthOutput + 6; nciPropSetUwbConfig[8] = lengthOutput; - mFWInfo->uwbVersion = + mFWInfo->fileUwbVersion = nciPropSetUwbConfig[9] << 8 | nciPropSetUwbConfig[10]; STLOG_HAL_D("%s --> uwb configuration version 0x%04X \n", __func__, - mFWInfo->uwbVersion); + mFWInfo->fileUwbVersion); return true; } else { STLOG_HAL_D("%s: lengthOutput null", __func__); @@ -415,11 +543,34 @@ } return false; } +/******************************************************************************* +** +** Function resetHandlerState +** +** Description Reset FW update state. +** +** Parameters void +** +** +*******************************************************************************/ void resetHandlerState() { STLOG_HAL_D("%s", __func__); mHalFDState = HAL_FD_STATE_AUTHENTICATE; + mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER; } +/******************************************************************************* +** +** Function UpdateHandler +** +** Description Handler to update ST54J NFCC FW. +** +** Parameters mHalHandle - HAL handle +** data_len - Buffer length +** p_data - Data buffer from NFCC +** +** +*******************************************************************************/ void UpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t *p_data) { HalSendDownstreamStopTimer(mHalHandle); @@ -512,8 +663,9 @@ STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_EXIT_APDU", __func__); if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) { STLOG_HAL_D( - "%s - Error exiting loader mode, i.e. a problem occured during FW " - "update", __func__); + "%s - Error exiting loader mode, i.e. a problem occurred" + "during FW update", + __func__); } I2cResetPulse(); @@ -529,6 +681,176 @@ } } +/******************************************************************************* +** +** Function UpdateHandlerST54L +** +** Description Handler to update ST54L NFCC FW. +** +** Parameters mHalHandle - HAL handle +** data_len - Buffer length +** p_data - Data buffer from NFCC +** +** +*******************************************************************************/ +static void UpdateHandlerST54L(HALHANDLE mHalHandle, uint16_t data_len, + uint8_t* p_data) { + STLOG_HAL_D("%s : Enter state = %d", __func__, mHalFD54LState); + + switch (mHalFD54LState) { + case HAL_FD_ST54L_STATE_PUY_KEYUSER: + if (!HalSendDownstreamTimer( + mHalHandle, (uint8_t*)ApduPutKeyUser1[mFWInfo->chipProdType], + sizeof(ApduPutKeyUser1[mFWInfo->chipProdType]), + FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_UPGRADE_START; + break; + + case HAL_FD_ST54L_STATE_ERASE_UPGRADE_START: + if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) { + if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseUpgradeStart, + sizeof(ApduEraseUpgradeStart), + FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_NFC_AREA; + } else { + STLOG_HAL_D("%s - FW flash not succeeded", __func__); + SendSwitchToUserMode(mHalHandle); + } + break; + + case HAL_FD_ST54L_STATE_ERASE_NFC_AREA: + if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) { + if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseNfcArea, + sizeof(ApduEraseNfcArea), + FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP; + } else { + STLOG_HAL_D("%s - FW flash not succeeded", __func__); + SendSwitchToUserMode(mHalHandle); + } + break; + + case HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP: + if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) { + if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseUpgradeStop, + sizeof(ApduEraseUpgradeStop), + FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + mHalFD54LState = HAL_FD_ST54L_STATE_SEND_RAW_APDU; + } else { + STLOG_HAL_D("%s - FW flash not succeeded", __func__); + SendSwitchToUserMode(mHalHandle); + } + break; + + case HAL_FD_ST54L_STATE_SEND_RAW_APDU: + STLOG_HAL_D("%s - mHalFDState = HAL_FD_ST54L_STATE_SEND_RAW_APDU", + __func__); + if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) { + if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) { + mRetry = true; + + fgetpos(mFwFileBin, &mPos); // save current position in stream + if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) && + (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) == + mBinData[2])) { + if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3, + FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + } else { + STLOG_HAL_D("%s - EOF of FW binary", __func__); + if (!HalSendDownstreamTimer( + mHalHandle, (uint8_t*)ApduSetVariousConfig, + sizeof(ApduSetVariousConfig), FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + mHalFD54LState = HAL_FD_ST54L_STATE_SET_CONFIG; + } + } else if (mRetry == true) { + STLOG_HAL_D("%s - Last Tx was NOK. Retry", __func__); + mRetry = false; + fsetpos(mFwFileBin, &mPos); + if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) && + (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) == + mBinData[2])) { + if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3, + FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + fgetpos(mFwFileBin, &mPos); // save current position in stream + } else { + STLOG_HAL_D("%s - EOF of FW binary", __func__); + if (!HalSendDownstreamTimer( + mHalHandle, (uint8_t*)ApduSetVariousConfig, + sizeof(ApduSetVariousConfig), FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + mHalFD54LState = HAL_FD_ST54L_STATE_SET_CONFIG; + } + } else { + STLOG_HAL_D("%s - FW flash not succeeded.", __func__); + I2cResetPulse(); + SendSwitchToUserMode(mHalHandle); + } + } + break; + + case HAL_FD_ST54L_STATE_SET_CONFIG: + + if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) { + SendSwitchToUserMode(mHalHandle); + } + break; + + case HAL_FD_ST54L_STATE_SWITCH_TO_USER: + if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) { + STLOG_HAL_D( + "%s - Error exiting loader mode, i.e. a problem occurred during FW " + "update", + __func__); + } + + I2cResetPulse(); + hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN); + mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER; + break; + + default: + STLOG_HAL_D("%s - mHalFD54LState = unknown", __func__); + STLOG_HAL_D("%s - FW flash not succeeded", __func__); + SendSwitchToUserMode(mHalHandle); + break; + } +} + +/******************************************************************************* +** +** Function FwUpdateHandler +** +** Description Handler to update NFCC FW. +** +** Parameters mHalHandle - HAL handle +** data_len - Buffer length +** p_data - Data buffer from NFCC +** +** +*******************************************************************************/ +void FwUpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data) { + if (mFWInfo->chipHwVersion == HW_ST54L) { + UpdateHandlerST54L(mHalHandle, data_len, p_data); + } else { + UpdateHandler(mHalHandle, data_len, p_data); + } +} + void ApplyCustomParamHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t *p_data) { STLOG_HAL_D("%s - Enter ", __func__); @@ -595,8 +917,8 @@ nciPropSetConfig_CustomField[8] = p_data[6]; nciPropSetConfig_CustomField[2] = p_data[6] + 6; memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]); - nciPropSetConfig_CustomField[13] = mFWInfo->uwbFwVersion >> 8; - nciPropSetConfig_CustomField[14] = mFWInfo->uwbFwVersion; + nciPropSetConfig_CustomField[13] = mFWInfo->chipUwbVersion >> 8; + nciPropSetConfig_CustomField[14] = mFWInfo->chipUwbVersion; if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField, nciPropSetConfig_CustomField[2] + 3)) { @@ -697,8 +1019,8 @@ nciPropSetConfig_CustomField[8] = p_data[6]; nciPropSetConfig_CustomField[2] = p_data[6] + 6; memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]); - nciPropSetConfig_CustomField[13] = mFWInfo->uwbVersion >> 8; - nciPropSetConfig_CustomField[14] = mFWInfo->uwbVersion; + nciPropSetConfig_CustomField[13] = mFWInfo->fileUwbVersion >> 8; + nciPropSetConfig_CustomField[14] = mFWInfo->fileUwbVersion; if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField, nciPropSetConfig_CustomField[2] + 3)) { @@ -739,3 +1061,13 @@ } mHalFDState = HAL_FD_STATE_EXIT_APDU; } + +void SendSwitchToUserMode(HALHANDLE mmHalHandle) { + STLOG_HAL_D("%s: enter", __func__); + + if (!HalSendDownstreamTimer(mmHalHandle, ApduSwitchToUser, + sizeof(ApduSwitchToUser), FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } + mHalFD54LState = HAL_FD_ST54L_STATE_SWITCH_TO_USER; +}
diff --git a/st21nfc/hal/hal_fd.h b/st21nfc/hal/hal_fd.h index 3ee42e9..44cde09 100644 --- a/st21nfc/hal/hal_fd.h +++ b/st21nfc/hal/hal_fd.h
@@ -28,14 +28,18 @@ */ typedef struct FWInfo { uint32_t patchVersion; - uint32_t fwVersion; - uint8_t hwVersion; - uint32_t loaderVersion; - uint16_t custVersion; - uint16_t confVersion; - uint16_t uwbFwVersion; - uint16_t uwbVersion; + uint32_t chipFwVersion; + uint8_t chipHwVersion; + uint32_t chipLoaderVersion; + uint16_t chipCustVersion; + uint16_t chipUwbVersion; bool hibernate_exited; + + uint16_t fileUwbVersion; + uint8_t fileHwVersion; // if 0, no FW patch available. + uint32_t fileFwVersion; + uint16_t fileCustVersion; // if 0, no custom params available. + uint8_t chipProdType; } FWInfo; typedef enum { @@ -46,6 +50,16 @@ HAL_FD_STATE_EXIT_APDU, } hal_fd_state_e; +typedef enum { + HAL_FD_ST54L_STATE_PUY_KEYUSER, + HAL_FD_ST54L_STATE_ERASE_UPGRADE_START, + HAL_FD_ST54L_STATE_ERASE_NFC_AREA, + HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP, + HAL_FD_ST54L_STATE_SEND_RAW_APDU, + HAL_FD_ST54L_STATE_SET_CONFIG, + HAL_FD_ST54L_STATE_SWITCH_TO_USER, +} hal_fd_st54l_state_e; + #define FT_CLF_MODE_ERROR 0 #define FT_CLF_MODE_LOADER 1 #define FT_CLF_MODE_ROUTER 2 @@ -62,13 +76,18 @@ #define MAX_BUFFER_SIZE 300 +// HwVersion : +#define HW_NFCD 0x04 +#define HW_ST54J 0x05 +#define HW_ST54L 0x06 + /* Function declarations */ int hal_fd_init(); void hal_fd_close(); uint8_t ft_cmd_HwReset(uint8_t* pdata, uint8_t* clf_mode); void ExitHibernateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data); -void UpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data); +void FwUpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data); void ApplyCustomParamHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data); void ApplyUwbParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
diff --git a/st21nfc/hal/halcore.cc b/st21nfc/hal/halcore.cc index 67ecbf9..d705fd9 100644 --- a/st21nfc/hal/halcore.cc +++ b/st21nfc/hal/halcore.cc
@@ -95,7 +95,7 @@ usleep(1000 * (TX_DELAY - delta_time_ms)); } rf_deactivate_delay = false; - } else if (data[0] == 0x00 && data[1] == 0x00) { + } else if (length > 1 && data[0] == 0x00 && data[1] == 0x00) { start_tx_data = HalGetTimestamp(); rf_deactivate_delay = true; } else { @@ -118,7 +118,8 @@ STLOG_HAL_W( "length is illogical. Header length is %d, packet length %zu\n", data[2], length); - } else if (rf_deactivate_delay && data[0] == 0x00 && data[1] == 0x00) { + } else if (length > 1 && rf_deactivate_delay + && data[0] == 0x00 && data[1] == 0x00) { rf_deactivate_delay = false; }
diff --git a/st21nfc/hal_wrapper.cc b/st21nfc/hal_wrapper.cc index 5c97179..626f4e1 100644 --- a/st21nfc/hal_wrapper.cc +++ b/st21nfc/hal_wrapper.cc
@@ -51,6 +51,7 @@ uint8_t mError_count = 0; bool mIsActiveRW = false; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t mutex_activerw = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; static const uint8_t ApduGetAtr[] = {0x2F, 0x04, 0x05, 0x80, @@ -213,6 +214,7 @@ STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_OPEN", __func__); if ((p_data[0] == 0x60) && (p_data[1] == 0x00)) { + mIsActiveRW = false; mFwUpdateTaskMask = ft_cmd_HwReset(p_data, &mClfMode); if (mfactoryReset == true) { @@ -240,12 +242,17 @@ mHalWrapperCallback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED); I2cCloseLayer(); } else { - STLOG_HAL_V("%s - Send APDU_GET_ATR_CMD", __func__); - mRetryFwDwl--; - if (!HalSendDownstreamTimer(mHalHandle, ApduGetAtr, - sizeof(ApduGetAtr), - FW_TIMER_DURATION)) { - STLOG_HAL_E("%s - SendDownstream failed", __func__); + if (((p_data[3] == 0x01) && (p_data[8] == HW_ST54L)) || + ((p_data[2] == 0x41) && (p_data[3] == 0xA2))) { // ST54L + FwUpdateHandler(mHalHandle, data_len, p_data); + } else { + STLOG_HAL_V("%s - Send APDU_GET_ATR_CMD", __func__); + mRetryFwDwl--; + if (!HalSendDownstreamTimer(mHalHandle, ApduGetAtr, + sizeof(ApduGetAtr), + FW_TIMER_DURATION)) { + STLOG_HAL_E("%s - SendDownstream failed", __func__); + } } mHalWrapperState = HAL_WRAPPER_STATE_UPDATE; } @@ -488,11 +495,14 @@ } } } else if ((p_data[0] == 0x6f) && (p_data[1] == 0x05)) { + (void)pthread_mutex_lock(&mutex_activerw); // start timer mTimerStarted = true; HalSendDownstreamTimer(mHalHandle, 5000); mIsActiveRW = true; + (void)pthread_mutex_unlock(&mutex_activerw); } else if ((p_data[0] == 0x6f) && (p_data[1] == 0x06)) { + (void)pthread_mutex_lock(&mutex_activerw); // stop timer if (mTimerStarted) { HalSendDownstreamStopTimer(mHalHandle); @@ -510,6 +520,7 @@ HalSendDownstreamTimer(mHalHandle, 1); } } + (void)pthread_mutex_unlock(&mutex_activerw); } else if (((p_data[0] == 0x61) && (p_data[1] == 0x05)) || ((p_data[0] == 0x61) && (p_data[1] == 0x03))) { mError_count = 0; @@ -518,16 +529,33 @@ HalSendDownstreamStopTimer(mHalHandle); mTimerStarted = false; } - } else if ((p_data[0] == 0x60) && (p_data[1] == 0x07) && (p_data[3] == 0xE1)) { - // Core Generic Error - Buffer Overflow Ntf - Restart all - STLOG_HAL_E("Core Generic Error - restart"); - p_data[0] = 0x60; - p_data[1] = 0x00; - p_data[2] = 0x03; - p_data[3] = 0xE1; - p_data[4] = 0x00; - p_data[5] = 0x00; - data_len = 0x6; + } else if (data_len >= 4 && p_data[0] == 0x60 && p_data[1] == 0x07) { + if (p_data[3] == 0xE1) { + // Core Generic Error - Buffer Overflow Ntf - Restart all + STLOG_HAL_E("Core Generic Error - restart"); + p_data[0] = 0x60; + p_data[1] = 0x00; + p_data[2] = 0x03; + p_data[3] = 0xE1; + p_data[4] = 0x00; + p_data[5] = 0x00; + data_len = 0x6; + } else if (p_data[3] == 0xE6) { + unsigned long hal_ctrl_clk = 0; + GetNumValue(NAME_STNFC_CONTROL_CLK, &hal_ctrl_clk, + sizeof(hal_ctrl_clk)); + if (hal_ctrl_clk) { + STLOG_HAL_E("%s - Clock Error - restart", __func__); + // Core Generic Error + p_data[0] = 0x60; + p_data[1] = 0x00; + p_data[2] = 0x03; + p_data[3] = 0xE6; + p_data[4] = 0x00; + p_data[5] = 0x00; + data_len = 0x6; + } + } } mHalWrapperDataCallback(data_len, p_data); } else { @@ -556,7 +584,7 @@ case HAL_WRAPPER_STATE_UPDATE: // 7 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_UPDATE", __func__); - UpdateHandler(mHalHandle, data_len, p_data); + FwUpdateHandler(mHalHandle, data_len, p_data); break; case HAL_WRAPPER_STATE_APPLY_CUSTOM_PARAM: // 8 STLOG_HAL_V( @@ -570,8 +598,9 @@ ApplyUwbParamHandler(mHalHandle, data_len, p_data); break; case HAL_WRAPPER_STATE_SET_ACTIVERW_TIMER: // 10 + (void)pthread_mutex_lock(&mutex_activerw); if (mIsActiveRW == true) { - STLOG_HAL_V( + STLOG_HAL_D( "%s - mHalWrapperState = " "HAL_WRAPPER_STATE_SET_ACTIVERW_TIMER", __func__); @@ -581,6 +610,7 @@ // Chip state should back to Active // at screen off state. } + (void)pthread_mutex_unlock(&mutex_activerw); mHalWrapperState = HAL_WRAPPER_STATE_READY; mHalWrapperDataCallback(data_len, p_data); break;
diff --git a/st21nfc/include/android_logmsg.h b/st21nfc/include/android_logmsg.h index 66c05b7..f8a49cf 100644 --- a/st21nfc/include/android_logmsg.h +++ b/st21nfc/include/android_logmsg.h
@@ -33,6 +33,7 @@ #define HAL_LOG_TAG "StNfcHal" extern unsigned char hal_trace_level; +extern unsigned char hal_conf_trace_level; extern int GetNumValue(const char* name, void* p_value, unsigned long len); extern int GetByteArrayValue(const char* name, char* pValue, long bufflen, long* len);