fix in image upload function

This commit is contained in:
Jakob Meier 2021-12-09 15:02:58 +01:00
parent e64a3fb645
commit 1895d7c3db
5 changed files with 167 additions and 68 deletions

View File

@ -90,10 +90,15 @@ static const DeviceCommandId_t BOOT = 1;
static const DeviceCommandId_t REQ_VERSION = 2;
static const DeviceCommandId_t REQ_INTERFACE = 3;
static const DeviceCommandId_t REQ_TIME = 4;
static const DeviceCommandId_t ERASE = 5;
static const DeviceCommandId_t UNLOCK = 6;
static const DeviceCommandId_t REBOOT = 7;
static const DeviceCommandId_t DOWNLOAD_IMAGE = 9;
static const DeviceCommandId_t UPLOAD_IMAGE = 10;
static const DeviceCommandId_t REQ_POWER = 11;
static const DeviceCommandId_t TAKE_IMAGE = 15;
static const DeviceCommandId_t DOWNLOAD_CENTROID = 16;
static const DeviceCommandId_t UPLOAD_CENTROID = 17;
static const DeviceCommandId_t SUBSCRIBE_TO_TM = 18;
static const DeviceCommandId_t REQ_SOLUTION = 24;
static const DeviceCommandId_t REQ_TEMPERATURE = 25;
@ -107,6 +112,11 @@ static const DeviceCommandId_t MATCHING = 46;
static const DeviceCommandId_t TRACKING = 47;
static const DeviceCommandId_t VALIDATION = 48;
static const DeviceCommandId_t ALGO = 49;
static const DeviceCommandId_t CHECKSUM = 50;
static const DeviceCommandId_t READ = 51;
static const DeviceCommandId_t WRITE = 52;
static const DeviceCommandId_t DOWNLOAD_MATCHED_STAR = 53;
static const DeviceCommandId_t DOWNLOAD_DB_IMAGE = 54;
static const DeviceCommandId_t NONE = 0xFFFFFFFF;
static const uint32_t VERSION_SET_ID = REQ_VERSION;
@ -149,6 +159,12 @@ namespace ID {
static const uint8_t SOLUTION = 24;
static const uint8_t TEMPERATURE = 25;
static const uint8_t TIME = 1;
static const uint8_t WRITE = 2;
static const uint8_t READ = 3;
static const uint8_t CHECKSUM = 4;
static const uint8_t ERASE = 5;
static const uint8_t UNLOCK = 6;
static const uint8_t TAKE_IMAGE = 15;
}
/**

View File

@ -86,7 +86,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
return EXECUTION_FINISHED;
}
case(StarTracker::DOWNLOAD_IMAGE): {
strImageLoader->startImageDownload();
strImageLoader->startImageDownload(std::string(reinterpret_cast<const char*>(data), size));
imageLoaderExecuting = true;
return EXECUTION_FINISHED;
}
@ -167,12 +167,6 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
prepareInterfaceRequest();
return RETURN_OK;
}
case (StarTracker::UPLOAD_IMAGE): {
std::string uploadImage = std::string(reinterpret_cast<const char*>(commandData),
commandDataLen);
strImageLoader->startImageUpload(uploadImage);
return result;
}
case (StarTracker::REQ_POWER): {
preparePowerRequest();
return RETURN_OK;
@ -181,6 +175,10 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
prepareRebootCommand();
return RETURN_OK;
}
case (StarTracker::TAKE_IMAGE): {
prepareTakeImageCommand();
return RETURN_OK;
}
case (StarTracker::SUBSCRIBE_TO_TM): {
prepareSubscriptionCommand(commandData);
return RETURN_OK;
@ -261,6 +259,7 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
this->insertInCommandAndReplyMap(StarTracker::REQ_TIME, 3, &timeSet,
StarTracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandMap(StarTracker::UPLOAD_IMAGE);
this->insertInCommandMap(StarTracker::DOWNLOAD_IMAGE);
this->insertInCommandAndReplyMap(StarTracker::REQ_POWER, 3, &powerSet,
StarTracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(StarTracker::REQ_INTERFACE, 3, &interfaceSet,
@ -293,6 +292,8 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
StarTracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(StarTracker::ALGO, 3, nullptr,
StarTracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(StarTracker::TAKE_IMAGE, 3, nullptr,
StarTracker::MAX_FRAME_SIZE * 2 + 2);
}
ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize,
@ -365,6 +366,10 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con
result = handleActionReply();
break;
}
case (StarTracker::TAKE_IMAGE): {
result = handleActionReply();
break;
}
case (StarTracker::REQ_VERSION): {
result = handleVersionTm();
break;
@ -522,6 +527,10 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId)
*foundId = StarTracker::BOOT;
break;
}
case (StarTracker::ID::TAKE_IMAGE): {
*foundId = StarTracker::TAKE_IMAGE;
break;
}
case (StarTracker::ID::UPLOAD_IMAGE): {
*foundId = StarTracker::UPLOAD_IMAGE;
break;
@ -701,6 +710,15 @@ void StarTrackerHandler::prepareRebootCommand() {
rawPacketLen = dataLinkLayer.getEncodedLength();
}
void StarTrackerHandler::prepareTakeImageCommand() {
uint32_t length = 0;
struct CameraActionRequest camReq;
arc_pack_camera_action_req(&camReq, commandBuffer, &length);
dataLinkLayer.encodeFrame(commandBuffer, length);
rawPacket = dataLinkLayer.getEncodedFrame();
rawPacketLen = dataLinkLayer.getEncodedLength();
}
void StarTrackerHandler::prepareSubscriptionCommand(const uint8_t* tmId) {
uint32_t length = 18;
commandBuffer[0] = TMTC_SETPARAMREQ;

View File

@ -183,6 +183,11 @@ private:
*/
void prepareBootCommand();
/**
* @brief Fills the command buffer with the command to take an image.
*/
void prepareTakeImageCommand();
/**
* @brief Fills command buffer with data to request the version telemetry packet
*/

