From 301358f29fff701253004b8a0ccd51d2be27ad40 Mon Sep 17 00:00:00 2001 From: Waldemar Porscha Date: Sun, 6 Oct 2019 23:52:29 +0200 Subject: [PATCH] restart device command --- src/knx/application_layer.cpp | 24 +++++++++++++-- src/knx/application_layer.h | 7 +++-- src/knx/bau.cpp | 4 +++ src/knx/bau.h | 1 + src/knx/bau_systemB.cpp | 58 +++++++++++++++++++++++++++++++++-- src/knx/bau_systemB.h | 6 +++- 6 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/knx/application_layer.cpp b/src/knx/application_layer.cpp index 321942a..0252c0f 100644 --- a/src/knx/application_layer.cpp +++ b/src/knx/application_layer.cpp @@ -176,7 +176,10 @@ void ApplicationLayer::connectIndication(uint16_t tsap) void ApplicationLayer::connectConfirm(uint16_t destination, uint16_t tsap, bool status) { if (status) + { _connectedTsap = tsap; + _bau.connectConfirm(tsap); + } else _connectedTsap = -1; } @@ -188,7 +191,7 @@ void ApplicationLayer::disconnectIndication(uint16_t tsap) void ApplicationLayer::disconnectConfirm(Priority priority, uint16_t tsap, bool status) { - + _connectedTsap = -1; } void ApplicationLayer::dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) @@ -334,13 +337,23 @@ void ApplicationLayer::deviceDescriptorReadResponse(AckType ack, Priority priori individualSend(ack, hopType, priority, asap, apdu); } -void ApplicationLayer::restartRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap) +void ApplicationLayer::connectRequest(uint16_t destination, Priority priority) +{ + _transportLayer->connectRequest(destination, priority); +} + +void ApplicationLayer::disconnectRequest(Priority priority) +{ + _transportLayer->disconnectRequest(_connectedTsap, priority); +} + +void ApplicationLayer::restartRequest(AckType ack, Priority priority, HopCountType hopType) { CemiFrame frame(1); APDU& apdu = frame.apdu(); apdu.type(Restart); - individualSend(ack, hopType, priority, asap, apdu); + individualSend(ack, hopType, priority, _connectedTsap, apdu); } void ApplicationLayer::propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, @@ -788,3 +801,8 @@ void ApplicationLayer::individualSend(AckType ack, HopCountType hopType, Priorit else _transportLayer->dataIndividualRequest(ack, hopType, priority, asap, apdu); } + +bool ApplicationLayer::isConnected() +{ + return (_connectedTsap >= 0); +} \ No newline at end of file diff --git a/src/knx/application_layer.h b/src/knx/application_layer.h index 7af7262..81a80b6 100644 --- a/src/knx/application_layer.h +++ b/src/knx/application_layer.h @@ -95,7 +95,10 @@ class ApplicationLayer uint8_t descriptorType); void deviceDescriptorReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t descriptorType, uint8_t* deviceDescriptor); - void restartRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap); + void connectRequest(uint16_t destination, Priority priority); + void disconnectRequest(Priority priority); + bool isConnected(); + void restartRequest(AckType ack, Priority priority, HopCountType hopType); void propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex); void propertyValueReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, @@ -147,5 +150,5 @@ class ApplicationLayer AssociationTableObject& _assocTable; BusAccessUnit& _bau; TransportLayer* _transportLayer = 0; - int32_t _connectedTsap; + int32_t _connectedTsap = -1; }; diff --git a/src/knx/bau.cpp b/src/knx/bau.cpp index 105b380..4bed0e5 100644 --- a/src/knx/bau.cpp +++ b/src/knx/bau.cpp @@ -236,3 +236,7 @@ void BusAccessUnit::keyWriteResponseConfirm(AckType ack, Priority priority, HopC void BusAccessUnit::keyWriteAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, uint8_t level) { } + +void BusAccessUnit::connectConfirm(uint16_t destination) +{ +} \ No newline at end of file diff --git a/src/knx/bau.h b/src/knx/bau.h index 14ca5b5..b979185 100644 --- a/src/knx/bau.h +++ b/src/knx/bau.h @@ -108,4 +108,5 @@ class BusAccessUnit virtual void keyWriteResponseConfirm(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level, bool status); virtual void keyWriteAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, uint8_t level); + virtual void connectConfirm(uint16_t destination); }; diff --git a/src/knx/bau_systemB.cpp b/src/knx/bau_systemB.cpp index 4e66daa..b0e7ef8 100644 --- a/src/knx/bau_systemB.cpp +++ b/src/knx/bau_systemB.cpp @@ -1,4 +1,5 @@ #include "bau_systemB.h" +#include "bits.h" #include #include @@ -21,6 +22,7 @@ void BauSystemB::loop() dataLinkLayer().loop(); _transLayer.loop(); sendNextGroupTelegram(); + nextRestartState(); } bool BauSystemB::enabled() @@ -293,8 +295,58 @@ void BauSystemB::addSaveRestore(SaveRestore* obj) _memory.addSaveRestore(obj); } - -void BauSystemB::restartRequest(uint16_t asap) +bool BauSystemB::restartRequest(uint16_t asap) { - _appLayer.restartRequest(AckRequested, LowPriority, NetworkLayerParameter, asap); + if (_appLayer.isConnected()) + return false; + _restartState = 1; // order important, has to be set BEFORE connectRequest + _appLayer.connectRequest(asap, SystemPriority); + _appLayer.deviceDescriptorReadRequest(AckRequested, SystemPriority, NetworkLayerParameter, asap, 0); + return true; } + +void BauSystemB::connectConfirm(uint16_t tsap) +{ + if (_restartState == 1 && tsap >= 0) + { + /* restart connection is confirmed, go to the next state */ + _restartState = 2; + _restartDelay = millis(); + } + else + { + _restartState = 0; + } +} + +void BauSystemB::nextRestartState() +{ + switch (_restartState) + { + case 0: + /* inactive state, do nothing */ + break; + case 1: + /* wait for connection, we do nothing here */ + break; + case 2: + /* connection confirmed, we send restartRequest, but we wait a moment (sending ACK etc)... */ + if (millis() - _restartDelay > 30) + { + _appLayer.restartRequest(AckRequested, SystemPriority, NetworkLayerParameter); + _restartState = 3; + _restartDelay = millis(); + } + break; + case 3: + /* restart is finished, we send a discommect */ + if (millis() - _restartDelay > 30) + { + _appLayer.disconnectRequest(SystemPriority); + _restartState = 0; + } + default: + break; + } +} + diff --git a/src/knx/bau_systemB.h b/src/knx/bau_systemB.h index 91a0741..546135d 100644 --- a/src/knx/bau_systemB.h +++ b/src/knx/bau_systemB.h @@ -27,7 +27,7 @@ class BauSystemB : protected BusAccessUnit void readMemory(); void writeMemory(); void addSaveRestore(SaveRestore* obj); - void restartRequest(uint16_t asap); + bool restartRequest(uint16_t asap); protected: virtual DataLinkLayer& dataLinkLayer() = 0; @@ -58,10 +58,12 @@ class BauSystemB : protected BusAccessUnit uint8_t* data, uint8_t dataLength) override; void groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, uint8_t* data, uint8_t dataLength) override; + void connectConfirm(uint16_t tsap) override; virtual InterfaceObject* getInterfaceObject(uint8_t idx) = 0; void sendNextGroupTelegram(); void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length); + void nextRestartState(); DeviceObject _deviceObj; Memory _memory; @@ -74,4 +76,6 @@ class BauSystemB : protected BusAccessUnit TransportLayer _transLayer; NetworkLayer _netLayer; bool _configured = true; + uint8_t _restartState = 0; + uint32_t _restartDelay = 0; }; \ No newline at end of file