Skip to content

Commit 1815711

Browse files
authored
Merge branch 'main' into feature/v201-api-upgrade
2 parents ad0fe21 + 2d5dee9 commit 1815711

File tree

13 files changed

+145
-12
lines changed

13 files changed

+145
-12
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
### Changed
66

77
- Change `MicroOcpp::TxNotification` into C-style enum, replace `OCPP_TxNotication`
8+
- Improved UUID generation ([#383](https://github.com/matth-x/MicroOcpp/pull/383))
9+
10+
### Fixed
11+
12+
- Timing issues for OCTT test cases ([#383](https://github.com/matth-x/MicroOcpp/pull/383))
813

914
## [1.2.0] - 2024-11-03
1015

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ set(MO_SRC
2323
src/MicroOcpp/Core/Request.cpp
2424
src/MicroOcpp/Core/Connection.cpp
2525
src/MicroOcpp/Core/Time.cpp
26+
src/MicroOcpp/Core/UuidUtils.cpp
2627
src/MicroOcpp/Operations/Authorize.cpp
2728
src/MicroOcpp/Operations/BootNotification.cpp
2829
src/MicroOcpp/Operations/CancelReservation.cpp

src/MicroOcpp/Core/Request.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <MicroOcpp/Core/Operation.h>
77
#include <MicroOcpp/Core/Connection.h>
88
#include <MicroOcpp/Model/Transactions/Transaction.h>
9+
#include <MicroOcpp/Core/UuidUtils.h>
910

1011
#include <MicroOcpp/Operations/StartTransaction.h>
1112
#include <MicroOcpp/Operations/StopTransaction.h>
@@ -68,16 +69,9 @@ void Request::setMessageID(const char *id){
6869
Request::CreateRequestResult Request::createRequest(JsonDoc& requestJson) {
6970

7071
if (messageID.empty()) {
71-
unsigned char random [18];
72-
char guuid [sizeof(random) * 2 + 1];
73-
74-
writeRandomNonsecure(random, sizeof(random));
75-
76-
for (size_t i = 0; i < sizeof(random); i++) {
77-
snprintf(guuid + i * 2, 3, "%02x", random[i]);
78-
}
79-
guuid[8] = guuid[13] = guuid[18] = guuid[23] = '-';
80-
messageID = guuid;
72+
char uuid [37] = {'\0'};
73+
generateUUID(uuid, 37);
74+
messageID = uuid;
8175
}
8276

8377
/*

src/MicroOcpp/Core/Time.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,13 @@ int Timestamp::operator-(const Timestamp &rhs) const {
255255
}
256256

257257
int dt = (lhsDays - rhsDays) * (24 * 3600) + (hour - rhs.hour) * 3600 + (minute - rhs.minute) * 60 + second - rhs.second;
258+
259+
#if MO_ENABLE_TIMESTAMP_MILLISECONDS
260+
// Make it so that we round the difference to the nearest second, instead of being up to almost a whole second off
261+
if ((ms - rhs.ms) > 500) dt++;
262+
if ((ms - rhs.ms) < -500) dt--;
263+
#endif //MO_ENABLE_TIMESTAMP_MILLISECONDS
264+
258265
return dt;
259266
}
260267

src/MicroOcpp/Core/UuidUtils.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <MicroOcpp/Core/UuidUtils.h>
2+
#include <MicroOcpp/Platform.h>
3+
4+
#include <stdint.h>
5+
6+
namespace MicroOcpp {
7+
8+
#define UUID_STR_LEN 36
9+
10+
bool generateUUID(char *uuidBuffer, size_t len) {
11+
if (len < UUID_STR_LEN + 1)
12+
{
13+
return false;
14+
}
15+
16+
uint32_t ar[4];
17+
for (uint8_t i = 0; i < 4; i++) {
18+
ar[i] = mocpp_rng();
19+
}
20+
21+
// Conforming to RFC 4122 Specification
22+
// - byte 7: four most significant bits ==> 0100 --> always 4
23+
// - byte 9: two most significant bits ==> 10 --> always {8, 9, A, B}.
24+
//
25+
// patch bits for version 1 and variant 4 here
26+
ar[1] &= 0xFFF0FFFF; // remove 4 bits.
27+
ar[1] |= 0x00040000; // variant 4
28+
ar[2] &= 0xFFFFFFF3; // remove 2 bits
29+
ar[2] |= 0x00000008; // version 1
30+
31+
// loop through the random 16 byte array
32+
for (uint8_t i = 0, j = 0; i < 16; i++) {
33+
// multiples of 4 between 8 and 20 get a -.
34+
// note we are processing 2 digits in one loop.
35+
if ((i & 0x1) == 0) {
36+
if ((4 <= i) && (i <= 10)) {
37+
uuidBuffer[j++] = '-';
38+
}
39+
}
40+
41+
// encode the byte as two hex characters
42+
uint8_t nr = i / 4;
43+
uint8_t xx = ar[nr];
44+
uint8_t ch = xx & 0x0F;
45+
uuidBuffer[j++] = (ch < 10)? '0' + ch : ('a' - 10) + ch;
46+
47+
ch = (xx >> 4) & 0x0F;
48+
ar[nr] >>= 8;
49+
uuidBuffer[j++] = (ch < 10)? '0' + ch : ('a' - 10) + ch;
50+
}
51+
52+
uuidBuffer[UUID_STR_LEN] = 0;
53+
return true;
54+
}
55+
56+
}

src/MicroOcpp/Core/UuidUtils.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef MO_UUIDUTILS_H
2+
#define MO_UUIDUTILS_H
3+
4+
#include <stddef.h>
5+
namespace MicroOcpp {
6+
7+
// Generates a UUID (Universally Unique Identifier) and writes it into a given buffer
8+
// Returns false if the generation failed
9+
// The buffer must be at least 37 bytes long (36 characters + zero termination)
10+
bool generateUUID(char *uuidBuffer, size_t len);
11+
12+
}
13+
14+
#endif

src/MicroOcpp/Model/ConnectorBase/Connector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ void Connector::loop() {
305305
transaction->getBeginTimestamp() > MIN_TIME &&
306306
connectionTimeOutInt && connectionTimeOutInt->getInt() > 0 &&
307307
!connectorPluggedInput() &&
308-
model.getClock().now() - transaction->getBeginTimestamp() >= connectionTimeOutInt->getInt()) {
308+
model.getClock().now() - transaction->getBeginTimestamp() > connectionTimeOutInt->getInt()) {
309309

310310
MO_DBG_INFO("Session mngt: timeout");
311311
transaction->setInactive();

src/MicroOcpp/Model/Heartbeat/HeartbeatService.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ void HeartbeatService::loop() {
2929
lastHeartbeat = now;
3030

3131
auto heartbeat = makeRequest(new Ocpp16::Heartbeat(context.getModel()));
32+
// Heartbeats can not deviate more than 4s from the configured interval
33+
heartbeat->setTimeout(std::min(4000UL, hbInterval));
3234
context.initiateRequest(std::move(heartbeat));
3335
}
3436
}

src/MicroOcpp/Model/Metering/MeteringConnector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void MeteringConnector::loop() {
9090

9191
auto& timestampNow = model.getClock().now();
9292
auto dt = nextAlignedTime - timestampNow;
93-
if (dt <= 0 || //normal case: interval elapsed
93+
if (dt < 0 || //normal case: interval elapsed
9494
dt > clockAlignedDataIntervalInt->getInt()) { //special case: clock has been adjusted or first run
9595

9696
MO_DBG_DEBUG("Clock aligned measurement %ds: %s", dt,

src/MicroOcpp/Platform.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,31 @@ unsigned long mocpp_tick_ms_unix() {
8282
}
8383
#endif
8484
#endif
85+
86+
#ifdef MO_CUSTOM_RNG
87+
uint32_t (*mocpp_rng_impl)() = nullptr;
88+
89+
void mocpp_set_rng(uint32_t (*rng)()) {
90+
mocpp_rng_impl = rng;
91+
}
92+
93+
uint32_t mocpp_rng_custom(void) {
94+
if (mocpp_rng_impl) {
95+
return mocpp_rng_impl();
96+
} else {
97+
return 0;
98+
}
99+
}
100+
#else
101+
102+
// Time-based Pseudo RNG.
103+
// Contains internal state which is mixed with the current timestamp
104+
// each time it is called. Then this is passed through a multiply-with-carry
105+
// PRNG operation to get a pseudo-random number.
106+
uint32_t mocpp_time_based_prng(void) {
107+
static uint32_t prng_state = 1;
108+
uint32_t entropy = mocpp_tick_ms();
109+
prng_state = (prng_state ^ entropy)*1664525U + 1013904223U; // assuming complement-2 integers and non-signaling overflow
110+
return prng_state;
111+
}
112+
#endif

0 commit comments

Comments
 (0)