Skip to content

Commit fee517c

Browse files
committed
Inital Release of Andriod APK.
1 parent a9798e7 commit fee517c

File tree

140 files changed

+15125
-1075
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

140 files changed

+15125
-1075
lines changed

.claude/settings.local.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(flutter analyze:*)",
5+
"Bash(flutter build web:*)",
6+
"Bash(echo:*)",
7+
"Bash(sed:*)",
8+
"Bash(flutter pub get:*)",
9+
"Bash(curl:*)",
10+
"Bash(flutter --version:*)",
11+
"Bash(flutter pub run build_runner:*)",
12+
"Bash(flutter build:*)",
13+
"Bash(flutter doctor:*)",
14+
"Bash(flutter create:*)",
15+
"Bash(find:*)"
16+
]
17+
}
18+
}

.metadata

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: "3b62efc2a3da49882f43c372e0bc53daef7295a6"
8+
channel: "stable"
9+
10+
project_type: app
11+
12+
# Tracks metadata for the flutter migrate command
13+
migration:
14+
platforms:
15+
- platform: root
16+
create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6
17+
base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6
18+
- platform: ios
19+
create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6
20+
base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6
21+
22+
# User provided section
23+
24+
# List of Local paths (relative to this file) that should be
25+
# ignored by the migrate tool.
26+
#
27+
# Files that are not part of the templates will be ignored by default.
28+
unmanaged_files:
29+
- 'lib/main.dart'
30+
- 'ios/Runner.xcodeproj/project.pbxproj'

.vscode/tasks.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "Flutter: Build & Serve Web",
6+
"type": "shell",
7+
"command": "
8+
",
9+
"isBackground": true,
10+
"problemMatcher": [],
11+
"group": "build",
12+
"presentation": {
13+
"echo": true,
14+
"reveal": "always",
15+
"focus": false,
16+
"panel": "dedicated",
17+
"showReuseMessage": false
18+
}
19+
}
20+
]
21+
}

