Compare commits
17 Commits
main
...
meshcore-v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
caeada16cc | ||
|
|
3ccb052a54 | ||
|
|
87e6acec5a | ||
|
|
28bb07adec | ||
|
|
8075edb2d7 | ||
|
|
c6c4951480 | ||
|
|
dc9e6ae893 | ||
|
|
de97baba4f | ||
|
|
8744213945 | ||
|
|
952d12c8b9 | ||
|
|
d804434f5b | ||
|
|
c0d19a007d | ||
|
|
1b922cdaf4 | ||
|
|
101880f834 | ||
|
|
06a0faeca8 | ||
|
|
14a97e3dc7 | ||
|
|
f864c5f547 |
@@ -255,7 +255,7 @@ float MyMesh::getAirtimeBudgetFactor() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int MyMesh::getInterferenceThreshold() const {
|
int MyMesh::getInterferenceThreshold() const {
|
||||||
return 0; // disabled for now, until currentRSSI() problem is resolved
|
return 1; // non-zero enables hardware CAD (Channel Activity Detection) before TX
|
||||||
}
|
}
|
||||||
|
|
||||||
int MyMesh::calcRxDelay(float score, uint32_t air_time) const {
|
int MyMesh::calcRxDelay(float score, uint32_t air_time) const {
|
||||||
|
|||||||
@@ -434,6 +434,15 @@ bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Limit flood advert paket forwarding using a probabilistic reduction defined by P(h) = 0.308^(hops-1)
|
||||||
|
// https://github.com/meshcore-dev/MeshCore/issues/1223
|
||||||
|
if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood()) {
|
||||||
|
double roll_dice = (double)rand() / RAND_MAX;
|
||||||
|
double forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1);
|
||||||
|
if (roll_dice > forw_prob)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -537,7 +546,10 @@ bool MyMesh::filterRecvFloodPacket(mesh::Packet* pkt) {
|
|||||||
if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) {
|
if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) {
|
||||||
recv_pkt_region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
|
recv_pkt_region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
|
||||||
} else if (pkt->getRouteType() == ROUTE_TYPE_FLOOD) {
|
} else if (pkt->getRouteType() == ROUTE_TYPE_FLOOD) {
|
||||||
if (region_map.getWildcard().flags & REGION_DENY_FLOOD) {
|
if ((pkt->getPayloadType() == PAYLOAD_TYPE_GRP_TXT ||
|
||||||
|
pkt->getPayloadType() == PAYLOAD_TYPE_GRP_DATA ||
|
||||||
|
pkt->getPayloadType() == PAYLOAD_TYPE_ADVERT) &&
|
||||||
|
region_map.getWildcard().flags & REGION_DENY_FLOOD) {
|
||||||
recv_pkt_region = NULL;
|
recv_pkt_region = NULL;
|
||||||
} else {
|
} else {
|
||||||
recv_pkt_region = ®ion_map.getWildcard();
|
recv_pkt_region = ®ion_map.getWildcard();
|
||||||
@@ -869,9 +881,10 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
|||||||
_prefs.cr = LORA_CR;
|
_prefs.cr = LORA_CR;
|
||||||
_prefs.tx_power_dbm = LORA_TX_POWER;
|
_prefs.tx_power_dbm = LORA_TX_POWER;
|
||||||
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
|
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
|
||||||
_prefs.flood_advert_interval = 12; // 12 hours
|
_prefs.flood_advert_interval = 0; // disabled
|
||||||
|
_prefs.flood_advert_base = 0.308f;
|
||||||
_prefs.flood_max = 64;
|
_prefs.flood_max = 64;
|
||||||
_prefs.interference_threshold = 0; // disabled
|
_prefs.interference_threshold = 1; // non-zero enables hardware CAD before TX
|
||||||
|
|
||||||
// bridge defaults
|
// bridge defaults
|
||||||
_prefs.bridge_enabled = 1; // enabled
|
_prefs.bridge_enabled = 1; // enabled
|
||||||
|
|||||||
@@ -282,7 +282,17 @@ uint32_t MyMesh::getDirectRetransmitDelay(const mesh::Packet *packet) {
|
|||||||
|
|
||||||
bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
|
||||||
if (_prefs.disable_fwd) return false;
|
if (_prefs.disable_fwd) return false;
|
||||||
if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false;
|
if (packet->isRouteFlood() && packet->path_len >= _prefs.flood_max) return false;
|
||||||
|
|
||||||
|
// Limit flood advert packet forwarding using a probabilistic reduction defined by P(h) = base^(hops-1)
|
||||||
|
// https://github.com/meshcore-dev/MeshCore/issues/1223
|
||||||
|
if (packet->getPayloadType() == PAYLOAD_TYPE_ADVERT && packet->isRouteFlood()) {
|
||||||
|
double roll_dice = (double)rand() / RAND_MAX;
|
||||||
|
double forw_prob = pow(_prefs.flood_advert_base, packet->path_len - 1);
|
||||||
|
if (roll_dice > forw_prob)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,8 +631,9 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
|||||||
_prefs.disable_fwd = 1;
|
_prefs.disable_fwd = 1;
|
||||||
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
|
_prefs.advert_interval = 1; // default to 2 minutes for NEW installs
|
||||||
_prefs.flood_advert_interval = 12; // 12 hours
|
_prefs.flood_advert_interval = 12; // 12 hours
|
||||||
|
_prefs.flood_advert_base = 0.308f;
|
||||||
_prefs.flood_max = 64;
|
_prefs.flood_max = 64;
|
||||||
_prefs.interference_threshold = 0; // disabled
|
_prefs.interference_threshold = 1; // non-zero enables hardware CAD before TX
|
||||||
#ifdef ROOM_PASSWORD
|
#ifdef ROOM_PASSWORD
|
||||||
StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password));
|
StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -723,7 +723,7 @@ SensorMesh::SensorMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::Millise
|
|||||||
_prefs.flood_advert_interval = 0; // disabled
|
_prefs.flood_advert_interval = 0; // disabled
|
||||||
_prefs.disable_fwd = true;
|
_prefs.disable_fwd = true;
|
||||||
_prefs.flood_max = 64;
|
_prefs.flood_max = 64;
|
||||||
_prefs.interference_threshold = 0; // disabled
|
_prefs.interference_threshold = 1; // non-zero enables hardware CAD before TX
|
||||||
|
|
||||||
// GPS defaults
|
// GPS defaults
|
||||||
_prefs.gps_enabled = 0;
|
_prefs.gps_enabled = 0;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ build_flags = -w -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1
|
|||||||
-D LORA_FREQ=869.618
|
-D LORA_FREQ=869.618
|
||||||
-D LORA_BW=62.5
|
-D LORA_BW=62.5
|
||||||
-D LORA_SF=8
|
-D LORA_SF=8
|
||||||
|
-D LORA_CR=8
|
||||||
-D ENABLE_ADVERT_ON_BOOT=1
|
-D ENABLE_ADVERT_ON_BOOT=1
|
||||||
-D ENABLE_PRIVATE_KEY_IMPORT=1 ; NOTE: comment these out for more secure firmware
|
-D ENABLE_PRIVATE_KEY_IMPORT=1 ; NOTE: comment these out for more secure firmware
|
||||||
-D ENABLE_PRIVATE_KEY_EXPORT=1
|
-D ENABLE_PRIVATE_KEY_EXPORT=1
|
||||||
|
|||||||
@@ -87,8 +87,9 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
|||||||
file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
|
file.read((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
|
||||||
file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
|
file.read((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
|
||||||
file.read((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170
|
file.read((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170
|
||||||
file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290
|
file.read((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290
|
||||||
// next: 291
|
file.read((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 294
|
||||||
|
|
||||||
|
|
||||||
// sanitise bad pref values
|
// sanitise bad pref values
|
||||||
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
|
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
|
||||||
@@ -119,6 +120,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
|||||||
// sanitise settings
|
// sanitise settings
|
||||||
_prefs->rx_boosted_gain = constrain(_prefs->rx_boosted_gain, 0, 1); // boolean
|
_prefs->rx_boosted_gain = constrain(_prefs->rx_boosted_gain, 0, 1); // boolean
|
||||||
|
|
||||||
|
_prefs->flood_advert_base = constrain(_prefs->flood_advert_base, 0, 1);
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,8 +181,10 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
|||||||
file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
|
file.write((uint8_t *)&_prefs->discovery_mod_timestamp, sizeof(_prefs->discovery_mod_timestamp)); // 162
|
||||||
file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
|
file.write((uint8_t *)&_prefs->adc_multiplier, sizeof(_prefs->adc_multiplier)); // 166
|
||||||
file.write((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170
|
file.write((uint8_t *)_prefs->owner_info, sizeof(_prefs->owner_info)); // 170
|
||||||
file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 290
|
file.write((uint8_t *)&_prefs->flood_advert_base, sizeof(_prefs->flood_advert_base)); // 290
|
||||||
// next: 291
|
file.write((uint8_t *)&_prefs->rx_boosted_gain, sizeof(_prefs->rx_boosted_gain)); // 294
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
@@ -421,6 +426,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
|||||||
} else {
|
} else {
|
||||||
sprintf(reply, "> %.3f", adc_mult);
|
sprintf(reply, "> %.3f", adc_mult);
|
||||||
}
|
}
|
||||||
|
} else if (memcmp(config, "flood.advert.base", 17) == 0) {
|
||||||
|
sprintf(reply, "> %s", StrHelper::ftoa(_prefs->flood_advert_base));
|
||||||
// Power management commands
|
// Power management commands
|
||||||
} else if (memcmp(config, "pwrmgt.support", 14) == 0) {
|
} else if (memcmp(config, "pwrmgt.support", 14) == 0) {
|
||||||
#ifdef NRF52_POWER_MANAGEMENT
|
#ifdef NRF52_POWER_MANAGEMENT
|
||||||
@@ -717,6 +724,15 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
|||||||
_prefs->adc_multiplier = 0.0f;
|
_prefs->adc_multiplier = 0.0f;
|
||||||
strcpy(reply, "Error: unsupported by this board");
|
strcpy(reply, "Error: unsupported by this board");
|
||||||
};
|
};
|
||||||
|
} else if (memcmp(config, "flood.advert.base ", 18) == 0) {
|
||||||
|
float f = atof(&config[18]);
|
||||||
|
if(f >= 0 && f <= 1) {
|
||||||
|
_prefs->flood_advert_base = f;
|
||||||
|
savePrefs();
|
||||||
|
strcpy(reply, "OK");
|
||||||
|
} else {
|
||||||
|
strcpy(reply, "Error: base must be between 0 and 1");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sprintf(reply, "unknown config: %s", config);
|
sprintf(reply, "unknown config: %s", config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ struct NodePrefs { // persisted to file
|
|||||||
uint8_t flood_max;
|
uint8_t flood_max;
|
||||||
uint8_t interference_threshold;
|
uint8_t interference_threshold;
|
||||||
uint8_t agc_reset_interval; // secs / 4
|
uint8_t agc_reset_interval; // secs / 4
|
||||||
|
float flood_advert_base;
|
||||||
// Bridge settings
|
// Bridge settings
|
||||||
uint8_t bridge_enabled; // boolean
|
uint8_t bridge_enabled; // boolean
|
||||||
uint16_t bridge_delay; // milliseconds (default 500 ms)
|
uint16_t bridge_delay; // milliseconds (default 500 ms)
|
||||||
|
|||||||
@@ -168,10 +168,20 @@ void RadioLibWrapper::onSendFinished() {
|
|||||||
state = STATE_IDLE;
|
state = STATE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t RadioLibWrapper::performChannelScan() {
|
||||||
|
return _radio->scanChannel();
|
||||||
|
}
|
||||||
|
|
||||||
bool RadioLibWrapper::isChannelActive() {
|
bool RadioLibWrapper::isChannelActive() {
|
||||||
return _threshold == 0
|
if (_threshold == 0) return false; // interference check is disabled
|
||||||
? false // interference check is disabled
|
|
||||||
: getCurrentRSSI() > _noise_floor + _threshold;
|
int16_t result = performChannelScan();
|
||||||
|
// scanChannel() triggers DIO interrupt (CAD done) which sets STATE_INT_READY
|
||||||
|
// via setFlag() ISR. Clear it before restarting RX so recvRaw() doesn't
|
||||||
|
// try to read a non-existent packet and count a spurious recv error.
|
||||||
|
state = STATE_IDLE;
|
||||||
|
startRecv();
|
||||||
|
return result != RADIOLIB_CHANNEL_FREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
float RadioLibWrapper::getLastRSSI() const {
|
float RadioLibWrapper::getLastRSSI() const {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual float getCurrentRSSI() =0;
|
virtual float getCurrentRSSI() =0;
|
||||||
|
virtual int16_t performChannelScan();
|
||||||
|
|
||||||
int getNoiseFloor() const override { return _noise_floor; }
|
int getNoiseFloor() const override { return _noise_floor; }
|
||||||
void triggerNoiseFloorCalibrate(int threshold) override;
|
void triggerNoiseFloorCalibrate(int threshold) override;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
// Power management boot protection threshold (millivolts)
|
// Power management boot protection threshold (millivolts)
|
||||||
// Set to 0 to disable boot protection
|
// Set to 0 to disable boot protection
|
||||||
#define PWRMGT_VOLTAGE_BOOTLOCK 3300 // Won't boot below this voltage (mV)
|
#define PWRMGT_VOLTAGE_BOOTLOCK 0 // Won't boot below this voltage (mV)
|
||||||
// LPCOMP wake configuration (voltage recovery from SYSTEMOFF)
|
// LPCOMP wake configuration (voltage recovery from SYSTEMOFF)
|
||||||
// AIN2 = P0.04 = BATTERY_PIN / PIN_VBAT_READ
|
// AIN2 = P0.04 = BATTERY_PIN / PIN_VBAT_READ
|
||||||
#define PWRMGT_LPCOMP_AIN 2
|
#define PWRMGT_LPCOMP_AIN 2
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ extern "C"
|
|||||||
|
|
||||||
// Power management boot protection threshold (millivolts)
|
// Power management boot protection threshold (millivolts)
|
||||||
// Set to 0 to disable boot protection
|
// Set to 0 to disable boot protection
|
||||||
#define PWRMGT_VOLTAGE_BOOTLOCK 3300 // Won't boot below this voltage (mV)
|
#define PWRMGT_VOLTAGE_BOOTLOCK 0 // Won't boot below this voltage (mV)
|
||||||
// LPCOMP wake configuration (voltage recovery from SYSTEMOFF)
|
// LPCOMP wake configuration (voltage recovery from SYSTEMOFF)
|
||||||
// AIN3 = P0.05 = PIN_A0 / PIN_VBAT_READ
|
// AIN3 = P0.05 = PIN_A0 / PIN_VBAT_READ
|
||||||
#define PWRMGT_LPCOMP_AIN 3
|
#define PWRMGT_LPCOMP_AIN 3
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ static const uint8_t D10 = 10;
|
|||||||
|
|
||||||
// Power management boot protection threshold (millivolts)
|
// Power management boot protection threshold (millivolts)
|
||||||
// Set to 0 to disable boot protection
|
// Set to 0 to disable boot protection
|
||||||
#define PWRMGT_VOLTAGE_BOOTLOCK 3300 // Won't boot below this voltage
|
#define PWRMGT_VOLTAGE_BOOTLOCK 0 // Won't boot below this voltage
|
||||||
|
|
||||||
// LPCOMP wake configuration (voltage recovery from SYSTEMOFF)
|
// LPCOMP wake configuration (voltage recovery from SYSTEMOFF)
|
||||||
#define PWRMGT_LPCOMP_AIN 7 // AIN7 = P0.31 = PIN_VBAT
|
#define PWRMGT_LPCOMP_AIN 7 // AIN7 = P0.31 = PIN_VBAT
|
||||||
|
|||||||
Reference in New Issue
Block a user