-
Notifications
You must be signed in to change notification settings - Fork 0
MeshCore
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.
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/ttyACM0or/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.
Add or edit the top-level configuration in /usr/local/crow/crow.conf.override.
Restart Crow after changing configuration.
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.
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.
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.
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.
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
0x83message-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
Restart Crow:
/etc/init.d/crow restartFor TCP, confirm the MeshCore endpoint is reachable:
nc -zv 192.168.4.1 4403Check 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.
Last hardware validation: 2026-08-25 on KJ6DZB-WSB-hub5 (AREDN 4.26.7.0).
- Source:
main, commit4eea321. - 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, andkmod-usb3). - AREDN's minimal image omits
stty, so Crow's packaged staticcrow-rawttyhelper applies persistent 115200/raw termios settings. This was verified independently before Crow was restarted. - Crow selects the direct serial backend, opens
/dev/ttyACM0, sendsCMD_APP_START, and receivesRESP_SELF_INFOfrom the radio, identified asKJ6DZB-Crow. -
CMD_GET_CHANNELdiscovery was verified on slots 0–7. The radio currently reports only thePublicgroup 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
mainintegration 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.jsWhen 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.
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.
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.
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.

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.
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.keyTo 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.shAssuming everything goes well, the bridge will run as a service after reboot.
- Configuration - MeshCore bridge configuration.
- Configuring Channels - channel setup and backend selection.
-
Commands -
/cmd discover,/cmd info, and/join. - Strict Gatekeeper - callsign and access-control behavior.
- Home
- Change Log
- Configuration
- Configuring Channels
- MeshCore
- Backend Selection and Test Deployment
- Command Reference
- APRS Bridge
- LoRa Gateway Tags
- Meshtastic API Backend
- Memory Use
- Strict Gatekeeper
- Winlink
- USB Storage
APRS.mdBackend-Selection-and-Deployment.mdChange-Log.mdCommand-Reference.mdConfiguration.mdConfiguring-Channels.mdMeshCore.mdHome.mdLoRa-Gateway-Tags.mdMeshtastic-API.mdMemory-Use.mdStrict-Gatekeeper.mdUSB-Storage.mdWinlink.md_Sidebar.md
- Keep every
.mdwiki page linked here. - Keep
Home.mdand_Sidebar.mdin sync. - When a wiki page is removed, remove it from both the Home page inventory and this sidebar.