Finish deprecating the Repeater role behavior (#8144)

* Finish deprecating the Repeater role behavior

* Validate

* Fixed bad if/else block

* Get your crap together!
This commit is contained in:
Ben Meadors 2025-09-28 15:30:53 -05:00 committed by GitHub
parent 033fc0c8f3
commit a15d654767
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 126 additions and 187 deletions

View File

@ -76,9 +76,6 @@ const char *DisplayFormatters::getDeviceRole(meshtastic_Config_DeviceConfig_Role
case meshtastic_Config_DeviceConfig_Role_ROUTER_LATE: case meshtastic_Config_DeviceConfig_Role_ROUTER_LATE:
return "Router Late"; return "Router Late";
break; break;
case meshtastic_Config_DeviceConfig_Role_REPEATER:
return "Repeater";
break;
default: default:
return "Unknown"; return "Unknown";
break; break;

View File

@ -1104,11 +1104,6 @@ int32_t GPS::runOnce()
publishUpdate(); publishUpdate();
} }
// Repeaters have no need for GPS
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
return disable();
}
if (whileActive()) { if (whileActive()) {
// if we have received valid NMEA claim we are connected // if we have received valid NMEA claim we are connected
setConnected(); setConnected();

View File

@ -793,14 +793,7 @@ void setup()
} }
#endif #endif
// If we're taking on the repeater role, use NextHopRouter and turn off 3V3_S rail because peripherals are not needed router = new ReliableRouter();
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
router = new NextHopRouter();
#ifdef PIN_3V3_EN
digitalWrite(PIN_3V3_EN, LOW);
#endif
} else
router = new ReliableRouter();
// only play start melody when role is not tracker or sensor // only play start melody when role is not tracker or sensor
if (config.power.is_power_saving == true && if (config.power.is_power_saving == true &&
@ -926,8 +919,7 @@ void setup()
if (sensor_detected == false) { if (sensor_detected == false) {
#endif #endif
if (HAS_GPS) { if (HAS_GPS) {
if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER && if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
gps = GPS::createGps(); gps = GPS::createGps();
if (gps) { if (gps) {
gpsStatus->observe(&gps->newStatus); gpsStatus->observe(&gps->newStatus);

View File

@ -81,9 +81,8 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
bool FloodingRouter::roleAllowsCancelingDupe(const meshtastic_MeshPacket *p) bool FloodingRouter::roleAllowsCancelingDupe(const meshtastic_MeshPacket *p)
{ {
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE) { config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE) {
// ROUTER, REPEATER, ROUTER_LATE should never cancel relaying a packet (i.e. we should always rebroadcast), // ROUTER, ROUTER_LATE should never cancel relaying a packet (i.e. we should always rebroadcast),
// even if we've heard another station rebroadcast it already. // even if we've heard another station rebroadcast it already.
return false; return false;
} }
@ -102,7 +101,7 @@ bool FloodingRouter::roleAllowsCancelingDupe(const meshtastic_MeshPacket *p)
void FloodingRouter::perhapsCancelDupe(const meshtastic_MeshPacket *p) void FloodingRouter::perhapsCancelDupe(const meshtastic_MeshPacket *p)
{ {
if (p->transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA && roleAllowsCancelingDupe(p)) { if (p->transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA && roleAllowsCancelingDupe(p)) {
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater! // cancel rebroadcast of this message *if* there was already one, unless we're a router!
// But only LoRa packets should be able to trigger this. // But only LoRa packets should be able to trigger this.
if (Router::cancelSending(p->from, p->id)) if (Router::cancelSending(p->from, p->id))
txRelayCanceled++; txRelayCanceled++;

View File

@ -59,7 +59,7 @@ class FloodingRouter : public Router
*/ */
virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override; virtual void sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c) override;
// Return false for roles like ROUTER or REPEATER which should always rebroadcast even when we've heard another rebroadcast of // Return false for roles like ROUTER which should always rebroadcast even when we've heard another rebroadcast of
// the same packet // the same packet
bool roleAllowsCancelingDupe(const meshtastic_MeshPacket *p); bool roleAllowsCancelingDupe(const meshtastic_MeshPacket *p);

View File

@ -85,12 +85,11 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping powerFSM.trigger(EVENT_PACKET_FOR_PHONE); // Possibly keep the node from sleeping
nodeDB->updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio nodeDB->updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
bool isPreferredRebroadcaster = bool isPreferredRebroadcaster = config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER;
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_ROUTER, meshtastic_Config_DeviceConfig_Role_REPEATER);
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
mp->decoded.portnum == meshtastic_PortNum_TELEMETRY_APP && mp->decoded.request_id > 0) { mp->decoded.portnum == meshtastic_PortNum_TELEMETRY_APP && mp->decoded.request_id > 0) {
LOG_DEBUG("Received telemetry response. Skip sending our NodeInfo"); // because this potentially a Repeater which will LOG_DEBUG("Received telemetry response. Skip sending our NodeInfo");
// ignore our request for its NodeInfo // ignore our request for its NodeInfo
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user && } else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user &&
nodeInfoModule && !isPreferredRebroadcaster && !nodeDB->isFull()) { nodeInfoModule && !isPreferredRebroadcaster && !nodeDB->isFull()) {
if (airTime->isTxAllowedChannelUtil(true)) { if (airTime->isTxAllowedChannelUtil(true)) {

View File

@ -170,7 +170,6 @@ bool NextHopRouter::perhapsRelay(const meshtastic_MeshPacket *p)
*/ */
uint8_t NextHopRouter::getNextHop(NodeNum to, uint8_t relay_node) uint8_t NextHopRouter::getNextHop(NodeNum to, uint8_t relay_node)
{ {
// When we're a repeater router->sniffReceived will call NextHopRouter directly without checking for broadcast
if (isBroadcast(to)) if (isBroadcast(to))
return NO_NEXT_HOP_PREFERENCE; return NO_NEXT_HOP_PREFERENCE;
@ -208,7 +207,7 @@ bool NextHopRouter::roleAllowsCancelingFromTxQueue(const meshtastic_MeshPacket *
{ {
// Return true if we're allowed to cancel a packet in the txQueue (so we may never transmit it even once) // Return true if we're allowed to cancel a packet in the txQueue (so we may never transmit it even once)
// Return false for roles like ROUTER, REPEATER, ROUTER_LATE which should always transmit the packet at least once. // Return false for roles like ROUTER, ROUTER_LATE which should always transmit the packet at least once.
return roleAllowsCancelingDupe(p); // same logic as FloodingRouter::roleAllowsCancelingDupe return roleAllowsCancelingDupe(p); // same logic as FloodingRouter::roleAllowsCancelingDupe
} }
@ -221,7 +220,7 @@ bool NextHopRouter::stopRetransmission(GlobalPacketId key)
/* Only when we already transmitted a packet via LoRa, we will cancel the packet in the Tx queue /* Only when we already transmitted a packet via LoRa, we will cancel the packet in the Tx queue
to avoid canceling a transmission if it was ACKed super fast via MQTT */ to avoid canceling a transmission if it was ACKed super fast via MQTT */
if (old->numRetransmissions < NUM_RELIABLE_RETX - 1) { if (old->numRetransmissions < NUM_RELIABLE_RETX - 1) {
// We only cancel it if we are the original sender or if we're not a router(_late)/repeater // We only cancel it if we are the original sender or if we're not a router(_late)
if (isFromUs(p) || roleAllowsCancelingFromTxQueue(p)) { if (isFromUs(p) || roleAllowsCancelingFromTxQueue(p)) {
// remove the 'original' (identified by originator and packet->id) from the txqueue and free it // remove the 'original' (identified by originator and packet->id) from the txqueue and free it
cancelSending(getFrom(p), p->id); cancelSending(getFrom(p), p->id);

View File

@ -554,10 +554,9 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
#endif #endif
#ifdef USERPREFS_CONFIG_DEVICE_ROLE #ifdef USERPREFS_CONFIG_DEVICE_ROLE
// Restrict ROUTER*, LOST AND FOUND, and REPEATER roles for security reasons // Restrict ROUTER*, LOST AND FOUND roles for security reasons
if (IS_ONE_OF(USERPREFS_CONFIG_DEVICE_ROLE, meshtastic_Config_DeviceConfig_Role_ROUTER, if (IS_ONE_OF(USERPREFS_CONFIG_DEVICE_ROLE, meshtastic_Config_DeviceConfig_Role_ROUTER,
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE, meshtastic_Config_DeviceConfig_Role_REPEATER, meshtastic_Config_DeviceConfig_Role_ROUTER_LATE, meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND)) {
meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND)) {
LOG_WARN("ROUTER roles are restricted, falling back to CLIENT role"); LOG_WARN("ROUTER roles are restricted, falling back to CLIENT role");
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT; config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
} else { } else {
@ -906,11 +905,6 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
moduleConfig.telemetry.device_update_interval = ONE_DAY; moduleConfig.telemetry.device_update_interval = ONE_DAY;
owner.has_is_unmessagable = true; owner.has_is_unmessagable = true;
owner.is_unmessagable = true; owner.is_unmessagable = true;
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
owner.has_is_unmessagable = true;
owner.is_unmessagable = true;
config.display.screen_on_secs = 1;
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) { } else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
owner.has_is_unmessagable = true; owner.has_is_unmessagable = true;
owner.is_unmessagable = true; owner.is_unmessagable = true;

View File

@ -317,9 +317,8 @@ uint32_t RadioInterface::getTxDelayMsecWeightedWorst(float snr)
/** Returns true if we should rebroadcast early like a ROUTER */ /** Returns true if we should rebroadcast early like a ROUTER */
bool RadioInterface::shouldRebroadcastEarlyLikeRouter(meshtastic_MeshPacket *p) bool RadioInterface::shouldRebroadcastEarlyLikeRouter(meshtastic_MeshPacket *p)
{ {
// If we are a ROUTER or REPEATER, we always rebroadcast early // If we are a ROUTER, we always rebroadcast early
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER) {
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
return true; return true;
} }

View File

@ -399,10 +399,6 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
{ {
concurrency::LockGuard g(cryptLock); concurrency::LockGuard g(cryptLock);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER &&
config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_ALL_SKIP_DECODING)
return DecodeState::DECODE_FAILURE;
if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY && if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_KNOWN_ONLY &&
(nodeDB->getMeshNode(p->from) == NULL || !nodeDB->getMeshNode(p->from)->has_user)) { (nodeDB->getMeshNode(p->from) == NULL || !nodeDB->getMeshNode(p->from)->has_user)) {
LOG_DEBUG("Node 0x%x not in nodeDB-> Rebroadcast mode KNOWN_ONLY will ignore packet", p->from); LOG_DEBUG("Node 0x%x not in nodeDB-> Rebroadcast mode KNOWN_ONLY will ignore packet", p->from);

View File

@ -611,10 +611,9 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
} }
config.device = c.payload_variant.device; config.device = c.payload_variant.device;
if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_NONE && if (config.device.rebroadcast_mode == meshtastic_Config_DeviceConfig_RebroadcastMode_NONE &&
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_ROUTER, config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER) {
meshtastic_Config_DeviceConfig_Role_REPEATER)) {
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_ALL; config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_ALL;
const char *warning = "Rebroadcast mode can't be set to NONE for a router or repeater"; const char *warning = "Rebroadcast mode can't be set to NONE for a router";
LOG_WARN(warning); LOG_WARN(warning);
sendWarning(warning); sendWarning(warning);
} }
@ -627,8 +626,9 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
LOG_DEBUG("Tried to set node_info_broadcast_secs too low, setting to %d", min_node_info_broadcast_secs); LOG_DEBUG("Tried to set node_info_broadcast_secs too low, setting to %d", min_node_info_broadcast_secs);
config.device.node_info_broadcast_secs = min_node_info_broadcast_secs; config.device.node_info_broadcast_secs = min_node_info_broadcast_secs;
} }
// Router Client is deprecated; Set it to client // Router Client and Repeater deprecated; Set it to client
if (c.payload_variant.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT) { if (IS_ONE_OF(c.payload_variant.device.role, meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT,
meshtastic_Config_DeviceConfig_Role_REPEATER)) {
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT; config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
if (moduleConfig.store_forward.enabled && !moduleConfig.store_forward.is_server) { if (moduleConfig.store_forward.enabled && !moduleConfig.store_forward.is_server) {
moduleConfig.store_forward.is_server = true; moduleConfig.store_forward.is_server = true;
@ -637,10 +637,9 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
} }
} }
#if USERPREFS_EVENT_MODE #if USERPREFS_EVENT_MODE
// If we're in event mode, nobody is a Router or Repeater // If we're in event mode, nobody is a Router or Router Late
if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || if (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE || config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE) {
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT; config.device.role = meshtastic_Config_DeviceConfig_Role_CLIENT;
} }
#endif #endif

View File

@ -112,204 +112,191 @@
*/ */
void setupModules() void setupModules()
{ {
if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
#if (HAS_BUTTON || ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_INPUTBROKER #if (HAS_BUTTON || ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_INPUTBROKER
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
inputBroker = new InputBroker(); inputBroker = new InputBroker();
systemCommandsModule = new SystemCommandsModule(); systemCommandsModule = new SystemCommandsModule();
buzzerFeedbackThread = new BuzzerFeedbackThread(); buzzerFeedbackThread = new BuzzerFeedbackThread();
} }
#endif #endif
#if !MESHTASTIC_EXCLUDE_ADMIN #if !MESHTASTIC_EXCLUDE_ADMIN
adminModule = new AdminModule(); adminModule = new AdminModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_NODEINFO #if !MESHTASTIC_EXCLUDE_NODEINFO
nodeInfoModule = new NodeInfoModule(); nodeInfoModule = new NodeInfoModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_GPS #if !MESHTASTIC_EXCLUDE_GPS
positionModule = new PositionModule(); positionModule = new PositionModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_WAYPOINT #if !MESHTASTIC_EXCLUDE_WAYPOINT
waypointModule = new WaypointModule(); waypointModule = new WaypointModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_TEXTMESSAGE #if !MESHTASTIC_EXCLUDE_TEXTMESSAGE
textMessageModule = new TextMessageModule(); textMessageModule = new TextMessageModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_TRACEROUTE #if !MESHTASTIC_EXCLUDE_TRACEROUTE
traceRouteModule = new TraceRouteModule(); traceRouteModule = new TraceRouteModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_NEIGHBORINFO #if !MESHTASTIC_EXCLUDE_NEIGHBORINFO
if (moduleConfig.has_neighbor_info && moduleConfig.neighbor_info.enabled) { if (moduleConfig.has_neighbor_info && moduleConfig.neighbor_info.enabled) {
neighborInfoModule = new NeighborInfoModule(); neighborInfoModule = new NeighborInfoModule();
} }
#endif #endif
#if !MESHTASTIC_EXCLUDE_DETECTIONSENSOR #if !MESHTASTIC_EXCLUDE_DETECTIONSENSOR
if (moduleConfig.has_detection_sensor && moduleConfig.detection_sensor.enabled) { if (moduleConfig.has_detection_sensor && moduleConfig.detection_sensor.enabled) {
detectionSensorModule = new DetectionSensorModule(); detectionSensorModule = new DetectionSensorModule();
} }
#endif #endif
#if !MESHTASTIC_EXCLUDE_ATAK #if !MESHTASTIC_EXCLUDE_ATAK
if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TAK, if (IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TAK, meshtastic_Config_DeviceConfig_Role_TAK_TRACKER)) {
meshtastic_Config_DeviceConfig_Role_TAK_TRACKER)) { atakPluginModule = new AtakPluginModule();
atakPluginModule = new AtakPluginModule(); }
}
#endif #endif
#if !MESHTASTIC_EXCLUDE_PKI #if !MESHTASTIC_EXCLUDE_PKI
keyVerificationModule = new KeyVerificationModule(); keyVerificationModule = new KeyVerificationModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_DROPZONE #if !MESHTASTIC_EXCLUDE_DROPZONE
dropzoneModule = new DropzoneModule(); dropzoneModule = new DropzoneModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_GENERIC_THREAD_MODULE #if !MESHTASTIC_EXCLUDE_GENERIC_THREAD_MODULE
new GenericThreadModule(); new GenericThreadModule();
#endif #endif
// Note: if the rest of meshtastic doesn't need to explicitly use your module, you do not need to assign the instance // 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. // to a global variable.
#if !MESHTASTIC_EXCLUDE_REMOTEHARDWARE #if !MESHTASTIC_EXCLUDE_REMOTEHARDWARE
new RemoteHardwareModule(); new RemoteHardwareModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_POWERSTRESS #if !MESHTASTIC_EXCLUDE_POWERSTRESS
new PowerStressModule(); new PowerStressModule();
#endif #endif
// Example: Put your module here // Example: Put your module here
// new ReplyModule(); // new ReplyModule();
#if (HAS_BUTTON || ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_INPUTBROKER #if (HAS_BUTTON || ARCH_PORTDUINO) && !MESHTASTIC_EXCLUDE_INPUTBROKER
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1(); rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1();
if (!rotaryEncoderInterruptImpl1->init()) { if (!rotaryEncoderInterruptImpl1->init()) {
delete rotaryEncoderInterruptImpl1; delete rotaryEncoderInterruptImpl1;
rotaryEncoderInterruptImpl1 = nullptr; rotaryEncoderInterruptImpl1 = nullptr;
} }
#ifdef T_LORA_PAGER #ifdef T_LORA_PAGER
// use a special FSM based rotary encoder version for T-LoRa Pager // use a special FSM based rotary encoder version for T-LoRa Pager
rotaryEncoderImpl = new RotaryEncoderImpl(); rotaryEncoderImpl = new RotaryEncoderImpl();
if (!rotaryEncoderImpl->init()) { if (!rotaryEncoderImpl->init()) {
delete rotaryEncoderImpl; delete rotaryEncoderImpl;
rotaryEncoderImpl = nullptr; rotaryEncoderImpl = nullptr;
} }
#else #else
upDownInterruptImpl1 = new UpDownInterruptImpl1(); upDownInterruptImpl1 = new UpDownInterruptImpl1();
if (!upDownInterruptImpl1->init()) { if (!upDownInterruptImpl1->init()) {
delete upDownInterruptImpl1; delete upDownInterruptImpl1;
upDownInterruptImpl1 = nullptr; upDownInterruptImpl1 = nullptr;
} }
#endif #endif
cardKbI2cImpl = new CardKbI2cImpl(); cardKbI2cImpl = new CardKbI2cImpl();
cardKbI2cImpl->init(); cardKbI2cImpl->init();
#if defined(M5STACK_UNITC6L) #if defined(M5STACK_UNITC6L)
i2cButton = new i2cButtonThread("i2cButtonThread"); i2cButton = new i2cButtonThread("i2cButtonThread");
#endif #endif
#ifdef INPUTBROKER_MATRIX_TYPE #ifdef INPUTBROKER_MATRIX_TYPE
kbMatrixImpl = new KbMatrixImpl(); kbMatrixImpl = new KbMatrixImpl();
kbMatrixImpl->init(); kbMatrixImpl->init();
#endif // INPUTBROKER_MATRIX_TYPE #endif // INPUTBROKER_MATRIX_TYPE
#ifdef INPUTBROKER_SERIAL_TYPE #ifdef INPUTBROKER_SERIAL_TYPE
aSerialKeyboardImpl = new SerialKeyboardImpl(); aSerialKeyboardImpl = new SerialKeyboardImpl();
aSerialKeyboardImpl->init(); aSerialKeyboardImpl->init();
#endif // INPUTBROKER_MATRIX_TYPE #endif // INPUTBROKER_MATRIX_TYPE
} }
#endif // HAS_BUTTON #endif // HAS_BUTTON
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
seesawRotary = new SeesawRotary("SeesawRotary"); seesawRotary = new SeesawRotary("SeesawRotary");
if (!seesawRotary->init()) { if (!seesawRotary->init()) {
delete seesawRotary; delete seesawRotary;
seesawRotary = nullptr; seesawRotary = nullptr;
}
aLinuxInputImpl = new LinuxInputImpl();
aLinuxInputImpl->init();
} }
aLinuxInputImpl = new LinuxInputImpl();
aLinuxInputImpl->init();
}
#endif #endif
#if !MESHTASTIC_EXCLUDE_INPUTBROKER && HAS_TRACKBALL #if !MESHTASTIC_EXCLUDE_INPUTBROKER && HAS_TRACKBALL
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
trackballInterruptImpl1 = new TrackballInterruptImpl1(); trackballInterruptImpl1 = new TrackballInterruptImpl1();
trackballInterruptImpl1->init(TB_DOWN, TB_UP, TB_LEFT, TB_RIGHT, TB_PRESS); trackballInterruptImpl1->init(TB_DOWN, TB_UP, TB_LEFT, TB_RIGHT, TB_PRESS);
} }
#endif #endif
#ifdef INPUTBROKER_EXPRESSLRSFIVEWAY_TYPE #ifdef INPUTBROKER_EXPRESSLRSFIVEWAY_TYPE
expressLRSFiveWayInput = new ExpressLRSFiveWay(); expressLRSFiveWayInput = new ExpressLRSFiveWay();
#endif #endif
#if HAS_SCREEN && !MESHTASTIC_EXCLUDE_CANNEDMESSAGES #if HAS_SCREEN && !MESHTASTIC_EXCLUDE_CANNEDMESSAGES
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
cannedMessageModule = new CannedMessageModule(); cannedMessageModule = new CannedMessageModule();
} }
#endif #endif
#if ARCH_PORTDUINO #if ARCH_PORTDUINO
new HostMetricsModule(); new HostMetricsModule();
#endif #endif
#if HAS_TELEMETRY #if HAS_TELEMETRY
new DeviceTelemetryModule(); new DeviceTelemetryModule();
#endif #endif
#if HAS_TELEMETRY && HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #if HAS_TELEMETRY && HAS_SENSOR && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (moduleConfig.has_telemetry && if (moduleConfig.has_telemetry &&
(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) { (moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) {
new EnvironmentTelemetryModule(); new EnvironmentTelemetryModule();
} }
#if __has_include("Adafruit_PM25AQI.h") #if __has_include("Adafruit_PM25AQI.h")
if (moduleConfig.has_telemetry && moduleConfig.telemetry.air_quality_enabled && if (moduleConfig.has_telemetry && moduleConfig.telemetry.air_quality_enabled &&
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) { nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) {
new AirQualityTelemetryModule(); new AirQualityTelemetryModule();
} }
#endif #endif
#if !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY #if !MESHTASTIC_EXCLUDE_HEALTH_TELEMETRY
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX30102].first > 0 || if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MAX30102].first > 0 ||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MLX90614].first > 0) { nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MLX90614].first > 0) {
new HealthTelemetryModule(); new HealthTelemetryModule();
} }
#endif #endif
#endif #endif
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_POWER_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
if (moduleConfig.has_telemetry && if (moduleConfig.has_telemetry &&
(moduleConfig.telemetry.power_measurement_enabled || moduleConfig.telemetry.power_screen_enabled)) { (moduleConfig.telemetry.power_measurement_enabled || moduleConfig.telemetry.power_screen_enabled)) {
new PowerTelemetryModule(); new PowerTelemetryModule();
} }
#endif #endif
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_STM32WL)) && \ #if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040) || defined(ARCH_STM32WL)) && \
!defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
#if !MESHTASTIC_EXCLUDE_SERIAL #if !MESHTASTIC_EXCLUDE_SERIAL
if (moduleConfig.has_serial && moduleConfig.serial.enabled && if (moduleConfig.has_serial && moduleConfig.serial.enabled &&
config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) { config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
new SerialModule(); new SerialModule();
} }
#endif #endif
#endif #endif
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// Only run on an esp32 based device. // Only run on an esp32 based device.
#if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO #if defined(USE_SX1280) && !MESHTASTIC_EXCLUDE_AUDIO
audioModule = new AudioModule(); audioModule = new AudioModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_PAXCOUNTER #if !MESHTASTIC_EXCLUDE_PAXCOUNTER
if (moduleConfig.has_paxcounter && moduleConfig.paxcounter.enabled) { if (moduleConfig.has_paxcounter && moduleConfig.paxcounter.enabled) {
paxcounterModule = new PaxcounterModule(); paxcounterModule = new PaxcounterModule();
} }
#endif #endif
#endif #endif
#if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) #if defined(ARCH_ESP32) || defined(ARCH_PORTDUINO)
#if !MESHTASTIC_EXCLUDE_STOREFORWARD #if !MESHTASTIC_EXCLUDE_STOREFORWARD
if (moduleConfig.has_store_forward && moduleConfig.store_forward.enabled) { if (moduleConfig.has_store_forward && moduleConfig.store_forward.enabled) {
storeForwardModule = new StoreForwardModule(); storeForwardModule = new StoreForwardModule();
} }
#endif #endif
#endif #endif
#if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION #if !MESHTASTIC_EXCLUDE_EXTERNALNOTIFICATION
externalNotificationModule = new ExternalNotificationModule(); externalNotificationModule = new ExternalNotificationModule();
#endif #endif
#if !MESHTASTIC_EXCLUDE_RANGETEST && !MESHTASTIC_EXCLUDE_GPS #if !MESHTASTIC_EXCLUDE_RANGETEST && !MESHTASTIC_EXCLUDE_GPS
if (moduleConfig.has_range_test && moduleConfig.range_test.enabled) if (moduleConfig.has_range_test && moduleConfig.range_test.enabled)
new RangeTestModule(); new RangeTestModule();
#endif #endif
} else {
#if !MESHTASTIC_EXCLUDE_ADMIN
adminModule = new AdminModule();
#endif
#if HAS_TELEMETRY
new DeviceTelemetryModule();
#endif
#if !MESHTASTIC_EXCLUDE_TRACEROUTE
traceRouteModule = new TraceRouteModule();
#endif
}
// NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra // NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra
// acks // acks
routingModule = new RoutingModule(); routingModule = new RoutingModule();

