don't let user update firmware without setting a region.

This commit is contained in:
Kevin Hester
2021-03-20 17:47:02 +08:00
parent fb07b1dc83
commit c9d18b00a4
4 changed files with 53 additions and 48 deletions

View File

@@ -134,15 +134,10 @@ class UIViewModel(private val app: Application) : AndroidViewModel(app), Logging
}
}
var region: RadioConfigProtos.RegionCode?
get() = radioConfig.value?.preferences?.region
var region: RadioConfigProtos.RegionCode
get() = meshService?.region?.let { RadioConfigProtos.RegionCode.forNumber(it) } ?: RadioConfigProtos.RegionCode.Unset
set(value) {
val config = radioConfig.value
if (value != null && config != null) {
val builder = config.toBuilder()
builder.preferencesBuilder.region = value
setRadioConfig(builder.build())
}
meshService?.region = value.number
}
/// hardware info about our local device (can be null)

View File

@@ -1313,6 +1313,28 @@ class MeshService : Service(), Logging {
}
private fun setRegionOnDevice() {
val curConfigRegion =
radioConfig?.preferences?.region ?: RadioConfigProtos.RegionCode.Unset
if (curConfigRegion.number != curRegionValue && curRegionValue != RadioConfigProtos.RegionCode.Unset_VALUE)
if (deviceVersion >= minFirmwareVersion) {
info("Telling device to upgrade region")
// Tell the device to set the new region field (old devices will simply ignore this)
radioConfig?.let { currentConfig ->
val newConfig = currentConfig.toBuilder()
val newPrefs = currentConfig.preferences.toBuilder()
newPrefs.regionValue = curRegionValue
newConfig.preferences = newPrefs.build()
sendRadioConfig(newConfig.build())
}
} else
warn("Device is too old to understand region changes")
}
/**
* If we are updating nodes we might need to use old (fixed by firmware build)
* region info to populate our new universal ROMs.
@@ -1346,23 +1368,7 @@ class MeshService : Service(), Logging {
}
// If nothing was set in our (new style radio preferences, but we now have a valid setting - slam it in)
if (curConfigRegion == RadioConfigProtos.RegionCode.Unset && curRegionValue != RadioConfigProtos.RegionCode.Unset_VALUE) {
if (deviceVersion >= minFirmwareVersion) {
info("Telling device to upgrade region")
// Tell the device to set the new region field (old devices will simply ignore this)
radioConfig?.let { currentConfig ->
val newConfig = currentConfig.toBuilder()
val newPrefs = currentConfig.preferences.toBuilder()
newPrefs.regionValue = curRegionValue
newConfig.preferences = newPrefs.build()
sendRadioConfig(newConfig.build())
}
} else
warn("Device is too old to understand region changes")
}
setRegionOnDevice()
}
}
@@ -1651,7 +1657,7 @@ class MeshService : Service(), Logging {
offlineSentPackets.add(p)
}
val binder = object : IMeshService.Stub() {
private val binder = object : IMeshService.Stub() {
override fun setDeviceAddress(deviceAddr: String?) = toRemoteExceptions {
debug("Passing through device change to radio service: ${deviceAddr.anonymize}")
@@ -1675,6 +1681,12 @@ class MeshService : Service(), Logging {
}
override fun getUpdateStatus(): Int = SoftwareUpdateService.progress
override fun getRegion(): Int = curRegionValue
override fun setRegion(regionCode: Int) = toRemoteExceptions {
curRegionValue = regionCode
setRegionOnDevice()
}
override fun startFirmwareUpdate() = toRemoteExceptions {
doFirmwareUpdate()

View File

@@ -524,7 +524,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
}
/// Set the correct update button configuration based on current progress
private fun refreshUpdateButton() {
private fun refreshUpdateButton(enable: Boolean) {
debug("Reiniting the udpate button")
val info = model.myNodeInfo.value
val service = model.meshService
@@ -535,7 +535,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
val progress = service.updateStatus
binding.updateFirmwareButton.isEnabled =
binding.updateFirmwareButton.isEnabled = enable &&
(progress < 0) // if currently doing an upgrade disable button
if (progress >= 0) {
@@ -572,7 +572,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
val connected = model.isConnected.value
val isConnected = connected == MeshService.ConnectionState.CONNECTED
binding.nodeSettings.visibility = if(isConnected) View.VISIBLE else View.GONE
binding.nodeSettings.visibility = if (isConnected) View.VISIBLE else View.GONE
if (connected == MeshService.ConnectionState.DISCONNECTED)
model.ownerName.value = ""
@@ -582,25 +582,19 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
val spinner = binding.regionSpinner
val unsetIndex = regions.indexOf(RadioConfigProtos.RegionCode.Unset.name)
spinner.onItemSelectedListener = null
if(region != null) {
debug("current region is $region")
var regionIndex = regions.indexOf(region.name)
if(regionIndex == -1) // Not found, probably because the device has a region our app doesn't yet understand. Punt and say Unset
regionIndex = unsetIndex
// We don't want to be notified of our own changes, so turn off listener while making them
spinner.setSelection(regionIndex, false)
spinner.onItemSelectedListener = regionSpinnerListener
spinner.isEnabled = true
}
else {
warn("region is unset!")
spinner.setSelection(unsetIndex, false)
spinner.isEnabled = false // leave disabled, because we can't get our region
}
debug("current region is $region")
var regionIndex = regions.indexOf(region.name)
if (regionIndex == -1) // Not found, probably because the device has a region our app doesn't yet understand. Punt and say Unset
regionIndex = unsetIndex
// We don't want to be notified of our own changes, so turn off listener while making them
spinner.setSelection(regionIndex, false)
spinner.onItemSelectedListener = regionSpinnerListener
spinner.isEnabled = true
// If actively connected possibly let the user update firmware
refreshUpdateButton()
refreshUpdateButton(region != RadioConfigProtos.RegionCode.Unset)
// Update the status string (highest priority messages first)
val info = model.myNodeInfo.value
@@ -620,7 +614,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
}
}
private val regionSpinnerListener = object : AdapterView.OnItemSelectedListener{
private val regionSpinnerListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>,
view: View,
@@ -652,7 +646,8 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
// init our region spinner
val spinner = binding.regionSpinner
val regionAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, regions)
val regionAdapter =
ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, regions)
regionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = regionAdapter
@@ -965,7 +960,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
private val updateProgressReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
refreshUpdateButton()
refreshUpdateButton(true)
}
}