From 551a8f021b0e59bb01310b7bb5a1bc66e00e1421 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" Date: Mon, 14 Dec 2020 08:42:48 +0100 Subject: [PATCH] wip CspComIF --- bsp_linux/comIF/CspComIF.cpp | 167 +++++++++ bsp_linux/comIF/CspComIF.h | 66 ++++ bsp_linux/comIF/cookies/CspCookie.cpp | 24 ++ bsp_linux/comIF/cookies/CspCookie.h | 31 ++ mission/core/GenericFactory.cpp | 11 +- mission/devices/P60DockHandler.cpp | 84 +++-- mission/devices/P60DockHandler.h | 22 +- .../devicedefinitions/GomSpacePackets.h | 332 ++++++++++++++++++ .../P60DockHandlerDefinitions.h | 32 ++ 9 files changed, 727 insertions(+), 42 deletions(-) create mode 100644 bsp_linux/comIF/CspComIF.cpp create mode 100644 bsp_linux/comIF/CspComIF.h create mode 100644 bsp_linux/comIF/cookies/CspCookie.cpp create mode 100644 bsp_linux/comIF/cookies/CspCookie.h create mode 100644 mission/devices/devicedefinitions/GomSpacePackets.h diff --git a/bsp_linux/comIF/CspComIF.cpp b/bsp_linux/comIF/CspComIF.cpp new file mode 100644 index 00000000..6716c530 --- /dev/null +++ b/bsp_linux/comIF/CspComIF.cpp @@ -0,0 +1,167 @@ +#include "CspComIF.h" +#include +#include +#include +#include + +CspComIF::CspComIF(object_id_t objectId) : + SystemObject(objectId) { + +} + +CspComIF::~CspComIF() { +} + +ReturnValue_t CspComIF::initializeInterface(CookieIF *cookie) { + if(cookie == nullptr) { + return NULLPOINTER; + } + + CspCookie* cspCookie = dynamic_cast(cookie); + if(cspCookie == nullptr) { + return NULLPOINTER; + } + char* canInterface = cspCookie->getCanIf(); + int bitrate = cspCookie->getBitrate(); + /* Define the memory to allocate for the CSP stack */ + int buf_count = 10; + int buf_size = 300; + /* Init CSP and CSP buffer system */ + if (csp_init(cspClientAddress) != CSP_ERR_NONE + || csp_buffer_init(buf_count, buf_size) != CSP_ERR_NONE) { + sif::error << "Failed to init CSP\r\n" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + int promisc = 0; // Set filter mode on + csp_iface_t *csp_if_ptr = &csp_if; + csp_if_ptr = csp_can_socketcan_init(canInterface, bitrate, promisc); + + /* Set default route and start router */ + uint8_t address = CSP_DEFAULT_ROUTE; + uint8_t netmask = 0; + uint8_t mac = CSP_NODE_MAC; + int result = csp_rtable_set(address, netmask, csp_if_ptr, mac); + if(result != CSP_ERR_NONE){ + sif::error << "Failed to add can interface to router table" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + /* Start the route task */ + unsigned int task_stack_size = 500; + unsigned int priority = 0; + result = csp_route_start_task(task_stack_size, priority); + if(result != CSP_ERR_NONE){ + sif::error << "Failed to start csp route task" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + uint8_t cspAddress = cspCookie->getCspAddress(); + uint16_t maxReplyLength = cspCookie->getMaxReplyLength(); + if(cspDeviceMap.find(cspAddress) != cspDeviceMap.end()){ + /* Insert device information in CSP map */ + cspDeviceMap.emplace(cspAddress, vectorBuffer(maxReplyLength)); + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CspComIF::sendMessage(CookieIF *cookie, + const uint8_t * sendData, size_t sendLen) { + int result; + if(cookie == NULL){ + return HasReturnvaluesIF::RETURN_FAILED; + } + CspCookie* cspCookie = dynamic_cast (cookie); + if(cspCookie == NULL){ + return HasReturnvaluesIF::RETURN_FAILED; + } + + /* Extract csp port and bytes to query from command buffer */ + uint8_t cspPort; + uint16_t querySize; + SerializeAdapter::deSerialize(&cspPort, &sendData, &sendLen, + SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&querySize, &sendData, &sendLen, + SerializeIF::Endianness::BIG); + uint8_t cspAddress = cspCookie->getCspAddress(); + + if(cspPort == csp_reserved_ports_e::CSP_PING){ + uint32_t timeout = 1000; // ms + unsigned int pingSize = 100; // 100 bytes + uint32_t replyTime = csp_ping(cspAddress, timeout, pingSize, + CSP_O_NONE); + sif::info << "Ping address: " << cspAddress << ", reply after " + << replyTime << " ms" << std::endl; + /* Store reply time in reply buffer * */ + uint8_t* replyBuffer = cspDeviceMap[cspAddress].data(); + memcpy(replyBuffer, &replyTime, sizeof(replyTime)); + } + else if(cspPort == csp_reserved_ports_e::CSP_REBOOT){ + csp_reboot(cspCookie->getCspAddress()); + } + else{ + /* No CSP fixed port was selected. Send data to the specified port and + * wait for querySize number of bytes */ + result = cspTransfer(cspAddress, cspPort, sendData, sendLen, + querySize); + if(result != HasReturnvaluesIF::RETURN_OK){ + return HasReturnvaluesIF::RETURN_FAILED; + } + rememberQuerySize = querySize; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CspComIF::getSendSuccess(CookieIF *cookie) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CspComIF::requestReceiveMessage(CookieIF *cookie, + size_t requestLen) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CspComIF::readReceivedMessage(CookieIF *cookie, + uint8_t** buffer, size_t* size) { + if(cookie == NULL){ + return HasReturnvaluesIF::RETURN_FAILED; + } + CspCookie* cspCookie = dynamic_cast (cookie); + if(cspCookie == NULL){ + return HasReturnvaluesIF::RETURN_FAILED; + } + + uint8_t cspAddress = cspCookie->getCspAddress(); + + *buffer = cspDeviceMap[cspAddress].data(); + *size = rememberQuerySize; + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CspComIF::cspTransfer(uint8_t cspAddress, uint8_t cspPort, + const uint8_t* cmdBuffer, int cmdBufferLen, uint16_t querySize) { + + uint32_t timeout_ms = 1000; + uint8_t* replyBuffer = cspDeviceMap[cspAddress].data(); + uint8_t tmpCmdBuffer[cmdBufferLen]; + memcpy(tmpCmdBuffer, cmdBuffer, cmdBufferLen); + + csp_conn_t * conn = csp_connect(CSP_PRIO_HIGH, cspAddress, cspPort, 0, + CSP_O_NONE); + + querySize = 12; + int receivedBytes = csp_transaction_persistent(conn, timeout_ms, + tmpCmdBuffer, cmdBufferLen, replyBuffer, querySize); + if(receivedBytes != querySize){ + sif::error << "CSP transfer failed to receive all requested bytes " + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + csp_close(conn); + + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/bsp_linux/comIF/CspComIF.h b/bsp_linux/comIF/CspComIF.h new file mode 100644 index 00000000..4fb24226 --- /dev/null +++ b/bsp_linux/comIF/CspComIF.h @@ -0,0 +1,66 @@ +#ifndef BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ +#define BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ + +#include +#include +#include +#include + +#include +#include + +/** + * @brief This class is serves as the communication interface to devices + * supporting the CSP protocol. For now as physical interface only + * CAN is supported by this CSP implementation. + * @author Jakob Meier + */ +class CspComIF: public DeviceCommunicationIF, public SystemObject { +public: + CspComIF(object_id_t objectId); + virtual ~CspComIF(); + + ReturnValue_t initializeInterface(CookieIF * cookie) override; + ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData, + size_t sendLen) override; + ReturnValue_t getSendSuccess(CookieIF *cookie) override; + ReturnValue_t requestReceiveMessage(CookieIF *cookie, + size_t requestLen) override; + ReturnValue_t readReceivedMessage(CookieIF *cookie, + uint8_t **readData, size_t *readLen) override; + +private: + + /** + * @brief This function initiates the CSP transfer. + * + * @param cspAddress The CSP address of the target device. + * @param cspPort The port of the target device. + * @param timeout The timeout to wait for csp_send and csp_read + * functions. Specifies how long the functions wait + * for a successful operation. + * @param cmdBuffer The data to send. + * @param cmpBuffer The number of bytes to send. + * @param querySize The size of the requested message. + */ + ReturnValue_t cspTransfer(uint8_t cspAddress, uint8_t cspPort, + const uint8_t* cmdBuffer, int cmdBufferLen, uint16_t querySize); + + typedef uint8_t node_t; + using vectorBuffer = std::vector; + using VectorBufferMap = std::unordered_map; + using vectorBufferIter = VectorBufferMap::iterator; + + /* In this map assigns reply buffers to a CSP device */ + VectorBufferMap cspDeviceMap; + + uint16_t rememberQuerySize = 0; + + /* This is the CSP address of the OBC. */ + node_t cspClientAddress = 1; + + /* Interface struct for csp protocol stack */ + csp_iface_t csp_if; +}; + +#endif /* BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ */ diff --git a/bsp_linux/comIF/cookies/CspCookie.cpp b/bsp_linux/comIF/cookies/CspCookie.cpp new file mode 100644 index 00000000..64c160f5 --- /dev/null +++ b/bsp_linux/comIF/cookies/CspCookie.cpp @@ -0,0 +1,24 @@ +#include "CspCookie.h" + +CspCookie::CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_) : + maxReplyLength(maxReplyLength_), cspAddress(cspAddress_) { +} + +CspCookie::~CspCookie() { +} + +uint16_t CspCookie::getMaxReplyLength(){ + return maxReplyLength; +} + +uint8_t CspCookie::getCspAddress(){ + return cspAddress; +} + +char* CspCookie::getCanIf(){ + return canInterface; +} + +int CspCookie::getBitrate(){ + return bitrate; +} diff --git a/bsp_linux/comIF/cookies/CspCookie.h b/bsp_linux/comIF/cookies/CspCookie.h new file mode 100644 index 00000000..5dfebfc0 --- /dev/null +++ b/bsp_linux/comIF/cookies/CspCookie.h @@ -0,0 +1,31 @@ +#ifndef BSP_LINUX_COMIF_COOKIES_CSPCOOKIE_H_ +#define BSP_LINUX_COMIF_COOKIES_CSPCOOKIE_H_ + +#include +#include + +/** + * @brief This is the cookie for devices supporting the CSP (CubeSat Space + * Protocol). + * @author J. Meier + */ +class CspCookie: public CookieIF { +public: + + CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_); + virtual ~CspCookie(); + + uint16_t getMaxReplyLength(); + uint8_t getCspAddress(); + char* getCanIf(); + int getBitrate(); + +private: + + uint16_t maxReplyLength; + char canInterface[5] = "can0"; + uint8_t cspAddress; + int bitrate = 1000; +}; + +#endif /* BSP_LINUX_COMIF_COOKIES_CSPCOOKIE_H_ */ diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index b350cbd4..2964e0d3 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -21,8 +21,8 @@ #include #include #include -#include -#include +#include +#include #if ADD_TEST_CODE == 1 //#include @@ -86,14 +86,15 @@ void ObjectFactory::produceGenericObjects() { apid::EIVE_OBSW, pus::PUS_SERVICE_200); /* Cookies */ - P60DockCookie* p60DockCookie = new P60DockCookie(addresses::P60DOCK); + CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, + addresses::P60DOCK); /* Communication interfaces */ - new P60DockComIF(objects::P60_DOCK_COM_IF); + new CspComIF(objects::P60_DOCK_COM_IF); /* Device Handler */ new P60DockHandler(objects::P60DOCK_HANDLER, objects::P60_DOCK_COM_IF, - p60DockCookie); + p60DockCspCookie); /* Test Device Handler */ #if ADD_TEST_CODE == 1 diff --git a/mission/devices/P60DockHandler.cpp b/mission/devices/P60DockHandler.cpp index fa4ebebb..ab914681 100644 --- a/mission/devices/P60DockHandler.cpp +++ b/mission/devices/P60DockHandler.cpp @@ -1,8 +1,5 @@ -#include -#include #include -#include "bsp_linux/comIF/cookies/P60DockCookie.h" -#include "bsp_linux/comIF/P60DockComIF.h" +#include P60DockHandler::P60DockHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie):DeviceHandlerBase(objectId, comIF, comCookie) { @@ -10,10 +7,6 @@ P60DockHandler::P60DockHandler(object_id_t objectId, object_id_t comIF, if(comCookie == NULL){ sif::error << "P60DockHandler invalid com cookie" << std::endl; } - p60DockCookie = dynamic_cast (comCookie); - if(p60DockCookie == NULL){ - sif::error << "P60DockHandler failed to get P60DockCookie" << std::endl; - } } P60DockHandler::~P60DockHandler() { @@ -41,15 +34,39 @@ ReturnValue_t P60DockHandler::buildCommandFromCommand( size_t commandDataLen) { switch(deviceCommand) { case(PING): { - p60DockCookie->setPingMessage(); break; } - case(READ_MODULE_CFG):{ - p60DockCookie->setReadModuleCfgMessage(); + case(PARAM_SET):{ break; } - case(READ_HK):{ - p60DockCookie->setReadHkMessage(); + case(PARAM_GET):{ + /* Unpack the received action message */ + GetParamMessageUnpacker getParamMessage(commandData, commandDataLen); + uint8_t tableId = getParamMessage.getTableId(); + uint16_t address = getParamMessage.getAddress(); + uint16_t length = EndianConverter::convertLittleEndian( + sizeof(address)); + uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM; + uint16_t seq = 0; + uint16_t total = 0; + uint16_t querySize = getParamMessage.getQuerySize(); + + /* Generate the CSP command to send to the P60 Dock */ + CspGetParamCommand getParamCmd(querySize, PARAM_GET, tableId, length, + checksum, seq, total, address); + size_t cspPacketLen = 0; + uint8_t* buffer = cspPacket; + getParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket), + SerializeIF::Endianness::BIG); + if(cspPacketLen > MAX_PACKET_LEN){ + sif::error << "P60DockHandler: Received invalid get parameter " + "command" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + rawPacket = cspPacket; + rawPacketLen = cspPacketLen; + rememberRequestedSize = querySize; + rememberCommandId = PARAM_GET; break; } default: @@ -60,44 +77,51 @@ ReturnValue_t P60DockHandler::buildCommandFromCommand( void P60DockHandler::fillCommandAndReplyMap(){ this->insertInCommandAndReplyMap(PING, 3); - this->insertInCommandAndReplyMap(READ_MODULE_CFG, 3); - this->insertInCommandAndReplyMap(READ_HK, 3); + this->insertInCommandAndReplyMap(PARAM_SET, 3); + this->insertInCommandAndReplyMap(PARAM_GET, 3); } ReturnValue_t P60DockHandler::scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { - MessageType_t messageType = p60DockCookie->getMessageType(); - switch(messageType) { + switch(rememberCommandId) { case(PING): *foundId = PING; - *foundLen = 4; + *foundLen = rememberRequestedSize; + rememberCommandId = NONE; break; - case(READ_MODULE_CFG): { - *foundId = READ_MODULE_CFG; - *foundLen = moduleCfgTableSize; - break; - } - case(READ_HK): { - *foundId = READ_HK; - *foundLen = hkTableSize; + case(PARAM_GET): { + *foundId = PARAM_GET; + *foundLen = rememberRequestedSize + CspGetParamReply::GS_HDR_LENGTH; + rememberCommandId = NONE; break; } default: return IGNORE_REPLY_DATA; } - p60DockCookie->resetMessageType(); return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t P60DockHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { switch(id) { - case(READ_MODULE_CFG): { + case(PING): { handleDeviceTM((SerializeIF*)packet, id, true, true); break; } - case(READ_HK): { - handleDeviceTM((SerializeIF*)packet, id, true, true); + case(PARAM_GET): { + uint16_t payloadLength = *(packet + 2); + uint8_t tempPayloadBuffer[payloadLength]; + CspGetParamReply cspGetParamReply(tempPayloadBuffer, payloadLength); + uint8_t action = cspGetParamReply.getAction(); + uint8_t tableId = cspGetParamReply.getTableId(); + uint16_t length = cspGetParamReply.getLength(); + uint16_t address = cspGetParamReply.getAddress(); + size_t size = CspGetParamReply::GS_HDR_LENGTH + payloadLength; + cspGetParamReply.deSerialize(&packet, &size, + SerializeIF::Endianness::LITTLE); + ParamReply paramReply(action, tableId, address, length, tempPayloadBuffer, + payloadLength); + handleDeviceTM(¶mReply, id, true, true); break; } default: diff --git a/mission/devices/P60DockHandler.h b/mission/devices/P60DockHandler.h index 40161e42..abb61ba4 100644 --- a/mission/devices/P60DockHandler.h +++ b/mission/devices/P60DockHandler.h @@ -4,6 +4,13 @@ #include #include +namespace P60Dock{ + /* The maximum size of a reply from the P60 dock. Maximum size is reached + * when retrieving the full parameter configuration table. 412 bytes of + * payload data and 12 bytes of CSP header data. */ + static const uint16_t MAX_REPLY_LENGTH = 424; +} + class P60DockHandler: public DeviceHandlerBase { public: P60DockHandler(object_id_t objectId, object_id_t comIF, @@ -26,15 +33,16 @@ protected: private: + static const uint8_t MAX_PACKET_LEN = 36; + /* Device commands are derived from the rparam.h of the gomspace lib */ static const DeviceCommandId_t PING = 0x1; //!< [EXPORT] : [COMMAND] - static const DeviceCommandId_t READ_MODULE_CFG = 0x71; //!< [EXPORT] : [COMMAND] - static const DeviceCommandId_t READ_HK = 0x72; //!< [EXPORT] : [COMMAND] + static const DeviceCommandId_t NONE = 0x2; // Set when no command is pending + static const DeviceCommandId_t PARAM_GET = 0x00; //!< [EXPORT] : [COMMAND] + static const DeviceCommandId_t PARAM_SET = 0xFF; //!< [EXPORT] : [COMMAND] - uint16_t moduleCfgTableSize = 412; - uint8_t calibrationTableSize = 174; - uint8_t hkTableSize = 188; - - P60DockCookie* p60DockCookie; + uint8_t rememberRequestedSize = 0; + uint8_t rememberCommandId = NONE; + uint8_t cspPacket[MAX_PACKET_LEN]; }; #endif /* MISSION_DEVICES_P60DOCKHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/GomSpacePackets.h b/mission/devices/devicedefinitions/GomSpacePackets.h new file mode 100644 index 00000000..5fab5a8b --- /dev/null +++ b/mission/devices/devicedefinitions/GomSpacePackets.h @@ -0,0 +1,332 @@ +#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEPACKETS_H_ +#define MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEPACKETS_H_ + +#include "fsfw/serialize/SerialBufferAdapter.h" +#include "fsfw/serialize/SerializeElement.h" +#include "fsfw/serialize/SerialLinkedListAdapter.h" + +namespace GOMSPACE{ + static const uint16_t IGNORE_CHECKSUM = 0x0bb0; + /* CSP port to ping gomspace devices. */ + static const uint8_t PING_PORT = 1; + static const uint8_t REBOOT_PORT = 4; + /* CSP port of gomspace devices to request or set parameters */ + static const uint8_t PARAM_PORT = 7; +} + +/** + * @brief A serial linked list adapter implementation to generate ping + * messages for gomspace devices. + * + * @details A ping request simply sends back the received data provided by the + * data buffer. cspPort and querySize are only informations required + * by the CspComI and other than the data array not physically + * transmitted to the target device. + */ +class CspPing : public SerialLinkedListAdapter { +public: + /** + * @brief Constructor + * + * @param querySize_ The size of bytes replied by the ping request. + * Amounts to the number of bytes send. + * @param parameters_ Pointer to data which should be sent to the device. + * All data will be sent back by the ping target. + * @param paramterCount_ Number of bytes to send with the ping request. + */ + CspPing(uint16_t querySize_, const uint8_t* parameters_, + uint8_t parameterCount_) : + querySize(querySize_), data(parameters_, parameterCount_) { + setLinks(); + } + +private: + CspPing(const CspPing &command); + void setLinks() { + setStart(&cspPort); + cspPort.setNext(&querySize); + querySize.setNext(&data); + } + SerializeElement cspPort = GOMSPACE::PING_PORT; + SerializeElement querySize; + SerializeElement> data; +}; + + +/** + * @brief A serial linked list adapter implementation of the gs_rparam_query_t + * struct defined in rparam.h. Can be used to build the message to set + * a parameter in gomspace devices. + * + * @note cspPort and querySize will not be sent with the CSP packet to the + * gomspace device but are required for the CspComIF to get the port + * and the size to query. + */ +class CspSetParamCommand : public SerialLinkedListAdapter { +public: + CspSetParamCommand(uint8_t action_, uint8_t tableId_, + uint16_t addresslength_, uint16_t checksum_, uint16_t seq_, + uint16_t total_, uint16_t addr_, const uint8_t* parameters_, + uint8_t parameterCount_) : + action(action_), tableId(tableId_), addresslength(addresslength_), checksum( + checksum_), seq(seq_), total(total_), addr(addr_), parameters( + parameters_, parameterCount_) { + setLinks(); + } + +private: + CspSetParamCommand(const CspSetParamCommand &command); + void setLinks() { + setStart(&cspPort); + cspPort.setNext(&querySize); + querySize.setNext(&action); + action.setNext(&tableId); + tableId.setNext(&addresslength); + addresslength.setNext(&checksum); + checksum.setNext(&seq); + seq.setNext(&addr); + addr.setNext(¶meters); + } + SerializeElement cspPort = GOMSPACE::PARAM_PORT; + /* Only parameters are set. No data will be queried with this command */ + SerializeElement querySize = 0; + SerializeElement action; + SerializeElement tableId; + SerializeElement addresslength; + SerializeElement checksum; + SerializeElement seq; + SerializeElement total; + SerializeElement addr; + SerializeElement> parameters; +}; + + +/** + * @brief This class can be used to generate a get param command for the + * gomspace devices which will be sent to the device communication + * interface object. + * + * @note cspPort and querySize only serve as information for the CspComIF + * and will not be transmitted physically to the target device. + */ +class CspGetParamCommand : public SerialLinkedListAdapter { +public: + + CspGetParamCommand(uint16_t querySize_, uint8_t action_, uint8_t tableId_, + uint16_t addresslength_, uint16_t checksum_, uint16_t seq_, + uint16_t total_, uint16_t addr_) : + querySize(querySize_), action(action_), tableId(tableId_), addresslength( + addresslength_), checksum(checksum_), seq(seq_), total( + total_), addr(addr_) { + fixedValuesInit(); + setLinks(); + } + +private: + CspGetParamCommand(const CspGetParamCommand &command); + void setLinks() { + setStart(&cspPort); + cspPort.setNext(&querySize); + querySize.setNext(&action); + action.setNext(&tableId); + tableId.setNext(&addresslength); + addresslength.setNext(&checksum); + checksum.setNext(&seq); + seq.setNext(&total); + total.setNext(&addr); + } + void fixedValuesInit(){ + cspPort.entry = GOMSPACE::PARAM_PORT; + } + SerializeElement cspPort; + SerializeElement querySize; // size of bytes to query + /* Following information will also be physically transmitted to the target + * device*/ + SerializeElement action; + SerializeElement tableId; + SerializeElement addresslength; // size of address + SerializeElement checksum; + SerializeElement seq; + SerializeElement total; + SerializeElement addr; +}; + + +/** + * @brief This class can be used to deserialize replies from gomspace devices + * and extract the relevant data. + */ +class CspGetParamReply : public SerialLinkedListAdapter { +public: + /* The size of the header of a gomspace CSP packet. */ + static const uint8_t GS_HDR_LENGTH = 12; + /** + * @brief Constructor + * + * @param payloadBuffer Pointer to a buffer to store the payload data of + * the CSP packet. + * @param payloadBufferSz The size of the payload buffer where the payload + * data will be stored. + */ + CspGetParamReply(uint8_t* payloadBuffer_, uint8_t payloadBufferSz_) : + payload(payloadBuffer_, payloadBufferSz_) { + setLinks(); + } + + uint8_t getAction(){ + return action; + } + + uint8_t getTableId(){ + return tableId; + } + + uint16_t getLength(){ + return length; + } + + uint16_t getAddress(){ + return addr; + } + +private: + CspGetParamReply(const CspGetParamReply &reply); + void setLinks() { + setStart(&action); + action.setNext(&tableId); + seq.setNext(&addr); + addr.setNext(&payload); + } + + SerializeElement action; + SerializeElement tableId; + SerializeElement length; //length of payload data + SerializeElement checksum; + SerializeElement seq; + SerializeElement total; + SerializeElement addr; + SerializeElement> payload; +}; + + +/** + * @brief This class generates telemetry packets containing data from + * CSP get-parameter-replies. + */ +class ParamReply : public SerialLinkedListAdapter { +public: + /** + * @brief Constructor + * + * @param payloadBuffer Pointer to a buffer to store the payload data of + * the CSP packet. + * @param payloadBufferSz The size of the payload buffer where the payload + * data will be stored. + */ + ParamReply(uint8_t action_, uint8_t tableId_, uint16_t addr_, + uint16_t length_, uint8_t* payloadBuffer_, uint8_t payloadBufferSz_) : + payload(payloadBuffer_, payloadBufferSz_) { + setLinks(); + } + +private: + ParamReply(const CspGetParamReply &reply); + void setLinks() { + setStart(&action); + action.setNext(&tableId); + tableId.setNext(&addr); + addr.setNext(&length); + length.setNext(&payload); + } + SerializeElement action; + SerializeElement tableId; + SerializeElement addr; + SerializeElement length; + SerializeElement> payload; +}; + + +/** + * @brief This class helps to unpack information from an action messages + * to set a parameter in gomspace devices. The action message can be + * for example received from the PUS Service 8. + */ +class SetParamMessageUnpacker: public SerialLinkedListAdapter { +public: + + SetParamMessageUnpacker(const uint8_t* commandData, size_t commandDataLen) { + SerializeAdapter::deSerialize(&tableId, &commandData, &commandDataLen, + SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&address, &commandData, &commandDataLen, + SerializeIF::Endianness::BIG); + parameterBuffer = commandData; + parameterCount = commandDataLen; + } + + uint8_t getTableId() const { + return tableId; + } + + uint16_t getAddress() const { + return address; + } + + const uint8_t* getParameters() { + return parameterBuffer; + } + + uint8_t getParameterCount(){ + return parameterCount; + } + + +private: + SetParamMessageUnpacker(const SetParamMessageUnpacker &message); + uint8_t tableId; + uint16_t address; + /* Parameter buffer holds the values of the parameters to set while the + * address points to the location of a parameter. */ + const uint8_t * parameterBuffer; + uint8_t parameterCount; +}; + + +/** + * @brief This class helps to unpack information from an action message + * to get a parameter from gomspace devices. The action message can be + * for example received from the PUS Service 8. + */ +class GetParamMessageUnpacker: public SerialLinkedListAdapter { +public: + + GetParamMessageUnpacker(const uint8_t* commandData, size_t commandDataLen) { + SerializeAdapter::deSerialize(&tableId, &commandData, &commandDataLen, + SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&address, &commandData, &commandDataLen, + SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&querySize, &commandData, &commandDataLen, + SerializeIF::Endianness::BIG); + } + + uint8_t getTableId() const { + return tableId; + } + + uint16_t getAddress() const { + return address; + } + + uint8_t getQuerySize(){ + return querySize; + } + + +private: + GetParamMessageUnpacker(const GetParamMessageUnpacker &message); + uint8_t tableId; + uint16_t address; //The memory address offset within the table + uint8_t querySize; //defines number of bytes to query +}; + + +#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEPACKETS_H_ */ diff --git a/mission/devices/devicedefinitions/P60DockHandlerDefinitions.h b/mission/devices/devicedefinitions/P60DockHandlerDefinitions.h index 001c7b76..756c52bd 100644 --- a/mission/devices/devicedefinitions/P60DockHandlerDefinitions.h +++ b/mission/devices/devicedefinitions/P60DockHandlerDefinitions.h @@ -53,6 +53,38 @@ // SerializeElement> filename; //}; +/** + * @brief A serial linked list adapter implementation of the gs_rparam_query_t struct + * defined in rparam.h + */ +class GetParamCommand: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 130 +public: + typedef uint16_t typeOfMaxDataSize; + static const uint16_t MAX_DATA_LENGTH = sizeof(typeOfMaxDataSize); + GetParamCommand(uint8_t objectId_, ActionId_t actionId_, + const uint8_t * replyDataBuffer_ = NULL, uint16_t replyDataSize_ = 0): + objectId(objectId_), actionId(actionId_), replyData(replyDataBuffer_,replyDataSize_){ + setLinks(); + } +private: + GetParamCommand(const GetParamCommand &reply); + void setLinks() { + setStart(&action); + action.setNext(&tableId); + tableId.setNext(&length); + lenght.setNext(&checksum); + checksum.setNext(&seq); + checksum.setNext(&addr); + } + SerializeElement cspPort = 7; + SerializeElement action; + SerializeElement tableId; + SerializeElement length; + SerializeElement checksum; + SerializeElement seq; + SerializeElement total; + SerializeElement addr; +}; #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_P60DOCKHANDLERDEFINITIONS_H_ */