Compare commits

..

1 Commits

Author SHA1 Message Date
vidplace7
0560a50ca7 DefCon 33 userPrefs 2025-07-17 21:47:54 -04:00
22 changed files with 65 additions and 353 deletions

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -226,14 +226,7 @@ RTCSetResult perhapsSetRTC(RTCQuality q, struct tm &t)
time_t res = gm_mktime(&t);
struct timeval tv;
tv.tv_sec = res;
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
#ifdef BUILD_EPOCH
if (tv.tv_sec < BUILD_EPOCH) {
LOG_WARN("Ignore time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
return RTCSetResultInvalidTime;
}
#endif
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
// LOG_DEBUG("Got time from GPS month=%d, year=%d, unixtime=%ld", t.tm_mon, t.tm_year, tv.tv_sec);
if (t.tm_year < 0 || t.tm_year >= 300) {

View File

@@ -1,156 +0,0 @@
#include "BRC.h"
#include "GPSStatus.h"
#include "gps/GeoCoord.h"
#include "graphics/Screen.h"
#if HAS_SCREEN
using namespace meshtastic;
const int32_t BRC_LATI = (40.786958 * 1e7);
const int32_t BRC_LONI = (-119.202994 * 1e7);
const double BRC_LATF = 40.786958;
const double BRC_LONF = -119.202994;
const double BRC_NOON = 1.5;
const double RAD_TO_HOUR = (6.0 / 3.14159);
const double METER_TO_FEET = 3.28084;
const double FEET_TO_METER = 1.0 / METER_TO_FEET;
// Pre-calculated street data for performance
struct StreetInfo {
float center;
float width;
const char *name;
};
/*
# python code to generate the StreetInfo
esp_center = 2500
street_info = [
# name, width, preceeding block depth
('Esp', 40, 60), # block size is fake
('A', 30, 400),
('B', 30, 250),
('C', 30, 250),
('D', 30, 250),
('E', 40, 250),
('F', 30, 450), # E-F block is exra deep
('G', 30, 250),
('H', 30, 250),
('I', 30, 250),
('J', 30, 150),
('K', 50, 150),
]
street_center = esp_center - street_info[0][1] //2 - street_info[0][2]
last_center = esp_center
for (name, street_width, block_width) in street_info:
offset = (street_width + block_width) // 2
street_center += street_width //2 + block_width
dia = street_center * 2
dist = street_center - last_center
print(f"{{{street_center}, {offset}, \"{name}\"}},\t// +{dist}ft\tdia: {dia:,}ft")
last_center = street_center
street_center += street_width //2
street_center += 50 # extra buffer after the edge of k to include walk-in camping parking
print(f"{{{street_center}, 0, nullptr}},\t// +{street_center-last_center}ft")
*/
static const StreetInfo streets[] = {
{2500, 50, "Esp"}, // +0ft dia: 5,000ft
{2935, 215, "A"}, // +435ft dia: 5,870ft
{3215, 140, "B"}, // +280ft dia: 6,430ft
{3495, 140, "C"}, // +280ft dia: 6,990ft
{3775, 140, "D"}, // +280ft dia: 7,550ft
{4060, 145, "E"}, // +285ft dia: 8,120ft
{4545, 240, "F"}, // +485ft dia: 9,090ft
{4825, 140, "G"}, // +280ft dia: 9,650ft
{5105, 140, "H"}, // +280ft dia: 10,210ft
{5385, 140, "I"}, // +280ft dia: 10,770ft
{5565, 90, "J"}, // +180ft dia: 11,130ft
{5755, 100, "K"}, // +190ft dia: 11,510ft
{5830, 0, nullptr}, // +75ft
};
BRCAddress::BRCAddress(int32_t lat, int32_t lon)
{
bearing = GeoCoord::bearing(BRC_LATF, BRC_LONF, DegD(lat), DegD(lon)) * RAD_TO_HOUR;
bearing += 12.0 - BRC_NOON;
while (bearing > 12.0) {
bearing -= 12.0;
}
// In imperial units because that is how golden spike data is provided.
distance = GeoCoord::latLongToMeter(BRC_LATF, BRC_LONF, DegD(lat), DegD(lon)) * METER_TO_FEET;
};
int BRCAddress::radial(char *buf, size_t len)
{
uint8_t hour = (uint8_t)(bearing);
uint8_t minute = (uint8_t)((bearing - hour) * 60.0);
hour %= 12;
if (hour == 0) {
hour = 12;
}
return snprintf(buf, len, "%d:%02d", hour, minute);
};
int BRCAddress::annular(char *buf, size_t len, bool noUnit)
{
const char *unit = "m";
float unitMultiplier = FEET_TO_METER;
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
unitMultiplier = 1.0;
unit = "ft";
}
if (noUnit)
unit = "";
if (bearing > 1.75 && bearing < 10.25) {
const char *street = nullptr;
float dist = 0;
// Find the appropriate street based on distance
for (const auto &s : streets) {
if (distance > s.center - s.width) {
street = s.name;
dist = distance - s.center;
} else {
break;
}
}
if (street) {
return snprintf(buf, len, "%s %d%s", street, int(dist * unitMultiplier), unit);
}
}
return snprintf(buf, len, "%d%s", int(distance * unitMultiplier), unit);
};
int BRCAddress::full(char *buf, size_t len)
{
auto l = radial(buf, len - 4);
buf += l;
*(buf++) = ' ';
*(buf++) = '&';
*(buf++) = ' ';
buf += annular(buf, len - l - 4, false);
buf[l] = 0; // always null terminated
return l;
};
int BRCAddress::compact(char *buf, size_t len)
{
auto l = radial(buf, len - 2);
buf += l;
*(buf++) = '&';
buf += annular(buf, len - l - 2, true);
buf[l] = 0; // always null terminated
return l;
};
#endif

View File

@@ -1,21 +0,0 @@
#pragma once
// For size_t/int32_t types on some platforms.
#include <cstdint>
// For size_t
#include <cstddef>
class BRCAddress
{
public:
BRCAddress(int32_t lat, int32_t lon);
int radial(char *buf, size_t len);
int annular(char *buf, size_t len, bool noUnit);
int full(char *buf, size_t len);
int compact(char *buf, size_t len);
private:
float bearing;
float distance;
};

View File

@@ -924,12 +924,6 @@ void Screen::setFrames(FrameFocus focus)
normalFrames[numframes++] = graphics::NodeListRenderer::drawNodeListWithCompasses;
indicatorIcons.push_back(icon_list);
#if HAS_SCREEN
fsi.positions.nodelist_brc = numframes;
normalFrames[numframes++] = graphics::NodeListRenderer::drawBRCList;
indicatorIcons.push_back(icon_bm);
#endif
fsi.positions.gps = numframes;
normalFrames[numframes++] = graphics::UIRenderer::drawCompassAndLocationScreen;
indicatorIcons.push_back(icon_compass);
@@ -1397,8 +1391,7 @@ int Screen::handleInputEvent(const InputEvent *event)
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_hopsignal ||
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_distance ||
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_hopsignal ||
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_bearings ||
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_brc) {
this->ui->getUiState()->currentFrame == framesetInfo.positions.nodelist_bearings) {
menuHandler::nodeListMenu();
} else if (this->ui->getUiState()->currentFrame == framesetInfo.positions.wifi) {
menuHandler::wifiBaseMenu();

View File

@@ -662,7 +662,6 @@ class Screen : public concurrency::OSThread
uint8_t nodelist_hopsignal = 255;
uint8_t nodelist_distance = 255;
uint8_t nodelist_bearings = 255;
uint8_t nodelist_brc = 255;
uint8_t clock = 255;
uint8_t firstFavorite = 255;
uint8_t lastFavorite = 255;

View File

@@ -6,7 +6,6 @@
#include "UIRenderer.h"
#include "gps/GeoCoord.h"
#include "gps/RTC.h" // for getTime() function
#include "graphics/BRC.h"
#include "graphics/ScreenFonts.h"
#include "graphics/SharedUIDisplay.h"
#include "graphics/images.h"
@@ -88,8 +87,6 @@ const char *getCurrentModeTitle(int screenWidth)
#endif
case MODE_DISTANCE:
return "Distance";
case MODE_BEARING:
return "Bearing";
default:
return "Nodes";
}
@@ -312,9 +309,6 @@ void drawEntryDynamic(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16
case MODE_DISTANCE:
drawNodeDistance(display, node, x, y, columnWidth);
break;
case MODE_BEARING:
drawEntryCompass(display, node, x, y, columnWidth);
break;
default:
break;
}
@@ -341,35 +335,6 @@ void drawEntryCompass(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16
}
}
void drawEntryBRC(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x, int16_t y, int columnWidth)
{
bool isLeftCol = (x < SCREEN_WIDTH / 2);
// Adjust max text width depending on column and screen width
int nameMaxWidth = columnWidth - (isHighResolution ? (isLeftCol ? 25 : 28) : (isLeftCol ? 20 : 22));
const char *nodeName = getSafeNodeName(node);
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
auto xText = x + ((isHighResolution) ? 6 : 3);
display->drawString(xText, y, nodeName);
if (nodeDB->hasValidPosition(node)) {
char buf[14] = "";
BRCAddress(node->position.latitude_i, node->position.longitude_i).compact(buf, 14);
auto nameWidth = display->getStringWidth("WWWW") - 2; // Fixed width so they are aligned.
display->drawString(xText + nameWidth, y, buf);
}
if (node->is_favorite) {
if (isHighResolution) {
drawScaledXBitmap16x16(x, y + 6, smallbulletpoint_width, smallbulletpoint_height, smallbulletpoint, display);
} else {
display->drawXbm(x, y + 5, smallbulletpoint_width, smallbulletpoint_height, smallbulletpoint);
}
}
}
void drawCompassArrow(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x, int16_t y, int columnWidth, float myHeading,
double userLat, double userLon)
{
@@ -419,46 +384,17 @@ void drawCompassArrow(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16
*/
}
void drawLastSeenExtra(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x, int16_t y, int columnWidth,
float /*myHeading*/, double /*userLat*/, double /*userLon*/)
{
char timeStr[10];
uint32_t seconds = sinceLastSeen(node);
if (seconds == 0 || seconds == UINT32_MAX) {
snprintf(timeStr, sizeof(timeStr), "?");
} else {
uint32_t minutes = seconds / 60, hours = minutes / 60, days = hours / 24;
snprintf(timeStr, sizeof(timeStr), (days > 99 ? "?" : "%d%c"),
(days ? days
: hours ? hours
: minutes),
(days ? 'd'
: hours ? 'h'
: 'm'));
}
bool isLeftCol = (x < SCREEN_WIDTH / 2);
int timeOffset = (isHighResolution) ? (isLeftCol ? 7 : 10) : (isLeftCol ? 3 : 7);
int rightEdge = x + columnWidth - timeOffset;
if (timeStr[strlen(timeStr) - 1] == 'm') // Fix the fact that our fonts don't line up well all the time
rightEdge -= 1;
// display->setTextAlignment(TEXT_ALIGN_RIGHT);
int textWidth = display->getStringWidth(timeStr);
display->drawString(rightEdge - textWidth, y, timeStr);
}
// =============================
// Main Screen Functions
// =============================
void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *title,
EntryRenderer renderer, NodeExtrasRenderer extras, float heading, double lat, double lon,
int totalColumns)
EntryRenderer renderer, NodeExtrasRenderer extras, float heading, double lat, double lon)
{
const int COMMON_HEADER_HEIGHT = FONT_HEIGHT_SMALL - 1;
const int rowYOffset = FONT_HEIGHT_SMALL - 3;
int columnWidth = display->getWidth() / totalColumns;
int columnWidth = display->getWidth() / 2;
display->clear();
@@ -472,6 +408,7 @@ void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t
int totalRowsAvailable = (display->getHeight() - y) / rowYOffset;
int visibleNodeRows = totalRowsAvailable;
int totalColumns = 2;
int startIndex = scrollIndex * visibleNodeRows * totalColumns;
if (nodeDB->getMeshNodeByIndex(startIndex)->num == nodeDB->getNodeNum()) {
@@ -509,7 +446,7 @@ void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t
}
// Draw column separator
if (shownCount > 0 && totalColumns > 1) {
if (shownCount > 0) {
const int firstNodeY = y + 3;
drawColumnSeparator(display, x, firstNodeY, lastNodeY);
}
@@ -545,31 +482,7 @@ void drawDynamicNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state,
// Render screen based on currentMode
const char *title = getCurrentModeTitle(display->getWidth());
if (currentMode == MODE_BEARING) {
float heading = 0;
bool validHeading = false;
auto ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
double lat = DegD(ourNode->position.latitude_i);
double lon = DegD(ourNode->position.longitude_i);
if (uiconfig.compass_mode != meshtastic_CompassMode_FREEZE_HEADING) {
if (screen->hasHeading()) {
heading = screen->getHeading(); // degrees
validHeading = true;
} else {
heading = screen->estimatedHeading(lat, lon);
validHeading = !isnan(heading);
}
if (!validHeading) {
lastRenderedMode = MODE_COUNT;
return;
}
}
drawNodeListScreen(display, state, x, y, title, drawEntryCompass, drawCompassArrow, heading, lat, lon);
} else {
drawNodeListScreen(display, state, x, y, title, drawEntryDynamic);
}
drawNodeListScreen(display, state, x, y, title, drawEntryDynamic);
// Track the last mode to avoid reinitializing modeStartTime
lastRenderedMode = currentMode;
@@ -626,11 +539,6 @@ void drawNodeListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state,
drawNodeListScreen(display, state, x, y, "Bearings", drawEntryCompass, drawCompassArrow, heading, lat, lon);
}
void drawBRCList(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
drawNodeListScreen(display, state, x, y, "BRC", drawEntryBRC, drawLastSeenExtra, 0, 0, 0, 1);
}
/// Draw a series of fields in a column, wrapping to multiple columns if needed
void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields)
{
@@ -656,4 +564,4 @@ void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields
} // namespace NodeListRenderer
} // namespace graphics
#endif
#endif

