Implement ScanFilter (#17)
* Implement ScanFilter * Add windows implementation * Fix Linux and cleanups * Update Readme, Changelog and Version * Minor fixes from AI comments * Fix windows crash and update pigeon * Fix UUID parsing * Apply suggestions from code review Co-authored-by: Foti Dim <foti@navideck.com> --------- Co-authored-by: Foti Dim <foti@navideck.com>
This commit is contained in:
Vendored
+3
-1
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"bluez",
|
||||
"BTLE",
|
||||
"bytevc",
|
||||
"connnection",
|
||||
@@ -25,7 +26,8 @@
|
||||
"unwatch",
|
||||
"uuidstr",
|
||||
"winrt",
|
||||
"WPARAM"
|
||||
"WPARAM",
|
||||
"ZUUID"
|
||||
],
|
||||
"cmake.configureOnOpen": false,
|
||||
"files.associations": {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
## 0.9.3
|
||||
* Add scan filter (withServices:) in `startScan()`
|
||||
* Add service UUIDs from advertisements in `BleScanResult`
|
||||
* Fix Windows release build compilation
|
||||
|
||||
## 0.9.2
|
||||
* Add command queue
|
||||
* Improve error handling on Android, iOS, macOS, Windows, Linux and web
|
||||
|
||||
@@ -60,6 +60,13 @@ UniversalBle.onScanResult = (scanResult) {
|
||||
// Perform a scan
|
||||
UniversalBle.startScan();
|
||||
|
||||
// Or optionally add a scan filter
|
||||
UniversalBle.startScan(
|
||||
scanFilter: ScanFilter(
|
||||
withServices: ["SERVICE_UUID"],
|
||||
)
|
||||
);
|
||||
|
||||
// Stop scanning
|
||||
UniversalBle.stopScan();
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// Autogenerated from Pigeon (v17.1.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
package com.navideck.universal_ble
|
||||
@@ -53,7 +53,8 @@ data class UniversalBleScanResult (
|
||||
val isPaired: Boolean? = null,
|
||||
val rssi: Long? = null,
|
||||
val manufacturerData: ByteArray? = null,
|
||||
val manufacturerDataHead: ByteArray? = null
|
||||
val manufacturerDataHead: ByteArray? = null,
|
||||
val services: List<String?>? = null
|
||||
|
||||
) {
|
||||
companion object {
|
||||
@@ -65,7 +66,8 @@ data class UniversalBleScanResult (
|
||||
val rssi = list[3].let { if (it is Int) it.toLong() else it as Long? }
|
||||
val manufacturerData = list[4] as ByteArray?
|
||||
val manufacturerDataHead = list[5] as ByteArray?
|
||||
return UniversalBleScanResult(deviceId, name, isPaired, rssi, manufacturerData, manufacturerDataHead)
|
||||
val services = list[6] as List<String?>?
|
||||
return UniversalBleScanResult(deviceId, name, isPaired, rssi, manufacturerData, manufacturerDataHead, services)
|
||||
}
|
||||
}
|
||||
fun toList(): List<Any?> {
|
||||
@@ -76,6 +78,7 @@ data class UniversalBleScanResult (
|
||||
rssi,
|
||||
manufacturerData,
|
||||
manufacturerDataHead,
|
||||
services,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -124,6 +127,25 @@ data class UniversalBleCharacteristic (
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated class from Pigeon that represents data sent in messages. */
|
||||
data class UniversalScanFilter (
|
||||
val withServices: List<String?>
|
||||
|
||||
) {
|
||||
companion object {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun fromList(list: List<Any?>): UniversalScanFilter {
|
||||
val withServices = list[0] as List<String?>
|
||||
return UniversalScanFilter(withServices)
|
||||
}
|
||||
}
|
||||
fun toList(): List<Any?> {
|
||||
return listOf<Any?>(
|
||||
withServices,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private object UniversalBlePlatformChannelCodec : StandardMessageCodec() {
|
||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||
@@ -143,6 +165,11 @@ private object UniversalBlePlatformChannelCodec : StandardMessageCodec() {
|
||||
UniversalBleService.fromList(it)
|
||||
}
|
||||
}
|
||||
131.toByte() -> {
|
||||
return (readValue(buffer) as? List<Any?>)?.let {
|
||||
UniversalScanFilter.fromList(it)
|
||||
}
|
||||
}
|
||||
else -> super.readValueOfType(type, buffer)
|
||||
}
|
||||
}
|
||||
@@ -160,6 +187,10 @@ private object UniversalBlePlatformChannelCodec : StandardMessageCodec() {
|
||||
stream.write(130)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
is UniversalScanFilter -> {
|
||||
stream.write(131)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
else -> super.writeValue(stream, value)
|
||||
}
|
||||
}
|
||||
@@ -173,7 +204,7 @@ private object UniversalBlePlatformChannelCodec : StandardMessageCodec() {
|
||||
interface UniversalBlePlatformChannel {
|
||||
fun getBluetoothAvailabilityState(callback: (Result<Long>) -> Unit)
|
||||
fun enableBluetooth(callback: (Result<Boolean>) -> Unit)
|
||||
fun startScan()
|
||||
fun startScan(filter: UniversalScanFilter?)
|
||||
fun stopScan()
|
||||
fun connect(deviceId: String)
|
||||
fun disconnect(deviceId: String)
|
||||
@@ -234,10 +265,12 @@ interface UniversalBlePlatformChannel {
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { _, reply ->
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val filterArg = args[0] as UniversalScanFilter?
|
||||
var wrapped: List<Any?>
|
||||
try {
|
||||
api.startScan()
|
||||
api.startScan(filterArg)
|
||||
wrapped = listOf<Any?>(null)
|
||||
} catch (exception: Throwable) {
|
||||
wrapped = wrapError(exception)
|
||||
|
||||
@@ -13,7 +13,9 @@ import android.bluetooth.le.ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED
|
||||
import android.bluetooth.le.ScanCallback.SCAN_FAILED_INTERNAL_ERROR
|
||||
import android.bluetooth.le.ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES
|
||||
import android.bluetooth.le.ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY
|
||||
import android.bluetooth.le.ScanFilter
|
||||
import android.bluetooth.le.ScanResult
|
||||
import android.os.ParcelUuid
|
||||
import android.util.Log
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
@@ -61,6 +63,15 @@ enum class CharacteristicProperty(val value: Long) {
|
||||
ExtendedProperties(7)
|
||||
}
|
||||
|
||||
|
||||
fun String.validFullUUID(): String {
|
||||
return when (this.count()) {
|
||||
4 -> "0000$this-0000-1000-8000-00805F9B34FB"
|
||||
8 -> "$this-0000-1000-8000-00805F9B34FB"
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
fun String.toBluetoothGatt(): BluetoothGatt {
|
||||
return knownGatts.find { it.device.address == this }
|
||||
?: throw FlutterError("IllegalArgument", "Unknown deviceId: $this", null)
|
||||
@@ -132,6 +143,32 @@ fun Int.parseGattErrorCode(): String? {
|
||||
}
|
||||
}
|
||||
|
||||
fun UniversalScanFilter.toScanFilters(): List<ScanFilter> {
|
||||
var scanFilters: List<ScanFilter> = emptyList()
|
||||
|
||||
// Add withServices Filter
|
||||
for (service in this.withServices) {
|
||||
try {
|
||||
val serviceUUID = service?.validFullUUID()
|
||||
serviceUUID?.let {
|
||||
val parcelUUId = ParcelUuid.fromString(it)
|
||||
scanFilters = scanFilters.plus(
|
||||
ScanFilter.Builder().setServiceUuid(parcelUUId).build()
|
||||
)
|
||||
Log.e(TAG, "scanFilters: $parcelUUId")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, e.toString())
|
||||
throw FlutterError(
|
||||
"illegalIllegalArgument",
|
||||
"Invalid serviceId: $service",
|
||||
e.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return scanFilters
|
||||
}
|
||||
|
||||
val ScanResult.manufacturerDataHead: ByteArray?
|
||||
get() {
|
||||
|
||||
@@ -6,7 +6,9 @@ import android.bluetooth.*
|
||||
import android.bluetooth.BluetoothDevice.BOND_BONDED
|
||||
import android.bluetooth.BluetoothDevice.BOND_NONE
|
||||
import android.bluetooth.le.ScanCallback
|
||||
import android.bluetooth.le.ScanFilter
|
||||
import android.bluetooth.le.ScanResult
|
||||
import android.bluetooth.le.ScanSettings
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Context.RECEIVER_EXPORTED
|
||||
@@ -15,6 +17,7 @@ import android.content.IntentFilter
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.ParcelUuid
|
||||
import android.util.Log
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
@@ -24,6 +27,7 @@ import java.util.*
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
private const val TAG = "UniversalBlePlugin"
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@@ -95,12 +99,24 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
bluetoothEnableRequestFuture = callback
|
||||
}
|
||||
|
||||
override fun startScan() {
|
||||
override fun startScan(filter: UniversalScanFilter?) {
|
||||
if (!isBluetoothAvailable()) throw FlutterError(
|
||||
"BluetoothNotEnabled",
|
||||
"Bluetooth not enabled",
|
||||
)
|
||||
bluetoothManager.adapter.bluetoothLeScanner?.startScan(scanCallback)
|
||||
|
||||
val builder = ScanSettings.Builder()
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
builder.setPhy(ScanSettings.PHY_LE_ALL_SUPPORTED)
|
||||
builder.setLegacy(false)
|
||||
}
|
||||
val settings = builder.build()
|
||||
|
||||
bluetoothManager.adapter.bluetoothLeScanner?.startScan(
|
||||
filter?.toScanFilters() ?: emptyList<ScanFilter>(),
|
||||
settings,
|
||||
scanCallback
|
||||
)
|
||||
}
|
||||
|
||||
override fun stopScan() {
|
||||
@@ -656,7 +672,9 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
deviceId = result.device.address,
|
||||
isPaired = result.device.bondState == BOND_BONDED,
|
||||
manufacturerDataHead = result.manufacturerDataHead,
|
||||
rssi = result.rssi.toLong()
|
||||
rssi = result.rssi.toLong(),
|
||||
services = result.device.uuids?.map { it.uuid?.toString() ?: "" }
|
||||
?: emptyList()
|
||||
)
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// Autogenerated from Pigeon (v17.1.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
import Foundation
|
||||
@@ -51,6 +51,7 @@ struct UniversalBleScanResult {
|
||||
var rssi: Int64? = nil
|
||||
var manufacturerData: FlutterStandardTypedData? = nil
|
||||
var manufacturerDataHead: FlutterStandardTypedData? = nil
|
||||
var services: [String?]? = nil
|
||||
|
||||
static func fromList(_ list: [Any?]) -> UniversalBleScanResult? {
|
||||
let deviceId = list[0] as! String
|
||||
@@ -59,6 +60,7 @@ struct UniversalBleScanResult {
|
||||
let rssi: Int64? = isNullish(list[3]) ? nil : (list[3] is Int64? ? list[3] as! Int64? : Int64(list[3] as! Int32))
|
||||
let manufacturerData: FlutterStandardTypedData? = nilOrValue(list[4])
|
||||
let manufacturerDataHead: FlutterStandardTypedData? = nilOrValue(list[5])
|
||||
let services: [String?]? = nilOrValue(list[6])
|
||||
|
||||
return UniversalBleScanResult(
|
||||
deviceId: deviceId,
|
||||
@@ -66,7 +68,8 @@ struct UniversalBleScanResult {
|
||||
isPaired: isPaired,
|
||||
rssi: rssi,
|
||||
manufacturerData: manufacturerData,
|
||||
manufacturerDataHead: manufacturerDataHead
|
||||
manufacturerDataHead: manufacturerDataHead,
|
||||
services: services
|
||||
)
|
||||
}
|
||||
func toList() -> [Any?] {
|
||||
@@ -77,6 +80,7 @@ struct UniversalBleScanResult {
|
||||
rssi,
|
||||
manufacturerData,
|
||||
manufacturerDataHead,
|
||||
services,
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -125,6 +129,24 @@ struct UniversalBleCharacteristic {
|
||||
}
|
||||
}
|
||||
|
||||
/// Generated class from Pigeon that represents data sent in messages.
|
||||
struct UniversalScanFilter {
|
||||
var withServices: [String?]
|
||||
|
||||
static func fromList(_ list: [Any?]) -> UniversalScanFilter? {
|
||||
let withServices = list[0] as! [String?]
|
||||
|
||||
return UniversalScanFilter(
|
||||
withServices: withServices
|
||||
)
|
||||
}
|
||||
func toList() -> [Any?] {
|
||||
return [
|
||||
withServices
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private class UniversalBlePlatformChannelCodecReader: FlutterStandardReader {
|
||||
override func readValue(ofType type: UInt8) -> Any? {
|
||||
switch type {
|
||||
@@ -134,6 +156,8 @@ private class UniversalBlePlatformChannelCodecReader: FlutterStandardReader {
|
||||
return UniversalBleScanResult.fromList(self.readValue() as! [Any?])
|
||||
case 130:
|
||||
return UniversalBleService.fromList(self.readValue() as! [Any?])
|
||||
case 131:
|
||||
return UniversalScanFilter.fromList(self.readValue() as! [Any?])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
@@ -151,6 +175,9 @@ private class UniversalBlePlatformChannelCodecWriter: FlutterStandardWriter {
|
||||
} else if let value = value as? UniversalBleService {
|
||||
super.writeByte(130)
|
||||
super.writeValue(value.toList())
|
||||
} else if let value = value as? UniversalScanFilter {
|
||||
super.writeByte(131)
|
||||
super.writeValue(value.toList())
|
||||
} else {
|
||||
super.writeValue(value)
|
||||
}
|
||||
@@ -177,7 +204,7 @@ class UniversalBlePlatformChannelCodec: FlutterStandardMessageCodec {
|
||||
protocol UniversalBlePlatformChannel {
|
||||
func getBluetoothAvailabilityState(completion: @escaping (Result<Int64, Error>) -> Void)
|
||||
func enableBluetooth(completion: @escaping (Result<Bool, Error>) -> Void)
|
||||
func startScan() throws
|
||||
func startScan(filter: UniversalScanFilter?) throws
|
||||
func stopScan() throws
|
||||
func connect(deviceId: String) throws
|
||||
func disconnect(deviceId: String) throws
|
||||
@@ -230,9 +257,11 @@ class UniversalBlePlatformChannelSetup {
|
||||
}
|
||||
let startScanChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan", binaryMessenger: binaryMessenger, codec: codec)
|
||||
if let api = api {
|
||||
startScanChannel.setMessageHandler { _, reply in
|
||||
startScanChannel.setMessageHandler { message, reply in
|
||||
let args = message as! [Any?]
|
||||
let filterArg: UniversalScanFilter? = nilOrValue(args[0])
|
||||
do {
|
||||
try api.startScan()
|
||||
try api.startScan(filter: filterArg)
|
||||
reply(wrapResult(nil))
|
||||
} catch {
|
||||
reply(wrapError(error))
|
||||
|
||||
@@ -141,6 +141,20 @@ public extension CBPeripheral {
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
var validFullUUID: String {
|
||||
let uuidLength = self.count
|
||||
if uuidLength == 4 || uuidLength == 8 {
|
||||
let baseUuid = "00000000-0000-1000-8000-00805F9B34FB"
|
||||
let start = baseUuid.startIndex
|
||||
let range = baseUuid.index(start, offsetBy: 4-uuidLength)..<baseUuid.index(start, offsetBy: 4)
|
||||
return baseUuid.replacingCharacters(in: range, with: self)
|
||||
} else {
|
||||
return self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Future classes
|
||||
class CharacteristicReadFuture {
|
||||
let deviceId: String
|
||||
|
||||
@@ -56,8 +56,20 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
|
||||
completion(Result.failure(FlutterError(code: "NotSupported", message: nil, details: nil)))
|
||||
}
|
||||
|
||||
func startScan() throws {
|
||||
manager.scanForPeripherals(withServices: nil)
|
||||
func startScan(filter: UniversalScanFilter?) throws {
|
||||
|
||||
// Apply services filter
|
||||
var withServices: [CBUUID] = []
|
||||
for service in filter?.withServices ?? [] {
|
||||
if let service = service {
|
||||
if UUID(uuidString: service.validFullUUID) == nil {
|
||||
throw FlutterError(code: "IllegalArgument", message: "Invalid service UUID:\(service)", details: nil)
|
||||
}
|
||||
withServices.append(CBUUID(string: service))
|
||||
}
|
||||
}
|
||||
|
||||
manager.scanForPeripherals(withServices: withServices)
|
||||
}
|
||||
|
||||
func stopScan() throws {
|
||||
@@ -228,12 +240,14 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
|
||||
public func centralManager(_: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
|
||||
discoveredPeripherals[peripheral.uuid.uuidString] = peripheral
|
||||
let manufacturerData = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data
|
||||
let services = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID]
|
||||
callbackChannel.onScanResult(result: UniversalBleScanResult(
|
||||
deviceId: peripheral.uuid.uuidString,
|
||||
name: peripheral.name,
|
||||
isPaired: nil,
|
||||
rssi: RSSI as? Int64,
|
||||
manufacturerData: FlutterStandardTypedData(bytes: manufacturerData ?? Data())
|
||||
manufacturerData: FlutterStandardTypedData(bytes: manufacturerData ?? Data()),
|
||||
services: services?.map { $0.uuidStr }
|
||||
)) { _ in }
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,10 @@ class MockUniversalBle extends UniversalBlePlatform {
|
||||
]);
|
||||
|
||||
@override
|
||||
Future<void> startScan({WebRequestOptionsBuilder? webRequestOptions}) async {
|
||||
Future<void> startScan({
|
||||
WebRequestOptionsBuilder? webRequestOptions,
|
||||
ScanFilter? scanFilter,
|
||||
}) async {
|
||||
onScanResult?.call(_mockBleScanResult);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ class _MyAppState extends State<MyApp> {
|
||||
};
|
||||
|
||||
UniversalBle.onScanResult = (result) {
|
||||
// debugPrint("ScanResult: ${result.name} ${result.services}");
|
||||
// debugPrint("${result.name} ${result.manufacturerData}");
|
||||
int index = _scanResults.indexWhere((e) => e.deviceId == result.deviceId);
|
||||
if (index == -1) {
|
||||
@@ -110,7 +111,9 @@ class _MyAppState extends State<MyApp> {
|
||||
});
|
||||
try {
|
||||
await UniversalBle.startScan(
|
||||
webRequestOptions: _requestOptions);
|
||||
webRequestOptions: _requestOptions,
|
||||
// scanFilter: ScanFilter(withServices: ['180f']),
|
||||
);
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
_isScanning = false;
|
||||
|
||||
@@ -7,6 +7,7 @@ class BleScanResult {
|
||||
Uint8List? manufacturerDataHead;
|
||||
Uint8List? manufacturerData;
|
||||
int? rssi;
|
||||
List<String> services;
|
||||
|
||||
BleScanResult({
|
||||
required this.name,
|
||||
@@ -15,6 +16,7 @@ class BleScanResult {
|
||||
this.isPaired,
|
||||
Uint8List? manufacturerData,
|
||||
Uint8List? manufacturerDataHead,
|
||||
this.services = const [],
|
||||
}) {
|
||||
this.manufacturerDataHead = manufacturerDataHead ?? Uint8List.fromList([]);
|
||||
this.manufacturerData = manufacturerData ?? manufacturerDataHead;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
export 'package:universal_ble/src/models/uuid.dart';
|
||||
export 'package:universal_ble/src/models/scan_filter.dart';
|
||||
export 'package:universal_ble/src/models/web_request_options_builder.dart';
|
||||
export 'package:universal_ble/src/models/ble_property.dart';
|
||||
export 'package:universal_ble/src/models/ble_service.dart';
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class ScanFilter {
|
||||
final List<String> withServices;
|
||||
|
||||
ScanFilter({
|
||||
this.withServices = const [],
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import 'package:bluez/bluez.dart';
|
||||
|
||||
class UUID {
|
||||
late String value;
|
||||
|
||||
UUID(String uuid) {
|
||||
// To validate the short UUID
|
||||
if (uuid.length <= 4) {
|
||||
try {
|
||||
int shortValue = int.parse(uuid, radix: 16);
|
||||
value = BlueZUUID.short(shortValue).toString();
|
||||
return;
|
||||
} catch (_) {}
|
||||
}
|
||||
// To validate the UUID
|
||||
BlueZUUID.fromString(uuid);
|
||||
value = uuid;
|
||||
}
|
||||
|
||||
factory UUID.fromShort(int short) {
|
||||
BlueZUUID blueZUUID = BlueZUUID.short(short);
|
||||
return UUID(blueZUUID.toString());
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a list of strings to a list of UUIDs
|
||||
extension StringListToUUID on List<String> {
|
||||
List<String> toValidUUIDList() => map((e) => UUID(e).value).toList();
|
||||
}
|
||||
@@ -1,20 +1,21 @@
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter_web_bluetooth/flutter_web_bluetooth.dart';
|
||||
import 'package:universal_ble/universal_ble.dart';
|
||||
|
||||
class WebRequestOptionsBuilder {
|
||||
final bool _acceptAllDevices;
|
||||
final List<WebRequestFilterBuilder> _requestFilters;
|
||||
final List<WebRequestFilterBuilder>? _exclusionFilters;
|
||||
final List<String>? _optionalServices;
|
||||
List<String>? _optionalServices;
|
||||
|
||||
WebRequestOptionsBuilder(
|
||||
List<WebRequestFilterBuilder> requestFilters, {
|
||||
List<WebRequestFilterBuilder>? exclusionFilters,
|
||||
List<String>? optionalServices,
|
||||
}) : _requestFilters = requestFilters,
|
||||
}) : _optionalServices = optionalServices,
|
||||
_requestFilters = requestFilters,
|
||||
_exclusionFilters = exclusionFilters,
|
||||
_acceptAllDevices = false,
|
||||
_optionalServices = optionalServices {
|
||||
_acceptAllDevices = false {
|
||||
if (_requestFilters.isEmpty) {
|
||||
throw StateError(
|
||||
'No filters have been set, consider using '
|
||||
@@ -26,25 +27,38 @@ class WebRequestOptionsBuilder {
|
||||
/// To accept all devices
|
||||
WebRequestOptionsBuilder.acceptAllDevices({
|
||||
List<String>? optionalServices,
|
||||
}) : _acceptAllDevices = true,
|
||||
}) : _optionalServices = optionalServices,
|
||||
_acceptAllDevices = true,
|
||||
_requestFilters = [],
|
||||
_exclusionFilters = null,
|
||||
_optionalServices = optionalServices;
|
||||
_exclusionFilters = null;
|
||||
|
||||
/// For internal use
|
||||
/// To convert UniversalBleRequestOptions to FlutterWebBluetoothRequestOptions
|
||||
RequestOptionsBuilder toRequestOptionsBuilder() {
|
||||
RequestOptionsBuilder toRequestOptionsBuilder({ScanFilter? scanFilter}) {
|
||||
if (scanFilter != null) _applyScanFilter(scanFilter);
|
||||
|
||||
if (_acceptAllDevices) {
|
||||
return RequestOptionsBuilder.acceptAllDevices(
|
||||
optionalServices: _optionalServices,
|
||||
);
|
||||
} else {
|
||||
return RequestOptionsBuilder(
|
||||
_requestFilters.map((e) => e.getRequestFilterBuilder()).toList(),
|
||||
exclusionFilters:
|
||||
_exclusionFilters?.map((e) => e.getRequestFilterBuilder()).toList(),
|
||||
optionalServices: _optionalServices,
|
||||
);
|
||||
}
|
||||
|
||||
return RequestOptionsBuilder(
|
||||
_requestFilters.map((e) => e.getRequestFilterBuilder()).toList(),
|
||||
exclusionFilters:
|
||||
_exclusionFilters?.map((e) => e.getRequestFilterBuilder()).toList(),
|
||||
optionalServices: _optionalServices,
|
||||
);
|
||||
}
|
||||
|
||||
/// To apply scan filter
|
||||
void _applyScanFilter(ScanFilter scanFilter) {
|
||||
List<String> filterServices = scanFilter.withServices;
|
||||
_optionalServices ??= filterServices.toValidUUIDList();
|
||||
|
||||
for (var requestFilter in _requestFilters) {
|
||||
// Apply services filter
|
||||
requestFilter.services ??= filterServices.toValidUUIDList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:universal_ble/src/models/scan_filter.dart';
|
||||
import 'package:universal_ble/src/universal_ble_linux/universal_ble_linux.dart';
|
||||
import 'package:universal_ble/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart';
|
||||
import 'package:universal_ble/src/universal_ble_web/universal_ble_web.dart';
|
||||
@@ -45,9 +46,13 @@ class UniversalBle {
|
||||
/// `webRequestOptions` supported on Web only
|
||||
static Future<void> startScan({
|
||||
WebRequestOptionsBuilder? webRequestOptions,
|
||||
ScanFilter? scanFilter,
|
||||
}) async {
|
||||
return await _executeCommand(
|
||||
() => _platform.startScan(webRequestOptions: webRequestOptions),
|
||||
() => _platform.startScan(
|
||||
webRequestOptions: webRequestOptions,
|
||||
scanFilter: scanFilter,
|
||||
),
|
||||
timeout: null,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,9 +55,14 @@ class UniversalBleLinux extends UniversalBlePlatform {
|
||||
@override
|
||||
Future<void> startScan({
|
||||
WebRequestOptionsBuilder? webRequestOptions,
|
||||
ScanFilter? scanFilter,
|
||||
}) async {
|
||||
await _ensureInitialized();
|
||||
if (_activeAdapter?.discovering != true) {
|
||||
// Add services filter
|
||||
_activeAdapter?.setDiscoveryFilter(
|
||||
uuids: scanFilter?.withServices.toValidUUIDList(),
|
||||
);
|
||||
await _activeAdapter?.startDiscovery();
|
||||
_client.devices.forEach(_onDeviceAdd);
|
||||
}
|
||||
@@ -455,11 +460,8 @@ extension BlueZDeviceExtension on BlueZDevice {
|
||||
int companyId = sorted.first.key.id;
|
||||
List<int> manufacturerDataValue = sorted.first.value;
|
||||
var byteData = ByteData(2);
|
||||
byteData.setInt16(
|
||||
0,
|
||||
companyId,
|
||||
Endian
|
||||
.host); // TODO: Verify that this works regardless of the endianess
|
||||
// TODO: Verify that this works regardless of the endianess
|
||||
byteData.setInt16(0, companyId, Endian.host);
|
||||
List<int> bytes = byteData.buffer.asUint8List();
|
||||
return Uint8List.fromList(bytes + manufacturerDataValue);
|
||||
} catch (e) {
|
||||
@@ -479,6 +481,7 @@ extension BlueZDeviceExtension on BlueZDevice {
|
||||
manufacturerData: manufacturerDataHead,
|
||||
manufacturerDataHead: manufacturerDataHead,
|
||||
rssi: rssi,
|
||||
services: uuids.map((e) => e.toString()).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// Autogenerated from Pigeon (v17.1.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
||||
|
||||
@@ -33,6 +33,7 @@ class UniversalBleScanResult {
|
||||
this.rssi,
|
||||
this.manufacturerData,
|
||||
this.manufacturerDataHead,
|
||||
this.services,
|
||||
});
|
||||
|
||||
String deviceId;
|
||||
@@ -47,6 +48,8 @@ class UniversalBleScanResult {
|
||||
|
||||
Uint8List? manufacturerDataHead;
|
||||
|
||||
List<String?>? services;
|
||||
|
||||
Object encode() {
|
||||
return <Object?>[
|
||||
deviceId,
|
||||
@@ -55,6 +58,7 @@ class UniversalBleScanResult {
|
||||
rssi,
|
||||
manufacturerData,
|
||||
manufacturerDataHead,
|
||||
services,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -67,6 +71,7 @@ class UniversalBleScanResult {
|
||||
rssi: result[3] as int?,
|
||||
manufacturerData: result[4] as Uint8List?,
|
||||
manufacturerDataHead: result[5] as Uint8List?,
|
||||
services: (result[6] as List<Object?>?)?.cast<String?>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -123,6 +128,27 @@ class UniversalBleCharacteristic {
|
||||
}
|
||||
}
|
||||
|
||||
class UniversalScanFilter {
|
||||
UniversalScanFilter({
|
||||
required this.withServices,
|
||||
});
|
||||
|
||||
List<String?> withServices;
|
||||
|
||||
Object encode() {
|
||||
return <Object?>[
|
||||
withServices,
|
||||
];
|
||||
}
|
||||
|
||||
static UniversalScanFilter decode(Object result) {
|
||||
result as List<Object?>;
|
||||
return UniversalScanFilter(
|
||||
withServices: (result[0] as List<Object?>?)!.cast<String?>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _UniversalBlePlatformChannelCodec extends StandardMessageCodec {
|
||||
const _UniversalBlePlatformChannelCodec();
|
||||
@override
|
||||
@@ -136,6 +162,9 @@ class _UniversalBlePlatformChannelCodec extends StandardMessageCodec {
|
||||
} else if (value is UniversalBleService) {
|
||||
buffer.putUint8(130);
|
||||
writeValue(buffer, value.encode());
|
||||
} else if (value is UniversalScanFilter) {
|
||||
buffer.putUint8(131);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
@@ -150,6 +179,8 @@ class _UniversalBlePlatformChannelCodec extends StandardMessageCodec {
|
||||
return UniversalBleScanResult.decode(readValue(buffer)!);
|
||||
case 130:
|
||||
return UniversalBleService.decode(readValue(buffer)!);
|
||||
case 131:
|
||||
return UniversalScanFilter.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
@@ -221,7 +252,7 @@ class UniversalBlePlatformChannel {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> startScan() async {
|
||||
Future<void> startScan(UniversalScanFilter? filter) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
@@ -229,7 +260,7 @@ class UniversalBlePlatformChannel {
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(null) as List<Object?>?;
|
||||
await __pigeon_channel.send(<Object?>[filter]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
|
||||
@@ -30,8 +30,12 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
||||
@override
|
||||
Future<void> startScan({
|
||||
WebRequestOptionsBuilder? webRequestOptions,
|
||||
}) =>
|
||||
_channel.startScan();
|
||||
ScanFilter? scanFilter,
|
||||
}) async {
|
||||
await _channel.startScan(
|
||||
scanFilter.toUniversalScanFilter(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> stopScan() => _channel.stopScan();
|
||||
@@ -192,6 +196,23 @@ extension _UniversalBleScanResultExtension on UniversalBleScanResult {
|
||||
manufacturerData: mnfData,
|
||||
manufacturerDataHead: mnfDataHead,
|
||||
rssi: rssi,
|
||||
services: services
|
||||
?.where((e) => e != null)
|
||||
.map((e) => UUID(e!).toString())
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension _ScanFilterExtension on ScanFilter? {
|
||||
UniversalScanFilter? toUniversalScanFilter() {
|
||||
// Windows crashes if it's null, so we need to pass empty scan filter in this case
|
||||
if (this == null && Platform.isWindows) {
|
||||
return UniversalScanFilter(withServices: []);
|
||||
}
|
||||
return UniversalScanFilter(
|
||||
withServices: this?.withServices.toValidUUIDList() ?? [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'dart:developer';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:universal_ble/universal_ble.dart';
|
||||
|
||||
abstract class UniversalBlePlatform {
|
||||
@@ -10,6 +9,7 @@ abstract class UniversalBlePlatform {
|
||||
|
||||
Future<void> startScan({
|
||||
WebRequestOptionsBuilder? webRequestOptions,
|
||||
ScanFilter? scanFilter,
|
||||
});
|
||||
|
||||
Future<void> stopScan();
|
||||
|
||||
@@ -110,10 +110,21 @@ class UniversalBleWeb extends UniversalBlePlatform {
|
||||
@override
|
||||
Future<void> startScan({
|
||||
WebRequestOptionsBuilder? webRequestOptions,
|
||||
ScanFilter? scanFilter,
|
||||
}) async {
|
||||
RequestOptionsBuilder requestFilterBuilder;
|
||||
if (webRequestOptions != null) {
|
||||
requestFilterBuilder = webRequestOptions.toRequestOptionsBuilder(
|
||||
scanFilter: scanFilter,
|
||||
);
|
||||
} else if (scanFilter != null) {
|
||||
requestFilterBuilder = scanFilter.toRequestOptionsBuilder();
|
||||
} else {
|
||||
requestFilterBuilder = RequestOptionsBuilder.acceptAllDevices();
|
||||
}
|
||||
|
||||
BluetoothDevice device = await FlutterWebBluetooth.instance.requestDevice(
|
||||
webRequestOptions?.toRequestOptionsBuilder() ??
|
||||
RequestOptionsBuilder.acceptAllDevices(),
|
||||
requestFilterBuilder,
|
||||
);
|
||||
|
||||
// Update local device list
|
||||
@@ -137,6 +148,7 @@ class UniversalBleWeb extends UniversalBlePlatform {
|
||||
device.toBleScanResult(
|
||||
rssi: event.rssi,
|
||||
manufacturerDataMap: event.manufacturerData,
|
||||
services: event.uuids,
|
||||
),
|
||||
);
|
||||
});
|
||||
@@ -346,6 +358,7 @@ extension _BluetoothDeviceExtension on BluetoothDevice {
|
||||
BleScanResult toBleScanResult({
|
||||
int? rssi,
|
||||
UnmodifiableMapView<int, ByteData>? manufacturerDataMap,
|
||||
List<String> services = const [],
|
||||
}) {
|
||||
return BleScanResult(
|
||||
name: name,
|
||||
@@ -353,6 +366,7 @@ extension _BluetoothDeviceExtension on BluetoothDevice {
|
||||
manufacturerData: manufacturerDataMap?.toUint8List(),
|
||||
manufacturerDataHead: manufacturerDataMap?.toUint8List(),
|
||||
rssi: rssi,
|
||||
services: services,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -372,3 +386,12 @@ extension _UnmodifiableMapViewExtension on UnmodifiableMapView<int, ByteData> {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
extension ScanFilterExtension on ScanFilter {
|
||||
RequestOptionsBuilder toRequestOptionsBuilder() {
|
||||
return RequestOptionsBuilder(
|
||||
[RequestFilterBuilder(services: withServices.toValidUUIDList())],
|
||||
optionalServices: withServices.toValidUUIDList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ abstract class UniversalBlePlatformChannel {
|
||||
@async
|
||||
bool enableBluetooth();
|
||||
|
||||
void startScan();
|
||||
void startScan(UniversalScanFilter? filter);
|
||||
|
||||
void stopScan();
|
||||
|
||||
@@ -105,6 +105,7 @@ class UniversalBleScanResult {
|
||||
final int? rssi;
|
||||
final Uint8List? manufacturerData;
|
||||
final Uint8List? manufacturerDataHead;
|
||||
final List<String?>? services;
|
||||
|
||||
UniversalBleScanResult({
|
||||
required this.name,
|
||||
@@ -113,6 +114,7 @@ class UniversalBleScanResult {
|
||||
required this.rssi,
|
||||
required this.manufacturerData,
|
||||
required this.manufacturerDataHead,
|
||||
required this.services,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -127,3 +129,9 @@ class UniversalBleCharacteristic {
|
||||
List<int?> properties;
|
||||
UniversalBleCharacteristic(this.uuid, this.properties);
|
||||
}
|
||||
|
||||
class UniversalScanFilter {
|
||||
final List<String?> withServices;
|
||||
|
||||
UniversalScanFilter(this.withServices);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
name: universal_ble
|
||||
description: A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE) plugin for Flutter
|
||||
version: 0.9.2
|
||||
version: 0.9.3
|
||||
homepage: https://navideck.com
|
||||
repository: https://github.com/Navideck/universal_ble
|
||||
issue_tracker: https://github.com/Navideck/universal_ble/issues
|
||||
@@ -32,7 +32,7 @@ dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^2.0.0
|
||||
pigeon: ^16.0.5
|
||||
pigeon: ^17.1.1
|
||||
|
||||
flutter:
|
||||
plugin:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// Autogenerated from Pigeon (v17.1.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
#undef _HAS_EXCEPTIONS
|
||||
@@ -39,13 +39,15 @@ UniversalBleScanResult::UniversalBleScanResult(
|
||||
const bool* is_paired,
|
||||
const int64_t* rssi,
|
||||
const std::vector<uint8_t>* manufacturer_data,
|
||||
const std::vector<uint8_t>* manufacturer_data_head)
|
||||
const std::vector<uint8_t>* manufacturer_data_head,
|
||||
const EncodableList* services)
|
||||
: device_id_(device_id),
|
||||
name_(name ? std::optional<std::string>(*name) : std::nullopt),
|
||||
is_paired_(is_paired ? std::optional<bool>(*is_paired) : std::nullopt),
|
||||
rssi_(rssi ? std::optional<int64_t>(*rssi) : std::nullopt),
|
||||
manufacturer_data_(manufacturer_data ? std::optional<std::vector<uint8_t>>(*manufacturer_data) : std::nullopt),
|
||||
manufacturer_data_head_(manufacturer_data_head ? std::optional<std::vector<uint8_t>>(*manufacturer_data_head) : std::nullopt) {}
|
||||
manufacturer_data_head_(manufacturer_data_head ? std::optional<std::vector<uint8_t>>(*manufacturer_data_head) : std::nullopt),
|
||||
services_(services ? std::optional<EncodableList>(*services) : std::nullopt) {}
|
||||
|
||||
const std::string& UniversalBleScanResult::device_id() const {
|
||||
return device_id_;
|
||||
@@ -121,15 +123,29 @@ void UniversalBleScanResult::set_manufacturer_data_head(const std::vector<uint8_
|
||||
}
|
||||
|
||||
|
||||
const EncodableList* UniversalBleScanResult::services() const {
|
||||
return services_ ? &(*services_) : nullptr;
|
||||
}
|
||||
|
||||
void UniversalBleScanResult::set_services(const EncodableList* value_arg) {
|
||||
services_ = value_arg ? std::optional<EncodableList>(*value_arg) : std::nullopt;
|
||||
}
|
||||
|
||||
void UniversalBleScanResult::set_services(const EncodableList& value_arg) {
|
||||
services_ = value_arg;
|
||||
}
|
||||
|
||||
|
||||
EncodableList UniversalBleScanResult::ToEncodableList() const {
|
||||
EncodableList list;
|
||||
list.reserve(6);
|
||||
list.reserve(7);
|
||||
list.push_back(EncodableValue(device_id_));
|
||||
list.push_back(name_ ? EncodableValue(*name_) : EncodableValue());
|
||||
list.push_back(is_paired_ ? EncodableValue(*is_paired_) : EncodableValue());
|
||||
list.push_back(rssi_ ? EncodableValue(*rssi_) : EncodableValue());
|
||||
list.push_back(manufacturer_data_ ? EncodableValue(*manufacturer_data_) : EncodableValue());
|
||||
list.push_back(manufacturer_data_head_ ? EncodableValue(*manufacturer_data_head_) : EncodableValue());
|
||||
list.push_back(services_ ? EncodableValue(*services_) : EncodableValue());
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -156,6 +172,10 @@ UniversalBleScanResult UniversalBleScanResult::FromEncodableList(const Encodable
|
||||
if (!encodable_manufacturer_data_head.IsNull()) {
|
||||
decoded.set_manufacturer_data_head(std::get<std::vector<uint8_t>>(encodable_manufacturer_data_head));
|
||||
}
|
||||
auto& encodable_services = list[6];
|
||||
if (!encodable_services.IsNull()) {
|
||||
decoded.set_services(std::get<EncodableList>(encodable_services));
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
@@ -251,6 +271,33 @@ UniversalBleCharacteristic UniversalBleCharacteristic::FromEncodableList(const E
|
||||
return decoded;
|
||||
}
|
||||
|
||||
// UniversalScanFilter
|
||||
|
||||
UniversalScanFilter::UniversalScanFilter(const EncodableList& with_services)
|
||||
: with_services_(with_services) {}
|
||||
|
||||
const EncodableList& UniversalScanFilter::with_services() const {
|
||||
return with_services_;
|
||||
}
|
||||
|
||||
void UniversalScanFilter::set_with_services(const EncodableList& value_arg) {
|
||||
with_services_ = value_arg;
|
||||
}
|
||||
|
||||
|
||||
EncodableList UniversalScanFilter::ToEncodableList() const {
|
||||
EncodableList list;
|
||||
list.reserve(1);
|
||||
list.push_back(EncodableValue(with_services_));
|
||||
return list;
|
||||
}
|
||||
|
||||
UniversalScanFilter UniversalScanFilter::FromEncodableList(const EncodableList& list) {
|
||||
UniversalScanFilter decoded(
|
||||
std::get<EncodableList>(list[0]));
|
||||
return decoded;
|
||||
}
|
||||
|
||||
|
||||
UniversalBlePlatformChannelCodecSerializer::UniversalBlePlatformChannelCodecSerializer() {}
|
||||
|
||||
@@ -264,6 +311,8 @@ EncodableValue UniversalBlePlatformChannelCodecSerializer::ReadValueOfType(
|
||||
return CustomEncodableValue(UniversalBleScanResult::FromEncodableList(std::get<EncodableList>(ReadValue(stream))));
|
||||
case 130:
|
||||
return CustomEncodableValue(UniversalBleService::FromEncodableList(std::get<EncodableList>(ReadValue(stream))));
|
||||
case 131:
|
||||
return CustomEncodableValue(UniversalScanFilter::FromEncodableList(std::get<EncodableList>(ReadValue(stream))));
|
||||
default:
|
||||
return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
|
||||
}
|
||||
@@ -288,6 +337,11 @@ void UniversalBlePlatformChannelCodecSerializer::WriteValue(
|
||||
WriteValue(EncodableValue(std::any_cast<UniversalBleService>(*custom_value).ToEncodableList()), stream);
|
||||
return;
|
||||
}
|
||||
if (custom_value->type() == typeid(UniversalScanFilter)) {
|
||||
stream->WriteByte(131);
|
||||
WriteValue(EncodableValue(std::any_cast<UniversalScanFilter>(*custom_value).ToEncodableList()), stream);
|
||||
return;
|
||||
}
|
||||
}
|
||||
flutter::StandardCodecSerializer::WriteValue(value, stream);
|
||||
}
|
||||
@@ -302,9 +356,9 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
flutter::BinaryMessenger* binary_messenger,
|
||||
UniversalBlePlatformChannel* api) {
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
api->GetBluetoothAvailabilityState([reply](ErrorOr<int64_t>&& output) {
|
||||
if (output.has_error()) {
|
||||
@@ -320,13 +374,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
api->EnableBluetooth([reply](ErrorOr<bool>&& output) {
|
||||
if (output.has_error()) {
|
||||
@@ -342,15 +396,18 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
std::optional<FlutterError> output = api->StartScan();
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_filter_arg = args.at(0);
|
||||
const auto* filter_arg = &(std::any_cast<const UniversalScanFilter&>(std::get<CustomEncodableValue>(encodable_filter_arg)));
|
||||
std::optional<FlutterError> output = api->StartScan(filter_arg);
|
||||
if (output.has_value()) {
|
||||
reply(WrapError(output.value()));
|
||||
return;
|
||||
@@ -363,13 +420,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
std::optional<FlutterError> output = api->StopScan();
|
||||
if (output.has_value()) {
|
||||
@@ -384,13 +441,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -412,13 +469,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -440,13 +497,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -486,13 +543,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -515,13 +572,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -556,13 +613,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -591,13 +648,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -644,13 +701,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -673,13 +730,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -701,13 +758,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_device_id_arg = args.at(0);
|
||||
@@ -729,13 +786,13 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices", &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_with_services_arg = args.at(0);
|
||||
@@ -758,7 +815,7 @@ void UniversalBlePlatformChannel::SetUp(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
channel.SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -819,11 +876,11 @@ void UniversalBleCallbackChannel::OnAvailabilityChanged(
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, channel_name, &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
EncodableValue(state_arg),
|
||||
});
|
||||
channel->Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
channel.Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
std::unique_ptr<EncodableValue> response = GetCodec().DecodeMessage(reply, reply_size);
|
||||
const auto& encodable_return_value = *response;
|
||||
const auto* list_return_value = std::get_if<EncodableList>(&encodable_return_value);
|
||||
@@ -846,13 +903,13 @@ void UniversalBleCallbackChannel::OnPairStateChange(
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, channel_name, &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
EncodableValue(device_id_arg),
|
||||
EncodableValue(is_paired_arg),
|
||||
error_arg ? EncodableValue(*error_arg) : EncodableValue(),
|
||||
});
|
||||
channel->Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
channel.Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
std::unique_ptr<EncodableValue> response = GetCodec().DecodeMessage(reply, reply_size);
|
||||
const auto& encodable_return_value = *response;
|
||||
const auto* list_return_value = std::get_if<EncodableList>(&encodable_return_value);
|
||||
@@ -873,11 +930,11 @@ void UniversalBleCallbackChannel::OnScanResult(
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, channel_name, &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
CustomEncodableValue(result_arg),
|
||||
});
|
||||
channel->Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
channel.Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
std::unique_ptr<EncodableValue> response = GetCodec().DecodeMessage(reply, reply_size);
|
||||
const auto& encodable_return_value = *response;
|
||||
const auto* list_return_value = std::get_if<EncodableList>(&encodable_return_value);
|
||||
@@ -900,13 +957,13 @@ void UniversalBleCallbackChannel::OnValueChanged(
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, channel_name, &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
EncodableValue(device_id_arg),
|
||||
EncodableValue(characteristic_id_arg),
|
||||
EncodableValue(value_arg),
|
||||
});
|
||||
channel->Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
channel.Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
std::unique_ptr<EncodableValue> response = GetCodec().DecodeMessage(reply, reply_size);
|
||||
const auto& encodable_return_value = *response;
|
||||
const auto* list_return_value = std::get_if<EncodableList>(&encodable_return_value);
|
||||
@@ -928,12 +985,12 @@ void UniversalBleCallbackChannel::OnConnectionChanged(
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, channel_name, &GetCodec());
|
||||
BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
EncodableValue(device_id_arg),
|
||||
EncodableValue(state_arg),
|
||||
});
|
||||
channel->Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
channel.Send(encoded_api_arguments, [channel_name, on_success = std::move(on_success), on_error = std::move(on_error)](const uint8_t* reply, size_t reply_size) {
|
||||
std::unique_ptr<EncodableValue> response = GetCodec().DecodeMessage(reply, reply_size);
|
||||
const auto& encodable_return_value = *response;
|
||||
const auto* list_return_value = std::get_if<EncodableList>(&encodable_return_value);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// Autogenerated from Pigeon (v17.1.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
#ifndef PIGEON_UNIVERSAL_BLE_G_H_
|
||||
@@ -70,7 +70,8 @@ class UniversalBleScanResult {
|
||||
const bool* is_paired,
|
||||
const int64_t* rssi,
|
||||
const std::vector<uint8_t>* manufacturer_data,
|
||||
const std::vector<uint8_t>* manufacturer_data_head);
|
||||
const std::vector<uint8_t>* manufacturer_data_head,
|
||||
const flutter::EncodableList* services);
|
||||
|
||||
const std::string& device_id() const;
|
||||
void set_device_id(std::string_view value_arg);
|
||||
@@ -95,6 +96,10 @@ class UniversalBleScanResult {
|
||||
void set_manufacturer_data_head(const std::vector<uint8_t>* value_arg);
|
||||
void set_manufacturer_data_head(const std::vector<uint8_t>& value_arg);
|
||||
|
||||
const flutter::EncodableList* services() const;
|
||||
void set_services(const flutter::EncodableList* value_arg);
|
||||
void set_services(const flutter::EncodableList& value_arg);
|
||||
|
||||
|
||||
private:
|
||||
static UniversalBleScanResult FromEncodableList(const flutter::EncodableList& list);
|
||||
@@ -109,6 +114,7 @@ class UniversalBleScanResult {
|
||||
std::optional<int64_t> rssi_;
|
||||
std::optional<std::vector<uint8_t>> manufacturer_data_;
|
||||
std::optional<std::vector<uint8_t>> manufacturer_data_head_;
|
||||
std::optional<flutter::EncodableList> services_;
|
||||
|
||||
};
|
||||
|
||||
@@ -172,6 +178,28 @@ class UniversalBleCharacteristic {
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Generated class from Pigeon that represents data sent in messages.
|
||||
class UniversalScanFilter {
|
||||
public:
|
||||
// Constructs an object setting all fields.
|
||||
explicit UniversalScanFilter(const flutter::EncodableList& with_services);
|
||||
|
||||
const flutter::EncodableList& with_services() const;
|
||||
void set_with_services(const flutter::EncodableList& value_arg);
|
||||
|
||||
|
||||
private:
|
||||
static UniversalScanFilter FromEncodableList(const flutter::EncodableList& list);
|
||||
flutter::EncodableList ToEncodableList() const;
|
||||
friend class UniversalBlePlatformChannel;
|
||||
friend class UniversalBlePlatformChannelCodecSerializer;
|
||||
friend class UniversalBleCallbackChannel;
|
||||
friend class UniversalBleCallbackChannelCodecSerializer;
|
||||
flutter::EncodableList with_services_;
|
||||
|
||||
};
|
||||
|
||||
class UniversalBlePlatformChannelCodecSerializer : public flutter::StandardCodecSerializer {
|
||||
public:
|
||||
UniversalBlePlatformChannelCodecSerializer();
|
||||
@@ -201,7 +229,7 @@ class UniversalBlePlatformChannel {
|
||||
virtual ~UniversalBlePlatformChannel() {}
|
||||
virtual void GetBluetoothAvailabilityState(std::function<void(ErrorOr<int64_t> reply)> result) = 0;
|
||||
virtual void EnableBluetooth(std::function<void(ErrorOr<bool> reply)> result) = 0;
|
||||
virtual std::optional<FlutterError> StartScan() = 0;
|
||||
virtual std::optional<FlutterError> StartScan(const UniversalScanFilter* filter) = 0;
|
||||
virtual std::optional<FlutterError> StopScan() = 0;
|
||||
virtual std::optional<FlutterError> Connect(const std::string& device_id) = 0;
|
||||
virtual std::optional<FlutterError> Disconnect(const std::string& device_id) = 0;
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace universal_ble
|
||||
} });
|
||||
}
|
||||
|
||||
std::optional<FlutterError> UniversalBlePlugin::StartScan()
|
||||
std::optional<FlutterError> UniversalBlePlugin::StartScan(const UniversalScanFilter *filter)
|
||||
{
|
||||
if (bluetoothRadio && bluetoothRadio.State() == RadioState::On)
|
||||
{
|
||||
@@ -99,6 +99,8 @@ namespace universal_ble
|
||||
{
|
||||
bluetoothLEWatcher = BluetoothLEAdvertisementWatcher();
|
||||
bluetoothLEWatcher.ScanningMode(BluetoothLEScanningMode::Active);
|
||||
if (filter != nullptr)
|
||||
ApplyScanFilter(filter, bluetoothLEWatcher);
|
||||
bluetoothLEWatcherReceivedToken = bluetoothLEWatcher.Received({this, &UniversalBlePlugin::BluetoothLEWatcher_Received});
|
||||
}
|
||||
bluetoothLEWatcher.Start();
|
||||
@@ -116,6 +118,20 @@ namespace universal_ble
|
||||
}
|
||||
};
|
||||
|
||||
void UniversalBlePlugin::ApplyScanFilter(const UniversalScanFilter *filter, BluetoothLEAdvertisementWatcher &bluetoothWatcher)
|
||||
{
|
||||
// Apply Services filter
|
||||
const auto &services = filter->with_services();
|
||||
if (!services.empty())
|
||||
{
|
||||
for (const auto &uuid : services)
|
||||
{
|
||||
std::string uuid_str = std::get<std::string>(uuid);
|
||||
bluetoothWatcher.AdvertisementFilter().Advertisement().ServiceUuids().Append(uuid_to_guid(uuid_str));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<FlutterError> UniversalBlePlugin::StopScan()
|
||||
{
|
||||
|
||||
@@ -516,6 +532,11 @@ namespace universal_ble
|
||||
scanResult.set_manufacturer_data_head(existingScanResult.manufacturer_data_head());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if (scanResult.services() == nullptr && existingScanResult.services() != nullptr)
|
||||
{
|
||||
scanResult.set_services(existingScanResult.services());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
|
||||
// if nothing to update then return
|
||||
if (!shouldUpdate)
|
||||
@@ -629,6 +650,7 @@ namespace universal_ble
|
||||
int16_t rssi = rssiPropertyValue.GetInt16();
|
||||
universalScanResult.set_rssi(rssi);
|
||||
}
|
||||
|
||||
pushUniversalScanResult(universalScanResult);
|
||||
}
|
||||
}
|
||||
@@ -668,6 +690,12 @@ namespace universal_ble
|
||||
universalScanResult.set_manufacturer_data_head(manufacturerData);
|
||||
universalScanResult.set_rssi(args.RawSignalStrengthInDBm());
|
||||
|
||||
// Add services
|
||||
flutter::EncodableList services = flutter::EncodableList();
|
||||
for (auto &&uuid : args.Advertisement().ServiceUuids())
|
||||
services.push_back(guid_to_uuid(uuid));
|
||||
universalScanResult.set_services(services);
|
||||
|
||||
// check if this device already discovered in deviceWatcher
|
||||
auto it = deviceWatcherDevices.find(deviceId);
|
||||
if (it != deviceWatcherDevices.end())
|
||||
@@ -686,7 +714,6 @@ namespace universal_ble
|
||||
universalScanResult.set_name(winrt::to_string(deviceInfo.Name()));
|
||||
}
|
||||
|
||||
// Cache connectable status
|
||||
pushUniversalScanResult(universalScanResult);
|
||||
}
|
||||
catch (...)
|
||||
|
||||
@@ -123,11 +123,12 @@ namespace universal_ble
|
||||
winrt::fire_and_forget WriteAsync(GattCharacteristic characteristic, GattWriteOption writeOption,
|
||||
const std::vector<uint8_t> &value,
|
||||
std::function<void(std::optional<FlutterError> reply)> result);
|
||||
void ApplyScanFilter(const UniversalScanFilter *filter, BluetoothLEAdvertisementWatcher &bluetoothWatcher);
|
||||
|
||||
// UniversalBlePlatformChannel implementation.
|
||||
void GetBluetoothAvailabilityState(std::function<void(ErrorOr<int64_t> reply)> result) override;
|
||||
void EnableBluetooth(std::function<void(ErrorOr<bool> reply)> result) override;
|
||||
std::optional<FlutterError> StartScan() override;
|
||||
std::optional<FlutterError> StartScan(const UniversalScanFilter *filter) override;
|
||||
std::optional<FlutterError> StopScan() override;
|
||||
std::optional<FlutterError> Connect(const std::string &device_id) override;
|
||||
std::optional<FlutterError> Disconnect(const std::string &device_id) override;
|
||||
|
||||
Reference in New Issue
Block a user