yanshouwang / bluetooth_low_energy

A Flutter plugin for controlling the bluetooth low energy.
https://pub.dev/packages/bluetooth_low_energy
MIT License
49 stars 16 forks source link

Setting serviceData,but sanner not found #92

Open tangdekun opened 2 months ago

tangdekun commented 2 months ago

image image

yanshouwang commented 2 months ago

Which platform are you running on?

yangfeifei1994 commented 2 months ago

I also couldn't get the serviceData on Windows

yanshouwang commented 2 months ago

I also couldn't get the serviceData on Windows

I'm afraid that is a normal behavior on Windows, The GATT server and advertisement broadcast are two different concepts, when you advertising and act as a GATT server at the same time on Windows, the scanner will find two devices instead of one. One is the GATT server device and the other is advertising device(also known as iBeacon). I also wonder why the API is designed like this by Microsoft.

Here is a QA about this: https://learn.microsoft.com/en-us/answers/questions/189891/windows10-uwp-app-conflict-ble-advertisement-and-g

Here is the official docs about BLE on Windows, you can see the GATT server and Advertisements are two different features to use. When we use the GattServiceProvider API, there is nothing we can do to the advertisement. And when we use the BluetoothLEAdvertisementPublisher API, the device will be unconnectable and just run as an iBeacon device. Currently I combined these tow roles when you call the startAdvertising API in this plugin. But the behavior maybe different on different devices. There will be two devices on my desktop, one is the GATT server and the other is the advertisement publisher.

yangfeifei1994 commented 2 months ago

image I'm currently using low-energy Bluetooth without a central device. When testing device scanning on Android, I'm not receiving the serviceData. Could you please check if there's anything I need to configure? Below is the broadcast data from the debugging tool.

89d96ea3352a9732152ca6fea5674a0

yanshouwang commented 2 months ago

I'm currently using low-energy Bluetooth without a central device. When testing device scanning on Android, I'm not receiving the serviceData. Could you please check if there's anything I need to configure? Below is the broadcast data from the debugging tool.

Do you mean you can't discover service data using this plugin? From the debugging tool, there is no service data in the advertisement. The servcie data type should be 0x16 or 0x20 or 0x21, but there is no this type in the advertisement. Is that peripheral is developed using this plugin?

yangfeifei1994 commented 2 months ago

I'm currently using low-energy Bluetooth without a central device. When testing device scanning on Android, I'm not receiving the serviceData. Could you please check if there's anything I need to configure? Below is the broadcast data from the debugging tool.我目前正在使用没有中央设备的低功耗蓝牙。在 Android 上测试设备扫描时,我没有收到 serviceData。您能否请检查一下我是否需要配置任何内容?下面是来自调试工具的广播数据。

Do you mean you can't discover service data using this plugin? From the debugging tool, there is no service data in the advertisement. The servcie data type should be 0x16 or 0x20 or 0x21, but there is no this type in the advertisement. Is that peripheral is developed using this plugin?你的意思是你不能用这个插件发现服务数据?从调试工具来看,播发中没有服务数据。servcie 数据类型应为 0x16 或 0x20 或 0x21,但广告中没有此类型。那个外围设备是用这个插件开发的吗?

I see, now I understand. Our hardware development engineer customized a broadcast data type as 0xFF. How can I retrieve this data?

yanshouwang commented 2 months ago

I see, now I understand. Our hardware development engineer customized a broadcast data type as 0xFF. How can I retrieve this data?

0xff means the manufacturer specific data. So you can get the customized data form the Advertisement.manufacturerSpecificData property.

yangfeifei1994 commented 2 months ago

I see, now I understand. Our hardware development engineer customized a broadcast data type as 0xFF. How can I retrieve this data?我明白了,现在我明白了。我们的硬件开发工程师将广播数据类型定制为0xFF。如何检索此数据?

0xff means the manufacturer specific data. So you can get the customized data form the Advertisement.manufacturerSpecificData property.0xff是指制造商的特定数据。因此,您可以从属性中获取自定义数据。

Thank you, I understand now.

tangdekun commented 2 months ago

Here are two question:

  1. if we start advertising without addService(service),deviceName is not found image image
  2. if start advertising without addService(service),but setting serviceUUIDs in Advertisement ,app is crash;
    App crached.
      PlatformException(winrt::hresult_error, 参数错误。, null, null)
      #0      MyPeripheralManagerHostAPI.startAdvertising (package:bluetooth_low_energy_windows/src/my_api.g.dart:1326:7)
      <asynchronous suspension>
      #1      MyPeripheralManager.startAdvertising (package:bluetooth_low_energy_windows/src/my_peripheral_manager.dart:132:5)
      <asynchronous suspension>
      #2      PeripheralManagerViewModel.startAdvertising (package:bluetooth_low_energy_example/view_models/peripheral_manager_view_model.dart:161:5)
      <asynchronous suspension>
      #3      PeripheralManagerView.build.<anonymous closure> (package:bluetooth_low_energy_example/views/peripheral_manager_view.dart:29:23)
      <asynchronous 
  3. if we start Advertising with addService(service), but setting serviceUUIDs or serviceData in Advertisement ,app is crash;
    [log] App crached.
      PlatformException(winrt::hresult_error, 参数错误。, null, null)
      #0      MyPeripheralManagerHostAPI.startAdvertising (package:bluetooth_low_energy_windows/src/my_api.g.dart:1326:7)
      <asynchronous suspension>
      #1      MyPeripheralManager.startAdvertising (package:bluetooth_low_energy_windows/src/my_peripheral_manager.dart:132:5)
      <asynchronous suspension>
      #2      PeripheralManagerViewModel.startAdvertising (package:bluetooth_low_energy_example/view_models/peripheral_manager_view_model.dart:161:5)
      <asynchronous suspension>
      #3      PeripheralManagerView.build.<anonymous closure> (package:bluetooth_low_energy_example/views/peripheral_manager_view.dart:29:23)
      <asynchronous suspension>
  4. only addService(service), but Advertising data is not found ;
    final value = Uint8List.fromList([0x01, 0x02, 0x03]);
    UUID mServiceUUID = UUID.fromString("0000FD35-0000-1000-8000-00805f9b34fb");
    UUID mServiceUUID1 =
        UUID.fromString("00009231-0000-1000-8000-00805f9b34fb");
    UUID mServiceUUID2 =
        UUID.fromString("00003166-0000-1000-8000-00805f9b34fb");
    final service = GATTService(
      uuid: mServiceUUID,
      isPrimary: true,
      includedServices: [],
      characteristics: [
        GATTCharacteristic.immutable(
          uuid: mServiceUUID1,
          value: value,
          descriptors: [],
        ),
        GATTCharacteristic.mutable(
          uuid: mServiceUUID2,
          properties: [
            GATTCharacteristicProperty.read,
            GATTCharacteristicProperty.write,
            GATTCharacteristicProperty.writeWithoutResponse,
            GATTCharacteristicProperty.notify,
            GATTCharacteristicProperty.indicate,
          ],
          permissions: [
            GATTCharacteristicPermission.read,
            GATTCharacteristicPermission.write,
          ],
          descriptors: [],
        ),
      ],
    );
    await _manager.addService(service);

    image image UUID FD35 is found,but not value

yanshouwang commented 2 months ago

Here are two question:

  1. if we start advertising without addService(service),deviceName is not found

  2. if start advertising without addService(service),but setting serviceUUIDs in Advertisement ,app is crash;

  3. if we start Advertising with addService(service), but setting serviceUUIDs or serviceData in Advertisement ,app is crash;

  4. only addService(service), but Advertising data is not found ;

See the https://github.com/yanshouwang/bluetooth_low_energy/issues/92#issuecomment-2300383381 above to see the limitation on Windows when act as a Peripheral.

Also notice that the startAdvertising method throws when the advertisement data is too large

tangdekun commented 2 months ago

image serviceData + manufacturerSpecificData = 6 byte ,data is not too large; on Windows when act as a Peripheral, startAdvertising and addService should be used Separately, if I use startAdvertising only, how to show deviceName and how to set Advertisement ?
only set manufacturerSpecificData is ok , so serviceUUIDs and serviceData is not allow to set?

yanshouwang commented 2 months ago

image serviceData + manufacturerSpecificData = 6 byte ,data is not too large; on Windows when act as a Peripheral, startAdvertising and addService should be used Separately, if I use startAdvertising only, how to show deviceName and how to set Advertisement ? only set manufacturerSpecificData is ok , so serviceUUIDs and serviceData is not allow to set?

