fsfw/src/fsfw/pus/Service9TimeManagement.cpp

100 lines
3.1 KiB
C++

#include "fsfw/pus/Service9TimeManagement.h"
#include <cmath>
#include "fsfw/events/EventManagerIF.h"
#include "fsfw/pus/servicepackets/Service9Packets.h"
#include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/timemanager/CCSDSTime.h"
Service9TimeManagement::Service9TimeManagement(PsbParams params) : PusServiceBase(params) {
params.name = "PUS 9 Time MGMT";
}
Service9TimeManagement::~Service9TimeManagement() = default;
ReturnValue_t Service9TimeManagement::performService() { return returnvalue::OK; }
ReturnValue_t Service9TimeManagement::handleRequest(uint8_t subservice) {
switch (subservice) {
case Subservice::SET_TIME: {
return setTime();
}
case Subservice::DUMP_TIME: {
timeval newTime;
ReturnValue_t result = Clock::getClock_timeval(&newTime);
if (result != returnvalue::OK) {
return result;
}
triggerEvent(CLOCK_DUMP, newTime.tv_sec, newTime.tv_usec);
return returnvalue::OK;
}
case Subservice::RELATIVE_TIMESHIFT: {
timeval currentTime;
ReturnValue_t result = Clock::getClock_timeval(&currentTime);
if (result != returnvalue::OK) {
return result;
}
if (currentPacket.getUserDataLen() != 8) {
return AcceptsTelecommandsIF::ILLEGAL_APPLICATION_DATA;
}
size_t deserLen = 8;
int64_t timeshiftNanos = 0;
result = SerializeAdapter::deSerialize(&timeshiftNanos, currentPacket.getUserData(),
&deserLen, SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
bool positiveShift = true;
if (timeshiftNanos < 0) {
positiveShift = false;
}
timeval offset{};
offset.tv_sec = std::abs(timeshiftNanos) / 1000000000;
offset.tv_usec = (std::abs(timeshiftNanos) % 1000000000) / 1000;
timeval newTime;
if (positiveShift) {
newTime = currentTime + offset;
} else {
newTime = currentTime - offset;
}
result = Clock::setClock(&newTime);
if (result == returnvalue::OK) {
// Report new time as event.
triggerEvent(CLOCK_DUMP, newTime.tv_sec, newTime.tv_usec);
}
return result;
}
default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
}
ReturnValue_t Service9TimeManagement::setTime() {
Clock::TimeOfDay_t timeToSet;
TimePacket timePacket(currentPacket.getUserData(), currentPacket.getUserDataLen());
ReturnValue_t result =
CCSDSTime::convertFromCcsds(&timeToSet, timePacket.getTime(), timePacket.getTimeSize());
if (result != returnvalue::OK) {
triggerEvent(CLOCK_SET_FAILURE, result, 0);
return result;
}
timeval time;
Clock::getClock_timeval(&time);
result = Clock::setClock(&timeToSet);
if (result == returnvalue::OK) {
timeval newTime;
Clock::getClock_timeval(&newTime);
triggerEvent(CLOCK_SET, time.tv_sec, newTime.tv_sec);
return returnvalue::OK;
} else {
triggerEvent(CLOCK_SET_FAILURE, result, 0);
return returnvalue::FAILED;
}
}