Skip to content

web: with manufacturerData filter for requestDevice, namePrefix is ignored #774

@arxarx

Description

@arxarx

Describe the bug
On web platform, when requestDevice is used like this:

const peripheral = await BleClient.requestDevice({
  namePrefix        : "abc"
});

It works fine. But after manufacturerData filter is added:

const peripheral = await BleClient.requestDevice({
  namePrefix        : "abc",
  manufacturerData: [{
    companyIdentifier : 0x02FF,
    dataPrefix        : new Uint8Array([0x00]),
    mask              : new Uint8Array([0x00])
  }]
});

the namePrefix is ignored, at least for devices which have the requested manufacturerData.

I believe there's a bug here:
https://github.com/steinerjakob/bluetooth-le/blob/c6453910e383212a9aca3aa11a92e7e644332b99/src/web.ts#L381

  private getFilters(options?: RequestBleDeviceOptions): BluetoothLEScanFilter[] {
    const filters: BluetoothLEScanFilter[] = [];
    for (const service of options?.services ?? []) {
      filters.push({
        services: [service],
        name: options?.name,
        namePrefix: options?.namePrefix,
      });
    }
    if ((options?.name || options?.namePrefix) && filters.length === 0) {
      filters.push({
        name: options.name,
        namePrefix: options.namePrefix,
      });
    }
    for (const manufacturerData of options?.manufacturerData ?? []) {
      filters.push({
        manufacturerData: [manufacturerData],
        // !!!! my note: missing name and namePrefix here !!!!!
      });
    }
    return filters;
  }

I think the filter for manufacturerData should also contain the fields name and namePrefix, the same as the services filter does.
My theory is that filters are applied in OR fashion. It's not very clear from the documentation. I think that currently, requestDevice will find all devices which have these manufacturerData OR this namePrefix, which effectively ignores namePrefix for devices with the requested manufacturerData.

Expected behavior
Both nameFilter and manufacturerData filters should be applied in an "AND" fashion. This is how it works - to my knowledge - on iOS and Android.

Plugin version:

  • @capacitor-community/bluetooth-le: 7.1.1

Desktop (please complete the following information):

  • OS: MacOS Sonoma 14.7.6
  • Browser: Chrome
  • Version 139.0.7258.139 (Official Build) (arm64)

Additional context
Introduced in #752 I believe.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions