Use meshtastic_HardwareModel_PRIVATE_HW to resolve crashing on android meshtastic client#3
Open
dblaber wants to merge 2 commits intoexploiteers:masterfrom
Open
Use meshtastic_HardwareModel_PRIVATE_HW to resolve crashing on android meshtastic client#3dblaber wants to merge 2 commits intoexploiteers:masterfrom
dblaber wants to merge 2 commits intoexploiteers:masterfrom
Conversation
…ckerpager, but meshtastic_HardwareModel_EXPLOITEERS_PAGER resolves to 251 in the protobuf generated code. This is problematic to the android app, and perhaps other equipment, as it causes the android app to crash anytime a device queries the nodeinfo for the hacker pager node (in other words, if they click the shortname in nodelist on android app of hackerpager node, their node will crash. Setting this to meshtastic_HardwareModel_PRIVATE_HW will return 255, which is recognized on the android devices protobuf, and not crash (and treated like a private developer device). According to https://meshtastic.org/docs/development/firmware/build/ (Alternative for Community Contributors section), Private Hardware is for non-official community meshtastic devices.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
If exploiteers pager constant is set, build is obviously targeting hackerpager, but meshtastic_HardwareModel_EXPLOITEERS_PAGER resolves to 251 in the protobuf generated code. This is problematic to the android app, and perhaps other equipment, as it causes the android app to crash anytime a device queries the nodeinfo for the hacker pager node (in other words, if they click the shortname in nodelist on android app of hackerpager node, their node will crash. Setting this to meshtastic_HardwareModel_PRIVATE_HW will return 255, which is recognized on the android devices protobuf, and not crash (and treated like a private developer device). According to https://meshtastic.org/docs/development/firmware/build/ (Alternative for Community Contributors section), Private Hardware is for non-official community meshtastic devices, so this should be the appropriate value, or Meshtastic would have to add support.
This fix is tested and works, in this screenshot, I have opened up my hackerpager node (from a different remote node, which was previously crashing before patch)
🤝 Attestations
Quick Note:
I have observed the latest the alpha version of android app now shows hardware info on the node list (as opposed to earlier only when you open a view of a node), which results the app crashing at startup if any hackerpager nodes are in the nodelist. This makes this (or another similar fix) somewhat important to fix fast.
Here is stacktrace from android client without the hardware model fix/change:
2025-08-23 10:06:20.033 8437-8437 AndroidRuntime com.geeksville.mesh E FATAL EXCEPTION: main Process: com.geeksville.mesh, PID: 8437 java.lang.IllegalArgumentException: Can't get the number of an unknown enum value. at com.geeksville.mesh.MeshProtos$HardwareModel.getNumber(Unknown Source:11) at com.geeksville.mesh.model.MetricsViewModel$1$2.invokeSuspend(Unknown Source:81) at com.geeksville.mesh.model.MetricsViewModel$1$2.invoke(SourceFile:2) at com.geeksville.mesh.model.MetricsViewModel$1$2.invoke(SourceFile:1) at kotlinx.coroutines.flow.FlowKt__LimitKt$drop$2$1.emit(SourceFile:8) at kotlinx.coroutines.flow.FlowKt__LimitKt$take$2$1.emit(Unknown Source:254) at kotlinx.coroutines.flow.FlowKt.emitAllImpl$FlowKt__ChannelsKt(Unknown Source:129) at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:11) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(Unknown Source:8) at kotlinx.coroutines.DispatchedTask.run(Unknown Source:114) at kotlinx.coroutines.EventLoopImplPlatform.processUnconfinedEvent(Unknown Source:23) at kotlinx.coroutines.internal.InlineList.resumeCancellableWith(Unknown Source:141) at kotlinx.coroutines.AbstractCoroutine.start(Unknown Source:106) at kotlinx.coroutines.JobKt.launch(Unknown Source:23) at kotlinx.coroutines.JobKt.launch$default(Unknown Source:12) at kotlinx.coroutines.flow.FlowKt.launchIn(Unknown Source:7) at com.geeksville.mesh.model.MetricsViewModel.<init>(Unknown Source:148) at com.geeksville.mesh.DaggerMeshUtilApplication_HiltComponents_SingletonC$ViewModelCImpl$SwitchingProvider.get(Unknown Source:214) at androidx.lifecycle.viewmodel.InitializerViewModelFactory.create(Unknown Source:123) at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(SourceFile:2) at androidx.lifecycle.ViewModelProvider$Factory.create(SourceFile:5) at androidx.emoji2.text.MetadataRepo.getViewModel$lifecycle_viewmodel_release(Unknown Source:93) at androidx.lifecycle.AtomicReference.get(Unknown Source:16) at androidx.core.math.MathUtils.get(Unknown Source:59) at androidx.core.math.MathUtils.viewModel(Unknown Source:4) at com.geeksville.mesh.navigation.NodesRoutesKt.nodeDetailGraph$lambda$17$lambda$13(Unknown Source:69) at com.geeksville.mesh.navigation.NodesRoutesKt.$r8$lambda$xw83FLYFDiTkvkyU_PnkBFXW0cw(Unknown Source:0) at com.geeksville.mesh.navigation.MapRoutesKt$$ExternalSyntheticLambda0.invoke(Unknown Source:48) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:28) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:3) at androidx.compose.material3.ButtonKt$Button$2$1.invoke(Unknown Source:56) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:11) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:1) at androidx.compose.runtime.AnchoredGroupPath.CompositionLocalProvider(SourceFile:81) at androidx.compose.runtime.saveable.SaveableStateHolderImpl.SaveableStateProvider(Unknown Source:95) at androidx.compose.ui.unit.IntRectKt.SaveableStateProvider(Unknown Source:139) at androidx.compose.material3.ButtonKt$Button$2$1.invoke(Unknown Source:98) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:11) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:1) at androidx.compose.runtime.AnchoredGroupPath.CompositionLocalProvider(SourceFile:29) at androidx.compose.ui.unit.IntRectKt.LocalOwnersProvider(Unknown Source:86) at androidx.navigation.compose.NavHostKt$NavHost$32.invoke(Unknown Source:122) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:28) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:3) at androidx.compose.foundation.text.TextFieldCursorKt$cursor$1.invoke(Unknown Source:150) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:20) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:2) 2025-08-23 10:06:20.033 8437-8437 AndroidRuntime com.geeksville.mesh E at androidx.compose.animation.Scale.AnimatedEnterExitImpl(Unknown Source:1305) at androidx.compose.animation.AnimatedContentKt$AnimatedContent$6$1.invoke(Unknown Source:264) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:11) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(SourceFile:1) at androidx.compose.animation.AnimatedContentKt.AnimatedContent(Unknown Source:864) at androidx.sqlite.SQLite.NavHost(SourceFile:369) at androidx.navigation.compose.NavHostKt$$ExternalSyntheticLambda4.invoke(Unknown Source:75) at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Unknown Source:564) at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Unknown Source:144) at androidx.compose.runtime.ComposerImpl.doCompose-aFTiNEg(Unknown Source:118) at androidx.compose.runtime.ComposerImpl.recompose-aFTiNEg$runtime_release(Unknown Source:30) at androidx.compose.runtime.CompositionImpl.recompose(Unknown Source:26) at androidx.compose.runtime.Recomposer.access$performRecompose(Unknown Source:102) at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$1.invoke(Unknown Source:484) at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(Unknown Source:6) at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(Unknown Source:47) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1568) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1579) at android.view.Choreographer.doCallbacks(Choreographer.java:1179) at android.view.Choreographer.doFrame(Choreographer.java:1104) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1553) at android.os.Handler.handleCallback(Handler.java:995) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loopOnce(Looper.java:248) at android.os.Looper.loop(Looper.java:338) at android.app.ActivityThread.main(ActivityThread.java:9067) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932) Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@afcd6c6, Dispatchers.Main.immediate]