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, size);
43  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
44  outgoing.setSize(static_cast<U32>(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  status = incoming.deserializeTo(type_in);
109  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
110  type = static_cast<HubType>(type_in);
111  FW_ASSERT(type < HUB_TYPE_MAX, type);
112  status = incoming.deserializeTo(port);
113  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
114  status = incoming.deserializeTo(size);
115  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
116 
117  // invokeSerial deserializes arguments before calling a normal invoke, this will return ownership immediately
118  U8* rawData = fwBuffer.getData() + sizeof(U32) + sizeof(U32) + sizeof(FwBuffSizeType);
119  U32 rawSize = static_cast<U32>(fwBuffer.getSize() - sizeof(U32) - sizeof(U32) - sizeof(FwBuffSizeType));
120  FW_ASSERT(rawSize == static_cast<U32>(size));
121  if (type == HUB_TYPE_PORT) {
122  // Com buffer representations should be copied before the call returns, so we need not "allocate" new data
123  Fw::ExternalSerializeBuffer wrapper(rawData, rawSize);
124  status = wrapper.setBuffLen(rawSize);
125  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
126  serialOut_out(static_cast<FwIndexType>(port), wrapper);
127  // Deallocate the existing buffer
128  fromBufferDriverReturn_out(0, fwBuffer);
129  } else if (type == HUB_TYPE_BUFFER) {
130  // Fw::Buffers can reuse the existing data buffer as the storage type! No deallocation done.
131  fwBuffer.set(rawData, rawSize, fwBuffer.getContext());
132  bufferOut_out(static_cast<FwIndexType>(port), fwBuffer);
133  } else if (type == HUB_TYPE_EVENT) {
134  FwEventIdType id;
135  Fw::Time timeTag;
136  Fw::LogSeverity severity;
137  Fw::LogBuffer args;
138 
139  // Deserialize tokens for events
140  status = incoming.deserializeTo(id);
141  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
142  status = incoming.deserializeTo(timeTag);
143  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
144  status = incoming.deserializeTo(severity);
145  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
146  status = incoming.deserializeTo(args);
147  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
148 
149  // Send it!
150  this->eventOut_out(static_cast<FwIndexType>(port), id, timeTag, severity, args);
151 
152  // Deallocate the existing buffer
153  fromBufferDriverReturn_out(0, fwBuffer);
154  } else if (type == HUB_TYPE_CHANNEL) {
155  FwChanIdType id;
156  Fw::Time timeTag;
157  Fw::TlmBuffer val;
158 
159  // Deserialize tokens for channels
160  status = incoming.deserializeTo(id);
161  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
162  status = incoming.deserializeTo(timeTag);
163  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
164  status = incoming.deserializeTo(val);
165  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
166 
167  // Send it!
168  this->tlmOut_out(static_cast<FwIndexType>(port), id, timeTag, val);
169 
170  // Return the received buffer
171  fromBufferDriverReturn_out(0, fwBuffer);
172  } else if (type == HUB_TYPE_CMD_DISP) {
173  U32 context;
174 
175  // Com buffer representations should be copied before the call returns, so we need not "allocate" new data
176  Fw::ComBuffer wrapper(rawData, (rawSize - sizeof(U32)));
177  status = wrapper.setBuffLen(rawSize - sizeof(U32));
178  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
179 
180  incoming.deserializeSkip(rawSize - sizeof(U32));
181  status = incoming.deserializeTo(context);
182  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
183 
184  this->cmdDispOut_out(static_cast<FwIndexType>(port), wrapper, context);
185 
186  // Deallocate the existing buffer
187  fromBufferDriverReturn_out(0, fwBuffer);
188  } else if (type == HUB_TYPE_CMD_RESP) {
189  FwOpcodeType opCode;
190  U32 cmdSeq;
191  Fw::CmdResponse response;
192 
193  // Deserialize tokens for channels
194  status = incoming.deserializeTo(opCode);
195  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
196  status = incoming.deserializeTo(cmdSeq);
197  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
198  status = incoming.deserializeTo(response);
199  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(status));
200 
201  // Send it!
202  this->cmdRespOut_out(static_cast<FwIndexType>(port), opCode, cmdSeq, response);
203 
204  // Return the received buffer
205  fromBufferDriverReturn_out(0, fwBuffer);
206  }
207 }
208 
209 void GenericHub::toBufferDriverReturn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
210  // Deallocate the existing buffer
211  deallocate_out(portNum, fwBuffer);
212 }
213 
214 void GenericHub::eventIn_handler(const FwIndexType portNum,
215  FwEventIdType id,
216  Fw::Time& timeTag,
217  const Fw::LogSeverity& severity,
218  Fw::LogBuffer& args) {
222  Fw::ExternalSerializeBuffer serializer(buffer, sizeof(buffer));
223  serializer.resetSer();
224  status = serializer.serializeFrom(id);
226  status = serializer.serializeFrom(timeTag);
228  status = serializer.serializeFrom(severity);
230  status = serializer.serializeFrom(args);
232  FwSizeType size = serializer.getSize();
233  this->send_data(HubType::HUB_TYPE_EVENT, portNum, buffer, size);
234 }
235 
236 void GenericHub::tlmIn_handler(const FwIndexType portNum, FwChanIdType id, Fw::Time& timeTag, Fw::TlmBuffer& val) {
239  Fw::ExternalSerializeBuffer serializer(buffer, sizeof(buffer));
240  serializer.resetSer();
241  status = serializer.serializeFrom(id);
243  status = serializer.serializeFrom(timeTag);
245  status = serializer.serializeFrom(val);
247  FwSizeType size = serializer.getSize();
248  this->send_data(HubType::HUB_TYPE_CHANNEL, portNum, buffer, size);
249 }
250 
251 // ----------------------------------------------------------------------
252 // Handler implementations for user-defined serial input ports
253 // ----------------------------------------------------------------------
254 
255 void GenericHub::serialIn_handler(FwIndexType portNum,
256  Fw::SerializeBufferBase& Buffer
257 ) {
258  send_data(HUB_TYPE_PORT, portNum, Buffer.getBuffAddr(), Buffer.getSize());
259 }
260 
261 } // 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
The size of the serial representation.
Serializable::SizeType getSize() const override
Get current buffer size.
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.
Buffer type transmission.
Definition: GenericHub.hpp:29
Omit length from serialization.
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.
The size of the serial representation.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
FwSizeType getSize() const
Definition: Buffer.cpp:60
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