View File

@ -94,11 +94,6 @@ meshtastic_MeshPacket *NodeInfoModule::allocReply()
u.public_key.bytes[0] = 0; u.public_key.bytes[0] = 0;
u.public_key.size = 0; u.public_key.size = 0;
} }
// Coerce unmessagable for Repeater role
if (u.role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
u.has_is_unmessagable = true;
u.is_unmessagable = true;
}
LOG_INFO("Send owner %s/%s/%s", u.id, u.long_name, u.short_name); LOG_INFO("Send owner %s/%s/%s", u.id, u.long_name, u.short_name);
lastSentToMesh = millis(); lastSentToMesh = millis();

View File

@ -42,8 +42,6 @@ bool RoutingModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mesh
meshtastic_MeshPacket *RoutingModule::allocReply() meshtastic_MeshPacket *RoutingModule::allocReply()
{ {
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
return NULL;
assert(currentRequest); assert(currentRequest);
return NULL; return NULL;

View File

@ -26,7 +26,6 @@ int32_t DeviceTelemetryModule::runOnce()
Default::getConfiguredOrDefaultMsScaled(moduleConfig.telemetry.device_update_interval, Default::getConfiguredOrDefaultMsScaled(moduleConfig.telemetry.device_update_interval,
default_telemetry_broadcast_interval_secs, numOnlineNodes))) && default_telemetry_broadcast_interval_secs, numOnlineNodes))) &&
airTime->isTxAllowedChannelUtil(!isImpoliteRole) && airTime->isTxAllowedAirUtil() && airTime->isTxAllowedChannelUtil(!isImpoliteRole) && airTime->isTxAllowedAirUtil() &&
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER &&
config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN) { config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_HIDDEN) {
sendTelemetry(); sendTelemetry();
lastSentToMesh = uptimeLastMs; lastSentToMesh = uptimeLastMs;
@ -44,10 +43,6 @@ int32_t DeviceTelemetryModule::runOnce()
bool DeviceTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t) bool DeviceTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
{ {
// Don't worry about storing telemetry in NodeDB if we're a repeater
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
return false;
if (t->which_variant == meshtastic_Telemetry_device_metrics_tag) { if (t->which_variant == meshtastic_Telemetry_device_metrics_tag) {
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE) #if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
const char *sender = getSenderShortName(mp); const char *sender = getSenderShortName(mp);

View File

@ -22,10 +22,6 @@ int32_t HostMetricsModule::runOnce()
bool HostMetricsModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t) bool HostMetricsModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
{ {
// Don't worry about storing telemetry in NodeDB if we're a repeater
if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
return false;
if (t->which_variant == meshtastic_Telemetry_host_metrics_tag) { if (t->which_variant == meshtastic_Telemetry_host_metrics_tag) {
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE) #if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
const char *sender = getSenderShortName(mp); const char *sender = getSenderShortName(mp);

View File

@ -532,8 +532,7 @@ void enableModemSleep()
bool shouldLoraWake(uint32_t msecToWake) bool shouldLoraWake(uint32_t msecToWake)
{ {
return msecToWake < portMAX_DELAY && (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || return msecToWake < portMAX_DELAY && (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER);
config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER);
} }
void enableLoraInterrupt() void enableLoraInterrupt()

View File

@ -21,7 +21,7 @@
// "USERPREFS_CONFIG_LORA_REGION": "meshtastic_Config_LoRaConfig_RegionCode_US", // "USERPREFS_CONFIG_LORA_REGION": "meshtastic_Config_LoRaConfig_RegionCode_US",
// "USERPREFS_CONFIG_OWNER_LONG_NAME": "My Long Name", // "USERPREFS_CONFIG_OWNER_LONG_NAME": "My Long Name",
// "USERPREFS_CONFIG_OWNER_SHORT_NAME": "MLN", // "USERPREFS_CONFIG_OWNER_SHORT_NAME": "MLN",
// "USERPREFS_CONFIG_DEVICE_ROLE": "meshtastic_Config_DeviceConfig_Role_CLIENT", // Defaults to CLIENT. ROUTER*, LOST AND FOUND, and REPEATER roles are restricted. // "USERPREFS_CONFIG_DEVICE_ROLE": "meshtastic_Config_DeviceConfig_Role_CLIENT", // Defaults to CLIENT. ROUTER*, and LOST AND FOUND roles are restricted.
// "USERPREFS_EVENT_MODE": "1", // "USERPREFS_EVENT_MODE": "1",
// "USERPREFS_FIRMWARE_EDITION": "meshtastic_FirmwareEdition_BURNING_MAN", // "USERPREFS_FIRMWARE_EDITION": "meshtastic_FirmwareEdition_BURNING_MAN",
// "USERPREFS_FIXED_BLUETOOTH": "121212", // "USERPREFS_FIXED_BLUETOOTH": "121212",