diff --git a/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl b/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl index 55206fcc6..bb310e092 100644 --- a/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl +++ b/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl @@ -79,6 +79,9 @@ interface IMeshService { /// It sets a Channel protobuf via admin packet void setChannel(in byte []payload); + /// Send position packet with wantResponse to nodeNum + void requestPosition(in int idNum); + /// Send Shutdown admin packet to nodeNum void requestShutdown(in int idNum); diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index 17dd7f7f6..7adf827b8 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -152,10 +152,6 @@ class UIViewModel @Inject constructor( fun sendMessage(str: String, channel: Int = 0, dest: String = DataPacket.ID_BROADCAST) { val p = DataPacket(dest, channel, str) - sendDataPacket(p) - } - - fun sendDataPacket(p: DataPacket) { try { meshService?.send(p) } catch (ex: RemoteException) { @@ -163,6 +159,14 @@ class UIViewModel @Inject constructor( } } + fun requestPosition(destNum: Int) { + try { + meshService?.requestPosition(destNum) + } catch (ex: RemoteException) { + errormsg("Request position error: ${ex.message}") + } + } + fun deleteAllLogs() = viewModelScope.launch(Dispatchers.IO) { meshLogRepository.deleteAll() } 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 7c7d3e888..928779eec 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -1351,6 +1351,10 @@ class MeshService : Service(), Logging { }) } + private fun requestPosition(idNum: Int) { + sendPosition(time = 0, destNum = idNum, wantResponse = true) + } + private fun requestShutdown(idNum: Int) { sendToRadio(newMeshPacketTo(idNum).buildAdminPacket { shutdownSeconds = 5 @@ -1400,12 +1404,14 @@ class MeshService : Service(), Logging { lon: Double = 0.0, alt: Int = 0, time: Int = currentSecond(), + destNum: Int? = null, + wantResponse: Boolean = false ) { try { val mi = myNodeInfo if (mi != null) { - val destNum = mi.myNodeNum // we just send to the local node - debug("Sending our position/time to=$destNum lat=${lat.anonymize}, lon=${lon.anonymize}, alt=$alt, time=$time") + val idNum = destNum ?: mi.myNodeNum // when null we just send to the local node + debug("Sending our position/time to=$idNum lat=${lat.anonymize}, lon=${lon.anonymize}, alt=$alt, time=$time") val position = MeshProtos.Position.newBuilder().also { it.longitudeI = Position.degI(lon) @@ -1419,11 +1425,11 @@ class MeshService : Service(), Logging { handleReceivedPosition(mi.myNodeNum, position) val fullPacket = - newMeshPacketTo(destNum).buildMeshPacket(priority = MeshPacket.Priority.BACKGROUND) { + newMeshPacketTo(idNum).buildMeshPacket(priority = MeshPacket.Priority.BACKGROUND) { // Use the new position as data format portnumValue = Portnums.PortNum.POSITION_APP_VALUE payload = position.toByteString() - this.wantResponse = false + this.wantResponse = wantResponse } // send the packet into the mesh @@ -1688,6 +1694,10 @@ class MeshService : Service(), Logging { stopLocationRequests() } + override fun requestPosition(idNum: Int) = toRemoteExceptions { + this@MeshService.requestPosition(idNum) + } + override fun requestShutdown(idNum: Int) = toRemoteExceptions { this@MeshService.requestShutdown(idNum) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt index ff6ff5114..e728a9eee 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/UsersFragment.kt @@ -59,7 +59,7 @@ class UsersFragment : ScreenFragment("Users"), Logging { val showAdmin = position == 0 || model.adminChannelIndex > 0 val popup = PopupMenu(requireContext(), view) popup.inflate(R.menu.menu_nodes) - popup.menu.findItem(R.id.direct_message).isVisible = position > 0 + popup.menu.setGroupVisible(R.id.group_remote, position > 0) popup.menu.setGroupVisible(R.id.group_admin, showAdmin) popup.setOnMenuItemClickListener { item: MenuItem -> when (item.itemId) { @@ -79,6 +79,12 @@ class UsersFragment : ScreenFragment("Users"), Logging { .commit() } } + R.id.request_position -> { + if (position > 0 && user != null) { + debug("requesting position for ${user.longName}") + model.requestPosition(node.num) + } + } R.id.reboot -> { MaterialAlertDialogBuilder(requireContext()) .setTitle("${getString(R.string.reboot)}\n${user?.longName}?") diff --git a/app/src/main/res/menu/menu_nodes.xml b/app/src/main/res/menu/menu_nodes.xml index ee6b0d9e2..3dfbf14f1 100644 --- a/app/src/main/res/menu/menu_nodes.xml +++ b/app/src/main/res/menu/menu_nodes.xml @@ -1,10 +1,16 @@ - + + + + 15 miles Tile download estimate: Start Download + Request position