mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	Openknx version support (#190)
* Feature: Allow additional version check on startup - added versionCheckCallback - added apiVersion to DeviceObject - added new versionCheck to memory,cpp * updated source code formatting * changes for PR - (old) version is again part of version check - naming conventions * forgotten parameter in callback * correct wrong buffer initialization * version <-> apiVersion swapped Co-authored-by: Waldemar Porscha <waldemar.porscha@sap.com>
This commit is contained in:
		
							parent
							
								
									a10fa20bde
								
							
						
					
					
						commit
						22af8267c3
					
				@ -614,6 +614,16 @@ Memory& BauSystemB::memory()
 | 
			
		||||
    return _memory;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BauSystemB::versionCheckCallback(VersionCheckCallback func)
 | 
			
		||||
{
 | 
			
		||||
    _memory.versionCheckCallback(func);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VersionCheckCallback BauSystemB::versionCheckCallback()
 | 
			
		||||
{
 | 
			
		||||
    return _memory.versionCheckCallback();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BauSystemB::beforeRestartCallback(BeforeRestartCallback func)
 | 
			
		||||
{
 | 
			
		||||
    _beforeRestart = func;
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,8 @@ class BauSystemB : protected BusAccessUnit
 | 
			
		||||
    void propertyValueWrite(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId,
 | 
			
		||||
                            uint8_t& numberOfElements, uint16_t startIndex,
 | 
			
		||||
                            uint8_t* data, uint32_t length) override;
 | 
			
		||||
    void versionCheckCallback(VersionCheckCallback func);
 | 
			
		||||
    VersionCheckCallback versionCheckCallback();
 | 
			
		||||
    void beforeRestartCallback(BeforeRestartCallback func);
 | 
			
		||||
    BeforeRestartCallback beforeRestartCallback();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,10 @@
 | 
			
		||||
class DeviceObject: public InterfaceObject
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // increase this version anytime DeviceObject-API changes 
 | 
			
		||||
    // the following value represents the serialized representation of DeviceObject.
 | 
			
		||||
    const uint16_t apiVersion = 1;
 | 
			
		||||
    
 | 
			
		||||
    DeviceObject();
 | 
			
		||||
    uint8_t* save(uint8_t* buffer) override;
 | 
			
		||||
    const uint8_t* restore(const uint8_t* buffer) override;
 | 
			
		||||
 | 
			
		||||
@ -29,38 +29,68 @@ void Memory::readMemory()
 | 
			
		||||
 | 
			
		||||
    _freeList = new MemoryBlock(flashStart + metadataBlockSize, flashSize - metadataBlockSize);
 | 
			
		||||
 | 
			
		||||
    uint16_t apiVersion = 0;
 | 
			
		||||
    const uint8_t* buffer = popWord(apiVersion, flashStart);
 | 
			
		||||
 | 
			
		||||
    uint16_t manufacturerId = 0;
 | 
			
		||||
    const uint8_t* buffer = popWord(manufacturerId, flashStart);
 | 
			
		||||
    buffer = popWord(manufacturerId, buffer);
 | 
			
		||||
 | 
			
		||||
    uint8_t hardwareType[LEN_HARDWARE_TYPE] = {0};
 | 
			
		||||
    buffer = popByteArray(hardwareType, LEN_HARDWARE_TYPE, buffer);
 | 
			
		||||
 | 
			
		||||
    uint16_t version = 0;
 | 
			
		||||
    buffer = popWord(version, buffer);
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    if (_deviceObject.manufacturerId() != manufacturerId
 | 
			
		||||
       || _deviceObject.version() != version
 | 
			
		||||
       || memcmp(_deviceObject.hardwareType(), hardwareType, LEN_HARDWARE_TYPE) != 0)
 | 
			
		||||
 | 
			
		||||
    VersionCheckResult versionCheck = FlashAllInvalid;
 | 
			
		||||
 | 
			
		||||
    // first check correct format of deviceObject-API
 | 
			
		||||
    if (_deviceObject.apiVersion == apiVersion) 
 | 
			
		||||
    {
 | 
			
		||||
        println("saved memory doesn't match manufacturerId, version or hardwaretype");
 | 
			
		||||
        print("manufacturerId: ");
 | 
			
		||||
        print(manufacturerId, HEX);
 | 
			
		||||
        print(" ");
 | 
			
		||||
        println(_deviceObject.manufacturerId(), HEX);
 | 
			
		||||
        print("version: ");
 | 
			
		||||
        print(version, HEX);
 | 
			
		||||
        print(" ");
 | 
			
		||||
        println(_deviceObject.version(), HEX);
 | 
			
		||||
        print("hardwareType: ");
 | 
			
		||||
        printHex("", hardwareType, LEN_HARDWARE_TYPE);
 | 
			
		||||
        print(" ");
 | 
			
		||||
        printHex("", _deviceObject.hardwareType(), LEN_HARDWARE_TYPE);
 | 
			
		||||
        if (_versionCheckCallback != 0) {
 | 
			
		||||
            versionCheck = _versionCheckCallback(manufacturerId, hardwareType, version);
 | 
			
		||||
            // callback should provide infomation about version check failure reasons
 | 
			
		||||
        }
 | 
			
		||||
        else if (_deviceObject.manufacturerId() == manufacturerId &&
 | 
			
		||||
                 memcmp(_deviceObject.hardwareType(), hardwareType, LEN_HARDWARE_TYPE) == 0) 
 | 
			
		||||
        {
 | 
			
		||||
            if (_deviceObject.version() == version) {
 | 
			
		||||
                versionCheck = FlashValid;
 | 
			
		||||
            } 
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                versionCheck = FlashTablesInvalid;
 | 
			
		||||
            }
 | 
			
		||||
        } 
 | 
			
		||||
        else 
 | 
			
		||||
        {
 | 
			
		||||
            println("manufacturerId or hardwareType are different");
 | 
			
		||||
            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(apiVersion, HEX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (versionCheck == FlashAllInvalid)
 | 
			
		||||
    {
 | 
			
		||||
        println("ETS has to reprogram PA and application!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println("manufacturerId, version and hardwareType matches");
 | 
			
		||||
    println("restoring data from flash...");
 | 
			
		||||
    print("saverestores ");
 | 
			
		||||
    println(_saveCount);
 | 
			
		||||
    for (int i = 0; i < _saveCount; i++)
 | 
			
		||||
@ -70,6 +100,11 @@ void Memory::readMemory()
 | 
			
		||||
        buffer = _saveRestores[i]->restore(buffer);
 | 
			
		||||
    }
 | 
			
		||||
    println("restored saveRestores");
 | 
			
		||||
    if (versionCheck == FlashTablesInvalid) 
 | 
			
		||||
    {
 | 
			
		||||
        println("TableObjects are referring to an older firmware version and are not loaded");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    print("tableObjs ");
 | 
			
		||||
    println(_tableObjCount);
 | 
			
		||||
    for (int i = 0; i < _tableObjCount; i++)
 | 
			
		||||
@ -103,6 +138,7 @@ void Memory::writeMemory()
 | 
			
		||||
    uint32_t flashPos = 0;
 | 
			
		||||
    uint8_t* bufferPos = buffer;
 | 
			
		||||
 | 
			
		||||
    bufferPos = pushWord(_deviceObject.apiVersion, bufferPos);
 | 
			
		||||
    bufferPos = pushWord(_deviceObject.manufacturerId(), bufferPos);
 | 
			
		||||
    bufferPos = pushByteArray(_deviceObject.hardwareType(), LEN_HARDWARE_TYPE, bufferPos);
 | 
			
		||||
    bufferPos = pushWord(_deviceObject.version(), bufferPos);
 | 
			
		||||
@ -451,3 +487,13 @@ void Memory::addNewUsedBlock(uint8_t* address, size_t size)
 | 
			
		||||
    MemoryBlock* newUsedBlock = new MemoryBlock(address, size);
 | 
			
		||||
    addToUsedList(newUsedBlock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Memory::versionCheckCallback(VersionCheckCallback func)
 | 
			
		||||
{
 | 
			
		||||
    _versionCheckCallback = func;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VersionCheckCallback Memory::versionCheckCallback()
 | 
			
		||||
{
 | 
			
		||||
    return _versionCheckCallback;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,15 @@ class MemoryBlock
 | 
			
		||||
    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, uint16_t version);
 | 
			
		||||
 | 
			
		||||
class Memory
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
@ -41,6 +50,9 @@ public:
 | 
			
		||||
    uint8_t* toAbsolute(uint32_t relativeAddress);
 | 
			
		||||
    uint32_t toRelative(uint8_t* absoluteAddress);
 | 
			
		||||
 | 
			
		||||
    void versionCheckCallback(VersionCheckCallback func);
 | 
			
		||||
    VersionCheckCallback versionCheckCallback();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    void removeFromFreeList(MemoryBlock* block);
 | 
			
		||||
    void addToUsedList(MemoryBlock* block);
 | 
			
		||||
@ -56,6 +68,7 @@ public:
 | 
			
		||||
    uint8_t* eraseBlockEnd(uint32_t blockNum);
 | 
			
		||||
    void saveBufferdEraseBlock();
 | 
			
		||||
 | 
			
		||||
    VersionCheckCallback _versionCheckCallback = 0;
 | 
			
		||||
    Platform& _platform;
 | 
			
		||||
    DeviceObject& _deviceObject;
 | 
			
		||||
    SaveRestore* _saveRestores[MAXSAVE] = {0};
 | 
			
		||||
@ -64,5 +77,5 @@ public:
 | 
			
		||||
    uint8_t _tableObjCount = 0;
 | 
			
		||||
    MemoryBlock* _freeList = nullptr;
 | 
			
		||||
    MemoryBlock* _usedList = nullptr;
 | 
			
		||||
    uint16_t _metadataSize = 4 + LEN_HARDWARE_TYPE; // accounting for 2x pushWord and pushByteArray of length LEN_HARDWARE_TYPE
 | 
			
		||||
    uint16_t _metadataSize = 6 + LEN_HARDWARE_TYPE; // accounting for 3x pushWord and pushByteArray of length LEN_HARDWARE_TYPE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user