kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
fix(conifg): implement `sessionPasskey` handling for admin requests (#1263)
rodzic
16b822cec4
commit
36a13d7687
|
@ -16,12 +16,14 @@ import com.geeksville.mesh.MyNodeInfo
|
|||
import com.geeksville.mesh.NodeInfo
|
||||
import com.geeksville.mesh.Portnums
|
||||
import com.geeksville.mesh.Position
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.config
|
||||
import com.geeksville.mesh.database.entity.toNodeInfo
|
||||
import com.geeksville.mesh.deviceProfile
|
||||
import com.geeksville.mesh.moduleConfig
|
||||
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
|
||||
import com.geeksville.mesh.ui.AdminRoute
|
||||
import com.geeksville.mesh.ui.ConfigRoute
|
||||
import com.geeksville.mesh.ui.ResponseState
|
||||
import com.google.protobuf.MessageLite
|
||||
|
@ -44,6 +46,7 @@ import javax.inject.Inject
|
|||
*/
|
||||
data class RadioConfigState(
|
||||
val route: String = "",
|
||||
val metadata: MeshProtos.DeviceMetadata = MeshProtos.DeviceMetadata.getDefaultInstance(),
|
||||
val userConfig: MeshProtos.User = MeshProtos.User.getDefaultInstance(),
|
||||
val channelList: List<ChannelProtos.ChannelSettings> = emptyList(),
|
||||
val radioConfig: ConfigProtos.Config = config {},
|
||||
|
@ -51,7 +54,9 @@ data class RadioConfigState(
|
|||
val ringtone: String = "",
|
||||
val cannedMessageMessages: String = "",
|
||||
val responseState: ResponseState<Boolean> = ResponseState.Empty,
|
||||
)
|
||||
) {
|
||||
fun hasMetadata() = metadata != MeshProtos.DeviceMetadata.getDefaultInstance()
|
||||
}
|
||||
|
||||
@HiltViewModel
|
||||
class RadioConfigViewModel @Inject constructor(
|
||||
|
@ -247,30 +252,55 @@ class RadioConfigViewModel @Inject constructor(
|
|||
"Request getCannedMessages error"
|
||||
)
|
||||
|
||||
fun requestShutdown(destNum: Int) = request(
|
||||
private fun requestShutdown(destNum: Int) = request(
|
||||
destNum,
|
||||
{ service, packetId, dest -> service.requestShutdown(packetId, dest) },
|
||||
"Request shutdown error"
|
||||
)
|
||||
|
||||
fun requestReboot(destNum: Int) = request(
|
||||
private fun requestReboot(destNum: Int) = request(
|
||||
destNum,
|
||||
{ service, packetId, dest -> service.requestReboot(packetId, dest) },
|
||||
"Request reboot error"
|
||||
)
|
||||
|
||||
fun requestFactoryReset(destNum: Int) = request(
|
||||
private fun requestFactoryReset(destNum: Int) = request(
|
||||
destNum,
|
||||
{ service, packetId, dest -> service.requestFactoryReset(packetId, dest) },
|
||||
"Request factory reset error"
|
||||
)
|
||||
|
||||
fun requestNodedbReset(destNum: Int) = request(
|
||||
private fun requestNodedbReset(destNum: Int) = request(
|
||||
destNum,
|
||||
{ service, packetId, dest -> service.requestNodedbReset(packetId, dest) },
|
||||
"Request NodeDB reset error"
|
||||
)
|
||||
|
||||
private fun sendAdminRequest(destNum: Int) {
|
||||
when (radioConfigState.value.route) {
|
||||
AdminRoute.REBOOT.name -> requestReboot(destNum)
|
||||
AdminRoute.SHUTDOWN.name -> with(radioConfigState.value) {
|
||||
if (hasMetadata() && !metadata.canShutdown) {
|
||||
setResponseStateError(app.getString(R.string.cant_shutdown))
|
||||
} else {
|
||||
requestShutdown(destNum)
|
||||
}
|
||||
}
|
||||
|
||||
AdminRoute.FACTORY_RESET.name -> requestFactoryReset(destNum)
|
||||
AdminRoute.NODEDB_RESET.name -> requestNodedbReset(destNum)
|
||||
}
|
||||
}
|
||||
|
||||
fun getSessionPasskey(destNum: Int) {
|
||||
if (radioConfigState.value.hasMetadata()) {
|
||||
sendAdminRequest(destNum)
|
||||
} else {
|
||||
getConfig(destNum, AdminProtos.AdminMessage.ConfigType.SESSIONKEY_CONFIG_VALUE)
|
||||
setResponseStateTotal(2)
|
||||
}
|
||||
}
|
||||
|
||||
fun setFixedPosition(destNum: Int, position: Position) {
|
||||
try {
|
||||
meshService?.setFixedPosition(destNum, position)
|
||||
|
@ -444,9 +474,12 @@ class RadioConfigViewModel @Inject constructor(
|
|||
setResponseStateError("Unexpected sender: ${packet.from.toUInt()} instead of ${destNum.toUInt()}.")
|
||||
return
|
||||
}
|
||||
// check if destination is channel editor
|
||||
val goChannels = route == ConfigRoute.CHANNELS.name
|
||||
when (parsed.payloadVariantCase) {
|
||||
AdminProtos.AdminMessage.PayloadVariantCase.GET_DEVICE_METADATA_RESPONSE -> {
|
||||
_radioConfigState.update { it.copy(metadata = parsed.getDeviceMetadataResponse) }
|
||||
incrementCompleted()
|
||||
}
|
||||
|
||||
AdminProtos.AdminMessage.PayloadVariantCase.GET_CHANNEL_RESPONSE -> {
|
||||
val response = parsed.getChannelResponse
|
||||
// Stop once we get to the first disabled entry
|
||||
|
@ -457,7 +490,7 @@ class RadioConfigViewModel @Inject constructor(
|
|||
})
|
||||
}
|
||||
incrementCompleted()
|
||||
if (response.index + 1 < maxChannels && goChannels) {
|
||||
if (response.index + 1 < maxChannels && route == ConfigRoute.CHANNELS.name) {
|
||||
// Not done yet, request next channel
|
||||
getChannel(destNum, response.index + 1)
|
||||
}
|
||||
|
@ -504,6 +537,10 @@ class RadioConfigViewModel @Inject constructor(
|
|||
|
||||
else -> TODO()
|
||||
}
|
||||
|
||||
if (AdminRoute.entries.any { it.name == route }) {
|
||||
sendAdminRequest(destNum)
|
||||
}
|
||||
requestIds.update { it.apply { remove(data.requestId) } }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1794,7 +1794,11 @@ class MeshService : Service(), Logging {
|
|||
|
||||
override fun getRemoteConfig(id: Int, destNum: Int, config: Int) = toRemoteExceptions {
|
||||
sendToRadio(newMeshPacketTo(destNum).buildAdminPacket(id = id, wantResponse = true) {
|
||||
getConfigRequestValue = config
|
||||
if (config == AdminProtos.AdminMessage.ConfigType.SESSIONKEY_CONFIG_VALUE) {
|
||||
getDeviceMetadataRequest = true
|
||||
} else {
|
||||
getConfigRequestValue = config
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -163,6 +163,14 @@ class DeviceSettingsFragment : ScreenFragment("Radio Configuration"), Logging {
|
|||
}
|
||||
}
|
||||
|
||||
enum class AdminRoute(@StringRes val title: Int) {
|
||||
REBOOT(R.string.reboot),
|
||||
SHUTDOWN(R.string.shutdown),
|
||||
FACTORY_RESET(R.string.factory_reset),
|
||||
NODEDB_RESET(R.string.nodedb_reset),
|
||||
;
|
||||
}
|
||||
|
||||
// Config (configType = AdminProtos.AdminMessage.ConfigType)
|
||||
enum class ConfigRoute(val title: String, val configType: Int = 0) {
|
||||
USER("User"),
|
||||
|
@ -197,6 +205,7 @@ enum class ModuleRoute(val title: String, val configType: Int = 0) {
|
|||
}
|
||||
|
||||
private fun getName(route: Any): String = when (route) {
|
||||
is AdminRoute -> route.name
|
||||
is ConfigRoute -> route.name
|
||||
is ModuleRoute -> route.name
|
||||
else -> ""
|
||||
|
@ -304,8 +313,11 @@ fun RadioConfigNavHost(
|
|||
},
|
||||
onComplete = {
|
||||
val route = radioConfigState.route
|
||||
if (route.isNotEmpty()) navController.navigate(route)
|
||||
viewModel.clearPacketResponse()
|
||||
if (ConfigRoute.entries.any { it.name == route } ||
|
||||
ModuleRoute.entries.any { it.name == route }) {
|
||||
navController.navigate(route)
|
||||
viewModel.clearPacketResponse()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -346,20 +358,8 @@ fun RadioConfigNavHost(
|
|||
showEditDeviceProfileDialog = true
|
||||
}
|
||||
|
||||
"REBOOT" -> {
|
||||
viewModel.requestReboot(destNum)
|
||||
}
|
||||
|
||||
"SHUTDOWN" -> {
|
||||
viewModel.requestShutdown(destNum)
|
||||
}
|
||||
|
||||
"FACTORY_RESET" -> {
|
||||
viewModel.requestFactoryReset(destNum)
|
||||
}
|
||||
|
||||
"NODEDB_RESET" -> {
|
||||
viewModel.requestNodedbReset(destNum)
|
||||
is AdminRoute -> {
|
||||
viewModel.getSessionPasskey(destNum)
|
||||
}
|
||||
|
||||
is ConfigRoute -> {
|
||||
|
@ -753,10 +753,7 @@ private fun RadioSettingsScreen(
|
|||
item { NavCard("Export configuration", enabled = enabled) { onRouteClick("EXPORT") } }
|
||||
}
|
||||
|
||||
item { NavButton(R.string.reboot, enabled) { onRouteClick("REBOOT") } }
|
||||
item { NavButton(R.string.shutdown, enabled) { onRouteClick("SHUTDOWN") } }
|
||||
item { NavButton(R.string.factory_reset, enabled) { onRouteClick("FACTORY_RESET") } }
|
||||
item { NavButton(R.string.nodedb_reset, enabled) { onRouteClick("NODEDB_RESET") } }
|
||||
items(AdminRoute.entries) { NavButton(it.title, enabled) { onRouteClick(it) } }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,7 @@
|
|||
<string name="preferences_system_default">System default</string>
|
||||
<string name="resend">Resend</string>
|
||||
<string name="shutdown">Shutdown</string>
|
||||
<string name="cant_shutdown">Shutdown not supported on this device</string>
|
||||
<string name="reboot">Reboot</string>
|
||||
<string name="traceroute">Traceroute</string>
|
||||
<string name="intro_show">Show Introduction</string>
|
||||
|
|
Ładowanie…
Reference in New Issue