Repository files navigation

MeshMapper Flutter App

Note: All issues and feature requests are tracked in the main project repo: MeshMapper/MeshMapper_Project. Please open issues there rather than in this repository.

Cross-platform wardriving app for MeshCore. Connect to MeshCore companions via Bluetooth, map repeater coverage, and contribute data to the community mesh map.

Built with contributions by The Greater Ottawa Mesh Radio Enthusiasts

View the Map | Wiki | Onboard Your Region | Submit Bug/Feature


Get the App

App Store Releases

Beta Releases

Quick Start — Power on your MeshCore Companion, open the app, tap Connect, and select your device via Bluetooth.


Features

  • Cross-Platform — Android and iOS
  • BLE Connectivity — Connect to MeshCore companion devices via Bluetooth Low Energy
  • GPS Tracking — High-accuracy location tracking with 50m distance filter
  • Real-time Map — View TX/RX/DISC ping markers on OpenStreetMap with dark mode tiles
  • Repeater Echo Detection — 7-second window detects which repeaters echo your pings
  • Passive RX Logging — Continuously monitors mesh traffic and logs observations
  • Persistent API Queue — Batch upload with retry logic, survives app restarts
  • Offline Mode — Wardrive without connectivity, upload data later
  • 30+ Device Models — Automatic identification and power reporting for Ikoka, Heltec, RAK, LilyGo, Seeed, and more
  • Noise Floor Graphing — Track signal quality over time
  • Dark/Light Theme — System theme support

Development

See CONTRIBUTING.md for setup instructions and PR workflow, and DEVELOPMENT.md for architecture docs and coding standards.


Architecture

The app uses a service-oriented architecture with platform-specific BLE abstraction:

lib/
├── main.dart # App entry point, platform detection
├── models/ # Data models (Hive-annotated)
├── providers/ # State management (Provider/ChangeNotifier)
├── screens/ # Full-page UI screens
├── widgets/ # Reusable components
└── services/
├── bluetooth/ # BLE abstraction layer
│ ├── bluetooth_service.dart # Abstract interface
│ ├── mobile_bluetooth.dart # Android/iOS (flutter_blue_plus)
│ └── web_bluetooth.dart # Web (flutter_web_bluetooth)
├── meshcore/ # MeshCore protocol layer
│ ├── connection.dart # 10-step connection workflow
│ ├── packet_parser.dart # Binary packet parsing
│ ├── unified_rx_handler.dart # Packet routing (TX vs RX)
│ ├── tx_tracker.dart # Repeater echo detection
│ └── rx_logger.dart # Passive observation logging
├── gps_service.dart # GPS tracking
├── ping_service.dart # TX/RX ping orchestration
├── api_queue_service.dart # Persistent upload queue
└── device_model_service.dart # Device identification

Key design decisions:

  • Unified RX Handler — All incoming BLE packets are accepted, parsed once, then routed to TX tracking or RX logging
  • Platform BLE abstraction — Runtime selection via kIsWeb in main.dart
  • Hive for persistence — Local storage for API queue, preferences, and offline sessions
  • Provider for state — Single AppStateProvider with ChangeNotifier

See DEVELOPMENT.md for full details.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.

License

This project is licensed under the MIT License — see LICENSE for details.

Acknowledgments

About

Cross-platform wardriving app for MeshCore mesh devices

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

MeshMapper Flutter App

Note: All issues and feature requests are tracked in the main project repo: MeshMapper/MeshMapper_Project. Please open issues there rather than in this repository.

Cross-platform wardriving app for MeshCore. Connect to MeshCore companions via Bluetooth, map repeater coverage, and contribute data to the community mesh map.

Built with contributions by The Greater Ottawa Mesh Radio Enthusiasts

View the Map | Wiki | Onboard Your Region | Submit Bug/Feature


Get the App

App Store Releases

Beta Releases

Quick Start — Power on your MeshCore Companion, open the app, tap Connect, and select your device via Bluetooth.


Features

  • Cross-Platform — Android and iOS
  • BLE Connectivity — Connect to MeshCore companion devices via Bluetooth Low Energy
  • GPS Tracking — High-accuracy location tracking with 50m distance filter
  • Real-time Map — View TX/RX/DISC ping markers on OpenStreetMap with dark mode tiles
  • Repeater Echo Detection — 7-second window detects which repeaters echo your pings
  • Passive RX Logging — Continuously monitors mesh traffic and logs observations
  • Persistent API Queue — Batch upload with retry logic, survives app restarts
  • Offline Mode — Wardrive without connectivity, upload data later
  • 30+ Device Models — Automatic identification and power reporting for Ikoka, Heltec, RAK, LilyGo, Seeed, and more
  • Noise Floor Graphing — Track signal quality over time
  • Dark/Light Theme — System theme support

