Skip to content

Commit ef8e771

Browse files
Matthias Akstallermatth-x
authored andcommitted
Update C-APIs
* Remove Platform setup functions from MicroOcpp_c.h /.cpp which can be found in Platform.h * Add FilesystemAdapter C-handle * Expose library lifecycle through `ocpp_is_initialized()` * Update Configuration C-API * Update Transaction C-API
1 parent 92764c2 commit ef8e771

File tree

7 files changed

+230
-53
lines changed

7 files changed

+230
-53
lines changed

src/MicroOcpp/Core/Configuration_c.cpp

Lines changed: 128 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ class ConfigurationC : public Configuration, public MemoryManaged {
1515
public:
1616
ConfigurationC(ocpp_configuration *config) :
1717
config(config) {
18-
config->mo_data = this;
18+
if (config->read_only) {
19+
setReadOnly();
20+
}
21+
if (config->write_only) {
22+
setWriteOnly();
23+
}
24+
if (config->reboot_required) {
25+
setRebootRequired();
26+
}
1927
}
2028

2129
bool setKey(const char *key) override {
@@ -116,6 +124,59 @@ class ConfigurationC : public Configuration, public MemoryManaged {
116124
}
117125
};
118126

127+
namespace MicroOcpp {
128+
129+
ConfigurationC *getConfigurationC(ocpp_configuration *config) {
130+
if (!config->mo_data) {
131+
return nullptr;
132+
}
133+
return reinterpret_cast<std::shared_ptr<ConfigurationC>*>(config->mo_data)->get();
134+
}
135+
136+
}
137+
138+
using namespace MicroOcpp;
139+
140+
141+
void ocpp_setRebootRequired(ocpp_configuration *config) {
142+
if (auto c = getConfigurationC(config)) {
143+
c->setRebootRequired();
144+
}
145+
config->reboot_required = true;
146+
}
147+
bool ocpp_isRebootRequired(ocpp_configuration *config) {
148+
if (auto c = getConfigurationC(config)) {
149+
return c->isRebootRequired();
150+
}
151+
return config->reboot_required;
152+
}
153+
154+
void ocpp_setReadOnly(ocpp_configuration *config) {
155+
if (auto c = getConfigurationC(config)) {
156+
c->setReadOnly();
157+
}
158+
config->read_only = true;
159+
}
160+
bool ocpp_isReadOnly(ocpp_configuration *config) {
161+
if (auto c = getConfigurationC(config)) {
162+
return c->isReadOnly();
163+
}
164+
return config->read_only;
165+
}
166+
bool ocpp_isReadable(ocpp_configuration *config) {
167+
if (auto c = getConfigurationC(config)) {
168+
return c->isReadable();
169+
}
170+
return !config->write_only;
171+
}
172+
173+
void ocpp_setWriteOnly(ocpp_configuration *config) {
174+
if (auto c = getConfigurationC(config)) {
175+
c->setWriteOnly();
176+
}
177+
config->write_only = true;
178+
}
179+
119180
class ConfigurationContainerC : public ConfigurationContainer, public MemoryManaged {
120181
private:
121182
ocpp_configuration_container *container;
@@ -125,15 +186,41 @@ class ConfigurationContainerC : public ConfigurationContainer, public MemoryMana
125186

126187
}
127188

189+
~ConfigurationContainerC() {
190+
for (size_t i = 0; i < container->size(container->user_data); i++) {
191+
if (auto config = container->get_configuration(container->user_data, i)) {
192+
if (config->mo_data) {
193+
delete reinterpret_cast<std::shared_ptr<ConfigurationC>*>(config->mo_data);
194+
config->mo_data = nullptr;
195+
}
196+
}
197+
}
198+
}
199+
128200
bool load() override {
129-
return container->load(container->user_data);
201+
if (container->load) {
202+
return container->load(container->user_data);
203+
} else {
204+
return true;
205+
}
130206
}
131207

132208
bool save() override {
133-
return container->save(container->user_data);
209+
if (container->save) {
210+
return container->save(container->user_data);
211+
} else {
212+
return true;
213+
}
134214
}
135215

136216
std::shared_ptr<Configuration> createConfiguration(TConfig type, const char *key) override {
217+
218+
auto result = std::shared_ptr<ConfigurationC>(nullptr, std::default_delete<ConfigurationC>(), makeAllocator<ConfigurationC>(getMemoryTag()));
219+
220+
if (!container->create_configuration) {
221+
return result;
222+
}
223+
137224
ocpp_config_datatype dt;
138225
switch (type) {
139226
case TConfig::Int:
@@ -147,19 +234,38 @@ class ConfigurationContainerC : public ConfigurationContainer, public MemoryMana
147234
break;
148235
default:
149236
MO_DBG_ERR("internal error");
150-
return nullptr;
237+
return result;
151238
}
152239
ocpp_configuration *config = container->create_configuration(container->user_data, dt, key);
240+
if (!config) {
241+
return result;
242+
}
243+
244+
result.reset(new ConfigurationC(config));
153245

154-
if (config) {
155-
return std::allocate_shared<ConfigurationC>(makeAllocator<ConfigurationC>(getMemoryTag()), config);
246+
if (result) {
247+
auto captureConfigC = new std::shared_ptr<ConfigurationC>(result);
248+
config->mo_data = reinterpret_cast<void*>(captureConfigC);
156249
} else {
157250
MO_DBG_ERR("could not create config: %s", key);
158-
return nullptr;
251+
if (container->remove) {
252+
container->remove(container->user_data, key);
253+
}
159254
}
255+
256+
return result;
160257
}
161258

162259
void remove(Configuration *config) override {
260+
if (!container->remove) {
261+
return;
262+
}
263+
264+
if (auto c = container->get_configuration_by_key(container->user_data, config->getKey())) {
265+
delete reinterpret_cast<std::shared_ptr<ConfigurationC>*>(c->mo_data);
266+
c->mo_data = nullptr;
267+
}
268+
163269
container->remove(container->user_data, config->getKey());
164270
}
165271

@@ -170,16 +276,28 @@ class ConfigurationContainerC : public ConfigurationContainer, public MemoryMana
170276
Configuration *getConfiguration(size_t i) override {
171277
auto config = container->get_configuration(container->user_data, i);
172278
if (config) {
173-
return static_cast<Configuration*>(config->mo_data);
279+
if (!config->mo_data) {
280+
auto c = new ConfigurationC(config);
281+
if (c) {
282+
config->mo_data = reinterpret_cast<void*>(new std::shared_ptr<ConfigurationC>(c, std::default_delete<ConfigurationC>(), makeAllocator<ConfigurationC>(getMemoryTag())));
283+
}
284+
}
285+
return static_cast<Configuration*>(config->mo_data ? reinterpret_cast<std::shared_ptr<ConfigurationC>*>(config->mo_data)->get() : nullptr);
174286
} else {
175287
return nullptr;
176288
}
177289
}
178290

179291
std::shared_ptr<Configuration> getConfiguration(const char *key) override {
180-
ocpp_configuration *config = container->get_configuration_by_key(container->user_data, key);
292+
auto config = container->get_configuration_by_key(container->user_data, key);
181293
if (config) {
182-
return std::allocate_shared<ConfigurationC>(makeAllocator<ConfigurationC>(getMemoryTag()), config);
294+
if (!config->mo_data) {
295+
auto c = new ConfigurationC(config);
296+
if (c) {
297+
config->mo_data = reinterpret_cast<void*>(new std::shared_ptr<ConfigurationC>(c, std::default_delete<ConfigurationC>(), makeAllocator<ConfigurationC>(getMemoryTag())));
298+
}
299+
}
300+
return config->mo_data ? *reinterpret_cast<std::shared_ptr<ConfigurationC>*>(config->mo_data) : nullptr;
183301
} else {
184302
return nullptr;
185303
}

src/MicroOcpp/Core/Configuration_c.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,22 @@ typedef struct ocpp_configuration {
4242

4343
uint16_t (*get_write_count) (void *user_data); // Return number of changes of the value. MO uses this to detect if the firmware has updated the config
4444

45+
bool read_only;
46+
bool write_only;
47+
bool reboot_required;
48+
4549
void *mo_data; // Reserved for MO
4650
} ocpp_configuration;
4751

52+
void ocpp_setRebootRequired(ocpp_configuration *config);
53+
bool ocpp_isRebootRequired(ocpp_configuration *config);
54+
55+
void ocpp_setReadOnly(ocpp_configuration *config);
56+
bool ocpp_isReadOnly(ocpp_configuration *config);
57+
bool ocpp_isReadable(ocpp_configuration *config);
58+
59+
void ocpp_setWriteOnly(ocpp_configuration *config);
60+
4861
typedef struct ocpp_configuration_container {
4962
void *user_data; //set this at your choice. MO passes it back to the functions below
5063

src/MicroOcpp/Model/Transactions/Transaction.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,16 @@ const char *ocpp_tx_getIdTag(OCPP_Transaction *tx) {
444444
return reinterpret_cast<MicroOcpp::Transaction*>(tx)->getIdTag();
445445
}
446446

447+
const char *ocpp_tx_getParentIdTag(OCPP_Transaction *tx) {
448+
#if MO_ENABLE_V201
449+
if (g_ocpp_tx_compat_v201) {
450+
MO_DBG_ERR("only supported in v16");
451+
return nullptr;
452+
}
453+
#endif //MO_ENABLE_V201
454+
return reinterpret_cast<MicroOcpp::Transaction*>(tx)->getParentIdTag();
455+
}
456+
447457
bool ocpp_tx_getBeginTimestamp(OCPP_Transaction *tx, char *buf, size_t len) {
448458
#if MO_ENABLE_V201
449459
if (g_ocpp_tx_compat_v201) {

src/MicroOcpp/Model/Transactions/Transaction.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ extern "C" {
1414

1515
//TxNotification - event from MO to the main firmware to notify it about transaction state changes
1616
typedef enum {
17-
UNDEFINED,
17+
TxNotification_UNDEFINED,
1818

1919
//Authorization events
2020
TxNotification_Authorized, //success
@@ -473,6 +473,8 @@ bool ocpp_tx_isCompleted(OCPP_Transaction *tx);
473473

474474
const char *ocpp_tx_getIdTag(OCPP_Transaction *tx);
475475

476+
const char *ocpp_tx_getParentIdTag(OCPP_Transaction *tx);
477+
476478
bool ocpp_tx_getBeginTimestamp(OCPP_Transaction *tx, char *buf, size_t len);
477479

478480
int32_t ocpp_tx_getMeterStart(OCPP_Transaction *tx);

src/MicroOcpp/Platform.h

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
#define MO_PLATFORM MO_PLATFORM_ARDUINO
1717
#endif
1818

19+
#ifdef __cplusplus
20+
#define MO_EXTERN_C extern "C"
21+
#else
22+
#define MO_EXTERN_C
23+
#endif
24+
1925
#if MO_PLATFORM == MO_PLATFORM_NONE
2026
#ifndef MO_CUSTOM_CONSOLE
2127
#define MO_CUSTOM_CONSOLE
@@ -32,18 +38,10 @@
3238
#define MO_CUSTOM_CONSOLE_MAXMSGSIZE 256
3339
#endif
3440

35-
#ifdef __cplusplus
36-
extern "C" {
37-
#endif
38-
3941
extern char _mo_console_msg_buf [MO_CUSTOM_CONSOLE_MAXMSGSIZE]; //define msg_buf in data section to save memory (see https://github.com/matth-x/MicroOcpp/pull/304)
40-
void _mo_console_out(const char *msg);
41-
42-
void mocpp_set_console_out(void (*console_out)(const char *msg));
42+
MO_EXTERN_C void _mo_console_out(const char *msg);
4343

44-
#ifdef __cplusplus
45-
}
46-
#endif
44+
MO_EXTERN_C void mocpp_set_console_out(void (*console_out)(const char *msg));
4745

4846
#define MO_CONSOLE_PRINTF(X, ...) \
4947
do { \
@@ -79,30 +77,30 @@ void mocpp_set_console_out(void (*console_out)(const char *msg));
7977
#endif
8078

8179
#ifdef MO_CUSTOM_TIMER
82-
extern "C" void mocpp_set_timer(unsigned long (*get_ms)());
80+
MO_EXTERN_C void mocpp_set_timer(unsigned long (*get_ms)());
8381

84-
extern "C" unsigned long mocpp_tick_ms_custom();
82+
MO_EXTERN_C unsigned long mocpp_tick_ms_custom();
8583
#define mocpp_tick_ms mocpp_tick_ms_custom
8684
#else
8785

8886
#if MO_PLATFORM == MO_PLATFORM_ARDUINO
8987
#include <Arduino.h>
9088
#define mocpp_tick_ms millis
9189
#elif MO_PLATFORM == MO_PLATFORM_ESPIDF
92-
extern "C" unsigned long mocpp_tick_ms_espidf();
90+
MO_EXTERN_C unsigned long mocpp_tick_ms_espidf();
9391
#define mocpp_tick_ms mocpp_tick_ms_espidf
9492
#elif MO_PLATFORM == MO_PLATFORM_UNIX
95-
extern "C" unsigned long mocpp_tick_ms_unix();
93+
MO_EXTERN_C unsigned long mocpp_tick_ms_unix();
9694
#define mocpp_tick_ms mocpp_tick_ms_unix
9795
#endif
9896
#endif
9997

10098
#ifdef MO_CUSTOM_RNG
101-
void mocpp_set_rng(uint32_t (*rng)());
102-
uint32_t mocpp_rng_custom();
99+
MO_EXTERN_C void mocpp_set_rng(uint32_t (*rng)());
100+
MO_EXTERN_C uint32_t mocpp_rng_custom();
103101
#define mocpp_rng mocpp_rng_custom
104102
#else
105-
uint32_t mocpp_time_based_prng(void);
103+
MO_EXTERN_C uint32_t mocpp_time_based_prng(void);
106104
#define mocpp_rng mocpp_time_based_prng
107105
#endif
108106

0 commit comments

Comments
 (0)