Add platform specific options in start scan (#65)
* Add platform specific options in start scan * Add code level doc and ChangeLog * Minor improvements
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
export 'package:universal_ble/src/models/platform_config.dart';
|
||||
export 'package:universal_ble/src/models/queue_type.dart';
|
||||
export 'package:universal_ble/src/models/ble_uuid_parser.dart';
|
||||
export 'package:universal_ble/src/models/scan_filter.dart';
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/// Platform specific config to scan devices
|
||||
class PlatformConfig {
|
||||
WebConfig? web;
|
||||
|
||||
PlatformConfig({this.web});
|
||||
}
|
||||
|
||||
/// Web config to scan devices
|
||||
/// [optionalServices] is a list of service uuid's to ensure that you can access the specified services after connecting to the device,
|
||||
/// by default services from scanFilter will be used
|
||||
/// [optionalManufacturerData] is list of `CompanyIdentifier's` and used to add `ManufacturerData` in advertisement results of selected device from web dialog,
|
||||
/// by default manufacturerData from scanFilter will be used
|
||||
/// Checkout more details on [web](https://developer.mozilla.org/en-US/docs/Web/API/Bluetooth/requestDevice)
|
||||
/// Note: you will only get advertisements if Experimental Flag is enabled in the browser
|
||||
class WebConfig {
|
||||
List<String> optionalServices;
|
||||
List<int> optionalManufacturerData;
|
||||
|
||||
WebConfig({
|
||||
this.optionalServices = const [],
|
||||
this.optionalManufacturerData = const [],
|
||||
});
|
||||
}
|
||||
@@ -49,9 +49,13 @@ class UniversalBle {
|
||||
/// `webRequestOptions` is supported on Web only
|
||||
static Future<void> startScan({
|
||||
ScanFilter? scanFilter,
|
||||
PlatformConfig? platformConfig,
|
||||
}) async {
|
||||
return await _bleCommandQueue.queueCommand(
|
||||
() => _platform.startScan(scanFilter: scanFilter),
|
||||
() => _platform.startScan(
|
||||
scanFilter: scanFilter,
|
||||
platformConfig: platformConfig,
|
||||
),
|
||||
withTimeout: false,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ class UniversalBleLinux extends UniversalBlePlatform {
|
||||
@override
|
||||
Future<void> startScan({
|
||||
ScanFilter? scanFilter,
|
||||
PlatformConfig? platformConfig,
|
||||
}) async {
|
||||
await _ensureInitialized();
|
||||
await super.startScan(scanFilter: scanFilter);
|
||||
|
||||
@@ -30,6 +30,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
||||
@override
|
||||
Future<void> startScan({
|
||||
ScanFilter? scanFilter,
|
||||
PlatformConfig? platformConfig,
|
||||
}) async {
|
||||
await super.startScan(scanFilter: scanFilter);
|
||||
await _channel.startScan(
|
||||
|
||||
@@ -11,6 +11,7 @@ abstract class UniversalBlePlatform {
|
||||
|
||||
Future<void> startScan({
|
||||
ScanFilter? scanFilter,
|
||||
PlatformConfig? platformConfig,
|
||||
}) async {
|
||||
_scanFilter = scanFilter;
|
||||
}
|
||||
|
||||
@@ -116,17 +116,10 @@ class UniversalBleWeb extends UniversalBlePlatform {
|
||||
@override
|
||||
Future<void> startScan({
|
||||
ScanFilter? scanFilter,
|
||||
PlatformConfig? platformConfig,
|
||||
}) async {
|
||||
if (scanFilter == null || scanFilter.withServices.isEmpty) {
|
||||
UniversalBlePlatform.logInfo(
|
||||
"Service list empty: on web you have to specify services in the ScanFilter in order to be able to access those after connecting",
|
||||
isError: true,
|
||||
);
|
||||
}
|
||||
|
||||
BluetoothDevice device = await FlutterWebBluetooth.instance.requestDevice(
|
||||
scanFilter?.toRequestOptionsBuilder() ??
|
||||
RequestOptionsBuilder.acceptAllDevices(),
|
||||
_getRequestOptionBuilder(scanFilter, platformConfig?.web),
|
||||
);
|
||||
|
||||
// Update local device list
|
||||
@@ -158,7 +151,7 @@ class UniversalBleWeb extends UniversalBlePlatform {
|
||||
device.toBleScanResult(
|
||||
rssi: event.rssi,
|
||||
manufacturerDataMap: event.manufacturerData,
|
||||
services: event.uuids,
|
||||
services: event.uuids.toSet().toList(),
|
||||
),
|
||||
);
|
||||
});
|
||||
@@ -366,6 +359,78 @@ class UniversalBleWeb extends UniversalBlePlatform {
|
||||
Future<bool> enableBluetooth() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
RequestOptionsBuilder _getRequestOptionBuilder(
|
||||
ScanFilter? scanFilter,
|
||||
WebConfig? webConfig,
|
||||
) {
|
||||
List<RequestFilterBuilder> filters = [];
|
||||
List<int> optionalManufacturerData = [];
|
||||
List<String> optionalServices = [];
|
||||
|
||||
if (webConfig != null) {
|
||||
optionalServices.addAll(webConfig.optionalServices.toValidUUIDList());
|
||||
optionalManufacturerData.addAll(webConfig.optionalManufacturerData);
|
||||
}
|
||||
|
||||
if (scanFilter != null) {
|
||||
// Add services filter
|
||||
for (var service in scanFilter.withServices.toValidUUIDList()) {
|
||||
filters.add(RequestFilterBuilder(services: [service]));
|
||||
if (webConfig == null || webConfig.optionalServices.isEmpty) {
|
||||
optionalServices.add(service);
|
||||
}
|
||||
}
|
||||
|
||||
// Add manufacturer data filter
|
||||
for (var manufacturerData in scanFilter.withManufacturerData) {
|
||||
filters.add(
|
||||
RequestFilterBuilder(
|
||||
manufacturerData: [
|
||||
ManufacturerDataFilterBuilder(
|
||||
companyIdentifier: manufacturerData.companyIdentifier,
|
||||
dataPrefix: manufacturerData.data,
|
||||
mask: manufacturerData.mask,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
// Add optionalManufacturerData from scanFilter if webConfig is not provided
|
||||
if (webConfig == null || webConfig.optionalManufacturerData.isEmpty) {
|
||||
int? companyId = manufacturerData.companyIdentifier;
|
||||
if (companyId != null) {
|
||||
optionalManufacturerData.add(companyId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add name filter
|
||||
for (var name in scanFilter.withNamePrefix) {
|
||||
filters.add(RequestFilterBuilder(namePrefix: name));
|
||||
}
|
||||
}
|
||||
|
||||
if (optionalServices.isEmpty) {
|
||||
UniversalBlePlatform.logInfo(
|
||||
"OptionalServices list is empty on web, you have to specify services in the ScanFilter in order to be able to access those after connecting",
|
||||
isError: true,
|
||||
);
|
||||
}
|
||||
|
||||
if (filters.isEmpty) {
|
||||
return RequestOptionsBuilder.acceptAllDevices(
|
||||
optionalServices: optionalServices,
|
||||
optionalManufacturerData: optionalManufacturerData,
|
||||
);
|
||||
} else {
|
||||
return RequestOptionsBuilder(
|
||||
filters,
|
||||
optionalServices: optionalServices,
|
||||
optionalManufacturerData: optionalManufacturerData,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension _BluetoothDeviceExtension on BluetoothDevice {
|
||||
@@ -398,55 +463,3 @@ extension _UnmodifiableMapViewExtension on UnmodifiableMapView<int, ByteData> {
|
||||
return Uint8List.fromList(bytes + manufacturerDataValue);
|
||||
}
|
||||
}
|
||||
|
||||
extension ScanFilterExtension on ScanFilter {
|
||||
RequestOptionsBuilder toRequestOptionsBuilder() {
|
||||
List<RequestFilterBuilder> filters = [];
|
||||
List<int> manufacturerCompanyIdentifiers = [];
|
||||
|
||||
// Add services filter
|
||||
for (var service in withServices.toValidUUIDList()) {
|
||||
filters.add(
|
||||
RequestFilterBuilder(
|
||||
services: [service],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Add manufacturer data filter
|
||||
for (var manufacturerData in withManufacturerData) {
|
||||
filters.add(
|
||||
RequestFilterBuilder(
|
||||
manufacturerData: [
|
||||
ManufacturerDataFilterBuilder(
|
||||
companyIdentifier: manufacturerData.companyIdentifier,
|
||||
dataPrefix: manufacturerData.data,
|
||||
mask: manufacturerData.mask,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
int? companyId = manufacturerData.companyIdentifier;
|
||||
if (companyId != null) {
|
||||
manufacturerCompanyIdentifiers.add(companyId);
|
||||
}
|
||||
}
|
||||
|
||||
// Add name filter
|
||||
for (var name in withNamePrefix) {
|
||||
filters.add(
|
||||
RequestFilterBuilder(namePrefix: name),
|
||||
);
|
||||
}
|
||||
|
||||
if (filters.isEmpty) {
|
||||
return RequestOptionsBuilder.acceptAllDevices();
|
||||
}
|
||||
|
||||
return RequestOptionsBuilder(
|
||||
filters,
|
||||
optionalServices: withServices.toValidUUIDList(),
|
||||
optionalManufacturerData: manufacturerCompanyIdentifiers,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user