diff --git a/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl b/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl index f91d5184c..e6990925d 100644 --- a/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl +++ b/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl @@ -72,6 +72,8 @@ interface IMeshService { List getNodes(); /// This method is only intended for use in our GUI, so the user can set radio options + /// It returns a DeviceConfig protobuf. + byte []getConfig(); /// It sets a Config protobuf via admin packet void setConfig(in byte []payload); @@ -83,6 +85,12 @@ interface IMeshService { /// It sets a Channel protobuf via admin packet void setChannel(in byte []payload); + /// Send beginEditSettings admin packet to nodeNum + void beginEditSettings(); + + /// Send commitEditSettings admin packet to nodeNum + void commitEditSettings(); + /// Send position packet with wantResponse to nodeNum void requestPosition(in int idNum, in double lat, in double lon, in int alt); diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 653fc0f85..d9a409c09 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -92,12 +92,16 @@ class MeshService : Service(), Logging { const val ACTION_NODE_CHANGE = "$prefix.NODE_CHANGE" const val ACTION_MESH_CONNECTED = "$prefix.MESH_CONNECTED" + const val ACTION_MESSAGE_STATUS = "$prefix.MESSAGE_STATUS" open class NodeNotFoundException(reason: String) : Exception(reason) class InvalidNodeIdException : NodeNotFoundException("Invalid NodeId") class NodeNumNotFoundException(id: Int) : NodeNotFoundException("NodeNum not found $id") class IdNotFoundException(id: String) : NodeNotFoundException("ID not found $id") + class NoDeviceConfigException(message: String = "No radio settings received (is our app too old?)") : + RadioNotConnectedException(message) + /** We treat software update as similar to loss of comms to the regular bluetooth service (so things like sendPosition for background GPS ignores the problem */ class IsUpdatingException : RadioNotConnectedException("Operation prohibited during firmware update") @@ -833,6 +837,7 @@ class MeshService : Service(), Logging { serviceScope.handledLaunch { packetRepository.get().updateMessageStatus(p, m) } + serviceBroadcasts.broadcastMessageStatus(p) } /** @@ -1365,30 +1370,6 @@ class MeshService : Service(), Logging { }) } - private fun requestShutdown(idNum: Int) { - sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { - shutdownSeconds = 5 - }) - } - - private fun requestReboot(idNum: Int) { - sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { - rebootSeconds = 5 - }) - } - - private fun requestFactoryReset(idNum: Int) { - sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { - factoryReset = 1 - }) - } - - private fun requestNodedbReset(idNum: Int) { - sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { - nodedbReset = 1 - }) - } - /** * Start the modern (REV2) API configuration flow */ @@ -1609,6 +1590,8 @@ class MeshService : Service(), Logging { val res = radioInterfaceService.setDeviceAddress(deviceAddr) if (res) { discardNodeDB() + } else { + serviceBroadcasts.broadcastConnection() } res } @@ -1685,6 +1668,10 @@ class MeshService : Service(), Logging { } } + override fun getConfig(): ByteArray = toRemoteExceptions { + this@MeshService.localConfig.toByteArray() ?: throw NoDeviceConfigException() + } + override fun setConfig(payload: ByteArray) = toRemoteExceptions { val parsed = ConfigProtos.Config.parseFrom(payload) setConfig(parsed) @@ -1700,6 +1687,18 @@ class MeshService : Service(), Logging { setChannel(parsed) } + override fun beginEditSettings() = toRemoteExceptions { + sendToRadio(newMeshPacketTo(myNodeNum).buildAdminPacket { + beginEditSettings = true + }) + } + + override fun commitEditSettings() = toRemoteExceptions { + sendToRadio(newMeshPacketTo(myNodeNum).buildAdminPacket { + commitEditSettings = true + }) + } + override fun getNodes(): MutableList = toRemoteExceptions { val r = nodeDBbyID.values.toMutableList() info("in getOnline, count=${r.size}") @@ -1730,19 +1729,27 @@ class MeshService : Service(), Logging { } override fun requestShutdown(idNum: Int) = toRemoteExceptions { - this@MeshService.requestShutdown(idNum) + sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { + shutdownSeconds = 5 + }) } override fun requestReboot(idNum: Int) = toRemoteExceptions { - this@MeshService.requestReboot(idNum) + sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { + rebootSeconds = 5 + }) } override fun requestFactoryReset(idNum: Int) = toRemoteExceptions { - this@MeshService.requestFactoryReset(idNum) + sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { + factoryReset = 1 + }) } override fun requestNodedbReset(idNum: Int) = toRemoteExceptions { - this@MeshService.requestNodedbReset(idNum) + sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { + nodedbReset = 1 + }) } } } 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 4cbc58f8f..05ed747be 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt @@ -2,6 +2,7 @@ package com.geeksville.mesh.service import android.content.Context import android.content.Intent +import android.os.Parcelable import com.geeksville.mesh.DataPacket import com.geeksville.mesh.NodeInfo @@ -37,6 +38,20 @@ class MeshServiceBroadcasts( explicitBroadcast(intent) } + fun broadcastMessageStatus(p: DataPacket) { + if (p.id == 0) { + MeshService.debug("Ignoring anonymous packet status") + } else { + // Do not log, contains PII possibly + // MeshService.debug("Broadcasting message status $p") + val intent = Intent(MeshService.ACTION_MESSAGE_STATUS).apply { + putExtra(EXTRA_PACKET_ID, p.id) + putExtra(EXTRA_STATUS, p.status as Parcelable) + } + explicitBroadcast(intent) + } + } + /** * Broadcast our current connection status */