Full Code of OpenMANET/docs for AI

main dec70a268ed9 cached
28 files
80.2 KB
23.1k tokens
1 requests
Download .txt
Repository: OpenMANET/docs
Branch: main
Commit: dec70a268ed9
Files: 28
Total size: 80.2 KB

Directory structure:
gitextract_x8_5kufu/

├── .github/
│   ├── funding.yml
│   └── workflows/
│       └── pages.yml
├── .gitignore
├── README.md
├── docs/
│   ├── .gitignore
│   ├── 404.html
│   ├── Gemfile
│   ├── _config.yml
│   ├── _posts/
│   │   └── 2025-09-11-welcome-to-jekyll.markdown
│   ├── adsb-to-cot.md
│   ├── firmware.md
│   ├── gnss.md
│   ├── hardware/
│   │   ├── halowlink2.md
│   │   ├── heltec.md
│   │   ├── raspberry-pi.md
│   │   └── venice.md
│   ├── hardware.md
│   ├── index.md
│   ├── initial-setup/
│   │   ├── halowlink2.md
│   │   ├── heltec.md
│   │   ├── raspberry-pi.md
│   │   └── venice.md
│   ├── initial-setup.md
│   ├── networking.md
│   ├── openmanetd.md
│   ├── range-testing.md
│   └── troubleshooting.md
└── scripts/
    └── rangetest.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/funding.yml
================================================
buy_me_a_coffee: jeremymcgee

================================================
FILE: .github/workflows/pages.yml
================================================
# Build and deploy Jekyll site from /docs to GitHub Pages (served from root)
name: Deploy Jekyll site to Pages

on:
  push:
    branches: ["main"]
  # run manually from Actions tab
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Ruby (Bundler uses docs/Gemfile)
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.3'
          bundler-cache: true
          cache-version: 0
        env:
          BUNDLE_GEMFILE: docs/Gemfile

      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5

      - name: Build with Jekyll (source=docs → _site at repo root)
        run: bundle exec jekyll build --source docs --destination _site --baseurl "${{ steps.pages.outputs.base_path }}"
        env:
          JEKYLL_ENV: production
          BUNDLE_GEMFILE: docs/Gemfile

      - name: Upload artifact (_site/)
        uses: actions/upload-pages-artifact@v4
        with:
          path: _site/

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

================================================
FILE: .gitignore
================================================
.DS_Store
docs/_site/
docs/.jekyll-cache/
docs/.sass-cache/
vendor/bundle/


================================================
FILE: README.md
================================================
# OpenMANET

**OpenMANET** is a Raspberry Pi–based MANET (Mobile Ad-Hoc Network) radio built on **Wi-Fi HaLow (802.11ah)**. Designed around **Raspberry Pi HATs** and OpenWrt, it supports **802.11s** mesh + **batman-adv**, GPS-driven range testing, and a PTT app, aiming for a rugged, field-ready kit. The project currently targets the **Seeed HaLow** HAT; support for other devices will be added over time. A different BCF raises TX power to ~27 dBm versus Seeed defaults.

