NordicSemiconductor / Android-nRF-Mesh-Library

The Bluetooth Mesh Provisioner and Configurator library.
https://www.nordicsemi.com/
BSD 3-Clause "New" or "Revised" License
414 stars 177 forks source link

java.lang.NullPointerException: Attempt to invoke interface method 'void no.nordicsemi.android.mesh.InternalTransportCallbacks.onMeshPduCreated(int, byte[])' on a null object reference #447

Closed KcLeung514 closed 2 years ago

KcLeung514 commented 3 years ago

Describe the bug Exception may thrown if Invoke "MeshManagerApi#createMeshPdu" too often.

To Reproduce Invoke "MeshManagerApi#createMeshPdu" method with high frequency. ( User send "VendorModelMessageAcked" via trigger UI, the interval around 1 seconds. )

Expected behavior Let app client catch the exception to avoid app crash.

Platform details:

Logs / Screenshots

Fatal Exception: java.lang.NullPointerException: Attempt to invoke interface method 'void no.nordicsemi.android.mesh.InternalTransportCallbacks.onMeshPduCreated(int, byte[])' on a null object reference
       at no.nordicsemi.android.mesh.transport.MeshMessageState.sendSegmentAcknowledgementMessage(MeshMessageState.java:59)
       at no.nordicsemi.android.mesh.transport.LowerTransportLayer.sendBlockAck(LowerTransportLayer.java:115)
       at no.nordicsemi.android.mesh.transport.LowerTransportLayer.lambda$initSegmentedAccessAcknowledgementTimer$0(LowerTransportLayer.java:7)
       at no.nordicsemi.android.mesh.transport.LowerTransportLayer.$r8$lambda$qTByC7sBLyiT_YEVpMUYnkrHITk(LowerTransportLayer.java)
       at no.nordicsemi.android.mesh.transport.LowerTransportLayer$$InternalSyntheticLambda$0$40fa1d885b2ecaa88363e7d5e92ea6befb4732f4aefe7a7290462273435dc7a2$0.run(LowerTransportLayer.java:12)
       at android.os.Handler.handleCallback(Handler.java:789)
       at android.os.Handler.dispatchMessage(Handler.java:98)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6944)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
roshanrajaratnam commented 3 years ago

Hi, are you still having this issue? I am trying to reproduce this on a Pixel 5 with Android 12 and I don't see this happening.

roshanrajaratnam commented 3 years ago

I just did some tests with a Galaxy S7 running Android 8.0.0 and I am not able to reproduce this.

slydeur commented 3 years ago

Hi @roshanrajaratnam,

we're experiencing this issue from time to time. Sadly i don't have a reliable way to reproduce this. The Use Case where this happens in our development is that we request 3-4 Properties (on a detail page) at the same time (queued) and we don't get an answer for some of them. Then we give it a retry and maybe again. While developing we're navigating on this detail page often and then this crash happens.

I hope this might help you to reproduce this error 🙋‍♂️

roshanrajaratnam commented 3 years ago

@slydeur I will be away from work today so I will definitely give this a test on Monday. Thanks for the details.

daretobeorjan commented 2 years ago

I'm actually seeing this problem as well, although similarly difficult to reproduce.

What I'm doing is sending a lot of model app key bind and add subscription/publish messages when we configure our node after provisioning. Around ~15 messages in very quick succession.

I've made a helper utility that sends a Set-message and then waits for the corresponding Status-message (using RX java). I am then chaining all those messages together so that the next is sent as soon as the previous receives its reply.

This usually triggers the NPE at around message 8-10 or so. I worked around it by adding a 200ms delay between each messages.

roshanrajaratnam commented 2 years ago

Does this happen when you send to multiple messages to multiple nodes?

daretobeorjan commented 2 years ago

Does this happen when you send to multiple messages to multiple nodes?

I'm just working with one node at the moment.

This is basically my setup:

fun sendAndWait(cmd, response): Single {
    return Single.create { e ->
        createMeshPdu(cmd)
        addIncomingMessageListener(response) {
            e.onNext(it)
        }
    }.timeout().retry()
}

sendAndWait(ConfigModelAppBind, ConfigModelAppStatus).flatMap {
sendAndWait(ConfigModelAppBind, ConfigModelAppStatus).flatMap {
// repeat for many more models
sendAndWait(ConfigModelSubscriptionAdd, ConfigModelSubscriptionStatus).flatMap {
// and many more
sendAndWait(ConfigModelPublicationSet, ConfigModelPublicationStatus)
// and many more
}.subscribe()

It seems to work when only chaining a handful of messages, but as soon as I approach 10, it starts failing. Not always on the same message, it varies a bit, probably due to timing.