From 34b075519251c8f6512aa86bcde7641c05ddd354 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sat, 7 Feb 2026 15:45:11 -0600 Subject: [PATCH] refactor: Centralize Meshtastic intent constants This commit centralizes all Android Intent constants into a new `MeshtasticIntent` object within the `core/api` module. This refactoring makes the constants accessible to external applications and removes the duplicated definitions from the main application. The app and the service example have been updated to use these new centralized constants. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../com/geeksville/mesh/service/Constants.kt | 41 +++++----- .../mesh/service/MeshDataHandler.kt | 8 +- .../mesh/service/MeshServiceBroadcasts.kt | 2 +- .../meshtastic/core/api/MeshtasticIntent.kt | 77 +++++++++++++++++++ .../meshserviceexample/MainActivity.kt | 27 +++---- 5 files changed, 118 insertions(+), 37 deletions(-) create mode 100644 core/api/src/main/kotlin/org/meshtastic/core/api/MeshtasticIntent.kt diff --git a/app/src/main/java/com/geeksville/mesh/service/Constants.kt b/app/src/main/java/com/geeksville/mesh/service/Constants.kt index 36c48add3..f350d6c28 100644 --- a/app/src/main/java/com/geeksville/mesh/service/Constants.kt +++ b/app/src/main/java/com/geeksville/mesh/service/Constants.kt @@ -16,22 +16,24 @@ */ package com.geeksville.mesh.service +import org.meshtastic.core.api.MeshtasticIntent + const val PREFIX = "com.geeksville.mesh" -const val ACTION_NODE_CHANGE = "$PREFIX.NODE_CHANGE" -const val ACTION_MESH_CONNECTED = "$PREFIX.MESH_CONNECTED" -const val ACTION_MESH_DISCONNECTED = "$PREFIX.MESH_DISCONNECTED" -const val ACTION_CONNECTION_CHANGED = "$PREFIX.CONNECTION_CHANGED" -const val ACTION_MESSAGE_STATUS = "$PREFIX.MESSAGE_STATUS" +const val ACTION_NODE_CHANGE = MeshtasticIntent.ACTION_NODE_CHANGE +const val ACTION_MESH_CONNECTED = MeshtasticIntent.ACTION_MESH_CONNECTED +const val ACTION_MESH_DISCONNECTED = MeshtasticIntent.ACTION_MESH_DISCONNECTED +const val ACTION_CONNECTION_CHANGED = MeshtasticIntent.ACTION_CONNECTION_CHANGED +const val ACTION_MESSAGE_STATUS = MeshtasticIntent.ACTION_MESSAGE_STATUS -const val ACTION_RECEIVED_TEXT_MESSAGE_APP = "$PREFIX.RECEIVED.TEXT_MESSAGE_APP" -const val ACTION_RECEIVED_POSITION_APP = "$PREFIX.RECEIVED.POSITION_APP" -const val ACTION_RECEIVED_NODEINFO_APP = "$PREFIX.RECEIVED.NODEINFO_APP" -const val ACTION_RECEIVED_TELEMETRY_APP = "$PREFIX.RECEIVED.TELEMETRY_APP" -const val ACTION_RECEIVED_ATAK_PLUGIN = "$PREFIX.RECEIVED.ATAK_PLUGIN" -const val ACTION_RECEIVED_ATAK_FORWARDER = "$PREFIX.RECEIVED.ATAK_FORWARDER" -const val ACTION_RECEIVED_DETECTION_SENSOR_APP = "$PREFIX.RECEIVED.DETECTION_SENSOR_APP" -const val ACTION_RECEIVED_PRIVATE_APP = "$PREFIX.RECEIVED.PRIVATE_APP" +const val ACTION_RECEIVED_TEXT_MESSAGE_APP = MeshtasticIntent.ACTION_RECEIVED_TEXT_MESSAGE_APP +const val ACTION_RECEIVED_POSITION_APP = MeshtasticIntent.ACTION_RECEIVED_POSITION_APP +const val ACTION_RECEIVED_NODEINFO_APP = MeshtasticIntent.ACTION_RECEIVED_NODEINFO_APP +const val ACTION_RECEIVED_TELEMETRY_APP = MeshtasticIntent.ACTION_RECEIVED_TELEMETRY_APP +const val ACTION_RECEIVED_ATAK_PLUGIN = MeshtasticIntent.ACTION_RECEIVED_ATAK_PLUGIN +const val ACTION_RECEIVED_ATAK_FORWARDER = MeshtasticIntent.ACTION_RECEIVED_ATAK_FORWARDER +const val ACTION_RECEIVED_DETECTION_SENSOR_APP = MeshtasticIntent.ACTION_RECEIVED_DETECTION_SENSOR_APP +const val ACTION_RECEIVED_PRIVATE_APP = MeshtasticIntent.ACTION_RECEIVED_PRIVATE_APP fun actionReceived(portNum: String) = "$PREFIX.RECEIVED.$portNum" @@ -39,14 +41,11 @@ fun actionReceived(portNum: String) = "$PREFIX.RECEIVED.$portNum" // standard EXTRA bundle definitions // -// a bool true means now connected, false means not -const val EXTRA_CONNECTED = "$PREFIX.Connected" +const val EXTRA_CONNECTED = MeshtasticIntent.EXTRA_CONNECTED const val EXTRA_PROGRESS = "$PREFIX.Progress" - -// / a bool true means we expect this condition to continue until, false means device might come back const val EXTRA_PERMANENT = "$PREFIX.Permanent" -const val EXTRA_PAYLOAD = "$PREFIX.Payload" -const val EXTRA_NODEINFO = "$PREFIX.NodeInfo" -const val EXTRA_PACKET_ID = "$PREFIX.PacketId" -const val EXTRA_STATUS = "$PREFIX.Status" +const val EXTRA_PAYLOAD = MeshtasticIntent.EXTRA_PAYLOAD +const val EXTRA_NODEINFO = MeshtasticIntent.EXTRA_NODEINFO +const val EXTRA_PACKET_ID = MeshtasticIntent.EXTRA_PACKET_ID +const val EXTRA_STATUS = MeshtasticIntent.EXTRA_STATUS diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt b/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt index be63802bf..4a3589b44 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt @@ -137,7 +137,9 @@ constructor( PortNum.POSITION_APP -> handlePosition(packet, dataPacket, myNodeNum) PortNum.NODEINFO_APP -> if (!fromUs) handleNodeInfo(packet) PortNum.TELEMETRY_APP -> handleTelemetry(packet, dataPacket, myNodeNum) - else -> shouldBroadcast = handleSpecializedDataPacket(packet, dataPacket, myNodeNum, logUuid, logInsertJob) + else -> + shouldBroadcast = + handleSpecializedDataPacket(packet, dataPacket, myNodeNum, fromUs, logUuid, logInsertJob) } return shouldBroadcast } @@ -146,14 +148,16 @@ constructor( packet: MeshPacket, dataPacket: DataPacket, myNodeNum: Int, + fromUs: Boolean, logUuid: String?, logInsertJob: Job?, ): Boolean { - var shouldBroadcast = false + var shouldBroadcast = !fromUs val decoded = packet.decoded ?: return shouldBroadcast when (decoded.portnum) { PortNum.TRACEROUTE_APP -> { tracerouteHandler.handleTraceroute(packet, logUuid, logInsertJob) + shouldBroadcast = false } PortNum.ROUTING_APP -> { handleRouting(packet, dataPacket) diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt index 14f9da3c7..e0215bc15 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt @@ -113,7 +113,7 @@ constructor( * NODE_CHANGE for new IDs appearing or disappearing * ACTION_MESH_CONNECTED for losing/gaining connection to the packet radio * Note: this is not the same as RadioInterfaceService.RADIO_CONNECTED_ACTION, - * because it implies we have assembled a warehouse valid node db. + * because it implies we have assembled a valid node db. */ private fun explicitBroadcast(intent: Intent) { context.sendBroadcast( diff --git a/core/api/src/main/kotlin/org/meshtastic/core/api/MeshtasticIntent.kt b/core/api/src/main/kotlin/org/meshtastic/core/api/MeshtasticIntent.kt new file mode 100644 index 000000000..f0c59993f --- /dev/null +++ b/core/api/src/main/kotlin/org/meshtastic/core/api/MeshtasticIntent.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025-2026 Meshtastic LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.meshtastic.core.api + +import org.meshtastic.core.api.MeshtasticIntent.EXTRA_CONNECTED +import org.meshtastic.core.api.MeshtasticIntent.EXTRA_NODEINFO +import org.meshtastic.core.api.MeshtasticIntent.EXTRA_PACKET_ID +import org.meshtastic.core.api.MeshtasticIntent.EXTRA_STATUS + + +/** + * Constants for Meshtastic Android Intents. These are used by external applications to communicate with the Meshtastic + * service. + */ +object MeshtasticIntent { + private const val PREFIX = "com.geeksville.mesh" + + /** Broadcast when a node's information changes. Extra: [EXTRA_NODEINFO] */ + const val ACTION_NODE_CHANGE = "$PREFIX.NODE_CHANGE" + + /** Broadcast when the mesh radio connects. Extra: [EXTRA_CONNECTED] */ + const val ACTION_MESH_CONNECTED = "$PREFIX.MESH_CONNECTED" + + /** Broadcast when the mesh radio disconnects. */ + const val ACTION_MESH_DISCONNECTED = "$PREFIX.MESH_DISCONNECTED" + + /** Legacy broadcast for connection changes. Extra: [EXTRA_CONNECTED] */ + const val ACTION_CONNECTION_CHANGED = "$PREFIX.CONNECTION_CHANGED" + + /** Broadcast for message status updates. Extras: [EXTRA_PACKET_ID], [EXTRA_STATUS] */ + const val ACTION_MESSAGE_STATUS = "$PREFIX.MESSAGE_STATUS" + + /** Received a text message. */ + const val ACTION_RECEIVED_TEXT_MESSAGE_APP = "$PREFIX.RECEIVED.TEXT_MESSAGE_APP" + + /** Received a position update. */ + const val ACTION_RECEIVED_POSITION_APP = "$PREFIX.RECEIVED.POSITION_APP" + + /** Received node info. */ + const val ACTION_RECEIVED_NODEINFO_APP = "$PREFIX.RECEIVED.NODEINFO_APP" + + /** Received telemetry data. */ + const val ACTION_RECEIVED_TELEMETRY_APP = "$PREFIX.RECEIVED.TELEMETRY_APP" + + /** Received ATAK Plugin data. */ + const val ACTION_RECEIVED_ATAK_PLUGIN = "$PREFIX.RECEIVED.ATAK_PLUGIN" + + /** Received ATAK Forwarder data. */ + const val ACTION_RECEIVED_ATAK_FORWARDER = "$PREFIX.RECEIVED.ATAK_FORWARDER" + + /** Received detection sensor data. */ + const val ACTION_RECEIVED_DETECTION_SENSOR_APP = "$PREFIX.RECEIVED.DETECTION_SENSOR_APP" + + /** Received private app data. */ + const val ACTION_RECEIVED_PRIVATE_APP = "$PREFIX.RECEIVED.PRIVATE_APP" + + // standard EXTRA bundle definitions + const val EXTRA_CONNECTED = "$PREFIX.Connected" + const val EXTRA_PAYLOAD = "$PREFIX.Payload" + const val EXTRA_NODEINFO = "$PREFIX.NodeInfo" + const val EXTRA_PACKET_ID = "$PREFIX.PacketId" + const val EXTRA_STATUS = "$PREFIX.Status" +} diff --git a/mesh_service_example/src/main/kotlin/com/meshtastic/android/meshserviceexample/MainActivity.kt b/mesh_service_example/src/main/kotlin/com/meshtastic/android/meshserviceexample/MainActivity.kt index 5c8376686..c558de7e8 100644 --- a/mesh_service_example/src/main/kotlin/com/meshtastic/android/meshserviceexample/MainActivity.kt +++ b/mesh_service_example/src/main/kotlin/com/meshtastic/android/meshserviceexample/MainActivity.kt @@ -39,6 +39,7 @@ import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext +import org.meshtastic.core.api.MeshtasticIntent import org.meshtastic.core.service.IMeshService private const val TAG: String = "MeshServiceExample" @@ -83,19 +84,19 @@ class MainActivity : ComponentActivity() { val intentFilter = IntentFilter().apply { - addAction("com.geeksville.mesh.NODE_CHANGE") - addAction("com.geeksville.mesh.CONNECTION_CHANGED") - addAction("com.geeksville.mesh.MESH_CONNECTED") - addAction("com.geeksville.mesh.MESH_DISCONNECTED") - addAction("com.geeksville.mesh.MESSAGE_STATUS") - addAction("com.geeksville.mesh.RECEIVED.TEXT_MESSAGE_APP") - addAction("com.geeksville.mesh.RECEIVED.POSITION_APP") - addAction("com.geeksville.mesh.RECEIVED.TELEMETRY_APP") - addAction("com.geeksville.mesh.RECEIVED.NODEINFO_APP") - addAction("com.geeksville.mesh.RECEIVED.ATAK_PLUGIN") - addAction("com.geeksville.mesh.RECEIVED.ATAK_FORWARDER") - addAction("com.geeksville.mesh.RECEIVED.DETECTION_SENSOR_APP") - addAction("com.geeksville.mesh.RECEIVED.PRIVATE_APP") + addAction(MeshtasticIntent.ACTION_NODE_CHANGE) + addAction(MeshtasticIntent.ACTION_CONNECTION_CHANGED) + addAction(MeshtasticIntent.ACTION_MESH_CONNECTED) + addAction(MeshtasticIntent.ACTION_MESH_DISCONNECTED) + addAction(MeshtasticIntent.ACTION_MESSAGE_STATUS) + addAction(MeshtasticIntent.ACTION_RECEIVED_TEXT_MESSAGE_APP) + addAction(MeshtasticIntent.ACTION_RECEIVED_POSITION_APP) + addAction(MeshtasticIntent.ACTION_RECEIVED_TELEMETRY_APP) + addAction(MeshtasticIntent.ACTION_RECEIVED_NODEINFO_APP) + addAction(MeshtasticIntent.ACTION_RECEIVED_ATAK_PLUGIN) + addAction(MeshtasticIntent.ACTION_RECEIVED_ATAK_FORWARDER) + addAction(MeshtasticIntent.ACTION_RECEIVED_DETECTION_SENSOR_APP) + addAction(MeshtasticIntent.ACTION_RECEIVED_PRIVATE_APP) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {