Skip to content
Builder Bob edited this page Aug 25, 2026 · 24 revisions

MeshCore Bridge

You should only enable the MeshCore bridge if you have an appropriate MeshCore device available to your Crow node, either over the network or attached by USB.

MeshCore Companion API

For current Crow builds, the recommended MeshCore integration is the MeshCore Companion binary API. Crow can use the same Companion message backend over:

  • TCP to a network-reachable MeshCore endpoint, normally port 4403.
  • USB serial through /dev/ttyACM0 or /dev/ttyUSB0.

This is a binary framed protocol, not a line-oriented command console. Crow sends the Companion startup frame, receives device self-info, drains queued messages after 0x83 message-waiting notifications, and sends text through the same backend.

KISS is not the MeshCore Companion protocol. Crow's kiss_tcp mode is APRS/AX.25 support and should not be used for MeshCore Companion traffic.

Configure Crow

Add or edit the top-level configuration in /usr/local/crow/crow.conf.override. Restart Crow after changing configuration.

TCP Companion API

Use TCP when the Companion API is reachable over the network:

{
  "meshcore": { "backend": "tcp" },
  "meshcore_tcp_api": {
    "enabled": true,
    "host": "192.168.4.1",
    "port": 4403,
    "max_pending_rx": 4,
    "channel_discovery": true,
    "channel_refresh_seconds": 600
  }
}

Use the MeshCore device or Companion API bridge IP for host, not the Crow node IP. The default Companion TCP port is 4403; do not use Crow's WebSocket/UI port for this setting.

USB serial Companion API

Use serial when the MeshCore node is physically attached to the Crow host:

{
  "meshcore": { "backend": "serial" },
  "meshcore_serial_api": {
    "enabled": true,
    "device": "/dev/ttyACM0",
    "baud": 115200,
    "app_start_profile": "crow_zeros",
    "max_pending_rx": 4,
    "channel_discovery": true,
    "channel_refresh_seconds": 600
  }
}

/dev/ttyUSB0 is also supported. meshcore_usb_api is accepted as an alias for meshcore_serial_api.

TCP is preferred when TCP and serial are both enabled without an explicit selector. Set meshcore.backend to serial to force USB.

Backend selector values

Accepted explicit selectors are:

TCP:   api, tcp, tcp-api, companion-api
USB:   serial, serial-api, usb, usb-api
UDP:   udp

A channel entry by itself does not enable a MeshCore backend; one of the transport configurations above is also required.

Public channel and custom channels

The built-in MeshCore public channel is:

MeshCore izOH6cXN6mrJ5e26oRXNcg==

It uses MeshCore channel slot 0 and is created automatically by Crow. To use a custom MeshCore channel, configure the same name/key in Crow and MeshCore. Enable channel_discovery to inspect slots on the radio.

If a custom slot cannot be resolved from discovery, provide an optional map:

{
  "meshcore_tcp_api": {
    "enabled": true,
    "host": "192.168.4.1",
    "channel_slots": {
      "MeshTalk AQ==": 2
    }
  }
}

For USB serial, use the same channel mapping under meshcore_serial_api.

Transmit and receive

The TCP and USB serial paths share the same Companion TX/RX implementation.

Crow receives:

  • direct messages delivered to the connected MeshCore node;
  • public and custom channel messages from mapped MeshCore slots;
  • queued messages drained after 0x83 message-waiting notifications.

Crow sends:

  • channel text with Companion command 0x03;
  • no direct (one-to-one) text yet. Crow receives direct messages, but rejects outbound direct messages until it can safely synchronize the radio's contact and path tables.

Useful status counters include:

pending_rx
message_waiting
sync_requests
no_more_messages
outbound_group_sent
outbound_group_rejected
outbound_confirmed
radio_errors

Verify setup

Restart Crow:

/etc/init.d/crow restart

For TCP, confirm the MeshCore endpoint is reachable:

nc -zv 192.168.4.1 4403

Check startup logs:

logread | grep -E 'meshcore_backend|meshcore_tcp_api|meshcore_serial_api'

Expected startup output includes selected tcp backend or selected serial backend, followed by a successful Companion handshake.

Send a unique message from another MeshCore node on the public channel. The message should appear in Crow. Then send a message from Crow on the public channel and verify that a second MeshCore node receives it.

Hardware validation status

Last hardware validation: 2026-08-25 on KJ6DZB-WSB-hub5 (AREDN 4.26.7.0).

  • Source: main, commit 4eea321.
  • The attached RAK USB Companion radio enumerates as a RAKwireless WisCore RAK4631 (239a:8029) at /dev/ttyACM0.
  • Hub5 required the matching USB host/CDC drivers (kmod-usb2, kmod-usb-acm, kmod-usb-dwc3, kmod-usb-dwc3-qcom, and kmod-usb3).
  • AREDN's minimal image omits stty, so Crow's packaged static crow-rawtty helper applies persistent 115200/raw termios settings. This was verified independently before Crow was restarted.
  • Crow selects the direct serial backend, opens /dev/ttyACM0, sends CMD_APP_START, and receives RESP_SELF_INFO from the radio, identified as KJ6DZB-Crow.
  • CMD_GET_CHANNEL discovery was verified on slots 0–7. The radio currently reports only the Public group in slot 0; no matching configured Crow group channel was found or imported automatically.
  • Host-side protocol tests passed: serial Companion tests (57), TCP Companion tests (51), backend-selection checks, and router/gatekeeper matrix checks.
  • The final main integration was redeployed to Hub5 and repeated the USB Companion handshake successfully before publication.

Group receive, group transmit, and over-air delivery are still pending. Before enabling transmit, explicitly configure the same group name/key in both Crow and the radio, then bind Crow's tx_channel_index to the discovered radio slot. Crow deliberately does not persist a key discovered from the radio or select a transmit channel automatically. Direct messages and GPS were not tested in this validation.

For developer-level protocol tests, see the main repository docs and run:

node tests/run_meshcore_tcp_api_tests.js

Channel discovery

When channel_discovery is enabled, Crow queries MeshCore channel slots with CMD_GET_CHANNEL (0x1F) after startup and on the refresh timer.

Discovery is runtime-only. It helps Crow resolve MeshCore slots and inspect the radio's channel state, but it does not persist channel secrets or overwrite operator-managed configuration.

Once a channel is available, join it with:

/join #TacNet key=your-passphrase

See Commands for command details and Configuring Channels for channel setup.

Legacy MeshCore2Net setup

The older MeshCore2Net/UDP path remains available for deployments that already use it. New installs should prefer the Companion TCP or USB serial backend above.

Firmware

Building an AREDN to MeshCore hardware bridge is more involved than the Meshtastic bridge. By default, MeshCore does not provide Ethernet access, but the official firmware can send and receive packets through the serial port on a MeshCore node. See https://github.com/meshcore-dev/MeshCore.

Hardware

These instructions use the WisBlock system: the WisBlock Base (RAK19007) and the WisBlock Core (RAK4631). This device has a serial port available and is powered and programmed over USB. A Raspberry Pi can support remote programming and configuration over USB, plus serial packet forwarding.

MeshCoreBridge

The picture above shows the Raspberry Pi connected to the WisBlock boards via a USB cable and 3-wire ribbon serial cable. The PoE HAT allows powering and communicating with the board over a single Ethernet cable.

MeshCore configuration

The MeshCore node must be configured first. The Python tools are available at https://github.com/meshcore-dev/meshcore-cli.

After configuration, retrieve the node's public key:

meshcli -s /dev/ttyACM0 -r get public.key

MeshCore2Net

To copy MeshCore packets between the MeshCore node and the local network, the Raspberry Pi must run bridge software. The historical bridge is https://github.com/kn6plv/MeshCore2Net.

Install NodeJS using the official instructions at https://github.com/nvm-sh/nvm#installing-and-updating, then install the bridge:

cd /root
git clone https://github.com/kn6plv/MeshCore2Net.git
cd MeshCore2Net
./install.sh

Assuming everything goes well, the bridge will run as a service after reboot.

References

Crow Wiki

Pages

Markdown files

  • APRS.md
  • Backend-Selection-and-Deployment.md
  • Change-Log.md
  • Command-Reference.md
  • Configuration.md
  • Configuring-Channels.md
  • MeshCore.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