Development

See CONTRIBUTING.md for setup instructions and PR workflow, and DEVELOPMENT.md for architecture docs and coding standards.


Architecture

The app uses a service-oriented architecture with platform-specific BLE abstraction:

lib/
├── main.dart # App entry point, platform detection
├── models/ # Data models (Hive-annotated)
├── providers/ # State management (Provider/ChangeNotifier)
├── screens/ # Full-page UI screens
├── widgets/ # Reusable components
└── services/
├── bluetooth/ # BLE abstraction layer
│ ├── bluetooth_service.dart # Abstract interface
│ ├── mobile_bluetooth.dart # Android/iOS (flutter_blue_plus)
│ └── web_bluetooth.dart # Web (flutter_web_bluetooth)
├── meshcore/ # MeshCore protocol layer
│ ├── connection.dart # 10-step connection workflow
│ ├── packet_parser.dart # Binary packet parsing
│ ├── unified_rx_handler.dart # Packet routing (TX vs RX)
│ ├── tx_tracker.dart # Repeater echo detection
│ └── rx_logger.dart # Passive observation logging
├── gps_service.dart # GPS tracking
├── ping_service.dart # TX/RX ping orchestration
├── api_queue_service.dart # Persistent upload queue
└── device_model_service.dart # Device identification

Key design decisions:

  • Unified RX Handler — All incoming BLE packets are accepted, parsed once, then routed to TX tracking or RX logging
  • Platform BLE abstraction — Runtime selection via kIsWeb in main.dart
  • Hive for persistence — Local storage for API queue, preferences, and offline sessions
  • Provider for state — Single AppStateProvider with ChangeNotifier

See DEVELOPMENT.md for full details.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.

License

This project is licensed under the MIT License — see LICENSE for details.

Acknowledgments

About

Cross-platform wardriving app for MeshCore mesh devices

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MeshMapper Flutter App

Note: All issues and feature requests are tracked in the main project repo: MeshMapper/MeshMapper_Project. Please open issues there rather than in this repository.

Cross-platform wardriving app for MeshCore. Connect to MeshCore companions via Bluetooth, map repeater coverage, and contribute data to the community mesh map.

Built with contributions by The Greater Ottawa Mesh Radio Enthusiasts

View the Map | Wiki | Onboard Your Region | Submit Bug/Feature


Get the App

App Store Releases

Beta Releases

Quick Start — Power on your MeshCore Companion, open the app, tap Connect, and select your device via Bluetooth.


Features

  • Cross-Platform — Android and iOS
  • BLE Connectivity — Connect to MeshCore companion devices via Bluetooth Low Energy
  • GPS Tracking — High-accuracy location tracking with 50m distance filter
  • Real-time Map — View TX/RX/DISC ping markers on OpenStreetMap with dark mode tiles
  • Repeater Echo Detection — 7-second window detects which repeaters echo your pings
  • Passive RX Logging — Continuously monitors mesh traffic and logs observations
  • Persistent API Queue — Batch upload with retry logic, survives app restarts
  • Offline Mode — Wardrive without connectivity, upload data later
  • 30+ Device Models — Automatic identification and power reporting for Ikoka, Heltec, RAK, LilyGo, Seeed, and more
  • Noise Floor Graphing — Track signal quality over time
  • Dark/Light Theme — System theme support

Development

See CONTRIBUTING.md for setup instructions and PR workflow, and DEVELOPMENT.md for architecture docs and coding standards.


Architecture

The app uses a service-oriented architecture with platform-specific BLE abstraction:

