+3
-3
@@ -32,7 +32,7 @@ Only modify code for clearly scoped EastMesh features:
|
||||
|
||||
| Change | File |
|
||||
| --------------------- | -------------------- |
|
||||
| CLI / allowlist | `docs/custom-cli.md` |
|
||||
| CLI | `docs/custom-cli.md` |
|
||||
| Web panel UI/behavior | `docs/web-panel.md` |
|
||||
| Releases | `release-notes.yml` |
|
||||
| Flashing guidance | `docs/releases.md` |
|
||||
@@ -124,7 +124,7 @@ uv run pio run -e T_Beam_S3_Supreme_SX1262_repeater_mqtt -t upload --upload-port
|
||||
|
||||
If you change any of the following, update docs in the same PR when practical:
|
||||
|
||||
- Web-panel allowlisted commands:
|
||||
- Web-panel commands:
|
||||
- update `docs/custom-cli.md`
|
||||
- Web-panel user-facing behavior, sections, controls, or troubleshooting:
|
||||
- update `docs/web-panel.md`
|
||||
@@ -200,7 +200,7 @@ Do NOT (unless asked):
|
||||
|
||||
- rename tracks
|
||||
- change tag formats
|
||||
- expand allowlist without updating docs
|
||||
- expand cli without updating docs
|
||||
- change upstream CLI semantics
|
||||
- introduce new versioning schemes
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_16MB.csv",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
|
||||
@@ -103,7 +103,6 @@ This table includes all repeater MQTT targets currently defined in `variants/eas
|
||||
| LilyGo_TBeam_1W | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | OLED (SH1106) | ✅ | ✅ |
|
||||
| LilyGo_TDeck | ESP32S3 | 512 KB | No | 16 MB | SX1262 | TFT (ST7789) | ✅ | 🧪 |
|
||||
| LilyGo_Tlora_C6 | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
|
||||
| LilyGo_TLora_V2_1_1_6 | ESP32 | 520 KB | No | 4 MB | SX1276 | OLED (SSD1306) | ✅ | |
|
||||
| M5Stack_Unit_C6L | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | ✅ | |
|
||||
| Meshadventurer_sx1262 | ESP32 | 520 KB | No | 4 MB | SX1262 | OLED (SSD1306) | ✅ | |
|
||||
| Meshadventurer_sx1268 | ESP32 | 520 KB | No | 4 MB | SX1268 | OLED (SSD1306) | ✅ | |
|
||||
|
||||
@@ -82,90 +82,15 @@ Legacy dotted aliases are also accepted:
|
||||
- `get battery.reporting`: shows whether board battery reporting is enabled. Support is board-dependent.
|
||||
- `set battery.reporting on|off`: enables or disables battery voltage reporting on supported boards. This is currently useful for Heltec V3 boards where USB-only power can produce misleading battery readings. If your board needs this too, open an issue and support can be added board-by-board.
|
||||
|
||||
## Web Panel Allowlisted Commands
|
||||
## Web Panel CLI Access
|
||||
|
||||
When the repeater web panel is enabled, it only allows a limited command set.
|
||||
When the repeater web panel is enabled and you are authenticated, the browser CLI panel can run the same CLI commands accepted by the repeater.
|
||||
|
||||
That allowlist currently includes:
|
||||
Notes:
|
||||
|
||||
- `clock`
|
||||
- `get mqtt.status`
|
||||
- `get web`
|
||||
- `get web.status`
|
||||
- `get web.stats.status`
|
||||
- `advert`
|
||||
- `reboot`
|
||||
- `start ota`
|
||||
- `memory`
|
||||
- `stats-core`
|
||||
- `stats-radio`
|
||||
- `stats-packets`
|
||||
- `get wifi.status`
|
||||
- `get wifi.powersaving`
|
||||
- `set wifi.ssid <ssid>`
|
||||
- `set wifi.pwd <password>`
|
||||
- `set wifi.powersaving on|off`
|
||||
- `get mqtt.iata`
|
||||
- `set mqtt.iata <code>`
|
||||
- `get mqtt.owner`
|
||||
- `set mqtt.owner <64-hex-char-public-key>`
|
||||
- `get mqtt.email`
|
||||
- `set mqtt.email <email>`
|
||||
- `get mqtt.packets`
|
||||
- `set mqtt.packets on|off`
|
||||
- `get mqtt.raw`
|
||||
- `set mqtt.raw on|off`
|
||||
- `get mqtt.statuscfg`
|
||||
- `set mqtt.status on|off`
|
||||
- `get mqtt.tx`
|
||||
- `set mqtt.tx on|off`
|
||||
- `get mqtt.eastmesh-au`
|
||||
- `set mqtt.eastmesh-au on|off`
|
||||
- `get mqtt.eastmesh.au`
|
||||
- `set mqtt.eastmesh.au on|off`
|
||||
- `get mqtt.letsmesh-eu`
|
||||
- `set mqtt.letsmesh-eu on|off`
|
||||
- `get mqtt.letsmesh.eu`
|
||||
- `set mqtt.letsmesh.eu on|off`
|
||||
- `get mqtt.letsmesh-us`
|
||||
- `set mqtt.letsmesh-us on|off`
|
||||
- `get mqtt.letsmesh.us`
|
||||
- `set mqtt.letsmesh.us on|off`
|
||||
- `set web on|off`
|
||||
- `set.web on|off`
|
||||
- `set web.stats on|off`
|
||||
- `set.web.stats on|off`
|
||||
- `get name`
|
||||
- `set name <device-name>`
|
||||
- `get lat`
|
||||
- `set lat <latitude>`
|
||||
- `get lon`
|
||||
- `set lon <longitude>`
|
||||
- `get radio`
|
||||
- `set radio <freq> <bw> <sf> <cr>`
|
||||
- `get prv.key`
|
||||
- `get guest.password`
|
||||
- `password <admin-password>`
|
||||
- `set guest.password <password>`
|
||||
- `set prv.key <64-hex-char-private-key>`
|
||||
- `get role`
|
||||
- `get public.key`
|
||||
- `get advert.interval`
|
||||
- `set advert.interval <minutes>`
|
||||
- `get agc.reset.interval`
|
||||
- `set agc.reset.interval <seconds>`
|
||||
- `get flood.advert.interval`
|
||||
- `set flood.advert.interval <hours>`
|
||||
- `get repeat`
|
||||
- `set repeat on|off`
|
||||
- `get flood.max`
|
||||
- `set flood.max <count>`
|
||||
- `get path.hash.mode`
|
||||
- `set path.hash.mode <mode>`
|
||||
- `get owner.info`
|
||||
- `set owner.info <text>`
|
||||
- `time <iso-or-epoch>`
|
||||
- `time.force <iso-or-epoch>`
|
||||
- the panel still uses the repeater admin password for access
|
||||
- commands run with the same care as if you typed them into the repeater CLI directly
|
||||
- this is intended for local admin use on a trusted network
|
||||
|
||||
## Companion WiFi Rescue Commands
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ LilyGo_T3S3_sx1276_repeater_mqtt
|
||||
LilyGo_TBeam_1W_repeater_mqtt
|
||||
LilyGo_TDeck_repeater_mqtt
|
||||
LilyGo_Tlora_C6_repeater_mqtt
|
||||
LilyGo_TLora_V2_1_1_6_repeater_mqtt
|
||||
M5Stack_Unit_C6L_repeater_mqtt
|
||||
Meshadventurer_sx1262_repeater_mqtt
|
||||
Meshadventurer_sx1268_repeater_mqtt
|
||||
|
||||
@@ -13,7 +13,7 @@ It gives you:
|
||||
- a password-gated local admin page at `/app`
|
||||
- a dedicated stats and trends page at `/stats`
|
||||
- quick `get` commands for common repeater and MQTT checks
|
||||
- a terminal-style CLI panel for allowlisted commands
|
||||
- a terminal-style CLI panel for full repeater CLI access
|
||||
- editable repeater settings
|
||||
- editable MQTT settings
|
||||
- a historical stats view with trends, neighbours, and recent events
|
||||
@@ -71,7 +71,7 @@ Example:
|
||||
- the panel uses the same admin password as the repeater CLI
|
||||
- the connection is HTTPS, but the certificate is self-signed
|
||||
- browsers will warn the first time you connect
|
||||
- the panel only exposes an allowlisted subset of CLI commands
|
||||
- the panel exposes the repeater CLI after login
|
||||
|
||||
This is intended for local admin use on a trusted network, not for open internet exposure.
|
||||
|
||||
@@ -134,13 +134,13 @@ These are useful for quick checks without typing into the CLI field.
|
||||
|
||||
## Run CLI Command
|
||||
|
||||
This is a small terminal for allowlisted commands.
|
||||
This is a small terminal for the repeater CLI.
|
||||
|
||||
- press `Enter` to run the command
|
||||
- command history is shown in the terminal box below
|
||||
- save buttons elsewhere in the page also show the generated command and the reply here
|
||||
- `clock` is available here if you want to check the repeater's current board time
|
||||
- the full current allowlist is documented in `docs/custom-cli.md` under `Web Panel Allowlisted Commands`
|
||||
- authenticated sessions can run the same CLI commands accepted by the repeater
|
||||
|
||||
This makes it easy to see exactly what the panel sent to the repeater.
|
||||
|
||||
@@ -310,9 +310,9 @@ Check:
|
||||
|
||||
For fixed installations where MQTT uptime matters more than browser access, use the panel briefly and then disable it again.
|
||||
|
||||
### A command says it is not allowlisted
|
||||
### HTTP opens instead of HTTPS
|
||||
|
||||
The panel intentionally limits what can be run from the browser. Use the serial CLI for commands outside the web allowlist. `clock` is included, but most maintenance and debug commands are still serial-only.
|
||||
The repeater now redirects plain `http://` requests to the local `https://` panel URL. If the browser still shows a connection problem after redirecting, open `https://<repeater-ip>/` directly and accept the self-signed certificate warning first.
|
||||
|
||||
### Stats or settings do not refresh
|
||||
|
||||
|
||||
@@ -1992,100 +1992,6 @@ void MyMesh::runWebCommand(const char* command, char* reply, size_t reply_size)
|
||||
return;
|
||||
}
|
||||
|
||||
auto matches_exact = [command](const char* candidate) -> bool {
|
||||
return strcmp(command, candidate) == 0;
|
||||
};
|
||||
auto matches_prefix = [command](const char* candidate) -> bool {
|
||||
size_t len = strlen(candidate);
|
||||
return strncmp(command, candidate, len) == 0;
|
||||
};
|
||||
|
||||
bool allowed =
|
||||
matches_exact("clock") ||
|
||||
matches_exact("get mqtt.status") ||
|
||||
matches_exact("get web.status") ||
|
||||
matches_exact("get web.stats.status") ||
|
||||
matches_exact("get web") ||
|
||||
matches_exact("advert") ||
|
||||
matches_exact("reboot") ||
|
||||
matches_exact("start ota") ||
|
||||
matches_exact("get wifi.status") ||
|
||||
matches_exact("get wifi.powersaving") ||
|
||||
matches_exact("stats-core") ||
|
||||
matches_exact("stats-radio") ||
|
||||
matches_exact("stats-packets") ||
|
||||
matches_exact("memory") ||
|
||||
matches_exact("get mqtt.iata") ||
|
||||
matches_exact("get mqtt.owner") ||
|
||||
matches_exact("get mqtt.email") ||
|
||||
matches_exact("get mqtt.packets") ||
|
||||
matches_exact("get mqtt.raw") ||
|
||||
matches_exact("get mqtt.statuscfg") ||
|
||||
matches_exact("get mqtt.tx") ||
|
||||
matches_exact("get mqtt.eastmesh-au") ||
|
||||
matches_exact("get mqtt.eastmesh.au") ||
|
||||
matches_exact("get mqtt.letsmesh-eu") ||
|
||||
matches_exact("get mqtt.letsmesh.eu") ||
|
||||
matches_exact("get mqtt.letsmesh-us") ||
|
||||
matches_exact("get mqtt.letsmesh.us") ||
|
||||
matches_exact("get name") ||
|
||||
matches_exact("get lat") ||
|
||||
matches_exact("get lon") ||
|
||||
matches_exact("get radio") ||
|
||||
matches_exact("get prv.key") ||
|
||||
matches_exact("get role") ||
|
||||
matches_exact("get public.key") ||
|
||||
matches_exact("get advert.interval") ||
|
||||
matches_exact("get agc.reset.interval") ||
|
||||
matches_exact("get flood.advert.interval") ||
|
||||
matches_exact("get repeat") ||
|
||||
matches_exact("get flood.max") ||
|
||||
matches_exact("get path.hash.mode") ||
|
||||
matches_exact("get owner.info") ||
|
||||
matches_exact("get guest.password") ||
|
||||
matches_prefix("set wifi.ssid ") ||
|
||||
matches_prefix("set wifi.pwd ") ||
|
||||
matches_prefix("set wifi.powersaving ") ||
|
||||
matches_prefix("set mqtt.iata ") ||
|
||||
matches_prefix("set mqtt.owner ") ||
|
||||
matches_prefix("set mqtt.email ") ||
|
||||
matches_prefix("set mqtt.packets ") ||
|
||||
matches_prefix("set mqtt.raw ") ||
|
||||
matches_prefix("set mqtt.status ") ||
|
||||
matches_prefix("set mqtt.tx ") ||
|
||||
matches_prefix("set web ") ||
|
||||
matches_prefix("set.web ") ||
|
||||
matches_prefix("set web.stats ") ||
|
||||
matches_prefix("set.web.stats ") ||
|
||||
matches_prefix("set mqtt.eastmesh-au ") ||
|
||||
matches_prefix("set mqtt.eastmesh.au ") ||
|
||||
matches_prefix("set mqtt.letsmesh-eu ") ||
|
||||
matches_prefix("set mqtt.letsmesh.eu ") ||
|
||||
matches_prefix("set mqtt.letsmesh-us ") ||
|
||||
matches_prefix("set mqtt.letsmesh.us ") ||
|
||||
matches_prefix("set name ") ||
|
||||
matches_prefix("set lat ") ||
|
||||
matches_prefix("set lon ") ||
|
||||
matches_prefix("set radio ") ||
|
||||
matches_prefix("password ") ||
|
||||
matches_prefix("set guest.password ") ||
|
||||
matches_prefix("set prv.key ") ||
|
||||
matches_prefix("set advert.interval ") ||
|
||||
matches_prefix("set agc.reset.interval ") ||
|
||||
matches_prefix("set flood.advert.interval ") ||
|
||||
matches_prefix("set repeat ") ||
|
||||
matches_prefix("set flood.max ") ||
|
||||
matches_prefix("set path.hash.mode ") ||
|
||||
matches_prefix("time ") ||
|
||||
matches_prefix("time.force ") ||
|
||||
matches_prefix("set owner.info ");
|
||||
|
||||
if (!allowed) {
|
||||
strncpy(reply, "Err - command not allowlisted for web access", reply_size - 1);
|
||||
reply[reply_size - 1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
char command_buf[192];
|
||||
StrHelper::strncpy(command_buf, command, sizeof(command_buf));
|
||||
handleCommand(0, command_buf, reply);
|
||||
|
||||
@@ -320,3 +320,27 @@ releases:
|
||||
area: upstream
|
||||
text: "Updated the repeater_mqtt firmware base to upstream MeshCore v1.15.0."
|
||||
breaking_changes: []
|
||||
|
||||
- track: repeater-mqtt
|
||||
version: "1.3.6"
|
||||
tag: "repeater-mqtt-eastmesh-v1.3.6"
|
||||
date: "2026-04-20"
|
||||
previous_version: "1.3.5"
|
||||
summary: "Opened the repeater web CLI fully after login, added HTTP-to-HTTPS redirect support, preserved /stats through the login bounce, and fixed 4 MB repeater partition layouts."
|
||||
changes:
|
||||
- type: changed
|
||||
area: web-panel
|
||||
text: "Removed the browser-side repeater CLI allowlist so authenticated web panel sessions can run the same CLI commands accepted by the repeater."
|
||||
- type: added
|
||||
area: web-panel
|
||||
text: "Added a lightweight local HTTP listener that redirects browser requests to the repeater's HTTPS web panel URL."
|
||||
- type: changed
|
||||
area: web-panel
|
||||
text: "Changed the login flow so refreshing /stats and re-authenticating returns to /stats without persisting the last page in browser storage."
|
||||
- type: fixed
|
||||
area: board-support
|
||||
text: "Updated repeater_mqtt partition layouts for 4 MB boards so the affected targets use the correct flash sizing."
|
||||
- type: docs
|
||||
area: web-panel
|
||||
text: "Updated the repeater web panel and custom CLI docs to reflect full web CLI access and the new HTTP-to-HTTPS behavior."
|
||||
breaking_changes: []
|
||||
|
||||
@@ -256,10 +256,10 @@ const char kWebPanelLoginHtml[] PROGMEM = R"HTML(
|
||||
</main>
|
||||
<script>
|
||||
const statusEl = document.getElementById("status");
|
||||
const LAST_PAGE_KEY = "repeater-last-page";
|
||||
function getPreferredPage() {
|
||||
const stored = localStorage.getItem(LAST_PAGE_KEY);
|
||||
return stored === "/stats" ? "/stats" : "/app";
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const next = params.get("next");
|
||||
return next === "/stats" ? "/stats" : "/app";
|
||||
}
|
||||
async function login() {
|
||||
const pwd = document.getElementById("password").value;
|
||||
@@ -586,7 +586,7 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
<input id="command" placeholder="get mqtt.status">
|
||||
<button id="runBtn">Run</button>
|
||||
</div>
|
||||
<p class="panel-copy">Only the allowlisted commands exposed by this panel will run here.</p>
|
||||
<p class="panel-copy">Authenticated sessions can run repeater CLI commands here.</p>
|
||||
<div id="reply" class="terminal"></div>
|
||||
</section>
|
||||
|
||||
@@ -993,7 +993,6 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
<script>
|
||||
const RADIO_PRESETS_URL = "https://api.meshcore.nz/api/v1/config";
|
||||
const isStatsPage = window.location.pathname === "/stats";
|
||||
const LAST_PAGE_KEY = "repeater-last-page";
|
||||
const PANEL_TITLE_KEY = "repeater-panel-title";
|
||||
let token = sessionStorage.getItem("repeater-token") || "";
|
||||
let commandQueue = Promise.resolve();
|
||||
@@ -1020,16 +1019,12 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
document.title = cachedTitle.trim();
|
||||
}
|
||||
}
|
||||
function rememberCurrentPage() {
|
||||
localStorage.setItem(LAST_PAGE_KEY, isStatsPage ? "/stats" : "/app");
|
||||
}
|
||||
function redirectToLogin() {
|
||||
rememberCurrentPage();
|
||||
const next = isStatsPage ? "/stats" : "/app";
|
||||
sessionStorage.removeItem("repeater-token");
|
||||
token = "";
|
||||
window.location.replace("/");
|
||||
window.location.replace("/?next=" + encodeURIComponent(next));
|
||||
}
|
||||
rememberCurrentPage();
|
||||
applyCachedPanelTitle();
|
||||
function getPreferredTheme() {
|
||||
const saved = localStorage.getItem("repeater-theme");
|
||||
@@ -2466,7 +2461,7 @@ const char kWebPanelAppHtml[] PROGMEM = R"HTML(
|
||||
} // namespace
|
||||
|
||||
WebPanelServer::WebPanelServer()
|
||||
: _runner(nullptr), _server(nullptr), _token{0}, _last_activity_ms(0), _route_context{this} {
|
||||
: _runner(nullptr), _server(nullptr), _redirect_server(nullptr), _token{0}, _last_activity_ms(0), _route_context{this} {
|
||||
}
|
||||
|
||||
void WebPanelServer::setCommandRunner(WebPanelCommandRunner* runner) {
|
||||
@@ -2518,11 +2513,37 @@ bool WebPanelServer::start() {
|
||||
httpd_register_uri_handler(_server, &login_uri);
|
||||
httpd_register_uri_handler(_server, &command_uri);
|
||||
httpd_register_uri_handler(_server, &stats_uri);
|
||||
|
||||
httpd_config_t redirect_config = HTTPD_DEFAULT_CONFIG();
|
||||
redirect_config.server_port = 80;
|
||||
redirect_config.ctrl_port = 32768;
|
||||
redirect_config.max_open_sockets = 2;
|
||||
redirect_config.max_uri_handlers = 1;
|
||||
redirect_config.max_resp_headers = 4;
|
||||
redirect_config.backlog_conn = 2;
|
||||
redirect_config.recv_wait_timeout = 2;
|
||||
redirect_config.send_wait_timeout = 2;
|
||||
redirect_config.stack_size = kWebServerStackSize;
|
||||
redirect_config.uri_match_fn = httpd_uri_match_wildcard;
|
||||
|
||||
rc = httpd_start(&_redirect_server, &redirect_config);
|
||||
if (rc == ESP_OK) {
|
||||
httpd_uri_t redirect_uri = {.uri = "/*", .method = HTTP_GET, .handler = &WebPanelServer::handleHttpRedirect, .user_ctx = &_route_context};
|
||||
httpd_register_uri_handler(_redirect_server, &redirect_uri);
|
||||
} else {
|
||||
_redirect_server = nullptr;
|
||||
WEB_PANEL_LOG("redirect server start failed rc=0x%x", static_cast<unsigned>(rc));
|
||||
}
|
||||
|
||||
WEB_PANEL_LOG("server started on https://%s/", WiFi.localIP().toString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebPanelServer::stop() {
|
||||
if (_redirect_server != nullptr) {
|
||||
httpd_stop(_redirect_server);
|
||||
_redirect_server = nullptr;
|
||||
}
|
||||
if (_server != nullptr) {
|
||||
WEB_PANEL_LOG("server stopped");
|
||||
httpd_ssl_stop(_server);
|
||||
@@ -2563,6 +2584,21 @@ esp_err_t WebPanelServer::handleIndex(httpd_req_t* req) {
|
||||
return sendProgmemChunked(req, kWebPanelLoginHtml);
|
||||
}
|
||||
|
||||
esp_err_t WebPanelServer::handleHttpRedirect(httpd_req_t* req) {
|
||||
auto* ctx = static_cast<RouteContext*>(req->user_ctx);
|
||||
if (ctx == nullptr || ctx->self == nullptr) {
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
|
||||
char location[160];
|
||||
const char* path = (req->uri != nullptr && req->uri[0] != 0) ? req->uri : "/";
|
||||
snprintf(location, sizeof(location), "https://%s%s", WiFi.localIP().toString().c_str(), path);
|
||||
httpd_resp_set_status(req, "302 Found");
|
||||
httpd_resp_set_hdr(req, "Location", location);
|
||||
httpd_resp_set_hdr(req, "Cache-Control", "no-store");
|
||||
return httpd_resp_send(req, "", 0);
|
||||
}
|
||||
|
||||
esp_err_t WebPanelServer::handleApp(httpd_req_t* req) {
|
||||
auto* ctx = static_cast<RouteContext*>(req->user_ctx);
|
||||
if (ctx == nullptr || ctx->self == nullptr) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endif
|
||||
#if WITH_WEB_PANEL
|
||||
#include <esp_https_server.h>
|
||||
#include <esp_http_server.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -53,11 +54,13 @@ private:
|
||||
|
||||
WebPanelCommandRunner* _runner;
|
||||
httpd_handle_t _server;
|
||||
httpd_handle_t _redirect_server;
|
||||
char _token[33];
|
||||
unsigned long _last_activity_ms;
|
||||
RouteContext _route_context;
|
||||
|
||||
static esp_err_t handleIndex(httpd_req_t* req);
|
||||
static esp_err_t handleHttpRedirect(httpd_req_t* req);
|
||||
static esp_err_t handleApp(httpd_req_t* req);
|
||||
static esp_err_t handleStatsPage(httpd_req_t* req);
|
||||
static esp_err_t handleLogin(httpd_req_t* req);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[env:Ebyte_EoRa-S3_Repeater_mqtt]
|
||||
extends = Ebyte_EoRa-S3
|
||||
board_build.partitions = min_spiffs.csv
|
||||
build_flags =
|
||||
${Ebyte_EoRa-S3.build_flags}
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
@@ -25,6 +26,7 @@ lib_deps =
|
||||
|
||||
[env:Generic_E22_sx1262_repeater_mqtt]
|
||||
extends = Generic_E22
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
build_src_filter = ${Generic_E22.build_src_filter}
|
||||
+<../examples/simple_repeater/*.cpp>
|
||||
+<helpers/mqtt/*.cpp>
|
||||
@@ -51,6 +53,7 @@ lib_deps =
|
||||
|
||||
[env:Generic_E22_sx1268_repeater_mqtt]
|
||||
extends = Generic_E22
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
build_src_filter = ${Generic_E22.build_src_filter}
|
||||
+<../examples/simple_repeater/*.cpp>
|
||||
+<helpers/mqtt/*.cpp>
|
||||
@@ -359,6 +362,7 @@ lib_deps =
|
||||
|
||||
[env:LilyGo_T3S3_sx1262_repeater_mqtt]
|
||||
extends = LilyGo_T3S3_sx1262
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
build_flags =
|
||||
${LilyGo_T3S3_sx1262.build_flags}
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
@@ -384,6 +388,7 @@ lib_deps =
|
||||
|
||||
[env:LilyGo_T3S3_sx1276_repeater_mqtt]
|
||||
extends = LilyGo_T3S3_sx1276
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
build_flags =
|
||||
${LilyGo_T3S3_sx1276.build_flags}
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
@@ -478,29 +483,6 @@ build_flags =
|
||||
lib_deps =
|
||||
${tlora_c6.lib_deps}
|
||||
|
||||
[env:LilyGo_TLora_V2_1_1_6_repeater_mqtt]
|
||||
extends = LilyGo_TLora_V2_1_1_6
|
||||
build_src_filter = ${LilyGo_TLora_V2_1_1_6.build_src_filter}
|
||||
+<../examples/simple_repeater>
|
||||
+<helpers/mqtt/*.cpp>
|
||||
+<helpers/web/*.cpp>
|
||||
build_flags =
|
||||
${LilyGo_TLora_V2_1_1_6.build_flags}
|
||||
-D ADVERT_NAME='"TLora-V2.1-1.6 Repeater"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=50
|
||||
-D WITH_MQTT_UPLINK=1
|
||||
-D MQTT_DEBUG=1
|
||||
-D WIFI_SSID='"myssid"'
|
||||
-D WIFI_PWD='"mypwd"'
|
||||
-D MQTT_DEFAULT_IATA='"MEL"'
|
||||
-D CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=1
|
||||
lib_deps =
|
||||
${LilyGo_TLora_V2_1_1_6.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:M5Stack_Unit_C6L_repeater_mqtt]
|
||||
extends = M5Stack_Unit_C6L
|
||||
build_src_filter = ${M5Stack_Unit_C6L.build_src_filter}
|
||||
@@ -601,6 +583,7 @@ lib_deps =
|
||||
|
||||
[env:nibble_screen_connect_repeater_mqtt]
|
||||
extends = nibble_screen_connect_base
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
build_flags =
|
||||
${nibble_screen_connect_base.build_flags}
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
@@ -648,17 +631,15 @@ lib_deps =
|
||||
${esp32_ota.lib_deps}
|
||||
bakercp/CRC32 @ ^2.0.0
|
||||
|
||||
[env:Station_G2_logging_repeater_mqtt]
|
||||
[env:Station_G2_repeater_mqtt]
|
||||
extends = Station_G2
|
||||
build_flags =
|
||||
${Station_G2.build_flags}
|
||||
-D ADVERT_NAME='"Station G2 Logging Repeater"'
|
||||
-D ADVERT_NAME='"Station G2 Repeater"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=50
|
||||
-D MESH_PACKET_LOGGING=1
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
-D WITH_MQTT_UPLINK=1
|
||||
-D MQTT_DEBUG=1
|
||||
-D WIFI_SSID='"myssid"'
|
||||
@@ -673,15 +654,17 @@ lib_deps =
|
||||
${Station_G2.lib_deps}
|
||||
${esp32_ota.lib_deps}
|
||||
|
||||
[env:Station_G2_repeater_mqtt]
|
||||
[env:Station_G2_logging_repeater_mqtt]
|
||||
extends = Station_G2
|
||||
build_flags =
|
||||
${Station_G2.build_flags}
|
||||
-D ADVERT_NAME='"Station G2 Repeater"'
|
||||
-D ADVERT_NAME='"Station G2 Logging Repeater"'
|
||||
-D ADVERT_LAT=0.0
|
||||
-D ADVERT_LON=0.0
|
||||
-D ADMIN_PASSWORD='"password"'
|
||||
-D MAX_NEIGHBOURS=50
|
||||
-D MESH_PACKET_LOGGING=1
|
||||
-D SX126X_RX_BOOSTED_GAIN=1
|
||||
-D WITH_MQTT_UPLINK=1
|
||||
-D MQTT_DEBUG=1
|
||||
-D WIFI_SSID='"myssid"'
|
||||
@@ -768,6 +751,7 @@ lib_deps =
|
||||
|
||||
[env:ThinkNode_M2_Repeater_mqtt]
|
||||
extends = ThinkNode_M2
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
build_src_filter = ${ThinkNode_M2.build_src_filter}
|
||||
+<../examples/simple_repeater/*.cpp>
|
||||
+<helpers/mqtt/*.cpp>
|
||||
@@ -791,6 +775,7 @@ lib_deps =
|
||||
|
||||
[env:ThinkNode_M5_Repeater_mqtt]
|
||||
extends = ThinkNode_M5
|
||||
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
|
||||
build_src_filter = ${ThinkNode_M5.build_src_filter}
|
||||
+<../examples/simple_repeater/*.cpp>
|
||||
+<helpers/mqtt/*.cpp>
|
||||
|
||||
@@ -18,7 +18,7 @@ build_flags =
|
||||
-D HAS_NEOPIXEL
|
||||
-D NEOPIXEL_COUNT=1
|
||||
-D NEOPIXEL_DATA=21
|
||||
-D NEOPIXEL_TYPE=(NEO_GRB+NEO_KHZ800)
|
||||
-DNEOPIXEL_TYPE=NEO_GRB+NEO_KHZ800
|
||||
-D SX126X_DIO2_AS_RF_SWITCH=true
|
||||
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
|
||||
-D SX126X_CURRENT_LIMIT=140
|
||||
|
||||
@@ -39,6 +39,7 @@ build_src_filter = ${esp32_base.build_src_filter}
|
||||
lib_deps = ${esp32_base.lib_deps}
|
||||
adafruit/Adafruit SH110X @ ~2.1.13
|
||||
adafruit/Adafruit GFX Library @ ^1.12.1
|
||||
end2endzone/NonBlockingRTTTL @ ^1.4.0
|
||||
|
||||
[env:ThinkNode_M2_Repeater]
|
||||
extends = ThinkNode_M2
|
||||
|
||||
Ссылка в новой задаче
Block a user