Improve windows device name discovery (#4)
* Improve windows device name discovery * Imrove classes and folders structuring * rename generated files * Improve windows threads and other fixes * More optimizations * Cleanups * Update .vscode/settings.json Co-authored-by: Foti Dim <foti@navideck.com> * Resolve comments * Performance improvements --------- Co-authored-by: Foti Dim <foti@navideck.com> Co-authored-by: Foti Dim <fdimanidis@gmail.com>
This commit is contained in:
Vendored
+14
-1
@@ -1,18 +1,31 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"BTLE",
|
||||
"bytevc",
|
||||
"connnection",
|
||||
"DSIMPLEBLE",
|
||||
"hresult",
|
||||
"hstring",
|
||||
"HWND",
|
||||
"Inspectable",
|
||||
"LPARAM",
|
||||
"LRESULT",
|
||||
"microtask",
|
||||
"modalias",
|
||||
"navideck",
|
||||
"NSUUID",
|
||||
"NTDDI",
|
||||
"pairable",
|
||||
"rssi",
|
||||
"simpleble",
|
||||
"unawaited",
|
||||
"UNIVERSALBLE",
|
||||
"Unpair",
|
||||
"Unpairing",
|
||||
"unwatch",
|
||||
"uuidstr"
|
||||
"uuidstr",
|
||||
"winrt",
|
||||
"WPARAM"
|
||||
],
|
||||
"cmake.configureOnOpen": false,
|
||||
"files.associations": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v13.0.0), do not edit directly.
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
package com.navideck.universal_ble
|
||||
@@ -31,6 +31,9 @@ private fun wrapError(exception: Throwable): List<Any?> {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createConnectionError(channelName: String): FlutterError {
|
||||
return FlutterError("channel-error", "Unable to establish connection on channel: '$channelName'.", "")}
|
||||
|
||||
/**
|
||||
* Error class for passing custom error details to Flutter via a thrown PlatformException.
|
||||
* @property code The error code.
|
||||
@@ -525,73 +528,83 @@ class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger)
|
||||
UniversalBleCallbackChannelCodec
|
||||
}
|
||||
}
|
||||
fun onAvailabilityChanged(stateArg: Long, callback: (Result<Unit>) -> Unit) {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged", codec)
|
||||
fun onAvailabilityChanged(stateArg: Long, callback: (Result<Unit>) -> Unit)
|
||||
{
|
||||
val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged"
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||
channel.send(listOf(stateArg)) {
|
||||
if (it is List<*>) {
|
||||
if (it.size > 1) {
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)));
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||
} else {
|
||||
callback(Result.success(Unit));
|
||||
callback(Result.success(Unit))
|
||||
}
|
||||
} else {
|
||||
callback(Result.failure(FlutterError("channel-error", "Unable to establish connection on channel.", "")));
|
||||
callback(Result.failure(createConnectionError(channelName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
fun onPairStateChange(deviceIdArg: String, isPairedArg: Boolean, errorArg: String?, callback: (Result<Unit>) -> Unit) {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange", codec)
|
||||
fun onPairStateChange(deviceIdArg: String, isPairedArg: Boolean, errorArg: String?, callback: (Result<Unit>) -> Unit)
|
||||
{
|
||||
val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange"
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||
channel.send(listOf(deviceIdArg, isPairedArg, errorArg)) {
|
||||
if (it is List<*>) {
|
||||
if (it.size > 1) {
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)));
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||
} else {
|
||||
callback(Result.success(Unit));
|
||||
callback(Result.success(Unit))
|
||||
}
|
||||
} else {
|
||||
callback(Result.failure(FlutterError("channel-error", "Unable to establish connection on channel.", "")));
|
||||
callback(Result.failure(createConnectionError(channelName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
fun onScanResult(resultArg: UniversalBleScanResult, callback: (Result<Unit>) -> Unit) {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult", codec)
|
||||
fun onScanResult(resultArg: UniversalBleScanResult, callback: (Result<Unit>) -> Unit)
|
||||
{
|
||||
val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult"
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||
channel.send(listOf(resultArg)) {
|
||||
if (it is List<*>) {
|
||||
if (it.size > 1) {
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)));
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||
} else {
|
||||
callback(Result.success(Unit));
|
||||
callback(Result.success(Unit))
|
||||
}
|
||||
} else {
|
||||
callback(Result.failure(FlutterError("channel-error", "Unable to establish connection on channel.", "")));
|
||||
callback(Result.failure(createConnectionError(channelName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
fun onValueChanged(deviceIdArg: String, characteristicIdArg: String, valueArg: ByteArray, callback: (Result<Unit>) -> Unit) {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged", codec)
|
||||
fun onValueChanged(deviceIdArg: String, characteristicIdArg: String, valueArg: ByteArray, callback: (Result<Unit>) -> Unit)
|
||||
{
|
||||
val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged"
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||
channel.send(listOf(deviceIdArg, characteristicIdArg, valueArg)) {
|
||||
if (it is List<*>) {
|
||||
if (it.size > 1) {
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)));
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||
} else {
|
||||
callback(Result.success(Unit));
|
||||
callback(Result.success(Unit))
|
||||
}
|
||||
} else {
|
||||
callback(Result.failure(FlutterError("channel-error", "Unable to establish connection on channel.", "")));
|
||||
callback(Result.failure(createConnectionError(channelName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
fun onConnectionChanged(deviceIdArg: String, stateArg: Long, callback: (Result<Unit>) -> Unit) {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged", codec)
|
||||
fun onConnectionChanged(deviceIdArg: String, stateArg: Long, callback: (Result<Unit>) -> Unit)
|
||||
{
|
||||
val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged"
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||
channel.send(listOf(deviceIdArg, stateArg)) {
|
||||
if (it is List<*>) {
|
||||
if (it.size > 1) {
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)));
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||
} else {
|
||||
callback(Result.success(Unit));
|
||||
callback(Result.success(Unit))
|
||||
}
|
||||
} else {
|
||||
callback(Result.failure(FlutterError("channel-error", "Unable to establish connection on channel.", "")));
|
||||
callback(Result.failure(createConnectionError(channelName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
// Autogenerated from Pigeon (v13.0.0), do not edit directly.
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
import Foundation
|
||||
#if os(iOS)
|
||||
import Flutter
|
||||
#elseif os(macOS)
|
||||
import FlutterMacOS
|
||||
#else
|
||||
#error("Unsupported platform.")
|
||||
#endif
|
||||
|
||||
private func isNullish(_ value: Any?) -> Bool {
|
||||
return value is NSNull || value == nil
|
||||
}
|
||||
#if os(iOS)
|
||||
import Flutter
|
||||
#elseif os(macOS)
|
||||
import FlutterMacOS
|
||||
#else
|
||||
#error("Unsupported platform.")
|
||||
#endif
|
||||
|
||||
private func wrapResult(_ result: Any?) -> [Any?] {
|
||||
return [result]
|
||||
@@ -23,16 +20,24 @@ private func wrapError(_ error: Any) -> [Any?] {
|
||||
return [
|
||||
flutterError.code,
|
||||
flutterError.message,
|
||||
flutterError.details
|
||||
flutterError.details,
|
||||
]
|
||||
}
|
||||
return [
|
||||
"\(error)",
|
||||
"\(type(of: error))",
|
||||
"Stacktrace: \(Thread.callStackSymbols)"
|
||||
"Stacktrace: \(Thread.callStackSymbols)",
|
||||
]
|
||||
}
|
||||
|
||||
private func createConnectionError(withChannelName channelName: String) -> FlutterError {
|
||||
return FlutterError(code: "channel-error", message: "Unable to establish connection on channel: '\(channelName)'.", details: "")
|
||||
}
|
||||
|
||||
private func isNullish(_ value: Any?) -> Bool {
|
||||
return value is NSNull || value == nil
|
||||
}
|
||||
|
||||
private func nilOrValue<T>(_ value: Any?) -> T? {
|
||||
if value is NSNull { return nil }
|
||||
return value as! T?
|
||||
@@ -123,14 +128,14 @@ struct UniversalBleCharacteristic {
|
||||
private class UniversalBlePlatformChannelCodecReader: FlutterStandardReader {
|
||||
override func readValue(ofType type: UInt8) -> Any? {
|
||||
switch type {
|
||||
case 128:
|
||||
return UniversalBleCharacteristic.fromList(self.readValue() as! [Any?])
|
||||
case 129:
|
||||
return UniversalBleScanResult.fromList(self.readValue() as! [Any?])
|
||||
case 130:
|
||||
return UniversalBleService.fromList(self.readValue() as! [Any?])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
case 128:
|
||||
return UniversalBleCharacteristic.fromList(self.readValue() as! [Any?])
|
||||
case 129:
|
||||
return UniversalBleScanResult.fromList(self.readValue() as! [Any?])
|
||||
case 130:
|
||||
return UniversalBleService.fromList(self.readValue() as! [Any?])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,12 +201,12 @@ class UniversalBlePlatformChannelSetup {
|
||||
let getBluetoothAvailabilityStateChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState", binaryMessenger: binaryMessenger, codec: codec)
|
||||
if let api = api {
|
||||
getBluetoothAvailabilityStateChannel.setMessageHandler { _, reply in
|
||||
api.getBluetoothAvailabilityState() { result in
|
||||
api.getBluetoothAvailabilityState { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,12 +216,12 @@ class UniversalBlePlatformChannelSetup {
|
||||
let enableBluetoothChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth", binaryMessenger: binaryMessenger, codec: codec)
|
||||
if let api = api {
|
||||
enableBluetoothChannel.setMessageHandler { _, reply in
|
||||
api.enableBluetooth() { result in
|
||||
api.enableBluetooth { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,10 +309,10 @@ class UniversalBlePlatformChannelSetup {
|
||||
let deviceIdArg = args[0] as! String
|
||||
api.discoverServices(deviceId: deviceIdArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -323,10 +328,10 @@ class UniversalBlePlatformChannelSetup {
|
||||
let characteristicArg = args[2] as! String
|
||||
api.readValue(deviceId: deviceIdArg, service: serviceArg, characteristic: characteristicArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,10 +346,10 @@ class UniversalBlePlatformChannelSetup {
|
||||
let expectedMtuArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
|
||||
api.requestMtu(deviceId: deviceIdArg, expectedMtu: expectedMtuArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,10 +367,10 @@ class UniversalBlePlatformChannelSetup {
|
||||
let bleOutputPropertyArg = args[4] is Int64 ? args[4] as! Int64 : Int64(args[4] as! Int32)
|
||||
api.writeValue(deviceId: deviceIdArg, service: serviceArg, characteristic: characteristicArg, value: valueArg, bleOutputProperty: bleOutputPropertyArg) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
reply(wrapResult(nil))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
case .success:
|
||||
reply(wrapResult(nil))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,10 +384,10 @@ class UniversalBlePlatformChannelSetup {
|
||||
let deviceIdArg = args[0] as! String
|
||||
api.isPaired(deviceId: deviceIdArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,10 +431,10 @@ class UniversalBlePlatformChannelSetup {
|
||||
let withServicesArg = args[0] as! [String]
|
||||
api.getConnectedDevices(withServices: withServicesArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,10 +446,10 @@ class UniversalBlePlatformChannelSetup {
|
||||
private class UniversalBleCallbackChannelCodecReader: FlutterStandardReader {
|
||||
override func readValue(ofType type: UInt8) -> Any? {
|
||||
switch type {
|
||||
case 128:
|
||||
return UniversalBleScanResult.fromList(self.readValue() as! [Any?])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
case 128:
|
||||
return UniversalBleScanResult.fromList(self.readValue() as! [Any?])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -478,48 +483,108 @@ class UniversalBleCallbackChannelCodec: FlutterStandardMessageCodec {
|
||||
///
|
||||
/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift.
|
||||
protocol UniversalBleCallbackChannelProtocol {
|
||||
func onAvailabilityChanged(state stateArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onPairStateChange(deviceId deviceIdArg: String, isPaired isPairedArg: Bool, error errorArg: String?, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onScanResult(result resultArg: UniversalBleScanResult, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onValueChanged(deviceId deviceIdArg: String, characteristicId characteristicIdArg: String, value valueArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onConnectionChanged(deviceId deviceIdArg: String, state stateArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onAvailabilityChanged(state stateArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onPairStateChange(deviceId deviceIdArg: String, isPaired isPairedArg: Bool, error errorArg: String?, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onScanResult(result resultArg: UniversalBleScanResult, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onValueChanged(deviceId deviceIdArg: String, characteristicId characteristicIdArg: String, value valueArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
func onConnectionChanged(deviceId deviceIdArg: String, state stateArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
|
||||
}
|
||||
class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol {
|
||||
private let binaryMessenger: FlutterBinaryMessenger
|
||||
init(binaryMessenger: FlutterBinaryMessenger){
|
||||
init(binaryMessenger: FlutterBinaryMessenger) {
|
||||
self.binaryMessenger = binaryMessenger
|
||||
}
|
||||
var codec: FlutterStandardMessageCodec {
|
||||
return UniversalBleCallbackChannelCodec.shared
|
||||
}
|
||||
func onAvailabilityChanged(state stateArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([stateArg] as [Any?]) { _ in
|
||||
completion(.success(Void()))
|
||||
func onAvailabilityChanged(state stateArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged"
|
||||
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([stateArg] as [Any?]) { response in
|
||||
guard let listResponse = response as? [Any?] else {
|
||||
completion(.failure(createConnectionError(withChannelName: channelName)))
|
||||
return
|
||||
}
|
||||
if listResponse.count > 1 {
|
||||
let code: String = listResponse[0] as! String
|
||||
let message: String? = nilOrValue(listResponse[1])
|
||||
let details: String? = nilOrValue(listResponse[2])
|
||||
completion(.failure(FlutterError(code: code, message: message, details: details)))
|
||||
} else {
|
||||
completion(.success(Void()))
|
||||
}
|
||||
}
|
||||
}
|
||||
func onPairStateChange(deviceId deviceIdArg: String, isPaired isPairedArg: Bool, error errorArg: String?, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([deviceIdArg, isPairedArg, errorArg] as [Any?]) { _ in
|
||||
completion(.success(Void()))
|
||||
func onPairStateChange(deviceId deviceIdArg: String, isPaired isPairedArg: Bool, error errorArg: String?, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange"
|
||||
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([deviceIdArg, isPairedArg, errorArg] as [Any?]) { response in
|
||||
guard let listResponse = response as? [Any?] else {
|
||||
completion(.failure(createConnectionError(withChannelName: channelName)))
|
||||
return
|
||||
}
|
||||
if listResponse.count > 1 {
|
||||
let code: String = listResponse[0] as! String
|
||||
let message: String? = nilOrValue(listResponse[1])
|
||||
let details: String? = nilOrValue(listResponse[2])
|
||||
completion(.failure(FlutterError(code: code, message: message, details: details)))
|
||||
} else {
|
||||
completion(.success(Void()))
|
||||
}
|
||||
}
|
||||
}
|
||||
func onScanResult(result resultArg: UniversalBleScanResult, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([resultArg] as [Any?]) { _ in
|
||||
completion(.success(Void()))
|
||||
func onScanResult(result resultArg: UniversalBleScanResult, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult"
|
||||
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([resultArg] as [Any?]) { response in
|
||||
guard let listResponse = response as? [Any?] else {
|
||||
completion(.failure(createConnectionError(withChannelName: channelName)))
|
||||
return
|
||||
}
|
||||
if listResponse.count > 1 {
|
||||
let code: String = listResponse[0] as! String
|
||||
let message: String? = nilOrValue(listResponse[1])
|
||||
let details: String? = nilOrValue(listResponse[2])
|
||||
completion(.failure(FlutterError(code: code, message: message, details: details)))
|
||||
} else {
|
||||
completion(.success(Void()))
|
||||
}
|
||||
}
|
||||
}
|
||||
func onValueChanged(deviceId deviceIdArg: String, characteristicId characteristicIdArg: String, value valueArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([deviceIdArg, characteristicIdArg, valueArg] as [Any?]) { _ in
|
||||
completion(.success(Void()))
|
||||
func onValueChanged(deviceId deviceIdArg: String, characteristicId characteristicIdArg: String, value valueArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged"
|
||||
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([deviceIdArg, characteristicIdArg, valueArg] as [Any?]) { response in
|
||||
guard let listResponse = response as? [Any?] else {
|
||||
completion(.failure(createConnectionError(withChannelName: channelName)))
|
||||
return
|
||||
}
|
||||
if listResponse.count > 1 {
|
||||
let code: String = listResponse[0] as! String
|
||||
let message: String? = nilOrValue(listResponse[1])
|
||||
let details: String? = nilOrValue(listResponse[2])
|
||||
completion(.failure(FlutterError(code: code, message: message, details: details)))
|
||||
} else {
|
||||
completion(.success(Void()))
|
||||
}
|
||||
}
|
||||
}
|
||||
func onConnectionChanged(deviceId deviceIdArg: String, state stateArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([deviceIdArg, stateArg] as [Any?]) { _ in
|
||||
completion(.success(Void()))
|
||||
func onConnectionChanged(deviceId deviceIdArg: String, state stateArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
|
||||
let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged"
|
||||
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([deviceIdArg, stateArg] as [Any?]) { response in
|
||||
guard let listResponse = response as? [Any?] else {
|
||||
completion(.failure(createConnectionError(withChannelName: channelName)))
|
||||
return
|
||||
}
|
||||
if listResponse.count > 1 {
|
||||
let code: String = listResponse[0] as! String
|
||||
let message: String? = nilOrValue(listResponse[1])
|
||||
let details: String? = nilOrValue(listResponse[2])
|
||||
completion(.failure(FlutterError(code: code, message: message, details: details)))
|
||||
} else {
|
||||
completion(.success(Void()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ packages:
|
||||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.8.3"
|
||||
version: "0.8.4"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
// Autogenerated from Pigeon (v13.0.0), do not edit directly.
|
||||
// Autogenerated from Pigeon (v16.0.5), 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
|
||||
// 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
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
||||
|
||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
PlatformException _createConnectionError(String channelName) {
|
||||
return PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel: "$channelName".',
|
||||
);
|
||||
}
|
||||
|
||||
List<Object?> wrapResponse({Object? result, PlatformException? error, bool empty = false}) {
|
||||
if (empty) {
|
||||
return <Object?>[];
|
||||
@@ -154,81 +162,81 @@ class UniversalBlePlatformChannel {
|
||||
/// available for dependency injection. If it is left null, the default
|
||||
/// BinaryMessenger will be used which routes to the host platform.
|
||||
UniversalBlePlatformChannel({BinaryMessenger? binaryMessenger})
|
||||
: _binaryMessenger = binaryMessenger;
|
||||
final BinaryMessenger? _binaryMessenger;
|
||||
: __pigeon_binaryMessenger = binaryMessenger;
|
||||
final BinaryMessenger? __pigeon_binaryMessenger;
|
||||
|
||||
static const MessageCodec<Object?> codec = _UniversalBlePlatformChannelCodec();
|
||||
static const MessageCodec<Object?> pigeonChannelCodec = _UniversalBlePlatformChannelCodec();
|
||||
|
||||
Future<int> getBluetoothAvailabilityState() async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(null) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(null) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
} else if (__pigeon_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as int?)!;
|
||||
return (__pigeon_replyList[0] as int?)!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> enableBluetooth() async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(null) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(null) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
} else if (__pigeon_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as bool?)!;
|
||||
return (__pigeon_replyList[0] as bool?)!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> startScan() async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(null) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(null) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
@@ -236,291 +244,291 @@ class UniversalBlePlatformChannel {
|
||||
}
|
||||
|
||||
Future<void> stopScan() async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(null) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(null) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> connect(String arg_deviceId) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<void> connect(String deviceId) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> disconnect(String arg_deviceId) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<void> disconnect(String deviceId) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setNotifiable(String arg_deviceId, String arg_service, String arg_characteristic, int arg_bleInputProperty) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId, arg_service, arg_characteristic, arg_bleInputProperty]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<void> setNotifiable(String deviceId, String service, String characteristic, int bleInputProperty) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId, service, characteristic, bleInputProperty]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<UniversalBleService?>> discoverServices(String arg_deviceId) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<List<UniversalBleService?>> discoverServices(String deviceId) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
} else if (__pigeon_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as List<Object?>?)!.cast<UniversalBleService?>();
|
||||
return (__pigeon_replyList[0] as List<Object?>?)!.cast<UniversalBleService?>();
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> readValue(String arg_deviceId, String arg_service, String arg_characteristic) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId, arg_service, arg_characteristic]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<Uint8List> readValue(String deviceId, String service, String characteristic) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId, service, characteristic]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
} else if (__pigeon_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as Uint8List?)!;
|
||||
return (__pigeon_replyList[0] as Uint8List?)!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<int> requestMtu(String arg_deviceId, int arg_expectedMtu) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId, arg_expectedMtu]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<int> requestMtu(String deviceId, int expectedMtu) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId, expectedMtu]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
} else if (__pigeon_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as int?)!;
|
||||
return (__pigeon_replyList[0] as int?)!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> writeValue(String arg_deviceId, String arg_service, String arg_characteristic, Uint8List arg_value, int arg_bleOutputProperty) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId, arg_service, arg_characteristic, arg_value, arg_bleOutputProperty]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<void> writeValue(String deviceId, String service, String characteristic, Uint8List value, int bleOutputProperty) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId, service, characteristic, value, bleOutputProperty]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> isPaired(String arg_deviceId) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<bool> isPaired(String deviceId) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
} else if (__pigeon_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as bool?)!;
|
||||
return (__pigeon_replyList[0] as bool?)!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> pair(String arg_deviceId) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<void> pair(String deviceId) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> unPair(String arg_deviceId) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_deviceId]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<void> unPair(String deviceId) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[deviceId]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<UniversalBleScanResult?>> getConnectedDevices(List<String?> arg_withServices) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_withServices]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
Future<List<UniversalBleScanResult?>> getConnectedDevices(List<String?> withServices) async {
|
||||
const String __pigeon_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices';
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
__pigeon_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: __pigeon_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? __pigeon_replyList =
|
||||
await __pigeon_channel.send(<Object?>[withServices]) as List<Object?>?;
|
||||
if (__pigeon_replyList == null) {
|
||||
throw _createConnectionError(__pigeon_channelName);
|
||||
} else if (__pigeon_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
code: __pigeon_replyList[0]! as String,
|
||||
message: __pigeon_replyList[1] as String?,
|
||||
details: __pigeon_replyList[2],
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
} else if (__pigeon_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as List<Object?>?)!.cast<UniversalBleScanResult?>();
|
||||
return (__pigeon_replyList[0] as List<Object?>?)!.cast<UniversalBleScanResult?>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -550,7 +558,7 @@ class _UniversalBleCallbackChannelCodec extends StandardMessageCodec {
|
||||
|
||||
/// Native -> Flutter
|
||||
abstract class UniversalBleCallbackChannel {
|
||||
static const MessageCodec<Object?> codec = _UniversalBleCallbackChannelCodec();
|
||||
static const MessageCodec<Object?> pigeonChannelCodec = _UniversalBleCallbackChannelCodec();
|
||||
|
||||
void onAvailabilityChanged(int state);
|
||||
|
||||
@@ -564,13 +572,13 @@ abstract class UniversalBleCallbackChannel {
|
||||
|
||||
static void setup(UniversalBleCallbackChannel? api, {BinaryMessenger? binaryMessenger}) {
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged', codec,
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged', pigeonChannelCodec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
__pigeon_channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
__pigeon_channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
@@ -589,13 +597,13 @@ abstract class UniversalBleCallbackChannel {
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange', codec,
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange', pigeonChannelCodec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
__pigeon_channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
__pigeon_channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
@@ -618,13 +626,13 @@ abstract class UniversalBleCallbackChannel {
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult', codec,
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult', pigeonChannelCodec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
__pigeon_channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
__pigeon_channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
@@ -643,13 +651,13 @@ abstract class UniversalBleCallbackChannel {
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged', codec,
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged', pigeonChannelCodec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
__pigeon_channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
__pigeon_channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
@@ -674,13 +682,13 @@ abstract class UniversalBleCallbackChannel {
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged', codec,
|
||||
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged', pigeonChannelCodec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
__pigeon_channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
__pigeon_channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
|
||||
@@ -12,8 +12,8 @@ import 'package:pigeon/pigeon.dart';
|
||||
kotlinOptions: KotlinOptions(package: 'com.navideck.universal_ble'),
|
||||
swiftOptions: SwiftOptions(),
|
||||
cppOptions: CppOptions(namespace: 'universal_ble'),
|
||||
cppHeaderOut: 'windows/UniversalBle.g.h',
|
||||
cppSourceOut: 'windows/UniversalBle.g.cpp',
|
||||
cppHeaderOut: 'windows/src/generated/universal_ble.g.h',
|
||||
cppSourceOut: 'windows/src/generated/universal_ble.g.cpp',
|
||||
debugGenerators: true,
|
||||
),
|
||||
)
|
||||
|
||||
+2
-4
@@ -12,7 +12,7 @@ platforms:
|
||||
macos:
|
||||
web:
|
||||
windows:
|
||||
|
||||
|
||||
environment:
|
||||
sdk: ">=3.1.3 <4.0.0"
|
||||
flutter: ">=3.3.0"
|
||||
@@ -30,7 +30,7 @@ dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^2.0.0
|
||||
pigeon: ^13.0.0
|
||||
pigeon: ^16.0.5
|
||||
|
||||
flutter:
|
||||
plugin:
|
||||
@@ -46,5 +46,3 @@ flutter:
|
||||
sharedDarwinSource: true
|
||||
windows:
|
||||
pluginClass: UniversalBlePluginCApi
|
||||
|
||||
|
||||
|
||||
+24
-25
@@ -6,7 +6,7 @@ include(FetchContent)
|
||||
set(CPPWINRT_VERSION "2.0.220418.1")
|
||||
set(PLUGIN_NAME "universal_ble_plugin")
|
||||
|
||||
################ NuGet intall begin ################
|
||||
# ############### NuGet intall begin ################
|
||||
FetchContent_Declare(nuget
|
||||
URL "https://dist.nuget.org/win-x86-commandline/v6.0.0/nuget.exe"
|
||||
URL_HASH SHA256=04eb6c4fe4213907e2773e1be1bbbd730e9a655a3c9c58387ce8d4a714a5b9e1
|
||||
@@ -14,31 +14,33 @@ FetchContent_Declare(nuget
|
||||
)
|
||||
|
||||
find_program(NUGET nuget)
|
||||
if (NOT NUGET)
|
||||
message("Nuget.exe not found, trying to download or use cached version.")
|
||||
FetchContent_MakeAvailable(nuget)
|
||||
set(NUGET ${nuget_SOURCE_DIR}/nuget.exe)
|
||||
|
||||
if(NOT NUGET)
|
||||
message("Nuget.exe not found, trying to download or use cached version.")
|
||||
FetchContent_MakeAvailable(nuget)
|
||||
set(NUGET ${nuget_SOURCE_DIR}/nuget.exe)
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND
|
||||
${NUGET} install "Microsoft.Windows.CppWinRT" -Version ${CPPWINRT_VERSION} -OutputDirectory packages
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
RESULT_VARIABLE ret)
|
||||
if (NOT ret EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to install nuget package Microsoft.Windows.CppWinRT.${CPPWINRT_VERSION}")
|
||||
${NUGET} install "Microsoft.Windows.CppWinRT" -Version ${CPPWINRT_VERSION} -OutputDirectory packages
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
RESULT_VARIABLE ret)
|
||||
|
||||
if(NOT ret EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to install nuget package Microsoft.Windows.CppWinRT.${CPPWINRT_VERSION}")
|
||||
endif()
|
||||
|
||||
################ NuGet install end ################
|
||||
|
||||
|
||||
# ############### NuGet install end ################
|
||||
list(APPEND PLUGIN_SOURCES
|
||||
"universal_ble_plugin.cpp"
|
||||
"universal_ble_plugin.h"
|
||||
"universal_enum.h"
|
||||
"Utils.cpp"
|
||||
"Utils.h"
|
||||
"UniversalBle.g.cpp"
|
||||
"UniversalBle.g.h"
|
||||
"src/universal_ble_plugin.cpp"
|
||||
"src/universal_ble_plugin.h"
|
||||
"src/helper/universal_enum.h"
|
||||
"src/helper/universal_ble_base.h"
|
||||
"src/helper/utils.cpp"
|
||||
"src/helper/utils.h"
|
||||
"src/ui_thread_handler.hpp"
|
||||
"src/generated/universal_ble.g.cpp"
|
||||
"src/generated/universal_ble.g.h"
|
||||
)
|
||||
|
||||
add_library(${PLUGIN_NAME} SHARED
|
||||
@@ -47,11 +49,9 @@ add_library(${PLUGIN_NAME} SHARED
|
||||
${PLUGIN_SOURCES}
|
||||
)
|
||||
|
||||
|
||||
apply_standard_settings(${PLUGIN_NAME})
|
||||
|
||||
|
||||
################ NuGet import begin ################
|
||||
# ############### NuGet import begin ################
|
||||
set_target_properties(${PLUGIN_NAME} PROPERTIES VS_PROJECT_IMPORT
|
||||
${CMAKE_BINARY_DIR}/packages/Microsoft.Windows.CppWinRT.${CPPWINRT_VERSION}/build/native/Microsoft.Windows.CppWinRT.props
|
||||
)
|
||||
@@ -59,8 +59,8 @@ set_target_properties(${PLUGIN_NAME} PROPERTIES VS_PROJECT_IMPORT
|
||||
target_link_libraries(${PLUGIN_NAME} PRIVATE
|
||||
${CMAKE_BINARY_DIR}/packages/Microsoft.Windows.CppWinRT.${CPPWINRT_VERSION}/build/native/Microsoft.Windows.CppWinRT.targets
|
||||
)
|
||||
################ NuGet import end ################
|
||||
|
||||
# ############### NuGet import end ################
|
||||
set_target_properties(${PLUGIN_NAME} PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden)
|
||||
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
|
||||
@@ -69,7 +69,6 @@ target_include_directories(${PLUGIN_NAME} INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)
|
||||
|
||||
|
||||
set(universal_ble_bundled_libraries
|
||||
""
|
||||
PARENT_SCOPE
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Autogenerated from Pigeon (v13.0.0), do not edit directly.
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
#undef _HAS_EXCEPTIONS
|
||||
|
||||
#include "UniversalBle.g.h"
|
||||
#include "universal_ble.g.h"
|
||||
|
||||
#include <flutter/basic_message_channel.h>
|
||||
#include <flutter/binary_messenger.h>
|
||||
@@ -21,6 +21,13 @@ using flutter::EncodableList;
|
||||
using flutter::EncodableMap;
|
||||
using flutter::EncodableValue;
|
||||
|
||||
FlutterError CreateConnectionError(const std::string channel_name) {
|
||||
return FlutterError(
|
||||
"channel-error",
|
||||
"Unable to establish connection on channel: '" + channel_name + "'.",
|
||||
EncodableValue(""));
|
||||
}
|
||||
|
||||
// UniversalBleScanResult
|
||||
|
||||
UniversalBleScanResult::UniversalBleScanResult(const std::string& device_id)
|
||||
@@ -811,22 +818,23 @@ void UniversalBleCallbackChannel::OnAvailabilityChanged(
|
||||
int64_t state_arg,
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged", &GetCodec());
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, channel_name, &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
EncodableValue(state_arg),
|
||||
});
|
||||
channel->Send(encoded_api_arguments, [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);
|
||||
if (list_return_value) {
|
||||
if (list_return_value->size() > 1) {
|
||||
on_error(FlutterError( std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
on_error(FlutterError(std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
} else {
|
||||
on_success();
|
||||
}
|
||||
} else {
|
||||
on_error(FlutterError("channel-error", "Unable to establish connection on channel.", EncodableValue("")));
|
||||
on_error(CreateConnectionError(channel_name));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -837,24 +845,25 @@ void UniversalBleCallbackChannel::OnPairStateChange(
|
||||
const std::string* error_arg,
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange", &GetCodec());
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(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, [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);
|
||||
if (list_return_value) {
|
||||
if (list_return_value->size() > 1) {
|
||||
on_error(FlutterError( std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
on_error(FlutterError(std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
} else {
|
||||
on_success();
|
||||
}
|
||||
} else {
|
||||
on_error(FlutterError("channel-error", "Unable to establish connection on channel.", EncodableValue("")));
|
||||
on_error(CreateConnectionError(channel_name));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -863,22 +872,23 @@ void UniversalBleCallbackChannel::OnScanResult(
|
||||
const UniversalBleScanResult& result_arg,
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult", &GetCodec());
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, channel_name, &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
CustomEncodableValue(result_arg),
|
||||
});
|
||||
channel->Send(encoded_api_arguments, [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);
|
||||
if (list_return_value) {
|
||||
if (list_return_value->size() > 1) {
|
||||
on_error(FlutterError( std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
on_error(FlutterError(std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
} else {
|
||||
on_success();
|
||||
}
|
||||
} else {
|
||||
on_error(FlutterError("channel-error", "Unable to establish connection on channel.", EncodableValue("")));
|
||||
on_error(CreateConnectionError(channel_name));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -889,24 +899,25 @@ void UniversalBleCallbackChannel::OnValueChanged(
|
||||
const std::vector<uint8_t>& value_arg,
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged", &GetCodec());
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(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, [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);
|
||||
if (list_return_value) {
|
||||
if (list_return_value->size() > 1) {
|
||||
on_error(FlutterError( std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
on_error(FlutterError(std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
} else {
|
||||
on_success();
|
||||
}
|
||||
} else {
|
||||
on_error(FlutterError("channel-error", "Unable to establish connection on channel.", EncodableValue("")));
|
||||
on_error(CreateConnectionError(channel_name));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -916,23 +927,24 @@ void UniversalBleCallbackChannel::OnConnectionChanged(
|
||||
int64_t state_arg,
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged", &GetCodec());
|
||||
const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged";
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, channel_name, &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
EncodableValue(device_id_arg),
|
||||
EncodableValue(state_arg),
|
||||
});
|
||||
channel->Send(encoded_api_arguments, [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);
|
||||
if (list_return_value) {
|
||||
if (list_return_value->size() > 1) {
|
||||
on_error(FlutterError( std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
on_error(FlutterError(std::get<std::string>(list_return_value->at(0)), std::get<std::string>(list_return_value->at(1)), list_return_value->at(2)));
|
||||
} else {
|
||||
on_success();
|
||||
}
|
||||
} else {
|
||||
on_error(FlutterError("channel-error", "Unable to establish connection on channel.", EncodableValue("")));
|
||||
on_error(CreateConnectionError(channel_name));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Autogenerated from Pigeon (v13.0.0), do not edit directly.
|
||||
// Autogenerated from Pigeon (v16.0.5), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
#ifndef PIGEON_UNIVERSALBLE_G_H_
|
||||
#define PIGEON_UNIVERSALBLE_G_H_
|
||||
#ifndef PIGEON_UNIVERSAL_BLE_G_H_
|
||||
#define PIGEON_UNIVERSAL_BLE_G_H_
|
||||
#include <flutter/basic_message_channel.h>
|
||||
#include <flutter/binary_messenger.h>
|
||||
#include <flutter/encodable_value.h>
|
||||
@@ -308,4 +308,4 @@ class UniversalBleCallbackChannel {
|
||||
};
|
||||
|
||||
} // namespace universal_ble
|
||||
#endif // PIGEON_UNIVERSALBLE_G_H_
|
||||
#endif // PIGEON_UNIVERSAL_BLE_G_H_
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <winrt/Windows.Devices.Bluetooth.h>
|
||||
#include <winrt/Windows.Devices.Bluetooth.Advertisement.h>
|
||||
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
||||
#include <winrt/Windows.Devices.Enumeration.h>
|
||||
#include <winrt/Windows.Devices.Radios.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
|
||||
namespace universal_ble
|
||||
{
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows;
|
||||
using namespace winrt::Windows::Devices;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
using namespace winrt::Windows::Devices::Radios;
|
||||
using namespace winrt::Windows::Devices::Bluetooth;
|
||||
using namespace winrt::Windows::Devices::Bluetooth::Advertisement;
|
||||
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile;
|
||||
using namespace Windows::Devices::Enumeration;
|
||||
}
|
||||
@@ -9,11 +9,10 @@
|
||||
#if WDK_NTDDI_VERSION < NTDDI_WIN10_VB
|
||||
#error "Windows SDK version before 10.0.19041.0 is not supported"
|
||||
#elif WDK_NTDDI_VERSION == NTDDI_WIN10_VB
|
||||
// For Windows SDK version before 10.0.19041.0, remap functions to post-10.0.19041.0 versions
|
||||
#define WINRT_IMPL_CoGetApartmentType WINRT_CoGetApartmentType
|
||||
#endif
|
||||
|
||||
#define MAC_ADDRESS_STR_LENGTH (size_t)17 // Two chars per byte, 5 chars for colon
|
||||
#define MAC_ADDRESS_STR_LENGTH (size_t)17
|
||||
|
||||
namespace universal_ble
|
||||
{
|
||||
@@ -29,7 +28,6 @@ namespace universal_ble
|
||||
|
||||
uint64_t _str_to_mac_address(std::string mac_str)
|
||||
{
|
||||
// TODO: Validate input - Expected Format: XX:XX:XX:XX:XX:XX
|
||||
uint64_t mac_address_number = 0;
|
||||
uint8_t *mac_ptr = (uint8_t *)&mac_address_number;
|
||||
sscanf_s(mac_str.c_str(), "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac_ptr[5], &mac_ptr[4], &mac_ptr[3],
|
||||
@@ -39,7 +37,6 @@ namespace universal_ble
|
||||
|
||||
winrt::guid uuid_to_guid(const std::string &uuid)
|
||||
{
|
||||
// TODO: Add proper cleanup / validation
|
||||
std::stringstream helper;
|
||||
for (int i = 0; i < uuid.length(); i++)
|
||||
{
|
||||
@@ -63,23 +60,18 @@ namespace universal_ble
|
||||
std::string guid_to_uuid(const winrt::guid &guid)
|
||||
{
|
||||
std::stringstream helper;
|
||||
// TODO: It might be cleaner to use snprintf instead of string streams.
|
||||
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
{
|
||||
// * NOTE: We're performing a byte swap!
|
||||
helper << std::hex << std::setw(2) << std::setfill('0') << (int)((uint8_t *)&guid.Data1)[3 - i];
|
||||
}
|
||||
helper << '-';
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
// * NOTE: We're performing a byte swap!
|
||||
helper << std::hex << std::setw(2) << std::setfill('0') << (int)((uint8_t *)&guid.Data2)[1 - i];
|
||||
}
|
||||
helper << '-';
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
{
|
||||
// * NOTE: We're performing a byte swap!
|
||||
helper << std::hex << std::setw(2) << std::setfill('0') << (int)((uint8_t *)&guid.Data3)[1 - i];
|
||||
}
|
||||
helper << '-';
|
||||
@@ -7,10 +7,7 @@
|
||||
#include "winrt/Windows.Foundation.h"
|
||||
#include "winrt/Windows.Storage.Streams.h"
|
||||
#include "winrt/base.h"
|
||||
#include "UniversalBle.g.h"
|
||||
|
||||
using namespace winrt::Windows;
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
#include "universal_ble_base.h"
|
||||
|
||||
constexpr uint32_t TEN_SECONDS_IN_MSECS = 10000;
|
||||
|
||||
@@ -29,34 +26,8 @@ namespace universal_ble
|
||||
|
||||
std::string to_uuidstr(winrt::guid guid);
|
||||
|
||||
/// Structs for passing data between background to ui thread
|
||||
struct ConnectionStateStruct
|
||||
{
|
||||
std::string deviceId;
|
||||
int64_t connectionState;
|
||||
ConnectionStateStruct(std::string deviceId, int64_t connectionState)
|
||||
: deviceId(deviceId), connectionState(connectionState) {}
|
||||
};
|
||||
|
||||
struct PairStateStruct
|
||||
{
|
||||
std::string deviceId;
|
||||
bool isPaired;
|
||||
std::string errorMessage;
|
||||
PairStateStruct(std::string deviceId, bool isPaired, std::string errorMessage)
|
||||
: deviceId(deviceId), isPaired(isPaired), errorMessage(errorMessage) {}
|
||||
};
|
||||
|
||||
struct ValueChangeStruct
|
||||
{
|
||||
std::string deviceId;
|
||||
std::string characteristicId;
|
||||
std::vector<uint8_t> value;
|
||||
ValueChangeStruct(std::string deviceId, std::string characteristicId, std::vector<uint8_t> value)
|
||||
: deviceId(deviceId), characteristicId(characteristicId), value(value) {}
|
||||
};
|
||||
|
||||
/// To call async functions synchronously
|
||||
/// To call async functions synchronously
|
||||
template <typename async_t>
|
||||
static auto async_get(async_t const &async)
|
||||
{
|
||||
@@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <flutter/plugin_registrar_windows.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <mutex>
|
||||
|
||||
class UniversalBleUiThreadHandler
|
||||
{
|
||||
public:
|
||||
explicit UniversalBleUiThreadHandler(flutter::PluginRegistrarWindows *registrar)
|
||||
: registrar_(registrar)
|
||||
{
|
||||
windowProcId_ = registrar_->RegisterTopLevelWindowProcDelegate(
|
||||
[this](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
return HandleWindowMessage(hwnd, message, wparam, lparam);
|
||||
});
|
||||
}
|
||||
|
||||
~UniversalBleUiThreadHandler()
|
||||
{
|
||||
registrar_->UnregisterTopLevelWindowProcDelegate(windowProcId_);
|
||||
}
|
||||
|
||||
UniversalBleUiThreadHandler(const UniversalBleUiThreadHandler &) = delete;
|
||||
UniversalBleUiThreadHandler &operator=(const UniversalBleUiThreadHandler &) = delete;
|
||||
|
||||
void Post(std::function<void()> &&func)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
queuedFuncs_.emplace_back(std::move(func));
|
||||
Notify();
|
||||
}
|
||||
|
||||
private:
|
||||
static const UINT kWmCallQueuedFunctions = WM_APP + 0x1d7;
|
||||
|
||||
void Notify()
|
||||
{
|
||||
if (hwnd_ != 0)
|
||||
{
|
||||
PostMessage(hwnd_, kWmCallQueuedFunctions, 0, reinterpret_cast<LPARAM>(this));
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<LRESULT> HandleWindowMessage(
|
||||
HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (hwnd_ == 0)
|
||||
{
|
||||
hwnd_ = hwnd;
|
||||
Notify(); // Make sure queued functions are processed
|
||||
}
|
||||
if (message == kWmCallQueuedFunctions && lparam == reinterpret_cast<LPARAM>(this))
|
||||
{
|
||||
std::list<std::function<void()>> queuedFuncs;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
std::swap(queuedFuncs_, queuedFuncs);
|
||||
}
|
||||
for (auto &func : queuedFuncs)
|
||||
{
|
||||
func();
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
flutter::PluginRegistrarWindows *registrar_;
|
||||
int windowProcId_ = 0;
|
||||
HWND hwnd_ = 0;
|
||||
std::list<std::function<void()>> queuedFuncs_;
|
||||
std::mutex mutex_;
|
||||
};
|
||||
@@ -9,16 +9,11 @@
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
#include "UniversalBle.g.h"
|
||||
#include "Utils.h"
|
||||
#include "universal_enum.h"
|
||||
#include <regex>
|
||||
|
||||
#define WM_AVAILABILITY_CHANGE WM_USER + 101
|
||||
#define WM_PAIR_CHANGE WM_USER + 102
|
||||
#define WM_SCAN_RESULT WM_USER + 103
|
||||
#define WM_VALUE_CHANGE WM_USER + 104
|
||||
#define WM_CONNECTION_CHANGE WM_USER + 105
|
||||
#include "helper/utils.h"
|
||||
#include "helper/universal_enum.h"
|
||||
#include "generated/universal_ble.g.h"
|
||||
|
||||
namespace universal_ble
|
||||
{
|
||||
@@ -27,8 +22,15 @@ namespace universal_ble
|
||||
using universal_ble::UniversalBlePlatformChannel;
|
||||
using universal_ble::UniversalBleScanResult;
|
||||
|
||||
const auto isConnectableKey = L"System.Devices.Aep.Bluetooth.Le.IsConnectable";
|
||||
const auto isConnectedKey = L"System.Devices.Aep.IsConnected";
|
||||
const auto isPairedKey = L"System.Devices.Aep.IsPaired";
|
||||
const auto isPresentKey = L"System.Devices.Aep.IsPresent";
|
||||
const auto deviceAddressKey = L"System.Devices.Aep.DeviceAddress";
|
||||
const auto signalStrengthKey = L"System.Devices.Aep.SignalStrength";
|
||||
|
||||
std::unique_ptr<UniversalBleCallbackChannel> callbackChannel;
|
||||
std::map<std::string, winrt::event_token> characteristicsTokens{};
|
||||
std::unordered_map<std::string, winrt::event_token> characteristicsTokens{}; // TODO: Remove the map and store the token inside the characteristic object object
|
||||
|
||||
union uint16_t_union
|
||||
{
|
||||
@@ -44,81 +46,14 @@ namespace universal_ble
|
||||
registrar->AddPlugin(std::move(plugin));
|
||||
}
|
||||
|
||||
UniversalBlePlugin::UniversalBlePlugin(flutter::PluginRegistrarWindows *registrar) : registrar_(registrar)
|
||||
UniversalBlePlugin::UniversalBlePlugin(flutter::PluginRegistrarWindows *registrar)
|
||||
: uiThreadHandler_(registrar)
|
||||
{
|
||||
if (window_proc_delegate_id_ == -1)
|
||||
{
|
||||
window_proc_delegate_id_ = registrar_->RegisterTopLevelWindowProcDelegate(
|
||||
std::bind(
|
||||
&UniversalBlePlugin::WindowProcDelegate, this,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3, std::placeholders::_4)
|
||||
|
||||
);
|
||||
}
|
||||
InitializeAsync();
|
||||
}
|
||||
|
||||
UniversalBlePlugin::~UniversalBlePlugin()
|
||||
{
|
||||
if (window_proc_delegate_id_ != -1)
|
||||
{
|
||||
registrar_->UnregisterTopLevelWindowProcDelegate(
|
||||
static_cast<int32_t>(window_proc_delegate_id_));
|
||||
}
|
||||
}
|
||||
|
||||
HWND UniversalBlePlugin::GetWindow()
|
||||
{
|
||||
return ::GetAncestor(registrar_->GetView()->GetNativeWindow(), GA_ROOT);
|
||||
}
|
||||
|
||||
/// Background Messages Handler
|
||||
std::optional<LRESULT> UniversalBlePlugin::WindowProcDelegate(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_SCAN_RESULT:
|
||||
{
|
||||
UniversalBleScanResult *scanResult = reinterpret_cast<UniversalBleScanResult *>(wp);
|
||||
callbackChannel->OnScanResult(*scanResult, SuccessCallback, ErrorCallback);
|
||||
delete scanResult;
|
||||
return 0;
|
||||
}
|
||||
case WM_AVAILABILITY_CHANGE:
|
||||
{
|
||||
callbackChannel->OnAvailabilityChanged(static_cast<int>(wp), SuccessCallback, ErrorCallback);
|
||||
return 0;
|
||||
}
|
||||
case WM_CONNECTION_CHANGE:
|
||||
{
|
||||
ConnectionStateStruct *connectionStateStruct = reinterpret_cast<ConnectionStateStruct *>(wp);
|
||||
callbackChannel->OnConnectionChanged(connectionStateStruct->deviceId, connectionStateStruct->connectionState, SuccessCallback, ErrorCallback);
|
||||
delete connectionStateStruct;
|
||||
return 0;
|
||||
}
|
||||
case WM_VALUE_CHANGE:
|
||||
{
|
||||
ValueChangeStruct *valueChangeStruct = reinterpret_cast<ValueChangeStruct *>(wp);
|
||||
callbackChannel->OnValueChanged(valueChangeStruct->deviceId, valueChangeStruct->characteristicId, valueChangeStruct->value, SuccessCallback, ErrorCallback);
|
||||
delete valueChangeStruct;
|
||||
return 0;
|
||||
}
|
||||
case WM_PAIR_CHANGE:
|
||||
{
|
||||
PairStateStruct *pairStateStruct = reinterpret_cast<PairStateStruct *>(wp);
|
||||
callbackChannel->OnPairStateChange(pairStateStruct->deviceId, pairStateStruct->isPaired, &pairStateStruct->errorMessage, SuccessCallback, ErrorCallback);
|
||||
delete pairStateStruct;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void UniversalBlePlugin::PostConnectionUpdate(uint64_t bluetoothAddress, ConnectionState connectionState)
|
||||
{
|
||||
ConnectionStateStruct *connectionStateStruct = new ConnectionStateStruct(_mac_address_to_str(bluetoothAddress), static_cast<int>(connectionState));
|
||||
::PostMessage(GetWindow(), WM_CONNECTION_CHANGE, reinterpret_cast<WPARAM>(connectionStateStruct), 0);
|
||||
}
|
||||
|
||||
// UniversalBlePlatformChannel implementation.
|
||||
@@ -163,9 +98,16 @@ namespace universal_ble
|
||||
if (!bluetoothLEWatcher)
|
||||
{
|
||||
bluetoothLEWatcher = BluetoothLEAdvertisementWatcher();
|
||||
bluetoothLEWatcher.ScanningMode(BluetoothLEScanningMode::Active);
|
||||
bluetoothLEWatcherReceivedToken = bluetoothLEWatcher.Received({this, &UniversalBlePlugin::BluetoothLEWatcher_Received});
|
||||
}
|
||||
bluetoothLEWatcher.Start();
|
||||
setupDeviceWatcher();
|
||||
DeviceWatcherStatus status = deviceWatcher.Status();
|
||||
if (status != DeviceWatcherStatus::Started)
|
||||
deviceWatcher.Start();
|
||||
else
|
||||
return FlutterError("Already scanning");
|
||||
return std::nullopt;
|
||||
}
|
||||
else
|
||||
@@ -176,6 +118,7 @@ namespace universal_ble
|
||||
|
||||
std::optional<FlutterError> UniversalBlePlugin::StopScan()
|
||||
{
|
||||
|
||||
if (bluetoothRadio && bluetoothRadio.State() == RadioState::On)
|
||||
{
|
||||
if (bluetoothLEWatcher)
|
||||
@@ -184,6 +127,7 @@ namespace universal_ble
|
||||
bluetoothLEWatcher.Received(bluetoothLEWatcherReceivedToken);
|
||||
}
|
||||
bluetoothLEWatcher = nullptr;
|
||||
disposeDeviceWatcher();
|
||||
return std::nullopt;
|
||||
}
|
||||
else
|
||||
@@ -194,12 +138,6 @@ namespace universal_ble
|
||||
|
||||
std::optional<FlutterError> UniversalBlePlugin::Connect(const std::string &device_id)
|
||||
{
|
||||
auto isConnectable = deviceConnectableStatus[_str_to_mac_address(device_id)];
|
||||
if (isConnectable == false)
|
||||
{
|
||||
return FlutterError("Device is not connectable");
|
||||
}
|
||||
|
||||
ConnectAsync(_str_to_mac_address(device_id));
|
||||
return std::nullopt;
|
||||
};
|
||||
@@ -208,7 +146,10 @@ namespace universal_ble
|
||||
{
|
||||
auto deviceAddress = _str_to_mac_address(device_id);
|
||||
CleanConnection(deviceAddress);
|
||||
PostConnectionUpdate(deviceAddress, ConnectionState::disconnected);
|
||||
// TODO: send disconnect event only after disconnect is complete
|
||||
uiThreadHandler_.Post([deviceAddress]
|
||||
{ callbackChannel->OnConnectionChanged(_mac_address_to_str(deviceAddress), static_cast<int>(ConnectionState::disconnected), SuccessCallback, ErrorCallback); });
|
||||
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
@@ -233,6 +174,7 @@ namespace universal_ble
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "DiscoverServicesLog: Unknown error" << std::endl;
|
||||
return result(FlutterError("Unknown error"));
|
||||
}
|
||||
}
|
||||
@@ -249,7 +191,7 @@ namespace universal_ble
|
||||
if (it == connectedDevices.end())
|
||||
return FlutterError("IllegalArgument", "Unknown devicesId:" + device_id);
|
||||
auto bluetoothAgent = *it->second;
|
||||
gatt_characteristic_t &gatt_characteristic_holder = bluetoothAgent._fetch_characteristic(service, characteristic);
|
||||
GattCharacteristicObject &gatt_characteristic_holder = bluetoothAgent._fetch_characteristic(service, characteristic);
|
||||
GattCharacteristic gattCharacteristic = gatt_characteristic_holder.obj;
|
||||
auto descriptorValue = GattClientCharacteristicConfigurationDescriptorValue::None;
|
||||
auto properties = gattCharacteristic.CharacteristicProperties();
|
||||
@@ -280,6 +222,7 @@ namespace universal_ble
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "SetNotifiableLog: Unknown error" << std::endl;
|
||||
return FlutterError("Unknown error");
|
||||
}
|
||||
};
|
||||
@@ -299,7 +242,7 @@ namespace universal_ble
|
||||
return;
|
||||
}
|
||||
auto bluetoothAgent = *it->second;
|
||||
gatt_characteristic_t &gatt_characteristic_holder = bluetoothAgent._fetch_characteristic(service, characteristic);
|
||||
GattCharacteristicObject &gatt_characteristic_holder = bluetoothAgent._fetch_characteristic(service, characteristic);
|
||||
GattCharacteristic gattCharacteristic = gatt_characteristic_holder.obj;
|
||||
auto properties = gattCharacteristic.CharacteristicProperties();
|
||||
if ((properties & GattCharacteristicProperties::Read) == GattCharacteristicProperties::None)
|
||||
@@ -336,6 +279,7 @@ namespace universal_ble
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "ReadValueLog: Unknown error" << std::endl;
|
||||
return result(FlutterError("Unknown error"));
|
||||
}
|
||||
}
|
||||
@@ -357,7 +301,7 @@ namespace universal_ble
|
||||
return;
|
||||
}
|
||||
auto bluetoothAgent = *it->second;
|
||||
gatt_characteristic_t &gatt_characteristic_holder = bluetoothAgent._fetch_characteristic(service, characteristic);
|
||||
GattCharacteristicObject &gatt_characteristic_holder = bluetoothAgent._fetch_characteristic(service, characteristic);
|
||||
GattCharacteristic gattCharacteristic = gatt_characteristic_holder.obj;
|
||||
auto properties = gattCharacteristic.CharacteristicProperties();
|
||||
auto writeOption = GattWriteOption::WriteWithResponse;
|
||||
@@ -407,6 +351,7 @@ namespace universal_ble
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "WriteValue: Unknown error" << std::endl;
|
||||
result(FlutterError("Unknown error"));
|
||||
}
|
||||
}
|
||||
@@ -449,13 +394,14 @@ namespace universal_ble
|
||||
try
|
||||
{
|
||||
auto device = async_get(BluetoothLEDevice::FromBluetoothAddressAsync(_str_to_mac_address(device_id)));
|
||||
std::cout << "PairLog: Device to be paired was found" << std::endl;
|
||||
auto deviceInformation = device.DeviceInformation();
|
||||
bool isPaired = deviceInformation.Pairing().IsPaired();
|
||||
if (isPaired)
|
||||
return FlutterError("Device is already paired");
|
||||
return FlutterError("PairLog: Device is already paired");
|
||||
bool canPair = deviceInformation.Pairing().CanPair();
|
||||
if (!canPair)
|
||||
return FlutterError("Device is not pairable");
|
||||
return FlutterError("PairLog: Device is not pairable");
|
||||
|
||||
auto customPairing = deviceInformation.Pairing().Custom();
|
||||
winrt::event_token token = customPairing.PairingRequested([this](const Enumeration::DeviceInformationCustomPairing &sender, const Enumeration::DevicePairingRequestedEventArgs &eventArgs)
|
||||
@@ -466,18 +412,21 @@ namespace universal_ble
|
||||
eventArgs.Accept(); });
|
||||
// DevicePairingKinds => None, ConfirmOnly, DisplayPin, ProvidePin, ConfirmPinMatch, ProvidePasswordCredential
|
||||
// DevicePairingProtectionLevel => Default, None, Encryption, EncryptionAndAuthentication
|
||||
std::cout << "PairLog: Trying to pair" << std::endl;
|
||||
auto async_c = customPairing.PairAsync(
|
||||
Enumeration::DevicePairingKinds::ConfirmOnly,
|
||||
Enumeration::DevicePairingProtectionLevel::None);
|
||||
async_c.Completed([this, customPairing, token, device_id](IAsyncOperation<DevicePairingResult> const &sender, AsyncStatus const args)
|
||||
{
|
||||
auto result = sender.GetResults();
|
||||
std::cout << "PairLog: Received pairing status" << std::endl;
|
||||
customPairing.PairingRequested(token);
|
||||
auto isPaired = result.Status() == Enumeration::DevicePairingResultStatus::Paired;
|
||||
// Post to main thread
|
||||
PairStateStruct *pairStateStruct = new PairStateStruct(device_id, isPaired, parsePairingFailError(result));
|
||||
::PostMessage(GetWindow(), WM_PAIR_CHANGE, reinterpret_cast<WPARAM>(pairStateStruct), 0); });
|
||||
|
||||
// Post to main thread
|
||||
std::string errorStr = parsePairingFailError(result);
|
||||
uiThreadHandler_.Post([device_id, isPaired, errorStr]
|
||||
{ callbackChannel->OnPairStateChange(device_id, isPaired, &errorStr, SuccessCallback, ErrorCallback); }); });
|
||||
return std::nullopt;
|
||||
}
|
||||
catch (const FlutterError &err)
|
||||
@@ -528,6 +477,31 @@ namespace universal_ble
|
||||
}
|
||||
|
||||
/// Helper Methods
|
||||
|
||||
std::vector<uint8_t> parseManufacturerDataHead(BluetoothLEAdvertisement advertisement, std::string deviceId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (advertisement.ManufacturerData().Size() == 0)
|
||||
{
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
auto manufacturerData = advertisement.ManufacturerData().GetAt(0);
|
||||
// FIXME Compat with REG_DWORD_BIG_ENDIAN
|
||||
uint8_t *prefix = uint16_t_union{manufacturerData.CompanyId()}.bytes;
|
||||
auto result = std::vector<uint8_t>{prefix, prefix + sizeof(uint16_t_union)};
|
||||
|
||||
auto data = to_bytevc(manufacturerData.Data());
|
||||
result.insert(result.end(), data.begin(), data.end());
|
||||
return result;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "Error in parsing manufacturer data: " << deviceId << std::endl;
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
}
|
||||
|
||||
winrt::fire_and_forget UniversalBlePlugin::InitializeAsync()
|
||||
{
|
||||
auto bluetoothAdapter = co_await BluetoothAdapter::GetDefaultAsync();
|
||||
@@ -538,6 +512,209 @@ namespace universal_ble
|
||||
}
|
||||
}
|
||||
|
||||
// Send device to callback channel
|
||||
// if device is already discovered in deviceWatcher then merge the scan result
|
||||
void UniversalBlePlugin::pushUniversalScanResult(UniversalBleScanResult scanResult)
|
||||
{
|
||||
auto it = scanResults.find(scanResult.device_id());
|
||||
if (it != scanResults.end())
|
||||
{
|
||||
UniversalBleScanResult &existingScanResult = it->second;
|
||||
bool shouldUpdate = false;
|
||||
if ((scanResult.name() == nullptr || scanResult.name()->empty()) && (existingScanResult.name() != nullptr && !existingScanResult.name()->empty()))
|
||||
{
|
||||
scanResult.set_name(*existingScanResult.name());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if (scanResult.is_paired() == nullptr && existingScanResult.is_paired() != nullptr)
|
||||
{
|
||||
scanResult.set_is_paired(existingScanResult.is_paired());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if (scanResult.manufacturer_data_head() == nullptr && existingScanResult.manufacturer_data_head() != nullptr)
|
||||
{
|
||||
scanResult.set_manufacturer_data_head(existingScanResult.manufacturer_data_head());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
|
||||
// if nothing to update then return
|
||||
if (!shouldUpdate)
|
||||
return;
|
||||
|
||||
// update the existing scan result
|
||||
existingScanResult = scanResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not present, insert the new scan result
|
||||
scanResults.insert(std::make_pair(scanResult.device_id(), scanResult));
|
||||
}
|
||||
|
||||
uiThreadHandler_.Post([scanResult]
|
||||
{ callbackChannel->OnScanResult(scanResult, SuccessCallback, ErrorCallback); });
|
||||
}
|
||||
|
||||
void UniversalBlePlugin::setupDeviceWatcher()
|
||||
{
|
||||
if (deviceWatcher != nullptr)
|
||||
return;
|
||||
|
||||
deviceWatcher = DeviceInformation::CreateWatcher(
|
||||
L"(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")",
|
||||
{
|
||||
deviceAddressKey,
|
||||
isConnectedKey,
|
||||
isPairedKey,
|
||||
isPresentKey,
|
||||
isConnectableKey,
|
||||
signalStrengthKey,
|
||||
},
|
||||
DeviceInformationKind::AssociationEndpoint);
|
||||
|
||||
/// Device Added from DeviceWatcher
|
||||
deviceWatcherAddedToken = deviceWatcher.Added([this](DeviceWatcher sender, DeviceInformation deviceInfo)
|
||||
{
|
||||
std::string deviceId = winrt::to_string(deviceInfo.Id());
|
||||
deviceWatcherDevices.insert_or_assign(deviceId, deviceInfo);
|
||||
onDeviceInfoReceived(deviceInfo);
|
||||
// On Device Added
|
||||
});
|
||||
|
||||
// Update only if device is already discovered in deviceWatcher.Added
|
||||
deviceWatcherUpdatedToken = deviceWatcher.Updated([this](DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
|
||||
{
|
||||
std::string deviceId = winrt::to_string(deviceInfoUpdate.Id());
|
||||
auto it = deviceWatcherDevices.find(deviceId);
|
||||
if (it != deviceWatcherDevices.end())
|
||||
{
|
||||
it->second.Update(deviceInfoUpdate);
|
||||
onDeviceInfoReceived(it->second);
|
||||
}
|
||||
// On Device Updated
|
||||
});
|
||||
|
||||
deviceWatcherRemovedToken = deviceWatcher.Removed([this](DeviceWatcher sender, DeviceInformationUpdate args)
|
||||
{
|
||||
std::string deviceId = winrt::to_string(args.Id());
|
||||
deviceWatcherDevices.erase(deviceId);
|
||||
// On Device Removed
|
||||
});
|
||||
}
|
||||
|
||||
void UniversalBlePlugin::disposeDeviceWatcher()
|
||||
{
|
||||
if (deviceWatcher != nullptr)
|
||||
{
|
||||
if (deviceWatcher.Status() == DeviceWatcherStatus::Started)
|
||||
deviceWatcher.Stop();
|
||||
deviceWatcher.Added(deviceWatcherAddedToken);
|
||||
deviceWatcher.Updated(deviceWatcherUpdatedToken);
|
||||
deviceWatcher.Removed(deviceWatcherRemovedToken);
|
||||
deviceWatcher = nullptr;
|
||||
// Dispose tokens
|
||||
deviceWatcherDevices.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void UniversalBlePlugin::onDeviceInfoReceived(DeviceInformation deviceInfo)
|
||||
{
|
||||
auto properties = deviceInfo.Properties();
|
||||
|
||||
// Avoid devices if not connectable or if deviceAddressKey is not present
|
||||
if (!(properties.HasKey(isConnectableKey) && (properties.Lookup(isConnectableKey).as<IPropertyValue>()).GetBoolean()) || !properties.HasKey(deviceAddressKey))
|
||||
return;
|
||||
|
||||
auto bluetoothAddressPropertyValue = properties.Lookup(deviceAddressKey).as<IPropertyValue>();
|
||||
std::string deviceAddress = winrt::to_string(bluetoothAddressPropertyValue.GetString());
|
||||
|
||||
// Update device info if already discovered in advertisementWatcher
|
||||
if (scanResults.count(deviceAddress) > 0)
|
||||
{
|
||||
bool isPaired = deviceInfo.Pairing().IsPaired();
|
||||
if (properties.HasKey(isPairedKey))
|
||||
{
|
||||
auto isPairedPropertyValue = properties.Lookup(isPairedKey).as<IPropertyValue>();
|
||||
isPaired = isPairedPropertyValue.GetBoolean();
|
||||
}
|
||||
|
||||
UniversalBleScanResult universalScanResult(deviceAddress);
|
||||
universalScanResult.set_is_paired(isPaired);
|
||||
|
||||
if (!deviceInfo.Name().empty())
|
||||
universalScanResult.set_name(winrt::to_string(deviceInfo.Name()));
|
||||
|
||||
if (properties.HasKey(signalStrengthKey))
|
||||
{
|
||||
auto rssiPropertyValue = properties.Lookup(signalStrengthKey).as<IPropertyValue>();
|
||||
int16_t rssi = rssiPropertyValue.GetInt16();
|
||||
universalScanResult.set_rssi(rssi);
|
||||
}
|
||||
pushUniversalScanResult(universalScanResult);
|
||||
}
|
||||
}
|
||||
|
||||
/// Advertisement received from advertisementWatcher
|
||||
void UniversalBlePlugin::BluetoothLEWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Avoid devices if they are not connectable
|
||||
if (!args.IsConnectable())
|
||||
return;
|
||||
|
||||
auto deviceId = _mac_address_to_str(args.BluetoothAddress());
|
||||
auto universalScanResult = UniversalBleScanResult(deviceId);
|
||||
std::string name = winrt::to_string(args.Advertisement().LocalName());
|
||||
|
||||
// Use CompleteName from dataType if localName is empty
|
||||
if (name.empty())
|
||||
{
|
||||
auto dataSection = args.Advertisement().DataSections();
|
||||
for (auto &&data : dataSection)
|
||||
{
|
||||
auto dataBytes = to_bytevc(data.Data());
|
||||
if (data.DataType() == 0x09)
|
||||
{
|
||||
name = std::string(dataBytes.begin(), dataBytes.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!name.empty())
|
||||
universalScanResult.set_name(name);
|
||||
|
||||
auto manufacturerData = parseManufacturerDataHead(args.Advertisement(), deviceId);
|
||||
universalScanResult.set_manufacturer_data_head(manufacturerData);
|
||||
universalScanResult.set_rssi(args.RawSignalStrengthInDBm());
|
||||
|
||||
// check if this device already discovered in deviceWatcher
|
||||
auto it = deviceWatcherDevices.find(deviceId);
|
||||
if (it != deviceWatcherDevices.end())
|
||||
{
|
||||
auto &deviceInfo = it->second;
|
||||
auto properties = deviceInfo.Properties();
|
||||
|
||||
// Update Paired Status
|
||||
bool isPaired = deviceInfo.Pairing().IsPaired();
|
||||
if (properties.HasKey(isPairedKey))
|
||||
isPaired = (properties.Lookup(isPairedKey).as<IPropertyValue>()).GetBoolean();
|
||||
universalScanResult.set_is_paired(isPaired);
|
||||
|
||||
// Update Name
|
||||
if (name.empty() && !deviceInfo.Name().empty())
|
||||
universalScanResult.set_name(winrt::to_string(deviceInfo.Name()));
|
||||
}
|
||||
|
||||
// Cache connectable status
|
||||
pushUniversalScanResult(universalScanResult);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "ScanResultErrorInParsing" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
AvailabilityState UniversalBlePlugin::getAvailabilityStateFromRadio(RadioState radioState)
|
||||
{
|
||||
auto state = [=]() -> AvailabilityState
|
||||
@@ -575,56 +752,12 @@ namespace universal_ble
|
||||
}
|
||||
oldRadioState = radioState;
|
||||
auto state = getAvailabilityStateFromRadio(radioState);
|
||||
::PostMessage(GetWindow(), WM_AVAILABILITY_CHANGE, static_cast<int>(state), 0);
|
||||
|
||||
uiThreadHandler_.Post([state]
|
||||
{ callbackChannel->OnAvailabilityChanged(static_cast<int>(state), SuccessCallback, ErrorCallback); });
|
||||
}
|
||||
|
||||
std::vector<uint8_t> parseManufacturerDataHead(BluetoothLEAdvertisement advertisement, std::string deviceId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (advertisement.ManufacturerData().Size() == 0)
|
||||
{
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
auto manufacturerData = advertisement.ManufacturerData().GetAt(0);
|
||||
// FIXME Compat with REG_DWORD_BIG_ENDIAN
|
||||
uint8_t *prefix = uint16_t_union{manufacturerData.CompanyId()}.bytes;
|
||||
auto result = std::vector<uint8_t>{prefix, prefix + sizeof(uint16_t_union)};
|
||||
|
||||
auto data = to_bytevc(manufacturerData.Data());
|
||||
result.insert(result.end(), data.begin(), data.end());
|
||||
return result;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "Error in parsing manufacturer data: " << deviceId << std::endl;
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
}
|
||||
|
||||
void UniversalBlePlugin::BluetoothLEWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto deviceId = _mac_address_to_str(args.BluetoothAddress());
|
||||
auto universalScanResult = new UniversalBleScanResult(deviceId);
|
||||
hstring localName = args.Advertisement().LocalName();
|
||||
if (!localName.empty())
|
||||
universalScanResult->set_name(winrt::to_string(localName));
|
||||
|
||||
universalScanResult->set_manufacturer_data_head(parseManufacturerDataHead(args.Advertisement(), deviceId));
|
||||
universalScanResult->set_rssi(args.RawSignalStrengthInDBm());
|
||||
// Cache connectable status
|
||||
deviceConnectableStatus[_str_to_mac_address(deviceId)] = args.IsConnectable();
|
||||
::PostMessage(GetWindow(), WM_SCAN_RESULT, reinterpret_cast<WPARAM>(universalScanResult), 0);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "ScanResultErrorInParsing" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GattCommunicationStatusToString(GattCommunicationStatus status)
|
||||
std::string UniversalBlePlugin::GattCommunicationStatusToString(GattCommunicationStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
@@ -643,19 +776,32 @@ namespace universal_ble
|
||||
|
||||
winrt::fire_and_forget UniversalBlePlugin::ConnectAsync(uint64_t bluetoothAddress)
|
||||
{
|
||||
auto device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(bluetoothAddress);
|
||||
auto servicesResult = co_await device.GetGattServicesAsync((BluetoothCacheMode::Uncached));
|
||||
if (servicesResult.Status() != GattCommunicationStatus::Success)
|
||||
BluetoothLEDevice device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(bluetoothAddress);
|
||||
std::cout << "ConnectionLog: Device found" << std::endl;
|
||||
if (!device)
|
||||
{
|
||||
PostConnectionUpdate(bluetoothAddress, ConnectionState::disconnected);
|
||||
std::cout << "ConnectionLog: ConnectionFailed: Failed to get device" << std::endl;
|
||||
uiThreadHandler_.Post([bluetoothAddress]
|
||||
{ callbackChannel->OnConnectionChanged(_mac_address_to_str(bluetoothAddress), static_cast<int>(ConnectionState::disconnected), SuccessCallback, ErrorCallback); });
|
||||
|
||||
co_return;
|
||||
}
|
||||
auto servicesResult = co_await device.GetGattServicesAsync((BluetoothCacheMode::Uncached));
|
||||
auto status = servicesResult.Status();
|
||||
if (status != GattCommunicationStatus::Success)
|
||||
{
|
||||
std::cout << "ConnectionFailed: Failed to get services: " << GattCommunicationStatusToString(status) << std::endl;
|
||||
uiThreadHandler_.Post([bluetoothAddress]
|
||||
{ callbackChannel->OnConnectionChanged(_mac_address_to_str(bluetoothAddress), static_cast<int>(ConnectionState::disconnected), SuccessCallback, ErrorCallback); });
|
||||
|
||||
std::map<std::string, gatt_service_t> gatt_map_;
|
||||
co_return;
|
||||
}
|
||||
std::cout << "ConnectionLog: Services discovered" << std::endl;
|
||||
std::unordered_map<std::string, GattServiceObject> gatt_map_;
|
||||
auto gatt_services = servicesResult.Services();
|
||||
for (GattDeviceService &&service : gatt_services)
|
||||
{
|
||||
gatt_service_t gatt_service;
|
||||
GattServiceObject gatt_service;
|
||||
gatt_service.obj = service;
|
||||
std::string service_uuid = guid_to_uuid(service.Uuid());
|
||||
auto characteristics_result = co_await service.GetCharacteristicsAsync(BluetoothCacheMode::Uncached);
|
||||
@@ -669,19 +815,21 @@ namespace universal_ble
|
||||
auto gatt_characteristics = characteristics_result.Characteristics();
|
||||
for (GattCharacteristic &&characteristic : gatt_characteristics)
|
||||
{
|
||||
gatt_characteristic_t gatt_characteristic;
|
||||
GattCharacteristicObject gatt_characteristic;
|
||||
gatt_characteristic.obj = characteristic;
|
||||
std::string characteristic_uuid = guid_to_uuid(characteristic.Uuid());
|
||||
gatt_service.characteristics.emplace(characteristic_uuid, std::move(gatt_characteristic));
|
||||
gatt_service.characteristics.insert_or_assign(characteristic_uuid, std::move(gatt_characteristic));
|
||||
}
|
||||
gatt_map_.emplace(service_uuid, std::move(gatt_service));
|
||||
gatt_map_.insert_or_assign(service_uuid, std::move(gatt_service));
|
||||
}
|
||||
|
||||
auto connnectionStatusChangedToken = device.ConnectionStatusChanged({this, &UniversalBlePlugin::BluetoothLEDevice_ConnectionStatusChanged});
|
||||
winrt::event_token connnectionStatusChangedToken = device.ConnectionStatusChanged({this, &UniversalBlePlugin::BluetoothLEDevice_ConnectionStatusChanged});
|
||||
auto deviceAgent = std::make_unique<BluetoothDeviceAgent>(device, connnectionStatusChangedToken, gatt_map_);
|
||||
auto pair = std::make_pair(bluetoothAddress, std::move(deviceAgent));
|
||||
connectedDevices.insert(std::move(pair));
|
||||
PostConnectionUpdate(bluetoothAddress, ConnectionState::connected);
|
||||
std::cout << "ConnectionLog: Connected" << std::endl;
|
||||
uiThreadHandler_.Post([bluetoothAddress]
|
||||
{ callbackChannel->OnConnectionChanged(_mac_address_to_str(bluetoothAddress), static_cast<int>(ConnectionState::connected), SuccessCallback, ErrorCallback); });
|
||||
}
|
||||
|
||||
void UniversalBlePlugin::BluetoothLEDevice_ConnectionStatusChanged(BluetoothLEDevice sender, IInspectable args)
|
||||
@@ -689,7 +837,9 @@ namespace universal_ble
|
||||
if (sender.ConnectionStatus() == BluetoothConnectionStatus::Disconnected)
|
||||
{
|
||||
CleanConnection(sender.BluetoothAddress());
|
||||
PostConnectionUpdate(sender.BluetoothAddress(), ConnectionState::disconnected);
|
||||
auto bluetoothAddress = sender.BluetoothAddress();
|
||||
uiThreadHandler_.Post([bluetoothAddress]
|
||||
{ callbackChannel->OnConnectionChanged(_mac_address_to_str(bluetoothAddress), static_cast<int>(ConnectionState::disconnected), SuccessCallback, ErrorCallback); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,9 +856,11 @@ namespace universal_ble
|
||||
auto &service = servicePair.second;
|
||||
for (auto &characteristicPair : service.characteristics)
|
||||
{
|
||||
gatt_characteristic_t &characteristic = characteristicPair.second;
|
||||
GattCharacteristicObject &characteristic = characteristicPair.second;
|
||||
auto gattCharacteristic = characteristic.obj;
|
||||
auto uniqTokenKey = to_uuidstr(gattCharacteristic.Uuid()) + _mac_address_to_str(gattCharacteristic.Service().Device().BluetoothAddress());
|
||||
std::stringstream uniqTokenKeyStream;
|
||||
uniqTokenKeyStream << to_uuidstr(gattCharacteristic.Uuid()) << _mac_address_to_str(gattCharacteristic.Service().Device().BluetoothAddress());
|
||||
std::string uniqTokenKey = uniqTokenKeyStream.str();
|
||||
if (characteristicsTokens.count(uniqTokenKey) != 0)
|
||||
{
|
||||
characteristic.obj.ValueChanged(characteristicsTokens[uniqTokenKey]);
|
||||
@@ -758,12 +910,13 @@ namespace universal_ble
|
||||
universalScanResult.set_name(winrt::to_string(deviceInfo.Name()));
|
||||
universalScanResult.set_is_paired(deviceInfo.Pairing().IsPaired());
|
||||
results.push_back(flutter::CustomEncodableValue(universalScanResult));
|
||||
deviceConnectableStatus[_str_to_mac_address(deviceId)] = true;
|
||||
// deviceConnectableStatus[_str_to_mac_address(deviceId)] = true;
|
||||
}
|
||||
result(results);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "Unknown error GetConnectedDevicesAsync" << std::endl;
|
||||
result(FlutterError("Unknown error"));
|
||||
}
|
||||
}
|
||||
@@ -840,7 +993,7 @@ namespace universal_ble
|
||||
catch (...)
|
||||
{
|
||||
result(FlutterError("DiscoverServiceError: Unknown error"));
|
||||
std::cerr << "DiscoverServiceError: Unknown error" << '\n';
|
||||
std::cout << "DiscoverServiceError: Unknown error" << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -864,7 +1017,7 @@ namespace universal_ble
|
||||
winrt::fire_and_forget UniversalBlePlugin::SetNotifiableAsync(BluetoothDeviceAgent &bluetoothDeviceAgent, const std::string &service,
|
||||
const std::string &characteristic, GattClientCharacteristicConfigurationDescriptorValue descriptorValue)
|
||||
{
|
||||
gatt_characteristic_t &gatt_characteristic_holder = bluetoothDeviceAgent._fetch_characteristic(service, characteristic);
|
||||
GattCharacteristicObject &gatt_characteristic_holder = bluetoothDeviceAgent._fetch_characteristic(service, characteristic);
|
||||
GattCharacteristic gattCharacteristic = gatt_characteristic_holder.obj;
|
||||
|
||||
auto uuid = to_uuidstr(gattCharacteristic.Uuid());
|
||||
@@ -898,7 +1051,9 @@ namespace universal_ble
|
||||
}
|
||||
// create uniqKey with uuid and deviceId
|
||||
// TODO: store token key in gatt_characteristic_t struct instead of using map
|
||||
auto uniqTokenKey = uuid + _mac_address_to_str(gattCharacteristic.Service().Device().BluetoothAddress());
|
||||
std::stringstream uniqTokenKeyStream;
|
||||
uniqTokenKeyStream << uuid << _mac_address_to_str(gattCharacteristic.Service().Device().BluetoothAddress());
|
||||
auto uniqTokenKey = uniqTokenKeyStream.str();
|
||||
|
||||
// Register/UnRegister handler for the ValueChanged event.
|
||||
if (descriptorValue == GattClientCharacteristicConfigurationDescriptorValue::None)
|
||||
@@ -927,8 +1082,8 @@ namespace universal_ble
|
||||
{
|
||||
auto uuid = to_uuidstr(sender.Uuid());
|
||||
auto bytes = to_bytevc(args.CharacteristicValue());
|
||||
ValueChangeStruct *valueChangeStruct = new ValueChangeStruct(_mac_address_to_str(sender.Service().Device().BluetoothAddress()), uuid, bytes);
|
||||
::PostMessage(GetWindow(), WM_VALUE_CHANGE, reinterpret_cast<WPARAM>(valueChangeStruct), 0);
|
||||
uiThreadHandler_.Post([sender, uuid, bytes]
|
||||
{ callbackChannel->OnValueChanged(_mac_address_to_str(sender.Service().Device().BluetoothAddress()), uuid, bytes, SuccessCallback, ErrorCallback); });
|
||||
}
|
||||
|
||||
std::string UniversalBlePlugin::parsePairingFailError(Enumeration::DevicePairingResult result)
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <flutter/plugin_registrar_windows.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <winrt/base.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
@@ -15,42 +16,32 @@
|
||||
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
|
||||
|
||||
#include <memory>
|
||||
#include "Utils.h"
|
||||
#include "UniversalBle.g.h"
|
||||
#include "universal_enum.h"
|
||||
#include "helper/utils.h"
|
||||
#include "helper/universal_enum.h"
|
||||
#include "helper/universal_ble_base.h"
|
||||
#include "generated/universal_ble.g.h"
|
||||
#include "ui_thread_handler.hpp"
|
||||
|
||||
namespace universal_ble
|
||||
{
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::Devices;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
using namespace winrt::Windows::Devices::Radios;
|
||||
using namespace winrt::Windows::Devices::Bluetooth;
|
||||
using namespace winrt::Windows::Devices::Bluetooth::Advertisement;
|
||||
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile;
|
||||
using namespace Windows::Devices::Enumeration;
|
||||
|
||||
struct gatt_characteristic_t
|
||||
struct GattCharacteristicObject
|
||||
{
|
||||
GattCharacteristic obj = nullptr;
|
||||
// winrt::event_token value_changed_token;
|
||||
};
|
||||
|
||||
struct gatt_service_t
|
||||
struct GattServiceObject
|
||||
{
|
||||
GattDeviceService obj = nullptr;
|
||||
std::map<std::string, gatt_characteristic_t> characteristics;
|
||||
std::unordered_map<std::string, GattCharacteristicObject> characteristics;
|
||||
};
|
||||
|
||||
struct BluetoothDeviceAgent
|
||||
{
|
||||
BluetoothLEDevice device;
|
||||
winrt::event_token connnectionStatusChangedToken;
|
||||
std::map<std::string, gatt_service_t> gatt_map_;
|
||||
std::unordered_map<std::string, GattServiceObject> gatt_map_;
|
||||
|
||||
BluetoothDeviceAgent(BluetoothLEDevice device, winrt::event_token connnectionStatusChangedToken, std::map<std::string, gatt_service_t> gatt_map_)
|
||||
BluetoothDeviceAgent(BluetoothLEDevice device, winrt::event_token connnectionStatusChangedToken, std::unordered_map<std::string, GattServiceObject> gatt_map_)
|
||||
: device(device),
|
||||
connnectionStatusChangedToken(connnectionStatusChangedToken),
|
||||
gatt_map_(gatt_map_) {}
|
||||
@@ -60,19 +51,13 @@ namespace universal_ble
|
||||
device = nullptr;
|
||||
}
|
||||
|
||||
gatt_characteristic_t &_fetch_characteristic(const std::string &service_uuid,
|
||||
const std::string &characteristic_uuid)
|
||||
GattCharacteristicObject &_fetch_characteristic(const std::string &service_uuid,
|
||||
const std::string &characteristic_uuid)
|
||||
{
|
||||
if (gatt_map_.count(service_uuid) == 0)
|
||||
{
|
||||
throw FlutterError("Service not found");
|
||||
}
|
||||
|
||||
if (gatt_map_[service_uuid].characteristics.count(characteristic_uuid) == 0)
|
||||
{
|
||||
throw FlutterError("Characteristic not found");
|
||||
}
|
||||
|
||||
return gatt_map_[service_uuid].characteristics.at(characteristic_uuid);
|
||||
}
|
||||
};
|
||||
@@ -97,19 +82,31 @@ namespace universal_ble
|
||||
UniversalBlePlugin &operator=(const UniversalBlePlugin &) = delete;
|
||||
|
||||
flutter::PluginRegistrarWindows *registrar_;
|
||||
int64_t window_proc_delegate_id_ = -1;
|
||||
|
||||
HWND GetWindow();
|
||||
std::optional<LRESULT> WindowProcDelegate(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
winrt::fire_and_forget InitializeAsync();
|
||||
UniversalBleUiThreadHandler uiThreadHandler_;
|
||||
Radio bluetoothRadio{nullptr};
|
||||
void Radio_StateChanged(Radio sender, IInspectable args);
|
||||
RadioState oldRadioState = RadioState::Unknown;
|
||||
BluetoothLEAdvertisementWatcher bluetoothLEWatcher{nullptr};
|
||||
DeviceWatcher deviceWatcher{nullptr};
|
||||
std::unordered_map<uint64_t, std::unique_ptr<BluetoothDeviceAgent>> connectedDevices{};
|
||||
std::unordered_map<std::string, DeviceInformation> deviceWatcherDevices{};
|
||||
|
||||
winrt::event_token bluetoothLEWatcherReceivedToken;
|
||||
winrt::event_token deviceWatcherAddedToken;
|
||||
winrt::event_token deviceWatcherUpdatedToken;
|
||||
winrt::event_token deviceWatcherRemovedToken;
|
||||
|
||||
winrt::fire_and_forget InitializeAsync();
|
||||
void Radio_StateChanged(Radio sender, IInspectable args);
|
||||
|
||||
void setupDeviceWatcher();
|
||||
void disposeDeviceWatcher();
|
||||
void pushUniversalScanResult(UniversalBleScanResult scanResult);
|
||||
void BluetoothLEWatcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args);
|
||||
std::map<uint64_t, std::unique_ptr<BluetoothDeviceAgent>> connectedDevices{};
|
||||
std::map<uint64_t, bool> deviceConnectableStatus{};
|
||||
void onDeviceInfoReceived(DeviceInformation deviceInfo);
|
||||
|
||||
std::string GattCommunicationStatusToString(GattCommunicationStatus status);
|
||||
std::unordered_map<std::string, UniversalBleScanResult> scanResults{};
|
||||
winrt::event_revoker<IRadio> radioStateChangedRevoker;
|
||||
winrt::fire_and_forget ConnectAsync(uint64_t bluetoothAddress);
|
||||
void BluetoothLEDevice_ConnectionStatusChanged(BluetoothLEDevice sender, IInspectable args);
|
||||
@@ -120,7 +117,6 @@ namespace universal_ble
|
||||
void GattCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args);
|
||||
AvailabilityState getAvailabilityStateFromRadio(RadioState radioState);
|
||||
std::string parsePairingFailError(Enumeration::DevicePairingResult result);
|
||||
void PostConnectionUpdate(uint64_t bluetoothAddress, ConnectionState connectionState);
|
||||
winrt::fire_and_forget GetConnectedDevicesAsync(std::vector<std::string> with_services,
|
||||
std::function<void(ErrorOr<flutter::EncodableList> reply)> result);
|
||||
winrt::fire_and_forget IsPairedAsync(std::string device_id, std::function<void(ErrorOr<bool> reply)> result);
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
#include <flutter/plugin_registrar_windows.h>
|
||||
|
||||
#include "universal_ble_plugin.h"
|
||||
#include "src/universal_ble_plugin.h"
|
||||
|
||||
void UniversalBlePluginCApiRegisterWithRegistrar(
|
||||
FlutterDesktopPluginRegistrarRef registrar) {
|
||||
universal_ble::UniversalBlePlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarManager::GetInstance()
|
||||
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
|
||||
FlutterDesktopPluginRegistrarRef registrar)
|
||||
{
|
||||
universal_ble::UniversalBlePlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarManager::GetInstance()
|
||||
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user