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
gpio_integration_test.c File Reference

Integration tests for MeshX GPIO subsystem. More...

Data Structures

struct  gpio_integration_state_t
 Integration test state for tracking cross-subsystem operations. More...

Functions

void meshx_gpio_test_set_pin_count (uint8_t count)
void meshx_gpio_test_set_pin_mode (uint8_t pin, meshx_gpio_mode_t mode)
void meshx_pwm_test_set_pin_count (uint8_t count)
static void mock_hosted_event_callback (const meshx_gpio_hosted_event_t *event)
 Mock hosted event callback for testing UART transport.
static void mock_interrupt_callback (uint8_t logical_pin, void *user_data)
 Mock interrupt callback for testing.
static void init_integration_state (void)
 Initialize integration test state.
static void setup_test_gpio_config (void)
 Setup test GPIO configuration.
static void cleanup_integration_test (void)
 Cleanup integration test resources.
static meshx_err_t test_io_interface_creation (void)
 Test GPIO with abstract IO interface creation.
static meshx_err_t test_element_state_change (void)
 Test GPIO with element state changes.
static meshx_err_t test_io_function_execution (void)
 Test GPIO function execution through abstract IO interface.
static meshx_err_t test_hosted_mode_switching (void)
 Test hosted mode switching.
static meshx_err_t test_gpio_operations_in_hosted_mode (void)
 Test GPIO operations in hosted mode.
static meshx_err_t test_hosted_interrupt_processing (void)
 Test hosted interrupt processing.
static meshx_err_t test_kv_engine_init (void)
 Test GPIO KV Engine initialization.
static meshx_err_t test_kv_config_save (void)
 Test GPIO configuration save to KV Engine.
static meshx_err_t test_kv_config_load (void)
 Test GPIO configuration load from KV Engine.
static meshx_err_t test_kv_config_round_trip (void)
 Test KV Engine configuration round-trip.
static meshx_err_t test_kv_pin_state_persistence (void)
 Test KV Engine pin state persistence.
static meshx_err_t test_kv_config_export_import (void)
 Test KV Engine configuration export/import.
static meshx_err_t test_kv_corruption_recovery (void)
 Test KV Engine corruption recovery.
static meshx_err_t test_gpio_logging_integration (void)
 Test GPIO with logging subsystem integration.
static meshx_err_t test_full_gpio_lifecycle (void)
 Test full GPIO lifecycle with all subsystems.
static meshx_err_t run_gpio_integration_tests (void)
 Run all GPIO integration tests.
static meshx_err_t gpio_integration_test_handler (int cmd_id, int argc, char **argv)
 Integration test command handler.
meshx_err_t register_gpio_integration_tests (void)
 Register GPIO integration tests.

Variables

static gpio_integration_state_t intg_state
static meshx_fal_partition_t mock_kv_partition
 Mock FAL partition for KV Engine testing.

Detailed Description

Integration tests for MeshX GPIO subsystem.

This file implements comprehensive integration tests for the MeshX GPIO subsystem, testing GPIO with element integration, hosted/non-hosted mode switching, and KV Engine persistence and recovery.

Validates: Requirements 10.5-10.8

Requirements coverage:

  • 10.5: Integration tests for GPIO on each supported BSP (xiao_c3, weact_c3, esp32_devkitC)
  • 10.6: Integration tests for GPIO usage from elements (relay, light, sensor)
  • 10.7: Integration tests for YAML configuration parsing and code generation
  • 10.8: Integration tests for GPIO with other MeshX subsystems (BLE, NVS, logging)

Integration test categories:

  1. Element Integration: Tests GPIO with abstract IO interface and element state changes
  2. Hosted/Non-Hosted Mode: Tests mode switching and UART transport
  3. KV Engine Persistence: Tests configuration save/load, recovery, and state persistence
Author
MeshX Team
Date
2024

Function Documentation

◆ cleanup_integration_test()

void cleanup_integration_test ( void )
static

Cleanup integration test resources.

197{
198 if (intg_state.gpio_initialized) {
200 intg_state.gpio_initialized = false;
201 }
202
203 if (intg_state.kv_initialized) {
205 intg_state.kv_initialized = false;
206 }
207}
static gpio_integration_state_t intg_state
Definition gpio_integration_test.c:69
meshx_err_t meshx_gpio_deinit(void)
Deinitialize GPIO subsystem.
Definition meshx_gpio.c:189
meshx_err_t meshx_gpio_kv_deinit(void)
Deinitialize GPIO KV Engine persistence.
Definition meshx_gpio_kv.c:620

◆ gpio_integration_test_handler()

meshx_err_t gpio_integration_test_handler ( int cmd_id,
int argc,
char ** argv )
static

Integration test command handler.

Parameters
cmd_idCommand ID specifying which test to run
argcArgument count
argvArgument values
Returns
meshx_err_t Test result
1251{
1252 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "GPIO Integration Test Handler: cmd_id=%d", cmd_id);
1253
1254 switch (cmd_id) {
1255 case 100: return run_gpio_integration_tests();
1256
1260
1264
1265 case 107: init_integration_state(); return test_kv_engine_init();
1266 case 108: init_integration_state(); return test_kv_config_save();
1267 case 109: init_integration_state(); return test_kv_config_load();
1272
1275
1276 default:
1277 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Unknown integration test cmd_id: %d", cmd_id);
1278 return MESHX_INVALID_ARG;
1279 }
1280}
static meshx_err_t test_gpio_logging_integration(void)
Test GPIO with logging subsystem integration.
Definition gpio_integration_test.c:1005
static meshx_err_t test_kv_config_round_trip(void)
Test KV Engine configuration round-trip.
Definition gpio_integration_test.c:765
static meshx_err_t test_kv_corruption_recovery(void)
Test KV Engine corruption recovery.
Definition gpio_integration_test.c:949
static meshx_err_t run_gpio_integration_tests(void)
Run all GPIO integration tests.
Definition gpio_integration_test.c:1106
static meshx_err_t test_hosted_mode_switching(void)
Test hosted mode switching.
Definition gpio_integration_test.c:447
static meshx_err_t test_hosted_interrupt_processing(void)
Test hosted interrupt processing.
Definition gpio_integration_test.c:579
static meshx_err_t test_kv_config_export_import(void)
Test KV Engine configuration export/import.
Definition gpio_integration_test.c:879
static meshx_err_t test_kv_engine_init(void)
Test GPIO KV Engine initialization.
Definition gpio_integration_test.c:636
static meshx_err_t test_gpio_operations_in_hosted_mode(void)
Test GPIO operations in hosted mode.
Definition gpio_integration_test.c:521
static meshx_err_t test_kv_config_save(void)
Test GPIO configuration save to KV Engine.
Definition gpio_integration_test.c:666
static meshx_err_t test_kv_config_load(void)
Test GPIO configuration load from KV Engine.
Definition gpio_integration_test.c:708
static meshx_err_t test_io_interface_creation(void)
Test GPIO with abstract IO interface creation.
Definition gpio_integration_test.c:221
static meshx_err_t test_full_gpio_lifecycle(void)
Test full GPIO lifecycle with all subsystems.
Definition gpio_integration_test.c:1041
static void init_integration_state(void)
Initialize integration test state.
Definition gpio_integration_test.c:114
static meshx_err_t test_kv_pin_state_persistence(void)
Test KV Engine pin state persistence.
Definition gpio_integration_test.c:827
static meshx_err_t test_io_function_execution(void)
Test GPIO function execution through abstract IO interface.
Definition gpio_integration_test.c:364
static meshx_err_t test_element_state_change(void)
Test GPIO with element state changes.
Definition gpio_integration_test.c:284
@ MESHX_INVALID_ARG
Definition meshx_err.h:46
#define MESHX_LOGI(module_id, format,...)
Definition meshx_log.h:126
#define MESHX_LOGE(module_id, format,...)
Definition meshx_log.h:114
@ MODULE_ID_COMPONENT_MESHX_GPIO
Definition module_id.h:44

