Merge branch 'mueller_framework' into front_branch
This commit is contained in:
commit
b6427d017b
@ -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);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <framework/datapoollocal/LocalDataPoolManager.h>
|
||||
#include <framework/datapoollocal/LocalDataSet.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/objectmanager/frameworkObjects.h>
|
||||
#include <framework/ipc/MutexFactory.h>
|
||||
#include <framework/ipc/MutexHelper.h>
|
||||
|
||||
@ -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<StorageManagerIF>(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<LocalDataSet*>(
|
||||
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<uint8_t, 256> 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;
|
||||
}
|
||||
|
@ -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!
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <framework/datapoolglob/GlobalPoolVariable.h>
|
||||
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
|
||||
#include <framework/globalfunctions/CRC.h>
|
||||
#include <framework/housekeeping/HousekeepingMessage.h>
|
||||
#include <framework/ipc/MessageQueueMessage.h>
|
||||
#include <framework/subsystem/SubsystemBase.h>
|
||||
#include <framework/ipc/QueueFactory.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
@ -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<CommandMessage*>(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<HousekeepingMessage*>(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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -1,5 +1,13 @@
|
||||
#include <framework/housekeeping/HousekeepingMessage.h>
|
||||
|
||||
HousekeepingMessage::HousekeepingMessage() {
|
||||
|
||||
}
|
||||
|
||||
void HousekeepingMessage::setHkReportMessage() {
|
||||
}
|
||||
|
||||
|
||||
//void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message,
|
||||
// set_t setId, store_address_t packet) {
|
||||
// message->setCommand(ADD_HK_REPORT_STRUCT);
|
||||
|
@ -5,12 +5,14 @@
|
||||
#include <limits>
|
||||
|
||||
union sid_t {
|
||||
static constexpr uint64_t INVALID_ADDRESS = std::numeric_limits<uint64_t>::max();
|
||||
static constexpr uint64_t INVALID_ADDRESS =
|
||||
std::numeric_limits<uint64_t>::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();
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,10 +1,3 @@
|
||||
/**
|
||||
* @file CommandMessage.cpp
|
||||
* @brief This file defines the CommandMessage class.
|
||||
* @date 20.06.2013
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#include <framework/devicehandlers/DeviceHandlerMessage.h>
|
||||
#include <framework/health/HealthMessage.h>
|
||||
#include <framework/ipc/CommandMessage.h>
|
||||
@ -15,7 +8,8 @@
|
||||
#include <framework/tmstorage/TmStoreMessage.h>
|
||||
#include <framework/parameters/ParameterMessage.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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 <framework/ipc/FwMessageTypes.h>
|
||||
#include <config/ipc/MissionMessageTypes.h>
|
||||
@ -15,10 +7,11 @@
|
||||
#include <framework/ipc/MessageQueueMessage.h>
|
||||
|
||||
#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
|
||||
* @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;
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef MESSAGEQUEUEMESSAGE_H_
|
||||
#define MESSAGEQUEUEMESSAGE_H_
|
||||
|
||||
#include <framework/ipc/MessageQueueMessageIF.h>
|
||||
#include <framework/ipc/MessageQueueSenderIF.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@ -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
|
||||
|
49
ipc/MessageQueueMessageIF.h
Normal file
49
ipc/MessageQueueMessageIF.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_
|
||||
#define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_
|
||||
#include <framework/ipc/MessageQueueSenderIF.h>
|
||||
#include <cstddef>
|
||||
|
||||
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_ */
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -9,8 +9,9 @@
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
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' <pathToBinary>
|
||||
|
||||
// Permanent solution (EventManager has mq depth of 80):
|
||||
// echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max
|
||||
// Persistent solution for session:
|
||||
// echo <newMsgMax> | sudo tee /proc/sys/fs/mqueue/msg_max
|
||||
|
||||
// Permanent solution:
|
||||
// sudo nano /etc/sysctl.conf
|
||||
// Append at end: fs/mqueue/msg_max = <newMsgMaxLen>
|
||||
// Apply changes with: sudo sysctl -p
|
||||
sif::error << "MessageQueue::MessageQueue: Default MQ size "
|
||||
<< defaultMqMaxMsg << " is too small for requested size "
|
||||
<< messageDepth << std::endl;
|
||||
@ -75,7 +83,6 @@ 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);
|
||||
@ -94,7 +101,6 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
|
||||
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>(
|
||||
InternalErrorReporterIF* internalErrorReporter =
|
||||
objectManager->get<InternalErrorReporterIF>(
|
||||
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*/
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,10 +228,11 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice,
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
this->tmPacketCounter++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void CommandingServiceBase::sendTmPacket(uint8_t subservice,
|
||||
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;
|
||||
@ -245,11 +246,11 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice,
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
this->tmPacketCounter++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void CommandingServiceBase::sendTmPacket(uint8_t subservice,
|
||||
ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice,
|
||||
SerializeIF* content, SerializeIF* header) {
|
||||
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
|
||||
this->tmPacketCounter, content, header);
|
||||
@ -258,6 +259,7 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice,
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
this->tmPacketCounter++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user