MeshX 0.4
This repository provides an implementation for Bluetooth Low Energy (BLE) Mesh network nodes. The project allows you to create BLE mesh nodes that can communicate with each other, enabling the development of smart home solutions or other IoT-based applications.
Loading...
Searching...
No Matches
meshx_ro_cfg.h File Reference

Persistent Serialized Configuration Loader (Read-Only). More...

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "meshx_err.h"

Go to the source code of this file.

Functions

meshx_err_t meshx_ro_cfg_init (uint16_t *cid, uint16_t *pid, char *product_name, size_t name_max_len, uint8_t *uuid)
 Initialize and load the MeshX configuration from the meshx_cfg partition.

Detailed Description

Persistent Serialized Configuration Loader (Read-Only).

Copyright © 2024 - 2025 MeshX

Function Documentation

◆ meshx_ro_cfg_init()

meshx_err_t meshx_ro_cfg_init ( uint16_t * cid,
uint16_t * pid,
char * product_name,
size_t name_max_len,
uint8_t * uuid )

Initialize and load the MeshX configuration from the meshx_cfg partition.

This function locates the meshx_cfg partition using FAL, validates the CRC-16-CCITT checksums of the header and payload, decodes the Protobuf payload using nanopb, and applies the configuration (e.g., global IDs, element composition, and GPIO bindings).

If the loaded UUID is all zeros (or missing), the system should fall back to the legacy UUID generation method (e.g., based on device MAC).

