diff --git a/action/ActionMessage.h b/action/ActionMessage.h index 5d8332cb..59ad619e 100644 --- a/action/ActionMessage.h +++ b/action/ActionMessage.h @@ -10,7 +10,7 @@ class ActionMessage { private: ActionMessage(); public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::ACTION; + static const uint8_t MESSAGE_ID = messagetypes::ACTION; static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1); static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2); static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3); diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 78e57c8c..37dbed36 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -13,7 +14,15 @@ LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner) { } this->owner = owner; mutex = MutexFactory::instance()->createMutex(); - //owner->setMinimalHkSamplingFrequency(); + if(mutex == nullptr) { + sif::error << "LocalDataPoolManager::LocalDataPoolManager: " + "Could not create mutex." << std::endl; + } + ipcStore = objectManager->get(objects::IPC_STORE); + if(ipcStore == nullptr) { + sif::error << "LocalDataPoolManager::LocalDataPoolManager: " + "Could not set IPC store." << std::endl; + } } LocalDataPoolManager::~LocalDataPoolManager() {} @@ -32,7 +41,7 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { } ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( - CommandMessage *message) { + MessageQueueMessage *message) { return HasReturnvaluesIF::RETURN_OK; } @@ -52,32 +61,37 @@ MutexIF* LocalDataPoolManager::getMutexHandle() { return mutex; } -//void HousekeepingManager::setMinimalSamplingFrequency(float frequencySeconds) { -// this->samplingFrequency = frequencySeconds; -// -//} - -void LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { +ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { LocalDataSet* dataSetToSerialize = dynamic_cast( owner->getDataSetHandle(sid)); if(dataSetToSerialize == nullptr) { sif::warning << "HousekeepingManager::generateHousekeepingPacket:" " Set ID not found" << std::endl; - return; + return HasReturnvaluesIF::RETURN_FAILED; + } + store_address_t storeId; + size_t hkSize = dataSetToSerialize->getSerializedSize(); + uint8_t* storePtr = nullptr; + ReturnValue_t result = ipcStore->getFreeElement(&storeId, hkSize,&storePtr); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "HousekeepingManager::generateHousekeepingPacket: " + "Could not get free element from IPC store." << std::endl; + return result; } - std::array testBuffer = {}; - uint8_t* dataPtr = testBuffer.data(); size_t size = 0; - dataSetToSerialize->serialize(&dataPtr, &size, testBuffer.size(), - false); - // and now we send it to the TM funnel or somewhere else - + dataSetToSerialize->serialize(&storePtr, &size, hkSize, false); + // and now we have to set a HK message and send it the queue. + return HasReturnvaluesIF::RETURN_OK; } void LocalDataPoolManager::setHkPacketQueue(MessageQueueIF *msgQueue) { this->hkPacketQueue = msgQueue; } +void LocalDataPoolManager::setHkReplyQueue(MessageQueueIF *replyQueue) { + this->hkReplyQueue = replyQueue; +} + const OwnsLocalDataPoolIF* LocalDataPoolManager::getOwner() const { return owner; } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index c8a6bf15..1d25fa48 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -37,15 +37,16 @@ class LocalDataPoolManager { friend class LocalPoolVector; friend class LocalDataSet; public: - static constexpr float MINIMAL_SAMPLING_FREQUENCY = 0.2; LocalDataPoolManager(OwnsLocalDataPoolIF* owner); virtual~ LocalDataPoolManager(); + /* Copying forbidden */ + LocalDataPoolManager(const LocalDataPoolManager &) = delete; + LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; - // propably will just call respective local data set functions. - void generateHousekeepingPacket(sid_t sid); - ReturnValue_t handleHousekeepingMessage(CommandMessage* message); + ReturnValue_t generateHousekeepingPacket(sid_t sid); + ReturnValue_t handleHousekeepingMessage(MessageQueueMessage* message); /** * This function is used to fill the local data pool map with pool @@ -55,7 +56,12 @@ public: */ ReturnValue_t initializeHousekeepingPoolEntriesOnce(); + //! Set the queue for HK packets, which are sent unrequested. void setHkPacketQueue(MessageQueueIF* msgQueue); + //! Set the queue for replies. This can be set manually or by the owner + //! class if the manager if message are relayed by it. + void setHkReplyQueue(MessageQueueIF* replyQueue); + const OwnsLocalDataPoolIF* getOwner() const; ReturnValue_t printPoolEntry(lp_id_t localPoolId); @@ -81,6 +87,8 @@ private: //! Maybe this will just be the TM funnel. MessageQueueIF* hkPacketQueue = nullptr; + //! Global IPC store is used to store all packets. + StorageManagerIF* ipcStore = nullptr; /** * Get the pointer to the mutex. Can be used to lock the data pool * eternally. Use with care and don't forget to unlock locked mutexes! diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 59bfb6af..94c9dc63 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -36,7 +38,7 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, - CommandMessage::MAX_MESSAGE_SIZE); + MessageQueueMessage::MAX_MESSAGE_SIZE); insertInCommandMap(RAW_COMMAND_ID); cookieInfo.state = COOKIE_UNUSED; cookieInfo.pendingCommand = deviceCommandMap.end(); @@ -212,40 +214,59 @@ void DeviceHandlerBase::readCommandQueue() { return; } - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + // This is not ideal. What if it is not a command message? (e.g. another + // message with 3 parameters). The full buffer is filled anyway + // and I could just copy the content into the other message but + // all I need are few additional functions the other message type offers. + CommandMessage cmdMessage; + ReturnValue_t result = commandQueue->receiveMessage(&cmdMessage); if (result != RETURN_OK) { return; } + // This is really annoying. I can't cast a parent object to a child. + // But I want to use another message format.. +// CommandMessage* cmdMessage = dynamic_cast(msgPtr); +// if(cmdMessage == nullptr) { +// sif::error << "DeviceHandlerBase::readCommandQueue: Could not cast" +// " message to CommandMessage!" << std::endl; +// return; +// } + if(healthHelperActive) { - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&cmdMessage); if (result == RETURN_OK) { return; } } - result = modeHelper.handleModeCommand(&message); + result = modeHelper.handleModeCommand(&cmdMessage); if (result == RETURN_OK) { return; } - result = actionHelper.handleActionMessage(&message); + result = actionHelper.handleActionMessage(&cmdMessage); if (result == RETURN_OK) { return; } - result = parameterHelper.handleParameterMessage(&message); + result = parameterHelper.handleParameterMessage(&cmdMessage); if (result == RETURN_OK) { return; } - result = handleDeviceHandlerMessage(&message); +// HousekeepingMessage* hkMessage = dynamic_cast(msgPtr); +// result = hkManager.handleHousekeepingMessage(hkMessage); +// if (result == RETURN_OK) { +// return; +// } + + result = handleDeviceHandlerMessage(&cmdMessage); if (result == RETURN_OK) { return; } - result = letChildHandleMessage(&message); + result = letChildHandleMessage(&cmdMessage); if (result == RETURN_OK) { return; } diff --git a/devicehandlers/DeviceHandlerMessage.h b/devicehandlers/DeviceHandlerMessage.h index c91bb0a4..2bdf03b2 100644 --- a/devicehandlers/DeviceHandlerMessage.h +++ b/devicehandlers/DeviceHandlerMessage.h @@ -25,7 +25,7 @@ public: /** * These are the commands that can be sent to a DeviceHandlerBase */ - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::DEVICE_HANDLER_COMMAND; + static const uint8_t MESSAGE_ID = messagetypes::DEVICE_HANDLER_COMMAND; static const Command_t CMD_RAW = MAKE_COMMAND_ID( 1 ); //!< Sends a raw command, setParameter is a ::store_id_t containing the raw packet to send // static const Command_t CMD_DIRECT = MAKE_COMMAND_ID( 2 ); //!< Sends a direct command, setParameter is a ::DeviceCommandId_t, setParameter2 is a ::store_id_t containing the data needed for the command static const Command_t CMD_SWITCH_ADDRESS = MAKE_COMMAND_ID( 3 ); //!< Requests a IO-Board switch, setParameter() is the IO-Board identifier diff --git a/health/HealthMessage.h b/health/HealthMessage.h index 7fd00904..13e79b88 100644 --- a/health/HealthMessage.h +++ b/health/HealthMessage.h @@ -6,7 +6,7 @@ class HealthMessage { public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::HEALTH_COMMAND; + static const uint8_t MESSAGE_ID = messagetypes::HEALTH_COMMAND; static const Command_t HEALTH_SET = MAKE_COMMAND_ID(1);//REPLY_COMMAND_OK/REPLY_REJECTED static const Command_t HEALTH_ANNOUNCE = MAKE_COMMAND_ID(3); //NO REPLY! static const Command_t HEALTH_INFO = MAKE_COMMAND_ID(5); diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index b0109e5d..c94a69d7 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,5 +1,13 @@ #include +HousekeepingMessage::HousekeepingMessage() { + +} + +void HousekeepingMessage::setHkReportMessage() { +} + + //void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message, // set_t setId, store_address_t packet) { // message->setCommand(ADD_HK_REPORT_STRUCT); diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index e7ba68ba..3ba6f94d 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -5,12 +5,14 @@ #include union sid_t { - static constexpr uint64_t INVALID_ADDRESS = std::numeric_limits::max(); + static constexpr uint64_t INVALID_ADDRESS = + std::numeric_limits::max(); sid_t(): raw(INVALID_ADDRESS) {} struct { object_id_t objectId ; - // A generic 32 bit ID to identify unique HK packets for a single object. + // A generic 32 bit ID to identify unique HK packets for a single + // object. // For example, the DeviceCommandId_t is used for DeviceHandlers uint32_t ownerSetId; }; @@ -19,17 +21,19 @@ union sid_t { */ uint64_t raw; }; -class HousekeepingMessage { + + +class HousekeepingMessage: public MessageQueueMessage { public: /** * No instances of a message shall be created, instead * a CommandMessage instance is manipulated. */ - HousekeepingMessage() = delete; - HousekeepingMessage(const HousekeepingMessage&) = delete; - HousekeepingMessage operator=(const HousekeepingMessage &) = delete; + HousekeepingMessage(); +// HousekeepingMessage(const HousekeepingMessage&) = delete; +// HousekeepingMessage operator=(const HousekeepingMessage &) = delete; - static constexpr uint8_t MESSAGE_ID = MESSAGE_TYPE::HOUSEKEEPING; + static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; static constexpr Command_t ADD_HK_REPORT_STRUCT = MAKE_COMMAND_ID(1); static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT = @@ -76,6 +80,7 @@ public: // static void setAddHkReportStructMessage(CommandMessage* message, // DevisetId, store_address_t packet); + static void setHkReportMessage(); }; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index fa41c653..f9e2e010 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -1,10 +1,3 @@ -/** - * @file CommandMessage.cpp - * @brief This file defines the CommandMessage class. - * @date 20.06.2013 - * @author baetz - */ - #include #include #include @@ -15,7 +8,8 @@ #include #include -namespace MESSAGE_TYPE { +namespace messagetypes { +// Implemented in config. void clearMissionMessage(CommandMessage* message); } @@ -39,6 +33,10 @@ Command_t CommandMessage::getCommand() const { return command; } +uint8_t CommandMessage::getMessageType() const { + return getCommand() >> 8 & 0xff; +} + void CommandMessage::setCommand(Command_t command) { memcpy(getData(), &command, sizeof(command)); } @@ -66,36 +64,36 @@ void CommandMessage::setParameter2(uint32_t parameter2) { } void CommandMessage::clearCommandMessage() { - switch((getCommand()>>8) & 0xff){ - case MESSAGE_TYPE::MODE_COMMAND: + switch(getMessageType()){ + case messagetypes::MODE_COMMAND: ModeMessage::clear(this); break; - case MESSAGE_TYPE::HEALTH_COMMAND: + case messagetypes::HEALTH_COMMAND: HealthMessage::clear(this); break; - case MESSAGE_TYPE::MODE_SEQUENCE: + case messagetypes::MODE_SEQUENCE: ModeSequenceMessage::clear(this); break; - case MESSAGE_TYPE::ACTION: + case messagetypes::ACTION: ActionMessage::clear(this); break; - case MESSAGE_TYPE::DEVICE_HANDLER_COMMAND: + case messagetypes::DEVICE_HANDLER_COMMAND: DeviceHandlerMessage::clear(this); break; - case MESSAGE_TYPE::MEMORY: + case messagetypes::MEMORY: MemoryMessage::clear(this); break; - case MESSAGE_TYPE::MONITORING: + case messagetypes::MONITORING: MonitoringMessage::clear(this); break; - case MESSAGE_TYPE::TM_STORE: + case messagetypes::TM_STORE: TmStoreMessage::clear(this); break; - case MESSAGE_TYPE::PARAMETER: + case messagetypes::PARAMETER: ParameterMessage::clear(this); break; default: - MESSAGE_TYPE::clearMissionMessage(this); + messagetypes::clearMissionMessage(this); break; } } diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 21c393e5..a5c187f5 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -1,13 +1,5 @@ -/** - * @file CommandMessage.h - * @brief This file defines the CommandMessage class. - * @date 20.06.2013 - * @author baetz - */ - -#ifndef COMMANDMESSAGE_H_ -#define COMMANDMESSAGE_H_ - +#ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_ +#define FRAMEWORK_IPC_COMMANDMESSAGE_H_ #include #include @@ -15,10 +7,11 @@ #include #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) -typedef ReturnValue_t Command_t; +typedef uint16_t Command_t; /** - * @brief Used to pass command messages between tasks + * @brief Used to pass command messages between tasks + * @author Bastian Baetz */ class CommandMessage : public MessageQueueMessage { public: @@ -26,13 +19,17 @@ public: static const ReturnValue_t UNKNOW_COMMAND = MAKE_RETURN_CODE(0x01); - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::COMMAND; - static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 );//!< Used internally, will be ignored + static const uint8_t MESSAGE_ID = messagetypes::COMMAND; + //! Used internally, will be ignored + static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 ); static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID( 3 ); - static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 );//!< Reply indicating that the current command was rejected, par1 should contain the error code + //! Reply indicating that the current command was rejected, + //! par1 should contain the error code + static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 ); /** - * This is the size of a message as it is seen by the MessageQueue + * This is the size of a message as it is seen by the MessageQueue. + * 14 of the 24 available MessageQueueMessage bytes are used. */ static const size_t COMMAND_MESSAGE_SIZE = HEADER_SIZE + sizeof(Command_t) + 2 * sizeof(uint32_t); @@ -40,11 +37,13 @@ public: /** * Default Constructor, does not initialize anything. * - * This constructor should be used when receiving a Message, as the content is filled by the MessageQueue. + * This constructor should be used when receiving a Message, as the + * content is filled by the MessageQueue. */ CommandMessage(); /** - * This constructor creates a new message with all message content initialized + * This constructor creates a new message with all message content + * initialized * * @param command The DeviceHandlerCommand_t that will be sent * @param parameter1 The first parameter @@ -60,12 +59,14 @@ public: } /** - * Read the DeviceHandlerCommand_t that is stored in the message, usually used after receiving + * Read the DeviceHandlerCommand_t that is stored in the message, + * usually used after receiving. * * @return the Command stored in the Message */ Command_t getCommand() const; + uint8_t getMessageType() const; /** * Set the DeviceHandlerCOmmand_t of the message * @@ -126,7 +127,8 @@ public: * Is needed quite often, so we better code it once only. */ void setToUnknownCommand(); - void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); + void setReplyRejected(ReturnValue_t reason, + Command_t initialCommand = CMD_NONE); size_t getMinimumMessageSize() const; }; diff --git a/ipc/FwMessageTypes.h b/ipc/FwMessageTypes.h index 1665747e..8b49c122 100644 --- a/ipc/FwMessageTypes.h +++ b/ipc/FwMessageTypes.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_IPC_FWMESSAGETYPES_H_ #define FRAMEWORK_IPC_FWMESSAGETYPES_H_ -namespace MESSAGE_TYPE { +namespace messagetypes { //Remember to add new Message Types to the clearCommandMessage function! -enum FW_MESSAGE_TYPE { +enum FsfwMessageTypes { COMMAND = 0, MODE_COMMAND, HEALTH_COMMAND, diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 4d82bd88..93671321 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -1,6 +1,7 @@ #ifndef MESSAGEQUEUEMESSAGE_H_ #define MESSAGEQUEUEMESSAGE_H_ +#include #include #include @@ -23,7 +24,7 @@ * receive messages from other tasks. * @ingroup message_queue */ -class MessageQueueMessage { +class MessageQueueMessage: public MessageQueueMessageIF { public: /** * @brief The class is initialized empty with this constructor. @@ -43,6 +44,7 @@ public: * MAX_MESSAGE_SIZE and larger than MIN_MESSAGE_SIZE. */ MessageQueueMessage(uint8_t* data, size_t size); + /** * @brief The size information of each message is stored in this attribute. * @details diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h new file mode 100644 index 00000000..70c87d3c --- /dev/null +++ b/ipc/MessageQueueMessageIF.h @@ -0,0 +1,49 @@ +#ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ +#define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ +#include +#include + +class MessageQueueMessageIF { +public: + virtual ~MessageQueueMessageIF() {}; + + /** + * @brief With this method, the whole content and the message + * size is set to zero. + */ + virtual void clear() = 0; + /** + * @brief This is a debug method that prints the content + * (till messageSize) to the debug output. + */ + virtual void print() = 0; + + /** + * @brief Get read-only pointer to the raw buffer. + * @return + */ + virtual const uint8_t* getBuffer() const = 0; + + /** + * @brief This method is used to get the complete data of the message. + */ + virtual uint8_t* getBuffer() = 0; + + /** + * @brief This method is used to set the sender's message queue id + * information prior to sending the message. + * @param setId + * The message queue id that identifies the sending message queue. + */ + virtual void setSender(MessageQueueId_t setId) = 0; + + /** + * @brief This helper function is used by the MessageQueue class to + * check the size of an incoming message. + */ + virtual size_t getMinimumMessageSize() = 0; +}; + + + +#endif /* FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ */ diff --git a/memory/FileSystemMessage.h b/memory/FileSystemMessage.h index b6fd7309..9f9c1496 100644 --- a/memory/FileSystemMessage.h +++ b/memory/FileSystemMessage.h @@ -16,7 +16,7 @@ class FileSystemMessage { private: FileSystemMessage(); //A private ctor inhibits instantiation public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::FILE_SYSTEM_MESSAGE; + static const uint8_t MESSAGE_ID = messagetypes::FILE_SYSTEM_MESSAGE; static const Command_t CREATE_FILE = MAKE_COMMAND_ID( 0x01 ); static const Command_t DELETE_FILE = MAKE_COMMAND_ID( 0x02 ); static const Command_t WRITE_TO_FILE = MAKE_COMMAND_ID( 0x80 ); diff --git a/memory/MemoryMessage.h b/memory/MemoryMessage.h index bcc262e9..e2c87ca3 100644 --- a/memory/MemoryMessage.h +++ b/memory/MemoryMessage.h @@ -9,7 +9,7 @@ class MemoryMessage { private: MemoryMessage(); //A private ctor inhibits instantiation public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MEMORY; + static const uint8_t MESSAGE_ID = messagetypes::MEMORY; static const Command_t CMD_MEMORY_LOAD = MAKE_COMMAND_ID( 0x01 ); static const Command_t CMD_MEMORY_DUMP = MAKE_COMMAND_ID( 0x02 ); static const Command_t CMD_MEMORY_CHECK = MAKE_COMMAND_ID( 0x03 ); diff --git a/modes/ModeMessage.h b/modes/ModeMessage.h index f72fdeec..675c614b 100644 --- a/modes/ModeMessage.h +++ b/modes/ModeMessage.h @@ -17,7 +17,7 @@ class ModeMessage { private: ModeMessage(); public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MODE_COMMAND; + static const uint8_t MESSAGE_ID = messagetypes::MODE_COMMAND; static const Command_t CMD_MODE_COMMAND = MAKE_COMMAND_ID(0x01);//!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies, as this will break the subsystem mode machine!! static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(0xF1);//!> Command to set the specified Mode, regardless of external control flag, replies are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies, as this will break the subsystem mode machine!! static const Command_t REPLY_MODE_REPLY = MAKE_COMMAND_ID(0x02);//!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ diff --git a/monitoring/MonitoringMessage.h b/monitoring/MonitoringMessage.h index d2ff9b4d..793e1fbf 100644 --- a/monitoring/MonitoringMessage.h +++ b/monitoring/MonitoringMessage.h @@ -6,7 +6,7 @@ class MonitoringMessage: public CommandMessage { public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MONITORING; + static const uint8_t MESSAGE_ID = messagetypes::MONITORING; //Object id could be useful, but we better manage that on service level (register potential reporters). static const Command_t LIMIT_VIOLATION_REPORT = MAKE_COMMAND_ID(10); virtual ~MonitoringMessage(); diff --git a/osal/host/SemaphoreFactory.cpp b/osal/host/SemaphoreFactory.cpp index 8712d866..0c077f68 100644 --- a/osal/host/SemaphoreFactory.cpp +++ b/osal/host/SemaphoreFactory.cpp @@ -23,6 +23,7 @@ SemaphoreFactory* SemaphoreFactory::instance() { } SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { + // Just gonna wait for full C++20 for now. sif::error << "SemaphoreFactory: Binary Semaphore not implemented yet." " Returning nullptr!\n" << std::flush; return nullptr; @@ -30,6 +31,7 @@ SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { SemaphoreIF* SemaphoreFactory::createCountingSemaphore(const uint8_t maxCount, uint8_t initCount, uint32_t arguments) { + // Just gonna wait for full C++20 for now. sif::error << "SemaphoreFactory: Counting Semaphore not implemented yet." " Returning nullptr!\n" << std::flush; return nullptr; diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 86d1e0d9..a0749ded 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -9,8 +9,9 @@ #include -MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0), - lastPartner(0), defaultDestination(NO_QUEUE) { +MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): + id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE), + defaultDestination(MessageQueueIF::NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; @@ -56,16 +57,23 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, sif::error << "MessageQueue::MessageQueue: Invalid name or attributes" " for message size" << std::endl; size_t defaultMqMaxMsg = 0; + // Not POSIX conformant, but should work for all UNIX systems. + // Just an additional helpful printout :-) if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html // This happens if the msg_max value is not large enough // It is ignored if the executable is run in privileged mode. - // Run the unlockRealtime script or grant the mode manully by using: + // Run the unlockRealtime script or grant the mode manually by using: // sudo setcap 'CAP_SYS_RESOURCE=+ep' - // Permanent solution (EventManager has mq depth of 80): - // echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max + // Persistent solution for session: + // echo | sudo tee /proc/sys/fs/mqueue/msg_max + + // Permanent solution: + // sudo nano /etc/sysctl.conf + // Append at end: fs/mqueue/msg_max = + // Apply changes with: sudo sysctl -p sif::error << "MessageQueue::MessageQueue: Default MQ size " << defaultMqMaxMsg << " is too small for requested size " << messageDepth << std::endl; @@ -75,24 +83,22 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, case(EEXIST): { // An error occured during open // We need to distinguish if it is caused by an already created queue - if (errno == EEXIST) { - //There's another queue with the same name - //We unlink the other queue - int status = mq_unlink(name); - if (status != 0) { - sif::error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; - } - else { - // Successful unlinking, try to open again - mqd_t tempId = mq_open(name, - O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); - if (tempId != -1) { - //Successful mq_open - this->id = tempId; - return HasReturnvaluesIF::RETURN_OK; - } + //There's another queue with the same name + //We unlink the other queue + int status = mq_unlink(name); + if (status != 0) { + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; + } + else { + // Successful unlinking, try to open again + mqd_t tempId = mq_open(name, + O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, + S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); + if (tempId != -1) { + //Successful mq_open + this->id = tempId; + return HasReturnvaluesIF::RETURN_OK; } } break; @@ -150,12 +156,13 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { //Success but no message received return MessageQueueIF::EMPTY; } else { - //No message was received. Keep lastPartner anyway, I might send something later. - //But still, delete packet content. + //No message was received. Keep lastPartner anyway, I might send + //something later. But still, delete packet content. memset(message->getData(), 0, message->MAX_DATA_SIZE); switch(errno){ case EAGAIN: - //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages currently on the specified queue. + //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages + //currently on the specified queue. return MessageQueueIF::EMPTY; case EBADF: //mqdes doesn't represent a valid queue open for reading. @@ -165,9 +172,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { case EINVAL: /* * This value indicates one of the following: - * * The pointer to the buffer for storing the received message, msg_ptr, is NULL. - * * The number of bytes requested, msg_len is less than zero. - * * msg_len is anything other than the mq_msgsize of the specified queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't been set in the queue's mq_flags. + * - The pointer to the buffer for storing the received message, + * msg_ptr, is NULL. + * - The number of bytes requested, msg_len is less than zero. + * - msg_len is anything other than the mq_msgsize of the specified + * queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't + * been set in the queue's mq_flags. */ sif::error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; @@ -175,8 +185,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { case EMSGSIZE: /* * This value indicates one of the following: - * * the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, and the given msg_len is shorter than the mq_msgsize for the given queue. - * * the extended option MQ_READBUF_DYNAMIC has been set, but the given msg_len is too short for the message that would have been received. + * - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, + * and the given msg_len is shorter than the mq_msgsize for + * the given queue. + * - the extended option MQ_READBUF_DYNAMIC has been set, but the + * given msg_len is too short for the message that would have + * been received. */ sif::error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; @@ -224,9 +238,10 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { case EINVAL: /* * This value indicates one of the following: - * * mq_attr is NULL. - * * MQ_MULT_NOTIFY had been set for this queue, and the given mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once MQ_MULT_NOTIFY has been turned on, it may never be turned off. - * + * - mq_attr is NULL. + * - MQ_MULT_NOTIFY had been set for this queue, and the given + * mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once + * MQ_MULT_NOTIFY has been turned on, it may never be turned off. */ default: return HasReturnvaluesIF::RETURN_FAILED; @@ -275,7 +290,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, //TODO: Check if we're in ISR. if (result != 0) { if(!ignoreFault){ - InternalErrorReporterIF* internalErrorReporter = objectManager->get( + InternalErrorReporterIF* internalErrorReporter = + objectManager->get( objects::INTERNAL_ERROR_REPORTER); if (internalErrorReporter != NULL) { internalErrorReporter->queueMessageNotSent(); @@ -283,10 +299,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, } switch(errno){ case EAGAIN: - //The O_NONBLOCK flag was set when opening the queue, or the MQ_NONBLOCK flag was set in its attributes, and the specified queue is full. + //The O_NONBLOCK flag was set when opening the queue, or the + //MQ_NONBLOCK flag was set in its attributes, and the + //specified queue is full. return MessageQueueIF::FULL; case EBADF: - //mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing. + //mq_des doesn't represent a valid message queue descriptor, + //or mq_des wasn't opened for writing. sif::error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send mqSendTo: " << sendTo << " sent from " << sentFrom << std::endl; @@ -296,13 +315,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, case EINVAL: /* * This value indicates one of the following: - * * msg_ptr is NULL. - * * msg_len is negative. - * * msg_prio is greater than MQ_PRIO_MAX. - * * msg_prio is less than 0. - * * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, - * and msg_prio is greater than the priority of the calling process. - * */ + * - msg_ptr is NULL. + * - msg_len is negative. + * - msg_prio is greater than MQ_PRIO_MAX. + * - msg_prio is less than 0. + * - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and + * msg_prio is greater than the priority of the calling process. + */ sif::error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send" << std::endl; /*NO BREAK*/ diff --git a/parameters/ParameterMessage.h b/parameters/ParameterMessage.h index 0f286675..43283294 100644 --- a/parameters/ParameterMessage.h +++ b/parameters/ParameterMessage.h @@ -9,7 +9,7 @@ class ParameterMessage { private: ParameterMessage(); public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::PARAMETER; + static const uint8_t MESSAGE_ID = messagetypes::PARAMETER; static const Command_t CMD_PARAMETER_LOAD = MAKE_COMMAND_ID( 0x01 ); static const Command_t CMD_PARAMETER_DUMP = MAKE_COMMAND_ID( 0x02 ); static const Command_t REPLY_PARAMETER_DUMP = MAKE_COMMAND_ID( 0x03 ); diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h index 57c9369c..06947974 100644 --- a/storagemanager/StorageAccessor.h +++ b/storagemanager/StorageAccessor.h @@ -84,8 +84,8 @@ public: //! The copy ctor and copy assignemnt should be deleted implicitely //! according to https://foonathan.net/2019/02/special-member-functions/ //! but I still deleted them to make it more explicit. (remember rule of 5). - ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete; - ConstStorageAccessor (ConstStorageAccessor&) = delete; + ConstStorageAccessor& operator= (const ConstStorageAccessor&) = delete; + ConstStorageAccessor (const ConstStorageAccessor&) = delete; protected: const uint8_t* constDataPointer = nullptr; store_address_t storeId; diff --git a/subsystem/modes/ModeSequenceMessage.h b/subsystem/modes/ModeSequenceMessage.h index 830cf532..61d1b628 100644 --- a/subsystem/modes/ModeSequenceMessage.h +++ b/subsystem/modes/ModeSequenceMessage.h @@ -7,7 +7,7 @@ class ModeSequenceMessage { public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MODE_SEQUENCE; + static const uint8_t MESSAGE_ID = messagetypes::MODE_SEQUENCE; static const Command_t ADD_SEQUENCE = MAKE_COMMAND_ID(0x01); static const Command_t ADD_TABLE = MAKE_COMMAND_ID(0x02); diff --git a/tmstorage/TmStoreMessage.h b/tmstorage/TmStoreMessage.h index 0883063c..bd6b2def 100644 --- a/tmstorage/TmStoreMessage.h +++ b/tmstorage/TmStoreMessage.h @@ -41,7 +41,7 @@ public: static store_address_t getStoreId(const CommandMessage* cmd); virtual ~TmStoreMessage(); - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::TM_STORE; + static const uint8_t MESSAGE_ID = messagetypes::TM_STORE; static const Command_t ENABLE_STORING = MAKE_COMMAND_ID(1); static const Command_t DELETE_STORE_CONTENT = MAKE_COMMAND_ID(2); static const Command_t DOWNLINK_STORE_CONTENT = MAKE_COMMAND_ID(3); diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 5b397756..adc9400f 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -218,7 +218,7 @@ void CommandingServiceBase::handleRequestQueue() { } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, const uint8_t* data, size_t dataLen, const uint8_t* headerData, size_t headerSize) { TmPacketStored tmPacketStored(this->apid, this->service, subservice, @@ -228,36 +228,38 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice, if (result == HasReturnvaluesIF::RETURN_OK) { this->tmPacketCounter++; } + return result; } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, - object_id_t objectId, const uint8_t *data, size_t dataLen) { - uint8_t buffer[sizeof(object_id_t)]; - uint8_t* pBuffer = buffer; - size_t size = 0; - SerializeAdapter::serialize(&objectId, &pBuffer, &size, - sizeof(object_id_t), true); - TmPacketStored tmPacketStored(this->apid, this->service, subservice, - this->tmPacketCounter, data, dataLen, buffer, size); - ReturnValue_t result = tmPacketStored.sendPacket( - requestQueue->getDefaultDestination(), requestQueue->getId()); - if (result == HasReturnvaluesIF::RETURN_OK) { - this->tmPacketCounter++; - } - +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, + object_id_t objectId, const uint8_t *data, size_t dataLen) { + uint8_t buffer[sizeof(object_id_t)]; + uint8_t* pBuffer = buffer; + size_t size = 0; + SerializeAdapter::serialize(&objectId, &pBuffer, &size, + sizeof(object_id_t), true); + TmPacketStored tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, data, dataLen, buffer, size); + ReturnValue_t result = tmPacketStored.sendPacket( + requestQueue->getDefaultDestination(), requestQueue->getId()); + if (result == HasReturnvaluesIF::RETURN_OK) { + this->tmPacketCounter++; + } + return result; } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, - SerializeIF* content, SerializeIF* header) { - TmPacketStored tmPacketStored(this->apid, this->service, subservice, - this->tmPacketCounter, content, header); - ReturnValue_t result = tmPacketStored.sendPacket( - requestQueue->getDefaultDestination(), requestQueue->getId()); - if (result == HasReturnvaluesIF::RETURN_OK) { - this->tmPacketCounter++; - } +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, + SerializeIF* content, SerializeIF* header) { + TmPacketStored tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, content, header); + ReturnValue_t result = tmPacketStored.sendPacket( + requestQueue->getDefaultDestination(), requestQueue->getId()); + if (result == HasReturnvaluesIF::RETURN_OK) { + this->tmPacketCounter++; + } + return result; } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 259ed1a3..e79e806d 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -212,36 +212,38 @@ protected: */ PeriodicTaskIF* executingTask; - // todo: why do these functions not have returnvalues? the caller should be - // able to check whether the send operations actually work. /** - * Send TM data from pointer to data. If a header is supplied it is added before data + * @brief Send TM data from pointer to data. + * If a header is supplied it is added before data * @param subservice Number of subservice * @param data Pointer to the data in the Packet * @param dataLen Lenght of data in the Packet * @param headerData HeaderData will be placed before data * @param headerSize Size of HeaderData */ - void sendTmPacket(uint8_t subservice, const uint8_t *data, size_t dataLen, - const uint8_t* headerData = nullptr,size_t headerSize = 0); + ReturnValue_t sendTmPacket(uint8_t subservice, const uint8_t *data, + size_t dataLen, const uint8_t* headerData = nullptr, + size_t headerSize = 0); /** - * To send TM packets of objects that still need to be serialized and consist of an object ID with appended data + * @brief To send TM packets of objects that still need to be serialized + * and consist of an object ID with appended data. * @param subservice Number of subservice * @param objectId ObjectId is placed before data * @param data Data to append to the packet * @param dataLen Length of Data */ - void sendTmPacket(uint8_t subservice, object_id_t objectId, + ReturnValue_t sendTmPacket(uint8_t subservice, object_id_t objectId, const uint8_t *data, size_t dataLen); /** - * To send packets has data which is in form of a SerializeIF or Adapters implementing it + * @brief To send packets which are contained inside a class implementing + * SerializeIF. * @param subservice Number of subservice * @param content This is a pointer to the serialized packet * @param header Serialize IF header which will be placed before content */ - void sendTmPacket(uint8_t subservice, SerializeIF* content, + ReturnValue_t sendTmPacket(uint8_t subservice, SerializeIF* content, SerializeIF* header = nullptr); virtual void handleUnrequestedReply(CommandMessage *reply);