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
2 changes: 1 addition & 1 deletion .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ jobs:
uses: actions/checkout@v3
with:
repository: google/bloaty
ref: 379d5305670c00c36a57e608079fd253f13bde63
ref: e1155149d54bb09b81e86f0e4e5cb7fbd2a318eb
path: tools/bloaty
submodules: recursive
- name: Install bloaty
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
run: ./build/mo_unit_tests --abort
- name: Create coverage report
run: |
lcov --directory . --capture --output-file coverage.info
lcov --directory . --capture --output-file coverage.info --ignore-errors mismatch
lcov --remove coverage.info '/usr/*' '*/tests/*' '*/ArduinoJson.h' --output-file coverage.info
lcov --list coverage.info
- name: Upload coverage reports to Codecov
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@
- Change `MicroOcpp::TxNotification` into C-style enum, replace `OCPP_TxNotication` ([#386](https://github.com/matth-x/MicroOcpp/pull/386))
- Improved UUID generation ([#383](https://github.com/matth-x/MicroOcpp/pull/383))
- `beginTransaction()` returns bool for better v2.0.1 interop ([#386](https://github.com/matth-x/MicroOcpp/pull/386))
- Configurations C-API updates ([#400](https://github.com/matth-x/MicroOcpp/pull/400))
- Platform integrations C-API upates ([#400](https://github.com/matth-x/MicroOcpp/pull/400))

### Added

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

### Fixed

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

## [1.2.0] - 2024-11-03

Expand Down
11 changes: 5 additions & 6 deletions SConscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Use this file as a starting point for writing your own SCons integration. And as always, any
# contributions are highly welcome!

Import("env", "ARDUINOJSON_DIR")
Import("env")

import os, pathlib

Expand All @@ -17,16 +17,15 @@ def getAllDirs(root_dir):
dir_list.append(Dir(root))
return dir_list

SOURCE_DIR = Dir(".").srcnode()
SOURCE_DIR = Dir(".").srcnode().Dir("src")

source_dirs = getAllDirs(SOURCE_DIR.Dir("src"))
source_dirs += getAllDirs(ARDUINOJSON_DIR.Dir("src"))
source_dirs = getAllDirs(SOURCE_DIR)

source_files = []

for folder in source_dirs:
source_files += folder.glob("*.c")
source_files += folder.glob("*.cpp")
env["CPPPATH"].append(folder)

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

exports = {
'library': libmicroocpp,
'CPPPATH': source_dirs.copy()
'CPPPATH': SOURCE_DIR
}

Return("exports")
20 changes: 18 additions & 2 deletions src/MicroOcpp/Core/ConfigurationKeyValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,27 @@ bool Configuration::isRebootRequired() {
}

void Configuration::setReadOnly() {
readOnly = true;
if (mutability == Mutability::ReadWrite) {
mutability = Mutability::ReadOnly;
} else {
mutability = Mutability::None;
}
}

bool Configuration::isReadOnly() {
return readOnly;
return mutability == Mutability::ReadOnly;
}

bool Configuration::isReadable() {
return mutability == Mutability::ReadWrite || mutability == Mutability::ReadOnly;
}

void Configuration::setWriteOnly() {
if (mutability == Mutability::ReadWrite) {
mutability = Mutability::WriteOnly;
} else {
mutability = Mutability::None;
}
}

/*
Expand Down
13 changes: 12 additions & 1 deletion src/MicroOcpp/Core/ConfigurationKeyValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,15 @@ class Configuration {
revision_t value_revision = 0; //write access counter; used to check if this config has been changed
private:
bool rebootRequired = false;
bool readOnly = false;

enum class Mutability : uint8_t {
ReadWrite,
ReadOnly,
WriteOnly,
None
};
Mutability mutability = Mutability::ReadWrite;

public:
virtual ~Configuration();

Expand All @@ -60,6 +68,9 @@ class Configuration {

void setReadOnly();
bool isReadOnly();
bool isReadable();

void setWriteOnly();
};

/*
Expand Down
138 changes: 128 additions & 10 deletions src/MicroOcpp/Core/Configuration_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ class ConfigurationC : public Configuration, public MemoryManaged {
public:
ConfigurationC(ocpp_configuration *config) :
config(config) {
config->mo_data = this;
if (config->read_only) {
setReadOnly();
}
if (config->write_only) {
setWriteOnly();
}
if (config->reboot_required) {
setRebootRequired();
}
}

bool setKey(const char *key) override {
Expand Down Expand Up @@ -116,6 +124,59 @@ class ConfigurationC : public Configuration, public MemoryManaged {
}
};

namespace MicroOcpp {

ConfigurationC *getConfigurationC(ocpp_configuration *config) {
if (!config->mo_data) {
return nullptr;
}
return reinterpret_cast<std::shared_ptr<ConfigurationC>*>(config->mo_data)->get();
}

}

using namespace MicroOcpp;


void ocpp_setRebootRequired(ocpp_configuration *config) {
if (auto c = getConfigurationC(config)) {
c->setRebootRequired();
}
config->reboot_required = true;
}
bool ocpp_isRebootRequired(ocpp_configuration *config) {
if (auto c = getConfigurationC(config)) {
return c->isRebootRequired();
}
return config->reboot_required;
}

void ocpp_setReadOnly(ocpp_configuration *config) {
if (auto c = getConfigurationC(config)) {
c->setReadOnly();
}
config->read_only = true;
}
bool ocpp_isReadOnly(ocpp_configuration *config) {
if (auto c = getConfigurationC(config)) {
return c->isReadOnly();
}
return config->read_only;
}
bool ocpp_isReadable(ocpp_configuration *config) {
if (auto c = getConfigurationC(config)) {
return c->isReadable();
}
return !config->write_only;
}

void ocpp_setWriteOnly(ocpp_configuration *config) {
if (auto c = getConfigurationC(config)) {
c->setWriteOnly();
}
config->write_only = true;
}

class ConfigurationContainerC : public ConfigurationContainer, public MemoryManaged {
private:
ocpp_configuration_container *container;
Expand All @@ -125,15 +186,41 @@ class ConfigurationContainerC : public ConfigurationContainer, public MemoryMana

}

~ConfigurationContainerC() {
for (size_t i = 0; i < container->size(container->user_data); i++) {
if (auto config = container->get_configuration(container->user_data, i)) {
if (config->mo_data) {
delete reinterpret_cast<std::shared_ptr<ConfigurationC>*>(config->mo_data);
config->mo_data = nullptr;
}
}
}
}

bool load() override {
return container->load(container->user_data);
if (container->load) {
return container->load(container->user_data);
} else {
return true;
}
}

bool save() override {
return container->save(container->user_data);
if (container->save) {
return container->save(container->user_data);
} else {
return true;
}
}

std::shared_ptr<Configuration> createConfiguration(TConfig type, const char *key) override {

auto result = std::shared_ptr<ConfigurationC>(nullptr, std::default_delete<ConfigurationC>(), makeAllocator<ConfigurationC>(getMemoryTag()));

if (!container->create_configuration) {
return result;
}

ocpp_config_datatype dt;
switch (type) {
case TConfig::Int:
Expand All @@ -147,19 +234,38 @@ class ConfigurationContainerC : public ConfigurationContainer, public MemoryMana
break;
default:
MO_DBG_ERR("internal error");
return nullptr;
return result;
}
ocpp_configuration *config = container->create_configuration(container->user_data, dt, key);
if (!config) {
return result;
}

result.reset(new ConfigurationC(config));

if (config) {
return std::allocate_shared<ConfigurationC>(makeAllocator<ConfigurationC>(getMemoryTag()), config);
if (result) {
auto captureConfigC = new std::shared_ptr<ConfigurationC>(result);
config->mo_data = reinterpret_cast<void*>(captureConfigC);
} else {
MO_DBG_ERR("could not create config: %s", key);
return nullptr;
if (container->remove) {
container->remove(container->user_data, key);
}
}

return result;
}

void remove(Configuration *config) override {
if (!container->remove) {
return;
}

if (auto c = container->get_configuration_by_key(container->user_data, config->getKey())) {
delete reinterpret_cast<std::shared_ptr<ConfigurationC>*>(c->mo_data);
c->mo_data = nullptr;
}

container->remove(container->user_data, config->getKey());
}

Expand All @@ -170,16 +276,28 @@ class ConfigurationContainerC : public ConfigurationContainer, public MemoryMana
Configuration *getConfiguration(size_t i) override {
auto config = container->get_configuration(container->user_data, i);
if (config) {
return static_cast<Configuration*>(config->mo_data);
if (!config->mo_data) {
auto c = new ConfigurationC(config);
if (c) {
config->mo_data = reinterpret_cast<void*>(new std::shared_ptr<ConfigurationC>(c, std::default_delete<ConfigurationC>(), makeAllocator<ConfigurationC>(getMemoryTag())));
}
}
return static_cast<Configuration*>(config->mo_data ? reinterpret_cast<std::shared_ptr<ConfigurationC>*>(config->mo_data)->get() : nullptr);
} else {
return nullptr;
}
}

std::shared_ptr<Configuration> getConfiguration(const char *key) override {
ocpp_configuration *config = container->get_configuration_by_key(container->user_data, key);
auto config = container->get_configuration_by_key(container->user_data, key);
if (config) {
return std::allocate_shared<ConfigurationC>(makeAllocator<ConfigurationC>(getMemoryTag()), config);
if (!config->mo_data) {
auto c = new ConfigurationC(config);
if (c) {
config->mo_data = reinterpret_cast<void*>(new std::shared_ptr<ConfigurationC>(c, std::default_delete<ConfigurationC>(), makeAllocator<ConfigurationC>(getMemoryTag())));
}
}
return config->mo_data ? *reinterpret_cast<std::shared_ptr<ConfigurationC>*>(config->mo_data) : nullptr;
} else {
return nullptr;
}
Expand Down
13 changes: 13 additions & 0 deletions src/MicroOcpp/Core/Configuration_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,22 @@ typedef struct ocpp_configuration {

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

bool read_only;
bool write_only;
bool reboot_required;

void *mo_data; // Reserved for MO
} ocpp_configuration;

void ocpp_setRebootRequired(ocpp_configuration *config);
bool ocpp_isRebootRequired(ocpp_configuration *config);

void ocpp_setReadOnly(ocpp_configuration *config);
bool ocpp_isReadOnly(ocpp_configuration *config);
bool ocpp_isReadable(ocpp_configuration *config);

void ocpp_setWriteOnly(ocpp_configuration *config);

typedef struct ocpp_configuration_container {
void *user_data; //set this at your choice. MO passes it back to the functions below

Expand Down
10 changes: 10 additions & 0 deletions src/MicroOcpp/Model/Transactions/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,16 @@ const char *ocpp_tx_getIdTag(OCPP_Transaction *tx) {
return reinterpret_cast<MicroOcpp::Transaction*>(tx)->getIdTag();
}

const char *ocpp_tx_getParentIdTag(OCPP_Transaction *tx) {
#if MO_ENABLE_V201
if (g_ocpp_tx_compat_v201) {
MO_DBG_ERR("only supported in v16");
return nullptr;
}
#endif //MO_ENABLE_V201
return reinterpret_cast<MicroOcpp::Transaction*>(tx)->getParentIdTag();
}

bool ocpp_tx_getBeginTimestamp(OCPP_Transaction *tx, char *buf, size_t len) {
#if MO_ENABLE_V201
if (g_ocpp_tx_compat_v201) {
Expand Down
4 changes: 3 additions & 1 deletion src/MicroOcpp/Model/Transactions/Transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern "C" {

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

//Authorization events
TxNotification_Authorized, //success
Expand Down Expand Up @@ -473,6 +473,8 @@ bool ocpp_tx_isCompleted(OCPP_Transaction *tx);

const char *ocpp_tx_getIdTag(OCPP_Transaction *tx);

const char *ocpp_tx_getParentIdTag(OCPP_Transaction *tx);

bool ocpp_tx_getBeginTimestamp(OCPP_Transaction *tx, char *buf, size_t len);

int32_t ocpp_tx_getMeterStart(OCPP_Transaction *tx);
Expand Down
Loading
Loading