Plugin refactor#1127
Open
TheGreatCodeholio wants to merge 17 commits intoTrunkRecorder:masterfrom
Open
Conversation
- remove OpenMHz/Broadcastify credential storage from System - stop parsing legacy system-level uploader settings in config.cc - move uploader compressWav validation into plugin init() - require uploader plugins to be explicitly loaded via plugins array - fix plugin manager parse_config/init failure handling - initialize plugin state when creating plugin instances - clean up remaining mixed legacy uploader config behavior Updated documentation to reflect plugin changes and added new docs for each "interal" plugin
… archival - keep wav/json/m4a artifacts in temp while uploadScript and plugins run - split working paths from final archive destinations - finalize by moving archived call/transmission files from temp to captureDir - keep temp files for retries and clean them only after finalization - replace legacy remove_call_files flow with explicit finalize/cleanup handling This makes uploadScript and plugins operate on guaranteed temp artifacts, reduces unnecessary disk writes/removals, and prepares the pipeline for future archive plugins and JSON enrichment before archival.
… plugin - add shared call_end JSON context for plugin metadata - write plugin output under each plugin name in final call JSON - preserve plugin JSON state across retries - add whisper_transcribe example plugin for OpenAI-compatible APIs - support per-system shortName matching and talkgroup allow/deny filters - return a stable transcript metadata shape for all outcomes - add build wiring for whisper_transcribe This makes plugin metadata enrichment first-class and provides a practical reference plugin for future transcript and post-processing plugins.
- update rdioscanner_uploader and openmhz_uploader to override the new Plugin_Api call_end signature - pass through the shared plugin JSON context parameter (unused for now) - add temporary call concluder debug logging to verify worker flow and plugin execution Why: plugin_manager now calls the new call_end(Call_Data_t&, ordered_json&) API. RDIO and OpenMHz still implemented the old one-argument call_end method, so their uploader logic was never invoked and uploads were silently skipped.
…e retries - add pluginType support to plugin manager and Plugin objects - split call_end handling into ordered blocking and concurrent deferred phases - track blocking/deferred plugin retries separately in Call_Data_t - keep blocking plugins as JSON enrichers and deferred plugins as read-only consumers of temp artifacts - run deferred plugins before archive/finalize so temp JSON/audio remain available throughout plugin processing - restore encrypted call handling to the legacy inline path with metadata JSON creation/writing and immediate finalize/cleanup - preserve tempDir-first artifact flow and archive only after plugin work completes This gives metadata plugins a deterministic enrichment phase, lets uploader and notification plugins run concurrently with retries, and keeps encrypted calls and temp-file behavior aligned with existing expectations.
# Conflicts: # docs/CONFIGURE.md # trunk-recorder/global_structs.h
fix some bugs in call_concluder where files were not deleted from tmp properly.
…lugins marked running
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR is a significant rework of the plugin system, call conclusion pipeline, and runtime configuration. The changes fall into five areas:
plugin_api.h, plugin_manager.cc/.h, global_structs.h
call_end now takes two additional parameters:
virtual int call_end(Call_Data_t& call_info, nlohmann::ordered_json& plugin_ctx);
Plugins are classified in config as "pluginType": "blocking" (default) or "pluginType": "deferred".
independently.
Retry tracking is split into blocking_plugin_retry_list and deferred_plugin_retry_list on Call_Data_t. Files are only finalized (moved from tempDir to captureDir) after both phases complete successfully.
Three bugs fixed in this dispatch logic (see last section).
All existing plugins (broadcastify, openmhz, rdioscanner, simplestream, stat_socket) updated to the new signature.
Each blocking plugin gets a nlohmann::ordered_json object keyed by plugin name in call_info.call_json. This lets plugins write structured data into the call's JSON file — useful for transcription results, upload receipts, or
any per-plugin metadata that should travel with the call record.
The JSON file is written twice: once before upload script / plugins run (so the upload script sees complete call metadata), and again after all blocking plugins complete (so any plugin-written context is persisted to disk
before deferred plugins receive it).
New files: config_service.h, config_service.cc, examples/example_config_plugin.cc/.h
Plugins can now request runtime changes to SDR source and system parameters without restarting. The service exposes a thread-safe command queue processed on the main loop:
// From any plugin:
get_config_service()->set_source_gain(0, 45.0, plugin_name, callback);
get_config_service()->set_system_squelch_db(0, -60.0, plugin_name, callback);
Supported parameters:
Changes trigger on_config_change(ConfigChangeInfo&) callbacks to all running plugins, so plugins can react to changes made by other plugins.
Source::set_error now immediately applies the correction to the SDR hardware (osmosdr/USRP) rather than only updating the in-memory value. Source::get_gain_mode accessor added.
Sources and Systems track a config_index (their array position in the JSON) so the config service can look them up for save_config.
save_config() added to persist runtime changes back to the config file.
call_concluder.cc
Temp-dir-first archival
All call artifacts (.wav, .m4a, .json, raw wav) are written to tempDir during processing. Only after all plugins succeed are they moved to their final destinations under captureDir. Cross-device moves (e.g. tmpfs/ramdisk →
disk) fall back to copy+delete. Call_Data_t gains final_* fields for the archive destinations.
remove_call_files replaced by two focused functions:
Bug fixes
config.cc, global_structs.h, system_impl.cc/.h
upload_server and bcfy_calls_server removed from Config. api_key, bcfy_api_key, and bcfy_system_id removed from System. These were only ever used by the uploader plugins; keeping them on shared structs forced the core to know
about plugin-specific config.
The three previously hard-coded "internal" plugins (openmhz_uploader, broadcastify_uploader, unit_script) are no longer auto-loaded via add_internal_plugin. They are now regular plugins configured in the plugins array. The
add_internal_plugin function is removed entirely.
The compressWav validation for Broadcastify is moved from config.cc into Broadcastify_Uploader::init(), where it belongs.
Three bugs fixed in this session:
Deferred plugins silently skipped after blocking retry. When blocking plugins failed on the initial attempt, upload_call_worker returned early before reaching plugman_call_end_deferred. On the retry pass, call_info.status ==
RETRY caused plugman_call_end_deferred to take the retry-list path — but deferred_plugin_retry_list was empty (deferred had never run), so all deferred plugins were skipped and files finalized without them. Fixed by adding
deferred_plugins_ran to Call_Data_t; plugman_call_end_deferred always does a full run on first invocation regardless of status.
Failed plugins promoted to PLUGIN_RUNNING. start_plugins set plugin->state = PLUGIN_RUNNING unconditionally for any plugin that didn't call continue inside the function. Plugins already in PLUGIN_FAILED (from parse_config or
init) skipped the PLUGIN_INITIALIZED block but still hit the assignment. Fixed with an early continue on PLUGIN_FAILED.
Missing retry logging. Per-plugin retry attempt logging was lost in the blocking path rewrite. Restored.
Documentation
Per-plugin documentation added under docs/plugins/:
docs/Plugins.md and docs/CONFIGURE.md updated to reflect the new plugin configuration format, pluginType, and removal of top-level uploader keys.
simplestream plugin enabled in CMakeLists.txt.
Test Plan