F´ Flight Software - C/C++ Documentation  NASA-v1.5.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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