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");
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 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()
{
return _dlLayer;

View File

@ -20,6 +20,7 @@ class Bau27B0 : public BauSystemB
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
DataLinkLayer& dataLinkLayer();
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel) override;
private:
RfDataLinkLayer _dlLayer;
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()
{
return _dlLayer;

View File

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

View File

@ -169,7 +169,7 @@ bool BauSystemB::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 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;
}
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:
{
// TODO: increase download counter except for confirmed restart (PID_DOWNLOAD_COUNTER)
print("Factory reset requested. type: ");
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
println("Factory reset requested. type: without IA");
return successCode;
}
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));
}
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)
{
if (restartType == RestartType::BasicRestart)
@ -275,12 +287,17 @@ void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopTyp
}
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);
doMasterReset(eraseCode, channel);
}
else
{
// Cannot happen as restartType is just one bit
println("Unhandled restart type.");
_platform.fatalError();
}
// Flush the EEPROM before resetting

View File

@ -32,7 +32,7 @@ class BauSystemB : protected BusAccessUnit
void writeMemory();
void addSaveRestore(SaveRestore* obj);
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,
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 nextRestartState();
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel);
enum RestartState
{
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)
{
Property* prop = property(id);

View File

@ -3,6 +3,7 @@
#include <stddef.h>
#include "property.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 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);
// 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.
*/

View File

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

View File

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

View File

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