Skip to content
Merged
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
151 changes: 75 additions & 76 deletions src/MicroOcppMongooseClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ MOcppMongooseClient::MOcppMongooseClient(struct mg_mgr *mgr,
#if !MOCPP_CA_CERT_LOCAL
setting_ca_cert_str = declareConfiguration<const char*>(
MOCPP_CONFIG_EXT_PREFIX "CaCert", CA_cert_factory, MOCPP_WSCONN_FN, readonly, true);
#else
ca_cert = CA_cert_factory ? CA_cert_factory : "";
#endif

ws_ping_interval_int = declareConfiguration<int>(
Expand All @@ -56,17 +58,9 @@ MOcppMongooseClient::MOcppMongooseClient(struct mg_mgr *mgr,
stale_timeout_int = declareConfiguration<int>(
MOCPP_CONFIG_EXT_PREFIX "StaleTimeout", 300, MOCPP_WSCONN_FN);

configuration_load(MOCPP_WSCONN_FN);
configuration_load(MOCPP_WSCONN_FN); //load configs with values stored on flash

backend_url = setting_backend_url_str ? setting_backend_url_str->getString() : "";
cb_id = setting_cb_id_str ? setting_cb_id_str->getString() : "";
auth_key = setting_auth_key_str ? setting_auth_key_str->getString() : "";

#if !MOCPP_CA_CERT_LOCAL
ca_cert = setting_ca_cert_str ? setting_ca_cert_str->getString() : "";
#else
ca_cert = CA_cert_factory ? CA_cert_factory : "";
#endif
reloadConfigs(); //load WS creds with configs values

#if defined(MOCPP_MG_VERSION_614)
MOCPP_DBG_DEBUG("use MG version %s (tested with 6.14)", MG_VERSION);
Expand Down Expand Up @@ -153,11 +147,6 @@ void MOcppMongooseClient::maintainWsConn() {
return;
}

if (credentials_changed) {
reload_credentials();
credentials_changed = false;
}

if (url.empty()) {
//cannot open OCPP connection: credentials missing
return;
Expand Down Expand Up @@ -227,126 +216,136 @@ void MOcppMongooseClient::maintainWsConn() {

}

void MOcppMongooseClient::reload_credentials() {
url.clear();
basic_auth64.clear();

if (backend_url.empty()) {
MOCPP_DBG_DEBUG("empty URL closes connection");
void MOcppMongooseClient::reconnect() {
if (!websocket) {
return;
} else {
url = backend_url;

if (url.back() != '/' && !cb_id.empty()) {
url.append("/");
}

url.append(cb_id);
}

if (!auth_key.empty()) {
std::string token = cb_id + ":" + auth_key;

MOCPP_DBG_DEBUG("auth Token=%s", token.c_str());

unsigned int base64_length = encode_base64_length(token.length());
std::vector<unsigned char> base64 (base64_length + 1);

// encode_base64() places a null terminator automatically, because the output is a string
base64_length = encode_base64((const unsigned char*) token.c_str(), token.length(), &base64[0]);

MOCPP_DBG_DEBUG("auth64 len=%u, auth64 Token=%s", base64_length, &base64[0]);

basic_auth64 = (const char*) &base64[0];
} else {
MOCPP_DBG_DEBUG("no authentication");
(void) 0;
#if defined(MOCPP_MG_VERSION_614)
if (!connection_closing) {
const char *msg = "socket closed by client";
mg_send_websocket_frame(websocket, WEBSOCKET_OP_CLOSE, msg, strlen(msg));
}
#else
websocket->is_closing = 1; //Mongoose will close the socket and the following maintainWsConn() call will open it again
#endif
setConnectionOpen(false);
}

void MOcppMongooseClient::setBackendUrl(const char *backend_url_cstr) {
if (!backend_url_cstr) {
MOCPP_DBG_ERR("invalid argument");
return;
}
backend_url = backend_url_cstr;

if (setting_backend_url_str) {
setting_backend_url_str->setString(backend_url_cstr);
configuration_save();
}

credentials_changed = true; //reload composed credentials when reconnecting the next time

reconnect();
}

void MOcppMongooseClient::setChargeBoxId(const char *cb_id_cstr) {
if (!cb_id_cstr) {
MOCPP_DBG_ERR("invalid argument");
return;
}
cb_id = cb_id_cstr;

if (setting_cb_id_str) {
setting_cb_id_str->setString(cb_id_cstr);
configuration_save();
}

credentials_changed = true; //reload composed credentials when reconnecting the next time

reconnect();
}

void MOcppMongooseClient::setAuthKey(const char *auth_key_cstr) {
if (!auth_key_cstr) {
MOCPP_DBG_ERR("invalid argument");
return;
}
auth_key = auth_key_cstr;

if (setting_auth_key_str) {
setting_auth_key_str->setString(auth_key_cstr);
configuration_save();
}

credentials_changed = true; //reload composed credentials when reconnecting the next time

reconnect();
}

void MOcppMongooseClient::setCaCert(const char *ca_cert_cstr) {
if (!ca_cert_cstr) {
MOCPP_DBG_ERR("invalid argument");
return;
}
ca_cert = ca_cert_cstr;

#if !MOCPP_CA_CERT_LOCAL
if (setting_ca_cert_str) {
setting_ca_cert_str->setString(ca_cert_cstr);
configuration_save();
}
#else
ca_cert = ca_cert_cstr; //updated ca_cert takes immediate effect
#endif
}

credentials_changed = true; //reload composed credentials when reconnecting the next time
void MOcppMongooseClient::reloadConfigs() {

reconnect();
}
reconnect(); //closes WS connection; will be reopened in next maintainWsConn execution

void MOcppMongooseClient::reconnect() {
if (!websocket) {
return;
/*
* reload WS credentials from configs
*/
if (setting_backend_url_str) {
backend_url = setting_backend_url_str->getString();
}
#if defined(MOCPP_MG_VERSION_614)
if (!connection_closing) {
const char *msg = "socket closed by client";
mg_send_websocket_frame(websocket, WEBSOCKET_OP_CLOSE, msg, strlen(msg));

if (setting_cb_id_str) {
cb_id = setting_cb_id_str->getString();
}

if (setting_auth_key_str) {
auth_key = setting_auth_key_str->getString();
}

#if !MOCPP_CA_CERT_LOCAL
if (setting_ca_cert_str) {
ca_cert = setting_ca_cert_str->getString();
}
#else
websocket->is_closing = 1; //Mongoose will close the socket and the following maintainWsConn() call will open it again
#endif
setConnectionOpen(false);

/*
* determine new URL and auth token with updated WS credentials
*/

url.clear();
basic_auth64.clear();

if (backend_url.empty()) {
MOCPP_DBG_DEBUG("empty URL closes connection");
return;
} else {
url = backend_url;

if (url.back() != '/' && !cb_id.empty()) {
url.append("/");
}

url.append(cb_id);
}

if (!auth_key.empty()) {
std::string token = cb_id + ":" + auth_key;

MOCPP_DBG_DEBUG("auth Token=%s", token.c_str());

unsigned int base64_length = encode_base64_length(token.length());
std::vector<unsigned char> base64 (base64_length + 1);

// encode_base64() places a null terminator automatically, because the output is a string
base64_length = encode_base64((const unsigned char*) token.c_str(), token.length(), &base64[0]);

MOCPP_DBG_DEBUG("auth64 len=%u, auth64 Token=%s", base64_length, &base64[0]);

basic_auth64 = (const char*) &base64[0];
} else {
MOCPP_DBG_DEBUG("no authentication");
(void) 0;
}
}

void MOcppMongooseClient::setConnectionOpen(bool open) {
Expand Down
6 changes: 3 additions & 3 deletions src/MicroOcppMongooseClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ class MOcppMongooseClient : public MicroOcpp::Connection {
bool connection_closing {false};
ReceiveTXTcallback receiveTXTcallback = [] (const char *, size_t) {return false;};

bool credentials_changed {true}; //set credentials to be reloaded
void reload_credentials();
void reconnect();

void maintainWsConn();

Expand All @@ -88,12 +87,13 @@ class MOcppMongooseClient : public MicroOcpp::Connection {
return receiveTXTcallback;
}

//update WS configs. To apply the updates, call `reloadConfigs()` afterwards
void setBackendUrl(const char *backend_url);
void setChargeBoxId(const char *cb_id);
void setAuthKey(const char *auth_key);
void setCaCert(const char *ca_cert); //forwards this string to Mongoose as ssl_ca_cert (see https://github.com/cesanta/mongoose/blob/ab650ec5c99ceb52bb9dc59e8e8ec92a2724932b/mongoose.h#L4192)

void reconnect(); //after updating all credentials, reconnect to apply them
void reloadConfigs();

const char *getBackendUrl() {return backend_url.c_str();}
const char *getChargeBoxId() {return cb_id.c_str();}
Expand Down
4 changes: 2 additions & 2 deletions src/MicroOcppMongooseClient_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ void ocpp_setCaCert(OCPP_Connection *sock, const char *ca_cert) {
mgsock->setCaCert(ca_cert);
}

void ocpp_reconnect(OCPP_Connection *sock) {
void ocpp_reloadConfigs(OCPP_Connection *sock) {
if (!sock) {
MOCPP_DBG_ERR("invalid argument");
return;
}
auto mgsock = reinterpret_cast<MOcppMongooseClient*>(sock);
mgsock->reconnect();
mgsock->reloadConfigs();
}

const char *ocpp_getBackendUrl(OCPP_Connection *sock) {
Expand Down
3 changes: 2 additions & 1 deletion src/MicroOcppMongooseClient_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ OCPP_Connection *ocpp_makeConnection(struct mg_mgr *mgr,

void ocpp_deinitConnection(OCPP_Connection *sock);

//update WS configs. To apply the updates, call `ocpp_reloadConfigs()` afterwards
void ocpp_setBackendUrl(OCPP_Connection *sock, const char *backend_url);
void ocpp_setChargeBoxId(OCPP_Connection *sock, const char *cb_id);
void ocpp_setAuthKey(OCPP_Connection *sock, const char *auth_key);
void ocpp_setCaCert(OCPP_Connection *sock, const char *ca_cert);

void ocpp_reconnect(OCPP_Connection *sock); //after updating all credentials, reconnect to apply them
void ocpp_reloadConfigs(OCPP_Connection *sock);

const char *ocpp_getBackendUrl(OCPP_Connection *sock);
const char *ocpp_getChargeBoxId(OCPP_Connection *sock);
Expand Down