Merge remote-tracking branch 'origin/develop' into flipped-tmtctest-preproc-define
This commit is contained in:
@ -1,303 +1,301 @@
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/events/EventManagerIF.h"
|
||||
#include "CCSDSHandler.h"
|
||||
|
||||
#include <linux/obc/PdecHandler.h>
|
||||
|
||||
#include "CCSDSHandler.h"
|
||||
#include "fsfw/events/EventManagerIF.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
|
||||
|
||||
CCSDSHandler::CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination,
|
||||
TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData) :
|
||||
SystemObject(objectId), ptmeId(ptmeId), tcDestination(tcDestination), parameterHelper(this), actionHelper(
|
||||
this, nullptr), txRateSetterIF(txRateSetterIF), gpioIF(gpioIF), enTxClock(
|
||||
enTxClock), enTxData(enTxData) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 2);
|
||||
TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock,
|
||||
gpioId_t enTxData)
|
||||
: SystemObject(objectId),
|
||||
ptmeId(ptmeId),
|
||||
tcDestination(tcDestination),
|
||||
parameterHelper(this),
|
||||
actionHelper(this, nullptr),
|
||||
txRateSetterIF(txRateSetterIF),
|
||||
gpioIF(gpioIF),
|
||||
enTxClock(enTxClock),
|
||||
enTxData(enTxData) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 2);
|
||||
}
|
||||
|
||||
CCSDSHandler::~CCSDSHandler() {
|
||||
}
|
||||
CCSDSHandler::~CCSDSHandler() {}
|
||||
|
||||
ReturnValue_t CCSDSHandler::performOperation(uint8_t operationCode) {
|
||||
checkEvents();
|
||||
readCommandQueue();
|
||||
handleTelemetry();
|
||||
handleTelecommands();
|
||||
checkTxTimer();
|
||||
return RETURN_OK;
|
||||
checkEvents();
|
||||
readCommandQueue();
|
||||
handleTelemetry();
|
||||
handleTelecommands();
|
||||
checkTxTimer();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void CCSDSHandler::handleTelemetry() {
|
||||
VirtualChannelMapIter iter;
|
||||
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
||||
iter->second->performOperation();
|
||||
}
|
||||
VirtualChannelMapIter iter;
|
||||
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
||||
iter->second->performOperation();
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::handleTelecommands() {
|
||||
|
||||
}
|
||||
void CCSDSHandler::handleTelecommands() {}
|
||||
|
||||
ReturnValue_t CCSDSHandler::initialize() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
PtmeIF* ptme = ObjectManager::instance()->get<PtmeIF>(ptmeId);
|
||||
if (ptme == nullptr) {
|
||||
sif::warning << "Invalid PTME object" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
PtmeIF* ptme = ObjectManager::instance()->get<PtmeIF>(ptmeId);
|
||||
if (ptme == nullptr) {
|
||||
sif::warning << "Invalid PTME object" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
AcceptsTelecommandsIF* tcDistributor =
|
||||
ObjectManager::instance()->get<AcceptsTelecommandsIF>(tcDestination);
|
||||
if (tcDistributor == nullptr) {
|
||||
AcceptsTelecommandsIF* tcDistributor =
|
||||
ObjectManager::instance()->get<AcceptsTelecommandsIF>(tcDestination);
|
||||
if (tcDistributor == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "CCSDSHandler::initialize: Invalid TC Distributor object" << std::endl;
|
||||
sif::error << "CCSDSHandler::initialize: Invalid TC Distributor object" << std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
tcDistributorQueueId = tcDistributor->getRequestQueue();
|
||||
tcDistributorQueueId = tcDistributor->getRequestQueue();
|
||||
|
||||
result = parameterHelper.initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = parameterHelper.initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = actionHelper.initialize(commandQueue);
|
||||
result = actionHelper.initialize(commandQueue);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
VirtualChannelMapIter iter;
|
||||
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
||||
result = iter->second->initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
iter->second->setPtmeObject(ptme);
|
||||
}
|
||||
|
||||
VirtualChannelMapIter iter;
|
||||
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
||||
result = iter->second->initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
iter->second->setPtmeObject(ptme);
|
||||
}
|
||||
|
||||
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(
|
||||
objects::EVENT_MANAGER);
|
||||
if (manager == nullptr) {
|
||||
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||
if (manager == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "CCSDSHandler::initialize: Invalid event manager" << std::endl;
|
||||
sif::error << "CCSDSHandler::initialize: Invalid event manager" << std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
result = manager->registerListener(eventQueue->getId());
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
result = manager->registerListener(eventQueue->getId());
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "CCSDSHandler::initialize: Failed to register CCSDS handler as event "
|
||||
"listener" << std::endl;
|
||||
sif::warning << "CCSDSHandler::initialize: Failed to register CCSDS handler as event "
|
||||
"listener"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;;
|
||||
}
|
||||
result = manager->subscribeToEventRange(eventQueue->getId(),
|
||||
event::getEventId(PdecHandler::CARRIER_LOCK),
|
||||
event::getEventId(PdecHandler::BIT_LOCK_PDEC));
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
;
|
||||
}
|
||||
result = manager->subscribeToEventRange(eventQueue->getId(),
|
||||
event::getEventId(PdecHandler::CARRIER_LOCK),
|
||||
event::getEventId(PdecHandler::BIT_LOCK_PDEC));
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "CCSDSHandler::initialize: Failed to subscribe to events from PDEC "
|
||||
"handler" << std::endl;
|
||||
sif::error << "CCSDSHandler::initialize: Failed to subscribe to events from PDEC "
|
||||
"handler"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void CCSDSHandler::readCommandQueue(void) {
|
||||
CommandMessage commandMessage;
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
CommandMessage commandMessage;
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
|
||||
result = commandQueue->receiveMessage(&commandMessage);
|
||||
result = commandQueue->receiveMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
result = parameterHelper.handleParameterMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
result = parameterHelper.handleParameterMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
result = actionHelper.handleActionMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
CommandMessage reply;
|
||||
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND,
|
||||
commandMessage.getCommand());
|
||||
commandQueue->reply(&reply);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
result = actionHelper.handleActionMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
CommandMessage reply;
|
||||
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
|
||||
commandQueue->reply(&reply);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueId_t CCSDSHandler::getCommandQueue() const {
|
||||
return commandQueue->getId();
|
||||
}
|
||||
MessageQueueId_t CCSDSHandler::getCommandQueue() const { return commandQueue->getId(); }
|
||||
|
||||
void CCSDSHandler::addVirtualChannel(VcId_t vcId, VirtualChannel* virtualChannel) {
|
||||
if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) {
|
||||
sif::warning << "CCSDSHandler::addVirtualChannel: Invalid virtual channel ID" << std::endl;
|
||||
return;
|
||||
}
|
||||
if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) {
|
||||
sif::warning << "CCSDSHandler::addVirtualChannel: Invalid virtual channel ID" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (virtualChannel == nullptr) {
|
||||
sif::warning << "CCSDSHandler::addVirtualChannel: Invalid virtual channel interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
if (virtualChannel == nullptr) {
|
||||
sif::warning << "CCSDSHandler::addVirtualChannel: Invalid virtual channel interface"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto status = virtualChannelMap.emplace(vcId, virtualChannel);
|
||||
if (status.second == false) {
|
||||
sif::warning << "CCSDSHandler::addVirtualChannel: Failed to add virtual channel to "
|
||||
"virtual channel map" << std::endl;
|
||||
return;
|
||||
}
|
||||
auto status = virtualChannelMap.emplace(vcId, virtualChannel);
|
||||
if (status.second == false) {
|
||||
sif::warning << "CCSDSHandler::addVirtualChannel: Failed to add virtual channel to "
|
||||
"virtual channel map"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueId_t CCSDSHandler::getReportReceptionQueue(uint8_t virtualChannel) {
|
||||
if (virtualChannel < common::NUMBER_OF_VIRTUAL_CHANNELS) {
|
||||
VirtualChannelMapIter iter = virtualChannelMap.find(virtualChannel);
|
||||
if (iter != virtualChannelMap.end()) {
|
||||
return iter->second->getReportReceptionQueue();
|
||||
}
|
||||
else {
|
||||
sif::warning << "CCSDSHandler::getReportReceptionQueue: Virtual channel with ID "
|
||||
<< static_cast<unsigned int>(virtualChannel) << " not in virtual channel map"
|
||||
<< std::endl;
|
||||
return MessageQueueIF::NO_QUEUE;
|
||||
}
|
||||
} else {
|
||||
sif::debug << "CCSDSHandler::getReportReceptionQueue: Invalid virtual channel requested";
|
||||
|
||||
}
|
||||
return MessageQueueIF::NO_QUEUE;
|
||||
if (virtualChannel < common::NUMBER_OF_VIRTUAL_CHANNELS) {
|
||||
VirtualChannelMapIter iter = virtualChannelMap.find(virtualChannel);
|
||||
if (iter != virtualChannelMap.end()) {
|
||||
return iter->second->getReportReceptionQueue();
|
||||
} else {
|
||||
sif::warning << "CCSDSHandler::getReportReceptionQueue: Virtual channel with ID "
|
||||
<< static_cast<unsigned int>(virtualChannel) << " not in virtual channel map"
|
||||
<< std::endl;
|
||||
return MessageQueueIF::NO_QUEUE;
|
||||
}
|
||||
} else {
|
||||
sif::debug << "CCSDSHandler::getReportReceptionQueue: Invalid virtual channel requested";
|
||||
}
|
||||
return MessageQueueIF::NO_QUEUE;
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) {
|
||||
return RETURN_OK;
|
||||
ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
uint16_t CCSDSHandler::getIdentifier() {
|
||||
return 0;
|
||||
}
|
||||
uint16_t CCSDSHandler::getIdentifier() { return 0; }
|
||||
|
||||
MessageQueueId_t CCSDSHandler::getRequestQueue() {
|
||||
// Forward packets directly to TC distributor
|
||||
return tcDistributorQueueId;
|
||||
// Forward packets directly to TC distributor
|
||||
return tcDistributorQueueId;
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||
|
||||
switch(actionId) {
|
||||
ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) {
|
||||
switch (actionId) {
|
||||
case SET_LOW_RATE: {
|
||||
txRateSetterIF->setRate(BitRates::RATE_400KHZ);
|
||||
return EXECUTION_FINISHED;
|
||||
txRateSetterIF->setRate(BitRates::RATE_400KHZ);
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case SET_HIGH_RATE: {
|
||||
txRateSetterIF->setRate(BitRates::RATE_2000KHZ);
|
||||
return EXECUTION_FINISHED;
|
||||
txRateSetterIF->setRate(BitRates::RATE_2000KHZ);
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case EN_TRANSMITTER: {
|
||||
enableTransmit();
|
||||
return EXECUTION_FINISHED;
|
||||
enableTransmit();
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case DIS_TRANSMITTER: {
|
||||
disableTransmit();
|
||||
return EXECUTION_FINISHED;
|
||||
disableTransmit();
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
default:
|
||||
return COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::checkEvents() {
|
||||
EventMessage event;
|
||||
for (ReturnValue_t result = eventQueue->receiveMessage(&event);
|
||||
result == RETURN_OK; result = eventQueue->receiveMessage(&event)) {
|
||||
switch (event.getMessageId()) {
|
||||
case EventMessage::EVENT_MESSAGE:
|
||||
handleEvent(&event);
|
||||
break;
|
||||
default:
|
||||
sif::debug << "CCSDSHandler::checkEvents: Did not subscribe to this event message"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
EventMessage event;
|
||||
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == RETURN_OK;
|
||||
result = eventQueue->receiveMessage(&event)) {
|
||||
switch (event.getMessageId()) {
|
||||
case EventMessage::EVENT_MESSAGE:
|
||||
handleEvent(&event);
|
||||
break;
|
||||
default:
|
||||
sif::debug << "CCSDSHandler::checkEvents: Did not subscribe to this event message"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCSDSHandler::handleEvent(EventMessage* eventMessage) {
|
||||
Event event = eventMessage->getEvent();
|
||||
switch(event){
|
||||
Event event = eventMessage->getEvent();
|
||||
switch (event) {
|
||||
case PdecHandler::BIT_LOCK_PDEC: {
|
||||
handleBitLockEvent();
|
||||
break;
|
||||
handleBitLockEvent();
|
||||
break;
|
||||
}
|
||||
case PdecHandler::CARRIER_LOCK: {
|
||||
handleCarrierLockEvent();
|
||||
break;
|
||||
handleCarrierLockEvent();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::debug << "CCSDSHandler::handleEvent: Did not subscribe to this event"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
sif::debug << "CCSDSHandler::handleEvent: Did not subscribe to this event" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::handleBitLockEvent() {
|
||||
if(transmitterCountdown.isBusy()) {
|
||||
// Transmitter already enabled
|
||||
return;
|
||||
}
|
||||
enableTransmit();
|
||||
if (transmitterCountdown.isBusy()) {
|
||||
// Transmitter already enabled
|
||||
return;
|
||||
}
|
||||
enableTransmit();
|
||||
}
|
||||
|
||||
void CCSDSHandler::handleCarrierLockEvent() {
|
||||
if (!enableTxWhenCarrierLock) {
|
||||
return;
|
||||
}
|
||||
enableTransmit();
|
||||
if (!enableTxWhenCarrierLock) {
|
||||
return;
|
||||
}
|
||||
enableTransmit();
|
||||
}
|
||||
|
||||
void CCSDSHandler::forwardLinkstate() {
|
||||
VirtualChannelMapIter iter;
|
||||
for(iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
||||
iter->second->setLinkState(linkState);
|
||||
}
|
||||
VirtualChannelMapIter iter;
|
||||
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
|
||||
iter->second->setLinkState(linkState);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::enableTransmit() {
|
||||
if(transmitterCountdown.isBusy()) {
|
||||
// Transmitter already enabled
|
||||
return;
|
||||
}
|
||||
transmitterCountdown.setTimeout(TRANSMITTER_TIMEOUT);
|
||||
if (transmitterCountdown.isBusy()) {
|
||||
// Transmitter already enabled
|
||||
return;
|
||||
}
|
||||
transmitterCountdown.setTimeout(TRANSMITTER_TIMEOUT);
|
||||
#if BOARD_TE0720 == 0
|
||||
gpioIF->pullHigh(enTxClock);
|
||||
gpioIF->pullHigh(enTxData);
|
||||
gpioIF->pullHigh(enTxClock);
|
||||
gpioIF->pullHigh(enTxData);
|
||||
#endif /* BOARD_TE0720 == 0 */
|
||||
linkState = UP;
|
||||
// Set link state of all virtual channels to link up
|
||||
forwardLinkstate();
|
||||
linkState = UP;
|
||||
// Set link state of all virtual channels to link up
|
||||
forwardLinkstate();
|
||||
}
|
||||
|
||||
void CCSDSHandler::checkTxTimer() {
|
||||
if(linkState == DOWN) {
|
||||
return;
|
||||
}
|
||||
if (transmitterCountdown.hasTimedOut()) {
|
||||
disableTransmit();
|
||||
}
|
||||
if (linkState == DOWN) {
|
||||
return;
|
||||
}
|
||||
if (transmitterCountdown.hasTimedOut()) {
|
||||
disableTransmit();
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::disableTransmit() {
|
||||
#if BOARD_TE0720 == 0
|
||||
gpioIF->pullLow(enTxClock);
|
||||
gpioIF->pullLow(enTxData);
|
||||
gpioIF->pullLow(enTxClock);
|
||||
gpioIF->pullLow(enTxData);
|
||||
#endif /* BOARD_TE0720 == 0 */
|
||||
linkState = DOWN;
|
||||
forwardLinkstate();
|
||||
transmitterCountdown.setTimeout(0);
|
||||
linkState = DOWN;
|
||||
forwardLinkstate();
|
||||
transmitterCountdown.setTimeout(0);
|
||||
}
|
||||
|
@ -1,22 +1,23 @@
|
||||
#ifndef CCSDSHANDLER_H_
|
||||
#define CCSDSHANDLER_H_
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw/parameters/ParameterHelper.h"
|
||||
#include "VirtualChannel.h"
|
||||
#include "fsfw/action/ActionHelper.h"
|
||||
#include "fsfw/action/HasActionsIF.h"
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
#include "fsfw/events/EventMessage.h"
|
||||
#include "linux/obc/TxRateSetterIF.h"
|
||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/parameters/ParameterHelper.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "VirtualChannel.h"
|
||||
#include <unordered_map>
|
||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||
#include "linux/obc/TxRateSetterIF.h"
|
||||
|
||||
/**
|
||||
* @brief This class handles the data exchange with the CCSDS IP cores implemented in the
|
||||
@ -24,70 +25,69 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class CCSDSHandler: public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
public AcceptsTelemetryIF,
|
||||
public AcceptsTelecommandsIF,
|
||||
public HasReturnvaluesIF,
|
||||
public ReceivesParameterMessagesIF,
|
||||
public HasActionsIF {
|
||||
public:
|
||||
class CCSDSHandler : public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
public AcceptsTelemetryIF,
|
||||
public AcceptsTelecommandsIF,
|
||||
public HasReturnvaluesIF,
|
||||
public ReceivesParameterMessagesIF,
|
||||
public HasActionsIF {
|
||||
public:
|
||||
using VcId_t = uint8_t;
|
||||
|
||||
using VcId_t = uint8_t;
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId Object ID of the CCSDS handler
|
||||
* @param ptmeId Object ID of the PTME object providing access to the PTME IP Core.
|
||||
* @param tcDestination Object ID of object handling received TC space packets
|
||||
* @param txRateSetter Object providing the functionality to switch the input bitrate of
|
||||
* the S-Band transceiver.
|
||||
* @param gpioIF Required to enable TX data and TX clock RS485 transceiver chips.
|
||||
* @param enTxClock GPIO ID of RS485 tx clock enable
|
||||
* @param enTxData GPIO ID of RS485 tx data enable
|
||||
*/
|
||||
CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination,
|
||||
TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock,
|
||||
gpioId_t enTxData);
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId Object ID of the CCSDS handler
|
||||
* @param ptmeId Object ID of the PTME object providing access to the PTME IP Core.
|
||||
* @param tcDestination Object ID of object handling received TC space packets
|
||||
* @param txRateSetter Object providing the functionality to switch the input bitrate of
|
||||
* the S-Band transceiver.
|
||||
* @param gpioIF Required to enable TX data and TX clock RS485 transceiver chips.
|
||||
* @param enTxClock GPIO ID of RS485 tx clock enable
|
||||
* @param enTxData GPIO ID of RS485 tx data enable
|
||||
*/
|
||||
CCSDSHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination,
|
||||
TxRateSetterIF* txRateSetterIF, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData);
|
||||
~CCSDSHandler();
|
||||
|
||||
~CCSDSHandler();
|
||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||
ReturnValue_t initialize();
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
|
||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||
ReturnValue_t initialize();
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
/**
|
||||
* @brief Function to add a virtual channel
|
||||
*
|
||||
* @param virtualChannelId ID of the virtual channel to add
|
||||
* @param virtualChannel Pointer to virtual channel object
|
||||
*/
|
||||
void addVirtualChannel(VcId_t virtualChannelId, VirtualChannel* virtualChannel);
|
||||
|
||||
/**
|
||||
* @brief Function to add a virtual channel
|
||||
*
|
||||
* @param virtualChannelId ID of the virtual channel to add
|
||||
* @param virtualChannel Pointer to virtual channel object
|
||||
*/
|
||||
void addVirtualChannel(VcId_t virtualChannelId, VirtualChannel* virtualChannel);
|
||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0);
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex);
|
||||
|
||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0);
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex);
|
||||
uint16_t getIdentifier() override;
|
||||
MessageQueueId_t getRequestQueue() override;
|
||||
|
||||
uint16_t getIdentifier() override;
|
||||
MessageQueueId_t getRequestQueue() override;
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size);
|
||||
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size);
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER;
|
||||
|
||||
private:
|
||||
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER;
|
||||
static const ActionId_t SET_LOW_RATE = 0;
|
||||
static const ActionId_t SET_HIGH_RATE = 1;
|
||||
static const ActionId_t EN_TRANSMITTER = 2;
|
||||
static const ActionId_t DIS_TRANSMITTER = 3;
|
||||
|
||||
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
|
||||
|
||||
static const ActionId_t SET_LOW_RATE = 0;
|
||||
static const ActionId_t SET_HIGH_RATE = 1;
|
||||
static const ActionId_t EN_TRANSMITTER = 2;
|
||||
static const ActionId_t DIS_TRANSMITTER = 3;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
|
||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
|
||||
|
||||
#if OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT == 1
|
||||
// syrlinks must not be transmitting more than 15 minutes (according to datasheet)
|
||||
@ -97,72 +97,72 @@ private:
|
||||
static const uint32_t TRANSMITTER_TIMEOUT = 86400000; // 1 day
|
||||
#endif /* OBSW_SYRLINKS_DOWNLINK == 0 */
|
||||
|
||||
static const bool UP = true;
|
||||
static const bool DOWN = false;
|
||||
static const bool UP = true;
|
||||
static const bool DOWN = false;
|
||||
|
||||
using VirtualChannelMap = std::unordered_map<VcId_t, VirtualChannel*>;
|
||||
using VirtualChannelMapIter = VirtualChannelMap::iterator;
|
||||
using VirtualChannelMap = std::unordered_map<VcId_t, VirtualChannel*>;
|
||||
using VirtualChannelMapIter = VirtualChannelMap::iterator;
|
||||
|
||||
VirtualChannelMap virtualChannelMap;
|
||||
VirtualChannelMap virtualChannelMap;
|
||||
|
||||
// Object ID of PTME object
|
||||
object_id_t ptmeId;
|
||||
// Object ID of PTME object
|
||||
object_id_t ptmeId;
|
||||
|
||||
object_id_t tcDestination;
|
||||
object_id_t tcDestination;
|
||||
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
|
||||
ParameterHelper parameterHelper;
|
||||
ParameterHelper parameterHelper;
|
||||
|
||||
ActionHelper actionHelper;
|
||||
ActionHelper actionHelper;
|
||||
|
||||
MessageQueueId_t tcDistributorQueueId;
|
||||
MessageQueueId_t tcDistributorQueueId;
|
||||
|
||||
TxRateSetterIF* txRateSetterIF = nullptr;
|
||||
TxRateSetterIF* txRateSetterIF = nullptr;
|
||||
|
||||
GpioIF* gpioIF = nullptr;
|
||||
gpioId_t enTxClock = gpio::NO_GPIO;
|
||||
gpioId_t enTxData = gpio::NO_GPIO;
|
||||
GpioIF* gpioIF = nullptr;
|
||||
gpioId_t enTxClock = gpio::NO_GPIO;
|
||||
gpioId_t enTxData = gpio::NO_GPIO;
|
||||
|
||||
// Countdown to disable transmitter after 15 minutes
|
||||
Countdown transmitterCountdown;
|
||||
// Countdown to disable transmitter after 15 minutes
|
||||
Countdown transmitterCountdown;
|
||||
|
||||
// When true transmitting is started as soon as carrier lock has been detected
|
||||
bool enableTxWhenCarrierLock = false;
|
||||
// When true transmitting is started as soon as carrier lock has been detected
|
||||
bool enableTxWhenCarrierLock = false;
|
||||
|
||||
bool linkState = DOWN;
|
||||
bool linkState = DOWN;
|
||||
|
||||
void readCommandQueue(void);
|
||||
void handleTelemetry();
|
||||
void handleTelecommands();
|
||||
void checkEvents();
|
||||
void handleEvent(EventMessage* eventMessage);
|
||||
void readCommandQueue(void);
|
||||
void handleTelemetry();
|
||||
void handleTelecommands();
|
||||
void checkEvents();
|
||||
void handleEvent(EventMessage* eventMessage);
|
||||
|
||||
void handleBitLockEvent();
|
||||
void handleCarrierLockEvent();
|
||||
void handleBitLockEvent();
|
||||
void handleCarrierLockEvent();
|
||||
|
||||
/**
|
||||
* @brief Forward link state to virtual channels.
|
||||
*/
|
||||
void forwardLinkstate();
|
||||
/**
|
||||
* @brief Forward link state to virtual channels.
|
||||
*/
|
||||
void forwardLinkstate();
|
||||
|
||||
/**
|
||||
* @brief Starts transmit timer and enables transmitter.
|
||||
*/
|
||||
void enableTransmit();
|
||||
/**
|
||||
* @brief Starts transmit timer and enables transmitter.
|
||||
*/
|
||||
void enableTransmit();
|
||||
|
||||
/**
|
||||
* @brief Checks Tx timer for timeout and disables RS485 tx clock and tx data in case
|
||||
* timer has expired.
|
||||
*/
|
||||
void checkTxTimer();
|
||||
/**
|
||||
* @brief Checks Tx timer for timeout and disables RS485 tx clock and tx data in case
|
||||
* timer has expired.
|
||||
*/
|
||||
void checkTxTimer();
|
||||
|
||||
/**
|
||||
* @brief Disables the transmitter by pulling the enable tx clock and tx data pin of the
|
||||
* RS485 transceiver chips to high.
|
||||
*/
|
||||
void disableTransmit();
|
||||
/**
|
||||
* @brief Disables the transmitter by pulling the enable tx clock and tx data pin of the
|
||||
* RS485 transceiver chips to high.
|
||||
*/
|
||||
void disableTransmit();
|
||||
};
|
||||
|
||||
#endif /* CCSDSHANDLER_H_ */
|
||||
|
@ -1,69 +1,65 @@
|
||||
#include "CCSDSHandler.h"
|
||||
#include "VirtualChannel.h"
|
||||
|
||||
#include "CCSDSHandler.h"
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||
|
||||
|
||||
VirtualChannel::VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth) :
|
||||
vcId(vcId) {
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(tmQueueDepth,
|
||||
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
VirtualChannel::VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth) : vcId(vcId) {
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(tmQueueDepth,
|
||||
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
ReturnValue_t VirtualChannel::initialize() {
|
||||
tmStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if(tmStore == nullptr) {
|
||||
sif::error << "VirtualChannel::initialize: Failed to get tm store" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
tmStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if (tmStore == nullptr) {
|
||||
sif::error << "VirtualChannel::initialize: Failed to get tm store" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t VirtualChannel::performOperation() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
TmTcMessage message;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
TmTcMessage message;
|
||||
|
||||
while(tmQueue->receiveMessage(&message) == RETURN_OK) {
|
||||
store_address_t storeId = message.getStorageId();
|
||||
const uint8_t* data = nullptr;
|
||||
size_t size = 0;
|
||||
result = tmStore->getData(storeId, &data, &size);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "VirtualChannel::performOperation: Failed to read data from IPC store"
|
||||
<< std::endl;
|
||||
tmStore->deleteData(storeId);
|
||||
return result;
|
||||
}
|
||||
while (tmQueue->receiveMessage(&message) == RETURN_OK) {
|
||||
store_address_t storeId = message.getStorageId();
|
||||
const uint8_t* data = nullptr;
|
||||
size_t size = 0;
|
||||
result = tmStore->getData(storeId, &data, &size);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "VirtualChannel::performOperation: Failed to read data from IPC store"
|
||||
<< std::endl;
|
||||
tmStore->deleteData(storeId);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (linkIsUp) {
|
||||
result = ptme->writeToVc(vcId, data, size);
|
||||
}
|
||||
if (linkIsUp) {
|
||||
result = ptme->writeToVc(vcId, data, size);
|
||||
}
|
||||
|
||||
tmStore->deleteData(storeId);
|
||||
tmStore->deleteData(storeId);
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageQueueId_t VirtualChannel::getReportReceptionQueue(uint8_t virtualChannel) {
|
||||
return tmQueue->getId();
|
||||
return tmQueue->getId();
|
||||
}
|
||||
|
||||
void VirtualChannel::setPtmeObject(PtmeIF* ptme_) {
|
||||
if (ptme_ == nullptr) {
|
||||
sif::warning << "VirtualChannel::setPtmeObject: Invalid ptme object" << std::endl;
|
||||
return;
|
||||
}
|
||||
ptme = ptme_;
|
||||
if (ptme_ == nullptr) {
|
||||
sif::warning << "VirtualChannel::setPtmeObject: Invalid ptme object" << std::endl;
|
||||
return;
|
||||
}
|
||||
ptme = ptme_;
|
||||
}
|
||||
|
||||
void VirtualChannel::setLinkState(bool linkIsUp_) {
|
||||
linkIsUp = linkIsUp_;
|
||||
}
|
||||
void VirtualChannel::setLinkState(bool linkIsUp_) { linkIsUp = linkIsUp_; }
|
||||
|
@ -1,12 +1,13 @@
|
||||
#ifndef VIRTUALCHANNEL_H_
|
||||
#define VIRTUALCHANNEL_H_
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
#include <linux/obc/PtmeIF.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
|
||||
class StorageManagerIF;
|
||||
|
||||
/**
|
||||
@ -15,42 +16,41 @@ class StorageManagerIF;
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class VirtualChannel: public AcceptsTelemetryIF, public HasReturnvaluesIF {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param vcId The virtual channel id assigned to this object
|
||||
* @param tmQueueDepth Queue depth of queue receiving telemetry from other objects
|
||||
*/
|
||||
VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth);
|
||||
class VirtualChannel : public AcceptsTelemetryIF, public HasReturnvaluesIF {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param vcId The virtual channel id assigned to this object
|
||||
* @param tmQueueDepth Queue depth of queue receiving telemetry from other objects
|
||||
*/
|
||||
VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth);
|
||||
|
||||
ReturnValue_t initialize();
|
||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override;
|
||||
ReturnValue_t performOperation();
|
||||
ReturnValue_t initialize();
|
||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override;
|
||||
ReturnValue_t performOperation();
|
||||
|
||||
/**
|
||||
* @brief Sets the PTME object which handles access to the PTME IP Core.
|
||||
*
|
||||
* @param ptme Pointer to ptme object
|
||||
*/
|
||||
void setPtmeObject(PtmeIF* ptme_);
|
||||
/**
|
||||
* @brief Sets the PTME object which handles access to the PTME IP Core.
|
||||
*
|
||||
* @param ptme Pointer to ptme object
|
||||
*/
|
||||
void setPtmeObject(PtmeIF* ptme_);
|
||||
|
||||
/**
|
||||
* @brief Can be used by the owner to set the link state. Packets will be discarded if link
|
||||
* to ground station is down.
|
||||
*/
|
||||
void setLinkState(bool linkIsUp_);
|
||||
/**
|
||||
* @brief Can be used by the owner to set the link state. Packets will be discarded if link
|
||||
* to ground station is down.
|
||||
*/
|
||||
void setLinkState(bool linkIsUp_);
|
||||
|
||||
private:
|
||||
private:
|
||||
PtmeIF* ptme = nullptr;
|
||||
MessageQueueIF* tmQueue = nullptr;
|
||||
uint8_t vcId;
|
||||
|
||||
PtmeIF* ptme = nullptr;
|
||||
MessageQueueIF* tmQueue = nullptr;
|
||||
uint8_t vcId;
|
||||
bool linkIsUp = false;
|
||||
|
||||
bool linkIsUp = false;
|
||||
|
||||
StorageManagerIF* tmStore = nullptr;
|
||||
StorageManagerIF* tmStore = nullptr;
|
||||
};
|
||||
|
||||
#endif /* VIRTUALCHANNEL_H_ */
|
||||
|
Reference in New Issue
Block a user