* 调整接口

* 临时提交

* 重构 Android 平台代码

* 临时提交

* 临时提交

* Android 6.0.0-dev.0

* 临时提交

* 实现 Windows 接口

* windows-6.0.0-dev.0

* Darwin 6.0.0-dev.0

* 临时提交

* 1

* 临时提交

* 调整接口

* windows-6.0.0-dev.1

* 临时提交

* interface-6.0.0-dev.7

* interface-6.0.0-dev.8

* 临时提交

* windows-6.0.0-dev.2

* 删除多余脚本

* interface-6.0.0-dev.9

* 临时提交

* 临时提交

* interface-6.0.0-dev.10

* android-6.0.0-dev.1

* windows-6.0.0-dev.3

* 临时提交

* interface-6.0.0-dev.11

* windows-6.0.0-dev.4

* 更新 pubspec.lock

* 1

* interface-6.0.0-dev.12

* interface-6.0.0-dev.13

* interface-6.0.0-dev.14

* 临时提交

* interface-6.0.0-dev.15

* 临时提交

* interface-6.0.0-dev.16

* android-6.0.0-dev.2

* 临时提交

* windows-6.0.0-dev.5

* 临时提交

* 临时提交

* windows-6.0.0-dev.6

* 优化注释和代码样式

* 优化代码

* 临时提交

* 实现 Dart 接口

* darwin-6.0.0-dev.0

* linux-6.0.0-dev.0

* 修复已知问题

* 修复问题

* 6.0.0-dev.0

* 修改包名

* 更新版本

* 移除原生部分

* 临时提交

* 修复问题

* 更新 pigeon 19.0.0

* 更新 README,添加迁移文档

* linux-6.0.0-dev.1

* 解析扫描回复和扩展广播

* 修复 googletest 版本警告问题

* Use centralArgs instead of addressArgs

* interface-6.0.0-dev.18

* android-6.0.0-dev.4

* linux-6.0.0-dev.2

* windows-6.0.0-dev.8

* darwin-6.0.0-dev.2

* 6.0.0-dev.1

* Update LICENSE

* clang-format

* Combine ADV_IND and SCAN_RES

* TEMP commit: update exampe

* Adjust advertisement combine logic

* Implement `MyPeripheralMananger` on Windows

