Skip to content

Commit 0455ec0

Browse files
authored
Merge pull request #400 from matth-x/feature/improve-platform-compat
Improvements for custom platform integrations
2 parents 4b080f6 + bb88b16 commit 0455ec0

File tree

16 files changed

+279
-65
lines changed

16 files changed

+279
-65
lines changed

.github/workflows/documentation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ jobs:
158158
uses: actions/checkout@v3
159159
with:
160160
repository: google/bloaty
161-
ref: 379d5305670c00c36a57e608079fd253f13bde63
161+
ref: e1155149d54bb09b81e86f0e4e5cb7fbd2a318eb
162162
path: tools/bloaty
163163
submodules: recursive
164164
- name: Install bloaty

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
run: ./build/mo_unit_tests --abort
5353
- name: Create coverage report
5454
run: |
55-
lcov --directory . --capture --output-file coverage.info
55+
lcov --directory . --capture --output-file coverage.info --ignore-errors mismatch
5656
lcov --remove coverage.info '/usr/*' '*/tests/*' '*/ArduinoJson.h' --output-file coverage.info
5757
lcov --list coverage.info
5858
- name: Upload coverage reports to Codecov

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@
77
- Change `MicroOcpp::TxNotification` into C-style enum, replace `OCPP_TxNotication` ([#386](https://github.com/matth-x/MicroOcpp/pull/386))
88
- Improved UUID generation ([#383](https://github.com/matth-x/MicroOcpp/pull/383))
99
- `beginTransaction()` returns bool for better v2.0.1 interop ([#386](https://github.com/matth-x/MicroOcpp/pull/386))
10+
- Configurations C-API updates ([#400](https://github.com/matth-x/MicroOcpp/pull/400))
11+
- Platform integrations C-API upates ([#400](https://github.com/matth-x/MicroOcpp/pull/400))
1012

1113
### Added
1214

1315
- `getTransactionV201()` exposes v201 Tx in API ([#386](https://github.com/matth-x/MicroOcpp/pull/386))
1416
- v201 support in Transaction.h C-API ([#386](https://github.com/matth-x/MicroOcpp/pull/386))
17+
- Write-only Configurations ([#400](https://github.com/matth-x/MicroOcpp/pull/400))
1518

1619
### Fixed
1720

1821
- Timing issues for OCTT test cases ([#383](https://github.com/matth-x/MicroOcpp/pull/383))
1922
- Misleading Reset failure dbg msg ([#388](https://github.com/matth-x/MicroOcpp/pull/388))
2023
- Reject negative ints in ChangeConfig ([#388](https://github.com/matth-x/MicroOcpp/pull/388))
24+
- Revised SCons integration ([#400](https://github.com/matth-x/MicroOcpp/pull/400))
2125

2226
## [1.2.0] - 2024-11-03
2327

SConscript.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# Use this file as a starting point for writing your own SCons integration. And as always, any
88
# contributions are highly welcome!
99

10-
Import("env", "ARDUINOJSON_DIR")
10+
Import("env")
1111

1212
import os, pathlib
1313

@@ -17,16 +17,15 @@ def getAllDirs(root_dir):
1717
dir_list.append(Dir(root))
1818
return dir_list
1919

20-
SOURCE_DIR = Dir(".").srcnode()
20+
SOURCE_DIR = Dir(".").srcnode().Dir("src")
2121

22-
source_dirs = getAllDirs(SOURCE_DIR.Dir("src"))
23-
source_dirs += getAllDirs(ARDUINOJSON_DIR.Dir("src"))
22+
source_dirs = getAllDirs(SOURCE_DIR)
2423

2524
source_files = []
2625

2726
for folder in source_dirs:
27+
source_files += folder.glob("*.c")
2828
source_files += folder.glob("*.cpp")
29-
env["CPPPATH"].append(folder)
3029

3130
compiled_objects = []
3231
for source_file in source_files:
@@ -44,7 +43,7 @@ def getAllDirs(root_dir):
4443

4544
exports = {
4645
'library': libmicroocpp,
47-
'CPPPATH': source_dirs.copy()
46+
'CPPPATH': SOURCE_DIR
4847
}
4948

5049
Return("exports")

src/MicroOcpp/Core/ConfigurationKeyValue.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,27 @@ bool Configuration::isRebootRequired() {
7575
}
7676

7777
void Configuration::setReadOnly() {
78-
readOnly = true;
78+
if (mutability == Mutability::ReadWrite) {
79+
mutability = Mutability::ReadOnly;
80+
} else {
81+
mutability = Mutability::None;
82+
}
7983
}
8084

8185
bool Configuration::isReadOnly() {
82-
return readOnly;
86+
return mutability == Mutability::ReadOnly;
87+
}
88+
89+
bool Configuration::isReadable() {
90+
return mutability == Mutability::ReadWrite || mutability == Mutability::ReadOnly;
91+
}
92+
93+
void Configuration::setWriteOnly() {
94+
if (mutability == Mutability::ReadWrite) {
95+
mutability = Mutability::WriteOnly;
96+
} else {
97+
mutability = Mutability::None;
98+
}
8399
}
84100

85101
/*

src/MicroOcpp/Core/ConfigurationKeyValue.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,15 @@ class Configuration {
3636
revision_t value_revision = 0; //write access counter; used to check if this config has been changed
3737
private:
3838
bool rebootRequired = false;
39-
bool readOnly = false;
39+
40+
enum class Mutability : uint8_t {
41+
ReadWrite,
42+
ReadOnly,
43+
WriteOnly,
44+
None
45+
};
46+
Mutability mutability = Mutability::ReadWrite;
47+
4048
public:
4149
virtual ~Configuration();
4250

@@ -60,6 +68,9 @@ class Configuration {
6068

6169
void setReadOnly();
6270
bool isReadOnly();
71+
bool isReadable();
72+
73+
void setWriteOnly();
6374
};
6475

6576
/*

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);

0 commit comments

Comments
 (0)