◆ init_integration_state()

void init_integration_state ( void )
static

Initialize integration test state.

115{
122 memset(&intg_state, 0, sizeof(intg_state));
123 intg_state.current_hosted_mode = MESHX_GPIO_MODE_NON_HOSTED;
124}
void meshx_gpio_test_set_pin_count(uint8_t count)
Definition meshx_gpio.c:72
void meshx_pwm_test_set_pin_count(uint8_t count)
Definition meshx_pwm.c:714
meshx_err_t meshx_gpio_init(void)
Initialize GPIO subsystem.
Definition meshx_gpio.c:95
@ MESHX_GPIO_MODE_NON_HOSTED
Definition meshx_gpio_types.h:170
meshx_err_t meshx_pwm_deinit(void)
Deinitialize PWM subsystem.
Definition meshx_pwm.c:119
meshx_err_t meshx_pwm_init(void)
Initialize PWM subsystem.
Definition meshx_pwm.c:69

◆ meshx_gpio_test_set_pin_count()

void meshx_gpio_test_set_pin_count ( uint8_t count)
extern
73{
74 if (count <= 128) {
75 gpio_runtime.pin_count = count;
76 return MESHX_SUCCESS;
77 }
78 return MESHX_FAIL;
79}
@ MESHX_FAIL
Definition meshx_err.h:45
static meshx_gpio_runtime_t gpio_runtime
Definition meshx_gpio.c:38
**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

◆ meshx_gpio_test_set_pin_mode()

void meshx_gpio_test_set_pin_mode ( uint8_t pin,
meshx_gpio_mode_t mode )
extern

◆ meshx_pwm_test_set_pin_count()

void meshx_pwm_test_set_pin_count ( uint8_t count)
extern
715{
716 if (count > 128) count = 128;
717 pwm_runtime.pwm_pin_count = count;
718}
static meshx_pwm_runtime_t pwm_runtime
Definition meshx_pwm.c:54

◆ mock_hosted_event_callback()

void mock_hosted_event_callback ( const meshx_gpio_hosted_event_t * event)
static

Mock hosted event callback for testing UART transport.

90{
91 intg_state.hosted_events_sent++;
93 "Mock hosted event: type=%d, pin=%u, value=%u",
94 event->event_type, event->logical_pin, event->value);
95}
uint8_t logical_pin
Definition meshx_gpio_types.h:182
uint8_t event_type
Definition meshx_gpio_types.h:181
uint8_t value
Definition meshx_gpio_types.h:183

◆ mock_interrupt_callback()

void mock_interrupt_callback ( uint8_t logical_pin,
void * user_data )
static

Mock interrupt callback for testing.

102{
104 "Mock interrupt on pin %u", logical_pin);
105}

◆ register_gpio_integration_tests()

meshx_err_t register_gpio_integration_tests ( void )

Register GPIO integration tests.

Register GPIO integration tests with the unit test framework.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
1288{
1289 MESHX_LOGD(MODULE_ID_GPIO_INTEGRATION_TEST, "Registering GPIO integration tests");
1291}
static meshx_err_t gpio_integration_test_handler(int cmd_id, int argc, char **argv)
Integration test command handler.
Definition gpio_integration_test.c:1250
#define MESHX_LOGD(module_id, format,...)
Definition meshx_log.h:132
@ MODULE_ID_GPIO_INTEGRATION_TEST
Definition module_id.h:47
meshx_err_t register_unit_test(module_id_t module_id, module_callback_t callback)
Register a unit test for a specific module.
Definition unit_test.c:137

◆ run_gpio_integration_tests()

meshx_err_t run_gpio_integration_tests ( void )
static

Run all GPIO integration tests.

Returns
meshx_err_t MESHX_SUCCESS if all tests pass, error code on failure
1107{
1108 meshx_err_t result;
1109
1110 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "========================================");
1111 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "GPIO Integration Tests (Requirements 10.5-10.8)");
1112 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "========================================");
1113
1115
1116 /* Element Integration Tests (Requirement 10.6) */
1117 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "--- Element Integration Tests ---");
1118
1119 result = test_io_interface_creation();
1120 if (result != MESHX_SUCCESS) {
1122 return result;
1123 }
1124
1126 result = test_element_state_change();
1127 if (result != MESHX_SUCCESS) {
1129 return result;
1130 }
1131
1133 result = test_io_function_execution();
1134 if (result != MESHX_SUCCESS) {
1136 return result;
1137 }
1138
1139 /* Hosted/Non-Hosted Mode Tests (Requirement 10.8) */
1140 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "--- Hosted Mode Integration Tests ---");
1141
1143 result = test_hosted_mode_switching();
1144 if (result != MESHX_SUCCESS) {
1146 return result;
1147 }
1148
1151 if (result != MESHX_SUCCESS) {
1153 return result;
1154 }
1155
1158 if (result != MESHX_SUCCESS) {
1160 return result;
1161 }
1162
1163 /* KV Engine Persistence Tests (Requirement 10.8, 13.x) */
1164 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "--- KV Engine Persistence Tests ---");
1165
1167 result = test_kv_engine_init();
1168 if (result != MESHX_SUCCESS) {
1170 return result;
1171 }
1172
1173 result = test_kv_config_save();
1174 if (result != MESHX_SUCCESS) {
1176 return result;
1177 }
1178
1179 result = test_kv_config_load();
1180 if (result != MESHX_SUCCESS) {
1182 return result;
1183 }
1184
1186 result = test_kv_config_round_trip();
1187 if (result != MESHX_SUCCESS) {
1189 return result;
1190 }
1191
1194 if (result != MESHX_SUCCESS) {
1196 return result;
1197 }
1198
1201 if (result != MESHX_SUCCESS) {
1203 return result;
1204 }
1205
1207 result = test_kv_corruption_recovery();
1208 if (result != MESHX_SUCCESS) {
1210 return result;
1211 }
1212
1213 /* Cross-Subsystem Tests (Requirement 10.8) */
1214 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "--- Cross-Subsystem Tests ---");
1215
1218 if (result != MESHX_SUCCESS) {
1220 return result;
1221 }
1222
1224 result = test_full_gpio_lifecycle();
1225 if (result != MESHX_SUCCESS) {
1227 return result;
1228 }
1229
1230 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "========================================");
1231 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "All GPIO Integration Tests PASSED");
1232 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "========================================");
1233
1235 return MESHX_SUCCESS;
1236}
static void cleanup_integration_test(void)
Cleanup integration test resources.
Definition gpio_integration_test.c:196
meshx_err_t
MeshX Error Codes.
Definition meshx_err.h:43

◆ setup_test_gpio_config()

void setup_test_gpio_config ( void )
static

Setup test GPIO configuration.

130{
131 /* Configure test pins with various modes */
132 intg_state.test_configs[0] = (meshx_gpio_pin_config_t){
133 .logical_pin = 0,
134 .physical_pin = 4,
136 .pull = MESHX_GPIO_PULL_NONE,
137 .drive_strength = MESHX_GPIO_DRIVE_MEDIUM,
138 .initial_level = 0,
139 .signal_inversion = false,
140 };
141
142 intg_state.test_configs[1] = (meshx_gpio_pin_config_t){
143 .logical_pin = 1,
144 .physical_pin = 5,
145 .mode = MESHX_GPIO_MODE_INPUT,
146 .pull = MESHX_GPIO_PULL_UP,
147 .drive_strength = MESHX_GPIO_DRIVE_MEDIUM,
148 .initial_level = 0,
149 .signal_inversion = false,
150 };
151
152 intg_state.test_configs[2] = (meshx_gpio_pin_config_t){
153 .logical_pin = 2,
154 .physical_pin = 6,
156 .pull = MESHX_GPIO_PULL_NONE,
157 .drive_strength = MESHX_GPIO_DRIVE_MEDIUM,
158 .initial_level = 0,
159 .signal_inversion = false,
160 .mode_config.pwm = {
161 .frequency = 1000,
162 .duty_cycle = 50,
163 .resolution = 10,
164 .channel = 0,
165 },
166 };
167
168 intg_state.test_configs[3] = (meshx_gpio_pin_config_t){
169 .logical_pin = 3,
170 .physical_pin = 7,
171 .mode = MESHX_GPIO_MODE_INPUT,
172 .pull = MESHX_GPIO_PULL_UP,
173 .drive_strength = MESHX_GPIO_DRIVE_MEDIUM,
174 .initial_level = 0,
175 .signal_inversion = false,
176 .mode_config.interrupt = {
178 .task_priority = 5,
179 .task_stack_size = 2048,
180 },
181 };
182
183 /* Sync with runtime */
184 for (int i = 0; i < 8; i++) {
185 if (intg_state.test_configs[i].logical_pin < 128 &&
186 intg_state.test_configs[i].mode != MESHX_GPIO_MODE_MAX) {
187 meshx_gpio_test_set_pin_mode(intg_state.test_configs[i].logical_pin,
188 intg_state.test_configs[i].mode);
189 }
190 }
191}
void meshx_gpio_test_set_pin_mode(uint8_t pin, meshx_gpio_mode_t mode)
@ MESHX_GPIO_PULL_NONE
Definition meshx_gpio.h:42
@ MESHX_GPIO_PULL_UP
Definition meshx_gpio.h:43
@ MESHX_GPIO_MODE_INPUT
Definition meshx_gpio.h:29
@ MESHX_GPIO_MODE_PWM_OUTPUT
Definition meshx_gpio.h:34
@ MESHX_GPIO_MODE_MAX
Definition meshx_gpio.h:35
@ MESHX_GPIO_MODE_OUTPUT
Definition meshx_gpio.h:30
@ MESHX_GPIO_DRIVE_MEDIUM
Definition meshx_gpio.h:54
@ MESHX_GPIO_INTR_NEGATIVE_EDGE
Definition meshx_gpio_types.h:31
GPIO Pin Configuration Structure.
Definition meshx_gpio_types.h:51

◆ test_element_state_change()

meshx_err_t test_element_state_change ( void )
static

Test GPIO with element state changes.

