// ----------------------------------------------------------------------------- /// @file DeviceParameters.c /// @brief Description // ----------------------------------------------------------------------------- // Micro-Key bv // Industrieweg 28, 9804 TG Noordhorn // Postbus 92, 9800 AB Zuidhorn // The Netherlands // Tel: +31 594 503020 // Fax: +31 594 505825 // Email: support@microkey.nl // Web: www.microkey.nl // ----------------------------------------------------------------------------- /// $Revision$ /// $Author$ /// $Date$ // (c) 2017 Micro-Key bv // ----------------------------------------------------------------------------- /// @file DeviceParameters.c /// @ingroup {group_name} // ----------------------------------------------------------------------------- // Include files // ----------------------------------------------------------------------------- #include "DeviceParameters.h" #include "hsb-mrts.h" #include "Error.h" #include "PIDParameters.h" #include "PIN.h" #include "CachedStorage.h" #include "crc32.h" #include "Logger.h" #include "MemoryDevice.h" // ----------------------------------------------------------------------------- // Constant and macro definitions // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- struct DeviceParameters { bool initialized; struct CachedStorage* parametersStorage; struct MemoryDevice* memoryDevice; unsigned int PIDParametersOffset; unsigned int PINOffset; }; struct PIDParametersStorageClass { uint32_t crc; struct PIDParameters pidParameters; }; struct PINStorageClass { uint32_t crc; struct PIN pin; }; // ----------------------------------------------------------------------------- // File-scope variables // ----------------------------------------------------------------------------- static struct CachedStorage deviceParameters = {.initialized = false}; static struct DeviceParameters _dParam = {.initialized = false, .parametersStorage = &deviceParameters}; struct DeviceParameters* const dParam = &_dParam; // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- static void DeviceParameters_verifyCRCs(void); // ----------------------------------------------------------------------------- // Function definitions // ----------------------------------------------------------------------------- ErrorStatus DeviceParameters_construct(struct MemoryDevice* memoryDevice) { ErrorStatus returnValue = SUCCESS; if (!dParam->initialized) { if (returnValue == SUCCESS) { if (memoryDevice != NULL) { if (memoryDevice->initialized) { dParam->memoryDevice = memoryDevice; } else { returnValue = ERROR; } } else { returnValue = ERROR; } } if (returnValue == SUCCESS) { // Create new cachedStorage with preset page number returnValue = CachedStorage_construct(dParam->parametersStorage, dParam->memoryDevice, APP_FLASH_PARAMETERS_PAGE, (sizeof(struct PIDParametersStorageClass) + sizeof(struct PINStorageClass)) / 4); } if (returnValue == SUCCESS) { dParam->PIDParametersOffset = 0; dParam->PINOffset = sizeof(struct PIDParametersStorageClass) / 4; dParam->initialized = true; } // Check the CRC on the loaded parameters // If a CRC fails, corrupted data will automatically be replaced with defaults if (returnValue == SUCCESS) { DeviceParameters_verifyCRCs(); } } else { returnValue = ERROR; } return returnValue; } void DeviceParameters_destruct(void) { if (dParam->initialized) { CachedStorage_destruct(dParam->parametersStorage); dParam->parametersStorage = NULL; dParam->memoryDevice = NULL; } } struct PIDParameters* DeviceParameters_getPIDParameters(void) { struct PIDParameters* returnValue = NULL; if (dParam->initialized) { struct PIDParametersStorageClass* tempValue; tempValue = (struct PIDParametersStorageClass*)CachedStorage_readBlob(dParam->parametersStorage, dParam->PIDParametersOffset); returnValue = &tempValue->pidParameters; } return returnValue; } struct PIN* DeviceParameters_getPIN(void) { struct PIN* returnValue = NULL; if (dParam->initialized) { struct PINStorageClass* tempValue; tempValue = (struct PINStorageClass*)CachedStorage_readBlob(dParam->parametersStorage, dParam->PINOffset); returnValue = &tempValue->pin; } return returnValue; } void DeviceParameters_saveParameters(void) { if (dParam->initialized) { // Commit cache to memory - will not write if no changes have been made CachedStorage_commit(dParam->parametersStorage); } } ErrorStatus DeviceParameters_writePIDParameters(struct PIDParameters* parameters) { ErrorStatus returnValue = SUCCESS; if (dParam->initialized) { struct PIDParametersStorageClass tempPIDStorage; tempPIDStorage.pidParameters = *parameters; // Calculate CRC over preset tempPIDStorage.crc = crc32_calculate(0, &tempPIDStorage.pidParameters, sizeof(struct PIDParameters)); // Put default preset on Cache CachedStorage_writeBlob(dParam->parametersStorage, dParam->PIDParametersOffset, &tempPIDStorage, sizeof(struct PIDParametersStorageClass) / 4); } else { returnValue = ERROR; } return returnValue; } ErrorStatus DeviceParameters_writePIN(struct PIN* pin) { ErrorStatus returnValue = SUCCESS; if (dParam->initialized) { struct PINStorageClass tempPINStorage; tempPINStorage.pin = *pin; // Calculate CRC over preset tempPINStorage.crc = crc32_calculate(0, &tempPINStorage.pin, sizeof(struct PIN)); // Put default preset on Cache CachedStorage_writeBlob(dParam->parametersStorage, dParam->PINOffset, &tempPINStorage, sizeof(struct PINStorageClass) / 4); } else { returnValue = ERROR; } return returnValue; } static void DeviceParameters_verifyCRCs(void) { uint32_t tempCRC; if (dParam->initialized) { // PID PARAMETERS CHECK struct PIDParametersStorageClass _tempPIDParameters; struct PIDParametersStorageClass* tempPIDParameters = &_tempPIDParameters; tempPIDParameters = (struct PIDParametersStorageClass*)CachedStorage_readBlob(dParam->parametersStorage, dParam->PIDParametersOffset); // Calculate the CRC of the parameters tempCRC = crc32_calculate(0, &tempPIDParameters->pidParameters, sizeof(struct PIDParameters)); // Compare CRC if (tempCRC != tempPIDParameters->crc) { Error_postError(ERROR_CRC_PARAMETERS); // CRC do not match LOGGER_ERROR(mainLog, "CRC ERROR at Device Parameters (calculated %X but loaded %X)", (unsigned int)tempCRC, (unsigned int)tempPIDParameters->crc); // Replace corrupt Device parameters with defaults PIDParameters_generateDefaultParameters(&tempPIDParameters->pidParameters); // Write parameters to cache including the CRC (calculated inside write function) DeviceParameters_writePIDParameters(&tempPIDParameters->pidParameters); } // PIN CHECK struct PINStorageClass _tempPIN; struct PINStorageClass* tempPIN = &_tempPIN; tempPIN = (struct PINStorageClass*)CachedStorage_readBlob(dParam->parametersStorage, dParam->PINOffset); // Calculate the CRC of the PIN // Calculate the CRC of the parameters tempCRC = crc32_calculate(0, &tempPIN->pin, sizeof(struct PIN)); // Compare CRC if (tempCRC != tempPIN->crc) { Error_postError(ERROR_CRC_PIN); // CRC do not match LOGGER_ERROR(mainLog, "CRC ERROR at Device PIN (calculated %X but loaded %X)", (unsigned int)tempCRC, (unsigned int)tempPIN->crc); // Replace corrupt Device parameters with defaults PIN_generateDefaultPIN(&tempPIN->pin); // Write parameters to cache including the CRC (calculated inside write function) DeviceParameters_writePIN(&tempPIN->pin); } DeviceParameters_saveParameters(); } }