I'm afraid we can't publish these data on Windows after looked up the Microsoft's docs.

According to this docs, the following data sections are reserved by system and not allowed to use for us. image

yanshouwang commented 2 months ago

Now that the advertisement data sections on Windows only support manufacturer specific data, we need to throws an UnsupportedError when the data sections which are unspported is set by develoers. And clearify this in the docs.

JUV-666 commented 2 months ago

@yanshouwang Hello, On Windows I have noticed that in the provided example for setting up GattServiceProviderAdvertisingParameters, the ServiceData is not being set. This is a crucial part of the advertisement data, especially when specific service-related information needs to be broadcast.

Here's the current example provided in the source:

auto parameters = winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::GattServiceProviderAdvertisingParameters(); parameters.IsDiscoverable(true); parameters.IsConnectable(true); However, it is missing the line to set the service data:

parameters.ServiceData(data); For completeness and to ensure the advertisement data is fully configured, the example should include this line. The corrected code should look like this:

auto parameters = winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::GattServiceProviderAdvertisingParameters(); parameters.IsDiscoverable(true); parameters.IsConnectable(true); parameters.ServiceData(data); // Add this line to set the service data 0x16 Please include the setting of ServiceData in the example to avoid any confusion and ensure that users can correctly set up their advertisement parameters.

Thank you!

yanshouwang commented 2 months ago

@yanshouwang

Hello,

On Windows

I have noticed that in the provided example for setting up GattServiceProviderAdvertisingParameters, the ServiceData is not being set. This is a crucial part of the advertisement data, especially when specific service-related information needs to be broadcast.

Here's the current example provided in the source:

auto parameters = winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::GattServiceProviderAdvertisingParameters();

parameters.IsDiscoverable(true);

parameters.IsConnectable(true);

However, it is missing the line to set the service data:

parameters.ServiceData(data);

For completeness and to ensure the advertisement data is fully configured, the example should include this line. The corrected code should look like this:

auto parameters = winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::GattServiceProviderAdvertisingParameters();

parameters.IsDiscoverable(true);

parameters.IsConnectable(true);

parameters.ServiceData(data); // Add this line to set the service data 0x16

Please include the setting of ServiceData in the example to avoid any confusion and ensure that users can correctly set up their advertisement parameters.

Thank you!

Oh. I have missed that the ServiceProvider can include the service data. Thanks for your advice. You can pull a request to add this feature!

tangdekun commented 2 months ago

@JUV-666 @yanshouwang parameters.ServiceData(data); // 添加此行以设置服务数据 0x16 Since the broadcast started with startAdvertising is non-connectable, my business requires the broadcast to be connectable, so I chose to use AddService to start the broadcast; however, the broadcast content cannot be displayed when using AddService to start the broadcast.So,Can this API solve the problem of using AddService alone to start broadcasting, but unable to display broadcast content?

And how to set the broadcast data, I configured it in the immutable value of the service's GATTCharacteristic. Is this correct?

GATTService createBasicGattService(Uint8List serviceData) {
    return GATTService(
      uuid: BleConstants.sServiceUUID,
      isPrimary: true,
      includedServices: [],
      characteristics: [
        GATTCharacteristic.immutable(
          uuid: BleConstants.sCharacteristicsImmutableUUID,
          value: serviceData,
          descriptors: [],
        ),
        GATTCharacteristic.mutable(
          uuid: BleConstants.sCharacteristicsMutableUUID,
          properties: [
            GATTCharacteristicProperty.read,
            GATTCharacteristicProperty.write,
            GATTCharacteristicProperty.writeWithoutResponse,
            GATTCharacteristicProperty.notify,
            GATTCharacteristicProperty.indicate,
          ],
          permissions: [
            GATTCharacteristicPermission.read,
            GATTCharacteristicPermission.write,
          ],
          descriptors: [],
        ),
      ],
    );
  }

image

yanshouwang commented 2 months ago

@tangdekun After this feature is added. You can get the service uuids which are added by addService and service data set in the startAdvertising method parameters. Other data sections will be disabled as it can't be included in the connectable GATT server. You will need to call startAdvertising. Just call the addService will not start the advertising.

github-actions[bot] commented 1 month ago

This issue is stale because it has been open for 30 days with no activity.