feat: migrate config management from TOML to FlatBuffers
Config is now loaded at runtime via WebSocket (ConfigCtrlMessage) instead of from hardcoded TOML files. The emulator starts with no devices and waits for clients to send configuration. - Define FlatBuffers schemas: EmulationConfig, ComposeDeviceConfig, BaseDeviceConfig with recursive DeviceConfig union - Rename MemSegment.start → addr (flatcc builder/reader name collision) - Add ConfigCtrlMessage handler: validates STILL state, walks the device tree depth-first, assigns numeric IDs, responds with DeviceIdMappingNotif or ConfigLoadError - Add fb_build_config_device_id_mapping() and fb_build_config_error() FlatBuffer builders - Remove hardcoded device loading from main.c; iterate dynamically loaded devices in the exec loop - Fix double-free: freeConf() already frees the struct itself, remove redundant free() calls in config.c and base_device.c - Fix heap-buffer-overflow in device parseSpecsFromConfig: malloc for segment name was missing +1 for the null terminator Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
102
src/proto/msg.c
102
src/proto/msg.c
@@ -248,3 +248,105 @@ uint8_t* fb_build_stream_reg_confirm(
|
||||
NULL_GUARD(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
uint8_t* fb_build_config_device_id_mapping(
|
||||
uint64_t nonce,
|
||||
char** paths[], size_t path_lens[],
|
||||
size_t device_count, size_t* len_out)
|
||||
{
|
||||
flatcc_builder_t B;
|
||||
if (flatcc_builder_init(&B)) {
|
||||
panic("flatcc_builder_init failed\n");
|
||||
}
|
||||
|
||||
// Pre-create DeviceIdEntry refs (bottom-up: strings first, then tables)
|
||||
hmmmm_ctrl_config_notif_DeviceIdEntry_ref_t entry_refs[device_count];
|
||||
|
||||
for (size_t i = 0; i < device_count; i++) {
|
||||
// Build string vector for path
|
||||
flatbuffers_string_vec_start(&B);
|
||||
for (size_t j = 0; j < path_lens[i]; j++) {
|
||||
flatbuffers_string_ref_t sref = flatbuffers_string_create_str(&B, paths[i][j]);
|
||||
flatbuffers_string_vec_push(&B, sref);
|
||||
}
|
||||
flatbuffers_string_vec_ref_t path_vec = flatbuffers_string_vec_end(&B);
|
||||
|
||||
// Empty seg_ids vector
|
||||
hmmmm_ctrl_config_notif_SegIdEntry_vec_start(&B);
|
||||
hmmmm_ctrl_config_notif_SegIdEntry_vec_ref_t seg_ids_vec =
|
||||
hmmmm_ctrl_config_notif_SegIdEntry_vec_end(&B);
|
||||
|
||||
entry_refs[i] = hmmmm_ctrl_config_notif_DeviceIdEntry_create(
|
||||
&B, path_vec, (uint32_t)i, seg_ids_vec);
|
||||
}
|
||||
|
||||
// Build entries vector
|
||||
hmmmm_ctrl_config_notif_DeviceIdEntry_vec_start(&B);
|
||||
for (size_t i = 0; i < device_count; i++) {
|
||||
hmmmm_ctrl_config_notif_DeviceIdEntry_vec_push(&B, entry_refs[i]);
|
||||
}
|
||||
hmmmm_ctrl_config_notif_DeviceIdEntry_vec_ref_t entries_vec =
|
||||
hmmmm_ctrl_config_notif_DeviceIdEntry_vec_end(&B);
|
||||
|
||||
hmmmm_ctrl_config_notif_DeviceIdMappingNotif_ref_t mapping =
|
||||
hmmmm_ctrl_config_notif_DeviceIdMappingNotif_create(&B, entries_vec);
|
||||
|
||||
hmmmm_ctrl_config_notif_ConfigNotifPayload_union_ref_t notif_payload =
|
||||
hmmmm_ctrl_config_notif_ConfigNotifPayload_as_DeviceIdMappingNotif(mapping);
|
||||
|
||||
hmmmm_ctrl_config_notif_ConfigNotifMessage_ref_t notif_msg =
|
||||
hmmmm_ctrl_config_notif_ConfigNotifMessage_create(&B, 0, notif_payload);
|
||||
|
||||
hmmmm_ctrl_CtrlServerPayload_union_ref_t ctrl_payload =
|
||||
hmmmm_ctrl_CtrlServerPayload_as_ConfigNotifMessage(notif_msg);
|
||||
|
||||
hmmmm_ctrl_CtrlServerMessage_ref_t ctrl_msg =
|
||||
hmmmm_ctrl_CtrlServerMessage_create(&B, ctrl_payload);
|
||||
|
||||
hmmmm_ServerPayload_union_ref_t payload =
|
||||
hmmmm_ServerPayload_as_CtrlServerMessage(ctrl_msg);
|
||||
|
||||
hmmmm_ServerMessage_create_as_root(&B, nonce, payload);
|
||||
|
||||
uint8_t* buf = flatcc_builder_finalize_buffer(&B, len_out);
|
||||
flatcc_builder_clear(&B);
|
||||
NULL_GUARD(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
uint8_t* fb_build_config_error(uint64_t nonce, const char* message, size_t* len_out)
|
||||
{
|
||||
flatcc_builder_t B;
|
||||
if (flatcc_builder_init(&B)) {
|
||||
panic("flatcc_builder_init failed\n");
|
||||
}
|
||||
|
||||
flatbuffers_string_ref_t msg_str = flatbuffers_string_create_str(&B, message);
|
||||
|
||||
hmmmm_ctrl_config_notif_ConfigLoadError_ref_t err =
|
||||
hmmmm_ctrl_config_notif_ConfigLoadError_create(&B, msg_str);
|
||||
|
||||
hmmmm_ctrl_config_notif_ConfigNotifPayload_union_ref_t notif_payload =
|
||||
hmmmm_ctrl_config_notif_ConfigNotifPayload_as_ConfigLoadError(err);
|
||||
|
||||
hmmmm_ctrl_config_notif_ConfigNotifMessage_ref_t notif_msg =
|
||||
hmmmm_ctrl_config_notif_ConfigNotifMessage_create(&B, 0, notif_payload);
|
||||
|
||||
hmmmm_ctrl_CtrlServerPayload_union_ref_t ctrl_payload =
|
||||
hmmmm_ctrl_CtrlServerPayload_as_ConfigNotifMessage(notif_msg);
|
||||
|
||||
hmmmm_ctrl_CtrlServerMessage_ref_t ctrl_msg =
|
||||
hmmmm_ctrl_CtrlServerMessage_create(&B, ctrl_payload);
|
||||
|
||||
hmmmm_ServerPayload_union_ref_t payload =
|
||||
hmmmm_ServerPayload_as_CtrlServerMessage(ctrl_msg);
|
||||
|
||||
hmmmm_ServerMessage_create_as_root(&B, nonce, payload);
|
||||
|
||||
uint8_t* buf = flatcc_builder_finalize_buffer(&B, len_out);
|
||||
flatcc_builder_clear(&B);
|
||||
NULL_GUARD(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user