Validates that GPIO operations triggered by element state changes work correctly through the abstract IO interface.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
285{
286 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Test: Element state change integration");
287
288 if (!intg_state.gpio_initialized) {
290 if (err != MESHX_SUCCESS) return MESHX_FAIL;
291 intg_state.gpio_initialized = true;
292 }
293
294 /* Create IO instance for relay element */
295 meshx_io_config_t io_config = {
296 .logical_pin = 0,
297 .io_type = 0,
298 .name = "RELAY_1",
299 .config.gpio = {
301 .pull = MESHX_GPIO_PULL_NONE,
303 .initial_level = 0,
304 .signal_inversion = false,
305 },
306 };
307
308 meshx_io_handle_t io_handle = meshx_io_create(&io_config);
309 if (io_handle == NULL) {
310 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to create relay IO");
311 return MESHX_FAIL;
312 }
313
314 /* Simulate element state change: Turn relay ON */
315 meshx_err_t err = meshx_io_set_level(io_handle, 1);
316 if (err != MESHX_SUCCESS) {
317 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to set relay ON: %d", err);
318 meshx_io_destroy(io_handle);
319 return MESHX_FAIL;
320 }
321
322 /* Verify level was set */
323 uint8_t level;
324 err = meshx_io_get_level(io_handle, &level);
325 if (err != MESHX_SUCCESS || level != 1) {
326 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Relay level verification failed");
327 meshx_io_destroy(io_handle);
328 return MESHX_FAIL;
329 }
330
331 /* Simulate element state change: Turn relay OFF */
332 err = meshx_io_set_level(io_handle, 0);
333 if (err != MESHX_SUCCESS) {
334 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to set relay OFF: %d", err);
335 meshx_io_destroy(io_handle);
336 return MESHX_FAIL;
337 }
338
339 /* Verify level was set */
340 err = meshx_io_get_level(io_handle, &level);
341 if (err != MESHX_SUCCESS || level != 0) {
342 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Relay level verification failed");
343 meshx_io_destroy(io_handle);
344 return MESHX_FAIL;
345 }
346
347 intg_state.element_state_changes += 2;
348
349 /* Cleanup */
350 meshx_io_destroy(io_handle);
351
352 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: Element state change integration");
353 return MESHX_SUCCESS;
354}
meshx_io_handle_t meshx_io_create(const meshx_io_config_t *config)
Create IO instance from configuration.
Definition meshx_io_bridge.cpp:23
meshx_err_t meshx_io_set_level(meshx_io_handle_t handle, uint8_t level)
Set pin level (convenience function).
Definition meshx_io_bridge.cpp:102
meshx_err_t meshx_io_get_level(meshx_io_handle_t handle, uint8_t *level)
Get pin level (convenience function).
Definition meshx_io_bridge.cpp:110
void meshx_io_destroy(meshx_io_handle_t handle)
Destroy IO instance.
Definition meshx_io_bridge.cpp:56
void * meshx_io_handle_t
Opaque handle to IO instance.
Definition meshx_io_bridge.h:26
IO configuration structure (C compatible).
Definition meshx_io_bridge.h:47

◆ test_full_gpio_lifecycle()

meshx_err_t test_full_gpio_lifecycle ( void )
static

Test full GPIO lifecycle with all subsystems.

Validates the complete GPIO lifecycle including initialization, operation, hosted mode switching, KV persistence, and deinitialization.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
1042{
1043 MESHX_LOGD(MODULE_ID_COMMON, "Test: Full GPIO lifecycle");
1044
1045 /* Phase 1: Initialize all subsystems */
1047 if (err != MESHX_SUCCESS) {
1048 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Lifecycle: GPIO init failed");
1049 return MESHX_FAIL;
1050 }
1051 intg_state.gpio_initialized = true;
1052
1053 err = meshx_gpio_kv_init(&mock_kv_partition, "lifecycle_test");
1054 if (err != MESHX_SUCCESS) {
1055 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Lifecycle: KV init failed");
1057 return MESHX_FAIL;
1058 }
1059 intg_state.kv_initialized = true;
1060
1061 /* Phase 2: Configure pins */
1063
1064 /* Phase 3: Perform operations */
1067
1068 /* Phase 4: Switch to hosted mode */
1071
1072 /* Phase 5: Operations in hosted mode */
1074
1075 /* Phase 6: Switch back to non-hosted mode */
1077
1078 /* Phase 7: Save configuration to KV Engine */
1080
1081 /* Phase 8: Load configuration from KV Engine */
1082 meshx_gpio_pin_config_t loaded_configs[8];
1083 uint8_t pin_count = 0;
1084 meshx_gpio_load_config_from_kv(loaded_configs, 8, &pin_count);
1085
1086 /* Phase 9: Cleanup */
1088 intg_state.kv_initialized = false;
1089
1091 intg_state.gpio_initialized = false;
1092
1093 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: Full GPIO lifecycle");
1094 return MESHX_SUCCESS;
1095}
static meshx_fal_partition_t mock_kv_partition
Mock FAL partition for KV Engine testing.
Definition gpio_integration_test.c:74
static void setup_test_gpio_config(void)
Setup test GPIO configuration.
Definition gpio_integration_test.c:129
static void mock_hosted_event_callback(const meshx_gpio_hosted_event_t *event)
Mock hosted event callback for testing UART transport.
Definition gpio_integration_test.c:89
meshx_err_t meshx_gpio_register_hosted_event_cb(meshx_gpio_hosted_event_cb_t callback)
Register callback function for hosted mode events.
Definition meshx_gpio.c:802
meshx_err_t meshx_gpio_set_level(uint8_t logical_pin, uint8_t level)
Set GPIO pin level.
Definition meshx_gpio.c:322
meshx_err_t meshx_gpio_set_hosted_mode(meshx_gpio_hosted_mode_t mode)
Set hosted mode for GPIO subsystem.
Definition meshx_gpio.c:711
meshx_err_t meshx_gpio_toggle(uint8_t logical_pin)
Toggle GPIO pin level.
Definition meshx_gpio.c:453
meshx_err_t meshx_gpio_kv_init(const meshx_fal_partition_t *kv_partition, const char *product_name)
Initialize GPIO KV Engine persistence.
Definition meshx_gpio_kv.c:230
meshx_err_t meshx_gpio_load_config_from_kv(meshx_gpio_pin_config_t *configs, uint8_t max_pins, uint8_t *out_pin_count)
Load GPIO configuration from KV Engine.
Definition meshx_gpio_kv.c:331
meshx_err_t meshx_gpio_save_config_to_kv(const meshx_gpio_pin_config_t *configs, uint8_t pin_count)
Save GPIO configuration to KV Engine.
Definition meshx_gpio_kv.c:269
@ MESHX_GPIO_MODE_HOSTED
Definition meshx_gpio_types.h:171
@ MODULE_ID_COMMON
Definition module_id.h:36

◆ test_gpio_logging_integration()

meshx_err_t test_gpio_logging_integration ( void )
static

Test GPIO with logging subsystem integration.

Validates that GPIO operations correctly integrate with the MeshX logging subsystem for debug and error reporting.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
1006{
1007 MESHX_LOGD(MODULE_ID_COMMON, "Test: GPIO logging integration");
1008
1009 /* Initialize GPIO subsystem */
1010 if (!intg_state.gpio_initialized) {
1012 if (err != MESHX_SUCCESS) return MESHX_FAIL;
1013 intg_state.gpio_initialized = true;
1014 }
1015
1016 /* Perform various GPIO operations that should generate log output */
1017 /* Note: This test validates that logging works, actual log verification
1018 * would require a log capture mechanism */
1019
1020 /* This operation will generate debug logs */
1022
1023 /* This operation will generate info logs */
1025
1026 /* This operation will generate debug logs */
1028
1029 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: GPIO logging integration");
1030 return MESHX_SUCCESS;
1031}
meshx_gpio_hosted_mode_t meshx_gpio_get_hosted_mode(void)
Get current hosted mode.
Definition meshx_gpio.c:786

