diff --git a/fsfwconfig/returnvalues/classIds.h b/fsfwconfig/returnvalues/classIds.h index 419a24ef..c5e4d27a 100644 --- a/fsfwconfig/returnvalues/classIds.h +++ b/fsfwconfig/returnvalues/classIds.h @@ -16,7 +16,8 @@ enum { LINUX_LIBGPIO_IF, PCDU_HANDLER, HEATER_HANDLER, - SA_DEPL_HANDLER + SA_DEPL_HANDLER, + SYRLINKS_HANDLER, }; } diff --git a/mission/devices/SyrlinksHkHandler.cpp b/mission/devices/SyrlinksHkHandler.cpp index 8c1feff9..a13c0286 100644 --- a/mission/devices/SyrlinksHkHandler.cpp +++ b/mission/devices/SyrlinksHkHandler.cpp @@ -1,5 +1,6 @@ #include #include +#include SyrlinksHkHandler::SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie) : DeviceHandlerBase(objectId, comIF, comCookie), rxStatusRegistersSet(this) { @@ -84,46 +85,95 @@ void SyrlinksHkHandler::fillCommandAndReplyMap() { ReturnValue_t SyrlinksHkHandler::scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { + + ReturnValue_t result = RETURN_OK; + switch(rememberCommandId) { case(SYRLINKS::RESET_UNIT): - *foundId = SYRLINKS::RESET_UNIT; - *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; - rememberCommandId = SYRLINKS::NONE; + if (remainingSize != SYRLINKS::REQUEST_STATUS_REPLY_SIZE) { + result = REPLY_WRONG_SIZE; + break; + } + *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; + *foundId = SYRLINKS::RESET_UNIT; + rememberCommandId = SYRLINKS::NONE; break; case(SYRLINKS::SET_TX_MODE_STANDBY): - *foundId = SYRLINKS::SET_TX_MODE_STANDBY; - *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; - rememberCommandId = SYRLINKS::NONE; + if (remainingSize != SYRLINKS::REQUEST_STATUS_REPLY_SIZE) { + result = REPLY_WRONG_SIZE; + } + *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; + rememberCommandId = SYRLINKS::NONE; + *foundId = SYRLINKS::SET_TX_MODE_STANDBY; break; case(SYRLINKS::SET_TX_MODE_MODULATION): - *foundId = SYRLINKS::SET_TX_MODE_MODULATION; - *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; - rememberCommandId = SYRLINKS::NONE; + if (remainingSize != SYRLINKS::REQUEST_STATUS_REPLY_SIZE) { + result = REPLY_WRONG_SIZE; + } + *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; + *foundId = SYRLINKS::SET_TX_MODE_MODULATION; + rememberCommandId = SYRLINKS::NONE; break; case(SYRLINKS::SET_TX_MODE_CW): - *foundId = SYRLINKS::SET_TX_MODE_CW; - *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; - rememberCommandId = SYRLINKS::NONE; + if (remainingSize != SYRLINKS::REQUEST_STATUS_REPLY_SIZE) { + result = REPLY_WRONG_SIZE; + } + *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; + *foundId = SYRLINKS::SET_TX_MODE_CW; + rememberCommandId = SYRLINKS::NONE; break; case(SYRLINKS::READ_RX_STATUS_REGISTERS): - *foundId = SYRLINKS::READ_RX_STATUS_REGISTERS; - *foundLen = SYRLINKS::REQUEST_STATUS_REPLY_SIZE; - rememberCommandId = SYRLINKS::NONE; + if (remainingSize != SYRLINKS::RX_STATUS_REGISTERS_REPLY_SIZE) { + result = REPLY_WRONG_SIZE; + } + *foundLen = SYRLINKS::RX_STATUS_REGISTERS_REPLY_SIZE; + *foundId = SYRLINKS::READ_RX_STATUS_REGISTERS; + rememberCommandId = SYRLINKS::NONE; break; default: - return IGNORE_REPLY_DATA; + result = IGNORE_REPLY_DATA; + break; } - return HasReturnvaluesIF::RETURN_OK; + + if (result == REPLY_WRONG_SIZE) { + sif::debug << "SyrlinksHkHandler::scanForReply: Received reply with invalid length" + << std::endl; + return result; + } + + return result; } ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { - switch (id) { - case (SYRLINKS::RESET_UNIT): { - break; - } + ReturnValue_t result; + switch (id) { + case (SYRLINKS::RESET_UNIT): + case (SYRLINKS::SET_TX_MODE_STANDBY): + case (SYRLINKS::SET_TX_MODE_MODULATION): + case (SYRLINKS::SET_TX_MODE_CW): + result = verifyTansmissionStatusReply(packet); + if (result != RETURN_OK) { + sif::debug << "SyrlinksHkHandler::interpretDeviceReply: Status reply has invalid crc" + << std::endl; + return CRC_FAILURE; + } + result = parseReplyStatus(static_cast(packet + SYRLINKS::MESSAGE_HEADER_SIZE)); + if (result != RETURN_OK) { + return result; + } + break; + case(SYRLINKS::READ_RX_STATUS_REGISTERS): + result = verifyReadRxStatusRegistersReply(packet); + if (result != RETURN_OK) { + sif::debug << "SyrlinksHkHandler::interpretDeviceReply: Read rx status registers reply " + << "has invalid crc" << std::endl; + return CRC_FAILURE; + } + + break; default: { return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY; } @@ -132,6 +182,78 @@ ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, return HasReturnvaluesIF::RETURN_OK; } + +ReturnValue_t SyrlinksHkHandler::verifyTansmissionStatusReply() { + int result = 0; + uint16_t crc = CRC::crc16ccitt(packet, + SYRLINKS::REQUEST_STATUS_REPLY_SIZE - SYRLINKS::SIZE_CRC_AND_TERMINATION, + CRC_INITIAL_VALUE); + std::string recalculatedCrc = convertIntToHexString(crc); + const char* replyCrc = packet + SYRLINKS::REQUEST_STATUS_REPLY_SIZE + - SYRLINKS::SIZE_CRC_AND_TERMINATION; + size_t startPosition = 0; + result = recalculatedCrc.compare(startPosition, SYRLINKS_CRC_FIELD_SIZE, replyCrc); + if (result != 0) { + return RETURN_FAILED; + } + return RETURN_OK; +} + +std::string SyrlinksHkHandler::convertIntToHexString(uint16_t intValue) { + std::stringstream stream; + stream << std::hex << intValue; + return stream.str(); +} + +ReturnValue_t SyrlinksHkHandler::parseReplyStatus(char* status) { + switch (*status) { + case '0': + return RETURN_OK; + case '1': + sif::debug << "SyrlinksHkHandler::parseReplyStatus: Uart faming or parity error" + << std::endl; + return UART_FRAMIN_OR_PARITY_ERROR_ACK; + case '2': + sif::debug << "SyrlinksHkHandler::parseReplyStatus: Bad character detected" << std::endl; + return BAD_CHARACTER_ACK; + case '3': + sif::debug << "SyrlinksHkHandler::parseReplyStatus: Bad parameter value (unexpected value " + << "detected" << std::endl; + return BAD_PARAMETER_VALUE_ACK; + case '4': + sif::debug << "SyrlinksHkHandler::parseReplyStatus: Bad end of frame" << std::endl; + return BAD_END_OF_FRAME_ACK; + case '5': + sif::debug << "SyrlinksHkHandler::parseReplyStatus: Unknown command id or attempt to access" + << " a protected register" << std::endl; + return UNKNOWN_COMMAND_ID_ACK; + case '6': + sif::debug << "SyrlinksHkHandler::parseReplyStatus: Bad CRC" << std::endl; + return BAD_CRC_ACK; + default: + sif::debug << "SyrlinksHkHandler::parseReplyStatus: Status reply holds invalid status " + << "id" << std::endl; + return RETURN_FAILED; + } +} + +ReturnValue_t SyrlinksHkHandler::verifyReadRxStatusRegistersReply(uint8_t* packet) { + int result = 0; + /* Calculate crc of received packet */ + uint16_t crc = CRC::crc16ccitt(packet, + SYRLINKS::RX_STATUS_REGISTERS_REPLY_SIZE - SYRLINKS::SIZE_CRC_AND_TERMINATION, + CRC_INITIAL_VALUE); + std::string recalculatedCrc = convertIntToHexString(crc); + const char* replyCrc = packet + SYRLINKS::RX_STATUS_REGISTERS_REPLY_SIZE + - SYRLINKS::SIZE_CRC_AND_TERMINATION; + size_t startPosition = 0; + result = recalculatedCrc.compare(startPosition, SYRLINKS_CRC_FIELD_SIZE, replyCrc); + if (result != 0) { + return RETURN_FAILED; + } + return RETURN_OK; +} + void SyrlinksHkHandler::setNormalDatapoolEntriesInvalid(){ } diff --git a/mission/devices/SyrlinksHkHandler.h b/mission/devices/SyrlinksHkHandler.h index 55beec65..aefc99f9 100644 --- a/mission/devices/SyrlinksHkHandler.h +++ b/mission/devices/SyrlinksHkHandler.h @@ -39,6 +39,19 @@ protected: private: + static const uint8_t INTERFACE_ID = CLASS_ID::SYRLINKS_HANDLER; + + static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0); + static const ReturnValue_t UART_FRAMIN_OR_PARITY_ERROR_ACK = MAKE_RETURN_CODE(0xA1); + static const ReturnValue_t BAD_CHARACTER_ACK = MAKE_RETURN_CODE(0xA2); + static const ReturnValue_t BAD_PARAMETER_VALUE_ACK = MAKE_RETURN_CODE(0xA3); + static const ReturnValue_t BAD_END_OF_FRAME_ACK = MAKE_RETURN_CODE(0xA4); + static const ReturnValue_t UNKNOWN_COMMAND_ID_ACK = MAKE_RETURN_CODE(0xA5); + static const ReturnValue_t BAD_CRC_ACK = MAKE_RETURN_CODE(0xA6); + static const ReturnValue_t REPLY_WRONG_SIZE = MAKE_RETURN_CODE(0xA7); + + static const uint8_t CRC_INITIAL_VALUE = 0x0; + std::string resetCommand = ""; std::string readRxStatusRegCommand = ""; std::string setTxModeStandby = ""; @@ -51,10 +64,51 @@ private: static const uint8_t MAX_CMD_LEN = 3; uint8_t rememberRequestedSize = 0; - uint8_t rememberCommandId = TMP1075::NONE; + uint8_t rememberCommandId = SYRLINKS::NONE; uint8_t cmdBuffer[MAX_CMD_LEN]; CommunicationStep communicationStep = CommunicationStep::START_ADC_CONVERSION; + + + /** + * @brief This function verifies the checksum of a status reply packet of the syrlinks. + * + * @param packet Pointer to the received status reply. + * + * @return RETURN_OK if successful, otherwise RETURN_FAILURE. + * + * @details A status reply only contains one byte of payload data giving information about + * the transmission status. + */ + ReturnValue_t verifyTansmissionStatusReply(const uint8_t* packet); + + /** + * @brief This function converts an uint16_t into its hexadecimal string representation. + * + * @param The value to convert. + * + * @return An std::string object containing the hex representation of intValue. + */ + std::string SyrlinksHkHandler::convertIntToHexString(uint16_t intValue); + + /** + * @brief This function parses the status reply + * @param status Pointer to the status information. + * + * @details Some commands reply with a status message giving information about the preceding + * command transmission and/or execution was successful. + */ + ReturnValue_t parseReplyStatus(char* status); + + /** + * @brief Function verifies the received reply from the syrlinks by recalculating and + * comparing the crc. + * + * @param packet Pointer to the received reply. + * + * @return RETURN_OK if successful, otherwise RETURN_FAILED. + */ + ReturnValue_t verifyReadRxStatusRegistersReply(uint8_t* packet) }; #endif /* MISSION_DEVICES_SYRLINKSHKHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/SyrlinksDefinitions.h b/mission/devices/devicedefinitions/SyrlinksDefinitions.h index 3e50238b..2cd159af 100644 --- a/mission/devices/devicedefinitions/SyrlinksDefinitions.h +++ b/mission/devices/devicedefinitions/SyrlinksDefinitions.h @@ -24,6 +24,9 @@ namespace SYRLINKS { /** Size of a simple transmission success response */ static const uint8_t REQUEST_STATUS_REPLY_SIZE = 11; + static const uint8_t SIZE_CRC_AND_TERMINATION = 5; + /** The size of the header with the message identifier and the payload size field */ + static const uint8_t MESSAGE_HEADER_SIZE = 5; /** Size of reply to an rx status registers request */ static const uint8_t RX_STATUS_REGISTERS_REPLY_SIZE = 39;