working on tm
This commit is contained in:
parent
ad4adc7cba
commit
de93bff561
@ -30,6 +30,7 @@ add_subdirectory(tasks)
|
|||||||
add_subdirectory(tcdistribution)
|
add_subdirectory(tcdistribution)
|
||||||
#add_subdirectory(thermal)
|
#add_subdirectory(thermal)
|
||||||
add_subdirectory(timemanager)
|
add_subdirectory(timemanager)
|
||||||
|
add_subdirectory(tmtc)
|
||||||
add_subdirectory(tmtcpacket)
|
add_subdirectory(tmtcpacket)
|
||||||
add_subdirectory(tmtcservices)
|
add_subdirectory(tmtcservices)
|
||||||
add_subdirectory(filesystem)
|
add_subdirectory(filesystem)
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fsfw/returnvalues/returnvalue.h>
|
|
||||||
#include <fsfw/introspection/Enum.h>
|
#include <fsfw/introspection/Enum.h>
|
||||||
#include <fsfw/ipc/MutexIF.h>
|
#include <fsfw/ipc/MutexIF.h>
|
||||||
|
#include <fsfw/returnvalues/returnvalue.h>
|
||||||
|
#include <fsfw/storagemanager/storeAddress.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -10,6 +11,32 @@
|
|||||||
#include "DatasetEntryIF.h"
|
#include "DatasetEntryIF.h"
|
||||||
#include "HasDatapoolIF.h"
|
#include "HasDatapoolIF.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class has a dual use
|
||||||
|
*
|
||||||
|
* 1) It is used as an IPC method:
|
||||||
|
* It implements a shared memory which can be written and read by different parties
|
||||||
|
*
|
||||||
|
* 2) It is used to define data that is to be downlinked, either periodically or
|
||||||
|
* triggered by an (abstract, not in the sense of fsfw/events) event occuring, ie
|
||||||
|
* data was received from an external source and should be shared with ground.
|
||||||
|
*
|
||||||
|
* Generating a downlinked report is coupled to commiting, as without a commit there is no
|
||||||
|
* change in information to be reported.
|
||||||
|
*
|
||||||
|
* Nominally, the decision to report is done by the set itself, depending on its settings.
|
||||||
|
* If a report is to be forced regardless of these settings, the commitAndReport() functions
|
||||||
|
* are provided which will always generate a report.
|
||||||
|
*
|
||||||
|
* Periodic reports are not tied to a specific tc and are reported as "unrequested". When forcing
|
||||||
|
* a report, optionally a tc can be provided which (logically) triggered the report.
|
||||||
|
*
|
||||||
|
* And, as life is complicated, there is a third set of commits: commitAndReportIfRequested(). Same
|
||||||
|
* as before, but this time, a report is only generated, if the store_address_t is valid. These are
|
||||||
|
* used if at the place where the commit is called, it is not known if there is a request (cf DHB
|
||||||
|
* interpretDeviceReply)
|
||||||
|
*/
|
||||||
|
|
||||||
class Dataset {
|
class Dataset {
|
||||||
protected:
|
protected:
|
||||||
#ifdef FSFW_INTROSPECTION
|
#ifdef FSFW_INTROSPECTION
|
||||||
@ -31,11 +58,59 @@ class Dataset {
|
|||||||
/**
|
/**
|
||||||
* Copy content of local copies into actual variable
|
* Copy content of local copies into actual variable
|
||||||
*
|
*
|
||||||
* calls setValit(valid) before committing
|
* calls setValid(valid) before committing
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void commit(bool valid);
|
void commit(bool valid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy content of local copies into actual variable
|
||||||
|
* Force sending of TM packet
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void commitAndReport();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy content of local copies into actual variable
|
||||||
|
* Force sending of TM packet
|
||||||
|
*
|
||||||
|
* calls setValid(valid) before committing
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void commitAndReport(bool valid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy content of local copies into actual variable
|
||||||
|
* Force sending of TM packet, in reference to tc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void commitAndReport(store_address_t tc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy content of local copies into actual variable
|
||||||
|
* Force sending of TM packet, in reference to tc
|
||||||
|
*
|
||||||
|
* calls setValid(valid) before committing
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void commitAndReport(bool valid, store_address_t tc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy content of local copies into actual variable
|
||||||
|
* Force sending of TM packet, in reference to tc
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void commitAndReportIfRequested(store_address_t tc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy content of local copies into actual variable
|
||||||
|
* Force sending of TM packet, in reference to tc
|
||||||
|
*
|
||||||
|
* calls setValid(valid) before committing
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void commitAndReportIfRequested(bool valid, store_address_t tc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set all contained variables to #valid
|
* set all contained variables to #valid
|
||||||
*
|
*
|
||||||
@ -71,7 +146,6 @@ class Dataset {
|
|||||||
*/
|
*/
|
||||||
virtual const std::vector<DatasetEntryIF*>* getVariables() const;
|
virtual const std::vector<DatasetEntryIF*>* getVariables() const;
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t initialize();
|
ReturnValue_t initialize();
|
||||||
|
|
||||||
// operator[]
|
// operator[]
|
||||||
|
29
src/fsfw/tmtc/AcceptsTelemetryIF.h
Normal file
29
src/fsfw/tmtc/AcceptsTelemetryIF.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef FSFW_TMTCSERVICES_ACCEPTSTELEMETRYIF_H_
|
||||||
|
#define FSFW_TMTCSERVICES_ACCEPTSTELEMETRYIF_H_
|
||||||
|
|
||||||
|
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
||||||
|
/**
|
||||||
|
* @brief This interface is implemented by classes that are sinks for
|
||||||
|
* Telemetry.
|
||||||
|
* @details Any object receiving telemetry shall implement this interface
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class AcceptsTelemetryIF {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief The virtual destructor as it is mandatory for C++ interfaces.
|
||||||
|
*/
|
||||||
|
virtual ~AcceptsTelemetryIF() = default;
|
||||||
|
|
||||||
|
// [[nodiscard]] virtual const char* getName() const = 0;
|
||||||
|
// /**
|
||||||
|
// * @brief This method returns the message queue id of the telemetry
|
||||||
|
// * receiving message queue.
|
||||||
|
// * @return The telemetry reception message queue id.
|
||||||
|
// */
|
||||||
|
// [[nodiscard]] virtual MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual MessageQueueId_t getReportReceptionQueue() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_TMTCSERVICES_ACCEPTSTELEMETRYIF_H_ */
|
5
src/fsfw/tmtc/CMakeLists.txt
Normal file
5
src/fsfw/tmtc/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
target_sources(
|
||||||
|
${LIB_FSFW_NAME} PRIVATE
|
||||||
|
FsfwProtocolHeader.cpp
|
||||||
|
TmManager.cpp
|
||||||
|
UdpTmTcBridge.cpp)
|
51
src/fsfw/tmtc/FsfwProtocolHeader.cpp
Normal file
51
src/fsfw/tmtc/FsfwProtocolHeader.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "FsfwProtocolHeader.h"
|
||||||
|
|
||||||
|
#include <fsfw/serialize/SerializeAdapter.h>
|
||||||
|
|
||||||
|
FsfwProtocolHeader::FsfwProtocolHeader() {}
|
||||||
|
|
||||||
|
FsfwProtocolHeader::FsfwProtocolHeader(object_id_t objectId, uint8_t interface, uint8_t function)
|
||||||
|
: objectId(objectId), interface(interface), function(function) {}
|
||||||
|
|
||||||
|
FsfwProtocolHeader::~FsfwProtocolHeader() {}
|
||||||
|
|
||||||
|
ReturnValue_t FsfwProtocolHeader::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
|
Endianness streamEndianness) const {
|
||||||
|
ReturnValue_t result =
|
||||||
|
SerializeAdapter::serialize(&objectId, buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = SerializeAdapter::serialize(&interface, buffer, size, maxSize, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return SerializeAdapter::serialize(&function, buffer, size, maxSize, streamEndianness);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FsfwProtocolHeader::getSerializedSize() const {
|
||||||
|
return HEADER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t FsfwProtocolHeader::deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
|
Endianness streamEndianness) {
|
||||||
|
ReturnValue_t result = SerializeAdapter::deSerialize(&objectId, buffer, size, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = SerializeAdapter::deSerialize(&interface, buffer, size, streamEndianness);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = SerializeAdapter::deSerialize(&function, buffer, size, streamEndianness);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_id_t FsfwProtocolHeader::getObjectId() const { return objectId; }
|
||||||
|
|
||||||
|
uint8_t FsfwProtocolHeader::getInterface() const { return interface; }
|
||||||
|
|
||||||
|
uint8_t FsfwProtocolHeader::getFunction() const { return function; }
|
30
src/fsfw/tmtc/FsfwProtocolHeader.h
Normal file
30
src/fsfw/tmtc/FsfwProtocolHeader.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/serialize/SerializeIF.h>
|
||||||
|
|
||||||
|
class FsfwProtocolHeader : public SerializeIF {
|
||||||
|
public:
|
||||||
|
static const size_t HEADER_SIZE = 6;
|
||||||
|
|
||||||
|
FsfwProtocolHeader();
|
||||||
|
FsfwProtocolHeader(object_id_t objectID, uint8_t interface, uint8_t function);
|
||||||
|
~FsfwProtocolHeader() override;
|
||||||
|
|
||||||
|
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
|
Endianness streamEndianness) const override;
|
||||||
|
|
||||||
|
size_t getSerializedSize() const override;
|
||||||
|
|
||||||
|
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||||
|
Endianness streamEndianness) override;
|
||||||
|
|
||||||
|
object_id_t getObjectId() const;
|
||||||
|
uint8_t getInterface() const;
|
||||||
|
uint8_t getFunction() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
object_id_t objectId;
|
||||||
|
uint8_t interface;
|
||||||
|
uint8_t function;
|
||||||
|
};
|
5
src/fsfw/tmtc/FsfwProtocols.h
Normal file
5
src/fsfw/tmtc/FsfwProtocols.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
enum neither_type : uint8_t { IP4, IP6, IP4_ENCAPSULATED, SPACEPACKET };
|
64
src/fsfw/tmtc/TmManager.cpp
Normal file
64
src/fsfw/tmtc/TmManager.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "TmManager.h"
|
||||||
|
|
||||||
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
|
|
||||||
|
ReturnValue_t TmManager::initialize() {
|
||||||
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
|
if (IPCStore == nullptr) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t TmManager::getProtocolInformation(store_address_t tc,
|
||||||
|
protocolInformation* information) const {
|
||||||
|
const uint8_t* tcData;
|
||||||
|
size_t tcDataSize;
|
||||||
|
ReturnValue_t result = IPCStore->getData(tc, &tcData, &tcDataSize);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return getDefaultProtocolInformation(information);
|
||||||
|
}
|
||||||
|
|
||||||
|
neither_type tcProtocol = neither_type(*tcData);
|
||||||
|
|
||||||
|
if (not protocolMap.contains(tcProtocol)) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
auto protocolIter = protocolMap.find(tcProtocol);
|
||||||
|
|
||||||
|
information->reportingQueue = protocolIter->second.queue;
|
||||||
|
information->offset = protocolIter->second.offset;
|
||||||
|
information->protocol = tcProtocol;
|
||||||
|
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t TmManager::registerNetworkProtocolInterface(AcceptsTelemetryIF* object,
|
||||||
|
neither_type protocol, size_t offset) {
|
||||||
|
if (protocolMap.contains(protocol)) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocolMap.emplace(protocol, ProtocolInformation({object->getReportReceptionQueue(), offset}));
|
||||||
|
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t TmManager::getDefaultProtocolInformation(protocolInformation* information) const {
|
||||||
|
if (protocolMap.empty()) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto protocolIter = protocolMap.begin();
|
||||||
|
|
||||||
|
information->reportingQueue = protocolIter->second.queue;
|
||||||
|
information->offset = protocolIter->second.offset;
|
||||||
|
information->protocol = protocolIter->first;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
56
src/fsfw/tmtc/TmManager.h
Normal file
56
src/fsfw/tmtc/TmManager.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/storagemanager/StorageManagerIF.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "AcceptsTelemetryIF.h"
|
||||||
|
#include "FsfwProtocols.h"
|
||||||
|
|
||||||
|
// TODO handle VCs and backpressure
|
||||||
|
|
||||||
|
class TmManager : public SystemObject {
|
||||||
|
public:
|
||||||
|
struct protocolInformation {
|
||||||
|
neither_type protocol;
|
||||||
|
size_t offset;
|
||||||
|
MessageQueueId_t reportingQueue;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TmManager(object_id_t setObjectId);
|
||||||
|
|
||||||
|
virtual ~TmManager() = default;
|
||||||
|
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the offset which the application data should start at, using the same network layer as
|
||||||
|
* the tc, as well as the protocol type which should be the first byte of the tm
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ReturnValue_t getProtocolInformation(store_address_t tc, protocolInformation *information) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If tm is unrequested, get Default path
|
||||||
|
*/
|
||||||
|
ReturnValue_t getDefaultProtocolInformation(protocolInformation *information) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset is where application data should start in a preset zero-copy packet. If no fixed value,
|
||||||
|
* report 0 and allocate and copy yourself
|
||||||
|
*/
|
||||||
|
ReturnValue_t registerNetworkProtocolInterface(AcceptsTelemetryIF *object, neither_type protocol,
|
||||||
|
size_t offset);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct ProtocolInformation {
|
||||||
|
MessageQueueId_t queue;
|
||||||
|
size_t offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
StorageManagerIF *IPCStore;
|
||||||
|
|
||||||
|
std::map<neither_type, ProtocolInformation> protocolMap;
|
||||||
|
};
|
142
src/fsfw/tmtc/UdpTmTcBridge.cpp
Normal file
142
src/fsfw/tmtc/UdpTmTcBridge.cpp
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#include "UdpTmTcBridge.h"
|
||||||
|
|
||||||
|
#include "FsfwProtocolHeader.h"
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fsfw/action.h>
|
||||||
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
|
#include <fsfw/objectmanager.h>
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h> // POSIX.1-2001 does not require the inclusion of <sys/types.h>, and this header file is not required on Linux. However, some historical (BSD) implementations required this header file, and portable applications are probably wise to include it.
|
||||||
|
|
||||||
|
UdpTmTcBridgeNew::UdpTmTcBridgeNew(object_id_t objectId, object_id_t tmStoreId,
|
||||||
|
object_id_t tcStoreId)
|
||||||
|
: SystemObject(objectId) {
|
||||||
|
messageQueue =
|
||||||
|
QueueFactory::instance()->createMessageQueue(50, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpTmTcBridgeNew::~UdpTmTcBridgeNew() {}
|
||||||
|
|
||||||
|
ReturnValue_t UdpTmTcBridgeNew::initialize() {
|
||||||
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||||
|
if (IPCStore == nullptr) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
serverSocket = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0);
|
||||||
|
if (serverSocket == -1) {
|
||||||
|
// TODO resolve errno
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "UdpTmTcBridge::initialize: Socket initialization failed!" << std::endl;
|
||||||
|
#endif
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_in serverAddr;
|
||||||
|
serverAddr.sin_family = AF_INET;
|
||||||
|
serverAddr.sin_port = htons(6667);
|
||||||
|
|
||||||
|
retval = inet_aton("10.13.90.2", &serverAddr.sin_addr);
|
||||||
|
if (retval == 0) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "UdpTmTcBridge::initialize: Invalid IP!" << std::endl;
|
||||||
|
#endif
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
|
||||||
|
if (retval == -1) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "UdpTmTcBridge::initialize: bind failed with " << errno << std::endl;
|
||||||
|
#endif
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t UdpTmTcBridgeNew::performOperation(uint8_t operationCode) {
|
||||||
|
ssize_t peekLen = recv(serverSocket, NULL, 0, MSG_PEEK | MSG_TRUNC);
|
||||||
|
|
||||||
|
if (peekLen <= 0) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peekLen < FsfwProtocolHeader::HEADER_SIZE) {
|
||||||
|
recv(serverSocket, NULL, 0, MSG_TRUNC);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
store_address_t storageId;
|
||||||
|
uint8_t *bufferPointer;
|
||||||
|
ReturnValue_t result = IPCStore->getFreeElement(&storageId, peekLen, &bufferPointer);
|
||||||
|
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_storage sender;
|
||||||
|
socklen_t senderlen = sizeof(sender);
|
||||||
|
|
||||||
|
ssize_t receivedLen =
|
||||||
|
recvfrom(serverSocket, bufferPointer, peekLen, 0, (struct sockaddr *)&sender, &senderlen);
|
||||||
|
|
||||||
|
if (receivedLen == -1) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (receivedLen != peekLen) {
|
||||||
|
// should not happen, if it does throw away
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t bufferLen = receivedLen;
|
||||||
|
const uint8_t *constBufferPointer = bufferPointer;
|
||||||
|
|
||||||
|
FsfwProtocolHeader header;
|
||||||
|
|
||||||
|
result = header.deSerialize(&constBufferPointer, &bufferLen,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
sif::debug << "Received msg for 0x" << std::hex << header.getObjectId() << std::dec << " interface "
|
||||||
|
<< (int) header.getInterface() << std::endl;
|
||||||
|
|
||||||
|
CommandMessage message;
|
||||||
|
|
||||||
|
switch (header.getInterface()) {
|
||||||
|
case HasActionsIF::INTERFACE_ID: {
|
||||||
|
HasActionsIF *object = ObjectManager::instance()->get<HasActionsIF>(header.getObjectId());
|
||||||
|
if (object == nullptr) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionMessage::setCommand(&message, header.HEADER_SIZE, storageId);
|
||||||
|
result = messageQueue->sendMessage(object->getCommandQueue(), &message);
|
||||||
|
// sif::debug << "UdpTmTcBridge::performOperation: sent " << (int)storageId.raw << std::endl;
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
// sif::debug << "UdpTmTcBridge::performOperation: illegal interface"
|
||||||
|
// << (int) header.getInterface() << std::endl;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
25
src/fsfw/tmtc/UdpTmTcBridge.h
Normal file
25
src/fsfw/tmtc/UdpTmTcBridge.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/storagemanager/StorageManagerIF.h>
|
||||||
|
#include <fsfw/ipc/MessageQueueIF.h>
|
||||||
|
|
||||||
|
|
||||||
|
class UdpTmTcBridgeNew : public SystemObject, public ExecutableObjectIF {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static const size_t MINIMAL_LENGTH = 4 + 2; // ObjectId, interface, function
|
||||||
|
UdpTmTcBridgeNew(object_id_t objectId,
|
||||||
|
object_id_t tmStoreId, object_id_t tcStoreId);
|
||||||
|
virtual ~UdpTmTcBridgeNew();
|
||||||
|
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MessageQueueIF* messageQueue;
|
||||||
|
int serverSocket;
|
||||||
|
StorageManagerIF* IPCStore;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user