From d29c86ee74ad64cbd91013a60cb51b5b5213e69e Mon Sep 17 00:00:00 2001 From: andrekir Date: Sun, 16 Oct 2022 12:36:21 -0300 Subject: [PATCH 1/7] admin channel not case-sensitive --- app/src/main/java/com/geeksville/mesh/model/UIState.kt | 3 ++- app/src/main/java/com/geeksville/mesh/service/MeshService.kt | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) 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 9886ecf2..d1505c69 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -383,7 +383,8 @@ class UIViewModel @Inject constructor( } } - val adminChannelIndex: Int get() = channelSet.settingsList.map { it.name }.indexOf("admin") + val adminChannelIndex: Int + get() = channelSet.settingsList.map { it.name.lowercase() }.indexOf("admin") fun requestShutdown(idNum: Int) { try { 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 66de2ef5..f2841949 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -930,7 +930,7 @@ class MeshService : Service(), Logging { } private fun addChannelSettings(ch: ChannelProtos.Channel) { - if (ch.index == 0 || ch.settings.name == "admin") adminChannelIndex = ch.index + if (ch.index == 0 || ch.settings.name.lowercase() == "admin") adminChannelIndex = ch.index serviceScope.handledLaunch { channelSetRepository.addSettings(ch) } @@ -1354,7 +1354,7 @@ class MeshService : Service(), Logging { } private fun setChannel(ch: ChannelProtos.Channel) { - if (ch.index == 0 || ch.settings.name == "admin") adminChannelIndex = ch.index + if (ch.index == 0 || ch.settings.name.lowercase() == "admin") adminChannelIndex = ch.index sendToRadio(newMeshPacketTo(myNodeNum).buildAdminPacket(wantResponse = true) { setChannel = ch }) From a3cc422afc56daef6c763a42b5591f6f831c0fe8 Mon Sep 17 00:00:00 2001 From: andrekir Date: Sun, 16 Oct 2022 12:40:05 -0300 Subject: [PATCH 2/7] reset channels no longer in use --- .../java/com/geeksville/mesh/model/UIState.kt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) 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 d1505c69..b9862b3d 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -44,8 +44,9 @@ import java.io.BufferedWriter import java.io.FileNotFoundException import java.io.FileWriter import java.text.SimpleDateFormat -import java.util.* +import java.util.Locale import javax.inject.Inject +import kotlin.math.max import kotlin.math.roundToInt /// Given a human name, strip out the first letter of the first three words and return that as the initials for @@ -312,17 +313,17 @@ class UIViewModel @Inject constructor( private var _channelSet: AppOnlyProtos.ChannelSet get() = channels.value.protobuf set(value) { - val asChannels = value.settingsList.mapIndexed { i, c -> + (0 until max(_channelSet.settingsCount, value.settingsCount)).map { i -> channel { - role = if (i == 0) ChannelProtos.Channel.Role.PRIMARY - else ChannelProtos.Channel.Role.SECONDARY + role = when (i) { + 0 -> ChannelProtos.Channel.Role.PRIMARY + in 1 until value.settingsCount -> ChannelProtos.Channel.Role.SECONDARY + else -> ChannelProtos.Channel.Role.DISABLED + } index = i - settings = c + settings = value.settingsList.getOrNull(i) ?: channelSettings { } } - } - - debug("Sending channels to device") - asChannels.forEach { + }.forEach { meshService?.setChannel(it.toByteArray()) } From f4007744814dac3bfdc28a054852e91b8189e1f3 Mon Sep 17 00:00:00 2001 From: andrekir Date: Sun, 16 Oct 2022 19:02:27 -0300 Subject: [PATCH 3/7] fix default channel LoRa settings --- app/src/main/java/com/geeksville/mesh/model/Channel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/model/Channel.kt b/app/src/main/java/com/geeksville/mesh/model/Channel.kt index 5b9077ac..6be86b58 100644 --- a/app/src/main/java/com/geeksville/mesh/model/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/Channel.kt @@ -29,7 +29,8 @@ data class Channel( // The default channel that devices ship with val default = Channel( channelSettings { psk = ByteString.copyFrom(defaultPSK) }, - loRaConfig { usePreset = true; modemPreset = ModemPreset.LONG_FAST } + // reference: NodeDB::installDefaultConfig + loRaConfig { txEnabled = true; modemPreset = ModemPreset.LONG_FAST; hopLimit = 3 } ) } From 9d0c637ec1c1a7ee33081fba581381d3f4e0c15e Mon Sep 17 00:00:00 2001 From: andrekir Date: Sun, 16 Oct 2022 19:12:23 -0300 Subject: [PATCH 4/7] updating proto submodule to latest --- app/src/main/proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/proto b/app/src/main/proto index d3dfaa63..c85caacf 160000 --- a/app/src/main/proto +++ b/app/src/main/proto @@ -1 +1 @@ -Subproject commit d3dfaa63a5108c1da7571cd780efaf561b99cc74 +Subproject commit c85caacf3c92717ad5547927c784cbe527ee1d74 From 6c37b451c3c2001359722568047772ceab5149f4 Mon Sep 17 00:00:00 2001 From: andrekir Date: Sun, 16 Oct 2022 19:16:33 -0300 Subject: [PATCH 5/7] clean up view bindings --- .../java/com/geeksville/mesh/MainActivity.kt | 18 ++++-------------- .../java/com/geeksville/mesh/ui/MapFragment.kt | 10 +++------- app/src/main/res/layout/map_view.xml | 1 + 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 8d728cd3..aa02eca0 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -13,7 +13,6 @@ import android.text.method.LinkMovementMethod import android.view.Menu import android.view.MenuItem import android.view.MotionEvent -import android.view.View import android.widget.TextView import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts @@ -58,7 +57,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.cancel import java.nio.charset.Charset import java.text.DateFormat -import java.util.* +import java.util.Date import javax.inject.Inject /* @@ -303,8 +302,7 @@ class MainActivity : BaseActivity(), Logging { } private fun initToolbar() { - val toolbar = - findViewById(R.id.toolbar) as Toolbar + val toolbar = binding.toolbar as Toolbar setSupportActionBar(toolbar) supportActionBar?.setDisplayShowTitleEnabled(false) } @@ -497,11 +495,7 @@ class MainActivity : BaseActivity(), Logging { private fun showSnackbar(msgId: Int) { try { - Snackbar.make( - findViewById(android.R.id.content), - msgId, - Snackbar.LENGTH_LONG - ).show() + Snackbar.make(binding.root, msgId, Snackbar.LENGTH_LONG).show() } catch (ex: IllegalStateException) { errormsg("Snackbar couldn't find view for msgId $msgId") } @@ -509,11 +503,7 @@ class MainActivity : BaseActivity(), Logging { private fun showSnackbar(msg: String) { try { - Snackbar.make( - findViewById(android.R.id.content), - msg, - Snackbar.LENGTH_INDEFINITE - ) + Snackbar.make(binding.root, msg, Snackbar.LENGTH_INDEFINITE) .apply { view.findViewById(R.id.snackbar_text).isSingleLine = false } .setAction(R.string.okay) { // dismiss diff --git a/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt index 4b44917a..5bb19681 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt @@ -24,7 +24,6 @@ import com.geeksville.mesh.model.map.CustomOverlayManager import com.geeksville.mesh.model.map.CustomTileSource import com.geeksville.mesh.util.formatAgo import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.google.android.material.floatingactionbutton.FloatingActionButton import dagger.hilt.android.AndroidEntryPoint import org.osmdroid.api.IMapController import org.osmdroid.config.Configuration @@ -54,7 +53,6 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener { // UI Elements private lateinit var binding: MapViewBinding private lateinit var map: MapView - private lateinit var downloadBtn: FloatingActionButton private lateinit var cacheEstimate: TextView private lateinit var executeJob: Button private var downloadPrompt: AlertDialog? = null @@ -92,8 +90,6 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = MapViewBinding.inflate(inflater) - downloadBtn = binding.root.findViewById(R.id.downloadButton) - binding.cacheLayout.visibility = View.GONE return binding.root } @@ -134,7 +130,7 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener { } zoomToNodes(mapController) } - downloadBtn.setOnClickListener(this) + binding.downloadButton.setOnClickListener(this) } override fun onClick(v: View) { @@ -384,9 +380,9 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener { private fun renderDownloadButton() { if (!(map.tileProvider.tileSource as OnlineTileSourceBase).tileSourcePolicy.acceptsBulkDownload()) { - downloadBtn.hide() + binding.downloadButton.hide() } else { - downloadBtn.show() + binding.downloadButton.show() } } diff --git a/app/src/main/res/layout/map_view.xml b/app/src/main/res/layout/map_view.xml index 85597ab6..96d4a954 100644 --- a/app/src/main/res/layout/map_view.xml +++ b/app/src/main/res/layout/map_view.xml @@ -28,6 +28,7 @@ android:id="@+id/cache_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> From ce140383bb33f2a9cb2a445fd0d275121550e385 Mon Sep 17 00:00:00 2001 From: andrekir Date: Sun, 16 Oct 2022 19:19:03 -0300 Subject: [PATCH 6/7] install channels from wantConfig --- .../datastore/ChannelSetRepository.kt | 2 +- .../geeksville/mesh/service/MeshService.kt | 39 ++++++++----------- .../geeksville/mesh/ui/SettingsFragment.kt | 9 +++-- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt index 25438373..bcb1f7f1 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt @@ -42,7 +42,7 @@ class ChannelSetRepository @Inject constructor( suspend fun addSettings(channel: ChannelProtos.Channel) { channelSetStore.updateData { preference -> - preference.toBuilder().addSettings(channel.index, channel.settings).build() + preference.toBuilder().addSettings(channel.settings).build() } } 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 f2841949..ffcf1dba 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -712,28 +712,8 @@ class MeshService : Service(), Logging { val ch = a.getChannelResponse debug("Admin: Received channel ${ch.index}") - val packetToSave = MeshLog( - UUID.randomUUID().toString(), - "Channel", - System.currentTimeMillis(), - ch.toString() - ) - insertMeshLog(packetToSave) - if (ch.index + 1 < mi.maxChannels) { - - // Stop once we get to the first disabled entry - if (/* ch.hasSettings() || */ ch.role != ChannelProtos.Channel.Role.DISABLED) { - // Not done yet, add new entries and request next channel - addChannelSettings(ch) - requestChannel(ch.index + 1) - } else { - debug("We've received the last channel, allowing rest of app to start...") - onHasSettings() - } - } else { - debug("Received max channels, starting app") - onHasSettings() + handleChannel(ch) } } } @@ -1110,6 +1090,7 @@ class MeshService : Service(), Logging { MeshProtos.FromRadio.CONFIG_COMPLETE_ID_FIELD_NUMBER -> handleConfigComplete(proto.configCompleteId) MeshProtos.FromRadio.MY_INFO_FIELD_NUMBER -> handleMyInfo(proto.myInfo) MeshProtos.FromRadio.NODE_INFO_FIELD_NUMBER -> handleNodeInfo(proto.nodeInfo) + MeshProtos.FromRadio.CHANNEL_FIELD_NUMBER -> handleChannel(proto.channel) MeshProtos.FromRadio.CONFIG_FIELD_NUMBER -> handleDeviceConfig(proto.config) MeshProtos.FromRadio.MODULECONFIG_FIELD_NUMBER -> handleModuleConfig(proto.moduleConfig) else -> errormsg("Unexpected FromRadio variant") @@ -1152,6 +1133,18 @@ class MeshService : Service(), Logging { // setModuleConfig(config) } + private fun handleChannel(ch: ChannelProtos.Channel) { + debug("Received channel ${ch.index}") + val packetToSave = MeshLog( + UUID.randomUUID().toString(), + "Channel", + System.currentTimeMillis(), + ch.toString() + ) + insertMeshLog(packetToSave) + if (ch.role != ChannelProtos.Channel.Role.DISABLED) addChannelSettings(ch) + } + /** * Convert a protobuf NodeInfo into our model objects and update our node DB */ @@ -1328,8 +1321,8 @@ class MeshService : Service(), Logging { if (deviceVersion < minDeviceVersion || appVersion < minAppVersion) { info("Device firmware or app is too old, faking config so firmware update can occur") clearLocalConfig() - onHasSettings() - } else requestChannel(0) // Now start reading channels + } + onHasSettings() } } else warn("Ignoring stale config complete") diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 3c9bae20..4f37591d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -299,14 +299,15 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { model.localConfig.asLiveData().observe(viewLifecycleOwner) { if (!model.isConnected()) { val configCount = it.allFields.size - binding.scanStatusText.text = "Device config ($configCount / 7)" + if (configCount > 0) + binding.scanStatusText.text = "Device config ($configCount / 7)" } else updateNodeInfo() } model.channels.asLiveData().observe(viewLifecycleOwner) { - if (!model.isConnected()) { - val channelCount = it.protobuf.settingsCount - if (channelCount > 0) binding.scanStatusText.text = "Channels ($channelCount / 8)" + if (!model.isConnected()) it.protobuf.let { ch -> + if (!ch.hasLoraConfig() && ch.settingsCount > 0) + binding.scanStatusText.text = "Channels (${ch.settingsCount} / 8)" } } From a3aa2a51aa3d81bc42ce0f540ad2fa745f778534 Mon Sep 17 00:00:00 2001 From: andrekir Date: Sun, 16 Oct 2022 19:30:45 -0300 Subject: [PATCH 7/7] 1.3.45 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9f8ea339..cc66f08c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,8 +43,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 30 - versionCode 20343 // format is Mmmss (where M is 1+the numeric major number - versionName "1.3.43" + versionCode 20345 // format is Mmmss (where M is 1+the numeric major number + versionName "1.3.45" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // per https://developer.android.com/studio/write/vector-asset-studio