Refactor master reset

This commit is contained in:
Nanosonde 2020-07-06 14:53:30 +02:00
parent 5efc450bc7
commit 9db2524e5a
12 changed files with 63 additions and 29 deletions

View File

@ -121,15 +121,6 @@ int main(int argc, char **argv)
{ {
printf("main() start.\n"); printf("main() start.\n");
if (argc > 1)
{
EraseCode eraseCode = (EraseCode) atoi(argv[2]);
print("Performing factory reset with erase code: ");
println(eraseCode, HEX);
knx.masterReset(eraseCode, 0);
}
uint8_t serialNumber[] = { 0x00, 0xFA, 0x01, 0x02, 0x03, 0x04}; uint8_t serialNumber[] = { 0x00, 0xFA, 0x01, 0x02, 0x03, 0x04};
uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};

View File

@ -120,6 +120,14 @@ InterfaceObject* Bau27B0::getInterfaceObject(ObjectType objectType, uint8_t obje
} }
} }
void Bau27B0::doMasterReset(EraseCode eraseCode, uint8_t channel)
{
// Common SystemB objects
BauSystemB::doMasterReset(eraseCode, channel);
_rfMediumObj.masterReset(eraseCode, channel);
}
DataLinkLayer& Bau27B0::dataLinkLayer() DataLinkLayer& Bau27B0::dataLinkLayer()
{ {
return _dlLayer; return _dlLayer;

View File

@ -20,6 +20,7 @@ class Bau27B0 : public BauSystemB
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance); InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
DataLinkLayer& dataLinkLayer(); DataLinkLayer& dataLinkLayer();
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel) override;
private: private:
RfDataLinkLayer _dlLayer; RfDataLinkLayer _dlLayer;
RfMediumObject _rfMediumObj; RfMediumObject _rfMediumObj;

View File

@ -116,6 +116,14 @@ InterfaceObject* Bau57B0::getInterfaceObject(ObjectType objectType, uint8_t obje
} }
} }
void Bau57B0::doMasterReset(EraseCode eraseCode, uint8_t channel)
{
// Common SystemB objects
BauSystemB::doMasterReset(eraseCode, channel);
_ipParameters.masterReset(eraseCode, channel);
}
DataLinkLayer& Bau57B0::dataLinkLayer() DataLinkLayer& Bau57B0::dataLinkLayer()
{ {
return _dlLayer; return _dlLayer;

View File

@ -17,6 +17,7 @@ class Bau57B0 : public BauSystemB
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance); InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
DataLinkLayer& dataLinkLayer(); DataLinkLayer& dataLinkLayer();
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel) override;
private: private:
IpParameterObject _ipParameters; IpParameterObject _ipParameters;
IpDataLinkLayer _dlLayer; IpDataLinkLayer _dlLayer;

View File

@ -169,7 +169,7 @@ bool BauSystemB::configured()
return _configured; return _configured;
} }
uint8_t BauSystemB::masterReset(EraseCode eraseCode, uint8_t channel) uint8_t BauSystemB::checkmasterResetValidity(EraseCode eraseCode, uint8_t channel)
{ {
static constexpr uint8_t successCode = 0x00; // Where does this come from? It is the code for "success". static constexpr uint8_t successCode = 0x00; // Where does this come from? It is the code for "success".
static constexpr uint8_t invalidEraseCode = 0x02; // Where does this come from? It is the error code for "unspported erase code". static constexpr uint8_t invalidEraseCode = 0x02; // Where does this come from? It is the error code for "unspported erase code".
@ -206,18 +206,15 @@ uint8_t BauSystemB::masterReset(EraseCode eraseCode, uint8_t channel)
return successCode; return successCode;
} }
case EraseCode::FactoryReset: case EraseCode::FactoryReset:
{
// TODO: increase download counter except for confirmed restart (PID_DOWNLOAD_COUNTER)
println("Factory reset requested. type: with IA");
return successCode;
}
case EraseCode::FactoryResetWithoutIA: case EraseCode::FactoryResetWithoutIA:
{ {
// TODO: increase download counter except for confirmed restart (PID_DOWNLOAD_COUNTER) // TODO: increase download counter except for confirmed restart (PID_DOWNLOAD_COUNTER)
print("Factory reset requested. type: "); println("Factory reset requested. type: without IA");
println(eraseCode == EraseCode::FactoryReset ? "FactoryReset with IA" : "FactoryReset without IA");
#ifdef USE_DATASECURE
// If erase code is FactoryReset or FactoryResetWithoutIA, set FDSK as toolkey again
// and disable security mode.
// FIXME: the A_RestartResponse PDU has still to be sent with the current toolkey.
// Idea: use local confirmation of sent A_RestartResponse PDU to trigger writing the FDSK afterwards
_secIfObj.masterReset(eraseCode);
#endif
return successCode; return successCode;
} }
default: default:
@ -267,6 +264,21 @@ void BauSystemB::memoryExtReadIndication(Priority priority, HopCountType hopType
_appLayer.memoryExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress)); _appLayer.memoryExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress));
} }
void BauSystemB::doMasterReset(EraseCode eraseCode, uint8_t channel)
{
_addrTable.masterReset(eraseCode, channel);
_assocTable.masterReset(eraseCode, channel);
_groupObjTable.masterReset(eraseCode, channel);
_appProgram.masterReset(eraseCode, channel);
#ifdef USE_DATASECURE
// If erase code is FactoryReset or FactoryResetWithoutIA, set FDSK as toolkey again
// and disable security mode.
// FIXME: the A_RestartResponse PDU has still to be sent with the current toolkey.
// Idea: use local confirmation of sent A_RestartResponse PDU to trigger writing the FDSK afterwards
_secIfObj.masterReset(eraseCode, channel);
#endif
}
void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, RestartType restartType, EraseCode eraseCode, uint8_t channel) void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, RestartType restartType, EraseCode eraseCode, uint8_t channel)
{ {
if (restartType == RestartType::BasicRestart) if (restartType == RestartType::BasicRestart)
@ -275,12 +287,17 @@ void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopTyp
} }
else if (restartType == RestartType::MasterReset) else if (restartType == RestartType::MasterReset)
{ {
uint8_t errorCode = masterReset(eraseCode, channel); uint8_t errorCode = checkmasterResetValidity(eraseCode, channel);
// We send the restart response now before actually applying the reset values
// Processing time is kRestartProcessTime (example 3 seconds) that we require for the applying the master reset with restart
_appLayer.restartResponse(AckRequested, priority, hopType, secCtrl, errorCode, (errorCode == 0) ? kRestartProcessTime : 0); _appLayer.restartResponse(AckRequested, priority, hopType, secCtrl, errorCode, (errorCode == 0) ? kRestartProcessTime : 0);
doMasterReset(eraseCode, channel);
} }
else else
{ {
// Cannot happen as restartType is just one bit // Cannot happen as restartType is just one bit
println("Unhandled restart type.");
_platform.fatalError();
} }
// Flush the EEPROM before resetting // Flush the EEPROM before resetting

