v0.7.1: rename C core header to victronble_core.h (fixes #2)

src/ held both VictronBLE.h and victronble.h. On case-insensitive
filesystems (Windows, macOS) extracting the library ZIP overwrote one
with the other and the Arduino build failed.

The core header is now victronble_core.h in include/ and src/, and every
include is updated. include/victronble.h stays as a deprecated forwarder
so 0.7.0 Zephyr and host code still builds; it is never in src/.

check_version.sh now fails if two tracked paths differ only in case.
This commit is contained in:
scottp committed 2026-10-09 12:54:06 +11:00
1 parent 22af47854d
commit 318e221170
18 files changed
+247 -219

No files matched your search

+1 -1
View File
@@ -488,7 +488,7 @@ The library keeps everything platform-independent except the BLE radio:
``` ```
include/ include/
├── victronble.h Pure C99 core API — decode one advert, no I/O ├── victronble_core.h Pure C99 core API — decode one advert, no I/O
└── victronble_zephyr.h Zephyr observer API └── victronble_zephyr.h Zephyr observer API
src/ src/
├── victronble_core.c Decrypt + parse; no BLE, no alloc, reentrant ├── victronble_core.c Decrypt + parse; no BLE, no alloc, reentrant
+11
View File
@@ -1,5 +1,16 @@
# Version History # Version History
## 0.7.1 (2026-10-09)
### Fixed
- The library ZIP no longer breaks on Windows and other case-insensitive
filesystems. `src/` held both `VictronBLE.h` and `victronble.h`, so
extracting one overwrote the other (issue #2, with thanks for the report
and the workaround). The C core header is now `victronble_core.h` in both
`include/` and `src/`. Code that includes `victronble.h` from `include/`
(Zephyr, host builds) still works through a deprecated forwarder.
- `check_version.sh` now fails if two tracked paths differ only in case.
## 0.7.0 (2026-08-21) ## 0.7.0 (2026-08-21)
Pure C core + Zephyr support. One repo now serves three ecosystems: Arduino Pure C core + Zephyr support. One repo now serves three ecosystems: Arduino
+10 -1
View File
@@ -4,7 +4,8 @@
# #
# Read-only: confirms the version matches in both manifests and that a matching # Read-only: confirms the version matches in both manifests and that a matching
# git tag (vX.Y.Z) exists. Run it before tagging a release. Non-zero exit if the # git tag (vX.Y.Z) exists. Run it before tagging a release. Non-zero exit if the
# versions disagree or the tag is missing. # versions disagree, the tag is missing, or two tracked paths differ only in
# case (they collide when the ZIP is extracted on Windows or macOS).
# #
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
@@ -31,4 +32,12 @@ else
echo "FAIL no git tag v$json -- create one to release: git tag v$json"; fail=1 echo "FAIL no git tag v$json -- create one to release: git tag v$json"; fail=1
fi fi
clash=$(git ls-files | tr '[:upper:]' '[:lower:]' | sort | uniq -d)
if [ -z "$clash" ]; then
echo "ok no paths differ only in case"
else
echo "FAIL paths differ only in case (breaks Windows/macOS extract):"
echo "$clash" | sed 's/^/ /'; fail=1
fi
exit "$fail" exit "$fail"
+2 -2
View File
@@ -98,7 +98,7 @@ done you can unit-test the parser on your workstation for the first time.
- Freestanding-safe: `<stdint.h>`, `<stddef.h>`, `<string.h>`, `<math.h>` only. - Freestanding-safe: `<stdint.h>`, `<stddef.h>`, `<string.h>`, `<math.h>` only.
- Reentrant. No file-scope mutable state in the parse path. - Reentrant. No file-scope mutable state in the parse path.
### `include/victronble.h` ### `include/victronble_core.h`
```c ```c
#ifndef VICTRONBLE_H #ifndef VICTRONBLE_H
@@ -339,7 +339,7 @@ victronble/
├── zephyr/ ├── zephyr/
│ └── module.yml │ └── module.yml
├── include/ ├── include/
│ └── victronble.h # pure C core │ └── victronble_core.h # pure C core
│ └── victronble_zephyr.h # Zephyr-specific observer API │ └── victronble_zephyr.h # Zephyr-specific observer API
├── src/ ├── src/
│ ├── victronble_core.c # pure C99, no dependencies │ ├── victronble_core.c # pure C99, no dependencies
+1 -1
View File
@@ -79,6 +79,6 @@ victronble_device_type_str()
victronble_state_str() victronble_state_str()
``` ```
That is the whole portable core. See `include/victronble.h` for the record That is the whole portable core. See `include/victronble_core.h` for the record
structures, and `samples/observer/` for the same printing logic driven by a structures, and `samples/observer/` for the same printing logic driven by a
live BLE scan under Zephyr. live BLE scan under Zephyr.
+1 -1
View File
@@ -25,7 +25,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "victronble.h" #include "victronble_core.h"
/* /*
* Sample advertisement from the library's own test vectors * Sample advertisement from the library's own test vectors
+5 -203
View File
@@ -1,206 +1,8 @@
/** /* Deprecated: the core header was renamed to victronble_core.h in 0.7.1.
* victronble — pure C99 decoder for Victron Energy "Instant Readout" BLE * This forwarder keeps 0.7.0 Zephyr and host code building. It lives only in
* advertisements (manufacturer ID 0x02E1, record type 0x10, AES-128-CTR). * include/, never in src/, where it would clash with VictronBLE.h on
* * case-insensitive filesystems (issue #2). */
* This is the portable core of the VictronBLE library: no Arduino, no BLE
* stack, no allocation, no I/O, reentrant. Feed it one manufacturer-specific
* data blob (starting at the company ID) plus the device's 16-byte
* advertisement key; get a decoded record back. Transport (scanning), device
* registries, rate limiting and logging belong to the platform wrappers
* (Arduino C++ class, Zephyr module).
*
* Copyright (c) 2025-2026 Scott Penrose
* License: MIT
*/
#ifndef VICTRONBLE_H #ifndef VICTRONBLE_H
#define VICTRONBLE_H #define VICTRONBLE_H
#include "victronble_core.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif #endif
#define VICTRONBLE_COMPANY_ID 0x02E1u /* Victron Energy BV */
#define VICTRONBLE_KEY_LEN 16
#define VICTRONBLE_MAX_CIPHER_LEN 21 /* encrypted payload in one advert */
#define VICTRONBLE_MIN_MFG_LEN 10 /* header before the ciphertext */
typedef enum {
VICTRONBLE_OK = 0,
VICTRONBLE_ERR_NOT_VICTRON = -1, /* company ID mismatch */
VICTRONBLE_ERR_SHORT = -2, /* truncated advertisement */
VICTRONBLE_ERR_NOT_PRODUCT = -3, /* not a product-advertisement record */
VICTRONBLE_ERR_KEY_MISMATCH = -4, /* key check byte failed */
VICTRONBLE_ERR_UNSUPPORTED = -5, /* known record type, no decoder */
VICTRONBLE_ERR_CRYPTO = -6, /* AES backend failed */
} victronble_err_t;
/* Values are the raw Victron record-type IDs. The inverter family
* (0x03/0x06/0x0B/0x0C) all decode to VICTRONBLE_DEV_INVERTER. */
typedef enum {
VICTRONBLE_DEV_UNKNOWN = 0x00,
VICTRONBLE_DEV_SOLAR_CHARGER = 0x01,
VICTRONBLE_DEV_BATTERY_MONITOR = 0x02,
VICTRONBLE_DEV_INVERTER = 0x03,
VICTRONBLE_DEV_DCDC_CONVERTER = 0x04,
VICTRONBLE_DEV_SMART_LITHIUM = 0x05,
VICTRONBLE_DEV_INVERTER_RS = 0x06,
VICTRONBLE_DEV_GX_DEVICE = 0x07,
VICTRONBLE_DEV_AC_CHARGER = 0x08,
VICTRONBLE_DEV_BATTERY_PROTECT = 0x09,
VICTRONBLE_DEV_LYNX_SMART_BMS = 0x0A,
VICTRONBLE_DEV_MULTI_RS = 0x0B,
VICTRONBLE_DEV_VE_BUS = 0x0C,
VICTRONBLE_DEV_DC_ENERGY_METER = 0x0D,
VICTRONBLE_DEV_ORION_XS = 0x0F,
} victronble_device_type_t;
/* Charger states shared by solar / AC chargers (VE.Direct "CS"). */
enum {
VICTRONBLE_STATE_OFF = 0,
VICTRONBLE_STATE_LOW_POWER = 1,
VICTRONBLE_STATE_FAULT = 2,
VICTRONBLE_STATE_BULK = 3,
VICTRONBLE_STATE_ABSORPTION = 4,
VICTRONBLE_STATE_FLOAT = 5,
VICTRONBLE_STATE_STORAGE = 6,
VICTRONBLE_STATE_EQUALIZE = 7,
VICTRONBLE_STATE_INVERTING = 9,
VICTRONBLE_STATE_POWER_SUPPLY = 11,
VICTRONBLE_STATE_EXTERNAL_CONTROL = 252,
};
/* Fields the wire encodes as "not available" are NAN (test with isnan()).
* Integer fields keep the raw value; sentinels are documented per field. */
typedef struct {
uint8_t state; /* VICTRONBLE_STATE_* */
uint8_t error;
float battery_voltage; /* V */
float battery_current; /* A */
float pv_power; /* W */
uint32_t yield_today_wh; /* Wh */
float load_current; /* A, NAN if no load output */
} victronble_solar_charger_t;
typedef struct {
float voltage; /* V */
float current; /* A */
float temperature; /* degC, NAN unless aux mode = temperature */
float aux_voltage; /* V, NAN unless aux mode = aux voltage */
uint16_t remaining_minutes; /* time-to-go; 0xFFFF = not available */
float consumed_ah; /* Ah, negative = consumed */
float soc; /* % */
uint8_t aux_mode; /* 0=aux V, 1=midpoint, 2=temperature, 3=none */
uint16_t alarm; /* raw 16-bit alarm bitmask */
} victronble_battery_monitor_t;
typedef struct {
uint8_t state;
uint8_t alarms; /* raw alarm bits: 0x01 lowV, 0x02 highV,
* 0x04 highT, 0x08 overload */
float battery_voltage; /* V */
float battery_current; /* A */
float ac_power; /* W (signed) */
} victronble_inverter_t;
typedef struct {
uint8_t state; /* charge state */
uint8_t error;
float input_voltage; /* V */
float output_voltage; /* V */
float output_current; /* A */
} victronble_dcdc_t;
typedef struct {
uint8_t state;
uint8_t error;
float voltage1, current1; /* output 1 (V, A), NAN if absent */
float voltage2, current2; /* output 2 */
float voltage3, current3; /* output 3 */
float temperature; /* degC, NAN if not available */
float ac_current; /* A, NAN if not available */
} victronble_ac_charger_t;
typedef struct {
victronble_device_type_t type; /* decoded family (inverter collapsed) */
uint8_t record_type; /* raw record type from the wire */
uint16_t model_id;
uint8_t readout_type;
uint16_t nonce; /* data counter, as received */
union {
victronble_solar_charger_t solar;
victronble_battery_monitor_t batmon;
victronble_inverter_t inverter;
victronble_dcdc_t dcdc;
victronble_ac_charger_t ac;
} u;
} victronble_record_t;
/**
* Decode one Victron manufacturer-data blob.
*
* @param mfg Manufacturer-specific data, starting at the company ID.
* @param len Length of @p mfg in bytes.
* @param key 16-byte per-device advertisement key.
* @param out Populated on VICTRONBLE_OK; untouched otherwise.
*
* Reentrant, allocation-free, no I/O. Duplicate suppression (nonce
* tracking) is the caller's job — the nonce is returned in @p out.
*/
victronble_err_t victronble_decode(const uint8_t *mfg, size_t len,
const uint8_t key[VICTRONBLE_KEY_LEN],
victronble_record_t *out);
/** Cheap pre-filter: company ID + product-advertisement record, no crypto. */
bool victronble_is_product_adv(const uint8_t *mfg, size_t len);
/** Key check byte test — pick the right key from several without decrypting. */
bool victronble_key_matches(const uint8_t *mfg, size_t len,
const uint8_t key[VICTRONBLE_KEY_LEN]);
/** Parse a 32-hex-char advertisement key. Returns false on bad input. */
bool victronble_parse_key(const char *hex, uint8_t key[VICTRONBLE_KEY_LEN]);
const char *victronble_strerror(victronble_err_t err);
const char *victronble_device_type_str(victronble_device_type_t type);
/** Short lower-case charger-state label ("bulk", "float", ...). */
const char *victronble_state_str(uint8_t state);
/**
* AES-128-CTR transform hook.
*
* @param key 16-byte key.
* @param iv 16-byte initial counter block (nonce in the low bytes, rest 0).
* @param in Ciphertext.
* @param out Plaintext. May alias @p in.
* @param len Byte count, not necessarily a multiple of 16.
* @param user Opaque context supplied at registration.
* @return 0 on success, negative on failure.
*/
typedef int (*victronble_aes_ctr_fn)(const uint8_t key[16],
const uint8_t iv[16],
const uint8_t *in, uint8_t *out,
size_t len, void *user);
/** Override the AES backend at runtime (NULL restores the default). */
void victronble_set_aes_ctr(victronble_aes_ctr_fn fn, void *user);
/**
* Default AES backend. Weak symbol: the bundled software AES
* (victronble_aes_sw.c) provides it; an alternative backend (PSA, mbedTLS,
* hardware) may define it strong and the linker drops the bundled code.
*/
int victronble_aes_ctr_default(const uint8_t key[16], const uint8_t iv[16],
const uint8_t *in, uint8_t *out,
size_t len, void *user);
#ifdef __cplusplus
}
#endif
#endif /* VICTRONBLE_H */
+206
View File
@@ -0,0 +1,206 @@
/**
* victronble_core — pure C99 decoder for Victron Energy "Instant Readout" BLE
* advertisements (manufacturer ID 0x02E1, record type 0x10, AES-128-CTR).
*
* This is the portable core of the VictronBLE library: no Arduino, no BLE
* stack, no allocation, no I/O, reentrant. Feed it one manufacturer-specific
* data blob (starting at the company ID) plus the device's 16-byte
* advertisement key; get a decoded record back. Transport (scanning), device
* registries, rate limiting and logging belong to the platform wrappers
* (Arduino C++ class, Zephyr module).
*
* Copyright (c) 2025-2026 Scott Penrose
* License: MIT
*/
#ifndef VICTRONBLE_CORE_H
#define VICTRONBLE_CORE_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#define VICTRONBLE_COMPANY_ID 0x02E1u /* Victron Energy BV */
#define VICTRONBLE_KEY_LEN 16
#define VICTRONBLE_MAX_CIPHER_LEN 21 /* encrypted payload in one advert */
#define VICTRONBLE_MIN_MFG_LEN 10 /* header before the ciphertext */
typedef enum {
VICTRONBLE_OK = 0,
VICTRONBLE_ERR_NOT_VICTRON = -1, /* company ID mismatch */
VICTRONBLE_ERR_SHORT = -2, /* truncated advertisement */
VICTRONBLE_ERR_NOT_PRODUCT = -3, /* not a product-advertisement record */
VICTRONBLE_ERR_KEY_MISMATCH = -4, /* key check byte failed */
VICTRONBLE_ERR_UNSUPPORTED = -5, /* known record type, no decoder */
VICTRONBLE_ERR_CRYPTO = -6, /* AES backend failed */
} victronble_err_t;
/* Values are the raw Victron record-type IDs. The inverter family
* (0x03/0x06/0x0B/0x0C) all decode to VICTRONBLE_DEV_INVERTER. */
typedef enum {
VICTRONBLE_DEV_UNKNOWN = 0x00,
VICTRONBLE_DEV_SOLAR_CHARGER = 0x01,
VICTRONBLE_DEV_BATTERY_MONITOR = 0x02,
VICTRONBLE_DEV_INVERTER = 0x03,
VICTRONBLE_DEV_DCDC_CONVERTER = 0x04,
VICTRONBLE_DEV_SMART_LITHIUM = 0x05,
VICTRONBLE_DEV_INVERTER_RS = 0x06,
VICTRONBLE_DEV_GX_DEVICE = 0x07,
VICTRONBLE_DEV_AC_CHARGER = 0x08,
VICTRONBLE_DEV_BATTERY_PROTECT = 0x09,
VICTRONBLE_DEV_LYNX_SMART_BMS = 0x0A,
VICTRONBLE_DEV_MULTI_RS = 0x0B,
VICTRONBLE_DEV_VE_BUS = 0x0C,
VICTRONBLE_DEV_DC_ENERGY_METER = 0x0D,
VICTRONBLE_DEV_ORION_XS = 0x0F,
} victronble_device_type_t;
/* Charger states shared by solar / AC chargers (VE.Direct "CS"). */
enum {
VICTRONBLE_STATE_OFF = 0,
VICTRONBLE_STATE_LOW_POWER = 1,
VICTRONBLE_STATE_FAULT = 2,
VICTRONBLE_STATE_BULK = 3,
VICTRONBLE_STATE_ABSORPTION = 4,
VICTRONBLE_STATE_FLOAT = 5,
VICTRONBLE_STATE_STORAGE = 6,
VICTRONBLE_STATE_EQUALIZE = 7,
VICTRONBLE_STATE_INVERTING = 9,
VICTRONBLE_STATE_POWER_SUPPLY = 11,
VICTRONBLE_STATE_EXTERNAL_CONTROL = 252,
};
/* Fields the wire encodes as "not available" are NAN (test with isnan()).
* Integer fields keep the raw value; sentinels are documented per field. */
typedef struct {
uint8_t state; /* VICTRONBLE_STATE_* */
uint8_t error;
float battery_voltage; /* V */
float battery_current; /* A */
float pv_power; /* W */
uint32_t yield_today_wh; /* Wh */
float load_current; /* A, NAN if no load output */
} victronble_solar_charger_t;
typedef struct {
float voltage; /* V */
float current; /* A */
float temperature; /* degC, NAN unless aux mode = temperature */
float aux_voltage; /* V, NAN unless aux mode = aux voltage */
uint16_t remaining_minutes; /* time-to-go; 0xFFFF = not available */
float consumed_ah; /* Ah, negative = consumed */
float soc; /* % */
uint8_t aux_mode; /* 0=aux V, 1=midpoint, 2=temperature, 3=none */
uint16_t alarm; /* raw 16-bit alarm bitmask */
} victronble_battery_monitor_t;
typedef struct {
uint8_t state;
uint8_t alarms; /* raw alarm bits: 0x01 lowV, 0x02 highV,
* 0x04 highT, 0x08 overload */
float battery_voltage; /* V */
float battery_current; /* A */
float ac_power; /* W (signed) */
} victronble_inverter_t;
typedef struct {
uint8_t state; /* charge state */
uint8_t error;
float input_voltage; /* V */
float output_voltage; /* V */
float output_current; /* A */
} victronble_dcdc_t;
typedef struct {
uint8_t state;
uint8_t error;
float voltage1, current1; /* output 1 (V, A), NAN if absent */
float voltage2, current2; /* output 2 */
float voltage3, current3; /* output 3 */
float temperature; /* degC, NAN if not available */
float ac_current; /* A, NAN if not available */
} victronble_ac_charger_t;
typedef struct {
victronble_device_type_t type; /* decoded family (inverter collapsed) */
uint8_t record_type; /* raw record type from the wire */
uint16_t model_id;
uint8_t readout_type;
uint16_t nonce; /* data counter, as received */
union {
victronble_solar_charger_t solar;
victronble_battery_monitor_t batmon;
victronble_inverter_t inverter;
victronble_dcdc_t dcdc;
victronble_ac_charger_t ac;
} u;
} victronble_record_t;
/**
* Decode one Victron manufacturer-data blob.
*
* @param mfg Manufacturer-specific data, starting at the company ID.
* @param len Length of @p mfg in bytes.
* @param key 16-byte per-device advertisement key.
* @param out Populated on VICTRONBLE_OK; untouched otherwise.
*
* Reentrant, allocation-free, no I/O. Duplicate suppression (nonce
* tracking) is the caller's job — the nonce is returned in @p out.
*/
victronble_err_t victronble_decode(const uint8_t *mfg, size_t len,
const uint8_t key[VICTRONBLE_KEY_LEN],
victronble_record_t *out);
/** Cheap pre-filter: company ID + product-advertisement record, no crypto. */
bool victronble_is_product_adv(const uint8_t *mfg, size_t len);
/** Key check byte test — pick the right key from several without decrypting. */
bool victronble_key_matches(const uint8_t *mfg, size_t len,
const uint8_t key[VICTRONBLE_KEY_LEN]);
/** Parse a 32-hex-char advertisement key. Returns false on bad input. */
bool victronble_parse_key(const char *hex, uint8_t key[VICTRONBLE_KEY_LEN]);
const char *victronble_strerror(victronble_err_t err);
const char *victronble_device_type_str(victronble_device_type_t type);
/** Short lower-case charger-state label ("bulk", "float", ...). */
const char *victronble_state_str(uint8_t state);
/**
* AES-128-CTR transform hook.
*
* @param key 16-byte key.
* @param iv 16-byte initial counter block (nonce in the low bytes, rest 0).
* @param in Ciphertext.
* @param out Plaintext. May alias @p in.
* @param len Byte count, not necessarily a multiple of 16.
* @param user Opaque context supplied at registration.
* @return 0 on success, negative on failure.
*/
typedef int (*victronble_aes_ctr_fn)(const uint8_t key[16],
const uint8_t iv[16],
const uint8_t *in, uint8_t *out,
size_t len, void *user);
/** Override the AES backend at runtime (NULL restores the default). */
void victronble_set_aes_ctr(victronble_aes_ctr_fn fn, void *user);
/**
* Default AES backend. Weak symbol: the bundled software AES
* (victronble_aes_sw.c) provides it; an alternative backend (PSA, mbedTLS,
* hardware) may define it strong and the linker drops the bundled code.
*/
int victronble_aes_ctr_default(const uint8_t key[16], const uint8_t iv[16],
const uint8_t *in, uint8_t *out,
size_t len, void *user);
#ifdef __cplusplus
}
#endif
#endif /* VICTRONBLE_CORE_H */
+1 -1
View File
@@ -19,7 +19,7 @@
#include <zephyr/bluetooth/addr.h> #include <zephyr/bluetooth/addr.h>
#include <zephyr/sys/slist.h> #include <zephyr/sys/slist.h>
#include "victronble.h" #include "victronble_core.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "victronble", "name": "victronble",
"version": "0.7.0", "version": "0.7.1",
"description": "Portable Arduino library for reading Victron Energy device data via Bluetooth Low Energy (BLE) advertisements. Runs on ESP32, ESP32-S3, ESP32-C3 and nRF52 (nRF52840, nRF52832). Supports SmartSolar MPPT, SmartShunt, BMV, MultiPlus, Orion, Blue Smart AC chargers and other Victron devices. No external crypto dependency. Also ships a Zephyr module (CONFIG_VICTRONBLE) and a dependency-free pure C99 core usable on any platform.", "description": "Portable Arduino library for reading Victron Energy device data via Bluetooth Low Energy (BLE) advertisements. Runs on ESP32, ESP32-S3, ESP32-C3 and nRF52 (nRF52840, nRF52832). Supports SmartSolar MPPT, SmartShunt, BMV, MultiPlus, Orion, Blue Smart AC chargers and other Victron devices. No external crypto dependency. Also ships a Zephyr module (CONFIG_VICTRONBLE) and a dependency-free pure C99 core usable on any platform.",
"keywords": "victron, ble, zephyr, bluetooth, solar, mppt, battery, smartshunt, smartsolar, bmv, inverter, multiplus, esp32, esp32-s3, esp32-c3, nrf52, nrf52840, nrf52832, xiao, iot, energy, monitoring", "keywords": "victron, ble, zephyr, bluetooth, solar, mppt, battery, smartshunt, smartsolar, bmv, inverter, multiplus, esp32, esp32-s3, esp32-c3, nrf52, nrf52840, nrf52832, xiao, iot, energy, monitoring",
"repository": { "repository": {
+1 -1
View File
@@ -1,5 +1,5 @@
name=VictronBLE name=VictronBLE
version=0.7.0 version=0.7.1
author=Scott Penrose author=Scott Penrose
maintainer=Scott Penrose <scottp@dd.com.au> maintainer=Scott Penrose <scottp@dd.com.au>
sentence=Portable library for reading Victron Energy device data via BLE on ESP32/S3/C3 and nRF52 (nRF52840/nRF52832) sentence=Portable library for reading Victron Energy device data via BLE on ESP32/S3/C3 and nRF52 (nRF52840/nRF52832)
+1 -1
View File
@@ -62,7 +62,7 @@ static const struct {
/* /*
* A float field the device did not send comes back as NAN (see * A float field the device did not send comes back as NAN (see
* include/victronble.h). Render that as "n/a" rather than letting "nan" leak * include/victronble_core.h). Render that as "n/a" rather than letting "nan" leak
* into the log — a missing load-current reading is not a fault. The unit goes * into the log — a missing load-current reading is not a fault. The unit goes
* in here too, so an absent field reads "n/a" and not "n/a A". * in here too, so an absent field reads "n/a" and not "n/a A".
* *
+1 -1
View File
@@ -11,7 +11,7 @@
*/ */
#include "VictronBLE.h" #include "VictronBLE.h"
#include "victronble.h" #include "victronble_core.h"
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
+1 -1
View File
@@ -16,7 +16,7 @@
#define VICTRON_BLE_H #define VICTRON_BLE_H
#include <Arduino.h> #include <Arduino.h>
#include "victronble.h" // pure C core: decode + decrypt (src/victronble_core.c) #include "victronble_core.h" // pure C core: decode + decrypt (src/victronble_core.c)
// --- Platform BLE backend selection --- // --- Platform BLE backend selection ---
// The BLE scanning layer is the only platform-specific part of the library. // The BLE scanning layer is the only platform-specific part of the library.
+1 -1
View File
@@ -9,7 +9,7 @@
* License: MIT * License: MIT
*/ */
#include "victronble.h" #include "victronble_core.h"
#include "crypto/vble_aes.h" #include "crypto/vble_aes.h"
#include <string.h> #include <string.h>
+1 -1
View File
@@ -9,7 +9,7 @@
* License: MIT * License: MIT
*/ */
#include "victronble.h" #include "victronble_core.h"
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
+1 -1
View File
@@ -2,4 +2,4 @@
* path, so route to the canonical core header in include/. Zephyr and host * path, so route to the canonical core header in include/. Zephyr and host
* builds add include/ directly and never see this file first — both paths * builds add include/ directly and never see this file first — both paths
* end up in the same header (it has an include guard). */ * end up in the same header (it has an include guard). */
#include "../include/victronble.h" #include "../include/victronble_core.h"
+1 -1
View File
@@ -12,7 +12,7 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include "victronble.h" #include "victronble_core.h"
#include "test_vectors.h" #include "test_vectors.h"
static int failures; static int failures;