◆ test_gpio_operations_in_hosted_mode()

meshx_err_t test_gpio_operations_in_hosted_mode ( void )
static

Test GPIO operations in hosted mode.

Validates that GPIO operations in hosted mode correctly invoke the hosted event callback instead of direct hardware access.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
522{
523 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Test: GPIO operations in hosted mode");
524
525 if (!intg_state.gpio_initialized) {
527 if (err != MESHX_SUCCESS) return MESHX_FAIL;
528 intg_state.gpio_initialized = true;
529 }
530
531 /* Ensure we're in non-hosted mode first */
533
534 /* Register hosted event callback */
536 if (err != MESHX_SUCCESS) {
537 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to register hosted callback");
538 return MESHX_FAIL;
539 }
540
541 /* Reset counter */
542 intg_state.hosted_events_sent = 0;
543
544 /* Switch to hosted mode */
546 if (err != MESHX_SUCCESS) {
547 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to switch to hosted mode");
548 return MESHX_FAIL;
549 }
550
551 /* Perform GPIO operation - should trigger hosted event callback */
552 /* Note: This test requires GPIO to have at least one configured pin */
553 err = meshx_gpio_set_level(0, 1);
554 if (err != MESHX_SUCCESS) {
556 "GPIO set_level failed in hosted mode: %d", err);
557 /* This is expected if no pins are configured - continue test */
558 }
559
560 /* Switch back to non-hosted mode */
562 if (err != MESHX_SUCCESS) {
563 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to switch back to non-hosted");
564 return MESHX_FAIL;
565 }
566
567 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: GPIO operations in hosted mode");
568 return MESHX_SUCCESS;
569}

◆ test_hosted_interrupt_processing()

meshx_err_t test_hosted_interrupt_processing ( void )
static

Test hosted interrupt processing.

Validates that interrupts from the host are correctly processed and dispatched to registered callbacks.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
580{
581 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Test: Hosted interrupt processing");
582
583 if (!intg_state.gpio_initialized) {
585 if (err != MESHX_SUCCESS) return MESHX_FAIL;
586 intg_state.gpio_initialized = true;
587 }
588
589 /* Switch to hosted mode */
591 if (err != MESHX_SUCCESS) {
592 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to switch to hosted mode");
593 return MESHX_FAIL;
594 }
595
596 /* Register interrupt in hosted mode (no hardware interrupt needed) */
599 if (err != MESHX_SUCCESS) {
601 "Failed to register interrupt in hosted mode: %d", err);
602 /* This is expected if pin configuration is not set up - continue */
603 }
604
605 /* Simulate interrupt from host */
607 if (err != MESHX_SUCCESS) {
609 "Failed to process hosted interrupt: %d", err);
610 /* This is expected if no interrupt is registered - continue */
611 }
612
613 /* Switch back to non-hosted mode */
615 if (err != MESHX_SUCCESS) {
616 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to switch back");
617 return MESHX_FAIL;
618 }
619
620 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: Hosted interrupt processing");
621 return MESHX_SUCCESS;
622}
static void mock_interrupt_callback(uint8_t logical_pin, void *user_data)
Mock interrupt callback for testing.
Definition gpio_integration_test.c:101
meshx_err_t meshx_gpio_process_hosted_interrupt(uint8_t logical_pin, uint8_t value)
Process GPIO interrupt event from host (hosted mode).
Definition meshx_gpio.c:856
meshx_err_t meshx_gpio_register_intr(uint8_t logical_pin, meshx_gpio_intr_type_t intr_type, meshx_gpio_intr_cb_t callback, void *user_data)
Register GPIO interrupt handler.
Definition meshx_gpio.c:488

◆ test_hosted_mode_switching()

meshx_err_t test_hosted_mode_switching ( void )
static

Test hosted mode switching.

Validates that the GPIO subsystem correctly switches between hosted and non-hosted modes while preserving pin state and interrupt registrations.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
448{
449 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Test: Hosted mode switching");
450
451 if (!intg_state.gpio_initialized) {
453 if (err != MESHX_SUCCESS) return MESHX_FAIL;
454 intg_state.gpio_initialized = true;
455 }
456
457 /* Verify initial mode is non-hosted */
459 if (mode != MESHX_GPIO_MODE_NON_HOSTED) {
461 "Initial mode should be non-hosted, got %d", mode);
462 return MESHX_FAIL;
463 }
464
465 /* Register hosted event callback */
467 if (err != MESHX_SUCCESS) {
469 "Failed to register hosted event callback: %d", err);
470 return MESHX_FAIL;
471 }
472
473 /* Switch to hosted mode */
475 if (err != MESHX_SUCCESS) {
476 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to switch to hosted mode: %d", err);
477 return MESHX_FAIL;
478 }
479
481 if (mode != MESHX_GPIO_MODE_HOSTED) {
482 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Mode should be hosted, got %d", mode);
483 return MESHX_FAIL;
484 }
485
486 intg_state.current_hosted_mode = MESHX_GPIO_MODE_HOSTED;
487
488 /* Verify is_hosted_mode returns true */
490 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "is_hosted_mode should return true");
491 return MESHX_FAIL;
492 }
493
494 /* Switch back to non-hosted mode */
496 if (err != MESHX_SUCCESS) {
497 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to switch to non-hosted mode: %d", err);
498 return MESHX_FAIL;
499 }
500
502 if (mode != MESHX_GPIO_MODE_NON_HOSTED) {
503 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Mode should be non-hosted, got %d", mode);
504 return MESHX_FAIL;
505 }
506
507 intg_state.current_hosted_mode = MESHX_GPIO_MODE_NON_HOSTED;
508
509 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: Hosted mode switching");
510 return MESHX_SUCCESS;
511}
bool meshx_gpio_is_hosted_mode(void)
Check if GPIO subsystem is in hosted mode.
Definition meshx_gpio.c:794
meshx_gpio_hosted_mode_t
Hosted Mode State.
Definition meshx_gpio_types.h:169

