nativescript-community / ble

Connect to and interact with Bluetooth LE peripherals.
https://nativescript-community.github.io/ble/
MIT License
192 stars 77 forks source link

bluetooth.connect with autoDiscoverAll hangs on iOS for BT Assigned Numbers #256

Open two-bridges opened 1 year ago

two-bridges commented 1 year ago

I'm investigating an issue where bluetooth.connect() fails to resolve the promise when a serviceUUID falls under the Bluetooth Assigned Numbers list:

my project versions:

{
        "@nativescript/core": "^8.4.1",
        "@nativescript-community/ble": "^3.1.11",
}

the call to bluetooth.connect():

            await this.bluetooth.connect({
                UUID: deviceUuid,
                // autoDiscoverAll causes the hang... but only for those Assigned Number serviceUUIDs (link above)
                autoDiscoverAll: true, 
                onConnected: (peripheral) => {
                    // the onConnected() callback is never called... 
                },
                onDisconnected: function (peripheral) {
                    // onDisconnected IS called, on disconnect
                }
            });

I have tracked the problem down to: https://github.com/nativescript-community/ble/blob/master/src/bluetooth.ios.ts#L1643-L1644

    @bluetoothEnabled
    @prepareArgs
    public discoverCharacteristics(args: DiscoverCharacteristicsOptions) {
        // ...
                    const sUUID = CBUUIDToString(service.UUID);
                    if (UUID === pUUID && sUUID === args.serviceUUID) {
                        // ...
                    }
        // ...
    }

the issue is the following comparison fails:

# "0000181a-0000-1000-8000-00805f9b34fb" == "181a"
sUUID === args.serviceUUID

args.serviceUUID is being be modified by the decorator prepareArgs() to a "Short UUID", if the service's UUID matches a Bluetooth Assigned Number of the form

const pattern = /0000(.{4})-0000-1000-8000-00805f9b34fb/;

however, sUUID returned by CBUUIDToString(service.UUID) is a "Long UUID"

Long vs Short UUIDs:

I'll work on a fix and submit a PR today hopefully...

two-bridges commented 1 year ago

PR created in forked repo (I don't have access to this repo):

https://github.com/two-bridges/ble/pull/1

I'm testing it now...

two-bridges commented 1 year ago

my local testing passed. I'm not sure how to automate the testing. Since, it required physical BLE device and physical iPhone to get the result...

Anyway, could you please review the code and consider if/how to merge this into a future version 🙏

Here's my forked code with an open PR for consideration: https://github.com/two-bridges/ble/pull/1

Thanks 🙌

farfromrefug commented 1 year ago

@two-bridges i like the fact that you now compare long and short. Seems safer. Though what s weird is that I know for sure it was working for me for battery and other BAN. Might it be in a new iOS version? Anyway your PR looks good. Could you open it on this repo?

two-bridges commented 1 year ago

Yeah I have been using this plugin for a while and this issue was new for me...

There are two things that have changed on my side that could have caused this:

  1. iPhone upgrade to latest 16.x
  2. the arduino BLE programming is new (from a contractor). This programming should not really be using an Assigned Name actually... but here we are.

I cannot tell if (1) or (2) caused this issue, since they have both changed since I last did a build.

i like the fact that you now compare long and short. Seems safer

cool cool. I think this is the way to go too... should be backwards compatible

two-bridges commented 1 year ago

Anyway your PR looks good. Could you open it on this repo?

oh yeah, I've worked it out... will create the PR from my fork shortly

https://github.com/nativescript-community/ble/pull/258

thanks for the great plugin 🙌