Feature: Allow additional version check on startup

- added versionCheckCallback
- added apiVersion to DeviceObject
- added new versionCheck to memory,cpp
This commit is contained in:
Waldemar Porscha 2022-02-27 15:35:31 +01:00
parent f4d7f604be
commit 82c41bfbf6
5 changed files with 114 additions and 49 deletions

View File

@ -611,3 +611,13 @@ Memory& BauSystemB::memory()
{ {
return _memory; return _memory;
} }
void BauSystemB::addVersionCheckCallback(versionCheckCallback func)
{
_memory.addVersionCheckCallback(func);
}
versionCheckCallback BauSystemB::getVersionCheckCallback()
{
return _memory.getVersionCheckCallback();
}

View File

@ -38,6 +38,8 @@ class BauSystemB : protected BusAccessUnit
void propertyValueWrite(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, void propertyValueWrite(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId,
uint8_t& numberOfElements, uint16_t startIndex, uint8_t& numberOfElements, uint16_t startIndex,
uint8_t* data, uint32_t length) override; uint8_t* data, uint32_t length) override;
void addVersionCheckCallback(versionCheckCallback func);
versionCheckCallback getVersionCheckCallback();
protected: protected:
virtual ApplicationLayer& applicationLayer() = 0; virtual ApplicationLayer& applicationLayer() = 0;

View File

@ -7,36 +7,40 @@
class DeviceObject: public InterfaceObject class DeviceObject: public InterfaceObject
{ {
public: public:
DeviceObject(); // increase this version anytime DeviceObject-API changes
uint8_t* save(uint8_t* buffer) override; // the following value represents the serialized representation of DeviceObject.
const uint8_t* restore(const uint8_t* buffer) override; const uint16_t apiVersion = 1;
uint16_t saveSize() override;
DeviceObject();
uint8_t* save(uint8_t* buffer) override;
const uint8_t* restore(const uint8_t* buffer) override;
uint16_t saveSize() override;
uint16_t individualAddress(); uint16_t individualAddress();
void individualAddress(uint16_t value); void individualAddress(uint16_t value);
void individualAddressDuplication(bool value); void individualAddressDuplication(bool value);
bool verifyMode(); bool verifyMode();
void verifyMode(bool value); void verifyMode(bool value);
bool progMode(); bool progMode();
void progMode(bool value); void progMode(bool value);
uint16_t manufacturerId(); uint16_t manufacturerId();
void manufacturerId(uint16_t value); void manufacturerId(uint16_t value);
uint32_t bauNumber(); uint32_t bauNumber();
void bauNumber(uint32_t value); void bauNumber(uint32_t value);
const uint8_t* orderNumber(); const uint8_t* orderNumber();
void orderNumber(const uint8_t* value); void orderNumber(const uint8_t* value);
const uint8_t* hardwareType(); const uint8_t* hardwareType();
void hardwareType(const uint8_t* value); void hardwareType(const uint8_t* value);
uint16_t version(); uint16_t version();
void version(uint16_t value); void version(uint16_t value);
uint16_t maskVersion(); uint16_t maskVersion();
void maskVersion(uint16_t value); void maskVersion(uint16_t value);
uint16_t maxApduLength(); uint16_t maxApduLength();
void maxApduLength(uint16_t value); void maxApduLength(uint16_t value);
const uint8_t* rfDomainAddress(); const uint8_t* rfDomainAddress();
void rfDomainAddress(uint8_t* value); void rfDomainAddress(uint8_t* value);
uint8_t defaultHopCount(); uint8_t defaultHopCount();
private: private:
uint8_t _prgMode = 0; uint8_t _prgMode = 0;
uint16_t _ownAddress = 65535; // 15.15.255; uint16_t _ownAddress = 65535; // 15.15.255;

View File

@ -37,30 +37,51 @@ void Memory::readMemory()
uint16_t version = 0; uint16_t version = 0;
buffer = popWord(version, buffer); buffer = popWord(version, buffer);
VersionCheckResult versionCheck = FlashAllInvalid;
if (_deviceObject.manufacturerId() != manufacturerId // first check correct format of deviceObject-API
|| _deviceObject.version() != version if (_deviceObject.apiVersion == version)
|| memcmp(_deviceObject.hardwareType(), hardwareType, LEN_HARDWARE_TYPE) != 0)
{ {
println("saved memory doesn't match manufacturerId, version or hardwaretype"); if (_versionCheckCallback != 0) {
print("manufacturerId: "); versionCheck = _versionCheckCallback(manufacturerId, hardwareType);
print(manufacturerId, HEX); // callback should provide infomation about version check failure reasons
print(" "); }
println(_deviceObject.manufacturerId(), HEX); else if (_deviceObject.manufacturerId() == manufacturerId &&
print("version: "); memcmp(_deviceObject.hardwareType(), hardwareType, LEN_HARDWARE_TYPE) == 0)
print(version, HEX); {
print(" "); versionCheck = FlashValid;
println(_deviceObject.version(), HEX); }
print("hardwareType: "); else
printHex("", hardwareType, LEN_HARDWARE_TYPE); {
print(" "); println("manufacturerId or hardwareType are different");
printHex("", _deviceObject.hardwareType(), LEN_HARDWARE_TYPE); print("expexted manufacturerId: ");
print(_deviceObject.manufacturerId(), HEX);
print(", stored manufacturerId: ");
println(manufacturerId, HEX);
print("expexted hardwareType: ");
printHex("", _deviceObject.hardwareType(), LEN_HARDWARE_TYPE);
print(", stored hardwareType: ");
printHex("", hardwareType, LEN_HARDWARE_TYPE);
println("");
}
}
else
{
println("DataObject api changed, any data stored in flash is invalid.");
print("expexted DataObject api version: ");
print(_deviceObject.apiVersion, HEX);
print(", stored api version: ");
println(version, HEX);
}
if (versionCheck == FlashAllInvalid)
{
println("ETS has to reprogram PA and application!");
return; return;
} }
println("manufacturerId, version and hardwareType matches"); println("restoring data from flash...");
print("saverestores "); print("saverestores ");
println(_saveCount); println(_saveCount);
for (int i = 0; i < _saveCount; i++) for (int i = 0; i < _saveCount; i++)
@ -70,6 +91,11 @@ void Memory::readMemory()
buffer = _saveRestores[i]->restore(buffer); buffer = _saveRestores[i]->restore(buffer);
} }
println("restored saveRestores"); println("restored saveRestores");
if (versionCheck == FlashTablesInvalid)
{
println("TableObjects are referring to an older firmware version and are not loaded");
return;
}
print("tableObjs "); print("tableObjs ");
println(_tableObjCount); println(_tableObjCount);
for (int i = 0; i < _tableObjCount; i++) for (int i = 0; i < _tableObjCount; i++)
@ -105,7 +131,7 @@ void Memory::writeMemory()
bufferPos = pushWord(_deviceObject.manufacturerId(), bufferPos); bufferPos = pushWord(_deviceObject.manufacturerId(), bufferPos);
bufferPos = pushByteArray(_deviceObject.hardwareType(), LEN_HARDWARE_TYPE, bufferPos); bufferPos = pushByteArray(_deviceObject.hardwareType(), LEN_HARDWARE_TYPE, bufferPos);
bufferPos = pushWord(_deviceObject.version(), bufferPos); bufferPos = pushWord(_deviceObject.apiVersion, bufferPos);
flashPos = _platform.writeNonVolatileMemory(flashPos, buffer, bufferPos - buffer); flashPos = _platform.writeNonVolatileMemory(flashPos, buffer, bufferPos - buffer);
@ -451,3 +477,13 @@ void Memory::addNewUsedBlock(uint8_t* address, size_t size)
MemoryBlock* newUsedBlock = new MemoryBlock(address, size); MemoryBlock* newUsedBlock = new MemoryBlock(address, size);
addToUsedList(newUsedBlock); addToUsedList(newUsedBlock);
} }
void Memory::addVersionCheckCallback(versionCheckCallback func)
{
_versionCheckCallback = func;
}
versionCheckCallback Memory::getVersionCheckCallback()
{
return _versionCheckCallback;
}

View File

@ -24,6 +24,15 @@ class MemoryBlock
MemoryBlock* next = nullptr; MemoryBlock* next = nullptr;
}; };
enum VersionCheckResult
{
FlashAllInvalid = 0, //!< All flash content is not valid for this firmware, we delete it
FlashTablesInvalid = 1,//!< All table objects are invalid for this firmware, device object and saveRestores are OK
FlashValid = 2 //!< Flash content is valid and will be used
};
typedef VersionCheckResult (*versionCheckCallback)(uint16_t manufacturerId, uint8_t* hardwareType);
class Memory class Memory
{ {
public: public:
@ -41,6 +50,9 @@ public:
uint8_t* toAbsolute(uint32_t relativeAddress); uint8_t* toAbsolute(uint32_t relativeAddress);
uint32_t toRelative(uint8_t* absoluteAddress); uint32_t toRelative(uint8_t* absoluteAddress);
void addVersionCheckCallback(versionCheckCallback func);
versionCheckCallback getVersionCheckCallback();
private: private:
void removeFromFreeList(MemoryBlock* block); void removeFromFreeList(MemoryBlock* block);
void addToUsedList(MemoryBlock* block); void addToUsedList(MemoryBlock* block);
@ -56,6 +68,7 @@ public:
uint8_t* eraseBlockEnd(uint32_t blockNum); uint8_t* eraseBlockEnd(uint32_t blockNum);
void saveBufferdEraseBlock(); void saveBufferdEraseBlock();
versionCheckCallback _versionCheckCallback = 0;
Platform& _platform; Platform& _platform;
DeviceObject& _deviceObject; DeviceObject& _deviceObject;
SaveRestore* _saveRestores[MAXSAVE] = {0}; SaveRestore* _saveRestores[MAXSAVE] = {0};