mirror of
https://github.com/meshtastic/firmware.git
synced 2026-11-06 06:14:45 -05:00
* DMShell: an on-board test client for the remote shell A DMShell session is normally driven by bin/dmshell_client.py over the API, which puts the test's own traffic on the serial port it is logging. This builds the client into the firmware instead: -DDMSHELL_TEST_PEER=0x<node> gives the board a client that opens a session to that node and types a workload itself, so a run needs no host and the serial port stays in logging mode for its whole length. It speaks the same protocol as the Python client, on the sequence and replay bookkeeping already in DMShellRecovery.h, and keeps the same per-session counters so the two can be compared directly. Unset, nothing is built and nothing is linked: the flag guards both source files and the one hook in Modules.cpp. DMSHELL_TEST_* set the workload (the command, keystroke interval, session length and count, how keystrokes are batched into frames, the input window). DMSHELL_TEST_SLOT_PARITY, when set, stamps slot_parity on every packet it sends. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VUcRFYYQhAcSSKRC2h7mMn * DMShellTest: require PKI on the peer's frames The test client accepted any decoded packet on the remote shell port whose `from` matched its peer. A channel-encrypted packet can claim any `from`, so a forged CLOSED with the live session id would end a session and a forged `ack_seq` would move the send window. The server already refuses a frame without PKI; the client now does the same. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VUcRFYYQhAcSSKRC2h7mMn --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
311 lines
10 KiB
C++
311 lines
10 KiB
C++
#include "configuration.h"
|
|
#if !MESHTASTIC_EXCLUDE_INPUTBROKER
|
|
#include "buzz/BuzzerFeedbackThread.h"
|
|
#include "modules/SystemCommandsModule.h"
|
|
#endif
|
|
#include "modules/StatusLEDModule.h"
|
|
#if !MESHTASTIC_EXCLUDE_REPLYBOT
|
|
#include "ReplyBotModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_PKI
|
|
#include "KeyVerificationModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_ADMIN
|
|
#include "modules/AdminModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_ATAK
|
|
#include "modules/AtakPluginModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_CANNEDMESSAGES
|
|
#include "modules/CannedMessageModule.h"
|
|
#endif
|
|
#if HAS_SCREEN && BASEUI_HAS_GAMES
|
|
#include "modules/games/GamesModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_DETECTIONSENSOR
|
|
#include "modules/DetectionSensorModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_NEIGHBORINFO
|
|
#include "modules/NeighborInfoModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_NODEINFO
|
|
#include "modules/NodeInfoModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_BEACON
|
|
#include "modules/MeshBeaconModule.h"
|
|
#endif
|
|
// Generated by bin/optional-modules.py from whatever sits in src/modules/optional/. Absent from a
|
|
// stock checkout, and empty unless a module has been dropped in.
|
|
#if __has_include("OptionalModules.h")
|
|
#include "OptionalModules.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_GPS
|
|
#include "modules/PositionModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_REMOTEHARDWARE
|
|
#include "modules/RemoteHardwareModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_POWERSTRESS
|
|
#include "modules/PowerStressModule.h"
|
|
#endif
|
|
#include "modules/RoutingModule.h"
|
|
#if HAS_TRAFFIC_MANAGEMENT && !MESHTASTIC_EXCLUDE_TRAFFIC_MANAGEMENT
|
|
#include "modules/TrafficManagementModule.h"
|
|
#endif
|
|
#if HAS_VARIABLE_HOPS
|
|
#include "modules/HopScalingModule.h"
|
|
#endif
|
|
#include "modules/TextMessageModule.h"
|
|
#if !MESHTASTIC_EXCLUDE_TRACEROUTE
|
|
#include "modules/TraceRouteModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_WAYPOINT
|
|
#include "modules/GeofenceModule.h"
|
|
#include "modules/WaypointModule.h"
|
|
#endif
|
|
#ifdef DMSHELL_TEST_PEER
|
|
#include "modules/DMShellTestModule.h"
|
|
#endif
|
|
#if ARCH_PORTDUINO
|
|
#include "modules/DMShell.h"
|
|
#include "modules/Telemetry/HostMetrics.h"
|
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
|
#include "modules/StoreForwardModule.h"
|
|
#endif
|
|
#endif
|
|
#if HAS_TELEMETRY
|
|
#include "modules/Telemetry/DeviceTelemetry.h"
|
|
#endif
|
|
#if HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
|
#include "main.h"
|
|
#include "modules/Telemetry/EnvironmentTelemetry.h"
|
|
#include "modules/Telemetry/HealthTelemetry.h"
|
|
#include "modules/Telemetry/Sensor/TelemetrySensor.h"
|
|
#endif
|
|
#if HAS_SENSOR && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
|
#include "main.h"
|
|
#include "modules/Telemetry/AirQualityTelemetry.h"
|
|
#include "modules/Telemetry/Sensor/TelemetrySensor.h"
|
|
#endif
|
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY
|
|
#include "modules/Telemetry/PowerTelemetry.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_GENERIC_THREAD_MODULE
|
|
#include "modules/GenericThreadModule.h"
|
|
#endif
|
|
|
|
#ifdef ARCH_ESP32
|
|
#if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO
|
|
#include "modules/esp32/AudioModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_PAXCOUNTER
|
|
#include "modules/esp32/PaxcounterModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
|
#include "modules/StoreForwardModule.h"
|
|
#endif
|
|
#endif
|
|
|
|
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
|
|
#include "modules/ExternalNotificationModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_RANGETEST && !MESHTASTIC_EXCLUDE_GPS
|
|
#include "modules/RangeTestModule.h"
|
|
#endif
|
|
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_SERIAL
|
|
#include "modules/SerialModule.h"
|
|
#endif
|
|
|
|
#if !MESHTASTIC_EXCLUDE_DROPZONE
|
|
#include "modules/DropzoneModule.h"
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_STATUS
|
|
#include "modules/StatusMessageModule.h"
|
|
#endif
|
|
|
|
#if defined(HAS_HARDWARE_WATCHDOG)
|
|
#include "watchdog/watchdogThread.h"
|
|
#endif
|
|
/**
|
|
* Create module instances here. If you are adding a new module, you must 'new' it here (or somewhere else)
|
|
*/
|
|
void setupModules()
|
|
{
|
|
#if (HAS_BUTTON || ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_INPUTBROKER
|
|
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
|
inputBroker = new InputBroker();
|
|
systemCommandsModule = new SystemCommandsModule();
|
|
buzzerFeedbackThread = new BuzzerFeedbackThread();
|
|
}
|
|
#endif
|
|
statusLEDModule = new StatusLEDModule();
|
|
#if !MESHTASTIC_EXCLUDE_REPLYBOT
|
|
new ReplyBotModule();
|
|
#endif
|
|
|
|
#if HAS_TRAFFIC_MANAGEMENT && !MESHTASTIC_EXCLUDE_TRAFFIC_MANAGEMENT
|
|
if (moduleConfig.has_traffic_management) {
|
|
trafficManagementModule = new TrafficManagementModule();
|
|
}
|
|
#endif
|
|
|
|
#if HAS_VARIABLE_HOPS
|
|
hopScalingModule = new HopScalingModule();
|
|
#endif
|
|
|
|
#if !MESHTASTIC_EXCLUDE_ADMIN
|
|
adminModule = new AdminModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_NODEINFO
|
|
nodeInfoModule = new NodeInfoModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_BEACON
|
|
meshBeaconBroadcastModule = new MeshBeaconBroadcastModule();
|
|
meshBeaconListenerModule = new MeshBeaconListenerModule();
|
|
meshBeaconTxHook = new MeshBeaconTxHook(); // registers itself with the radio driver's TX hooks
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_GPS
|
|
positionModule = new PositionModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_WAYPOINT
|
|
waypointModule = new WaypointModule();
|
|
geofenceModule = new GeofenceModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_TEXTMESSAGE
|
|
textMessageModule = new TextMessageModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_TRACEROUTE
|
|
traceRouteModule = new TraceRouteModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_NEIGHBORINFO
|
|
if (moduleConfig.has_neighbor_info && moduleConfig.neighbor_info.enabled) {
|
|
neighborInfoModule = new NeighborInfoModule();
|
|
}
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_DETECTIONSENSOR
|
|
if (moduleConfig.has_detection_sensor && moduleConfig.detection_sensor.enabled) {
|
|
detectionSensorModule = new DetectionSensorModule();
|
|
}
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_ATAK
|
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_TAK ||
|
|
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) {
|
|
atakPluginModule = new AtakPluginModule();
|
|
}
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_PKI
|
|
keyVerificationModule = new KeyVerificationModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_DROPZONE
|
|
dropzoneModule = new DropzoneModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_STATUS
|
|
statusMessageModule = new StatusMessageModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_GENERIC_THREAD_MODULE
|
|
new GenericThreadModule();
|
|
#endif
|
|
// Note: if the rest of meshtastic doesn't need to explicitly use your module, you do not need to assign the instance
|
|
// to a global variable.
|
|
|
|
#if !MESHTASTIC_EXCLUDE_REMOTEHARDWARE
|
|
new RemoteHardwareModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_POWERSTRESS
|
|
new PowerStressModule();
|
|
#endif
|
|
// Example: Put your module here
|
|
// new ReplyModule();
|
|
#if HAS_SCREEN && !MESHTASTIC_EXCLUDE_CANNEDMESSAGES
|
|
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
|
cannedMessageModule = new CannedMessageModule();
|
|
}
|
|
#endif
|
|
#if HAS_SCREEN && BASEUI_HAS_GAMES
|
|
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
|
gamesModule = new GamesModule();
|
|
}
|
|
#endif
|
|
#if ARCH_PORTDUINO
|
|
new HostMetricsModule();
|
|
#if defined(MESHTASTIC_HAS_DMSHELL)
|
|
dmShellModule = new DMShellModule();
|
|
#endif
|
|
#endif
|
|
#ifdef DMSHELL_TEST_PEER
|
|
dmShellTestModule = new DMShellTestModule();
|
|
#endif
|
|
#if HAS_TELEMETRY
|
|
new DeviceTelemetryModule();
|
|
#endif
|
|
#if HAS_TELEMETRY && HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
|
if (moduleConfig.has_telemetry &&
|
|
(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) {
|
|
environmentTelemetryModule = new EnvironmentTelemetryModule();
|
|
}
|
|
#if HAS_TELEMETRY && HAS_SENSOR && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
|
if (moduleConfig.has_telemetry &&
|
|
(moduleConfig.telemetry.air_quality_enabled || moduleConfig.telemetry.air_quality_screen_enabled)) {
|
|
new AirQualityTelemetryModule();
|
|
}
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY
|
|
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX30102].first > 0 ||
|
|
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MLX90614].first > 0) {
|
|
new HealthTelemetryModule();
|
|
}
|
|
#endif
|
|
#endif
|
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
|
if (moduleConfig.has_telemetry &&
|
|
(moduleConfig.telemetry.power_measurement_enabled || moduleConfig.telemetry.power_screen_enabled)) {
|
|
new PowerTelemetryModule();
|
|
}
|
|
#endif
|
|
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_STM32WL)) && \
|
|
!defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
|
#if !MESHTASTIC_EXCLUDE_SERIAL
|
|
if (moduleConfig.has_serial && moduleConfig.serial.enabled &&
|
|
config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
|
|
new SerialModule();
|
|
}
|
|
#endif
|
|
#endif
|
|
#ifdef ARCH_ESP32
|
|
// Only run on an esp32 based device.
|
|
#if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO
|
|
audioModule = new AudioModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_PAXCOUNTER
|
|
if (moduleConfig.has_paxcounter && moduleConfig.paxcounter.enabled) {
|
|
paxcounterModule = new PaxcounterModule();
|
|
}
|
|
#endif
|
|
#endif
|
|
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
|
|
#if !MESHTASTIC_EXCLUDE_STOREFORWARD
|
|
if (moduleConfig.has_store_forward && moduleConfig.store_forward.enabled) {
|
|
storeForwardModule = new StoreForwardModule();
|
|
}
|
|
#endif
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
|
|
externalNotificationModule = new ExternalNotificationModule();
|
|
#endif
|
|
#if !MESHTASTIC_EXCLUDE_RANGETEST && !MESHTASTIC_EXCLUDE_GPS
|
|
if (moduleConfig.has_range_test && moduleConfig.range_test.enabled)
|
|
new RangeTestModule();
|
|
#endif
|
|
#if defined(HAS_HARDWARE_WATCHDOG)
|
|
watchdogThread = new WatchdogThread();
|
|
#endif
|
|
// Anything dropped into src/modules/optional/. Undefined, so compiled away, unless a module is
|
|
// actually present.
|
|
#ifdef OPTIONAL_MODULES_SETUP
|
|
OPTIONAL_MODULES_SETUP();
|
|
#endif
|
|
// NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra
|
|
// acks
|
|
routingModule = new RoutingModule();
|
|
}
|