View File

@ -37,6 +37,11 @@ ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) {
break;
}
case InternalState::DOWNLOAD_IMAGE:
result = performImageDownload();
if (result == RETURN_OK){
triggerEvent(IMAGE_DOWNLOAD_SUCCESSFUL);
}
internalState = InternalState::IDLE;
break;
}
}
@ -51,7 +56,6 @@ void StrImageLoader::setComCookie(CookieIF* comCookie_) {
}
ReturnValue_t StrImageLoader::startImageUpload(std::string image) {
// Check if file is stored on SD card and if associated SD card is mounted
if (image.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT))
== std::string(SdCardManager::SD_0_MOUNT_POINT)) {
@ -66,31 +70,58 @@ ReturnValue_t StrImageLoader::startImageUpload(std::string image) {
return SD_NOT_MOUNTED;
}
}
uploadImage = image;
if(not std::filesystem::exists(uploadImage)) {
return FILE_NOT_EXISTS;
}
internalState = InternalState::UPLOAD_IMAGE;
semaphore.release();
return RETURN_OK;
}
ReturnValue_t StrImageLoader::startImageDownload() {
void StrImageLoader::startImageDownload(std::string downloadImage_) {
downloadImage = downloadImage_;
internalState = InternalState::DOWNLOAD_IMAGE;
semaphore.release();
}
ReturnValue_t StrImageLoader::performImageDownload() {
ReturnValue_t result;
struct DownloadActionRequest downloadReq;
uint32_t size = 0;
std::ofstream file(downloadImage, std::ios_base::app | std::ios_base::out);
while(downloadReq.position < LAST_POSITION) {
arc_pack_download_action_req(&downloadReq, commandBuffer, &size);
result = sendAndRead(size, downloadReq.position);
if (result != RETURN_OK) {
file.close();
return result;
}
result = checkReply();
if (result != RETURN_OK) {
file.close();
return result;
}
result = checkReplyPosition(downloadReq.position);
if (result != RETURN_OK) {
file.close();
return result;
}
file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + DATA_OFFSET),
IMAGE_DATA_SIZE);
downloadReq.position++;
}
file.close();
return RETURN_OK;
}
ReturnValue_t StrImageLoader::performImageUpload() {
ReturnValue_t result = RETURN_OK;
uint32_t size = 0;
uint32_t imageSize = 0;
struct UploadActionRequest uploadReq;
uploadReq.position = 0;
std::memset(&uploadReq.data, 0, sizeof(uploadReq.data));
if (not std::filesystem::exists(uploadImage)) {
triggerEvent(IMAGE_FILE_NOT_EXISTS, uploadReq.position);
internalState = InternalState::IDLE;
@ -101,57 +132,51 @@ ReturnValue_t StrImageLoader::performImageUpload() {
file.seekg(0, file.end);
// tellg returns position of character in input stream
imageSize = file.tellg();
// Set position of next character to beginning of file input stream
file.seekg(0, file.beg);
if (imageSize >= SIZE_IMAGE_PART) {
while((uploadReq.position + 1) * SIZE_IMAGE_PART < imageSize) {
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
file.read(reinterpret_cast<char*>(uploadReq.data), SIZE_IMAGE_PART);
}
else {
file.read(reinterpret_cast<char*>(uploadReq.data), imageSize);
}
while(uploadReq.position * SIZE_IMAGE_PART < imageSize) {
result = uploadSendAndRead(&uploadReq);
arc_pack_upload_action_req(&uploadReq, commandBuffer, &size);
result = sendAndRead(size, uploadReq.position);
if (result != RETURN_OK) {
return RETURN_FAILED;
}
result = checkUploadReply();
result = checkReply();
if (result != RETURN_OK) {
return result;
}
uploadReq.position++;
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
}
std::memset(uploadReq.data, 0, sizeof(uploadReq.data));
uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART;
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
file.close();
uploadReq.position++;
result = uploadSendAndRead(&uploadReq);
arc_pack_upload_action_req(&uploadReq, commandBuffer, &size);
result = sendAndRead(size, uploadReq.position);
if (result != RETURN_OK) {
return RETURN_FAILED;
}
result = checkUploadReply();
result = checkReply();
if (result != RETURN_OK) {
return result;
}
return RETURN_OK;
}
ReturnValue_t StrImageLoader::uploadSendAndRead(struct UploadActionRequest* uploadReq) {
ReturnValue_t StrImageLoader::sendAndRead(size_t size, uint32_t position) {
ReturnValue_t result = RETURN_OK;
ReturnValue_t decResult = RETURN_OK;
size_t receivedDataLen = 0;
uint8_t *receivedData = nullptr;
size_t bytesLeft = 0;
uint32_t size = 0;
uint32_t missedReplies = 0;
arc_pack_upload_action_req(uploadReq, commandBuffer, &size);
datalinkLayer.encodeFrame(commandBuffer, size);
result = communicationInterface->sendMessage(comCookie, datalinkLayer.getEncodedFrame(),
datalinkLayer.getEncodedLength());
if (result != RETURN_OK) {
sif::warning << "StrImageLoader::uploadImage: Failed to send upload packet" << std::endl;
triggerEvent(SENDING_UPLOAD_PACKET_FAILED, result, uploadReq->position);
sif::warning << "StrImageLoader::sendAndRead: Failed to send packet" << std::endl;
triggerEvent(IMG_LOADER_SENDING_PACKET_FAILED, result, position);
return RETURN_FAILED;
}
decResult = ArcsecDatalinkLayer::DEC_IN_PROGRESS;
@ -159,14 +184,14 @@ ReturnValue_t StrImageLoader::uploadSendAndRead(struct UploadActionRequest* uplo
result = communicationInterface->requestReceiveMessage(comCookie,
StarTracker::MAX_FRAME_SIZE * 2 + 2);
if (result != RETURN_OK) {
sif::warning << "StrImageLoader::uploadImage: Failed to request reply" << std::endl;
triggerEvent(UPLOAD_REQUESTING_MSG_FAILED, result, uploadReq->position);
sif::warning << "StrImageLoader::sendAndRead: Failed to request reply" << std::endl;
triggerEvent(IMG_LOADER_REQUESTING_MSG_FAILED, result, position);
return RETURN_FAILED;
}
result = communicationInterface->readReceivedMessage(comCookie, &receivedData, &receivedDataLen);
if (result != RETURN_OK) {
sif::warning << "StrImageLoader::uploadImage: Failed to read received message" << std::endl;
triggerEvent(UPLOAD_READING_REPLY_FAILED, result, uploadReq->position);
sif::warning << "StrImageLoader::sendAndRead: Failed to read received message" << std::endl;
triggerEvent(IMG_LOADER_READING_REPLY_FAILED, result, position);
return RETURN_FAILED;
}
if (receivedDataLen == 0 && missedReplies < MAX_POLLS) {
@ -174,7 +199,7 @@ ReturnValue_t StrImageLoader::uploadSendAndRead(struct UploadActionRequest* uplo
continue;
}
else if ((receivedDataLen == 0) && (missedReplies >= MAX_POLLS)) {
triggerEvent(NO_REPLY, uploadReq->position);
triggerEvent(IMG_LOADER_NO_REPLY, position);
return RETURN_FAILED;
}
else {
@ -183,22 +208,22 @@ ReturnValue_t StrImageLoader::uploadSendAndRead(struct UploadActionRequest* uplo
decResult = datalinkLayer.decodeFrame(receivedData, receivedDataLen, &bytesLeft);
if (bytesLeft != 0) {
// This should never happen
sif::warning << "StrImageLoader::uploadSendAndRead: Bytes left after decoding" << std::endl;
triggerEvent(UPLOAD_COM_ERROR, result, uploadReq->position);
sif::warning << "StrImageLoader::sendAndRead: Bytes left after decoding" << std::endl;
triggerEvent(IMG_LOADER_COM_ERROR, result, position);
return RETURN_FAILED;
}
}
if (decResult != RETURN_OK) {
triggerEvent(DEC_ERROR, decResult, uploadReq->position);
triggerEvent(IMG_LOADER_DEC_ERROR, decResult, position);
return RETURN_FAILED;
}
return RETURN_OK;
}
ReturnValue_t StrImageLoader::checkUploadReply() {
ReturnValue_t StrImageLoader::checkReply() {
uint8_t type = datalinkLayer.getReplyFrameType();
if (type != TMTC_ACTIONREPLY) {
sif::warning << "StrImageLoader::checkUploadReply: Received invalid upload reply"
sif::warning << "StrImageLoader::checkUploadReply: Received reply with invalid type ID"
<< std::endl;
triggerEvent(INVALID_TYPE_ID);
return RETURN_FAILED;
@ -211,3 +236,13 @@ ReturnValue_t StrImageLoader::checkUploadReply() {
}
return RETURN_OK;
}
ReturnValue_t StrImageLoader::checkReplyPosition(uint32_t expectedPosition) {
uint32_t receivedPosition = 0;
std::memcpy(&receivedPosition, datalinkLayer.getReply() + POS_OFFSET, sizeof(receivedPosition));
if (receivedPosition != expectedPosition) {
triggerEvent(POSITION_MISMATCH, receivedPosition);
return RETURN_FAILED;
}
return RETURN_OK;
}

View File

@ -29,35 +29,40 @@ public:
//! [EXPORT] : [COMMENT] Try to upload image but specified image does not exist
static const Event IMAGE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW);
//! [EXPORT] : [COMMENT] Sending image upload packet to star tracker failed
//! [EXPORT] : [COMMENT] Sending packet (download or upload) to star tracker failed
//!P1: Return code of communication interface sendMessage function
//!P2: Position of upload packet for which the transmission failed
static const Event SENDING_UPLOAD_PACKET_FAILED = MAKE_EVENT(1, severity::LOW);
//!P2: Position of upload/download packet for which the transmission failed
static const Event IMG_LOADER_SENDING_PACKET_FAILED = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] Communication interface requesting reply failed
//!P1: Return code of failed request
//!P1: Upload position for which the request failed
static const Event UPLOAD_REQUESTING_MSG_FAILED = MAKE_EVENT(2, severity::LOW);
//!P1: Upload/download position for which the request failed
static const Event IMG_LOADER_REQUESTING_MSG_FAILED = MAKE_EVENT(2, severity::LOW);
//! [EXPORT] : [COMMENT] Uploading image to star tracker was successful
static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] Failed to read communication interface reply data
//!P1: Return code of failed communication interface read call
//!P1: Upload position for which the read call failed
static const Event UPLOAD_READING_REPLY_FAILED = MAKE_EVENT(4, severity::LOW);
//!P1: Upload/download position for which the read call failed
static const Event IMG_LOADER_READING_REPLY_FAILED = MAKE_EVENT(4, severity::LOW);
//! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence
//!P1: Return code of failed communication interface read call
//!P1: Upload position for which the read call failed
static const Event UPLOAD_COM_ERROR = MAKE_EVENT(5, severity::LOW);
//!P1: Upload/download position for which the read call failed
static const Event IMG_LOADER_COM_ERROR = MAKE_EVENT(5, severity::LOW);
//! [EXPORT] : [COMMENT] Star tracker did not send replies (maybe device is powered off)
//!P1: Position of upload packet for which no reply was sent
static const Event NO_REPLY = MAKE_EVENT(6, severity::LOW);
//!P1: Position of upload or download packet for which no reply was sent
static const Event IMG_LOADER_NO_REPLY = MAKE_EVENT(6, severity::LOW);
//! [EXPORT] : [COMMENT] Received reply with invalid type ID
static const Event INVALID_TYPE_ID = MAKE_EVENT(7, severity::LOW);
//! [EXPORT] : [COMMENT] Status field in reply signals error
static const Event STATUS_ERROR = MAKE_EVENT(8, severity::LOW);
//! [EXPORT] : [COMMENT] Error during decoding of received reply occurred
//P1: Return value of decoding function
//P2: Position of upload packet for which reply decoding failed
static const Event DEC_ERROR = MAKE_EVENT(9, severity::LOW);
//P2: Position of upload/download packet for which reply decoding failed
static const Event IMG_LOADER_DEC_ERROR = MAKE_EVENT(9, severity::LOW);
//! [EXPORT] : [COMMENT] Image download was successful
static const Event IMAGE_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(10, severity::LOW);
//! [EXPORT] : [COMMENT] Position mismatch
//! P1: The expected position and thus the position for which the image upload/download failed
static const Event POSITION_MISMATCH = MAKE_EVENT(11, severity::LOW);
StrImageLoader(object_id_t objectId);
@ -80,7 +85,7 @@ public:
/**
* @brief Calling this function initiates the download of an image from the star tracker.
*/
ReturnValue_t startImageDownload();
void startImageDownload(std::string downloadImage_);
private:
@ -94,8 +99,14 @@ private:
// Size of one image part which can be sent per action request
static const size_t SIZE_IMAGE_PART = 1024;
static const uint32_t LAST_POSITION = 4095;
static const uint32_t MAX_POLLS = 10000;
static const uint8_t POS_OFFSET = 2;
static const uint8_t DATA_OFFSET = 5;
static const size_t IMAGE_DATA_SIZE = 1024;
enum class InternalState {
IDLE,
UPLOAD_IMAGE,
@ -108,8 +119,10 @@ private:
BinarySemaphore semaphore;
// Absolute path and name to image to upload
// Name including absolute path of image to upload
std::string uploadImage;
// Name including the absolute path of downloaded image
std::string downloadImage;
SdCardManager* sdcMan = nullptr;
@ -132,21 +145,33 @@ private:
ReturnValue_t performImageUpload();
/**
* @brief Sends a upload image packet and receives the action reply.
*
* @param uploadReq Pointer to upload request structure to send
*
* @return RETURN_OK if successful, otherwise RETURN_FALIED
* @bried Performs download of last taken image from the star tracker.
*/
ReturnValue_t uploadSendAndRead(struct UploadActionRequest* uploadReq);
ReturnValue_t performImageDownload();
/**
* @brief Checks the reply to an upload action request
* @brief Sends packet to the star tracker and reads reply by using the communication
* interface
*
* @return RETURN_OK if reply confirms success of upload packet transfer, otherwise
* REUTRN_FAILED
* @return RETURN_OK if successful, otherwise RETURN_FAILED
*/
ReturnValue_t checkUploadReply();
ReturnValue_t sendAndRead(size_t size, uint32_t position);
/**
* @brief Checks the reply header (type id and status fields)
*
* @return RETURN_OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED
*/
ReturnValue_t checkReply();
/**
* @brief Checks the position field in a star tracker reply.
*
* @param expectedPosition Value of expected position
*
* @return RETURN_OK if received position matches expected position, otherwise RETURN_FAILED
*/
ReturnValue_t checkReplyPosition(uint32_t expectedPosition);
};
#endif /* BSP_Q7S_DEVICES_STRIMAGELOADER_H_ */