2022-03-29 15:07:29 +02:00
|
|
|
#ifndef MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_
|
|
|
|
#define MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_
|
|
|
|
|
|
|
|
#include <etl/multimap.h>
|
|
|
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
|
|
|
#include <fsfw/tmtcservices/TmTcMessage.h>
|
|
|
|
|
|
|
|
#include "fsfw/FSFW.h"
|
2022-05-12 16:53:34 +02:00
|
|
|
#include "fsfw/returnvalues/FwClassIds.h"
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief: PUS-Service 11 - Telecommand scheduling.
|
|
|
|
* @details:
|
|
|
|
* PUS-Service 11 - Telecommand scheduling.
|
|
|
|
* Full documentation: ECSS-E-ST-70-41C, p. 168:
|
|
|
|
* ST[11] time-based scheduling
|
|
|
|
*
|
|
|
|
* This service provides the capability to command pre-loaded
|
|
|
|
* application processes (telecommands) by releasing them at their
|
|
|
|
* due-time.
|
|
|
|
* References to telecommands are stored together with their due-timepoints
|
|
|
|
* and are released at their corresponding due-time.
|
|
|
|
*
|
|
|
|
* Necessary subservice functionalities are implemented.
|
|
|
|
* Those are:
|
|
|
|
* TC[11,4] activity insertion
|
|
|
|
* TC[11,5] activity deletion
|
|
|
|
* TC[11,6] filter-based activity deletion
|
|
|
|
* TC[11,7] activity time-shift
|
|
|
|
* TC[11,8] filter-based activity time-shift
|
|
|
|
*
|
|
|
|
* Groups are not supported.
|
|
|
|
* This service remains always enabled. Sending a disable-request has no effect.
|
|
|
|
*/
|
|
|
|
template <size_t MAX_NUM_TCS>
|
|
|
|
class Service11TelecommandScheduling final : public PusServiceBase {
|
|
|
|
public:
|
2022-05-12 16:53:34 +02:00
|
|
|
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_11;
|
|
|
|
|
2022-08-22 15:02:16 +02:00
|
|
|
static constexpr ReturnValue_t INVALID_TYPE_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 1);
|
2022-08-30 15:16:54 +02:00
|
|
|
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
|
|
|
|
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
|
|
|
|
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
|
2022-05-12 17:05:58 +02:00
|
|
|
|
2022-05-24 11:52:29 +02:00
|
|
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
|
|
|
|
|
|
|
//! [EXPORT] : [COMMENT] Deletion of a TC from the map failed.
|
|
|
|
//! P1: First 32 bit of request ID, P2. Last 32 bit of Request ID
|
|
|
|
static constexpr Event TC_DELETION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
|
|
|
|
2022-03-29 15:07:29 +02:00
|
|
|
// The types of PUS-11 subservices
|
2022-05-24 10:40:25 +02:00
|
|
|
enum Subservice : uint8_t {
|
|
|
|
ENABLE_SCHEDULING = 1,
|
|
|
|
DISABLE_SCHEDULING = 2,
|
|
|
|
RESET_SCHEDULING = 3,
|
|
|
|
INSERT_ACTIVITY = 4,
|
|
|
|
DELETE_ACTIVITY = 5,
|
|
|
|
FILTER_DELETE_ACTIVITY = 6,
|
|
|
|
TIMESHIFT_ACTIVITY = 7,
|
|
|
|
FILTER_TIMESHIFT_ACTIVITY = 8,
|
|
|
|
DETAIL_REPORT = 9,
|
|
|
|
TIMEBASE_SCHEDULE_DETAIL_REPORT = 10,
|
|
|
|
TIMESHIFT_ALL_SCHEDULE_ACTIVITIES = 15
|
|
|
|
};
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
// The types of time windows for TC[11,6] and TC[11,8], as defined in ECSS-E-ST-70-41C,
|
|
|
|
// requirement 8.11.3c (p. 507)
|
|
|
|
enum TypeOfTimeWindow : uint32_t {
|
|
|
|
SELECT_ALL = 0,
|
|
|
|
FROM_TIMETAG_TO_TIMETAG = 1,
|
|
|
|
FROM_TIMETAG = 2,
|
|
|
|
TO_TIMETAG = 3
|
|
|
|
};
|
|
|
|
|
2022-07-27 11:26:47 +02:00
|
|
|
Service11TelecommandScheduling(PsbParams params, AcceptsTelecommandsIF* tcRecipient,
|
2022-03-29 15:07:29 +02:00
|
|
|
uint16_t releaseTimeMarginSeconds = DEFAULT_RELEASE_TIME_MARGIN,
|
|
|
|
bool debugMode = false);
|
|
|
|
|
2022-05-20 08:34:14 +02:00
|
|
|
~Service11TelecommandScheduling() override;
|
2022-03-29 15:07:29 +02:00
|
|
|
|
2022-05-24 11:52:29 +02:00
|
|
|
void enableExpiredTcDeletion();
|
|
|
|
void disableExpiredTcDeletion();
|
|
|
|
|
2022-03-29 15:07:29 +02:00
|
|
|
/** PusServiceBase overrides */
|
|
|
|
ReturnValue_t handleRequest(uint8_t subservice) override;
|
|
|
|
ReturnValue_t performService() override;
|
|
|
|
ReturnValue_t initialize() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
struct TelecommandStruct {
|
2022-05-20 08:34:14 +02:00
|
|
|
uint64_t requestId{};
|
|
|
|
uint32_t seconds{};
|
2022-03-29 15:07:29 +02:00
|
|
|
store_address_t storeAddr; // uint16
|
|
|
|
};
|
|
|
|
|
|
|
|
static constexpr uint16_t DEFAULT_RELEASE_TIME_MARGIN = 5;
|
|
|
|
|
|
|
|
// minimum release time offset to insert into schedule
|
|
|
|
const uint16_t RELEASE_TIME_MARGIN_SECONDS = 5;
|
|
|
|
|
2022-05-24 11:52:29 +02:00
|
|
|
/**
|
|
|
|
* By default, the scheduling will be disabled. This is a standard requirement
|
|
|
|
*/
|
|
|
|
bool schedulingEnabled = false;
|
|
|
|
bool deleteExpiredTcWhenDisabled = true;
|
2022-03-29 15:07:29 +02:00
|
|
|
bool debugMode = false;
|
|
|
|
StorageManagerIF* tcStore = nullptr;
|
|
|
|
AcceptsTelecommandsIF* tcRecipient = nullptr;
|
|
|
|
MessageQueueId_t recipientMsgQueueId = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The telecommand map uses the exectution time as a Unix time stamp as
|
|
|
|
* the key. This is mapped to a generic telecommand struct.
|
|
|
|
*/
|
|
|
|
using TelecommandMap = etl::multimap<uint32_t, TelecommandStruct, MAX_NUM_TCS>;
|
|
|
|
using TcMapIter = typename TelecommandMap::iterator;
|
|
|
|
|
|
|
|
TelecommandMap telecommandMap;
|
|
|
|
|
2022-05-24 11:52:29 +02:00
|
|
|
ReturnValue_t handleResetCommand();
|
2022-03-29 15:07:29 +02:00
|
|
|
/**
|
|
|
|
* @brief Logic to be performed on an incoming TC[11,4].
|
2022-08-16 12:12:21 +02:00
|
|
|
* @return returnvalue::OK if successful
|
2022-03-29 15:07:29 +02:00
|
|
|
*/
|
2022-05-12 16:53:34 +02:00
|
|
|
ReturnValue_t doInsertActivity(const uint8_t* data, size_t size);
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Logic to be performed on an incoming TC[11,5].
|
2022-08-16 12:12:21 +02:00
|
|
|
* @return returnvalue::OK if successful
|
2022-03-29 15:07:29 +02:00
|
|
|
*/
|
2022-05-12 16:53:34 +02:00
|
|
|
ReturnValue_t doDeleteActivity(const uint8_t* data, size_t size);
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Logic to be performed on an incoming TC[11,6].
|
2022-08-16 12:12:21 +02:00
|
|
|
* @return returnvalue::OK if successful
|
2022-03-29 15:07:29 +02:00
|
|
|
*/
|
2022-05-12 16:53:34 +02:00
|
|
|
ReturnValue_t doFilterDeleteActivity(const uint8_t* data, size_t size);
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Logic to be performed on an incoming TC[11,7].
|
2022-08-16 12:12:21 +02:00
|
|
|
* @return returnvalue::OK if successful
|
2022-03-29 15:07:29 +02:00
|
|
|
*/
|
2022-05-12 16:53:34 +02:00
|
|
|
ReturnValue_t doTimeshiftActivity(const uint8_t* data, size_t size);
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Logic to be performed on an incoming TC[11,8].
|
2022-08-16 12:12:21 +02:00
|
|
|
* @return returnvalue::OK if successful
|
2022-03-29 15:07:29 +02:00
|
|
|
*/
|
2022-05-12 16:53:34 +02:00
|
|
|
ReturnValue_t doFilterTimeshiftActivity(const uint8_t* data, size_t size);
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Extracts the Request ID from the Application Data of a TC by utilizing a ctor of the
|
|
|
|
* class TcPacketPus.
|
|
|
|
* NOTE: This only works if the payload data is a TC (e.g. not for TC[11,5] which does not
|
|
|
|
* send a TC as payload)!
|
|
|
|
* @param data The Application data of the TC (get via getApplicationData()).
|
|
|
|
* @return requestId
|
|
|
|
*/
|
2022-07-27 11:26:47 +02:00
|
|
|
[[nodiscard]] uint64_t getRequestIdFromTc() const;
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Extracts the Request ID from the Application Data directly, assuming it is packed
|
|
|
|
* as follows (acc. to ECSS): | source ID (uint32) | apid (uint32) | ssc (uint32) |.
|
|
|
|
* @param data Pointer to first byte described data
|
|
|
|
* @param dataSize Remaining size of data NOTE: non-const, this is modified by the function
|
|
|
|
* @param [out] requestId Request ID
|
2022-08-16 12:12:21 +02:00
|
|
|
* @return returnvalue::OK if successful
|
2022-03-29 15:07:29 +02:00
|
|
|
*/
|
2022-05-12 16:53:34 +02:00
|
|
|
ReturnValue_t getRequestIdFromData(const uint8_t*& data, size_t& dataSize, uint64_t& requestId);
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Builds the Request ID from its three elements.
|
|
|
|
* @param sourceId Source ID
|
|
|
|
* @param apid Application Process ID (APID)
|
|
|
|
* @param ssc Source Sequence Count
|
|
|
|
* @return Request ID
|
|
|
|
*/
|
2022-05-20 08:34:14 +02:00
|
|
|
[[nodiscard]] uint64_t buildRequestId(uint32_t sourceId, uint16_t apid, uint16_t ssc) const;
|
2022-03-29 15:07:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Gets the filter range for filter TCs from a data packet
|
|
|
|
* @param data TC data
|
|
|
|
* @param dataSize TC data size
|
|
|
|
* @param [out] itBegin Begin of filter range
|
|
|
|
* @param [out] itEnd End of filter range
|
2022-08-16 12:12:21 +02:00
|
|
|
* @return returnvalue::OK if successful
|
2022-03-29 15:07:29 +02:00
|
|
|
*/
|
2022-05-12 16:53:34 +02:00
|
|
|
ReturnValue_t getMapFilterFromData(const uint8_t*& data, size_t& size, TcMapIter& itBegin,
|
2022-03-29 15:07:29 +02:00
|
|
|
TcMapIter& itEnd);
|
|
|
|
|
2022-05-12 16:53:34 +02:00
|
|
|
ReturnValue_t handleInvalidData(const char* ctx);
|
2022-03-29 15:07:29 +02:00
|
|
|
/**
|
|
|
|
* @brief Prints content of multimap. Use for simple debugging only.
|
|
|
|
*/
|
2022-05-20 08:34:14 +02:00
|
|
|
void debugPrintMultimapContent() const;
|
2022-03-29 15:07:29 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#include "Service11TelecommandScheduling.tpp"
|
|
|
|
|
|
|
|
#endif /* MISSION_PUS_SERVICE11TELECOMMANDSCHEDULING_H_ */
|