◆ test_io_function_execution()

meshx_err_t test_io_function_execution ( void )
static

Test GPIO function execution through abstract IO interface.

Validates that the function-based API works correctly through the abstract IO interface for various GPIO operations.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
365{
366 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Test: IO function execution");
367
368 if (!intg_state.gpio_initialized) {
370 if (err != MESHX_SUCCESS) return MESHX_FAIL;
371 intg_state.gpio_initialized = true;
372 }
373
374 /* Create IO instance */
375 meshx_io_config_t io_config = {
376 .logical_pin = 0,
377 .io_type = 0,
378 .name = "TEST_PIN",
379 .config.gpio = {
381 .pull = MESHX_GPIO_PULL_NONE,
383 .initial_level = 0,
384 .signal_inversion = false,
385 },
386 };
387
388 meshx_io_handle_t io_handle = meshx_io_create(&io_config);
389 if (io_handle == NULL) {
390 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to create IO instance");
391 return MESHX_FAIL;
392 }
393
394 /* Test SET_LEVEL function */
395 uint32_t args[1] = {1};
396 meshx_err_t err = meshx_io_execute(io_handle, MESHX_IO_FUNC_SET_LEVEL, args, 1);
397 if (err != MESHX_SUCCESS) {
398 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "SET_LEVEL function failed: %d", err);
399 meshx_io_destroy(io_handle);
400 return MESHX_FAIL;
401 }
402
403 /* Test TOGGLE function */
404 err = meshx_io_execute(io_handle, MESHX_IO_FUNC_TOGGLE, NULL, 0);
405 if (err != MESHX_SUCCESS) {
406 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "TOGGLE function failed: %d", err);
407 meshx_io_destroy(io_handle);
408 return MESHX_FAIL;
409 }
410
411 /* Verify toggle worked (should be back to 0) */
412 uint8_t level;
413 err = meshx_io_get_level(io_handle, &level);
414 if (err != MESHX_SUCCESS || level != 0) {
415 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Toggle verification failed");
416 meshx_io_destroy(io_handle);
417 return MESHX_FAIL;
418 }
419
420 /* Test function support query */
421 bool supported = meshx_io_is_function_supported(io_handle, MESHX_IO_FUNC_SET_LEVEL);
422 if (!supported) {
423 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "SET_LEVEL should be supported for output pin");
424 meshx_io_destroy(io_handle);
425 return MESHX_FAIL;
426 }
427
428 /* Cleanup */
429 meshx_io_destroy(io_handle);
430
431 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: IO function execution");
432 return MESHX_SUCCESS;
433}
bool meshx_io_is_function_supported(meshx_io_handle_t handle, meshx_io_func_t function)
Check if function is supported.
Definition meshx_io_bridge.cpp:94
meshx_err_t meshx_io_execute(meshx_io_handle_t handle, meshx_io_func_t function, const uint32_t *args, uint8_t arg_count)
Execute IO function.
Definition meshx_io_bridge.cpp:62
@ MESHX_IO_FUNC_SET_LEVEL
Definition meshx_io_bridge.h:32
@ MESHX_IO_FUNC_TOGGLE
Definition meshx_io_bridge.h:34

◆ test_io_interface_creation()

meshx_err_t test_io_interface_creation ( void )
static

Test GPIO with abstract IO interface creation.

Validates that GPIO pins can be created through the abstract IO interface and that the IO bridge correctly dispatches operations to the GPIO subsystem.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
222{
223 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Test: IO interface creation");
224
225 /* Initialize GPIO subsystem */
227 if (err != MESHX_SUCCESS) {
228 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "GPIO init failed: %d", err);
229 return MESHX_FAIL;
230 }
231 intg_state.gpio_initialized = true;
232
233 /* Create IO instance through bridge */
234 meshx_io_config_t io_config = {
235 .logical_pin = 0,
236 .io_type = 0, /* GPIO type */
237 .name = "TEST_RELAY",
238 .config.gpio = {
240 .pull = MESHX_GPIO_PULL_NONE,
242 .initial_level = 0,
243 .signal_inversion = false,
244 },
245 };
246
247 meshx_io_handle_t io_handle = meshx_io_create(&io_config);
248 if (io_handle == NULL) {
249 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to create IO instance");
250 return MESHX_FAIL;
251 }
252
253 /* Verify IO instance properties */
254 uint8_t logical_pin = meshx_io_get_logical_pin(io_handle);
255 if (logical_pin != 0) {
257 "IO instance logical pin mismatch: expected 0, got %u", logical_pin);
258 meshx_io_destroy(io_handle);
259 return MESHX_FAIL;
260 }
261
262 const char* name = meshx_io_get_name(io_handle);
263 if (name == NULL || strcmp(name, "TEST_RELAY") != 0) {
264 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "IO instance name mismatch");
265 meshx_io_destroy(io_handle);
266 return MESHX_FAIL;
267 }
268
269 /* Cleanup */
270 meshx_io_destroy(io_handle);
271
272 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: IO interface creation");
273 return MESHX_SUCCESS;
274}
const char * meshx_io_get_name(meshx_io_handle_t handle)
Get pin name.
Definition meshx_io_bridge.cpp:87
uint8_t meshx_io_get_logical_pin(meshx_io_handle_t handle)
Get logical pin number.
Definition meshx_io_bridge.cpp:80

◆ test_kv_config_export_import()

meshx_err_t test_kv_config_export_import ( void )
static

Test KV Engine configuration export/import.

