Skip to content
Snippets Groups Projects
ErrorHandler.hpp 16.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • kongr45gpen's avatar
    kongr45gpen committed
    #ifndef PROJECT_ERRORHANDLER_HPP
    #define PROJECT_ERRORHANDLER_HPP
    
    
    kongr45gpen's avatar
    kongr45gpen committed
    #include <stdint.h> // for the uint_8t stepID
    
    #include <type_traits>
    
    // Forward declaration of the class, since its header file depends on the ErrorHandler
    class Message;
    
    kongr45gpen's avatar
    kongr45gpen committed
    
    /**
     * A class that handles unexpected software errors, including internal errors or errors due to
     * invalid & incorrect input data.
     *
     * @todo Add auxiliary data field to errors
     */
    class ErrorHandler {
    private:
    	/**
    
    	 * Log the error to a logging facility. Platform-dependent.
    
    	template <typename ErrorType>
    	static void logError(const Message& message, ErrorType errorType);
    
    	 * Log an error without a Message to a logging facility. Platform-dependent.
    
    	template <typename ErrorType>
    
    kongr45gpen's avatar
    kongr45gpen committed
    	static void logError(ErrorType errorType);
    
    public:
    	enum InternalErrorType {
    		UnknownInternalError = 0,
    		/**
    		 * While writing (creating) a message, an amount of bytes was tried to be added but
    		 * resulted in failure, since the message storage was not enough.
    		 */
    
    		MessageTooLarge = 1,
    
    kongr45gpen's avatar
    kongr45gpen committed
    		/**
    		 * Asked to append a number of bits larger than supported
    		 */
    
    		TooManyBitsAppend = 2,
    
    kongr45gpen's avatar
    kongr45gpen committed
    		/**
    		 * Asked to append a byte, while the previous byte was not complete
    		 */
    
    		ByteBetweenBits = 3,
    
    kongr45gpen's avatar
    kongr45gpen committed
    		/**
    		 * A string is larger than the largest allowed string
    		 */
    
    		StringTooLarge = 4,
    
    kongr45gpen's avatar
    kongr45gpen committed
    		/**
    		 * An error in the header of a packet makes it unable to be parsed
    		 */
    
    		UnacceptablePacket = 5,
    
    		 * A date that isn't valid according to the Gregorian calendar or cannot be parsed by the
    		 * TimeHelper
    		 */
    		InvalidDate = 6,
    
    		/**
    		 * Asked a Message type that doesn't exist
    
    		UnknownMessageType = 7,
    
    
    		/**
    		 * Asked to append unnecessary spare bits
    		 */
    
    		InvalidSpareBits = 8,
    
    		/**
    		 * A function received a Message that was not of the correct type
    		 */
    
    		OtherMessageType = 9,
    
    athatheo's avatar
    athatheo committed
    		 * Attempt to insert new element in a full map ST[08]
    
    		/**
    		 * A Message that is included within another message is too large
    		 */
    
    		/**
    		 * Request to copy packets in a time window, whose type is not recognized (ST(15)).
    		 */
    		InvalidTimeWindowType = 12,
    
    		/**
    		 * A request to access a non existing housekeeping structure in ST[03]
    		 */
    
    		/**
    		 * Attempt to access an invalid parameter in ST[03]
    		 */
    
    		/**
    		 * Invalid TimeStamp parameters at creation
    		 */
    
    kongr45gpen's avatar
    kongr45gpen committed
    	};
    
    	/**
    	 * The error code for failed acceptance reports, as specified in ECSS 6.1.4.3d
    	 *
    	 * Note: Numbers are kept in code explicitly, so that there is no uncertainty when something
    	 * changes.
    	 */
    	enum AcceptanceErrorType {
    		UnknownAcceptanceError = 0,
    		/**
    		 * The received message does not contain enough information as specified
    		 */
    
    		MessageTooShort = 1,
    
    kongr45gpen's avatar
    kongr45gpen committed
    		/**
    		 * Asked to read a number of bits larger than supported
    		 */
    
    		TooManyBitsRead = 2,
    
    kongr45gpen's avatar
    kongr45gpen committed
    		/**
    		 * Cannot read a string, because it is larger than the largest allowed string
    		 */
    
    		StringTooShort = 4,
    
    kongr45gpen's avatar
    kongr45gpen committed
    		/**
    		 * Cannot parse a Message, because there is an error in its secondary header
    		 */
    
    		UnacceptableMessage = 5
    
    	/**
    	 * The error code for failed start of execution reports, as specified in ECSS 5.3.5.2.3g
    	 *
    	 * Note: Numbers are kept in code explicitly, so that there is no uncertainty when something
    	 * changes.
    	 */
    
    thodkatz's avatar
    thodkatz committed
    	enum ExecutionStartErrorType {
    		UnknownExecutionStartError = 0,
    
    		/**
    		 * In the Event Action Service, in the addEventActionDefinition function an attempt was
    
    		 * made to add an event Action Definition with an eventActionDefinitionID that exists
    
    		EventActionDefinitionIDExistsError = 1,
    
    		/**
    		 * In the Event Action Service, in the deleteEventActionDefinition function, an attempt
    		 * was made to delete an event action definition that was enabled
    		 */
    		EventActionDeleteEnabledDefinitionError = 2,
    		/**
    		 * In the Event Action Service, an access attempt was made to an unknown event
    		 * action definition
    		 */
    
    		EventActionUnknownEventDefinitionError = 3,
    		/**
    		 * EventAction refers to the service, EventActionIDefinitionID refers to the variable
    		 * In the Event Action Service, an access attempt was made to an unknown eventActionDefinitionID
    		 */
    
    		EventActionUnknownEventActionDefinitionIDError = 4,
    		SubServiceExecutionStartError = 5,
    		InstructionExecutionStartError = 6,
    
    		/**
    		 * Attempt to change the value of a non existing parameter (ST[20])
    		 */
    		SetNonExistingParameter = 7,
    		/**
    		 * Attempt to access a non existing parameter (ST[20])
    		 */
    
    		 * Attempt to access a packet store that does not exist (ST[15])
    		 */
    		NonExistingPacketStore = 9,
    		/**
    		 * Attempt to change the start time tag of a packet store, whose open retrieval status is in progress (ST[15])
    		 */
    		SetPacketStoreWithOpenRetrievalInProgress = 10,
    		/**
    		 * Attempt to resume open retrieval of a packet store, whose by-time-range retrieval is enabled (ST[15])
    
    		SetPacketStoreWithByTimeRangeRetrieval = 11,
    		/**
    		 * Attempt to access a packet with by-time range retrieval enabled (ST[15])
    		 */
    		GetPacketStoreWithByTimeRangeRetrieval = 12,
    		/**
    		 * Attempt to start the by-time-range retrieval of packet store, whose open retrieval is in progress (ST[15])
    		 */
    		GetPacketStoreWithOpenRetrievalInProgress = 13,
    		/**
    		 * Attempt to start by-time-range retrieval when its already enabled (ST[15])
    		 */
    		ByTimeRangeRetrievalAlreadyEnabled = 14,
    		/**
    		 * Attempt to create packet store, whose ID already exists (ST[15])
    		 */
    		AlreadyExistingPacketStore = 15,
    		/**
    		 * Attempt to create packet store, when the max number of packet stores is already reached (ST[15])
    		 */
    		MaxNumberOfPacketStoresReached = 16,
    		/**
    		 * Attempt to access a packet store with the storage status enabled (ST[15])
    		 */
    		GetPacketStoreWithStorageStatusEnabled = 17,
    		/**
    		 * Attempt to delete a packet whose by time range retrieval status is enabled (ST[15])
    		 */
    		DeletionOfPacketWithByTimeRangeRetrieval = 18,
    		/**
    		 * Attempt to delete a packet whose open retrieval status is in progress (ST[15])
    		 */
    		DeletionOfPacketWithOpenRetrievalInProgress = 19,
    		/**
    		 * Requested a time window where the start time is larger than the end time (ST[15])
    		 */
    		InvalidTimeWindow = 20,
    		/**
    		 * Attempt to copy a packet store to a destination packet store that is not empty (ST[15])
    		 */
    		DestinationPacketStoreNotEmtpy = 21,
    		/**
    		 * Attempt to set a reporting rate which is smaller than the parameter sampling rate.
    		 * ST[04]
    		 */
    		InvalidReportingRateError = 22,
    		/**
    		 * Attempt to add definition to the struct map but its already full.(ST[19])
    		 */
    		EventActionDefinitionsMapIsFull = 23,
    
    		 * Attempt to report/delete non existing housekeeping structure (ST[03])
    		 */
    
    		RequestedNonExistingStructure = 24,
    
    		/**
    		 * Attempt to create already created structure (ST[03])
    		 */
    
    		RequestedAlreadyExistingStructure = 25,
    
    		/**
    		 * Attempt to delete structure which has the periodic reporting status enabled (ST[03]) as per 6.3.3.5.2(d-2)
    		 */
    
    		RequestedDeletionOfEnabledHousekeeping = 26,
    
    		/**
    		 * Attempt to append a new parameter ID to a housekeeping structure, but the ID is already in the structure
    		 * (ST[03])
    		 */
    
    		/**
    		 * Attempt to append a new parameter id to a housekeeping structure, but the periodic generation status is
    		 * enabled (ST[03])
    		 */
    
    		RequestedAppendToEnabledHousekeeping = 28,
    
    		/**
    		 * Attempt to create a new housekeeping structure in Housekeeping Service, when the maximum number of
    		 * housekeeping structures is already reached (ST[03])
    		 */
    
    		ExceededMaxNumberOfHousekeepingStructures = 29,
    
    		/**
    		 * Attempt to add a new simply commutated parameter in a specific housekeeping structure, but the maximum
    		 * number of simply commutated parameters for this structure is already reached (ST[03])
    		 */
    
    		ExceededMaxNumberOfSimplyCommutatedParameters = 30,
    
    		 * Attempt to set a reporting rate which is smaller than the parameter sampling rate.
    
    		/**
    		 * Attempt to add new statistic definition but the maximum number is already reached (ST[04])
    		 */
    
    		MaxStatisticDefinitionsReached = 32,
    		/**
    		 * Attempt to set the virtual channel of a packet store to a invalid value (ST[15])
    		 */
    		InvalidVirtualChannel = 33,
    		/**
    		 * Attempt to delete a packet store, whose storage status is enabled (ST[15])
    		 */
    		DeletionOfPacketStoreWithStorageStatusEnabled = 34,
    		/**
    		 * Attempt to copy packets from a packet store to another, but either no packet timestamp falls inside the
    		 * specified timestamp, or more than one boolean argument were given as true in the 'copyPacketsTo' function
    		 * (ST[15])
    		 */
    		CopyOfPacketsFailed = 35,
    		/**
    		 * Attempt to set a packet store size to a value that the available memory cannot handle (ST[15]).
    		 */
    		UnableToHandlePacketStoreSize = 36,
    
    		/**
    		 * Attempt to delete all parameter monitoring definitions but the Parameter Monitoring Function Status is
    		 * enabled.
    		 */
    
    		InvalidRequestToDeleteAllParameterMonitoringDefinitions = 37,
    
    		/**
    		 * Attempt to delete one parameter monitoring definition but its Parameter Monitoring Status is
    		 * enabled.
    		 */
    
    		InvalidRequestToDeleteParameterMonitoringDefinition = 38,
    
    		/**
    		 * Attempt to add a parameter that already exists to the Parameter Monitoring List.
    		 */
    
    		/**
    		 * Attempt to add a parameter in the Parameter Monitoring List but it's full
    		 */
    
    		ParameterMonitoringListIsFull = 40,
    
    		/**
    		 * Attempt to add or modify a limit check parameter monitoring definition, but the high limit is lower than
    		 * the low limit.
    		 */
    
    		HighLimitIsLowerThanLowLimit = 41,
    
    		/**
    		 * Attempt to add or modify a delta check parameter monitoring definition, but the high threshold is lower than
    		 * the low threshold.
    		 */
    
    		HighThresholdIsLowerThanLowThreshold = 42,
    
    		/**
    		 * Attempt to modify a non existent Parameter Monitoring definition.
    		 */
    
    		ModifyParameterNotInTheParameterMonitoringList = 43,
    
    		/**
    		 * Attempt to modify a parameter monitoring definition, but the instruction refers to a monitored parameter
    		 * that is not the one used in that parameter monitoring definition.
    		 */
    
    		DifferentParameterMonitoringDefinitionAndMonitoredParameter = 44,
    
    		/**
    		 * Attempt to get a parameter monitoring definition that does not exist.
    		 */
    
    		GetNonExistingParameterMonitoringDefinition = 45,
    
    		/**
    		 * Request to report a non existent parameter monitoring definition.
    		 */
    
    		ReportParameterNotInTheParameterMonitoringList = 46,
    		/**
    		 * Attempt to add a new service type, when the addition of all service types is already enabled in the
    		 * Application Process configuration (ST[14])
    		 */
    		AllServiceTypesAlreadyAllowed = 47,
    		/**
    		 * Attempt to add a new report type, when the max number of reports types allowed per service type
    		 * definition in the Application Process configuration is already reached (ST[14])
    		 */
    		MaxReportTypesReached = 48,
    		/**
    		 * Attempt to add a new service type, when the max number of service types allowed per application process
    		 * definition in the Application Process configuration is already reached (ST[14])
    		 */
    		MaxServiceTypesReached = 49,
    		/**
    		 * Attempt to add a report/event definition/housekeeping report type, when the specified application process
    		 * ID is not controlled by the Service (ST[14])
    		 */
    		NotControlledApplication = 50,
    
    		/**
    		 * Parameter is requested, but the provider of the parameter value does not exist yet
    		 */
    		ParameterValueMissing = 51,
    		/**
    		 * Attempted to write to a read-only parameter
    		 */
    		ParameterReadOnly = 52,
    		/**
    		 * Attempted to read from a write-only parameter
    		 */
    		ParameterWriteOnly = 53,
    
    
    	/**
    	 * The error code for failed progress of execution reports, as specified in ECSS 5.3.5.2.3g
    	 *
    	 * Note: Numbers are kept in code explicitly, so that there is no uncertainty when something
    	 * changes.
    	 */
    
    thodkatz's avatar
    thodkatz committed
    	enum ExecutionProgressErrorType {
    		UnknownExecutionProgressError = 0,
    
    kongr45gpen's avatar
    kongr45gpen committed
    	};
    
    	/**
    	 * The error code for failed completion of execution reports, as specified in ECSS 5.3.5.2.3g
    	 *
    	 * Note: Numbers are kept in code explicitly, so that there is no uncertainty when something
    	 * changes.
    	 */
    
    thodkatz's avatar
    thodkatz committed
    	enum ExecutionCompletionErrorType {
    		UnknownExecutionCompletionError = 0,
    
    		/**
    		 * Checksum comparison failed
    		 */
    
    		ChecksumFailed = 1,
    
    		/**
    		 * Address of a memory is out of the defined range for the type of memory
    		 */
    
    		AddressOutOfRange = 2,
    
    thodkatz's avatar
    thodkatz committed
    	 * The error code for failed routing reports, as specified in ECSS 6.1.3.3d
    
    kongr45gpen's avatar
    kongr45gpen committed
    	 *
    	 * Note: Numbers are kept in code explicitly, so that there is no uncertainty when something
    	 * changes.
    	 */
    	enum RoutingErrorType {
    
    		UnknownRoutingError = 0,
    
    kongr45gpen's avatar
    kongr45gpen committed
    	};
    
    	/**
    	 * The location where the error occurred
    	 */
    	enum ErrorSource {
    		Internal,
    		Acceptance,
    		ExecutionStart,
    		ExecutionProgress,
    		ExecutionCompletion,
    
    kongr45gpen's avatar
    kongr45gpen committed
    	};
    
    	/**
    	 * Report a failure and, if applicable, store a failure report message
    	 *
    	 * @tparam ErrorType The Type struct of the error; can be AcceptanceErrorType,
    
    	 * StartExecutionErrorType,CompletionExecutionErrorType,  or RoutingErrorType.
    
    kongr45gpen's avatar
    kongr45gpen committed
    	 * @param message The incoming message that prompted the failure
    	 * @param errorCode The error's code, as defined in ErrorHandler
    	 * @todo See if this needs to include InternalErrorType
    	 */
    
    	template <typename ErrorType>
    	static void reportError(const Message& message, ErrorType errorCode);
    
    	 * Report a failure about the progress of the execution of a request
    	 *
    	 * @note This function is different from reportError, because we need one more \p stepID
    	 * to call the proper function for reporting the progress of the execution of a request
    	 *
    	 * @param message The incoming message that prompted the failure
    	 * @param errorCode The error's code, when a failed progress of the execution of a request
    	 * occurs
    	 * @param stepID If the execution of a request is a long process, then we can divide
    
    thodkatz's avatar
    thodkatz committed
    	 * the process into steps. Each step goes with its own definition, the stepID. Each value
    	 * ,that the stepID is assigned, should be documented.
    
    	 */
    	static void reportProgressError(const Message& message, ExecutionProgressErrorType errorCode, uint8_t stepID);
    
    kongr45gpen's avatar
    kongr45gpen committed
    	/**
    	 * Report a failure that occurred internally, not due to a failure of a received packet.
    	 *
    	 * Note that these errors correspond to bugs or faults in the software, and should be treated
    	 * differently. Such an error may prompt a task or software reset.
    	 */
    	static void reportInternalError(InternalErrorType errorCode);
    
    	/**
    	 * Make an assertion, to ensure that a runtime condition is met.
    	 *
    	 * Reports a failure that occurred internally, not due to a failure of a received packet.
    	 *
    	 * Creates an error if \p condition is false. The created error is Internal.
    
    kongr45gpen's avatar
    kongr45gpen committed
    	 *
    	 * @param condition The condition to check. Throws an error if false.
    	 * @param errorCode The error code that is assigned to this error. One of the \ref ErrorHandler enum values.
    	 * @return Returns \p condition, i.e. true if the assertion is successful, false if not.
    
    kongr45gpen's avatar
    kongr45gpen committed
    	static bool assertInternal(bool condition, InternalErrorType errorCode) {
    
    kongr45gpen's avatar
    kongr45gpen committed
    		if (not condition) {
    			reportInternalError(errorCode);
    		}
    
    kongr45gpen's avatar
    kongr45gpen committed
    
    		return condition;
    
    kongr45gpen's avatar
    kongr45gpen committed
    	}
    
    	/**
    	 * Make an assertion, to ensure that a runtime condition is met.
    	 *
    	 * Reports a failure that occurred while processing a request, in any of the process phases.
    	 *
    	 * Creates an error if \p condition is false. The created error corresponds to a \p message.
    
    kongr45gpen's avatar
    kongr45gpen committed
    	 *
    	 * @param condition The condition to check. Throws an error if false.
    	 * @param message The message to associate with this error
    	 * @param errorCode The error code that is assigned to this error. One of the \ref ErrorHandler enum values.
    	 * @return Returns \p condition, i.e. true if the assertion is successful, false if not.
    
    	template <typename ErrorType>
    
    kongr45gpen's avatar
    kongr45gpen committed
    	static bool assertRequest(bool condition, const Message& message, ErrorType errorCode) {
    
    kongr45gpen's avatar
    kongr45gpen committed
    		if (not condition) {
    			reportError(message, errorCode);
    		}
    
    kongr45gpen's avatar
    kongr45gpen committed
    
    		return condition;
    
    
    	/**
    	 * Convert a parameter given in C++ to an ErrorSource that can be easily used in comparisons.
    	 * @tparam ErrorType One of the enums specified in ErrorHandler.
    	 * @param error An error code of a specific type
    	 * @return The corresponding ErrorSource
    	 */
    
    	template <typename ErrorType>
    
    	inline static ErrorSource findErrorSource(ErrorType error) {
    
    		// Static type checking
    
    kongr45gpen's avatar
    kongr45gpen committed
    		ErrorSource source = Internal;
    
    
    		if (std::is_same<ErrorType, AcceptanceErrorType>()) {
    
    kongr45gpen's avatar
    kongr45gpen committed
    			source = Acceptance;
    
    		if (std::is_same<ErrorType, ExecutionStartErrorType>()) {
    
    kongr45gpen's avatar
    kongr45gpen committed
    			source = ExecutionStart;
    
    		if (std::is_same<ErrorType, ExecutionProgressErrorType>()) {
    
    kongr45gpen's avatar
    kongr45gpen committed
    			source = ExecutionProgress;
    
    		if (std::is_same<ErrorType, ExecutionCompletionErrorType>()) {
    
    kongr45gpen's avatar
    kongr45gpen committed
    			source = ExecutionCompletion;
    
    		if (std::is_same<ErrorType, RoutingErrorType>()) {
    
    kongr45gpen's avatar
    kongr45gpen committed
    			source = Routing;
    
    kongr45gpen's avatar
    kongr45gpen committed
    
    		return source;
    
    #endif // PROJECT_ERRORHANDLER_HPP