Skip to content
Snippets Groups Projects
TimeBasedSchedulingService.hpp 10.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef ECSS_SERVICES_TIMEBASEDSCHEDULINGSERVICE_HPP
    #define ECSS_SERVICES_TIMEBASEDSCHEDULINGSERVICE_HPP
    
    
    #include "ErrorHandler.hpp"
    
    #include "Helpers/CRCHelper.hpp"
    
    Xhulio Luli's avatar
    Xhulio Luli committed
    #include "MessageParser.hpp"
    #include "Service.hpp"
    #include "etl/list.h"
    
    // Include platform specific files
    
    #include "Helpers/TimeGetter.hpp"
    
    /**
     * @def SUB_SCHEDULES_ENABLED
     * @brief Indicates whether sub-schedules are supported
     *
    
     * @details Sub-schedules are currently not implemented so this has no effect
    
     */
    /**
     * @def GROUPS_ENABLED
     * @brief Indicates whether scheduling groups are enabled
     */
    
    #define GROUPS_ENABLED 0
    #define SUB_SCHEDULES_ENABLED 0
    
    /**
     * @brief Namespace to access private members during test
     *
     * @details Define a namespace for the access of the private members to avoid conflicts
     */
    
    Xhulio Luli's avatar
    Xhulio Luli committed
    namespace unit_test {
    	struct Tester;
    
    Dimitrios Stoupis's avatar
    Dimitrios Stoupis committed
    } // namespace unit_test
    
    /**
     * @brief An implementation of the ECSS standard ST[11] service
     *
     * @details This service is taking care of the timed release of a received TC packet from the
     * ground.
    
     * @todo Define whether the parsed absolute release time is saved in the scheduled activity as an
     * uint32_t or in the time format specified by the time management service.
    
    class TimeBasedSchedulingService : public Service {
    
    private:
    
    	/**
    	 * @brief Indicator of the schedule execution
    
    athatheo's avatar
    athatheo committed
    	 * True indicates "enabled" and False "disabled" state
    
    	 * @details The schedule execution indicator will be updated by the process that is running
    	 * the time scheduling service.
    	 */
    
    athatheo's avatar
    athatheo committed
    	bool executionFunctionStatus = false;
    
    
    	/**
    	 * @brief Request identifier of the received packet
    	 *
    	 * @details The request identifier consists of the application process ID, the packet
    	 * sequence count and the source ID, all defined in the ECSS standard.
    	 */
    
    kongr45gpen's avatar
    kongr45gpen committed
    		uint16_t applicationID = 0; ///< Application process ID
    		uint16_t sequenceCount = 0; ///< Packet sequence count
    
    Xhulio Luli's avatar
    Xhulio Luli committed
    		uint8_t sourceID = 0;       ///< Packet source ID
    
    		bool operator!=(const RequestID& rightSide) const {
    			return (sequenceCount != rightSide.sequenceCount) or (applicationID != rightSide.applicationID) or
    			       (sourceID != rightSide.sourceID);
    
    	/**
    	 * @brief Instances of activities to run in the schedule
    	 *
    	 * @details All scheduled activities must contain the request they exist for, their release
    	 * time and the corresponding request identifier.
    
    	 *
    	 * @todo If we decide to use sub-schedules, the ID of that has to be defined
    	 * @todo If groups are used, then the group ID has to be defined here
    
    	struct ScheduledActivity {
    
    Xhulio Luli's avatar
    Xhulio Luli committed
    		Message request;                         ///< Hold the received command request
    		RequestID requestID;                     ///< Request ID, characteristic of the definition
    
    		Time::CustomCUC_t requestReleaseTime{0}; ///< Keep the command release time
    
    	/**
    	 * @brief Hold the scheduled activities
    	 *
    
    	 * @details The scheduled activities in this list are ordered by their release time, as the
    
    	 * standard requests.
    
    kchristin22's avatar
    kchristin22 committed
    	etl::list<ScheduledActivity, ECSSMaxNumberOfTimeSchedActivities> scheduledActivities;
    
    
    	/**
    	 * @brief Sort the activities by their release time
    	 *
    	 * @details The ECSS standard requires that the activities are sorted in the TM message
    	 * response. Also it is better to have the activities sorted.
    	 */
    
    kchristin22's avatar
    kchristin22 committed
    	sortActivitiesReleaseTime(etl::list<ScheduledActivity, ECSSMaxNumberOfTimeSchedActivities>& schedActivities) {
    
    		schedActivities.sort([](ScheduledActivity const& leftSide, ScheduledActivity const& rightSide) {
    
    kongr45gpen's avatar
    kongr45gpen committed
    			// cppcheck-suppress
    
    			return leftSide.requestReleaseTime < rightSide.requestReleaseTime;
    
    	/**
    	 * @brief Define a friend in order to be able to access private members during testing
    	 *
    
    	 * @details The private members defined in this class, must not in any way be public to avoid
    	 * misuse. During testing, access to private members for verification is required, so an
    	 * access friend structure is defined here.
    
    	friend struct ::unit_test::Tester;
    
    
    Xhulio Luli's avatar
    Xhulio Luli committed
    	/**
         * Notifies the timeBasedSchedulingTask after the insertion of activities to scheduleActivity list.
         */
    	void notifyNewActivityAddition();
    
    Xhulio Luli's avatar
    Xhulio Luli committed
    public:
    
    	inline static const uint8_t ServiceType = 11;
    
    	enum MessageType : uint8_t {
    		EnableTimeBasedScheduleExecutionFunction = 1,
    		DisableTimeBasedScheduleExecutionFunction = 2,
    		ResetTimeBasedSchedule = 3,
    		InsertActivities = 4,
    		DeleteActivitiesById = 5,
    		TimeShiftActivitiesById = 7,
    		DetailReportActivitiesById = 9,
    		TimeBasedScheduleReportById = 10,
    		ActivitiesSummaryReportById = 12,
    		TimeBasedScheduledSummaryReport = 13,
    		TimeShiftALlScheduledActivities = 15,
    		DetailReportAllScheduledActivities = 16,
    	};
    
    
    Dimitrios Stoupis's avatar
    Dimitrios Stoupis committed
    	/**
    	 * @brief Class constructor
    	 * @details Initializes the serviceType
    	 */
    
    	TimeBasedSchedulingService();
    
    
    Xhulio Luli's avatar
    Xhulio Luli committed
    	/**
    	 * This function executes the next activity and removes it from the list.
    	 * @return the requestReleaseTime of next activity to be executed after this time
    	 */
    	Time::CustomCUC_t executeScheduledActivity(Time::CustomCUC_t currentTime);
    
    
    	 * @brief TC[11,1] enable the time-based schedule execution function
    
    	 *
    	 * @details Enables the time-based command execution scheduling
    	 * @param request Provide the received message as a parameter
    	 */
    
    	void enableScheduleExecution(Message& request);
    
    kongr45gpen's avatar
    kongr45gpen committed
    	 * @brief TC[11,2] disable the time-based schedule execution function
    
    	 *
    	 * @details Disables the time-based command execution scheduling
    	 * @param request Provide the received message as a parameter
    	 */
    
    	void disableScheduleExecution(Message& request);
    
    	 * @brief TC[11,3] reset the time-based schedule
    
    	 * @details Resets the time-based command execution schedule, by clearing all scheduled
    	 * activities.
    
    	 * @param request Provide the received message as a parameter
    	 */
    
    	void resetSchedule(Message& request);
    
    	 * @brief TC[11,4] insert activities into the time based schedule
    
    	 * @details Add activities into the schedule for future execution. The activities are inserted
    	 * by ascending order of their release time. This done to avoid confusion during the
    	 * execution of the schedule and also to make things easier whenever a release time sorted
    	 * report is requested by he corresponding service.
    
    	 * @param request Provide the received message as a parameter
    
    	 * @todo Definition of the time format is required
    
    Dimitrios Stoupis's avatar
    Dimitrios Stoupis committed
    	 * @throws ExecutionStartError If there is request to be inserted and the maximum
    	 * number of activities in the current schedule has been reached, then an @ref
    	 * ErrorHandler::ExecutionStartErrorType is being issued.  Also if the release time of the
    	 * request is less than a set time margin, defined in @ref ECSS_TIME_MARGIN_FOR_ACTIVATION,
    	 * from the current time a @ref ErrorHandler::ExecutionStartErrorType is also issued.
    
    	void insertActivities(Message& request);
    
    	 * @brief TC[11,15] time-shift all scheduled activities
    
    	 * @details All scheduled activities are shifted per user request. The relative time offset
    	 * received and tested against the current time.
    
    	 * @param request Provide the received message as a parameter
    
    	 * @todo Definition of the time format is required for the relative time format
    
    Dimitrios Stoupis's avatar
    Dimitrios Stoupis committed
    	 * @throws ExecutionStartError If the release time of the request is less than a
    	 * set time margin, defined in @ref ECSS_TIME_MARGIN_FOR_ACTIVATION, from the current time an
    	 * @ref ErrorHandler::ExecutionStartErrorType report is issued for that instruction.
    
    	void timeShiftAllActivities(Message& request);
    
    	 * @brief TC[11,16] detail-report all activities
    
    	 *
    	 * @details Send a detailed report about the status of all the activities
    
    	 * on the current schedule. Generates a TM[11,10] response.
    
    	 * @param request Provide the received message as a parameter
    
    	 * @todo Replace the time parsing with the time parser
    
    	void detailReportAllActivities(Message& request);
    
    	 * @brief TC[11,9] detail-report activities identified by request identifier
    
    	 * @details Send a detailed report about the status of the requested activities, based on the
    	 * provided request identifier. Generates a TM[11,10] response. The matched activities are
    	 * contained in the report, in an ascending order based on their release time.
    
    	 * @param request Provide the received message as a parameter
    
    	 * @todo Replace time parsing with the time parser
    
    Dimitrios Stoupis's avatar
    Dimitrios Stoupis committed
    	 * @throws ExecutionStartError If a requested activity, identified by the provided
    	 * request identifier is not found in the schedule issue an @ref
    	 * ErrorHandler::ExecutionStartErrorType for that instruction.
    
    	void detailReportActivitiesByID(Message& request);
    
    	 * @brief TC[11,12] summary-report activities identified by request identifier
    
    	 * @details Send a summary report about the status of the requested activities. Generates a
    
    	 * TM[11,13] response, with activities ordered in an ascending order, based on their release
    	 * time.
    
    	 * @param request Provide the received message as a parameter
    
    Dimitrios Stoupis's avatar
    Dimitrios Stoupis committed
    	 * @throws ExecutionStartError If a requested activity, identified by the provided
    	 * request identifier is not found in the schedule issue an @ref
    	 * ErrorHandler::ExecutionStartErrorType for that instruction.
    
    	void summaryReportActivitiesByID(Message& request);
    
    	 * @brief TC[11,5] delete time-based scheduled activities identified by a request identifier
    
    	 * @details Delete certain activities by using the unique request identifier.
    
    	 * @param request Provide the received message as a parameter
    
    Dimitrios Stoupis's avatar
    Dimitrios Stoupis committed
    	 * @throws ExecutionStartError If a requested activity, identified by the provided
    	 * request identifier is not found in the schedule issue an @ref
    	 * ErrorHandler::ExecutionStartErrorType for that instruction.
    
    	void deleteActivitiesByID(Message& request);
    
    	 * @brief TC[11,7] time-shift scheduled activities identified by a request identifier
    
    	 *
    	 * @details Time-shift certain activities by using the unique request identifier
    	 * @param request Provide the received message as a parameter
    
    	 * @todo Definition of the time format is required
    
    Dimitrios Stoupis's avatar
    Dimitrios Stoupis committed
    	 * @throws ExecutionStartError If the requested time offset is less than the earliest
    	 * time from the currently scheduled activities plus the @ref ECSS_TIME_MARGIN_FOR_ACTIVATION,
    	 * then the request is rejected and an @ref ErrorHandler::ExecutionStartErrorType is issued.
    	 * Also if an activity with a specified request identifier is not found, generate a failed
    	 * start of execution for that specific instruction.
    
    Xhulio Luli's avatar
    Xhulio Luli committed
    	void timeShiftActivitiesByID(Message& request);
    
    
    	/**
    	 * It is responsible to call the suitable function that executes a telecommand packet. The source of that packet
    	 * is the ground station.
    	 *
    	 * @note This function is called from the main execute() that is defined in the file MessageParser.hpp
    	 * @param message Contains the necessary parameters to call the suitable subservice
    	 */
    
    hiluluk's avatar
    hiluluk committed
    	void execute(Message& message);
    
    #endif // ECSS_SERVICES_TIMEBASEDSCHEDULINGSERVICE_HPP