lib/
├── main.dart # App entry point, platform detection
├── models/ # Data models (Hive-annotated)
├── providers/ # State management (Provider/ChangeNotifier)
├── screens/ # Full-page UI screens
├── widgets/ # Reusable components
└── services/
├── bluetooth/ # BLE abstraction layer
│ ├── bluetooth_service.dart # Abstract interface
│ ├── mobile_bluetooth.dart # Android/iOS (flutter_blue_plus)
│ └── web_bluetooth.dart # Web (flutter_web_bluetooth)
├── meshcore/ # MeshCore protocol layer
│ ├── connection.dart # 10-step connection workflow
│ ├── packet_parser.dart # Binary packet parsing
│ ├── unified_rx_handler.dart # Packet routing (TX vs RX)
│ ├── tx_tracker.dart # Repeater echo detection
│ └── rx_logger.dart # Passive observation logging
├── gps_service.dart # GPS tracking
├── ping_service.dart # TX/RX ping orchestration
├── api_queue_service.dart # Persistent upload queue
└── device_model_service.dart # Device identification

Key design decisions:

  • Unified RX Handler — All incoming BLE packets are accepted, parsed once, then routed to TX tracking or RX logging
  • Platform BLE abstraction — Runtime selection via kIsWeb in main.dart
  • Hive for persistence — Local storage for API queue, preferences, and offline sessions
  • Provider for state — Single AppStateProvider with ChangeNotifier

See DEVELOPMENT.md for full details.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.

License

This project is licensed under the MIT License — see LICENSE for details.

Acknowledgments

About

Cross-platform wardriving app for MeshCore mesh devices

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MeshMapper Flutter App

Note: All issues and feature requests are tracked in the main project repo: MeshMapper/MeshMapper_Project. Please open issues there rather than in this repository.

Cross-platform wardriving app for MeshCore. Connect to MeshCore companions via Bluetooth, map repeater coverage, and contribute data to the community mesh map.

Built with contributions by The Greater Ottawa Mesh Radio Enthusiasts

View the Map | Wiki | Onboard Your Region | Submit Bug/Feature


Get the App

App Store Releases

Beta Releases

Quick Start — Power on your MeshCore Companion, open the app, tap Connect, and select your device via Bluetooth.


Features

  • Cross-Platform — Android and iOS
  • BLE Connectivity — Connect to MeshCore companion devices via Bluetooth Low Energy
  • GPS Tracking — High-accuracy location tracking with 50m distance filter
  • Real-time Map — View TX/RX/DISC ping markers on OpenStreetMap with dark mode tiles
  • Repeater Echo Detection — 7-second window detects which repeaters echo your pings
  • Passive RX Logging — Continuously monitors mesh traffic and logs observations
  • Persistent API Queue — Batch upload with retry logic, survives app restarts
  • Offline Mode — Wardrive without connectivity, upload data later
  • 30+ Device Models — Automatic identification and power reporting for Ikoka, Heltec, RAK, LilyGo, Seeed, and more
  • Noise Floor Graphing — Track signal quality over time
  • Dark/Light Theme — System theme support

Development

See CONTRIBUTING.md for setup instructions and PR workflow, and DEVELOPMENT.md for architecture docs and coding standards.


Architecture

The app uses a service-oriented architecture with platform-specific BLE abstraction:

lib/
├── main.dart # App entry point, platform detection
├── models/ # Data models (Hive-annotated)
├── providers/ # State management (Provider/ChangeNotifier)
├── screens/ # Full-page UI screens
├── widgets/ # Reusable components
└── services/
├── bluetooth/ # BLE abstraction layer
│ ├── bluetooth_service.dart # Abstract interface
│ ├── mobile_bluetooth.dart # Android/iOS (flutter_blue_plus)
│ └── web_bluetooth.dart # Web (flutter_web_bluetooth)
├── meshcore/ # MeshCore protocol layer
│ ├── connection.dart # 10-step connection workflow
│ ├── packet_parser.dart # Binary packet parsing
│ ├── unified_rx_handler.dart # Packet routing (TX vs RX)
│ ├── tx_tracker.dart # Repeater echo detection
│ └── rx_logger.dart # Passive observation logging
├── gps_service.dart # GPS tracking
├── ping_service.dart # TX/RX ping orchestration
├── api_queue_service.dart # Persistent upload queue
└── device_model_service.dart # Device identification

Key design decisions:

  • Unified RX Handler — All incoming BLE packets are accepted, parsed once, then routed to TX tracking or RX logging
  • Platform BLE abstraction — Runtime selection via kIsWeb in main.dart
  • Hive for persistence — Local storage for API queue, preferences, and offline sessions
  • Provider for state — Single AppStateProvider with ChangeNotifier

See DEVELOPMENT.md for full details.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.

License

This project is licensed under the MIT License — see LICENSE for details.

Acknowledgments

About

Cross-platform wardriving app for MeshCore mesh devices

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

