Open-source Flutter client for MeshCore LoRa mesh networking devices
Find a file
Winston Lowe d2b693e5ce
Add a signal readout for the nearest repeater. With improvements to app bar and other UI polish. (#200)
* Refactor Cayenne LPP parsing with error handling and logging

- Added error handling and logging to the Cayenne LPP parsing methods to manage malformed data gracefully.
- Improved the structure of the parsing logic for better readability and maintainability.
- Updated the Contact model to include error handling during frame parsing.
- Refactored Channels, Contacts, Map, and Neighbours screens to utilize a new AppBarTitle widget for consistent app bar design.
- Enhanced the BatteryIndicator widget to display SNR information for direct repeaters.
- Introduced SNRUi class for better management of SNR icon and text representation.
- Improved error handling in PathTraceMap and Neighbours screens to log errors appropriately.

* Fix trace route bytes generation logic in Contact model

* Ignore advertisements from self in MeshCoreConnector

* Refactor PathTraceData to use List<double> for snrData and adjust data mapping in PathTraceMapScreen

* Add SNRIndicator to AppBar and refactor BatteryIndicator layout

* Enhance path management dialog to display direct repeaters with color coding based on signal strength

* Remove unused import from SNR indicator widget

* Update lib/models/contact.dart

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update lib/connector/meshcore_connector.dart

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update lib/connector/meshcore_connector.dart

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update lib/screens/path_trace_map.dart

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update lib/widgets/battery_indicator.dart

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update lib/helpers/cayenne_lpp.dart

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Refactor packet handling to skip only the RSSI byte for improved reliability

* Add SNR indicator localization and update UI references for nearby repeaters

* Handle loading state and error parsing in PathTraceMapScreen; update SNR indicator dialog content layout

* Throw an exception for unsupported LPP types in CayenneLpp class

* Refactor AppBarTitle widget to remove unused style parameter; update related screens to reflect changes
Improve SNR handling by adding validation for spreading factor range in snrUiFromSNR function
Update contact handling in MeshCoreConnector to fix variable naming and improve readability
Stop parsing unsupported LPP types in CayenneLpp to avoid misalignment

* Sort direct repeaters by last updated time and SNR; limit to top three for improved path management dialog

* Prevent notifications for chat and sensor adverts without a valid path

* Implement ranking system for direct repeaters based on SNR and recency; update related UI components to reflect changes

* Refactor localization keys for "neighbors" terminology across multiple languages

- Updated localization keys from "neighbours" to "neighbors" in the following files:
  - app_localizations_bg.dart
  - app_localizations_de.dart
  - app_localizations_en.dart
  - app_localizations_es.dart
  - app_localizations_fr.dart
  - app_localizations_it.dart
  - app_localizations_nl.dart
  - app_localizations_pl.dart
  - app_localizations_pt.dart
  - app_localizations_ru.dart
  - app_localizations_sk.dart
  - app_localizations_sl.dart
  - app_localizations_sv.dart
  - app_localizations_uk.dart
  - app_localizations_zh.dart
- Updated corresponding ARB files to reflect the changes in keys.
- Renamed the NeighboursScreen to NeighborsScreen in the chat and repeater hub screens for consistency.

* Adjust ranking calculation for direct repeaters by adding offset to SNR for improved accuracy

* Fix typo in variable name for second direct repeater in path management dialog

* Refactor ranking calculation for direct repeaters and update path handling in channel message screens

* Refactor path handling in ChannelMessagePathScreen to improve logic for outgoing messages and channel messages

* Fix AppBarTitle horizontal overflow with long titles (#187)

* Initial plan

* Wrap title Column in Expanded to prevent horizontal overflow in AppBarTitle

Co-authored-by: wel97459 <12990640+wel97459@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wel97459 <12990640+wel97459@users.noreply.github.com>

* Refactor AppBarTitle widget to simplify Text widget initialization

* Add "Show All Paths" feature to chat path management

- Implemented localization for "Show All Paths" in multiple languages (DE, EN, ES, FR, IT, NL, PL, PT, RU, SK, SL, SV, UK, ZH).
- Updated path management dialog to include a toggle for showing all paths.
- Refactored path history display logic to conditionally show paths based on the toggle state.
- Cleaned up unused print statements and improved code readability in path tracing and chat screens.

* Refactor FeatureToggleRow visibility in chat and path management dialogs based on repeaters list

* Remove unused import of 'dart:ffi' in path_trace_map.dart

* Refactor repeater management logic and update UI state handling in chat and path management dialogs

* Refactor RX data handling and improve repeater management logic in chat and path management dialogs

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wel97459 <12990640+wel97459@users.noreply.github.com>
2026-02-20 20:27:38 -08:00
.github/workflows add flutter test to actions 2026-02-05 09:40:31 -08:00
android Update dependencies and improve code consistency across multiple files 2026-02-14 02:22:45 -07:00
assets add obtainium badge 2026-01-30 08:44:03 -08:00
docs Add Privacy Policy document outlining data collection practices and user rights 2026-01-11 18:12:31 -07:00
ios fix commit 2026-02-01 16:57:17 -07:00
lib Add a signal readout for the nearest repeater. With improvements to app bar and other UI polish. (#200) 2026-02-20 20:27:38 -08:00
linux feat: integrate link handling in chat screen with linkify support 2026-01-20 21:42:54 -07:00
macos Integrate SharePlus plugin for enhanced sharing functionality across platforms 2026-02-08 12:26:49 -08:00
test format dart files 2026-02-04 08:32:35 -08:00
tools fix commit 2026-02-01 16:57:17 -07:00
web Initial commit: MeshCore Open Flutter client 2025-12-26 11:42:02 -07:00
windows Update dependencies and improve code consistency across multiple files 2026-02-14 02:22:45 -07:00
.gitattributes Configure Git LFS for binary files 2025-12-31 22:24:06 -07:00
.gitignore keep ignores organized 2026-02-11 08:16:07 -08:00
.metadata Initial commit: MeshCore Open Flutter client 2025-12-26 11:42:02 -07:00
.ruby-version add rbenv support 2026-02-19 11:17:58 -08:00
AGENTS.md Initial commit: MeshCore Open Flutter client 2025-12-26 11:42:02 -07:00
analysis_options.yaml Initial commit: MeshCore Open Flutter client 2025-12-26 11:42:02 -07:00
CLAUDE.md Initial commit: MeshCore Open Flutter client 2025-12-26 11:42:02 -07:00
flake.lock add flake.lock 2026-02-11 17:26:43 +01:00
flake.nix fix smaller copilot issues 2026-02-11 17:45:15 +01:00
l10n.yaml Add untranslated messages file and update localization keys 2026-01-19 19:13:22 -07:00
LICENSE Add MIT License to the project 2025-12-31 22:37:39 -07:00
mesh-icon.png add icon, also misc improvments 2025-12-30 20:04:53 -07:00
pubspec.lock Add a signal readout for the nearest repeater. With improvements to app bar and other UI polish. (#200) 2026-02-20 20:27:38 -08:00
pubspec.yaml Update dependencies and improve code consistency across multiple files 2026-02-14 02:22:45 -07:00
README.md add dart format workflow 2026-02-04 08:33:49 -08:00
TESTFLIGHT_GUIDE.md issue #112 fixes and more 2026-02-01 18:37:14 -07:00
untranslated.json Fixed banner flash, added enable bluetooth button fixed theme to use app theme colors removed FAB overrides because material 3 does this for us, fixed missing translations. 2026-02-14 01:46:40 -07:00

MeshCore Open

Open-source Flutter client for MeshCore LoRa mesh networking devices.

Overview

MeshCore Open is a cross-platform mobile application for communicating with MeshCore LoRa mesh network devices via Bluetooth Low Energy (BLE). The app enables long-range, off-grid communication through peer-to-peer messaging, public channels, and mesh networking capabilities.

Get it on Obtainium

Screenshots


Contacts


Chat


Reactions


Map


Channels

Features

Core Functionality

  • Direct Messaging: Private encrypted conversations with individual contacts
  • Public Channels: Broadcast messages to channel subscribers on the mesh network
  • Contact Management: Organize contacts, track last seen times, and manage conversation history
  • Contact Groups: Create custom groups to organize your mesh network contacts
  • Message Reactions: React to messages with emoji responses
  • Message Replies: Thread conversations with inline reply functionality

Mesh Network

  • Path Visualization: View routing paths and signal quality for each contact
  • Route Management: Manual path overriding and automatic route rotation
  • Signal Metrics: Real-time SNR (Signal-to-Noise Ratio) tracking
  • Node Discovery: Automatic detection of nearby mesh nodes
  • Repeater Support: Connect to and manage repeater nodes for extended range

Map & Location

  • Live Map View: Real-time visualization of mesh network nodes on an interactive map
  • Node Filtering: Filter by node type (chat, repeater, sensor) and time range
  • Location Sharing: Share GPS coordinates and custom markers with contacts
  • Offline Maps: Download map tiles for offline use in remote areas
  • MGRS Coordinates: Support for Military Grid Reference System coordinate format

Device Management

  • BLE Connection: Scan and connect to MeshCore devices via Bluetooth
  • Device Settings: Configure radio parameters, power settings, and network options
  • Battery Monitoring: Real-time battery status with chemistry-specific voltage curves
  • Firmware Updates: Over-the-air firmware updates via BLE (coming soon)

Repeater Hub

  • CLI Access: Full command-line interface to repeater nodes
  • Settings Management: Configure repeater behavior, power limits, and network settings
  • Statistics Dashboard: View repeater traffic, connected clients, and system health
  • Remote Management: Administer repeaters from anywhere on the mesh network

Technical Details

Architecture

  • Framework: Flutter 3.38.5 / Dart 3.10.4
  • State Management: Provider pattern with ChangeNotifier
  • BLE Protocol: Nordic UART Service (NUS) over Bluetooth Low Energy
  • Storage: Local SQLite database for messages and contact data
  • Encryption: End-to-end encryption for private messages using the MeshCore protocol

Platform Support

  • Android: Full support (API 21+)
  • iOS: Full support (iOS 12+)
  • 🚧 Desktop: Limited support (macOS/Linux/Windows)

Dependencies

Package Purpose
flutter_blue_plus Bluetooth Low Energy communication
provider State management
sqflite Local database storage
flutter_map Interactive map display
latlong2 Geographic coordinate handling
flutter_local_notifications Background notification support
smaz Message compression
pointycastle Cryptographic operations
intl Internationalization and date formatting

Getting Started

Prerequisites

  • Flutter SDK 3.38.5 or later
  • Android Studio / Xcode (for mobile development)
  • A MeshCore-compatible LoRa device

Installation

  1. Clone the repository

    git clone https://github.com/zjs81/meshcore-open.git
    cd meshcore-open
    
  2. Install dependencies

    flutter pub get
    
  3. Run the app

    flutter run
    

Building for Release

Android APK:

flutter build apk --release

iOS:

flutter build ios --release

Project Structure

lib/
├── main.dart                    # App entry point
├── connector/
│   ├── meshcore_connector.dart  # BLE communication & state management
│   └── meshcore_protocol.dart   # Protocol definitions & frame parsing
├── screens/
│   ├── scanner_screen.dart      # Device scanning (home screen)
│   ├── contacts_screen.dart     # Contact list
│   ├── chat_screen.dart         # Direct messaging
│   ├── channels_screen.dart     # Public channels
│   ├── map_screen.dart          # Network visualization map
│   ├── settings_screen.dart     # Device settings
│   └── repeater_hub_screen.dart # Repeater management
├── models/
│   ├── contact.dart             # Contact data model
│   ├── message.dart             # Message data structure
│   └── channel.dart             # Channel definitions
├── services/
│   ├── notification_service.dart      # Push notifications
│   ├── message_retry_service.dart     # Automatic message retry
│   ├── background_service.dart        # Background BLE connection
│   └── map_tile_cache_service.dart    # Offline map storage
└── storage/
    ├── message_store.dart       # Message persistence
    ├── contact_store.dart       # Contact database
    └── unread_store.dart        # Unread message tracking

BLE Protocol

Nordic UART Service (NUS)

  • Service UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
  • RX Characteristic: 6e400002-b5a3-f393-e0a9-e50e24dcca9e (Write to device)
  • TX Characteristic: 6e400003-b5a3-f393-e0a9-e50e24dcca9e (Notify from device)

Device Discovery

Devices are discovered by scanning for BLE advertisements with the name prefix MeshCore-

Message Format

Messages are transmitted as binary frames using a custom protocol optimized for LoRa transmission. See meshcore_protocol.dart for frame structure definitions.

Configuration

App Settings

  • Theme: System default, light, or dark mode
  • Notifications: Configurable for messages, channels, and node advertisements
  • Battery Chemistry: Support for NMC, LiFePO4, and LiPo battery types
  • Message Retry: Automatic retry with configurable path clearing

Device Settings

  • Radio Power: Transmit power adjustment (10-30 dBm)
  • Frequency: LoRa frequency configuration
  • Bandwidth: Channel bandwidth selection
  • Spreading Factor: Range vs. speed trade-off
  • Network ID: Mesh network identifier

Contributing

This is an open-source project. Contributions are welcome!

Development Guidelines

  • Follow the Flutter style guide
  • Use Material 3 design components
  • Write clear commit messages
  • Test on both Android and iOS before submitting PRs

Code Style

  • Prefer StatelessWidget with Consumer for reactive UI
  • Use const constructors where possible
  • Keep functions small and focused
  • Avoid premature abstractions
  • Run dart format on all changes before submitting

Support

For issues, questions, or feature requests, please open an issue on GitHub: https://github.com/zjs81/meshcore-open/issues

Donate

If you find MeshCore Open useful and would like to support development, you can donate Solana or other Solana tokens:

Solana Address: F15YanjZj96YTBtKJYgNa8RLQLCZkx5CEwogPWkqXeoQ

Your support helps maintain and improve this open-source project!

Acknowledgments