Skip to content

Configuring Channels

Builder Bob edited this page Jun 23, 2026 · 27 revisions

Configuring Channels

This page is the operator how-to for Crow channel setup.

Start with the backend/bridge setup first, then join or configure channels. The order matters: Crow needs to know which bridge backends are active before channel membership and routing behavior make sense.

Configuration order

Use this order when setting up a node:

  1. Initial setup
  2. MeshIP (AREDN) Bridge
  3. Meshtastic UDP Bridge
  4. MeshCore UDP Bridge
  5. APRS Backend
  6. Experimental: Meshtastic API Backend
  7. Experimental: MeshCore TCP API Backend with Auto-Discovery
  8. Joining channels
  9. Validation

Initial setup

Crow ships with default bridge paths. The purpus of Crow is to provide a messaging app, that bridges backend modes to channel in concept. Clearly name channels before changing backend configuration!

The default bridged channels are:

Default bridge channel What it means Default backend
Meshtastic UDP Device Bridge Channel Channel/path used for the original Meshtastic UDP device bridge. meshtastic.uc
MeshCore UDP Device Bridge Channel Channel/path used for the original MeshCore UDP device bridge. meshcore.uc

These are bridge/channel roles, not proof that a user has joined a chat channel yet. Configure the bridge backend first, then join or map specific operator channels.

Backend / Bridges

Crow can bridge messages between several transport families. Start here before joining channels.

Bridge section Backend module Status Default?
MeshIP (AREDN) Bridge meship.uc Native AREDN mesh transport Yes
Meshtastic UDP Bridge meshtastic.uc Legacy UDP/multicast device bridge Yes
MeshCore UDP Bridge meshcore.uc Legacy UDP/multicast device bridge Yes
APRS Backend Text tnc/tcpIP KISS tnc/APRS-IS backend config Operator-configured APRS bridge Optional
Experimental: Meshtastic API Backend meshtastic_API.uc Experimental TCP Port-API backend No
Experimental: MeshCore TCP API Backend with Auto-Discovery meshcore_tcp_api.uc Experimental TCP API backend No

The bridge setup layer decides how Crow talks to each transport. Channel setup decides which message groups/keys are allowed to route.

The router imports selector modules:

import * as meshtastic from "meshtastic_backend";
import * as meshcore from "meshcore_backend";

The selector modules preserve the original UDP defaults while allowing API backends to be enabled for testing.

Default behavior:

  • meshtastic.enabled=true selects the Meshtastic UDP Device Bridge Channel through meshtastic.uc.
  • meshcore.enabled=true selects the MeshCore UDP Device Bridge Channel through meshcore.uc.
  • APRS is independent and is enabled through APRS config.
  • API backends are not selected unless explicitly requested.
  • Only one backend per bridge family should be active at a time.

MeshIP (AREDN) Bridge

This is the native AREDN mesh transport used for AREDN-to-AREDN routing and MeshIP messaging.

Bridge channel: All AREDN channels use MeshIP
Backend module: meship.uc
Transport: MeshIP (native AREDN UDP/IP routing)
Port: 4404

MeshIP is enabled by default and requires no external hardware—it uses the native AREDN mesh routing. Your Crow node is a full participant in the AREDN mesh.

Configuration

Basic configuration:

{
  "meship": {}
}

Client vs. Gateway Mode:

  • Client mode (default, "bridge": false): Your node receives messages from other AREDN nodes but does not forward between separate AREDN meshes.
  • Gateway mode ("bridge": true): Your node forwards messages between connected AREDN networks (useful for split-mesh bridges or multi-radio gateways).
{
  "meship": {
    "bridge": true
  }
}

Restart Crow to apply changes:

/etc/init.d/crow restart

Channel Binding

All channels automatically use MeshIP for AREDN routing. You do not need to explicitly bind MeshIP to channels—it is the default transport layer for all messages on your AREDN node.

You can bridge other networks into AREDN: Meshtastic, MeshCore, and APRS traffic can be routed into AREDN channels through their respective bridge configurations (see Meshtastic UDP Bridge, MeshCore UDP Bridge, and APRS Backend).


Meshtastic UDP Bridge

This is the original Meshtastic backend and remains the default compatibility path.

Bridge channel: Meshtastic UDP Device Bridge Channel
Backend module: meshtastic.uc
Transport: UDP/multicast
Port: 4403

Use it when you want Crow to behave like the original UDP Meshtastic bridge.

{
  "meshtastic": {
    "enabled": true
  }
}

Expected selector log:

meshtastic_backend: selected udp backend

MeshCore UDP Bridge

This is the original MeshCore backend and remains the default compatibility path.

Bridge channel: MeshCore UDP Device Bridge Channel
Backend module: meshcore.uc
Transport: UDP/multicast
Port: 4402