MeshMapper Flutter App

Note: All issues and feature requests are tracked in the main project repo: MeshMapper/MeshMapper_Project. Please open issues there rather than in this repository.

Cross-platform wardriving app for MeshCore. Connect to MeshCore companions via Bluetooth, map repeater coverage, and contribute data to the community mesh map.

Built with contributions by The Greater Ottawa Mesh Radio Enthusiasts

View the Map | Wiki | Onboard Your Region | Submit Bug/Feature


Get the App

App Store Releases

Beta Releases

Quick Start — Power on your MeshCore Companion, open the app, tap Connect, and select your device via Bluetooth.


Features

  • Cross-Platform — Android and iOS
  • BLE Connectivity — Connect to MeshCore companion devices via Bluetooth Low Energy
  • GPS Tracking — High-accuracy location tracking with 50m distance filter
  • Real-time Map — View TX/RX/DISC ping markers on OpenStreetMap with dark mode tiles
  • Repeater Echo Detection — 7-second window detects which repeaters echo your pings
  • Passive RX Logging — Continuously monitors mesh traffic and logs observations
  • Persistent API Queue — Batch upload with retry logic, survives app restarts
  • Offline Mode — Wardrive without connectivity, upload data later
  • 30+ Device Models — Automatic identification and power reporting for Ikoka, Heltec, RAK, LilyGo, Seeed, and more
  • Noise Floor Graphing — Track signal quality over time
  • Dark/Light Theme — System theme support

Development

See CONTRIBUTING.md for setup instructions and PR workflow, and DEVELOPMENT.md for architecture docs and coding standards.


Architecture

The app uses a service-oriented architecture with platform-specific BLE abstraction:

lib/
├── main.dart # App entry point, platform detection
├── models/ # Data models (Hive-annotated)
├── providers/ # State management (Provider/ChangeNotifier)
├── screens/ # Full-page UI screens
├── widgets/ # Reusable components
└── services/
├── bluetooth/ # BLE abstraction layer
│ ├── bluetooth_service.dart # Abstract interface
│ ├── mobile_bluetooth.dart # Android/iOS (flutter_blue_plus)
│ └── web_bluetooth.dart # Web (flutter_web_bluetooth)
├── meshcore/ # MeshCore protocol layer
│ ├── connection.dart # 10-step connection workflow
│ ├── packet_parser.dart # Binary packet parsing
│ ├── unified_rx_handler.dart # Packet routing (TX vs RX)
│ ├── tx_tracker.dart # Repeater echo detection
│ └── rx_logger.dart # Passive observation logging
├── gps_service.dart # GPS tracking
├── ping_service.dart # TX/RX ping orchestration
├── api_queue_service.dart # Persistent upload queue
└── device_model_service.dart # Device identification

Key design decisions:

  • Unified RX Handler — All incoming BLE packets are accepted, parsed once, then routed to TX tracking or RX logging
  • Platform BLE abstraction — Runtime selection via kIsWeb in main.dart
  • Hive for persistence — Local storage for API queue, preferences, and offline sessions
  • Provider for state — Single AppStateProvider with ChangeNotifier

See DEVELOPMENT.md for full details.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.

License

This project is licensed under the MIT License — see LICENSE for details.

Acknowledgments

About

Cross-platform wardriving app for MeshCore mesh devices

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MeshMapper Flutter App

Note: All issues and feature requests are tracked in the main project repo: MeshMapper/MeshMapper_Project. Please open issues there rather than in this repository.

Cross-platform wardriving app for MeshCore. Connect to MeshCore companions via Bluetooth, map repeater coverage, and contribute data to the community mesh map.

Built with contributions by The Greater Ottawa Mesh Radio Enthusiasts

View the Map | Wiki | Onboard Your Region | Submit Bug/Feature


Get the App

App Store Releases

Beta Releases

Quick Start — Power on your MeshCore Companion, open the app, tap Connect, and select your device via Bluetooth.


Features

  • Cross-Platform — Android and iOS
  • BLE Connectivity — Connect to MeshCore companion devices via Bluetooth Low Energy
  • GPS Tracking — High-accuracy location tracking with 50m distance filter
  • Real-time Map — View TX/RX/DISC ping markers on OpenStreetMap with dark mode tiles
  • Repeater Echo Detection — 7-second window detects which repeaters echo your pings
  • Passive RX Logging — Continuously monitors mesh traffic and logs observations
  • Persistent API Queue — Batch upload with retry logic, survives app restarts
  • Offline Mode — Wardrive without connectivity, upload data later
  • 30+ Device Models — Automatic identification and power reporting for Ikoka, Heltec, RAK, LilyGo, Seeed, and more
  • Noise Floor Graphing — Track signal quality over time
  • Dark/Light Theme — System theme support