View File

@@ -24,12 +24,12 @@ typedef void (*EntryRenderer)(OLEDDisplay *, meshtastic_NodeInfoLite *, int16_t,
typedef void (*NodeExtrasRenderer)(OLEDDisplay *, meshtastic_NodeInfoLite *, int16_t, int16_t, int, float, double, double);
// Node list mode enumeration
enum NodeListMode { MODE_LAST_HEARD = 0, MODE_HOP_SIGNAL = 1, MODE_DISTANCE = 2, MODE_BEARING = 3, MODE_COUNT = 4 };
enum NodeListMode { MODE_LAST_HEARD = 0, MODE_HOP_SIGNAL = 1, MODE_DISTANCE = 2, MODE_COUNT = 3 };
// Main node list screen function
void drawNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *title,
EntryRenderer renderer, NodeExtrasRenderer extras = nullptr, float heading = 0, double lat = 0,
double lon = 0, int totalColumns = 2);
double lon = 0);
// Entry renderers
void drawEntryLastHeard(OLEDDisplay *display, meshtastic_NodeInfoLite *node, int16_t x, int16_t y, int columnWidth);
@@ -48,7 +48,6 @@ void drawHopSignalScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
void drawDistanceScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
void drawDynamicNodeListScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
void drawNodeListWithCompasses(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
void drawBRCList(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
// Utility functions
const char *getCurrentModeTitle(int screenWidth);

View File

@@ -8,7 +8,6 @@
#include "airtime.h"
#include "configuration.h"
#include "gps/GeoCoord.h"
#include "graphics/BRC.h"
#include "graphics/Screen.h"
#include "graphics/ScreenFonts.h"
#include "graphics/SharedUIDisplay.h"
@@ -309,12 +308,23 @@ void UIRenderer::drawNodeInfo(OLEDDisplay *display, const OLEDDisplayUiState *st
display->drawString(x, getTextPositions(display)[line++], seenStr);
}
// === 4. Burning Man location (only show if their position is known) ===
char brcStr[32] = "";
if (nodeDB->hasValidPosition(node) && line < 5) {
brcStr[0] = 32; // Space before the address to align with other rows.
BRCAddress(node->position.latitude_i, node->position.longitude_i).full(brcStr + 1, sizeof(brcStr) - 1);
display->drawString(x, getTextPositions(display)[line++], brcStr);
// === 4. Uptime (only show if metric is present) ===
char uptimeStr[32] = "";
if (node->has_device_metrics && node->device_metrics.has_uptime_seconds) {
uint32_t uptime = node->device_metrics.uptime_seconds;
uint32_t days = uptime / 86400;
uint32_t hours = (uptime % 86400) / 3600;
uint32_t mins = (uptime % 3600) / 60;
// Show as "Up: 2d 3h", "Up: 5h 14m", or "Up: 37m"
if (days)
snprintf(uptimeStr, sizeof(uptimeStr), " Uptime: %ud %uh", days, hours);
else if (hours)
snprintf(uptimeStr, sizeof(uptimeStr), " Uptime: %uh %um", hours, mins);
else
snprintf(uptimeStr, sizeof(uptimeStr), " Uptime: %um", mins);
}
if (uptimeStr[0] && line < 5) {
display->drawString(x, getTextPositions(display)[line++], uptimeStr);
}
// === 5. Distance (only if both nodes have GPS position) ===
@@ -911,7 +921,7 @@ void UIRenderer::drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayU
}
// If GPS is off, no need to display these parts
if (strcmp(displayLine, "GPS off") != 0 && strcmp(displayLine, "No GPS") != 0 && gpsStatus->getHasLock()) {
if (strcmp(displayLine, "GPS off") != 0 && strcmp(displayLine, "No GPS") != 0) {
// === Second Row: Date ===
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true);
@@ -932,18 +942,14 @@ void UIRenderer::drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayU
snprintf(lonStr, sizeof(lonStr), " Lon: %.5f", geoCoord.getLongitude() * 1e-7);
display->drawString(x, getTextPositions(display)[line++], lonStr);
// === Fifth Row: Burning Man! ===
char addrStr[32];
BRCAddress(geoCoord.getLatitude(), geoCoord.getLongitude()).full(addrStr, sizeof(addrStr));
display->drawString(x, getTextPositions(display)[line++], addrStr);
} else {
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
// from cell phone?
if (nodeDB->hasValidPosition(ourNode)) {
char addrStr[32];
BRCAddress(ourNode->position.latitude_i, ourNode->position.longitude_i).full(addrStr, sizeof(addrStr));
display->drawString(x, getTextPositions(display)[line++], addrStr);
// === Fifth Row: Altitude ===
char DisplayLineTwo[32] = {0};
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
snprintf(DisplayLineTwo, sizeof(DisplayLineTwo), " Alt: %.0fft", geoCoord.getAltitude() * METERS_TO_FEET);
} else {
snprintf(DisplayLineTwo, sizeof(DisplayLineTwo), " Alt: %.0im", geoCoord.getAltitude());
}
display->drawString(x, getTextPositions(display)[line++], DisplayLineTwo);
}
// === Draw Compass if heading is valid ===
@@ -1219,4 +1225,4 @@ std::string UIRenderer::drawTimeDelta(uint32_t days, uint32_t hours, uint32_t mi
} // namespace graphics
#endif // HAS_SCREEN
#endif // HAS_SCREEN

View File

@@ -156,18 +156,6 @@ const uint8_t icon_list[] PROGMEM = {
0x82 // Row 7: #.....#.
};
// ➤ The Man Icon (8x8)
const uint8_t icon_bm[] PROGMEM = {
0x42, // Row 0: .#....#.
0x3C, // Row 1: ..####..
0x3C, // Row 2: ..####..
0x18, // Row 3: ...##...
0x18, // Row 4: ...##...
0x24, // Row 5: ..#..#..
0x24, // Row 6: ..#..#..
0x42 // Row 7: .#....#.
};
// 📶 Signal Bars Icon (left to right, small to large with spacing)
const uint8_t icon_signal[] PROGMEM = {
0b00000000, // ░░░░░░░

View File

@@ -72,11 +72,10 @@ void FloodingRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
tosend->hop_limit--; // bump down the hop count
#if USERPREFS_EVENT_MODE
// BURNING MESH!
if (tosend->hop_limit > 3) {
if (tosend->hop_limit > 2) {
// if we are "correcting" the hop_limit, "correct" the hop_start by the same amount to preserve hops away.
tosend->hop_start -= (tosend->hop_limit - 3);
tosend->hop_limit = 3;
tosend->hop_start -= (tosend->hop_limit - 2);
tosend->hop_limit = 2;
}
#endif
tosend->next_hop = NO_NEXT_HOP_PREFERENCE; // this should already be the case, but just in case

View File

@@ -38,8 +38,7 @@ enum RxSource {
#define HOP_MAX 7
/// We normally just use max 3 hops for sending reliable messages
// BURNING MESH!
#define HOP_RELIABLE 4
#define HOP_RELIABLE 3
// For old firmware or when falling back to flooding, there is no next-hop preference
#define NO_NEXT_HOP_PREFERENCE 0

View File

@@ -1,20 +1,20 @@
{
// "USERPREFS_BUTTON_PIN": "36",
"USERPREFS_CHANNELS_TO_WRITE": "1",
"USERPREFS_CHANNELS_TO_WRITE": "3",
// "USERPREFS_CHANNEL_0_DOWNLINK_ENABLED": "false",
"USERPREFS_CHANNEL_0_NAME": "Everyone",
"USERPREFS_CHANNEL_0_PRECISION": "0",
"USERPREFS_CHANNEL_0_NAME": "DEFCONnect",
"USERPREFS_CHANNEL_0_PRECISION": "14",
"USERPREFS_CHANNEL_0_PSK": "{ 0x38, 0x4b, 0xbc, 0xc0, 0x1d, 0xc0, 0x22, 0xd1, 0x81, 0xbf, 0x36, 0xb8, 0x61, 0x21, 0xe1, 0xfb, 0x96, 0xb7, 0x2e, 0x55, 0xbf, 0x74, 0x22, 0x7e, 0x9d, 0x6a, 0xfb, 0x48, 0xd6, 0x4c, 0xb1, 0xa1 }",
// "USERPREFS_CHANNEL_0_UPLINK_ENABLED": "true",
"USERPREFS_CHANNEL_0_UPLINK_ENABLED": "true",
// "USERPREFS_CHANNEL_1_DOWNLINK_ENABLED": "false",
// "USERPREFS_CHANNEL_1_NAME": "NodeChat",
"USERPREFS_CHANNEL_1_NAME": "HackerComms",
// "USERPREFS_CHANNEL_1_PRECISION": "14",
// "USERPREFS_CHANNEL_1_PSK": "{ 0x4e, 0x22, 0x1d, 0x8b, 0xc3, 0x09, 0x1b, 0xe2, 0x11, 0x9c, 0x89, 0x12, 0xf2, 0x25, 0x19, 0x5d, 0x15, 0x3e, 0x30, 0x7b, 0x86, 0xb6, 0xec, 0xc4, 0x6a, 0xc3, 0x96, 0x5e, 0x9e, 0x10, 0x9d, 0xd5 }",
"USERPREFS_CHANNEL_1_PSK": "{ 0xe8, 0x8c, 0xec, 0x6a, 0x85, 0x61, 0xc7, 0x51, 0x13, 0x59, 0xe5, 0xae, 0xbb, 0x47, 0x54, 0x58, 0xc2, 0xea, 0x22, 0xdb, 0xd8, 0x24, 0xb6, 0xd1, 0xcf, 0x08, 0x13, 0x00, 0xa0, 0x9f, 0xbe, 0xd6 }",
// "USERPREFS_CHANNEL_1_UPLINK_ENABLED": "false",
// "USERPREFS_CHANNEL_2_DOWNLINK_ENABLED": "false",
// "USERPREFS_CHANNEL_2_NAME": "YardSale",
"USERPREFS_CHANNEL_2_NAME": "NodeChat",
// "USERPREFS_CHANNEL_2_PRECISION": "14",
// "USERPREFS_CHANNEL_2_PSK": "{ 0x15, 0x6f, 0xfe, 0x46, 0xd4, 0x56, 0x63, 0x8a, 0x54, 0x43, 0x13, 0xf2, 0xef, 0x6c, 0x63, 0x89, 0xf0, 0x06, 0x30, 0x52, 0xce, 0x36, 0x5e, 0xb1, 0xe8, 0xbb, 0x86, 0xe6, 0x26, 0x5b, 0x1d, 0x58 }",
"USERPREFS_CHANNEL_2_PSK": "{ 0x4e, 0x22, 0x1d, 0x8b, 0xc3, 0x09, 0x1b, 0xe2, 0x11, 0x9c, 0x89, 0x12, 0xf2, 0x25, 0x19, 0x5d, 0x15, 0x3e, 0x30, 0x7b, 0x86, 0xb6, 0xec, 0xc4, 0x6a, 0xc3, 0x96, 0x5e, 0x9e, 0x10, 0x9d, 0xd5 }",
// "USERPREFS_CHANNEL_2_UPLINK_ENABLED": "false",
// "USERPREFS_CONFIG_GPS_MODE": "meshtastic_Config_PositionConfig_GpsMode_ENABLED",
"USERPREFS_CONFIG_LORA_IGNORE_MQTT": "true",
@@ -37,23 +37,23 @@
// "USERPREFS_USE_ADMIN_KEY_0": "{ 0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a, 0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c }",
// "USERPREFS_USE_ADMIN_KEY_1": "{}",
// "USERPREFS_USE_ADMIN_KEY_2": "{}",
"USERPREFS_OEM_TEXT": "Burning Mesh 2025",
"USERPREFS_OEM_TEXT": "DefCon 33",
"USERPREFS_OEM_FONT_SIZE": "0",
"USERPREFS_OEM_IMAGE_WIDTH": "36",
"USERPREFS_OEM_IMAGE_HEIGHT": "56",
"USERPREFS_OEM_IMAGE_DATA": "{ 0x06, 0x00, 0x06, 0x00, 0x06, 0x0F, 0x00, 0x0F, 0x00, 0x0F, 0x1F, 0x80, 0x1F, 0x80, 0x0F, 0x1E, 0xC0, 0x3F, 0x80, 0x07, 0x3C, 0xE0, 0x7F, 0xC0, 0x03, 0x7C, 0xF0, 0xF9, 0xE0, 0x03, 0xF8, 0xF8, 0xF0, 0xF1, 0x01, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0xE0, 0xF1, 0xF0, 0x78, 0x00, 0xE0, 0xE3, 0x79, 0x7C, 0x00, 0xC0, 0xE3, 0x79, 0x3C, 0x00, 0x80, 0xC7, 0x3F, 0x1E, 0x00, 0x80, 0xC7, 0x3F, 0x1E, 0x00, 0x00, 0x8F, 0x1F, 0x0F, 0x00, 0x00, 0x8F, 0x0F, 0x0F, 0x00, 0x00, 0x1E, 0x8F, 0x07, 0x00, 0x00, 0x1E, 0x86, 0x07, 0x00, 0x00, 0x3C, 0xC0, 0x03, 0x00, 0x00, 0x3C, 0xC0, 0x03, 0x00, 0x00, 0x78, 0xE0, 0x01, 0x00, 0x00, 0x78, 0xE0, 0x01, 0x00, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x70, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x70, 0xE0, 0x00, 0x00, 0x00, 0x78, 0xE0, 0x01, 0x00, 0x00, 0x78, 0xE0, 0x01, 0x00, 0x00, 0x78, 0xE0, 0x01, 0x00, 0x00, 0x38, 0xC0, 0x01, 0x00, 0x00, 0x3C, 0xC0, 0x03, 0x00, 0x00, 0x3C, 0xC0, 0x03, 0x00, 0x00, 0x1C, 0x80, 0x03, 0x00, 0x00, 0x1E, 0x80, 0x07, 0x00, 0x00, 0x1E, 0x80, 0x07, 0x00, 0x00, 0x0F, 0x00, 0x07, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x80, 0x07, 0x00, 0x1E, 0x00, 0xC0, 0x03, 0x00, 0x1C, 0x00, 0xC0, 0x03, 0x00, 0x3C, 0x00, 0xC0, 0x03, 0x00, 0x3C, 0x00, 0xC0, 0x01, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x00 }",
"USERPREFS_OEM_IMAGE_WIDTH": "68",
"USERPREFS_OEM_IMAGE_HEIGHT": "58",
"USERPREFS_OEM_IMAGE_DATA": "{ 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0xef, 0xcf, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0xc7, 0x87, 0xff, 0x03, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x83, 0x07, 0xff, 0x03, 0x00, 0xf0, 0xf0, 0x00, 0xff, 0xc1, 0x03, 0xff, 0x03, 0x00, 0xf0, 0xf0, 0x00, 0xff, 0xc1, 0x01, 0xfe, 0x03, 0x00, 0xf0, 0xf0, 0x03, 0xff, 0xe0, 0x01, 0xfc, 0x0f, 0x3c, 0xf0, 0xf0, 0x03, 0x7f, 0xf0, 0x30, 0xfc, 0x0f, 0x3c, 0xf0, 0xf0, 0x03, 0x7f, 0x70, 0x78, 0xf8, 0x03, 0xfc, 0xf0, 0xf0, 0x03, 0x3f, 0x78, 0x78, 0xf0, 0x03, 0xfc, 0xf0, 0xf0, 0x0f, 0x1f, 0x3c, 0xfc, 0xf0, 0x0f, 0xfc, 0xf0, 0xf0, 0x0f, 0x0f, 0x1e, 0xfe, 0xe1, 0x0f, 0xfc, 0xf0, 0xfc, 0x3f, 0x0f, 0x0f, 0xfe, 0xc1, 0x03, 0xff, 0xf0, 0xfc, 0x3f, 0x07, 0x07, 0xff, 0x83, 0x03, 0xff, 0xf0, 0xfc, 0xff, 0x83, 0x87, 0xff, 0x87, 0xc3, 0xff, 0xf3, 0xfc, 0xff, 0xc7, 0xc3, 0xff, 0x0f, 0xc3, 0xff, 0xf3, 0xfc, 0xff, 0xef, 0xc7, 0xff, 0x8f, 0xff, 0xff, 0xf3, 0xfc, 0xff, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xff, 0xf3, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0xff, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0xff, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xc0, 0xc3, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x0c, 0xf0, 0xc0, 0xc3, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x0c, 0xf0, 0xf0, 0xff, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x3f, 0xf0, 0xf0, 0xff, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x3f, 0xf0, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0xff, 0x3f, 0xf0, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0xff, 0x3f, 0xf0, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0xf0, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0xf0, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xf0, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xf0, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xf0, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xf0, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xf0, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0 }",
// "USERPREFS_NETWORK_ENABLED_PROTOCOLS": "1", // Enable UDP mesh
// "USERPREFS_NETWORK_WIFI_ENABLED": "true",
// "USERPREFS_NETWORK_WIFI_SSID": "wifi_ssid",
// "USERPREFS_NETWORK_WIFI_PSK": "wifi_psk",
// "USERPREFS_MQTT_ENABLED": "1",
// "USERPREFS_MQTT_ADDRESS": "'mqtt.meshtastic.org'",
// "USERPREFS_MQTT_USERNAME": "meshdev",
// "USERPREFS_MQTT_PASSWORD": "large4cats",
// "USERPREFS_MQTT_ENCRYPTION_ENABLED": "true",
// "USERPREFS_MQTT_TLS_ENABLED": "false",
"USERPREFS_MQTT_ROOT_TOPIC": "event/BurningMesh",
// "USERPREFS_RINGTONE_NAG_SECS": "60",
"USERPREFS_RINGTONE_RTTTL": "24:d=32,o=5,b=565:f6,p,f6,4p,p,f6,p,f6,2p,p,b6,p,b6,p,b6,p,b6,p,b,p,b,p,b,p,b,p,b,p,b,p,b,p,b,1p.,2p.,p",
"USERPREFS_MQTT_ADDRESS": "'mqtt.defcon.org'",
"USERPREFS_MQTT_USERNAME": "public",
"USERPREFS_MQTT_PASSWORD": "'31337'",
"USERPREFS_MQTT_ENCRYPTION_ENABLED": "true",
"USERPREFS_MQTT_TLS_ENABLED": "true",
"USERPREFS_MQTT_ROOT_TOPIC": "event/defcon33",
"USERPREFS_RINGTONE_NAG_SECS": "10",
"USERPREFS_RINGTONE_RTTTL": "n:d=4,o=5,b=200:8g,8a,8c6,8a,e6,8p,e6,8p,d6.,p,8p,8g,8a,8c6,8a,d6,8p,d6,8p,c6,8b,a.,8g,8a,8c6,8a,2c6,d6,b,a,g.,8p,g,2d6,2c6.,p,8g,8a,8c6,8a,e6,8p,e6,8p,d6.,p,8p,8g,8a,8c6,8a,2g6,b,c6.,8b,a,8g,8a,8c6,8a,2c6,d6,b,a,g.,8p",
"USERPREFS_TZ_STRING": "PST8PDT,M3.2.0,M11.1.0"
}