F´ Flight Software - C/C++ Documentation  devel
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
14 #include <Fw/Types/Assert.hpp>
15 #include <FpConfig.hpp>
16 
17 namespace Svc {
18 
19  // ----------------------------------------------------------------------
20  // Construction, initialization, and destruction
21  // ----------------------------------------------------------------------
22 
24  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  {
33 
34  }
35 
38  {
39 
40  }
41 
42  // ----------------------------------------------------------------------
43  // Handler implementations for user-defined typed input ports
44  // ----------------------------------------------------------------------
45 
46  void FileUplink ::
47  bufferSendIn_handler(
48  const NATIVE_INT_TYPE portNum,
49  Fw::Buffer& buffer
50  )
51  {
52  Fw::FilePacket filePacket;
53  const Fw::SerializeStatus status = filePacket.fromBuffer(buffer);
54  if (status != Fw::FW_SERIALIZE_OK) {
55  this->log_WARNING_HI_DecodeError(status);
56  } else {
57  Fw::FilePacket::Type header_type = filePacket.asHeader().getType();
58  switch (header_type) {
60  this->handleStartPacket(filePacket.asStartPacket());
61  break;
63  this->handleDataPacket(filePacket.asDataPacket());
64  break;
66  this->handleEndPacket(filePacket.asEndPacket());
67  break;
69  this->handleCancelPacket();
70  break;
71  default:
72  FW_ASSERT(0);
73  break;
74  }
75  }
76  this->bufferSendOut_out(0, buffer);
77  }
78 
79  void FileUplink ::
80  pingIn_handler(
81  const NATIVE_INT_TYPE portNum,
82  U32 key
83  )
84  {
85  // return key
86  this->pingOut_out(0,key);
87  }
88 
89  // ----------------------------------------------------------------------
90  // Private helper functions
91  // ----------------------------------------------------------------------
92 
93  void FileUplink ::
94  handleStartPacket(const Fw::FilePacket::StartPacket& startPacket)
95  {
96  // Clear all event throttles in preparation for new start packet
101  this->m_packetsReceived.packetReceived();
102  if (this->m_receiveMode != START) {
103  this->m_file.osFile.close();
104  this->m_warnings.invalidReceiveMode(Fw::FilePacket::T_START);
105  }
106  const Os::File::Status status = this->m_file.open(startPacket);
107  if (status == Os::File::OP_OK) {
108  this->goToDataMode();
109  }
110  else {
111  this->m_warnings.fileOpen(this->m_file.name);
112  this->goToStartMode();
113  }
114  }
115 
116  void FileUplink ::
117  handleDataPacket(const Fw::FilePacket::DataPacket& dataPacket)
118  {
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 &&
129  this->checkDuplicatedPacket(sequenceIndex)) {
130  return;
131  }
132 
133  this->checkSequenceIndex(sequenceIndex);
134  const U32 byteOffset = dataPacket.getByteOffset();
135  const U32 dataSize = dataPacket.getDataSize();
136  if (byteOffset + dataSize > this->m_file.size) {
137  this->m_warnings.packetOutOfBounds(sequenceIndex, this->m_file.name);
138  return;
139  }
140  const Os::File::Status status = this->m_file.write(
141  dataPacket.getData(),
142  byteOffset,
143  dataSize
144  );
145  if (status != Os::File::OP_OK) {
146  this->m_warnings.fileWrite(this->m_file.name);
147  }
148 
149  this->m_lastPacketWriteStatus = status;
150  }
151 
152  void FileUplink ::
153  handleEndPacket(const Fw::FilePacket::EndPacket& endPacket)
154  {
155  this->m_packetsReceived.packetReceived();
156  if (this->m_receiveMode == DATA) {
157  this->m_filesReceived.fileReceived();
158  this->checkSequenceIndex(endPacket.asHeader().getSequenceIndex());
159  this->compareChecksums(endPacket);
160  this->log_ACTIVITY_HI_FileReceived(this->m_file.name);
161  }
162  else {
163  this->m_warnings.invalidReceiveMode(Fw::FilePacket::T_END);
164  }
165  this->goToStartMode();
166  }
167 
168  void FileUplink ::
169  handleCancelPacket()
170  {
171  this->m_packetsReceived.packetReceived();
173  this->goToStartMode();
174  }
175 
176  void FileUplink ::
177  checkSequenceIndex(const U32 sequenceIndex)
178  {
179  if (sequenceIndex != this->m_lastSequenceIndex + 1) {
180  this->m_warnings.packetOutOfOrder(
181  sequenceIndex,
182  this->m_lastSequenceIndex
183  );
184  }
185  this->m_lastSequenceIndex = sequenceIndex;
186  }
187 
188  bool FileUplink ::
189  checkDuplicatedPacket(const U32 sequenceIndex)
190  {
191  // check for duplicate packet
192  if (sequenceIndex == this->m_lastSequenceIndex) {
193  this->m_warnings.packetDuplicate(sequenceIndex);
194  return true;
195  }
196 
197  return false;
198  }
199 
200  void FileUplink ::
201  compareChecksums(const Fw::FilePacket::EndPacket& endPacket)
202  {
203  CFDP::Checksum computed, stored;
204  this->m_file.getChecksum(computed);
205  endPacket.getChecksum(stored);
206  if (computed != stored) {
207  this->m_warnings.badChecksum(
208  computed.getValue(),
209  stored.getValue()
210  );
211  }
212  }
213 
214  void FileUplink ::
215  goToStartMode()
216  {
217  this->m_file.osFile.close();
218  this->m_receiveMode = START;
219  this->m_lastSequenceIndex = 0;
220  this->m_lastPacketWriteStatus = Os::File::MAX_STATUS;
221  }
222 
223  void FileUplink ::
224  goToDataMode()
225  {
226  this->m_receiveMode = DATA;
227  this->m_lastSequenceIndex = 0;
228  this->m_lastPacketWriteStatus = Os::File::MAX_STATUS;
229  }
230 
231 }
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition: BasicTypes.h:55
C++-compatible configuration header for fprime configuration.
Class representing a 32-bit checksum as mandated by the CCSDS File Delivery Protocol.
Definition: Checksum.hpp:53
U32 getValue() const
Get the checksum value.
Definition: Checksum.cpp:66
The type of a data packet.
Definition: FilePacket.hpp:197
const FilePacket::Header & asHeader() const
Get this as a Header.
Definition: FilePacket.hpp:237
U32 getByteOffset() const
Get the byte offset.
Definition: FilePacket.hpp:242
const U8 * getData() const
Get the data.
Definition: FilePacket.hpp:252
U32 getDataSize() const
Get the data size.
Definition: FilePacket.hpp:247
The type of an end packet.
Definition: FilePacket.hpp:269
void getChecksum(CFDP::Checksum &checksum) const
Get the checksum.
Definition: EndPacket.cpp:54
const FilePacket::Header & asHeader() const
Get this as a Header.
Definition: FilePacket.hpp:293
U32 getSequenceIndex(void) const
Definition: FilePacket.hpp:132
Type getType(void) const
Definition: FilePacket.hpp:128
@ MAX_STATUS
Maximum value of status.
Definition: File.hpp:41
@ OP_OK
Operation was successful.
Definition: File.hpp:30
SerializeStatus
forward declaration for string
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
The type of a start packet.
Definition: FilePacket.hpp:139
A file packet.
Definition: FilePacket.hpp:27
SerializeStatus fromBuffer(const Buffer &buffer)
Definition: FilePacket.cpp:23
const StartPacket & asStartPacket() const
Definition: FilePacket.cpp:41
const EndPacket & asEndPacket() const
Definition: FilePacket.cpp:55
Type
Packet type.
Definition: FilePacket.hpp:36
const DataPacket & asDataPacket() const
Definition: FilePacket.cpp:48
const Header & asHeader() const
Definition: FilePacket.cpp:35