Skip to content

Use meshtastic_HardwareModel_PRIVATE_HW to resolve crashing on android meshtastic client#3

Open
dblaber wants to merge 2 commits intoexploiteers:masterfrom
dblaber:master
Open

Use meshtastic_HardwareModel_PRIVATE_HW to resolve crashing on android meshtastic client#3
dblaber wants to merge 2 commits intoexploiteers:masterfrom
dblaber:master

Conversation

@dblaber
Copy link

@dblaber dblaber commented Aug 23, 2025

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) image

🤝 Attestations

  • [YES] I have tested that my proposed changes behave as described.

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]

…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.
@dblaber dblaber changed the title If exploiteers pager constant is set, build is obviously targeting ha… Use meshtastic_HardwareModel_PRIVATE_HW to resolve crashing on android meshtastic client Aug 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant