Skip to content

Commit

Permalink
Fix for infinate loop in getNextEvent
Browse files Browse the repository at this point in the history
getNextEvent could get stuck in an infinate loop if searching for a type that is not in the list. This can happen when there is only enteries ofa single type, eg disabled and you search for active, as the LCD module does causing a watchdog timeout.

Fixes #414
  • Loading branch information
jeremypoulter committed Feb 21, 2023
1 parent 39dddf8 commit 169c789
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
26 changes: 13 additions & 13 deletions src/lcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,13 +324,13 @@ LcdTask::LcdInfoLine LcdTask::getNextInfoLine(LcdInfoLine info)
case LcdInfoLine::Time:
return LcdInfoLine::Date;
case LcdInfoLine::Date:
return _scheduler->getNextEvent().isValid() ?
LcdInfoLine::TimerStart :
LcdInfoLine::EnergySession;
if(_scheduler->getNextEvent(EvseState::Active).isValid()) {
return LcdInfoLine::TimerStart;
}
case LcdInfoLine::TimerStart:
return _scheduler->getNextEvent().isValid() ?
LcdInfoLine::TimerStop :
LcdInfoLine::EnergySession;
if(_scheduler->getNextEvent(EvseState::Disabled).isValid()) {
return LcdInfoLine::TimerStop;
}
default:
return LcdInfoLine::EnergySession;
}
Expand All @@ -353,7 +353,7 @@ LcdTask::LcdInfoLine LcdTask::getNextInfoLine(LcdInfoLine info)
case LcdInfoLine::EnergyTotal:
return LcdInfoLine::Temperature;
case LcdInfoLine::Temperature:
if(_scheduler->getNextEvent().isValid()) {
if(_scheduler->getNextEvent(EvseState::Disabled).isValid()) {
return LcdInfoLine::TimerStop;
}
case LcdInfoLine::TimerStop:
Expand Down Expand Up @@ -388,13 +388,13 @@ LcdTask::LcdInfoLine LcdTask::getNextInfoLine(LcdInfoLine info)
case LcdInfoLine::Time:
return LcdInfoLine::Date;
case LcdInfoLine::Date:
return _scheduler->getNextEvent().isValid() ?
LcdInfoLine::TimerStart :
LcdInfoLine::Time;
if(_scheduler->getNextEvent(EvseState::Active).isValid()) {
return LcdInfoLine::TimerStart;
}
case LcdInfoLine::TimerStart:
return _scheduler->getNextEvent().isValid() ?
LcdInfoLine::TimerStop :
LcdInfoLine::Time;
if(_scheduler->getNextEvent(EvseState::Disabled).isValid()) {
return LcdInfoLine::TimerStop;
}
default:
return LcdInfoLine::Time;
}
Expand Down
13 changes: 12 additions & 1 deletion src/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

uint32_t Scheduler::Event::_next_id = 1;

Scheduler::EventInstance nullEventInstance;

const char * days_of_the_week_strings[] = {
"sunday",
"monday",
Expand Down Expand Up @@ -422,14 +424,23 @@ Scheduler::EventInstance &Scheduler::getCurrentEvent()

Scheduler::EventInstance &Scheduler::getNextEvent(EvseState type)
{
DBUGVAR(type);
EventInstance *event = &_activeEvent; // Assume active event is correct
if(event->isValid())
{
event = &event->getNext();
if(EvseState::None != type)
{
while(event->getState() != type) {
EventInstance *startEvent = event;

while(event->getState() != type)
{
event = &event->getNext();
DBUGVAR((uint32_t)event, HEX);
DBUGVAR((uint32_t)startEvent, HEX);
if(startEvent == event) {

This comment has been minimized.

Copy link
@KipK

KipK Mar 5, 2023

Collaborator

@jeremypoulter , can this block here be the culprit of this issue ? KipK/openevse-gui-v2#31 (comment)

This comment has been minimized.

Copy link
@KipK

KipK Mar 5, 2023

Collaborator

if (startEvent == event && event->getEvent() == event->getNext().getEvent() )
Does this will avoid the issue ? not sure

return nullEventInstance;
}
}
}
}
Expand Down

0 comments on commit 169c789

Please sign in to comment.