Skip to content

Commit 09a93ff

Browse files
authored
Merge pull request #1 from MeshMapper/copilot/port-meshmapper-to-flutter
Port MeshMapper WebClient to Flutter
2 parents 9aca6fc + 9c917b0 commit 09a93ff

39 files changed

+6375
-1
lines changed

.gitignore

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Miscellaneous
2+
*.class
3+
*.log
4+
*.pyc
5+
*.swp
6+
.DS_Store
7+
.atom/
8+
.buildlog/
9+
.history
10+
.svn/
11+
migrate_working_dir/
12+
13+
# IntelliJ related
14+
*.iml
15+
*.ipr
16+
*.iws
17+
.idea/
18+
19+
# The .vscode folder contains launch configuration and tasks you configure in
20+
# VS Code which you may wish to be included in version control, so this line
21+
# is commented out by default.
22+
#.vscode/
23+
24+
# Flutter/Dart/Pub related
25+
**/doc/api/
26+
**/ios/Flutter/.last_build_id
27+
.dart_tool/
28+
.flutter-plugins
29+
.flutter-plugins-dependencies
30+
.pub-cache/
31+
.pub/
32+
/build/
33+
34+
# Symbolication related
35+
app.*.symbols
36+
37+
# Obfuscation related
38+
app.*.map.json
39+
40+
# Android Studio will place build artifacts here
41+
/android/app/debug
42+
/android/app/profile
43+
/android/app/release
44+
45+
# iOS generated files
46+
/ios/Flutter/Flutter.framework
47+
/ios/Flutter/Flutter.podspec
48+
/ios/Runner/GeneratedPluginRegistrant.*
49+
/ios/.symlinks/
50+
/ios/Pods/
51+
52+
# Web generated files
53+
/web/*.dart.js
54+
/web/*.dart.js.map
55+
56+
# Code coverage
57+
coverage/
58+
59+
# Test related
60+
test/.test_coverage.dart

README.md

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,164 @@
1-
# MeshMapper_Flutter_App
1+
# MeshMapper Flutter App
2+
3+
Cross-platform wardriving app for MeshCore devices. A Flutter port of the [MeshMapper WebClient](https://github.com/MeshMapper/MeshMapper_WebClient).
4+
5+
## Features
6+
7+
- **Cross-Platform**: Runs on Android, iOS, and Web (Chrome/Edge)
8+
- **BLE Connectivity**: Connect to MeshCore devices via Bluetooth Low Energy
9+
- **GPS Tracking**: High-accuracy location tracking with 25m distance filter
10+
- **Geofencing**: Enforces 150km boundary from Ottawa (service area)
11+
- **Auto-Power Selection**: Automatically configures TX power based on device model
12+
- **Real-time Map**: View TX/RX ping markers on OpenStreetMap
13+
- **API Queue**: Persistent queue with batch upload and retry logic
14+
- **Dark Mode**: System theme support
15+
16+
## Screenshots
17+
18+
*Coming soon*
19+
20+
## Getting Started
21+
22+
### Prerequisites
23+
24+
- [Flutter SDK](https://flutter.dev/docs/get-started/install) 3.2.0 or higher
25+
- For Android: Android SDK with API 21+
26+
- For iOS: Xcode 14+ and iOS 12+ deployment target
27+
- For Web: Chrome or Edge browser (Safari not supported for Web Bluetooth)
28+
29+
### Installation
30+
31+
1. Clone the repository:
32+
```bash
33+
git clone https://github.com/MeshMapper/MeshMapper_Flutter_App.git
34+
cd MeshMapper_Flutter_App
35+
```
36+
37+
2. Install dependencies:
38+
```bash
39+
flutter pub get
40+
```
41+
42+
3. Run the app:
43+
```bash
44+
# For Android/iOS
45+
flutter run
46+
47+
# For Web
48+
flutter run -d chrome
49+
```
50+
51+
## Project Structure
52+
53+
```
54+
lib/
55+
├── main.dart # App entry point
56+
├── models/ # Data models
57+
├── services/ # Business logic
58+
│ ├── bluetooth/ # BLE abstractions
59+
│ ├── meshcore/ # MeshCore protocol
60+
│ └── ... # GPS, API, etc.
61+
├── providers/ # State management
62+
├── screens/ # Full-page UI
63+
└── widgets/ # Reusable components
64+
65+
assets/
66+
└── device-models.json # Device database
67+
68+
docs/
69+
├── ARCHITECTURE.md # System design
70+
└── PORTING_NOTES.md # JS→Dart translation
71+
```
72+
73+
## Supported Devices
74+
75+
The app supports 30+ MeshCore device variants including:
76+
77+
- **Ikoka**: Stick, Nano, Handheld (22dBm, 30dBm, 33dBm variants)
78+
- **Heltec**: V2, V3, V4, T114, T190, E213, E290, MeshPocket
79+
- **RAK**: 4631, 3x72
80+
- **LilyGo**: T-Echo, T-Deck, T-Beam, T-LoRa
81+
- **Seeed**: Wio E5, Wio Tracker, T1000, Xiao variants
82+
- And more...
83+
84+
See `assets/device-models.json` for the full list.
85+
86+
## Usage
87+
88+
### Connecting to a Device
89+
90+
1. Tap the Bluetooth icon in the app bar
91+
2. Tap "Scan" to search for nearby MeshCore devices
92+
3. Select your device from the list
93+
4. The app will automatically:
94+
- Connect via BLE
95+
- Query device info
96+
- Configure TX power based on device model
97+
- Sync time
98+
- Acquire API slot
99+
100+
### Wardriving
101+
102+
1. Ensure GPS is enabled and permissions granted
103+
2. Wait for GPS lock (green GPS indicator)
104+
3. Tap the "PING" button to send a TX ping
105+
4. Or enable "Auto Ping" to automatically ping every 25m of movement
106+
107+
### Understanding the Map
108+
109+
- **Green markers**: Your TX pings
110+
- **Colored markers**: RX responses from repeaters (color by repeater ID)
111+
- **Blue circle**: Your current position
112+
113+
## Critical Safety Notes
114+
115+
⚠️ **PA Amplifier Devices**: The app automatically configures TX power for high-power PA amplifier devices. Do NOT manually override power settings as incorrect values can damage hardware.
116+
117+
⚠️ **Geofence**: Pings are only allowed within 150km of Ottawa. This is enforced both client-side and server-side.
118+
119+
## Development
120+
121+
### Running Tests
122+
123+
```bash
124+
flutter test
125+
```
126+
127+
### Building for Release
128+
129+
```bash
130+
# Android
131+
flutter build apk --release
132+
133+
# iOS
134+
flutter build ios --release
135+
136+
# Web
137+
flutter build web --release
138+
```
139+
140+
## Architecture
141+
142+
The app follows a service-oriented architecture:
143+
144+
- **BluetoothService**: Abstract interface with platform-specific implementations
145+
- **MeshCoreConnection**: Handles the 10-step connection workflow and protocol
146+
- **GpsService**: GPS tracking with geofence validation
147+
- **PingService**: TX/RX ping orchestration
148+
- **ApiQueueService**: Persistent upload queue with retry logic
149+
150+
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for details.
151+
152+
## Contributing
153+
154+
Contributions are welcome! Please read the [PORTING_NOTES.md](docs/PORTING_NOTES.md) for guidance on the JavaScript to Dart translation patterns used.
155+
156+
## License
157+
158+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
159+
160+
## Acknowledgments
161+
162+
- Original [MeshMapper WebClient](https://github.com/MeshMapper/MeshMapper_WebClient)
163+
- [MeshCore](https://github.com/meshcore-dev/MeshCore) firmware project
164+
- Flutter and Dart teams

analysis_options.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
include: package:flutter_lints/flutter.yaml
2+
3+
linter:
4+
rules:
5+
- prefer_const_constructors
6+
- prefer_const_declarations
7+
- prefer_const_literals_to_create_immutables
8+
- avoid_print
9+
- prefer_single_quotes
10+
- sort_child_properties_last
11+
- use_key_in_widget_constructors
12+
- prefer_final_fields
13+
- prefer_final_locals
14+
- unnecessary_this
15+
- prefer_is_empty
16+
- prefer_is_not_empty
17+
18+
analyzer:
19+
errors:
20+
invalid_annotation_target: ignore
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
2+
<!-- Bluetooth permissions for BLE scanning and connecting -->
3+
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
4+
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
5+
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
6+
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
7+
8+
<!-- Location permissions for GPS and BLE scanning -->
9+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
10+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
11+
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
12+
13+
<!-- BLE hardware feature -->
14+
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
15+
16+
<!-- Internet for API uploads -->
17+
<uses-permission android:name="android.permission.INTERNET" />
18+
19+
<application
20+
android:label="MeshMapper"
21+
android:name="${applicationName}"
22+
android:icon="@mipmap/ic_launcher">
23+
<activity
24+
android:name=".MainActivity"
25+
android:exported="true"
26+
android:launchMode="singleTop"
27+
android:taskAffinity=""
28+
android:theme="@style/LaunchTheme"
29+
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
30+
android:hardwareAccelerated="true"
31+
android:windowSoftInputMode="adjustResize">
32+
<!-- Specifies an Android theme to apply to this Activity as soon as
33+
the Android process has started. This theme is visible to the user
34+
while the Flutter UI initializes. After that, this theme continues
35+
to determine the Window background behind the Flutter UI. -->
36+
<meta-data
37+
android:name="io.flutter.embedding.android.NormalTheme"
38+
android:resource="@style/NormalTheme"
39+
/>
40+
<intent-filter>
41+
<action android:name="android.intent.action.MAIN"/>
42+
<category android:name="android.intent.category.LAUNCHER"/>
43+
</intent-filter>
44+
</activity>
45+
<!-- Don't delete the meta-data below.
46+
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
47+
<meta-data
48+
android:name="flutterEmbedding"
49+
android:value="2" />
50+
</application>
51+
<!-- Required to query activities that can process text, see:
52+
https://developer.android.com/training/package-visibility and
53+
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
54+
55+
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
56+
<queries>
57+
<intent>
58+
<action android:name="android.intent.action.PROCESS_TEXT"/>
59+
<data android:mimeType="text/plain"/>
60+
</intent>
61+
</queries>
62+
</manifest>

0 commit comments

Comments
 (0)