From 14dec1d7007ffd8ac787c34cfe5461cbefbf8015 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 23 Dec 2021 18:33:31 +0100 Subject: [PATCH] checksum command --- .../startracker/StarTrackerDefinitions.h | 73 +++++++++++++++++ .../startracker/StarTrackerHandler.cpp | 82 ++++++++++++++++++- .../devices/startracker/StarTrackerHandler.h | 32 ++++++++ bsp_q7s/devices/startracker/StrHelper.h | 4 +- 4 files changed, 187 insertions(+), 4 deletions(-) diff --git a/bsp_q7s/devices/startracker/StarTrackerDefinitions.h b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h index a66b16e7..1efa0bc7 100644 --- a/bsp_q7s/devices/startracker/StarTrackerDefinitions.h +++ b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h @@ -846,6 +846,79 @@ public: sif::info << "ContrastSet::printSet: BinD8: " << this->binD8 << std::endl; } }; + +/** + * @brief Helper Class to extract information from bytestream. + */ +class ChecksumReply { +public: + + /** + * @brief Constructor + * + * @param datafield Pointer to datafield in reply buffer + * + */ + ChecksumReply(const uint8_t* datafield) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + region = *(datafield); + const uint8_t* addressData = datafield + ADDRESS_OFFSET; + size_t size = sizeof(address); + result = SerializeAdapter::deSerialize(&address, &addressData, &size, + SerializeIF::Endianness::LITTLE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize address" + << std::endl; + } + const uint8_t* lengthData = datafield + LENGTH_OFFSET; + size = sizeof(length); + result = SerializeAdapter::deSerialize(&length, &lengthData, &size, + SerializeIF::Endianness::LITTLE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize length" + << std::endl; + } + const uint8_t* checksumData = datafield + CHECKSUM_OFFSET; + size = sizeof(checksum); + result = SerializeAdapter::deSerialize(&checksum, &checksumData, &size, + SerializeIF::Endianness::LITTLE); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "ChecksumReply::ChecksumReply: Failed to deserialize checksum" + << std::endl; + } + } + + uint8_t getRegion() { + return region; + } + + uint32_t getAddress() { + return address; + } + + uint32_t getLength() { + return length; + } + + uint32_t getChecksum() { + return checksum; + } + + void printChecksum() { + sif::info << "ChecksumReply::printChecksum: 0x" << checksum << std::endl; + } + +private: + + static const uint8_t ADDRESS_OFFSET = 1; + static const uint8_t LENGTH_OFFSET = 5; + static const uint8_t CHECKSUM_OFFSET = 9; + + uint8_t region = 0; + uint32_t address = 0; + uint32_t length = 0; + uint32_t checksum = 0; +}; } #endif /* MISSION_STARTRACKER_DEFINITIONS_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp index 9b97b422..7ae5d72c 100644 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp @@ -420,6 +420,10 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi result = prepareUnlockCommand(commandData, commandDataLen); return result; } + case (StarTracker::CHECKSUM): { + result = prepareChecksumCommand(commandData, commandDataLen); + return result; + } default: return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } @@ -480,6 +484,8 @@ void StarTrackerHandler::fillCommandAndReplyMap() { StarTracker::MAX_FRAME_SIZE * 2 + 2); this->insertInCommandAndReplyMap(StarTracker::UNLOCK, 3, nullptr, StarTracker::MAX_FRAME_SIZE * 2 + 2); + this->insertInCommandAndReplyMap(StarTracker::CHECKSUM, 3, nullptr, + StarTracker::MAX_FRAME_SIZE * 2 + 2); } ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize, @@ -555,6 +561,10 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con result = handleActionReply(); break; } + case (StarTracker::CHECKSUM): { + result = handleChecksumReply(); + break; + } case (StarTracker::REQ_VERSION): { result = handleTm(versionSet, StarTracker::VersionSet::SIZE); if (result != RETURN_OK) { @@ -834,6 +844,10 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) *foundId = StarTracker::UNLOCK; break; } + case (StarTracker::ID::CHECKSUM): { + *foundId = StarTracker::CHECKSUM; + break; + } default: sif::warning << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id" << std::endl; @@ -970,7 +984,7 @@ ReturnValue_t StarTrackerHandler::executeWriteCommand(const uint8_t* commandData size_t size = sizeof(address); const uint8_t* addressPtr = commandData + WriteCmd::ADDRESS_OFFSET; result = SerializeAdapter::deSerialize(&address, addressPtr, &size, - SerializeIF::Endianness::LITTLE); + SerializeIF::Endianness::BIG); if (result != RETURN_OK) { sif::debug << "StarTrackerHandler::executeWriteCommand: Deserialization of address failed" << std::endl; @@ -1003,7 +1017,7 @@ ReturnValue_t StarTrackerHandler::executeReadCommand(const uint8_t* commandData, size_t size = sizeof(address); const uint8_t* addressPtr = commandData + ReadCmd::ADDRESS_OFFSET; result = SerializeAdapter::deSerialize(&address, addressPtr, &size, - SerializeIF::Endianness::LITTLE); + SerializeIF::Endianness::BIG); if (result != RETURN_OK) { sif::debug << "StarTrackerHandler::executeReadCommand: Deserialization of address failed" << std::endl; @@ -1062,6 +1076,44 @@ ReturnValue_t StarTrackerHandler::prepareUnlockCommand(const uint8_t* commandDat return result; } +ReturnValue_t StarTrackerHandler::prepareChecksumCommand(const uint8_t* commandData, + size_t commandDataLen) { + struct ChecksumActionRequest req; + ReturnValue_t result = RETURN_OK; + if (commandDataLen != ChecksumCmd::LENGTH) { + sif::warning << "StarTrackerHandler::prepareChecksumCommand: Invalid length" << std::endl; + return INVALID_LENGTH; + } + req.region = *(commandData); + size_t size = sizeof(req.address); + const uint8_t* addressPtr = commandData + ChecksumCmd::ADDRESS_OFFSET; + result = SerializeAdapter::deSerialize(&req.address, addressPtr, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::prepareChecksumCommand: Deserialization of address " + << "failed" << std::endl; + return result; + } + size = sizeof(req.length); + const uint8_t* lengthPtr = commandData + ChecksumCmd::LENGTH_OFFSET; + result = SerializeAdapter::deSerialize(&req.length, lengthPtr, &size, + SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::prepareChecksumCommand: Deserialization of length failed" + << std::endl; + return result; + } + uint32_t rawCmdLength = 0; + arc_pack_checksum_action_req(&req, commandBuffer, &rawCmdLength); + dataLinkLayer.encodeFrame(commandBuffer, rawCmdLength); + rawPacket = dataLinkLayer.getEncodedFrame(); + rawPacketLen = dataLinkLayer.getEncodedLength(); + checksumCmd.rememberRegion = req.region; + checksumCmd.rememberAddress = req.address; + checksumCmd.rememberLength = req.length; + return result; +} + void StarTrackerHandler::prepareTimeRequest() { uint32_t length = 0; arc_tm_pack_time_req(commandBuffer, &length); @@ -1240,6 +1292,32 @@ ReturnValue_t StarTrackerHandler::handleActionReply() { return RETURN_OK; } +ReturnValue_t StarTrackerHandler::handleChecksumReply() { + ReturnValue_t result = RETURN_OK; + result = handleActionReply(); + if (result != RETURN_OK) { + return result; + } + const uint8_t* replyData = dataLinkLayer.getReply() + ACTION_DATA_OFFSET; + StarTracker::ChecksumReply checksumReply(replyData); + if (checksumReply.getRegion() != checksumCmd.rememberRegion) { + sif::warning << "StarTrackerHandler::handleChecksumReply: Region mismatch" << std::endl; + return REGION_MISMATCH; + } + if (checksumReply.getAddress() != checksumCmd.rememberAddress) { + sif::warning << "StarTrackerHandler::handleChecksumReply: Address mismatch" << std::endl; + return ADDRESS_MISMATCH; + } + if (checksumReply.getLength() != checksumCmd.rememberLength) { + sif::warning << "StarTrackerHandler::handleChecksumReply: Length mismatch" << std::endl; + return LENGTH_MISSMATCH; + } +#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 + checksumReply.printChecksum(); +#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */ + return RETURN_OK; +} + ReturnValue_t StarTrackerHandler::handlePingReply() { ReturnValue_t result = RETURN_OK; uint32_t pingId = 0; diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.h b/bsp_q7s/devices/startracker/StarTrackerHandler.h index 16b00d3b..095105b3 100644 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.h +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.h @@ -117,6 +117,14 @@ private: static const ReturnValue_t CONTRAST_REQ_FAILED = MAKE_RETURN_CODE(0xAE); //! [EXPORT] : [COMMENT] Received command which is too short (some data is missing for proper execution) static const ReturnValue_t COMMAND_TOO_SHORT = MAKE_RETURN_CODE(0xAF); + //! [EXPORT] : [COMMENT] Received command with invalid length (too few or too many parameters) + static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xB0); + //! [EXPORT] : [COMMENT] Region mismatch between send and received data + static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xB1); + //! [EXPORT] : [COMMENT] Address mismatch between send and received data + static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xB2); + //! [EXPORT] : [COMMENT] Length field mismatch between send and received data + static const ReturnValue_t lENGTH_MISMATCH = MAKE_RETURN_CODE(0xB3); static const size_t MAX_PATH_SIZE = 50; static const size_t MAX_FILE_NAME = 30; @@ -161,6 +169,20 @@ private: static const uint8_t CODE_OFFSET = 1; }; + class ChecksumCmd { + public: + static const uint8_t ADDRESS_OFFSET = 1; + static const uint8_t LENGTH_OFFSET = 5; + // Length of checksum command + static const size_t LENGTH = 9; + + uint8_t rememberRegion = 0; + uint32_t rememberAddress = 0; + uint32_t rememberLength = 0; + }; + + ChecksumCmd checksumCmd; + MessageQueueIF* eventQueue = nullptr; ArcsecDatalinkLayer dataLinkLayer; @@ -281,6 +303,11 @@ private: */ ReturnValue_t prepareUnlockCommand(const uint8_t* commandData, size_t commandDataLen); + /** + * @brief Fills command buffer with command to get the checksum of a flash part + */ + ReturnValue_t prepareChecksumCommand(const uint8_t* commandData, size_t commandDataLen); + /** * @brief Fills the command buffer with the command to take an image. */ @@ -354,6 +381,11 @@ private: */ ReturnValue_t handleActionReply(); + /** + * @brief Handles reply to checksum command + */ + ReturnValue_t handleChecksumReply(); + /** * @brief Handles all set parameter replies */ diff --git a/bsp_q7s/devices/startracker/StrHelper.h b/bsp_q7s/devices/startracker/StrHelper.h index ff2f3ca6..372c2abd 100644 --- a/bsp_q7s/devices/startracker/StrHelper.h +++ b/bsp_q7s/devices/startracker/StrHelper.h @@ -194,9 +194,9 @@ private: std::string flashReadPath = ""; // Default name of downloaded image, can be changed via command - std::string downloadImage = "image"; + std::string downloadImage = "image.bin"; // Default name of file containing the data read from flash, can be changed via command - std::string flashReadFile = "flashread"; + std::string flashReadFile = "flashread.bin"; // Will be set with the flash write command uint8_t flashWriteRegion = 0; // Will be set with the flash write command and specifies the start address where to write the