|
|
|
@ -3,6 +3,7 @@
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
|
|
|
|
|
#include "fsfw/globalfunctions/CRC.h"
|
|
|
|
|
#include "fsfw/globalfunctions/timevalOperations.h"
|
|
|
|
|
#include "fsfw/objectmanager/ObjectManager.h"
|
|
|
|
|
#include "fsfw/serialize/SerializeAdapter.h"
|
|
|
|
|
#include "fsfw/serviceinterface.h"
|
|
|
|
@ -79,7 +80,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService
|
|
|
|
|
// NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg
|
|
|
|
|
// does not work in this case as we are deleting the current element here.
|
|
|
|
|
for (auto it = telecommandMap.begin(); it != telecommandMap.end();) {
|
|
|
|
|
if (it->first <= tNow.tv_sec) {
|
|
|
|
|
if (it->first <= tNow) {
|
|
|
|
|
if (schedulingEnabled) {
|
|
|
|
|
// release tc
|
|
|
|
|
TmTcMessage releaseMsg(it->second.storeAddr);
|
|
|
|
@ -150,17 +151,25 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleResetCom
|
|
|
|
|
template <size_t MAX_NUM_TCS>
|
|
|
|
|
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivity(
|
|
|
|
|
const uint8_t *data, size_t size) {
|
|
|
|
|
uint32_t timestamp = 0;
|
|
|
|
|
ReturnValue_t result = SerializeAdapter::deSerialize(×tamp, &data, &size, DEF_END);
|
|
|
|
|
uint32_t seconds = 0;
|
|
|
|
|
ReturnValue_t result = SerializeAdapter::deSerialize(&seconds, &data, &size, DEF_END);
|
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
timeval scheduledTime;
|
|
|
|
|
scheduledTime.tv_sec = seconds;
|
|
|
|
|
scheduledTime.tv_usec = 0;
|
|
|
|
|
|
|
|
|
|
// Insert possible if sched. time is above margin
|
|
|
|
|
// (See requirement for Time margin)
|
|
|
|
|
timeval tNow = {};
|
|
|
|
|
Clock::getClock_timeval(&tNow);
|
|
|
|
|
if (timestamp - tNow.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) {
|
|
|
|
|
timeval timeDifference = scheduledTime - tNow;
|
|
|
|
|
// round subseconds up
|
|
|
|
|
if (timeDifference.tv_usec != 0) {
|
|
|
|
|
timeDifference.tv_sec++;
|
|
|
|
|
}
|
|
|
|
|
if (timeDifference.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) {
|
|
|
|
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
|
|
|
sif::warning << "Service11TelecommandScheduling::doInsertActivity: Release time too close to "
|
|
|
|
|
"current time"
|
|
|
|
@ -197,11 +206,10 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
|
|
|
|
|
|
|
|
|
// insert into multimap with new store address
|
|
|
|
|
TelecommandStruct tc;
|
|
|
|
|
tc.seconds = timestamp;
|
|
|
|
|
tc.storeAddr = addr;
|
|
|
|
|
tc.requestId = getRequestIdFromTc(); // TODO: Missing sanity check of the returned request id
|
|
|
|
|
|
|
|
|
|
auto it = telecommandMap.insert(std::pair<uint32_t, TelecommandStruct>(timestamp, tc));
|
|
|
|
|
auto it = telecommandMap.insert(std::pair<timeval, TelecommandStruct>(scheduledTime, tc));
|
|
|
|
|
if (it == telecommandMap.end()) {
|
|
|
|
|
return returnvalue::FAILED;
|
|
|
|
|
}
|
|
|
|
@ -391,7 +399,8 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doTimeshiftAct
|
|
|
|
|
|
|
|
|
|
// temporarily hold the item
|
|
|
|
|
TelecommandStruct tempTc(tcToTimeshiftIt->second);
|
|
|
|
|
uint32_t tempKey = tcToTimeshiftIt->first + relativeTime;
|
|
|
|
|
timeval tempKey = tcToTimeshiftIt->first;
|
|
|
|
|
tempKey.tv_sec += relativeTime;
|
|
|
|
|
|
|
|
|
|
// delete old entry from the mm
|
|
|
|
|
telecommandMap.erase(tcToTimeshiftIt);
|
|
|
|
@ -436,7 +445,8 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doFilterTimesh
|
|
|
|
|
for (auto it = itBegin; it != itEnd;) {
|
|
|
|
|
// temporarily hold the item
|
|
|
|
|
TelecommandStruct tempTc(it->second);
|
|
|
|
|
uint32_t tempKey = it->first + relativeTime;
|
|
|
|
|
timeval tempKey = it->first;
|
|
|
|
|
tempKey.tv_sec += relativeTime;
|
|
|
|
|
|
|
|
|
|
// delete the old entry from the mm
|
|
|
|
|
telecommandMap.erase(it++);
|
|
|
|
@ -533,12 +543,16 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case TypeOfTimeWindow::FROM_TIMETAG: {
|
|
|
|
|
uint32_t fromTimestamp = 0;
|
|
|
|
|
result = SerializeAdapter::deSerialize(&fromTimestamp, &data, &dataSize, DEF_END);
|
|
|
|
|
uint32_t fromSeconds = 0;
|
|
|
|
|
result = SerializeAdapter::deSerialize(&fromSeconds, &data, &dataSize, DEF_END);
|
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timeval fromTimestamp;
|
|
|
|
|
fromTimestamp.tv_sec = fromSeconds;
|
|
|
|
|
fromTimestamp.tv_usec = 0;
|
|
|
|
|
|
|
|
|
|
itBegin = telecommandMap.begin();
|
|
|
|
|
while (itBegin->first < fromTimestamp && itBegin != telecommandMap.end()) {
|
|
|
|
|
itBegin++;
|
|
|
|
@ -549,11 +563,15 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case TypeOfTimeWindow::TO_TIMETAG: {
|
|
|
|
|
uint32_t toTimestamp;
|
|
|
|
|
result = SerializeAdapter::deSerialize(&toTimestamp, &data, &dataSize, DEF_END);
|
|
|
|
|
uint32_t toSeconds = 0;
|
|
|
|
|
result = SerializeAdapter::deSerialize(&toSeconds, &data, &dataSize, DEF_END);
|
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
timeval toTimestamp;
|
|
|
|
|
toTimestamp.tv_sec = toSeconds;
|
|
|
|
|
toTimestamp.tv_usec = 0;
|
|
|
|
|
|
|
|
|
|
itBegin = telecommandMap.begin();
|
|
|
|
|
itEnd = telecommandMap.begin();
|
|
|
|
|
while (itEnd->first <= toTimestamp && itEnd != telecommandMap.end()) {
|
|
|
|
@ -563,19 +581,27 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case TypeOfTimeWindow::FROM_TIMETAG_TO_TIMETAG: {
|
|
|
|
|
uint32_t fromTimestamp;
|
|
|
|
|
uint32_t toTimestamp;
|
|
|
|
|
uint32_t fromSeconds = 0;
|
|
|
|
|
uint32_t toSeconds = 0;
|
|
|
|
|
|
|
|
|
|
result = SerializeAdapter::deSerialize(&fromTimestamp, &data, &dataSize,
|
|
|
|
|
result = SerializeAdapter::deSerialize(&fromSeconds, &data, &dataSize,
|
|
|
|
|
SerializeIF::Endianness::BIG);
|
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
result = SerializeAdapter::deSerialize(&toTimestamp, &data, &dataSize,
|
|
|
|
|
result = SerializeAdapter::deSerialize(&toSeconds, &data, &dataSize,
|
|
|
|
|
SerializeIF::Endianness::BIG);
|
|
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
timeval fromTimestamp;
|
|
|
|
|
fromTimestamp.tv_sec = fromSeconds;
|
|
|
|
|
fromTimestamp.tv_usec = 0;
|
|
|
|
|
timeval toTimestamp;
|
|
|
|
|
toTimestamp.tv_sec = toSeconds;
|
|
|
|
|
toTimestamp.tv_usec = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fromTimestamp > toTimestamp) {
|
|
|
|
|
return INVALID_TIME_WINDOW;
|
|
|
|
|
}
|
|
|
|
|
Is timeval guaranteed to be signed?
This also rounds up when subsecond micros are 0, is this intended?
Can we use
timestamp <= tNow.tv_sec + RELEASE_TIME_MARGIN_SECONDS
compare logic instead?That is a bit more readable in my opinion.
Changed rounding to be correct.
The unreadable comparison is removed with this PR.