From 8b92bdf8657e0a5f14e68ab73a877070d141ddce Mon Sep 17 00:00:00 2001 From: Waldemar Porscha Date: Sun, 27 Feb 2022 13:15:44 +0100 Subject: [PATCH] Feature: additional callbacks for application - beforeRestart callback - beforeTablesUnload callback --- src/knx/address_table_object.cpp | 4 +++- src/knx/association_table_object.cpp | 1 + src/knx/bau.cpp | 9 +++++++++ src/knx/bau.h | 4 ++++ src/knx/bau_systemB.cpp | 12 ++++++++++++ src/knx/bau_systemB.h | 3 +++ src/knx/group_object_table_object.cpp | 1 + src/knx/table_object.cpp | 26 ++++++++++++++++++++++++++ src/knx/table_object.h | 18 ++++++++++++++---- src/knx_facade.h | 13 ++++++++++++- 10 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/knx/address_table_object.cpp b/src/knx/address_table_object.cpp index 689580c..c2e9154 100644 --- a/src/knx/address_table_object.cpp +++ b/src/knx/address_table_object.cpp @@ -19,7 +19,8 @@ AddressTableObject::AddressTableObject(Memory& memory) uint16_t AddressTableObject::entryCount() { - if (loadState() != LS_LOADED) + // after programming without GA the module hangs + if (loadState() != LS_LOADED || _groupAddresses[0] == 0xFFFF) return 0; return ntohs(_groupAddresses[0]); @@ -67,6 +68,7 @@ bool AddressTableObject::contains(uint16_t addr) void AddressTableObject::beforeStateChange(LoadState& newState) { + TableObject::beforeStateChange(newState); if (newState != LS_LOADED) return; diff --git a/src/knx/association_table_object.cpp b/src/knx/association_table_object.cpp index 0880fc7..92cc839 100644 --- a/src/knx/association_table_object.cpp +++ b/src/knx/association_table_object.cpp @@ -60,6 +60,7 @@ int32_t AssociationTableObject::translateAsap(uint16_t asap) void AssociationTableObject::beforeStateChange(LoadState& newState) { + TableObject::beforeStateChange(newState); if (newState != LS_LOADED) return; diff --git a/src/knx/bau.cpp b/src/knx/bau.cpp index a74e7bf..f2885f2 100644 --- a/src/knx/bau.cpp +++ b/src/knx/bau.cpp @@ -338,3 +338,12 @@ void BusAccessUnit::propertyValueWrite(ObjectType objectType, uint8_t objectInst uint8_t* data, uint32_t length) { } + +void BusAccessUnit::addBeforeRestartCallback(beforeRestartCallback func) +{ +} + +beforeRestartCallback BusAccessUnit::getBeforeRestartCallback() +{ + return 0; +} diff --git a/src/knx/bau.h b/src/knx/bau.h index 78b3580..479a52e 100644 --- a/src/knx/bau.h +++ b/src/knx/bau.h @@ -3,6 +3,8 @@ #include "knx_types.h" #include "interface_object.h" +typedef void (*beforeRestartCallback)(void); + class BusAccessUnit { public: @@ -161,4 +163,6 @@ class BusAccessUnit virtual void propertyValueWrite(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t& numberOfElements, uint16_t startIndex, uint8_t* data, uint32_t length); + virtual void addBeforeRestartCallback(beforeRestartCallback func); + virtual beforeRestartCallback getBeforeRestartCallback(); }; diff --git a/src/knx/bau_systemB.cpp b/src/knx/bau_systemB.cpp index 9c6fb0a..623a503 100644 --- a/src/knx/bau_systemB.cpp +++ b/src/knx/bau_systemB.cpp @@ -152,6 +152,8 @@ void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopTyp if (restartType == RestartType::BasicRestart) { println("Basic restart requested"); + if (_beforeRestart != 0) + _beforeRestart(); } else if (restartType == RestartType::MasterReset) { @@ -611,3 +613,13 @@ Memory& BauSystemB::memory() { return _memory; } + +void BauSystemB::addBeforeRestartCallback(beforeRestartCallback func) +{ + _beforeRestart = func; +} + +beforeRestartCallback BauSystemB::getBeforeRestartCallback() +{ + return _beforeRestart; +} diff --git a/src/knx/bau_systemB.h b/src/knx/bau_systemB.h index abbc653..61882d1 100644 --- a/src/knx/bau_systemB.h +++ b/src/knx/bau_systemB.h @@ -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 addBeforeRestartCallback(beforeRestartCallback func); + beforeRestartCallback getBeforeRestartCallback(); protected: virtual ApplicationLayer& applicationLayer() = 0; @@ -107,4 +109,5 @@ class BauSystemB : protected BusAccessUnit RestartState _restartState = Idle; SecurityControl _restartSecurity; uint32_t _restartDelay = 0; + beforeRestartCallback _beforeRestart = 0; }; diff --git a/src/knx/group_object_table_object.cpp b/src/knx/group_object_table_object.cpp index b610404..bdcf8dd 100644 --- a/src/knx/group_object_table_object.cpp +++ b/src/knx/group_object_table_object.cpp @@ -77,6 +77,7 @@ void GroupObjectTableObject::groupObjects(GroupObject * objs, uint16_t size) void GroupObjectTableObject::beforeStateChange(LoadState& newState) { + TableObject::beforeStateChange(newState); if (newState != LS_LOADED) return; diff --git a/src/knx/table_object.cpp b/src/knx/table_object.cpp index 44c504e..6758892 100644 --- a/src/knx/table_object.cpp +++ b/src/knx/table_object.cpp @@ -6,6 +6,19 @@ #include "callback_property.h" #include "data_property.h" +beforeTablesUnloadCallback TableObject::_beforeTablesUnload = 0; +uint8_t TableObject::_tableUnloadCount = 0; + +void TableObject::addBeforeTablesUnloadCallback(beforeTablesUnloadCallback func) +{ + _beforeTablesUnload = func; +} + +beforeTablesUnloadCallback TableObject::getBeforeTablesUnloadCallback() +{ + return _beforeTablesUnload; +} + TableObject::TableObject(Memory& memory) : _memory(memory) {} @@ -13,6 +26,19 @@ TableObject::TableObject(Memory& memory) TableObject::~TableObject() {} +void TableObject::beforeStateChange(LoadState& newState) +{ + if (newState == LS_LOADED && _tableUnloadCount > 0) + _tableUnloadCount--; + if (_tableUnloadCount > 0) + return; + if (newState == LS_UNLOADED) { + _tableUnloadCount++; + if (_beforeTablesUnload != 0) + _beforeTablesUnload(); + } +} + LoadState TableObject::loadState() { return _state; diff --git a/src/knx/table_object.h b/src/knx/table_object.h index c4213b3..35fc5f6 100644 --- a/src/knx/table_object.h +++ b/src/knx/table_object.h @@ -3,6 +3,9 @@ #include "interface_object.h" class Memory; + +typedef void (*beforeTablesUnloadCallback)(); + /** * This class provides common functionality for interface objects that are configured by ETS with MemorWrite. */ @@ -28,14 +31,18 @@ class TableObject: public InterfaceObject uint8_t* save(uint8_t* buffer) override; const uint8_t* restore(const uint8_t* buffer) override; uint16_t saveSize() override; - protected: + + static void addBeforeTablesUnloadCallback(beforeTablesUnloadCallback func); + static beforeTablesUnloadCallback getBeforeTablesUnloadCallback(); + + protected: /** * This method is called before the interface object enters a new ::LoadState. * If there is a error changing the state newState should be set to ::LS_ERROR and errorCode() * to a reason for the failure. */ - virtual void beforeStateChange(LoadState& newState) {} - + virtual void beforeStateChange(LoadState& newState); + /** * returns the internal data of the interface object. This pointer belongs to the TableObject class and * must not be freed. @@ -47,7 +54,9 @@ class TableObject: public InterfaceObject void errorCode(ErrorCode errorCode); void initializeProperties(size_t propertiesSize, Property** properties) override; - + + static beforeTablesUnloadCallback _beforeTablesUnload; + private: uint32_t tableReference(); bool allocTable(uint32_t size, bool doFill, uint8_t fillByte); @@ -68,6 +77,7 @@ class TableObject: public InterfaceObject LoadState _state = LS_UNLOADED; Memory& _memory; uint8_t *_data = 0; + static uint8_t _tableUnloadCount; /** * used to store size of data() in allocTable(), needed for calculation of crc in PID_MCB_TABLE. diff --git a/src/knx_facade.h b/src/knx_facade.h index ecfbda0..2691338 100644 --- a/src/knx_facade.h +++ b/src/knx_facade.h @@ -400,7 +400,18 @@ template class KnxFacade : private SaveRestore void restart(uint16_t individualAddress) { - _bau.restartRequest(individualAddress); + SecurityControl sc = {false, None}; + _bau.restartRequest(individualAddress, sc); + } + + void addBeforeRestartCallback(beforeRestartCallback func) + { + _bau.addBeforeRestartCallback(func); + } + + beforeRestartCallback getBeforeRestartCallback() + { + return _bau.getBeforeRestartCallback(); } private: