feat: SDK improvements for Meshtastic-Android hard cutover#1
Merged
Conversation
Guard axionRelease plugin with gradle.parent == null so the SDK can be included as a Gradle composite build (e.g. from Meshtastic-Android) without the plugin erroring out trying to access the root project too early. Resolves UnknownDomainObjectException when the build is consumed as a composite dependency. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a RadioClient extension property that filters the raw packets flow
by TEXT_MESSAGE_APP portnum, giving callers a typed stream of text messages
without hand-decoding portnum on every packet.
RadioClient.textMessages: Flow<MeshPacket>
= packets.filter { it.decoded?.portnum == PortNum.TEXT_MESSAGE_APP }
Filter is portnum-based (not asText() != null) so that empty-payload
TEXT_MESSAGE_APP packets are included — callers that care about delivery
receipts or zero-length pings can distinguish the packet from 'no message'.
Also adds FakeRadioTransport.injectPacket(MeshPacket) to the testing module
so integration tests can exercise packet flows without constructing raw frames.
Tests (PayloadAccessorsTest):
- textMessagesEmitsTextPackets
- textMessagesExcludesNonTextPackets
- textMessagesIncludesEmptyPayloadTextPackets
- rawPacketsFlowReceivesInjected (diagnostic)
Test note: use runCurrent() not advanceUntilIdle() in engine integration
tests — advanceUntilIdle() advances virtual time past the 60 s liveness
timeout, triggering handleDisconnect and silently dropping all subsequent
injected frames.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Exposes a reactive channel list on RadioClient so callers don't have to
issue 8 serial admin RPCs (admin.listChannels()) just to read channels.
RadioClient.channels: StateFlow<List<Channel>?>
Seeding:
- Populated in the SeedingSession commit from pendingChannels (the
channel frames received during the Stage-1 handshake drain).
- Falls back to storage (loadChannels()) on reconnect sessions where
the device does not re-send channels (ifEmpty { null } so a known-
empty storage slot stays null rather than an empty list).
Write-through:
- AdminApiImpl.setChannel now calls engine.updateChannelAndPersist()
on success: atomically patches the in-memory StateFlow (StateFlow.update)
and enqueues a best-effort saveChannels() on engineScope.
- Guards invalid channel indices (< 0 or > MAX_CHANNEL_INDEX).
- Sparse gaps (idx > list.size) are silently skipped to avoid holes.
Lifecycle:
- Cleared to null in cleanup() so stale channels never leak into a
new session.
- Preserved across auto-reconnect resets (aligns with existing engine
comment: 'channels live across the cycle').
Imports: added ChannelIndex, kotlinx.coroutines.flow.update to MeshEngine.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…droid (Gap F)
Adds an androidMain-only factory function that creates a BleTransport from a
persisted MAC address string, eliminating the need for callers to manually
construct a Kable Peripheral before instantiating the transport.
On Android, Kable's Identifier is a String typealias. The factory calls
toIdentifier() on the address for forward-compatibility with Kable versioning,
then delegates to the primary BleTransport(peripheral, address) constructor.
Callers can supply a PeripheralBuilder action for GATT configuration:
BleTransport("AA:BB:CC:DD:EE:FF") { autoConnectIf { true } }
The autoConnectIf { true } flag is required for bonded devices that connect
without a fresh BLE advertisement (avoids GATT error 133). iOS MAC addresses
are UUIDs (NSUUID), not strings, so this factory is Android-specific and lives
in androidMain.
Compile-verified: :transport-ble:compileAndroidMain + :transport-ble:jvmTest pass.
Gap F workaround (BlePeripheralFactory.kt in Meshtastic-Android core:ble) can
now be replaced with this SDK factory.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- NodeDiff: populate NodeChange.Updated with actual changed fields - NodeStatus: isOnline(), ConnectionQuality, SignalQuality extensions - MeshNode: unified consumer-friendly node model with computed status - ConfigMerge: section-key-based merge for Gap G (configBundle refresh) - AdminApiImpl: track written configs, call applyConfigEdits() after commit - MeshEngine: flush dirty heartbeats on disconnect for presence restore - MeshEngine: detect external config/channel changes (Gap C refinement) - MeshEngine: telemetry→node update pipeline (maybeMergeDeviceMetrics) - PayloadAccessors: asWaypoint(), asTraceroute(), asNeighborInfo() - Node.kt: ExternalConfigChange event + ExternalChangeKind enum - MeshEngine: updateChannelAndPersist handles null→init channel list - Tests: ExternalConfigChangeTest, MeshNodeTest, PayloadAccessors additions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BUG-01 (CRITICAL): get_channel_request now sends 1-based index per admin.proto spec. Firmware expects index+1 to avoid proto3 zero-value omission. Without this, all channel reads returned BAD_REQUEST. BUG-02: Remove misleading preserveFavorites param from nodeDbReset(). Proto3 cannot encode false for the nodedb_reset field — firmware always preserves favorites during reset. Simplified API with clear docs. BUG-03: Replace fragile transport::class.simpleName check with transport.identity.raw prefix check. simpleName is erased by R8 minification; identity is a stable runtime value. PASSKEY-01: Reduce SESSION_PASSKEY_TTL from 24h to 4min. Firmware regenerates passkeys every ~150s (valid for ~300s). The 24h TTL meant every reconnect admin call failed once before re-seeding via retry. ASSUMPTION-01: Detect is_managed mode from SecurityConfig in config bundle. If device is managed, all admin commands from non-zero 'from' addresses are silently dropped by firmware. SDK now returns AdminResult.Unauthorized immediately instead of timing out. GAP-H3: Send 4×0x94 wake bytes before first want_config_id on stream-based transports (TCP/Serial). Required by protocol spec to resync firmware's frame decoder after unclean disconnect. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- protocol.md §16: Fix heartbeat nonce description (SDK uses nonce=0, not incrementing counter starting at 2) - protocol.md §13: Fix get_channel_request type annotation (uint32 1-based, not bool) - protocol.md §13: Correct session passkey TTL (~4min, not ~5min) - protocol.md §13: Document managed mode (is_managed) behavior - protocol.md §13: Document editSettings BLE disconnect side-effect - protocol.md: Clarify wake bytes are now sent (not just recommended) - SPEC.md + api-reference.md: Remove obsolete preserveFavorites param from nodeDbReset() signature Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GAP-A1: Add 18 missing AdminApi operations:
- toggleMuted(node)
- setFixedPosition(position), removeFixedPosition()
- getUIConfig(), storeUIConfig(config)
- getCannedMessages(), setCannedMessages(messages)
- getRingtone(), setRingtone(rtttl)
- getDeviceConnectionStatus(), getRemoteHardwarePins()
- setHamMode(params)
- enterDfuMode(), deleteFile(path)
- backupPreferences(location), restorePreferences(location),
removeBackupPreferences(location)
GAP-H1: Capture DeviceUIConfig during handshake:
- Add deviceUIConfig field to ConfigBundle
- Process FromRadio.deviceuiConfig in Stage 1 envelope handler
- Store in pendingDeviceUIConfig buffer, include in bundle assembly
GAP-T1: Add 3 missing telemetry request methods:
- requestHealth(node) → HealthMetrics
- requestHost(node) → HostMetrics
- requestTrafficManagement(node) → TrafficManagementStats
Also adds 5 new ResponseKind variants for the new admin RPC responses
(CannedMessages, Ringtone, DeviceConnectionStatus, RemoteHardwarePins,
DeviceUIConfig).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds the remaining AdminMessage operations to achieve 100% coverage of the admin.proto payload_variant oneOf: - removeNode(node) — remove a node from device NodeDB - setScale(scale) — e-ink display DPI calibration - sendInputEvent(event) — synthetic button/touch input - addContact(contact) — shared contact management - keyVerification(verification) — key verification exchange - rebootOta(after) — reboot into OTA update mode - otaRequest(event) — firmware update control - setSensorConfig(config) — attached sensor configuration - exitSimulator() — exit firmware simulator (dev only) The SDK AdminApi now exposes every admin operation defined in the meshtastic protobufs spec. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expose a public escape hatch on RadioClient for sending raw ToRadio frames that aren't MeshPackets. This is needed by consumers that manage MQTT client proxy messages and XModem file transfers — both are non-packet ToRadio variants that the engine passes directly to the transport without internal tracking. The MeshEngine.sendToRadio() method visibility is changed from private to internal so RadioClient can delegate to it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d surface SDK gap implementation for multi-client consumption: Protocol Utilities (S1): - DeviceCapabilities: firmware version parsing + capability gates - NodeIds: toDefaultId()/fromDefaultId() conversions - SfppHash: SFPP message deduplication hash - ChannelUrls: channelNameHashDjb2() for channel identification - PositionUtils: Haversine distance, bearing, coordinate validation Missing APIs (S2): - SharedContactUrl: contact URL encoding/decoding - ConnectionState extensions: isUsable, isInProgress, statusMessage - RouteDiscoveryResult: traceroute result model from proto - NodeChange.WentOffline/CameOnline: presence event types - NeighborInfo: parsed neighbor info model Higher-Level Features (S3): - ChannelHelpers: validation, findEmptySlot, createSettings - RetryPolicy: None/Fixed/ExponentialBackoff strategies - CongestionLevel + CongestionMetrics: mesh congestion awareness - MeshEvent: CongestionWarning, MqttConnected, MqttDisconnected Store-and-Forward (S4): - StoreForwardApi interface + StoreForwardStats + StoreForwardEvent All features are KMP commonMain with full test coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ion, Store-and-Forward impl Engine Wiring: - E1: CongestionMetrics emission on telemetry level transitions (MeshEvent.CongestionWarning) - E2: Presence timer with configurable timeout (Builder.presenceTimeout), emits WentOffline/CameOnline - E3: MessageHandle.retryWith(policy) suspend extension for structured retries - E4: StoreForwardApiImpl — RPC dispatch, server discovery, event emission via RadioClient.storeForward Integration Tests: - CongestionEmissionTest: threshold transitions, zero suppression, per-node tracking - PresenceTimerTest: stale→offline, recovery→online, self-exclusion - MessageHandleRetryTest: retry/no-retry/exhaustion/exponential-backoff - StoreForwardImplTest: instantiation, state, RPC smoke Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add SfppLinkProvided and SfppCanonAnnounced events to StoreForwardApi - StoreForwardApiImpl: parse SFPP packets, compute hashes, emit events - MeshTopology: incremental graph from NeighborInfo (BFS shortest path, SNR edges) - Tests for SFPP event emission and topology graph operations Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- MeshTopology: usage example, Edge KDoc, shortestPath return docs - RetryPolicy: document delayForAttempt null return - MeshTopologyTest: clear(), self-loop, disconnected components - StoreForwardApiImplSfppTest: malformed payloads, null hash, unknown type Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…opology doc - SfppLinkProvided.to now emits normalized destination (broadcast 0 → NodeId.BROADCAST) so consumers can reliably correlate/recompute hashes from event data - MeshTopology KDoc: remove false thread-safety claim (unsynchronized mutableMap) - Update SFPP test to assert normalized broadcast destination Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- AdminApi.forNode(dest): returns a remote-targeting AdminApi instance that routes all admin calls to the specified mesh node - AdminApi.getDeviceMetadata(): request DeviceMetadata from target node - RadioClient.sendReaction(): convenience for emoji reactions with proper emoji indicator and reply_id These additions eliminate the need for consumers to manually construct AdminMessage + MeshPacket envelopes for remote admin operations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- RadioClient.requestNodeInfo(node): sends NODEINFO_APP with want_response=true to request a remote node's identity - Fix AdminEditImpl.enqueueOrThrow to route through localNode() (respects targetNode for remote editSettings) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add getOrNull, getOrElse, isSuccess, map, fold, onSuccess, onFailure extensions to AdminResult for ergonomic API usage - Cache MeshTopology.nodes with invalidation on addNeighborInfo/removeNode/clear to avoid O(n) allocation on every access - Document threading risk on RadioClient.close() (runBlocking can ANR on main thread — prefer suspend disconnect() from coroutines) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…, error mapping
Phase 1 critical fixes:
1. MeshTopology thread-safety: All methods are now suspend with
internal Mutex synchronization. Safe for concurrent engine/UI access.
Property 'nodes' → function nodes(), 'edgeCount' → edgeCount().
2. submitAdminAck timeout: Wrap stateFlow.first{} with
withTimeoutOrNull(rpcTimeout) so ACK-based admin ops cannot block
forever if transport dies without emitting a terminal state.
3. Flow caching: RadioClient's public flow properties (connection,
ownNode, configBundle, channels, nodes, packets, events) are now
initialized once at construction — no new flow/StateFlow wrapper
created per property access.
4. Routing error mapping: Added AdminResult.RateLimited variant for
RATE_LIMIT_EXCEEDED. Fixed ACK-path mapSendFailureToAdminResult to
properly map ADMIN_BAD_SESSION_KEY → SessionKeyExpired and
ADMIN_PUBLIC_KEY_UNAUTHORIZED → Unauthorized (previously fell through
to generic Failed). CommandDispatcher also maps RateLimited.
5. Session passkey: Verified already fully implemented (engine stamps
all outgoing admin msgs, seeds from handshake, retryOnSessionExpiry
handles refresh).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rchy - getOrThrow() maps failure variants to typed exceptions for callers preferring exception-based error handling - AdminResultException sealed hierarchy with SessionKeyExpired, Unauthorized, Timeout, RateLimited, NodeUnreachable, RoutingFailed(error) - Improved toggleMuted KDoc (documents toggle-not-set firmware semantics) - Tests for all getOrThrow() failure paths, fold, and map Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- AdminApiImplComprehensiveTest: 75 tests covering all config/channel/device ops - MeshEngineEdgeCasesTest: 28 tests for malformed packets, dedup, encryption - HandshakeAndReconnectTest: handshake FSM, backoff, session key lifecycle - StoreForwardProtocolTest: server discovery, history, SFPP, multi-chunk Also hardens MeshEngine with frame validation and duplicate detection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…PI surface - Fix 5 sample compilation errors: add NodeChange.CameOnline/WentOffline branches (ConnectCmds.kt, TuiCmd.kt, MeshSampleController.kt) and AdminResult.RateLimited branches (Scenarios.kt x2) - Update api-reference.md: add CameOnline/WentOffline to NodeChange, RateLimited to AdminResult, forNode() to AdminApi, sendReaction()/ sendRaw() to Outbound table, StoreForwardApi full section, all 23 config builder extensions, StoreForwardStats/Event/Api to package map - Update error-taxonomy.md: add RateLimited to AdminResult listing, wire mapping table, and example when block - Update integration-guide.md: add §6 admin operations and config builders with editSettings/forNode examples - Update reactive-lifecycle-management.md: add WentOffline/CameOnline to NodeChange when example - Update meshtastic-android-migration.md: add presence variants to scan() accumulator and make AdminResult when exhaustive Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add KDoc to ~15 public API symbols (AutoReconnectConfig, BatteryStatus, ChannelHelpers, ChannelUrls, CongestionLevel, Connect, DeviceCapabilities) - Fix incomplete comment fragment in MeshEngine.kt - Update KeyVerificationPrompt: remove stale Phase-1 marker, clarify as marker interface pending PKI verification UI - Update RadioClient.Builder transport comment: Phase-2 → Future - Fix stale sample paths in docs/decisions/003-tooling.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 2 RPC dispatch, admin timeout, backpressure, and reconnect are all implemented. Remove 'Phase 2' labels from EngineMessage, CommandDispatcher, P2AdminRpcTest, and HandshakeFsmTest comments since they describe current behavior, not future plans. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Broadcast MessageHandle.await() would hang forever because the mesh never sends a Routing ACK for broadcasts. The engine now transitions broadcast sends to Acked immediately after dispatching to the transport. - MeshEngine.dispatchSend: auto-resolve broadcast (to=BROADCAST, no want_response) to Acked and remove from pendingSends - Scenarios: rename cs2 to 'broadcast text acceptance', add cs7 unicast DM scenario (requires --peer-node) - ConformanceCmd: wire cs7 into the conformance sweep - Tests: update 4 existing tests that assumed broadcast stays in Sent, add sendText_broadcastAutoResolvesToSuccess test 566 tests, 0 failures. Verified against real hardware (firmware 2.7.19): cs1 ✓ cs2 ✓ cs3 ✓ cs5 ✓ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Align with Apple/Android client behavior: sendText() now sets want_ack=true on all packets (including broadcasts). The firmware generates an implicit ACK when it overhears a neighbor relay the packet, providing relay confirmation. Engine changes: - Fire-and-forget broadcasts (want_ack=false) still auto-resolve - Broadcasts with want_ack=true arm the ACK timeout and wait for the firmware's implicit ACK (or timeout to Failed) - Removes the unconditional broadcast auto-resolve that previously reported success before the radio even transmitted This gives consumers meaningful feedback: Success means at least one mesh node relayed the message. Failure (AckTimeout) means no relay was overheard within the timeout window. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace wildcard import in StoreForwardApiTest with explicit imports - Apply spotless formatting across source and test files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Regenerated via :core:updateKotlinAbi to reflect new public API surface. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR closes multiple SDK gaps discovered during a hard cutover integration into Meshtastic-Android by adding missing public APIs (notably Store-and-Forward, presence tracking, retry helpers, and various convenience builders), expanding test coverage, and syncing documentation/specs to the updated behavior and API surface.
Changes:
- Add new public APIs and utilities (StoreForwardApi, presence NodeChange events, congestion helpers, retry policy, node status/mesh-node helpers, channel helpers, shared-contact URL support).
- Expand protocol/engine behavior coverage with extensive new unit/integration tests (WireCodec, StoreForward/SFPP, presence timer, external config changes, etc.).
- Refresh docs and samples for new sealed variants, updated semantics, and new CLI conformance scenario.
Reviewed changes
Copilot reviewed 103 out of 105 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| transport-ble/src/androidMain/kotlin/org/meshtastic/sdk/transport/ble/BleTransport.android.kt | Adds Android factory for creating BleTransport from persisted MAC address. |
| testing/src/commonMain/kotlin/org/meshtastic/sdk/testing/FakeRadioTransport.kt | Adds test injection helpers for arbitrary packets and Store-and-Forward responses. |
| testing/api/testing.klib.api | Updates KLIB ABI surface for FakeRadioTransport injections. |
| testing/api/jvm/testing.api | Updates JVM ABI surface for FakeRadioTransport injections. |
| samples/parity-app/src/commonMain/kotlin/org/meshtastic/sample/MeshSampleController.kt | Updates sample to handle new NodeChange presence events. |
| samples/cli/src/main/kotlin/org/meshtastic/cli/conformance/Scenarios.kt | Refines cs2 semantics and adds cs7 unicast-DM conformance scenario. |
| samples/cli/src/main/kotlin/org/meshtastic/cli/cmd/TuiCmd.kt | Updates TUI node event logging for presence events. |
| samples/cli/src/main/kotlin/org/meshtastic/cli/cmd/ConnectCmds.kt | Updates CLI JSON/human node events output for presence events. |
| samples/cli/src/main/kotlin/org/meshtastic/cli/cmd/ConformanceCmd.kt | Exposes cs7 filtering and execution wiring. |
| gradle/libs.versions.toml | Bumps Android Gradle Plugin version. |
| docs/SPEC.md | Syncs AdminApi spec (nodeDbReset signature change). |
| docs/protocol.md | Updates protocol notes (admin channel indexing, session-passkey timing, reconnect wake bytes, managed mode, heartbeat nonce behavior, BLE commit disconnect note). |
| docs/integration-guide.md | Adds Admin/config builder usage section and renumbers subsequent sections. |
| docs/error-taxonomy.md | Documents AdminResult.RateLimited and routing error interception mapping. |
| docs/decisions/003-tooling.md | Updates sample app paths in tooling ADR. |
| docs/consumer-guides/reactive-lifecycle-management.md | Updates guide examples for NodeChange presence events. |
| docs/architecture/meshtastic-android-migration.md | Updates migration guide for presence events and new AdminResult variant handling. |
| docs/api-reference.md | Expands API reference for StoreForwardApi, presence NodeChange events, new send APIs, AdminResult.RateLimited, config builders, forNode(). |
| core/src/jvmTest/kotlin/org/meshtastic/sdk/MeshTopologyTest.kt | Adds tests for MeshTopology graph operations. |
| core/src/jvmTest/kotlin/org/meshtastic/sdk/internal/StoreForwardApiImplSfppTest.kt | Adds SFPP StoreForward event behavior tests. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/WireCodecTest.kt | Adds additional framing/boundary/resync test coverage. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/P2RoutingRpcTest.kt | Resolves NeighborInfo type ambiguity by aliasing proto type in tests. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/P0ReliabilityTest.kt | Updates broadcast ACK expectations and adds want_ack broadcast timeout test. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/NodeStatusTest.kt | Adds tests for online/connection/signal quality helpers on NodeInfo. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/MeshNodeTest.kt | Adds tests for MeshNode convenience wrapper/accessors. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/internal/NodeDiffTest.kt | Adds tests for diffNodeFields field categorization. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/internal/ConfigMergeTest.kt | Adds tests for config/module-config merge helpers. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/HandshakeFsmTest.kt | Renames/retitles audit section header. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ExternalConfigChangeTest.kt | Adds tests for unsolicited admin updates applying to local state + event emission. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/StoreForwardImplTest.kt | Adds StoreForward API integration tests using FakeRadioTransport. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/StoreForwardApiTest.kt | Adds basic StoreForwardStats and StoreForwardEvent sealed-shape tests. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/SharedContactUrlTest.kt | Adds tests for shared-contact URL encode/parse behavior. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/SfppHashTest.kt | Adds tests for SFPP hash properties (size/determinism). |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/RouteDiscoveryResultTest.kt | Adds tests for RouteDiscoveryResult assembly and formatting. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/RetryPolicyTest.kt | Adds tests for retry delay computation. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/PresenceTimerTest.kt | Adds tests for presence timeout/offline-online transitions. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/PositionUtilsTest.kt | Adds tests for position conversions/validation/distance/bearing. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/PayloadAccessorsTest.kt | Adds tests for packets/textMessages flow and new payload accessors. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/NodeIdsTest.kt | Adds tests for default-id formatting/parsing. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/NodeChangePresenceTest.kt | Adds tests ensuring presence changes are pattern-matchable NodeChange variants. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/NeighborInfoTest.kt | Adds tests for parsed NeighborInfo model. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/MqttEventsTest.kt | Adds tests for MQTT MeshEvent variants. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/MessageHandleRetryTest.kt | Adds tests for MessageHandle.retryWith behavior using a fake handle. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/DeviceCapabilitiesTest.kt | Adds tests for firmware version parsing and capability gating. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/ConnectionStateTest.kt | Adds tests for new ConnectionState convenience extensions. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/CongestionTest.kt | Adds tests for congestion level derivation and backoff suggestions. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/CongestionEmissionTest.kt | Adds tests for congestion warning emission behavior. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/ChannelUrlsTest.kt | Adds test for DJB2 channel-name hash. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/ext/ChannelHelpersTest.kt | Adds tests for channel validation and empty-slot selection. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/EngineTest.kt | Adjusts engine tests to use unicast packets where broadcasts now auto-resolve. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/EngineAuditFixesTest.kt | Updates audit test to assert DeviceUIConfig is captured in ConfigBundle. |
| core/src/commonTest/kotlin/org/meshtastic/sdk/AdminResultExtensionsTest.kt | Adds tests for AdminResult extension helpers and getOrThrow exceptions. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/TelemetryApi.kt | Adds telemetry RPCs for health/host/traffic-management metrics. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/StoreForwardApi.kt | Introduces StoreForwardApi, StoreForwardStats, and StoreForwardEvent public types. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/Storage.kt | Extends ConfigBundle to optionally include DeviceUIConfig. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/SharedContactUrl.kt | Adds shared-contact URL encoding/parsing helpers and extension. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/SfppHash.kt | Adds SFPP deduplication hash computation utility. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/RoutingApi.kt | Disambiguates proto NeighborInfo type via alias in public API. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/RouteDiscoveryResult.kt | Adds parsed traceroute result model + formatting helper. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/RetryPolicy.kt | Introduces retry policy types and delay computation. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/Result.kt | Adds ConnectionState helpers and AdminResult.RateLimited + AdminResult extensions/exceptions. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/PositionUtils.kt | Adds reusable geographic computations (validation, haversine distance, bearing). |
| core/src/commonMain/kotlin/org/meshtastic/sdk/PayloadAccessors.kt | Adds RadioClient.textMessages flow and new payload decoding helpers. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/NodeStatus.kt | Adds online/connection/signal quality helpers for NodeInfo. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/NodeIds.kt | Adds default-id formatting/parsing helpers. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/Node.kt | Adds presence NodeChange variants + new MeshEvent variants and external-config change kinds. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/NeighborInfo.kt | Introduces parsed NeighborInfo model distinct from proto type. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/MessageHandleRetry.kt | Adds MessageHandle.retryWith and retryability classification. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/MeshTopology.kt | Introduces a topology graph utility built from NeighborInfo reports. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/MeshNode.kt | Adds MeshNode consumer-friendly wrapper with flattened accessors. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/internal/TelemetryApiImpl.kt | Implements new telemetry RPC variants and propagates RateLimited. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/internal/RoutingApiImpl.kt | Updates neighbor-info RPC to use proto alias consistently. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/internal/NodeDiff.kt | Adds internal node-diff helper used for changed-field reporting. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/internal/EngineMessage.kt | Adds presence tick message and removes stale “Phase 2” wording. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/internal/ConfigMerge.kt | Adds internal config merge utilities for section-based replacement. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/internal/CommandDispatcher.kt | Extends RPC response decoding (Admin/UI/status/etc.) and StoreForward decode paths; maps RateLimited. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/internal/Base64Url.kt | Centralizes base64url encode/decode for URL-based sharing features. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/DeviceCapabilities.kt | Adds firmware version parsing and capability flags. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/Connect.kt | Adds @since tag to connectAndAwaitReady documentation. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/CongestionLevel.kt | Adds congestion metrics model and derived levels/backoff guidance. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/ConfigBuilders.kt | Adds AdminApi config builder extensions for common writes and batching. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/ChannelUrls.kt | Reuses centralized base64url helpers and adds DJB2 channel-name hashing. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/ChannelHelpers.kt | Adds channel validation and slot selection helpers. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/BatteryStatus.kt | Improves KDoc and adds @since tags for battery status helpers. |
| core/src/commonMain/kotlin/org/meshtastic/sdk/AutoReconnectConfig.kt | Minor KDoc wording update. |
| build.gradle.kts | Applies axion-release conditionally for composite-build compatibility and sets a composite fallback version. |
…olicy example - MeshTopology: clarify KDoc that Mutex is for consumer-side concurrency, not engine-actor hot path (ADR-002 compliant) - MeshTopology.nodes(): return immutable copy via toSet() to prevent cache corruption through external mutation - RetryPolicy: fix KDoc example from policy.execute(handle) to handle.retryWith(policy) matching actual API Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: James Rich <james.a.rich@gmail.com>
e545616 to
ef0b432
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hard-cutover integration of
meshtastic-sdkintoMeshtastic-Androidrevealed SDK gaps, missing APIs, and documentation staleness. This PR addresses all findings across multiple audit rounds.API additions (29 commits, 97 files, +13.5k lines)
Phase 1 — Core gaps:
RadioClient.textMessagesflow,RadioClient.channelsStateFlowBleTransport(address)factory for AndroidsendRaw(ToRadio)for MQTT proxy/XModemAdminApi— all 9 remaining operations for full proto coveragePhase 2 — Feature APIs:
AdminApi.forNode(dest)— remote node adminsendReaction()— emoji reactionsgetDeviceMetadata(),requestNodeInfo()editSettings {}batch support +AdminBatchScopeMeshTopologygraph utilityAdminResult.RateLimited,AdminResult.getOrThrow()Quality:
Documentation
api-reference.mdfully synced: NodeChange.CameOnline/WentOffline, AdminResult.RateLimited, StoreForwardApi, 23 config builders, forNode(), sendReaction/sendRawerror-taxonomy.md,integration-guide.md, consumer guides updatedTests (565 total, 0 failures)
Samples