F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
FileUplink.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title FileUplink.cpp
3 // \author bocchino
4 // \brief cpp file for FileUplink component implementation class
5 //
6 // \copyright
7 // Copyright 2009-2016, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 #include <Fw/Com/ComPacket.hpp>
14 #include <Fw/FPrimeBasicTypes.hpp>
15 #include <Fw/Types/Assert.hpp>
17 
18 namespace Svc {
19 
20 // ----------------------------------------------------------------------
21 // Construction, initialization, and destruction
22 // ----------------------------------------------------------------------
23 
24 FileUplink ::FileUplink(const char* const name)
26  m_receiveMode(START),
27  m_lastSequenceIndex(0),
28  m_lastPacketWriteStatus(Os::File::MAX_STATUS),
29  m_filesReceived(this),
30  m_packetsReceived(this),
31  m_warnings(this) {}
32 
34 
35 // ----------------------------------------------------------------------
36 // Handler implementations for user-defined typed input ports
37 // ----------------------------------------------------------------------
38 
39 void FileUplink ::bufferSendIn_handler(const FwIndexType portNum, Fw::Buffer& buffer) {
40  // If packet is too small to contain a packet type, log + deallocate and return
41  if (buffer.getSize() < sizeof(FwPacketDescriptorType)) {
42  this->log_WARNING_HI_InvalidPacketReceived(Fw::ComPacketType::FW_PACKET_UNKNOWN);
43  this->bufferSendOut_out(0, buffer);
44  return;
45  }
46 
47  // Read the packet type from the packet buffer
48  FwPacketDescriptorType packetType;
49  Fw::SerializeStatus status = buffer.getDeserializer().deserialize(packetType);
50  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
51 
52  // If packet type is not a file packet, log + deallocate and return
53  if (packetType != Fw::ComPacketType::FW_PACKET_FILE) {
54  this->log_WARNING_HI_InvalidPacketReceived(packetType);
55  this->bufferSendOut_out(0, buffer);
56  return;
57  }
58 
59  // Deserialize the file packet contents into Fw::FilePacket (remove packet type token)
60  Fw::Buffer packetBuffer(buffer.getData() + sizeof(packetType),
61  buffer.getSize() - static_cast<Fw::Buffer::SizeType>(sizeof(packetType)));
62  Fw::FilePacket filePacket;
63  status = filePacket.fromBuffer(packetBuffer);
64  if (status != Fw::FW_SERIALIZE_OK) {
65  this->log_WARNING_HI_DecodeError(status);
66  } else {
67  Fw::FilePacket::Type header_type = filePacket.asHeader().getType();
68  switch (header_type) {
70  this->handleStartPacket(filePacket.asStartPacket());
71  break;
73  this->handleDataPacket(filePacket.asDataPacket());
74  break;
76  this->handleEndPacket(filePacket.asEndPacket());
77  break;
79  this->handleCancelPacket();
80  break;
81  default:
82  FW_ASSERT(0);
83  break;
84  }
85  }
86  this->bufferSendOut_out(0, buffer);
87 }
88 
89 void FileUplink ::pingIn_handler(const FwIndexType portNum, U32 key) {
90  // return key
91  this->pingOut_out(0, key);
92 }
93 
94 // ----------------------------------------------------------------------
95 // Private helper functions
96 // ----------------------------------------------------------------------
97 
98 void FileUplink ::handleStartPacket(const Fw::FilePacket::StartPacket& startPacket) {
99  // Clear all event throttles in preparation for new start packet
104  this->m_packetsReceived.packetReceived();
105  if (this->m_receiveMode != START) {
106  this->m_file.osFile.close();
107  this->m_warnings.invalidReceiveMode(Fw::FilePacket::T_START);
108  }
109  const Os::File::Status status = this->m_file.open(startPacket);
110  if (status == Os::File::OP_OK) {
111  this->goToDataMode();
112  } else {
113  this->m_warnings.fileOpen(this->m_file.name);
114  this->goToStartMode();
115  }
116 }
117 
118 void FileUplink ::handleDataPacket(const Fw::FilePacket::DataPacket& dataPacket) {
119  this->m_packetsReceived.packetReceived();
120  if (this->m_receiveMode != DATA) {
121  this->m_warnings.invalidReceiveMode(Fw::FilePacket::T_DATA);
122  return;
123  }
124 
125  const U32 sequenceIndex = dataPacket.asHeader().getSequenceIndex();
126 
127  // skip this packet if it is a duplicate and it has already been written
128  if (this->m_lastPacketWriteStatus == Os::File::OP_OK && this->checkDuplicatedPacket(sequenceIndex)) {
129  return;
130  }
131 
132  this->checkSequenceIndex(sequenceIndex);
133  const U32 byteOffset = dataPacket.getByteOffset();
134  const U32 dataSize = dataPacket.getDataSize();
135  if (byteOffset + dataSize > this->m_file.size) {
136  this->m_warnings.packetOutOfBounds(sequenceIndex, this->m_file.name);
137  return;
138  }
139  const Os::File::Status status = this->m_file.write(dataPacket.getData(), byteOffset, dataSize);
140  if (status != Os::File::OP_OK) {
141  this->m_warnings.fileWrite(this->m_file.name);
142  }
143 
144  this->m_lastPacketWriteStatus = status;
145 }
146 
147 void FileUplink ::handleEndPacket(const Fw::FilePacket::EndPacket& endPacket) {
148  this->m_packetsReceived.packetReceived();
149  if (this->m_receiveMode == DATA) {
150  this->m_filesReceived.fileReceived();
151  this->checkSequenceIndex(endPacket.asHeader().getSequenceIndex());
152  this->compareChecksums(endPacket);
153  this->log_ACTIVITY_HI_FileReceived(this->m_file.name);
154  } else {
155  this->m_warnings.invalidReceiveMode(Fw::FilePacket::T_END);
156  }
157  this->goToStartMode();
158 }
159 
160 void FileUplink ::handleCancelPacket() {
161  this->m_packetsReceived.packetReceived();
163  this->goToStartMode();
164 }
165 
166 void FileUplink ::checkSequenceIndex(const U32 sequenceIndex) {
167  if (sequenceIndex != this->m_lastSequenceIndex + 1) {
168  this->m_warnings.packetOutOfOrder(sequenceIndex, this->m_lastSequenceIndex);
169  }
170  this->m_lastSequenceIndex = sequenceIndex;
171 }
172 
173 bool FileUplink ::checkDuplicatedPacket(const U32 sequenceIndex) {
174  // check for duplicate packet
175  if (sequenceIndex == this->m_lastSequenceIndex) {
176  this->m_warnings.packetDuplicate(sequenceIndex);
177  return true;
178  }
179 
180  return false;
181 }
182 
183 void FileUplink ::compareChecksums(const Fw::FilePacket::EndPacket& endPacket) {
184  CFDP::Checksum computed, stored;
185  this->m_file.getChecksum(computed);
186  endPacket.getChecksum(stored);
187  if (computed != stored) {
188  this->m_warnings.badChecksum(computed.getValue(), stored.getValue());
189  }
190 }
191 
192 void FileUplink ::goToStartMode() {
193  this->m_file.osFile.close();
194  this->m_receiveMode = START;
195  this->m_lastSequenceIndex = 0;
196  this->m_lastPacketWriteStatus = Os::File::MAX_STATUS;
197 }
198 
199 void FileUplink ::goToDataMode() {
200  this->m_receiveMode = DATA;
201  this->m_lastSequenceIndex = 0;
202  this->m_lastPacketWriteStatus = Os::File::MAX_STATUS;
203 }
204 
205 } // namespace Svc
const U8 * getData() const
Get the data.
Definition: FilePacket.hpp:270
Serialization/Deserialization operation was successful.
FwIdType FwPacketDescriptorType
The type of a com packet descriptor.
const FilePacket::Header & asHeader() const
Get this as a Header.
Definition: FilePacket.hpp:255
U32 getByteOffset() const
Get the byte offset.
Definition: FilePacket.hpp:260
const FilePacket::Header & asHeader() const
Get this as a Header.
Definition: FilePacket.hpp:313
The type of a data packet.
Definition: FilePacket.hpp:213
U8 * getData() const
Definition: Buffer.cpp:68
void getChecksum(CFDP::Checksum &checksum) const
Get the checksum.
Definition: EndPacket.cpp:54
Type
Packet type.
Definition: FilePacket.hpp:42
U32 getDataSize() const
Get the data size.
Definition: FilePacket.hpp:265
Maximum value of status.
Definition: File.hpp:46
SerializeStatus
forward declaration for string
ExternalSerializeBufferWithMemberCopy getDeserializer()
Definition: Buffer.cpp:117
Class representing a 32-bit checksum as mandated by the CCSDS File Delivery Protocol.
Definition: Checksum.hpp:53
The type of a start packet.
Definition: FilePacket.hpp:150
U32 getValue() const
Get the checksum value.
Definition: Checksum.cpp:66
SerializeStatus fromBuffer(const Buffer &buffer)
Definition: FilePacket.cpp:23
Operation was successful.
Definition: File.hpp:34
SerializeStatus deserialize(U8 &val)
deserialize 8-bit unsigned int
PlatformIndexType FwIndexType
RateGroupDivider component implementation.
A file packet.
Definition: FilePacket.hpp:33
SizeType getSize() const
Definition: Buffer.cpp:72
U32 getSequenceIndex(void) const
Definition: FilePacket.hpp:143
U32 SizeType
The size type for a buffer.
Definition: Buffer.hpp:52
#define FW_ASSERT(...)
Definition: Assert.hpp:14
The type of an end packet.
Definition: FilePacket.hpp:287