Use it when you want Crow to behave like the original UDP MeshCore bridge.

{
  "meshcore": {
    "enabled": true
  }
}

Expected selector log:

meshcore_backend: selected udp backend

APRS Backend

APRS is independent of the Meshtastic and MeshCore backend selectors. Configure APRS separately using the APRS/KISS/APRS-IS settings for the deployed build.

Bridge channel: APRS Backend Channel
Backend: APRS/KISS/APRS-IS config
Transport: APRS-IS, KISS TCP, or local TNC depending on deployment

Example placeholder shape:

{
  "aprs": {
    "enabled": true
  }
}

Operator notes:

  • APRS should continue to work whether Meshtastic/MeshCore are using UDP or API backends.
  • APRS should be included in regression tests after changing LoRa backend selection.
  • Do not mix APRS channel behavior with Meshtastic/MeshCore backend selection; they are separate layers.

See also: APRS Bridge.

Experimental: Meshtastic API Backend

This is the experimental Meshtastic TCP Port-API backend.

Backend module: meshtastic_API.uc
Transport: TCP Port-API
Default Port-API port: 4403
Status: experimental / opt-in
Discovery: read-only runtime channel discovery

Use it only when deliberately testing the TCP API path.

{
  "meshtastic": {
    "enabled": false
  },
  "meshtastic_api": {
    "enabled": true,
    "host": "192.168.4.1",
    "port": 4403,
    "channel_discovery": true,
    "channel_sync": "read_only",
    "channel_refresh_seconds": 600
  }
}

Replace 192.168.4.1 with the Meshtastic node IP.

Expected logs:

meshtastic_backend: selected tcp-port-api backend
meshtastic_API: connected tcp-port-api 192.168.4.1:4403
meshtastic_API: config request sent id=... reason=connect

Important Meshtastic API notes:

  • channel_discovery is disabled by default.
  • channel_sync currently supports off or read_only only.
  • Read-only discovery does not write Crow config files.
  • Read-only discovery does not push channel configuration back to the radio.
  • Raw PSKs must not be logged.
  • Do not run Meshtastic UDP and Meshtastic API at the same time unless explicitly testing selector failure handling.

Alternative explicit selector form:

{
  "meshtastic": {
    "enabled": true,
    "backend": "api"
  },
  "meshtastic_api": {
    "enabled": true,
    "host": "192.168.4.1",
    "port": 4403
  }
}

Accepted API selector values:

api
tcp-api
port-api

For field testing, the clearer and safer pattern is still to set meshtastic.enabled=false and meshtastic_api.enabled=true.

Experimental: MeshCore TCP API Backend with Auto-Discovery

This is the experimental MeshCore TCP API backend.

Backend module: meshcore_tcp_api.uc
Transport: TCP API
Status: experimental / opt-in
Discovery: companion/API discovery where supported by the backend

Use it only when deliberately testing the TCP API path.

{
  "meshcore": {
    "enabled": false
  },
  "meshcore_tcp_api": {
    "enabled": true,
    "host": "127.0.0.1",
    "port": 4403
  }
}

Use 127.0.0.1 when the MeshCore companion/API service is on the same node. Use the service IP if it is reachable over the network.

Expected log:

meshcore_backend: selected tcp-api backend

Validation command:

logread -f | grep -Ei 'crow|meshcore_backend|meshcore_tcp_api|meshcore'

Important MeshCore API notes:

  • MeshCore UDP should be disabled while testing MeshCore TCP API.
  • The TCP API backend should fail/reconnect cleanly if the service is unavailable.
  • Do not run MeshCore UDP and MeshCore TCP API at the same time unless explicitly testing selector failure handling.

Alternative explicit selector form:

{
  "meshcore": {
    "enabled": true,
    "backend": "api"
  },
  "meshcore_tcp_api": {
    "enabled": true,
    "host": "127.0.0.1",
    "port": 4403
  }
}

Accepted API selector values:

api
tcp-api
companion-api

For field testing, the clearer and safer pattern is still to set meshcore.enabled=false and meshcore_tcp_api.enabled=true.

Joining channels

After the backend/bridge setup is correct, configure or join channels.

Channels determine where messages are allowed to route. Backends determine how Crow talks to each radio/transport.

Join by command

If the running build supports slash commands, use the channel join command from chat/UI:

/join #channel-name key=passphrase

For MeshCore group/channel testing, a slot-based group may need to be mapped before messages can route to a Crow channel.

Manual channel config pattern

A Crow channel entry normally needs enough information to identify:

  • channel name;
  • namekey;
  • symmetric key;
  • any Meshtastic or MeshCore hash/index mapping used by the backend.

Example conceptual channel record:

