Commit Graph

132 Commits

Author SHA1 Message Date
James Rich
439dee7134 fix: use Node.isOnline instead of hardcoded 30s threshold
The model's isOnline property uses the project-standard 2-hour window
(onlineTimeThreshold), consistent with getMeshStatus().onlineNodeCount.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 17:50:16 -05:00
James Rich
65a4d4f692 fix: propagate SendMessageUseCase errors and add provider/resolver tests
- SendMessageUseCase now rethrows exceptions after logging (Finding #1)
- AiFunctionProviderImpl catches send failures and returns InvalidArgument
- Added AiFunctionProviderImplTest with 10 unit tests covering:
  - Disconnection checks for all three function groups
  - Node lookup (found, not found, null position, invalid hex)
  - Metrics aggregation (active nodes, empty, zero lastHeard, degraded health)
  - Rate limiting behavior
- Expanded FuzzyNameResolverTest with 8 behavioral tests (Finding #5):
  - resolveNodeName: exact, fuzzy, ambiguous, not found
  - resolveChannelName: exact, admin exclusion, empty channels

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 17:43:54 -05:00
James Rich
a629336642 Fix review findings: timeout handling, cancellation, docs
- Add TimeoutCancellationException handling to getNodeDetails and getMeshMetrics
  AppFunctions (consistent with Phase 1 functions)
- Rethrow CancellationException in all provider catch blocks to preserve
  structured concurrency semantics
- Fix voltage documentation: millivolts → volts (matches actual Float field)
- Fix stale test comment referencing non-existent test class

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 17:17:14 -05:00
James Rich
175602102e Fix Phase 2b edge case: mostRecentPacketTime when all nodes have lastHeard=0
- Add takeIf check to distinguish lastHeard=0 (never heard) from no nodes
- Previously: maxOfOrNull returns 0, Elvis operator doesn't trigger (0 is not null)
- Now: takeIf { it > 0 } filters out zero, falling back to current time
- Ensures API returns meaningful timestamp instead of epoch 1970

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 15:54:50 -05:00
James Rich
3e9fdde9a6 Fix Phase 2b critical data integrity issues
- Fix location filtering: Only treat (0,0) as invalid if position.time is 0
  - Previously filtered all (0,0) coords as null, losing valid equatorial data
  - Now checks position.time to distinguish 'no fix' from real coordinates

- Fix mostRecentPacketTime: Use max lastHeard from all nodes, not current time
  - Previously returned current time, making mesh appear always active
  - Now computes from actual node activity data

- Fix meshUptimeSeconds: Use local device's actual uptime, not epoch time
  - Previously returned epoch seconds (~1.7B), not elapsed time
  - Now uses device's DeviceMetrics.uptime_seconds

All checks passing: Android (Google/fdroid), detekt, spotless, unit tests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 15:46:31 -05:00
James Rich
1abdd1a143 Phase 2b: Add getNodeDetails and getMeshMetrics App Functions
- Extend AiFunctionProvider with two new suspend methods for advanced queries
- getNodeDetails: Retrieve per-node telemetry (16 fields) by hex or user ID
- getMeshMetrics: Aggregate mesh statistics and compute health score
- Add result types (GetNodeDetailsResult, GetMeshMetricsResult) and data models
- Add response models (@AppFunctionSerializable) for KSP serialization
- Both methods support timeout protection and rate limiting
- Health score calculation: 50 base + 50 online ratio, clamped 0-100
- All JVM, Android, detekt, spotless checks passing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 15:36:54 -05:00
James Rich
e9dbb23bd5 Phase 2a: Add non-destructive AppFunctions (getNodeList, getChannelInfo, getDeviceStatus)
Implement three Phase 2a read-only query functions for AI agent integration:

Core Data (commonMain):
- Extended AiFunctionProvider interface with 3 new methods
- Implemented getNodeList() - queries all mesh nodes with battery and online status
- Implemented getChannelInfo() - lists mesh channels with settings
- Implemented getDeviceStatus() - returns local device info and status
- Added result types: GetNodeListResult, GetChannelInfoResult, GetDeviceStatusResult
- Added data models: NodeSummary, ChannelSummary, DeviceStatus
- All functions protected by timeout (5s), rate limiter (5 calls/60s), connection check

Android AppFunctions:
- Added 3 @AppFunction methods with KSP annotations
- Response models marked @AppFunctionSerializable for AI runtime
- Proper exception handling and timeout protection

Constants:
- HEX_RADIX (16): For node ID formatting
- MS_PER_SEC (1000): Time unit conversions
- ONLINE_THRESHOLD_MS (30000): Node online detection threshold

Fixes:
- Use node.user.long_name (not longName)
- Use node.deviceMetrics.battery_level?.coerceIn() for nullable battery
- Use nodeRepository.nodeDBbyNum (not nodes)
- Convert node.lastHeard (seconds) to milliseconds
- Suppress MagicNumber and ReturnCount lints appropriately

All builds and tests pass:
✓ :core:data:compileKotlinJvm
✓ :androidApp:compileGoogleDebugKotlin
✓ :androidApp:compileFdroidDebugKotlin
✓ detekt clean
✓ spotlessApply clean
✓ :core:data:allTests pass

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 15:19:12 -05:00
James Rich
d66c393732 fix: Return unique messageId from SendMessageUseCase
Previously, AiFunctionProviderImpl returned a hardcoded messageId of 0
for all successful sends, preventing unique message identification. The
underlying SendMessageUseCase generates a packetId but had no return
value to expose it.

Changes:
- Modified SendMessageUseCase interface to return Int (the packetId)
- Updated SendMessageUseCaseImpl to return the generated packetId
- Updated AiFunctionProviderImpl to capture and use the returned messageId

This enables the AI system to track individual messages and correlate
responses to specific send requests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 14:23:59 -05:00
James Rich
88c6cf98a8 feat: add App Functions integration for system AI assistants
Expose Meshtastic mesh networking capabilities (sendMessage, getMeshStatus)
to Android system AI agents via the App Functions API.

Architecture:
- AiFunctionProvider interface in core/data commonMain (platform-agnostic)
- FuzzyNameResolver for node/channel name matching (LCS algorithm)
- RateLimiter with 5-call/60s sliding window to protect mesh radio
- AiFunctionProviderImpl wiring repositories and use cases
- @AppFunction declarations in androidApp Google flavor only
- GoogleMeshUtilApplication with AppFunctionConfiguration.Provider
- DI via AppFunctionsModule included in FlavorModule

Key design decisions:
- No confirmation dialog (AI invocation = user intent)
- Fuzzy name matching with 50% LCS threshold, error on ambiguity
- Admin channels excluded from resolution
- 5-second operation timeout
- 237-byte message length limit (Meshtastic standard)

Includes unit tests for RateLimiter and FuzzyNameResolver (LCS algorithm).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 10:50:22 -05:00
James Rich
4c09377ba5 fix: use single-shot low battery notifications (#5550)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-20 21:53:44 +00:00
James Rich
877909fa94 fix: prevent node details hang when device hardware API is unreachable (#5514)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-19 20:37:42 -05:00
James Rich
f4b6b02ace refactor(build): rename entry modules and remove DESKTOP_ONLY mode (#5476)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 12:44:12 +00:00
Ben Meadors
a04a261b80 feat: TAK v2 protocol integration with zstd compression and full CoT type support (#5434)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jamesarich <2199651+jamesarich@users.noreply.github.com>
Co-authored-by: James Rich <james.a.rich@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-14 12:50:01 +00:00
James Rich
0f2b1c064a fix: clamp future lastHeard timestamps to current time on ingestion (#5418)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-12 07:35:11 -05:00
James Rich
10c5b5db2e feat(api): add hasAnyEntries method to local data sources and improve… (#5406) 2026-05-11 19:34:41 -05:00
James Rich
95c3bc0bce Brownfield gap remediation: 28 tasks + intro commonMain migration (#5401)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-11 20:10:23 +00:00
James Rich
3c75510f01 fix(mqtt): harden TLS enforcement, add user CA trust, and improve error diagnostics (#5365)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-06 12:09:49 -05:00
James Rich
400e0404f6 fix(data): default new-node notifications off for event firmware (#5323) 2026-05-02 02:02:30 +00:00
James Rich
e198f52de5 refactor(coroutines): migrate to kotlinx-coroutines 1.11.0-rc02 (#5312)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-01 03:11:22 +00:00
James Rich
2822290908 refactor(build): build-logic cleanup, CC safety, and detekt 2.0 upgrade (#5311) 2026-05-01 02:48:37 +00:00
James Rich
3d2b21843e refactor: update user lookups and localize traceroute responses (#5294) 2026-04-29 16:42:02 +00:00
James Rich
bbb7f8b23f fix(crashlytics): resolve beta 2.7.14 crash issues (#5245)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-25 19:23:21 +00:00
James Rich
f14ae2643c feat(node): smoother remote-admin UX with per-node session tracking (#5217)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-22 14:21:04 -05:00
James Rich
765594f7ee fix: MQTT proxy connection and probe test failures (#5215)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-22 11:05:24 -05:00
James Rich
f21d8af9ae fix(transport): improve BLE / TCP / USB reconnect and handshake resilience (#5196)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 17:34:16 +00:00
James Rich
14e86b90f1 feat(mqtt): adopt mqttastic-client-kmp 0.2.0 — disconnect reasons + Test Connection (#5181)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 21:33:55 -05:00
James Rich
cdeb1ac532 fix: redact MeshLog proto secrets and centralize Compose keep-rules (#5166)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 16:20:50 +00:00
James Rich
a97f704300 feat(mqtt): migrate to MQTTastic-Client-KMP (#5165)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 15:19:08 +00:00
James Rich
17e69c6d4c chore: review-cleanup fleet (audit + fix + hardening) (#5158) 2026-04-17 00:02:59 +00:00
James Rich
878905aea3 perf(messaging): batch node + reply lookups in message loading (#5149)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 15:48:26 +00:00
James Rich
84621acb04 fix: align BLE connection handshake with firmware protocol expectations (#5141)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 11:55:15 +00:00
James Rich
72b981f73b chore: KMP audit — commonize code, centralize utilities, eliminate dead abstractions (#5133)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-15 02:17:50 +00:00
James Rich
938a951737 refactor: leverage CMP 1.11 + Lifecycle 2.11 — v2 test API, Json privacy, dropUnlessResumed nav guards (#5112) 2026-04-13 20:02:31 +00:00
James Rich
e85300531e refactor(transport): complete transport architecture overhaul — extract callback, wire BleReconnectPolicy, fix safety issues (#5080) 2026-04-12 04:22:18 +00:00
James Rich
9468bc6ebe refactor(service): unify dual connectionState flows into single source of truth (#5077) 2026-04-12 00:50:52 +00:00
James Rich
5e44cbd3a9 fix(data): make MeshConnectionManagerImpl.onConnectionChanged atomic (#5076) 2026-04-12 00:49:09 +00:00
James Rich
62264b10c6 refactor(model): remove ConnectionState helper methods and fix updateStatusNotification return type (#5074) 2026-04-11 23:41:34 +00:00
James Rich
174315b21f refactor(data): replace lateinit var scope + start() with constructor injection (#5075) 2026-04-11 23:39:29 +00:00
James Rich
a3c0a4832d fix(transport): Kable BLE audit + thread-safety, MQTT, and logging fixes across transport layers (#5071) 2026-04-11 22:56:29 +00:00
James Rich
14b381c1eb fix: harden reliability, clean up KMP compliance, and improve code quality (#5023) 2026-04-09 18:21:46 +00:00
James Rich
60cc2f4237 fix: resolve bugs across connection, PKI, admin, packet flow, and stability subsystems (#5011) 2026-04-09 13:20:06 +00:00
James Rich
b3be9e2c38 fix: improve PKI message routing and resolve database migration racecondition (#4996) 2026-04-05 00:37:20 +00:00
James Rich
6af3ad6f0c refactor(service): harden KMP service layer — database init, connection reliability, handler decomposition (#4992) 2026-04-04 18:07:44 +00:00
James Rich
51251ab16a feat(ci): shard test suite and enable JUnit 5 parallel execution (#4977) 2026-04-03 13:08:49 +00:00
James Rich
0167063497 feat(analytics): expand DataDog RUM integration and align with iOS parity (#4970) 2026-04-01 20:27:28 +00:00
James Rich
e249461e3c feat(tak): introduce built-in Local TAK Server and mesh integration (#4951)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
2026-04-01 20:21:25 +00:00
James Rich
c75c9b34d6 feat: implement XModem file transfers and enhance BLE connection robustness (#4959) 2026-03-31 03:49:31 +00:00
James Rich
a005231d94 Refactor map layer management and navigation infrastructure (#4921)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
2026-03-26 00:29:24 +00:00
James Rich
6516287c62 refactor: BLE transport and UI for Kotlin Multiplatform unification (#4911)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
2026-03-25 02:15:51 +00:00
James Rich
96060a0a4d refactor: coroutine dispatchers and modernize testing infrastructure (#4901)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
2026-03-24 01:31:48 +00:00