3 Commits
7 changed files with 40 additions and 21 deletions

No files matched your search

+3 -6
View File
@@ -13,13 +13,10 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Clone donglora (sibling dependency)
uses: actions/checkout@v4
with:
repository: swaits/donglora
path: ../donglora
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libudev-dev
- uses: dtolnay/rust-toolchain@master
with:
+20
View File
@@ -1,5 +1,25 @@
# Changelog
## [0.2.3] - 2026-04-06
### Changed
- README: clarify that the bridge relays raw LoRa packets and works with any
protocol (Meshtastic, MeshCore, etc.) simultaneously.
## [0.2.2] - 2026-04-06
### Fixed
- TUI now fits in 80-column terminals (was 86).
## [0.2.1] - 2026-04-06
### Fixed
- CI: removed stale sibling-clone step, added `libudev-dev` dependency,
upgraded `actions/checkout` to v5 (Node.js 24).
## [0.2.0] - 2026-04-06
### Added
Generated
+1 -1
View File
@@ -906,7 +906,7 @@ dependencies = [
[[package]]
name = "donglora-bridge"
version = "0.2.0"
version = "0.2.2"
dependencies = [
"anyhow",
"blake3",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "donglora-bridge"
version = "0.2.0"
version = "0.2.3"
edition = "2024"
authors = ["Stephen Waits <steve@waits.net>"]
license = "MIT"
+11 -8
View File
@@ -4,16 +4,19 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
![Rust](https://img.shields.io/badge/rust-1.94.1%2B-orange)
**donglora-bridge** connects LoRa radios to the internet so packets heard by one
radio can be retransmitted by another radio anywhere in the world.
**donglora-bridge** relays raw LoRa packets over the internet. Every packet your
radio hears is forwarded to every other bridge running the same passphrase, and
their radios retransmit it locally. Because it operates on raw packets, it works
with any protocol built on LoRa --
[Meshtastic](https://meshtastic.org/),
[MeshCore](https://github.com/rocketgithub/meshcore-firmware),
or anything else -- simultaneously and without configuration. If your radio can
hear it, the bridge will relay it.
[LoRa](https://en.wikipedia.org/wiki/LoRa) is a long-range, low-power wireless
protocol used by off-grid mesh networks like
[MeshCore](https://github.com/rocketgithub/meshcore-firmware). A single LoRa
radio might cover a few kilometers. This bridge removes that limit: any packet
your radio hears gets relayed over the internet to every other bridge running the
same passphrase, and their radios retransmit it locally. The result is a single
mesh network across a larger geographic area.
modulation used by off-grid mesh networks. A single radio might cover a few
kilometers. This bridge removes that limit, extending a local LoRa network
across a larger geographic area.
There is no central server. Bridges discover each other automatically using the
[Mainline DHT](https://en.wikipedia.org/wiki/Mainline_DHT) and communicate
+1 -2
View File
@@ -99,8 +99,7 @@ fn connect_and_run(
} else if let Ok(c) = donglora_client::connect_mux_auto(timeout) {
(c, "mux".to_string())
} else {
let port_path = donglora_client::find_port()
.ok_or_else(|| anyhow::anyhow!("no mux or USB dongle found"))?;
let port_path = donglora_client::find_port().ok_or_else(|| anyhow::anyhow!("no mux or USB dongle found"))?;
info!("no mux found, connecting to serial port {port_path}");
let c = donglora_client::connect(Some(&port_path), timeout)?;
(c, shorten_path(&port_path))
+3 -3
View File
@@ -245,8 +245,8 @@ fn draw_ui(
series: &TimeSeries,
) {
// Minimum terminal size for the 3-column layout.
if area.width < 86 || area.height < 12 {
let msg = format!("Terminal too small ({}x{}), need 86x12+", area.width, area.height);
if area.width < 80 || area.height < 12 {
let msg = format!("Terminal too small ({}x{}), need 80x12+", area.width, area.height);
frame.render_widget(
Paragraph::new(msg).alignment(Alignment::Center).style(Style::default().fg(C_RATE_DROP)),
area,
@@ -266,7 +266,7 @@ fn draw_ui(
// Packet log columns: Age=5 Hash=8 RF=4 Net=4 Size=6 RSSI=6 SNR=5 Act=5 = 43 + 2 border + 1 pad = 46
let cols = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Length(30), Constraint::Length(46), Constraint::Min(10)])
.constraints([Constraint::Length(30), Constraint::Length(46), Constraint::Min(4)])
.split(rows[1]);
// Left column: Network, Radio, Stats stacked.