Today's the day. Renamed platform to framework.
This commit is contained in:
43
tmtcservices/AcceptsTelecommandsIF.h
Normal file
43
tmtcservices/AcceptsTelecommandsIF.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef ACCEPTSTELECOMMANDSIF_H_
|
||||
#define ACCEPTSTELECOMMANDSIF_H_
|
||||
|
||||
#include <framework/ipc/MessageQueue.h>
|
||||
|
||||
/**
|
||||
* @brief This interface is implemented by classes that are sinks for
|
||||
* Telecommands.
|
||||
* @details Any service receiving telecommands shall implement this interface
|
||||
* and thus make the service id and the receiving message queue public.
|
||||
*/
|
||||
class AcceptsTelecommandsIF {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = ACCEPTS_TELECOMMANDS_IF;
|
||||
static const ReturnValue_t ACTIVITY_STARTED = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t INVALID_SUBSERVICE = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t ILLEGAL_APPLICATION_DATA = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t SEND_TM_FAILED = MAKE_RETURN_CODE(4);
|
||||
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(5);
|
||||
/**
|
||||
* @brief The virtual destructor as it is mandatory for C++ interfaces.
|
||||
*/
|
||||
virtual ~AcceptsTelecommandsIF() {
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief Getter for the service id.
|
||||
* @details Any receiving service (at least any PUS service) shall have a
|
||||
* service id. If the receiver can handle Telecommands, but for
|
||||
* some reason has no service id, it shall return 0.
|
||||
* @return The service id or 0.
|
||||
*/
|
||||
virtual uint16_t getIdentifier() = 0;
|
||||
/**
|
||||
* @brief This method returns the message queue id of the telecommand
|
||||
* receiving message queue.
|
||||
* @return The telecommand reception message queue id.
|
||||
*/
|
||||
virtual MessageQueueId_t getRequestQueue() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* ACCEPTSTELECOMMANDSIF_H_ */
|
26
tmtcservices/AcceptsTelemetryIF.h
Normal file
26
tmtcservices/AcceptsTelemetryIF.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef ACCEPTSTELEMETRYIF_H_
|
||||
#define ACCEPTSTELEMETRYIF_H_
|
||||
|
||||
#include <framework/ipc/MessageQueueSender.h>
|
||||
/**
|
||||
* @brief This interface is implemented by classes that are sinks for
|
||||
* Telemetry.
|
||||
* @details Any object receiving telemetry shall implement this interface
|
||||
* and thus make the service id and the receiving message queue public.
|
||||
*/
|
||||
class AcceptsTelemetryIF {
|
||||
public:
|
||||
/**
|
||||
* @brief The virtual destructor as it is mandatory for C++ interfaces.
|
||||
*/
|
||||
virtual ~AcceptsTelemetryIF() {
|
||||
}
|
||||
/**
|
||||
* @brief This method returns the message queue id of the telemetry
|
||||
* receiving message queue.
|
||||
* @return The telemetry reception message queue id.
|
||||
*/
|
||||
virtual MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) = 0;
|
||||
};
|
||||
|
||||
#endif /* ACCEPTSTELEMETRYIF_H_ */
|
22
tmtcservices/AcceptsVerifyMessageIF.h
Normal file
22
tmtcservices/AcceptsVerifyMessageIF.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* AcceptsVerifyMessageIF.h
|
||||
*
|
||||
* Created on: 23.11.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef ACCEPTSVERIFICATIONMESSAGEIF_H_
|
||||
#define ACCEPTSVERIFICATIONMESSAGEIF_H_
|
||||
|
||||
#include <framework/ipc/MessageQueue.h>
|
||||
|
||||
class AcceptsVerifyMessageIF {
|
||||
public:
|
||||
virtual ~AcceptsVerifyMessageIF() {
|
||||
|
||||
}
|
||||
virtual MessageQueueId_t getVerificationQueue() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* ACCEPTSVERIFICATIONMESSAGEIF_H_ */
|
486
tmtcservices/CommandingServiceBase.h
Normal file
486
tmtcservices/CommandingServiceBase.h
Normal file
@ -0,0 +1,486 @@
|
||||
#ifndef COMMANDINGSERVICEBASE_H_
|
||||
#define COMMANDINGSERVICEBASE_H_
|
||||
|
||||
#include <framework/container/FixedMap.h>
|
||||
#include <framework/container/FIFO.h>
|
||||
#include <framework/ipc/CommandMessage.h>
|
||||
#include <framework/ipc/MessageQueue.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/tcdistribution/PUSDistributorIF.h>
|
||||
#include <framework/tmtcpacket/pus/TcPacketStored.h>
|
||||
#include <framework/tmtcpacket/pus/TmPacketStored.h>
|
||||
#include <framework/tmtcservices/AcceptsTelecommandsIF.h>
|
||||
#include <framework/tmtcservices/AcceptsTelemetryIF.h>
|
||||
#include <framework/tmtcservices/TmTcMessage.h>
|
||||
#include <framework/tmtcservices/VerificationReporter.h>
|
||||
|
||||
template<typename STATE_T>
|
||||
class CommandingServiceBase: public SystemObject,
|
||||
public AcceptsTelecommandsIF,
|
||||
public ExecutableObjectIF,
|
||||
public HasReturnvaluesIF {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = COMMAND_SERVICE_BASE;
|
||||
static const ReturnValue_t EXECUTION_COMPLETE = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t NO_STEP_MESSAGE = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t OBJECT_BUSY = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(4);
|
||||
static const ReturnValue_t INVALID_TC = MAKE_RETURN_CODE(5);
|
||||
static const ReturnValue_t INVALID_OBJECT = MAKE_RETURN_CODE(6);
|
||||
static const ReturnValue_t INVALID_REPLY = MAKE_RETURN_CODE(7);
|
||||
|
||||
CommandingServiceBase(object_id_t setObjectId, uint16_t apid,
|
||||
uint8_t service, uint8_t numberOfParallelCommands,
|
||||
uint16_t commandTimeout_seconds, size_t queueDepth = 20);
|
||||
virtual ~CommandingServiceBase();
|
||||
|
||||
virtual ReturnValue_t performOperation();
|
||||
|
||||
virtual uint16_t getIdentifier();
|
||||
|
||||
virtual MessageQueueId_t getRequestQueue();
|
||||
|
||||
virtual ReturnValue_t initialize();
|
||||
|
||||
protected:
|
||||
struct CommandInfo {
|
||||
struct tcInfo {
|
||||
uint8_t ackFlags;
|
||||
uint16_t tcPacketId;
|
||||
uint16_t tcSequenceControl;
|
||||
} tcInfo;
|
||||
uint32_t uptimeOfStart;
|
||||
uint8_t step;
|
||||
uint8_t subservice;
|
||||
STATE_T state;
|
||||
Command_t command;
|
||||
object_id_t objectId;
|
||||
FIFO<store_address_t, 3> fifo;
|
||||
};
|
||||
|
||||
const uint16_t apid;
|
||||
|
||||
const uint8_t service;
|
||||
|
||||
const uint16_t timeout_seconds;
|
||||
|
||||
uint8_t tmPacketCounter;
|
||||
|
||||
StorageManagerIF *IPCStore;
|
||||
|
||||
StorageManagerIF *TCStore;
|
||||
|
||||
MessageQueue commandQueue;
|
||||
|
||||
MessageQueue requestQueue;
|
||||
|
||||
VerificationReporter verificationReporter;
|
||||
|
||||
FixedMap<MessageQueueId_t, CommandInfo> commandMap;
|
||||
|
||||
uint32_t failureParameter1; //!< May be set be children to return a more precise failure condition.
|
||||
uint32_t failureParameter2; //!< May be set be children to return a more precise failure condition.
|
||||
|
||||
void sendTmPacket(uint8_t subservice, const uint8_t *data,
|
||||
uint32_t dataLen);
|
||||
void sendTmPacket(uint8_t subservice, object_id_t objectId,
|
||||
const uint8_t *data, uint32_t dataLen);
|
||||
|
||||
void sendTmPacket(uint8_t subservice, SerializeIF* content);
|
||||
virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0;
|
||||
|
||||
virtual ReturnValue_t prepareCommand(CommandMessage *message,
|
||||
uint8_t subservice, const uint8_t *tcData, uint32_t tcDataLen,
|
||||
STATE_T *state, object_id_t objectId) = 0;
|
||||
|
||||
virtual ReturnValue_t handleReply(const CommandMessage *reply,
|
||||
Command_t previousCommand, STATE_T *state,
|
||||
CommandMessage *optionalNextCommand, object_id_t objectId,
|
||||
bool *isStep) = 0;
|
||||
|
||||
virtual ReturnValue_t getMessageQueueAndObject(uint8_t subservice,
|
||||
const uint8_t *tcData, uint32_t tcDataLen, MessageQueueId_t *id,
|
||||
object_id_t *objectId) = 0;
|
||||
|
||||
virtual void handleUnrequestedReply(CommandMessage *reply);
|
||||
|
||||
virtual void doPeriodicOperation();
|
||||
|
||||
private:
|
||||
void handleCommandQueue();
|
||||
|
||||
void handleRequestQueue();
|
||||
|
||||
void rejectPacket(uint8_t reportId, TcPacketStored* packet,
|
||||
ReturnValue_t errorCode);
|
||||
|
||||
void acceptPacket(uint8_t reportId, TcPacketStored* packet);
|
||||
|
||||
void startExecution(TcPacketStored *storedPacket,
|
||||
typename FixedMap<MessageQueueId_t, CommandInfo>::Iterator *iter);
|
||||
|
||||
void checkAndExecuteFifo(
|
||||
typename FixedMap<MessageQueueId_t, CommandInfo>::Iterator *iter);
|
||||
|
||||
void checkTimeout();
|
||||
};
|
||||
|
||||
template<typename STATE_T>
|
||||
CommandingServiceBase<STATE_T>::CommandingServiceBase(object_id_t setObjectId,
|
||||
uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands,
|
||||
uint16_t commandTimeout_seconds, size_t queueDepth) :
|
||||
SystemObject(setObjectId), apid(apid), service(service), timeout_seconds(
|
||||
commandTimeout_seconds), tmPacketCounter(0), IPCStore(NULL), TCStore(
|
||||
NULL), commandQueue(queueDepth), requestQueue(20), commandMap(
|
||||
numberOfParallelCommands), failureParameter1(0), failureParameter2(
|
||||
0) {
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
CommandingServiceBase<STATE_T>::~CommandingServiceBase() {
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
ReturnValue_t CommandingServiceBase<STATE_T>::performOperation() {
|
||||
handleCommandQueue();
|
||||
handleRequestQueue();
|
||||
checkTimeout();
|
||||
doPeriodicOperation();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
uint16_t CommandingServiceBase<STATE_T>::getIdentifier() {
|
||||
return service;
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
MessageQueueId_t CommandingServiceBase<STATE_T>::getRequestQueue() {
|
||||
return requestQueue.getId();
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
ReturnValue_t CommandingServiceBase<STATE_T>::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
AcceptsTelemetryIF* packetForwarding =
|
||||
objectManager->get<AcceptsTelemetryIF>(
|
||||
objects::PUS_PACKET_FORWARDING);
|
||||
PUSDistributorIF* distributor = objectManager->get<PUSDistributorIF>(
|
||||
objects::PUS_PACKET_DISTRIBUTOR);
|
||||
if ((packetForwarding == NULL) && (distributor == NULL)) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
distributor->registerService(this);
|
||||
requestQueue.setDefaultDestination(
|
||||
packetForwarding->getReportReceptionQueue());
|
||||
|
||||
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
TCStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
|
||||
|
||||
if ((IPCStore == NULL) || (TCStore == NULL)) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
|
||||
}
|
||||
|
||||
//Whole method works like this, but I don't like it. Leave it anyway.
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::handleCommandQueue() {
|
||||
CommandMessage reply, nextCommand;
|
||||
ReturnValue_t result, sendResult = RETURN_OK;
|
||||
bool isStep = false;
|
||||
for (result = commandQueue.receiveMessage(&reply); result == RETURN_OK;
|
||||
result = commandQueue.receiveMessage(&reply)) {
|
||||
isStep = false;
|
||||
typename FixedMap<MessageQueueId_t,
|
||||
CommandingServiceBase<STATE_T>::CommandInfo>::Iterator iter;
|
||||
if ((iter = commandMap.find(reply.getSender())) == commandMap.end()) {
|
||||
handleUnrequestedReply(&reply);
|
||||
continue;
|
||||
}
|
||||
nextCommand.setCommand(CommandMessage::CMD_NONE);
|
||||
result = handleReply(&reply, iter->command, &iter->state, &nextCommand,
|
||||
iter->objectId, &isStep);
|
||||
switch (result) {
|
||||
case EXECUTION_COMPLETE:
|
||||
case RETURN_OK:
|
||||
case NO_STEP_MESSAGE:
|
||||
iter->command = nextCommand.getCommand();
|
||||
if (nextCommand.getCommand() != CommandMessage::CMD_NONE) {
|
||||
sendResult = commandQueue.sendMessage(reply.getSender(),
|
||||
&nextCommand);
|
||||
}
|
||||
if (sendResult == RETURN_OK) {
|
||||
if (isStep) {
|
||||
if (result != NO_STEP_MESSAGE) {
|
||||
verificationReporter.sendSuccessReport(
|
||||
TC_VERIFY::PROGRESS_SUCCESS,
|
||||
iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId,
|
||||
iter->tcInfo.tcSequenceControl, ++iter->step);
|
||||
}
|
||||
} else {
|
||||
verificationReporter.sendSuccessReport(
|
||||
TC_VERIFY::COMPLETION_SUCCESS,
|
||||
iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId,
|
||||
iter->tcInfo.tcSequenceControl, 0);
|
||||
checkAndExecuteFifo(&iter);
|
||||
}
|
||||
} else {
|
||||
if (isStep) {
|
||||
nextCommand.clearCommandMessage();
|
||||
verificationReporter.sendFailureReport(
|
||||
TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags,
|
||||
iter->tcInfo.tcPacketId,
|
||||
iter->tcInfo.tcSequenceControl, sendResult,
|
||||
++iter->step, failureParameter1, failureParameter2);
|
||||
} else {
|
||||
nextCommand.clearCommandMessage();
|
||||
verificationReporter.sendFailureReport(
|
||||
TC_VERIFY::COMPLETION_FAILURE,
|
||||
iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId,
|
||||
iter->tcInfo.tcSequenceControl, sendResult,
|
||||
0, failureParameter1, failureParameter2);
|
||||
}
|
||||
failureParameter1 = 0;
|
||||
failureParameter2 = 0;
|
||||
checkAndExecuteFifo(&iter);
|
||||
}
|
||||
break;
|
||||
case INVALID_REPLY:
|
||||
//might be just an unrequested reply at a bad moment
|
||||
handleUnrequestedReply(&reply);
|
||||
break;
|
||||
default:
|
||||
if (isStep) {
|
||||
verificationReporter.sendFailureReport(
|
||||
TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags,
|
||||
iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl,
|
||||
result, ++iter->step, failureParameter1, failureParameter2);
|
||||
} else {
|
||||
verificationReporter.sendFailureReport(
|
||||
TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags,
|
||||
iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl,
|
||||
result, 0, failureParameter1, failureParameter2);
|
||||
}
|
||||
failureParameter1 = 0;
|
||||
failureParameter2 = 0;
|
||||
checkAndExecuteFifo(&iter);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::handleRequestQueue() {
|
||||
TmTcMessage message;
|
||||
ReturnValue_t result;
|
||||
store_address_t address;
|
||||
TcPacketStored packet;
|
||||
MessageQueueId_t queue;
|
||||
object_id_t objectId;
|
||||
for (result = requestQueue.receiveMessage(&message); result == RETURN_OK;
|
||||
result = requestQueue.receiveMessage(&message)) {
|
||||
address = message.getStorageId();
|
||||
packet.setStoreAddress(address);
|
||||
|
||||
if ((packet.getSubService() == 0)
|
||||
|| (isValidSubservice(packet.getSubService()) != RETURN_OK)) {
|
||||
rejectPacket(TC_VERIFY::START_FAILURE, &packet, INVALID_SUBSERVICE);
|
||||
continue;
|
||||
}
|
||||
result = getMessageQueueAndObject(packet.getSubService(),
|
||||
packet.getApplicationData(), packet.getApplicationDataSize(),
|
||||
&queue, &objectId);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
rejectPacket(TC_VERIFY::START_FAILURE, &packet, result);
|
||||
continue;
|
||||
}
|
||||
|
||||
//is a command already active for the target object?
|
||||
typename FixedMap<MessageQueueId_t,
|
||||
CommandingServiceBase<STATE_T>::CommandInfo>::Iterator iter;
|
||||
iter = commandMap.find(queue);
|
||||
|
||||
if (iter != commandMap.end()) {
|
||||
result = iter->fifo.insert(address);
|
||||
if (result != RETURN_OK) {
|
||||
rejectPacket(TC_VERIFY::START_FAILURE, &packet, OBJECT_BUSY);
|
||||
}
|
||||
} else {
|
||||
CommandInfo newInfo; //Info will be set by startExecution if neccessary
|
||||
newInfo.objectId = objectId;
|
||||
result = commandMap.insert(queue, newInfo, &iter);
|
||||
if (result != RETURN_OK) {
|
||||
rejectPacket(TC_VERIFY::START_FAILURE, &packet, BUSY);
|
||||
} else {
|
||||
startExecution(&packet, &iter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::sendTmPacket(uint8_t subservice,
|
||||
const uint8_t* data, uint32_t dataLen) {
|
||||
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
|
||||
this->tmPacketCounter++, data, dataLen);
|
||||
TmTcMessage tmMessage(tmPacketStored.getStoreAddress());
|
||||
if (requestQueue.sendToDefault(&tmMessage) != RETURN_OK) {
|
||||
tmPacketStored.deletePacket();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::sendTmPacket(uint8_t subservice,
|
||||
object_id_t objectId, const uint8_t *data, uint32_t dataLen) {
|
||||
uint8_t buffer[sizeof(object_id_t)];
|
||||
uint8_t* pBuffer = buffer;
|
||||
uint32_t size = 0;
|
||||
SerializeAdapter<object_id_t>::serialize(&objectId, &pBuffer, &size,
|
||||
sizeof(object_id_t), true);
|
||||
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
|
||||
this->tmPacketCounter++, data, dataLen, buffer, size);
|
||||
TmTcMessage tmMessage(tmPacketStored.getStoreAddress());
|
||||
if (requestQueue.sendToDefault(&tmMessage) != RETURN_OK) {
|
||||
tmPacketStored.deletePacket();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::sendTmPacket(uint8_t subservice,
|
||||
SerializeIF* content) {
|
||||
TmPacketStored tmPacketStored(this->apid, this->service, subservice,
|
||||
this->tmPacketCounter++, content);
|
||||
TmTcMessage tmMessage(tmPacketStored.getStoreAddress());
|
||||
if (requestQueue.sendToDefault(&tmMessage) != RETURN_OK) {
|
||||
tmPacketStored.deletePacket();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::startExecution(
|
||||
TcPacketStored *storedPacket,
|
||||
typename FixedMap<MessageQueueId_t,
|
||||
CommandingServiceBase<STATE_T>::CommandInfo>::Iterator *iter) {
|
||||
ReturnValue_t result, sendResult = RETURN_OK;
|
||||
CommandMessage message;
|
||||
(*iter)->subservice = storedPacket->getSubService();
|
||||
result = prepareCommand(&message, (*iter)->subservice,
|
||||
storedPacket->getApplicationData(),
|
||||
storedPacket->getApplicationDataSize(), &(*iter)->state,
|
||||
(*iter)->objectId);
|
||||
|
||||
switch (result) {
|
||||
case RETURN_OK:
|
||||
if (message.getCommand() != CommandMessage::CMD_NONE) {
|
||||
sendResult = commandQueue.sendMessage((*iter).value->first,
|
||||
&message);
|
||||
}
|
||||
if (sendResult == RETURN_OK) {
|
||||
OSAL::getUptime(&(*iter)->uptimeOfStart);
|
||||
(*iter)->step = 0;
|
||||
// (*iter)->state = 0;
|
||||
(*iter)->subservice = storedPacket->getSubService();
|
||||
(*iter)->command = message.getCommand();
|
||||
(*iter)->tcInfo.ackFlags = storedPacket->getAcknowledgeFlags();
|
||||
(*iter)->tcInfo.tcPacketId = storedPacket->getPacketId();
|
||||
(*iter)->tcInfo.tcSequenceControl =
|
||||
storedPacket->getPacketSequenceControl();
|
||||
acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket);
|
||||
} else {
|
||||
message.clearCommandMessage();
|
||||
rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult);
|
||||
checkAndExecuteFifo(iter);
|
||||
}
|
||||
break;
|
||||
case EXECUTION_COMPLETE:
|
||||
if (message.getCommand() != CommandMessage::CMD_NONE) {
|
||||
//Fire-and-forget command.
|
||||
sendResult = commandQueue.sendMessage((*iter).value->first,
|
||||
&message);
|
||||
}
|
||||
if (sendResult == RETURN_OK) {
|
||||
verificationReporter.sendSuccessReport(TC_VERIFY::START_SUCCESS,
|
||||
storedPacket);
|
||||
acceptPacket(TC_VERIFY::COMPLETION_SUCCESS, storedPacket);
|
||||
checkAndExecuteFifo(iter);
|
||||
} else {
|
||||
message.clearCommandMessage();
|
||||
rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult);
|
||||
checkAndExecuteFifo(iter);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, result);
|
||||
checkAndExecuteFifo(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::rejectPacket(uint8_t report_id,
|
||||
TcPacketStored* packet, ReturnValue_t error_code) {
|
||||
verificationReporter.sendFailureReport(report_id, packet, error_code);
|
||||
packet->deletePacket();
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::acceptPacket(uint8_t reportId,
|
||||
TcPacketStored* packet) {
|
||||
verificationReporter.sendSuccessReport(reportId, packet);
|
||||
packet->deletePacket();
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::checkAndExecuteFifo(
|
||||
typename FixedMap<MessageQueueId_t,
|
||||
CommandingServiceBase<STATE_T>::CommandInfo>::Iterator *iter) {
|
||||
store_address_t address;
|
||||
if ((*iter)->fifo.retrieve(&address) != RETURN_OK) {
|
||||
commandMap.erase(iter);
|
||||
} else {
|
||||
TcPacketStored newPacket(address);
|
||||
startExecution(&newPacket, iter);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::handleUnrequestedReply(
|
||||
CommandMessage* reply) {
|
||||
reply->clearCommandMessage();
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
inline void CommandingServiceBase<STATE_T>::doPeriodicOperation() {
|
||||
}
|
||||
|
||||
template<typename STATE_T>
|
||||
void CommandingServiceBase<STATE_T>::checkTimeout() {
|
||||
uint32_t uptime;
|
||||
OSAL::getUptime(&uptime);
|
||||
typename FixedMap<MessageQueueId_t,
|
||||
CommandingServiceBase<STATE_T>::CommandInfo>::Iterator iter;
|
||||
for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) {
|
||||
if ((iter->uptimeOfStart + (timeout_seconds * 1000)) < uptime) {
|
||||
verificationReporter.sendFailureReport(
|
||||
TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags,
|
||||
iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl,
|
||||
TIMEOUT);
|
||||
checkAndExecuteFifo(&iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* COMMANDINGSERVICEBASE_H_ */
|
99
tmtcservices/PusServiceBase.cpp
Normal file
99
tmtcservices/PusServiceBase.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* PusServiceBase.cpp
|
||||
*
|
||||
* Created on: May 9, 2012
|
||||
* Author: baetz
|
||||
*/
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tcdistribution/PUSDistributorIF.h>
|
||||
#include <framework/tmtcservices/AcceptsTelemetryIF.h>
|
||||
#include <framework/tmtcservices/PusServiceBase.h>
|
||||
#include <framework/tmtcservices/PusVerificationReport.h>
|
||||
#include <framework/tmtcservices/TmTcMessage.h>
|
||||
|
||||
PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t set_apid,
|
||||
uint8_t set_service_id) :
|
||||
SystemObject(setObjectId), apid(set_apid), serviceId(set_service_id), errorParameter1(
|
||||
0), errorParameter2(0), requestQueue(PUS_SERVICE_MAX_RECEPTION) {
|
||||
}
|
||||
|
||||
PusServiceBase::~PusServiceBase() {
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t PusServiceBase::performOperation() {
|
||||
TmTcMessage message;
|
||||
for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) {
|
||||
ReturnValue_t status = this->requestQueue.receiveMessage(&message);
|
||||
// debug << "PusServiceBase::performOperation: Receiving from MQ ID: " << std::hex << this->requestQueue.getId() << std::dec << " returned: " << status << std::endl;
|
||||
if (status == RETURN_OK) {
|
||||
this->currentPacket.setStoreAddress(message.getStorageId());
|
||||
// info << "Service " << (uint16_t) this->serviceId << ": new packet!"
|
||||
// << std::endl;
|
||||
|
||||
ReturnValue_t return_code = this->handleRequest();
|
||||
// debug << "Service " << (uint16_t)this->serviceId << ": handleRequest returned: " << (int)return_code << std::endl;
|
||||
if (return_code == RETURN_OK) {
|
||||
this->verifyReporter.sendSuccessReport(
|
||||
TC_VERIFY::COMPLETION_SUCCESS, &this->currentPacket);
|
||||
} else {
|
||||
this->verifyReporter.sendFailureReport(
|
||||
TC_VERIFY::COMPLETION_FAILURE, &this->currentPacket,
|
||||
return_code, 0, errorParameter1, errorParameter2);
|
||||
}
|
||||
this->currentPacket.deletePacket();
|
||||
errorParameter1 = 0;
|
||||
errorParameter2 = 0;
|
||||
} else if (status == OSAL::QUEUE_EMPTY) {
|
||||
status = RETURN_OK;
|
||||
// debug << "PusService " << (uint16_t)this->serviceId << ": no new packet." << std::endl;
|
||||
break;
|
||||
} else {
|
||||
|
||||
error << "PusServiceBase::performOperation: Service "
|
||||
<< (uint16_t) this->serviceId
|
||||
<< ": Error receiving packet. Code: " << std::hex << status
|
||||
<< std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
ReturnValue_t return_code = this->performService();
|
||||
if (return_code == RETURN_OK) {
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
|
||||
error << "PusService " << (uint16_t) this->serviceId
|
||||
<< ": performService returned with " << (int16_t) return_code
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t PusServiceBase::getIdentifier() {
|
||||
return this->serviceId;
|
||||
}
|
||||
|
||||
MessageQueueId_t PusServiceBase::getRequestQueue() {
|
||||
return this->requestQueue.getId();
|
||||
}
|
||||
|
||||
ReturnValue_t PusServiceBase::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
AcceptsTelemetryIF* dest_service = objectManager->get<AcceptsTelemetryIF>(
|
||||
objects::PUS_PACKET_FORWARDING);
|
||||
PUSDistributorIF* distributor = objectManager->get<PUSDistributorIF>(
|
||||
objects::PUS_PACKET_DISTRIBUTOR);
|
||||
if ((dest_service != NULL) && (distributor != NULL)) {
|
||||
this->requestQueue.setDefaultDestination(
|
||||
dest_service->getReportReceptionQueue());
|
||||
distributor->registerService(this);
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
error << "PusServiceBase::PusServiceBase: Service "
|
||||
<< (uint32_t) this->serviceId << ": Configuration error."
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
112
tmtcservices/PusServiceBase.h
Normal file
112
tmtcservices/PusServiceBase.h
Normal file
@ -0,0 +1,112 @@
|
||||
#ifndef PUSSERVICEBASE_H_
|
||||
#define PUSSERVICEBASE_H_
|
||||
|
||||
#include <framework/ipc/MessageQueue.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/tmtcpacket/pus/TcPacketStored.h>
|
||||
#include <framework/tmtcservices/AcceptsTelecommandsIF.h>
|
||||
#include <framework/tmtcservices/VerificationCodes.h>
|
||||
#include <framework/tmtcservices/VerificationReporter.h>
|
||||
|
||||
/**
|
||||
* \defgroup pus_services PUS Service Framework
|
||||
* These group contains all implementations of PUS Services in the OBSW.
|
||||
* Most of the Services are directly taken from the ECSS PUS Standard.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class is the basis for all PUS Services, which can immediately process Telecommand Packets.
|
||||
* It manages Telecommand reception and the generation of Verification Reports. Every class that inherits
|
||||
* from this abstract class has to implement handleRequest and performService. Services that are created with this
|
||||
* Base class have to handle any kind of request immediately on reception.
|
||||
* All PUS Services are System Objects, so an Object ID needs to be specified on construction.
|
||||
* \ingroup pus_services
|
||||
*/
|
||||
class PusServiceBase : public ExecutableObjectIF, public AcceptsTelecommandsIF, public SystemObject, public HasReturnvaluesIF {
|
||||
private:
|
||||
/**
|
||||
* This constant sets the maximum number of packets accepted per call.
|
||||
* Remember that one packet must be completely handled in one #handleRequest call.
|
||||
*/
|
||||
static const uint8_t PUS_SERVICE_MAX_RECEPTION = 10;
|
||||
protected:
|
||||
/**
|
||||
* The APID of this instance of the Service.
|
||||
*/
|
||||
uint16_t apid;
|
||||
/**
|
||||
* The Service Identifier.
|
||||
*/
|
||||
uint8_t serviceId;
|
||||
/**
|
||||
* One of two error parameters for additional error information.
|
||||
*/
|
||||
uint32_t errorParameter1;
|
||||
/**
|
||||
* One of two error parameters for additional error information.
|
||||
*/
|
||||
uint8_t errorParameter2;
|
||||
/**
|
||||
* This is a complete instance of the Telecommand reception queue of the class.
|
||||
* It is initialized on construction of the class.
|
||||
*/
|
||||
MessageQueue requestQueue;
|
||||
/**
|
||||
* An instance of the VerificationReporter class, that simplifies sending any kind of
|
||||
* Verification Message to the TC Verification Service.
|
||||
*/
|
||||
VerificationReporter verifyReporter;
|
||||
/**
|
||||
* The current Telecommand to be processed.
|
||||
* It is deleted after handleRequest was executed.
|
||||
*/
|
||||
TcPacketStored currentPacket;
|
||||
public:
|
||||
/**
|
||||
* The constructor for the class.
|
||||
* The passed values are set, but inter-object initialization is done in the initialize method.
|
||||
* @param setObjectId The system object identifier of this Service instance.
|
||||
* @param set_apid The APID the Service is instantiated for.
|
||||
* @param set_service_id The Service Identifier as specified in ECSS PUS.
|
||||
*/
|
||||
PusServiceBase( object_id_t setObjectId, uint16_t set_apid, uint8_t set_service_id );
|
||||
/**
|
||||
* The destructor is empty.
|
||||
*/
|
||||
virtual ~PusServiceBase();
|
||||
/**
|
||||
* The handleRequest method shall handle any kind of Telecommand Request immediately.
|
||||
* Implemetations can take the Telecommand in currentPacket and perform any kind of operation.
|
||||
* They may send additional "Start Success (1,3)" messages with the verifyReporter, but Completion
|
||||
* Success or Failure Reports are generated automatically after execution of this method.
|
||||
* If a Telecommand can not be executed within one call cycle, this Base class is not the right parent.
|
||||
* The child class may add additional error information in #errorParameters which are attached to the generated
|
||||
* verification message.
|
||||
* @return The returned status_code is directly taken as main error code in the Verification Report.
|
||||
* On success, RETURN_OK shall be returned.
|
||||
*/
|
||||
virtual ReturnValue_t handleRequest() = 0;
|
||||
/**
|
||||
* In performService, implementations can handle periodic, non-TC-triggered activities.
|
||||
* The performService method is always called.
|
||||
* @return A success or failure code that does not trigger any kind of verification message.
|
||||
*/
|
||||
virtual ReturnValue_t performService() = 0;
|
||||
/**
|
||||
* This method implements the typical activity of a simple PUS Service.
|
||||
* It checks for new requests, and, if found, calls handleRequest, sends completion verification messages and deletes
|
||||
* the TC requests afterwards.
|
||||
* performService is always executed afterwards.
|
||||
* @return - \c RETURN_OK if the periodic performService was successfull.
|
||||
* - \c RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t performOperation();
|
||||
virtual uint16_t getIdentifier();
|
||||
MessageQueueId_t getRequestQueue();
|
||||
virtual ReturnValue_t initialize();
|
||||
};
|
||||
|
||||
#endif /* PUSSERVICEBASE_H_ */
|
170
tmtcservices/PusVerificationReport.cpp
Normal file
170
tmtcservices/PusVerificationReport.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* PusVerificationReport.cpp
|
||||
*
|
||||
* Created on: 22.05.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
#include <framework/tmtcservices/PusVerificationReport.h>
|
||||
|
||||
PusVerificationMessage::PusVerificationMessage() {
|
||||
}
|
||||
|
||||
//PusVerificationMessage::PusVerificationMessage(uint8_t set_report_id,
|
||||
// TcPacketBase* current_packet, ReturnValue_t set_error_code,
|
||||
// uint8_t set_step, uint32_t parameter1, uint32_t parameter2) {
|
||||
// uint8_t ackFlags = current_packet->getAcknowledgeFlags();
|
||||
// uint16_t tcPacketId = current_packet->getPacketId();
|
||||
// uint16_t tcSequenceControl = current_packet->getPacketSequenceControl();
|
||||
// uint8_t* data = this->getBuffer();
|
||||
// data[messageSize] = set_report_id;
|
||||
// messageSize += sizeof(set_report_id);
|
||||
// data[messageSize] = ackFlags;
|
||||
// messageSize += sizeof(ackFlags);
|
||||
// memcpy(&data[messageSize], &tcPacketId, sizeof(tcPacketId));
|
||||
// messageSize += sizeof(tcPacketId);
|
||||
// memcpy(&data[messageSize], &tcSequenceControl, sizeof(tcSequenceControl));
|
||||
// messageSize += sizeof(tcSequenceControl);
|
||||
// data[messageSize] = set_step;
|
||||
// messageSize += sizeof(set_step);
|
||||
// memcpy(&data[messageSize], &set_error_code, sizeof(set_error_code));
|
||||
// messageSize += sizeof(set_error_code);
|
||||
// memcpy(&data[messageSize], ¶meter1, sizeof(parameter1));
|
||||
// messageSize += sizeof(parameter1);
|
||||
// memcpy(&data[messageSize], ¶meter2, sizeof(parameter2));
|
||||
// messageSize += sizeof(parameter2);
|
||||
//}
|
||||
|
||||
PusVerificationMessage::PusVerificationMessage(uint8_t set_report_id,
|
||||
uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl,
|
||||
ReturnValue_t set_error_code, uint8_t set_step, uint32_t parameter1,
|
||||
uint32_t parameter2) {
|
||||
uint8_t* data = this->getBuffer();
|
||||
data[messageSize] = set_report_id;
|
||||
messageSize += sizeof(set_report_id);
|
||||
data[messageSize] = ackFlags;
|
||||
messageSize += sizeof(ackFlags);
|
||||
memcpy(&data[messageSize], &tcPacketId, sizeof(tcPacketId));
|
||||
messageSize += sizeof(tcPacketId);
|
||||
memcpy(&data[messageSize], &tcSequenceControl, sizeof(tcSequenceControl));
|
||||
messageSize += sizeof(tcSequenceControl);
|
||||
data[messageSize] = set_step;
|
||||
messageSize += sizeof(set_step);
|
||||
memcpy(&data[messageSize], &set_error_code, sizeof(set_error_code));
|
||||
messageSize += sizeof(set_error_code);
|
||||
memcpy(&data[messageSize], ¶meter1, sizeof(parameter1));
|
||||
messageSize += sizeof(parameter1);
|
||||
memcpy(&data[messageSize], ¶meter2, sizeof(parameter2));
|
||||
messageSize += sizeof(parameter2);
|
||||
}
|
||||
|
||||
uint8_t PusVerificationMessage::getReportId() {
|
||||
|
||||
return getContent()->reportId;
|
||||
}
|
||||
|
||||
uint8_t PusVerificationMessage::getAckFlags() {
|
||||
|
||||
return getContent()->ackFlags;
|
||||
}
|
||||
|
||||
uint16_t PusVerificationMessage::getTcPacketId() {
|
||||
|
||||
uint16_t tcPacketId;
|
||||
memcpy(&tcPacketId, &getContent()->packetId_0, sizeof(tcPacketId));
|
||||
return tcPacketId;
|
||||
}
|
||||
|
||||
uint16_t PusVerificationMessage::getTcSequenceControl() {
|
||||
|
||||
uint16_t tcSequenceControl;
|
||||
memcpy(&tcSequenceControl, &getContent()->tcSequenceControl_0,
|
||||
sizeof(tcSequenceControl));
|
||||
return tcSequenceControl;
|
||||
}
|
||||
|
||||
uint8_t PusVerificationMessage::getStep() {
|
||||
|
||||
return getContent()->step;
|
||||
}
|
||||
|
||||
ReturnValue_t PusVerificationMessage::getErrorCode() {
|
||||
ReturnValue_t errorCode;
|
||||
memcpy(&errorCode, &getContent()->error_code_0, sizeof(errorCode));
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
PusVerificationMessage::verifciationMessageContent* PusVerificationMessage::getContent() {
|
||||
return (verifciationMessageContent*) this->getData();
|
||||
}
|
||||
|
||||
uint32_t PusVerificationMessage::getParameter1() {
|
||||
uint32_t parameter;
|
||||
memcpy(¶meter, &getContent()->parameter1_0, sizeof(parameter));
|
||||
return parameter;
|
||||
}
|
||||
|
||||
uint32_t PusVerificationMessage::getParameter2() {
|
||||
uint32_t parameter;
|
||||
memcpy(¶meter, &getContent()->parameter2_0, sizeof(parameter));
|
||||
return parameter;
|
||||
}
|
||||
|
||||
PusSuccessReport::PusSuccessReport(uint16_t setPacketId,
|
||||
uint16_t setSequenceControl, uint8_t setStep) :
|
||||
reportSize(0), pBuffer(reportBuffer) {
|
||||
//Serialization won't fail, because we know the necessary max-size of the buffer.
|
||||
SerializeAdapter<uint16_t>::serialize(&setPacketId, &pBuffer, &reportSize,
|
||||
sizeof(reportBuffer), true);
|
||||
SerializeAdapter<uint16_t>::serialize(&setSequenceControl, &pBuffer,
|
||||
&reportSize, sizeof(reportBuffer), true);
|
||||
if (setStep != 0) {
|
||||
SerializeAdapter<uint8_t>::serialize(&setStep, &pBuffer, &reportSize,
|
||||
sizeof(reportBuffer), true);
|
||||
}
|
||||
}
|
||||
|
||||
PusSuccessReport::~PusSuccessReport() {
|
||||
|
||||
}
|
||||
|
||||
uint32_t PusSuccessReport::getSize() {
|
||||
return reportSize;
|
||||
}
|
||||
|
||||
uint8_t* PusSuccessReport::getReport() {
|
||||
return reportBuffer;
|
||||
}
|
||||
|
||||
PusFailureReport::PusFailureReport(uint16_t setPacketId,
|
||||
uint16_t setSequenceControl, ReturnValue_t setErrorCode,
|
||||
uint8_t setStep, uint32_t parameter1, uint32_t parameter2) :
|
||||
reportSize(0), pBuffer(reportBuffer) {
|
||||
//Serialization won't fail, because we know the necessary max-size of the buffer.
|
||||
SerializeAdapter<uint16_t>::serialize(&setPacketId, &pBuffer, &reportSize,
|
||||
sizeof(reportBuffer), true);
|
||||
SerializeAdapter<uint16_t>::serialize(&setSequenceControl, &pBuffer,
|
||||
&reportSize, sizeof(reportBuffer), true);
|
||||
if (setStep != 0) {
|
||||
SerializeAdapter<uint8_t>::serialize(&setStep, &pBuffer, &reportSize,
|
||||
sizeof(reportBuffer), true);
|
||||
}
|
||||
SerializeAdapter<ReturnValue_t>::serialize(&setErrorCode, &pBuffer,
|
||||
&reportSize, sizeof(reportBuffer), true);
|
||||
SerializeAdapter<uint32_t>::serialize(¶meter1, &pBuffer, &reportSize,
|
||||
sizeof(reportBuffer), true);
|
||||
SerializeAdapter<uint32_t>::serialize(¶meter2, &pBuffer, &reportSize,
|
||||
sizeof(reportBuffer), true);
|
||||
}
|
||||
|
||||
PusFailureReport::~PusFailureReport() {
|
||||
}
|
||||
|
||||
uint32_t PusFailureReport::getSize() {
|
||||
return reportSize;
|
||||
}
|
||||
|
||||
uint8_t* PusFailureReport::getReport() {
|
||||
return reportBuffer;
|
||||
}
|
84
tmtcservices/PusVerificationReport.h
Normal file
84
tmtcservices/PusVerificationReport.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* PusVerificationReport.h
|
||||
*
|
||||
* Created on: 22.05.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef PUSVERIFICATIONREPORT_H_
|
||||
#define PUSVERIFICATIONREPORT_H_
|
||||
|
||||
#include <framework/ipc/MessageQueueMessage.h>
|
||||
#include <framework/tmtcpacket/pus/TcPacketBase.h>
|
||||
#include <framework/tmtcservices/VerificationCodes.h>
|
||||
|
||||
class PusVerificationMessage: public MessageQueueMessage {
|
||||
private:
|
||||
struct verifciationMessageContent {
|
||||
uint8_t reportId;
|
||||
uint8_t ackFlags;
|
||||
uint8_t packetId_0;
|
||||
uint8_t packetId_1;
|
||||
uint8_t tcSequenceControl_0;
|
||||
uint8_t tcSequenceControl_1;
|
||||
uint8_t step;
|
||||
uint8_t error_code_0;
|
||||
uint8_t error_code_1;
|
||||
uint8_t parameter1_0;
|
||||
uint8_t parameter1_1;
|
||||
uint8_t parameter1_2;
|
||||
uint8_t parameter1_3;
|
||||
uint8_t parameter2_0;
|
||||
uint8_t parameter2_1;
|
||||
uint8_t parameter2_2;
|
||||
uint8_t parameter2_3;
|
||||
};
|
||||
verifciationMessageContent* getContent();
|
||||
public:
|
||||
static const uint8_t VERIFICATION_MIN_SIZE = 6;
|
||||
PusVerificationMessage();
|
||||
// PusVerificationMessage( uint8_t set_report_id, TcPacketBase* current_packet, ReturnValue_t set_error_code = 0, uint8_t set_step = 0, uint32_t parameter1 = 0, uint32_t parameter2 = 0 );
|
||||
PusVerificationMessage(uint8_t set_report_id, uint8_t ackFlags,
|
||||
uint16_t tcPacketId, uint16_t tcSequenceControl,
|
||||
ReturnValue_t set_error_code = 0, uint8_t set_step = 0,
|
||||
uint32_t parameter1 = 0, uint32_t parameter2 = 0);
|
||||
uint8_t getReportId();
|
||||
uint8_t getAckFlags();
|
||||
uint16_t getTcPacketId();
|
||||
uint16_t getTcSequenceControl();
|
||||
ReturnValue_t getErrorCode();
|
||||
uint8_t getStep();
|
||||
uint32_t getParameter1();
|
||||
uint32_t getParameter2();
|
||||
};
|
||||
|
||||
class PusSuccessReport {
|
||||
private:
|
||||
static const uint16_t MAX_SIZE = 7;
|
||||
uint8_t reportBuffer[MAX_SIZE];
|
||||
uint32_t reportSize;
|
||||
uint8_t * pBuffer;
|
||||
public:
|
||||
PusSuccessReport(uint16_t setPacketId, uint16_t setSequenceControl,
|
||||
uint8_t set_step = 0);
|
||||
~PusSuccessReport();
|
||||
uint32_t getSize();
|
||||
uint8_t* getReport();
|
||||
};
|
||||
|
||||
class PusFailureReport {
|
||||
private:
|
||||
static const uint16_t MAX_SIZE = 16;
|
||||
uint8_t reportBuffer[MAX_SIZE];
|
||||
uint32_t reportSize;
|
||||
uint8_t * pBuffer;
|
||||
public:
|
||||
PusFailureReport(uint16_t setPacketId, uint16_t setSequenceControl,
|
||||
ReturnValue_t setErrorCode, uint8_t setStep = 0,
|
||||
uint32_t parameter1 = 0, uint32_t parameter2 = 0);
|
||||
~PusFailureReport();
|
||||
uint32_t getSize();
|
||||
uint8_t* getReport();
|
||||
};
|
||||
|
||||
#endif /* PUSVERIFICATIONREPORT_H_ */
|
32
tmtcservices/ServiceTypes.h
Normal file
32
tmtcservices/ServiceTypes.h
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @file ServiceTypes.h
|
||||
* @brief This file defines the ServiceTypes class.
|
||||
* @date 11.04.2013
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#ifndef SERVICETYPES_H_
|
||||
#define SERVICETYPES_H_
|
||||
|
||||
namespace SERVICE {
|
||||
enum ServiceTypes {
|
||||
TELECOMMAND_VERIFICATION = 1,
|
||||
DEVICE_COMMAND_DISTRIBUTION = 2,
|
||||
HOUSEKEEPING_AND_DIAGNOSTIC_DATA_REPORTING = 3,
|
||||
PARAMETER_STATISTICS_REPORTING = 4,
|
||||
EVENT_REPORTING = 5,
|
||||
MEMORY_MANAGEMENT = 6,
|
||||
FUNCTION_MANAGEMENT = 8,
|
||||
TIME_MANAGEMENT = 9,
|
||||
ON_BOARD_OPERATIONS_SCHEDULING = 11,
|
||||
ON_BOARD_MONITORING = 12,
|
||||
LARGE_DATA_TRANSFER = 13,
|
||||
PACKET_FORWARDING_CONTROL = 14,
|
||||
ON_BOARD_STORAGE_AND_RETRIEVAL = 15,
|
||||
TEST = 17,
|
||||
ON_BOARD_OPERATIONS_PROCEDURE = 18,
|
||||
EVENT_ACTION = 19
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* SERVICETYPES_H_ */
|
30
tmtcservices/SourceSequenceCounter.h
Normal file
30
tmtcservices/SourceSequenceCounter.h
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @file SourceSequenceCounter.h
|
||||
* @brief This file defines the SourceSequenceCounter class.
|
||||
* @date 04.02.2013
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#ifndef SOURCESEQUENCECOUNTER_H_
|
||||
#define SOURCESEQUENCECOUNTER_H_
|
||||
#include <framework/tmtcpacket/SpacePacketBase.h>
|
||||
|
||||
class SourceSequenceCounter {
|
||||
private:
|
||||
uint16_t sequenceCount;
|
||||
public:
|
||||
SourceSequenceCounter() : sequenceCount(0) {}
|
||||
void increment() {
|
||||
this->sequenceCount = (++this->sequenceCount) % (SpacePacketBase::LIMIT_SEQUENCE_COUNT);
|
||||
}
|
||||
void decrement() {
|
||||
this->sequenceCount = (--this->sequenceCount) % (SpacePacketBase::LIMIT_SEQUENCE_COUNT);
|
||||
}
|
||||
uint16_t get() { return this->sequenceCount; }
|
||||
void reset(uint16_t toValue = 0) {
|
||||
sequenceCount = toValue % (SpacePacketBase::LIMIT_SEQUENCE_COUNT);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* SOURCESEQUENCECOUNTER_H_ */
|
28
tmtcservices/TmTcMessage.cpp
Normal file
28
tmtcservices/TmTcMessage.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include <framework/tmtcservices/TmTcMessage.h>
|
||||
|
||||
|
||||
TmTcMessage::TmTcMessage() {
|
||||
this->messageSize += sizeof(store_address_t);
|
||||
}
|
||||
|
||||
TmTcMessage::~TmTcMessage() {
|
||||
}
|
||||
|
||||
store_address_t TmTcMessage::getStorageId() {
|
||||
store_address_t temp_id;
|
||||
memcpy(&temp_id, this->getData(), sizeof(store_address_t) );
|
||||
return temp_id;
|
||||
}
|
||||
|
||||
TmTcMessage::TmTcMessage(store_address_t store_id) {
|
||||
this->messageSize += sizeof(store_address_t);
|
||||
this->setStorageId(store_id);
|
||||
}
|
||||
|
||||
size_t TmTcMessage::getMinimumMessageSize() {
|
||||
return this->HEADER_SIZE + sizeof(store_address_t);
|
||||
}
|
||||
|
||||
void TmTcMessage::setStorageId(store_address_t store_id) {
|
||||
memcpy(this->getData(), &store_id, sizeof(store_address_t) );
|
||||
}
|
50
tmtcservices/TmTcMessage.h
Normal file
50
tmtcservices/TmTcMessage.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef TMTCMESSAGE_H_
|
||||
#define TMTCMESSAGE_H_
|
||||
|
||||
#include <framework/ipc/MessageQueueMessage.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
/**
|
||||
* @brief This message class is used to pass Telecommand and Telemetry
|
||||
* packets between tasks.
|
||||
* @details Within such a packet, nothing is transported but the identifier of
|
||||
* a packet stored in one of the IPC stores (typically a special TM and
|
||||
* a special TC store). This makes passing commands very simple and
|
||||
* efficient.
|
||||
* \ingroup message_queue
|
||||
*/
|
||||
class TmTcMessage : public MessageQueueMessage {
|
||||
protected:
|
||||
/**
|
||||
* @brief This call always returns the same fixed size of the message.
|
||||
* @return Returns HEADER_SIZE + \c sizeof(store_address_t).
|
||||
*/
|
||||
size_t getMinimumMessageSize();
|
||||
public:
|
||||
/**
|
||||
* @brief In the default constructor, only the message_size is set.
|
||||
*/
|
||||
TmTcMessage();
|
||||
/**
|
||||
* @brief With this constructor, the passed packet id is directly put
|
||||
* into the message.
|
||||
* @param packet_id The packet id to put into the message.
|
||||
*/
|
||||
TmTcMessage( store_address_t packet_id );
|
||||
/**
|
||||
* @brief The class's destructor is empty.
|
||||
*/
|
||||
~TmTcMessage();
|
||||
/**
|
||||
* @brief This getter returns the packet id in the correct format.
|
||||
* @return Returns the packet id.
|
||||
*/
|
||||
store_address_t getStorageId();
|
||||
/**
|
||||
* @brief In some cases it might be useful to have a setter for packet id
|
||||
* as well.
|
||||
* @param packet_id The packet id to put into the message.
|
||||
*/
|
||||
void setStorageId( store_address_t packet_id );
|
||||
};
|
||||
|
||||
#endif /* TMTCMESSAGE_H_ */
|
35
tmtcservices/VerificationCodes.h
Normal file
35
tmtcservices/VerificationCodes.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* VerificationCodes.h
|
||||
*
|
||||
* Created on: Aug 8, 2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef VERIFICATIONCODES_H_
|
||||
#define VERIFICATIONCODES_H_
|
||||
|
||||
namespace TC_VERIFY {
|
||||
|
||||
enum verification_flags {
|
||||
NONE = 0b0000,
|
||||
ACCEPTANCE = 0b0001,
|
||||
START = 0b0010,
|
||||
PROGRESS = 0b0100,
|
||||
COMPLETION = 0b1000
|
||||
};
|
||||
|
||||
enum subservice_ids {
|
||||
NOTHING_TO_REPORT = 0,
|
||||
ACCEPTANCE_SUCCESS = 1,
|
||||
ACCEPTANCE_FAILURE = 2,
|
||||
START_SUCCESS = 3,
|
||||
START_FAILURE = 4,
|
||||
PROGRESS_SUCCESS = 5,
|
||||
PROGRESS_FAILURE = 6,
|
||||
COMPLETION_SUCCESS = 7,
|
||||
COMPLETION_FAILURE = 8,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* VERIFICATIONCODES_H_ */
|
92
tmtcservices/VerificationReporter.cpp
Normal file
92
tmtcservices/VerificationReporter.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* VerificationReporter.cpp
|
||||
*
|
||||
* Created on: 20.07.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tmtcservices/AcceptsVerifyMessageIF.h>
|
||||
#include <framework/tmtcservices/PusVerificationReport.h>
|
||||
#include <framework/tmtcservices/VerificationReporter.h>
|
||||
|
||||
VerificationReporter::VerificationReporter() :
|
||||
acknowledge_queue() {
|
||||
}
|
||||
|
||||
VerificationReporter::~VerificationReporter() {
|
||||
//Default, empty
|
||||
}
|
||||
|
||||
void VerificationReporter::sendSuccessReport(uint8_t set_report_id,
|
||||
TcPacketBase* current_packet, uint8_t set_step) {
|
||||
if (this->acknowledge_queue.getDefaultDestination() == 0) {
|
||||
this->initialize();
|
||||
}
|
||||
PusVerificationMessage message(set_report_id, current_packet->getAcknowledgeFlags(), current_packet->getPacketId(), current_packet->getPacketSequenceControl(), set_step);
|
||||
ReturnValue_t status = this->acknowledge_queue.sendToDefault(&message);
|
||||
if (status != OSAL::RETURN_OK) {
|
||||
error
|
||||
<< "VerificationReporter::sendSuccessReport: Error writing to queue. Code: "
|
||||
<< (uint16_t) status << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void VerificationReporter::sendSuccessReport(uint8_t set_report_id,
|
||||
uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, uint8_t set_step) {
|
||||
if (this->acknowledge_queue.getDefaultDestination() == 0) {
|
||||
this->initialize();
|
||||
}
|
||||
PusVerificationMessage message(set_report_id, ackFlags, tcPacketId, tcSequenceControl, set_step);
|
||||
ReturnValue_t status = this->acknowledge_queue.sendToDefault(&message);
|
||||
if (status != OSAL::RETURN_OK) {
|
||||
error
|
||||
<< "VerificationReporter::sendSuccessReport: Error writing to queue. Code: "
|
||||
<< (uint16_t) status << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void VerificationReporter::sendFailureReport(uint8_t report_id,
|
||||
TcPacketBase* current_packet, ReturnValue_t error_code, uint8_t step,
|
||||
uint32_t parameter1, uint32_t parameter2) {
|
||||
if (this->acknowledge_queue.getDefaultDestination() == 0) {
|
||||
this->initialize();
|
||||
}
|
||||
PusVerificationMessage message(report_id, current_packet->getAcknowledgeFlags(), current_packet->getPacketId(), current_packet->getPacketSequenceControl(), error_code, step,
|
||||
parameter1, parameter2);
|
||||
ReturnValue_t status = this->acknowledge_queue.sendToDefault(&message);
|
||||
if (status != OSAL::RETURN_OK) {
|
||||
error
|
||||
<< "VerificationReporter::sendFailureReport Error writing to queue. Code: "
|
||||
<< (uint16_t) status << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void VerificationReporter::sendFailureReport(uint8_t report_id,
|
||||
uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, ReturnValue_t error_code, uint8_t step,
|
||||
uint32_t parameter1, uint32_t parameter2) {
|
||||
if (this->acknowledge_queue.getDefaultDestination() == 0) {
|
||||
this->initialize();
|
||||
}
|
||||
PusVerificationMessage message(report_id, ackFlags, tcPacketId, tcSequenceControl, error_code, step,
|
||||
parameter1, parameter2);
|
||||
ReturnValue_t status = this->acknowledge_queue.sendToDefault(&message);
|
||||
if (status != OSAL::RETURN_OK) {
|
||||
error
|
||||
<< "VerificationReporter::sendFailureReport Error writing to queue. Code: "
|
||||
<< (uint16_t) status << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void VerificationReporter::initialize() {
|
||||
AcceptsVerifyMessageIF* temp = objectManager->get<AcceptsVerifyMessageIF>(
|
||||
objects::PUS_VERIFICATION_SERVICE);
|
||||
if (temp != NULL) {
|
||||
this->acknowledge_queue.setDefaultDestination(
|
||||
temp->getVerificationQueue());
|
||||
} else {
|
||||
error
|
||||
<< "VerificationReporter::VerificationReporter: Configuration error."
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
31
tmtcservices/VerificationReporter.h
Normal file
31
tmtcservices/VerificationReporter.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* VerificationReporter.h
|
||||
*
|
||||
* Created on: 20.07.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef VERIFICATIONREPORTER_H_
|
||||
#define VERIFICATIONREPORTER_H_
|
||||
|
||||
#include <framework/ipc/MessageQueueSender.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/tmtcservices/PusVerificationReport.h>
|
||||
|
||||
class VerificationReporter {
|
||||
protected:
|
||||
MessageQueueSender acknowledge_queue;
|
||||
public:
|
||||
VerificationReporter();
|
||||
virtual ~VerificationReporter();
|
||||
void sendSuccessReport( uint8_t set_report_id, TcPacketBase* current_packet, uint8_t set_step = 0 );
|
||||
void sendSuccessReport(uint8_t set_report_id, uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, uint8_t set_step = 0);
|
||||
void sendFailureReport( uint8_t report_id, TcPacketBase* current_packet, ReturnValue_t error_code = 0,
|
||||
uint8_t step = 0, uint32_t parameter1 = 0, uint32_t parameter2 = 0 );
|
||||
void sendFailureReport(uint8_t report_id,
|
||||
uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, ReturnValue_t error_code = 0, uint8_t step = 0,
|
||||
uint32_t parameter1 = 0, uint32_t parameter2 = 0);
|
||||
void initialize();
|
||||
};
|
||||
|
||||
#endif /* VERIFICATIONREPORTER_H_ */
|
Reference in New Issue
Block a user