deleted the scheduing files for now, will be added after tests

This commit is contained in:
taheran 2020-09-10 15:41:05 +02:00
parent 36616bfbbe
commit 95fdbbee78
6 changed files with 0 additions and 1000 deletions

View File

@ -1,221 +0,0 @@
#include "ScheduleTable.h"
/*ctor
* max_Commands: maximum number of commands in schedule
* max_Subschedules: maximum number of subschedules
*/
ScheduleTable::ScheduleTable(object_id_t objectid, uint8_t max_Commands, uint8_t max_Subschedules):SystemObject(objectid)
,schedule(max_Commands)/*TBD*/,statusMap(max_Subschedules){
}
ScheduleTable::~ScheduleTable(){
}
ReturnValue_t ScheduleTable::setStatus(bool state){
for (statusIterator=statusMap.begin();statusIterator!=statusMap.end(); statusIterator++){
statusIterator->second.status=State;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ScheduleTable::setStatusInMap(bool state,subscheduleId_t subscheduleId){
ReturnValue_t result = statusMap.exists(subscheduleId);
if (result!= HasReturnvaluesIF::RETURN_OK){
return result;
}
statusIterator = statusMap.find(subschduleId);
statusIterator->second.status=state;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ScheduleTable::addCommandEntry(timeval TcTime,store_address_t TcAddress,subscheduleId_t SubscheduleId){
commandInfo newCommandInfo = {TcAddress, SubscheduleId};
result = schedule.insert(TcTime,newCommandInfo);
if (result != HasRetrnvaluesIF::RETURN_OK){
return result;
}
statusIterator = statusMap.find(subscheduleId);
//would above return null?
statusIterator->second.tcCount ++;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ScheduleTable:: addSubschedule(subscheduleId_t subscheduleId){
// default status is false
return statusMap.insert(subscheduleId,{false,0});
}
ReturnValue_t ScheduleTable:: shiftMap(timeval timeOffset){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
schedule.clear();
scheduleIterator = schedule.begin();
for (scheduleIterator=schedule.begin();scheduleIterator!=schedule.end(); scheduleIterator++){
result = shiftCommand(scheduleIterator, timeOffset);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ScheduleTable::shiftInMap(timeval timeOffset, subscheduleId_t subscheduleId){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
scheduleIterator = schedule.begin();
for (scheduleIterator=schedule.begin();scheduleIterator!=schedule.end(); schdeuleIterator++){
if ((scheduleIterator->second.subschedule)==subscheduleId){
result = shiftCommand(scheduleIterator, timeOffset);
if (result !=HasReturnvaluesIF::RETURN_OK){
return result;
}
}else{
continue;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ScheduleTable::shiftCommand(OnboardSchedule_map::iterator it, timeval time_delta){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
timeval tctime;
//TODO check syntax
timeradd(it.first, &time_delta , &tctime);
commandInfo copyCommand= it->second;
result = schedule.erase(it);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
// expect no errors, as we already used the iterator
result =schedule.insert(tctime, copyCommand);
//should not happen really.
return result;
}
timeval ScheduleTable::findStart(subscheduleId_t subscheduleId){
scheduleIterator = schedule.begin();
timeval startTime= (*scheduleIterator).first;
if (subscheduleId == 0){
return startTime;
}
timeval checkTime;
for (scheduleIterator = schedule.begin(); scheduleIterator!=schedule.end();scheduleIterator++){
if ((scheduleIterator->second.subschedule)==subscheduleId){
checkTime= scheduleIterator->first;
if (checkTime < startTime){
startTime=checkTime;
}
}else{
continue;
}
return startTime;
}
}
bool ScheduleTable::isNew(subscheduleId_t subscheduleId){
bool newId = true;
ReturnValue_t result = statusMap.exists(SubscheduleId);
if (result != HasReturnvaluesIF::RETURN_OK){
NewId= true;
}
else {
NewId= false;
}
return NewId;
}
void scheduleTable::goToStart(){
scheduleIterator = schedule.begin();
}
void scheduleTable::getNextTc(timeval OnboardTime, stor_address_t *address){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
commandReached = false;
timeval time;
while ( !commandReached){
subscheduleId_t subscheduleId = scheduleIterator->second.subschedule;
statusItertaor = statusMap.find (subscheduleId);
if (statusIterator-> second.status != true){
schdeuleIterator++;
continue;
}
time = scheduleIterator.first;
if (OnboardTime > time){
address = scheduleIterator-> second.commandAddress;
commandReached = true;
//do sth with result??
result = schedule.erase(&scheduleIterator);
scheduleIterator++;
statusIterator->second.tccount --;
if (statusIterator-> second.tccount ==0){
result = status.erase(&statusIterator);
//for now I do nothing with the fail here
}
}
}
}
void scheduleTable::clearScheduleMap(){
schedule.clear();
statusMap.clear();
}
/*
void scheduleTable::printAll(uint8_t* pointer, uint32_t maxSize) {
uint32_t size = 0;
uint16_t count = scheduleMap.scheduleSize();//should iterate and add all subschedule sizes
ReturnValue_t result = SerializeAdapter<uint16_t>::serialize(&count,
&pointer, &size, maxSize, true);
for (scheduleIterator = schedule.begin(), scheduleIterator != schedule.end() && result == HasReturnvaluesIF::RETURN_OK;
++iter) {
for (subscheduleIterator = (scheduleIterator->second).begin();
subscheduleIterator != (scheduleIterator->second).end()&& result == HasReturnvaluesIF::RETURN_OK;
subscheduleIterator++ ){
result = SerializeAdapter<subscheduleId_t>::serialize(&scheduleIterator->first,
&pointer, &size, maxSize, true);
uint8_t health = iter->second;
result = SerializeAdapter<uint8_t>::serialize(&, &pointer, &size,
maxSize, true);
}
}
scheduleSize()
//how much the size should be?
uint16_t count = 0;
*/
*/

View File

@ -1,58 +0,0 @@
#ifndef SCHEDULETABLE_H_
#define SCHEDULETABLE_H_
#include "ScheduleTableIF.h"
#include "../objectmanager/SystemObject.h"
#include "../container/FixedOrderedMultiMap.h"
//include time
typedef struct {
Store_address_t commandAddress;
subscheduleId_t subschedule;
} commandInfo;
typedef struct {
bool status;
uint8_t tcCount;
} subscheduleInfo;
typedef FixedOrderedMultimap<timeval, commandInfo, CCSDSTime::TimevalLess> Schedule_Map;
typedef FixedOrderedMultimap<SubscheduleId_t,subscheduleInfo> Subschedule_Status;
class ScheduleTable: public ScheduleTableIF ,
public SystemObject {
public:
ScheduleTable(object_id_t objectid, uint8_t max_Commands, uint8_t max_Subschedules);
virtual ~ScheduleTable();
ReturnValue_t setStatus(bool state)override;
ReturnValue_t setStatusInMap(bool state,subscheduleId_t subscheduleId)override;
ReturnValue_t addCommandEntry(timeval TcTime,store_address_t TcAddress,subscheduleId_t subscheduleId) override;
ReturnValue_t addSubschedule(subscheduleId_t subscheduleId)override;
ReturnValue_t shiftinMap(timeval timeOffset, subscheduleId_t subscheduleId)override;
ReturnValue_t shiftMap(timeval timeOffset)override;
ReturnValue_t shiftOneSubschedule(Schedule_map::iterator it, timeval time_delta)override;
void getNextTc(timeval OnboardTime,store_address_t *address)override;
timeval findStart(subscheduleId_t subscheduleId = 0)override;
bool isNew(subscheduleId_t subscheduleId)override;
void goToStart()override;
void clearScheduleMap()override;
//add Interface Id
static const uint8_t INTERFACE_ID = CLASS_ID::SCHEDULE_TABLE;
protected:
OnboardSchedule_Map schedule;
Subschedule_Status statusMap;
Schedule_Map::iterator scheduleIterator;
Subschedule_Status::iterator statusIterator;
private:
ReturnValue_t shiftCommand(OnboardSchedule_Map::iterator it, timeval time_delta);

View File

@ -1,35 +0,0 @@
#ifndef SCHEDULETABLEIF_H_
#define SCHEDULETANLEIF_H_
#include "../returnvalues/HasReturnvaluesIF.h"
class ScheduleTableIF : public HasReturnvaluesIF {
//any inheritance???
//any friend class? I don't see any now, as there is only the scheduling service accessing this table.
public:
virtual ~ScheduleTableIF();
virtual ReturnValue_t addCommandEntry(timeval TcTime, store_address_t TcAddress,subscheduleId_t subSchedule= 0)= 0;
virtual ReturnValue_t getNextTC(timeval OnboardTime,timeval* time,store_address_t* address) = 0;
virtual timeval findStart(subscheduleId_t subscheduleId) = 0;
virtual void goToStart()=0;
virtual bool isNew(subscheduleId_t subscheduleId) = 0;
virtual ReturnValue_t addSubschedule(subscheduleId)= 0;
virtual ReturnValue_t shiftMap(timeval timeOffset) = 0;
virtual ReturnValue_t shiftInMap(timeval timeOffset,subscheduleId_t subscheduleId)= 0;
virtual void clearScheduleMap()= 0;
virtual ReturnValue_t setStatus(bool state) = 0;
virtual ReturnValue_t setStatusInMap(bool state, subscheduleId_t subScheduleId) = 0;
//TODO print entries
//TODO delete an entry

View File

@ -1,504 +0,0 @@
/*
* Scheduling.cpp
*
* Created on: Dec 4, 2019
* Author: mala
*/
#include "Scheduling.h"
#include <framework/tmtcservices/TmTcMessage.h>
#include "../events/EventManagerIF.h"
#include "../ipc/QueueFactory.h"
//#include <mission/controllers/time/TimeManager.h>//not yet implemented, but necessary?
/*figure out if we would like to act on any events,
*also the sizes of queue and pool and schedule and subschedule.
*also maybe a default true for subscheduling enabled?
*/
//the size of TC pool for ESBO? TODO
//Maybe given that we move it to framework, it should be set from user config? TODO
const uint16_t OPS_Scheduling::POOL_SIZES [N_POOLS] = {32,64,128,256};
const uint16_t OPS_Scheduling::N_ELEMENTS[N_POOLS]= {900,40,30,30};
//TODO TC_QUEUE construction, helper construction
OPS_Scheduling::OPS_Scheduling(uint16_t apid, bool HasInitialSchedule, bool HasSubschedules):
PusServiceBase(object::PUS_Scheduler, apid,SERVICE::Onboard_Scheduling),SchedulingEnabled(true),NoTimeError(false)
,CommandStorage(objects::PUS_SCHEDULING_STORAGE, POOL_SIZES,N_ELEMENTS,false,true), loadingIsComplete(false),
supportSubschedule (HasSubschedules),loadIninitialSchedule(HasInitialSchedule)
{
eventQueue = QueueFactory::instance()->createMessageQueue();
commandQueue = QueueFactory::instance()->createMessageQueue();
}
OPS_Scheduling::~OPS_Scheduling();
ReturnValue_t OPS_Scheduling::handleRequest(uint8_t subservice){
switch (subservice){
case subServices::ENABLE_RELEASE_OF_TC:
return enableScheduling();
case subServices::DISABLE_RELEASE_OF_TC:
return disableScheduling();
case subServices::ENABLE_SUBSCHEDULE:
return enable_Subschedule(currentPacket.getApplicationData());
case subServices::DISABLE_SUBSCHEDULE:
return disable_Subschedule(currentPacket.getApplicationData());
case subServices::RESET_SCHEDULE:
return resetSchedule();
case subServices::TIMESHIFT_SCHEDULE:
return shift_Schedule(currentPacket.getApplicationData(), currentPacket.getApplicationDataSize());
case subServices::TIMESHIFT_SUBSCHEDULE:
return shift_SubSchedule(currentPacket.getApplicationData(), currentPacket.getApplicationDataSize());
case subServices::INSERT_TC_SCHEDULE:
//With Ramses, we only have fixed length packet sizes, so we need to only put one command in one packet.
return insertCommandinSchedule(currentPacket.getApplicationData(), currentPacket.getApplicationDataSize());
//TODO report schedule
//case REPORT_SCHEDULE:
//return Create_Schedule_Report();
//delete TC, we should discuss if based on what criteria we delete it
//case DELETE_TC
//return Delete_Command(currentPacket.getApplicationData());
default:
return AcceptsTelecommandsIF::INVALID_SUBSERVICE;
}
}
Returnvalue_t OPS_Scheduling::initialize()
{
//base class init
Returnvalue_t result= PusServiceBase::initialize();
if (result!= RETURN_OK){
return result;
}
//storage init
result= commandStorage.initialize();
if (result!=RETURN_OK){
return result;
}
//helper init
/*result = scheduleHelper.initialize();
if (result !=HasReturnvaluesIF::RETURN_OK){
return result;
}*/
scheduleMap = objectManager->get<ScheduleTableIF>(objects::SCHEDULE_TABLE);
if (scheduleTable == NULL){
return HasReturnValuesIF::RETURN_FAILED;
}
//queue initialization
AcceptsTelecommandsIF* distributor = objectManager->get<
AcceptsTelecommandsIF>(objects::CCSDS_PACKET_DISTRIBUTOR);
if (distributor == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
commandQueue.setDefaultDestination(distributor->getRequestQueue());
//event manager initialization
EventManagerIF* eventManager = objectManager->get<EventManagerIF>(
objects::EVENT_MANAGER);
if (eventManager == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
//listening to what??
result = eventManager->registerListener(eventQueue->getId(), true);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
//this list to be edited, after we have the time manager and know what events we declare
//result = eventManager->subscribeToEventRange(eventReceptionQueue.getId(),
//EVENT::getEventId(TimeManager::TIME_WAS_SET),
//EVENT::getEventId(TimeManager::TIME_JUMP_DETECTED), false);
//if (result != HasReturnvaluesIF::RETURN_OK) {
//return result;
//}
result = eventManager->subscribeToAllEventsFrom(eventReceptionQueue.getId(),
objects::SYSTEM);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
//we should check time error before loading, required by insertTc
//TODO checkEvents first to get timeset
//load schedule: initialization does not fail fully if loading fails
if (loadInitialSchedule){
scheduleLoader = objectManager->get<scheduleLoaderIF>(
objects::SCHEDULE_LOADER);
if (scheduleLoader != NULL){
result = scheduleLoader->initializeLoader();
if (result!=RETURN_OK){
triggerEvent (SCHEDULE_LOAD_FAILED);
}else{
result = loadSchedule();
}
} else if (scheduleLoader == NULL) {
triggerEvent (SCHEDULE_LOAD_FAILED);
}else {
//nothing
}
}
return HasreturnvaluesIF::RETURN_OK;
}
ReturnValue_t OPS_Scheduling::loadSchedule(){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
uint8_t *data;
size_t size;
while (!loadingIsComplete){
result = scheduleLoader->getCommandPacket(**data, &size);
if (result!= HasReturnvaluesIF::RETURN_OK){
loadingIsComplete= true;
break;
}
//needs set system time!
result = insertCommandinSchedule(data, size);
tcCounter++;
if (result!= HasReturnvaluesIF:: RETURN_OK){ //only when map is full, normally should not reach here
// we can report how many commands are transferred
triggerEvent(SCHEDULE_LOADED_INCOMPLETE,tcCounter);
break;
}
}
}
}
//complete
ReturnValue_t OPS_Scheduling::enableScheduling()
{
if (NoTimeError){
SchedulingEnabled = true;
return HasReturnvaluesIF::RETURN_OK;
}
else {
return TIME_ERROR;
}
}
void OPS_Scheduling::disableScheduling()
{
if (SchedulingEnabled){
triggerEvent(OPS_SCHEDULE_DISABLED);
SchedulingEnabled = false;
}
}
//default subscheduleId is zero, which translates to enable/disable all subschedules
//set status is only a subschedule/group-specific feature.
ReturnValue_t OPS_Scheduling::enable_Subschedule(SubscheduleId_t subScheduleId)
{
/*bool state = STATE_ENABLED;
return scheduleHelper.setScheduleStatus(state, subScheduleId);
*/
ReturnValue_t result;
if (subScheduleId == 0){
result = scheduleMap->setStatus(true);
}else{
result = scheduleMap->setStatusInMap(true, subScheduleId);
}
return result;
}
//complete
ReturnValue_t OPS_Scheduling::disable_Subschedule (SubscheduleId_t subScheduleId)
{
/* bool state = STATE_DISABLED;
return scheduleHelper.setScheduleStatus(state , subScheduleId);*/
ReturnValue_t result;
if (subScheduleId == 0){
result = scheduleMap->setStatus(false);
}else{
result = scheduleMap->setStatusInMap(false, subScheduleId);
}
return result;
}
//complete
ReturnValue_t OPS_Scheduling::performService()
{
Do_Schedule();
Check_Events();
return HasReturnvaluesIF::RETURN_OK;
}
//complete
ReturnValue_t OPS_Scheduling::insertCommandinSchedule(const uint8_t* data, uint16_t size)
{
uint32_t dataLength = 0;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
//get subschedule from packet 1st byte
if (supportSubschedule){
SubscheduleId_t subscheduleId = 0;
getSubschedule(&subscheduleId,data);
data++;
size --;
}
timeval TcTime;
timeval OnboardTime;
//TODO, SSC time format is different
CCSDSTime::convertFromCUC(&TcTime, CCSDSTime::P_FIELD_CUC_6B_CCSDS, data, &dataLength, size)
data += dataLength;
size-= dataLength;
if (NoTimeError){
OSAL::getClock_timeval(&OnboardTime);
if (TcTime < OnboardTime){
return COMMAND_EXPIRED;
}
}else{
//does nothing and continue
}
TcPacketBase NewCommand(data);
if (NewCommand.getFullSize()!=size){
return ILLEGAL_APPLICATION_DATA;
}
store_address_t TcAddress;
result = CommandStorage.addData(&TcAddress, NewCommand.getWholeData(),NewCommand.getFullSize());
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
//Helper should have both options
if (supportSubschedule){
//result = scheduleHelper.addCommandtoSchedule(TcTime,TcAddress, subscheduleId);
bool newSubSchedule = scheduleMap->isNew(subSchedule);
if (newSubschedule){
result = scheduleMap->addsubSchedule();
if (result !=HasReturnvaluesIF::RETURN_OK){
return result;
}
}
return scheduleMap->addCommandEntry(TcTime, TcAddress,subSchedule);
}else{
//result = scheduleHelper.addCommandtoSchedule(TcTime,TcAddress);
return scheduleMap->addCommandEntry(TcTime, TcAddress);
}
//TODO check if it works with RETURN_OK, result is passed from Map
/* if (result!= HasReturnvaluesIF::RETURN_OK){
return SCHEDULE_MAP_FULL;
}*/
}
//only if subschedule supported
void OPS_Scheduling::get_Subschedule( SubscheduleId_t* subscheduleId,const uint8_t* data)
{
*subschdeuleId = *data;
}
//done
ReturnValue_t OPS_Scheduling::resetSchedule()
{
//scheduleHelper.clearSchedule();
scheduleMap->clearScheduleMap();
CommandStorage.clearStore();
SchedulingEnabled= false;
return HasReturnvaluesIF::RETURN_OK;
}
Returnvalue_t OPS_Scheduling::shift_Schedule (const uint8_t* data, uint16_t size){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
timeval time_offset;
uint32_t time_length;
//here the pfield is changed for the epoch not to be CCSDS, the time field is 6 bytes as usual
CCSDSTime::convertFromCUC(&time_offset, CCSDSTime::P_FIELD_CUC_6B_Agency, data, size, &time_length);
result = shiftIsValid(time_offset);
if (result !=HasReturnvaluesIF::RETURN_OK){
return INVALID_SHIFT;
}
//TODO shift returns replies from map, check if it works
//result = scheduleHelper.shiftSchedule(time_offset)
result = scheduleMap->shiftMap(timeOffset)
if (result == HasReturnvaluesIF::RETURN_OK){
return SCHEDULE_SCHIFTED;
}else{
return SCHEDULE_SHIFT_FAILED;
}
}
//it is only for subschedule support case
Returnvalue_t OPS_Scheduling::shift_SubSchedule (const uint8_t* data, uint16_t size){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
timeval timeOffset;
SubschedulId_t subScheduleId = 0;
uint32_t dataLength = 0;
get_Subschedule(&subScheduleId, data);
data ++;
size --;
CCSDSTime::convertFromCUC(&time_offset, CCSDSTime::P_FIELD_CUC_6B_Agency, data, size, &dataLength);
//result = scheduleHelper.shiftIsValid(timeOffset, subSchedule);
result = shiftIsValid(time_offset);
if (result !=HasReturnvaluesIF::RETURN_OK){
return INVALID_SHIFT;
}
//TODO shift returns replies from map, check if it works
//result = scheduleHelper.shiftSchedule(timeOffset, subScheduleId);
bool newSubschedule = scheduleMap->isNew(subscheduleId);
if (newSubschedule){
return SCHEDULE_SHIFT_FAILED;
}
result= scheduleMap->shiftInMap(timeOffset,subscheduleId);
if (result == HasReturnvaluesIF::RETURN_OK){
return SCHEDULE_SCHIFTED;
}else{
return SCHEDULE_SHIFT_FAILED;
}
}
ReturnValue_t OPS_Scheduling::shiftIsValid(timeval timeOffset, SubscheduleId_t subscheduleId){
//can be improved, putting it zero is not the best option
//maybe overloading
timeval scheduleStart = ScheduleMap->FindStart(subscheduleId)
timeval checkTime;//clean this up
timeradd(&scheduleStart, &timeOffset ,&checkTime);
timeval OnboardTime;
OSAL::getClock_timeval(&OnboardTime);
if (checkTime<OnboardTime){
return HasReturnValuesIF::RETURN_FAILED;
}
return HasReturnValuesIF::RETURN_OK;
}
void OPS_Scheduling::do_Schedule()
{
if (schedulingEnabled){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
store_address_t TcAddress;
timeval OnboardTime;
scheduleMap->goToStart();
//scheduleHelper.startScheduleIteration();
//Clock::getClock_timeval(&OnboardTime)
//what is the precison? would this work for schedule??
OSAL::getClock_timeval(&OnboardTime);
while (!reachedEnd()){
//scheduleHelper.getNextValidCommand(OnboardTime, &TcAddress);
scheduleMap->getNextTc(OnboardTime, address);
releaseCommand(TcAddress);
commandStorage.deleteData(TcAddress);
}
}
}
bool OPS_Scheduling::reachedEnd(){
//check syntax TODO
if(scheduleMap->scheduleIterator == scheduleMap->schedule.end()){
return true;
}else{
return false;
}
}
void releaseCommand(store_address_t address){
const uint8_t* pakcet;
uint32_t size;
ReturnValue_t result = commandStorage.getData(TcAddress, &packet, &size);
TcPacketStored Telecommand(packet,size);
if(Telecommand.getWholeData()==NULL){
triggerEvent(COMMAND_LOST);
} else {
message.setStorageId(Telecommand.getStoreAddress());
result=commandQueue.sendToDefault(&message);
if (result!=HasReturnvaluesIF::RETURN_OK){
triggerEvent(COMMAND_LOST,result);
}
}
Telecommand.deletePacket();
}
//still not working TODO
/*ReturnValue_t OPS_Scheduling::Create_Schedule_Report(){
//How big the packet can be??
//what happens if it is bigger than the maximum size?
ScheduleReportTmpacket schedulePacket;
OnboardSchedule_map::iterator it = Schedule.begin();
Subschedule_map::iterator sub_it = NULL;
const uint8_t* tcPacket;
uint32_t size;
timeval tctime;
SubscheduleId_t subscheduleId;
for (it = Schedule.begin();it!=Schedule.end();it++){
subscheduleId = *it.first;
sub_it = ((*it).second).begin();
while (sub_it!=((*it).second).end()){
tcime = *sub_it.first;
result = commandStorage->getData(*sub_it.second, &tcPacket, &tcLen);
schedulePacket.appendCommand(subscheduleId,tctime,tcPacket,tcLen);
this->tcCounter++;
}
}
schedulePacket.setCount(tcCounter);
TmPacketStored tmPacketStored(this->apid, this->serviceId,
subService, this->packetCounter, &schedukeReportPacket);
ReturnValue_t result = tmPacketStored.sendPacket(requestQueue.getDefaultDestination(), requestQueue.getId());
if (result == HasReturnvaluesIF::RETURN_OK) {
this->packetCounter++;
}
}*/
/*void OPS_Scheduling::Check_Events() {
EventMessage message;
for (ReturnValue_t result = eventQueue.receiveMessage(&message);
result == HasReturnvaluesIF::RETURN_OK;
result = eventQueue.receiveMessage(&message)) {
//based on time manager events, react
if (message.getEvent() == TimeManager::TIME_JUMP_DETECTED) {
DisableScheduling();
}
if (message.getEvent() == TimeManager::TIME_WAS_SET) {
NoTimeError = true;
}
//Disable schedule in case a high severity event (soft reboot, safe mode, ..) comes from SYSTEM.
if (message.getReporter() == objects::SYSTEM
&& message.getSeverity() == SEVERITY::HIGH) {
DisableScheduling();
}
}
}*/

View File

@ -1,153 +0,0 @@
/*
* Scheduling.h
*
* Created on: Nov 5, 2019
* Author: mala
*/
#ifndef STUDIO_TMTCSERVICES_SCHEDULING_H_
#define STUDIO_TMTCSERVICES_SCHEDULING_H_
#include <framework/container/FixedOrderedMultimap.h>
#include <framework/storagemanager/LocalPool.h>
#include <framework/timemanager/CCSDSTime.h>
#include <framework/tmtcservices/PusServiceBase.h>
#include "ScheduleTableIF.h"
//make sure this alias works in global scope
typedef uint8_t SubscheduleId_t;
/**
* @brief manages onboard time-based schedule, PUS service 11
* @details
*
* This service is responsible in managing an onboard time-based schedule of telecommands.
* The schedule can be through this service enabled, disabled, and time-shifted
* It can support subschedules. subschedules can be created,enabled and disabled, and time-shifted
*
* The service stores the schedule in the ScheduleMap, which has a ScheduleMapIF.
* Current Map includes subschedules, but it can be replaced by implementing the interface
* The service also can pre-load commands through scheduleLoaderIF.
* scheduleLoader and scheduleTable should be instantiated in factory
*
* right now we do not have control over one single command,in terms of
* shift/disable/delete. it might be required in future though,
*The following constants are in standards but not implemented in this version
*Time margin declared static const Time_Based_Schedule_Margin
*Time between specified release time and actual release time , maximum, declared
*
* @author M.Taheran
*
*/
class OPS_Scheduling: public PusServiceBase {
public:
OPS_Scheduling(uint16_t apid,bool HasInitialSchedule, bool HasSubschedules);
virtual ~OPS_Scheduling();
ReturnValue_t handleRequest(uint8_t subservice) override;
ReturnValue_t performService() override;
ReturnValue_t initialize() override;
protected:
ScheduleTableIF* scheduleMap = nullptr;
ScheduleLoaderIF * scheduleLoader = nullptr;
bool loadInitialSchedule;
bool supportSubschedules;
private:
enum class subServices {
static const uint8_t ENABLE_RELEASE_OF_TC = 1,
static const uint8_t DISABLE_RELEASE_OF_TC =2,
static const uint8_t ENABLE_SUBSCHEDULE = 20,
static const uint8_t DISABLE_SUBSCHEDULE = 21,
//static const uint8_t DELETE_TC = 5;//not implemented
static const uint8_t RESET_SCHEDULE = 3,
static const uint8_t TIMESHIFT_SCHEDULE = 15,
static const uint8_t TIMESHIFT_SUBSCHEDULE = 8,
static const uint8_t INSERT_TC_SCHEDULE = 4,
//TODO
//static const uint8_t REPORT_SCHEDULE = 16;//TM is type 10
};
//Interface and subsystem ID to be included in mission config
static const unit8_t INTERFACE_ID = CLASS_ID::OPS_SCHEDULING_SERVICE;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::OPS_SCHEDULER;
//list of return codes, tbc
static const ReturnValue_t TIME_ERROR = MAKE_RETURN_CODE (1);
static const ReturnValue_t COMMAND_EXPIRED = MAKE_RETURN_CODE (2);
static const ReturnValue_t ILLEGAL_APPLICATION_DATA= MAKE_RETURN_CODE (3);
//static const ReturnValue_t SCHEDULE_MAP_FULL= MAKE_RETURN_CODE (4);
static const ReturnValue_t INVALID_SHIFT= MAKE_RETURN_CODE (4);
static const ReturnValue_t SCHEDULE_SHIFTED= MAKE_RETURN_CODE (5);
static const ReturnValue_t SCHEDULE_SHIFT_FAILED= MAKE_RETURN_CODE (6);
//list of events,tbc
static const Event = OPS_SCHEDULE_DISABLED = MAKE_EVENT(1, SEVERITY::MEDIUM);
static const Event = COMMAND_LOST = MAKE_EVENT (2, SEVERITY::LOW);
static const Event = SCHEDULE_LOAD_FAILED = MAKE_EVENT (3, SEVERITY::MEDIUM);
static const Event = SCHEDULE_LOADED_INCOMPLETE = MAKE_EVENT (4, SEVERITY::LOW);
MessageQueueIF* commandQueue = nullptr;
MessageQueueIF* eventQueue = nullptr;
static const uint8_t N_POOLS = 4;
static const uint16_t POOL_SIZES[N_POOLS];
static const uint16_t N_ELEMENTS[N_POOLS];
LocalPool<N_POOLS> commandStorage;
//only used for reporting on incomplete loading
uint8_t tcCounter = 0;
bool SchedulingEnabled;
bool NoTimeError;
Returnvalue_t enableScheduling();
void disableScheduling();
ReturnValue_t enable_Subschedule (SubscheduleId_t SubScheduleID=0);
ReturnValue_t disable_Subschedule(SubscheduleId_t SubScheduleID=0);
Returnvalue_t resetSchedule();
Returnvalue_t insertCommandinSchedule(const uint8_t* data, uint16_t size);
void do_Schedule();
void check_Events();
Returnvalue_t shift_Schedule (const uint8_t* data, uint16_t size);
Returnvalue_t shift_SubSchedule (const uint8_t* data, uint16_t size);
void shift_Subschedule_Map(OnboardSchedule_map::iterator it, timeval time_delta);
void get_Subschedule(SubscheduleId_t* SubscheduleId,const uint8_t* data, uint32_t maxlength, uint32_t* foundlength, bool* NewId = false);
ReturnValue_t loadSchedule();
void releaseCommand(store_address_t address);
//TODO
//ReturnValue_t Create_Schedule_Report();
#endif /* STUDIO_TMTCSERVICES_SCHEDULING_H_ */

View File

@ -1,29 +0,0 @@
#ifndef SCHEDULELOADERIF_H_
#define SCHEDULELOADERIF_H_
#include<>
//either has returnvalues or include HasReturnValueIF.h
class ScheduleLoaderIF: public HasReturnValuesIF {
public:
/*this interface is used to get commands from another object
* and pass to scheduling to load at first. commands are get one by one
* in an application data packet.
haven't used it for anything else yet. changes come after
we implement the JSON system
*/
//ctor specific to implementation
static const uint8_t INTERFACE_ID = CLASS_ID::SCHEDULE_LOADER_IF;
//add ReturnValues
//TBD
virtual ~ScheduleLoaderIF();
//not sure if needed, might be.
virtual ReturnValue_t initializeLoader() = 0;
virtual ReturnValue_t getCommandPacket(uint8_t **data, uint32_t *size)= 0;
};
#endif