Validates that configuration can be exported to binary format and imported back correctly.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
880{
881 MESHX_LOGD(MODULE_ID_COMMON, "Test: KV config export/import");
882
883 if (!intg_state.kv_initialized) {
884 meshx_err_t err = meshx_gpio_kv_init(&mock_kv_partition, "test_product");
885 if (err != MESHX_SUCCESS) return MESHX_FAIL;
886 intg_state.kv_initialized = true;
887 }
888
889 /* Setup test configuration */
891
892 /* Export configuration to buffer */
893 uint8_t export_buffer[512];
894 uint16_t export_size = 0;
895
896 meshx_err_t err = meshx_gpio_export_config(intg_state.test_configs, 4,
897 export_buffer, sizeof(export_buffer),
898 &export_size);
899 if (err != MESHX_SUCCESS) {
900 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Export failed: %d", err);
901 return MESHX_FAIL;
902 }
903
904 /* Verify export size is reasonable */
905 if (export_size == 0 || export_size > sizeof(export_buffer)) {
906 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Invalid export size: %u", export_size);
907 return MESHX_FAIL;
908 }
909
910 /* Import configuration from buffer */
911 meshx_gpio_pin_config_t imported_configs[8];
912 uint8_t imported_count = 0;
913
914 err = meshx_gpio_import_config(export_buffer, export_size,
915 imported_configs, 8, &imported_count);
916 if (err != MESHX_SUCCESS) {
917 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Import failed: %d", err);
918 return MESHX_FAIL;
919 }
920
921 /* Verify imported configuration matches original */
922 if (imported_count != 4) {
924 "Imported count mismatch: expected 4, got %u", imported_count);
925 return MESHX_FAIL;
926 }
927
928 for (uint8_t i = 0; i < imported_count; i++) {
929 if (imported_configs[i].logical_pin != intg_state.test_configs[i].logical_pin ||
930 imported_configs[i].mode != intg_state.test_configs[i].mode) {
932 "Imported config mismatch at pin %u", i);
933 return MESHX_FAIL;
934 }
935 }
936
937 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: KV config export/import");
938 return MESHX_SUCCESS;
939}
meshx_err_t meshx_gpio_export_config(const meshx_gpio_pin_config_t *configs, uint8_t pin_count, uint8_t *buf, uint16_t buf_len, uint16_t *out_size)
Export GPIO configuration to serialized format.
Definition meshx_gpio_kv.c:532
meshx_err_t meshx_gpio_import_config(const uint8_t *buf, uint16_t buf_len, meshx_gpio_pin_config_t *configs, uint8_t max_pins, uint8_t *out_pin_count)
Import GPIO configuration from serialized format.
Definition meshx_gpio_kv.c:558

◆ test_kv_config_load()

meshx_err_t test_kv_config_load ( void )
static

Test GPIO configuration load from KV Engine.

Validates that GPIO configuration can be loaded and deserialized from KV Engine.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
709{
710 MESHX_LOGD(MODULE_ID_COMMON, "Test: KV config load");
711
712 if (!intg_state.kv_initialized) {
713 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV not initialized");
714 return MESHX_FAIL;
715 }
716
717 /* Load configuration from KV Engine */
718 meshx_gpio_pin_config_t loaded_configs[8];
719 uint8_t pin_count = 0;
720
721 meshx_err_t err = meshx_gpio_load_config_from_kv(loaded_configs, 8, &pin_count);
722 if (err != MESHX_SUCCESS) {
723 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to load config: %d", err);
724 return MESHX_FAIL;
725 }
726
727 intg_state.kv_load_count++;
728
729 /* Verify pin count matches */
730 if (pin_count != 4) {
732 "Pin count mismatch: expected 4, got %u", pin_count);
733 return MESHX_FAIL;
734 }
735
736 /* Verify configuration values */
737 for (uint8_t i = 0; i < pin_count; i++) {
738 if (loaded_configs[i].logical_pin != intg_state.test_configs[i].logical_pin) {
740 "Pin %u logical_pin mismatch", i);
741 return MESHX_FAIL;
742 }
743 if (loaded_configs[i].physical_pin != intg_state.test_configs[i].physical_pin) {
745 "Pin %u physical_pin mismatch", i);
746 return MESHX_FAIL;
747 }
748 if (loaded_configs[i].mode != intg_state.test_configs[i].mode) {
749 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Pin %u mode mismatch", i);
750 return MESHX_FAIL;
751 }
752 }
753
754 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: KV config load");
755 return MESHX_SUCCESS;
756}

◆ test_kv_config_round_trip()

meshx_err_t test_kv_config_round_trip ( void )
static

Test KV Engine configuration round-trip.

Validates that saving and loading configuration produces identical results.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
766{
767 MESHX_LOGD(MODULE_ID_COMMON, "Test: KV config round-trip");
768
769 /* Initialize KV if needed */
770 if (!intg_state.kv_initialized) {
771 meshx_err_t err = meshx_gpio_kv_init(&mock_kv_partition, "test_product");
772 if (err != MESHX_SUCCESS) return MESHX_FAIL;
773 intg_state.kv_initialized = true;
774 }
775
776 /* Clear any existing config */
778
779 /* Setup and save original configuration */
781
783 if (err != MESHX_SUCCESS) {
784 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to save original config");
785 return MESHX_FAIL;
786 }
787
788 /* Load configuration */
789 meshx_gpio_pin_config_t loaded_configs[8];
790 uint8_t pin_count = 0;
791
792 err = meshx_gpio_load_config_from_kv(loaded_configs, 8, &pin_count);
793 if (err != MESHX_SUCCESS) {
794 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to load config");
795 return MESHX_FAIL;
796 }
797
798 /* Compare configurations */
799 if (pin_count != 4) {
800 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Pin count mismatch in round-trip");
801 return MESHX_FAIL;
802 }
803
804 for (uint8_t i = 0; i < pin_count; i++) {
805 if (loaded_configs[i].logical_pin != intg_state.test_configs[i].logical_pin ||
806 loaded_configs[i].physical_pin != intg_state.test_configs[i].physical_pin ||
807 loaded_configs[i].mode != intg_state.test_configs[i].mode ||
808 loaded_configs[i].pull != intg_state.test_configs[i].pull ||
809 loaded_configs[i].drive_strength != intg_state.test_configs[i].drive_strength) {
811 "Config mismatch at pin %u in round-trip", i);
812 return MESHX_FAIL;
813 }
814 }
815
816 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: KV config round-trip");
817 return MESHX_SUCCESS;
818}
meshx_err_t meshx_gpio_clear_config_in_kv(void)
Clear GPIO configuration from KV Engine.
Definition meshx_gpio_kv.c:580

◆ test_kv_config_save()

meshx_err_t test_kv_config_save ( void )
static

Test GPIO configuration save to KV Engine.