Parameters
[out]cidPointer to store the loaded Company ID.
[out]pidPointer to store the loaded Product ID.
[out]product_nameBuffer to store the loaded product name.
[in]name_max_lenMaximum length of the product_name buffer.
[out]uuidBuffer to store the loaded 16-byte UUID.
Returns
meshx_err_t MESHX_SUCCESS on success, or an error code on failure.
90 {
92 if (meshx_fal_find_partition("meshx_cfg", &part) != MESHX_SUCCESS) {
93 MESHX_LOGI(MODULE_ID_RO_CFG, "No meshx_cfg partition found");
94 return MESHX_NOT_FOUND;
95 }
96
97 meshx_cfg_header_t header;
98 if (meshx_fal_read(&part, 0, (uint8_t *)&header, MESHX_HDR_SIZE) != MESHX_SUCCESS) {
99 return MESHX_ERR_PLAT;
100 }
101
102 if (header.magic != MESHX_CFG_MAGIC) {
103 MESHX_LOGE(MODULE_ID_RO_CFG, "Invalid config magic (0x%08X, exp: 0x%08X)", header.magic, MESHX_CFG_MAGIC);
105 }
106
107 if (header.version != MESHX_CFG_VERSION) {
108 MESHX_LOGE(MODULE_ID_RO_CFG, "Unsupported config version (0x%02X)", header.version);
110 }
111
112 if (header.schema_id != MESHX_SCHEMA_ID) {
113 MESHX_LOGE(MODULE_ID_RO_CFG, "Schema mismatch! Binary ID: 0x%08X, Firmware ID: 0x%08X",
114 header.schema_id, MESHX_SCHEMA_ID);
116 }
117
118 // Validate header CRC (all fields except header_crc and payload_crc)
119 uint16_t expected_hdr_crc = calc_crc16_ccitt((uint8_t *)&header, MESHX_HDR_SIZE - 4);
120 if (header.header_crc != expected_hdr_crc) {
121 MESHX_LOGE(MODULE_ID_RO_CFG, "Config header CRC mismatch (calc: 0x%04X, exp: 0x%04X)", expected_hdr_crc, header.header_crc);
123 }
124
125 size_t payload_len = header.total_len - MESHX_HDR_SIZE;
126 uint8_t *payload = malloc(payload_len);
127 if (!payload) return MESHX_NO_MEM;
128
129 if (meshx_fal_read(&part, MESHX_HDR_SIZE, payload, payload_len) != MESHX_SUCCESS) {
130 MESHX_LOGE(MODULE_ID_RO_CFG, "Failed to read config payload");
131 free(payload);
132 return MESHX_ERR_PLAT;
133 }
134
135 uint16_t expected_pld_crc = calc_crc16_ccitt(payload, payload_len);
136 if (header.payload_crc != expected_pld_crc) {
137 MESHX_LOGE(MODULE_ID_RO_CFG, "Config payload CRC mismatch (calc: 0x%04X, exp: 0x%04X)", expected_pld_crc, header.payload_crc);
138 free(payload);
140 }
141
142 MeshXConfig config = MeshXConfig_init_zero;
143 config.elements.funcs.decode = elements_decode_cb;
144 config.gpio.funcs.decode = gpio_decode_cb;
145 config.bindings.funcs.decode = bindings_decode_cb;
146
147 pb_istream_t stream = pb_istream_from_buffer(payload, payload_len);
148
150
151 if (!pb_decode(&stream, MeshXConfig_fields, &config)) {
152 MESHX_LOGE(MODULE_ID_RO_CFG, "Config protobuf decode failed");
153 free(payload);
155 }
156
158
159 if (config.has_product) {
160 if (cid) *cid = config.product.cid;
161 if (pid) *pid = config.product.pid;
162 if (product_name) {
163 strncpy(product_name, config.product.name, name_max_len - 1);
164 product_name[name_max_len - 1] = '\0';
165 }
166 if (uuid && config.product.has_uuid) {
167 memcpy(uuid, config.product.uuid, 16);
168 MESHX_LOGD(MODULE_ID_RO_CFG, "Loaded UUID: %02X%02X%02X%02X...", uuid[0], uuid[1], uuid[2], uuid[3]);
169 }
170 MESHX_LOGI(MODULE_ID_RO_CFG, "Loaded Config: CID 0x%04X, PID 0x%04X, Name: %s",
171 config.product.cid, config.product.pid, config.product.name);
172 }
173
174 free(payload);
175 return MESHX_SUCCESS;
176}
void meshx_builder_commit(void)
Definition meshx_composition_builder.cpp:166
void meshx_builder_begin(void)
C-friendly builder lifecycle functions.
Definition meshx_composition_builder.cpp:161
@ MESHX_ERR_RO_CFG_VERSION
Definition meshx_err.h:58
@ MESHX_ERR_PLAT
Definition meshx_err.h:47
@ MESHX_NOT_FOUND
Definition meshx_err.h:50
@ MESHX_NO_MEM
Definition meshx_err.h:48
@ MESHX_ERR_RO_CFG_FORMAT
Definition meshx_err.h:57
@ MESHX_ERR_RO_CFG_CRC
Definition meshx_err.h:59
meshx_err_t meshx_fal_read(const meshx_fal_partition_t *part, uint32_t offset, void *buf, size_t len)
Read data from a flash partition.
meshx_err_t meshx_fal_find_partition(const char *name, meshx_fal_partition_t *part)
Find a flash partition by name.
#define MESHX_LOGI(module_id, format,...)
Definition meshx_log.h:126
#define MESHX_LOGE(module_id, format,...)
Definition meshx_log.h:114
#define MESHX_LOGD(module_id, format,...)
Definition meshx_log.h:132
**This function is called by the parent element when a state change request *is received It validates the request and returns a result to the element not the model layer **return * MESHX_SUCCESS
Definition meshx_model_level.cpp:385
#define MODULE_ID_RO_CFG
Definition meshx_ro_cfg.c:18
static bool gpio_decode_cb(pb_istream_t *stream, const pb_field_iter_t *field, void **arg)
Definition meshx_ro_cfg.c:71
static uint16_t calc_crc16_ccitt(const uint8_t *data, size_t len)
Definition meshx_ro_cfg.c:45
static bool elements_decode_cb(pb_istream_t *stream, const pb_field_iter_t *field, void **arg)
Definition meshx_ro_cfg.c:61
static bool bindings_decode_cb(pb_istream_t *stream, const pb_field_iter_t *field, void **arg)
Definition meshx_ro_cfg.c:81
#define MESHX_HDR_SIZE
Definition meshx_ro_cfg.c:33
#define MESHX_CFG_MAGIC
Definition meshx_ro_cfg.c:31
#define MESHX_CFG_VERSION
Definition meshx_ro_cfg.c:32
Definition meshx_ro_cfg.c:21
Definition meshx_fal_interface.h:27