F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
GenericHub.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title GenericHub.cpp
3 // \author mstarch
4 // \brief cpp file for GenericHub component implementation class
5 //
6 // \copyright
7 // Copyright 2009-2015, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 #include <Fw/FPrimeBasicTypes.hpp>
15 #include "Fw/Logger/Logger.hpp"
16 #include "Fw/Types/Assert.hpp"
17 
18 // Required port serialization or the hub cannot work
19 static_assert(FW_PORT_SERIALIZATION, "FW_PORT_SERIALIZATION must be enabled to use GenericHub");
20 
21 namespace Svc {
22 
23 // ----------------------------------------------------------------------
24 // Construction, initialization, and destruction
25 // ----------------------------------------------------------------------
26 
27 GenericHub::GenericHub(const char* const compName) : GenericHubComponentBase(compName) {}
28 
30 
31 void GenericHub::send_data(const HubType type, const FwIndexType port, const U8* data, const FwSizeType size) {
32  FW_ASSERT(data != nullptr);
33  Fw::SerializeStatus status;
34  // Buffer to send and a buffer used to write to it
35  Fw::Buffer outgoing = allocate_out(0, static_cast<U32>(size + sizeof(U32) + sizeof(U32) + sizeof(FwBuffSizeType)));
36  auto serialize = outgoing.getSerializer();
37  // Write data to our buffer
38  status = serialize.serializeFrom(static_cast<U32>(type));
39  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
40  status = serialize.serializeFrom(static_cast<U32>(port));
41  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
42  status = serialize.serializeFrom(data, static_cast<FwBuffSizeType>(size));
43  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
44  outgoing.setSize(serialize.getSize());
45  toBufferDriver_out(0, outgoing);
46 }
47 
48 // ----------------------------------------------------------------------
49 // Handler implementations for user-defined typed input ports
50 // ----------------------------------------------------------------------
51 
52 void GenericHub::bufferIn_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) {
53  this->send_data(HUB_TYPE_BUFFER, portNum, fwBuffer.getData(), fwBuffer.getSize());
54  bufferInReturn_out(portNum, fwBuffer);
55 }
56 
57 void GenericHub::bufferOutReturn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
58  // Return the buffer
59  fromBufferDriverReturn_out(0, fwBuffer);
60 }
61 
62 void GenericHub ::cmdDispIn_handler(FwIndexType portNum, Fw::ComBuffer& data, U32 context) {
63  Fw::SerializeStatus status;
64  // Buffer to send and a buffer used to write to it
66 
67  Fw::ExternalSerializeBuffer serializer(buffer, sizeof(buffer));
68  serializer.resetSer();
69 
70  status = serializer.serializeFrom(data.getBuffAddr(), data.getSize(), Fw::Serialization::OMIT_LENGTH);
71  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
72  status = serializer.serializeFrom(context);
73  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
74  FwSizeType size = serializer.getSize();
75 
76  this->send_data(HUB_TYPE_CMD_DISP, portNum, buffer, size);
77 }
78 
79 void GenericHub ::cmdRespIn_handler(FwIndexType portNum,
80  FwOpcodeType opCode,
81  U32 cmdSeq,
82  const Fw::CmdResponse& response) {
84  U8 buffer[sizeof(opCode) + sizeof(cmdSeq) + Fw::CmdResponse::SERIALIZED_SIZE];
85  Fw::ExternalSerializeBuffer serializer(buffer, sizeof(buffer));
86  serializer.resetSer();
87 
88  status = serializer.serializeFrom(opCode);
90  status = serializer.serializeFrom(cmdSeq);
92  status = serializer.serializeFrom(response);
94  FwSizeType size = serializer.getSize();
95 
96  this->send_data(HUB_TYPE_CMD_RESP, portNum, buffer, size);
97 }
98 
99 void GenericHub::fromBufferDriver_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) {
100  HubType type = HUB_TYPE_MAX;
101  U32 type_in = 0;
102  U32 port = 0;
103  FwBuffSizeType size = 0;
105 
106  // Representation of incoming data prepped for serialization
107  auto incoming = fwBuffer.getDeserializer();
108  // Check the size of the data first
109  if (fwBuffer.getSize() < (sizeof(U32) + sizeof(U32) + sizeof(FwBuffSizeType))) {
111  } else {
112  status = incoming.deserializeTo(type_in);
113  }
114  // If the deserialization was good, but the type is invalid, set invalid data
115  if ((status == Fw::FW_SERIALIZE_OK) && (type_in >= HUB_TYPE_MAX)) {
117  }
118  // If the deserialization was good and the type was valid, set the type and move onto port deserialization
119  else if (status == Fw::FW_SERIALIZE_OK) {
120  type = static_cast<HubType>(type_in);
121  status = incoming.deserializeTo(port);
122  }
123  // If the deserialization was good, move onto size deserialization
124  if (status == Fw::FW_SERIALIZE_OK) {
125  status = incoming.deserializeTo(size);
126  }
127  // All deserialization looks good, check that the size matches the buffer size before calling the appropriate ports
128  if (status == Fw::FW_SERIALIZE_OK &&
129  (size == (fwBuffer.getSize() - sizeof(U32) - sizeof(U32) - sizeof(FwBuffSizeType)))) {
130  // invokeSerial deserializes arguments before calling a normal invoke, this will return ownership immediately
131  U8* rawData = fwBuffer.getData() + sizeof(U32) + sizeof(U32) + sizeof(FwBuffSizeType);
132  FwSizeType rawSize = fwBuffer.getSize() - sizeof(U32) - sizeof(U32) - sizeof(FwBuffSizeType);
133  if (type == HUB_TYPE_PORT) {
134  // Com buffer representations should be copied before the call returns, so we need not "allocate" new data
135  Fw::ExternalSerializeBuffer wrapper(rawData, rawSize);
136  status = wrapper.setBuffLen(rawSize);
137  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
138  // Confirm that the port is valid and connected before calling out
139  if (port < this->getNum_serialOut_OutputPorts() &&
140  this->isConnected_serialOut_OutputPort(static_cast<FwIndexType>(port))) {
141  serialOut_out(static_cast<FwIndexType>(port), wrapper);
142  }
143  // Deallocate the existing buffer
144  fromBufferDriverReturn_out(0, fwBuffer);
145  } else if (type == HUB_TYPE_BUFFER) {
146  // Fw::Buffers can reuse the existing data buffer as the storage type! No deallocation done.
147  fwBuffer.set(rawData, rawSize, fwBuffer.getContext());
148  // Confirm that the port is valid and connected before calling out
149  if (port < this->getNum_bufferOut_OutputPorts() &&
150  this->isConnected_bufferOut_OutputPort(static_cast<FwIndexType>(port))) {
151  bufferOut_out(static_cast<FwIndexType>(port), fwBuffer);
152  } else {
153  // Return the buffer if the port is invalid or not connected to avoid leaks
154  fromBufferDriverReturn_out(0, fwBuffer);
155  }
156  } else if (type == HUB_TYPE_EVENT) {
157  FwEventIdType id;
158  Fw::Time timeTag;
159  Fw::LogSeverity severity;
160  Fw::LogBuffer args;
161 
162  // Deserialize tokens for events
163  status = incoming.deserializeTo(id);
164  if (status == Fw::FW_SERIALIZE_OK) {
165  status = incoming.deserializeTo(timeTag);
166  }
167  if (status == Fw::FW_SERIALIZE_OK) {
168  status = incoming.deserializeTo(severity);
169  }
170  if (status == Fw::FW_SERIALIZE_OK) {
171  status = incoming.deserializeTo(args);
172  }
173 
174  // Send it!
175  if ((status == Fw::FW_SERIALIZE_OK) && (port < this->getNum_eventOut_OutputPorts()) &&
176  this->isConnected_eventOut_OutputPort(static_cast<FwIndexType>(port))) {
177  this->eventOut_out(static_cast<FwIndexType>(port), id, timeTag, severity, args);
178  }
179  // Deallocate the existing buffer
180  fromBufferDriverReturn_out(0, fwBuffer);
181  } else if (type == HUB_TYPE_CHANNEL) {
182  FwChanIdType id;
183  Fw::Time timeTag;
184  Fw::TlmBuffer val;
185 
186  // Deserialize tokens for channels
187  status = incoming.deserializeTo(id);
188  if (status == Fw::FW_SERIALIZE_OK) {
189  status = incoming.deserializeTo(timeTag);
190  }
191  if (status == Fw::FW_SERIALIZE_OK) {
192  status = incoming.deserializeTo(val);
193  }
194  if ((status == Fw::FW_SERIALIZE_OK) && (port < this->getNum_tlmOut_OutputPorts()) &&
195  this->isConnected_tlmOut_OutputPort(static_cast<FwIndexType>(port))) {
196  // Send it!
197  this->tlmOut_out(static_cast<FwIndexType>(port), id, timeTag, val);
198  }
199 
200  // Return the received buffer
201  fromBufferDriverReturn_out(0, fwBuffer);
202  } else if (type == HUB_TYPE_CMD_DISP) {
203  U32 context;
204  // Check that the size is sufficient for the context
205  if (rawSize < sizeof(U32) || (rawSize - sizeof(U32)) > Fw::ComBuffer::SERIALIZED_SIZE) {
207  }
208  // Shift the command buffer out and deserialize the context
209  if (status == Fw::FW_SERIALIZE_OK) {
210  Fw::ComBuffer wrapper(rawData, (rawSize - sizeof(U32)));
211  status = wrapper.setBuffLen(rawSize - sizeof(U32));
212  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
213  // Skip the command buffer that has already been wrapped
214  status = incoming.deserializeSkip(rawSize - sizeof(U32));
215  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
216  status = incoming.deserializeTo(context);
217  // Send it!
218  if ((status == Fw::FW_SERIALIZE_OK) && (port < this->getNum_cmdDispOut_OutputPorts()) &&
219  this->isConnected_cmdDispOut_OutputPort(static_cast<FwIndexType>(port))) {
220  this->cmdDispOut_out(static_cast<FwIndexType>(port), wrapper, context);
221  }
222  }
223  // Deallocate the existing buffer
224  fromBufferDriverReturn_out(0, fwBuffer);
225  } else if (type == HUB_TYPE_CMD_RESP) {
226  FwOpcodeType opCode;
227  U32 cmdSeq;
228  Fw::CmdResponse response;
229 
230  // Deserialize tokens for channels
231  status = incoming.deserializeTo(opCode);
232  if (status == Fw::FW_SERIALIZE_OK) {
233  status = incoming.deserializeTo(cmdSeq);
234  }
235  if (status == Fw::FW_SERIALIZE_OK) {
236  status = incoming.deserializeTo(response);
237  }
238  // Send it!
239  if ((status == Fw::FW_SERIALIZE_OK) && (port < this->getNum_cmdRespOut_OutputPorts()) &&
240  this->isConnected_cmdRespOut_OutputPort(static_cast<FwIndexType>(port))) {
241  this->cmdRespOut_out(static_cast<FwIndexType>(port), opCode, cmdSeq, response);
242  }
243  // Return the received buffer
244  fromBufferDriverReturn_out(0, fwBuffer);
245  }
246  } else {
247  // On deserialization failure, return the buffer to avoid leaks
248  fromBufferDriverReturn_out(0, fwBuffer);
249  }
250 }
251 
252 void GenericHub::toBufferDriverReturn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
253  // Deallocate the existing buffer
254  deallocate_out(portNum, fwBuffer);
255 }
256 
257 void GenericHub::eventIn_handler(const FwIndexType portNum,
258  FwEventIdType id,
259  Fw::Time& timeTag,
260  const Fw::LogSeverity& severity,
261  Fw::LogBuffer& args) {
265  Fw::ExternalSerializeBuffer serializer(buffer, sizeof(buffer));
266  serializer.resetSer();
267  status = serializer.serializeFrom(id);
269  status = serializer.serializeFrom(timeTag);
271  status = serializer.serializeFrom(severity);
273  status = serializer.serializeFrom(args);
275  FwSizeType size = serializer.getSize();
276  this->send_data(HubType::HUB_TYPE_EVENT, portNum, buffer, size);
277 }
278 
279 void GenericHub::tlmIn_handler(const FwIndexType portNum, FwChanIdType id, Fw::Time& timeTag, Fw::TlmBuffer& val) {
282  Fw::ExternalSerializeBuffer serializer(buffer, sizeof(buffer));
283  serializer.resetSer();
284  status = serializer.serializeFrom(id);
286  status = serializer.serializeFrom(timeTag);
288  status = serializer.serializeFrom(val);
290  FwSizeType size = serializer.getSize();
291  this->send_data(HubType::HUB_TYPE_CHANNEL, portNum, buffer, size);
292 }
293 
294 // ----------------------------------------------------------------------
295 // Handler implementations for user-defined serial input ports
296 // ----------------------------------------------------------------------
297 
298 void GenericHub::serialIn_handler(FwIndexType portNum,
299  Fw::SerializeBufferBase& Buffer
300 ) {
301  send_data(HUB_TYPE_PORT, portNum, Buffer.getBuffAddr(), Buffer.getSize());
302 }
303 
304 } // end namespace Svc
Serialization/Deserialization operation was successful.
FwIdType FwOpcodeType
The type of a command opcode.
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
void set(U8 *data, FwSizeType size, U32 context=NO_CONTEXT)
Definition: Buffer.cpp:86
PlatformSizeType FwSizeType
void setSize(FwSizeType size)
Definition: Buffer.cpp:75
Serializable::SizeType getSize() const override
Get current buffer size.
The size of the serial representation.
Command response type.
Definition: GenericHub.hpp:33
U32 getContext() const
Definition: Buffer.cpp:64
virtual U8 * getBuffAddr()=0
Get buffer address for data filling (non-const version)
U8 * getData() const
Definition: Buffer.cpp:56
FwSizeStoreType FwBuffSizeType
Enum representing a command response.
SerializeStatus
forward declaration for string
ExternalSerializeBufferWithMemberCopy getDeserializer()
Definition: Buffer.cpp:105
FwIdType FwEventIdType
The type of an event identifier.
Data failed validation.
Buffer type transmission.
Definition: GenericHub.hpp:29
Omit length from serialization.
Data was left in the buffer, but not enough to deserialize.
External serialize buffer with no copy semantics.
FwIdType FwChanIdType
The type of a telemetry channel identifier.
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
Definition: ComBuffer.cpp:42
Enum representing event severity.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
FwSizeType getSize() const
Definition: Buffer.cpp:60
The size of the serial representation.
PlatformIndexType FwIndexType
Telemetry channel type.
Definition: GenericHub.hpp:31
Port type transmission.
Definition: GenericHub.hpp:28
RateGroupDivider component implementation.
Command dispatch type.
Definition: GenericHub.hpp:32
SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG) override
Deserialize an 8-bit unsigned integer value.
GenericHub(const char *const compName)
Definition: GenericHub.cpp:27
Event transmission.
Definition: GenericHub.hpp:30
ExternalSerializeBufferWithMemberCopy getSerializer()
Definition: Buffer.cpp:95
#define FW_ASSERT(...)
Definition: Assert.hpp:14
#define FW_PORT_SERIALIZATION
calls for multi-note systems)
Definition: FpConfig.h:82