Development

See CONTRIBUTING.md for setup instructions and PR workflow, and DEVELOPMENT.md for architecture docs and coding standards.


Architecture

The app uses a service-oriented architecture with platform-specific BLE abstraction:

lib/
├── main.dart # App entry point, platform detection
├── models/ # Data models (Hive-annotated)
├── providers/ # State management (Provider/ChangeNotifier)
├── screens/ # Full-page UI screens
├── widgets/ # Reusable components
└── services/
├── bluetooth/ # BLE abstraction layer
│ ├── bluetooth_service.dart # Abstract interface
│ ├── mobile_bluetooth.dart # Android/iOS (flutter_blue_plus)
│ └── web_bluetooth.dart # Web (flutter_web_bluetooth)
├── meshcore/ # MeshCore protocol layer
│ ├── connection.dart # 10-step connection workflow
│ ├── packet_parser.dart # Binary packet parsing
│ ├── unified_rx_handler.dart # Packet routing (TX vs RX)
│ ├── tx_tracker.dart # Repeater echo detection
│ └── rx_logger.dart # Passive observation logging
├── gps_service.dart # GPS tracking
├── ping_service.dart # TX/RX ping orchestration
├── api_queue_service.dart # Persistent upload queue
└── device_model_service.dart # Device identification

Key design decisions:

  • Unified RX Handler — All incoming BLE packets are accepted, parsed once, then routed to TX tracking or RX logging
  • Platform BLE abstraction — Runtime selection via kIsWeb in main.dart
  • Hive for persistence — Local storage for API queue, preferences, and offline sessions
  • Provider for state — Single AppStateProvider with ChangeNotifier

See DEVELOPMENT.md for full details.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.

License

This project is licensed under the MIT License — see LICENSE for details.

Acknowledgments

About

Cross-platform wardriving app for MeshCore mesh devices

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

MeshMapper Flutter App

Note: All issues and feature requests are tracked in the main project repo: MeshMapper/MeshMapper_Project. Please open issues there rather than in this repository.

Cross-platform wardriving app for MeshCore. Connect to MeshCore companions via Bluetooth, map repeater coverage, and contribute data to the community mesh map.

Built with contributions by The Greater Ottawa Mesh Radio Enthusiasts

View the Map | Wiki | Onboard Your Region | Submit Bug/Feature


Get the App

App Store Releases

Beta Releases

Quick Start — Power on your MeshCore Companion, open the app, tap Connect, and select your device via Bluetooth.


Features

  • Cross-Platform — Android and iOS
  • BLE Connectivity — Connect to MeshCore companion devices via Bluetooth Low Energy
  • GPS Tracking — High-accuracy location tracking with 50m distance filter
  • Real-time Map — View TX/RX/DISC ping markers on OpenStreetMap with dark mode tiles
  • Repeater Echo Detection — 7-second window detects which repeaters echo your pings
  • Passive RX Logging — Continuously monitors mesh traffic and logs observations
  • Persistent API Queue — Batch upload with retry logic, survives app restarts
  • Offline Mode — Wardrive without connectivity, upload data later
  • 30+ Device Models — Automatic identification and power reporting for Ikoka, Heltec, RAK, LilyGo, Seeed, and more
  • Noise Floor Graphing — Track signal quality over time
  • Dark/Light Theme — System theme support

Development

See CONTRIBUTING.md for setup instructions and PR workflow, and DEVELOPMENT.md for architecture docs and coding standards.


Architecture

The app uses a service-oriented architecture with platform-specific BLE abstraction:

lib/
├── main.dart # App entry point, platform detection
├── models/ # Data models (Hive-annotated)
├── providers/ # State management (Provider/ChangeNotifier)
├── screens/ # Full-page UI screens
├── widgets/ # Reusable components
└── services/
├── bluetooth/ # BLE abstraction layer
│ ├── bluetooth_service.dart # Abstract interface
│ ├── mobile_bluetooth.dart # Android/iOS (flutter_blue_plus)
│ └── web_bluetooth.dart # Web (flutter_web_bluetooth)
├── meshcore/ # MeshCore protocol layer
│ ├── connection.dart # 10-step connection workflow
│ ├── packet_parser.dart # Binary packet parsing
│ ├── unified_rx_handler.dart # Packet routing (TX vs RX)
│ ├── tx_tracker.dart # Repeater echo detection
│ └── rx_logger.dart # Passive observation logging
├── gps_service.dart # GPS tracking
├── ping_service.dart # TX/RX ping orchestration
├── api_queue_service.dart # Persistent upload queue
└── device_model_service.dart # Device identification