CLAUDE.md

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
MeshMapper Flutter App is a cross-platform wardriving application for MeshCore mesh network devices. It's a Flutter port of the [MeshMapper WebClient](https://github.com/MeshMapper/MeshMapper_WebClient), supporting Android, iOS, and Web (Chrome/Edge only).
8+
9+
**Purpose**: Connect to MeshCore devices via Bluetooth Low Energy, send GPS-tagged pings to the `#wardriving` channel, track repeater echoes, and post coverage data to the MeshMapper API for community mesh mapping.
10+
11+
**Tech Stack**: Flutter 3.2.0+, Dart 3.2.0+, Hive for local storage, Provider for state management
12+
13+
## Common Commands
14+
15+
### Development
16+
```bash
17+
# Install dependencies
18+
flutter pub get
19+
20+
# Run code generation (for Hive models)
21+
flutter pub run build_runner build --delete-conflicting-outputs
22+
23+
# Run the app
24+
flutter run # Android/iOS (defaults to connected device)
25+
flutter run -d chrome # Web (Chrome required for Web Bluetooth)
26+
flutter run -d chrome --web-browser-flag="--disable-web-security" # For local testing with CORS
27+
28+
# Analyze code
29+
flutter analyze
30+
31+
# Run tests
32+
flutter test
33+
34+
# Run a single test file
35+
flutter test test/services/gps_service_test.dart
36+
```
37+
38+
### Building for Release
39+
```bash
40+
# Android APK
41+
flutter build apk --release
42+
43+
# iOS
44+
flutter build ios --release
45+
46+
# Web
47+
flutter build web --release
48+
```
49+
50+
### Debug Logging
51+
- Web: Add `?debug=1` to URL to enable debug logging in browser console
52+
- Mobile: Debug logging always enabled via `debugPrint()`
53+
54+
## Architecture
55+
56+
### Service-Oriented Architecture
57+
58+
The app uses a layered service architecture with clear separation of concerns:
59+
60+
**Bluetooth Abstraction Layer** (`lib/services/bluetooth/`):
61+
- `BluetoothService`: Abstract interface for BLE operations
62+
- `MobileBluetoothService`: Android/iOS implementation using `flutter_blue_plus`
63+
- `WebBluetoothService`: Web implementation using `flutter_web_bluetooth`
64+
- Platform selection happens at runtime in `main.dart` using `kIsWeb`
65+
66+
**MeshCore Protocol Layer** (`lib/services/meshcore/`):
67+
- `MeshCoreConnection`: Implements the 10-step connection workflow and MeshCore companion protocol
68+
- `PacketParser`: Binary packet parsing with BufferReader/Writer utilities
69+
- `UnifiedRxHandler`: Routes ALL incoming BLE packets to TX tracking or RX logging
70+
- `TxTracker`: Detects repeater echoes during 7-second window after sending ping
71+
- `RxLogger`: Logs passive mesh observations, buffers by repeater ID
72+
- `ChannelService`: Channel hash computation and management
73+
- `CryptoService`: SHA-256 channel key derivation, AES-ECB message decryption
74+
75+
**Application Services** (`lib/services/`):
76+
- `GpsService`: GPS tracking with 150km geofence from Ottawa (45.4215, -75.6972)
77+
- `PingService`: TX/RX ping orchestration, coordinates with TxTracker/RxLogger
78+
- `ApiQueueService`: Hive-based persistent upload queue with batch POST and retry logic
79+
- `ApiService`: HTTP client for MeshMapper API endpoints
80+
- `DeviceModelService`: Loads `assets/device-models.json` and auto-configures TX power
81+
82+
**State Management** (`lib/providers/`):
83+
- `AppStateProvider`: Single ChangeNotifier for all app state using Provider pattern
84+
- All UI updates happen via `notifyListeners()` after state mutations
85+
86+
### 10-Step Connection Workflow
87+
88+
Critical safety: The connection sequence MUST complete in order. See `docs/CONNECTION_WORKFLOW.md` for details.
89+
90+
1. **BLE GATT Connect**: Platform-specific BLE connection
91+
2. **Protocol Handshake**: `deviceQuery()` with protocol version
92+
3. **Device Info**: `getDeviceName()`, `getPublicKey()`, `getDeviceSettings()`
93+
4. **Auto-Power Configuration**: Parse manufacturer string, match against `device-models.json`, set power level
94+
5. **Time Sync**: `sendTime()` syncs device clock
95+
6. **API Slot Acquisition**: POST to `/capacitycheck.php` to reserve API slot
96+
7. **Channel Setup**: Create or use existing `#wardriving` channel
97+
8. **GPS Init**: Acquire GPS lock
98+
9. **Start Unified RX Handler**: Begin processing ALL incoming packets
99+
10. **Connected State**: Ready for wardriving
100+
101+
**Critical Power Safety**: PA amplifier devices (30dBm, 33dBm) require specific input power levels. Incorrect values can damage hardware. Auto-power selection from device-models.json is MANDATORY for these devices.
102+
103+
### Unified RX Handler Architecture
104+
105+
**Key Principle**: Accept ALL incoming BLE packets, parse metadata ONCE at entry point, then route to specialized handlers. Never filter by header at entry.
106+
107+
**Flow**:
108+
```
109+
BLE LogRxData Event
110+
111+
UnifiedRxHandler._handleLogRxData()
112+
113+
Parse PacketMetadata (ONCE)
114+
115+
┌────┴────┐
116+
↓ ↓
117+
TX Track RX Log
118+
(echoes) (passive)
119+
↓ ↓
120+
7s window Buffer by repeater
121+
↓ ↓
122+
Update UI Flush to API queue
123+
```
124+
125+
**TX Tracking** (during 7-second window after ping):
126+
- Validates: GROUP_TEXT header, RSSI < -30dBm, channel hash match, decrypted message match, path length > 0
127+
- Deduplicates by first hop (repeater ID), keeps best SNR
128+
- Updates UI with repeater counts
129+
130+
**RX Logging** (continuous passive monitoring):
131+
- Validates: path length > 0, valid GPS, channel hash in allowed list, decrypts successfully, 90% printable chars, RSSI < -30dBm
132+
- Buffers per repeater with GPS coordinates
133+
- Flushes to API queue on 25m movement OR 30s timeout
134+
- Maintains in-memory log (max 100 entries) for UI
135+
136+
### GPS & Geofencing
137+
138+
- Uses `geolocator` package with high accuracy and continuous tracking
139+
- **Ottawa Geofence**: 150km radius from Parliament Hill (45.4215, -75.6972) - hard boundary enforced client-side AND server-side
140+
- **Min Distance Filter**: 25m between pings prevents spam
141+
- **GPS Freshness**: Manual pings tolerate 60s old GPS, auto pings require fresh acquisition
142+
143+
### API Queue System
144+
145+
Two independent data flows (TX pings, RX observations) merge into unified API batch queue:
146+
147+
- **Storage**: Hive-based persistent queue survives app restarts
148+
- **Batch Size**: Max 50 messages, auto-flush at 10 items or 30 seconds
149+
- **Payload Format**: `[{type:"TX"|"RX", lat, lon, who, power, heard, session_id, iatacode}]`
150+
- **Authentication**: API key in JSON body (NOT query string)
151+
- **Retry Logic**: Exponential backoff on failures
152+
153+
## Critical Protocol Details
154+
155+
### BLE Service UUIDs (MeshCore Companion Protocol)
156+
- Service: `6E400001-B5A3-F393-E0A9-E50E24DCCA9E`
157+
- RX Characteristic: `6E400002-B5A3-F393-E0A9-E50E24DCCA9E` (write to device)
158+
- TX Characteristic: `6E400003-B5A3-F393-E0A9-E50E24DCCA9E` (notifications from device)
159+
160+
### Channel Key Derivation
161+
- **Hashtag channels** (`#wardriving`, `#testing`, `#ottawa`, `#wartest`): SHA-256 hash of channel name
162+
- **Public channel** (`Public`): Fixed key `8b3387e9c5cdea6ac9e5edbaa115cd72`
163+
- Channel hash (PSK identifier) computed at startup for `#wardriving`
164+
- Used for repeater echo detection and message decryption (AES-ECB via pointycastle)
165+
166+
### Packet Structure
167+
- Custom binary protocol with header byte (0x11 = GROUP_TEXT, 0x21 = ADVERT)
168+
- Path encoding: hop count + repeater IDs (4 bytes each)
169+
- SNR/RSSI metadata in BLE event payload
170+
- Encrypted message payload (AES-ECB with channel key)
171+
172+
## Platform-Specific Notes
173+
174+
### Web (Chrome/Edge only)
175+
- Safari NOT supported (no Web Bluetooth API)
176+
- Uses `flutter_web_bluetooth` package
177+
- Debug logging enabled via URL parameter `?debug=1`
178+
- CORS issues during local development - use `--web-browser-flag="--disable-web-security"`
179+
180+
### Android
181+
- Requires permissions: Bluetooth, Location (for BLE scanning)
182+
- minSdkVersion: 21 (Android 5.0+)
183+
- Background location permission for continuous tracking
184+
- Uses `flutter_blue_plus` package
185+
186+
### iOS
187+
- Requires Info.plist entries: NSBluetoothAlwaysUsageDescription, NSLocationWhenInUseUsageDescription
188+
- Deployment target: 12.0+
189+
- Background modes: bluetooth-central, location
190+
- Uses `flutter_blue_plus` package
191+
192+
## Development Workflow Requirements
193+
194+
### Debug Logging Convention (MANDATORY)
195+
All debug log messages MUST include a tag in square brackets:
196+
197+
```dart
198+
debugLog('[BLE] Connection established');
199+
debugLog('[GPS] Fresh position acquired: lat=45.12345');
200+
debugLog('[PING] Sending ping to channel 2');
201+
debugLog('[RX] Buffering observation for repeater 0xABCD1234');
202+
```
203+
204+
**Required Tags**: `[BLE]`, `[CONN]`, `[GPS]`, `[PING]`, `[API QUEUE]`, `[RX BATCH]`, `[RX]`, `[TX]`, `[DECRYPT]`, `[CRYPTO]`, `[UI]`, `[CHANNEL]`, `[TIMER]`, `[WAKE LOCK]`, `[GEOFENCE]`, `[CAPACITY]`, `[AUTO]`, `[INIT]`, `[MODEL]`, `[MAP]`
205+
206+
Never log without a tag. See `docs/DEVELOPMENT_REQUIREMENTS.md` for complete list.
207+
208+
### Documentation Update Requirements
209+
210+
When modifying code, you MUST also update relevant documentation:
211+
212+
1. **Connection workflow changes** → Update `docs/CONNECTION_WORKFLOW.md` (steps, states, error handling)
213+
2. **Ping/auto-ping changes** → Update `docs/PING_WORKFLOW.md` (validation, lifecycle, UI impacts)
214+
3. **New status messages** → Add to `docs/STATUS_MESSAGES.md` (exact text, trigger, color)
215+
4. **Architectural changes** → Update this CLAUDE.md file
216+
217+
### Code Style
218+
- Use Dart documentation comments (`///`) for public classes and methods
219+
- Prefer `async`/`await` over `.then()` chains
220+
- Always wrap async operations in `try`/`catch` blocks
221+
- Use `debugError()` for logging errors before handling
222+
- State mutations via `AppStateProvider` with `notifyListeners()`
223+
224+
## Device Model Database
225+
226+
**File**: `assets/device-models.json`
227+
228+
Contains 30+ MeshCore device variants with manufacturer strings, TX power levels, and platform info:
229+
- **Ikoka**: Stick, Nano, Handheld (22dBm, 30dBm, 33dBm variants)
230+
- **Heltec**: V2, V3, V4, Wireless Tracker, MeshPocket
231+
- **RAK**: 4631, 3x72
232+
- **LilyGo**: T-Echo, T-Deck, T-Beam, T-LoRa
233+
- **Seeed**: Wio E5, T1000, Xiao variants
234+
235+
**Detection Flow**:
236+
1. `deviceQuery()` returns manufacturer string (e.g., "Ikoka Stick-E22-30dBm (Xiao_nrf52)nightly-e31c46f")
237+
2. `parseDeviceModel()` strips build suffix ("nightly-COMMIT")
238+
3. `findDeviceConfig()` searches database for exact/partial match
239+
4. `autoSetPowerLevel()` configures radio power automatically
240+
241+
**Critical Safety**: PA amplifier models MUST use specific power values:
242+
- 33dBm models: txPower=9, power=2.0
243+
- 30dBm models: txPower=20, power=1.0
244+
- Standard (22dBm): txPower=22, power=0.3
245+
246+
## MeshMapper API Endpoints
247+
248+
**Base URL**: `https://yow.meshmapper.net/`
249+
250+
- **POST /capacitycheck.php**: Acquire API slot before connecting
251+
- Payload: `{iatacode: "YOW", apikey: "...", apiver: "1.6.0"}`
252+
- Response: `{valid: true|false, reason: null|"outofdate"}`
253+
254+
- **POST /wardriving-api.php**: Batch upload TX/RX coverage data
255+
- Payload: `[{type:"TX"|"RX", lat, lon, who, power, heard, session_id, iatacode}]`
256+
- Auth: API key in JSON body (NOT query string)
257+
258+
## Common Pitfalls
259+
260+
1. **Unified RX Handler accepts ALL packets** - No header filtering at entry point. Session log tracking filters headers internally.
261+
262+
2. **GPS freshness varies by context** - Manual pings tolerate 60s old GPS data, auto pings force fresh acquisition.
263+
264+
3. **Control locking during ping lifecycle** - `sendPing()` disables all controls until API post completes. Must call unlock in ALL code paths (success/error).
265+
266+
4. **Disconnect cleanup order matters** - Flush API queue → Release capacity → Delete channel → Close BLE → Clear timers/GPS/wake locks → Reset state. Out-of-order causes errors.
267+
268+
5. **Platform-specific Bluetooth imports** - Use conditional exports (bluetooth_service.dart exports platform-specific implementation). Never import platform-specific files directly.
269+
270+
6. **Hive model generation required** - After modifying `@HiveType` classes, run `flutter pub run build_runner build --delete-conflicting-outputs`.
271+
272+
7. **Web Bluetooth requires HTTPS** - Development uses `flutter run -d chrome` which works, but production deployment needs HTTPS.
273+
274+
## Key File Reference
275+
276+
- `lib/main.dart` - App entry point, platform detection, theme
277+
- `lib/providers/app_state_provider.dart` - Global state management
278+
- `lib/services/meshcore/connection.dart` - 10-step connection workflow, MeshCore protocol
279+
- `lib/services/meshcore/unified_rx_handler.dart` - Packet routing (TX vs RX)
280+
- `lib/services/meshcore/tx_tracker.dart` - Repeater echo detection (7s window)
281+
- `lib/services/meshcore/rx_logger.dart` - Passive observation logging
282+
- `lib/services/ping_service.dart` - TX/RX ping orchestration
283+
- `lib/services/gps_service.dart` - GPS tracking and geofencing
284+
- `lib/services/api_queue_service.dart` - Persistent upload queue
285+
- `lib/services/device_model_service.dart` - Auto-power configuration
286+
- `assets/device-models.json` - Device database (30+ models)
287+
- `docs/CONNECTION_WORKFLOW.md` - Connection sequence documentation
288+
- `docs/PING_WORKFLOW.md` - Ping lifecycle documentation
289+
- `docs/UNIFIED_RX_HANDLER_PLAN.md` - RX handler architecture
290+
- `docs/DEVELOPMENT_REQUIREMENTS.md` - Coding standards
291+
292+
## Original WebClient Reference
293+
294+
This Flutter app is a port of the JavaScript-based WebClient. When implementing features:
295+
296+
1. Reference original implementation in `PORTED_APP/content/wardrive.js` (5200+ lines)
297+
2. Follow same architectural patterns (connection workflow, API queue, channel crypto)
298+
3. Maintain feature parity where possible
299+
4. Key differences:
300+
- Flutter uses Provider for state (not global state object)
301+
- Hive for persistent storage (not IndexedDB)
302+
- Platform-specific BLE implementations (not just Web Bluetooth)
303+
- Dart type safety (not dynamic JavaScript)
304+
305+
The `PORTED_APP/.github/copilot-instructions.md` file contains detailed documentation of the original WebClient architecture and is a valuable reference for understanding intended behavior.

PORTED_APP

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 46696a7484bc4216f8d7a98a27e0c4bad91424f5

android/.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
gradle-wrapper.jar
2+
/.gradle
3+
/captures/
4+
/gradlew
5+
/gradlew.bat
6+
/local.properties
7+
GeneratedPluginRegistrant.java
8+
.cxx/
9+
10+
# Remember to never publicly share your keystore.
11+
# See https://flutter.dev/to/reference-keystore
12+
key.properties
13+
**/*.keystore
14+
**/*.jks

0 commit comments

Comments
 (0)