GCC Code Coverage Report


Directory: Svc/Ccsds/CfdpManager/
File: CfdpManager.cpp
Date: 2026-10-14 21:17:52
Exec Total Coverage
Lines: 378 389 97.2%
Functions: 41 41 100.0%
Branches: 252 280 90.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title CfdpManager.cpp
3 // \author Brian Campuzano
4 // \brief cpp file for CfdpManager component implementation class
5 // ======================================================================
6
7 #include <Fw/Com/ComPacket.hpp>
8 #include <Fw/Prm/ParamValid.hpp>
9 #include <Os/QueueString.hpp>
10 #include <Svc/Ccsds/CfdpManager/CfdpManager.hpp>
11 #include <Svc/Ccsds/CfdpManager/Channel.hpp>
12 #include <Svc/Ccsds/CfdpManager/Engine.hpp>
13 #include <new>
14
15 namespace Svc {
16 namespace Ccsds {
17 namespace Cfdp {
18
19 // ----------------------------------------------------------------------
20 // Component construction and destruction
21 // ----------------------------------------------------------------------
22
23
2/2
✓ Branch 14 taken 144 times.
✓ Branch 24 taken 144 times.
144 CfdpManager ::CfdpManager(const char* const compName) : CfdpManagerComponentBase(compName), m_engine(nullptr) {}
24
25 864 CfdpManager ::~CfdpManager() {
26 // Clean up the queue resources allocated during initialization
27 288 this->deinit();
28
29 // If cleanup() was not called, clean up manually
30
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 144 times.
288 if (this->m_engine != nullptr) {
31 ✗ this->cleanup();
32 }
33 576 }
34
35 144 void CfdpManager ::configure(Fw::MemAllocator& allocator, FwSizeType fileQueueDepth, FwEnumStoreType memId) {
36 // Allocate and initialize the CFDP engine
37 144 FwSizeType engineSize = sizeof(Engine);
38
1/1
✓ Branch 6 taken 144 times.
144 this->m_engine = static_cast<Engine*>(allocator.allocate(memId, engineSize));
39 144 FW_ASSERT(this->m_engine != nullptr);
40
1/3
✓ Branch 7 taken 144 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
144 (void)new (this->m_engine) Engine(this);
41
1/1
✓ Branch 8 taken 144 times.
144 this->m_engine->init(allocator, memId);
42
43 // Store allocator for cleanup
44 144 this->m_allocator = &allocator;
45 144 this->m_allocatorId = memId;
46
47 // Initialize telemetry counters to zero
48
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 144 times.
432 for (U8 i = 0; i < Cfdp::NumChannels; i++) {
49
3/3
✓ Branch 2 taken 288 times.
✓ Branch 11 taken 288 times.
✓ Branch 17 taken 288 times.
288 this->m_channelTelemetry[i] = Cfdp::ChannelTelemetry();
50 }
51
52 // Create the fileIn request handoff queue
53 144 this->m_fileInQueueDepth = fileQueueDepth;
54 Os::Queue::Status queueStat =
55
3/3
✓ Branch 7 taken 144 times.
✓ Branch 15 taken 144 times.
✓ Branch 18 taken 144 times.
144 this->m_fileInQueue.create(this->getInstance(), Os::QueueString("cfdpFileInQueue"), fileQueueDepth,
56 static_cast<FwSizeType>(sizeof(FileInRequest)));
57 144 FW_ASSERT(queueStat == Os::Queue::OP_OK, static_cast<FwAssertArgType>(queueStat));
58 144 }
59
60 144 void CfdpManager ::deinit() {
61 144 this->m_fileInQueue.teardown();
62 144 CfdpManagerComponentBase::deinit();
63 144 }
64
65 144 void CfdpManager ::cleanup() {
66 // Only try to deallocate if both pointers are non-null
67
2/4
✓ Branch 4 taken 144 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 144 times.
✗ Branch 11 not taken.
144 if ((this->m_allocator != nullptr) && (this->m_engine != nullptr)) {
68 // Manually call destructor since we used placement new
69 144 this->m_engine->~Engine();
70 // Deallocate the memory
71 144 this->m_allocator->deallocate(this->m_allocatorId, this->m_engine);
72 144 this->m_engine = nullptr;
73 }
74 144 }
75
76 // ----------------------------------------------------------------------
77 // Handler implementations for typed input ports
78 // ----------------------------------------------------------------------
79
80 1949 void CfdpManager ::run1Hz_handler(FwIndexType portNum, U32 context) {
81 // The timer logic built into the CFDP engine requires it to be driven at 1 Hz
82 1949 FW_ASSERT(this->m_engine != nullptr);
83
84 // Drain any port-initiated file send requests before cycling the engine
85 1949 this->drainFileInQueue();
86
87 1949 this->m_engine->cycle();
88
89 // Emit telemetry once per second
90
2/2
✓ Branch 6 taken 1949 times.
✓ Branch 12 taken 1949 times.
1949 this->tlmWrite_ChannelTelemetry(this->m_channelTelemetry);
91 1949 }
92
93 1953 void CfdpManager ::drainFileInQueue() {
94 1953 FW_ASSERT(this->m_engine != nullptr);
95
96 // Drain the whole queue; the depth bound guarantees the loop terminates.
97
1/2
✓ Branch 4 taken 1957 times.
✗ Branch 5 not taken.
1957 for (FwSizeType drained = 0; drained < this->m_fileInQueueDepth; drained++) {
98
1/1
✓ Branch 2 taken 1957 times.
1957 FileInRequest request;
99 1957 FwSizeType actualSize = 0;
100 1957 FwQueuePriorityType priority = 0;
101 Os::Queue::Status status =
102
1/1
✓ Branch 6 taken 1957 times.
1957 this->m_fileInQueue.receive(reinterpret_cast<U8*>(&request), static_cast<FwSizeType>(sizeof(request)),
103 Os::Queue::BlockingType::NONBLOCKING, actualSize, priority);
104
105 // Queue empty (or any non-OK status) ends the drain for this cycle
106
3/4
✓ Branch 0 taken 1953 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
1957 if (status != Os::Queue::Status::OP_OK || actualSize != sizeof(request)) {
107 break;
108 }
109
110 // Look up the per-channel default parameters
111
1/1
✓ Branch 2 taken 4 times.
4 Fw::ParamValid valid;
112
1/1
✓ Branch 5 taken 4 times.
4 U8 channelId = this->paramGet_FileInDefaultChannel(valid);
113 4 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
114
115 // Reject an out-of-range channel parameter rather than letting it assert in Engine::txFile
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (channelId >= Cfdp::NumChannels) {
117 ✗ this->log_WARNING_LO_InvalidChannel(channelId, Cfdp::NumChannels);
118 ✗ this->sendFileComplete(Svc::SendFileStatus::STATUS_INVALID);
119 ✗ continue;
120 }
121
122
1/1
✓ Branch 5 taken 4 times.
4 EntityId destEid = this->paramGet_FileInDefaultDestEntityId(valid);
123 4 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
124
125
1/1
✓ Branch 3 taken 4 times.
4 Class::T cfdpClass = this->paramGet_FileInDefaultClass(valid);
126 4 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
127
128
1/1
✓ Branch 3 taken 4 times.
4 Keep::T keep = this->paramGet_FileInDefaultKeep(valid);
129 4 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
130
131
1/1
✓ Branch 5 taken 4 times.
4 U8 priorityParam = this->paramGet_FileInDefaultPriority(valid);
132 4 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
133
134 // Initiate the transfer on the active thread
135 Status::T txStatus =
136
1/1
✓ Branch 8 taken 4 times.
4 this->m_engine->txFile(request.sourceFileName, request.destFileName, cfdpClass, keep, channelId,
137 priorityParam, destEid, TransactionInitType::INIT_BY_PORT);
138
139 // The caller already received queue-acceptance success; report the deferred initiation
140 // result via fileDoneOut so a failed initiation does not leave the caller waiting forever.
141
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (txStatus != Status::SUCCESS) {
142
1/1
✓ Branch 5 taken 1 times.
1 this->log_WARNING_LO_SendFileInitiateFail(request.sourceFileName);
143
1/1
✓ Branch 4 taken 1 times.
1 this->sendFileComplete(Svc::SendFileStatus::STATUS_ERROR);
144 }
145 1957 }
146 1953 }
147
148 2 void CfdpManager ::dataReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
149 // dataReturnIn is the allocated buffer coming back from the dataOut call
150 // Port mapping is the same from bufferAllocate -> dataOut -> dataReturnIn -> bufferDeallocate
151 2 FW_ASSERT(portNum < Cfdp::NumChannels, portNum, Cfdp::NumChannels);
152 2 this->bufferDeallocate_out(portNum, fwBuffer);
153 2 }
154
155 153 void CfdpManager ::dataIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
156 // There is a direct mapping between port number and channel index
157 153 FW_ASSERT(portNum < Cfdp::NumChannels, portNum, Cfdp::NumChannels);
158 153 FW_ASSERT(portNum >= 0, portNum);
159
160 // Strip FW_PACKET_FILE descriptor (first 2 bytes) from buffer
161 // FprimeRouter sends the entire Space Packet data field, which includes the packet type descriptor
162
3/3
✓ Branch 4 taken 153 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 152 times.
153 if (fwBuffer.getSize() < sizeof(FwPacketDescriptorType)) {
163 // Buffer too small - silently ignore
164
1/1
✓ Branch 5 taken 1 times.
1 this->dataInReturn_out(portNum, fwBuffer);
165 1 return;
166 }
167
168 // Read and verify packet type descriptor
169 152 FwPacketDescriptorType packetType = 0;
170
2/2
✓ Branch 2 taken 152 times.
✓ Branch 8 taken 152 times.
152 Fw::SerializeStatus status = fwBuffer.getDeserializer().deserializeTo(packetType);
171
3/4
✓ Branch 0 taken 152 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 151 times.
152 if (status != Fw::FW_SERIALIZE_OK || packetType != Fw::ComPacketType::FW_PACKET_FILE) {
172 // Invalid packet type - silently ignore (consistent with FileUplink behavior)
173
1/1
✓ Branch 5 taken 1 times.
1 this->dataInReturn_out(portNum, fwBuffer);
174 1 return;
175 }
176
177 // Create a new buffer view that skips the descriptor
178 // The deserializer advanced past the 2-byte descriptor, but Engine::receivePdu
179 // calls getData() which returns the raw pointer from byte 0. We need to create
180 // a buffer that starts after the descriptor.
181 151 const FwSizeType descriptorSize = sizeof(FwPacketDescriptorType);
182
2/2
✓ Branch 4 taken 151 times.
✓ Branch 9 taken 151 times.
453 Fw::Buffer pduBuffer(fwBuffer.getData() + descriptorSize, fwBuffer.getSize() - descriptorSize,
183
2/2
✓ Branch 4 taken 151 times.
✓ Branch 10 taken 151 times.
453 fwBuffer.getContext());
184
185 // Pass the adjusted buffer to the engine
186 151 FW_ASSERT(this->m_engine != nullptr);
187
1/1
✓ Branch 8 taken 151 times.
151 this->m_engine->receivePdu(static_cast<U8>(portNum), pduBuffer);
188
189 // Return buffer
190
1/1
✓ Branch 5 taken 151 times.
151 this->dataInReturn_out(portNum, fwBuffer);
191 151 }
192
193 5 Svc::SendFileResponse CfdpManager ::fileIn_handler(FwIndexType portNum,
194 const Fw::StringBase& sourceFileName,
195 const Fw::StringBase& destFileName,
196 U32 offset,
197 U32 length) {
198
1/1
✓ Branch 1 taken 5 times.
5 Svc::SendFileResponse response;
199 // Set context to portNum so we can identify this transaction later
200
1/1
✓ Branch 3 taken 5 times.
5 response.set_context(static_cast<U32>(portNum));
201
202 // CFDP engine does not support partial file retransmit at this time
203 // Offset and length must be 0 to send the entire file
204
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
5 if (offset > 0 || length > 0) {
205
1/1
✓ Branch 3 taken 1 times.
1 response.set_status(Svc::SendFileStatus::STATUS_INVALID);
206
1/1
✓ Branch 5 taken 1 times.
1 this->log_WARNING_LO_UnsupportedSendFileArguments(offset, length);
207 1 return response;
208 }
209
210 // Copy the request into the internal queue instead of touching the engine here. This handler
211 // runs on the caller's thread (guarded port); the engine is mutated on the active thread when
212 // run1Hz drains the queue. The synchronous response only indicates that the request was
213 // accepted for processing; the final transfer result is delivered later via fileDoneOut.
214
1/1
✓ Branch 2 taken 4 times.
4 FileInRequest request;
215
216 // Guard against filenames that would not fit in the queued request
217
4/7
✓ Branch 11 taken 4 times.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
8 if (sourceFileName.length() >= request.sourceFileName.getCapacity() ||
218
1/1
✓ Branch 11 taken 4 times.
4 destFileName.length() >= request.destFileName.getCapacity()) {
219 ✗ response.set_status(Svc::SendFileStatus::STATUS_INVALID);
220 ✗ this->log_WARNING_LO_SendFileInitiateFail(sourceFileName);
221 ✗ return response;
222 }
223
224
1/1
✓ Branch 5 taken 4 times.
4 request.sourceFileName = sourceFileName;
225
1/1
✓ Branch 5 taken 4 times.
4 request.destFileName = destFileName;
226 4 request.context = static_cast<U32>(portNum);
227
228 Os::Queue::Status status =
229
1/1
✓ Branch 6 taken 4 times.
4 this->m_fileInQueue.send(reinterpret_cast<U8*>(&request), static_cast<FwSizeType>(sizeof(request)), 0,
230 Os::Queue::BlockingType::NONBLOCKING);
231
232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (status != Os::Queue::Status::OP_OK) {
233 // Queue full - reject the request so the caller can retry later
234 ✗ response.set_status(Svc::SendFileStatus::STATUS_BUSY);
235 ✗ this->log_WARNING_LO_SendFileInitiateFail(sourceFileName);
236 } else {
237
1/1
✓ Branch 3 taken 4 times.
4 response.set_status(Svc::SendFileStatus::STATUS_OK);
238 }
239
240 4 return response;
241 4 }
242
243 1 void CfdpManager ::pingIn_handler(FwIndexType portNum, U32 key) {
244 // send ping response
245 1 this->pingOut_out(0, key);
246 1 }
247
248 // ----------------------------------------------------------------------
249 // Port calls that are invoked by the CFDP engine
250 // These functions are analogous to the functions in cf_cfdp_sbintf.*
251 // However these functions were not directly migrated due to the
252 // architectural differences between F' and cFE
253 // ----------------------------------------------------------------------
254
255 98 Status::T CfdpManager ::getPduBuffer(Fw::Buffer& buffer, Channel& channel, FwSizeType size) {
256 98 Status::T status = Status::ERROR;
257 FwIndexType portNum;
258
259 // There is a direct mapping between channel index and port number
260 98 portNum = static_cast<FwIndexType>(channel.getChannelId());
261
262 // Check if we have reached the maximum number of output PDUs for this cycle
263 98 U32 max_pdus = getMaxOutgoingPdusPerCycleParam(channel.getChannelId());
264
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 97 times.
98 if (channel.getOutgoingCounter() >= max_pdus) {
265 1 status = Status::SEND_PDU_NO_BUF_AVAIL_ERROR;
266 } else {
267
2/2
✓ Branch 3 taken 97 times.
✓ Branch 10 taken 97 times.
97 buffer = this->bufferAllocate_out(portNum, size);
268 // Check the allocation was successful based on size
269
2/2
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 1 times.
97 if (buffer.getSize() == size) {
270 96 channel.incrementOutgoingCounter();
271 96 status = Status::SUCCESS;
272 } else {
273 1 this->log_WARNING_LO_BuffersExhausted();
274 1 status = Status::SEND_PDU_NO_BUF_AVAIL_ERROR;
275 }
276 }
277 98 return status;
278 }
279
280 1 void CfdpManager ::returnPduBuffer(Channel& channel, Fw::Buffer& pduBuffer) {
281 FwIndexType portNum;
282
283 // There is a direct mapping between channel index and port number
284 1 portNum = static_cast<FwIndexType>(channel.getChannelId());
285
286 // Was unable to successfully populate the PDU buffer, return it
287 1 this->bufferDeallocate_out(portNum, pduBuffer);
288 1 }
289
290 95 void CfdpManager ::sendPduBuffer(Channel& channel, Fw::Buffer& pduBuffer) {
291 FwIndexType portNum;
292
293 // There is a direct mapping between channel index and port number
294 95 portNum = static_cast<FwIndexType>(channel.getChannelId());
295
296 // ComQueue expects buffers to start with a 2-byte packet descriptor (APID)
297 // The PDU data has already been serialized at offset PACKET_DESCRIPTOR_SIZE,
298 // so we just need to write the descriptor at the beginning
299
300 95 U8* bufferData = pduBuffer.getData();
301
302 // Write FW_PACKET_FILE descriptor at the beginning (big-endian U16)
303 95 const FwPacketDescriptorType descriptor = static_cast<FwPacketDescriptorType>(Fw::ComPacketType::FW_PACKET_FILE);
304 95 bufferData[0] = static_cast<U8>((descriptor >> 8) & 0xFF); // High byte
305 95 bufferData[1] = static_cast<U8>(descriptor & 0xFF); // Low byte
306
307 // Send buffer with descriptor
308 95 this->dataOut_out(portNum, pduBuffer);
309 95 }
310
311 4 void CfdpManager::sendFileComplete(Svc::SendFileStatus::T status) {
312
1/1
✓ Branch 2 taken 4 times.
4 Svc::SendFileResponse response;
313
1/1
✓ Branch 2 taken 4 times.
4 response.set_status(status);
314
1/1
✓ Branch 2 taken 4 times.
4 response.set_context(0);
315
316
1/1
✓ Branch 5 taken 4 times.
4 this->fileDoneOut_out(0, response);
317 8 }
318
319 // ----------------------------------------------------------------------
320 // Handler implementations for commands
321 // ----------------------------------------------------------------------
322
323 14 void CfdpManager ::SendFile_cmdHandler(FwOpcodeType opCode,
324 U32 cmdSeq,
325 U8 channelId,
326 EntityId destId,
327 const Class& cfdpClass,
328 const Keep& keep,
329 U8 priority,
330 const Fw::CmdStringArg& sourceFileName,
331 const Fw::CmdStringArg& destFileName) {
332 14 Fw::CmdResponse::T rspStatus = Fw::CmdResponse::OK;
333
334 // Check channel index is in range
335 14 rspStatus = this->checkCommandChannelIndex(channelId);
336 14 FW_ASSERT(this->m_engine != nullptr);
337
338
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
14 if (rspStatus == Fw::CmdResponse::OK) {
339
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (Status::SUCCESS !=
340
5/7
✗ Branch 10 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 13 times.
✓ Branch 22 taken 13 times.
✓ Branch 30 taken 13 times.
✓ Branch 34 taken 13 times.
13 this->m_engine->txFile(sourceFileName, destFileName, cfdpClass.e, keep.e, channelId, priority, destId)) {
341 // Engine emits specific failure reason EVR (e.g., MaxTxTransactionsReached)
342 1 rspStatus = Fw::CmdResponse::EXECUTION_ERROR;
343 }
344 }
345
346
2/2
✓ Branch 6 taken 14 times.
✓ Branch 9 taken 14 times.
14 this->cmdResponse_out(opCode, cmdSeq, rspStatus);
347 14 }
348
349 4 void CfdpManager ::PlaybackDirectory_cmdHandler(FwOpcodeType opCode,
350 U32 cmdSeq,
351 U8 channelId,
352 EntityId destId,
353 const Class& cfdpClass,
354 const Keep& keep,
355 U8 priority,
356 const Fw::CmdStringArg& sourceDirectory,
357 const Fw::CmdStringArg& destDirectory) {
358 4 Fw::CmdResponse::T rspStatus = Fw::CmdResponse::OK;
359
360 4 FW_ASSERT(this->m_engine != nullptr);
361 // Check channel index is in range
362 4 rspStatus = this->checkCommandChannelIndex(channelId);
363
364
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (rspStatus == Fw::CmdResponse::OK) {
365
5/5
✓ Branch 12 taken 3 times.
✓ Branch 21 taken 3 times.
✓ Branch 25 taken 3 times.
✓ Branch 35 taken 1 times.
✓ Branch 36 taken 2 times.
6 if (Status::SUCCESS == this->m_engine->playbackDir(sourceDirectory.toChar(), destDirectory.toChar(),
366
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
3 cfdpClass.e, keep.e, channelId, priority, destId)) {
367 1 this->log_ACTIVITY_LO_PlaybackInitiated(sourceDirectory);
368 } else {
369 // Engine emits specific failure reason EVR (e.g., PlaybackDirOpenFailed, PlaybackDirSlotUnavailable)
370 2 rspStatus = Fw::CmdResponse::EXECUTION_ERROR;
371 }
372 }
373
374
2/2
✓ Branch 6 taken 4 times.
✓ Branch 9 taken 4 times.
4 this->cmdResponse_out(opCode, cmdSeq, rspStatus);
375 4 }
376
377 8 void CfdpManager ::PollDirectory_cmdHandler(FwOpcodeType opCode,
378 U32 cmdSeq,
379 U8 channelId,
380 U8 pollId,
381 EntityId destId,
382 const Class& cfdpClass,
383 U8 priority,
384 U32 interval,
385 const Fw::CmdStringArg& sourceDirectory,
386 const Fw::CmdStringArg& destDirectory) {
387 8 Fw::CmdResponse::T rspStatus = Fw::CmdResponse::OK;
388
389 8 FW_ASSERT(this->m_engine != nullptr);
390 // Check channel index and poll index are in range
391 8 rspStatus = this->checkCommandChannelIndex(channelId);
392
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 if (rspStatus == Fw::CmdResponse::OK) {
393 7 rspStatus = this->checkCommandChannelPollIndex(pollId);
394 }
395
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 if (rspStatus == Fw::CmdResponse::OK) {
396 6 rspStatus = this->checkCommandPollInterval(interval);
397 }
398
399
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
8 if (rspStatus == Fw::CmdResponse::OK) {
400
5/5
✓ Branch 11 taken 5 times.
✓ Branch 19 taken 5 times.
✓ Branch 23 taken 5 times.
✓ Branch 33 taken 4 times.
✓ Branch 34 taken 1 times.
10 if (Status::SUCCESS == this->m_engine->startPollDir(channelId, pollId, sourceDirectory, destDirectory,
401
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
5 cfdpClass.e, priority, destId, interval)) {
402 4 this->log_ACTIVITY_LO_PollDirInitiated(sourceDirectory, pollId);
403 } else {
404 // Failure EVR was already emitted
405 1 rspStatus = Fw::CmdResponse::EXECUTION_ERROR;
406 }
407 }
408
409
2/2
✓ Branch 6 taken 8 times.
✓ Branch 9 taken 8 times.
8 this->cmdResponse_out(opCode, cmdSeq, rspStatus);
410 8 }
411
412 5 void CfdpManager ::StopPollDirectory_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 channelId, U8 pollId) {
413 5 Fw::CmdResponse::T rspStatus = Fw::CmdResponse::OK;
414
415 5 FW_ASSERT(this->m_engine != nullptr);
416 // Check channel index and poll index are in range
417 5 rspStatus = this->checkCommandChannelIndex(channelId);
418
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (rspStatus == Fw::CmdResponse::OK) {
419 5 rspStatus = this->checkCommandChannelPollIndex(pollId);
420 }
421
422
5/6
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 4 times.
✓ Branch 13 taken 1 times.
5 if ((rspStatus == Fw::CmdResponse::OK) && (Status::SUCCESS == this->m_engine->stopPollDir(channelId, pollId))) {
423 4 this->log_ACTIVITY_LO_PollDirStopped(channelId, pollId);
424 }
425 // Failure EVR was already emitted
426 // Not failing the command if the stop request failed
427 // This allows operators to reinforce state prior to calling PollDirectory
428
429
2/2
✓ Branch 6 taken 5 times.
✓ Branch 9 taken 5 times.
5 this->cmdResponse_out(opCode, cmdSeq, rspStatus);
430 5 }
431
432 2 void CfdpManager ::SetChannelFlow_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 channelId, const Flow& flowState) {
433 2 Fw::CmdResponse::T rspStatus = Fw::CmdResponse::OK;
434
435 2 FW_ASSERT(this->m_engine != nullptr);
436 // Check channel index is in range
437 2 rspStatus = checkCommandChannelIndex(channelId);
438
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (rspStatus == Fw::CmdResponse::OK) {
439 1 this->m_engine->setChannelFlowState(channelId, flowState);
440 1 this->log_ACTIVITY_LO_SetFlowState(channelId, flowState);
441 }
442
443
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, rspStatus);
444 2 }
445
446 4 void CfdpManager ::SuspendResumeTransaction_cmdHandler(FwOpcodeType opCode,
447 U32 cmdSeq,
448 U8 channelId,
449 TransactionSeq transactionSeq,
450 EntityId entityId,
451 const SuspendResume& action) {
452 4 Fw::CmdResponse::T rspStatus = Fw::CmdResponse::OK;
453
454 4 FW_ASSERT(this->m_engine != nullptr);
455
456 4 rspStatus = checkCommandChannelIndex(channelId);
457
458
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (rspStatus == Fw::CmdResponse::OK) {
459 3 Status::T status = this->m_engine->setSuspendResumeTransaction(channelId, transactionSeq, entityId, action);
460
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (status == Status::SUCCESS) {
461
2/2
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 if (action == SuspendResume::SUSPEND) {
462 1 log_ACTIVITY_LO_TransactionSuspended(transactionSeq, entityId);
463 } else {
464 1 log_ACTIVITY_LO_TransactionResumed(transactionSeq, entityId);
465 }
466 } else {
467 1 log_WARNING_LO_TransactionNotFound(transactionSeq, entityId);
468 1 rspStatus = Fw::CmdResponse::EXECUTION_ERROR;
469 }
470 }
471
472
2/2
✓ Branch 6 taken 4 times.
✓ Branch 9 taken 4 times.
4 this->cmdResponse_out(opCode, cmdSeq, rspStatus);
473 4 }
474
475 3 void CfdpManager ::CancelTransaction_cmdHandler(FwOpcodeType opCode,
476 U32 cmdSeq,
477 U8 channelId,
478 TransactionSeq transactionSeq,
479 EntityId entityId) {
480 3 Fw::CmdResponse::T rspStatus = Fw::CmdResponse::OK;
481
482 3 FW_ASSERT(this->m_engine != nullptr);
483
484 3 rspStatus = checkCommandChannelIndex(channelId);
485
486
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (rspStatus == Fw::CmdResponse::OK) {
487 2 Status::T status = this->m_engine->cancelTransactionBySeq(channelId, transactionSeq, entityId);
488
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (status == Status::SUCCESS) {
489 1 log_ACTIVITY_HI_TransactionCanceled(transactionSeq, entityId);
490 } else {
491 1 log_WARNING_LO_TransactionNotFound(transactionSeq, entityId);
492 1 rspStatus = Fw::CmdResponse::EXECUTION_ERROR;
493 }
494 }
495
496
2/2
✓ Branch 6 taken 3 times.
✓ Branch 9 taken 3 times.
3 this->cmdResponse_out(opCode, cmdSeq, rspStatus);
497 3 }
498
499 3 void CfdpManager ::AbandonTransaction_cmdHandler(FwOpcodeType opCode,
500 U32 cmdSeq,
501 U8 channelId,
502 TransactionSeq transactionSeq,
503 EntityId entityId) {
504 3 Fw::CmdResponse::T rspStatus = Fw::CmdResponse::OK;
505
506 3 FW_ASSERT(this->m_engine != nullptr);
507
508 3 rspStatus = checkCommandChannelIndex(channelId);
509
510
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (rspStatus == Fw::CmdResponse::OK) {
511 2 Status::T status = this->m_engine->abandonTransaction(channelId, transactionSeq, entityId);
512
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (status == Status::SUCCESS) {
513 1 log_ACTIVITY_HI_TransactionAbandoned(transactionSeq, entityId);
514 } else {
515 1 log_WARNING_LO_TransactionNotFound(transactionSeq, entityId);
516 1 rspStatus = Fw::CmdResponse::EXECUTION_ERROR;
517 }
518 }
519
520
2/2
✓ Branch 6 taken 3 times.
✓ Branch 9 taken 3 times.
3 this->cmdResponse_out(opCode, cmdSeq, rspStatus);
521 3 }
522
523 3 void CfdpManager ::ResetCounters_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 channelId) {
524 // 0xFF means reset all channels
525
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (channelId == 0xFF) {
526
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for (U8 i = 0; i < Cfdp::NumChannels; i++) {
527
3/3
✓ Branch 2 taken 2 times.
✓ Branch 11 taken 2 times.
✓ Branch 17 taken 2 times.
2 this->m_channelTelemetry[i] = Cfdp::ChannelTelemetry();
528 }
529 1 this->log_ACTIVITY_HI_ResetCounters(0xFF);
530 }
531 // Otherwise reset specific channel
532
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 else if (channelId < Cfdp::NumChannels) {
533
3/3
✓ Branch 2 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 17 taken 1 times.
1 this->m_channelTelemetry[channelId] = Cfdp::ChannelTelemetry();
534 1 this->log_ACTIVITY_HI_ResetCounters(channelId);
535 } else {
536 // Invalid channel ID
537 1 this->log_WARNING_LO_InvalidChannel(channelId, Cfdp::NumChannels - 1);
538
2/2
✓ Branch 6 taken 1 times.
✓ Branch 9 taken 1 times.
1 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
539 1 return;
540 }
541
542 // Emit updated telemetry
543
2/2
✓ Branch 6 taken 2 times.
✓ Branch 12 taken 2 times.
2 this->tlmWrite_ChannelTelemetry(this->m_channelTelemetry);
544
545
2/2
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
546 }
547
548 // ----------------------------------------------------------------------
549 // Private command helper functions
550 // ----------------------------------------------------------------------
551
552 43 Fw::CmdResponse::T CfdpManager ::checkCommandChannelIndex(U8 channelIndex) {
553
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 36 times.
43 if (channelIndex >= Cfdp::NumChannels) {
554 7 this->log_WARNING_LO_InvalidChannel(channelIndex, Cfdp::NumChannels);
555 7 return Fw::CmdResponse::VALIDATION_ERROR;
556 } else {
557 36 return Fw::CmdResponse::OK;
558 }
559 }
560
561 12 Fw::CmdResponse::T CfdpManager ::checkCommandChannelPollIndex(U8 pollIndex) {
562
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11 times.
12 if (pollIndex >= MaxPollingDirPerChan) {
563 1 this->log_WARNING_LO_InvalidChannelPoll(pollIndex, MaxPollingDirPerChan);
564 1 return Fw::CmdResponse::VALIDATION_ERROR;
565 } else {
566 11 return Fw::CmdResponse::OK;
567 }
568 }
569
570 6 Fw::CmdResponse::T CfdpManager ::checkCommandPollInterval(U32 interval) {
571 // A zero interval would arm the poll timer with no time remaining, which is
572 // not a valid polling configuration, so reject it here.
573
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (interval == 0) {
574 1 this->log_WARNING_LO_InvalidPollInterval(interval);
575 1 return Fw::CmdResponse::VALIDATION_ERROR;
576 } else {
577 5 return Fw::CmdResponse::OK;
578 }
579 }
580
581 // ----------------------------------------------------------------------
582 // Parameter update handling
583 // ----------------------------------------------------------------------
584
585 1459 void CfdpManager ::parameterUpdated(FwPrmIdType id) {
586 // Re-emit only the parameter that changed so ground can verify the active
587 // configuration.
588
1/1
✓ Branch 2 taken 1459 times.
1459 Fw::ParamValid valid;
589
10/11
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 146 times.
✓ Branch 2 taken 146 times.
✓ Branch 3 taken 145 times.
✓ Branch 4 taken 146 times.
✓ Branch 5 taken 146 times.
✓ Branch 6 taken 146 times.
✓ Branch 7 taken 146 times.
✓ Branch 8 taken 146 times.
✓ Branch 9 taken 146 times.
✗ Branch 10 not taken.
1459 switch (id) {
590 146 case PARAMID_LOCALEID: {
591
3/3
✓ Branch 6 taken 146 times.
✓ Branch 13 taken 146 times.
✓ Branch 16 taken 146 times.
146 this->tlmWrite_PRM_LOCAL_EID(this->paramGet_LocalEid(valid));
592 146 break;
593 }
594 146 case PARAMID_OUTGOINGFILECHUNKSIZE: {
595
3/3
✓ Branch 6 taken 146 times.
✓ Branch 13 taken 146 times.
✓ Branch 16 taken 146 times.
146 this->tlmWrite_PRM_OUTGOING_FILE_CHUNK_SIZE(this->paramGet_OutgoingFileChunkSize(valid));
596 146 break;
597 }
598 146 case PARAMID_RXCRCCALCBYTESPERCYCLE: {
599
3/3
✓ Branch 6 taken 146 times.
✓ Branch 13 taken 146 times.
✓ Branch 16 taken 146 times.
146 this->tlmWrite_PRM_RX_CRC_CALC_BYTES_PER_CYCLE(this->paramGet_RxCrcCalcBytesPerCycle(valid));
600 146 break;
601 }
602 145 case PARAMID_POSTINACTIVITYSENDRETRIES: {
603
3/3
✓ Branch 6 taken 145 times.
✓ Branch 13 taken 145 times.
✓ Branch 16 taken 145 times.
145 this->tlmWrite_PRM_POST_INACTIVITY_SEND_RETRIES(this->paramGet_PostInactivitySendRetries(valid));
604 145 break;
605 }
606 146 case PARAMID_FILEINDEFAULTCHANNEL: {
607
3/3
✓ Branch 6 taken 146 times.
✓ Branch 13 taken 146 times.
✓ Branch 16 taken 146 times.
146 this->tlmWrite_PRM_FILE_IN_DEFAULT_CHANNEL(this->paramGet_FileInDefaultChannel(valid));
608 146 break;
609 }
610 146 case PARAMID_FILEINDEFAULTDESTENTITYID: {
611
3/3
✓ Branch 6 taken 146 times.
✓ Branch 13 taken 146 times.
✓ Branch 16 taken 146 times.
146 this->tlmWrite_PRM_FILE_IN_DEFAULT_DEST_ENTITY_ID(this->paramGet_FileInDefaultDestEntityId(valid));
612 146 break;
613 }
614 146 case PARAMID_FILEINDEFAULTCLASS: {
615
3/3
✓ Branch 6 taken 146 times.
✓ Branch 11 taken 146 times.
✓ Branch 15 taken 146 times.
146 this->tlmWrite_PRM_FILE_IN_DEFAULT_CLASS(this->paramGet_FileInDefaultClass(valid));
616 146 break;
617 }
618 146 case PARAMID_FILEINDEFAULTKEEP: {
619
3/3
✓ Branch 6 taken 146 times.
✓ Branch 11 taken 146 times.
✓ Branch 15 taken 146 times.
146 this->tlmWrite_PRM_FILE_IN_DEFAULT_KEEP(this->paramGet_FileInDefaultKeep(valid));
620 146 break;
621 }
622 146 case PARAMID_FILEINDEFAULTPRIORITY: {
623
3/3
✓ Branch 6 taken 146 times.
✓ Branch 13 taken 146 times.
✓ Branch 16 taken 146 times.
146 this->tlmWrite_PRM_FILE_IN_DEFAULT_PRIORITY(this->paramGet_FileInDefaultPriority(valid));
624 146 break;
625 }
626 146 case PARAMID_CHANNELCONFIG: {
627
3/3
✓ Branch 6 taken 146 times.
✓ Branch 11 taken 146 times.
✓ Branch 15 taken 146 times.
146 this->tlmWrite_PRM_CHANNEL_CONFIG(this->paramGet_ChannelConfig(valid));
628 146 break;
629 }
630 ✗ default: {
631 ✗ FW_ASSERT(false, static_cast<FwAssertArgType>(id)); // coding error, forgot to include in switch statement
632 }
633 }
634
635 1459 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
636 2918 }
637
638 // ----------------------------------------------------------------------
639 // Parameter helpers used by the CFDP engine
640 // ----------------------------------------------------------------------
641
642 394 EntityId CfdpManager::getLocalEidParam(void) {
643
1/1
✓ Branch 2 taken 394 times.
394 Fw::ParamValid valid;
644
645 // Check for coding errors as all CFDP parameters must have a default
646
1/1
✓ Branch 5 taken 394 times.
394 EntityId localEid = this->paramGet_LocalEid(valid);
647 394 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
648
649 394 return localEid;
650 394 }
651
652 57 U32 CfdpManager::getOutgoingFileChunkSizeParam(void) {
653
1/1
✓ Branch 2 taken 57 times.
57 Fw::ParamValid valid;
654
655 // Check for coding errors as all CFDP parameters must have a default
656
1/1
✓ Branch 5 taken 57 times.
57 U32 chunkSize = this->paramGet_OutgoingFileChunkSize(valid);
657 57 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
658
659 57 return chunkSize;
660 57 }
661 9 U32 CfdpManager::getRxCrcCalcBytesPerCycleParam(void) {
662
1/1
✓ Branch 2 taken 9 times.
9 Fw::ParamValid valid;
663
664 // Check for coding errors as all CFDP parameters must have a default
665
1/1
✓ Branch 5 taken 9 times.
9 U32 rxSize = this->paramGet_RxCrcCalcBytesPerCycle(valid);
666 9 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
667
668 9 return rxSize;
669 9 }
670
671 1 U8 CfdpManager::getPostInactivitySendRetriesParam(void) {
672
1/1
✓ Branch 2 taken 1 times.
1 Fw::ParamValid valid;
673
674 // Check for coding errors as all CFDP parameters must have a default
675
1/1
✓ Branch 5 taken 1 times.
1 U8 retries = this->paramGet_PostInactivitySendRetries(valid);
676 1 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
677
678 1 return retries;
679 1 }
680
681 3 Fw::String CfdpManager::getTmpDirParam(U8 channelIndex) {
682
1/1
✓ Branch 2 taken 3 times.
3 Fw::ParamValid valid;
683
684 3 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
685
686 // Check for coding errors as all CFDP parameters must have a default
687 // Get the array first
688
1/1
✓ Branch 3 taken 3 times.
3 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
689 3 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
690
691 // Now get individual parameter
692
2/2
✓ Branch 2 taken 3 times.
✓ Branch 11 taken 3 times.
6 return paramArray[channelIndex].get_tmp_dir();
693 3 }
694
695 2 Fw::String CfdpManager::getFailDirParam(U8 channelIndex) {
696
1/1
✓ Branch 2 taken 2 times.
2 Fw::ParamValid valid;
697
698 2 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
699
700 // Check for coding errors as all CFDP parameters must have a default
701 // Get the array first
702
1/1
✓ Branch 3 taken 2 times.
2 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
703 2 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
704
705 // Now get individual parameter
706
2/2
✓ Branch 2 taken 2 times.
✓ Branch 11 taken 2 times.
4 return paramArray[channelIndex].get_fail_dir();
707 2 }
708
709 12 U8 CfdpManager::getAckLimitParam(U8 channelIndex) {
710
1/1
✓ Branch 2 taken 12 times.
12 Fw::ParamValid valid;
711
712 12 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
713
714 // Check for coding errors as all CFDP parameters must have a default
715 // Get the array first
716
1/1
✓ Branch 3 taken 12 times.
12 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
717 12 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
718
719 // Now get individual parameter
720
1/1
✓ Branch 2 taken 12 times.
24 return paramArray[channelIndex].get_ack_limit();
721 12 }
722
723 3 U8 CfdpManager::getNackLimitParam(U8 channelIndex) {
724
1/1
✓ Branch 2 taken 3 times.
3 Fw::ParamValid valid;
725
726 3 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
727
728 // Check for coding errors as all CFDP parameters must have a default
729 // Get the array first
730
1/1
✓ Branch 3 taken 3 times.
3 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
731 3 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
732
733 // Now get individual parameter
734
1/1
✓ Branch 2 taken 3 times.
6 return paramArray[channelIndex].get_nack_limit();
735 3 }
736
737 123 U32 CfdpManager::getAckTimerParam(U8 channelIndex) {
738
1/1
✓ Branch 2 taken 123 times.
123 Fw::ParamValid valid;
739
740 123 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
741
742 // Check for coding errors as all CFDP parameters must have a default
743 // Get the array first
744
1/1
✓ Branch 3 taken 123 times.
123 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
745 123 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
746
747 // Now get individual parameter
748
1/1
✓ Branch 2 taken 123 times.
246 return paramArray[channelIndex].get_ack_timer();
749 123 }
750
751 169 U32 CfdpManager::getInactivityTimerParam(U8 channelIndex) {
752
1/1
✓ Branch 2 taken 169 times.
169 Fw::ParamValid valid;
753
754 169 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
755
756 // Check for coding errors as all CFDP parameters must have a default
757 // Get the array first
758
1/1
✓ Branch 3 taken 169 times.
169 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
759 169 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
760
761 // Now get individual parameter
762
1/1
✓ Branch 2 taken 169 times.
338 return paramArray[channelIndex].get_inactivity_timer();
763 169 }
764
765 3898 Fw::Enabled CfdpManager::getDequeueEnabledParam(U8 channelIndex) {
766
1/1
✓ Branch 2 taken 3898 times.
3898 Fw::ParamValid valid;
767
768 3898 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
769
770 // Check for coding errors as all CFDP parameters must have a default
771 // Get the array first
772
1/1
✓ Branch 3 taken 3898 times.
3898 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
773 3898 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
774
775 // Now get individual parameter
776
2/2
✓ Branch 2 taken 3898 times.
✓ Branch 9 taken 3898 times.
7796 return paramArray[channelIndex].get_dequeue_enabled();
777 3898 }
778
779 7 Fw::String CfdpManager::getMoveDirParam(U8 channelIndex) {
780
1/1
✓ Branch 2 taken 7 times.
7 Fw::ParamValid valid;
781
782 7 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
783
784 // Check for coding errors as all CFDP parameters must have a default
785 // Get the array first
786
1/1
✓ Branch 3 taken 7 times.
7 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
787 7 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
788
789 // Now get individual parameter
790
2/2
✓ Branch 2 taken 7 times.
✓ Branch 11 taken 7 times.
14 return paramArray[channelIndex].get_move_dir();
791 7 }
792
793 99 U32 CfdpManager ::getMaxOutgoingPdusPerCycleParam(U8 channelIndex) {
794
1/1
✓ Branch 2 taken 99 times.
99 Fw::ParamValid valid;
795
796 99 FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
797
798 // Check for coding errors as all CFDP parameters must have a default
799 // Get the array first
800
1/1
✓ Branch 3 taken 99 times.
99 ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
801 99 FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
802
803 // Now get individual parameter
804
1/1
✓ Branch 2 taken 99 times.
198 return paramArray[channelIndex].get_max_outgoing_pdus_per_cycle();
805 99 }
806
807 } // namespace Cfdp
808 } // namespace Ccsds
809 } // namespace Svc
810