Key design decisions:

  • Unified RX Handler — All incoming BLE packets are accepted, parsed once, then routed to TX tracking or RX logging
  • Platform BLE abstraction — Runtime selection via kIsWeb in main.dart
  • Hive for persistence — Local storage for API queue, preferences, and offline sessions
  • Provider for state — Single AppStateProvider with ChangeNotifier

See DEVELOPMENT.md for full details.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.

License

This project is licensed under the MIT License — see LICENSE for details.

Acknowledgments

About

Cross-platform wardriving app for MeshCore mesh devices

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

MeshMapper Flutter App

Note: All issues and feature requests are tracked in the main project repo: MeshMapper/MeshMapper_Project. Please open issues there rather than in this repository.

Cross-platform wardriving app for MeshCore. Connect to MeshCore companions via Bluetooth, map repeater coverage, and contribute data to the community mesh map.

Built with contributions by The Greater Ottawa Mesh Radio Enthusiasts

View the Map | Wiki | Onboard Your Region | Submit Bug/Feature


Get the App

App Store Releases

Beta Releases

Quick Start — Power on your MeshCore Companion, open the app, tap Connect, and select your device via Bluetooth.


Features

  • Cross-Platform — Android and iOS
  • BLE Connectivity — Connect to MeshCore companion devices via Bluetooth Low Energy
  • GPS Tracking — High-accuracy location tracking with 50m distance filter
  • Real-time Map — View TX/RX/DISC ping markers on OpenStreetMap with dark mode tiles
  • Repeater Echo Detection — 7-second window detects which repeaters echo your pings
  • Passive RX Logging — Continuously monitors mesh traffic and logs observations
  • Persistent API Queue — Batch upload with retry logic, survives app restarts
  • Offline Mode — Wardrive without connectivity, upload data later
  • 30+ Device Models — Automatic identification and power reporting for Ikoka, Heltec, RAK, LilyGo, Seeed, and more
  • Noise Floor Graphing — Track signal quality over time
  • Dark/Light Theme — System theme support

Development

See CONTRIBUTING.md for setup instructions and PR workflow, and DEVELOPMENT.md for architecture docs and coding standards.


Architecture

The app uses a service-oriented architecture with platform-specific BLE abstraction:

lib/
├── main.dart # App entry point, platform detection
├── models/ # Data models (Hive-annotated)
├── providers/ # State management (Provider/ChangeNotifier)
├── screens/ # Full-page UI screens
├── widgets/ # Reusable components
└── services/
├── bluetooth/ # BLE abstraction layer
│ ├── bluetooth_service.dart # Abstract interface
│ ├── mobile_bluetooth.dart # Android/iOS (flutter_blue_plus)
│ └── web_bluetooth.dart # Web (flutter_web_bluetooth)
├── meshcore/ # MeshCore protocol layer
│ ├── connection.dart # 10-step connection workflow
│ ├── packet_parser.dart # Binary packet parsing
│ ├── unified_rx_handler.dart # Packet routing (TX vs RX)
│ ├── tx_tracker.dart # Repeater echo detection
│ └── rx_logger.dart # Passive observation logging
├── gps_service.dart # GPS tracking
├── ping_service.dart # TX/RX ping orchestration
├── api_queue_service.dart # Persistent upload queue
└── device_model_service.dart # Device identification

Key design decisions:

  • Unified RX Handler — All incoming BLE packets are accepted, parsed once, then routed to TX tracking or RX logging
  • Platform BLE abstraction — Runtime selection via kIsWeb in main.dart
  • Hive for persistence — Local storage for API queue, preferences, and offline sessions
  • Provider for state — Single AppStateProvider with ChangeNotifier

See DEVELOPMENT.md for full details.


Contributing

Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.

License

This project is licensed under the MIT License — see LICENSE for details.

Acknowledgments

About

Cross-platform wardriving app for MeshCore mesh devices

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages