- Removed global logger level setting and introduced a method to apply log levels based on service-specific verbose/debug settings.
- Added a new method for logging per-packet summaries, allowing for more granular logging control based on verbosity and debug flags.
- Updated packet logging to utilize the new summary method, ensuring appropriate log levels are used for packet capture actions.
Strip leading # when resolving channel names so webhook posts match
hashtag channels cached from the radio. Return HTTP 500 when mesh send
returns false instead of reporting success.
Updated the mesh scope assignment logic in the WebhookService to use a more concise inline conditional expression. This change improves code readability while maintaining the same functionality for determining the appropriate mesh scope based on the incoming request body.
Updated the _send_chunks method to assign timestamps based on the chunk index, ensuring each chunk receives a unique timestamp that increments by one second. This change facilitates proper ordering and deduplication of messages on the client side. Added a unit test to verify the correct behavior of timestamp assignment during chunk transmission.
- Introduced optional regional TC_FLOOD scope configuration for various services, allowing for more granular control over message routing.
- Updated the CommandManager to resolve and apply flood scopes from messages, configuration sections, and explicit parameters, ensuring correct message delivery.
- Enhanced service plugins to utilize the new flood scope functionality, including weather, earthquake, and webhook services.
- Added unit tests to verify the correct resolution and application of flood scopes in different scenarios, ensuring robust functionality.
For the emergency communication, we need to ensure that all messages are
transmitted (and received) correctly. We already check if a repeater
acks our message, however a missing ack does not tell us if the message
was lost, or the ack. For that, we repeat the message in this case,
leading to potentially content-wise duplicated receptions on the network.
To let the network depulicate the traffic, the re-transmissions need to
be bit identical with the original message. For that, we compute a
timestamp on initial send and use the same timestamp on
re-transmissions (per message). This further allows clients to
chronologically sort the received messages, making the result easier to
read.
Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
Some services are named <foo>_Service, whereby currently only the
Service part is stripped. By that, the service name is derived to be
<foo>_, instead of <foo>.
We fix this by stripping all leading and trailing underscores in the
service name.
Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
- Introduced `jwt_ttl_seconds` and `jwt_renewal_interval` settings in `config.ini.example` for global JWT management, allowing for better control over token expiration and renewal intervals.
- Updated documentation in `packet-capture.md` to clarify the usage of global and per-broker JWT settings, enhancing user understanding of authentication configurations.
- Refactored `PacketCaptureService` to incorporate new JWT settings, ensuring consistent handling of token lifetimes and renewal processes.
- Replaced the use of AdvertFlags enum for flag parsing with bitwise operations to handle invalid values correctly.
- Updated the parsing logic in both MessageHandler and MapUploaderService to use boolean flags for better clarity and performance.
- Adjusted error logging to use warnings instead of errors for parsing issues, enhancing the logging strategy.
- Added unit tests to ensure correct parsing behavior for edge cases with invalid flag values.
Add bridge_outbound posting, BaseServicePlugin.send_external_notifications,
and RepeaterPrefixCollision discovery vs collision routing with silence_mesh_output.
- Added configuration options `mqtt_skip_unparseable_packets` and `advert_require_valid_signature` to control MQTT publishing behavior based on packet validity.
- Updated `decode_path_len_byte` function to return `None` for reserved size codes, improving path length validation.
- Implemented logic in `PacketCaptureService` to skip publishing unparseable packets and ADVERT packets with invalid signatures.
- Introduced `verify_meshcore_advert_ed25519` function for signature verification of ADVERT packets, with corresponding unit tests to ensure functionality.
- Enhanced documentation to reflect new configuration options and their effects on packet processing.
- Replaced direct imports of `pytz` with dynamic imports for better compatibility.
- Updated type hints for server and loop attributes in the DARC MoWaS service.
- Enhanced XML handling by specifying `xml.dom.minidom.Element` in method signatures.
- Improved message processing logic to handle missing channels and ensure valid area descriptions.
- Refactored `_child_text` function to accept both `Document` and `Element` types for better flexibility.
- Adjusted unit tests to reflect changes in the DARC MoWaS service structure.
- Added configuration options to specify minimum path byte length requirements for the path, test, and multitest commands.
- Introduced methods to enforce these requirements and handle failure responses.
- Updated the packet capture service to correctly calculate packet hashes using the raw wire byte length.
- Enhanced unit tests to verify the correct behavior of the new path byte length logic.
For alert messages it is imporant to be sure they are received by the
network. For that, we implement a retry logic that waits for at least
one ack from a repeater and re-sends the message chunk if non is
received within a retry timeout.
Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
We implement support for the DARC MoWaS service that distributes
emergency messages from the German BBK via the "Warnmultiplikator"
interface to Meshcore channels. This service is push-based and receives
alerts on /api/alert, which are then formatted similar to cell-broadcast
messages (without modification of the text) and re-distributed on
Meshcore.
Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
Revised type hints in the PacketCaptureService class to use lowercase 'list' and 'dict' instead of 'List' and 'Dict', enhancing code readability and consistency with Python's typing conventions. Adjusted optional parameters to use the new union syntax for better clarity. No functional changes were made.
- Make MeshCoreBot.stop idempotent; remove duplicate stop from start().
- Avoid web viewer restart during shutdown; gate main-loop restarts.
- Fix packet capture MQTT callbacks to log each broker’s host.
- Only shutdown APScheduler when running; silence double-shutdown noise.
- Add regression tests in tests/test_shutdown_reliability.py.
Add SSRF host validation to maintenance.py send_nightly_email and
scheduler.py send_zombie_alert_email using validate_external_url().
New allow_local_smtp config key permits private-IP SMTP for local
relay setups.
Add sanitize_name() to security_utils and apply it to all log calls
in message_handler, repeater_manager, path_command, solarforecast_command,
command_manager, and discord_bridge_service to prevent log injection.
Move nightly email logic from duplicate scheduler._send_nightly_email()
into the canonical maintenance.py implementation, removing the duplicate.
Update tests to call maintenance.send_nightly_email() directly.
Add validate_external_url allow_private parameter with support for
loopback, RFC1918, CGN, and link-local address ranges.
- Increased the per-user rate limit from 5 to 30 seconds across multiple configuration files to reduce response frequency.
- Added the version command to the configuration examples and updated help text to include the new command.
- Refactored version information retrieval in the bot and web viewer to utilize a shared runtime resolver for consistency.
- Improved documentation in README.md to reflect changes in commands and configuration options.
- Updated type hints to use `|` for union types instead of `Optional` where applicable, enhancing readability and consistency.
- Cleaned up import statements by removing unnecessary imports and organizing them for better clarity.
- Adjusted function signatures in various modules to reflect the new type hinting style, improving type safety and code maintainability.
These changes contribute to a more modern and consistent codebase, aligning with current Python typing practices.
Resolve conflicts by combining v0.9 integration work with dev-only behavior:
- Keep channel_responses_enabled, greeter pause checks, and max_response_hops gating
- Retain TRACE/repeat handling, MQTT weather, temperature format helpers, and feed tooling
- Unify package-data globs, ruff/mypy/pytest config, Rate_Limits/Webhook in config example
- Web viewer: config panels + X-Requested-With on channel API; drop redundant DBManager import
Made-with: Cursor
- Added new configuration options in `config.ini.example` for enabling and configuring MQTT weather sources.
- Updated `WxCommand` and `GlobalWxCommand` classes to retrieve weather data from custom MQTT topics, enhancing flexibility in weather data sources.
- Introduced error handling for MQTT data retrieval, ensuring robust responses for various error scenarios.
- Expanded translation strings in `en.json` to support MQTT-related messages, improving user feedback.
These changes enhance the application's capability to utilize MQTT for weather data, providing users with more options for weather information retrieval.
- Updated `update_mesh_graph_from_trace_data` to clarify the format of `path_hashes` as per-hop hash strings from the trace payload.
- Modified `MessageHandler` to differentiate between TRACE packets and regular transmissions, preventing incorrect extraction of repeater prefixes from RF path bytes.
- Introduced `parse_trace_payload_route_hashes` utility to extract TRACE route hash segments from payloads, ensuring accurate handling of path data.
- Enhanced `PacketCaptureService` to correctly populate packet information for TRACE packets, including SNR path and route hashes.
- Expanded test coverage for TRACE payload decoding and path extraction to validate functionality and correctness.
These changes improve the accuracy and reliability of TRACE data processing in the application.
- Added new configuration options in `config.ini.example` for customizing the display of daily high/low temperatures.
- Introduced `format_temperature_high_low` function in `utils.py` to format temperature strings based on user-defined templates.
- Updated `WxCommand`, `GlobalWxCommand`, and `WeatherService` classes to utilize the new formatting function, enhancing the presentation of temperature data in weather forecasts.
- Refactored existing high/low temperature handling to improve code clarity and maintainability.
These changes enhance the flexibility and readability of temperature displays in weather-related outputs.
- Introduced a new configuration option for selecting Open-Meteo models in `config.ini.example`, allowing users to specify a model or default to "best_match".
- Implemented `_load_weather_model` method in `GlobalWxCommand` and `WeatherService` classes to handle model selection logic, including validation and fallback mechanisms.
- Updated API request parameters to include the selected weather model when available, enhancing the flexibility of weather data retrieval.
These changes improve the customization of weather data requests and ensure robust handling of model selection in the application.
- Added a regex pattern to validate SQLite column definitions, preventing SQL injection in the _add_column() function.
- Introduced a new validation function to ensure safe column definitions are used.
- Updated repeater_manager.py to use list() for iterating over contacts, ensuring compatibility with potential changes in the underlying data structure.
- Enhanced error handling in the MessageScheduler for better debugging during scheduler shutdown and message sending.
These changes improve the security and reliability of database operations and enhance the robustness of the repeater management system.
- Introduced an asyncio lock to serialize deduplication checks and updates to seen adverts, preventing race conditions during concurrent advert processing.
- Enhanced replay attack detection by ensuring deduplication state is consistent across await boundaries.
- Improved logging for duplicate advert uploads and invalid coordinate handling, providing clearer feedback on advert processing outcomes.
These changes enhance the reliability and integrity of advert uploads in the MapUploaderService.
- Added a new configuration option `condense_paths` in `config.ini.example` to control path formatting.
- Enhanced `MultitestCommand` to condense output paths using shared prefixes and tree branches when `condense_paths` is enabled.
- Introduced utility functions for path processing, including `_condense_path_lines` and `_path_to_tokens`.
- Updated tests to validate the new path condensing functionality and configuration behavior.
- Removed MQTT configuration from `config.ini.example` to streamline settings.
- Added new section for Repeater Prefix Collision Service in `config.ini.example`, including options for enabling notifications, alert channels, and prefix handling.
- Updated `service-plugins.md` to include documentation for the new Repeater Prefix Collision Service, enhancing user awareness of available plugins.
- Added today's high and low temperatures to the weather forecast output, improving clarity for users.
- Updated formatting to include labels for high and low temperatures, ensuring better readability of the forecast information.
- Removed MQTT configuration from `config.ini.example` to streamline settings.
- Added new section for Repeater Prefix Collision Service in `config.ini.example`, including options for enabling notifications, alert channels, and prefix handling.
- Updated `service-plugins.md` to include documentation for the new Repeater Prefix Collision Service, enhancing user awareness of available plugins.
- Added today's high and low temperatures to the weather forecast output, improving clarity for users.
- Updated formatting to include labels for high and low temperatures, ensuring better readability of the forecast information.
- Added configuration options for URL shortening in `config.ini.example` and updated documentation in `FEEDS.md`.
- Enhanced `FeedManager` to support URL shortening based on new settings, allowing for both global and per-link shortening.
- Refactored message formatting logic to incorporate URL shortening features, ensuring compatibility with existing link handling.
- Introduced new utility functions for encoding path length bytes in `utils.py`, improving path management in message handling.
- Added unit tests to validate the new URL shortening functionality and ensure proper behavior under various conditions.
- Added configuration options for URL shortening in `config.ini.example` and updated documentation in `FEEDS.md`.
- Enhanced `FeedManager` to support URL shortening based on new settings, allowing for both global and per-link shortening.
- Refactored message formatting logic to incorporate URL shortening features, ensuring compatibility with existing link handling.
- Introduced new utility functions for encoding path length bytes in `utils.py`, improving path management in message handling.
- Added unit tests to validate the new URL shortening functionality and ensure proper behavior under various conditions.
- Updated the `resolve_path` function in `utils.py` to clarify behavior regarding absolute paths.
- Changed type hints in `discord_bridge_service.py` for better clarity and consistency.
- Removed unused imports and unnecessary comments in various test files to improve code cleanliness and readability.
- Updated config.ini.example and discord-bridge.md to reflect the ability to fan out a single MeshCore channel to multiple Discord servers using a comma- or whitespace-separated list of webhook URLs.
- Modified DiscordBridgeService to handle multiple webhooks per channel, including validation and logging improvements for better monitoring of configured webhooks.
BUG-001: web viewer login/session auth (in web viewer commit)
BUG-002: db_manager ALTER TABLE for missing channel_operations and
feed_message_queue columns on startup
BUG-015: scheduler thread blocked on future.result(); replaced all
blocking waits with add_done_callback (fire-and-forget)
BUG-016: reboot_radio sends meshcore.commands.reboot() before disconnect
BUG-017: radio disconnect uses asyncio.wait_for(timeout=10)
BUG-022: custom asyncio loop exception handler suppresses IndexError
from meshcore parser at DEBUG level
BUG-024: last_db_backup_run updated after each run; 2-min startup
window; last-run seeded from DB on restart
BUG-025: send_channel_message retries up to 2 times (2s delay) on
no_event_received via _is_no_event_received() helper
BUG-026: split_text_into_chunks() and get_max_message_length() added
to CommandManager; keyword dispatch uses send_response_chunked()
BUG-028: byte_data = b"" initialised before try block in
decode_meshcore_packet to prevent UnboundLocalError in except handler
TraceCommand: path nodes reversed and return path truncated; fixed
format_elapsed_display: UTC normalisation before elapsed computation (#75)
RepeaterManager: auto_manage_contacts guard before any purge logic (#50)
Command aliases: [Aliases] config section injects shorthands at startup
JSON logging: _JsonFormatter; json_logging = true in [Logging]
Structured JSON logging compatible with Loki, Elasticsearch, Splunk
Discord bridge, Telegram bridge, and all service plugins updated
MeshGraph edge promotion logic corrected
Shutdown: scheduler and meshcore disconnect joined cleanly; log spam fixed
All modules: ruff and mypy cleanup applied (type annotations, imports)
Add POST /webhook endpoint to the web viewer. Authenticated via
Authorization: Bearer <token> set in [Webhook] config section. Relays
JSON or text payload to a configured MeshCore channel or user DM.
- Updated config.ini.example and discord-bridge.md to reflect the ability to fan out a single MeshCore channel to multiple Discord servers using a comma- or whitespace-separated list of webhook URLs.
- Modified DiscordBridgeService to handle multiple webhooks per channel, including validation and logging improvements for better monitoring of configured webhooks.
- Updated config.ini.example and discord-bridge.md to reflect the ability to fan out a single MeshCore channel to multiple Discord servers using a comma- or whitespace-separated list of webhook URLs.
- Modified DiscordBridgeService to handle multiple webhooks per channel, including validation and logging improvements for better monitoring of configured webhooks.
- Changed the default IATA code from 'LOC' to 'XYZ' in `config.ini.example` and `packet-capture.md` to reflect updated routing requirements.
- Updated the `PacketCaptureService` to use 'XYZ' as the fallback IATA code, ensuring consistency across the application.
- Added configuration options to bridge the bot's own channel responses to Discord and Telegram, allowing command replies to be sent to respective channels.
- Updated `DiscordBridgeService` and `TelegramBridgeService` to register listeners for bot-sent messages, ensuring they are included in the bridging process.
- Enhanced `CommandManager` to invoke listeners with a synthetic event when a message is successfully sent, providing context about the message.
- Updated `config.ini.example` to reflect the new `bridge_bot_responses` option for both services.
- Added tests to verify the correct invocation of listeners upon successful message sending.
- Introduced `filter_profanity` configuration option in `config.ini.example` to handle profanity in bridged messages: options include `drop` (default), `censor`, or `off`.
- Updated `requirements.txt` to include `better-profanity` for profanity filtering functionality.
- Enhanced `DiscordBridgeService` and `TelegramBridgeService` to implement the profanity filter logic, allowing messages with profanity to be dropped or censored before bridging.
- Updated documentation in `discord-bridge.md` and `telegram-bridge.md` to reflect the new profanity handling feature.