F´ Flight Software - C/C++ Documentation  NASA-v1.5.0
A framework for building embedded system applications to NASA flight quality standards.
CommandDispatcherImpl.cpp
Go to the documentation of this file.
1 /*
2  * CommandDispatcherImpl.cpp
3  *
4  * Created on: May 13, 2014
5  * Author: Timothy Canham
6  */
7 
9 #include <Fw/Cmd/CmdPacket.hpp>
10 #include <Fw/Types/Assert.hpp>
11 #include <stdio.h>
12 
13 namespace Svc {
16  m_seq(0),
17  m_numCmdsDispatched(0),
18  m_numCmdErrors(0)
19  {
20  memset(this->m_entryTable,0,sizeof(this->m_entryTable));
21  memset(this->m_sequenceTracker,0,sizeof(this->m_sequenceTracker));
22  }
23 
25  }
26 
28  NATIVE_INT_TYPE queueDepth,
29  NATIVE_INT_TYPE instance
30  ) {
32  }
33 
35  // search for an empty slot
36  bool slotFound = false;
37  for (U32 slot = 0; slot < FW_NUM_ARRAY_ELEMENTS(this->m_entryTable); slot++) {
38  if ((not this->m_entryTable[slot].used) and (not slotFound)) {
39  this->m_entryTable[slot].opcode = opCode;
40  this->m_entryTable[slot].port = portNum;
41  this->m_entryTable[slot].used = true;
42  this->log_DIAGNOSTIC_OpCodeRegistered(opCode,portNum,slot);
43  slotFound = true;
44  } else if (this->m_entryTable[slot].used) { // make sure no duplicates
45  FW_ASSERT(this->m_entryTable[slot].opcode != opCode, opCode);
46  }
47  }
48  FW_ASSERT(slotFound,opCode);
49  }
50 
52  // check response and log
53  if (Fw::COMMAND_OK == response) {
54  this->log_COMMAND_OpCodeCompleted(opCode);
55  } else {
56  this->m_numCmdErrors++;
58  ErrorResponse evrResp = ERR_UNEXP;
59  switch (response) {
61  evrResp = ERR_INVALID_OPCODE;
62  break;
64  evrResp = ERR_VALIDATION_ERROR;
65  break;
67  evrResp = ERR_FORMAT_ERROR;
68  break;
70  evrResp = ERR_EXECUTION_ERROR;
71  break;
72  case Fw::COMMAND_BUSY:
73  evrResp = ERR_BUSY;
74  break;
75  case Fw::COMMAND_OK:
76  FW_ASSERT(0); // should never get here
77  break;
78  default:
79  evrResp = ERR_UNEXP;
80  break;
81  }
82  this->log_WARNING_HI_OpCodeError(opCode,evrResp);
83  }
84  // look for command source
85  NATIVE_INT_TYPE portToCall = -1;
86  U32 context;
87  for (U32 pending = 0; pending < FW_NUM_ARRAY_ELEMENTS(this->m_sequenceTracker); pending++) {
88  if (
89  (this->m_sequenceTracker[pending].seq == cmdSeq) &&
90  (this->m_sequenceTracker[pending].used)
91  ) {
92  portToCall = this->m_sequenceTracker[pending].callerPort;
93  context = this->m_sequenceTracker[pending].context;
94  FW_ASSERT(opCode == this->m_sequenceTracker[pending].opCode);
95  FW_ASSERT(portToCall < this->getNum_seqCmdStatus_OutputPorts());
96  this->m_sequenceTracker[pending].used = false;
97  break;
98  }
99  }
100 
101  if (portToCall != -1) {
102  // call port to report status
103  if (this->isConnected_seqCmdStatus_OutputPort(portToCall)) {
104  this->seqCmdStatus_out(portToCall,opCode,context,response);
105  }
106  }
107  }
108 
110 
111  Fw::CmdPacket cmdPkt;
112  Fw::SerializeStatus stat = cmdPkt.deserialize(data);
113 
114  if (stat != Fw::FW_SERIALIZE_OK) {
115  CmdSerError serErr = ERR_UNEXP_STAT;
116  switch (stat) {
118  serErr = ERR_BUFFER_TOO_SMALL;
119  break;
121  serErr = ERR_BUFFER_FORMAT;
122  break;
124  serErr = ERR_SIZE_MISMATCH;
125  break;
127  serErr = ERR_TYPE_MISMATCH;
128  break;
129  case Fw::FW_SERIALIZE_OK:
130  FW_ASSERT(0); // should never get here
131  break;
132  default:
133  serErr = ERR_UNEXP_STAT;
134  break;
135  }
136  this->log_WARNING_HI_MalformedCommand(serErr);
137  if (this->isConnected_seqCmdStatus_OutputPort(portNum)) {
138  this->seqCmdStatus_out(portNum,cmdPkt.getOpCode(),context,Fw::COMMAND_VALIDATION_ERROR);
139  }
140  return;
141  }
142 
143  // search for opcode in dispatch table
144  U32 entry;
145  bool entryFound = false;
146 
147  for (entry = 0; entry < FW_NUM_ARRAY_ELEMENTS(this->m_entryTable); entry++) {
148  if ((this->m_entryTable[entry].used) and (cmdPkt.getOpCode() == this->m_entryTable[entry].opcode)) {
149  entryFound = true;
150  break;
151  }
152  }
153  if (entryFound and this->isConnected_compCmdSend_OutputPort(this->m_entryTable[entry].port)) {
154  // register command in command tracker only if response port is connect
155  if (this->isConnected_seqCmdStatus_OutputPort(portNum)) {
156  bool pendingFound = false;
157 
158  for (U32 pending = 0; pending < FW_NUM_ARRAY_ELEMENTS(this->m_sequenceTracker); pending++) {
159  if (not this->m_sequenceTracker[pending].used) {
160  pendingFound = true;
161  this->m_sequenceTracker[pending].used = true;
162  this->m_sequenceTracker[pending].opCode = cmdPkt.getOpCode();
163  this->m_sequenceTracker[pending].seq = this->m_seq;
164  this->m_sequenceTracker[pending].context = context;
165  this->m_sequenceTracker[pending].callerPort = portNum;
166  break;
167  }
168  }
169 
170  // if we couldn't find a slot to track the command, quit
171  if (not pendingFound) {
173  if (this->isConnected_seqCmdStatus_OutputPort(portNum)) {
174  this->seqCmdStatus_out(portNum,cmdPkt.getOpCode(),context,Fw::COMMAND_EXECUTION_ERROR);
175  }
176  return;
177  }
178  } // end if status port connected
179  // pass arguments to argument buffer
180  this->compCmdSend_out(this->m_entryTable[entry].port,cmdPkt.getOpCode(),this->m_seq,cmdPkt.getArgBuffer());
181  // log dispatched command
182  this->log_COMMAND_OpCodeDispatched(cmdPkt.getOpCode(),this->m_entryTable[entry].port);
183 
184  // increment command count
185  this->m_numCmdsDispatched++;
186  // write telemetry channel for dispatched commands
187  this->tlmWrite_CommandsDispatched(this->m_numCmdsDispatched);
188  } else {
190  this->m_numCmdErrors++;
191  // Fail command back to port, if connected
192  if (this->isConnected_seqCmdStatus_OutputPort(portNum)) {
193  this->seqCmdStatus_out(portNum,cmdPkt.getOpCode(),context,Fw::COMMAND_INVALID_OPCODE);
194  }
196  }
197 
198  // increment sequence number
199  this->m_seq++;
200  }
201 
203  Fw::LogStringArg no_op_string("Hello, World!");
204  // Log event for NO_OP here.
206  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
207  }
208 
210  Fw::LogStringArg msg(arg1.toChar());
211  // Echo the NO_OP_STRING args here.
213  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
214  }
215 
216  void CommandDispatcherImpl::CMD_TEST_CMD_1_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, I32 arg1, F32 arg2, U8 arg3) {
217  this->log_ACTIVITY_HI_TestCmd1Args(arg1,arg2,arg3);
218  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
219  }
220 
222  // clear tracking table
223  for (NATIVE_INT_TYPE entry = 0; entry < CMD_DISPATCHER_SEQUENCER_TABLE_SIZE; entry++) {
224  this->m_sequenceTracker[entry].used = false;
225  }
226  this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
227  }
228 
230  // respond to ping
231  this->pingOut_out(0,key);
232  }
233 
234 }
Svc::CommandDispatcherComponentBase::pingOut_out
void pingOut_out(NATIVE_INT_TYPE portNum, U32 key)
Definition: CommandDispatcherComponentAc.cpp:760
Fw::FW_DESERIALIZE_BUFFER_EMPTY
@ FW_DESERIALIZE_BUFFER_EMPTY
Deserialization buffer was empty when trying to read more data.
Definition: Serializable.hpp:18
Svc::CommandDispatcherComponentBase::log_WARNING_HI_MalformedCommand
void log_WARNING_HI_MalformedCommand(CmdSerError Status)
Definition: CommandDispatcherComponentAc.cpp:1920
Svc::CommandDispatcherImpl::SequenceTracker::context
U32 context
context passed by user
Definition: CommandDispatcherImpl.hpp:166
Svc::CommandDispatcherImpl::m_seq
I32 m_seq
current command sequence number
Definition: CommandDispatcherImpl.hpp:170
Svc::CommandDispatcherComponentBase::ERR_UNEXP_STAT
@ ERR_UNEXP_STAT
Definition: CommandDispatcherComponentAc.hpp:837
Svc::CommandDispatcherComponentBase
Auto-generated base for CommandDispatcher component.
Definition: CommandDispatcherComponentAc.hpp:50
Svc::CommandDispatcherComponentBase::ERR_BUFFER_TOO_SMALL
@ ERR_BUFFER_TOO_SMALL
Definition: CommandDispatcherComponentAc.hpp:833
Svc::CommandDispatcherComponentBase::portNum
PRIVATE NATIVE_INT_TYPE portNum
Definition: CommandDispatcherComponentAc.hpp:1057
Fw::SerializeStatus
SerializeStatus
forward declaration for string
Definition: Serializable.hpp:14
Svc::CommandDispatcherComponentBase::ERR_BUSY
PROTECTED ERR_BUSY
Definition: CommandDispatcherComponentAc.hpp:827
Fw::FW_DESERIALIZE_SIZE_MISMATCH
@ FW_DESERIALIZE_SIZE_MISMATCH
Data was left in in the buffer, but not enough to deserialize.
Definition: Serializable.hpp:20
Fw::CommandResponse
CommandResponse
Definition: CmdResponsePortAc.hpp:24
Fw::CmdStringArg::toChar
const char * toChar(void) const
Definition: CmdString.cpp:34
Svc::CommandDispatcherImpl::pingIn_handler
void pingIn_handler(NATIVE_INT_TYPE portNum, U32 key)
component ping handler
Definition: CommandDispatcherImpl.cpp:229
Svc::CommandDispatcherImpl::DispatchEntry::opcode
U32 opcode
opcode of entry
Definition: CommandDispatcherImpl.hpp:145
Svc::CommandDispatcherImpl::m_entryTable
struct Svc::CommandDispatcherImpl::DispatchEntry m_entryTable[CMD_DISPATCHER_DISPATCH_TABLE_SIZE]
table of dispatch entries
FW_NUM_ARRAY_ELEMENTS
#define FW_NUM_ARRAY_ELEMENTS(a)
number of elements in an array
Definition: BasicTypes.hpp:103
Fw::LogStringArg
Definition: LogString.hpp:11
Fw::COMMAND_BUSY
@ COMMAND_BUSY
Definition: CmdResponsePortAc.hpp:30
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
CmdPacket.hpp
Svc::CommandDispatcherComponentBase::port
PROTECTED I32 port
Definition: CommandDispatcherComponentAc.hpp:852
Svc::CommandDispatcherComponentBase::ERR_TYPE_MISMATCH
@ ERR_TYPE_MISMATCH
Definition: CommandDispatcherComponentAc.hpp:836
Svc::CommandDispatcherImpl::m_numCmdErrors
U32 m_numCmdErrors
number of commands with an error
Definition: CommandDispatcherImpl.hpp:173
Fw::COMMAND_FORMAT_ERROR
@ COMMAND_FORMAT_ERROR
Definition: CmdResponsePortAc.hpp:28
Svc::CommandDispatcherImpl::DispatchEntry::port
NATIVE_INT_TYPE port
which port the entry invokes
Definition: CommandDispatcherImpl.hpp:146
Svc::CommandDispatcherImpl::CommandDispatcherImpl
CommandDispatcherImpl(const char *name)
Command Dispatcher constructor.
Definition: CommandDispatcherImpl.cpp:14
Svc::CommandDispatcherImpl::SequenceTracker::callerPort
NATIVE_INT_TYPE callerPort
port command source port
Definition: CommandDispatcherImpl.hpp:167
Fw::CmdStringArg
Definition: CmdString.hpp:11
Svc::CommandDispatcherComponentBase::ERR_BUFFER_FORMAT
@ ERR_BUFFER_FORMAT
Definition: CommandDispatcherComponentAc.hpp:834
Svc::CommandDispatcherComponentBase::ERR_UNEXP
PROTECTED ERR_UNEXP
Definition: CommandDispatcherComponentAc.hpp:828
Svc::CommandDispatcherImpl::CMD_NO_OP_STRING_cmdHandler
void CMD_NO_OP_STRING_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdStringArg &arg1)
NO_OP with string command handler.
Definition: CommandDispatcherImpl.cpp:209
Svc::CommandDispatcherImpl::response
PROTECTED FwOpcodeType U32 Fw::CommandResponse response
Definition: CommandDispatcherImpl.hpp:67
Svc::CommandDispatcherComponentBase::log_ACTIVITY_HI_TestCmd1Args
void log_ACTIVITY_HI_TestCmd1Args(I32 arg1, F32 arg2, U8 arg3)
Definition: CommandDispatcherComponentAc.cpp:2381
Svc::CommandDispatcherComponentBase::log_WARNING_HI_OpCodeError
void log_WARNING_HI_OpCodeError(U32 Opcode, ErrorResponse error)
Definition: CommandDispatcherComponentAc.cpp:1804
Assert.hpp
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
Svc::CommandDispatcherComponentBase::log_WARNING_HI_InvalidCommand
void log_WARNING_HI_InvalidCommand(U32 Opcode)
Definition: CommandDispatcherComponentAc.cpp:2018
Svc::CommandDispatcherImpl::CMD_NO_OP_cmdHandler
void CMD_NO_OP_cmdHandler(FwOpcodeType opCode, U32 cmdSeq)
NO_OP command handler.
Definition: CommandDispatcherImpl.cpp:202
Fw::ObjBase::init
void init(void)
Object initializer.
Definition: ObjBase.cpp:26
Svc::CommandDispatcherComponentBase::ERR_SIZE_MISMATCH
@ ERR_SIZE_MISMATCH
Definition: CommandDispatcherComponentAc.hpp:835
Svc::CommandDispatcherComponentBase::isConnected_seqCmdStatus_OutputPort
bool isConnected_seqCmdStatus_OutputPort(NATIVE_INT_TYPE portNum)
Definition: CommandDispatcherComponentAc.cpp:902
Svc::CommandDispatcherComponentBase::getNum_seqCmdStatus_OutputPorts
NATIVE_INT_TYPE getNum_seqCmdStatus_OutputPorts(void)
Definition: CommandDispatcherComponentAc.cpp:798
Fw::FW_DESERIALIZE_FORMAT_ERROR
@ FW_DESERIALIZE_FORMAT_ERROR
Deserialization data had incorrect values (unexpected data types)
Definition: Serializable.hpp:19
Fw::COMMAND_EXECUTION_ERROR
@ COMMAND_EXECUTION_ERROR
Definition: CmdResponsePortAc.hpp:29
Svc::CommandDispatcherComponentBase::ErrorResponse
PROTECTED ErrorResponse_MAX ErrorResponse
Definition: CommandDispatcherComponentAc.hpp:830
Svc::CommandDispatcherComponentBase::log_WARNING_HI_TooManyCommands
void log_WARNING_HI_TooManyCommands(U32 Opcode)
Definition: CommandDispatcherComponentAc.cpp:2116
Svc::CommandDispatcherImpl::opCode
PROTECTED FwOpcodeType opCode
Definition: CommandDispatcherImpl.hpp:67
Svc::CommandDispatcherComponentBase::seqCmdStatus_out
void seqCmdStatus_out(NATIVE_INT_TYPE portNum, FwOpcodeType opCode, U32 cmdSeq, Fw::CommandResponse response)
Definition: CommandDispatcherComponentAc.cpp:750
Svc::CommandDispatcherComponentBase::log_ACTIVITY_HI_NoOpReceived
void log_ACTIVITY_HI_NoOpReceived(void)
Definition: CommandDispatcherComponentAc.cpp:2214
F32
float F32
32-bit floating point
Definition: BasicTypes.hpp:94
FwOpcodeType
#define FwOpcodeType
Type representation for a command opcode.
Definition: FpConfig.hpp:62
CommandDispatcherImpl.hpp
Component responsible for dispatching incoming commands to registered components.
Fw::CmdPacket::deserialize
SerializeStatus deserialize(SerializeBufferBase &buffer)
deserialize to contents
Definition: CmdPacket.cpp:29
Fw::CmdPacket::getArgBuffer
CmdArgBuffer & getArgBuffer(void)
Definition: CmdPacket.cpp:59
Svc::CommandDispatcherComponentBase::log_COMMAND_OpCodeCompleted
void log_COMMAND_OpCodeCompleted(U32 Opcode)
Definition: CommandDispatcherComponentAc.cpp:1706
Svc::CommandDispatcherImpl::cmdSeq
PROTECTED FwOpcodeType U32 cmdSeq
Definition: CommandDispatcherImpl.hpp:67
Fw::COMMAND_INVALID_OPCODE
@ COMMAND_INVALID_OPCODE
Definition: CmdResponsePortAc.hpp:26
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Svc::CommandDispatcherImpl::CMD_CLEAR_TRACKING_cmdHandler
void CMD_CLEAR_TRACKING_cmdHandler(FwOpcodeType opCode, U32 cmdSeq)
A command to clear the command tracking.
Definition: CommandDispatcherImpl.cpp:221
Svc::CommandDispatcherComponentBase::log_ACTIVITY_HI_NoOpStringReceived
void log_ACTIVITY_HI_NoOpStringReceived(Fw::LogStringArg &message)
Definition: CommandDispatcherComponentAc.cpp:2293
Svc::CommandDispatcherImpl::m_sequenceTracker
struct Svc::CommandDispatcherImpl::SequenceTracker m_sequenceTracker[CMD_DISPATCHER_SEQUENCER_TABLE_SIZE]
sequence tracking port for command completions;
Svc::CommandDispatcherComponentBase::ERR_EXECUTION_ERROR
PROTECTED ERR_EXECUTION_ERROR
Definition: CommandDispatcherComponentAc.hpp:826
Svc::CommandDispatcherComponentBase::log_COMMAND_OpCodeDispatched
void log_COMMAND_OpCodeDispatched(U32 Opcode, I32 port)
Definition: CommandDispatcherComponentAc.cpp:1590
Svc::CommandDispatcherImpl::m_numCmdsDispatched
U32 m_numCmdsDispatched
number of commands dispatched
Definition: CommandDispatcherImpl.hpp:172
Svc::CommandDispatcherImpl::seqCmdBuff_handler
void seqCmdBuff_handler(NATIVE_INT_TYPE portNum, Fw::ComBuffer &data, U32 context)
component command buffer handler
Definition: CommandDispatcherImpl.cpp:109
Svc::CommandDispatcherImpl::SequenceTracker::used
bool used
if this slot is used
Definition: CommandDispatcherImpl.hpp:163
Svc::CommandDispatcherComponentBase::ERR_VALIDATION_ERROR
PROTECTED ERR_VALIDATION_ERROR
Definition: CommandDispatcherComponentAc.hpp:824
Fw::FW_DESERIALIZE_TYPE_MISMATCH
@ FW_DESERIALIZE_TYPE_MISMATCH
Deserialized type ID didn't match.
Definition: Serializable.hpp:21
Svc::CommandDispatcherImpl::SequenceTracker::opCode
FwOpcodeType opCode
opcode being tracked
Definition: CommandDispatcherImpl.hpp:165
Svc::CommandDispatcherImpl::compCmdReg_handler
void compCmdReg_handler(NATIVE_INT_TYPE portNum, FwOpcodeType opCode)
component command registration handler
Definition: CommandDispatcherImpl.cpp:34
Svc::CommandDispatcherComponentBase::CmdSerError
CmdSerError
Definition: CommandDispatcherComponentAc.hpp:832
Svc
Definition: ActiveLoggerComponentAc.cpp:22
Svc::CommandDispatcherComponentBase::tlmWrite_CommandErrors
void tlmWrite_CommandErrors(U32 arg)
Definition: CommandDispatcherComponentAc.cpp:1393
Svc::CommandDispatcherImpl::DispatchEntry::used
bool used
if entry has been used yet
Definition: CommandDispatcherImpl.hpp:144
Fw::CmdPacket
Definition: CmdPacket.hpp:16
Svc::CommandDispatcherImpl::~CommandDispatcherImpl
virtual ~CommandDispatcherImpl()
Component destructor.
Definition: CommandDispatcherImpl.cpp:24
Fw::CmdPacket::getOpCode
FwOpcodeType getOpCode(void) const
Definition: CmdPacket.cpp:55
Svc::CommandDispatcherComponentBase::compCmdStat_handler
virtual void compCmdStat_handler(NATIVE_INT_TYPE portNum, FwOpcodeType opCode, U32 cmdSeq, Fw::CommandResponse response)=0
Handler for input port compCmdStat.
Fw::COMMAND_OK
@ COMMAND_OK
Definition: CmdResponsePortAc.hpp:25
CMD_DISPATCHER_SEQUENCER_TABLE_SIZE
@ CMD_DISPATCHER_SEQUENCER_TABLE_SIZE
Definition: CommandDispatcherImplCfg.hpp:15
Svc::CommandDispatcherImpl::CMD_TEST_CMD_1_cmdHandler
void CMD_TEST_CMD_1_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, I32 arg1, F32 arg2, U8 arg3)
A test command with different argument types.
Definition: CommandDispatcherImpl.cpp:216
Fw::COMMAND_VALIDATION_ERROR
@ COMMAND_VALIDATION_ERROR
Definition: CmdResponsePortAc.hpp:27
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
Svc::CommandDispatcherComponentBase::slot
PROTECTED I32 I32 slot
Definition: CommandDispatcherComponentAc.hpp:854
Fw::ComBuffer
Definition: ComBuffer.hpp:21
Svc::CommandDispatcherImpl::SequenceTracker::seq
U32 seq
command sequence number
Definition: CommandDispatcherImpl.hpp:164
Svc::CommandDispatcherComponentBase::ERR_FORMAT_ERROR
PROTECTED ERR_FORMAT_ERROR
Definition: CommandDispatcherComponentAc.hpp:825