F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
CfdpManager.cpp
Go to the documentation of this file.
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>
13 #include <new>
14 
15 namespace Svc {
16 namespace Ccsds {
17 namespace Cfdp {
18 
19 // ----------------------------------------------------------------------
20 // Component construction and destruction
21 // ----------------------------------------------------------------------
22 
23 CfdpManager ::CfdpManager(const char* const compName) : CfdpManagerComponentBase(compName), m_engine(nullptr) {}
24 
26  // Clean up the queue resources allocated during initialization
27  this->deinit();
28 
29  // If cleanup() was not called, clean up manually
30  if (this->m_engine != nullptr) {
31  this->cleanup();
32  }
33 }
34 
35 void CfdpManager ::configure(Fw::MemAllocator& allocator, FwSizeType fileQueueDepth, FwEnumStoreType memId) {
36  // Allocate and initialize the CFDP engine
37  FwSizeType engineSize = sizeof(Engine);
38  this->m_engine = static_cast<Engine*>(allocator.allocate(memId, engineSize));
39  FW_ASSERT(this->m_engine != nullptr);
40  (void)new (this->m_engine) Engine(this);
41  this->m_engine->init(allocator, memId);
42 
43  // Store allocator for cleanup
44  this->m_allocator = &allocator;
45  this->m_allocatorId = memId;
46 
47  // Initialize telemetry counters to zero
48  for (U8 i = 0; i < Cfdp::NumChannels; i++) {
49  this->m_channelTelemetry[i] = Cfdp::ChannelTelemetry();
50  }
51 
52  // Create the fileIn request handoff queue
53  this->m_fileInQueueDepth = fileQueueDepth;
54  Os::Queue::Status queueStat =
55  this->m_fileInQueue.create(this->getInstance(), Os::QueueString("cfdpFileInQueue"), fileQueueDepth,
56  static_cast<FwSizeType>(sizeof(FileInRequest)));
57  FW_ASSERT(queueStat == Os::Queue::OP_OK, static_cast<FwAssertArgType>(queueStat));
58 }
59 
61  this->m_fileInQueue.teardown();
63 }
64 
66  // Only try to deallocate if both pointers are non-null
67  if ((this->m_allocator != nullptr) && (this->m_engine != nullptr)) {
68  // Manually call destructor since we used placement new
69  this->m_engine->~Engine();
70  // Deallocate the memory
71  this->m_allocator->deallocate(this->m_allocatorId, this->m_engine);
72  this->m_engine = nullptr;
73  }
74 }
75 
76 // ----------------------------------------------------------------------
77 // Handler implementations for typed input ports
78 // ----------------------------------------------------------------------
79 
80 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  FW_ASSERT(this->m_engine != nullptr);
83 
84  // Drain any port-initiated file send requests before cycling the engine
85  this->drainFileInQueue();
86 
87  this->m_engine->cycle();
88 
89  // Emit telemetry once per second
90  this->tlmWrite_ChannelTelemetry(this->m_channelTelemetry);
91 }
92 
93 void CfdpManager ::drainFileInQueue() {
94  FW_ASSERT(this->m_engine != nullptr);
95 
96  // Drain the whole queue; the depth bound guarantees the loop terminates.
97  for (FwSizeType drained = 0; drained < this->m_fileInQueueDepth; drained++) {
98  FileInRequest request;
99  FwSizeType actualSize = 0;
100  FwQueuePriorityType priority = 0;
101  Os::Queue::Status status =
102  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  if (status != Os::Queue::Status::OP_OK || actualSize != sizeof(request)) {
107  break;
108  }
109 
110  // Look up the per-channel default parameters
111  Fw::ParamValid valid;
112  U8 channelId = this->paramGet_FileInDefaultChannel(valid);
113  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  if (channelId >= Cfdp::NumChannels) {
119  continue;
120  }
121 
122  EntityId destEid = this->paramGet_FileInDefaultDestEntityId(valid);
123  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
124 
125  Class::T cfdpClass = this->paramGet_FileInDefaultClass(valid);
126  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
127 
128  Keep::T keep = this->paramGet_FileInDefaultKeep(valid);
129  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
130 
131  U8 priorityParam = this->paramGet_FileInDefaultPriority(valid);
132  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  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  if (txStatus != Status::SUCCESS) {
142  this->log_WARNING_LO_SendFileInitiateFail(request.sourceFileName);
144  }
145  }
146 }
147 
148 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  FW_ASSERT(portNum < Cfdp::NumChannels, portNum, Cfdp::NumChannels);
152  this->bufferDeallocate_out(portNum, fwBuffer);
153 }
154 
155 void CfdpManager ::dataIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
156  // There is a direct mapping between port number and channel index
157  FW_ASSERT(portNum < Cfdp::NumChannels, portNum, Cfdp::NumChannels);
158  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  if (fwBuffer.getSize() < sizeof(FwPacketDescriptorType)) {
163  // Buffer too small - silently ignore
164  this->dataInReturn_out(portNum, fwBuffer);
165  return;
166  }
167 
168  // Read and verify packet type descriptor
169  FwPacketDescriptorType packetType = 0;
170  Fw::SerializeStatus status = fwBuffer.getDeserializer().deserializeTo(packetType);
171  if (status != Fw::FW_SERIALIZE_OK || packetType != Fw::ComPacketType::FW_PACKET_FILE) {
172  // Invalid packet type - silently ignore (consistent with FileUplink behavior)
173  this->dataInReturn_out(portNum, fwBuffer);
174  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  const FwSizeType descriptorSize = sizeof(FwPacketDescriptorType);
182  Fw::Buffer pduBuffer(fwBuffer.getData() + descriptorSize, fwBuffer.getSize() - descriptorSize,
183  fwBuffer.getContext());
184 
185  // Pass the adjusted buffer to the engine
186  FW_ASSERT(this->m_engine != nullptr);
187  this->m_engine->receivePdu(static_cast<U8>(portNum), pduBuffer);
188 
189  // Return buffer
190  this->dataInReturn_out(portNum, fwBuffer);
191 }
192 
193 Svc::SendFileResponse CfdpManager ::fileIn_handler(FwIndexType portNum,
194  const Fw::StringBase& sourceFileName,
195  const Fw::StringBase& destFileName,
196  U32 offset,
197  U32 length) {
198  Svc::SendFileResponse response;
199  // Set context to portNum so we can identify this transaction later
200  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  if (offset > 0 || length > 0) {
206  this->log_WARNING_LO_UnsupportedSendFileArguments(offset, length);
207  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  FileInRequest request;
215 
216  // Guard against filenames that would not fit in the queued request
217  if (sourceFileName.length() >= request.sourceFileName.getCapacity() ||
218  destFileName.length() >= request.destFileName.getCapacity()) {
220  this->log_WARNING_LO_SendFileInitiateFail(sourceFileName);
221  return response;
222  }
223 
224  request.sourceFileName = sourceFileName;
225  request.destFileName = destFileName;
226  request.context = static_cast<U32>(portNum);
227 
228  Os::Queue::Status status =
229  this->m_fileInQueue.send(reinterpret_cast<U8*>(&request), static_cast<FwSizeType>(sizeof(request)), 0,
230  Os::Queue::BlockingType::NONBLOCKING);
231 
232  if (status != Os::Queue::Status::OP_OK) {
233  // Queue full - reject the request so the caller can retry later
235  this->log_WARNING_LO_SendFileInitiateFail(sourceFileName);
236  } else {
238  }
239 
240  return response;
241 }
242 
243 void CfdpManager ::pingIn_handler(FwIndexType portNum, U32 key) {
244  // send ping response
245  this->pingOut_out(0, key);
246 }
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 
256  Status::T status = Status::ERROR;
257  FwIndexType portNum;
258 
259  // There is a direct mapping between channel index and port number
260  portNum = static_cast<FwIndexType>(channel.getChannelId());
261 
262  // Check if we have reached the maximum number of output PDUs for this cycle
263  U32 max_pdus = getMaxOutgoingPdusPerCycleParam(channel.getChannelId());
264  if (channel.getOutgoingCounter() >= max_pdus) {
266  } else {
267  buffer = this->bufferAllocate_out(portNum, size);
268  // Check the allocation was successful based on size
269  if (buffer.getSize() == size) {
270  channel.incrementOutgoingCounter();
271  status = Status::SUCCESS;
272  } else {
275  }
276  }
277  return status;
278 }
279 
281  FwIndexType portNum;
282 
283  // There is a direct mapping between channel index and port number
284  portNum = static_cast<FwIndexType>(channel.getChannelId());
285 
286  // Was unable to successfully populate the PDU buffer, return it
287  this->bufferDeallocate_out(portNum, pduBuffer);
288 }
289 
290 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  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  U8* bufferData = pduBuffer.getData();
301 
302  // Write FW_PACKET_FILE descriptor at the beginning (big-endian U16)
303  const FwPacketDescriptorType descriptor = static_cast<FwPacketDescriptorType>(Fw::ComPacketType::FW_PACKET_FILE);
304  bufferData[0] = static_cast<U8>((descriptor >> 8) & 0xFF); // High byte
305  bufferData[1] = static_cast<U8>(descriptor & 0xFF); // Low byte
306 
307  // Send buffer with descriptor
308  this->dataOut_out(portNum, pduBuffer);
309 }
310 
312  Svc::SendFileResponse response;
313  response.set_status(status);
314  response.set_context(0);
315 
316  this->fileDoneOut_out(0, response);
317 }
318 
319 // ----------------------------------------------------------------------
320 // Handler implementations for commands
321 // ----------------------------------------------------------------------
322 
323 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) {
333 
334  // Check channel index is in range
335  rspStatus = this->checkCommandChannelIndex(channelId);
336  FW_ASSERT(this->m_engine != nullptr);
337 
338  if (rspStatus == Fw::CmdResponse::OK) {
339  if (Status::SUCCESS !=
340  this->m_engine->txFile(sourceFileName, destFileName, cfdpClass.e, keep.e, channelId, priority, destId)) {
341  // Engine emits specific failure reason EVR (e.g., MaxTxTransactionsReached)
343  }
344  }
345 
346  this->cmdResponse_out(opCode, cmdSeq, rspStatus);
347 }
348 
349 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) {
359 
360  FW_ASSERT(this->m_engine != nullptr);
361  // Check channel index is in range
362  rspStatus = this->checkCommandChannelIndex(channelId);
363 
364  if (rspStatus == Fw::CmdResponse::OK) {
365  if (Status::SUCCESS == this->m_engine->playbackDir(sourceDirectory.toChar(), destDirectory.toChar(),
366  cfdpClass.e, keep.e, channelId, priority, destId)) {
367  this->log_ACTIVITY_LO_PlaybackInitiated(sourceDirectory);
368  } else {
369  // Engine emits specific failure reason EVR (e.g., PlaybackDirOpenFailed, PlaybackDirSlotUnavailable)
371  }
372  }
373 
374  this->cmdResponse_out(opCode, cmdSeq, rspStatus);
375 }
376 
377 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) {
388 
389  FW_ASSERT(this->m_engine != nullptr);
390  // Check channel index and poll index are in range
391  rspStatus = this->checkCommandChannelIndex(channelId);
392  if (rspStatus == Fw::CmdResponse::OK) {
393  rspStatus = this->checkCommandChannelPollIndex(pollId);
394  }
395  if (rspStatus == Fw::CmdResponse::OK) {
396  rspStatus = this->checkCommandPollInterval(interval);
397  }
398 
399  if (rspStatus == Fw::CmdResponse::OK) {
400  if (Status::SUCCESS == this->m_engine->startPollDir(channelId, pollId, sourceDirectory, destDirectory,
401  cfdpClass.e, priority, destId, interval)) {
402  this->log_ACTIVITY_LO_PollDirInitiated(sourceDirectory, pollId);
403  } else {
404  // Failure EVR was already emitted
406  }
407  }
408 
409  this->cmdResponse_out(opCode, cmdSeq, rspStatus);
410 }
411 
412 void CfdpManager ::StopPollDirectory_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 channelId, U8 pollId) {
414 
415  FW_ASSERT(this->m_engine != nullptr);
416  // Check channel index and poll index are in range
417  rspStatus = this->checkCommandChannelIndex(channelId);
418  if (rspStatus == Fw::CmdResponse::OK) {
419  rspStatus = this->checkCommandChannelPollIndex(pollId);
420  }
421 
422  if ((rspStatus == Fw::CmdResponse::OK) && (Status::SUCCESS == this->m_engine->stopPollDir(channelId, pollId))) {
423  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  this->cmdResponse_out(opCode, cmdSeq, rspStatus);
430 }
431 
432 void CfdpManager ::SetChannelFlow_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 channelId, const Flow& flowState) {
434 
435  FW_ASSERT(this->m_engine != nullptr);
436  // Check channel index is in range
437  rspStatus = checkCommandChannelIndex(channelId);
438  if (rspStatus == Fw::CmdResponse::OK) {
439  this->m_engine->setChannelFlowState(channelId, flowState);
440  this->log_ACTIVITY_LO_SetFlowState(channelId, flowState);
441  }
442 
443  this->cmdResponse_out(opCode, cmdSeq, rspStatus);
444 }
445 
446 void CfdpManager ::SuspendResumeTransaction_cmdHandler(FwOpcodeType opCode,
447  U32 cmdSeq,
448  U8 channelId,
449  TransactionSeq transactionSeq,
450  EntityId entityId,
451  const SuspendResume& action) {
453 
454  FW_ASSERT(this->m_engine != nullptr);
455 
456  rspStatus = checkCommandChannelIndex(channelId);
457 
458  if (rspStatus == Fw::CmdResponse::OK) {
459  Status::T status = this->m_engine->setSuspendResumeTransaction(channelId, transactionSeq, entityId, action);
460  if (status == Status::SUCCESS) {
461  if (action == SuspendResume::SUSPEND) {
462  log_ACTIVITY_LO_TransactionSuspended(transactionSeq, entityId);
463  } else {
464  log_ACTIVITY_LO_TransactionResumed(transactionSeq, entityId);
465  }
466  } else {
467  log_WARNING_LO_TransactionNotFound(transactionSeq, entityId);
469  }
470  }
471 
472  this->cmdResponse_out(opCode, cmdSeq, rspStatus);
473 }
474 
475 void CfdpManager ::CancelTransaction_cmdHandler(FwOpcodeType opCode,
476  U32 cmdSeq,
477  U8 channelId,
478  TransactionSeq transactionSeq,
479  EntityId entityId) {
481 
482  FW_ASSERT(this->m_engine != nullptr);
483 
484  rspStatus = checkCommandChannelIndex(channelId);
485 
486  if (rspStatus == Fw::CmdResponse::OK) {
487  Status::T status = this->m_engine->cancelTransactionBySeq(channelId, transactionSeq, entityId);
488  if (status == Status::SUCCESS) {
489  log_ACTIVITY_HI_TransactionCanceled(transactionSeq, entityId);
490  } else {
491  log_WARNING_LO_TransactionNotFound(transactionSeq, entityId);
493  }
494  }
495 
496  this->cmdResponse_out(opCode, cmdSeq, rspStatus);
497 }
498 
499 void CfdpManager ::AbandonTransaction_cmdHandler(FwOpcodeType opCode,
500  U32 cmdSeq,
501  U8 channelId,
502  TransactionSeq transactionSeq,
503  EntityId entityId) {
505 
506  FW_ASSERT(this->m_engine != nullptr);
507 
508  rspStatus = checkCommandChannelIndex(channelId);
509 
510  if (rspStatus == Fw::CmdResponse::OK) {
511  Status::T status = this->m_engine->abandonTransaction(channelId, transactionSeq, entityId);
512  if (status == Status::SUCCESS) {
513  log_ACTIVITY_HI_TransactionAbandoned(transactionSeq, entityId);
514  } else {
515  log_WARNING_LO_TransactionNotFound(transactionSeq, entityId);
517  }
518  }
519 
520  this->cmdResponse_out(opCode, cmdSeq, rspStatus);
521 }
522 
523 void CfdpManager ::ResetCounters_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 channelId) {
524  // 0xFF means reset all channels
525  if (channelId == 0xFF) {
526  for (U8 i = 0; i < Cfdp::NumChannels; i++) {
527  this->m_channelTelemetry[i] = Cfdp::ChannelTelemetry();
528  }
529  this->log_ACTIVITY_HI_ResetCounters(0xFF);
530  }
531  // Otherwise reset specific channel
532  else if (channelId < Cfdp::NumChannels) {
533  this->m_channelTelemetry[channelId] = Cfdp::ChannelTelemetry();
534  this->log_ACTIVITY_HI_ResetCounters(channelId);
535  } else {
536  // Invalid channel ID
537  this->log_WARNING_LO_InvalidChannel(channelId, Cfdp::NumChannels - 1);
538  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
539  return;
540  }
541 
542  // Emit updated telemetry
543  this->tlmWrite_ChannelTelemetry(this->m_channelTelemetry);
544 
545  this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
546 }
547 
548 // ----------------------------------------------------------------------
549 // Private command helper functions
550 // ----------------------------------------------------------------------
551 
552 Fw::CmdResponse::T CfdpManager ::checkCommandChannelIndex(U8 channelIndex) {
553  if (channelIndex >= Cfdp::NumChannels) {
556  } else {
557  return Fw::CmdResponse::OK;
558  }
559 }
560 
561 Fw::CmdResponse::T CfdpManager ::checkCommandChannelPollIndex(U8 pollIndex) {
562  if (pollIndex >= MaxPollingDirPerChan) {
565  } else {
566  return Fw::CmdResponse::OK;
567  }
568 }
569 
570 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  if (interval == 0) {
574  this->log_WARNING_LO_InvalidPollInterval(interval);
576  } else {
577  return Fw::CmdResponse::OK;
578  }
579 }
580 
581 // ----------------------------------------------------------------------
582 // Parameter helpers used by the CFDP engine
583 // ----------------------------------------------------------------------
584 
586  Fw::ParamValid valid;
587 
588  // Check for coding errors as all CFDP parameters must have a default
589  EntityId localEid = this->paramGet_LocalEid(valid);
590  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
591 
592  return localEid;
593 }
594 
596  Fw::ParamValid valid;
597 
598  // Check for coding errors as all CFDP parameters must have a default
599  U32 chunkSize = this->paramGet_OutgoingFileChunkSize(valid);
600  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
601 
602  return chunkSize;
603 }
605  Fw::ParamValid valid;
606 
607  // Check for coding errors as all CFDP parameters must have a default
608  U32 rxSize = this->paramGet_RxCrcCalcBytesPerCycle(valid);
609  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
610 
611  return rxSize;
612 }
613 
615  Fw::ParamValid valid;
616 
617  // Check for coding errors as all CFDP parameters must have a default
618  U8 retries = this->paramGet_PostInactivitySendRetries(valid);
619  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
620 
621  return retries;
622 }
623 
625  Fw::ParamValid valid;
626 
627  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
628 
629  // Check for coding errors as all CFDP parameters must have a default
630  // Get the array first
631  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
632  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
633 
634  // Now get individual parameter
635  return paramArray[channelIndex].get_tmp_dir();
636 }
637 
639  Fw::ParamValid valid;
640 
641  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
642 
643  // Check for coding errors as all CFDP parameters must have a default
644  // Get the array first
645  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
646  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
647 
648  // Now get individual parameter
649  return paramArray[channelIndex].get_fail_dir();
650 }
651 
653  Fw::ParamValid valid;
654 
655  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
656 
657  // Check for coding errors as all CFDP parameters must have a default
658  // Get the array first
659  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
660  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
661 
662  // Now get individual parameter
663  return paramArray[channelIndex].get_ack_limit();
664 }
665 
667  Fw::ParamValid valid;
668 
669  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
670 
671  // Check for coding errors as all CFDP parameters must have a default
672  // Get the array first
673  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
674  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
675 
676  // Now get individual parameter
677  return paramArray[channelIndex].get_nack_limit();
678 }
679 
681  Fw::ParamValid valid;
682 
683  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
684 
685  // Check for coding errors as all CFDP parameters must have a default
686  // Get the array first
687  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
688  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
689 
690  // Now get individual parameter
691  return paramArray[channelIndex].get_ack_timer();
692 }
693 
695  Fw::ParamValid valid;
696 
697  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
698 
699  // Check for coding errors as all CFDP parameters must have a default
700  // Get the array first
701  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
702  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
703 
704  // Now get individual parameter
705  return paramArray[channelIndex].get_inactivity_timer();
706 }
707 
709  Fw::ParamValid valid;
710 
711  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
712 
713  // Check for coding errors as all CFDP parameters must have a default
714  // Get the array first
715  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
716  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
717 
718  // Now get individual parameter
719  return paramArray[channelIndex].get_dequeue_enabled();
720 }
721 
723  Fw::ParamValid valid;
724 
725  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
726 
727  // Check for coding errors as all CFDP parameters must have a default
728  // Get the array first
729  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
730  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
731 
732  // Now get individual parameter
733  return paramArray[channelIndex].get_move_dir();
734 }
735 
737  Fw::ParamValid valid;
738 
739  FW_ASSERT(channelIndex < Cfdp::NumChannels, channelIndex, Cfdp::NumChannels);
740 
741  // Check for coding errors as all CFDP parameters must have a default
742  // Get the array first
743  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
744  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
745 
746  // Now get individual parameter
747  return paramArray[channelIndex].get_max_outgoing_pdus_per_cycle();
748 }
749 
750 } // namespace Cfdp
751 } // namespace Ccsds
752 } // namespace Svc
void configure(Fw::MemAllocator &allocator, FwSizeType fileQueueDepth, FwEnumStoreType memId=0)
Definition: CfdpManager.cpp:35
Serialization/Deserialization operation was successful.
CFDP Protocol Engine.
Definition: Engine.hpp:89
Svc::Ccsds::Cfdp::Keep paramGet_FileInDefaultKeep(Fw::ParamValid &valid)
void log_ACTIVITY_LO_TransactionResumed(Svc::Ccsds::Cfdp::TransactionSeq transactionSeq, Svc::Ccsds::Cfdp::EntityId entityId) const
void sendFileComplete(Svc::SendFileStatus::T status)
Status create(FwEnumStoreType id, const Fw::ConstStringBase &name, FwSizeType depth, FwSizeType messageSize) override
create queue storage through delegate
Definition: Queue.cpp:22
U16 FwPacketDescriptorType
The width of packet descriptors when they are serialized by the framework.
U8 getChannelId() const
Get the channel ID.
Definition: Channel.hpp:178
Status::T txFile(const Fw::String &src, const Fw::String &dst, Class::T cfdp_class, Keep::T keep, U8 chan_num, U8 priority, EntityId dest_id, TransactionInitType initType=TransactionInitType::INIT_BY_COMMAND)
Begin transmit of a file.
Definition: Engine.cpp:746
CFDP Channel class.
Definition: Channel.hpp:56
Enum used to determine if a file should be kept or deleted after a CFDP transaction.
Definition: KeepEnumAc.hpp:22
virtual void * allocate(const FwEnumStoreType identifier, FwSizeType &size, bool &recoverable, FwSizeType alignment=alignof(std::max_align_t))=0
Status::T stopPollDir(U8 chanId, U8 pollId)
Stop polling a directory.
Definition: Engine.cpp:921
FwIdType FwOpcodeType
The type of a command opcode.
Operation succeeded.
Definition: Os.hpp:27
Status::T cancelTransactionBySeq(U8 channelId, TransactionSeq transactionSeq, EntityId entityId)
Cancel a transaction with graceful close-out.
Definition: Engine.cpp:695
#define FW_PARAM_OK(paramValid)
Definition: ParamValid.hpp:22
void set_status(Svc::SendFileStatus::T status)
Set member status.
PlatformSizeType FwSizeType
Status receive(U8 *destination, FwSizeType capacity, BlockingType blockType, FwSizeType &actualSize, FwQueuePriorityType &priority) override
receive a message from the queue through delegate
Definition: Queue.cpp:71
I32 FwEnumStoreType
void init(Fw::MemAllocator &allocator, FwEnumStoreType memId)
Initialize the CFDP engine.
Definition: Engine.cpp:88
Status
status returned from the queue send function
Definition: Queue.hpp:30
void pingOut_out(FwIndexType portNum, U32 key) const
Invoke output port pingOut.
enum T e
The raw enum value.
U32 getOutgoingCounter() const
Get the outgoing PDU counter for this cycle.
Definition: Channel.hpp:185
U32 EntityId
Entity id size.
void log_ACTIVITY_LO_TransactionSuspended(Svc::Ccsds::Cfdp::TransactionSeq transactionSeq, Svc::Ccsds::Cfdp::EntityId entityId) const
void dataInReturn_out(FwIndexType portNum, Fw::Buffer &fwBuffer) const
Invoke output port dataInReturn.
Auto-generated base for CfdpManager component.
SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG) override
Deserialize an 8-bit unsigned integer value.
U8 getNackLimitParam(U8 channelIndex)
enum T e
The raw enum value.
Definition: KeepEnumAc.hpp:207
U32 getContext() const
Definition: Buffer.cpp:102
FwEnumStoreType getInstance() const
void fileDoneOut_out(FwIndexType portNum, const Svc::SendFileResponse &resp) const
Invoke output port fileDoneOut.
U8 * getData() const
Definition: Buffer.cpp:82
void tlmWrite_ChannelTelemetry(const Svc::Ccsds::Cfdp::ChannelTelemetryArray &arg, Fw::Time _tlmTime=Fw::Time()) const
Fw::String getFailDirParam(U8 channelIndex)
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
T
The raw enum type.
~CfdpManager()
Destroy CfdpManager object.
Definition: CfdpManager.cpp:25
void log_ACTIVITY_HI_TransactionAbandoned(Svc::Ccsds::Cfdp::TransactionSeq transactionSeq, Svc::Ccsds::Cfdp::EntityId entityId) const
void log_ACTIVITY_HI_ResetCounters(U8 channelId) const
Log event ResetCounters.
void sendPduBuffer(Channel &channel, Fw::Buffer &pduBuffer)
void deinit() override
Tear down the fileIn request queue.
Definition: CfdpManager.cpp:60
Status::T startPollDir(U8 chanId, U8 pollId, const Fw::String &srcDir, const Fw::String &dstDir, Class::T cfdp_class, U8 priority, EntityId destEid, U32 intervalSec)
Start polling a directory.
Definition: Engine.cpp:884
CfdpManager(const char *const compName)
Construct CfdpManager object.
Definition: CfdpManager.cpp:23
SerializeStatus
forward declaration for string
void log_WARNING_LO_SendFileInitiateFail(const Fw::StringBase &sourceFileName) const
Log event SendFileInitiateFail.
ExternalSerializeBufferWithMemberCopy getDeserializer()
Definition: Buffer.cpp:165
U32 TransactionSeq
transaction sequence number size
void returnPduBuffer(Channel &channel, Fw::Buffer &pduBuffer)
Fw::Enabled getDequeueEnabledParam(U8 channelIndex)
void log_ACTIVITY_LO_PlaybackInitiated(const Fw::StringBase &sourceDirectory) const
Log event PlaybackInitiated.
U8 getAckLimitParam(U8 channelIndex)
Svc::Ccsds::Cfdp::Class paramGet_FileInDefaultClass(Fw::ParamValid &valid)
T
The raw enum type.
Definition: KeepEnumAc.hpp:36
virtual ~Engine()
Destroy the Engine object.
Definition: Engine.cpp:66
void setChannelFlowState(U8 channelId, Flow::T flowState)
Set channel flow state.
Definition: Engine.cpp:671
Status::T getPduBuffer(Fw::Buffer &buffer, Channel &channel, FwSizeType size)
Svc::Ccsds::Cfdp::EntityId paramGet_LocalEid(Fw::ParamValid &valid)
void log_WARNING_LO_InvalidChannelPoll(U8 pollId, U8 maxPollId) const
Log event InvalidChannelPoll.
void receivePdu(U8 chan_id, const Fw::Buffer &buffer)
Receive and process a PDU.
Definition: Engine.cpp:597
void log_ACTIVITY_HI_TransactionCanceled(Svc::Ccsds::Cfdp::TransactionSeq transactionSeq, Svc::Ccsds::Cfdp::EntityId entityId) const
void log_WARNING_LO_InvalidChannel(U8 channelId, U8 maxChannelId) const
Log event InvalidChannel.
void deinit() override
Allows de-initialization on teardown.
void log_WARNING_LO_TransactionNotFound(Svc::Ccsds::Cfdp::TransactionSeq transactionSeq, Svc::Ccsds::Cfdp::EntityId entityId) const
Status send(const U8 *buffer, FwSizeType size, FwQueuePriorityType priority, BlockingType blockType) override
send a message into the queue through delegate
Definition: Queue.cpp:54
T
The raw enum type.
void log_WARNING_LO_UnsupportedSendFileArguments(U32 offset, U32 length) const
Log event UnsupportedSendFileArguments.
Generic CFDP error return code.
void teardown() override
teardown the queue
Definition: Queue.cpp:49
void log_ACTIVITY_LO_PollDirInitiated(const Fw::StringBase &sourceDirectory, U8 pollId) const
Log event PollDirInitiated.
const char * toChar() const
Convert to a C-style char*.
enum T e
The raw enum value.
Enabled and disabled states.
Command successfully executed.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
void dataOut_out(FwIndexType portNum, Fw::Buffer &fwBuffer) const
Invoke output port dataOut.
CFDP operation has been successful.
void bufferDeallocate_out(FwIndexType portNum, Fw::Buffer &fwBuffer) const
Invoke output port bufferDeallocate.
FwSizeType getSize() const
Definition: Buffer.cpp:90
U32 getAckTimerParam(U8 channelIndex)
void log_ACTIVITY_LO_SetFlowState(U8 channelId, const Svc::Ccsds::Cfdp::Flow &flowState) const
Log event SetFlowState.
Fw::Buffer bufferAllocate_out(FwIndexType portNum, FwSizeType size) const
Invoke output port bufferAllocate.
U32 getInactivityTimerParam(U8 channelIndex)
PlatformQueuePriorityType FwQueuePriorityType
The type of queue priorities used.
Command had execution error.
Structure for telemetry counters for a single CFDP channel.
void cycle()
Cycle the engine once per scheduler call.
Definition: Engine.cpp:951
Memory Allocation base class.
void log_WARNING_LO_BuffersExhausted() const
Log event BuffersExhausted.
PlatformIndexType FwIndexType
Transaction initiated via port interface.
Send file response struct.
void set_context(U32 context)
Set member context.
void incrementOutgoingCounter()
Increment the outgoing PDU counter.
Definition: Channel.hpp:190
void log_WARNING_LO_InvalidPollInterval(U32 interval) const
Log event InvalidPollInterval.
Structure for the telemetry array of CFDP channels.
Command failed validation.
RateGroupDivider component implementation.
virtual SizeType length() const
Get the length of the string.
message sent/received okay
Definition: Queue.hpp:31
Svc::Ccsds::Cfdp::EntityId paramGet_FileInDefaultDestEntityId(Fw::ParamValid &valid)
Enum representing parameter validity.
Status::T setSuspendResumeTransaction(U8 channelId, TransactionSeq transactionSeq, EntityId entityId, SuspendResume::T action)
Set transaction suspend state.
Definition: Engine.cpp:676
U32 getMaxOutgoingPdusPerCycleParam(U8 channelIndex)
Fw::String getTmpDirParam(U8 channelIndex)
void cleanup()
Cleanup CFDP engine and deallocate resources.
Definition: CfdpManager.cpp:65
Fw::String getMoveDirParam(U8 channelIndex)
virtual void deallocate(const FwEnumStoreType identifier, void *ptr)=0
Svc::Ccsds::Cfdp::ChannelArrayParams paramGet_ChannelConfig(Fw::ParamValid &valid)
Status::T abandonTransaction(U8 channelId, TransactionSeq transactionSeq, EntityId entityId)
Abandon a transaction immediately.
Definition: Engine.cpp:711
Send PDU: No send buffer available, throttling limit reached.
T
The raw enum type.
Definition: ClassEnumAc.hpp:42
Status::T playbackDir(const Fw::String &src, const Fw::String &dst, Class::T cfdp_class, Keep::T keep, U8 chan, U8 priority, EntityId dest_id)
Begin transmit of a directory.
Definition: Engine.cpp:855
#define FW_ASSERT(...)
Definition: Assert.hpp:14
void log_ACTIVITY_LO_PollDirStopped(U8 channelId, U8 pollId) const
Log event PollDirStopped.