Validates that GPIO configuration can be serialized and saved to KV Engine.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
667{
668 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Test: KV config save");
669
670 /* Initialize KV if needed */
671 if (!intg_state.kv_initialized) {
672 meshx_err_t err = meshx_gpio_kv_init(&mock_kv_partition, "test_product");
673 if (err != MESHX_SUCCESS) return MESHX_FAIL;
674 intg_state.kv_initialized = true;
675 }
676
677 /* Setup test configuration */
679
680 /* Save configuration to KV Engine */
682 if (err != MESHX_SUCCESS) {
683 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to save config: %d", err);
684 return MESHX_FAIL;
685 }
686
687 intg_state.kv_save_count++;
688
689 /* Verify config exists */
690 bool exists = false;
691 err = meshx_gpio_config_exists_in_kv(&exists);
692 if (err != MESHX_SUCCESS || !exists) {
693 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Config should exist after save");
694 return MESHX_FAIL;
695 }
696
697 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: KV config save");
698 return MESHX_SUCCESS;
699}
meshx_err_t meshx_gpio_config_exists_in_kv(bool *exists)
Check if GPIO configuration exists in KV Engine.
Definition meshx_gpio_kv.c:384

◆ test_kv_corruption_recovery()

meshx_err_t test_kv_corruption_recovery ( void )
static

Test KV Engine corruption recovery.

Validates that corrupted KV Engine data triggers fallback to defaults and logs appropriate errors.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
950{
951 MESHX_LOGD(MODULE_ID_COMMON, "Test: KV corruption recovery");
952
953 if (!intg_state.kv_initialized) {
954 meshx_err_t err = meshx_gpio_kv_init(&mock_kv_partition, "test_product");
955 if (err != MESHX_SUCCESS) return MESHX_FAIL;
956 intg_state.kv_initialized = true;
957 }
958
959 /* Clear any existing config */
961
962 /* Save valid configuration */
965 if (err != MESHX_SUCCESS) {
966 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to save config");
967 return MESHX_FAIL;
968 }
969
970 /* Clear config to simulate corruption scenario */
972 if (err != MESHX_SUCCESS) {
973 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to clear config");
974 return MESHX_FAIL;
975 }
976
977 /* Attempt to load - should return not found */
978 meshx_gpio_pin_config_t loaded_configs[8];
979 uint8_t pin_count = 0;
980
981 err = meshx_gpio_load_config_from_kv(loaded_configs, 8, &pin_count);
982 if (err == MESHX_SUCCESS) {
984 "Load should fail after clear");
985 return MESHX_FAIL;
986 }
987
988 /* This is expected - MESHX_NOT_FOUND indicates we should use compiled defaults */
989 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: KV corruption recovery");
990 return MESHX_SUCCESS;
991}

◆ test_kv_engine_init()

meshx_err_t test_kv_engine_init ( void )
static

Test GPIO KV Engine initialization.

Validates that the GPIO KV persistence layer initializes correctly with a FAL partition and product name.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
637{
638 MESHX_LOGD(MODULE_ID_COMPONENT_MESHX_GPIO, "Test: KV Engine initialization");
639
640 /* Initialize GPIO KV persistence */
641 meshx_err_t err = meshx_gpio_kv_init(&mock_kv_partition, "test_product");
642 if (err != MESHX_SUCCESS) {
643 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV init failed: %d", err);
644 return MESHX_FAIL;
645 }
646
647 intg_state.kv_initialized = true;
648
649 /* Verify initialized state */
651 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "KV should be initialized");
652 return MESHX_FAIL;
653 }
654
655 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: KV Engine initialization");
656 return MESHX_SUCCESS;
657}
bool meshx_gpio_kv_is_initialized(void)
Check if GPIO KV persistence is initialized.
Definition meshx_gpio_kv.c:639

◆ test_kv_pin_state_persistence()

meshx_err_t test_kv_pin_state_persistence ( void )
static

Test KV Engine pin state persistence.

Validates that runtime pin states can be saved and restored from KV Engine.

Returns
meshx_err_t MESHX_SUCCESS on success, error code on failure
828{
829 MESHX_LOGD(MODULE_ID_COMMON, "Test: KV pin state persistence");
830
831 if (!intg_state.kv_initialized) {
832 meshx_err_t err = meshx_gpio_kv_init(&mock_kv_partition, "test_product");
833 if (err != MESHX_SUCCESS) return MESHX_FAIL;
834 intg_state.kv_initialized = true;
835 }
836
837 /* Create test pin state */
838 meshx_gpio_pin_state_t original_state = {
839 .current_level = 1,
840 .interrupt_registered = false,
841 .intr_type = MESHX_GPIO_INTR_DISABLED,
842 .intr_callback = NULL,
843 .intr_user_data = NULL,
844 };
845
846 /* Save pin state */
847 meshx_err_t err = meshx_gpio_save_pin_state_to_kv(0, &original_state);
848 if (err != MESHX_SUCCESS) {
849 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to save pin state: %d", err);
850 return MESHX_FAIL;
851 }
852
853 /* Load pin state */
854 meshx_gpio_pin_state_t loaded_state;
855 err = meshx_gpio_load_pin_state_from_kv(0, &loaded_state);
856 if (err != MESHX_SUCCESS) {
857 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Failed to load pin state: %d", err);
858 return MESHX_FAIL;
859 }
860
861 /* Verify state */
862 if (loaded_state.current_level != original_state.current_level) {
863 MESHX_LOGE(MODULE_ID_COMPONENT_MESHX_GPIO, "Pin state level mismatch");
864 return MESHX_FAIL;
865 }
866
867 MESHX_LOGI(MODULE_ID_COMPONENT_MESHX_GPIO, "PASS: KV pin state persistence");
868 return MESHX_SUCCESS;
869}
meshx_err_t meshx_gpio_save_pin_state_to_kv(uint8_t logical_pin, const meshx_gpio_pin_state_t *state)
Save current pin state to KV Engine.
Definition meshx_gpio_kv.c:420
meshx_err_t meshx_gpio_load_pin_state_from_kv(uint8_t logical_pin, meshx_gpio_pin_state_t *state)
Load pin state from KV Engine.
Definition meshx_gpio_kv.c:477
@ MESHX_GPIO_INTR_DISABLED
Definition meshx_gpio_types.h:29
GPIO Pin State Structure.
Definition meshx_gpio_types.h:91
uint8_t current_level
Definition meshx_gpio_types.h:92

Variable Documentation

◆ intg_state

gpio_integration_state_t intg_state
static

◆ mock_kv_partition

meshx_fal_partition_t mock_kv_partition
static
Initial value:
= {
.name = "kv_store",
.base_addr = 0,
.size = 4096,
.sector_size = 4096,
.priv = NULL,
}

Mock FAL partition for KV Engine testing.

74 {
75 .name = "kv_store",
76 .base_addr = 0,
77 .size = 4096,
78 .sector_size = 4096,
79 .priv = NULL,
80};