Skip to content

Commit dbd8786

Browse files
authored
OCPP 2.0.1 BasicAuthPassword integration (#13)
* integrate v201 basic authentication * fix BasicAuthPassword * update changelog
1 parent e0a6ab3 commit dbd8786

File tree

3 files changed

+98
-30
lines changed

3 files changed

+98
-30
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
## Unreleased
44

55
### Added
6-
- Mongoose v7.13 support ([#11](https://github.com/matth-x/MicroOcppMongoose/pull/11)
6+
- Mongoose v7.13 support ([#11](https://github.com/matth-x/MicroOcppMongoose/pull/11))
7+
- OCPP 2.0.1 BasicAuthPassword integration ([#13](https://github.com/matth-x/MicroOcppMongoose/pull/13))
78

89
### Fixed
910
- AuthorizationKey hex conversion ([#12](https://github.com/matth-x/MicroOcppMongoose/pull/12))

src/MicroOcppMongooseClient.cpp

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
#include <MicroOcpp/Core/Configuration.h>
77
#include <MicroOcpp/Debug.h>
88

9+
#if MO_ENABLE_V201
10+
#include <MicroOcpp/Model/Variables/VariableContainer.h>
11+
#endif
12+
913
#define DEBUG_MSG_INTERVAL 5000UL
1014
#define WS_UNRESPONSIVE_THRESHOLD_MS 15000UL
1115

@@ -68,16 +72,32 @@ MOcppMongooseClient::MOcppMongooseClient(struct mg_mgr *mgr,
6872
MO_DBG_WARN("auth_key_factory too long - will be cropped");
6973
auth_key_factory_len = MO_AUTHKEY_LEN_MAX;
7074
}
71-
char auth_key_hex [2 * MO_AUTHKEY_LEN_MAX + 1];
72-
auth_key_hex[0] = '\0';
73-
if (auth_key_factory) {
74-
for (size_t i = 0; i < auth_key_factory_len; i++) {
75-
snprintf(auth_key_hex + 2 * i, 3, "%02X", auth_key_factory[i]);
75+
76+
#if MO_ENABLE_V201
77+
if (protocolVersion.major == 2) {
78+
websocketSettings = makeVariableContainerVolatile(MO_WSCONN_FN_V201, true);
79+
auto variable = websocketSettings->createVariable(Variable::InternalDataType::String, Variable::AttributeType::Actual);
80+
variable->setComponentId("SecurityCtrlr");
81+
variable->setName("BasicAuthPassword");
82+
char basicAuthPassword [MO_AUTHKEY_LEN_MAX + 1];
83+
snprintf(basicAuthPassword, sizeof(basicAuthPassword), "%.*s", (int)auth_key_factory_len, auth_key_factory ? (const char*)auth_key_factory : "");
84+
variable->setString(basicAuthPassword);
85+
websocketSettings->add(std::move(variable));
86+
basicAuthPasswordString = websocketSettings->getVariable("SecurityCtrlr", "BasicAuthPassword");
87+
} else
88+
#endif
89+
{
90+
char auth_key_hex [2 * MO_AUTHKEY_LEN_MAX + 1];
91+
auth_key_hex[0] = '\0';
92+
if (auth_key_factory) {
93+
for (size_t i = 0; i < auth_key_factory_len; i++) {
94+
snprintf(auth_key_hex + 2 * i, 3, "%02X", auth_key_factory[i]);
95+
}
7696
}
97+
setting_auth_key_hex_str = declareConfiguration<const char*>(
98+
"AuthorizationKey", auth_key_hex, MO_WSCONN_FN, readonly, true);
99+
registerConfigurationValidator("AuthorizationKey", validateAuthorizationKeyHex);
77100
}
78-
setting_auth_key_hex_str = declareConfiguration<const char*>(
79-
"AuthorizationKey", auth_key_hex, MO_WSCONN_FN, readonly, true);
80-
registerConfigurationValidator("AuthorizationKey", validateAuthorizationKeyHex);
81101

82102
ws_ping_interval_int = declareConfiguration<int>(
83103
"WebSocketPingInterval", 5, MO_WSCONN_FN);
@@ -378,15 +398,26 @@ void MOcppMongooseClient::setAuthKey(const unsigned char *auth_key, size_t len)
378398
return;
379399
}
380400

381-
char auth_key_hex [2 * MO_AUTHKEY_LEN_MAX + 1];
382-
auth_key_hex[0] = '\0';
383-
for (size_t i = 0; i < len; i++) {
384-
snprintf(auth_key_hex + 2 * i, 3, "%02X", auth_key[i]);
385-
}
386401

387-
if (setting_auth_key_hex_str) {
388-
setting_auth_key_hex_str->setString(auth_key_hex);
389-
configuration_save();
402+
#if MO_ENABLE_V201
403+
if (protocolVersion.major == 2) {
404+
char basicAuthPassword [MO_AUTHKEY_LEN_MAX + 1];
405+
snprintf(basicAuthPassword, sizeof(basicAuthPassword), "%.*s", (int)len, auth_key ? (const char*)auth_key : "");
406+
if (basicAuthPasswordString) {
407+
basicAuthPasswordString->setString(basicAuthPassword);
408+
}
409+
} else
410+
#endif
411+
{
412+
char auth_key_hex [2 * MO_AUTHKEY_LEN_MAX + 1];
413+
auth_key_hex[0] = '\0';
414+
for (size_t i = 0; i < len; i++) {
415+
snprintf(auth_key_hex + 2 * i, 3, "%02X", auth_key[i]);
416+
}
417+
if (setting_auth_key_hex_str) {
418+
setting_auth_key_hex_str->setString(auth_key_hex);
419+
configuration_save();
420+
}
390421
}
391422
}
392423

@@ -409,19 +440,29 @@ void MOcppMongooseClient::reloadConfigs() {
409440
cb_id = setting_cb_id_str->getString();
410441
}
411442

412-
if (setting_auth_key_hex_str) {
413-
auto auth_key_hex = setting_auth_key_hex_str->getString();
414-
415-
#if MO_MG_VERSION_614
416-
cs_from_hex((char*)auth_key, auth_key_hex, strlen(auth_key_hex));
417-
#elif MO_MG_USE_VERSION <= MO_MG_V713
418-
mg_unhex(auth_key_hex, strlen(auth_key_hex), auth_key);
419-
#else
420-
mg_str_to_num(mg_str(auth_key_hex), 16, auth_key, MO_AUTHKEY_LEN_MAX);
421-
#endif
443+
#if MO_ENABLE_V201
444+
if (protocolVersion.major == 2) {
445+
if (basicAuthPasswordString) {
446+
snprintf((char*)auth_key, sizeof(auth_key), "%s", basicAuthPasswordString->getString());
447+
auth_key_len = strlen((char*)auth_key);
448+
}
449+
} else
450+
#endif
451+
{
452+
if (setting_auth_key_hex_str) {
453+
auto auth_key_hex = setting_auth_key_hex_str->getString();
454+
455+
#if MO_MG_VERSION_614
456+
cs_from_hex((char*)auth_key, auth_key_hex, strlen(auth_key_hex));
457+
#elif MO_MG_USE_VERSION <= MO_MG_V713
458+
mg_unhex(auth_key_hex, strlen(auth_key_hex), auth_key);
459+
#else
460+
mg_str_to_num(mg_str(auth_key_hex), 16, auth_key, MO_AUTHKEY_LEN_MAX);
461+
#endif
422462

423-
auth_key_len = strlen(setting_auth_key_hex_str->getString()) / 2;
424-
auth_key[auth_key_len] = '\0'; //need null-termination as long as deprecated `const char *getAuthKey()` exists
463+
auth_key_len = strlen(setting_auth_key_hex_str->getString()) / 2;
464+
auth_key[auth_key_len] = '\0'; //need null-termination as long as deprecated `const char *getAuthKey()` exists
465+
}
425466
}
426467

427468
/*
@@ -480,6 +521,12 @@ unsigned long MOcppMongooseClient::getLastConnected() {
480521
return last_connection_established;
481522
}
482523

524+
#if MO_ENABLE_V201
525+
std::shared_ptr<VariableContainer> MOcppMongooseClient::getVariableContainer() {
526+
return websocketSettings;
527+
}
528+
#endif
529+
483530
#if MO_MG_USE_VERSION == MO_MG_V614
484531

485532
void ws_cb(struct mg_connection *nc, int ev, void *ev_data, void *user_data) {

src/MicroOcppMongooseClient.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,33 @@
1919

2020
#ifndef MO_WSCONN_FN
2121
#define MO_WSCONN_FN (MO_FILENAME_PREFIX "ws-conn.jsn")
22+
#define MO_WSCONN_FN_V201 (MO_FILENAME_PREFIX "ws-conn-v201.jsn")
2223
#endif
2324

25+
#if MO_ENABLE_V201
26+
#define MO_AUTHKEY_LEN_MAX 40 //BasicAuthPassword length
27+
#else
2428
#define MO_AUTHKEY_LEN_MAX 20 //AuthKey in Bytes. Hex value has double length
29+
#endif
2530

2631
namespace MicroOcpp {
2732

2833
class FilesystemAdapter;
2934
class Configuration;
3035

36+
#if MO_ENABLE_V201
37+
class Variable;
38+
class VariableContainer;
39+
#endif
40+
3141
class MOcppMongooseClient : public MicroOcpp::Connection {
3242
private:
3343
struct mg_mgr *mgr {nullptr};
3444
struct mg_connection *websocket {nullptr};
3545
std::string backend_url;
3646
std::string cb_id;
3747
std::string url; //url = backend_url + '/' + cb_id
38-
unsigned char auth_key [MO_AUTHKEY_LEN_MAX + 1]; //AuthKey in bytes encoding ("FF01" = {0xFF, 0x01})
48+
unsigned char auth_key [MO_AUTHKEY_LEN_MAX + 1]; //OCPP 2.0.1: BasicAuthPassword. OCPP 1.6: AuthKey in bytes encoding ("FF01" = {0xFF, 0x01}). Both versions append a terminating '\0'
3949
size_t auth_key_len;
4050
const char *ca_cert; //zero-copy. The host system must ensure that this pointer remains valid during the lifetime of this class
4151
std::shared_ptr<Configuration> setting_backend_url_str;
@@ -47,6 +57,10 @@ class MOcppMongooseClient : public MicroOcpp::Connection {
4757
std::shared_ptr<Configuration> stale_timeout_int; //inactivity period after which the connection will be closed
4858
std::shared_ptr<Configuration> ws_ping_interval_int; //heartbeat intervall in s. 0 sets hb off
4959
unsigned long last_hb {0};
60+
#if MO_ENABLE_V201
61+
std::shared_ptr<VariableContainer> websocketSettings;
62+
Variable *basicAuthPasswordString = nullptr;
63+
#endif
5064
bool connection_established {false};
5165
unsigned long last_connection_established {-1UL / 2UL};
5266
bool connection_closing {false};
@@ -115,6 +129,12 @@ class MOcppMongooseClient : public MicroOcpp::Connection {
115129
void updateRcvTimer();
116130
unsigned long getLastRecv(); //get time of last successful receive in millis
117131
unsigned long getLastConnected(); //get time of last connection establish
132+
133+
#if MO_ENABLE_V201
134+
//WS client creates and manages its own Variables. This getter function is a temporary solution, in future
135+
//the WS client will be initialized with a Context reference for registering the Variables directly
136+
std::shared_ptr<VariableContainer> getVariableContainer();
137+
#endif
118138
};
119139

120140
}

0 commit comments

Comments
 (0)