View File

@ -32,7 +32,7 @@ class BauSystemB : protected BusAccessUnit
void writeMemory(); void writeMemory();
void addSaveRestore(SaveRestore* obj); void addSaveRestore(SaveRestore* obj);
bool restartRequest(uint16_t asap, const SecurityControl secCtrl); bool restartRequest(uint16_t asap, const SecurityControl secCtrl);
uint8_t masterReset(EraseCode eraseCode, uint8_t channel); uint8_t checkmasterResetValidity(EraseCode eraseCode, uint8_t channel);
void propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, void propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId,
uint8_t& numberOfElements, uint16_t startIndex, uint8_t& numberOfElements, uint16_t startIndex,
@ -100,6 +100,8 @@ class BauSystemB : protected BusAccessUnit
void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length); void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length);
void nextRestartState(); void nextRestartState();
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel);
enum RestartState enum RestartState
{ {
Idle, Idle,

View File

@ -54,6 +54,12 @@ void InterfaceObject::readPropertyDescription(uint8_t& propertyId, uint8_t& prop
} }
} }
void InterfaceObject::masterReset(EraseCode eraseCode, uint8_t channel)
{
// every interface object shall implement this
// However, for the time being we provide an empty default implementation
}
void InterfaceObject::readProperty(PropertyID id, uint16_t start, uint8_t& count, uint8_t* data) void InterfaceObject::readProperty(PropertyID id, uint16_t start, uint8_t& count, uint8_t* data)
{ {
Property* prop = property(id); Property* prop = property(id);

View File

@ -3,6 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include "property.h" #include "property.h"
#include "save_restore.h" #include "save_restore.h"
#include "knx_types.h"
/** Enum for the type of an interface object. See Section 2.2 of knx:3/7/3 */ /** Enum for the type of an interface object. See Section 2.2 of knx:3/7/3 */
enum ObjectType enum ObjectType
@ -149,6 +150,10 @@ class InterfaceObject : public SaveRestore
*/ */
void readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access); void readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
// every interface object shall implement this
// However, for the time being we provide an empty default implementation
virtual void masterReset(EraseCode eraseCode, uint8_t channel);
/** /**
* Gets property with PropertyID id if it exists and nullptr otherwise. * Gets property with PropertyID id if it exists and nullptr otherwise.
*/ */

View File

@ -331,7 +331,7 @@ void SecurityInterfaceObject::errorCode(ErrorCode errorCode)
prop->write(data); prop->write(data);
} }
void SecurityInterfaceObject::masterReset(EraseCode eraseCode) void SecurityInterfaceObject::masterReset(EraseCode eraseCode, uint8_t channel)
{ {
// TODO handle different erase codes // TODO handle different erase codes
println("Factory reset of security interface object requested."); println("Factory reset of security interface object requested.");

View File

@ -15,7 +15,7 @@ public:
void secureApplicationLayer(SecureApplicationLayer& secAppLayer); void secureApplicationLayer(SecureApplicationLayer& secAppLayer);
void masterReset(EraseCode eraseCode); virtual void masterReset(EraseCode eraseCode, uint8_t channel) override;
bool isSecurityModeEnabled(); bool isSecurityModeEnabled();

View File

@ -93,11 +93,6 @@ template <class P, class B> class KnxFacade : private SaveRestore
return _bau.configured(); return _bau.configured();
} }
void masterReset(EraseCode erasecode, uint8_t channel)
{
_bau.masterReset(erasecode, channel);
}
/** /**
* returns HIGH if led is active on HIGH, LOW otherwise * returns HIGH if led is active on HIGH, LOW otherwise
*/ */