## Website & Docs
- 🌐 Website: **[openmanet.net](https://openmanet.net/)**
- 📚 Docs (GitHub Pages): **[openmanet.github.io/docs](https://openmanet.github.io/docs/)**
  - 🧩 Firmware & releases: **[firmware](https://openmanet.github.io/docs/firmware)**
  - 🚀 Initial setup: **[initial-setup.html](https://openmanet.github.io/docs/initial-setup.html)**
  - 🧰 Hardware: **[hardware](https://openmanet.github.io/docs/hardware)**
  - 🕸️ Networking: **[networking](https://openmanet.github.io/docs/networking)**
  - 🛠️ Troubleshooting: **[troubleshooting](https://openmanet.github.io/docs/troubleshooting)**
  - 📡 Range testing: **[range-testing.html](https://openmanet.github.io/docs/range-testing.html)**
  - ✈️ ADS-B to CoT: **[adsb-to-cot](https://openmanet.github.io/docs/adsb-to-cot)**

## Downloads
- 📦 Releases (images): **[github.com/OpenMANET/firmware/releases](https://github.com/OpenMANET/firmware/releases)**

Contributions and issues are welcome!


================================================
FILE: docs/.gitignore
================================================
_site
.sass-cache
.jekyll-cache
.jekyll-metadata
vendor


================================================
FILE: docs/404.html
================================================
---
permalink: /404.html
layout: page
---

<style type="text/css" media="screen">
  .container {
    margin: 10px auto;
    max-width: 600px;
    text-align: center;
  }
  h1 {
    margin: 30px 0;
    font-size: 4em;
    line-height: 1;
    letter-spacing: -1px;
  }
</style>

<div class="container">
  <h1>404</h1>

  <p><strong>Page not found :(</strong></p>
  <p>The requested page could not be found.</p>
</div>


================================================
FILE: docs/Gemfile
================================================
source "https://rubygems.org"
# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
#     bundle exec jekyll serve
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
gem "jekyll", "~> 4.4.1"
# This is the default theme for new Jekyll sites. You may change this to anything you like.
gem "just-the-docs"
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
# gem "github-pages", group: :jekyll_plugins
# If you have any plugins, put them here!
group :jekyll_plugins do
  gem "jekyll-feed", "~> 0.12"
end

# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
# and associated library.
platforms :mingw, :x64_mingw, :mswin, :jruby do
  gem "tzinfo", ">= 1", "< 3"
  gem "tzinfo-data"
end

# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1", :platforms => [:mingw, :x64_mingw, :mswin]

# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
# do not have a Java counterpart.
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]


================================================
FILE: docs/_config.yml
================================================
# Welcome to Jekyll!
#
# This config file sets site-wide values (title, email, description, etc.).
# Restart `bundle exec jekyll serve` after changing this file.

# Site settings
title: OpenMANET
email: info@openmanet.net
description: >-
  OpenMANET is a Raspberry Pi–based MANET radio built on Wi-Fi HaLow (802.11ah).
  Designed around Morse Micro HATs/SDIO boards and OpenWrt, it supports 802.11s
  + batman-adv, GPSD-driven range tests, and a PTT app—aiming for a rugged,
  field-ready kit. A custom BCF enables ~27 dBm TX power vs Seeed defaults.

# If you publish under a custom domain or project pages, set these:
# For a custom domain: url: "https://openmanet.net" and baseurl: ""
# For GitHub project pages: url: "https://<user>.github.io" and baseurl: "/<repo>"
baseurl: "/docs"   # the subpath of your site, e.g. /docs; keep "" if deploying at root of the Pages site
url: ""       # the base hostname & protocol for your site

twitter_username: ""
github_username: "OpenMANET"

# Build settings
theme: just-the-docs
plugins:
  - jekyll-feed

# Just the Docs options (optional; tweak as needed)
just_the_docs:
  search_enabled: true
  heading_anchors: true
color_scheme: dark

================================================
FILE: docs/_posts/2025-09-11-welcome-to-jekyll.markdown
================================================
---
layout: post
title:  "Welcome to Jekyll!"
date:   2025-09-11 14:13:46 -0600
categories: jekyll update
---
You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.

Jekyll requires blog post files to be named according to the following format:

`YEAR-MONTH-DAY-title.MARKUP`

Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.

Jekyll also offers powerful support for code snippets:

{% highlight ruby %}
def print_hi(name)
  puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
{% endhighlight %}

Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].

[jekyll-docs]: https://jekyllrb.com/docs/home
[jekyll-gh]:   https://github.com/jekyll/jekyll
[jekyll-talk]: https://talk.jekyllrb.com/


================================================
FILE: docs/adsb-to-cot.md
================================================
---
layout: default
title: ADS-B to CoT
nav_order: 8
permalink: /adsb-to-cot
description: ADS-B to Cursor on Target gateway using ADSBCOT on OpenMANET images.
---

# ADS-B to CoT

Display Aircraft in TAK — ADS-B feed to TAK Gateway.

ADSBCOT is available for OpenMANET via `opkg`, but it is not installed by default. Once installed and enabled, you can forward aircraft tracks into the Team Awareness Kit (TAK) ecosystem with minimal effort. The integration is intentionally opinionated: it assumes an RTL-SDR–based receiver and multicasts the resulting Cursor on Target (CoT) data across the mesh for TAK clients to consume.

For deeper details, refer to the [official ADSBCOT documentation](https://github.com/snstac/adsbcot).

---

## Features

- Converts ADS-B messages to CoT format for TAK clients.
- Preserves aircraft track, course, speed vectors, and metadata.
- Compatible with ATAK, TAKX, WinTAK, and iTAK.
- Supports multiple ADS-B data aggregators and COTS receivers.
- Accepts over-the-air RF ADS-B via SDR hardware.
- Runs on Python 3.7+ across Windows and Linux.

---

## Getting Started on OpenMANET

1. **Install ADSBCOT**
   Install via LuCI (System -> Software -> Update lists -> search `adsbtocot` -> Install) or CLI:

   ```bash
   opkg update
   opkg install adsbtocot
   ```

   If using an older `adsbtocot` package revision that does not pull crypto dependencies automatically:

   ```bash
   opkg install python3-cryptography
   ```

2. **Connect the SDR**
   Plug an RTL-SDR dongle into your Raspberry Pi (USB 3 preferred).

3. **Enable and start services**
   ADS-B to CoT relies on two OpenWrt services:
   - `dump1090` (collects ADS-B frames from SDR)
   - `adsbcot` (converts ADS-B feed to CoT)

   Enable via OpenWrt GUI (System -> Startup) or CLI:

   ```bash
   /etc/init.d/dump1090 enable
   /etc/init.d/dump1090 start
   /etc/init.d/adsbcot enable
   /etc/init.d/adsbcot start
   ```

4. **Verify service state**

   ```bash
   which adsbcot
   pgrep -af "adsbcot|dump1090"
   logread -e adsbcot | tail -n 40
   ```

5. **Confirm in TAK**
   Open ATAK/WinTAK/iTAK and verify aircraft CoT markers are appearing.


<img src="pics/adsb/rtl.jpeg" alt="RTL-SDR dongle connected for ADS-B capture" width="360" />

---


================================================
FILE: docs/firmware.md
================================================
---
layout: default
title: Firmware & Releases
nav_order: 2
permalink: /firmware
description: Firmware download guidance, naming conventions, and notable changes in recent OpenMANET releases.
---

# Firmware & Releases

Firmware images are published on GitHub: [OpenMANET Firmware Releases](https://github.com/OpenMANET/firmware/releases)

This page covers how to choose the correct image and summarizes notable changes in the `1.6.x` line.

---

## Choosing the Right Image

OpenMANET firmware filenames include the information you need to select the correct image:

- SBC/target (example: `rpi4`, `rpi3`)
- Morse Micro chipset family (example: `mm6108`, `mm8108`)
- HaLow interface (example: `spi`, `sdio`)

> **Important:** Select your firmware downloads carefully. If you are using a Seeed Studio HaLow board, you typically want an image with `spi` in the name.

### HaLow Interface Guidance (SPI vs SDIO)

- `spi` images are intended for SPI-based HaLow HATs (most commonly the Seeed WM1302 + Wio-WM6108 setups).
- `sdio` images are intended for SDIO-based HaLow modules (for example Silex or Alfa SDIO boards).

> Note: SDIO images can work across different SDIO boards, but the board configuration file (BCF) must match your specific radio/module. The default BCF is tuned for an Alfa board; for other SDIO boards you will need to obtain the correct BCF from the manufacturer and apply it.

### SBC Target Mapping

Use this as a quick guide for the `rpiX` part of the filename:

| SBC | Use firmware with |
|-----|-------------------|
| Raspberry Pi 4 / CM4 | `rpi4` |
| Raspberry Pi 3B | `rpi3` |
| Raspberry Pi Zero 2 W (Pi2W) | `rpi3` |

---

## Image Type: `sysupgrade`

OpenMANET release assets are published as `sysupgrade` images (for example: `...-squashfs-sysupgrade.img.gz`).

- You can use these images for upgrades from within OpenWrt (LuCI or `sysupgrade`), and they are also what we publish for flashing to an SD card.
- OpenWrt stores configuration in its writable overlay; changing/rewriting the SD card partition table alone may not remove all prior state. If you are trying to completely start over, fully wipe the SD card before re-flashing.

### Starting Over (Recommended SD Card Wipe)

If you want a truly fresh install, we recommend fully formatting the SD card with SD Card Formatter before re-flashing:

- https://www.sdcard.org/downloads/formatter/

In SD Card Formatter, use **Overwrite format**.

---

## Notable Changes (1.6.x)

- OpenWrt `24.10` base
- Linux kernel `6.6.104`
- `mac80211` `6.12.6` (backported Wi‑Fi drivers)
- Morse Micro drivers `1.16`
- `openmanetd` (beta) manages low-level configuration and auto addressing
- Expanded filesystem increased to `4GB`
- Morse Micro MM6108 and MM8108 drivers enabled on all targets
- Built-in Wi‑Fi support on SPI-based nodes (client AP mode)
- Most Wi‑Fi driver kernel modules included by default; additional packages available via `opkg`
- Custom packages migrated to `openmanet/packages` and included via `feed.conf`
- Improved automatic GPSd configuration for Seeed-based nodes

### Networking & Discovery

- mDNS support with reflection for easy mesh-wide discovery
  - Use `https://<hostname>.local` or `ssh root@<hostname>.local`
  - Example: `https://manet01.local`, `ssh root@manet01.local`
  - mDNS resolution only works inside the OpenMANET network and on clients that support mDNS
  - `nslookup` typically will not resolve mDNS names
  - To browse names from a node: `ubus call umdns browse` or `avahi-browse -a`
- `batctl` commands resolve hostnames (not only MAC addresses) once names propagate (can take a few minutes)
- Added a second batman-adv interface for future link bonding

### Setup Workflow Change (Reboot Required)

After the initial setup wizard, the node performs address/DHCP reservation and **must reboot** to apply it. It should reboot automatically; if it does not, reboot it manually.

### Hardware Notes

- A BCF for the Alfa AHM26108D is included, but it is **not loaded by default** and must be applied manually for now.

---

## Addressing Changes

- Fresh flash default address: `10.41.254.1` (was `10.42.0.1` on older releases)
- If your end user device gets a `10.41.x.x` IP, it is on the mesh
- Mesh gateways will always be within `10.41.0.0/24`
- Safe static ranges: `10.41.253.0/24` and `10.41.254.0/24` (auto addressing will not use these ranges)

After the post-wizard reboot, you may need to release/renew DHCP (or reconnect) on your device to obtain a fresh lease.

---

## `openmanetd` (Beta)

`openmanetd` is a new binary that manages low level configurations on OpenMANET:

- Automatic static IP assignment and DHCP range reservation
- Automatic gateway selection (matches gateway announcements with batman-adv best gateway)
- Periodic node announcements for future features (GPS, signal quality, battery life, etc.)

---

## Example Image Names (1.6.0)

Always verify SHA256 checksums on the GitHub release page for the version you are installing. These examples reflect recent `1.6.0` assets:

| Filename | SHA256 |
|----------|--------|
| `openmanet-1.6.0-mm8108-ekh01-spi-squashfs-sysupgrade.img.gz` | `afa1b4a258326d4a01409e4ce99009257421bb6a31a336c071aa09d8dec4a88c` |
| `openmanet-1.6.0-rpi4-mm6108-sdio-squashfs-sysupgrade.img.gz` | `541ef7bea159bf30ae3c23c48280ce81d432269b180bb3738e742c48f31cb87d` |
| `openmanet-1.6.0-rpi4-mm6108-spi-squashfs-sysupgrade.img.gz` | `6c7087520e60b825b32d57dcedcf81d2b539c95f97fc99a9353d7c6ab566243c` |
| `openmanet-1.6.0-rpi3-mm6108-sdio-squashfs-sysupgrade.img.gz` | `f90f1b698a9466bb73f12e18522fbf04db134923761cfee6a273090abc52c5f1` |
| `openmanet-1.6.0-rpi3-mm6108-spi-squashfs-sysupgrade.img.gz` | `f82274fe7c6863901aa0a400af89ecb31acaed429094c3486b499f508b863b87` |


================================================
FILE: docs/gnss.md
================================================
---
layout: default
title: GNSS
nav_order: 9
permalink: /gnss
description: GPS/GNSS integration for position tracking, ATAK CoT messaging, and NMEA streaming to end-user devices.
---

# GNSS

OpenMANET includes integrated GPS/GNSS support for position tracking, location sharing, and ATAK integration. When enabled, nodes automatically share their position across the mesh and stream NMEA data to connected end-user devices (EUDs).

---

## Overview

The GNSS module connected or included with your mesh radio provides:

- **Automatic position tracking** from TPV (Time-Position-Velocity) reports
- **NMEA GGA sentence streaming** to connected EUD clients
- **Position data in mesh announcements** for topology visualization
- **Position data in the API** for extendable functionality

---

## Supported Hardware
**Seeed WM1302 + Wio-WM6108**
The GPS receiver is automatically enabled on OpenMANET hardware.  The device appears at `/dev/ttyACM0`.
Please Note:
- The GPS antenna that comes with the Wio-WM6108 is not that great.  Consider getting a better antenna.
- Do not expect to get any or much signal indoors.  GNSS signals are fairly week unless you have a really good antenna.

Any **u-blox based USB GPS receiver** that works with gpsd should also function with OpenMANET. This may require manual configuration of `/etc/config/gpsd`.

---

## How It Works

### Connection & Monitoring

The GPS service in OpenMANET establishes a persistent connection to the GPS an generates both position reports and can stream NMEA data:

- **Latitude/Longitude** (decimal degrees)
- **Altitude** (meters above sea level)
- **Speed** (meters per second)
- **Track/Course** (degrees)
- **GPS fix mode** (2 = 2D fix, 3 = 3D fix)
- **Timestamp** (UTC)

The service maintains automatic reconnection with exponential backoff (up to 3 attempts) if the GPS daemon becomes unavailable.

### Position Validity

A position is considered valid when:
- GPS fix mode is **2 (2D)** or **3 (3D)**
- Position data has been received from gpsd

Invalid positions (mode 0 or 1) are not shared with EUDs or included in mesh announcements.

### NMEA Streaming to EUDs

When a valid GPS position is available, the service automatically:

1. Converts the position to **NMEA GGA format** (Global Positioning System Fix Data)
2. Queries current DHCP leases to find connected EUD clients
3. Sends the NMEA sentence via UDP to each EUD on **port 4349** (Standard Port in ATAK)

**NMEA GGA Format Example:**
```
$GPGGA,123045.00,3746.4946,N,12225.1640,W,1,08,1.0,50.0,M,0.0,M,,*47
```

This allows tactical applications like ATAK to receive real-time GPS position from the mesh node.

### Position Sharing in Mesh Announcements

When GPS is enabled and a valid position is available, nodes include their position in **node data announcements** sent periodically across the mesh.

This allows:
- Web UI map visualization of node locations
- Topology tracking with geographic context
- Range testing with position logging

The node data worker checks GPS validity before including position data (mode > 1) and logs the current position at the debug level.

---

## Automatic Reconnection

The GPS service includes robust connection handling:

- **Initial connection:** Connects to gpsd on startup
- **Automatic reconnection:** Retries up to **3 times** with a **5-second delay** between attempts
- **Connection loss recovery:** Automatically detects connection drops and re-establishes the session
- **Graceful shutdown:** Closes connections cleanly when the service stops

If the maximum reconnection attempts are reached, the service gives up and logs an error. Restarting `openmanetd` will reset the reconnection counter.

---

## Integration with Other Services

### Range Testing
The built-in range testing script (`/usr/bin/rangetest.sh`) logs GPS position alongside signal strength metrics when GPS is enabled, allowing you to correlate range performance with geographic location.

### Web UI
Future releases may include a map view showing node positions on the topology page when GPS data is available.

---

## Troubleshooting

### GPS not acquiring fix
- Ensure the GPS receiver has a clear view of the sky
- Wait 30-60 seconds for cold start (first fix after power-on)
- Check that gpsd is running: `ps | grep gpsd`
- Verify the GPS device is detected: `ls /dev/ttyUSB*`

### No position data in mesh
- Confirm GPS is enabled in `/etc/openmanet/config.yaml`
- Check logs: `logread | grep gps`
- Verify gpsd connection: `telnet localhost 2947` (type `?WATCH={"enable":true,"json":true}`)
- Restart openmanetd: `/etc/init.d/openmanetd restart`

### EUD not receiving NMEA data
- Confirm the EUD has a DHCP lease: `cat /tmp/dhcp.leases`
- Verify the EUD application is listening for NMEA on the correct port

### ATAK not showing node position
- Verify multicast is working across the mesh
- Ensure ATAK is subscribed to the SA multicast group `239.2.3.1:6969`

---

## Notes

- **NMEA streaming** uses UDP, so delivery is not guaranteed if network conditions are poor
- **CoT multicast** requires multicast routing to be enabled across the mesh (BATMAN-V handles this automatically)
- **Position updates** are sent whenever the GPS service receives a new TPV report with a valid fix
- **Checksums** are automatically calculated for NMEA sentences to ensure data integrity


================================================
FILE: docs/hardware/halowlink2.md
================================================
---
layout: default
title: HaLowLink2
parent: Hardware
nav_order: 2
permalink: /hardware/halowlink2
description: MorseMicro HaLow Link 2 hardware support, specifications, and configuration for OpenMANET.
---

# HaLow Link 2

The HaLow Link 2 is a Wi-Fi HaLow router, access point, and extender made by MorseMicro. It is based on the MediaTek MT7621 SoC with a Morse Micro MM8108 HaLow radio connected via SDIO.

---

## Supported Hardware

| Device | Status | Notes |
|--------|--------|-------|
| MorseMicro HaLow Link 2 | ✅ Tested | MT7621 + MM8108 (SDIO), 2.4 GHz Wi-Fi (MT7603) |

---

## Specifications

| Feature | Details |
|---------|---------|
| SoC | MediaTek MT7621 (MIPS 1004Kc, dual-core, 880 MHz) |
| RAM | 256 MB DDR3 |
| Flash | 32 MB SPI NOR |
| HaLow Radio | Morse Micro MM8108 (SDIO interface) |
| HaLow Band | 915 MHz (US) |
| 2.4 GHz Wi-Fi | MediaTek MT7603 (802.11b/g/n, PCIe) |
| Ethernet | 1x WAN + 1x LAN (Gigabit) |
| Power | USB-C, 5V |
| LEDs | 3x RGB (Wi-Fi, Status, HaLow) |
| Antenna | External SMA (sub-GHz), onboard 2.4 GHz |

---

### Radio Calibration (BCF Files)

The HaLow Link 2 uses the board-specific calibration file `bcf_mm_hl2_ext.bin` for the MM8108 HaLow radio. This BCF is included in the OpenMANET firmware image and is configured automatically.

---

### Default Configuration

| Setting | Value |
|---------|-------|
| HaLow Channel | 28 (916 MHz, 8 MHz BW) |
| 2.4 GHz SSID | openmanet |
| 2.4 GHz Password | openmanet |
| Mesh Routing | batman-adv (BATMAN_V) |

---


================================================
FILE: docs/hardware/heltec.md
================================================
---
layout: default
title: Heltec
parent: Hardware
nav_order: 3
permalink: /hardware/heltec
description: Heltec HT-HD01 V2 hardware support, specifications, and configuration for OpenMANET.
---

# Heltec

OpenMANET supports Heltec Wi-Fi HaLow devices. These are compact, self-contained gateways with integrated HaLow radios.

---

## Supported Hardware

| Device | Status | Notes |
|--------|--------|-------|
| Heltec HT-HD01 V2 | ✅ Tested | MT7628AN + MM6108 (SDIO), onboard 2.4 GHz Wi-Fi |

---

## HT-HD01 V2

The HT-HD01 V2 is a compact Wi-Fi HaLow gateway based on the MediaTek MT7628AN SoC with a Morse Micro MM6108 HaLow radio connected via SDIO.

### Specifications

| Feature | Details |
|---------|---------|
| SoC | MediaTek MT7628AN (MIPS 24KEc, 580 MHz) |
| RAM | 128 MB DDR2 |
| Flash | 32 MB SPI NOR |
| HaLow Radio | Morse Micro MM6108 (SDIO interface) |
| HaLow Band | 915 MHz (US) |
| 2.4 GHz Wi-Fi | MT7628AN built-in (802.11b/g/n) |
| Ethernet | 1x 100 Mbps |
| Power | USB-C, 5V |
| Antenna | External SMA (sub-GHz), onboard 2.4 GHz |

---

### Radio Calibration (BCF Files)

The HT-HD01 V2 requires the board-specific calibration file `bcf_HD01_v2.bin` for the MM6108 HaLow radio. This BCF is included in the OpenMANET firmware image and is configured automatically.

---

### Default Configuration

| Setting | Value |
|---------|-------|
| HaLow Channel | 28 (916 MHz, 8 MHz BW) |
| 2.4 GHz SSID | openmanet |
| 2.4 GHz Password | openmanet |
| 2.4 GHz Encryption | WPA2-PSK |
| Mesh Routing | batman-adv (BATMAN_V) |

---

### Known Limitations

- Only the HT-HD01 V2 is supported. The HT-HD01 V1 is not supported.
- The 2.4 GHz radio operates in AP mode only.
- Ethernet port is 100 Mbps (no gigabit).
- CPU performance is bad to the point where is affects webui load times.

---


================================================
FILE: docs/hardware/raspberry-pi.md
================================================
---
layout: default
title: Raspberry Pi
parent: Hardware
nav_order: 1
permalink: /hardware/raspberry-pi
description: Supported Raspberry Pi models, recommended parts, interface types, and CM4 build options for OpenMANET.
---

# Raspberry Pi

OpenMANET is designed for Raspberry Pi–based devices running OpenWrt, using Wi‑Fi HaLow boards from Morse Micro (MM6108/MM8108).

---

## Supported Hardware (Firmware-Dependent)

### SBC

| Device | Status | Notes |
|--------|--------|-------|
| Raspberry Pi 4 / CM4 | ✅ Tested | Onboard Wi‑Fi works in AP mode on SPI-based builds |
| Raspberry Pi 3B | ✅ Supported | Requires selecting the correct image for your HaLow interface |
| Raspberry Pi Zero 2 W (Pi2W) | ✅ Supported | Uses the `rpi3` firmware images; requires selecting the correct HaLow interface |
| [MCU Zone CM4-4G_Plus](https://www.aliexpress.us/item/3256808130597667.html) | ✅ Supported | For use with the GW16167 (MM8108). mPCIE to m.2 E-Key adapter needed |

### HaLow

| Device | Interface | MM Chipset | Notes |
|--------|-----------|------------|-------|
| Seeed WM1302 + Wio-WM6108 | SPI | 6108 | Common "Seeed board" setup |
| Silex SX-SDMAH | SDIO | 6108 | |
| Alfa AHPI6108E | SDIO | 6108 | |
| Gateworks GW16167 | M.2 E-Key (USB) | MM8108 | m.2 E-Key (USB Signaling) Interface |
---

## Recommended Parts List

| Item | Optional |
|------|----------|
| [Wio WM6108 Wi-Fi HaLow mini PCIe Module](https://www.seeedstudio.com/Wio-WM6108-Wi-Fi-HaLow-mini-PCIe-Module-p-6394.html) | No |
| [WM1302 Pi Hat](https://www.seeedstudio.com/WM1302-Pi-Hat-p-4897.html) | No |
| [External Antenna 868/915 MHz 2 dBi SMA Foldable](https://www.seeedstudio.com/External-Antenna-868-915MHZ-2dBi-SMA-L195mm-Foldable-p-5863.html) | No |
| [UF.L to SMA-K 1.13 mm Cable (120 mm)](https://www.seeedstudio.com/UF-L-SMA-K-1-13-120mm-p-5046.html) | No |
| Raspberry Pi (Pi 4 / CM4 / Pi 3B / Pi2W) | No |
| [21700 Rechargeable Batteries](https://www.amazon.com/dp/B0D3GX96H6?ref_=ppx_hzsearch_conn_dt_b_fed_asin_title_4) | Yes |
| [WaveShare UPS D (21700 version)](https://www.waveshare.com/ups-hat-d.htm) | Yes |
| [Panda PAU06 USB Wi-Fi Adapter](https://www.amazon.com/dp/B00762YNMG?ref_=ppx_hzsearch_conn_dt_b_fed_asin_title_1) | Yes |
| [USB GPS Receiver (u-blox based)](https://www.amazon.com/dp/B01MTU9KTF?ref_=ppx_hzsearch_conn_dt_b_fed_asin_title_1) | Yes |

---

## Board Interface Types: SDIO vs SPI

HaLow modules connect to the Raspberry Pi through different interfaces depending on the board design:

| Interface | Description | Supported on |
|------------|-------------|--------------|
| SDIO | High-speed 4-bit data bus. Offers better throughput and lower latency. | Image-dependent (common on Pi 4 / Pi 3B / CM4) |
| SPI | Serial Peripheral Interface used by some HaLow HATs (for example Seeed boards). Easier to wire but typically slower than SDIO. | Image-dependent (Pi 4 / CM4 / Pi 3B / Pi2W supported on current firmware) |

Notes:  
- Select firmware downloads carefully: the board type, Morse Micro chipset (MM6108 vs MM8108), and interface (SPI vs SDIO) are part of the firmware filename.
- On SDIO-based HaLow builds, onboard Wi‑Fi usually cannot be used due to SDIO bus conflicts.
- On SPI-based HaLow builds, onboard Wi‑Fi can be used for client access (AP mode).
- In general, `spi` images are for SPI-based Seeed HaLow boards; `sdio` images are for SDIO-based modules (for example Silex or Alfa).

---

## Radio Calibration (BCF Files)

HaLow radios use board configuration files (BCF) to set calibration and regulatory parameters. Some cards or devices, may need to acquire the BCF file from the manufacturer, and be copied to each device.

---

## Optional / Advanced Parts

### Compute Module 4 (CM4) Builds

Most Raspberry Pi Compute Module 4 (CM4) carrier boards work with the OpenMANET image.  
A good option is the [WaveShare CM4 Dual ETH WiFi6 Base](https://www.waveshare.com/cm4-dual-eth-wifi6-base.htm), which includes:

- Two Ethernet ports for bridging or mesh uplink  
- An M.2 slot for a standard Wi-Fi card (AX200 or AX210)  
- Full GPIO header and USB ports for power and debug

CM4 boards are ideal for advanced builds, providing better expandability and efficiency for multi-interface mesh nodes.

<img src="../pics/waveshare-cm4-wave/cm4.jpeg" alt="WaveShare CM4 build overview" width="360" />

<img src="../pics/waveshare-cm4-wave/cm4_inside.jpeg" alt="WaveShare CM4 internals" width="360" />

#### Other tested CM4 Carrier Boards

**WaveShare CM4-IO-Base-X**
Version A and B have been tested and work as expected
[CM4-IO-BASE-A](https://www.waveshare.com/product/raspberry-pi/boards-kits/compute-module-4-4s-cat/cm4-io-base-a.htm)
[CM4-IO-BASE-B](https://www.waveshare.com/product/raspberry-pi/boards-kits/compute-module-4-4s-cat/cm4-io-base-b.htm)

Notes:
- A M.2 **M Key** slot for communcation cards
- Full GPIO Header
- Same form factor as a Pi4

**MCUZone CM4_WiFi6**
This is a slightly larger carrier board than the WaveShare boards.

Can be found on [AliExpress](https://www.aliexpress.us/item/3256803637327862.html)

Notes:
- A M.2 **A Key** slot for communications cards.  This is limited to the 2230 form factor.
- Full GPIO Header
- Better for height constrained use cases, but a larger length and width form factor.

---

### M.2 Wi-Fi Cards for CM4 Boards

| Module | Band Support | Current Use |
|---------|--------------|-------------|
| [Intel AX200](https://www.waveshare.com/Wireless-AX200.htm) | 2.4 / 5 GHz Wi-Fi 6 | Works as an access point |
| [Intel AX210](https://www.waveshare.com/Wireless-AX210.htm) | 2.4 / 5 / 6 GHz Wi-Fi 6E | Works as an access point |

These cards currently operate as normal Wi-Fi access points.  

### M.2 Wi-Fi Cards that support 802.11s

| Chipset     | Interface  | 802.11s | Notes |
|-------------|------------|-----|----------------------------|
| Intel AX2XX | M.2 AE Key | no  | Can only operate in AP mode|
| QCNA765     | M.2 E Key  | no  | |
| WCN6856     | M.2 E Key  | no  |  |
| QCA6174     | M.2 E Key  | yes | You can only have one wifi network defined when using 802.11s |
| MT7921      | M.2 E Key  | no  | |
| MT7915DAN   | M.2 BM Key | yes | Dual Band AX; 802.11s mesh works, but stability may vary by kernel/driver |
| MT7916AED   | M.2 AE Key | yes | Dual Band AX; 802.11s mesh works, but stability may vary by kernel/driver |


Work is underway to support bonding of HaLow (915 MHz) and 2.4 GHz links together using BATMAN-V for multi-band uplinks.

---

## Development Notes and Future Plans

- Separate firmware builds for SDIO and SPI boards simplify setup.  
- CM4 carrier boards are increasingly recommended for advanced configurations.  
- Future releases will expand multi-gateway mesh support and improve multicast reliability.  

---


================================================
FILE: docs/hardware/venice.md
================================================
---
layout: default
title: Gateworks Venice
parent: Hardware
nav_order: 4
permalink: /hardware/venice
description: Gateworks Venice hardware support for OpenMANET.
---

# Gateworks Venice
OpenMANET is able to run on Gateworks Venice based SBCs.  The offer many different models, and while OpenMANET should run on all of them, it has only been tested on a few models.

## Supported Hardware

### SBC

| Device      | Status       | Notes |
|-------------|--------------|----------------------------------------------------------------------------------|
| Venice 7100 | ✅ Supported | 1 ethernet and 1 mPCIE full height (for HaLow)                                   |
| Venice 7200 | ✅ Tested    | Dual mPCIE Slots for HaLow and 802.11ax with 2 ethernet.                         |
| Venice 7500 | ✅ Tested    | 1 full size mPCIE (For 802.11ax Wifi) 1 half-size mPCIE (For HaLow), no ethernet |

### HaLow

| Device | Interface | MM Chipset | Notes |
|--------|-----------|------------|-------|
| Gateworks GW16167 | M.2 E-Key (USB) | 8108 | Only tested HaLow card for Gateworks |

### Wi-Fi Cards that support 802.11s

These are the only 2 WiFi cards that have been tested with Gateworks Venice, and are the best option to "do everything".

| Chipset     | Interface  | 802.11s | Notes |
|-------------|------------|---------|----------------------------|
| MT7915DAN   | mPCIE      | yes     | Dual Band AX; Power consumption maximum is 9W, average is 4 – 8W. |
| MT7916AN    | mPCIE      | yes     | Dual Band AX; Power consumption maximum is 9W, average is 4 – 8W. |



================================================
FILE: docs/hardware.md
================================================
---
layout: default
title: Hardware
nav_order: 4
has_children: true
permalink: /hardware
description: Overview of all supported hardware for OpenMANET nodes.
---

# Hardware

OpenMANET runs on Raspberry Pi–based devices paired with Wi‑Fi HaLow (802.11ah) boards from Morse Micro. The tables below provide a quick reference to every supported platform. For detailed setup, parts lists, and build-specific guidance, see the sub-pages.

---

## Supported Single-Board Computers

| Device | Status | Notes |
|--------|--------|-------|
| Raspberry Pi 4 | ✅ Tested | Onboard Wi‑Fi works in AP mode on SPI-based builds |
| Raspberry Pi CM4 | ✅ Tested | Recommended for advanced/multi-interface builds; CM4 carrier boards add M.2, dual Ethernet, etc. |
| Raspberry Pi 3B | ✅ Supported | Requires selecting the correct image for your HaLow interface |
| Raspberry Pi Zero 2 W | ✅ Supported | Uses `rpi3` firmware images; suitable for lightweight/portable nodes |
| HaLowLink2 | ✅ Supported | Integrated HaLow device — see [HaLowLink2](./hardware/halowlink2) |
| Heltec | ✅ Supported  | See [Heltec](./hardware/heltec) for current status |
| Gateworks Venice | ✅ Supported | See [Gateworks Venice](./hardware/venice) |

---

## Supported HaLow Modules

| Device | Interface | MM Chipset | Notes |
|--------|-----------|------------|-------|
| Seeed WM1302 + Wio-WM6108 | SPI | MM6108 | Common "Seeed board" setup; works on all supported Pi variants |
| Silex SX-SDMAH | SDIO | MM6108 | |
| Alfa AHPI6108E | SDIO | MM6108 | |
| Gateworks GW16167 | M.2 E-Key (USB) | MM8108 | |

### Interface Types at a Glance

| Interface | Throughput | Onboard Wi‑Fi | Typical Boards |
|-----------|------------|----------------|----------------|
| SPI | Lower | ✅ Available (AP mode) | Seeed WM1302 HAT |
| SDIO | Higher | ❌ Conflicts with HaLow bus | Silex, Alfa |
| USB | Higher | N/A | Gateworks GW16167 |

---

## Optional Accessories

| Item | Notes |
|------|-------|
| [WaveShare UPS HAT D (21700)](https://www.waveshare.com/ups-hat-d.htm) | Battery-backed power for field use |
| [Panda PAU06 USB Wi-Fi Adapter](https://www.amazon.com/dp/B00762YNMG) | Secondary Wi‑Fi interface (drivers included) |
| [USB GPS Receiver (u-blox)](https://www.amazon.com/dp/B01MTU9KTF) | Required for GNSS/range-testing features |
| [21700 Rechargeable Batteries](https://www.amazon.com/dp/B0D3GX96H6) | For use with WaveShare UPS HAT D |

---

## Sub-pages

| Page | Description |
|------|-------------|
| [Raspberry Pi Variants](./hardware/raspberry-pi) | Detailed parts list, SDIO/SPI reference, CM4 carrier boards, and M.2 Wi‑Fi cards |
| [HaLowLink2](./hardware/halowlink2) | HaLowLink2-specific hardware notes |
| [Heltec](./hardware/heltec) | Heltec hardware support |
| [Gateworks Venice](./hardware/venic) | Gateworks Venice hardware support |


================================================
FILE: docs/index.md
================================================
---
layout: home
title: OpenMANET
nav_order: 1
permalink: /
description: Raspberry Pi–based MANET radio built on Wi-Fi HaLow (802.11ah) with 802.11s + batman-adv, GPS-driven range testing, and PTT support.
---

# OpenMANET Project

**OpenMANET** is a Raspberry Pi–based MANET (Mobile Ad-Hoc Network) radio built on **Wi-Fi HaLow (802.11ah)**.  
It’s designed around Raspberry Pi HATs and currently built specifically for the Seeed HaLow board, with plans to add support for other devices later.

---

## Description
This project aims to provide a flexible HaLow mesh radio using Raspberry Pi hardware and HaLow HATs. A number of optional components are supported; current testing includes the WaveShare 1850 UPS for power and the Panda Wireless PAU06 USB Wi-Fi adapter (additional drivers are included but not yet fully tested).

> Note: On SDIO-based HaLow builds, the onboard Wi‑Fi usually shares the SDIO bus and cannot be used. On SPI-based HaLow builds (for example Seeed boards), onboard Wi‑Fi works for client access (AP mode).

---

## Networking Model
- The mesh exposes a flat `10.41.0.0/16` LAN to end users, even though BATMAN-V may send frames over multiple HaLow hops in the background.
- A single Mesh Gate runs strictly in router mode and NATs the MANET into whatever uplink you connect it to, your upstream network stays separate.
- Every mesh point keeps its own DHCP scope and unique 2.4/5 GHz SSID, so clients can join over Ethernet or Wi-Fi and still get a lease during disconnected operations.
- HaLow radios should share the same SSID/password/channel settings so the mesh forms reliably.
- mDNS (`hostname.local`) works across the mesh (on supported clients), so you can do `https://manet01.local` or `ssh root@manet01.local`.
- If your end user device gets a `10.41.x.x` IP, it is on the mesh.

This design is deliberately opinionated to reduce the amount of networking knowledge you need to bring a cluster online. See the dedicated [Networking](./networking) page for the full breakdown.

See [Firmware & Releases](./firmware) for download guidance, naming conventions, and `1.6.x` release notes.

If you run into issues, start with [Troubleshooting](./troubleshooting) (including the recommended “wipe and re-flash” recovery path).


## Advantages vs. the Seeed image
- Different BCF radio file increases TX power (≈21 dBm → **27 dBm**)  
- Newer build than the Seeed image 
- Includes **802.11s** and **batman-adv** support  

---

## 📡 Range Testing  
Want to see how OpenMANET performs in the field?  
Check out the dedicated **[Wi-Fi HaLow Range Testing](./range-testing.html)** page for detailed results, images, and notes from real-world testing.

---


================================================
FILE: docs/initial-setup/halowlink2.md
================================================
---
layout: default
title: HaLow Link 2 Initial Setup
parent: Initial Setup
nav_order: 2
permalink: /initial-setup/halowlink2
description: How to flash OpenMANET onto the HaLow Link 2
---

# How to flash OpenMANET on HaLow Link 2

![HaLow Link 2](../pics/halowlink2-setup/product.jpg)

---

### 1. Connect to the HaLow Link 2 Wi-Fi network

The SSID and password are on the label on the side of the device.

![Step 1 screenshot](../pics/halowlink2-setup/step01.png)

### 2. Click on properties

![Step 2 screenshot](../pics/halowlink2-setup/step02.png)

### 3. Remember the gateway IP address

![Step 3 screenshot](../pics/halowlink2-setup/step03.png)

### 4. In your browser type in the gateway IP address. If you get this warning hit Advanced

![Step 4 screenshot](../pics/halowlink2-setup/step04.jpg)

### 5. Then click Continue

![Step 5 screenshot](../pics/halowlink2-setup/step05.jpg)

### 6. Enter the root password

The Device Password can be found on the label on the side of the HaLow Link 2.

![Step 6 screenshot](../pics/halowlink2-setup/step06.jpg)

### 7. Click Login

![Step 7 screenshot](../pics/halowlink2-setup/step07.png)

### 8. Click on Advanced Config

![Step 8 screenshot](../pics/halowlink2-setup/step08.jpg)

### 9. Click on System

![Step 9 screenshot](../pics/halowlink2-setup/step09.jpg)

### 10. Click on Backup/Flash Firmware

![Step 10 screenshot](../pics/halowlink2-setup/step10.png)

### 11. Click on Flash Image

![Step 11 screenshot](../pics/halowlink2-setup/step11.png)

### 12. Click Browse

![Step 12 screenshot](../pics/halowlink2-setup/step12.jpg)

### 13. Select the image you want to flash

The latest images can be found at [https://github.com/OpenMANET/firmware/releases](https://github.com/OpenMANET/firmware/releases). Look for the file with `halowlink2` in the filename.

![Step 13 screenshot](../pics/halowlink2-setup/step13.png)

### 14. Click Open

![Step 14 screenshot](../pics/halowlink2-setup/step14.png)

### 15. Click Upload

![Step 15 screenshot](../pics/halowlink2-setup/step15.jpg)

### 16. Wait for the image to be verified

![Step 16 screenshot](../pics/halowlink2-setup/step16.jpg)

### 17. Uncheck "Keep settings and retain config"

![Step 17 screenshot](../pics/halowlink2-setup/step17.png)

### 18. Scroll down and check "Force upgrade"

![Step 18 screenshot](../pics/halowlink2-setup/step18.png)

### 19. Click Continue

This will start the flash. Wait at least 10 minutes and keep the device plugged into power.

![Step 19 screenshot](../pics/halowlink2-setup/step19.png)

### 20. Connect to the openmanet Wi-Fi network

Once flashing is complete, a Wi-Fi network called **openmanet** will appear. The password is `openmanet`.

![Step 20 screenshot](../pics/halowlink2-setup/step20.png)

### 21. Access the OpenMANET web interface

A freshly flashed device can be found at `10.41.254.1`.

![Step 21 screenshot](../pics/halowlink2-setup/step21.png)

### 22. Click Login

There is no password set on a fresh flash, so just click Login.

![Step 22 screenshot](../pics/halowlink2-setup/step22.png)

### 23. Complete the setup wizard

Select your country and finish the device setup.

![Step 23 screenshot](../pics/halowlink2-setup/step23.jpg)


================================================
FILE: docs/initial-setup/heltec.md
================================================
---
layout: default
title: Heltec HT-HD01-V2 Initial Setup
parent: Initial Setup
nav_order: 2
permalink: /initial-setup/heltec
description: How to flash OpenMANET onto the HT-HD01 V2
---

# How to flash OpenMANET onto the HT-HD01 V2

**IMPORTANT**:
V1 and V2 devices look identical except on a V2 device you will find the model name with `V2` printed on the device.  If you load OpenMANET firmware on a V1 device it may not work and you may brick your device.  We are not responsible if you do not check this carefully.

Make absolutely sure you are only flashing a V2 device.

**Please Note**:
The HD01 SOC is much slower than other devices.  The flashing time takes a few minutes.  BE PATIENT.  The WebUI will also operate a bit slower and take longer to load.  This is normal on these devices.

This walkthrough is geared toward a stock flashed HT-HD01 V2.

![HT-HD01 V2](../pics/heltec-setup/product.png)

---

### 1. Connect to the HT-HD01 V2's Wi-Fi network

The default password to the network is `heltec.org`

![Step 1 screenshot](../pics/heltec-setup/step01.png)

### 2. Once connected click on properties

![Step 2 screenshot](../pics/heltec-setup/step02.png)

### 3. You will need the default gateway value

![Step 3 screenshot](../pics/heltec-setup/step03.png)

### 4. In your web browser go to the gateway IP address and login

The default password should be `heltec.org`

![Step 4 screenshot](../pics/heltec-setup/step04.jpg)

### 5. Click on the X in the top right

![Step 5 screenshot](../pics/heltec-setup/step05.jpg)

### 6. Navigate to System > Reset / Flash Firmware

![Step 6 screenshot](../pics/heltec-setup/step06.jpg)

### 7. Click Flash Image

![Step 7 screenshot](../pics/heltec-setup/step07.jpg)

### 8. Click Browse

![Step 8 screenshot](../pics/heltec-setup/step08.jpg)

### 9. Select the bin file you want to flash

**IMPORTANT: You need to be flashing the correct bin for this board. Please double check.**
The image you are looking for will have ht-hd01-v2 in the filename. Images can be found here https://github.com/OpenMANET/firmware/releases

![Step 9 screenshot](../pics/heltec-setup/step09.png)

### 10. Click Open once you have confirmed the correct bin has been selected

![Step 10 screenshot](../pics/heltec-setup/step10.png)

### 11. Click Upload

![Step 11 screenshot](../pics/heltec-setup/step11.jpg)

### 12. Wait as the bin uploads

![Step 12 screenshot](../pics/heltec-setup/step12.jpg)

### 13. Uncheck "Keep settings"

![Step 13 screenshot](../pics/heltec-setup/step13.jpg)

### 13b. **IMPORTANT**
If you are flashing a Heltec HT-HD01-**V2** with OpenMANET for the first time you will get the following warning.
- Uncheck `Keep settings and retain the current configuration`.
- Check `Force Upgrade`.  IT IS ONLY SAFE TO DO THIS IF YOU HAVE AN HT-HD01-**V2**.

![Step 13B screenshot](../pics/heltec-setup/step13b.jpg)

### 14. Click Continue

![Step 14 screenshot](../pics/heltec-setup/step14.jpg)

### 15. Wait for the device to flash and reboot

You will need to wait about 10 minutes until the device has been flashed and booted up. You can tell once it's booted when a Wi-Fi network called **openmanet** appears.

![Step 15 screenshot](../pics/heltec-setup/step15.jpg)

### 16. Connect to the openmanet Wi-Fi network

The password is `openmanet`

![Step 16 screenshot](../pics/heltec-setup/step16.png)

### 17. Log in to the OpenMANET web interface

![Step 17 screenshot](../pics/heltec-setup/step17.png)

### 18. Go through the wizard to configure your device

![Step 18 screenshot](../pics/heltec-setup/step18.png)


================================================
FILE: docs/initial-setup/raspberry-pi.md
================================================
---
layout: default
title: Raspberry Pi
parent: Initial Setup
nav_order: 1
permalink: /initial-setup/raspberry-pi
description: Step-by-step guide to flashing, configuring, and deploying OpenMANET on Raspberry Pi HaLow HATs.
---

# Initial Setup — Raspberry Pi

This page walks you through downloading, flashing, and configuring the OpenMANET image on your Raspberry Pi HaLow HATs, plus initial mesh configuration tips and topology examples.

---

## Setup Steps

1. **Download the latest OpenMANET image**  
   Go to the Releases section: [OpenMANET Firmware Releases](https://github.com/OpenMANET/firmware/releases) and download the image.

2. **Flash the image to an SD card**  
   Use the official Raspberry Pi guide for instructions on flashing the image:  
   [Raspberry Pi Getting Started Guide](https://www.raspberrypi.com/documentation/computers/getting-started.html)

   OpenMANET release assets are published as `sysupgrade` images (`...-squashfs-sysupgrade.img.gz`) and are the images we provide for SD card flashing.

   If you want to completely start over, we recommend fully formatting the SD card with SD Card Formatter before re-flashing (OpenWrt stores config in its writable overlay, and rewriting the partition table alone doesn't always reset everything):
   - https://www.sdcard.org/downloads/formatter/

3. **Initial connection**  
   On a fresh flash, the node boots with a static IP of `10.41.254.1`.  
   Connect your computer directly via Ethernet and set your computer to obtain an IP automatically.  
   Your computer should get an IP address in that range from the node and you will be able to access it at `http://10.41.254.1` in a web browser.  
   The default username is `root`, and the default password is blank.  
   If your computer is connected to WiFi, you can plug the RPi into your Ethernet adapter and still stay connected to the internet at the same time.  
   *Note: after running the initial wizard, you will use the password you set.*

4. **Initial configuration**  
   Follow the wizard to configure the node type (mesh gate vs mesh point) and your radio settings.

   > **Important:** After initial configuration, the node performs address/DHCP reservation and will reboot to apply it. If it does not reboot on its own, reboot it manually.
   >
   > After that reboot, you may need to release/renew DHCP (or simply reconnect) on your end user device so it gets a new lease.

---

## Mesh Gate vs. Mesh Point

When configuring 802.11s with the Seeed HaLow HAT, there are two main node types:

### Mesh Gate
Think of a Mesh Gate as the "hub" of your mesh. It's the point where your next-hop connection (like an upstream internet connection or Starlink Mini) is attached.

- **Router Mode (required)**  
  The Mesh Gate acts as a NAT router. Its Ethernet uplink (`wan`) uses DHCP from whatever upstream network you plug into. Your HaLow mesh and local Wi-Fi AP live on the mesh (`10.41.x.x`).

### Mesh Point
A Mesh Point is a node that connects to the 802.11s mesh. It can bridge its Ethernet or 2.4/5 GHz Wi-Fi interface into the HaLow mesh.  
**Recommendation:** Create a mesh gate node first before creating a mesh point node. This will make it easier to confirm connectivity on the mesh.

If your node does not connect over HaLow, you will not be able to connect without connecting physically.

---

### Mesh SSID/Channel Consistency
For the HaLow mesh to form reliably, every HaLow radio should use the same:
- Network name (SSID / mesh ID)
- Password (if configured)
- Channel number
- Channel bandwidth

If an end user device (EUD) gets a `10.41.x.x` IP, it is on the mesh.

---

## Connecting by Hostname (mDNS)

OpenMANET supports mDNS (`.local`) for easy discovery inside the mesh network. After names propagate, you can connect to a node by hostname instead of IP:

- Web UI: `https://manet01.local`
- SSH: `ssh root@manet01.local`

To list mDNS names from a node, use `ubus call umdns browse` or `avahi-browse -a`. Note that `nslookup` typically will not resolve mDNS names.

---

## Mesh Gate in Router Mode (Topology)

```
           (Optional Upstream Router / Internet)
                         |
                    [ Ethernet ]
                         |
              +------------------------------------+
              |  Mesh Gate (ROUTER / NAT / DHCP/DNS|
              |  LAN = 802.11s mesh subnet         |
              +------------------------------------+
                        ))))))  802.11s  (((((( 
                 ________/         |            \________
                /                  |                       \
       +----------------+   +----------------+      +----------------+
       | Mesh Point A   |   | Mesh Point B   |      | Mesh Point C   |
       | (bridge later) |   | (bridge later) |      | (bridge later) |
       +----------------+   +----------------+      +----------------+
            |     \               |     \                   |     \
        [EUD A]  [WiFi AP]   [EUD B]  [WiFi AP]       [EUD C]  [WiFi AP]
```

**Notes:**
- Mesh Gate supplies DHCP/DNS on the mesh subnet.
- Traffic from mesh NATs to the upstream (if present).
- Works well in disconnected/off-grid scenarios; clients still have local name resolution and services.

---

## GPS Range Testing Script

A range-test script is included in the `scripts` folder. It uses the GPS module listed in the parts list to measure ping, RSSI, and SNR. You can use SCP to transfer the file to the Pi.

```bash
cp scripts/rangetest.sh /root/
chmod +x /root/rangetest.sh
```

It is recommended to run it inside `tmux` so it continues running even if you disconnect.

---


================================================
FILE: docs/initial-setup/venice.md
================================================
---
layout: default
title: Gateworks Venice
parent: Initial Setup
nav_order: 3
permalink: /initial-setup/venice
description: Initial setup guide for Gateworks Venice devices on OpenMANET.
---

# Initial Setup — Gateworks Venice
**Please Note: Setup on Gateworks Venice cards is for advanced users.  We do not provide technical support if you brick your device, and do not take responsibility if you do not follow Gateworks recommendations.**

The image can be installed a few different ways.  If you already have OpenMANET on your Gateworks SBC, you can install it through the Web UI using the update firmware functionality.

### Initial Install on Gateworks SBC
If you have not already installed OpenMANET on a Gateworks SBC you will need a few things to easily install the image for the first time.

Gateworks does provide documentation for [Installing Firmware](https://trac.gateworks.com/wiki/venice/firmware).

After trying several different ways to install the firmware, here is the easiest method.
#### Requirements
- [Gateworks JTAG Programmer](https://trac.gateworks.com/wiki/venice/firmware) (Only needed if you did not buy a full development kit)
- [USB-C Flash Drive](https://www.amazon.com/dp/B09WB2NL8W)
- [USB-C Ethernet Adapter](https://www.amazon.com/dp/B082K62S48) (Only needed for GW7500)
- Software for a Serial interface

**IMPORTANT**
Follow all instructions from Gateworks to [prevent a group loop](https://trac.gateworks.com/wiki/gettingstarted#Power) with your JTAG device

Steps to get a serial console (Linux/MacOS)
1. Connect your JTAG device to a USB port
2. Use [Gateworks Instructions](https://trac.gateworks.com/wiki/jtag_instructions#SerialConsoleAccessonLinux) for Serial Console
3. Copy the OpenMANET squashfs firmware from your host computer to the USB-C Flash drive
4. Plug the USB-C flash drive into the Gateworks SBC
5. Once a `screen` session is setup, plug your USB JTAG device into the Gateworks SBC.
6. Power on the Gateworks SBC
7. You should get information in the `screen` session similar to this

```console
U-Boot 2024.10-00043-g977697bc9710 (May 27 2025 - 21:33:09 +0000)

CPU:   Freescale i.MX8MP[8] rev1.1 1600 MHz (running at 1200 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 20C
Reset cause: POR
Model: Gateworks Venice GW75xx-2x i.MX8MP Development Kit
DRAM:  4 GiB
Core:  257 devices, 30 uclasses, devicetree: separate
WDT:   Started watchdog@30280000 with servicing every 1000ms (60s timeout)
MMC:   FSL_SDHC: 1, FSL_SDHC: 2
Loading Environment from MMC... Reading from MMC(2)... OK
In:    serial@30890000
Out:   serial@30890000
Err:   serial@30890000
SEC0:  RNG instantiated
Net:   No ethernet found.
GSC     : boot watchdog disabled
Thermal protection:enabled at 96C
Hit any key to stop autoboot:  0
```

8. Hit any key to stop the boot process and drop into the uboot terminal.
9. You will enter the follow command into the uboot terminal which will begin copying the firmware from the USB flash drive onto the Gateworks SBC
```
usb start && load usb 0:1 $loadaddr <name of flash image on the USBC Flash Drive> && gzwrite mmc $dev $loadaddr $filesize
```
10. Unplug the SBC from power
11. Plug in a USBC Ethernet Adapter.  Connect the USBC ethernet adapter to your computer with an ethernet cable.
12. Power on the Gateworks SBC.  After the UBoot menu you will see the linux system starting up.
13. Open a browser to http://10.41.254.1 and complete the setup through the WebUI.


================================================
FILE: docs/initial-setup.md
================================================
---
layout: default
title: Initial Setup
nav_order: 3
has_children: true
description: Step-by-step setup guides for all supported OpenMANET devices.
---

# Initial Setup

Select your device platform below for a step-by-step guide to downloading, flashing, and configuring OpenMANET.

| Device | Guide |
|--------|-------|
| Raspberry Pi (4, CM4, 3B, Zero 2 W) | [Raspberry Pi Setup](./initial-setup/raspberry-pi) |
| HaLowLink2 | [HaLowLink2 Setup](./initial-setup/halowlink2) |
| Heltec | [Heltec Setup](./initial-setup/heltec) |


================================================
FILE: docs/networking.md
================================================
---
layout: default
title: Networking
nav_order: 5
permalink: /networking
description: Explains the flat OpenMANET topology, addressing plan, and how mesh gates, mesh points, DHCP, MDNS, and BATMAN-V all fit together.
---

# Networking

OpenMANET purposely ships with an opinionated network design so that anyone—especially folks with limited networking experience—can assemble a working MANET without guesswork. The latest OpenMANET release moves every node onto a single `10.41.0.0/16` space, removes bridge mode from mesh gates, and layers **BATMAN-V** on top of **802.11s** to provide a true MANET. The result is a flat network for end users, even though the mesh is free to create multiple hops in the background.

---

## Flat Mesh Domain for Every Use

**All HaLow radios live in 10.41.0.0/16.** Each mesh point brings up `bat0` with a reserved static address (for example `10.41.113.1`) and bridges it with Ethernet and the 2.4/5 GHz AP (`br-ahwlan`). Mesh gateways are always within `10.41.0.0/24` (commonly `10.41.1.1`).

**Every mesh point runs its own DHCP server.** Sixteen leases are handed out locally per node (`start 351`, `limit 16` by default). Tablets, TAK devices, or laptops plugged in via Ethernet or Wi-Fi still receive an address when the mesh gate is offline.

**The mesh is one broadcast domain.** Because `bat0`, `eth0`, and the local AP ports sit inside the same bridge, clients see a single flat LAN no matter which node they use. This makes service discovery painless and lets multicast applications work across hops.

Example from `/etc/config/network` on a mesh point:

```sh
config device
	option name 'br-ahwlan'
	option type 'bridge'
	list ports 'eth0'
	list ports 'bat0'
```

---

## Addressing (Fresh Flash vs. After Setup)

**Fresh flash address:** a newly flashed node starts at `10.41.254.1`.

**After the initial wizard:** `openmanetd` reconciles addressing by asking other nodes to announce their IP/DHCP ranges, then reserves a static IP (and DHCP range) that is not in use. The node will reboot to apply the reserved settings.

**Client hint:** if your end user device gets a `10.41.x.x` IP, it is on the mesh. After the node reboots post-setup, you may need to release/renew DHCP (or reconnect) so your device gets a fresh lease.

**Safe static ranges:** you can safely assign static IPs within `10.41.253.0/24` and `10.41.254.0/24`. Auto addressing will not use those ranges.

---

## Mesh Gate = Router + NAT

**Router mode is mandatory.** Bridge mode and the HaLow AP wizard were removed in this release. The mesh gate always NATs the mesh into whatever upstream you plug into `eth0` (Starlink, LTE modem, hotel Wi-Fi, etc.).

**MANET vs. uplink separation.** The HaLow/BATMAN side stays on `10.41.0.0/16`. Your uplink continues to use whatever addressing the upstream network provides (DHCP on `wan`). The gate performs NAT and DNS forwarding between the two, keeping the MANET insulated from the outside network.

**Only one mesh gate today.** Multiple gates will return in a future release, but for now run a single router so default routes are predictable. Remember to reboot after running the initial configuration wizard so firewall, BATMAN, and Alfred services all restart cleanly.

---

## Client Access per Mesh Point

**Ethernet or Wi-Fi both work.** Every mesh point exposes `br-ahwlan` over the onboard Ethernet jack and an auxiliary 2.4/5 GHz AP. Pick whichever interface matches your end-user device.

**Unique SSIDs per radio.** Give each node a distinct SSID in the 2.4/5 GHz bands (e.g., `manet01-24G`, `manet02-24G`). That prevents clients from roaming to a distant node when you are diagnosing a specific radio.

**Always-on DHCP.** Because each node serves leases locally, clients retain connectivity even in a disconnected “dark” site where the mesh gate or upstream is unreachable.

**mDNS across the mesh.** OpenMANET supports mDNS reflection so you can reach nodes by name from anywhere on the mesh (on clients that support mDNS): `https://manet01.local` or `ssh root@manet01.local`.

To list mDNS names from a node:
- `ubus call umdns browse`
- `avahi-browse -a`

Note: `nslookup` typically will not resolve mDNS names.

**Hostname-aware BATMAN tools.** `batctl` commands will resolve device hostnames (instead of only MAC addresses) after a few minutes for names to propagate.

---

## BATMAN-V Adds the MANET Brain

**True MANET routing.** BATMAN-V monitors link quality per hop, redistributes neighbors, and reroutes automatically as nodes move. Your clients keep a flat IP experience while the mesh dynamically rebuilds paths.

**Bonding-ready.** Switching from BATMAN_IV to BATMAN_V opens the door to uplink bonding (HaLow + Wi-Fi or multiple USB Ethernet adapters) in future builds.

**Multicast friendly.** New firewall rules plus the BATMAN multicast optimizations improve reliability for TAK, ADSBCOT, and MDNS traffic.

**Second batman-adv interface.** A second batman-adv interface is included for future link bonding work.

---

## Why This Design?

This scheme intentionally hides complexity:

- Flat addressing and MDNS avoid the need for static routes or manual DNS.
- Local DHCP on every mesh point ensures a client-friendly experience even when nodes are disconnected from the mesh gate.
- NAT on the single mesh gate keeps the MANET isolated from whatever upstream you plug into it, ensuring the upstream network does not need any config changes.

Flash **all nodes** when upgrading to the latest OpenMANET so every device shares the same addressing plan and BATMAN-V stack.

---

## Troubleshooting

### See What BATMAN Thinks Is On The Mesh

Use `batctl dc` to view the distributed ARP table. This is a quick way to confirm which nodes/clients are currently visible on the mesh, along with their IPs and “last seen” time (and, after hostname propagation, their hostnames):

```sh
root@manet01:~# batctl dc
[B.A.T.M.A.N. adv 2024.3-openwrt-6, MainIF/MAC: wlan0/2c:c6:82:8a:2b:ca (bat0/9a:c2:84:47:71:98 BATMAN_V)]
Distributed ARP Table (bat0):
          IPv4             MAC        VID   last-seen
 *       10.41.0.1 manet01_br-ahwlan   -1      0:09
 *    10.41.88.231 manet02_br-ahwlan   -1      1:54
 *     10.41.0.111 0e:12:80:92:f7:dc   -1      0:39
 *   10.41.254.229 manet03_br-ahwlan   -1      0:38
```

In the output above, entries ending in `_br-ahwlan` are mesh nodes; entries shown as raw MAC addresses are typically end user devices behind a node.

### Browse mDNS Services

Use `avahi-browse -a` to see mDNS-advertised hostnames and services currently visible on the mesh:

```sh
root@manet01:~# avahi-browse -a
+ br-ahwlan IPv6 manet02                                       _ssh._tcp            local
+ br-ahwlan IPv4 manet03                                       _ssh._tcp            local
+ br-ahwlan IPv4 manet02                                       _ssh._tcp            local
+ br-ahwlan IPv6 manet02                                       _http._tcp           local
+ br-ahwlan IPv4 manet03                                       _http._tcp           local
+ br-ahwlan IPv4 manet02                                       _http._tcp           local
+ br-ahwlan IPv6 manet02 [c6:2a:60:bd:a5:6e]                   _workstation._tcp    local
+ br-ahwlan IPv4 manet03 [b2:95:f1:69:d9:0a]                   _workstation._tcp    local
+ br-ahwlan IPv4 manet03 [b8:27:eb:6c:45:ac]                   _workstation._tcp    local
+ br-ahwlan IPv4 manet02 [c6:2a:60:bd:a5:6e]                   _workstation._tcp    local
+ br-ahwlan IPv6 MacBook Air (3)                               _companion-link._tcp local
+ br-ahwlan IPv4 MacBook Air (3)                               _companion-link._tcp local
+ br-ahwlan IPv6 7A55CB537445@MacBook Air (3)                  _raop._tcp           local
+ br-ahwlan IPv4 7A55CB537445@MacBook Air (3)                  _raop._tcp           local
+ br-ahwlan IPv6 MacBook Air (3)                               _airplay._tcp        local
+ br-ahwlan IPv4 MacBook Air (3)                               _airplay._tcp        local
```

---

## Quick Reference

| Component   | Key Details |
|-------------|-------------|
| Fresh Flash | Node starts at `10.41.254.1` before the wizard |
| Mesh Gate   | Router-only, NAT enabled, static IP in `10.41.0.0/24`, DHCP/DNS for the mesh, WAN via DHCP |
| Mesh Point  | Reserved static `10.41.xxx.1`, local DHCP, bridges `bat0` + `eth0` + local AP |
| Client Link | Connect via Ethernet or unique 2.4/5 GHz SSID on each node |
| Discovery   | mDNS (`hostname.local`) + service announcements across the mesh |
| Routing     | 802.11s + BATMAN-V for MANET resiliency and future uplink bonding |


================================================
FILE: docs/openmanetd.md
================================================
---
layout: default
title: OpenMANETd Daemon
nav_order: 10
permalink: /openmanetd
description: openmanetd is the core management daemon for the OpenMANET mesh network.
---

## Overview

`openmanetd` is the core management daemon for the OpenMANET mesh network. It handles low-level configuration tasks, node discovery, IP address management, and provides both internal mesh communication and an external API for monitoring and control.

### Key Responsibilities

- **Node Discovery**: Publishes and receives mesh node information across the network
- **IP Address Management**: Handles static IP assignment and DHCP address reservations
- **Gateway Management**: Updates gateway routes and manages gateway mode operations
- **Position Tracking**: Distributes GPS position data when enabled
- **API Services**: Provides REST/gRPC API for monitoring mesh status and nodes

---

## Configuration

### Configuration File

The daemon uses a YAML configuration file located at `/etc/openmanetd/config.yml` by default.

### Configuration Structure

Below is the **default** `config.yml` with all available options:

```yaml
# Log level: "debug", "info", "warn", "error" (default: "info")
logLevel: info

# Mesh network interface (default: "br-ahwlan")
meshNetInterface: br-ahwlan

# Database file path (default: "/etc/openmanetd/openmanetd.db")
# DO NOT CHANGE
dbFile: /etc/openmanetd/openmanetd.db

# GNSS/GPS configuration
gnss:
  # Enable GNSS functionality (default: false)
  enable: true

  # External GNSS source configuration
  sendAsExternalGNSSSource:
    # Send position as NMEA sentences (default: false)
    sendAsNMEA: true
    # Send position as Cursor-on-Target (CoT) (default: false)
    sendAsCoT: true

# Alfred configuration
alfred:
  # Alfred mode: "primary" or "secondary" (default: "primary")
  mode: "primary"

  # BATMAN-adv interface (default: "bat0")
  batInterface: "bat0"

  # Alfred socket path (default: "/var/run/alfred.sock")
  socketPath: "/var/run/alfred.sock"

  # Data types to enable
  dataTypes:
    gateway: true          # Gateway announcements (default: true)
    node: true            # Node information (default: true)
    position: true        # GPS position data (default: true)
```

### Configuration Defaults

| Option | Default Value | Description |
|--------|--------------|-------------|
| `logLevel` | `info` | Logging level (debug, info, warn, error) |
| `meshNetInterface` | `br-ahwlan` | Primary mesh network interface |
| `dbFile` | `/etc/openmanetd/openmanetd.db` | SQLite database location |
| `resetDBOnStart` | `false` | Clear database on daemon startup |
| `gnss.enable` | `true` | Enable GNSS/GPS functionality |
| `gnss.sendAsExternalGNSSSource.sendAsNMEA` | `true` | Send position as NMEA sentences |
| `gnss.sendAsExternalGNSSSource.sendAsCoT` | `true` | Send position as CoT messages |
| `alfred.mode` | `primary` | Alfred synchronization mode |
| `alfred.batInterface` | `bat0` | BATMAN-adv interface name |
| `alfred.socketPath` | `/var/run/alfred.sock` | Alfred Unix socket |
| `alfred.dataTypes.gateway` | `true` | Publish gateway information |
| `alfred.dataTypes.node` | `true` | Publish node information |
| `alfred.dataTypes.position` | `true` | Publish GPS positions |

### Hot Reload

The configuration file is watched for changes and automatically reloaded when modified. This allows you to adjust settings without restarting the daemon. Changes are logged to the console:

```
Using config file: /etc/openmanetd/config.yml
```

---

## Protocol Buffer Specifications

OpenMANETd uses Protocol Buffers (protobuf) for two distinct purposes:
1. **Internal Mesh Communication**: Data exchange via ALFRED across the mesh
2. **External API**: REST/gRPC API using ConnectRPC

### Protobuf Repository

The protobuf schema is hosted with Buf Registry:

- Repository: [OpenMANET Buf Schema Registry](https://buf.build/openmanet/protobufs)

### Internal Mesh Messages

These protobuf messages are serialized and distributed across the mesh network using ALFRED.

#### Node Message

Announces node presence, configuration, and network details:

```protobuf
message Node {
  string mac = 1;               // Hardware MAC address
  string hostname = 2;          // Node hostname
  string ipaddr = 3;            // Assigned IP address
  Position position = 4;        // GPS coordinates (optional)
  string uci_dhcp_start = 5;    // DHCP pool start IP
  string uci_dhcp_limit = 6;    // DHCP pool size limit
}
```

**Distribution**: Sent every 60 seconds by all nodes

**Usage Example**:
```go
nodeData := &proto.Node{
    Mac:      "aa:bb:cc:dd:ee:ff",
    Hostname: "mesh-node-01",
    Ipaddr:   "10.41.1.5",
    Position: &proto.Position{
        Latitude:  37.7749,
        Longitude: -122.4194,
        Altitude:  10.5,
    },
}
```

#### Gateway Message

Announces gateway nodes that provide internet connectivity:

```protobuf
message Gateway {
  string gateway_address = 1;   // Gateway IP address
  string gateway_mac = 2;       // Gateway MAC address
  int32 bandwidth_down = 3;     // Download bandwidth (kbit/s)
  int32 bandwidth_up = 4;       // Upload bandwidth (kbit/s)
}
```

**Distribution**:
- Send: Every 60 seconds (gateway nodes only)
- Receive: Every 10 seconds (all nodes)

**Usage**: Client nodes use this data to select and route to internet gateways.

---

## ConnectRPC API

The daemon provides an HTTP/2 REST/gRPC API using [ConnectRPC](https://connectrpc.com/), compatible with gRPC clients and standard HTTP clients.

The API specification is available on [Buf Build](https://buf.build/openmanet/protobufs) where you can get code generation SDKs.

### API Server Configuration

- **Address**: `0.0.0.0:8087` (all interfaces, port 8087)
- **Protocol**: HTTP/2 with h2c (unencrypted HTTP/2)
- **Timeout**: 30 seconds for read/write operations
- **Format**: Protocol Buffers (binary) or JSON

### Service Endpoints

#### NodeService

Manages mesh node information stored in the local database.

**ListNodes** - Get all known mesh nodes

```bash
# Using curl with JSON
curl -X POST http://{MESH_NODE_IO}:8087/openmanet.service.v1.NodeService/ListNodes \
  -H "Content-Type: application/json" \
  -d '{}'

# Response
{
  "nodes": [
    {
      "mac": "aa:bb:cc:dd:ee:ff",
      "hostname": "mesh-node-01",
      "ipaddr": "10.41.1.5",
      "position": {
        "latitude": 37.7749,
        "longitude": -122.4194,
        "altitude": 10.5
      }
    }
  ]
}
```

**GetNode** - Get specific node by hostname

```bash
curl -X POST http://{MESH_NODE_IO}:8087/openmanet.service.v1.NodeService/GetNode \
  -H "Content-Type: application/json" \
  -d '{"hostname": "mesh-node-01"}'

# Response
{
  "node": {
    "mac": "aa:bb:cc:dd:ee:ff",
    "hostname": "mesh-node-01",
    "ipaddr": "10.41.1.5"
  }
}
```

#### InterfaceService

Provides wireless interface information.

**ListWirelessInterfaces** - Get all wireless interfaces

```bash
curl -X POST http://{MESH_NODE_IO}:8087/openmanet.service.v1.InterfaceService/ListWirelessInterfaces \
  -H "Content-Type: application/json" \
  -d '{}'

# Response
{
  "interfaces": [
    {
      "index": 3,
      "name": "wlan0",
      "hardwareAddress": "aa:bb:cc:dd:ee:ff",
      "phy": 0,
      "device": 0,
      "interfaceType": "MESH",
      "frequency": 2437,
      "channelWidth": 20
    }
  ]
}
```

**GetWirelessInterface** - Get specific interface details

```bash
curl -X POST http://{MESH_NODE_IO}:8087/openmanet.service.v1.InterfaceService/GetWirelessInterface \
  -H "Content-Type: application/json" \
  -d '{"name": "wlan0"}'
```

#### MeshNeighborService

Shows directly connected mesh neighbors.

**ListMeshNeighbors** - Get all mesh neighbors

```bash
curl -X POST http://{MESH_NODE_IO}:8087/openmanet.service.v1.MeshNeighborService/ListMeshNeighbors \
  -H "Content-Type: application/json" \
  -d '{}'

# Response
{
  "neighbors": [
    {
      "neighbor": "mesh-node-02",
      "hardwareAddress": "11:22:33:44:55:66",
      "signalStrength": -45,
      "signal": -45,
      "throughput": 54000
    }
  ]
}
```

#### StatusService

Provides mesh network status and health information.

**GetServiceStatus** - Get overall mesh status

```bash
curl -X POST http://{MESH_NODE_IO}:8087/openmanet.service.v1.StatusService/GetServiceStatus \
  -H "Content-Type: application/json" \
  -d '{}'

# Response
{
  "status": {
    "isConnected": true,
    "connectedNeighbors": 3,
    "activeMeshInterfaces": 2,
    "isMeshGateway": false
  }
}
```

### Using gRPC Clients

The API is fully compatible with standard gRPC tooling:

```bash
# Using grpcurl
grpcurl -plaintext -d '{}' \
  {MESH_NODE_IO}:8087 \
  openmanet.service.v1.NodeService/ListNodes

# Using buf curl (with Connect protocol)
buf curl --http2-prior-knowledge \
  --protocol connect \
  http://{MESH_NODE_IO}:8087/openmanet.service.v1.NodeService/ListNodes
```

---

## Management Workers

The daemon uses a worker-based architecture for mesh operations. Each worker runs in its own goroutine with periodic intervals.

### Node Data Worker

**Purpose**: Announces node presence and collects information from other nodes

**Send Interval**: 60 seconds

**Receive Interval**: Continuous listening

**Operations**:
- Publishes local node information (MAC, hostname, IP, position)
- Receives node announcements from other mesh nodes
- Updates local database with discovered nodes
- Handles duplicate node detection and cleanup

### Gateway Worker

**Purpose**: Manages gateway announcements and route updates

**Send Interval**: 60 seconds (gateway mode only)

**Receive Interval**: 10 seconds (all nodes)

**Operations**:
- Gateway nodes: Announce availability and bandwidth
- Client nodes: Discover gateways and update routing tables
- Monitor gateway connectivity and failover

**ALFRED Data Type**: Type 1 (standard BATMAN-adv gateway)

---

## Troubleshooting

### Common Issues

#### API Server Not Responding

**Symptoms**: Connection refused on port 8087

**Checks**:
```bash
# Verify daemon is running
ps aux | grep openmanetd

# Check port binding
netstat -tulpn | grep 8087

# Test local connection
curl http://127.0.0.1:8087/openmanet.service.v1.StatusService/GetServiceStatus
```

**Solutions**:
- Verify no firewall blocking port 8087
- Check daemon logs for startup errors
- Ensure no other service using port 8087

#### No Mesh Nodes Discovered

**Symptoms**: Empty response from ListNodes API

**Checks**:
```bash
# Check ALFRED is receiving data
alfred -r <node-data-type>

# Verify mesh connectivity
batctl n

# Check worker status in logs
grep "NodeDataWorker" /var/log/openmanetd.log
```

**Solutions**:
- Verify `alfred.dataTypes.node: true` in config
- Check mesh network connectivity
- Ensure other nodes are running openmanetd
- Verify BATMAN-adv interface is bridged correctly


#### GPS Position Not Publishing

**Symptoms**: Position data null in node announcements

**Checks**:
```bash
# Verify GPS service
/etc/init.d/gpsd status

# Check GPS fix
gpsmon
```

**Solutions**:
- Verify gpsd is running and has GPS fix
- Check gpsd socket connection
- See [GNSS Documentation](gnss.md) for GPS troubleshooting

### Debug Mode

Enable debug logging by modifying the daemon startup or configuration:

```bash
# Set log level via environment
export LOG_LEVEL=debug
openmanetd
```

### Monitoring

Check daemon health:

```bash
# System service status
/etc/init.d/openmanetd status

# View recent logs
logread | grep openmanetd

# API health check
curl http://127.0.0.1:8087/openmanet.service.v1.StatusService/GetServiceStatus
```

---

## See Also

- [GNSS/GPS Configuration](gnss.md) - GPS integration details
- [Networking](networking.md) - Mesh networking setup
- [Hardware](hardware.md) - Supported hardware platforms
- [Initial Setup](initial-setup.md) - Device configuration guide

## External Resources

- [ConnectRPC Documentation](https://connectrpc.com/docs/introduction)
- [Protocol Buffers Guide](https://protobuf.dev/)
- [BATMAN-adv Documentation](https://www.open-mesh.org/projects/batman-adv/wiki)
- [ALFRED Protocol](https://www.open-mesh.org/projects/alfred/wiki)
- [OpenMANET Protobufs Repository](https://buf.build/openmanet/protobufs)


================================================
FILE: docs/range-testing.md
================================================
---
layout: default
title: Range Testing
nav_order: 7
description: Field test results of Wi-Fi HaLow (802.11ah) mesh networking with Raspberry Pi HATs at Pulpit Rock, Colorado Springs.
---

# Wi-Fi HaLow Range Testing — Pulpit Rock, Colorado Springs

This round of testing went pretty well overall. The setup was running on a **2 MHz channel (42 @ 923 MHz)** with just **two nodes** in the 802.11s mesh. Speeds were tested using the Google Speed Test app on my iPhone (should’ve used `iperf3`—next time).  

- **Local test (within 15 ft):** 4.03 / 4.27 Mbps  
- **With a 3rd node added:** 2.00 / 4.06 Mbps  

The **Starlink and Mesh Gateway** were staged on top of **Pulpit Rock** in Colorado Springs, with tests conducted at different spots around the rock. All tests used a **Muzi Works whip antenna**. I planned to compare another antenna but forgot them at home.  

Next round of testing will be with **multiple nodes** and on **1, 4, and 8 MHz channels**. When testing locally at 8 MHz, I hit **~15 Mbps**, so it’ll be interesting to see how that holds up at distance.

> Note: Recent OpenMANET firmware improves automatic GPSd configuration on Seeed-based nodes, which makes long-running range tests more “plug and play”.

---

## Distance & Speed Results

| Location        | Distance (m) | Distance (mi) | Download (Mbps) | Upload (Mbps) |
|-----------------|--------------|---------------|-----------------|---------------|
| Parking garage  | ~1,548       | ~0.96         | 0.37            | 0.21          |
| Hospital        | ~619         | ~0.38         | 2.84            | 1.10          |
| Baseball lot    | ~669         | ~0.42         | 2.77            | 1.37          |
| Neighborhood    | ~1,038       | ~0.65         | 0.33            | N/A           |

---

## Test Images

### IMG_8480 — Equipment Setup
![IMG_8480](./pics/IMG_8480.jpg)  
Equipment staged on top of Pulpit Rock, running the Wi-Fi HaLow mesh.

### IMG_8481 — View to Baseball Parking Lot
![IMG_8481](./pics/IMG_8481.jpg)  
Looking out from the Rock toward the baseball lot, one of the test points.

### IMG_8482 — Parking Garage
![IMG_8482](./pics/IMG_8482.jpg)  
View from the Rock to the parking garage, almost a mile away.

### IMG_8484 — Hospital View
![IMG_8484](./pics/IMG_8484.jpg)  
Taken from the hospital parking lot, showing the Rock in the distance.

### IMG_8489 — Neighborhood View
![IMG_8489](./pics/IMG_8489.jpg)  
Obstructed line-of-sight to the Rock from inside a neighborhood.

### IMG_8491 — Rock From Parking Garage
![IMG_8491](./pics/IMG_8491.jpg)  
View of the Rock as seen from the parking garage test location.


================================================
FILE: docs/troubleshooting.md
================================================
---
layout: default
title: Troubleshooting
nav_order: 6
permalink: /troubleshooting
description: Quick checks for mesh connectivity, hostname access via mDNS, and a recommended recovery path if setup gets messy.
---

# Troubleshooting

This page covers quick checks for common issues and the recommended “reset” workflow.

---

## Don’t Hand-Tune Settings (Reset Instead)

If something feels off after setup (odd addressing, multicast issues, services not coming up, etc.), the fastest path is usually to **start over clean** rather than changing settings outside the wizard.

OpenWrt stores configuration in its writable overlay. If you want a truly fresh install, fully wipe the SD card and re-flash:

1. Format the SD card with **SD Card Formatter**: https://www.sdcard.org/downloads/formatter/
2. In SD Card Formatter, select **Overwrite format**.
3. Re-flash the latest OpenMANET image and rerun the wizard.

---

## Connect By Hostname (mDNS / `.local`)

OpenMANET uses mDNS for easy discovery inside the mesh network (on clients that support mDNS). The simplest way to connect to different nodes is by hostname:

- If your hostname is `meshgate01`, use `meshgate01.local`
- Web UI: `https://meshgate01.local`
- SSH: `ssh root@meshgate01.local`

To browse mDNS names from a node:
- `ubus call umdns browse`
- `avahi-browse -a`

Note: `nslookup` typically will not resolve mDNS names.

---

## Power Problems Look Like “Network” Problems

A weak power supply, thin USB cable, or low batteries can cause strange, hard-to-diagnose issues (random reboots, radios dropping, services failing to start, flaky USB devices, or SD card corruption).

If you see weird behavior:
- Try a known-good power supply and cable (short, thick cable recommended).
- If you’re running on batteries/UPS, make sure they can provide enough current under load and are fully charged.

---

## Quick Mesh Sanity Checks

- If your end user device gets a `10.41.x.x` IP, it is on the mesh.
- After running the wizard, the node will reboot after address/DHCP reservation; reconnect or renew DHCP on your end user device if needed.


================================================
FILE: scripts/rangetest.sh
================================================
#!/bin/sh

# If this doesnt work, gps might be using the wrong device.
killall gpsd 2>/dev/null
# dmesg | grep tty
# this should should a device name like below.
gpsd /dev/ttyACM0 -F /var/run/gpsd.sock

# === Config ===
IFNAME="wlan0"
PING_IP="192.168.1.1"
OUTDIR="/root/distance"
TS_FILE=$(date +%Y%m%d-%H%M%S)
CSV="$OUTDIR/$TS_FILE.csv"

# === Ensure output dir exists ===
mkdir -p "$OUTDIR"

# === Add CSV header ===
echo "timestamp,time,lat,lon,signal_dbm,noise_dbm,snr_db,tx_mcs,rx_mcs,connected" > "$CSV"

while true; do
    # === Get timestamp and time ===
    TS=$(date -Iseconds 2>/dev/null || date +"%Y-%m-%dT%H:%M:%S%z")
    TIME=$(date +%H:%M:%S)

    # === Get GPS ===
    GPS=$(gpspipe -w -n 30 | grep TPV | grep -m1 lat)
    LAT=$(echo "$GPS" | grep -o '"lat":[^,]*' | cut -d':' -f2 | tr -d ' ')
    LON=$(echo "$GPS" | grep -o '"lon":[^,]*' | cut -d':' -f2 | tr -d ' ')

    # Skip if no GPS fix
    if [ -z "$LAT" ] || [ -z "$LON" ]; then
        echo "[$TIME] No GPS fix. Skipping..."
        sleep 10
        continue
    fi

    # === Get Signal and Noise ===
    STATS=$(morse_cli -i "$IFNAME" stats)

    # case-insensitive, robust to spacing; extract the numeric value after the colon
    RSSI=$(printf "%s\n" "$STATS" | awk -F':' 'tolower($0) ~ /received[[:space:]]+power[[:space:]]*\(dbm\)/ {gsub(/^[ \t]+|[ \t]+$/,"",$2); print $2; exit}')
    NOISE=$(printf "%s\n" "$STATS" | awk -F':' 'tolower($0) ~ /^[[:space:]]*noise[[:space:]]*\(dbm\)/      {gsub(/^[ \t]+|[ \t]+$/,"",$2); print $2; exit}')

if [ -n "$RSSI" ] && [ -n "$NOISE" ]; then
    SNR=$(( RSSI - NOISE ))
else
    SNR=""
fi
    # === Get TX/RX MCS ===
    TX_MCS=$(iw dev "$IFNAME" station dump 2>/dev/null | grep "tx bitrate" | grep -oE 'MCS [0-9]+' | head -n1 | cut -d' ' -f2)
    RX_MCS=$(iw dev "$IFNAME" station dump 2>/dev/null | grep "rx bitrate" | grep -oE 'MCS [0-9]+' | head -n1 | cut -d' ' -f2)

    TX_MCS=${TX_MCS:-NA}
    RX_MCS=${RX_MCS:-NA}

    # === Ping test for connectivity ===
    if ping -c 1 -W 1 "$PING_IP" >/dev/null 2>&1; then
        STATUS="yes"
        echo "✅ Ping $PING_IP OK"
    else
        STATUS="no"
        echo "❌ Ping $PING_IP failed"
    fi

    # === Output to console and CSV ===
    echo "Logged at $TIME ($LAT, $LON) RSSI=$RSSI dBm, SNR=$SNR dB, TX_MCS=$TX_MCS, RX_MCS=$RX_MCS, Connected=$STATUS"
    echo "$TS,$TIME,$LAT,$LON,$RSSI,$NOISE,$SNR,$TX_MCS,$RX_MCS,$STATUS" >> "$CSV"

    sleep 10
done
Download .txt
gitextract_x8_5kufu/

├── .github/
│   ├── funding.yml
│   └── workflows/
│       └── pages.yml
├── .gitignore
├── README.md
├── docs/
│   ├── .gitignore
│   ├── 404.html
│   ├── Gemfile
│   ├── _config.yml
│   ├── _posts/
│   │   └── 2025-09-11-welcome-to-jekyll.markdown
│   ├── adsb-to-cot.md
│   ├── firmware.md
│   ├── gnss.md
│   ├── hardware/
│   │   ├── halowlink2.md
│   │   ├── heltec.md
│   │   ├── raspberry-pi.md
│   │   └── venice.md
│   ├── hardware.md
│   ├── index.md
│   ├── initial-setup/
│   │   ├── halowlink2.md
│   │   ├── heltec.md
│   │   ├── raspberry-pi.md
│   │   └── venice.md
│   ├── initial-setup.md
│   ├── networking.md
│   ├── openmanetd.md
│   ├── range-testing.md
│   └── troubleshooting.md
└── scripts/
    └── rangetest.sh
Condensed preview — 28 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (86K chars).
[
  {
    "path": ".github/funding.yml",
    "chars": 28,
    "preview": "buy_me_a_coffee: jeremymcgee"
  },
  {
    "path": ".github/workflows/pages.yml",
    "chars": 1416,
    "preview": "# Build and deploy Jekyll site from /docs to GitHub Pages (served from root)\nname: Deploy Jekyll site to Pages\n\non:\n  pu"
  },
  {
    "path": ".gitignore",
    "chars": 75,
    "preview": ".DS_Store\ndocs/_site/\ndocs/.jekyll-cache/\ndocs/.sass-cache/\nvendor/bundle/\n"
  },
  {
    "path": "README.md",
    "chars": 1428,
    "preview": "# OpenMANET\n\n**OpenMANET** is a Raspberry Pi–based MANET (Mobile Ad-Hoc Network) radio built on **Wi-Fi HaLow (802.11ah)"
  },
  {
    "path": "docs/.gitignore",
    "chars": 56,
    "preview": "_site\n.sass-cache\n.jekyll-cache\n.jekyll-metadata\nvendor\n"
  },
  {
    "path": "docs/404.html",
    "chars": 416,
    "preview": "---\npermalink: /404.html\nlayout: page\n---\n\n<style type=\"text/css\" media=\"screen\">\n  .container {\n    margin: 10px auto;\n"
  },
  {
    "path": "docs/Gemfile",
    "chars": 1304,
    "preview": "source \"https://rubygems.org\"\n# Hello! This is where you manage which Jekyll version is used to run.\n# When you want to "
  },
  {
    "path": "docs/_config.yml",
    "chars": 1184,
    "preview": "# Welcome to Jekyll!\n#\n# This config file sets site-wide values (title, email, description, etc.).\n# Restart `bundle exe"
  },
  {
    "path": "docs/_posts/2025-09-11-welcome-to-jekyll.markdown",
    "chars": 1361,
    "preview": "---\nlayout: post\ntitle:  \"Welcome to Jekyll!\"\ndate:   2025-09-11 14:13:46 -0600\ncategories: jekyll update\n---\nYou’ll fin"
  },
  {
    "path": "docs/adsb-to-cot.md",
    "chars": 2249,
    "preview": "---\nlayout: default\ntitle: ADS-B to CoT\nnav_order: 8\npermalink: /adsb-to-cot\ndescription: ADS-B to Cursor on Target gate"
  },
  {
    "path": "docs/firmware.md",
    "chars": 5750,
    "preview": "---\nlayout: default\ntitle: Firmware & Releases\nnav_order: 2\npermalink: /firmware\ndescription: Firmware download guidance"
  },
  {
    "path": "docs/gnss.md",
    "chars": 5344,
    "preview": "---\nlayout: default\ntitle: GNSS\nnav_order: 9\npermalink: /gnss\ndescription: GPS/GNSS integration for position tracking, A"
  },
  {
    "path": "docs/hardware/halowlink2.md",
    "chars": 1517,
    "preview": "---\nlayout: default\ntitle: HaLowLink2\nparent: Hardware\nnav_order: 2\npermalink: /hardware/halowlink2\ndescription: MorseMi"
  },
  {
    "path": "docs/hardware/heltec.md",
    "chars": 1807,
    "preview": "---\nlayout: default\ntitle: Heltec\nparent: Hardware\nnav_order: 3\npermalink: /hardware/heltec\ndescription: Heltec HT-HD01 "
  },
  {
    "path": "docs/hardware/raspberry-pi.md",
    "chars": 6754,
    "preview": "---\nlayout: default\ntitle: Raspberry Pi\nparent: Hardware\nnav_order: 1\npermalink: /hardware/raspberry-pi\ndescription: Sup"
  },
  {
    "path": "docs/hardware/venice.md",
    "chars": 1569,
    "preview": "---\nlayout: default\ntitle: Gateworks Venice\nparent: Hardware\nnav_order: 4\npermalink: /hardware/venice\ndescription: Gatew"
  },
  {
    "path": "docs/hardware.md",
    "chars": 2818,
    "preview": "---\nlayout: default\ntitle: Hardware\nnav_order: 4\nhas_children: true\npermalink: /hardware\ndescription: Overview of all su"
  },
  {
    "path": "docs/index.md",
    "chars": 2686,
    "preview": "---\nlayout: home\ntitle: OpenMANET\nnav_order: 1\npermalink: /\ndescription: Raspberry Pi–based MANET radio built on Wi-Fi H"
  },
  {
    "path": "docs/initial-setup/halowlink2.md",
    "chars": 3205,
    "preview": "---\nlayout: default\ntitle: HaLow Link 2 Initial Setup\nparent: Initial Setup\nnav_order: 2\npermalink: /initial-setup/halow"
  },
  {
    "path": "docs/initial-setup/heltec.md",
    "chars": 3570,
    "preview": "---\nlayout: default\ntitle: Heltec HT-HD01-V2 Initial Setup\nparent: Initial Setup\nnav_order: 2\npermalink: /initial-setup/"
  },
  {
    "path": "docs/initial-setup/raspberry-pi.md",
    "chars": 5637,
    "preview": "---\nlayout: default\ntitle: Raspberry Pi\nparent: Initial Setup\nnav_order: 1\npermalink: /initial-setup/raspberry-pi\ndescri"
  },
  {
    "path": "docs/initial-setup/venice.md",
    "chars": 3451,
    "preview": "---\nlayout: default\ntitle: Gateworks Venice\nparent: Initial Setup\nnav_order: 3\npermalink: /initial-setup/venice\ndescript"
  },
  {
    "path": "docs/initial-setup.md",
    "chars": 531,
    "preview": "---\nlayout: default\ntitle: Initial Setup\nnav_order: 3\nhas_children: true\ndescription: Step-by-step setup guides for all "
  },
  {
    "path": "docs/networking.md",
    "chars": 8661,
    "preview": "---\nlayout: default\ntitle: Networking\nnav_order: 5\npermalink: /networking\ndescription: Explains the flat OpenMANET topol"
  },
  {
    "path": "docs/openmanetd.md",
    "chars": 12166,
    "preview": "---\nlayout: default\ntitle: OpenMANETd Daemon\nnav_order: 10\npermalink: /openmanetd\ndescription: openmanetd is the core ma"
  },
  {
    "path": "docs/range-testing.md",
    "chars": 2624,
    "preview": "---\nlayout: default\ntitle: Range Testing\nnav_order: 7\ndescription: Field test results of Wi-Fi HaLow (802.11ah) mesh net"
  },
  {
    "path": "docs/troubleshooting.md",
    "chars": 2106,
    "preview": "---\nlayout: default\ntitle: Troubleshooting\nnav_order: 6\npermalink: /troubleshooting\ndescription: Quick checks for mesh c"
  },
  {
    "path": "scripts/rangetest.sh",
    "chars": 2435,
    "preview": "#!/bin/sh\n\n# If this doesnt work, gps might be using the wrong device.\nkillall gpsd 2>/dev/null\n# dmesg | grep tty\n# thi"
  }
]

About this extraction

This page contains the full source code of the OpenMANET/docs GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 28 files (80.2 KB), approximately 23.1k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!