{
  "name": "AREDN-Local",
  "namekey": "AREDN-Local <base64-key>",
  "access_control": {
    "require_callsign": true,
    "allow": ["KJ6DZB", "W6*"],
    "deny": []
  }
}

Exact channel object shape should follow the current Crow config schema in the deployed build.

Meshtastic API discovered channels

When meshtastic_api.channel_discovery=true, discovered channels are runtime-only for now.

The backend extracts:

  • channel index;
  • channel name;
  • PSK bytes;
  • runtime namekey form.

Current limits:

  • discovered channels are not written to config;
  • discovered channels do not automatically overwrite operator-managed channels;
  • discovered channels do not push changes back to the Meshtastic radio;
  • raw PSKs are not logged.

Use discovery to verify the radio's channel state, then deliberately add or map channels in Crow config when needed.

Validation

Restart Crow

After changing backend or channel configuration, restart Crow via SSH:

/etc/init.d/crow restart

Or from the Crow UI/chat:

/restart

Check Crow State and Logs

Get a summary of Crow's current state and backend selection:

/debug

This command prints:

  • Current Crow version and configuration status
  • Selected backends (UDP vs. API) for each family
  • Active APRS backends and their connection status
  • MeshCore/Meshtastic connectivity state
  • Recent log lines (last 50 lines)

Watch Live Logs

Stream logs from the SSH console:

logread -f | grep -Ei 'crow|meshtastic_backend|meshcore_backend|meshtastic_API|meshcore_tcp_api|meship|aprs'

Expected Backend Selection

When UDP backends are active (default):

meshtastic_backend: selected udp backend
meshcore_backend: selected udp backend

When testing API backends:

meshtastic_backend: selected tcp-port-api backend
meshcore_backend: selected tcp-api backend

Validation Checklist

  1. Crow restarts cleanly/restart completes, no crashes in logs.
  2. Backend selection is correct/debug shows intended UDP or API backends selected.
  3. UDP defaults are preserved — Legacy meshtastic / meshcore blocks use UDP, not API.
  4. API backends connect or fail cleanly — Logs show connection attempts, not silent failures.
  5. MeshIP routing is active — Messages route through AREDN mesh without errors.
  6. APRS state is expected/backends lists correct APRS backends and connection status.
  7. Strict Gatekeeper filters correctly — Bridged LoRa traffic is tagged and gated as expected.
  8. Joined channels route — Messages appear on expected channels without duplication.
  9. No raw PSKs in logs — Verify sensitive keys are not printed (check /debug output).
  10. Discovery is read-only/cmd discover lists channels but does not modify persistent config.

Quick mode examples

Both legacy UDP backends:

{
  "meshtastic": { "enabled": true },
  "meshcore": { "enabled": true }
}

Meshtastic API + MeshCore UDP:

{
  "meshtastic": { "enabled": false },
  "meshtastic_api": {
    "enabled": true,
    "host": "192.168.4.1",
    "port": 4403,
    "channel_discovery": true,
    "channel_sync": "read_only"
  },
  "meshcore": { "enabled": true }
}

Meshtastic UDP + MeshCore API:

{
  "meshtastic": { "enabled": true },
  "meshcore": { "enabled": false },
  "meshcore_tcp_api": {
    "enabled": true,
    "host": "127.0.0.1",
    "port": 4403
  }
}

Both API backends:

{
  "meshtastic": { "enabled": false },
  "meshtastic_api": {
    "enabled": true,
    "host": "192.168.4.1",
    "port": 4403,
    "channel_discovery": true,
    "channel_sync": "read_only"
  },
  "meshcore": { "enabled": false },
  "meshcore_tcp_api": {
    "enabled": true,
    "host": "127.0.0.1",
    "port": 4403
  }
}

Safety notes

  • Backend setup comes before channel joining.
  • The default bridge channels are the Meshtastic UDP Device Bridge Channel, MeshCore UDP Device Bridge Channel, and APRS Backend Channel.
  • UDP remains the compatibility default for Meshtastic and MeshCore.
  • API backends are experimental until field validation passes.
  • Only one backend per transport family should be active.
  • Do not push channel config to radios until an explicit write-sync phase is designed and tested.

Crow Wiki

Pages

Markdown files

  • APRS.md
  • Backend-Selection-and-Deployment.md
  • Change-Log.md
  • Command-Reference.md
  • Configuration.md
  • Configuring-Channels.md
  • Home.md
  • LoRa-Gateway-Tags.md
  • Meshtastic-API.md
  • Memory-Use.md
  • Strict-Gatekeeper.md
  • USB-Storage.md
  • Winlink.md
  • _Sidebar.md

Maintenance

  • Keep every .md wiki page linked here.
  • Keep Home.md and _Sidebar.md in sync.
  • When a wiki page is removed, remove it from both the Home page inventory and this sidebar.

Clone this wiki locally