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 update handling
583 // ----------------------------------------------------------------------
584 
585 void CfdpManager ::parameterUpdated(FwPrmIdType id) {
586  // Re-emit only the parameter that changed so ground can verify the active
587  // configuration.
588  Fw::ParamValid valid;
589  switch (id) {
590  case PARAMID_LOCALEID: {
591  this->tlmWrite_PRM_LOCAL_EID(this->paramGet_LocalEid(valid));
592  break;
593  }
596  break;
597  }
600  break;
601  }
604  break;
605  }
608  break;
609  }
612  break;
613  }
616  break;
617  }
620  break;
621  }
624  break;
625  }
626  case PARAMID_CHANNELCONFIG: {
628  break;
629  }
630  default: {
631  FW_ASSERT(false, static_cast<FwAssertArgType>(id)); // coding error, forgot to include in switch statement
632  }
633  }
634 
635  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
636 }
637 
638 // ----------------------------------------------------------------------
639 // Parameter helpers used by the CFDP engine
640 // ----------------------------------------------------------------------
641 
643  Fw::ParamValid valid;
644 
645  // Check for coding errors as all CFDP parameters must have a default
646  EntityId localEid = this->paramGet_LocalEid(valid);
647  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
648 
649  return localEid;
650 }
651 
653  Fw::ParamValid valid;
654 
655  // Check for coding errors as all CFDP parameters must have a default
656  U32 chunkSize = this->paramGet_OutgoingFileChunkSize(valid);
657  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
658 
659  return chunkSize;
660 }
662  Fw::ParamValid valid;
663 
664  // Check for coding errors as all CFDP parameters must have a default
665  U32 rxSize = this->paramGet_RxCrcCalcBytesPerCycle(valid);
666  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
667 
668  return rxSize;
669 }
670 
672  Fw::ParamValid valid;
673 
674  // Check for coding errors as all CFDP parameters must have a default
675  U8 retries = this->paramGet_PostInactivitySendRetries(valid);
676  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
677 
678  return retries;
679 }
680 
682  Fw::ParamValid valid;
683 
684  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
689  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
690 
691  // Now get individual parameter
692  return paramArray[channelIndex].get_tmp_dir();
693 }
694 
696  Fw::ParamValid valid;
697 
698  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
703  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
704 
705  // Now get individual parameter
706  return paramArray[channelIndex].get_fail_dir();
707 }
708 
710  Fw::ParamValid valid;
711 
712  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
717  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
718 
719  // Now get individual parameter
720  return paramArray[channelIndex].get_ack_limit();
721 }
722 
724  Fw::ParamValid valid;
725 
726  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
731  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
732 
733  // Now get individual parameter
734  return paramArray[channelIndex].get_nack_limit();
735 }
736 
738  Fw::ParamValid valid;
739 
740  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
745  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
746 
747  // Now get individual parameter
748  return paramArray[channelIndex].get_ack_timer();
749 }
750 
752  Fw::ParamValid valid;
753 
754  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
759  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
760 
761  // Now get individual parameter
762  return paramArray[channelIndex].get_inactivity_timer();
763 }
764 
766  Fw::ParamValid valid;
767 
768  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
773  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
774 
775  // Now get individual parameter
776  return paramArray[channelIndex].get_dequeue_enabled();
777 }
778 
780  Fw::ParamValid valid;
781 
782  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
787  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
788 
789  // Now get individual parameter
790  return paramArray[channelIndex].get_move_dir();
791 }
792 
794  Fw::ParamValid valid;
795 
796  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  ChannelArrayParams paramArray = paramGet_ChannelConfig(valid);
801  FW_ASSERT(FW_PARAM_OK(valid), static_cast<FwAssertArgType>(valid.e));
802 
803  // Now get individual parameter
804  return paramArray[channelIndex].get_max_outgoing_pdus_per_cycle();
805 }
806 
807 } // namespace Cfdp
808 } // namespace Ccsds
809 } // namespace Svc
void configure(Fw::MemAllocator &allocator, FwSizeType fileQueueDepth, FwEnumStoreType memId=0)
Definition: CfdpManager.cpp:35
Serialization/Deserialization operation was successful.
void tlmWrite_PRM_FILE_IN_DEFAULT_CHANNEL(U8 arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_FILE_IN_DEFAULT_CHANNEL.
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.
void tlmWrite_PRM_POST_INACTIVITY_SEND_RETRIES(U8 arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_POST_INACTIVITY_SEND_RETRIES.
Auto-generated base for CfdpManager component.
SerializeStatus deserializeTo(U8 &val, Endianness mode=Endianness::BIG) override
Deserialize an 8-bit unsigned integer value.
FwIdType FwPrmIdType
The type of a parameter identifier.
U8 getNackLimitParam(U8 channelIndex)
enum T e
The raw enum value.
Definition: KeepEnumAc.hpp:207
Default file retention policy for fileIn port-initiated file transfers.
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.
Parameter configuration for an array CFDP channels.
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
CFDP ID to denote the current node when sending PDUs.
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
The maximum number of received bytes to calculate a CRC for in a single scheduler cycle...
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)
Default CFDP channel for fileIn port-initiated file transfers.
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 tlmWrite_PRM_LOCAL_EID(Svc::Ccsds::Cfdp::EntityId arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_LOCAL_EID.
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 tlmWrite_PRM_FILE_IN_DEFAULT_PRIORITY(U8 arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_FILE_IN_DEFAULT_PRIORITY.
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
Default destination entity ID for fileIn port-initiated file transfers.
Default CFDP class for fileIn port-initiated file transfers.
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.
void tlmWrite_PRM_CHANNEL_CONFIG(const Svc::Ccsds::Cfdp::ChannelArrayParams &arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_CHANNEL_CONFIG.
const char * toChar() const
Convert to a C-style char*.
enum T e
The raw enum value.
Enabled and disabled states.
Command successfully executed.
void tlmWrite_PRM_OUTGOING_FILE_CHUNK_SIZE(U32 arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_OUTGOING_FILE_CHUNK_SIZE.
Default priority for fileIn port-initiated file transfers.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
void dataOut_out(FwIndexType portNum, Fw::Buffer &fwBuffer) const
Invoke output port dataOut.
void tlmWrite_PRM_RX_CRC_CALC_BYTES_PER_CYCLE(U32 arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_RX_CRC_CALC_BYTES_PER_CYCLE.
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 tlmWrite_PRM_FILE_IN_DEFAULT_DEST_ENTITY_ID(Svc::Ccsds::Cfdp::EntityId arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_FILE_IN_DEFAULT_DEST_ENTITY_ID.
void cycle()
Cycle the engine once per scheduler call.
Definition: Engine.cpp:951
Memory Allocation base class.
void tlmWrite_PRM_FILE_IN_DEFAULT_CLASS(const Svc::Ccsds::Cfdp::Class &arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_FILE_IN_DEFAULT_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 tlmWrite_PRM_FILE_IN_DEFAULT_KEEP(const Svc::Ccsds::Cfdp::Keep &arg, Fw::Time _tlmTime=Fw::Time())
Write telemetry channel PRM_FILE_IN_DEFAULT_KEEP.
void log_ACTIVITY_LO_PollDirStopped(U8 channelId, U8 pollId) const
Log event PollDirStopped.