Newer
Older
#include "ECSS_Configuration.hpp"
#ifdef SERVICE_TIMESCHEDULING
#include "Services/TimeBasedSchedulingService.hpp"
TimeBasedSchedulingService::TimeBasedSchedulingService() {
serviceType = TimeBasedSchedulingService::ServiceType;
Time::CustomCUC_t TimeBasedSchedulingService::executeScheduledActivity(Time::CustomCUC_t currentTime) {
if (currentTime >= scheduledActivities.front().requestReleaseTime && !scheduledActivities.empty()) {
if (scheduledActivities.front().requestID.applicationID == ApplicationId) {
MessageParser::execute(scheduledActivities.front().request);
}
scheduledActivities.pop_front();
}
if (!scheduledActivities.empty()) {
return scheduledActivities.front().requestReleaseTime;
} else {
Time::CustomCUC_t infinity;
infinity.elapsed100msTicks = std::numeric_limits<decltype(infinity.elapsed100msTicks)>::max();
return infinity;
}
}
void TimeBasedSchedulingService::enableScheduleExecution(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::EnableTimeBasedScheduleExecutionFunction);
executionFunctionStatus = true;
void TimeBasedSchedulingService::disableScheduleExecution(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::DisableTimeBasedScheduleExecutionFunction);
executionFunctionStatus = false;
void TimeBasedSchedulingService::resetSchedule(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::ResetTimeBasedSchedule);
executionFunctionStatus = false;
scheduledActivities.clear();
// todo: Add resetting for sub-schedules and groups, if defined
}
void TimeBasedSchedulingService::insertActivities(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::InsertActivities);
// todo: Get the sub-schedule ID if they are implemented
uint16_t iterationCount = request.readUint16();
// todo: Get the group ID first, if groups are used
Time::CustomCUC_t currentTime = TimeGetter::getCurrentTimeCustomCUC();
Time::CustomCUC_t releaseTime = request.readCustomCUCTimeStamp();
if ((scheduledActivities.available() == 0) || (releaseTime < (currentTime + ECSSTimeMarginForActivation))) {
ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
uint8_t requestData[ECSSTCRequestStringSize] = {0};
request.readString(requestData, ECSSTCRequestStringSize);
Message receivedTCPacket = MessageParser::parseECSSTC(requestData);
newActivity.request = receivedTCPacket;
newActivity.requestReleaseTime = releaseTime;
// todo: When implemented save the source ID
newActivity.requestID.applicationID = request.applicationId;
newActivity.requestID.sequenceCount = request.packetSequenceCount;
scheduledActivities.push_back(newActivity);
sortActivitiesReleaseTime(scheduledActivities);
void TimeBasedSchedulingService::timeShiftAllActivities(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::TimeShiftALlScheduledActivities);
Time::CustomCUC_t current_time = TimeGetter::getCurrentTimeCustomCUC();
const auto releaseTimes =
etl::minmax_element(scheduledActivities.begin(), scheduledActivities.end(),
[](ScheduledActivity const& leftSide, ScheduledActivity const& rightSide) {
return leftSide.requestReleaseTime < rightSide.requestReleaseTime;
});
// todo: Define what the time format is going to be
Time::RelativeTime relativeOffset = request.readRelativeTime();
if ((releaseTimes.first->requestReleaseTime + relativeOffset) < (current_time + ECSSTimeMarginForActivation)) {
ErrorHandler::reportError(request, ErrorHandler::SubServiceExecutionStartError);
for (auto& activity: scheduledActivities) {
activity.requestReleaseTime += relativeOffset;
void TimeBasedSchedulingService::timeShiftActivitiesByID(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::TimeShiftActivitiesById);
Time::CustomCUC_t current_time = TimeGetter::getCurrentTimeCustomCUC();
Time::RelativeTime relativeOffset = request.readRelativeTime();
uint16_t iterationCount = request.readUint16();
RequestID receivedRequestID;
receivedRequestID.sourceID = request.readUint8();
receivedRequestID.applicationID = request.readUint16();
receivedRequestID.sequenceCount = request.readUint16();
auto requestIDMatch = etl::find_if_not(scheduledActivities.begin(), scheduledActivities.end(),
[&receivedRequestID](ScheduledActivity const& currentElement) {
return receivedRequestID != currentElement.requestID;
if (requestIDMatch != scheduledActivities.end()) {
if ((requestIDMatch->requestReleaseTime + relativeOffset) <
ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
requestIDMatch->requestReleaseTime += relativeOffset;
} else {
ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
sortActivitiesReleaseTime(scheduledActivities);
void TimeBasedSchedulingService::deleteActivitiesByID(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::DeleteActivitiesById);
uint16_t iterationCount = request.readUint16();
RequestID receivedRequestID;
receivedRequestID.sourceID = request.readUint8();
receivedRequestID.applicationID = request.readUint16();
receivedRequestID.sequenceCount = request.readUint16();
const auto requestIDMatch = etl::find_if_not(scheduledActivities.begin(), scheduledActivities.end(),
[&receivedRequestID](ScheduledActivity const& currentElement) {
return receivedRequestID != currentElement.requestID;
});
if (requestIDMatch != scheduledActivities.end()) {
scheduledActivities.erase(requestIDMatch);
ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
void TimeBasedSchedulingService::detailReportAllActivities(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::DetailReportAllScheduledActivities);
Message report = createTM(TimeBasedSchedulingService::MessageType::TimeBasedScheduleReportById);
report.appendUint16(static_cast<uint16_t>(scheduledActivities.size()));
for (auto& activity: scheduledActivities) {
// todo: append sub-schedule and group ID if they are defined
report.appendCustomCUCTimeStamp(activity.requestReleaseTime);
report.appendString(MessageParser::composeECSS(activity.request));
void TimeBasedSchedulingService::detailReportActivitiesByID(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::DetailReportActivitiesById);
Message report = createTM(TimeBasedSchedulingService::MessageType::TimeBasedScheduleReportById);
etl::list<ScheduledActivity, ECSSMaxNumberOfTimeSchedActivities> matchedActivities;
uint16_t iterationCount = request.readUint16();
RequestID receivedRequestID;
receivedRequestID.sourceID = request.readUint8();
receivedRequestID.applicationID = request.readUint16();
receivedRequestID.sequenceCount = request.readUint16();
const auto requestIDMatch = etl::find_if_not(scheduledActivities.begin(), scheduledActivities.end(),
[&receivedRequestID](ScheduledActivity const& currentElement) {
return receivedRequestID != currentElement.requestID;
});
if (requestIDMatch != scheduledActivities.end()) {
matchedActivities.push_back(*requestIDMatch);
ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
sortActivitiesReleaseTime(matchedActivities);
// todo: append sub-schedule and group ID if they are defined
report.appendUint16(static_cast<uint16_t>(matchedActivities.size()));
for (auto& match: matchedActivities) {
report.appendCustomCUCTimeStamp(match.requestReleaseTime); // todo: Replace with the time parser
report.appendString(MessageParser::composeECSS(match.request));
void TimeBasedSchedulingService::summaryReportActivitiesByID(Message& request) {
request.assertTC(TimeBasedSchedulingService::ServiceType, TimeBasedSchedulingService::MessageType::ActivitiesSummaryReportById);
Message report = createTM(TimeBasedSchedulingService::MessageType::TimeBasedScheduledSummaryReport);
etl::list<ScheduledActivity, ECSSMaxNumberOfTimeSchedActivities> matchedActivities;
uint16_t iterationCount = request.readUint16();
RequestID receivedRequestID;
receivedRequestID.sourceID = request.readUint8();
receivedRequestID.applicationID = request.readUint16();
receivedRequestID.sequenceCount = request.readUint16();
auto requestIDMatch = etl::find_if_not(scheduledActivities.begin(), scheduledActivities.end(),
[&receivedRequestID](ScheduledActivity const& currentElement) {
return receivedRequestID != currentElement.requestID;
});
if (requestIDMatch != scheduledActivities.end()) {
matchedActivities.push_back(*requestIDMatch);
ErrorHandler::reportError(request, ErrorHandler::InstructionExecutionStartError);
sortActivitiesReleaseTime(matchedActivities);
// todo: append sub-schedule and group ID if they are defined
report.appendUint16(static_cast<uint16_t>(matchedActivities.size()));
// todo: append sub-schedule and group ID if they are defined
report.appendCustomCUCTimeStamp(match.requestReleaseTime);
report.appendUint8(match.requestID.sourceID);
report.appendUint16(match.requestID.applicationID);
report.appendUint16(match.requestID.sequenceCount);
case EnableTimeBasedScheduleExecutionFunction:
enableScheduleExecution(message);
case DisableTimeBasedScheduleExecutionFunction:
disableScheduleExecution(message);
case ResetTimeBasedSchedule:
resetSchedule(message);
case InsertActivities:
insertActivities(message);
case DeleteActivitiesById:
deleteActivitiesByID(message);
case TimeShiftActivitiesById:
timeShiftActivitiesByID(message);
case DetailReportActivitiesById:
detailReportActivitiesByID(message);
case ActivitiesSummaryReportById:
summaryReportActivitiesByID(message);
case TimeShiftALlScheduledActivities:
timeShiftAllActivities(message);
case DetailReportAllScheduledActivities:
detailReportAllActivities(message);
ErrorHandler::reportInternalError(ErrorHandler::OtherMessageType);