Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple ProfileServiceNotBound errors when trying to write to a Peripheral #714

Open
PavlosTze opened this issue Jul 16, 2024 · 13 comments
Labels
bug Something isn't working
Milestone

Comments

@PavlosTze
Copy link
Contributor

Hello,

I have the following code:

    private suspend fun enableDescriptorNotification(descriptor: Descriptor) {
        try {
            peripheral.write(descriptor, ENABLE_NOTIFICATION_VALUE)
        } catch (e: GattWriteException) {
            Timber.w(e, "[enable descriptor notification]: GattWriteException - Result: ${e.result}")
        }
    }

And for some weeks already this code is producing a lot of ProfileServiceNotBound types of exception, the log is the following:

Non-fatal Exception: f7.N: Write failed: ProfileServiceNotBound
at com.juul.kable.BluetoothGattKt.writeCharacteristicOrThrow(BluetoothGatt.kt:58)
at com.juul.kable.BluetoothDeviceAndroidPeripheral$write$$inlined$execute$1.invokeSuspend(Connection.kt:126)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
at android.os.Handler.handleCallback(Handler.java:959)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.os.HandlerThread.run(HandlerThread.java:85)

As you can see from these 3 screenshots issues started in early June:
εικόνα
εικόνα
εικόνα

In case that helps, our app producing those is Open Source.

Based on what I read in your writeResultFrom and in the Android-related code:

    /**
     * Error code indicating that the profile service is not bound. You can bind a profile service
     * by calling {@link BluetoothAdapter#getProfileProxy}.
     */
    public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9;

Any chance you can catch this error without letting it fail? What is this related to? As there aren't any logs producing it in the past and we've been using Kable for around 2 years already.

@twyatt
Copy link
Member

twyatt commented Jul 16, 2024

Can you provide a breakdown of the failure rate per Android version?
I'm wondering if this is the result of behavior changes in newer versions of Android?

@PavlosTze
Copy link
Contributor Author

Can you provide a breakdown of the failure rate per Android version? I'm wondering if this is the result of behavior changes in newer versions of Android?

Sure, here it is:
εικόνα

@twyatt
Copy link
Member

twyatt commented Jul 18, 2024

Thanks for the info. We're seeing this in our apps as well. I'll try to allocate some time soon to investigate.

@twyatt
Copy link
Member

twyatt commented Jul 23, 2024

@PavlosTze I'm currently investigating this issue. Do you happen to know what version of Kable you first saw this issue in?

@twyatt twyatt added the bug Something isn't working label Jul 24, 2024
@PavlosTze
Copy link
Contributor Author

@twyatt It started with 0.31.1.

@twyatt
Copy link
Member

twyatt commented Jul 24, 2024

Thanks, I believe I've tracked down the cause:

I believe it was introduced in #648, when a bug was fixed (whereas Kable would silently ignore failures to write to a characteristic). In #648, that behavior was fixed (to now throw an exception if the write failed).

Unfortunately, some might be relying on the bug (that was fixed) where it didn't propagate a failure when the write fails.

I'm trying to determine what the best API/behavior might be for this situation. I'll follow up soon.

@PavlosTze
Copy link
Contributor Author

Sure, I just want to mention that this is a non-crash failure. Which means that if it failed before in the same way, the only thing happening now is that it's been showing up in the logs, not that big of a deal.

I'm wondering if we can solve it in the background based on what it says here?

    /**
     * Error code indicating that the profile service is not bound. You can bind a profile service
     * by calling {@link BluetoothAdapter#getProfileProxy}.
     */
    public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9;

Is it possible to bind a profile service if we get across this failure?

@twyatt
Copy link
Member

twyatt commented Jul 24, 2024

I suspect that the code comment you referenced is misleading in this case.

I believe the failure happens when a write occurs after a connection is lost / disposed; because the connection was disposed, the underlying Android GATT object no longer has a "profile service" (essentially a reference to the underlying Android BLE system) and so propagates that failure. I believe it is unrelated to getProfileProxy; perhaps Android just re-used this failure case for multiple failure conditions. 🤷

I think in most cases it is safe to ignore the failure (in the cases where it happens because the connection was recently disposed). The case where it might be problematic is where BluetoothAdapter#getProfileProxy is being utilized (I suspect this isn't common though), in which case the failure could indicate other issues (aside from just a connection being lost).

The reason it is important for Kable to propagate the failure though, is the consumer should be aware that the requested write operation did not complete as requested.

@twyatt twyatt added this to the 0.35.0 milestone Aug 29, 2024
@twyatt
Copy link
Member

twyatt commented Nov 6, 2024

The connection management, especially around I/O has been refactored. Can you try 0.35.0-rc and see if the issue has been resolved?
Or, more specifically: check that an appropriate (connection I/O) failure is propagated rather than the cryptic ERROR_PROFILE_SERVICE_NOT_BOUND failure.

@PavlosTze
Copy link
Contributor Author

Hey, unfortunately I couldn't reproduce the error, but there are numerous crashlytics logs from our users. But...As I saw the changes of 0.35.0-rc and there are plenty of them, I can try to find some time in the next few days to test it myself and come back with any issues I may found (or just communicate that everything looked OK). How does that sound?

@twyatt
Copy link
Member

twyatt commented Nov 10, 2024

That sounds great. I appreciate you taking the time to help test. ❤️

@PavlosTze
Copy link
Contributor Author

That sounds great. I appreciate you taking the time to help test. ❤️

Hey, I tested it thoroughly today, I opened some issues. FYI our project is open-source, in case you want to have a look at how we use Kable, you can view our BluetoothConnectionManager:

Feel free to ask me if anything, happy to help.

@twyatt
Copy link
Member

twyatt commented Nov 12, 2024

Thanks for reporting all those issues! Super helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants