Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions src/MicroOcpp/Core/Time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

#include <MicroOcpp/Core/Time.h>
#include <string.h>
#include <ctype.h>
#include <ctype.h>

namespace MicroOcpp {

const Timestamp MIN_TIME = Timestamp(2010, 0, 0, 0, 0, 0);
const Timestamp MAX_TIME = Timestamp(2037, 0, 0, 0, 0, 0);

Timestamp::Timestamp() : MemoryManaged("Timestamp") {

}

Timestamp::Timestamp(const Timestamp& other) : MemoryManaged("Timestamp") {
Expand All @@ -22,7 +22,7 @@ Timestamp::Timestamp(const Timestamp& other) : MemoryManaged("Timestamp") {
#if MO_ENABLE_TIMESTAMP_MILLISECONDS
Timestamp::Timestamp(int16_t year, int16_t month, int16_t day, int32_t hour, int32_t minute, int32_t second, int32_t ms) :
MemoryManaged("Timestamp"), year(year), month(month), day(day), hour(hour), minute(minute), second(second), ms(ms) { }
#else
#else
Timestamp::Timestamp(int16_t year, int16_t month, int16_t day, int32_t hour, int32_t minute, int32_t second) :
MemoryManaged("Timestamp"), year(year), month(month), day(day), hour(hour), minute(minute), second(second) { }
#endif //MO_ENABLE_TIMESTAMP_MILLISECONDS
Expand Down Expand Up @@ -63,7 +63,7 @@ bool Timestamp::setTime(const char *jsonDateString) {
//ignore subsequent characters
return false;
}

int year = (jsonDateString[0] - '0') * 1000 +
(jsonDateString[1] - '0') * 100 +
(jsonDateString[2] - '0') * 10 +
Expand All @@ -85,7 +85,7 @@ bool Timestamp::setTime(const char *jsonDateString) {
if (isdigit(jsonDateString[20]) || //1
isdigit(jsonDateString[21]) || //2
isdigit(jsonDateString[22])) {

ms = (jsonDateString[20] - '0') * 100 +
(jsonDateString[21] - '0') * 10 +
(jsonDateString[22] - '0');
Expand Down Expand Up @@ -113,7 +113,7 @@ bool Timestamp::setTime(const char *jsonDateString) {
#if MO_ENABLE_TIMESTAMP_MILLISECONDS
this->ms = ms;
#endif //MO_ENABLE_TIMESTAMP_MILLISECONDS

return true;
}

Expand Down Expand Up @@ -188,7 +188,7 @@ Timestamp &Timestamp::operator+=(int secs) {
while (day >= noDays(month, year)) {
day -= noDays(month, year);
month++;

if (month >= 12) {
month -= 12;
year++;
Expand All @@ -213,7 +213,7 @@ Timestamp &Timestamp::addMilliseconds(int val) {
ms += val;

if (ms >= 0 && ms < 1000) return *this;

auto dsecond = ms / 1000;
ms %= 1000;
if (ms < 0) {
Expand All @@ -230,7 +230,7 @@ Timestamp &Timestamp::operator-=(int secs) {

int Timestamp::operator-(const Timestamp &rhs) const {
//dt = rhs - mocpp_base

int16_t year_base, year_end;
if (year <= rhs.year) {
year_base = year;
Expand Down Expand Up @@ -318,7 +318,7 @@ bool operator<(const Timestamp &lhs, const Timestamp &rhs) {
if (lhs.ms != rhs.ms)
return lhs.ms < rhs.ms;
#endif //MO_ENABLE_TIMESTAMP_MILLISECONDS
return false;
return false;
}

bool operator<=(const Timestamp &lhs, const Timestamp &rhs) {
Expand All @@ -341,7 +341,7 @@ Clock::Clock() {
bool Clock::setTime(const char* jsonDateString) {

Timestamp timestamp = Timestamp();

if (!timestamp.setTime(jsonDateString)) {
return false;
}
Expand All @@ -359,6 +359,18 @@ const Timestamp &Clock::now() {
auto tReading = mocpp_tick_ms();
auto delta = tReading - lastUpdate;

// Guard against implausible time jumps caused by overflow or
// concurrency issues (see https://github.com/matth-x/MicroOcpp/issues/421).
// If the delta exceeds a plausible threshold, skip the update entirely
// rather than applying a large time jump. The clock will resync on the
// next setTime() call from the CSMS.
const decltype(delta) MAX_PLAUSIBLE_DELTA_MS = 3600UL * 1000UL; // 1 hour
if (delta > MAX_PLAUSIBLE_DELTA_MS) {
// Reset lastUpdate so the next call starts fresh from here
lastUpdate = tReading;
return currentTime;
}

#if MO_ENABLE_TIMESTAMP_MILLISECONDS
currentTime.addMilliseconds(delta);
lastUpdate = tReading;
Expand Down
5 changes: 4 additions & 1 deletion src/MicroOcpp/Platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ unsigned long mocpp_millis_count = 0;

unsigned long mocpp_tick_ms_espidf() {
auto ticks_now = xTaskGetTickCount();
MicroOcpp::mocpp_millis_count += ((ticks_now - MicroOcpp::mocpp_ticks_count) * 1000UL) / configTICK_RATE_HZ;
auto tick_delta = ticks_now - MicroOcpp::mocpp_ticks_count;
// Use 64-bit intermediate to prevent overflow when tick_delta * 1000
// exceeds ULONG_MAX (~4.3M ticks at 1000 Hz = ~72 min between calls)
MicroOcpp::mocpp_millis_count += (unsigned long)(((unsigned long long)tick_delta * 1000ULL) / configTICK_RATE_HZ);
MicroOcpp::mocpp_ticks_count = ticks_now;
return MicroOcpp::mocpp_millis_count;
}
Expand Down