F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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
17namespace Svc {
18
19 // ----------------------------------------------------------------------
20 // Construction, initialization, and destruction
21 // ----------------------------------------------------------------------
22
23 FileUplink ::
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
36 FileUplink ::
37 ~FileUplink()
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
97 this->log_WARNING_HI_FileWriteError_ThrottleClear();
98 this->log_WARNING_HI_InvalidReceiveMode_ThrottleClear();
99 this->log_WARNING_HI_PacketOutOfBounds_ThrottleClear();
100 this->log_WARNING_HI_PacketOutOfOrder_ThrottleClear();
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();
172 this->log_ACTIVITY_HI_UplinkCanceled();
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.
const FilePacket::Header & asHeader() const
Get this as a Header.
U32 getByteOffset() const
Get the byte offset.
const U8 * getData() const
Get the data.
U32 getDataSize() const
Get the data size.
The type of an end packet.
const FilePacket::Header & asHeader() const
Get this as a Header.
void getChecksum(CFDP::Checksum &checksum) const
Get the checksum.
Definition EndPacket.cpp:54
U32 getSequenceIndex(void) const
Type getType(void) const
@ 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.
A file packet.
SerializeStatus fromBuffer(const Buffer &buffer)
const StartPacket & asStartPacket() const
const EndPacket & asEndPacket() const
Type
Packet type.
const DataPacket & asDataPacket() const
const Header & asHeader() const