wip CspComIF
This commit is contained in:
parent
c502ee1172
commit
551a8f021b
167
bsp_linux/comIF/CspComIF.cpp
Normal file
167
bsp_linux/comIF/CspComIF.cpp
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#include "CspComIF.h"
|
||||||
|
#include <bsp_linux/comIF/cookies/CspCookie.h>
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
#include <csp/drivers/can_socketcan.h>
|
||||||
|
#include <fsfw/serialize/SerializeAdapter.h>
|
||||||
|
|
||||||
|
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<CspCookie*>(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<CspCookie*> (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<CspCookie*> (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;
|
||||||
|
}
|
66
bsp_linux/comIF/CspComIF.h
Normal file
66
bsp_linux/comIF/CspComIF.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#ifndef BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_
|
||||||
|
#define BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_
|
||||||
|
|
||||||
|
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||||
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <csp/csp.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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<uint8_t>;
|
||||||
|
using VectorBufferMap = std::unordered_map<node_t, vectorBuffer>;
|
||||||
|
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_ */
|
24
bsp_linux/comIF/cookies/CspCookie.cpp
Normal file
24
bsp_linux/comIF/cookies/CspCookie.cpp
Normal file
@ -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;
|
||||||
|
}
|
31
bsp_linux/comIF/cookies/CspCookie.h
Normal file
31
bsp_linux/comIF/cookies/CspCookie.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef BSP_LINUX_COMIF_COOKIES_CSPCOOKIE_H_
|
||||||
|
#define BSP_LINUX_COMIF_COOKIES_CSPCOOKIE_H_
|
||||||
|
|
||||||
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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_ */
|
@ -21,8 +21,8 @@
|
|||||||
#include <fsfw/timemanager/TimeStamper.h>
|
#include <fsfw/timemanager/TimeStamper.h>
|
||||||
#include <mission/utility/TmFunnel.h>
|
#include <mission/utility/TmFunnel.h>
|
||||||
#include <mission/devices/P60DockHandler.h>
|
#include <mission/devices/P60DockHandler.h>
|
||||||
#include <bsp_linux/comIF/cookies/P60DockCookie.h>
|
#include <bsp_linux/comIF/cookies/CspCookie.h>
|
||||||
#include <bsp_linux/comIF/P60DockComIF.h>
|
#include <bsp_linux/comIF/CspComIF.h>
|
||||||
|
|
||||||
#if ADD_TEST_CODE == 1
|
#if ADD_TEST_CODE == 1
|
||||||
//#include <test/testtasks/TestTask.h>
|
//#include <test/testtasks/TestTask.h>
|
||||||
@ -86,14 +86,15 @@ void ObjectFactory::produceGenericObjects() {
|
|||||||
apid::EIVE_OBSW, pus::PUS_SERVICE_200);
|
apid::EIVE_OBSW, pus::PUS_SERVICE_200);
|
||||||
|
|
||||||
/* Cookies */
|
/* Cookies */
|
||||||
P60DockCookie* p60DockCookie = new P60DockCookie(addresses::P60DOCK);
|
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH,
|
||||||
|
addresses::P60DOCK);
|
||||||
|
|
||||||
/* Communication interfaces */
|
/* Communication interfaces */
|
||||||
new P60DockComIF(objects::P60_DOCK_COM_IF);
|
new CspComIF(objects::P60_DOCK_COM_IF);
|
||||||
|
|
||||||
/* Device Handler */
|
/* Device Handler */
|
||||||
new P60DockHandler(objects::P60DOCK_HANDLER, objects::P60_DOCK_COM_IF,
|
new P60DockHandler(objects::P60DOCK_HANDLER, objects::P60_DOCK_COM_IF,
|
||||||
p60DockCookie);
|
p60DockCspCookie);
|
||||||
|
|
||||||
/* Test Device Handler */
|
/* Test Device Handler */
|
||||||
#if ADD_TEST_CODE == 1
|
#if ADD_TEST_CODE == 1
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
#include <csp/csp.h>
|
|
||||||
#include <csp/interfaces/csp_if_can.h>
|
|
||||||
#include <mission/devices/P60DockHandler.h>
|
#include <mission/devices/P60DockHandler.h>
|
||||||
#include "bsp_linux/comIF/cookies/P60DockCookie.h"
|
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
|
||||||
#include "bsp_linux/comIF/P60DockComIF.h"
|
|
||||||
|
|
||||||
P60DockHandler::P60DockHandler(object_id_t objectId, object_id_t comIF,
|
P60DockHandler::P60DockHandler(object_id_t objectId, object_id_t comIF,
|
||||||
CookieIF * comCookie):DeviceHandlerBase(objectId, comIF, comCookie) {
|
CookieIF * comCookie):DeviceHandlerBase(objectId, comIF, comCookie) {
|
||||||
@ -10,10 +7,6 @@ P60DockHandler::P60DockHandler(object_id_t objectId, object_id_t comIF,
|
|||||||
if(comCookie == NULL){
|
if(comCookie == NULL){
|
||||||
sif::error << "P60DockHandler invalid com cookie" << std::endl;
|
sif::error << "P60DockHandler invalid com cookie" << std::endl;
|
||||||
}
|
}
|
||||||
p60DockCookie = dynamic_cast<P60DockCookie*> (comCookie);
|
|
||||||
if(p60DockCookie == NULL){
|
|
||||||
sif::error << "P60DockHandler failed to get P60DockCookie" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
P60DockHandler::~P60DockHandler() {
|
P60DockHandler::~P60DockHandler() {
|
||||||
@ -41,15 +34,39 @@ ReturnValue_t P60DockHandler::buildCommandFromCommand(
|
|||||||
size_t commandDataLen) {
|
size_t commandDataLen) {
|
||||||
switch(deviceCommand) {
|
switch(deviceCommand) {
|
||||||
case(PING): {
|
case(PING): {
|
||||||
p60DockCookie->setPingMessage();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(READ_MODULE_CFG):{
|
case(PARAM_SET):{
|
||||||
p60DockCookie->setReadModuleCfgMessage();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(READ_HK):{
|
case(PARAM_GET):{
|
||||||
p60DockCookie->setReadHkMessage();
|
/* Unpack the received action message */
|
||||||
|
GetParamMessageUnpacker getParamMessage(commandData, commandDataLen);
|
||||||
|
uint8_t tableId = getParamMessage.getTableId();
|
||||||
|
uint16_t address = getParamMessage.getAddress();
|
||||||
|
uint16_t length = EndianConverter::convertLittleEndian<uint16_t>(
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -60,44 +77,51 @@ ReturnValue_t P60DockHandler::buildCommandFromCommand(
|
|||||||
|
|
||||||
void P60DockHandler::fillCommandAndReplyMap(){
|
void P60DockHandler::fillCommandAndReplyMap(){
|
||||||
this->insertInCommandAndReplyMap(PING, 3);
|
this->insertInCommandAndReplyMap(PING, 3);
|
||||||
this->insertInCommandAndReplyMap(READ_MODULE_CFG, 3);
|
this->insertInCommandAndReplyMap(PARAM_SET, 3);
|
||||||
this->insertInCommandAndReplyMap(READ_HK, 3);
|
this->insertInCommandAndReplyMap(PARAM_GET, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t P60DockHandler::scanForReply(const uint8_t *start,
|
ReturnValue_t P60DockHandler::scanForReply(const uint8_t *start,
|
||||||
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
|
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||||
MessageType_t messageType = p60DockCookie->getMessageType();
|
switch(rememberCommandId) {
|
||||||
switch(messageType) {
|
|
||||||
case(PING):
|
case(PING):
|
||||||
*foundId = PING;
|
*foundId = PING;
|
||||||
*foundLen = 4;
|
*foundLen = rememberRequestedSize;
|
||||||
|
rememberCommandId = NONE;
|
||||||
break;
|
break;
|
||||||
case(READ_MODULE_CFG): {
|
case(PARAM_GET): {
|
||||||
*foundId = READ_MODULE_CFG;
|
*foundId = PARAM_GET;
|
||||||
*foundLen = moduleCfgTableSize;
|
*foundLen = rememberRequestedSize + CspGetParamReply::GS_HDR_LENGTH;
|
||||||
break;
|
rememberCommandId = NONE;
|
||||||
}
|
|
||||||
case(READ_HK): {
|
|
||||||
*foundId = READ_HK;
|
|
||||||
*foundLen = hkTableSize;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return IGNORE_REPLY_DATA;
|
return IGNORE_REPLY_DATA;
|
||||||
}
|
}
|
||||||
p60DockCookie->resetMessageType();
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t P60DockHandler::interpretDeviceReply(DeviceCommandId_t id,
|
ReturnValue_t P60DockHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||||
const uint8_t *packet) {
|
const uint8_t *packet) {
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case(READ_MODULE_CFG): {
|
case(PING): {
|
||||||
handleDeviceTM((SerializeIF*)packet, id, true, true);
|
handleDeviceTM((SerializeIF*)packet, id, true, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(READ_HK): {
|
case(PARAM_GET): {
|
||||||
handleDeviceTM((SerializeIF*)packet, id, true, true);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
#include <bsp_linux/comIF/cookies/P60DockCookie.h>
|
#include <bsp_linux/comIF/cookies/P60DockCookie.h>
|
||||||
|
|
||||||
|
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 {
|
class P60DockHandler: public DeviceHandlerBase {
|
||||||
public:
|
public:
|
||||||
P60DockHandler(object_id_t objectId, object_id_t comIF,
|
P60DockHandler(object_id_t objectId, object_id_t comIF,
|
||||||
@ -26,15 +33,16 @@ protected:
|
|||||||
|
|
||||||
private:
|
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 PING = 0x1; //!< [EXPORT] : [COMMAND]
|
||||||
static const DeviceCommandId_t READ_MODULE_CFG = 0x71; //!< [EXPORT] : [COMMAND]
|
static const DeviceCommandId_t NONE = 0x2; // Set when no command is pending
|
||||||
static const DeviceCommandId_t READ_HK = 0x72; //!< [EXPORT] : [COMMAND]
|
static const DeviceCommandId_t PARAM_GET = 0x00; //!< [EXPORT] : [COMMAND]
|
||||||
|
static const DeviceCommandId_t PARAM_SET = 0xFF; //!< [EXPORT] : [COMMAND]
|
||||||
|
|
||||||
uint16_t moduleCfgTableSize = 412;
|
uint8_t rememberRequestedSize = 0;
|
||||||
uint8_t calibrationTableSize = 174;
|
uint8_t rememberCommandId = NONE;
|
||||||
uint8_t hkTableSize = 188;
|
uint8_t cspPacket[MAX_PACKET_LEN];
|
||||||
|
|
||||||
P60DockCookie* p60DockCookie;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_P60DOCKHANDLER_H_ */
|
#endif /* MISSION_DEVICES_P60DOCKHANDLER_H_ */
|
||||||
|
332
mission/devices/devicedefinitions/GomSpacePackets.h
Normal file
332
mission/devices/devicedefinitions/GomSpacePackets.h
Normal file
@ -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<SerializeIF> {
|
||||||
|
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<uint8_t> cspPort = GOMSPACE::PING_PORT;
|
||||||
|
SerializeElement<uint16_t> querySize;
|
||||||
|
SerializeElement<SerialBufferAdapter<uint8_t>> 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<SerializeIF> {
|
||||||
|
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<uint8_t> cspPort = GOMSPACE::PARAM_PORT;
|
||||||
|
/* Only parameters are set. No data will be queried with this command */
|
||||||
|
SerializeElement<uint16_t> querySize = 0;
|
||||||
|
SerializeElement<uint8_t> action;
|
||||||
|
SerializeElement<uint8_t> tableId;
|
||||||
|
SerializeElement<uint16_t> addresslength;
|
||||||
|
SerializeElement<uint16_t> checksum;
|
||||||
|
SerializeElement<uint16_t> seq;
|
||||||
|
SerializeElement<uint16_t> total;
|
||||||
|
SerializeElement<uint16_t> addr;
|
||||||
|
SerializeElement<SerialBufferAdapter<uint8_t>> 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<SerializeIF> {
|
||||||
|
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<uint8_t> cspPort;
|
||||||
|
SerializeElement<uint16_t> querySize; // size of bytes to query
|
||||||
|
/* Following information will also be physically transmitted to the target
|
||||||
|
* device*/
|
||||||
|
SerializeElement<uint8_t> action;
|
||||||
|
SerializeElement<uint8_t> tableId;
|
||||||
|
SerializeElement<uint16_t> addresslength; // size of address
|
||||||
|
SerializeElement<uint16_t> checksum;
|
||||||
|
SerializeElement<uint16_t> seq;
|
||||||
|
SerializeElement<uint16_t> total;
|
||||||
|
SerializeElement<uint16_t> addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class can be used to deserialize replies from gomspace devices
|
||||||
|
* and extract the relevant data.
|
||||||
|
*/
|
||||||
|
class CspGetParamReply : public SerialLinkedListAdapter<SerializeIF> {
|
||||||
|
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<uint8_t> action;
|
||||||
|
SerializeElement<uint8_t> tableId;
|
||||||
|
SerializeElement<uint16_t> length; //length of payload data
|
||||||
|
SerializeElement<uint16_t> checksum;
|
||||||
|
SerializeElement<uint16_t> seq;
|
||||||
|
SerializeElement<uint16_t> total;
|
||||||
|
SerializeElement<uint16_t> addr;
|
||||||
|
SerializeElement<SerialBufferAdapter<uint8_t>> payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class generates telemetry packets containing data from
|
||||||
|
* CSP get-parameter-replies.
|
||||||
|
*/
|
||||||
|
class ParamReply : public SerialLinkedListAdapter<SerializeIF> {
|
||||||
|
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<uint8_t> action;
|
||||||
|
SerializeElement<uint8_t> tableId;
|
||||||
|
SerializeElement<uint16_t> addr;
|
||||||
|
SerializeElement<uint16_t> length;
|
||||||
|
SerializeElement<SerialBufferAdapter<uint8_t>> 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<SerializeIF> {
|
||||||
|
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<SerializeIF> {
|
||||||
|
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_ */
|
@ -53,6 +53,38 @@
|
|||||||
// SerializeElement<SerialFixedArrayListAdapter<dataBufferType, FN_MAXNAME, typeOfMaxData>> filename;
|
// SerializeElement<SerialFixedArrayListAdapter<dataBufferType, FN_MAXNAME, typeOfMaxData>> filename;
|
||||||
//};
|
//};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A serial linked list adapter implementation of the gs_rparam_query_t struct
|
||||||
|
* defined in rparam.h
|
||||||
|
*/
|
||||||
|
class GetParamCommand: public SerialLinkedListAdapter<SerializeIF> { //!< [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<uint8_t> cspPort = 7;
|
||||||
|
SerializeElement<uint8_t> action;
|
||||||
|
SerializeElement<uint8_t> tableId;
|
||||||
|
SerializeElement<uint16_t> length;
|
||||||
|
SerializeElement<uint16_t> checksum;
|
||||||
|
SerializeElement<uint16_t> seq;
|
||||||
|
SerializeElement<uint16_t> total;
|
||||||
|
SerializeElement<uint16_t> addr;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_P60DOCKHANDLERDEFINITIONS_H_ */
|
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_P60DOCKHANDLERDEFINITIONS_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user