This commit is contained in:
mikecarper committed 2026-10-21 08:13:31 +00:00
1 parent 58bd69beb9
commit 2ff75fe9fc
3 files changed
+360 -46

No files matched your search

+148 -18
View File
@@ -10026,7 +10026,7 @@ setting.</p>
<tbody>
<tr>
<td><code>radio</code></td>
<td>Ordinary LoRa flood forwarding. This is the default when <code>mode=</code> is omitted.</td>
<td>Ordinary LoRa forwarding; flood-only unless <code>route=direct</code> or <code>route=any</code> is selected. This is the default mode.</td>
</tr>
<tr>
<td><code>bridge</code></td>
@@ -10089,6 +10089,9 @@ removed. The fixed-size STM32WL FPF6 build cannot match authenticated channels.<
- <code>set flood.channel.scope.&lt;n&gt; &lt;channel|txt:*|login:*|other:*&gt; &lt;region|scope=name&gt; [path=blacklist|path=bucket:1-6] [tx=slow]</code>
- <code>del flood.channel.scope.&lt;n&gt;</code>
- <code>del flood.channel.scope all</code></p>
<p><code>fs</code> is the short family name for all these commands. Short options are
<code>p=bl</code> (<code>path=blacklist</code>), <code>p=b1</code> through <code>p=b6</code> (<code>path=bucket:1</code> through
<code>path=bucket:6</code>), and <code>tx=s</code>/<code>tx=f</code> (<code>tx=slow</code>/<code>tx=fast</code>).</p>
<p><strong>Parameters:</strong>
- <code>n</code>: Slot number within the table compiled for the target. Roomy ESP32 builds
provide <code>1-255</code>; classic ESP32 repeaters and nRF52/other
@@ -10269,6 +10272,8 @@ available for tables shared with <code>flood.filter path=blacklist</code> rules.
- <code>set flood.channel.scope.require.&lt;n&gt; &lt;public|#channel|128/256-bit-key&gt;</code>
- <code>del flood.channel.scope.require.&lt;n&gt;</code>
- <code>del flood.channel.scope.require all</code></p>
<p><code>fsr</code> is the short family name, with the same arguments and region/scope-manager
permissions.</p>
<p><strong>Default:</strong> Empty; normal global region enforcement remains active.</p>
<p>Once this table contains a row, received flood <code>GRP_TXT</code> and <code>GRP_DATA</code>
packets use selective region enforcement. A packet authenticating against a
@@ -10324,6 +10329,9 @@ worked moderation examples, see <a href="../flood_filtering/">Flood Filtering an
<li><code>del flood.filter.&lt;n&gt;</code></li>
<li><code>del flood.filter all</code></li>
</ul>
<p>Generalized rows also accept <code>sender=</code>, <code>text=</code>, <code>len=</code>, <code>route=</code>, <code>prob=</code>,
<code>enabled=</code>, and anchored <code>path=</code> chains. These use the same table and ordering;
see the parameters and short forms below.</p>
<p>The extended table is available on repeaters with the rule engine enabled and
on FULL-profile ESP32 room servers. A FULL room server exposes
<code>fr</code>, <code>flood.rule</code>, and <code>flood.filter</code>, has 31 slots, and requires an administrator
@@ -10373,7 +10381,35 @@ compile this table.</p>
relayed login/admin traffic, but not direct packets or local delivery.</li>
<li><code>prefix=&lt;ID[,ID...]&gt;</code>: Optional ordered source-path prefix of one to three
pbyte IDs. IDs must all be 2, 4, or 6 hex characters, matching a packet's
1-, 2-, or 3-byte pbyte width. <code>path=&lt;prefix&gt;</code> is an alias.</li>
1-, 2-, or 3-byte pbyte width. <code>p=</code> is the short form.</li>
<li><code>path=[^]ID&gt;ID...[$]</code> or <code>pa=...</code>: Ordered chain of up to four IDs, matched
anywhere in a flood path. <code>^</code> anchors the earliest relay and <code>$</code> the most
recent; both require exactly the chain. Commas may replace <code>&gt;</code>.
Each ID must use the packet's complete hash width. Direct paths and TRACE
SNR bytes never match. <code>path=blacklist</code> remains the separate unordered table.</li>
<li><code>sender=&lt;pattern&gt;</code> (<code>n=</code>), <code>text=&lt;pattern&gt;</code> (<code>x=</code>): Case-sensitive patterns
on the decrypted sender name and message body. Require an explicit
authenticated channel (<code>public</code>, <code>#name</code>, or key); <code>channel=*</code> and raw hashes
are insufficient. These match only plain group text. Patterns search
anywhere unless anchored with <code>^</code>/<code>$</code>, and support <code>.</code>, classes such as
<code>[A-Z]</code> or <code>[^0-9]</code>, <code>*</code>, <code>+</code>, <code>?</code>, groups, <code>|</code>, and escaped literals.
Use <code>[0-9]</code> for digits and quote values containing spaces. The maximum is
63 bytes per pattern. Matching uses complete fields, removes AES zero
padding, and shares a 131,072-operation work budget across one rule
evaluation. Exhaustion rejects the packet; it cannot grant an allow,
rewrite, or retry action.
A message without <code>:</code> has no sender field but can match a text rule.</li>
<li><code>len=N|N+|N-M</code> (<code>l=</code>): Inclusive range of payload bytes, excluding route/path
metadata. Ciphertext padding counts toward payload length.</li>
<li><code>route=flood|direct|any</code> (<code>rt=f|d|a</code>): Select route classes. Omitted radio
rules retain flood-only behavior. Direct/any rows support drop, rate, and
stop/allow; scope/region, retry, and TX timing require flood-only radio rules.</li>
<li><code>prob=1-100</code> (<code>pr=</code>): Apply the row to approximately this percentage of
otherwise-matching packets. Omitted means <code>100</code>; a failed roll leaves later
rows eligible. It is a sampling rule, not a forwarding quota.</li>
<li><code>enabled=on|off</code> (<code>e=1|0</code>): Keep a row while enabling or disabling it. To
change only this state, use <code>set fr.&lt;n&gt; e=off</code> or <code>set fr.&lt;n&gt; e=on</code>; its
conditions and actions stay saved.</li>
<li><code>in=any|none|scoped|allowed|unknown|scope:&lt;name&gt;|region:&lt;name&gt;</code>: Optional
condition on the original incoming scope, before any rule rewrites it.
<code>none</code> is an unscoped flood. <code>scope:name</code> is the exact public
@@ -10409,7 +10445,9 @@ compile this table.</p>
If the same row uses <code>region=</code> and that configured region is missing, denied,
wildcard, or has no usable transport key, both the rewrite and its <code>stop</code>
are inert so lower-order safety rows still run. A direct <code>scope=</code> target does
not depend on region configuration.</li>
not depend on region configuration.
<code>allow</code>, <code>forward</code>, and <code>a</code> are aliases for <code>stop</code>; they do not override
earlier drops, normal forwarding gates, or separate moderation rules.</li>
<li><code>suspend=tempradio</code>: Optional. Skip this row while either <code>tempradio</code> or
<code>tempradio2</code> is active, including scheduled temporary sessions.</li>
<li><code>require=region</code>: Legacy alias for <code>in=allowed</code>. Apply the row only if the
@@ -10522,11 +10560,11 @@ compile this table.</p>
</tr>
</tbody>
</table>
<p><strong>Route scope:</strong> <code>mode=radio</code> rules are evaluated only for the two flood route values:
<p><strong>Route scope:</strong> <code>mode=radio</code> defaults to the two flood route values:
<code>ROUTE_TYPE_TRANSPORT_FLOOD</code> (<code>0x00</code>, flood plus transport codes) and
<code>ROUTE_TYPE_FLOOD</code> (<code>0x01</code>, unscoped flood). Direct routes <code>0x02</code> and <code>0x03</code>
are unaffected by radio rules. Bridge/cross rules also cover direct routes at
their respective transport boundaries.</p>
require an explicit <code>route=direct</code> or <code>route=any</code> on a radio row. Bridge/cross
rules cover both route classes by default at their transport boundaries.</p>
<p><strong>Behavior:</strong> Match fields within one row are ANDed. Radio rows are matched
against the same immutable receive-time packet, before any rule changes its
scope. Bridge/cross rows match the packet at their admission boundary; a TX
@@ -10571,7 +10609,10 @@ preempted, and CAD and airtime-budget limits still apply.</p>
data and can be changed over serial or authenticated remote CLI without an OTA
or reboot. <code>flood.rule</code> and <code>flood.filter</code> address the same table on extended
builds; FPF6 files are migrated in memory and the next save writes FPF7.
FPF1-FPF5 files are rejected and filtering fails open. FPF7 stores canonical
New sender/text, length, route, probability, enabled-state, or extended-path
fields use FPF8 instead. Old firmware without FPF8 support cannot load that
table; remove the new fields before downgrading and keep a copy of the rules.
FPF1-FPF5 files are rejected and filtering fails open. FPF7/FPF8 store canonical
region names rather than transient numeric region
IDs. Removing, reordering, or reusing a region ID therefore cannot silently
retarget a rule. If a saved input or target region name is absent, that input
@@ -10581,11 +10622,10 @@ While either <code>tempradio</code> or <code>tempradio2</code> is active, only r
mode; normal payload types can also use the temporary channel. Other rows
remain in force, and suspended rows resume after both temporary sessions end.
A malformed persisted table fails open (no general rules are applied).</p>
<p>Within one receive evaluation, rows that use the same channel key share one
authentication result. The cache is discarded after that packet and stores
neither plaintext nor passwords; different keys are authenticated separately.
Raw <code>hash:XX</code> rows skip this authentication and compare only the one visible
byte.</p>
<p>Within one receive evaluation, rows using the same channel key share the
initial authentication verdict; content patterns also decrypt into temporary
scratch for matching. The cache and plaintext are discarded after the packet.
Raw <code>hash:XX</code> rows skip authentication and compare only the visible byte.</p>
<p><strong>Per-channel retry examples:</strong></p>
<pre><code class="language-text"># Use bridge-bucket retry only for authenticated Public and #hamradio traffic.
set flood.retry.bridge on
@@ -10656,6 +10696,17 @@ get fr.3
short setter; <code>get fr</code> lists the table. Unnumbered <code>set fr ...</code> reuses an
identical row or adds one to the first empty slot. <code>del fr.N</code> and <code>del fr all</code>
have the same behavior as their long forms.</p>
<p>Content, exceptions, and state changes use that same setter:</p>
<pre><code class="language-text">set fr grp_txt c=#local x=&quot;^BEACON&quot; d
set fr grp_txt c=#local n=&quot;^Alice$&quot; pri=200 a
set fr grp_txt c=#local d
set fr.4 e=off
set fr.4 e=on
</code></pre>
<p>The Alice rule stops lower-order general drops; separate moderation and hard
forwarding gates still apply. Sender names remain unverified display text.
Saved older prefix rules keep their start-anchored semantics; when retyping an
old <code>path=A1,B2</code>, use <code>prefix=A1,B2</code> or <code>pa=^A1&gt;B2</code>.</p>
<table>
<thead>
<tr>
@@ -10681,6 +10732,26 @@ have the same behavior as their long forms.</p>
<td><code>c=...</code>, <code>p=...</code></td>
</tr>
<tr>
<td><code>path=[^]ID&gt;ID...[$]</code></td>
<td><code>pa=...</code></td>
</tr>
<tr>
<td><code>sender=...</code>, <code>text=...</code></td>
<td><code>n=...</code>, <code>x=...</code></td>
</tr>
<tr>
<td><code>len=N/N+/N-M</code></td>
<td><code>l=...</code></td>
</tr>
<tr>
<td><code>route=flood/direct/any</code></td>
<td><code>rt=f/d/a</code></td>
</tr>
<tr>
<td><code>prob=N</code>, <code>enabled=on/off</code></td>
<td><code>pr=N</code>, <code>e=1/0</code></td>
</tr>
<tr>
<td><code>hashbytes=any/1/2/2+/3</code></td>
<td><code>pb=*/1/2/2+/3</code> (choose one value)</td>
</tr>
@@ -10701,6 +10772,10 @@ have the same behavior as their long forms.</p>
<td><code>d</code>, <code>s</code>, <code>r</code></td>
</tr>
<tr>
<td><code>allow</code>, <code>forward</code></td>
<td><code>a</code> (same action as <code>stop</code>)</td>
</tr>
<tr>
<td><code>scope=name</code>, <code>region=name</code></td>
<td><code>s=name</code>, <code>r=name</code></td>
</tr>
@@ -10715,8 +10790,46 @@ have the same behavior as their long forms.</p>
</tbody>
</table>
<p>All existing validation and permissions apply. <code>m=cb</code>, <code>m=b,c</code>, and <code>m=c,b</code>
also mean bridge and crossover. Short aliases for <code>flood.channel.scope</code>,
<code>flood.moderation</code>, and blacklist management are not added.</p>
also mean bridge and crossover.</p>
<table>
<thead>
<tr>
<th>Full family</th>
<th>Short family</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>flood.moderation</code></td>
<td><code>fm</code></td>
<td><code>get</code>, <code>set</code>, <code>del</code></td>
</tr>
<tr>
<td><code>flood.channel.scope</code></td>
<td><code>fs</code></td>
<td><code>get</code>, <code>set</code>, <code>del</code></td>
</tr>
<tr>
<td><code>flood.channel.scope.require</code></td>
<td><code>fsr</code></td>
<td><code>get</code>, <code>set</code>, <code>del</code></td>
</tr>
<tr>
<td><code>flood.filter.blacklist</code></td>
<td><code>fb</code></td>
<td><code>get</code>, <code>set</code>, <code>del</code></td>
</tr>
<tr>
<td><code>flood.advert</code></td>
<td><code>fa</code></td>
<td><code>get</code>, <code>clear</code></td>
</tr>
</tbody>
</table>
<p>Slot arguments, output, validation, and permissions are shared with the full
family names. For example, <code>get fa key 1</code> inspects the full advert key and
<code>clear fa all</code> clears advert history.</p>
<p>The numbered long getters use this complete short setter when descriptive
fields would exceed a reply. Defaults are omitted and specific payload types
are printed numerically. If it still cannot fit, the reply is
@@ -10728,7 +10841,7 @@ matching rule. Unknown or ambiguous references are rejected. See the
<a href="../flood_filtering/#shorthand-for-copying-rules">shorthand guide</a> for examples.</p>
<p>On generalized repeaters, filter rows, scope-rewrite rows, the shared
blacklist, and <code>flood.channel.data</code> compatibility state are committed in one
atomic FPF7 image. Compact FPF6 profiles retain separate files. Replacing or deleting
atomic FPF7/FPF8 image. Compact FPF6 profiles retain separate files. Replacing or deleting
the blacklist does not delete rows containing <code>path=blacklist</code>; such rows
remain dormant while the list is empty. Path hashes are truncated routing
identifiers, not authenticated identities, so this is a forwarding signal
@@ -10783,7 +10896,10 @@ FPF7 forward rows; hard gates and the rewrite/moderation phases still apply.</p>
<code>MESH_ENABLE_FLOOD_RULE_ENGINE=0</code> and retain the compact, persistent FPF6
<code>flood.filter</code> and blacklist commands. They still filter floods, but do not
expose the <code>flood.rule</code> alias or its extended channel, prefix, input-scope,
region-action, or rate fields. No partition size changes are required.</p>
region-action, or rate fields, nor sender/text patterns, length, route,
probability, enabled-state, or anchored chains. Their compiled legacy
families still accept the <code>fm</code>/<code>fs</code>/<code>fsr</code>/<code>fb</code>/<code>fa</code> aliases; <code>fm</code> requires
moderation support in that build. No partition size changes are required.</p>
<hr />
<h4 id="moderate-flood-group-text-by-channel-sender-and-source-path">Moderate flood group text by channel, sender, and source path</h4>
<p><strong>Usage:</strong>
@@ -10793,6 +10909,9 @@ region-action, or rate fields. No partition size changes are required.</p>
- <code>set flood.moderation.&lt;n&gt; &lt;channel&gt; &lt;sender&gt; &lt;action&gt; [action...]</code>
- <code>del flood.moderation.&lt;n&gt;</code>
- <code>del flood.moderation all</code></p>
<p><code>fm</code> is the short family name. Options can use <code>d</code> (<code>drop</code>), <code>q=N</code>
(<code>rate=N/min</code>), <code>h=N</code> (<code>hops=N</code>), and <code>p=...</code> (<code>path=...</code>). The short rate
also accepts <code>q=N/min</code> or <code>q=N/m</code>; duplicate rate/drop options remain invalid.</p>
<p><strong>Parameters:</strong>
- <code>n</code>: Moderation slot from <code>1</code> to <code>16</code>.
- <code>channel</code>:
@@ -10812,6 +10931,11 @@ region-action, or rate fields. No partition size changes are required.</p>
<p>At least one of <code>drop</code>, <code>rate=X/min</code>, or <code>hops=N</code> is required. Rate and hop
limits can be combined. Rate counters are local to this repeater and rule, use a
60-second window beginning with the first matching message, and reset on reboot.</p>
<p>Configured exact names are limited to 31 bytes. A wildcard <code>*</code> with a hop
restriction also matches longer valid sender names. The FGM1 storage format
is unchanged; saves use staging, readback, and backup recovery. A save reported
as unconfirmed may already have published, so rebooted settings can differ
from the restored live table.</p>
<p><strong>Decode and identity behavior:</strong> Moderation applies only to flood
<code>PAYLOAD_TYPE_GRP_TXT</code>. The repeater first checks the packet's channel-hash byte,
then validates and decrypts with the configured key. It extracts the text before
@@ -10829,6 +10953,7 @@ retransmission is denied. There are no moderation rules by default.</p>
<pre><code class="language-text">set flood.moderation public &quot;Noisy User&quot; rate=5/min
set flood.moderation #local bot drop path=A1B2C3,D4E5F6
set flood.moderation.3 00112233445566778899AABBCCDDEEFF alice rate=10/min hops=4 path=71CE82
set fm public &quot;Noisy User&quot; q=5
get flood.moderation
get flood.moderation.3
del flood.moderation.3
@@ -10851,13 +10976,18 @@ del flood.moderation.3
non-secret operational/filter status commands and can change the forwarding
controls <code>repeat</code>, <code>loop.detect</code>, <code>flood.max*</code>, <code>flood.channel.data*</code>,
<code>flood.filter*</code>, <code>flood.rule*</code>, <code>fr[.N]</code>, and
<code>flood.moderation*</code>. It cannot read
<code>flood.moderation*</code>, including the <code>fm</code>, <code>fb</code>, and <code>fa</code> aliases. It cannot read
guest, WiFi, MQTT, bridge, or other credentials, and it cannot change regions,
ACL entries, radio settings, or other admin configuration. Permission <code>4</code>
is limited to region commands, <code>flood.channel.scope*</code>, and the same non-secret
is limited to region commands, <code>flood.channel.scope*</code> (including <code>fs</code> and
<code>fsr</code>), and the same non-secret
status allowlist.
Both delegated manager roles are protected from least-recently-active ACL
eviction like administrators.</p>
<p>The same filter aliases work inside enrolled
<a href="../fleet_management/">signed fleet commands</a>, including quoted sender/text
patterns. Fleet signature, expiry, replay, and command-size checks still apply;
ordinary channel text cannot authorize a change.</p>
<p><strong>Note:</strong> Removes the entry when <code>permissions</code> is omitted</p>
<hr />
<h4 id="view-the-current-acl">View the current ACL</h4>
+211 -27
View File
@@ -1581,6 +1581,17 @@
<nav class="md-nav" aria-label="Runtime flood rules">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#content-patterns" class="md-nav__link">
<span class="md-ellipsis">
Content patterns
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#shorthand-for-copying-rules" class="md-nav__link">
<span class="md-ellipsis">
@@ -2726,6 +2737,17 @@
<nav class="md-nav" aria-label="Runtime flood rules">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#content-patterns" class="md-nav__link">
<span class="md-ellipsis">
Content patterns
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#shorthand-for-copying-rules" class="md-nav__link">
<span class="md-ellipsis">
@@ -2929,12 +2951,15 @@ scope-rewrite, passive-blacklist, or text-moderation phases. Standard room-serve
not compile the rule table. Filters decide whether the node retransmits a
packet and can assign a transport scope before that decision. They do not stop
local reception, packet logging, or MQTT observation.</p>
<p>Only flood routes are filtered:</p>
<p>Radio rules default to the two flood routes:</p>
<ul>
<li><code>0x00</code> / <code>ROUTE_TYPE_TRANSPORT_FLOOD</code> - flood routing with transport codes</li>
<li><code>0x01</code> / <code>ROUTE_TYPE_FLOOD</code> - unscoped flood routing</li>
</ul>
<p>Direct routes <code>0x02</code> and <code>0x03</code> are never affected by these rules.
<p>Generalized rules can opt into relayed direct routes (<code>0x02</code> and <code>0x03</code>) with
<code>route=direct</code>, or both route classes with <code>route=any</code>. Scope rewriting,
source-path matching, and the legacy moderation table remain flood-only.
Local delivery and requests addressed to this node are not relay decisions.
The route and payload values follow the upstream
<a href="https://docs.meshcore.io/packet_format/">packet-format reference</a> and
<a href="https://docs.meshcore.io/payloads/">payload layouts</a>, with this fork's LoRa
@@ -3089,7 +3114,7 @@ get flood.filter.blacklist
get flood.moderation
</code></pre>
<p><code>flood.rule</code> is an alias for <code>flood.filter</code>, not another table. Generalized
repeater FPF7 has 63 forward-rule slots plus scope-rewrite and shared-blacklist
repeaters have 63 forward-rule slots plus scope-rewrite and shared-blacklist
sections in the same atomic policy file. FULL room servers have 31 forward
slots and empty repeater-only sections. Compact target profiles retain their
separate FPF6-era controls. <code>flood.moderation</code> has 16 slots. A new
@@ -3115,6 +3140,9 @@ get flood.channel.scope.&lt;slot&gt;
del flood.channel.scope.&lt;slot&gt;
del flood.channel.scope all
</code></pre>
<p>Use <code>fs</code> in place of <code>flood.channel.scope</code> for any of these commands. Its
optional fields also accept <code>p=bl</code> for <code>path=blacklist</code>, <code>p=b1</code> through <code>p=b6</code>
for <code>path=bucket:1</code> through <code>path=bucket:6</code>, and <code>tx=s</code>/<code>tx=f</code> for slow/fast.</p>
<p>The channel may be <code>public</code>, <code>#channel</code>, or a 128/256-bit hex key. A bare
target names an existing region with a usable transport key. Use
<code>scope=&lt;name&gt;</code> instead to derive a regionless public hashtag scope exactly as
@@ -3230,7 +3258,7 @@ names for up to the smaller of the rule count or 32 distinct regionless
targets, except that very-tight STM32WL builds retain one reusable direct
target. Both configured regions and regionless targets can be reused by any
number of rules.</p>
<p>On generalized builds these records are the FPF7 rewrite phase, and the file
<p>On generalized builds these records are the shared rewrite phase, and the file
stores only through the highest occupied slot. Compact FPF6 builds retain the
standalone FCS5 file and the file sizes described by their build profile.</p>
<h2 id="require-valid-incoming-scopes-only-on-selected-channels">Require valid incoming scopes only on selected channels</h2>
@@ -3244,6 +3272,8 @@ get flood.channel.scope.require.&lt;slot&gt;
del flood.channel.scope.require.&lt;slot&gt;
del flood.channel.scope.require all
</code></pre>
<p><code>fsr</code> is the short name for <code>flood.channel.scope.require</code>, with the same
arguments, slots, and permissions.</p>
<p>An empty table preserves the normal global region behavior. Once at least one
row exists, a group-channel packet that authenticates against a listed key must
arrive as <code>ROUTE_TYPE_TRANSPORT_FLOOD</code> with a transport code matching a locally
@@ -3300,9 +3330,12 @@ scope arbitration.</p>
servers, <code>fr</code>, <code>flood.rule</code>, and <code>flood.filter</code> name the same persistent
table. The evaluator is fixed firmware, but every row is data, so an
authenticated operator can add, replace, inspect, or delete a row without an
OTA or reboot. Existing <code>flood.filter</code> commands remain compatible. Only FPF6
and FPF7 files are accepted; FPF1-FPF5 files are rejected and filtering fails
open. A row saved by the extended engine uses FPF7.
OTA or reboot. Existing <code>flood.filter</code> commands remain compatible. FPF6,
FPF7, and FPF8 files are accepted; FPF1-FPF5 files are rejected and filtering
fails open. New sender/text, payload-length, route, probability, enabled-state,
or extended-path fields are stored in FPF8. Tables using only older fields
retain FPF7. Firmware without FPF8 support cannot load an FPF8 table; remove
the new fields before downgrading and keep a copy of the rules.
Older firmware cannot preserve an FPF7 table containing the packed <code>retry</code>
action, one-byte <code>hash:XX</code> matcher, or <code>mode=bridge</code>/<code>cross</code> flags; remove those
rows before downgrading. Old firmware rejects such a table and fails open,
@@ -3322,7 +3355,7 @@ or updates that row; turning it on removes the row. Its hop setting maps to
of FPF7. Normal ordering applies, so a matching higher-priority <code>stop</code> row can
exempt selected traffic. The compact rule list marks the managed row with
<code>~data</code>.</p>
<p>FPF7 binds <code>in=region:&lt;name&gt;</code> and <code>region=&lt;name&gt;</code> to canonical region names,
<p>FPF7 and FPF8 bind <code>in=region:&lt;name&gt;</code> and <code>region=&lt;name&gt;</code> to canonical region names,
not numeric region IDs. Removing, reordering, or reusing a region ID cannot
silently redirect a rule. If the saved name is missing, an input-region match
does not match and a target-region rewrite is skipped. Re-adding the same name
@@ -3330,7 +3363,9 @@ reactivates the rule.</p>
<p>The extended form is:</p>
<pre><code class="language-text">set flood.rule[.&lt;slot&gt;] type=&lt;type&gt; [mode=radio|bridge|cross|bridge,cross]
[hops=&lt;range&gt;] [channel=&lt;channel&gt;] [hashbytes=any|1|2|2+|3]
[prefix=&lt;ID[,ID...]&gt;] [in=&lt;input-scope&gt;] &lt;action&gt; [rate=&lt;N&gt;/min]
[prefix=&lt;ID[,ID...]&gt;|path=[^]ID&gt;ID...[$]] [in=&lt;input-scope&gt;]
[sender=&lt;pattern&gt;] [text=&lt;pattern&gt;] [len=&lt;range&gt;] [route=flood|direct|any]
[prob=&lt;1-100&gt;] [enabled=on|off] &lt;action&gt; [rate=&lt;N&gt;/min]
[priority=&lt;0-255&gt;] [stop] [tx=fast|slow] [suspend=tempradio]
get flood.rule
get flood.rule.&lt;slot&gt;
@@ -3386,16 +3421,41 @@ independent and the highest-order matching scope or region rewrite wins.</p>
<li><code>prefix=</code> is a source-path prefix containing one to three comma-separated
pbyte IDs. Every ID must use the packet's pbyte width: 2, 4, or 6 hex
characters for 1-, 2-, or 3-byte paths. Order matters and matching begins at
the first received path entry. <code>path=&lt;prefix&gt;</code> is an alias;
<code>path=blacklist</code> retains its separate unordered-list behavior.</li>
<li><code>in=any|none|scoped|allowed|unknown|scope:&lt;name&gt;|region:&lt;name&gt;</code> tests the
the first received path entry. Its short name is <code>p=</code>.</li>
<li><code>path=</code> or <code>pa=</code> matches an ordered chain of up to four IDs anywhere in a
flood path. Separate IDs with <code>&gt;</code> or <code>,</code>; <code>^</code> anchors the first entry and
<code>$</code> the last. Thus <code>pa=A1&gt;B2</code> finds adjacent entries anywhere,
<code>pa=A1$</code> selects the most recent relay, and <code>pa=^A1&gt;B2$</code> requires exactly
those two entries. Each ID must use the packet's full 1-, 2-, or 3-byte
width. Direct paths and TRACE SNR bytes never match. <code>path=blacklist</code>
retains its separate unordered-list behavior.</li>
</ul>
<p>Saved older prefix rules keep their start-anchored meaning. When retyping an
older <code>path=A1,B2</code> command, use <code>prefix=A1,B2</code> or <code>pa=^A1&gt;B2</code> to retain it.
- <code>sender=</code> (<code>n=</code>) and <code>text=</code> (<code>x=</code>) match decrypted group text. An explicit
authenticated channel (<code>public</code>, <code>#name</code>, or a channel key) is required;
a raw channel hash is insufficient. See <a href="#content-patterns">content patterns</a>.
- <code>len=</code> (<code>l=</code>) matches payload bytes, using <code>N</code>, <code>N+</code>, or inclusive <code>N-M</code>.
It excludes the route/path envelope; encrypted padding is part of the payload.
- <code>route=</code> (<code>rt=</code>) selects <code>flood</code>, <code>direct</code>, or <code>any</code>; <code>f</code>, <code>d</code>, and <code>a</code> are
short values. Omitted radio rules remain flood-only. Direct/any rows may
drop, rate-limit, or stop; scope/region rewriting, retry, and TX timing
require flood-only radio rows.
- <code>prob=</code> (<code>pr=</code>) applies this rule to approximately that percentage of
otherwise-matching packets. Values are <code>1-100</code>; omitted means <code>100</code>.
A failed roll lets later rules run. This is sampling, not a delivery quota.
The decision stays the same for the same packet and row during one boot,
including repeated timing checks and scope rewrites.
- <code>enabled=off</code> (<code>e=off</code>) retains a row without evaluating it. <code>on</code>/<code>1</code>
enables and <code>off</code>/<code>0</code> disables. Change only this state with
<code>set fr.&lt;slot&gt; e=off</code> and <code>set fr.&lt;slot&gt; e=on</code>; the rest of the row stays saved.
- <code>in=any|none|scoped|allowed|unknown|scope:&lt;name&gt;|region:&lt;name&gt;</code> tests the
original incoming route before any rewrite. <code>none</code> means an unscoped flood;
<code>scoped</code> means any transport flood; <code>scope:name</code> compares the exact public
hashtag-derived scope; and <code>region:name</code> compares an allowed configured
region. <code>allowed</code> is the legacy <code>require=region</code> test and includes an
unscoped packet when the wildcard region allows it. <code>unknown</code> means a scoped
packet that does not resolve to an allowed local region.</li>
</ul>
packet that does not resolve to an allowed local region.</p>
<p>Actions:</p>
<ul>
<li><code>drop</code> prevents retransmission when the row matches. The strict
@@ -3424,13 +3484,47 @@ independent and the highest-order matching scope or region rewrite wins.</p>
first. Equal values use automatic channel specificity (authenticated, then
raw hash, then wildcard) before slot order. <code>pri=</code> is the compact alias.</li>
<li><code>stop</code> (or <code>action=stop</code>) applies this row and prevents lower-order FPF7 rows
from acting. It can stand alone or accompany drop, rewrite, or rate.</li>
from acting. It can stand alone or accompany drop, rewrite, or rate.
<code>allow</code>, <code>forward</code>, and <code>a</code> are aliases for the same stop action; they
do not bypass higher-priority drops, hard forwarding gates, or moderation.</li>
</ul>
<p>When several rows use the same channel key, authentication is performed once
for that packet and reused by those rows. This cache lives only for the current
receive evaluation; it is not persisted and never stores plaintext or a
password. A <code>hash:XX</code> row deliberately skips authentication and uses only the
one visible byte.</p>
<h3 id="content-patterns">Content patterns</h3>
<p>Sender/text patterns are case-sensitive byte matches. They search anywhere
unless anchored with <code>^</code> and <code>$</code>. Supported forms include <code>.</code>, <code>[A-Z]</code>,
<code>[^0-9]</code>, <code>*</code>, <code>+</code>, <code>?</code>, grouping, and <code>|</code> alternatives. Escape punctuation
with <code>\</code> to match it literally; use <code>[0-9]</code> for digits. Each pattern is at
most 63 bytes. Quote values containing spaces.</p>
<p>For <code>Alice: BEACON 123</code>, <code>n=^Alice$</code> matches the display name and
<code>x=^BEACON</code> matches the body. They can be combined in one row. The parser
uses the complete fields, including names longer than 31 bytes, and removes
AES zero padding before matching. A message without <code>:</code> has no sender field;
a text rule can still inspect its body. Wrong keys and non-text payloads do
not match content rules. Pattern matching shares a 131,072-operation budget
across the rules in one evaluation. Exhausting it rejects the packet rather
than granting an unverified allow, rewrite, or retry action. Keep patterns
short and specific.</p>
<pre><code class="language-text"># Block BEACON messages on this channel.
set fr grp_txt c=#local x=&quot;^BEACON&quot; d
# Exempt Alice from lower-order general rules, then block everyone else.
set fr grp_txt c=#local n=&quot;^Alice$&quot; pri=200 a
set fr grp_txt c=#local d
# Temporarily disable an occupied row without deleting its settings.
set fr.4 e=off
set fr.4 e=on
# Block floods whose most recent relay has this 3-byte ID.
set fr any pa=A1B2C3$ d
</code></pre>
<p>The allow exception remains subject to separate moderation and normal
forwarding gates. A sender name is freely chosen message text, not a verified
public-key identity. Legacy <code>flood.moderation</code> keeps its existing exact,
case-insensitive name matching.</p>
<p>Rows using the same channel key reuse the initial authentication verdict.
Content patterns also decrypt into temporary scratch for matching. Neither
the verdict cache nor plaintext survives the receive evaluation. A <code>hash:XX</code>
row skips authentication and uses only the one visible byte.</p>
<p>The global retry controls remain hard gates. A <code>retry</code> row does not override a
zero <code>flood.retry.count</code>, path/type attempt caps, disabled forwarding,
<code>flood.retry.advert</code>, a drop verdict, or any other forwarding rejection.
@@ -3578,6 +3672,31 @@ set fr.3 any c=#wardriving m=bc d
<td>Ordered path prefix.</td>
</tr>
<tr>
<td><code>path=[^]ID&gt;ID...[$]</code></td>
<td><code>pa=...</code></td>
<td>Ordered chain anywhere, or anchored at either end.</td>
</tr>
<tr>
<td><code>sender=...</code>, <code>text=...</code></td>
<td><code>n=...</code>, <code>x=...</code></td>
<td>Case-sensitive patterns on an authenticated group-text channel.</td>
</tr>
<tr>
<td><code>len=N</code>, <code>N+</code>, or <code>N-M</code></td>
<td><code>l=...</code></td>
<td>Payload-byte range.</td>
</tr>
<tr>
<td><code>route=flood</code>, <code>direct</code>, <code>any</code></td>
<td><code>rt=f</code>, <code>rt=d</code>, <code>rt=a</code></td>
<td>Route class.</td>
</tr>
<tr>
<td><code>prob=N</code>, <code>enabled=on/off</code></td>
<td><code>pr=N</code>, <code>e=1/0</code></td>
<td>Sample matches or retain a disabled row.</td>
</tr>
<tr>
<td><code>hashbytes=any</code>, <code>1</code>, <code>2</code>, <code>2+</code>, or <code>3</code></td>
<td><code>pb=*</code>, <code>1</code>, <code>2</code>, <code>2+</code>, or <code>3</code></td>
<td>Encoded path-hash width, even with zero hops; <code>2+</code> matches 2 and 3.</td>
@@ -3623,6 +3742,11 @@ set fr.3 any c=#wardriving m=bc d
<td>Stop later rules or allow the configured flood retry.</td>
</tr>
<tr>
<td><code>allow</code>, <code>forward</code></td>
<td><code>a</code></td>
<td>Same action as <code>stop</code>; other forwarding gates still apply.</td>
</tr>
<tr>
<td><code>tx=slow</code>, <code>suspend=tempradio</code>, <code>retry</code></td>
<td><code>f=s</code>, <code>f=t</code>, <code>f=r</code></td>
<td>Flags can combine, for example <code>f=str</code>.</td>
@@ -3661,9 +3785,48 @@ be pasted to edit or copy a rule there. On another device, or after deleting
the last rule holding that key, supply the original key instead. An unknown
or ambiguous reference is rejected; it never becomes an unauthenticated
channel-hash match.</p>
<p>The shorthand does not rename <code>flood.channel.scope</code>, <code>flood.moderation</code>, or
the blacklist-management commands. Companions and compact FPF6 profiles do
not expose <code>fr</code>.</p>
<p>Other repeater families have short names too, with identical arguments,
slot numbers, validation, persistence, and permissions:</p>
<table>
<thead>
<tr>
<th>Full family</th>
<th>Short family</th>
<th>Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>flood.moderation</code></td>
<td><code>fm</code></td>
<td><code>get</code>, <code>set</code>, <code>del</code></td>
</tr>
<tr>
<td><code>flood.channel.scope</code></td>
<td><code>fs</code></td>
<td><code>get</code>, <code>set</code>, <code>del</code></td>
</tr>
<tr>
<td><code>flood.channel.scope.require</code></td>
<td><code>fsr</code></td>
<td><code>get</code>, <code>set</code>, <code>del</code></td>
</tr>
<tr>
<td><code>flood.filter.blacklist</code></td>
<td><code>fb</code></td>
<td><code>get</code>, <code>set</code>, <code>del</code></td>
</tr>
<tr>
<td><code>flood.advert</code></td>
<td><code>fa</code></td>
<td><code>get</code>, <code>clear</code></td>
</tr>
</tbody>
</table>
<p>For example, <code>get fa key 1</code> inspects a full advert key and <code>clear fa all</code>
clears the advert limiter history. Companions do not expose these repeater
families. Compact FPF6 profiles retain their compiled legacy commands and
their family aliases, but do not expose <code>fr</code> or the new generalized fields.</p>
<h3 id="scope-actions-and-legacy-rules">Scope actions and legacy rules</h3>
<p>A legacy row without <code>scope=</code> is the existing drop action. On extended builds,
an explicit <code>drop</code> has the same result, while <code>rate=</code> by itself creates a
@@ -3695,7 +3858,7 @@ Selecting the scope already present does not grant special treatment. Active
radio transmission, CAD, and airtime-budget limits are unchanged.</p>
<p>On generalized repeaters, forward rules, <code>flood.channel.scope</code> rewrite rows,
the shared blacklist, and the <code>flood.channel.data</code> compatibility state are one
atomic FPF7 policy image. Existing <code>/flood_ch_scope</code>, <code>/flood_filter_bl</code>, FPF6,
atomic FPF7/FPF8 policy image. Existing <code>/flood_ch_scope</code>, <code>/flood_filter_bl</code>, FPF6,
and FCB2 data is imported once; the old files are removed only after the new
image verifies and commits. Compact FPF6 repeaters retain separate files.
Deleting the blacklist leaves <code>path=blacklist</code> rows in place but dormant until
@@ -3951,6 +4114,10 @@ not included in <code>get flood.moderation</code> output.</p>
<li><code>path=H1[,H2,H3]</code> - require the first one to three path hashes to match</li>
<li><code>path=*</code> - match every path; this is the default</li>
</ul>
<p><code>fm</code> is the short family name. Its option aliases are <code>d</code> for <code>drop</code>,
<code>q=N</code> for <code>rate=N/min</code>, <code>h=N</code> for <code>hops=N</code>, and <code>p=...</code> for <code>path=...</code>.
<code>q=N/min</code> and <code>q=N/m</code> are also accepted; mixed duplicate rate/drop options
are rejected just as in the full form.</p>
<p>At least one of <code>drop</code>, <code>rate=X/min</code>, or <code>hops=N</code> is required. Rate and hop
limits can be combined. <code>rate=0/min</code> is equivalent to <code>drop</code>.</p>
<h3 id="per-user-per-channel-rate-limits">Per-user, per-channel rate limits</h3>
@@ -3967,7 +4134,15 @@ set flood.moderation #local &quot;Noisy User&quot; rate=10/min
# Combine a rate limit with a maximum forwarding distance.
set flood.moderation public alice rate=4/min hops=5
# Same rule using short names.
set fm public alice q=4 h=5
</code></pre>
<p>The wildcard sender <code>*</code> works with a hop restriction, including for names
longer than 31 bytes. Exact configured names remain limited to 31 bytes.
Moderation settings retain the FGM1 format and use staged writes, readback,
and backup recovery. A failed save is reported as unconfirmed because a
failure after publication can leave the new settings available on reboot.</p>
<h3 id="match-the-start-of-a-path">Match the start of a path</h3>
<p>Path matching accepts one-, two-, or three-byte hashes. Every hash in one rule
must use the same width, and matching always starts at the beginning of the
@@ -4016,7 +4191,8 @@ control and will actually be retransmitted.</p>
</code></pre>
<p>A filter manager can read non-secret operational status and manage <code>repeat</code>,
<code>loop.detect</code>, <code>flood.max*</code>, <code>flood.channel.data*</code>,
<code>flood.filter*</code>, <code>flood.rule*</code>, <code>fr[.N]</code>, and <code>flood.moderation*</code>. Delegated <code>get</code> access uses an
<code>flood.filter*</code>, <code>flood.rule*</code>, <code>fr[.N]</code>, and <code>flood.moderation*</code>, including
the <code>fm</code>, <code>fb</code>, and <code>fa</code> aliases. Delegated <code>get</code> access uses an
explicit allowlist: it cannot retrieve guest, WiFi, MQTT, bridge, or other
credentials, and it cannot change regions, ACL entries, radio settings, or
unrelated administrator settings. Because <code>flood.filter scope=</code> derives a
@@ -4029,7 +4205,15 @@ permission <code>5</code>.</p>
delete <code>flood.channel.scope</code> and <code>flood.channel.scope.require</code> rows and manage
regions. This lets the same delegate create target regions, assign forced
scopes from regions or direct hashtag names, and select the channels that
require valid incoming scopes.</p>
require valid incoming scopes. The <code>fs</code> and <code>fsr</code> aliases retain this role.</p>
<p>Admin CLI sessions and these delegated roles use the same setters and
validation as the serial console. On enrolled builds, the aliases also work
inside <a href="../fleet_management/">signed fleet commands</a>, for example:</p>
<pre><code class="language-text">fleet send 3 set fr.4 grp_txt c=public x=&quot;^BEACON&quot; d
fleet send 3 set fr.4 e=off
</code></pre>
<p>Fleet enrollment, signature, expiry, replay, and command-size checks still
apply. An ordinary channel message cannot authorize a filter change.</p>
<h2 id="security-limitations">Security limitations</h2>
<p>Public and hashtag channels use shared, well-known keys. A valid channel MAC
proves that the sender knew the channel key; it does not identify a person.
@@ -4052,7 +4236,7 @@ private transport/channel keys, and controlled device access.</p>
<tbody>
<tr>
<td><code>radio</code></td>
<td>Ordinary LoRa flood forwarding. This is the default when <code>mode=</code> is omitted.</td>
<td>Ordinary LoRa forwarding; flood-only by default, or opt into direct routes with <code>route=</code>. This is the default mode.</td>
</tr>
<tr>
<td><code>bridge</code></td>
+1 -1
View File
@@ -1 +1 @@
{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Home","text":"<p>View this page on MeshCore Docs.</p>"},{"location":"#meshcore-documentation","title":"MeshCore documentation","text":"<p>Choose firmware with the firmware picker. For help with a device already in service, start with the FAQ.</p>"},{"location":"#current-release","title":"Current release","text":"<ul> <li>1.17.1.8 USA Cascade release notes</li> <li>Test Results \u2014 validation archive and 1.17.1.8 Preview 1 qualification evidence</li> </ul>"},{"location":"#documentation","title":"Documentation","text":"<ul> <li>Feature switches by role and Full Companion features</li> <li>Firmware update guide, easy LoRa OTA, and scripted LoRa OTA</li> <li>CLI commands, availability by build, and radio profiles</li> <li>Private fleet management: signed filtering and secondary-radio commands for a fleet or one node</li> <li>Room history, moderation, and information board: optional persistent chat and local Wi-Fi room access</li> <li>Companion protocol, packet format, and QR codes</li> </ul> <p>The navigation groups the remaining guides under Documentation, including board-specific updates, networking, power, and protocol references.</p>"},{"location":"#tools","title":"Tools","text":"<ul> <li>Firmware picker and USB web console</li> <li>Notification builder and temporary radio test builder</li> <li>Filter policy playground, telemetry decoder, and management report decoder</li> </ul>"},{"location":"#engineering-records","title":"Engineering records","text":"<ul> <li>Research \u2014 design notes, diagnostics, and historical update-chain studies</li> <li>Old Releases \u2014 historical release notes and supporting files</li> </ul> <p>Found a mistake or missing information? Edit the documentation.</p>"},{"location":"WiFi/","title":"WiFi","text":"<p>View this page on MeshCore Docs.</p>"},{"location":"WiFi/#wifi-and-mqtt-by-firmware-type","title":"WiFi and MQTT by Firmware Type","text":"<p>MeshCore itself does not require WiFi or the internet. LoRa packet exchange, repeating, room servers, companions, and sensors can all operate without either. WiFi is added by particular ESP32 firmware targets for one or more of these purposes:</p> <ul> <li>a TCP connection between a WiFi companion and a phone or computer;</li> <li>the WebConfig browser interface;</li> <li>MQTT uplinking from the radio to internet or LAN brokers;</li> <li>WiFi-assisted OTA services on builds that include them;</li> <li>ESP-NOW bridging, which uses the ESP32's 2.4 GHz radio but is not a connection to a WiFi access point.</li> </ul> <p>The firmware role and the build profile are separate choices. USB logging does not itself provide MQTT. MQTT-capable Full Companions include that feature without <code>mqtt</code> in their filename; check the artifact capability manifest. See feature switches by role for the different Companion and infrastructure controls and the USB web console.</p>"},{"location":"WiFi/#quick-reference","title":"Quick reference","text":"Firmware target or role Infrastructure WiFi MQTT What WiFi does <code>*_repeater</code> Build-dependent on ESP32 No FULL builds provide WebConfig, browser OTA, and the TCP 5001 LoRa-OTA seeder while WiFi is active <code>*_repeater_observer_mqtt</code> Yes Yes Uplinks heard and selected transmitted LoRa packets; repeating remains enabled by default <code>*_room_server</code> Build-dependent on ESP32 No FULL builds provide WebConfig, browser OTA, and the TCP 5001 LoRa-OTA seeder while WiFi is active <code>*_room_server_observer_mqtt</code> Yes Yes Runs the room server and uplinks radio traffic <code>*_companion_radio_wifi</code> Yes No Exposes the MeshCore companion protocol on TCP port 5000 <code>*_companion_radio_wifi_mqtt</code> Yes Yes Runs both the TCP companion interface and the MQTT uplink <code>*_companion_radio_full*</code> ESP32, subject to board/transport selection Where compiled on ESP32 Includes supported USB/wireless transports; configure MQTT through WebConfig Dedicated USB, BLE, or serial companion (not Full) No No Uses the transport named by the target instead <code>*_repeater_bridge_espnow</code> Build-dependent on ESP32 No Uses ESP-NOW for its bridge; <code>bridge.format wrapped|raw</code> selects legacy bridge framing or primary-ESP-NOW compatibility; a FULL build also exposes the TCP 5001 LoRa-OTA seeder whenever WiFi is usable RS232 bridge No No Bridges through a serial interface Ethernet repeater/room server No WiFi No Uses wired Ethernet for its role-specific network interface <code>*_sensor</code> Build-dependent on ESP32 No A FULL ESP32 sensor can expose the TCP 5001 LoRa-OTA seeder through its browser-OTA setup AP Terminal-chat or KISS modem No in current targets No Uses LoRa and its role-specific local interface <code>*_lora_ota_no_external_sensors</code> On demand on ESP32 No LeaLine truncated
{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Home","text":"<p>View this page on MeshCore Docs.</p>"},{"location":"#meshcore-documentation","title":"MeshCore documentation","text":"<p>Choose firmware with the firmware picker. For help with a device already in service, start with the FAQ.</p>"},{"location":"#current-release","title":"Current release","text":"<ul> <li>1.17.1.8 USA Cascade release notes</li> <li>Test Results \u2014 validation archive and 1.17.1.8 Preview 1 qualification evidence</li> </ul>"},{"location":"#documentation","title":"Documentation","text":"<ul> <li>Feature switches by role and Full Companion features</li> <li>Firmware update guide, easy LoRa OTA, and scripted LoRa OTA</li> <li>CLI commands, availability by build, and radio profiles</li> <li>Private fleet management: signed filtering and secondary-radio commands for a fleet or one node</li> <li>Room history, moderation, and information board: optional persistent chat and local Wi-Fi room access</li> <li>Companion protocol, packet format, and QR codes</li> </ul> <p>The navigation groups the remaining guides under Documentation, including board-specific updates, networking, power, and protocol references.</p>"},{"location":"#tools","title":"Tools","text":"<ul> <li>Firmware picker and USB web console</li> <li>Notification builder and temporary radio test builder</li> <li>Filter policy playground, telemetry decoder, and management report decoder</li> </ul>"},{"location":"#engineering-records","title":"Engineering records","text":"<ul> <li>Research \u2014 design notes, diagnostics, and historical update-chain studies</li> <li>Old Releases \u2014 historical release notes and supporting files</li> </ul> <p>Found a mistake or missing information? Edit the documentation.</p>"},{"location":"WiFi/","title":"WiFi","text":"<p>View this page on MeshCore Docs.</p>"},{"location":"WiFi/#wifi-and-mqtt-by-firmware-type","title":"WiFi and MQTT by Firmware Type","text":"<p>MeshCore itself does not require WiFi or the internet. LoRa packet exchange, repeating, room servers, companions, and sensors can all operate without either. WiFi is added by particular ESP32 firmware targets for one or more of these purposes:</p> <ul> <li>a TCP connection between a WiFi companion and a phone or computer;</li> <li>the WebConfig browser interface;</li> <li>MQTT uplinking from the radio to internet or LAN brokers;</li> <li>WiFi-assisted OTA services on builds that include them;</li> <li>ESP-NOW bridging, which uses the ESP32's 2.4 GHz radio but is not a connection to a WiFi access point.</li> </ul> <p>The firmware role and the build profile are separate choices. USB logging does not itself provide MQTT. MQTT-capable Full Companions include that feature without <code>mqtt</code> in their filename; check the artifact capability manifest. See feature switches by role for the different Companion and infrastructure controls and the USB web console.</p>"},{"location":"WiFi/#quick-reference","title":"Quick reference","text":"Firmware target or role Infrastructure WiFi MQTT What WiFi does <code>*_repeater</code> Build-dependent on ESP32 No FULL builds provide WebConfig, browser OTA, and the TCP 5001 LoRa-OTA seeder while WiFi is active <code>*_repeater_observer_mqtt</code> Yes Yes Uplinks heard and selected transmitted LoRa packets; repeating remains enabled by default <code>*_room_server</code> Build-dependent on ESP32 No FULL builds provide WebConfig, browser OTA, and the TCP 5001 LoRa-OTA seeder while WiFi is active <code>*_room_server_observer_mqtt</code> Yes Yes Runs the room server and uplinks radio traffic <code>*_companion_radio_wifi</code> Yes No Exposes the MeshCore companion protocol on TCP port 5000 <code>*_companion_radio_wifi_mqtt</code> Yes Yes Runs both the TCP companion interface and the MQTT uplink <code>*_companion_radio_full*</code> ESP32, subject to board/transport selection Where compiled on ESP32 Includes supported USB/wireless transports; configure MQTT through WebConfig Dedicated USB, BLE, or serial companion (not Full) No No Uses the transport named by the target instead <code>*_repeater_bridge_espnow</code> Build-dependent on ESP32 No Uses ESP-NOW for its bridge; <code>bridge.format wrapped|raw</code> selects legacy bridge framing or primary-ESP-NOW compatibility; a FULL build also exposes the TCP 5001 LoRa-OTA seeder whenever WiFi is usable RS232 bridge No No Bridges through a serial interface Ethernet repeater/room server No WiFi No Uses wired Ethernet for its role-specific network interface <code>*_sensor</code> Build-dependent on ESP32 No A FULL ESP32 sensor can expose the TCP 5001 LoRa-OTA seeder through its browser-OTA setup AP Terminal-chat or KISS modem No in current targets No Uses LoRa and its role-specific local interface <code>*_lora_ota_no_external_sensors</code> On demand on ESP32 No LeaLine truncated