diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index e32be68b..42ee4022 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -43,10 +43,10 @@ void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, queueToUse->sendMessage(reportTo, &reply); } -void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, +void ActionHelper::finish(bool success, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { CommandMessage reply; - ActionMessage::setCompletionReply(&reply, commandId, result); + ActionMessage::setCompletionReply(success, &reply, commandId, result); queueToUse->sendMessage(reportTo, &reply); } @@ -69,7 +69,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ipcStore->deleteData(dataAddress); if(result == HasActionsIF::EXECUTION_FINISHED) { CommandMessage reply; - ActionMessage::setCompletionReply(&reply, actionId, result); + ActionMessage::setCompletionReply(true, &reply, actionId, result); queueToUse->sendMessage(commandedBy, &reply); } if (result != HasReturnvaluesIF::RETURN_OK) { diff --git a/action/ActionHelper.h b/action/ActionHelper.h index 35ac41d1..c9024747 100644 --- a/action/ActionHelper.h +++ b/action/ActionHelper.h @@ -62,12 +62,12 @@ public: ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); /** * Function to be called by the owner to send a action completion message - * + * @param success Specify whether action was completed successfully or not. * @param reportTo MessageQueueId_t to report the action completion message to * @param commandId ID of the executed command * @param result Result of the execution */ - void finish(MessageQueueId_t reportTo, ActionId_t commandId, + void finish(bool success, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); /** * Function to be called by the owner if an action does report data. diff --git a/action/ActionMessage.cpp b/action/ActionMessage.cpp index c3eb4710..15b59b9d 100644 --- a/action/ActionMessage.cpp +++ b/action/ActionMessage.cpp @@ -53,11 +53,12 @@ void ActionMessage::setDataReply(CommandMessage* message, ActionId_t actionId, message->setParameter2(data.raw); } -void ActionMessage::setCompletionReply(CommandMessage* message, +void ActionMessage::setCompletionReply(bool success, CommandMessage* message, ActionId_t fid, ReturnValue_t result) { - if (result == HasReturnvaluesIF::RETURN_OK or result == HasActionsIF::EXECUTION_FINISHED) { + if (success) { message->setCommand(COMPLETION_SUCCESS); - } else { + } + else { message->setCommand(COMPLETION_FAILED); } message->setParameter(fid); diff --git a/action/ActionMessage.h b/action/ActionMessage.h index 246ac601..df97485b 100644 --- a/action/ActionMessage.h +++ b/action/ActionMessage.h @@ -24,19 +24,23 @@ public: static const Command_t DATA_REPLY = MAKE_COMMAND_ID(4); static const Command_t COMPLETION_SUCCESS = MAKE_COMMAND_ID(5); static const Command_t COMPLETION_FAILED = MAKE_COMMAND_ID(6); + virtual ~ActionMessage(); static void setCommand(CommandMessage* message, ActionId_t fid, store_address_t parameters); + static ActionId_t getActionId(const CommandMessage* message ); - static store_address_t getStoreId(const CommandMessage* message ); + static store_address_t getStoreId(const CommandMessage* message); + static void setStepReply(CommandMessage* message, ActionId_t fid, uint8_t step, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); static uint8_t getStep(const CommandMessage* message ); static ReturnValue_t getReturnCode(const CommandMessage* message ); static void setDataReply(CommandMessage* message, ActionId_t actionId, store_address_t data); - static void setCompletionReply(CommandMessage* message, ActionId_t fid, + static void setCompletionReply(bool success, CommandMessage* message, ActionId_t fid, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK); + static void clear(CommandMessage* message); }; diff --git a/action/SimpleActionHelper.cpp b/action/SimpleActionHelper.cpp index f77d0147..979ee3ad 100644 --- a/action/SimpleActionHelper.cpp +++ b/action/SimpleActionHelper.cpp @@ -62,7 +62,7 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, stepCount++; break; case HasActionsIF::EXECUTION_FINISHED: - ActionMessage::setCompletionReply(&reply, actionId, + ActionMessage::setCompletionReply(true, &reply, actionId, HasReturnvaluesIF::RETURN_OK); queueToUse->sendMessage(commandedBy, &reply); break; diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 35d34bf9..15eac11f 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -558,7 +558,7 @@ void DeviceHandlerBase::replyToCommand(ReturnValue_t status, if (cookieInfo.pendingCommand->second.sendReplyTo != NO_COMMANDER) { MessageQueueId_t queueId = cookieInfo.pendingCommand->second.sendReplyTo; if (status == NO_REPLY_EXPECTED) { - actionHelper.finish(queueId, cookieInfo.pendingCommand->first, + actionHelper.finish(true, queueId, cookieInfo.pendingCommand->first, RETURN_OK); } else { actionHelper.step(1, queueId, cookieInfo.pendingCommand->first, @@ -581,7 +581,11 @@ void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter, // Check if it was transition or internal command. // Don't send any replies in that case. if (info->sendReplyTo != NO_COMMANDER) { - actionHelper.finish(info->sendReplyTo, iter->first, status); + bool success = false; + if(status == HasReturnvaluesIF::RETURN_OK) { + success = true; + } + actionHelper.finish(success, info->sendReplyTo, iter->first, status); } info->isExecuting = false; } diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index 9c0a0267..806edcc7 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -16,56 +16,56 @@ uint16_t Clock::leapSeconds = 0; MutexIF* Clock::timeMutex = nullptr; uint32_t Clock::getTicksPerSecond(void) { - return 1000; + return 1000; } ReturnValue_t Clock::setClock(const TimeOfDay_t* time) { - timeval time_timeval; + timeval time_timeval; - ReturnValue_t result = convertTimeOfDayToTimeval(time, &time_timeval); - if (result != HasReturnvaluesIF::RETURN_OK){ - return result; - } + ReturnValue_t result = convertTimeOfDayToTimeval(time, &time_timeval); + if (result != HasReturnvaluesIF::RETURN_OK){ + return result; + } - return setClock(&time_timeval); + return setClock(&time_timeval); } ReturnValue_t Clock::setClock(const timeval* time) { - timeval uptime = getUptime(); + timeval uptime = getUptime(); - timeval offset = *time - uptime; + timeval offset = *time - uptime; - Timekeeper::instance()->setOffset(offset); + Timekeeper::instance()->setOffset(offset); - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t Clock::getClock_timeval(timeval* time) { - timeval uptime = getUptime(); + timeval uptime = getUptime(); - timeval offset = Timekeeper::instance()->getOffset(); + timeval offset = Timekeeper::instance()->getOffset(); - *time = offset + uptime; + *time = offset + uptime; - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t Clock::getUptime(timeval* uptime) { - *uptime = getUptime(); + *uptime = getUptime(); - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } timeval Clock::getUptime() { - TickType_t ticksSinceStart = xTaskGetTickCount(); - return Timekeeper::ticksToTimeval(ticksSinceStart); + TickType_t ticksSinceStart = xTaskGetTickCount(); + return Timekeeper::ticksToTimeval(ticksSinceStart); } ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { - timeval uptime = getUptime(); - *uptimeMs = uptime.tv_sec * 1000 + uptime.tv_usec / 1000; - return HasReturnvaluesIF::RETURN_OK; + timeval uptime = getUptime(); + *uptimeMs = uptime.tv_sec * 1000 + uptime.tv_usec / 1000; + return HasReturnvaluesIF::RETURN_OK; } @@ -76,129 +76,129 @@ ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { ReturnValue_t Clock::getClock_usecs(uint64_t* time) { - timeval time_timeval; - ReturnValue_t result = getClock_timeval(&time_timeval); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - *time = time_timeval.tv_sec * 1000000 + time_timeval.tv_usec; - return HasReturnvaluesIF::RETURN_OK; + timeval time_timeval; + ReturnValue_t result = getClock_timeval(&time_timeval); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + *time = time_timeval.tv_sec * 1000000 + time_timeval.tv_usec; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { - timeval time_timeval; - ReturnValue_t result = getClock_timeval(&time_timeval); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - struct tm time_tm; + timeval time_timeval; + ReturnValue_t result = getClock_timeval(&time_timeval); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + struct tm time_tm; - gmtime_r(&time_timeval.tv_sec,&time_tm); + gmtime_r(&time_timeval.tv_sec,&time_tm); - time->year = time_tm.tm_year + 1900; - time->month = time_tm.tm_mon + 1; - time->day = time_tm.tm_mday; + time->year = time_tm.tm_year + 1900; + time->month = time_tm.tm_mon + 1; + time->day = time_tm.tm_mday; - time->hour = time_tm.tm_hour; - time->minute = time_tm.tm_min; - time->second = time_tm.tm_sec; + time->hour = time_tm.tm_hour; + time->minute = time_tm.tm_min; + time->second = time_tm.tm_sec; - time->usecond = time_timeval.tv_usec; + time->usecond = time_timeval.tv_usec; - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, - timeval* to) { - struct tm time_tm; + timeval* to) { + struct tm time_tm; - time_tm.tm_year = from->year - 1900; - time_tm.tm_mon = from->month - 1; - time_tm.tm_mday = from->day; + time_tm.tm_year = from->year - 1900; + time_tm.tm_mon = from->month - 1; + time_tm.tm_mday = from->day; - time_tm.tm_hour = from->hour; - time_tm.tm_min = from->minute; - time_tm.tm_sec = from->second; + time_tm.tm_hour = from->hour; + time_tm.tm_min = from->minute; + time_tm.tm_sec = from->second; - time_t seconds = mktime(&time_tm); + time_t seconds = mktime(&time_tm); - to->tv_sec = seconds; - to->tv_usec = from->usecond; - //Fails in 2038.. - return HasReturnvaluesIF::RETURN_OK; + to->tv_sec = seconds; + to->tv_usec = from->usecond; + //Fails in 2038.. + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) { - *JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. - / 3600.; - return HasReturnvaluesIF::RETURN_OK; + *JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. + / 3600.; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { - //SHOULDDO: works not for dates in the past (might have less leap seconds) - if (timeMutex == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; - } + //SHOULDDO: works not for dates in the past (might have less leap seconds) + if (timeMutex == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } - uint16_t leapSeconds; - ReturnValue_t result = getLeapSeconds(&leapSeconds); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - timeval leapSeconds_timeval = { 0, 0 }; - leapSeconds_timeval.tv_sec = leapSeconds; + uint16_t leapSeconds; + ReturnValue_t result = getLeapSeconds(&leapSeconds); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + timeval leapSeconds_timeval = { 0, 0 }; + leapSeconds_timeval.tv_sec = leapSeconds; - //initial offset between UTC and TAI - timeval UTCtoTAI1972 = { 10, 0 }; + //initial offset between UTC and TAI + timeval UTCtoTAI1972 = { 10, 0 }; - timeval TAItoTT = { 32, 184000 }; + timeval TAItoTT = { 32, 184000 }; - *tt = utc + leapSeconds_timeval + UTCtoTAI1972 + TAItoTT; + *tt = utc + leapSeconds_timeval + UTCtoTAI1972 + TAItoTT; - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { - if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) { - return HasReturnvaluesIF::RETURN_FAILED; - } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) { + return HasReturnvaluesIF::RETURN_FAILED; + } + ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - leapSeconds = leapSeconds_; + leapSeconds = leapSeconds_; - result = timeMutex->unlockMutex(); - return result; + result = timeMutex->unlockMutex(); + return result; } ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { - if (timeMutex == NULL) { - return HasReturnvaluesIF::RETURN_FAILED; - } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + if (timeMutex == NULL) { + return HasReturnvaluesIF::RETURN_FAILED; + } + ReturnValue_t result = timeMutex->lockMutex(MutexIF::TimeoutType::BLOCKING); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } - *leapSeconds_ = leapSeconds; + *leapSeconds_ = leapSeconds; - result = timeMutex->unlockMutex(); - return result; + result = timeMutex->unlockMutex(); + return result; } ReturnValue_t Clock::checkOrCreateClockMutex() { - if (timeMutex == NULL) { - MutexFactory* mutexFactory = MutexFactory::instance(); - if (mutexFactory == NULL) { - return HasReturnvaluesIF::RETURN_FAILED; - } - timeMutex = mutexFactory->createMutex(); - if (timeMutex == NULL) { - return HasReturnvaluesIF::RETURN_FAILED; - } - } - return HasReturnvaluesIF::RETURN_OK; + if (timeMutex == NULL) { + MutexFactory* mutexFactory = MutexFactory::instance(); + if (mutexFactory == NULL) { + return HasReturnvaluesIF::RETURN_FAILED; + } + timeMutex = mutexFactory->createMutex(); + if (timeMutex == NULL) { + return HasReturnvaluesIF::RETURN_FAILED; + } + } + return HasReturnvaluesIF::RETURN_OK; } diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index aefcac2e..8f0d1c31 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -396,12 +396,20 @@ ReturnValue_t CCSDSTime::convertToCcsds(OBT_FLP* to, const timeval* from) { ReturnValue_t CCSDSTime::convertFromCcsds(timeval* to, const uint8_t* from, size_t* foundLength, size_t maxLength) { - //We don't expect ascii here. SHOULDDO + if(maxLength >= 19) { + Clock::TimeOfDay_t timeOfDay; + /* Try to parse it as ASCII */ + ReturnValue_t result = convertFromASCII(&timeOfDay, from, maxLength); + if (result == RETURN_OK) { + return Clock::convertTimeOfDayToTimeval(&timeOfDay, to); + } + } + uint8_t codeIdentification = (*from >> 4); switch (codeIdentification) { - //unsupported, as Leap second correction would have to be applied -// case CUC_LEVEL1: -// return convertFromCUC(to, from, foundLength, maxLength); + /* Unsupported, as Leap second correction would have to be applied */ + case CUC_LEVEL1: + return UNSUPPORTED_TIME_FORMAT; case CDS: return convertFromCDS(to, from, foundLength, maxLength); case CCS: diff --git a/unittest/tests/action/TestActionHelper.cpp b/unittest/tests/action/TestActionHelper.cpp index 2493a6b8..a7adfc82 100644 --- a/unittest/tests/action/TestActionHelper.cpp +++ b/unittest/tests/action/TestActionHelper.cpp @@ -70,7 +70,7 @@ TEST_CASE( "Action Helper" , "[ActionHelper]") { SECTION("Handle finish"){ CHECK(not testMqMock.wasMessageSent()); ReturnValue_t status = 0x9876; - actionHelper.finish(testMqMock.getId(), testActionId, status); + actionHelper.finish(true, testMqMock.getId(), testActionId, status); CHECK(testMqMock.wasMessageSent()); CommandMessage testMessage; REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast(HasReturnvaluesIF::RETURN_OK));