Device Handler Base API
DeviceHandlerBase
-
class DeviceHandlerBase : public DeviceHandlerIF, public ExecutableObjectIF, public SystemObject, public HasModesIF, public HasHealthIF, public HasActionsIF, public ReceivesParameterMessagesIF, public HasLocalDataPoolIF
This is the abstract base class for device handlers.
Documentation: Dissertation Baetz p.138,139, p.141-149
It features handling of Modes , communication with physical devices, using the DeviceCommunicationIF, and communication with commanding objects. It inherits SystemObject and thus can be created by the ObjectManagerIF.
This class uses the opcode of ExecutableObjectIF to perform a step-wise execution. For each step a different action is selected and executed. Currently, the device handler base performs a 4-step execution related to 4 communication steps (based on RMAP). NOTE: RMAP is a standard which is used for Flying Laptop. RMAP communication is not mandatory for projects implementing the FSFW. However, the communication principles are similar to RMAP as there are two write and two send calls involved.
Device handler instances should extend this class and implement the abstract functions. Components and drivers can send so called cookies which are used for communication and contain information about the communcation (e.g. slave address for I2C or RMAP structs). The following abstract methods must be implemented by a device handler:
Other important virtual methods with a default implementation are the getTransitionDelayMs() function and the getSwitches() function. If a transition to MODE_ON is desired without commanding, override the intialize() function and call setMode(_MODE_START_UP) before calling DeviceHandlerBase::initialize().
Subclassed by ChildHandlerBase, GyroHandlerL3GD20H, MgmLIS3MDLHandler, MgmRM3100Handler, TestDevice
Public Functions
-
DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF *comCookie, FailureIsolationBase *fdirInstance = nullptr, size_t cmdQueueSize = 20)
The constructor passes the objectId to the SystemObject().
- Parameters:
setObjectId – the ObjectId to pass to the SystemObject() Constructor
deviceCommuncation – Communcation Interface object which is used to implement communication functions
comCookie – This object will be passed to the communication inter- face and can contain user-defined information about the communication.
fdirInstance –
cmdQueueSize –
-
void setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID, lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID, uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID)
If the device handler is controlled by the FSFW thermal building blocks, this function should be called to initialize all required components. The device handler will then take care of creating local pool entries for the device thermal state and device heating request. Custom local pool IDs can be assigned as well.
- Parameters:
thermalStatePoolId –
thermalRequestPoolId –
-
void setStartUpImmediately()
Helper function to ease device handler development. This will instruct the transition to MODE_ON immediately (leading to doStartUp() being called for the transition to the ON mode), so external mode commanding is not necessary anymore.
This has to be called before the task is started! (e.g. in the task factory). This is only a helper function for development. Regular mode commanding should be performed by commanding the AssemblyBase or Subsystem objects resposible for the device handler.
-
virtual ReturnValue_t performOperation(uint8_t counter) override
This function is the device handler base core component and is called periodically.
General sequence, showing where abstract virtual functions are called: If the State is SEND_WRITE:
Set the cookie state to COOKIE_UNUSED and read the command queue
Handles Device State Modes by calling doStateMachine(). This function calls callChildStatemachine() which calls the abstract functions doStartUp() and doShutDown()
Check switch states by calling checkSwitchStates()
Decrements counter for timeout of replies by calling decrementDeviceReplyMap()
Performs FDIR check for failures
If the device mode is MODE_OFF, return returnvalue::OK. Otherwise, perform the Action property and performs depending on value specified by input value counter (incremented in PST). The child class tells base class what to do by setting this value.
SEND_WRITE: Send data or commands to device by calling doSendWrite() which calls sendMessage function of communicationInterface and calls buildInternalCommand if the cookie state is COOKIE_UNUSED
GET_WRITE: Get ackknowledgement for sending by calling doGetWrite() which calls getSendSuccess of communicationInterface. Calls abstract functions scanForReply() and interpretDeviceReply().
SEND_READ: Request reading data from device by calling doSendRead() which calls requestReceiveMessage of #communcationInterface
GET_READ: Access requested reading data by calling doGetRead() which calls readReceivedMessage of communicationInterface
- Parameters:
counter – Specifies which Action to perform
- Returns:
returnvalue::OK for successful execution
-
virtual ReturnValue_t initialize() override
Initializes the device handler.
Initialize Device Handler as system object and initializes all important helper classes. Calls fillCommandAndReplyMap().
- Returns:
-
virtual ReturnValue_t initializeAfterTaskCreation() override
Intialization steps performed after all tasks have been created. This function will be called by the executing task.
- Returns:
-
virtual ~DeviceHandlerBase()
Destructor.
-
virtual void setTaskIF(PeriodicTaskIF *task_) override
Implementation of ExecutableObjectIF function Used to setup the reference of the task, that executes this component
- Parameters:
task_ – Pointer to the taskIF of this task
-
virtual MessageQueueId_t getCommandQueue(void) const override
Function to get the MessageQueueId_t of the implementing object
- Returns:
MessageQueueId_t of the object
-
virtual object_id_t getObjectId() const override
Explicit interface implementation of getObjectId
-
virtual void setParentQueue(MessageQueueId_t parentQueueId)
- Parameters:
parentQueueId –
-
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size) override
Implementation required for HasActionIF.
-
virtual HealthState getHealth()
Get Health State.
- Returns:
Health State of the object
-
virtual ReturnValue_t setHealth(HealthState health)
Set the Health State The parent will be informed, if the Health changes.
- Parameters:
health –
-
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, uint16_t startAtIndex) override
This is the generic function overriden by child classes to set parameters. To set a parameter, the parameter wrapper is used with a variety of set functions. The provided values can be checked with newValues. Always set parameter before checking newValues!
- Parameters:
domainId –
parameterId –
parameterWrapper –
newValues –
startAtIndex – Linear index, runs left to right, top to bottom for matrix indexes.
- Returns:
Protected Types
-
enum WiretappingMode
Wiretapping flag:
indicates either that all raw messages to and from the device should be sent to defaultRawReceiver or that all device TM should be downlinked to defaultRawReceiver.
Values:
-
enumerator OFF
-
enumerator RAW
-
enumerator TM
-
enumerator OFF
Protected Functions
-
virtual void doStartUp() = 0
This is used to let the child class handle the transition from mode
_MODE_START_UPtoMODE_ON.It is only called when the device handler is in mode
_MODE_START_UP. That means, the device switch(es) are already set to on. Device handler commands are read and can be handled by the child class. If the child class handles a command, it should also send an reply accordingly. If an Command is not handled (ie #DeviceHandlerCommand is notCMD_NONE, the base class handles rejecting the command and sends a reply. The replies for mode transitions are handled by the base class.If the device is started and ready for operation, the mode should be set to MODE_ON. It is possible to set the mode to _MODE_TO_ON to use the to on transition if available.
If the power-up fails, the mode should be set to _MODE_POWER_DOWN which will lead to the device being powered off.
If the device does not change the mode, the mode will be changed to _MODE_POWER_DOWN, after the timeout (from getTransitionDelay()) has passed.
#transitionFailure can be set to a failure code indicating the reason for a failed transition
-
virtual void doShutDown() = 0
This is used to let the child class handle the transition from mode
_MODE_SHUT_DOWNto_MODE_POWER_DOWN.It is only called when the device handler is in mode
_MODE_SHUT_DOWN. Device handler commands are read and can be handled by the child class. If the child class handles a command, it should also send an reply accordingly. If an Command is not handled (ie #DeviceHandlerCommand is notCMD_NONE, the base class handles rejecting the command and sends a reply. The replies for mode transitions are handled by the base class.If the device ready to be switched off, the mode should be set to _MODE_POWER_DOWN.
If the device should not be switched off, the mode can be changed to _MODE_TO_ON (or MODE_ON if no transition is needed).
If the device does not change the mode, the mode will be changed to _MODE_POWER_DOWN, when the timeout (from getTransitionDelay()) has passed.
#transitionFailure can be set to a failure code indicating the reason for a failed transition
-
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) = 0
Build the device command to send for normal mode.
This is only called in
MODE_NORMAL. If multiple submodes forMODE_NORMALare supported, different commands can built, depending on the submode.rawPacket and rawPacketLen must be set by this method to the packet to be sent. If variable command frequence is required, a counter can be used and the frequency in the reply map has to be set manually by calling updateReplyMap().
- Parameters:
id – [out] the device command id that has been built
- Returns:
returnvalue::OKto send command after setting rawPacket and rawPacketLen.NOTHING_TO_SENDwhen no command is to be sent.Anything else triggers an even with the returnvalue as a parameter.
-
virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) = 0
Build the device command to send for a transitional mode.
This is only called in
_MODE_TO_NORMAL,_MODE_TO_ON,_MODE_TO_RAW,_MODE_START_UPand_MODE_SHUT_DOWN. So it is used by doStartUp() and doShutDown() as well as doTransition(), by setting those modes in the respective functions.A good idea is to implement a flag indicating a command has to be built and a variable containing the command number to be built and filling them in doStartUp(), doShutDown() and doTransition() so no modes have to be checked here.
rawPacket and rawPacketLen must be set by this method to the packet to be sent.
- Parameters:
id – [out] the device command id built
- Returns:
returnvalue::OKwhen a command is to be sentNOTHING_TO_SENDwhen no command is to be sentAnything else triggers an even with the returnvalue as a parameter
-
virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData, size_t commandDataLen) = 0
Build a device command packet from data supplied by a direct command (PUS Service 8)
This will be called if an functional command via PUS Service 8 is received and is the primary interface for functional command instead of executeAction for users. The supplied ActionId_t action ID will be converted to a DeviceCommandId_t command ID after an internal check whether the action ID is a key in the device command map.
rawPacket and rawPacketLen should be set by this method to the packet to be sent. The existence of the command in the command map and the command size check against 0 are done by the base class.
- Parameters:
deviceCommand – The command to build, already checked against deviceCommandMap
commandData – Pointer to the data from the direct command
commandDataLen – Length of commandData
- Returns:
returnvalue::OKto send command after rawPacket and rawPacketLen have been set.HasActionsIF::EXECUTION_COMPLETEto generate a finish reply immediately. This can be used if no reply is expectedAnything else triggers an event with the return code as a parameter as well as a step reply failed with the return code
-
virtual ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, size_t *foundLen) = 0
Scans a buffer for a valid reply.
This is used by the base class to check the data received for valid packets. It only checks if a valid packet starts at
start. It also only checks the structural validy of the packet, e.g. checksums lengths and protocol data. No information check is done, e.g. range checks etc.Errors should be reported directly, the base class does NOT report any errors based on the return value of this function.
See also
also fillCommandAndCookieMap() )
- Parameters:
start – start of remaining buffer to be scanned
len – length of remaining buffer to be scanned
foundId – [out] the id of the data found in the buffer.
foundLen – [out] length of the data found. Is to be set in function, buffer is scanned at previous position + foundLen.
- Returns:
returnvalue::OKa valid packet was found atstart,foundLenis validreturnvalue::FAILEDno reply could be found starting atstart, impliesfoundLenis not valid, base class will call scanForReply() again with ++startDeviceHandlerIF::INVALID_DATAa packet was found but it is invalid, e.g. checksum error, impliesfoundLenis valid, can be used to skip some bytesDeviceHandlerIF::LENGTH_MISSMATCHlenis invalidDeviceHandlerIF::IGNORE_REPLY_DATAIgnore this specific part of the packetDeviceHandlerIF::IGNORE_FULL_PACKETIgnore the packetAPERIODIC_REPLYif a valid reply is received that has not been requested by a command, but should be handled anyway (
-
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) = 0
Interpret a reply from the device.
This is called after scanForReply() found a valid packet, it can be assumed that the length and structure is valid. This routine extracts the data from the packet into a DataSet and then calls handleDeviceTM(), which either sends a TM packet or stores the data in the DataPool depending on whether it was an external command. No packet length is given, as it should be defined implicitly by the id.
- Parameters:
id – the id found by scanForReply()
packet –
- Returns:
returnvalue::OKwhen the reply was interpreted.IGNORE_REPLY_DATAIgnore the reply and don’t reset reply cycle counter.returnvalue::FAILEDwhen the reply could not be interpreted, e.g. logical errors or range violations occurred
-
DeviceCommandId_t getPendingCommand() const
Helper function to get pending command. This is useful for devices like SPI sensors to identify the last sent command. This only returns the command sent in the last SEND_WRITE cycle.
- Returns:
-
virtual void fillCommandAndReplyMap() = 0
Fill the #DeviceCommandMap and #DeviceReplyMap called by the initialize of the base class.
This is used to let the base class know which replies are expected. There are different scenarios regarding this:
“Normal” commands. These are commands, that trigger a direct reply from the device. In this case, the id of the command should be added to the command map with a commandData_t where maxDelayCycles is set to the maximum expected number of PST cycles the reply will take. Then, scanForReply returns the id of the command and the base class can handle time-out and missing replies.
Periodic, unrequested replies. These are replies that, once enabled, are sent by the device on its own in a defined interval. In this case, the id of the reply or a placeholder id should be added to the deviceCommandMap with a commandData_t where maxDelayCycles is set to the maximum expected number of PST cycles between two replies (also a tolerance should be added, as an FDIR message will be generated if it is missed). From then on, the base class handles the reception. Then, scanForReply returns the id of the reply or the placeholder id and the base class will take care of checking that all replies are received and the interval is correct.
Aperiodic, unrequested replies. These are replies that are sent by the device without any preceding command and not in a defined interval. These are not entered in the deviceCommandMap but handled by returning
APERIODIC_REPLYin scanForReply().
-
ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase *replyDataSet = nullptr, size_t replyLen = 0, bool periodic = false, bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0, Countdown *countdown = nullptr)
This is a helper method to facilitate inserting entries in the command map.
- Parameters:
deviceCommand – Identifier of the command to add.
maxDelayCycles – The maximum number of delay cycles the command waits until it times out.
replyLen – Will be supplied to the requestReceiveMessage call of the communication interface.
periodic – Indicates if the command is periodic (i.e. it is sent by the device repeatedly without request) or not. Default is aperiodic (0). Please note that periodic replies are disabled by default. You can enable them with updatePeriodicReply
countdown – Instead of using maxDelayCycles to timeout a device reply it is also possible to provide a pointer to a Countdown object which will signal the timeout when expired
- Returns:
-
returnvalue::OKwhen the command was successfully inserted,returnvalue::FAILEDelse.
-
ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, LocalPoolDataSetBase *dataSet = nullptr, size_t replyLen = 0, bool periodic = false, Countdown *countdown = nullptr)
This is a helper method to insert replies in the reply map.
- Parameters:
deviceCommand – Identifier of the reply to add.
maxDelayCycles – The maximum number of delay cycles the reply waits until it times out.
periodic – Indicates if the command is periodic (i.e. it is sent by the device repeatedly without request) or not. Default is aperiodic (0). Please note that periodic replies are disabled by default. You can enable them with updatePeriodicReply
countdown – Instead of using maxDelayCycles to timeout a device reply it is also possible to provide a pointer to a Countdown object which will signal the timeout when expired
- Returns:
-
returnvalue::OKwhen the command was successfully inserted,returnvalue::FAILEDelse.
-
ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand, bool useAlternativeReply = false, DeviceCommandId_t alternativeReplyId = 0)
A simple command to add a command to the commandList.
- Parameters:
deviceCommand – The command to add
- Returns:
-
returnvalue::OKwhen the command was successfully inserted,returnvalue::FAILEDelse.
-
ReturnValue_t updatePeriodicReply(bool enable, DeviceCommandId_t deviceReply)
Enables a periodic reply for a given command. It sets to delay cycles to the specified maximum delay cycles for a given reply ID if enabled or to 0 if disabled.
- Parameters:
enable – Specify whether to enable or disable a given periodic reply
- Returns:
-
virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand)
This function returns the reply length of the next reply to read.
The default implementation assumes only one reply is triggered by the command. In case the command triggers multiple replies (e.g. one acknowledgment, one data, and one execution status reply), this function can be overwritten to get the reply length of the next reply to read.
- Parameters:
deviceCommand – The command which triggered the device reply.
-
ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply, uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic = false)
This is a helper method to facilitate updating entries in the reply map.
- Parameters:
deviceCommand – Identifier of the reply to update.
delayCycles – The current number of delay cycles to wait. As stated in fillCommandAndReplyMap, to disable periodic commands, this is set to zero.
maxDelayCycles – The maximum number of delay cycles the reply waits until it times out. By passing 0 the entry remains untouched.
periodic – Indicates if the command is periodic (i.e. it is sent by the device repeatedly without request) or not. Default is aperiodic (0). Warning: The setting always overrides the value that was entered in the map.
- Returns:
-
returnvalue::OKwhen the command was successfully inserted,returnvalue::FAILEDelse.
-
ReturnValue_t setReplyDataset(DeviceCommandId_t replyId, LocalPoolDataSetBase *dataset)
Can be used to set the dataset corresponding to a reply ID manually.
Used by the local data pool manager.
-
virtual uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) = 0
Get the time needed to transit from modeFrom to modeTo.
Used for the following transitions: modeFrom -> modeTo: MODE_ON -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] MODE_NORMAL -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] MODE_RAW -> [MODE_ON, MODE_NORMAL, MODE_RAW, _MODE_POWER_DOWN] _MODE_START_UP -> MODE_ON (do not include time to set the switches, the base class got you covered)
The default implementation returns 0 !
- Parameters:
modeFrom –
modeTo –
- Returns:
time in ms
-
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) override
This function is used to initialize the local housekeeping pool entries. The default implementation leaves the pool empty.
- Parameters:
localDataPoolMap –
- Returns:
-
virtual void setNormalDatapoolEntriesInvalid()
Set all datapool variables that are update periodically in normal mode invalid.
The default implementation will set all datasets which have been added in fillCommandAndReplyMap to invalid. It will also set all pool variables inside the dataset to invalid. The user can override this method optionally.
-
virtual LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override
Get the dataset handle for a given SID.
The default implementation will use the deviceCommandMap to look for the corresponding dataset handle. The user can override this function if this is not desired.
- Parameters:
sid –
- Returns:
-
void setMode(Mode_t newMode)
Set the device handler mode.
Sets #timeoutStart with every call Also sets #transitionTargetMode if necessary so transitional states can be entered from everywhere without breaking the state machine (which relies on a correct #transitionTargetMode). The submode is left unchanged.
- Parameters:
newMode –
-
void setMode(Mode_t newMode, Submode_t submode)
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
- Parameters:
submode –
-
virtual ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode)
Should be implemented properly by child class.
- Parameters:
mode –
submode –
- Returns:
returnvalue::OKif validreturnvalue::FAILEDif invalid
-
virtual void modeChanged()
Notify child about mode change.
Can be overriden to be used like a callback.
-
virtual ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches)
Return the switches connected to the device.
The default implementation returns one switch set in the ctor.
- Parameters:
switches – [out] pointer to an array of switches
numberOfSwitches – [out] length of returned array
- Returns:
returnvalue::OKif the parameters were setreturnvalue::FAILEDif no switches exist
-
virtual void missedReply(DeviceCommandId_t id)
Helper function to report a missed reply.
Can be overwritten by children to act on missed replies or to fake reporting Id.
- Parameters:
id – of the missed reply
-
virtual void performOperationHook()
Hook function for child handlers which is called once per performOperation(). Default implementation is empty.
-
virtual void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0, uint32_t parameter = 0)
Can be implemented by child handler to perform debugging.
Example: Calling this in performOperation to track values like mode.
- Parameters:
positionTracker – Provide the child handler a way to know where the debugInterface was called
objectId – Provide the child handler object Id to specify actions for spefic devices
parameter – Supply a parameter of interest Please delete all debugInterface calls in DHB after debugging is finished !
-
void replyReturnvalueToCommand(ReturnValue_t status, uint32_t parameter = 0)
Send a reply to a received device handler command.
This also resets #DeviceHandlerCommand to 0.
- Parameters:
reply – the reply type
parameter – parameter for the reply
-
void replyToCommand(ReturnValue_t status, uint32_t parameter = 0)
TODO: Whats the difference between this and the upper command?
- Parameters:
status –
parameter –
-
virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom)
Do the transition to the main modes (MODE_ON, MODE_NORMAL and MODE_RAW).
If the transition is complete, the mode should be set to the target mode, which can be deduced from the current mode which is [_MODE_TO_ON, _MODE_TO_NORMAL, _MODE_TO_RAW]
The intended target submode is already set. The origin submode can be read in subModeFrom.
If the transition can not be completed, the child class can try to reach an working mode by setting the mode either directly or setting the mode to an transitional mode (TO_ON, TO_NORMAL, TO_RAW) if the device needs to be reconfigured.
If nothing works, the child class can wait for the timeout and the base class will reset the mode to the mode where the transition originated from (the child should report the reason for the failed transition).
The intended way to send commands is to set a flag (enum) indicating which command is to be sent here and then to check in buildTransitionCommand() for the flag. This flag can also be used by doStartUp() and doShutDown() to get a nice and clean implementation of buildTransitionCommand() without switching through modes.
When the the condition for the completion of the transition is met, the mode can be set, for example in the scanForReply() function.
The default implementation goes into the target mode directly.
#transitionFailure can be set to a failure code indicating the reason for a failed transition
- Parameters:
modeFrom – The mode the transition originated from: [MODE_ON, MODE_NORMAL, MODE_RAW and _MODE_POWER_DOWN (if the mode changed from _MODE_START_UP to _MODE_TO_ON)]
subModeFrom – the subMode of modeFrom
-
virtual CommunicationAction getComAction()
Get the communication action for the current step. The step number can be read from pstStep.
- Returns:
The communication action to execute in this step
-
virtual void checkSwitchState()
Checks state of switches in conjunction with mode and triggers an event if they don’t fit.
-
virtual void doOffActivity()
Reserved for the rare case where a device needs to perform additional operation cyclically in OFF mode.
-
virtual void doOnActivity()
Reserved for the rare case where a device needs to perform additional operation cyclically in ON mode.
-
virtual LocalDataPoolManager *getHkManagerHandle() override
Required for HasLocalDataPoolIF, return a handle to the local pool manager.
- Returns:
-
uint8_t getReplyDelayCycles(DeviceCommandId_t deviceCommand)
Returns the delay cycle count of a reply. A count != 0 indicates that the command is already executed.
- Parameters:
deviceCommand – The command to look for
- Returns:
The current delay count. If the command does not exist (should never happen) it returns 0.
-
void replyRawReplyIfnotWiretapped(const uint8_t *data, size_t len)
Calls replyRawData() with defaultRawReceiver, but checks if wiretapping is active and if so, does not send the data as the wiretapping will have sent it already
-
virtual ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command, uint8_t expectedReplies = 1, bool useAlternateId = false, DeviceCommandId_t alternateReplyID = 0)
Enable the reply checking for a command
Is only called, if the command was sent (i.e. the getWriteReply was successful). Must ensure that all replies are activated and correctly linked to the command that initiated it. The default implementation looks for a reply with the same id as the command id in the replyMap or uses the alternativeReplyId if flagged so. When found, copies maxDelayCycles to delayCycles in the reply information and sets the command to expect one reply.
Can be overwritten by the child, if a command activates multiple replies or replyId differs from commandId. Notes for child implementations:
If the command was not found in the reply map, NO_REPLY_EXPECTED MUST be returned.
A failure code may be returned if something went fundamentally wrong.
- Parameters:
deviceCommand –
- Returns:
- returnvalue::OK if a reply was activated.
NO_REPLY_EXPECTED if there was no reply found. This is not an error case as many commands do not expect a reply.
-
virtual ReturnValue_t buildChildRawCommand()
Build the device command to send for raw mode.
This is only called in
MODE_RAW. It is for the rare case that in raw mode packets are to be sent by the handler itself. It is NOT needed for the raw commanding service. Its only current use is in the STR handler which gets its raw packets from a different source. Also it can be used for transitional commands, to get the device ready forMODE_RAWAs it is almost never used, there is a default implementation returning
NOTHING_TO_SEND.rawPacket and rawPacketLen must be set by this method to the packet to be sent.
- Parameters:
id – [out] the device command id built
- Returns:
returnvalue::OKwhen a command is to be sentnot
NOTHING_TO_SENDwhen no command is to be sent
-
virtual void replyRawData(const uint8_t *data, size_t len, MessageQueueId_t sendTo, bool isCommand = false)
Construct a command reply containing a raw reply.
It gets space in the IPCStore, copies data there, then sends a raw reply containing the store address. This method is virtual, as devices can have different channels to send raw replies
- Parameters:
data – data to send
len – length of
datasendTo – the messageQueueId of the one to send to
isCommand – marks the raw data as a command, the message then will be of type raw_command
-
ReturnValue_t getStateOfSwitches()
Get the state of the PCDU switches in the local datapool
- Returns:
PowerSwitchIF::SWITCH_ONif all switches specified by #switches are onPowerSwitchIF::SWITCH_OFFone of the switches specified by #switches are offPowerSwitchIF::returnvalue::FAILEDif an error occured
-
virtual bool dontCheckQueue()
Children can overwrite this function to suppress checking of the command Queue
This can be used when the child does not want to receive a command in a certain situation. Care must be taken that checking is not permanentely disabled as this would render the handler unusable.
- Returns:
whether checking the queue should NOT be done
-
void handleDeviceTm(const uint8_t *rawData, size_t rawDataLen, DeviceCommandId_t replyId, bool forceDirectTm = false)
Wrapper function for @handleDeviceTm which wraps the raw buffer with @SerialBufferAdapter. For interpreted data, prefer the other function.
- Parameters:
rawData –
rawDataLen –
replyId –
forceDirectTm –
-
void handleDeviceTm(const SerializeIF &dataSet, DeviceCommandId_t replyId, bool forceDirectTm = false)
Can be used to handle Service 8 data replies. This will also generate the TM wiretapping packets accordingly.
- Parameters:
dataSet –
replyId –
forceDirectTm –
-
virtual void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) override
Overwrites SystemObject::triggerEvent in order to inform FDIR”Helper” faster about executed events. This is a bit sneaky, but improves responsiveness of the device FDIR.
- Parameters:
event – The event to be thrown
parameter1 – Optional parameter 1
parameter2 – Optional parameter 2
-
virtual void forwardEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0) const override
Same as triggerEvent, but for forwarding if object is used as proxy.
-
bool isTransitionalMode()
Checks if current mode is transitional mode.
- Returns:
true if mode is transitional, false else.
-
virtual ReturnValue_t acceptExternalDeviceCommands()
Checks if current handler state allows reception of external device commands. Default implementation allows commands only in plain MODE_ON and MODE_NORMAL.
- Returns:
returnvalue::OK if commands are accepted, anything else otherwise.
-
void commandSwitch(ReturnValue_t onOff)
set all switches returned by getSwitches()
- Parameters:
onOff – on ==
SWITCH_ON; off !=SWITCH_ON
-
virtual ReturnValue_t doSendReadHook()
This function can be used to insert device specific code during the do-send-read step.
Protected Attributes
-
uint8_t *rawPacket = nullptr
Pointer to the raw packet that will be sent.
-
Mode_t mode
The mode the device handler is currently in. This should never be changed directly but only with setMode()
-
Submode_t submode
The submode the device handler is currently in. This should never be changed directly but only with setMode()
-
uint8_t pstStep = 0
This is the counter value from performOperation().
-
MessageQueueId_t defaultRawReceiver = MessageQueueIF::NO_QUEUE
A message queue that accepts raw replies.
Statically initialized in initialize() to a configurable object. Used when there is no method of finding a recipient, ie raw mode and reporting erroneous replies
-
MessageQueueId_t requestedRawTraffic = 0
The message queue which wants to read all raw traffic If #isWiretappingActive all raw communication from and to the device will be sent to this queue.
-
StorageManagerIF *IPCStore = nullptr
Pointer to the IPCStore. This caches the pointer received from the objectManager in the constructor.
-
object_id_t deviceCommunicationId
The comIF object ID is cached for the intialize() function
-
DeviceCommunicationIF *communicationInterface = nullptr
Communication object used for device communication
-
CookieIF *comCookie
Cookie used for communication
-
DeviceCommandMap deviceCommandMap
Information about commands
-
DeviceReplyMap deviceReplyMap
This map is used to check and track correct reception of all replies.
It has multiple use:
It stores the information on pending replies. If a command is sent, the DeviceCommandInfo.count is incremented.
It is used to time-out missing replies. If a command is sent, the DeviceCommandInfo.DelayCycles is set to MaxDelayCycles.
It is queried to check if a reply from the device can be interpreted. scanForReply() returns the id of the command a reply was found for. The reply is ignored in the following cases:
No entry for the returned id was found
The deviceReplyInfo.delayCycles is == 0
-
MessageQueueIF *commandQueue = nullptr
The MessageQueue used to receive device handler commands and to send replies.
-
ReturnValue_t childTransitionFailure
Optional Error code. Can be set in doStartUp(), doShutDown() and doTransition() to signal cause for Transition failure.
-
uint32_t ignoreMissedRepliesCount = 0
Counts if communication channel lost a reply, so some missed replys can be ignored.
-
FailureIsolationBase *fdirInstance
Pointer to the used FDIR instance. If not provided by child, default class is instantiated.
-
bool defaultFDIRUsed
To correctly delete the default instance.
-
bool switchOffWasReported
Indicates if SWITCH_WENT_OFF was already thrown.
-
PeriodicTaskIF *executingTask = nullptr
Pointer to the task which executes this component, is invalid before setTaskIF was called.
Protected Static Attributes
-
static const ReturnValue_t APERIODIC_REPLY = MAKE_RETURN_CODE(0xB0)
This is used to specify for replies from a device which are not replies to requests.
-
static const ReturnValue_t IGNORE_REPLY_DATA = MAKE_RETURN_CODE(0xB1)
Ignore parts of the received packet.
-
static const ReturnValue_t IGNORE_FULL_PACKET = MAKE_RETURN_CODE(0xB2)
Ignore full received packet.
-
static const ReturnValue_t NOTHING_TO_SEND = MAKE_RETURN_CODE(0xC0)
Return this if no command sending in required.
-
static object_id_t powerSwitcherId = objects::NO_OBJECT
Object which switches power on and off.
-
static object_id_t rawDataReceiverId = objects::NO_OBJECT
Object which receives RAW data by default.
-
static object_id_t defaultFdirParentId = objects::NO_OBJECT
Object which may be the root cause of an identified fault.
-
struct DeviceCommandInfo
Information about commands.
Public Members
-
bool isExecuting
Indicates if the command is already executing.
-
uint8_t expectedReplies
Dynamic value to indicate how many replies are expected. Inititated with 0.
-
MessageQueueId_t sendReplyTo
if this is != NO_COMMANDER, DHB was commanded externally and shall report everything to commander.
-
bool isExecuting
-
struct DeviceReplyInfo
Information about expected replies This is used to keep track of pending replies.
Public Members
-
uint16_t maxDelayCycles
The maximum number of cycles the handler should wait for a reply to this command.
-
uint16_t delayCycles
The currently remaining cycles the handler should wait for a reply, 0 means there is no reply expected
-
size_t replyLen = 0
Expected size of the reply.
-
bool periodic = false
if this is !=0, the delayCycles will not be reset to 0 but to maxDelayCycles
-
LocalPoolDataSetBase *dataSet = nullptr
The dataset used to access housekeeping data related to the respective device reply. Will point to a dataset held by the child handler (if one is specified)
-
DeviceCommandMap::iterator command
The command that expects this reply.
-
Countdown *countdown = nullptr
Instead of using delayCycles to specify the maximum time to wait for the device reply, it is also possible specify a countdown
-
bool active = false
will be set to true when reply is enabled
-
uint16_t maxDelayCycles
DeviceHandlerIF
-
class DeviceHandlerIF
This is the Interface used to communicate with a device handler.
Includes all expected return values, events and modes.
Subclassed by DeviceHandlerBase
Public Types
-
enum CommunicationAction
Communication action that will be executed.
This is used by the child class to tell the base class what to do.
Values:
-
enumerator PERFORM_OPERATION
-
enumerator SEND_WRITE
Send write.
-
enumerator GET_WRITE
Get write.
-
enumerator SEND_READ
Send read.
-
enumerator GET_READ
Get read.
-
enumerator NOTHING
Do nothing.
-
enumerator PERFORM_OPERATION
Public Functions
-
inline virtual ~DeviceHandlerIF()
Default Destructor
-
virtual MessageQueueId_t getCommandQueue() const = 0
This MessageQueue is used to command the device handler.
- Returns:
the id of the MessageQueue
Public Static Attributes
-
static const Mode_t MODE_NORMAL = 2
This is the mode the device handler is in.
The mode of the device handler must not be confused with the mode the device is in. The mode of the device itself is transparent to the user but related to the mode of the handler. MODE_ON and MODE_OFF are included in hasModesIF.h The device is powered on and the device handler periodically sends commands. The commands to be sent are selected by the handler according to the submode.
-
static const Mode_t MODE_RAW = 3
The device is powered on and ready to perform operations. In this mode, raw commands can be sent. The device handler will send all replies received from the command back to the commanding object.
-
static const Mode_t MODE_ERROR_ON = 4
The device is shut down but the switch could not be turned off, so the device still is powered. In this mode, only a mode change to
MODE_OFFcan be commanded, which tries to switch off the device again.
-
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5
This is a transitional state which can not be commanded. The device handler performs all commands to get the device in a state ready to perform commands. When this is completed, the mode changes to
MODE_ON.
-
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6
This is a transitional state which can not be commanded. The device handler performs all actions and commands to get the device shut down. When the device is off, the mode changes to
MODE_OFF. It is possible to set the mode to _MODE_SHUT_DOWN to use the to off transition if available.
-
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON
It is possible to set the mode to _MODE_TO_ON to use the to on transition if available.
-
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW
It is possible to set the mode to _MODE_TO_RAW to use the to raw transition if available.
-
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL
It is possible to set the mode to _MODE_TO_NORMAL to use the to normal transition if available.
-
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1
This is a transitional state which can not be commanded. The device is shut down and ready to be switched off. After the command to set the switch off has been sent, the mode changes to
MODE_WAIT_OFF
-
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2
This is a transitional state which can not be commanded. The device will be switched on in this state. After the command to set the switch on has been sent, the mode changes to
MODE_WAIT_ON.
-
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3
This is a transitional state which can not be commanded. The switch has been commanded off and the handler waits for it to be off. When the switch is off, the mode changes to
MODE_OFF.
-
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4
This is a transitional state which can not be commanded. The switch has been commanded on and the handler waits for it to be on. When the switch is on, the mode changes to
MODE_TO_ON.
-
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5
This is a transitional state which can not be commanded. The switch has been commanded off and is off now. This state is only to do an RMAP cycle once more where the doSendRead() function will set the mode to MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
-
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW)
[EXPORT] : [COMMENT] Indicates a SW bug in child class.
-
static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0)
If no command data was given when expected.
-
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1)
Command ID not in commandMap. Checked in DHB.
-
static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2)
Command was already executed. Checked in DHB.
-
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7)
Used to indicate that this is a command-only command.
-
enum CommunicationAction