eive-obsw/mission/power/GomspaceDeviceHandler.cpp

653 lines
25 KiB
C++
Raw Normal View History

2022-04-07 19:48:09 +02:00
#include <fsfw/datapool/PoolReadGuard.h>
2022-08-26 03:20:44 +02:00
#include <fsfw/globalfunctions/arrayprinter.h>
2023-03-26 16:13:54 +02:00
#include <mission/power/GomSpacePackets.h>
#include <mission/power/GomspaceDeviceHandler.h>
2023-03-26 16:16:54 +02:00
#include <mission/power/defs.h>
2022-08-26 14:28:06 +02:00
#include <cassert>
2022-09-16 12:28:39 +02:00
#include "eive/objects.h"
2020-12-20 13:31:44 +01:00
2022-08-25 18:19:33 +02:00
using namespace GOMSPACE;
2020-12-20 13:31:44 +01:00
GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF,
2022-08-26 14:28:06 +02:00
CookieIF* comCookie, TableConfig& tableConfig,
2023-03-26 15:28:00 +02:00
FailureIsolationBase* customFdir, bool enableHkSets)
: DeviceHandlerBase(objectId, comIF, comCookie, customFdir),
enableHkSets(enableHkSets),
tableCfg(tableConfig) {
2022-01-18 11:41:19 +01:00
if (comCookie == nullptr) {
sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid com cookie" << std::endl;
}
2020-12-20 13:31:44 +01:00
}
2022-08-26 14:28:06 +02:00
void GomspaceDeviceHandler::initPduConfigTable() {
tableCfg.maxConfigTableAddress = PDU::MAX_CONFIGTABLE_ADDRESS;
tableCfg.maxHkTableAddress = PDU::MAX_HKTABLE_ADDRESS;
tableCfg.hkTableSize = PDU::HK_TABLE_SIZE;
tableCfg.cfgTableSize = PDU::CONFIG_TABLE_SIZE;
}
2022-01-18 11:41:19 +01:00
GomspaceDeviceHandler::~GomspaceDeviceHandler() {}
2020-12-20 13:31:44 +01:00
2022-01-18 11:41:19 +01:00
void GomspaceDeviceHandler::doStartUp() {}
2020-12-20 13:31:44 +01:00
2022-01-18 11:41:19 +01:00
void GomspaceDeviceHandler::doShutDown() {}
2020-12-20 13:31:44 +01:00
2022-01-18 11:41:19 +01:00
ReturnValue_t GomspaceDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
2022-01-18 11:41:19 +01:00
ReturnValue_t GomspaceDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
2022-01-18 11:41:19 +01:00
ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
size_t commandDataLen) {
2022-09-01 11:04:24 +02:00
auto* cspCookie = dynamic_cast<CspCookie*>(comCookie);
cspCookie->setRequest(SpecialRequestTypes::DEFAULT_COM_IF, 0);
2022-01-19 17:10:51 +01:00
ReturnValue_t result = childCommandHook(deviceCommand, commandData, commandDataLen);
2022-01-18 11:41:19 +01:00
switch (deviceCommand) {
case (GOMSPACE::PING): {
result = generatePingCommand(commandData, commandDataLen);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
return result;
}
break;
2021-08-02 12:50:36 +02:00
}
2022-01-18 11:41:19 +01:00
case (GOMSPACE::REBOOT): {
generateRebootCommand();
break;
2021-08-02 12:50:36 +02:00
}
2022-01-18 11:41:19 +01:00
case (GOMSPACE::PARAM_SET): {
result = generateSetParamCommand(commandData, commandDataLen);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
return result;
}
break;
2021-08-02 12:50:36 +02:00
}
2022-01-18 11:41:19 +01:00
case (GOMSPACE::PARAM_GET): {
result = generateGetParamCommand(commandData, commandDataLen);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
return result;
}
break;
2021-08-02 12:50:36 +02:00
}
2022-01-18 11:41:19 +01:00
case (GOMSPACE::GNDWDT_RESET): {
result = generateResetWatchdogCmd();
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
return result;
}
break;
2021-08-02 12:50:36 +02:00
}
case (GOMSPACE::PRINT_SWITCH_V_I):
case (GOMSPACE::PRINT_LATCHUPS): {
2022-01-18 11:41:19 +01:00
result = printStatus(deviceCommand);
break;
2021-09-07 16:11:02 +02:00
}
2022-01-18 11:41:19 +01:00
case (GOMSPACE::REQUEST_HK_TABLE): {
2022-09-01 15:23:39 +02:00
DeviceType devType;
2022-09-14 16:47:58 +02:00
if (getDevType(devType) != returnvalue::OK) {
2022-09-01 15:23:39 +02:00
return returnvalue::FAILED;
}
2022-09-01 15:23:39 +02:00
result =
generateRequestFullHkTableCmd(devType, tableCfg.hkTableSize, deviceCommand, cspCookie);
if (result != returnvalue::OK) {
2022-08-25 18:19:33 +02:00
return result;
}
break;
}
case (GOMSPACE::REQUEST_CONFIG_TABLE): {
2022-09-01 15:23:39 +02:00
DeviceType devType;
2022-09-14 16:47:58 +02:00
if (getDevType(devType) != returnvalue::OK) {
2022-09-01 15:23:39 +02:00
return returnvalue::FAILED;
2022-08-26 14:28:06 +02:00
}
2022-09-14 16:47:58 +02:00
result =
generateRequestFullCfgTableCmd(devType, tableCfg.cfgTableSize, deviceCommand, cspCookie);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
return result;
}
break;
2021-08-02 12:50:36 +02:00
}
2022-09-01 17:31:43 +02:00
case (GOMSPACE::LOAD_TABLE): {
if (commandDataLen != 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
auto* info = reinterpret_cast<GOMSPACE::TableInfo*>(cspPacket);
info->sourceTable = commandData[0];
info->targetTable = commandData[1];
rawPacket = cspPacket;
rawPacketLen = sizeof(GOMSPACE::TableInfo);
cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM);
cspCookie->setRequest(SpecialRequestTypes::LOAD_TABLE, 0);
rememberCommandId = deviceCommand;
break;
}
2022-08-31 22:52:32 +02:00
case (GOMSPACE::SAVE_TABLE_FILE): {
2022-09-01 15:23:39 +02:00
if (commandDataLen > 2) {
2022-08-31 22:52:32 +02:00
return HasActionsIF::INVALID_PARAMETERS;
}
auto* info = reinterpret_cast<GOMSPACE::TableInfo*>(cspPacket);
2022-09-01 15:23:39 +02:00
if (commandData[0] != 0 and commandData[0] != 1 and commandData[0] != 2 and
commandData[0] != 4) {
2022-08-31 22:52:32 +02:00
return HasActionsIF::INVALID_PARAMETERS;
}
info->sourceTable = commandData[0];
if (info->sourceTable != 4) {
2022-09-01 15:23:39 +02:00
if (commandDataLen == 2) {
2022-08-31 22:52:32 +02:00
info->targetTable = commandData[1];
} else {
info->targetTable = info->sourceTable;
}
} else {
// Will be ignored, still set the value which is always used
info->targetTable = 4;
}
rawPacket = cspPacket;
rawPacketLen = sizeof(GOMSPACE::TableInfo);
2022-09-01 16:58:51 +02:00
cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM);
cspCookie->setRequest(SpecialRequestTypes::SAVE_TABLE, 0);
2022-08-31 22:52:32 +02:00
rememberCommandId = deviceCommand;
break;
}
case (GOMSPACE::SAVE_TABLE_DEFAULT): {
2022-09-01 15:23:39 +02:00
if (commandDataLen != 1) {
2022-08-31 22:52:32 +02:00
return HasActionsIF::INVALID_PARAMETERS;
}
auto* info = reinterpret_cast<GOMSPACE::TableInfo*>(cspPacket);
2022-09-01 15:23:39 +02:00
if (commandData[0] != 0 and commandData[0] != 1 and commandData[0] != 2) {
2022-08-31 22:52:32 +02:00
return HasActionsIF::INVALID_PARAMETERS;
}
info->sourceTable = commandData[0];
info->targetTable = info->sourceTable + 4;
rawPacket = cspPacket;
rawPacketLen = sizeof(GOMSPACE::TableInfo);
2022-09-01 16:58:51 +02:00
cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM);
cspCookie->setRequest(SpecialRequestTypes::SAVE_TABLE, 0);
2022-08-31 22:52:32 +02:00
rememberCommandId = deviceCommand;
break;
}
2021-08-02 12:50:36 +02:00
default:
2022-01-19 17:10:51 +01:00
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
2022-01-18 11:41:19 +01:00
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
2022-01-18 11:41:19 +01:00
void GomspaceDeviceHandler::fillCommandAndReplyMap() {
this->insertInCommandAndReplyMap(GOMSPACE::PING, 3);
this->insertInCommandMap(GOMSPACE::REBOOT);
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_SET, 3);
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_GET, 3);
this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_HK_TABLE, 3);
2022-08-27 01:02:08 +02:00
this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_CONFIG_TABLE, 3);
2022-01-18 11:41:19 +01:00
this->insertInCommandMap(GOMSPACE::GNDWDT_RESET);
this->insertInCommandMap(GOMSPACE::PRINT_SWITCH_V_I);
this->insertInCommandMap(GOMSPACE::PRINT_LATCHUPS);
2022-08-31 22:52:32 +02:00
insertInCommandMap(GOMSPACE::SAVE_TABLE_FILE);
insertInCommandMap(GOMSPACE::SAVE_TABLE_DEFAULT);
2022-09-01 17:31:43 +02:00
insertInCommandMap(GOMSPACE::LOAD_TABLE);
2020-12-20 13:31:44 +01:00
}
2022-01-18 11:41:19 +01:00
ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
switch (rememberCommandId) {
case (GOMSPACE::PING):
*foundId = GOMSPACE::PING;
*foundLen = PING_REPLY_SIZE;
rememberCommandId = GOMSPACE::NONE;
break;
case (GOMSPACE::PARAM_GET): {
*foundId = GOMSPACE::PARAM_GET;
*foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH;
rememberCommandId = GOMSPACE::NONE;
break;
}
case (GOMSPACE::PARAM_SET): {
*foundId = GOMSPACE::PARAM_SET;
*foundLen = rememberRequestedSize;
rememberCommandId = GOMSPACE::NONE;
break;
}
2022-08-27 01:02:08 +02:00
case (GOMSPACE::REQUEST_HK_TABLE):
case (GOMSPACE::REQUEST_CONFIG_TABLE): {
if (remainingSize < rememberRequestedSize) {
sif::error << "GomspaceDeviceHandler::scanForReply: Table reply, received data smaller "
"than expected "
<< rememberRequestedSize << std::endl;
return returnvalue::FAILED;
}
*foundId = rememberCommandId;
*foundLen = rememberRequestedSize;
2022-01-18 11:41:19 +01:00
rememberCommandId = GOMSPACE::NONE;
break;
2021-08-02 12:50:36 +02:00
}
default:
2022-01-18 11:41:19 +01:00
return IGNORE_REPLY_DATA;
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
2022-01-18 11:41:19 +01:00
const uint8_t* packet) {
switch (id) {
case (GOMSPACE::PING): {
SerializeElement<uint32_t> replyTime = *packet;
2022-08-30 23:54:05 +02:00
handleDeviceTm(replyTime, true);
2022-01-18 11:41:19 +01:00
break;
}
case (GOMSPACE::PARAM_GET): {
// -2 to subtract address size from gomspace parameter reply packet
uint16_t payloadLength = (*(packet + 2) << 8 | *(packet + 3)) - 2;
if (payloadLength > sizeof(uint32_t)) {
sif::error << "GomspaceDeviceHandler: PARAM_GET: Invalid payload "
<< "size in reply" << std::endl;
return INVALID_PAYLOAD_SIZE;
}
uint8_t tempPayloadBuffer[payloadLength];
/* Extract information from received data */
CspGetParamReply cspGetParamReply(tempPayloadBuffer, payloadLength);
size_t size = GOMSPACE::GS_HDR_LENGTH + payloadLength;
ReturnValue_t result =
cspGetParamReply.deSerialize(&packet, &size, SerializeIF::Endianness::BIG);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Failed to deserialize get parameter"
<< "reply" << std::endl;
return result;
}
uint8_t action = cspGetParamReply.getAction();
uint8_t tableId = cspGetParamReply.getTableId();
uint16_t address = cspGetParamReply.getAddress();
/* Pack relevant information into a tm packet */
ParamReply paramReply(action, tableId, address, payloadLength, tempPayloadBuffer);
2022-08-30 23:54:05 +02:00
handleDeviceTm(paramReply, id, true);
2022-01-18 11:41:19 +01:00
break;
}
case (GOMSPACE::PARAM_SET): {
/* When setting a parameter, the p60dock sends back the state of the
* operation */
if (*packet != PARAM_SET_OK) {
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-01-18 11:41:19 +01:00
}
2022-01-19 18:51:44 +01:00
setParamCallback(setParamCacher, true);
2022-01-18 11:41:19 +01:00
break;
}
case (GOMSPACE::REQUEST_HK_TABLE): {
letChildHandleHkReply(id, packet);
break;
2021-08-02 12:50:36 +02:00
}
2022-08-27 01:02:08 +02:00
case (GOMSPACE::REQUEST_CONFIG_TABLE): {
letChildHandleConfigReply(id, packet);
break;
}
2021-08-02 12:50:36 +02:00
default:
2022-01-18 11:41:19 +01:00
break;
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
2022-01-18 11:41:19 +01:00
void GomspaceDeviceHandler::setNormalDatapoolEntriesInvalid() {}
2020-12-20 13:31:44 +01:00
2022-01-18 11:41:19 +01:00
ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* commandData,
size_t commandDataLen) {
2022-01-26 17:59:31 +01:00
ReturnValue_t result =
setParamCacher.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG);
// This breaks layering but I really don't want to accept this command..
if (setParamCacher.getAddress() == PDU2::CONFIG_ADDRESS_OUT_EN_Q7S and
this->getObjectId() == objects::PDU2_HANDLER) {
triggerEvent(power::SWITCHING_Q7S_DENIED, 0, 0);
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
}
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter "
"message"
<< std::endl;
return result;
}
2022-01-19 18:51:44 +01:00
result = setParamCallback(setParamCacher, false);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-19 17:10:51 +01:00
return result;
}
2022-01-18 11:41:19 +01:00
/* Get and check address */
2022-01-19 18:51:44 +01:00
uint16_t address = setParamCacher.getAddress();
2022-08-26 14:28:06 +02:00
if (address > tableCfg.maxConfigTableAddress) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Invalid address for set parameter "
<< "action" << std::endl;
return INVALID_ADDRESS;
}
/* CSP reply only contains the transaction state */
uint16_t querySize = 1;
2022-01-19 18:51:44 +01:00
const uint8_t* parameterPtr = setParamCacher.getParameter();
uint8_t parameterSize = setParamCacher.getParameterSize();
2022-01-18 11:41:19 +01:00
uint16_t payloadlength = sizeof(address) + parameterSize;
2020-12-20 13:31:44 +01:00
2022-01-18 11:41:19 +01:00
/* Generate command for CspComIF */
2022-08-26 00:39:06 +02:00
CspSetParamCommand setParamCmd(querySize, payloadlength, address, parameterPtr, parameterSize);
2022-01-18 11:41:19 +01:00
size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket;
result = setParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
SerializeIF::Endianness::BIG);
2020-12-20 13:31:44 +01:00
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Failed to serialize command for "
<< "CspComIF" << std::endl;
return result;
}
if (cspPacketLen > MAX_PACKET_LEN) {
sif::error << "GomspaceDeviceHandler: Invalid length of set parameter "
"command"
<< std::endl;
return PACKET_TOO_LONG;
}
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
rememberRequestedSize = querySize;
rememberCommandId = GOMSPACE::PARAM_SET;
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
2022-01-18 11:41:19 +01:00
ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(const uint8_t* commandData,
size_t commandDataLen) {
ReturnValue_t result;
/* Unpack the received action message */
GetParamMessageUnpacker getParamMessage;
result = getParamMessage.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
sif::error << "Failed to deserialize message to extract information "
"from get parameter message"
<< std::endl;
return result;
}
/* Get an check table id to read from */
uint8_t tableId = getParamMessage.getTableId();
2022-08-26 00:39:06 +02:00
if (not validTableId(tableId)) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Invalid table id in get parameter"
" message"
<< std::endl;
return INVALID_TABLE_ID;
}
/* Get and check address */
uint16_t address = getParamMessage.getAddress();
2022-08-26 14:28:06 +02:00
if (address > tableCfg.maxHkTableAddress and tableId == TableIds::HK) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from "
<< "housekeeping table" << std::endl;
return INVALID_ADDRESS;
}
2022-08-26 14:28:06 +02:00
if (address > tableCfg.maxConfigTableAddress and tableId == TableIds::CONFIG) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from "
<< "configuration table" << std::endl;
return INVALID_ADDRESS;
}
uint16_t length = sizeof(address);
uint8_t parameterSize = getParamMessage.getParameterSize();
if (parameterSize > sizeof(uint32_t)) {
sif::error << "GomspaceDeviceHandler: GET_PARAM: Invalid parameter "
<< "size" << std::endl;
return INVALID_PARAM_SIZE;
}
uint16_t querySize = parameterSize + GOMSPACE::GS_HDR_LENGTH;
2020-12-20 13:31:44 +01:00
2022-01-18 11:41:19 +01:00
/* Generate the CSP command to send to the P60 Dock */
2022-08-25 18:19:33 +02:00
CspGetParamCommand getParamCmd(querySize, tableId, length, address);
2022-01-18 11:41:19 +01:00
size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket;
result = getParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
SerializeIF::Endianness::BIG);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Failed to serialize command to "
<< "get parameter" << std::endl;
}
if (cspPacketLen > MAX_PACKET_LEN) {
sif::error << "GomspaceDeviceHandler: Received invalid get parameter "
"command"
<< std::endl;
return PACKET_TOO_LONG;
}
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
rememberRequestedSize = querySize;
rememberCommandId = GOMSPACE::PARAM_GET;
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
2022-01-18 11:41:19 +01:00
ReturnValue_t GomspaceDeviceHandler::generatePingCommand(const uint8_t* commandData,
size_t commandDataLen) {
CspPingCommand cspPingCommand(commandData, commandDataLen);
size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket;
ReturnValue_t result = cspPingCommand.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
SerializeIF::Endianness::BIG);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Failed to serialize ping command" << std::endl;
return result;
}
if (cspPacketLen > MAX_PACKET_LEN) {
sif::error << "GomspaceDeviceHandler: Received invalid ping message" << std::endl;
return PACKET_TOO_LONG;
}
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
rememberCommandId = GOMSPACE::PING;
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
2022-01-18 11:41:19 +01:00
void GomspaceDeviceHandler::generateRebootCommand() {
uint8_t cspPort = GOMSPACE::REBOOT_PORT;
uint16_t querySize = 0;
*cspPacket = GOMSPACE::REBOOT_PORT;
*(cspPacket + 1) = querySize;
size_t cspPacketLen = sizeof(cspPort) + sizeof(cspPacketLen);
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
2020-12-20 13:31:44 +01:00
}
2022-01-19 17:10:51 +01:00
ReturnValue_t GomspaceDeviceHandler::childCommandHook(DeviceCommandId_t cmd,
const uint8_t* commandData,
size_t commandDataLen) {
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
2022-01-19 18:51:44 +01:00
ReturnValue_t GomspaceDeviceHandler::setParamCallback(SetParamMessageUnpacker& unpacker,
2022-01-26 17:59:31 +01:00
bool afterExecution) {
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-01-19 17:10:51 +01:00
}
2022-04-07 19:48:09 +02:00
ReturnValue_t GomspaceDeviceHandler::initializePduPool(
localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager,
std::array<uint8_t, PDU::CHANNELS_LEN> initOutEnb) {
2022-08-27 01:02:08 +02:00
using namespace PDU;
localDataPoolMap.emplace(pool::PDU_CURRENTS, new PoolEntry<int16_t>(9));
localDataPoolMap.emplace(pool::PDU_VOLTAGES, new PoolEntry<int16_t>(9));
2022-04-07 19:48:09 +02:00
2022-08-27 01:02:08 +02:00
localDataPoolMap.emplace(pool::PDU_VCC, new PoolEntry<int16_t>({0}));
localDataPoolMap.emplace(pool::PDU_VBAT, new PoolEntry<int16_t>({0}));
localDataPoolMap.emplace(pool::PDU_TEMPERATURE, new PoolEntry<float>({0}));
localDataPoolMap.emplace(pool::PDU_CONV_EN, new PoolEntry<uint8_t>(3));
2022-04-07 19:48:09 +02:00
2022-08-27 01:02:08 +02:00
localDataPoolMap.emplace(pool::PDU_OUT_ENABLE,
2022-04-07 19:48:09 +02:00
new PoolEntry<uint8_t>(initOutEnb.data(), initOutEnb.size()));
2022-08-27 01:02:08 +02:00
localDataPoolMap.emplace(pool::PDU_BOOTCAUSE, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_BOOTCNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_UPTIME, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_RESETCAUSE, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(pool::PDU_BATT_MODE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(pool::PDU_LATCHUPS, new PoolEntry<uint16_t>(9));
localDataPoolMap.emplace(pool::PDU_DEVICES, new PoolEntry<uint8_t>(8));
localDataPoolMap.emplace(pool::PDU_STATUSES, new PoolEntry<uint8_t>(8));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_GND, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_I2C, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_CAN, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_CSP1, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_CSP2, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_I2C_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CAN_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CSP_LEFT1, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CSP_LEFT2, new PoolEntry<uint8_t>({0}));
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-04-07 19:48:09 +02:00
}
2022-08-25 18:19:33 +02:00
bool GomspaceDeviceHandler::validTableId(uint8_t id) {
if (id == TableIds::CONFIG or id == TableIds::BOARD_PARAMS or id == TableIds::CALIBRATION or
id == TableIds::HK) {
return true;
}
return false;
}
2022-09-01 15:23:39 +02:00
ReturnValue_t GomspaceDeviceHandler::getDevType(GOMSPACE::DeviceType& type) const {
if (getObjectId() == objects::PDU1_HANDLER or getObjectId() == objects::PDU2_HANDLER) {
type = DeviceType::PDU;
} else if (getObjectId() == objects::ACU_HANDLER) {
type = DeviceType::ACU;
} else if (getObjectId() == objects::P60DOCK_HANDLER) {
type = DeviceType::P60DOCK;
} else {
return returnvalue::FAILED;
}
return returnvalue::OK;
}
2022-01-18 11:41:19 +01:00
ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() {
WatchdogResetCommand watchdogResetCommand;
size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket;
ReturnValue_t result = watchdogResetCommand.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
SerializeIF::Endianness::BIG);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-18 11:41:19 +01:00
sif::error << "GomspaceDeviceHandler: Failed to serialize watchdog reset "
<< "command" << std::endl;
return result;
}
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
rememberRequestedSize = 0; // No bytes will be queried with the ground
// watchdog command.
rememberCommandId = GOMSPACE::GNDWDT_RESET;
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2020-12-20 13:31:44 +01:00
}
2020-12-27 17:31:38 +01:00
2022-09-01 15:23:39 +02:00
ReturnValue_t GomspaceDeviceHandler::generateRequestFullHkTableCmd(DeviceType dev,
uint16_t tableReplySize,
DeviceCommandId_t id,
CspCookie* cspCookie) {
if (dev == DeviceType::ACU) {
cspCookie->setRequest(SpecialRequestTypes::GET_ACU_HK, tableReplySize);
} else if (dev == DeviceType::P60DOCK) {
cspCookie->setRequest(SpecialRequestTypes::GET_P60DOCK_HK, tableReplySize);
} else if (dev == DeviceType::PDU) {
cspCookie->setRequest(SpecialRequestTypes::GET_PDU_HK, tableReplySize);
2022-01-18 11:41:19 +01:00
}
2022-08-26 14:28:06 +02:00
cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM);
2022-09-01 15:23:39 +02:00
rememberRequestedSize = tableReplySize;
rememberCommandId = id;
return returnvalue::OK;
}
ReturnValue_t GomspaceDeviceHandler::generateRequestFullCfgTableCmd(DeviceType dev,
uint16_t tableReplySize,
DeviceCommandId_t id,
CspCookie* cspCookie) {
if (dev == DeviceType::ACU) {
cspCookie->setRequest(SpecialRequestTypes::GET_ACU_CONFIG, tableReplySize);
} else if (dev == DeviceType::P60DOCK) {
cspCookie->setRequest(SpecialRequestTypes::GET_P60DOCK_CONFIG, tableReplySize);
} else if (dev == DeviceType::PDU) {
cspCookie->setRequest(SpecialRequestTypes::GET_PDU_CONFIG, tableReplySize);
}
cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM);
// Unfortunately, this does not work..
// cspPacket[0] = defaultTable;
// rawPacket = cspPacket;
// rawPacketLen = 1;
rememberRequestedSize = tableReplySize;
2022-08-27 01:02:08 +02:00
rememberCommandId = id;
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2021-01-28 14:55:21 +01:00
}
2022-01-18 11:41:19 +01:00
uint32_t GomspaceDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 0; }
2021-02-03 19:35:55 +01:00
2022-11-03 10:24:55 +01:00
void GomspaceDeviceHandler::setModeNormal() { setMode(_MODE_TO_NORMAL); }
2021-09-07 16:11:02 +02:00
ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) {
2022-01-18 11:41:19 +01:00
sif::info << "No printHkTable implementation given.." << std::endl;
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2021-09-07 16:11:02 +02:00
}
2022-04-07 19:48:09 +02:00
ReturnValue_t GomspaceDeviceHandler::parsePduHkTable(PDU::PduCoreHk& coreHk, PDU::PduAuxHk& auxHk,
const uint8_t* packet) {
PoolReadGuard pg0(&coreHk);
PoolReadGuard pg1(&auxHk);
2022-08-26 14:28:06 +02:00
if (pg0.getReadResult() != returnvalue::OK or pg1.getReadResult() != returnvalue::OK) {
2022-04-07 19:48:09 +02:00
sif::warning << "Reading PDU1 datasets failed!" << std::endl;
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-04-07 19:48:09 +02:00
}
/* Fist 10 bytes contain the gomspace header. Each variable is preceded by the 16-bit table
* address. */
2022-08-26 14:28:06 +02:00
// dataOffset += 12;
2022-04-07 19:48:09 +02:00
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
2022-08-26 03:20:44 +02:00
coreHk.currents[idx] = as<int16_t>(packet + (idx * 2));
2022-04-07 19:48:09 +02:00
}
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
2022-08-26 14:28:06 +02:00
coreHk.voltages[idx] = as<uint16_t>(packet + 0x12 + (idx * 2));
2022-04-07 19:48:09 +02:00
}
2023-05-31 10:39:56 +02:00
coreHk.vcc.value = as<int16_t>(packet + 0x24);
coreHk.vbat.value = as<int16_t>(packet + 0x26);
2022-08-26 03:20:44 +02:00
coreHk.temperature = as<int16_t>(packet + 0x28) * 0.1;
2022-04-07 19:48:09 +02:00
2022-04-12 16:36:04 +02:00
for (uint8_t idx = 0; idx < 3; idx++) {
2022-08-26 03:20:44 +02:00
auxHk.converterEnable[idx] = packet[0x2a + idx];
2022-04-12 16:36:04 +02:00
}
2022-04-07 19:48:09 +02:00
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
2022-08-26 03:20:44 +02:00
coreHk.outputEnables[idx] = packet[0x2e + idx];
}
auxHk.bootcause = as<uint32_t>(packet + 0x38);
coreHk.bootcount = as<uint32_t>(packet + 0x3c);
auxHk.uptime = as<uint32_t>(packet + 0x40);
auxHk.resetcause = as<uint16_t>(packet + 0x44);
coreHk.battMode = *(packet + 0x46);
2022-04-07 19:48:09 +02:00
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
2022-08-26 14:28:06 +02:00
auxHk.latchups[idx] = as<uint16_t>(packet + 0x48 + (idx * 2));
2022-04-07 19:48:09 +02:00
}
for (uint8_t idx = 0; idx < PDU::DEVICES_NUM; idx++) {
2022-08-26 03:20:44 +02:00
auxHk.deviceTypes[idx] = *(packet + 0x5a + idx);
2022-04-07 19:48:09 +02:00
}
for (uint8_t idx = 0; idx < PDU::DEVICES_NUM; idx++) {
2022-08-26 03:20:44 +02:00
auxHk.devicesStatus[idx] = *(packet + 0x62 + idx);
}
auxHk.gndWdtReboots = as<uint32_t>(packet + 0x6c);
auxHk.i2cWdtReboots = as<uint32_t>(packet + 0x70);
auxHk.canWdtReboots = as<uint32_t>(packet + 0x74);
auxHk.csp1WdtReboots = as<uint32_t>(packet + 0x78);
auxHk.csp2WdtReboots = as<uint32_t>(packet + 0x78 + 4);
auxHk.groundWatchdogSecondsLeft = as<uint32_t>(packet + 0x80);
auxHk.i2cWatchdogSecondsLeft = as<uint32_t>(packet + 0x84);
auxHk.canWatchdogSecondsLeft = as<uint32_t>(packet + 0x88);
auxHk.csp1WatchdogPingsLeft = *(packet + 0x8c);
auxHk.csp2WatchdogPingsLeft = *(packet + 0x8c + 1);
2022-04-07 19:48:09 +02:00
coreHk.setChanged(true);
if (not coreHk.isValid()) {
coreHk.setValidity(true, true);
}
if (not auxHk.isValid()) {
auxHk.setValidity(true, true);
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-04-07 19:48:09 +02:00
}
2023-04-04 14:45:09 +02:00
ReturnValue_t GomspaceDeviceHandler::setHealth(HealthState health) {
2023-04-04 14:52:22 +02:00
if (health != HealthState::HEALTHY and health != HealthState::EXTERNAL_CONTROL and
2023-04-04 14:45:09 +02:00
health != HealthState::NEEDS_RECOVERY) {
return returnvalue::FAILED;
}
return returnvalue::OK;
}