GCC Code Coverage Report


Directory: ./
File: Svc/FileDownlink/FileDownlink.hpp
Date: 2026-09-03 22:12:29
Exec Total Coverage
Lines: 10 33 30.3%
Functions: 6 16 37.5%
Branches: 3 9 33.3%

Line Branch Exec Source
1 // ======================================================================
2 // \title FileDownlink.hpp
3 // \author bocchino, mstarch
4 // \brief hpp file for FileDownlink 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 #ifndef Svc_FileDownlink_HPP
13 #define Svc_FileDownlink_HPP
14
15 #include <Fw/FilePacket/FilePacket.hpp>
16 #include <Fw/Types/FileNameString.hpp>
17 #include <Os/File.hpp>
18 #include <Os/Mutex.hpp>
19 #include <Os/Queue.hpp>
20 #include <Os/SandboxedFile.hpp>
21 #include <Svc/FileDownlink/FileDownlinkComponentAc.hpp>
22 #include <config/FileDownlinkCfg.hpp>
23
24 namespace Svc {
25
26 class FileDownlink final : public FileDownlinkComponentBase {
27 friend class FileDownlinkTester;
28
29 private:
30 // ----------------------------------------------------------------------
31 // Types
32 // ----------------------------------------------------------------------
33
34 //! The Mode class
35 class Mode {
36 friend class FileDownlinkTester;
37
38 public:
39 //! The Mode type
40 typedef enum { IDLE, DOWNLINK, CANCEL, WAIT, COOLDOWN } Type;
41
42 public:
43 //! Constructor
44 1 Mode() : m_value(IDLE) {}
45
46 public:
47 //! Set the Mode value
48 void set(const Type value) {
49 this->m_mutex.lock();
50 this->m_value = value;
51 this->m_mutex.unLock();
52 }
53
54 //! Get the Mode value
55 235 Type get() const {
56 235 this->m_mutex.lock();
57 235 const Type value = this->m_value;
58 235 this->m_mutex.unLock();
59 235 return value;
60 }
61
62 private:
63 //! The Mode value
64 Type m_value;
65
66 //! The Mode mutex
67 mutable Os::Mutex m_mutex;
68 };
69
70 //! Class representing an outgoing file
71 class File {
72 friend class FileDownlinkTester;
73
74 public:
75 //! Constructor
76
3/3
✓ Branch 2 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
1 File() : m_size(0) {}
77
78 private:
79 //! The source file name
80 Fw::LogStringArg m_sourceName;
81
82 //! The destination file name
83 Fw::LogStringArg m_destName;
84
85 //! The underlying OS file (sandboxed to restrict read locations)
86 Os::SandboxedFile m_osFile;
87
88 //! The file size
89 U32 m_size;
90
91 //! The checksum for the file
92 CFDP::Checksum m_checksum;
93
94 public:
95 //! Open the OS file for reading and initialize the checksum
96 Os::File::Status open(const Fw::FileNameString& sourceFileName, //!< The source file name
97 const Fw::FileNameString& destFileName //!< The destination file name
98 );
99
100 //! Read bytes from the OS file and update the checksum
101 Os::File::Status read(U8* const data, const U32 byteOffset, const U32 size);
102
103 //! Get the checksum
104 void getChecksum(CFDP::Checksum& checksum) { checksum = this->m_checksum; }
105
106 //! Get the source file name
107 Fw::LogStringArg& getSourceName(void) { return this->m_sourceName; }
108
109 //! Get the destination file name
110 Fw::LogStringArg& getDestName(void) { return this->m_destName; }
111
112 //! Configure the allowed read directory for sandboxed file opens
113 void configureSandbox(const char* directory) { this->m_osFile.configure(directory); }
114
115 //! Get the underlying OS file
116 Os::SandboxedFile& getOsFile(void) { return this->m_osFile; }
117
118 //! Get the file size
119 U32 getSize(void) { return this->m_size; }
120 };
121
122 //! Class to record files sent
123 class FilesSent {
124 friend class FileDownlinkTester;
125
126 public:
127 //! Construct a FilesSent object
128 1 FilesSent(FileDownlink* const fileDownlink) : m_sent_file_count(0), m_fileDownlink(fileDownlink) {}
129
130 public:
131 //! Record a file sent
132 void fileSent() {
133 ++this->m_sent_file_count;
134 this->m_fileDownlink->tlmWrite_FilesSent(m_sent_file_count);
135 }
136
137 private:
138 //! The total number of file sent
139 U32 m_sent_file_count;
140
141 //! The enclosing FileDownlink object
142 FileDownlink* const m_fileDownlink;
143 };
144
145 //! Class to record packets sent
146 class PacketsSent {
147 friend class FileDownlinkTester;
148
149 public:
150 //! Construct a PacketsSent object
151 1 PacketsSent(FileDownlink* const fileDownlink) : m_sent_packet_count(0), m_fileDownlink(fileDownlink) {}
152
153 public:
154 //! Record a packet sent
155 void packetSent() {
156 ++this->m_sent_packet_count;
157 this->m_fileDownlink->tlmWrite_PacketsSent(m_sent_packet_count);
158 }
159
160 private:
161 //! The total number of downlinked packets
162 U32 m_sent_packet_count;
163
164 //! The enclosing FileDownlink object
165 FileDownlink* const m_fileDownlink;
166 };
167
168 //! Class to record warnings
169 class Warnings {
170 friend class FileDownlinkTester;
171
172 public:
173 //! Construct a Warnings object
174 1 Warnings(FileDownlink* const fileDownlink) : m_warning_count(0), m_fileDownlink(fileDownlink) {}
175
176 public:
177 //! Issue a File Open Error warning
178 void fileOpenError();
179
180 //! Issue a File Read Error warning
181 void fileRead(const Os::File::Status status);
182
183 //! Issue a Zero-Size File warning
184 void zeroSize();
185
186 //! Issue a Source Out Of Sandbox warning
187 void sourceOutOfSandbox();
188
189 private:
190 //! Record a warning
191 void warning() {
192 ++this->m_warning_count;
193 this->m_fileDownlink->tlmWrite_Warnings(m_warning_count);
194 }
195
196 private:
197 //! The total number of warnings
198 U32 m_warning_count;
199
200 //! The enclosing FileDownlink object
201 FileDownlink* const m_fileDownlink;
202 };
203
204 //! Sources of send file requests
205 enum CallerSource { COMMAND, PORT };
206
207 //! Used to track a single file downlink request
208 struct FileEntry {
209 Fw::FileNameString srcFilename; // Name of requested file
210 Fw::FileNameString destFilename; // Name of requested file
211 U32 offset;
212 U32 length;
213 CallerSource source; // Source of the downlink request
214 FwOpcodeType opCode; // Op code of command, only set for CMD sources.
215 U32 cmdSeq; // CmdSeq number, only set for CMD sources.
216 U32 context; // Context id of request, only set for PORT sources.
217 };
218
219 //! Enumeration for packet types
220 //! Each type has a buffer to store it.
221 enum PacketType { FILE_PACKET, CANCEL_PACKET, COUNT_PACKET_TYPE };
222
223 public:
224 // ----------------------------------------------------------------------
225 // Construction, initialization, and destruction
226 // ----------------------------------------------------------------------
227
228 //! Construct object FileDownlink
229 //!
230 FileDownlink(const char* const compName //!< The component name
231 );
232
233 //! Configure FileDownlink component
234 //!
235 void configure(U32 cooldown, //!< Cooldown (in ms) between finishing a downlink and starting the next file.
236 U32 cycleTime, //!< Rate at which we are running
237 U32 fileQueueDepth //!< Max number of items in file downlink queue
238 );
239
240 //! Restrict SendFile / SendPartial reads to paths under the configured directory.
241 //! Fail-open: until called, the sandbox defaults to `/` (any readable path is allowed).
242 void configure(const char* directory);
243
244 //! Cleans up file queue before dispatching to underlying component
245 void deinit();
246
247 //! Start FileDownlink component
248 //! The component must be configured with configure() before starting.
249 //!
250 void preamble();
251
252 //! Destroy object FileDownlink
253 //!
254 ~FileDownlink();
255
256 private:
257 // ----------------------------------------------------------------------
258 // Handler implementations for user-defined typed input ports
259 // ----------------------------------------------------------------------
260
261 //! Handler implementation for Run
262 //!
263 void Run_handler(const FwIndexType portNum, //!< The port number
264 U32 context //!< The call order
265 );
266
267 //! Handler implementation for SendFile
268 //!
269 Svc::SendFileResponse SendFile_handler(
270 const FwIndexType portNum, /*!< The port number*/
271 const Fw::StringBase& sourceFilename, /*!< Path of file to downlink*/
272 const Fw::StringBase& destFilename, /*!< Path to store downlinked file at*/
273 U32 offset, /*!< Amount of data in bytes to downlink from file. 0 to read until end of file*/
274 U32 length /*!< Amount of data in bytes to downlink from file. 0 to read until end of file*/
275 );
276
277 //! Handler implementation for bufferReturn
278 //!
279 void bufferReturn_handler(const FwIndexType portNum, //!< The port number
280 Fw::Buffer& fwBuffer);
281
282 //! Handler implementation for pingIn
283 //!
284 void pingIn_handler(const FwIndexType portNum, /*!< The port number*/
285 U32 key /*!< Value to return to pinger*/
286 );
287
288 private:
289 // ----------------------------------------------------------------------
290 // Command handler implementations
291 // ----------------------------------------------------------------------
292
293 //! Implementation for FileDownlink_SendFile command handler
294 //!
295 void SendFile_cmdHandler(const FwOpcodeType opCode, //!< The opcode
296 const U32 cmdSeq, //!< The command sequence number
297 const Fw::CmdStringArg& sourceFilename, //!< The name of the on-board file to send
298 const Fw::CmdStringArg& destFilename //!< The name of the destination file on the ground
299 );
300
301 //! Implementation for FileDownlink_Cancel command handler
302 //!
303 void Cancel_cmdHandler(const FwOpcodeType opCode, //!< The opcode
304 const U32 cmdSeq //!< The command sequence number
305 );
306
307 //! Implementation for FILE_DWN_SEND_PARTIAL command handler
308 //!
309 void SendPartial_cmdHandler(
310 FwOpcodeType opCode, //!< The opcode
311 U32 cmdSeq, //!< The command sequence number
312 const Fw::CmdStringArg& sourceFilename, //!< The name of the on-board file to send
313 const Fw::CmdStringArg& destFilename, //!< The name of the destination file on the ground
314 U32 startOffset, //!< Starting offset of the source file
315 U32 length //!< Number of bytes to send from starting offset. Length of 0 implies until the end of the file
316 );
317
318 private:
319 // ----------------------------------------------------------------------
320 // Private helper methods
321 // ----------------------------------------------------------------------
322
323 void sendFile(
324 const Fw::FileNameString& sourceFilename, //!< The name of the on-board file to send
325 const Fw::FileNameString& destFilename, //!< The name of the destination file on the ground
326 U32 startOffset, //!< Starting offset of the source file
327 U32 length //!< Number of bytes to send from starting offset. Length of 0 implies until the end of the file
328 );
329
330 // Individual packet transfer functions
331 Os::File::Status sendDataPacket(U32& byteOffset);
332 void sendCancelPacket();
333 void sendEndPacket();
334 void sendStartPacket();
335 void sendFilePacket(const Fw::FilePacket& filePacket);
336
337 // State-helper functions
338 void exitFileTransfer();
339 void enterCooldown();
340
341 // Function to acquire a buffer internally
342 void getBuffer(Fw::Buffer& buffer, PacketType type);
343 // Downlink the "next" packet
344 void downlinkPacket();
345 // Finish the file transfer
346 void finishHelper(bool is_cancel);
347 // Convert internal status enum to a command response
348 Fw::CmdResponse statusToCmdResp(SendFileStatus status);
349 // Send response after completing file downlink
350 void sendResponse(SendFileStatus resp);
351
352 private:
353 // ----------------------------------------------------------------------
354 // Member variables
355 // ----------------------------------------------------------------------
356
357 //! Whether the configuration function has been called.
358 bool m_configured;
359
360 //! File downlink queue
361 Os::Queue m_fileQueue;
362
363 //! Buffer's memory backing
364 U8 m_memoryStore[COUNT_PACKET_TYPE][FILEDOWNLINK_INTERNAL_BUFFER_SIZE];
365
366 //! The mode
367 Mode m_mode;
368
369 //! The file
370 File m_file;
371
372 //! Files sent
373 FilesSent m_filesSent;
374
375 //! Packets sent
376 PacketsSent m_packetsSent;
377
378 //! Warnings
379 Warnings m_warnings;
380
381 //! The current sequence index
382 U32 m_sequenceIndex;
383
384 //! Timeout threshold (milliseconds) while in WAIT state
385 U32 m_timeout;
386
387 //! Cooldown (in ms) between finishing a downlink and starting the next file.
388 U32 m_cooldown;
389
390 //! current time residing in WAIT state
391 U32 m_curTimer;
392
393 //! rate (milliseconds) at which we are running
394 U32 m_cycleTime;
395
396 ////! Buffer for sending file data
397 Fw::Buffer m_buffer;
398
399 //! Buffer size for file data
400 U32 m_bufferSize;
401
402 //! Current byte offset in file
403 U32 m_byteOffset;
404
405 //! Amount of bytes left to read
406 U32 m_endOffset;
407
408 //! Set to true when all data packets have been sent
409 Fw::FilePacket::Type m_lastCompletedType;
410
411 //! Last buffer used
412 U32 m_lastBufferId;
413
414 //! Current in progress file entry from queue
415 struct FileEntry m_curEntry;
416
417 //! Incrementing context id used to unique identify a specific downlink request
418 U32 m_cntxId;
419 };
420
421 } // end namespace Svc
422
423 #endif
424