* Added NuGet auto download and scan for names on peripheral (#67)

* fetch nuget using other technique

* move FetchContent to right location in CMakeLists.txt

* also added hash for googletest

---------

Co-authored-by: Kevin De Keyser <kevin@dekeyser.ch>

* Fix errors.

* Check BluetoothAdapter role supported state and implement PeripheralManager on Flutter side.

* Sort code

* Fix known errors

* interface-6.0.0-dev.19

* windows-6.0.0-dev.9

* Optimize example

* android-6.0.0-dev.5

* Optimize the Adverrtisement BottomSheet.

* linux-6.0.0-dev.3

* Update dependency

* Fix example errors.

* Temp commit.

* darwin-6.0.0-dev.3

* 6.0.0-dev.2

* Update README.md

* 6.0.0

* darwin-6.0.0-dev.4

* android-6.0.0-dev.6

* 6.0.0-dev.3

* Update docs.

* interface-6.0.0

* android-6.0.0

* darwin-6.0.0

* linux-6.0.0

* windows-6.0.0

* 6.0.0

* Update dependency

---------

Co-authored-by: Kevin De Keyser <dekeyser.kevin97@gmail.com>
Co-authored-by: Kevin De Keyser <kevin@dekeyser.ch>
This commit is contained in:
渐渐被你吸引
2024-06-04 00:44:39 +08:00
committed by GitHub
parent 71de531ceb
commit 108b6a804f
380 changed files with 23782 additions and 14127 deletions

View File

@ -7,31 +7,18 @@
/// [1]: https://pub.dev/packages/bluetooth_low_energy
library;
export 'package:log_service/log_service.dart';
export 'src/event_args.dart';
export 'src/bluetooth_low_energy_state.dart';
export 'src/bluetooth_low_energy_event_args.dart';
export 'src/bluetooth_low_energy_manager.dart';
export 'src/bluetooth_low_energy_peer.dart';
export 'src/central_event_args.dart';
export 'src/central_manager.dart';
export 'src/central.dart';
export 'src/peripheral_event_args.dart';
export 'src/peripheral_manager.dart';
export 'src/peripheral.dart';
export 'src/uuid.dart';
export 'src/advertisement.dart';
export 'src/bluetooth_low_energy_state.dart';
export 'src/manufacturer_specific_data.dart';
export 'src/gatt_service.dart';
export 'src/gatt_characteristic.dart';
export 'src/gatt_characteristic_property.dart';
export 'src/gatt_characteristic_write_type.dart';
export 'src/gatt_descriptor.dart';
export 'src/my_bluetooth_low_energy_peer.dart';
export 'src/my_central.dart';
export 'src/my_peripheral.dart';
export 'src/my_gatt_attribute.dart';
export 'src/my_gatt_service.dart';
export 'src/my_gatt_characteristic.dart';
export 'src/my_gatt_descriptor.dart';
export 'src/advertisement.dart';
export 'src/connection_state.dart';
export 'src/gatt.dart';
export 'src/bluetooth_low_energy_manager.dart';
export 'src/central_manager.dart';
export 'src/peripheral_manager.dart';
export 'src/bluetooth_low_energy_peer.dart';
export 'src/central.dart';
export 'src/peripheral.dart';

View File

@ -4,24 +4,33 @@ import 'manufacturer_specific_data.dart';
import 'uuid.dart';
/// The advertisement of the peripheral.
class Advertisement {
final class Advertisement {
/// The name of the peripheral.
///
/// This field is available on Android, iOS and macOS, throws [UnsupportedError]
/// on other platforms.
final String? name;
/// The GATT service uuids of the peripheral.
final List<UUID> serviceUUIDs;
/// The GATT service data of the peripheral.
///
/// This field is available on Android and Windows, throws [UnsupportedError]
/// on other platforms.
final Map<UUID, Uint8List> serviceData;
/// The manufacturer specific data of the peripheral.
final ManufacturerSpecificData? manufacturerSpecificData;
///
/// This field is available on Android and Windows, throws [UnsupportedError]
/// on other platforms.
final List<ManufacturerSpecificData> manufacturerSpecificData;
/// Constructs an [Advertisement].
Advertisement({
this.name,
this.serviceUUIDs = const [],
this.serviceData = const {},
this.manufacturerSpecificData,
this.manufacturerSpecificData = const [],
});
}

View File

@ -1,11 +0,0 @@
import 'bluetooth_low_energy_state.dart';
import 'event_args.dart';
/// The bluetooth low energy state changed event arguments.
class BluetoothLowEnergyStateChangedEventArgs extends EventArgs {
/// The new state of the bluetooth low energy.
final BluetoothLowEnergyState state;
/// Constructs a [BluetoothLowEnergyStateChangedEventArgs].
BluetoothLowEnergyStateChangedEventArgs(this.state);
}

View File

@ -1,16 +1,51 @@
import 'package:log_service/log_service.dart';
import 'package:hybrid_logging/hybrid_logging.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'bluetooth_low_energy_event_args.dart';
import 'bluetooth_low_energy_state.dart';
import 'event_args.dart';
/// The bluetooth low energy state changed event arguments.
final class BluetoothLowEnergyStateChangedEventArgs extends EventArgs {
/// The new state of the bluetooth low energy.
final BluetoothLowEnergyState state;
/// Constructs a [BluetoothLowEnergyStateChangedEventArgs].
BluetoothLowEnergyStateChangedEventArgs(this.state);
}
/// The abstract base class that manages central and peripheral objects.
abstract class BluetoothLowEnergyManager implements LogController {
abstract interface class BluetoothLowEnergyManager implements LogController {
/// Gets the manager's state.
BluetoothLowEnergyState get state;
/// Tells the manager's state updated.
Stream<BluetoothLowEnergyStateChangedEventArgs> get stateChanged;
/// Sets up the manager.
Future<void> setUp();
/// Requests permissions to be granted to this application. These permissions
/// must be requested in your manifest, they should not be granted to your app,
/// and they should have protection level dangerous, regardless whether they
/// are declared by the platform or a third-party app.
///
/// This method is available on Android, throws [UnsupportedError] on other
/// platforms.
Future<bool> authorize();
/// Gets the manager's state.
Future<BluetoothLowEnergyState> getState();
/// Show screen of details about a particular application.
///
/// This method is available on Android and iOS, throws [UnsupportedError] on
/// other platforms.
Future<void> showAppSettings();
}
/// The abstract base channel class that manages central and peripheral objects.
abstract base class PlatformBluetoothLowEnergyManager extends PlatformInterface
with TypeLogger, LoggerController
implements BluetoothLowEnergyManager {
/// Constructs a [PlatformBluetoothLowEnergyManager].
PlatformBluetoothLowEnergyManager({
required super.token,
});
/// Initializes the [PlatformBluetoothLowEnergyManager].
void initialize();
}

View File

@ -1,7 +1,19 @@
import 'uuid.dart';
/// An object that represents a remote device.
abstract class BluetoothLowEnergyPeer {
abstract base class BluetoothLowEnergyPeer {
/// The UUID associated with the peer.
UUID get uuid;
final UUID uuid;
BluetoothLowEnergyPeer({
required this.uuid,
});
@override
int get hashCode => uuid.hashCode;
@override
bool operator ==(Object other) {
return other is BluetoothLowEnergyPeer && other.uuid == uuid;
}
}

View File

@ -1,4 +1,16 @@
import 'bluetooth_low_energy_peer.dart';
/// A remote device connected to a local app, which is acting as a peripheral.
abstract class Central extends BluetoothLowEnergyPeer {}
base class Central extends BluetoothLowEnergyPeer {
Central({
required super.uuid,
});
@override
int get hashCode => uuid.hashCode;
@override
bool operator ==(Object other) {
return other is Central && other.uuid == uuid;
}
}

View File

@ -1,51 +0,0 @@
import 'dart:typed_data';
import 'advertisement.dart';
import 'event_args.dart';
import 'gatt_characteristic.dart';
import 'peripheral.dart';
/// The discovered event arguments.
class DiscoveredEventArgs extends EventArgs {
/// The disvered peripheral.
final Peripheral peripheral;
/// The rssi of the peripheral.
final int rssi;
/// The advertisement of the peripheral.
final Advertisement advertisement;
/// Constructs a [DiscoveredEventArgs].
DiscoveredEventArgs(this.peripheral, this.rssi, this.advertisement);
}
/// The connection state cahnged event arguments.
class ConnectionStateChangedEventArgs extends EventArgs {
/// The peripheral which connection state changed.
final Peripheral peripheral;
/// The connection state.
final bool connectionState;
/// Constructs a [ConnectionStateChangedEventArgs].
ConnectionStateChangedEventArgs(
this.peripheral,
this.connectionState,
);
}
/// The GATT characteristic notified event arguments.
class GattCharacteristicNotifiedEventArgs extends EventArgs {
/// The GATT characteristic which notified.
final GattCharacteristic characteristic;
/// The notified value.
final Uint8List value;
/// Constructs a [GattCharacteristicNotifiedEventArgs].
GattCharacteristicNotifiedEventArgs(
this.characteristic,
this.value,
);
}

View File

@ -1,28 +1,215 @@
import 'dart:typed_data';
import 'package:log_service/log_service.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'advertisement.dart';
import 'bluetooth_low_energy_manager.dart';
import 'central_event_args.dart';
import 'gatt_characteristic.dart';
import 'gatt_characteristic_write_type.dart';
import 'gatt_descriptor.dart';
import 'gatt_service.dart';
import 'connection_state.dart';
import 'event_args.dart';
import 'gatt.dart';
import 'peripheral.dart';
import 'uuid.dart';
/// The discovered event arguments.
final class DiscoveredEventArgs extends EventArgs {
/// The disvered peripheral.
final Peripheral peripheral;
/// The rssi of the peripheral.
final int rssi;
/// The advertisement of the peripheral.
final Advertisement advertisement;
/// Constructs a [DiscoveredEventArgs].
DiscoveredEventArgs(
this.peripheral,
this.rssi,
this.advertisement,
);
}
/// The peripheral connection state cahnged event arguments.
final class PeripheralConnectionStateChangedEventArgs extends EventArgs {
/// The peripheral which connection state changed.
final Peripheral peripheral;
/// The connection state.
final ConnectionState state;
/// Constructs a [PeripheralConnectionStateChangedEventArgs].
PeripheralConnectionStateChangedEventArgs(
this.peripheral,
this.state,
);
}
/// The peripheral MTU changed event arguments.
final class PeripheralMTUChangedEventArgs extends EventArgs {
/// The peripheral which MTU changed.
final Peripheral peripheral;
/// The MTU.
final int mtu;
/// Constructs a [PeripheralMTUChangedEventArgs].
PeripheralMTUChangedEventArgs(
this.peripheral,
this.mtu,
);
}
/// The GATT characteristic notified event arguments.
final class GATTCharacteristicNotifiedEventArgs extends EventArgs {
/// The peripheral which notified.
final Peripheral peripheral;
/// The GATT characteristic which notified.
final GATTCharacteristic characteristic;
/// The notified value.
final Uint8List value;
/// Constructs a [GATTCharacteristicNotifiedEventArgs].
GATTCharacteristicNotifiedEventArgs(
this.peripheral,
this.characteristic,
this.value,
);
}
/// An object that scans for, discovers, connects to, and manages peripherals.
///
/// Platform-specific implementations should implement this class to support [CentralManager].
abstract class CentralManager extends PlatformInterface
with LoggerProvider, LoggerController
implements BluetoothLowEnergyManager {
static final Object _token = Object();
abstract interface class CentralManager implements BluetoothLowEnergyManager {
static CentralManager? _instance;
/// The default instance of [CentralManager] to use.
static CentralManager get instance {
/// Gets the instance of [CentralManager] to use.
factory CentralManager() {
final instance = PlatformCentralManager.instance;
if (instance != _instance) {
instance.initialize();
_instance = instance;
}
return instance;
}
/// Tells the central manager discovered a peripheral while scanning for devices.
Stream<DiscoveredEventArgs> get discovered;
/// Tells that retrieving the specified peripheral's connection state changed.
Stream<PeripheralConnectionStateChangedEventArgs> get connectionStateChanged;
/// Callback indicating the MTU for a given device connection has changed.
///
/// This callback is triggered in response to the BluetoothGatt#requestMtu
/// function, or in response to a connection event.
///
/// This event is available on Android and Windows, throws [UnsupportedError]
/// on other platforms.
Stream<PeripheralMTUChangedEventArgs> get mtuChanged;
/// Tells that retrieving the specified characteristics value changed.
Stream<GATTCharacteristicNotifiedEventArgs> get characteristicNotified;
/// Scans for peripherals that are advertising services.
///
/// The [serviceUUIDs] argument is an array of [UUID] objects that the app is
/// interested in. Each [UUID] object represents the [UUID] of a service that
/// a peripheral advertises.
Future<void> startDiscovery({
List<UUID>? serviceUUIDs,
});
/// Asks the central manager to stop scanning for peripherals.
Future<void> stopDiscovery();
/// Returns a list of the peripherals connected to the system.
///
/// This method is available on Android, iOS, macOS and Linux, throws
/// [UnsupportedError] on other platforms.
Future<List<Peripheral>> retrieveConnectedPeripherals();
/// Establishes a local connection to a peripheral.
Future<void> connect(Peripheral peripheral);
/// Cancels an active or pending local connection to a peripheral.
Future<void> disconnect(Peripheral peripheral);
/// Request an MTU size used for a given connection. Please note that starting
/// from Android 14, the Android Bluetooth stack requests the BLE ATT MTU to
/// 517 bytes when the first GATT client requests an MTU, and disregards all
/// subsequent MTU requests. Check out [MTU is set to 517 for the first GATT
/// client requesting an MTU](https://developer.android.com/about/versions/14/behavior-changes-all#mtu-set-to-517)
/// for more information.
///
/// This method is available on Android, throws [UnsupportedError] on other
/// platforms.
Future<int> requestMTU(
Peripheral peripheral, {
required int mtu,
});
/// The maximum amount of data, in bytes, you can send to a characteristic in
/// a single write type.
Future<int> getMaximumWriteLength(
Peripheral peripheral, {
required GATTCharacteristicWriteType type,
});
/// Retrieves the current RSSI value for the peripheral while connected to the
/// central manager.
///
/// This method is available on Android, iOS, macOS and Linux, throws
/// [UnsupportedError] on other platforms.
Future<int> readRSSI(Peripheral peripheral);
/// Discovers the GATT services, characteristics and descriptors of the peripheral.
Future<List<GATTService>> discoverGATT(Peripheral peripheral);
/// Retrieves the value of a specified characteristic.
Future<Uint8List> readCharacteristic(
Peripheral peripheral,
GATTCharacteristic characteristic,
);
/// Writes the value of a characteristic.
Future<void> writeCharacteristic(
Peripheral peripheral,
GATTCharacteristic characteristic, {
required Uint8List value,
required GATTCharacteristicWriteType type,
});
/// Sets notifications or indications for the value of a specified characteristic.
Future<void> setCharacteristicNotifyState(
Peripheral peripheral,
GATTCharacteristic characteristic, {
required bool state,
});
/// Retrieves the value of a specified characteristic descriptor.
Future<Uint8List> readDescriptor(
Peripheral peripheral,
GATTDescriptor descriptor,
);
/// Writes the value of a characteristic descriptor.
Future<void> writeDescriptor(
Peripheral peripheral,
GATTDescriptor descriptor, {
required Uint8List value,
});
}
/// Platform-specific implementations should implement this class to support
/// [PlatformCentralManager].
abstract base class PlatformCentralManager
extends PlatformBluetoothLowEnergyManager implements CentralManager {
static final Object _token = Object();
static PlatformCentralManager? _instance;
/// The default instance of [PlatformCentralManager] to use.
static PlatformCentralManager get instance {
final instance = _instance;
if (instance == null) {
throw UnimplementedError(
@ -32,67 +219,13 @@ abstract class CentralManager extends PlatformInterface
}
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [CentralManager] when
/// platform-specific class that extends [PlatformCentralManager] when
/// they register themselves.
static set instance(CentralManager instance) {
static set instance(PlatformCentralManager instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
/// Constructs a [CentralManager].
CentralManager() : super(token: _token);
/// Tells the central manager discovered a peripheral while scanning for devices.
Stream<DiscoveredEventArgs> get discovered;
/// Tells that retrieving the specified peripheral's connection lost.
Stream<ConnectionStateChangedEventArgs> get connectionStateChanged;
/// Tells that retrieving the specified characteristics value changed.
Stream<GattCharacteristicNotifiedEventArgs> get characteristicNotified;
/// Scans for peripherals that are advertising services.
Future<void> startDiscovery();
/// Asks the central manager to stop scanning for peripherals.
Future<void> stopDiscovery();
/// Establishes a local connection to a peripheral.
Future<void> connect(Peripheral peripheral);
/// Cancels an active or pending local connection to a peripheral.
Future<void> disconnect(Peripheral peripheral);
/// Retrieves the current RSSI value for the peripheral while connected to the central manager.
Future<int> readRSSI(Peripheral peripheral);
/// Discovers the GATT services, characteristics and descriptors of the peripheral.
Future<List<GattService>> discoverGATT(Peripheral peripheral);
/// Retrieves the value of a specified characteristic.
Future<Uint8List> readCharacteristic(GattCharacteristic characteristic);
/// Writes the value of a characteristic.
///
/// The maximum size of the value is 512, all bytes that exceed this size will be discarded.
Future<void> writeCharacteristic(
GattCharacteristic characteristic, {
required Uint8List value,
required GattCharacteristicWriteType type,
});
/// Sets notifications or indications for the value of a specified characteristic.
Future<void> setCharacteristicNotifyState(
GattCharacteristic characteristic, {
required bool state,
});
/// Retrieves the value of a specified characteristic descriptor.
Future<Uint8List> readDescriptor(GattDescriptor descriptor);
/// Writes the value of a characteristic descriptor.
Future<void> writeDescriptor(
GattDescriptor descriptor, {
required Uint8List value,
});
/// Constructs a [PlatformCentralManager].
PlatformCentralManager() : super(token: _token);
}

View File

@ -0,0 +1,8 @@
/// The connection state of a remote device.
enum ConnectionState {
/// The remote device is in disconnected state.
disconnected,
/// The remote device is in connected state.
connected,
}

View File

@ -1,2 +1,2 @@
/// The base event arguments.
abstract class EventArgs {}
base class EventArgs {}

View File

@ -0,0 +1,360 @@
import 'dart:typed_data';
import 'package:bluetooth_low_energy_platform_interface/bluetooth_low_energy_platform_interface.dart';
import 'uuid.dart';
/// A representation of common aspects of services offered by a peripheral.
abstract base class GATTAttribute {
/// The Bluetooth-specific UUID of the attribute.
final UUID uuid;
/// Constructs a [GATTAttribute].
GATTAttribute({
required this.uuid,
});
}
/// An object that provides further information about a remote peripherals
/// characteristic.
abstract base class GATTDescriptor extends GATTAttribute {
/// Constructs a [GATTDescriptor].
GATTDescriptor({
required super.uuid,
});
/// Creates a mutable descriptor.
///
/// [uuid] A 128-bit UUID that identifies the characteristic. You must use only
/// one of the two currently supported descriptor types:
/// CBUUIDCharacteristicUserDescriptionString or CBUUIDCharacteristicFormatString.
/// For more details about these descriptor types, see CBUUID.
factory GATTDescriptor.mutable({
required UUID uuid,
required List<GATTCharacteristicPermission> permissions,
}) =>
MutableGATTDescriptor(
uuid: uuid,
permissions: permissions,
);
/// Creates a immutable descriptor with a specified value.
///
/// [uuid] A 128-bit UUID that identifies the characteristic. You must use only
/// one of the two currently supported descriptor types:
/// CBUUIDCharacteristicUserDescriptionString or CBUUIDCharacteristicFormatString.
/// For more details about these descriptor types, see CBUUID.
///
/// [value] The descriptor value to cache. You must provide a non-nil value.
/// Once published, you cant update the value dynamically.
factory GATTDescriptor.immutable({
required UUID uuid,
required Uint8List value,
}) =>
ImmutableGATTDescriptor(
uuid: uuid,
value: value,
);
}
/// A characteristic of a remote peripherals service.
abstract base class GATTCharacteristic extends GATTAttribute {
/// The properties of the characteristic.
final List<GATTCharacteristicProperty> properties;
/// A list of the descriptors discovered in this characteristic.
final List<GATTDescriptor> descriptors;
/// Constructs a [GATTCharacteristic].
GATTCharacteristic({
required super.uuid,
required this.properties,
required this.descriptors,
});
/// Creates a mutable characteristic with specified permissions, properties.
///
/// [uuid] A 128-bit UUID that identifies the characteristic.
///
/// [properties] The properties of the characteristic.
///
/// [permissions] The permissions of the characteristic value.
factory GATTCharacteristic.mutable({
required UUID uuid,
required List<GATTCharacteristicProperty> properties,
required List<GATTCharacteristicPermission> permissions,
required List<GATTDescriptor> descriptors,
}) =>
MutableGATTCharacteristic(
uuid: uuid,
properties: properties,
permissions: permissions,
descriptors: descriptors,
);
/// Creates a immutable characteristic with a specified value.
///
/// [uuid] A 128-bit UUID that identifies the characteristic.
///
/// [value] The characteristic value to cache. You must provide a non-nil value.
/// Once published, you cant update the value dynamically.
factory GATTCharacteristic.immutable({
required UUID uuid,
required Uint8List value,
required List<GATTDescriptor> descriptors,
}) =>
ImmutableGATTCharacteristic(
uuid: uuid,
value: value,
descriptors: descriptors,
);
}
/// A collection of data and associated behaviors that accomplish a function or
/// feature of a device.
base class GATTService extends GATTAttribute {
/// A Boolean value that indicates whether the type of service is primary or
/// secondary.
final bool isPrimary;
/// A list of included services discovered in this service.
final List<GATTService> includedServices;
/// A list of characteristics discovered in this service.
final List<GATTCharacteristic> characteristics;
/// Creates a newly initialized mutable service specified by UUID and service
/// type.
GATTService({
required super.uuid,
required this.isPrimary,
required this.includedServices,
required this.characteristics,
});
}
/// An object that provides additional information about a local peripherals
/// characteristic.
final class MutableGATTDescriptor extends GATTDescriptor {
/// The permissions of the descriptor value.
final List<GATTCharacteristicPermission> permissions;
/// Creates a mutable descriptor with a specified value.
///
/// [uuid] A 128-bit UUID that identifies the characteristic. You must use only
/// one of the two currently supported descriptor types:
/// CBUUIDCharacteristicUserDescriptionString or CBUUIDCharacteristicFormatString.
/// For more details about these descriptor types, see CBUUID.
///
/// [permissions] The permissions of the descriptor value.
MutableGATTDescriptor({
required super.uuid,
required this.permissions,
});
}
/// An object that provides additional information about a local peripherals
/// characteristic.
final class ImmutableGATTDescriptor extends MutableGATTDescriptor {
/// The value of the descriptor.
final Uint8List value;
/// Creates an immutable descriptor with a specified value.
///
/// [uuid] A 128-bit UUID that identifies the characteristic. You must use only
/// one of the two currently supported descriptor types:
/// CBUUIDCharacteristicUserDescriptionString or CBUUIDCharacteristicFormatString.
/// For more details about these descriptor types, see CBUUID.
///
/// [value] The descriptor value to cache. You must provide a non-nil value.
/// Once published, you cant update the value dynamically.
ImmutableGATTDescriptor({
required super.uuid,
required this.value,
}) : super(
permissions: [
GATTCharacteristicPermission.read,
],
);
}
/// A mutable characteristic of a local peripherals service.
final class MutableGATTCharacteristic extends GATTCharacteristic {
/// The permissions of the characteristic value.
final List<GATTCharacteristicPermission> permissions;
/// Creates a mutable characteristic with specified permissions, properties.
///
/// [uuid] A 128-bit UUID that identifies the characteristic.
///
/// [properties] The properties of the characteristic.
///
/// [permissions] The permissions of the characteristic value.
MutableGATTCharacteristic({
required super.uuid,
required super.properties,
required this.permissions,
required super.descriptors,
});
}
/// An immutable characteristic of a local peripherals service.
final class ImmutableGATTCharacteristic extends MutableGATTCharacteristic {
/// The value of the characteristic.
final Uint8List value;
/// Creates an immutable characteristic with a specified value.
///
/// [uuid] A 128-bit UUID that identifies the characteristic.
///
/// [value] The characteristic value to cache. You must provide a non-nil value.
/// Once published, you cant update the value dynamically.
ImmutableGATTCharacteristic({
required super.uuid,
required this.value,
required super.descriptors,
}) : super(
properties: [
GATTCharacteristicProperty.read,
],
permissions: [
GATTCharacteristicPermission.read,
],
);
}
/// A read request that uses the Attribute Protocol (ATT).
abstract base class GATTReadRequest {
/// The zero-based index of the first byte for the read request.
final int offset;
/// Constructs a [GATTReadRequest].
GATTReadRequest({
required this.offset,
});
}
/// A write request that uses the Attribute Protocol (ATT).
abstract base class GATTWriteRequest {
/// The zero-based index of the first byte for the write request.
final int offset;
/// The data that the central writes to the peripheral.
final Uint8List value;
/// Constructs a [GATTWriteRequest].
GATTWriteRequest({
required this.offset,
required this.value,
});
}
/// Values that represent the possible properties of a characteristic.
enum GATTCharacteristicProperty {
/// A property that indicates a peripheral can read the characteristics value.
read,
/// A property that indicates a peripheral can write the characteristics value,
/// with a response to indicate that the write succeeded.
write,
/// A property that indicates a peripheral can write the characteristics value,
/// without a response to indicate that the write succeeded.
writeWithoutResponse,
/// A property that indicates the peripheral permits notifications of the
/// characteristics value, without a response from the central to indicate
/// receipt of the notification.
notify,
/// A property that indicates the peripheral permits notifications of the
/// characteristics value, with a response from the central to indicate receipt
/// of the notification.
indicate,
}
/// Values that represent the read, write, and encryption permissions for a
/// characteristics value.
enum GATTCharacteristicPermission {
/// A permission that indicates a peripheral can read the attributes value.
read,
/// A permission that indicates only trusted devices can read the attributes
/// value.
readEncrypted,
/// A permission that indicates a peripheral can write the attributes value.
write,
/// A permission that indicates only trusted devices can write the attributes
/// value.
writeEncrypted,
}
/// Values representing the possible write types to a characteristics value.
enum GATTCharacteristicWriteType {
/// Write a characteristic value, with a response from the peripheral to indicate
/// whether the write was successful.
withResponse,
/// Write a characteristic value, without any response from the peripheral to
/// indicate whether the write was successful.
withoutResponse,
}
/// The possible errors returned by a GATT server (a remote peripheral) during
/// Bluetooth low energy ATT transactions.
enum GATTError {
/// The attribute handle is invalid on this peripheral.
invalidHandle,
/// The permissions prohibit reading the attributes value.
readNotPermitted,
/// The permissions prohibit writing the attributes value.
writeNotPermitted,
/// The attribute Protocol Data Unit (PDU) is invalid.
invalidPDU,
/// Reading or writing the attributes value failed for lack of authentication.
insufficientAuthentication,
/// The attribute server doesnt support the request received from the client.
requestNotSupported,
/// The specified offset value was past the end of the attributes value.
invalidOffset,
/// Reading or writing the attributes value failed for lack of authorization.
insufficientAuthorization,
/// The prepare queue is full, as a result of there being too many write requests
/// in the queue.
prepareQueueFull,
/// The attribute wasnt found within the specified attribute handle range.
attributeNotFound,
/// The ATT read blob request cant read or write the attribute.
attributeNotLong,
/// The encryption key size used for encrypting this link is insufficient.
insufficientEncryptionKeySize,
/// The length of the attributes value is invalid for the intended operation.
invalidAttributeValueLength,
/// The ATT request encountered an unlikely error and wasnt completed.
unlikelyError,
/// Reading or writing the attributes value failed for lack of encryption.
insufficientEncryption,
/// The attribute type isnt a supported grouping attribute as defined by a
/// higher-layer specification.
unsupportedGroupType,
/// Resources are insufficient to complete the ATT request.
insufficientResources,
}

View File

@ -1,7 +0,0 @@
import 'uuid.dart';
/// A representation of common aspects of services offered by a peripheral.
abstract class GattAttribute {
/// The Bluetooth-specific UUID of the attribute.
UUID get uuid;
}

View File

@ -1,31 +0,0 @@
import 'dart:typed_data';
import 'gatt_attribute.dart';
import 'gatt_characteristic_property.dart';
import 'gatt_descriptor.dart';
import 'my_gatt_characteristic.dart';
import 'my_gatt_descriptor.dart';
import 'uuid.dart';
/// A characteristic of a remote peripherals service.
abstract class GattCharacteristic extends GattAttribute {
/// The properties of the characteristic.
List<GattCharacteristicProperty> get properties;
/// A list of the descriptors discovered in this characteristic.
List<GattDescriptor> get descriptors;
/// Constructs a [GattCharacteristic].
factory GattCharacteristic({
required UUID uuid,
required List<GattCharacteristicProperty> properties,
Uint8List? value,
required List<GattDescriptor> descriptors,
}) =>
MyGattCharacteristic(
uuid: uuid,
properties: properties,
value: value,
descriptors: descriptors.cast<MyGattDescriptor>(),
);
}

View File

@ -1,17 +0,0 @@
/// The properity for a GATT characteristic.
enum GattCharacteristicProperty {
/// The GATT characteristic is able to read.
read,
/// The GATT characteristic is able to write.
write,
/// The GATT characteristic is able to write without response.
writeWithoutResponse,
/// The GATT characteristic is able to notify.
notify,
/// The GATT characteristic is able to indicate.
indicate,
}

View File

@ -1,9 +0,0 @@
/// The write type for a GATT characteristic.
enum GattCharacteristicWriteType {
// Write with response
withResponse,
// Write without response
withoutResponse,
// Write with response and waiting for confirmation
// reliable,
}

View File

@ -1,18 +0,0 @@
import 'dart:typed_data';
import 'gatt_attribute.dart';
import 'my_gatt_descriptor.dart';
import 'uuid.dart';
/// An object that provides further information about a remote peripherals characteristic.
abstract class GattDescriptor extends GattAttribute {
/// Constructs a [GattDescriptor].
factory GattDescriptor({
required UUID uuid,
Uint8List? value,
}) =>
MyGattDescriptor(
uuid: uuid,
value: value,
);
}

View File

@ -1,21 +0,0 @@
import 'gatt_attribute.dart';
import 'gatt_characteristic.dart';
import 'my_gatt_characteristic.dart';
import 'my_gatt_service.dart';
import 'uuid.dart';
/// A collection of data and associated behaviors that accomplish a function or feature of a device.
abstract class GattService extends GattAttribute {
/// A list of characteristics discovered in this service.
List<GattCharacteristic> get characteristics;
/// Constructs a [GattService].
factory GattService({
required UUID uuid,
required List<GattCharacteristic> characteristics,
}) =>
MyGattService(
uuid: uuid,
characteristics: characteristics.cast<MyGattCharacteristic>(),
);
}

View File

@ -1,7 +1,7 @@
import 'dart:typed_data';
/// The manufacturer specific data of the peripheral
class ManufacturerSpecificData {
final class ManufacturerSpecificData {
/// The manufacturer id.
final int id;

View File

@ -1,11 +0,0 @@
import 'bluetooth_low_energy_peer.dart';
import 'uuid.dart';
abstract class MyBluetoothLowEnergyPeer implements BluetoothLowEnergyPeer {
@override
final UUID uuid;
MyBluetoothLowEnergyPeer({
required this.uuid,
});
}

View File

@ -1,16 +0,0 @@
import 'central.dart';
import 'my_bluetooth_low_energy_peer.dart';
class MyCentral extends MyBluetoothLowEnergyPeer implements Central {
MyCentral({
required super.uuid,
});
@override
int get hashCode => uuid.hashCode;
@override
bool operator ==(Object other) {
return other is Central && other.uuid == uuid;
}
}

View File

@ -1,19 +0,0 @@
import 'dart:typed_data';
import 'gatt_attribute.dart';
import 'uuid.dart';
abstract class MyGattAttribute implements GattAttribute {
@override
final UUID uuid;
MyGattAttribute({
required this.uuid,
});
}
extension MyGattAttributeUint8List on Uint8List {
Uint8List trimGATT() {
return length > 512 ? sublist(0, 512) : this;
}
}

View File

@ -1,27 +0,0 @@
import 'dart:typed_data';
import 'gatt_characteristic.dart';
import 'gatt_characteristic_property.dart';
import 'my_gatt_attribute.dart';
import 'my_gatt_descriptor.dart';
class MyGattCharacteristic extends MyGattAttribute
implements GattCharacteristic {
Uint8List _value;
@override
final List<GattCharacteristicProperty> properties;
@override
final List<MyGattDescriptor> descriptors;
MyGattCharacteristic({
required super.uuid,
required this.properties,
Uint8List? value,
required this.descriptors,
}) : _value = value?.trimGATT() ?? Uint8List(0);
Uint8List get value => _value;
set value(Uint8List value) {
_value = value.trimGATT();
}
}

View File

@ -1,18 +0,0 @@
import 'dart:typed_data';
import 'gatt_descriptor.dart';
import 'my_gatt_attribute.dart';
class MyGattDescriptor extends MyGattAttribute implements GattDescriptor {
Uint8List _value;
MyGattDescriptor({
required super.uuid,
Uint8List? value,
}) : _value = value?.trimGATT() ?? Uint8List(0);
Uint8List get value => _value;
set value(Uint8List value) {
_value = value.trimGATT();
}
}

View File

@ -1,13 +0,0 @@
import 'gatt_service.dart';
import 'my_gatt_attribute.dart';
import 'my_gatt_characteristic.dart';
class MyGattService extends MyGattAttribute implements GattService {
@override
final List<MyGattCharacteristic> characteristics;
MyGattService({
required super.uuid,
required this.characteristics,
});
}

View File

@ -1,16 +0,0 @@
import 'my_bluetooth_low_energy_peer.dart';
import 'peripheral.dart';
class MyPeripheral extends MyBluetoothLowEnergyPeer implements Peripheral {
MyPeripheral({
required super.uuid,
});
@override
int get hashCode => uuid.hashCode;
@override
bool operator ==(Object other) {
return other is Peripheral && other.uuid == uuid;
}
}

View File

@ -1,4 +1,16 @@
import 'bluetooth_low_energy_peer.dart';
/// A remote peripheral device.
abstract class Peripheral extends BluetoothLowEnergyPeer {}
base class Peripheral extends BluetoothLowEnergyPeer {
Peripheral({
required super.uuid,
});
@override
int get hashCode => uuid.hashCode;
@override
bool operator ==(Object other) {
return other is Peripheral && other.uuid == uuid;
}
}

View File

@ -1,61 +0,0 @@
import 'dart:typed_data';
import 'central.dart';
import 'gatt_characteristic.dart';
/// The GATT characteristic written event arguments.
class GattCharacteristicReadEventArgs {
/// The central which read this characteristic.
final Central central;
/// The GATT characteristic which value is read.
final GattCharacteristic characteristic;
/// The value.
final Uint8List value;
/// Constructs a [GattCharacteristicReadEventArgs].
GattCharacteristicReadEventArgs(
this.central,
this.characteristic,
this.value,
);
}
/// The GATT characteristic written event arguments.
class GattCharacteristicWrittenEventArgs {
/// The central which wrote this characteristic.
final Central central;
/// The GATT characteristic which value is written.
final GattCharacteristic characteristic;
/// The value.
final Uint8List value;
/// Constructs a [GattCharacteristicWrittenEventArgs].
GattCharacteristicWrittenEventArgs(
this.central,
this.characteristic,
this.value,
);
}
/// The GATT characteristic notify state changed event arguments.
class GattCharacteristicNotifyStateChangedEventArgs {
/// The central which set this notify state.
final Central central;
/// The GATT characteristic which notify state changed.
final GattCharacteristic characteristic;
/// The notify state.
final bool state;
/// Constructs a [GattCharacteristicNotifyStateChangedEventArgs].
GattCharacteristicNotifyStateChangedEventArgs(
this.central,
this.characteristic,
this.state,
);
}

View File

@ -1,27 +1,266 @@
import 'dart:typed_data';
import 'package:log_service/log_service.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'advertisement.dart';
import 'bluetooth_low_energy_manager.dart';
import 'central.dart';
import 'gatt_characteristic.dart';
import 'gatt_service.dart';
import 'peripheral_event_args.dart';
import 'connection_state.dart';
import 'event_args.dart';
import 'gatt.dart';
/// The central connection state cahnged event arguments.
final class CentralConnectionStateChangedEventArgs extends EventArgs {
/// The central which connection state changed.
final Central central;
/// The connection state.
final ConnectionState state;
/// Constructs a [CentralConnectionStateChangedEventArgs].
CentralConnectionStateChangedEventArgs(
this.central,
this.state,
);
}
/// The central MTU changed event arguments.
final class CentralMTUChangedEventArgs extends EventArgs {
/// The central which MTU changed.
final Central central;
/// The MTU.
final int mtu;
/// Constructs a [CentralMTUChangedEventArgs].
CentralMTUChangedEventArgs(
this.central,
this.mtu,
);
}
/// The GATT characteristic read requested event arguments.
final class GATTCharacteristicReadRequestedEventArgs extends EventArgs {
/// The central which read this characteristic.
final Central central;
/// The characteristic to read the value of.
final GATTCharacteristic characteristic;
/// The read request.
final GATTReadRequest request;
/// Constructs a [GATTCharacteristicReadRequestedEventArgs].
GATTCharacteristicReadRequestedEventArgs(
this.central,
this.characteristic,
this.request,
);
}
/// The GATT characteristic write requested event arguments.
final class GATTCharacteristicWriteRequestedEventArgs extends EventArgs {
/// The central which wrote this characteristic.
final Central central;
/// The characteristic to write the value of.
final GATTCharacteristic characteristic;
/// The write request.
final GATTWriteRequest request;
/// Constructs a [GATTCharacteristicWriteRequestedEventArgs].
GATTCharacteristicWriteRequestedEventArgs(
this.central,
this.characteristic,
this.request,
);
}
/// The GATT characteristic notify state changed event arguments.
final class GATTCharacteristicNotifyStateChangedEventArgs extends EventArgs {
/// The central which set this notify state.
final Central central;
/// The GATT characteristic which notify state changed.
final GATTCharacteristic characteristic;
/// The notify state.
final bool state;
/// Constructs a [GATTCharacteristicNotifyStateChangedEventArgs].
GATTCharacteristicNotifyStateChangedEventArgs(
this.central,
this.characteristic,
this.state,
);
}
/// The GATT descriptor read requested event arguments.
final class GATTDescriptorReadRequestedEventArgs extends EventArgs {
/// The central which read this descriptor.
final Central central;
/// The descriptor to read the value of.
final GATTDescriptor descriptor;
/// The read request.
final GATTReadRequest request;
/// Constructs a [GATTDescriptorReadRequestedEventArgs].
GATTDescriptorReadRequestedEventArgs(
this.central,
this.descriptor,
this.request,
);
}
/// The GATT descriptor write requested event arguments.
final class GATTDescriptorWriteRequestedEventArgs extends EventArgs {
/// The central which wrote this descriptor.
final Central central;
/// The descriptor to write the value of.
final GATTDescriptor descriptor;
/// The write request.
final GATTWriteRequest request;
/// Constructs a [GATTDescriptorWriteRequestedEventArgs].
GATTDescriptorWriteRequestedEventArgs(
this.central,
this.descriptor,
this.request,
);
}
/// An object that manages and advertises peripheral services exposed by this app.
///
/// Platform-specific implementations should implement this class to support [PeripheralManager].
abstract class PeripheralManager extends PlatformInterface
with LoggerProvider, LoggerController
abstract interface class PeripheralManager
implements BluetoothLowEnergyManager {
static final Object _token = Object();
static PeripheralManager? _instance;
/// The default instance of [PeripheralManager] to use.
static PeripheralManager get instance {
/// Gets the instance of [PeripheralManager] to use.
factory PeripheralManager() {
final instance = PlatformPeripheralManager.instance;
if (instance != _instance) {
instance.initialize();
_instance = instance;
}
return instance;
}
/// Callback indicating when a remote device has been connected or disconnected.
///
/// This event is available on Android, throws [UnsupportedError] on other
/// platforms.
Stream<CentralConnectionStateChangedEventArgs> get connectionStateChanged;
/// Callback indicating the MTU for a given device connection has changed.
///
/// This callback will be invoked if a remote client has requested to change
/// the MTU for a given connection.
///
/// This event is available on Android and Windows, throws [UnsupportedError]
/// on other platforms.
Stream<CentralMTUChangedEventArgs> get mtuChanged;
/// Tells that the local peripheral device received an Attribute Protocol (ATT)
/// read request for a characteristic with a dynamic value.
Stream<GATTCharacteristicReadRequestedEventArgs>
get characteristicReadRequested;
/// Tells that the local peripheral device received an Attribute Protocol (ATT)
/// write request for a characteristic with a dynamic value.
Stream<GATTCharacteristicWriteRequestedEventArgs>
get characteristicWriteRequested;
/// Tells that the peripheral manager received a characteristics notify changed.
Stream<GATTCharacteristicNotifyStateChangedEventArgs>
get characteristicNotifyStateChanged;
/// Tells that the local peripheral device received an Attribute Protocol (ATT)
/// read request for a descriptor with a dynamic value.
///
/// This event is available on Android and Windows, throws [UnsupportedError]
/// on other platforms.
Stream<GATTDescriptorReadRequestedEventArgs> get descriptorReadRequested;
/// Tells that the local peripheral device received an Attribute Protocol (ATT)
/// write request for a descriptor with a dynamic value.
///
/// This event is available on Android and Windows, throws [UnsupportedError]
/// on other platforms.
Stream<GATTDescriptorWriteRequestedEventArgs> get descriptorWriteRequested;
/// Publishes a service and any of its associated characteristics and characteristic
/// descriptors to the local GATT database.
Future<void> addService(GATTService service);
/// Removes a specified published service from the local GATT database.
Future<void> removeService(GATTService service);
/// Removes all published services from the local GATT database.
Future<void> removeAllServices();
/// Advertises peripheral manager data.
Future<void> startAdvertising(Advertisement advertisement);
/// Stops advertising peripheral manager data.
Future<void> stopAdvertising();
/// The maximum amount of data, in bytes, that the central can receive in a
/// single notification or indication.
Future<int> getMaximumNotifyLength(Central central);
/// Responds to a read request from a connected central.
Future<void> respondReadRequestWithValue(
GATTReadRequest request, {
required Uint8List value,
});
/// Responds to a read request from a connected central.
Future<void> respondReadRequestWithError(
GATTReadRequest request, {
required GATTError error,
});
/// Responds to a write request from a connected central.
Future<void> respondWriteRequest(GATTWriteRequest request);
/// Responds to a write request from a connected central.
Future<void> respondWriteRequestWithError(
GATTWriteRequest request, {
required GATTError error,
});
/// Send an updated characteristic value to one or more subscribed centrals,
/// using a notification or indication.
///
/// [central] A central (represented by CBCentral objects) that have subscribed
/// to receive updates of the characteristics value. The manager ignores any
/// centrals that havent subscribed to the characteristics value.
///
/// [characteristic] The characteristic whose value has changed.
///
/// [value] The characteristic value you want to send via a notification or
/// indication.
Future<void> notifyCharacteristic(
Central central,
GATTCharacteristic characteristic, {
required Uint8List value,
});
}
/// Platform-specific implementations should implement this class to support
/// [PlatformPeripheralManager].
abstract base class PlatformPeripheralManager
extends PlatformBluetoothLowEnergyManager implements PeripheralManager {
static final Object _token = Object();
static PlatformPeripheralManager? _instance;
/// The default instance of [PlatformPeripheralManager] to use.
static PlatformPeripheralManager get instance {
final instance = _instance;
if (instance == null) {
throw UnimplementedError(
@ -31,50 +270,13 @@ abstract class PeripheralManager extends PlatformInterface
}
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [PeripheralManager] when
/// platform-specific class that extends [PlatformPeripheralManager] when
/// they register themselves.
static set instance(PeripheralManager instance) {
static set instance(PlatformPeripheralManager instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
/// Constructs a [PeripheralManager].
PeripheralManager() : super(token: _token);
/// Tells that the local peripheral device received an Attribute Protocol (ATT) read request for a characteristic with a dynamic value.
Stream<GattCharacteristicReadEventArgs> get characteristicRead;
/// Tells that the local peripheral device received an Attribute Protocol (ATT) write request for a characteristic with a dynamic value.
Stream<GattCharacteristicWrittenEventArgs> get characteristicWritten;
/// Tells that the peripheral manager received a characteristics notify changed.
Stream<GattCharacteristicNotifyStateChangedEventArgs>
get characteristicNotifyStateChanged;
/// Publishes a service and any of its associated characteristics and characteristic descriptors to the local GATT database.
Future<void> addService(GattService service);
/// Removes a specified published service from the local GATT database.
Future<void> removeService(GattService service);
/// Removes all published services from the local GATT database.
Future<void> clearServices();
/// Advertises peripheral manager data.
Future<void> startAdvertising(Advertisement advertisement);
/// Stops advertising peripheral manager data.
Future<void> stopAdvertising();
/// Retrieves the value of a specified characteristic.
Future<Uint8List> readCharacteristic(GattCharacteristic characteristic);
/// Writes the value of a characteristic and sends an updated characteristic value to one or more subscribed centrals, using a notification or indication.
///
/// The maximum size of the value is 512, all bytes that exceed this size will be discarded.
Future<void> writeCharacteristic(
GattCharacteristic characteristic, {
required Uint8List value,
Central? central,
});
/// Constructs a [PlatformPeripheralManager].
PlatformPeripheralManager() : super(token: _token);
}

View File

@ -1,5 +1,5 @@
/// 128 bit universally unique identifier used in Bluetooth.
class UUID {
final class UUID {
/// The value of the UUID in 16 bytes.
final List<int> value;
@ -46,7 +46,8 @@ class UUID {
0xfb
];
/// Creates a new UUID from the string format encoding (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx where xx is a hexadecimal number).
/// Creates a new UUID from the string format encoding (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
/// where xx is a hexadecimal number).
factory UUID.fromString(String value) {
// 16 or 32 bits UUID.
if (value.length == 4 || value.length == 8) {
@ -96,11 +97,17 @@ class UUID {
}
/// Creates a new UUID form MAC address.
factory UUID.fromAddress(String address) {
final node = address.splitMapJoin(
':',
onMatch: (m) => '',
);
///
/// The address type must be String or int.
factory UUID.fromAddress(Object address) {
final node = address is String
? address.splitMapJoin(
':',
onMatch: (m) => '',
)
: address is int
? (address & 0xFFFFFFFFFFFF).toRadixString(16).padLeft(12, '0')
: throw TypeError();
// We don't know the timestamp of the bluetooth device, use nil UUID as prefix.
return UUID.fromString("00000000-0000-0000-0000-$node");
}