Update Universal BLE Plugin for Peripheral Support and Code Generation
- Updated autogenerated files to reflect changes from Pigeon v26.3.4. - Added new classes for UniversalBlePeripheralConfig, UniversalBlePeripheralService, UniversalBlePeripheralCharacteristic, UniversalBlePeripheralDescriptor, and UniversalBlePeripheralWriteEvent to handle peripheral configurations and events. - Modified UniversalBlePlugin to implement methods for peripheral support, including StartPeripheral, StopPeripheral, UpdatePeripheralCharacteristicValue, and NotifyPeripheralCharacteristic, returning appropriate error messages for unsupported features on Windows. - Updated HasPermissions method to include an additional parameter for Bluetooth advertising permissions. - Adjusted method signatures and implementations across the plugin to accommodate new peripheral functionality. Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
## 1.3.0
|
## 1.3.0
|
||||||
|
* Add Linux BLE peripheral/GATT-server support through BlueZ GATT application and LE advertisement registration
|
||||||
* Add `requestConnectionPriority` to allow tuning BLE connection intervals on Android
|
* Add `requestConnectionPriority` to allow tuning BLE connection intervals on Android
|
||||||
* Add SPM support on Apple
|
* Add SPM support on Apple
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE
|
|||||||
- [Connecting](#connecting)
|
- [Connecting](#connecting)
|
||||||
- [Discovering Services](#discovering-services)
|
- [Discovering Services](#discovering-services)
|
||||||
- [Reading & Writing data](#reading--writing-data)
|
- [Reading & Writing data](#reading--writing-data)
|
||||||
|
- [Peripheral Mode](#peripheral-mode)
|
||||||
- [Pairing](#pairing)
|
- [Pairing](#pairing)
|
||||||
- [Bluetooth Availability](#bluetooth-availability)
|
- [Bluetooth Availability](#bluetooth-availability)
|
||||||
- [Requesting MTU](#requesting-mtu)
|
- [Requesting MTU](#requesting-mtu)
|
||||||
@@ -57,6 +58,7 @@ A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE
|
|||||||
| requestConnectionPriority | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
| requestConnectionPriority | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||||
| readRssi | ✔️ | ✔️ | ✔️ | ❌ | 🚧 | ❌ |
|
| readRssi | ✔️ | ✔️ | ✔️ | ❌ | 🚧 | ❌ |
|
||||||
| requestPermissions | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
|
| requestPermissions | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
|
||||||
|
| peripheral/GATT server | ✔️ | 🚧 | 🚧 | 🚧 | ✔️ | ❌ |
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
@@ -338,6 +340,49 @@ Unsubscribe from notifications and indications of this characteristic.
|
|||||||
await characteristic.unsubscribe();
|
await characteristic.unsubscribe();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Peripheral Mode
|
||||||
|
|
||||||
|
`UniversalBlePeripheral` exposes a local GATT-server API for apps that need to advertise services and accept central/client writes. Android and Linux are implemented; Apple and Windows currently report `notSupported` until their platform server implementations are added. Web browsers do not expose a standard GATT-server API.
|
||||||
|
|
||||||
|
On Linux, peripheral mode uses BlueZ `GattManager1` and `LEAdvertisingManager1`. The Bluetooth adapter must be powered, support the peripheral role, and the app process must be allowed to register GATT applications and LE advertisements on the system bus.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
await UniversalBle.requestPermissions(withAndroidBluetoothAdvertise: true);
|
||||||
|
|
||||||
|
await UniversalBlePeripheral.start(
|
||||||
|
BlePeripheralConfig(
|
||||||
|
advertisedName: 'DALI Relay',
|
||||||
|
services: [
|
||||||
|
BlePeripheralService(
|
||||||
|
uuid: 'fff0',
|
||||||
|
characteristics: [
|
||||||
|
BlePeripheralCharacteristic(
|
||||||
|
uuid: 'fff1',
|
||||||
|
properties: const [
|
||||||
|
CharacteristicProperty.read,
|
||||||
|
CharacteristicProperty.write,
|
||||||
|
CharacteristicProperty.writeWithoutResponse,
|
||||||
|
CharacteristicProperty.notify,
|
||||||
|
],
|
||||||
|
permissions: const [
|
||||||
|
BlePeripheralCharacteristicPermission.read,
|
||||||
|
BlePeripheralCharacteristicPermission.write,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
UniversalBlePeripheral.writeStream.listen((event) {
|
||||||
|
debugPrint('Central ${event.deviceId} wrote ${event.value}');
|
||||||
|
});
|
||||||
|
|
||||||
|
await UniversalBlePeripheral.notify('fff0', 'fff1', Uint8List.fromList([1, 2]));
|
||||||
|
await UniversalBlePeripheral.stop();
|
||||||
|
```
|
||||||
|
|
||||||
### Pairing
|
### Pairing
|
||||||
|
|
||||||
#### Trigger pairing
|
#### Trigger pairing
|
||||||
|
|||||||
@@ -7,4 +7,5 @@
|
|||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.BLUETOOTH_ADMIN"
|
android:name="android.permission.BLUETOOTH_ADMIN"
|
||||||
android:maxSdkVersion="30" />
|
android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ class PermissionHandler(
|
|||||||
/**
|
/**
|
||||||
* Check if we have required permissions
|
* Check if we have required permissions
|
||||||
*/
|
*/
|
||||||
fun hasPermissions(withFineLocation: Boolean): Boolean {
|
fun hasPermissions(withFineLocation: Boolean, withAdvertise: Boolean): Boolean {
|
||||||
val validationError = validateRequiredPermissions(withFineLocation)
|
val validationError = validateRequiredPermissions(withFineLocation, withAdvertise)
|
||||||
if (validationError != null) {
|
if (validationError != null) {
|
||||||
throw validationError
|
throw validationError
|
||||||
}
|
}
|
||||||
val permissionsToRequest = getRequiredPermissions(withFineLocation)
|
val permissionsToRequest = getRequiredPermissions(withFineLocation, withAdvertise)
|
||||||
return permissionsToRequest.isEmpty()
|
return permissionsToRequest.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,17 +55,18 @@ class PermissionHandler(
|
|||||||
*/
|
*/
|
||||||
fun requestPermissions(
|
fun requestPermissions(
|
||||||
withFineLocation: Boolean,
|
withFineLocation: Boolean,
|
||||||
|
withAdvertise: Boolean,
|
||||||
callback: (Result<Unit>) -> Unit,
|
callback: (Result<Unit>) -> Unit,
|
||||||
) {
|
) {
|
||||||
// Validate required permissions are declared in manifest
|
// Validate required permissions are declared in manifest
|
||||||
val validationError = validateRequiredPermissions(withFineLocation)
|
val validationError = validateRequiredPermissions(withFineLocation, withAdvertise)
|
||||||
if (validationError != null) {
|
if (validationError != null) {
|
||||||
callback(Result.failure(validationError))
|
callback(Result.failure(validationError))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check which permissions need to be requested
|
// Check which permissions need to be requested
|
||||||
val permissionsToRequest = getRequiredPermissions(withFineLocation)
|
val permissionsToRequest = getRequiredPermissions(withFineLocation, withAdvertise)
|
||||||
|
|
||||||
if (permissionsToRequest.isEmpty()) {
|
if (permissionsToRequest.isEmpty()) {
|
||||||
// All required permissions are already granted
|
// All required permissions are already granted
|
||||||
@@ -163,7 +164,7 @@ class PermissionHandler(
|
|||||||
*
|
*
|
||||||
* Returns a list of permissions that need to be requested (excluding already granted ones)
|
* Returns a list of permissions that need to be requested (excluding already granted ones)
|
||||||
*/
|
*/
|
||||||
private fun getRequiredPermissions(withFineLocation: Boolean): List<String> {
|
private fun getRequiredPermissions(withFineLocation: Boolean, withAdvertise: Boolean): List<String> {
|
||||||
val permissionsToRequest = mutableListOf<String>()
|
val permissionsToRequest = mutableListOf<String>()
|
||||||
// Android 12+ (API 31+)
|
// Android 12+ (API 31+)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
@@ -175,6 +176,9 @@ class PermissionHandler(
|
|||||||
if (!hasPermissionGranted(Manifest.permission.BLUETOOTH_CONNECT)) {
|
if (!hasPermissionGranted(Manifest.permission.BLUETOOTH_CONNECT)) {
|
||||||
permissionsToRequest.add(Manifest.permission.BLUETOOTH_CONNECT)
|
permissionsToRequest.add(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
}
|
}
|
||||||
|
if (withAdvertise && !hasPermissionGranted(Manifest.permission.BLUETOOTH_ADVERTISE)) {
|
||||||
|
permissionsToRequest.add(Manifest.permission.BLUETOOTH_ADVERTISE)
|
||||||
|
}
|
||||||
// Location permission is optional - only request if user wants it
|
// Location permission is optional - only request if user wants it
|
||||||
if (withFineLocation) {
|
if (withFineLocation) {
|
||||||
// Prefer ACCESS_FINE_LOCATION over ACCESS_COARSE_LOCATION
|
// Prefer ACCESS_FINE_LOCATION over ACCESS_COARSE_LOCATION
|
||||||
@@ -236,7 +240,7 @@ class PermissionHandler(
|
|||||||
* @param withFineLocation Whether location permission should be requested
|
* @param withFineLocation Whether location permission should be requested
|
||||||
* @return FlutterError if validation fails, null if all required permissions are declared
|
* @return FlutterError if validation fails, null if all required permissions are declared
|
||||||
*/
|
*/
|
||||||
private fun validateRequiredPermissions(withFineLocation: Boolean): FlutterError? {
|
private fun validateRequiredPermissions(withFineLocation: Boolean, withAdvertise: Boolean): FlutterError? {
|
||||||
val sdkInt = Build.VERSION.SDK_INT
|
val sdkInt = Build.VERSION.SDK_INT
|
||||||
val missingPermissions = mutableListOf<String>()
|
val missingPermissions = mutableListOf<String>()
|
||||||
|
|
||||||
@@ -259,6 +263,10 @@ class PermissionHandler(
|
|||||||
missingPermissions.add(Manifest.permission.BLUETOOTH_CONNECT)
|
missingPermissions.add(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (withAdvertise && !hasPermissionInManifest(Manifest.permission.BLUETOOTH_ADVERTISE)) {
|
||||||
|
missingPermissions.add(Manifest.permission.BLUETOOTH_ADVERTISE)
|
||||||
|
}
|
||||||
|
|
||||||
// Location permission is optional on Android 12+ (depends on neverForLocation and withFineLocation)
|
// Location permission is optional on Android 12+ (depends on neverForLocation and withFineLocation)
|
||||||
// Only validate if it's actually needed
|
// Only validate if it's actually needed
|
||||||
if (withFineLocation && !hasDeclaredLocationPermission) {
|
if (withFineLocation && !hasDeclaredLocationPermission) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.4), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.4), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||||
|
|
||||||
@@ -37,7 +37,36 @@ private object UniversalBlePigeonUtils {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun doubleEquals(a: Double, b: Double): Boolean {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN equality.
|
||||||
|
return (if (a == 0.0) 0.0 else a) == (if (b == 0.0) 0.0 else b) || (a.isNaN() && b.isNaN())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatEquals(a: Float, b: Float): Boolean {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN equality.
|
||||||
|
return (if (a == 0.0f) 0.0f else a) == (if (b == 0.0f) 0.0f else b) || (a.isNaN() && b.isNaN())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doubleHash(d: Double): Int {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
|
||||||
|
val normalized = if (d == 0.0) 0.0 else d
|
||||||
|
val bits = java.lang.Double.doubleToLongBits(normalized)
|
||||||
|
return (bits xor (bits ushr 32)).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun floatHash(f: Float): Int {
|
||||||
|
// Normalize -0.0 to 0.0 and handle NaN to ensure consistent hash codes.
|
||||||
|
val normalized = if (f == 0.0f) 0.0f else f
|
||||||
|
return java.lang.Float.floatToIntBits(normalized)
|
||||||
|
}
|
||||||
|
|
||||||
fun deepEquals(a: Any?, b: Any?): Boolean {
|
fun deepEquals(a: Any?, b: Any?): Boolean {
|
||||||
|
if (a === b) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a == null || b == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (a is ByteArray && b is ByteArray) {
|
if (a is ByteArray && b is ByteArray) {
|
||||||
return a.contentEquals(b)
|
return a.contentEquals(b)
|
||||||
}
|
}
|
||||||
@@ -48,25 +77,110 @@ private object UniversalBlePigeonUtils {
|
|||||||
return a.contentEquals(b)
|
return a.contentEquals(b)
|
||||||
}
|
}
|
||||||
if (a is DoubleArray && b is DoubleArray) {
|
if (a is DoubleArray && b is DoubleArray) {
|
||||||
return a.contentEquals(b)
|
if (a.size != b.size) return false
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (!doubleEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a is FloatArray && b is FloatArray) {
|
||||||
|
if (a.size != b.size) return false
|
||||||
|
for (i in a.indices) {
|
||||||
|
if (!floatEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is Array<*> && b is Array<*>) {
|
if (a is Array<*> && b is Array<*>) {
|
||||||
return a.size == b.size &&
|
if (a.size != b.size) return false
|
||||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
for (i in a.indices) {
|
||||||
|
if (!deepEquals(a[i], b[i])) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is List<*> && b is List<*>) {
|
if (a is List<*> && b is List<*>) {
|
||||||
return a.size == b.size &&
|
if (a.size != b.size) return false
|
||||||
a.indices.all{ deepEquals(a[it], b[it]) }
|
val iterA = a.iterator()
|
||||||
|
val iterB = b.iterator()
|
||||||
|
while (iterA.hasNext() && iterB.hasNext()) {
|
||||||
|
if (!deepEquals(iterA.next(), iterB.next())) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (a is Map<*, *> && b is Map<*, *>) {
|
if (a is Map<*, *> && b is Map<*, *>) {
|
||||||
return a.size == b.size && a.all {
|
if (a.size != b.size) return false
|
||||||
(b as Map<Any?, Any?>).contains(it.key) &&
|
for (entry in a) {
|
||||||
deepEquals(it.value, b[it.key])
|
val key = entry.key
|
||||||
|
var found = false
|
||||||
|
for (bEntry in b) {
|
||||||
|
if (deepEquals(key, bEntry.key)) {
|
||||||
|
if (deepEquals(entry.value, bEntry.value)) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!found) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (a is Double && b is Double) {
|
||||||
|
return doubleEquals(a, b)
|
||||||
|
}
|
||||||
|
if (a is Float && b is Float) {
|
||||||
|
return floatEquals(a, b)
|
||||||
|
}
|
||||||
return a == b
|
return a == b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deepHash(value: Any?): Int {
|
||||||
|
return when (value) {
|
||||||
|
null -> 0
|
||||||
|
is ByteArray -> value.contentHashCode()
|
||||||
|
is IntArray -> value.contentHashCode()
|
||||||
|
is LongArray -> value.contentHashCode()
|
||||||
|
is DoubleArray -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + doubleHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is FloatArray -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + floatHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Array<*> -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + deepHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is List<*> -> {
|
||||||
|
var result = 1
|
||||||
|
for (item in value) {
|
||||||
|
result = 31 * result + deepHash(item)
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Map<*, *> -> {
|
||||||
|
var result = 0
|
||||||
|
for (entry in value) {
|
||||||
|
result += ((deepHash(entry.key) * 31) xor deepHash(entry.value))
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
is Double -> doubleHash(value)
|
||||||
|
is Float -> floatHash(value)
|
||||||
|
else -> value.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,7 +193,7 @@ class FlutterError (
|
|||||||
val code: String,
|
val code: String,
|
||||||
override val message: String? = null,
|
override val message: String? = null,
|
||||||
val details: Any? = null
|
val details: Any? = null
|
||||||
) : Throwable()
|
) : RuntimeException()
|
||||||
|
|
||||||
enum class UniversalBleLogLevel(val raw: Int) {
|
enum class UniversalBleLogLevel(val raw: Int) {
|
||||||
NONE(0),
|
NONE(0),
|
||||||
@@ -219,15 +333,28 @@ data class UniversalBleScanResult (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is UniversalBleScanResult) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as UniversalBleScanResult
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.deviceId, other.deviceId) && UniversalBlePigeonUtils.deepEquals(this.name, other.name) && UniversalBlePigeonUtils.deepEquals(this.isPaired, other.isPaired) && UniversalBlePigeonUtils.deepEquals(this.rssi, other.rssi) && UniversalBlePigeonUtils.deepEquals(this.manufacturerDataList, other.manufacturerDataList) && UniversalBlePigeonUtils.deepEquals(this.serviceData, other.serviceData) && UniversalBlePigeonUtils.deepEquals(this.services, other.services) && UniversalBlePigeonUtils.deepEquals(this.timestamp, other.timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.deviceId)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.name)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.isPaired)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.rssi)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.manufacturerDataList)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.serviceData)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.services)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.timestamp)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generated class from Pigeon that represents data sent in messages. */
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
@@ -250,15 +377,22 @@ data class UniversalBleService (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is UniversalBleService) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as UniversalBleService
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.uuid, other.uuid) && UniversalBlePigeonUtils.deepEquals(this.characteristics, other.characteristics)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.uuid)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.characteristics)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generated class from Pigeon that represents data sent in messages. */
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
@@ -284,15 +418,23 @@ data class UniversalBleCharacteristic (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is UniversalBleCharacteristic) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as UniversalBleCharacteristic
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.uuid, other.uuid) && UniversalBlePigeonUtils.deepEquals(this.properties, other.properties) && UniversalBlePigeonUtils.deepEquals(this.descriptors, other.descriptors)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.uuid)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.properties)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.descriptors)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generated class from Pigeon that represents data sent in messages. */
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
@@ -312,15 +454,235 @@ data class UniversalBleDescriptor (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is UniversalBleDescriptor) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as UniversalBleDescriptor
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.uuid, other.uuid)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.uuid)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
|
data class UniversalBlePeripheralConfig (
|
||||||
|
val advertisedName: String,
|
||||||
|
val services: List<UniversalBlePeripheralService>
|
||||||
|
)
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): UniversalBlePeripheralConfig {
|
||||||
|
val advertisedName = pigeonVar_list[0] as String
|
||||||
|
val services = pigeonVar_list[1] as List<UniversalBlePeripheralService>
|
||||||
|
return UniversalBlePeripheralConfig(advertisedName, services)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
advertisedName,
|
||||||
|
services,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other == null || other.javaClass != javaClass) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (this === other) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
val other = other as UniversalBlePeripheralConfig
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.advertisedName, other.advertisedName) && UniversalBlePigeonUtils.deepEquals(this.services, other.services)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.advertisedName)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.services)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
|
data class UniversalBlePeripheralService (
|
||||||
|
val uuid: String,
|
||||||
|
val characteristics: List<UniversalBlePeripheralCharacteristic>
|
||||||
|
)
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): UniversalBlePeripheralService {
|
||||||
|
val uuid = pigeonVar_list[0] as String
|
||||||
|
val characteristics = pigeonVar_list[1] as List<UniversalBlePeripheralCharacteristic>
|
||||||
|
return UniversalBlePeripheralService(uuid, characteristics)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
uuid,
|
||||||
|
characteristics,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other == null || other.javaClass != javaClass) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (this === other) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
val other = other as UniversalBlePeripheralService
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.uuid, other.uuid) && UniversalBlePigeonUtils.deepEquals(this.characteristics, other.characteristics)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.uuid)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.characteristics)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
|
data class UniversalBlePeripheralCharacteristic (
|
||||||
|
val uuid: String,
|
||||||
|
val properties: List<Long>,
|
||||||
|
val permissions: List<Long>,
|
||||||
|
val descriptors: List<UniversalBlePeripheralDescriptor>,
|
||||||
|
val initialValue: ByteArray? = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): UniversalBlePeripheralCharacteristic {
|
||||||
|
val uuid = pigeonVar_list[0] as String
|
||||||
|
val properties = pigeonVar_list[1] as List<Long>
|
||||||
|
val permissions = pigeonVar_list[2] as List<Long>
|
||||||
|
val descriptors = pigeonVar_list[3] as List<UniversalBlePeripheralDescriptor>
|
||||||
|
val initialValue = pigeonVar_list[4] as ByteArray?
|
||||||
|
return UniversalBlePeripheralCharacteristic(uuid, properties, permissions, descriptors, initialValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
uuid,
|
||||||
|
properties,
|
||||||
|
permissions,
|
||||||
|
descriptors,
|
||||||
|
initialValue,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other == null || other.javaClass != javaClass) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (this === other) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
val other = other as UniversalBlePeripheralCharacteristic
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.uuid, other.uuid) && UniversalBlePigeonUtils.deepEquals(this.properties, other.properties) && UniversalBlePigeonUtils.deepEquals(this.permissions, other.permissions) && UniversalBlePigeonUtils.deepEquals(this.descriptors, other.descriptors) && UniversalBlePigeonUtils.deepEquals(this.initialValue, other.initialValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.uuid)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.properties)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.permissions)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.descriptors)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.initialValue)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
|
data class UniversalBlePeripheralDescriptor (
|
||||||
|
val uuid: String,
|
||||||
|
val permissions: List<Long>,
|
||||||
|
val initialValue: ByteArray? = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): UniversalBlePeripheralDescriptor {
|
||||||
|
val uuid = pigeonVar_list[0] as String
|
||||||
|
val permissions = pigeonVar_list[1] as List<Long>
|
||||||
|
val initialValue = pigeonVar_list[2] as ByteArray?
|
||||||
|
return UniversalBlePeripheralDescriptor(uuid, permissions, initialValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
uuid,
|
||||||
|
permissions,
|
||||||
|
initialValue,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other == null || other.javaClass != javaClass) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (this === other) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
val other = other as UniversalBlePeripheralDescriptor
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.uuid, other.uuid) && UniversalBlePigeonUtils.deepEquals(this.permissions, other.permissions) && UniversalBlePigeonUtils.deepEquals(this.initialValue, other.initialValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.uuid)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.permissions)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.initialValue)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
|
data class UniversalBlePeripheralWriteEvent (
|
||||||
|
val deviceId: String,
|
||||||
|
val service: String,
|
||||||
|
val characteristic: String,
|
||||||
|
val value: ByteArray
|
||||||
|
)
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): UniversalBlePeripheralWriteEvent {
|
||||||
|
val deviceId = pigeonVar_list[0] as String
|
||||||
|
val service = pigeonVar_list[1] as String
|
||||||
|
val characteristic = pigeonVar_list[2] as String
|
||||||
|
val value = pigeonVar_list[3] as ByteArray
|
||||||
|
return UniversalBlePeripheralWriteEvent(deviceId, service, characteristic, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
deviceId,
|
||||||
|
service,
|
||||||
|
characteristic,
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other == null || other.javaClass != javaClass) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (this === other) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
val other = other as UniversalBlePeripheralWriteEvent
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.deviceId, other.deviceId) && UniversalBlePigeonUtils.deepEquals(this.service, other.service) && UniversalBlePigeonUtils.deepEquals(this.characteristic, other.characteristic) && UniversalBlePigeonUtils.deepEquals(this.value, other.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.deviceId)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.service)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.characteristic)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.value)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -355,15 +717,23 @@ data class AndroidOptions (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is AndroidOptions) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as AndroidOptions
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.requestLocationPermission, other.requestLocationPermission) && UniversalBlePigeonUtils.deepEquals(this.scanMode, other.scanMode) && UniversalBlePigeonUtils.deepEquals(this.reportDelayMillis, other.reportDelayMillis)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.requestLocationPermission)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.scanMode)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.reportDelayMillis)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generated class from Pigeon that represents data sent in messages. */
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
@@ -383,15 +753,21 @@ data class UniversalScanConfig (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is UniversalScanConfig) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as UniversalScanConfig
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.android, other.android)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.android)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -421,15 +797,23 @@ data class UniversalScanFilter (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is UniversalScanFilter) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as UniversalScanFilter
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.withServices, other.withServices) && UniversalBlePigeonUtils.deepEquals(this.withNamePrefix, other.withNamePrefix) && UniversalBlePigeonUtils.deepEquals(this.withManufacturerData, other.withManufacturerData)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.withServices)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.withNamePrefix)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.withManufacturerData)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generated class from Pigeon that represents data sent in messages. */
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
@@ -455,15 +839,23 @@ data class UniversalManufacturerDataFilter (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is UniversalManufacturerDataFilter) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as UniversalManufacturerDataFilter
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.companyIdentifier, other.companyIdentifier) && UniversalBlePigeonUtils.deepEquals(this.data, other.data) && UniversalBlePigeonUtils.deepEquals(this.mask, other.mask)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.companyIdentifier)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.data)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.mask)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generated class from Pigeon that represents data sent in messages. */
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
@@ -486,15 +878,22 @@ data class UniversalManufacturerData (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (other !is UniversalManufacturerData) {
|
if (other == null || other.javaClass != javaClass) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (this === other) {
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return UniversalBlePigeonUtils.deepEquals(toList(), other.toList()) }
|
val other = other as UniversalManufacturerData
|
||||||
|
return UniversalBlePigeonUtils.deepEquals(this.companyIdentifier, other.companyIdentifier) && UniversalBlePigeonUtils.deepEquals(this.data, other.data)
|
||||||
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int = toList().hashCode()
|
override fun hashCode(): Int {
|
||||||
|
var result = javaClass.hashCode()
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.companyIdentifier)
|
||||||
|
result = 31 * result + UniversalBlePigeonUtils.deepHash(this.data)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private open class UniversalBlePigeonCodec : StandardMessageCodec() {
|
private open class UniversalBlePigeonCodec : StandardMessageCodec() {
|
||||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||||
@@ -536,25 +935,50 @@ private open class UniversalBlePigeonCodec : StandardMessageCodec() {
|
|||||||
}
|
}
|
||||||
136.toByte() -> {
|
136.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
AndroidOptions.fromList(it)
|
UniversalBlePeripheralConfig.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
137.toByte() -> {
|
137.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
UniversalScanConfig.fromList(it)
|
UniversalBlePeripheralService.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
138.toByte() -> {
|
138.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
UniversalScanFilter.fromList(it)
|
UniversalBlePeripheralCharacteristic.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
139.toByte() -> {
|
139.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
UniversalManufacturerDataFilter.fromList(it)
|
UniversalBlePeripheralDescriptor.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
140.toByte() -> {
|
140.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
UniversalBlePeripheralWriteEvent.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
141.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
AndroidOptions.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
142.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
UniversalScanConfig.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
143.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
UniversalScanFilter.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
144.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
UniversalManufacturerDataFilter.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
145.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
UniversalManufacturerData.fromList(it)
|
UniversalManufacturerData.fromList(it)
|
||||||
}
|
}
|
||||||
@@ -592,26 +1016,46 @@ private open class UniversalBlePigeonCodec : StandardMessageCodec() {
|
|||||||
stream.write(135)
|
stream.write(135)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is AndroidOptions -> {
|
is UniversalBlePeripheralConfig -> {
|
||||||
stream.write(136)
|
stream.write(136)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is UniversalScanConfig -> {
|
is UniversalBlePeripheralService -> {
|
||||||
stream.write(137)
|
stream.write(137)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is UniversalScanFilter -> {
|
is UniversalBlePeripheralCharacteristic -> {
|
||||||
stream.write(138)
|
stream.write(138)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is UniversalManufacturerDataFilter -> {
|
is UniversalBlePeripheralDescriptor -> {
|
||||||
stream.write(139)
|
stream.write(139)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is UniversalManufacturerData -> {
|
is UniversalBlePeripheralWriteEvent -> {
|
||||||
stream.write(140)
|
stream.write(140)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
|
is AndroidOptions -> {
|
||||||
|
stream.write(141)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is UniversalScanConfig -> {
|
||||||
|
stream.write(142)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is UniversalScanFilter -> {
|
||||||
|
stream.write(143)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is UniversalManufacturerDataFilter -> {
|
||||||
|
stream.write(144)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is UniversalManufacturerData -> {
|
||||||
|
stream.write(145)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
else -> super.writeValue(stream, value)
|
else -> super.writeValue(stream, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -625,8 +1069,8 @@ private open class UniversalBlePigeonCodec : StandardMessageCodec() {
|
|||||||
*/
|
*/
|
||||||
interface UniversalBlePlatformChannel {
|
interface UniversalBlePlatformChannel {
|
||||||
fun getBluetoothAvailabilityState(callback: (Result<Long>) -> Unit)
|
fun getBluetoothAvailabilityState(callback: (Result<Long>) -> Unit)
|
||||||
fun hasPermissions(withAndroidFineLocation: Boolean): Boolean
|
fun hasPermissions(withAndroidFineLocation: Boolean, withAndroidBluetoothAdvertise: Boolean): Boolean
|
||||||
fun requestPermissions(withAndroidFineLocation: Boolean, callback: (Result<Unit>) -> Unit)
|
fun requestPermissions(withAndroidFineLocation: Boolean, withAndroidBluetoothAdvertise: Boolean, callback: (Result<Unit>) -> Unit)
|
||||||
fun enableBluetooth(callback: (Result<Boolean>) -> Unit)
|
fun enableBluetooth(callback: (Result<Boolean>) -> Unit)
|
||||||
fun disableBluetooth(callback: (Result<Boolean>) -> Unit)
|
fun disableBluetooth(callback: (Result<Boolean>) -> Unit)
|
||||||
fun startScan(filter: UniversalScanFilter?, config: UniversalScanConfig?)
|
fun startScan(filter: UniversalScanFilter?, config: UniversalScanConfig?)
|
||||||
@@ -646,6 +1090,11 @@ interface UniversalBlePlatformChannel {
|
|||||||
fun getConnectionState(deviceId: String): Long
|
fun getConnectionState(deviceId: String): Long
|
||||||
fun readRssi(deviceId: String, callback: (Result<Long>) -> Unit)
|
fun readRssi(deviceId: String, callback: (Result<Long>) -> Unit)
|
||||||
fun requestConnectionPriority(deviceId: String, priority: Long, callback: (Result<Unit>) -> Unit)
|
fun requestConnectionPriority(deviceId: String, priority: Long, callback: (Result<Unit>) -> Unit)
|
||||||
|
fun isPeripheralSupported(): Boolean
|
||||||
|
fun startPeripheral(config: UniversalBlePeripheralConfig, callback: (Result<Unit>) -> Unit)
|
||||||
|
fun stopPeripheral(callback: (Result<Unit>) -> Unit)
|
||||||
|
fun updatePeripheralCharacteristicValue(service: String, characteristic: String, value: ByteArray, callback: (Result<Unit>) -> Unit)
|
||||||
|
fun notifyPeripheralCharacteristic(service: String, characteristic: String, value: ByteArray, indicate: Boolean, callback: (Result<Unit>) -> Unit)
|
||||||
fun setLogLevel(logLevel: UniversalBleLogLevel)
|
fun setLogLevel(logLevel: UniversalBleLogLevel)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -681,8 +1130,9 @@ interface UniversalBlePlatformChannel {
|
|||||||
channel.setMessageHandler { message, reply ->
|
channel.setMessageHandler { message, reply ->
|
||||||
val args = message as List<Any?>
|
val args = message as List<Any?>
|
||||||
val withAndroidFineLocationArg = args[0] as Boolean
|
val withAndroidFineLocationArg = args[0] as Boolean
|
||||||
|
val withAndroidBluetoothAdvertiseArg = args[1] as Boolean
|
||||||
val wrapped: List<Any?> = try {
|
val wrapped: List<Any?> = try {
|
||||||
listOf(api.hasPermissions(withAndroidFineLocationArg))
|
listOf(api.hasPermissions(withAndroidFineLocationArg, withAndroidBluetoothAdvertiseArg))
|
||||||
} catch (exception: Throwable) {
|
} catch (exception: Throwable) {
|
||||||
UniversalBlePigeonUtils.wrapError(exception)
|
UniversalBlePigeonUtils.wrapError(exception)
|
||||||
}
|
}
|
||||||
@@ -698,7 +1148,8 @@ interface UniversalBlePlatformChannel {
|
|||||||
channel.setMessageHandler { message, reply ->
|
channel.setMessageHandler { message, reply ->
|
||||||
val args = message as List<Any?>
|
val args = message as List<Any?>
|
||||||
val withAndroidFineLocationArg = args[0] as Boolean
|
val withAndroidFineLocationArg = args[0] as Boolean
|
||||||
api.requestPermissions(withAndroidFineLocationArg) { result: Result<Unit> ->
|
val withAndroidBluetoothAdvertiseArg = args[1] as Boolean
|
||||||
|
api.requestPermissions(withAndroidFineLocationArg, withAndroidBluetoothAdvertiseArg) { result: Result<Unit> ->
|
||||||
val error = result.exceptionOrNull()
|
val error = result.exceptionOrNull()
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
reply.reply(UniversalBlePigeonUtils.wrapError(error))
|
reply.reply(UniversalBlePigeonUtils.wrapError(error))
|
||||||
@@ -1078,6 +1529,100 @@ interface UniversalBlePlatformChannel {
|
|||||||
channel.setMessageHandler(null)
|
channel.setMessageHandler(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPeripheralSupported$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { _, reply ->
|
||||||
|
val wrapped: List<Any?> = try {
|
||||||
|
listOf(api.isPeripheralSupported())
|
||||||
|
} catch (exception: Throwable) {
|
||||||
|
UniversalBlePigeonUtils.wrapError(exception)
|
||||||
|
}
|
||||||
|
reply.reply(wrapped)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startPeripheral$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val configArg = args[0] as UniversalBlePeripheralConfig
|
||||||
|
api.startPeripheral(configArg) { result: Result<Unit> ->
|
||||||
|
val error = result.exceptionOrNull()
|
||||||
|
if (error != null) {
|
||||||
|
reply.reply(UniversalBlePigeonUtils.wrapError(error))
|
||||||
|
} else {
|
||||||
|
reply.reply(UniversalBlePigeonUtils.wrapResult(null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopPeripheral$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { _, reply ->
|
||||||
|
api.stopPeripheral{ result: Result<Unit> ->
|
||||||
|
val error = result.exceptionOrNull()
|
||||||
|
if (error != null) {
|
||||||
|
reply.reply(UniversalBlePigeonUtils.wrapError(error))
|
||||||
|
} else {
|
||||||
|
reply.reply(UniversalBlePigeonUtils.wrapResult(null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.updatePeripheralCharacteristicValue$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val serviceArg = args[0] as String
|
||||||
|
val characteristicArg = args[1] as String
|
||||||
|
val valueArg = args[2] as ByteArray
|
||||||
|
api.updatePeripheralCharacteristicValue(serviceArg, characteristicArg, valueArg) { result: Result<Unit> ->
|
||||||
|
val error = result.exceptionOrNull()
|
||||||
|
if (error != null) {
|
||||||
|
reply.reply(UniversalBlePigeonUtils.wrapError(error))
|
||||||
|
} else {
|
||||||
|
reply.reply(UniversalBlePigeonUtils.wrapResult(null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.notifyPeripheralCharacteristic$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val serviceArg = args[0] as String
|
||||||
|
val characteristicArg = args[1] as String
|
||||||
|
val valueArg = args[2] as ByteArray
|
||||||
|
val indicateArg = args[3] as Boolean
|
||||||
|
api.notifyPeripheralCharacteristic(serviceArg, characteristicArg, valueArg, indicateArg) { result: Result<Unit> ->
|
||||||
|
val error = result.exceptionOrNull()
|
||||||
|
if (error != null) {
|
||||||
|
reply.reply(UniversalBlePigeonUtils.wrapError(error))
|
||||||
|
} else {
|
||||||
|
reply.reply(UniversalBlePigeonUtils.wrapResult(null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
run {
|
run {
|
||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setLogLevel$separatedMessageChannelSuffix", codec)
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setLogLevel$separatedMessageChannelSuffix", codec)
|
||||||
if (api != null) {
|
if (api != null) {
|
||||||
@@ -1196,4 +1741,55 @@ class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun onPeripheralConnectionChanged(deviceIdArg: String, connectedArg: Boolean, callback: (Result<Unit>) -> Unit)
|
||||||
|
{
|
||||||
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
|
val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPeripheralConnectionChanged$separatedMessageChannelSuffix"
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||||
|
channel.send(listOf(deviceIdArg, connectedArg)) {
|
||||||
|
if (it is List<*>) {
|
||||||
|
if (it.size > 1) {
|
||||||
|
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||||
|
} else {
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(Result.failure(UniversalBlePigeonUtils.createConnectionError(channelName)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun onPeripheralWrite(eventArg: UniversalBlePeripheralWriteEvent, callback: (Result<Unit>) -> Unit)
|
||||||
|
{
|
||||||
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
|
val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPeripheralWrite$separatedMessageChannelSuffix"
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||||
|
channel.send(listOf(eventArg)) {
|
||||||
|
if (it is List<*>) {
|
||||||
|
if (it.size > 1) {
|
||||||
|
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||||
|
} else {
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(Result.failure(UniversalBlePigeonUtils.createConnectionError(channelName)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun onPeripheralSubscriptionChanged(deviceIdArg: String, serviceArg: String, characteristicArg: String, subscribedArg: Boolean, callback: (Result<Unit>) -> Unit)
|
||||||
|
{
|
||||||
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
|
val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPeripheralSubscriptionChanged$separatedMessageChannelSuffix"
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||||
|
channel.send(listOf(deviceIdArg, serviceArg, characteristicArg, subscribedArg)) {
|
||||||
|
if (it is List<*>) {
|
||||||
|
if (it.size > 1) {
|
||||||
|
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||||
|
} else {
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(Result.failure(UniversalBlePigeonUtils.createConnectionError(channelName)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,16 @@ import android.bluetooth.BluetoothGatt
|
|||||||
import android.bluetooth.BluetoothGattCallback
|
import android.bluetooth.BluetoothGattCallback
|
||||||
import android.bluetooth.BluetoothGattCharacteristic
|
import android.bluetooth.BluetoothGattCharacteristic
|
||||||
import android.bluetooth.BluetoothGattDescriptor
|
import android.bluetooth.BluetoothGattDescriptor
|
||||||
|
import android.bluetooth.BluetoothGattServer
|
||||||
|
import android.bluetooth.BluetoothGattServerCallback
|
||||||
|
import android.bluetooth.BluetoothGattService
|
||||||
import android.bluetooth.BluetoothManager
|
import android.bluetooth.BluetoothManager
|
||||||
import android.bluetooth.BluetoothProfile
|
import android.bluetooth.BluetoothProfile
|
||||||
import android.bluetooth.BluetoothStatusCodes
|
import android.bluetooth.BluetoothStatusCodes
|
||||||
|
import android.bluetooth.le.AdvertiseCallback
|
||||||
|
import android.bluetooth.le.AdvertiseData
|
||||||
|
import android.bluetooth.le.AdvertiseSettings
|
||||||
|
import android.bluetooth.le.BluetoothLeAdvertiser
|
||||||
import android.bluetooth.le.ScanCallback
|
import android.bluetooth.le.ScanCallback
|
||||||
import android.bluetooth.le.ScanFilter
|
import android.bluetooth.le.ScanFilter
|
||||||
import android.bluetooth.le.ScanResult
|
import android.bluetooth.le.ScanResult
|
||||||
@@ -24,6 +31,7 @@ import android.content.IntentFilter
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.os.ParcelUuid
|
||||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||||
@@ -63,6 +71,12 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
|||||||
private val rssiResultFutureList = mutableListOf<RssiResultFuture>()
|
private val rssiResultFutureList = mutableListOf<RssiResultFuture>()
|
||||||
private val autoConnectDevices = mutableSetOf<String>()
|
private val autoConnectDevices = mutableSetOf<String>()
|
||||||
|
|
||||||
|
private var peripheralGattServer: BluetoothGattServer? = null
|
||||||
|
private var peripheralAdvertiser: BluetoothLeAdvertiser? = null
|
||||||
|
private var peripheralPendingStartCallback: ((Result<Unit>) -> Unit)? = null
|
||||||
|
private val peripheralConnectedDevices = mutableSetOf<BluetoothDevice>()
|
||||||
|
private val peripheralCharacteristics = mutableMapOf<String, BluetoothGattCharacteristic>()
|
||||||
|
|
||||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
UniversalBlePlatformChannel.setUp(flutterPluginBinding.binaryMessenger, this)
|
UniversalBlePlatformChannel.setUp(flutterPluginBinding.binaryMessenger, this)
|
||||||
callbackChannel = UniversalBleCallbackChannel(flutterPluginBinding.binaryMessenger)
|
callbackChannel = UniversalBleCallbackChannel(flutterPluginBinding.binaryMessenger)
|
||||||
@@ -84,6 +98,7 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
|||||||
|
|
||||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
bluetoothManager.adapter.bluetoothLeScanner?.stopScan(scanCallback)
|
bluetoothManager.adapter.bluetoothLeScanner?.stopScan(scanCallback)
|
||||||
|
stopPeripheralInternal()
|
||||||
context.unregisterReceiver(broadcastReceiver)
|
context.unregisterReceiver(broadcastReceiver)
|
||||||
callbackChannel = null
|
callbackChannel = null
|
||||||
mainThreadHandler = null
|
mainThreadHandler = null
|
||||||
@@ -99,12 +114,19 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasPermissions(withAndroidFineLocation: Boolean): Boolean {
|
override fun hasPermissions(
|
||||||
return permissionHandler?.hasPermissions(withAndroidFineLocation) ?: false
|
withAndroidFineLocation: Boolean,
|
||||||
|
withAndroidBluetoothAdvertise: Boolean,
|
||||||
|
): Boolean {
|
||||||
|
return permissionHandler?.hasPermissions(
|
||||||
|
withAndroidFineLocation,
|
||||||
|
withAndroidBluetoothAdvertise,
|
||||||
|
) ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun requestPermissions(
|
override fun requestPermissions(
|
||||||
withAndroidFineLocation: Boolean,
|
withAndroidFineLocation: Boolean,
|
||||||
|
withAndroidBluetoothAdvertise: Boolean,
|
||||||
callback: (Result<Unit>) -> Unit,
|
callback: (Result<Unit>) -> Unit,
|
||||||
) {
|
) {
|
||||||
if (permissionHandler == null) {
|
if (permissionHandler == null) {
|
||||||
@@ -117,7 +139,11 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
permissionHandler?.requestPermissions(withAndroidFineLocation, callback)
|
permissionHandler?.requestPermissions(
|
||||||
|
withAndroidFineLocation,
|
||||||
|
withAndroidBluetoothAdvertise,
|
||||||
|
callback,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun enableBluetooth(callback: (Result<Boolean>) -> Unit) {
|
override fun enableBluetooth(callback: (Result<Boolean>) -> Unit) {
|
||||||
@@ -801,6 +827,319 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isPeripheralSupported(): Boolean {
|
||||||
|
val adapter = bluetoothManager.adapter ?: return false
|
||||||
|
return adapter.isEnabled && adapter.isMultipleAdvertisementSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun startPeripheral(
|
||||||
|
config: UniversalBlePeripheralConfig,
|
||||||
|
callback: (Result<Unit>) -> Unit,
|
||||||
|
) {
|
||||||
|
val adapter = bluetoothManager.adapter
|
||||||
|
if (adapter == null || !adapter.isEnabled) {
|
||||||
|
callback(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.BLUETOOTH_NOT_ENABLED,
|
||||||
|
"Bluetooth not enabled"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!adapter.isMultipleAdvertisementSupported) {
|
||||||
|
callback(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.NOT_SUPPORTED,
|
||||||
|
"BLE peripheral advertising is not supported on this device"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (peripheralPendingStartCallback != null) {
|
||||||
|
callback(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.OPERATION_IN_PROGRESS,
|
||||||
|
"Peripheral start already in progress"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stopPeripheralInternal()
|
||||||
|
|
||||||
|
val server = bluetoothManager.openGattServer(context, peripheralGattServerCallback)
|
||||||
|
if (server == null) {
|
||||||
|
callback(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.FAILED,
|
||||||
|
"Unable to open GATT server"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
peripheralCharacteristics.clear()
|
||||||
|
config.services.forEach { serviceConfig ->
|
||||||
|
val service = BluetoothGattService(
|
||||||
|
UUID.fromString(serviceConfig.uuid),
|
||||||
|
BluetoothGattService.SERVICE_TYPE_PRIMARY,
|
||||||
|
)
|
||||||
|
serviceConfig.characteristics.forEach { characteristicConfig ->
|
||||||
|
val characteristic = BluetoothGattCharacteristic(
|
||||||
|
UUID.fromString(characteristicConfig.uuid),
|
||||||
|
characteristicConfig.properties.toPeripheralPropertyFlags(),
|
||||||
|
characteristicConfig.permissions.toPeripheralPermissionFlags(),
|
||||||
|
)
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
characteristic.value = characteristicConfig.initialValue ?: ByteArray(0)
|
||||||
|
characteristicConfig.descriptors.forEach { descriptorConfig ->
|
||||||
|
val descriptor = BluetoothGattDescriptor(
|
||||||
|
UUID.fromString(descriptorConfig.uuid),
|
||||||
|
descriptorConfig.permissions.toPeripheralPermissionFlags(),
|
||||||
|
)
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
descriptor.value = descriptorConfig.initialValue ?: ByteArray(0)
|
||||||
|
characteristic.addDescriptor(descriptor)
|
||||||
|
}
|
||||||
|
if (characteristicConfig.properties.any {
|
||||||
|
it == CharacteristicProperty.Notify.value ||
|
||||||
|
it == CharacteristicProperty.Indicate.value
|
||||||
|
} && characteristic.getDescriptor(ccdCharacteristic) == null
|
||||||
|
) {
|
||||||
|
characteristic.addDescriptor(
|
||||||
|
BluetoothGattDescriptor(
|
||||||
|
ccdCharacteristic,
|
||||||
|
BluetoothGattDescriptor.PERMISSION_READ or
|
||||||
|
BluetoothGattDescriptor.PERMISSION_WRITE,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
service.addCharacteristic(characteristic)
|
||||||
|
peripheralCharacteristics[peripheralCharacteristicKey(serviceConfig.uuid, characteristicConfig.uuid)] = characteristic
|
||||||
|
}
|
||||||
|
if (!server.addService(service)) {
|
||||||
|
throw createFlutterError(
|
||||||
|
UniversalBleErrorCode.FAILED,
|
||||||
|
"Failed to add GATT service ${serviceConfig.uuid}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: FlutterError) {
|
||||||
|
server.close()
|
||||||
|
peripheralCharacteristics.clear()
|
||||||
|
callback(Result.failure(e))
|
||||||
|
return
|
||||||
|
} catch (e: Exception) {
|
||||||
|
server.close()
|
||||||
|
peripheralCharacteristics.clear()
|
||||||
|
callback(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.FAILED,
|
||||||
|
"Failed to create GATT services",
|
||||||
|
e.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
peripheralGattServer = server
|
||||||
|
try {
|
||||||
|
adapter.name = config.advertisedName
|
||||||
|
} catch (_: SecurityException) {
|
||||||
|
}
|
||||||
|
|
||||||
|
val advertiser = adapter.bluetoothLeAdvertiser
|
||||||
|
if (advertiser == null) {
|
||||||
|
stopPeripheralInternal()
|
||||||
|
callback(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.NOT_SUPPORTED,
|
||||||
|
"BLE advertiser not available"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val settings = AdvertiseSettings.Builder()
|
||||||
|
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
|
||||||
|
.setConnectable(true)
|
||||||
|
.setTimeout(0)
|
||||||
|
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
|
||||||
|
.build()
|
||||||
|
val dataBuilder = AdvertiseData.Builder().setIncludeDeviceName(true)
|
||||||
|
config.services.forEach { service ->
|
||||||
|
dataBuilder.addServiceUuid(ParcelUuid(UUID.fromString(service.uuid)))
|
||||||
|
}
|
||||||
|
peripheralAdvertiser = advertiser
|
||||||
|
peripheralPendingStartCallback = callback
|
||||||
|
advertiser.startAdvertising(settings, dataBuilder.build(), peripheralAdvertiseCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopPeripheral(callback: (Result<Unit>) -> Unit) {
|
||||||
|
peripheralPendingStartCallback?.invoke(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.OPERATION_CANCELLED,
|
||||||
|
"Peripheral start cancelled"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
peripheralPendingStartCallback = null
|
||||||
|
stopPeripheralInternal()
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updatePeripheralCharacteristicValue(
|
||||||
|
service: String,
|
||||||
|
characteristic: String,
|
||||||
|
value: ByteArray,
|
||||||
|
callback: (Result<Unit>) -> Unit,
|
||||||
|
) {
|
||||||
|
val gattCharacteristic = peripheralCharacteristics[peripheralCharacteristicKey(service, characteristic)]
|
||||||
|
if (gattCharacteristic == null) {
|
||||||
|
callback(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.CHARACTERISTIC_NOT_FOUND,
|
||||||
|
"Unknown peripheral characteristic $characteristic"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
gattCharacteristic.value = value
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun notifyPeripheralCharacteristic(
|
||||||
|
service: String,
|
||||||
|
characteristic: String,
|
||||||
|
value: ByteArray,
|
||||||
|
indicate: Boolean,
|
||||||
|
callback: (Result<Unit>) -> Unit,
|
||||||
|
) {
|
||||||
|
val server = peripheralGattServer
|
||||||
|
val gattCharacteristic = peripheralCharacteristics[peripheralCharacteristicKey(service, characteristic)]
|
||||||
|
if (server == null || gattCharacteristic == null) {
|
||||||
|
callback(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.CHARACTERISTIC_NOT_FOUND,
|
||||||
|
"Unknown peripheral characteristic $characteristic"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
gattCharacteristic.value = value
|
||||||
|
val devices = synchronized(peripheralConnectedDevices) {
|
||||||
|
peripheralConnectedDevices.toList()
|
||||||
|
}
|
||||||
|
devices.forEach { device ->
|
||||||
|
server.notifyCharacteristicChanged(device, gattCharacteristic, indicate)
|
||||||
|
}
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopPeripheralInternal() {
|
||||||
|
peripheralAdvertiser?.stopAdvertising(peripheralAdvertiseCallback)
|
||||||
|
peripheralAdvertiser = null
|
||||||
|
peripheralGattServer?.close()
|
||||||
|
peripheralGattServer = null
|
||||||
|
synchronized(peripheralConnectedDevices) {
|
||||||
|
peripheralConnectedDevices.clear()
|
||||||
|
}
|
||||||
|
peripheralCharacteristics.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun peripheralCharacteristicKey(service: String, characteristic: String): String {
|
||||||
|
return "${service.lowercase()}|${characteristic.lowercase()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<Long>.toPeripheralPropertyFlags(): Int {
|
||||||
|
var flags = 0
|
||||||
|
forEach { property ->
|
||||||
|
when (CharacteristicProperty.entries.firstOrNull { it.value == property }) {
|
||||||
|
CharacteristicProperty.Broadcast -> flags = flags or BluetoothGattCharacteristic.PROPERTY_BROADCAST
|
||||||
|
CharacteristicProperty.Read -> flags = flags or BluetoothGattCharacteristic.PROPERTY_READ
|
||||||
|
CharacteristicProperty.WriteWithoutResponse -> flags = flags or BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE
|
||||||
|
CharacteristicProperty.Write -> flags = flags or BluetoothGattCharacteristic.PROPERTY_WRITE
|
||||||
|
CharacteristicProperty.Notify -> flags = flags or BluetoothGattCharacteristic.PROPERTY_NOTIFY
|
||||||
|
CharacteristicProperty.Indicate -> flags = flags or BluetoothGattCharacteristic.PROPERTY_INDICATE
|
||||||
|
CharacteristicProperty.AuthenticatedSignedWrites -> flags = flags or BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE
|
||||||
|
CharacteristicProperty.ExtendedProperties -> flags = flags or BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS
|
||||||
|
null -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<Long>.toPeripheralPermissionFlags(): Int {
|
||||||
|
var flags = 0
|
||||||
|
forEach { permission ->
|
||||||
|
when (permission) {
|
||||||
|
0L -> flags = flags or BluetoothGattCharacteristic.PERMISSION_READ
|
||||||
|
1L -> flags = flags or BluetoothGattCharacteristic.PERMISSION_WRITE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun callbackPeripheralConnection(deviceId: String, connected: Boolean) {
|
||||||
|
mainThreadHandler?.post {
|
||||||
|
callbackChannel?.onPeripheralConnectionChanged(deviceId, connected) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun callbackPeripheralSubscription(
|
||||||
|
deviceId: String,
|
||||||
|
service: String,
|
||||||
|
characteristic: String,
|
||||||
|
subscribed: Boolean,
|
||||||
|
) {
|
||||||
|
mainThreadHandler?.post {
|
||||||
|
callbackChannel?.onPeripheralSubscriptionChanged(
|
||||||
|
deviceId,
|
||||||
|
service,
|
||||||
|
characteristic,
|
||||||
|
subscribed,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun callbackPeripheralWrite(
|
||||||
|
deviceId: String,
|
||||||
|
service: String,
|
||||||
|
characteristic: String,
|
||||||
|
value: ByteArray,
|
||||||
|
) {
|
||||||
|
mainThreadHandler?.post {
|
||||||
|
callbackChannel?.onPeripheralWrite(
|
||||||
|
UniversalBlePeripheralWriteEvent(
|
||||||
|
deviceId,
|
||||||
|
service,
|
||||||
|
characteristic,
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) {
|
override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) {
|
||||||
val deviceId = gatt?.device?.address ?: return
|
val deviceId = gatt?.device?.address ?: return
|
||||||
mtuResultFutureList.removeAll {
|
mtuResultFutureList.removeAll {
|
||||||
@@ -1191,6 +1530,157 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val peripheralAdvertiseCallback = object : AdvertiseCallback() {
|
||||||
|
override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {
|
||||||
|
peripheralPendingStartCallback?.invoke(Result.success(Unit))
|
||||||
|
peripheralPendingStartCallback = null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartFailure(errorCode: Int) {
|
||||||
|
peripheralPendingStartCallback?.invoke(
|
||||||
|
Result.failure(
|
||||||
|
createFlutterError(
|
||||||
|
UniversalBleErrorCode.FAILED,
|
||||||
|
"BLE advertising failed with code $errorCode",
|
||||||
|
errorCode.toString()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
peripheralPendingStartCallback = null
|
||||||
|
stopPeripheralInternal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val peripheralGattServerCallback = object : BluetoothGattServerCallback() {
|
||||||
|
override fun onConnectionStateChange(device: BluetoothDevice, status: Int, newState: Int) {
|
||||||
|
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||||
|
synchronized(peripheralConnectedDevices) {
|
||||||
|
peripheralConnectedDevices.add(device)
|
||||||
|
}
|
||||||
|
callbackPeripheralConnection(device.address, true)
|
||||||
|
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||||
|
synchronized(peripheralConnectedDevices) {
|
||||||
|
peripheralConnectedDevices.remove(device)
|
||||||
|
}
|
||||||
|
callbackPeripheralConnection(device.address, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCharacteristicReadRequest(
|
||||||
|
device: BluetoothDevice,
|
||||||
|
requestId: Int,
|
||||||
|
offset: Int,
|
||||||
|
characteristic: BluetoothGattCharacteristic,
|
||||||
|
) {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val value = characteristic.value ?: ByteArray(0)
|
||||||
|
if (offset > value.size) {
|
||||||
|
peripheralGattServer?.sendResponse(
|
||||||
|
device,
|
||||||
|
requestId,
|
||||||
|
BluetoothGatt.GATT_INVALID_OFFSET,
|
||||||
|
offset,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
peripheralGattServer?.sendResponse(
|
||||||
|
device,
|
||||||
|
requestId,
|
||||||
|
BluetoothGatt.GATT_SUCCESS,
|
||||||
|
offset,
|
||||||
|
value.copyOfRange(offset, value.size),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCharacteristicWriteRequest(
|
||||||
|
device: BluetoothDevice,
|
||||||
|
requestId: Int,
|
||||||
|
characteristic: BluetoothGattCharacteristic,
|
||||||
|
preparedWrite: Boolean,
|
||||||
|
responseNeeded: Boolean,
|
||||||
|
offset: Int,
|
||||||
|
value: ByteArray,
|
||||||
|
) {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
characteristic.value = value
|
||||||
|
if (responseNeeded) {
|
||||||
|
peripheralGattServer?.sendResponse(
|
||||||
|
device,
|
||||||
|
requestId,
|
||||||
|
BluetoothGatt.GATT_SUCCESS,
|
||||||
|
offset,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
callbackPeripheralWrite(
|
||||||
|
device.address,
|
||||||
|
characteristic.service.uuid.toString(),
|
||||||
|
characteristic.uuid.toString(),
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDescriptorReadRequest(
|
||||||
|
device: BluetoothDevice,
|
||||||
|
requestId: Int,
|
||||||
|
offset: Int,
|
||||||
|
descriptor: BluetoothGattDescriptor,
|
||||||
|
) {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val value = descriptor.value ?: ByteArray(0)
|
||||||
|
if (offset > value.size) {
|
||||||
|
peripheralGattServer?.sendResponse(
|
||||||
|
device,
|
||||||
|
requestId,
|
||||||
|
BluetoothGatt.GATT_INVALID_OFFSET,
|
||||||
|
offset,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
peripheralGattServer?.sendResponse(
|
||||||
|
device,
|
||||||
|
requestId,
|
||||||
|
BluetoothGatt.GATT_SUCCESS,
|
||||||
|
offset,
|
||||||
|
value.copyOfRange(offset, value.size),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDescriptorWriteRequest(
|
||||||
|
device: BluetoothDevice,
|
||||||
|
requestId: Int,
|
||||||
|
descriptor: BluetoothGattDescriptor,
|
||||||
|
preparedWrite: Boolean,
|
||||||
|
responseNeeded: Boolean,
|
||||||
|
offset: Int,
|
||||||
|
value: ByteArray,
|
||||||
|
) {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
descriptor.value = value
|
||||||
|
if (responseNeeded) {
|
||||||
|
peripheralGattServer?.sendResponse(
|
||||||
|
device,
|
||||||
|
requestId,
|
||||||
|
BluetoothGatt.GATT_SUCCESS,
|
||||||
|
offset,
|
||||||
|
null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (descriptor.uuid == ccdCharacteristic) {
|
||||||
|
val subscribed = value.contentEquals(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE) ||
|
||||||
|
value.contentEquals(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)
|
||||||
|
callbackPeripheralSubscription(
|
||||||
|
device.address,
|
||||||
|
descriptor.characteristic.service.uuid.toString(),
|
||||||
|
descriptor.characteristic.uuid.toString(),
|
||||||
|
subscribed,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onConnectionStateChange(
|
override fun onConnectionStateChange(
|
||||||
gatt: BluetoothGatt,
|
gatt: BluetoothGatt,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.4), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.4), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
@@ -50,7 +50,7 @@ private func wrapError(_ error: Any) -> [Any?] {
|
|||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
"\(error)",
|
"\(error)",
|
||||||
"\(type(of: error))",
|
"\(Swift.type(of: error))",
|
||||||
"Stacktrace: \(Thread.callStackSymbols)",
|
"Stacktrace: \(Thread.callStackSymbols)",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -68,6 +68,19 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
|
|||||||
return value as! T?
|
return value as! T?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func doubleEqualsUniversalBle(_ lhs: Double, _ rhs: Double) -> Bool {
|
||||||
|
return (lhs.isNaN && rhs.isNaN) || lhs == rhs
|
||||||
|
}
|
||||||
|
|
||||||
|
private func doubleHashUniversalBle(_ value: Double, _ hasher: inout Hasher) {
|
||||||
|
if value.isNaN {
|
||||||
|
hasher.combine(0x7FF8000000000000)
|
||||||
|
} else {
|
||||||
|
// Normalize -0.0 to 0.0
|
||||||
|
hasher.combine(value == 0 ? 0 : value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func deepEqualsUniversalBle(_ lhs: Any?, _ rhs: Any?) -> Bool {
|
func deepEqualsUniversalBle(_ lhs: Any?, _ rhs: Any?) -> Bool {
|
||||||
let cleanLhs = nilOrValue(lhs) as Any?
|
let cleanLhs = nilOrValue(lhs) as Any?
|
||||||
let cleanRhs = nilOrValue(rhs) as Any?
|
let cleanRhs = nilOrValue(rhs) as Any?
|
||||||
@@ -78,58 +91,91 @@ func deepEqualsUniversalBle(_ lhs: Any?, _ rhs: Any?) -> Bool {
|
|||||||
case (nil, _), (_, nil):
|
case (nil, _), (_, nil):
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs:
|
||||||
|
return true
|
||||||
|
|
||||||
case is (Void, Void):
|
case is (Void, Void):
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case let (cleanLhsHashable, cleanRhsHashable) as (AnyHashable, AnyHashable):
|
case (let lhsArray, let rhsArray) as ([Any?], [Any?]):
|
||||||
return cleanLhsHashable == cleanRhsHashable
|
guard lhsArray.count == rhsArray.count else { return false }
|
||||||
|
for (index, element) in lhsArray.enumerated() {
|
||||||
case let (cleanLhsArray, cleanRhsArray) as ([Any?], [Any?]):
|
if !deepEqualsUniversalBle(element, rhsArray[index]) {
|
||||||
guard cleanLhsArray.count == cleanRhsArray.count else { return false }
|
|
||||||
for (index, element) in cleanLhsArray.enumerated() {
|
|
||||||
if !deepEqualsUniversalBle(element, cleanRhsArray[index]) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case let (cleanLhsDictionary, cleanRhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]):
|
case (let lhsArray, let rhsArray) as ([Double], [Double]):
|
||||||
guard cleanLhsDictionary.count == cleanRhsDictionary.count else { return false }
|
guard lhsArray.count == rhsArray.count else { return false }
|
||||||
for (key, cleanLhsValue) in cleanLhsDictionary {
|
for (index, element) in lhsArray.enumerated() {
|
||||||
guard cleanRhsDictionary.index(forKey: key) != nil else { return false }
|
if !doubleEqualsUniversalBle(element, rhsArray[index]) {
|
||||||
if !deepEqualsUniversalBle(cleanLhsValue, cleanRhsDictionary[key]!) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]):
|
||||||
|
guard lhsDictionary.count == rhsDictionary.count else { return false }
|
||||||
|
for (lhsKey, lhsValue) in lhsDictionary {
|
||||||
|
var found = false
|
||||||
|
for (rhsKey, rhsValue) in rhsDictionary {
|
||||||
|
if deepEqualsUniversalBle(lhsKey, rhsKey) {
|
||||||
|
if deepEqualsUniversalBle(lhsValue, rhsValue) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found { return false }
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
|
case (let lhs as Double, let rhs as Double):
|
||||||
|
return doubleEqualsUniversalBle(lhs, rhs)
|
||||||
|
|
||||||
|
case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable):
|
||||||
|
return lhsHashable == rhsHashable
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Any other type shouldn't be able to be used with pigeon. File an issue if you find this to be untrue.
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deepHashUniversalBle(value: Any?, hasher: inout Hasher) {
|
func deepHashUniversalBle(value: Any?, hasher: inout Hasher) {
|
||||||
if let valueList = value as? [AnyHashable] {
|
let cleanValue = nilOrValue(value) as Any?
|
||||||
for item in valueList { deepHashUniversalBle(value: item, hasher: &hasher) }
|
if let cleanValue = cleanValue {
|
||||||
return
|
if let doubleValue = cleanValue as? Double {
|
||||||
|
doubleHashUniversalBle(doubleValue, &hasher)
|
||||||
|
} else if let valueList = cleanValue as? [Any?] {
|
||||||
|
for item in valueList {
|
||||||
|
deepHashUniversalBle(value: item, hasher: &hasher)
|
||||||
}
|
}
|
||||||
|
} else if let valueList = cleanValue as? [Double] {
|
||||||
if let valueDict = value as? [AnyHashable: AnyHashable] {
|
for item in valueList {
|
||||||
for key in valueDict.keys {
|
doubleHashUniversalBle(item, &hasher)
|
||||||
hasher.combine(key)
|
|
||||||
deepHashUniversalBle(value: valueDict[key]!, hasher: &hasher)
|
|
||||||
}
|
}
|
||||||
return
|
} else if let valueDict = cleanValue as? [AnyHashable: Any?] {
|
||||||
|
var result = 0
|
||||||
|
for (key, value) in valueDict {
|
||||||
|
var entryKeyHasher = Hasher()
|
||||||
|
deepHashUniversalBle(value: key, hasher: &entryKeyHasher)
|
||||||
|
var entryValueHasher = Hasher()
|
||||||
|
deepHashUniversalBle(value: value, hasher: &entryValueHasher)
|
||||||
|
result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize())
|
||||||
}
|
}
|
||||||
|
hasher.combine(result)
|
||||||
if let hashableValue = value as? AnyHashable {
|
} else if let hashableValue = cleanValue as? AnyHashable {
|
||||||
hasher.combine(hashableValue.hashValue)
|
hasher.combine(hashableValue)
|
||||||
|
} else {
|
||||||
|
hasher.combine(String(describing: cleanValue))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasher.combine(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasher.combine(String(describing: value))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum UniversalBleLogLevel: Int {
|
enum UniversalBleLogLevel: Int {
|
||||||
@@ -261,9 +307,22 @@ struct UniversalBleScanResult: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: UniversalBleScanResult, rhs: UniversalBleScanResult) -> Bool {
|
static func == (lhs: UniversalBleScanResult, rhs: UniversalBleScanResult) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.deviceId, rhs.deviceId) && deepEqualsUniversalBle(lhs.name, rhs.name) && deepEqualsUniversalBle(lhs.isPaired, rhs.isPaired) && deepEqualsUniversalBle(lhs.rssi, rhs.rssi) && deepEqualsUniversalBle(lhs.manufacturerDataList, rhs.manufacturerDataList) && deepEqualsUniversalBle(lhs.serviceData, rhs.serviceData) && deepEqualsUniversalBle(lhs.services, rhs.services) && deepEqualsUniversalBle(lhs.timestamp, rhs.timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("UniversalBleScanResult")
|
||||||
|
deepHashUniversalBle(value: deviceId, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: name, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: isPaired, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: rssi, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: manufacturerDataList, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: serviceData, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: services, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: timestamp, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,9 +349,16 @@ struct UniversalBleService: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: UniversalBleService, rhs: UniversalBleService) -> Bool {
|
static func == (lhs: UniversalBleService, rhs: UniversalBleService) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.uuid, rhs.uuid) && deepEqualsUniversalBle(lhs.characteristics, rhs.characteristics)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("UniversalBleService")
|
||||||
|
deepHashUniversalBle(value: uuid, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: characteristics, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,9 +389,17 @@ struct UniversalBleCharacteristic: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: UniversalBleCharacteristic, rhs: UniversalBleCharacteristic) -> Bool {
|
static func == (lhs: UniversalBleCharacteristic, rhs: UniversalBleCharacteristic) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.uuid, rhs.uuid) && deepEqualsUniversalBle(lhs.properties, rhs.properties) && deepEqualsUniversalBle(lhs.descriptors, rhs.descriptors)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("UniversalBleCharacteristic")
|
||||||
|
deepHashUniversalBle(value: uuid, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: properties, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: descriptors, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,9 +422,225 @@ struct UniversalBleDescriptor: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: UniversalBleDescriptor, rhs: UniversalBleDescriptor) -> Bool {
|
static func == (lhs: UniversalBleDescriptor, rhs: UniversalBleDescriptor) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.uuid, rhs.uuid)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("UniversalBleDescriptor")
|
||||||
|
deepHashUniversalBle(value: uuid, hasher: &hasher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
struct UniversalBlePeripheralConfig: Hashable {
|
||||||
|
var advertisedName: String
|
||||||
|
var services: [UniversalBlePeripheralService]
|
||||||
|
|
||||||
|
|
||||||
|
// swift-format-ignore: AlwaysUseLowerCamelCase
|
||||||
|
static func fromList(_ pigeonVar_list: [Any?]) -> UniversalBlePeripheralConfig? {
|
||||||
|
let advertisedName = pigeonVar_list[0] as! String
|
||||||
|
let services = pigeonVar_list[1] as! [UniversalBlePeripheralService]
|
||||||
|
|
||||||
|
return UniversalBlePeripheralConfig(
|
||||||
|
advertisedName: advertisedName,
|
||||||
|
services: services
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func toList() -> [Any?] {
|
||||||
|
return [
|
||||||
|
advertisedName,
|
||||||
|
services,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
static func == (lhs: UniversalBlePeripheralConfig, rhs: UniversalBlePeripheralConfig) -> Bool {
|
||||||
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.advertisedName, rhs.advertisedName) && deepEqualsUniversalBle(lhs.services, rhs.services)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine("UniversalBlePeripheralConfig")
|
||||||
|
deepHashUniversalBle(value: advertisedName, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: services, hasher: &hasher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
struct UniversalBlePeripheralService: Hashable {
|
||||||
|
var uuid: String
|
||||||
|
var characteristics: [UniversalBlePeripheralCharacteristic]
|
||||||
|
|
||||||
|
|
||||||
|
// swift-format-ignore: AlwaysUseLowerCamelCase
|
||||||
|
static func fromList(_ pigeonVar_list: [Any?]) -> UniversalBlePeripheralService? {
|
||||||
|
let uuid = pigeonVar_list[0] as! String
|
||||||
|
let characteristics = pigeonVar_list[1] as! [UniversalBlePeripheralCharacteristic]
|
||||||
|
|
||||||
|
return UniversalBlePeripheralService(
|
||||||
|
uuid: uuid,
|
||||||
|
characteristics: characteristics
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func toList() -> [Any?] {
|
||||||
|
return [
|
||||||
|
uuid,
|
||||||
|
characteristics,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
static func == (lhs: UniversalBlePeripheralService, rhs: UniversalBlePeripheralService) -> Bool {
|
||||||
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.uuid, rhs.uuid) && deepEqualsUniversalBle(lhs.characteristics, rhs.characteristics)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine("UniversalBlePeripheralService")
|
||||||
|
deepHashUniversalBle(value: uuid, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: characteristics, hasher: &hasher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
struct UniversalBlePeripheralCharacteristic: Hashable {
|
||||||
|
var uuid: String
|
||||||
|
var properties: [Int64]
|
||||||
|
var permissions: [Int64]
|
||||||
|
var descriptors: [UniversalBlePeripheralDescriptor]
|
||||||
|
var initialValue: FlutterStandardTypedData? = nil
|
||||||
|
|
||||||
|
|
||||||
|
// swift-format-ignore: AlwaysUseLowerCamelCase
|
||||||
|
static func fromList(_ pigeonVar_list: [Any?]) -> UniversalBlePeripheralCharacteristic? {
|
||||||
|
let uuid = pigeonVar_list[0] as! String
|
||||||
|
let properties = pigeonVar_list[1] as! [Int64]
|
||||||
|
let permissions = pigeonVar_list[2] as! [Int64]
|
||||||
|
let descriptors = pigeonVar_list[3] as! [UniversalBlePeripheralDescriptor]
|
||||||
|
let initialValue: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[4])
|
||||||
|
|
||||||
|
return UniversalBlePeripheralCharacteristic(
|
||||||
|
uuid: uuid,
|
||||||
|
properties: properties,
|
||||||
|
permissions: permissions,
|
||||||
|
descriptors: descriptors,
|
||||||
|
initialValue: initialValue
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func toList() -> [Any?] {
|
||||||
|
return [
|
||||||
|
uuid,
|
||||||
|
properties,
|
||||||
|
permissions,
|
||||||
|
descriptors,
|
||||||
|
initialValue,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
static func == (lhs: UniversalBlePeripheralCharacteristic, rhs: UniversalBlePeripheralCharacteristic) -> Bool {
|
||||||
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.uuid, rhs.uuid) && deepEqualsUniversalBle(lhs.properties, rhs.properties) && deepEqualsUniversalBle(lhs.permissions, rhs.permissions) && deepEqualsUniversalBle(lhs.descriptors, rhs.descriptors) && deepEqualsUniversalBle(lhs.initialValue, rhs.initialValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine("UniversalBlePeripheralCharacteristic")
|
||||||
|
deepHashUniversalBle(value: uuid, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: properties, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: permissions, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: descriptors, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: initialValue, hasher: &hasher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
struct UniversalBlePeripheralDescriptor: Hashable {
|
||||||
|
var uuid: String
|
||||||
|
var permissions: [Int64]
|
||||||
|
var initialValue: FlutterStandardTypedData? = nil
|
||||||
|
|
||||||
|
|
||||||
|
// swift-format-ignore: AlwaysUseLowerCamelCase
|
||||||
|
static func fromList(_ pigeonVar_list: [Any?]) -> UniversalBlePeripheralDescriptor? {
|
||||||
|
let uuid = pigeonVar_list[0] as! String
|
||||||
|
let permissions = pigeonVar_list[1] as! [Int64]
|
||||||
|
let initialValue: FlutterStandardTypedData? = nilOrValue(pigeonVar_list[2])
|
||||||
|
|
||||||
|
return UniversalBlePeripheralDescriptor(
|
||||||
|
uuid: uuid,
|
||||||
|
permissions: permissions,
|
||||||
|
initialValue: initialValue
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func toList() -> [Any?] {
|
||||||
|
return [
|
||||||
|
uuid,
|
||||||
|
permissions,
|
||||||
|
initialValue,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
static func == (lhs: UniversalBlePeripheralDescriptor, rhs: UniversalBlePeripheralDescriptor) -> Bool {
|
||||||
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.uuid, rhs.uuid) && deepEqualsUniversalBle(lhs.permissions, rhs.permissions) && deepEqualsUniversalBle(lhs.initialValue, rhs.initialValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine("UniversalBlePeripheralDescriptor")
|
||||||
|
deepHashUniversalBle(value: uuid, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: permissions, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: initialValue, hasher: &hasher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
struct UniversalBlePeripheralWriteEvent: Hashable {
|
||||||
|
var deviceId: String
|
||||||
|
var service: String
|
||||||
|
var characteristic: String
|
||||||
|
var value: FlutterStandardTypedData
|
||||||
|
|
||||||
|
|
||||||
|
// swift-format-ignore: AlwaysUseLowerCamelCase
|
||||||
|
static func fromList(_ pigeonVar_list: [Any?]) -> UniversalBlePeripheralWriteEvent? {
|
||||||
|
let deviceId = pigeonVar_list[0] as! String
|
||||||
|
let service = pigeonVar_list[1] as! String
|
||||||
|
let characteristic = pigeonVar_list[2] as! String
|
||||||
|
let value = pigeonVar_list[3] as! FlutterStandardTypedData
|
||||||
|
|
||||||
|
return UniversalBlePeripheralWriteEvent(
|
||||||
|
deviceId: deviceId,
|
||||||
|
service: service,
|
||||||
|
characteristic: characteristic,
|
||||||
|
value: value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func toList() -> [Any?] {
|
||||||
|
return [
|
||||||
|
deviceId,
|
||||||
|
service,
|
||||||
|
characteristic,
|
||||||
|
value,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
static func == (lhs: UniversalBlePeripheralWriteEvent, rhs: UniversalBlePeripheralWriteEvent) -> Bool {
|
||||||
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.deviceId, rhs.deviceId) && deepEqualsUniversalBle(lhs.service, rhs.service) && deepEqualsUniversalBle(lhs.characteristic, rhs.characteristic) && deepEqualsUniversalBle(lhs.value, rhs.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine("UniversalBlePeripheralWriteEvent")
|
||||||
|
deepHashUniversalBle(value: deviceId, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: service, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: characteristic, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: value, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,9 +678,17 @@ struct AndroidOptions: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: AndroidOptions, rhs: AndroidOptions) -> Bool {
|
static func == (lhs: AndroidOptions, rhs: AndroidOptions) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.requestLocationPermission, rhs.requestLocationPermission) && deepEqualsUniversalBle(lhs.scanMode, rhs.scanMode) && deepEqualsUniversalBle(lhs.reportDelayMillis, rhs.reportDelayMillis)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("AndroidOptions")
|
||||||
|
deepHashUniversalBle(value: requestLocationPermission, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: scanMode, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: reportDelayMillis, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,9 +711,15 @@ struct UniversalScanConfig: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: UniversalScanConfig, rhs: UniversalScanConfig) -> Bool {
|
static func == (lhs: UniversalScanConfig, rhs: UniversalScanConfig) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.android, rhs.android)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("UniversalScanConfig")
|
||||||
|
deepHashUniversalBle(value: android, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,9 +752,17 @@ struct UniversalScanFilter: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: UniversalScanFilter, rhs: UniversalScanFilter) -> Bool {
|
static func == (lhs: UniversalScanFilter, rhs: UniversalScanFilter) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.withServices, rhs.withServices) && deepEqualsUniversalBle(lhs.withNamePrefix, rhs.withNamePrefix) && deepEqualsUniversalBle(lhs.withManufacturerData, rhs.withManufacturerData)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("UniversalScanFilter")
|
||||||
|
deepHashUniversalBle(value: withServices, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: withNamePrefix, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: withManufacturerData, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,9 +793,17 @@ struct UniversalManufacturerDataFilter: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: UniversalManufacturerDataFilter, rhs: UniversalManufacturerDataFilter) -> Bool {
|
static func == (lhs: UniversalManufacturerDataFilter, rhs: UniversalManufacturerDataFilter) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.companyIdentifier, rhs.companyIdentifier) && deepEqualsUniversalBle(lhs.data, rhs.data) && deepEqualsUniversalBle(lhs.mask, rhs.mask)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("UniversalManufacturerDataFilter")
|
||||||
|
deepHashUniversalBle(value: companyIdentifier, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: data, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: mask, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,9 +830,16 @@ struct UniversalManufacturerData: Hashable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: UniversalManufacturerData, rhs: UniversalManufacturerData) -> Bool {
|
static func == (lhs: UniversalManufacturerData, rhs: UniversalManufacturerData) -> Bool {
|
||||||
return deepEqualsUniversalBle(lhs.toList(), rhs.toList()) }
|
if Swift.type(of: lhs) != Swift.type(of: rhs) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return deepEqualsUniversalBle(lhs.companyIdentifier, rhs.companyIdentifier) && deepEqualsUniversalBle(lhs.data, rhs.data)
|
||||||
|
}
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
deepHashUniversalBle(value: toList(), hasher: &hasher)
|
hasher.combine("UniversalManufacturerData")
|
||||||
|
deepHashUniversalBle(value: companyIdentifier, hasher: &hasher)
|
||||||
|
deepHashUniversalBle(value: data, hasher: &hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,14 +873,24 @@ private class UniversalBlePigeonCodecReader: FlutterStandardReader {
|
|||||||
case 135:
|
case 135:
|
||||||
return UniversalBleDescriptor.fromList(self.readValue() as! [Any?])
|
return UniversalBleDescriptor.fromList(self.readValue() as! [Any?])
|
||||||
case 136:
|
case 136:
|
||||||
return AndroidOptions.fromList(self.readValue() as! [Any?])
|
return UniversalBlePeripheralConfig.fromList(self.readValue() as! [Any?])
|
||||||
case 137:
|
case 137:
|
||||||
return UniversalScanConfig.fromList(self.readValue() as! [Any?])
|
return UniversalBlePeripheralService.fromList(self.readValue() as! [Any?])
|
||||||
case 138:
|
case 138:
|
||||||
return UniversalScanFilter.fromList(self.readValue() as! [Any?])
|
return UniversalBlePeripheralCharacteristic.fromList(self.readValue() as! [Any?])
|
||||||
case 139:
|
case 139:
|
||||||
return UniversalManufacturerDataFilter.fromList(self.readValue() as! [Any?])
|
return UniversalBlePeripheralDescriptor.fromList(self.readValue() as! [Any?])
|
||||||
case 140:
|
case 140:
|
||||||
|
return UniversalBlePeripheralWriteEvent.fromList(self.readValue() as! [Any?])
|
||||||
|
case 141:
|
||||||
|
return AndroidOptions.fromList(self.readValue() as! [Any?])
|
||||||
|
case 142:
|
||||||
|
return UniversalScanConfig.fromList(self.readValue() as! [Any?])
|
||||||
|
case 143:
|
||||||
|
return UniversalScanFilter.fromList(self.readValue() as! [Any?])
|
||||||
|
case 144:
|
||||||
|
return UniversalManufacturerDataFilter.fromList(self.readValue() as! [Any?])
|
||||||
|
case 145:
|
||||||
return UniversalManufacturerData.fromList(self.readValue() as! [Any?])
|
return UniversalManufacturerData.fromList(self.readValue() as! [Any?])
|
||||||
default:
|
default:
|
||||||
return super.readValue(ofType: type)
|
return super.readValue(ofType: type)
|
||||||
@@ -584,21 +921,36 @@ private class UniversalBlePigeonCodecWriter: FlutterStandardWriter {
|
|||||||
} else if let value = value as? UniversalBleDescriptor {
|
} else if let value = value as? UniversalBleDescriptor {
|
||||||
super.writeByte(135)
|
super.writeByte(135)
|
||||||
super.writeValue(value.toList())
|
super.writeValue(value.toList())
|
||||||
} else if let value = value as? AndroidOptions {
|
} else if let value = value as? UniversalBlePeripheralConfig {
|
||||||
super.writeByte(136)
|
super.writeByte(136)
|
||||||
super.writeValue(value.toList())
|
super.writeValue(value.toList())
|
||||||
} else if let value = value as? UniversalScanConfig {
|
} else if let value = value as? UniversalBlePeripheralService {
|
||||||
super.writeByte(137)
|
super.writeByte(137)
|
||||||
super.writeValue(value.toList())
|
super.writeValue(value.toList())
|
||||||
} else if let value = value as? UniversalScanFilter {
|
} else if let value = value as? UniversalBlePeripheralCharacteristic {
|
||||||
super.writeByte(138)
|
super.writeByte(138)
|
||||||
super.writeValue(value.toList())
|
super.writeValue(value.toList())
|
||||||
} else if let value = value as? UniversalManufacturerDataFilter {
|
} else if let value = value as? UniversalBlePeripheralDescriptor {
|
||||||
super.writeByte(139)
|
super.writeByte(139)
|
||||||
super.writeValue(value.toList())
|
super.writeValue(value.toList())
|
||||||
} else if let value = value as? UniversalManufacturerData {
|
} else if let value = value as? UniversalBlePeripheralWriteEvent {
|
||||||
super.writeByte(140)
|
super.writeByte(140)
|
||||||
super.writeValue(value.toList())
|
super.writeValue(value.toList())
|
||||||
|
} else if let value = value as? AndroidOptions {
|
||||||
|
super.writeByte(141)
|
||||||
|
super.writeValue(value.toList())
|
||||||
|
} else if let value = value as? UniversalScanConfig {
|
||||||
|
super.writeByte(142)
|
||||||
|
super.writeValue(value.toList())
|
||||||
|
} else if let value = value as? UniversalScanFilter {
|
||||||
|
super.writeByte(143)
|
||||||
|
super.writeValue(value.toList())
|
||||||
|
} else if let value = value as? UniversalManufacturerDataFilter {
|
||||||
|
super.writeByte(144)
|
||||||
|
super.writeValue(value.toList())
|
||||||
|
} else if let value = value as? UniversalManufacturerData {
|
||||||
|
super.writeByte(145)
|
||||||
|
super.writeValue(value.toList())
|
||||||
} else {
|
} else {
|
||||||
super.writeValue(value)
|
super.writeValue(value)
|
||||||
}
|
}
|
||||||
@@ -625,8 +977,8 @@ class UniversalBlePigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable
|
|||||||
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
|
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
|
||||||
protocol UniversalBlePlatformChannel {
|
protocol UniversalBlePlatformChannel {
|
||||||
func getBluetoothAvailabilityState(completion: @escaping (Result<Int64, Error>) -> Void)
|
func getBluetoothAvailabilityState(completion: @escaping (Result<Int64, Error>) -> Void)
|
||||||
func hasPermissions(withAndroidFineLocation: Bool) throws -> Bool
|
func hasPermissions(withAndroidFineLocation: Bool, withAndroidBluetoothAdvertise: Bool) throws -> Bool
|
||||||
func requestPermissions(withAndroidFineLocation: Bool, completion: @escaping (Result<Void, Error>) -> Void)
|
func requestPermissions(withAndroidFineLocation: Bool, withAndroidBluetoothAdvertise: Bool, completion: @escaping (Result<Void, Error>) -> Void)
|
||||||
func enableBluetooth(completion: @escaping (Result<Bool, Error>) -> Void)
|
func enableBluetooth(completion: @escaping (Result<Bool, Error>) -> Void)
|
||||||
func disableBluetooth(completion: @escaping (Result<Bool, Error>) -> Void)
|
func disableBluetooth(completion: @escaping (Result<Bool, Error>) -> Void)
|
||||||
func startScan(filter: UniversalScanFilter?, config: UniversalScanConfig?) throws
|
func startScan(filter: UniversalScanFilter?, config: UniversalScanConfig?) throws
|
||||||
@@ -646,6 +998,11 @@ protocol UniversalBlePlatformChannel {
|
|||||||
func getConnectionState(deviceId: String) throws -> Int64
|
func getConnectionState(deviceId: String) throws -> Int64
|
||||||
func readRssi(deviceId: String, completion: @escaping (Result<Int64, Error>) -> Void)
|
func readRssi(deviceId: String, completion: @escaping (Result<Int64, Error>) -> Void)
|
||||||
func requestConnectionPriority(deviceId: String, priority: Int64, completion: @escaping (Result<Void, Error>) -> Void)
|
func requestConnectionPriority(deviceId: String, priority: Int64, completion: @escaping (Result<Void, Error>) -> Void)
|
||||||
|
func isPeripheralSupported() throws -> Bool
|
||||||
|
func startPeripheral(config: UniversalBlePeripheralConfig, completion: @escaping (Result<Void, Error>) -> Void)
|
||||||
|
func stopPeripheral(completion: @escaping (Result<Void, Error>) -> Void)
|
||||||
|
func updatePeripheralCharacteristicValue(service: String, characteristic: String, value: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void)
|
||||||
|
func notifyPeripheralCharacteristic(service: String, characteristic: String, value: FlutterStandardTypedData, indicate: Bool, completion: @escaping (Result<Void, Error>) -> Void)
|
||||||
func setLogLevel(logLevel: UniversalBleLogLevel) throws
|
func setLogLevel(logLevel: UniversalBleLogLevel) throws
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,8 +1032,9 @@ class UniversalBlePlatformChannelSetup {
|
|||||||
hasPermissionsChannel.setMessageHandler { message, reply in
|
hasPermissionsChannel.setMessageHandler { message, reply in
|
||||||
let args = message as! [Any?]
|
let args = message as! [Any?]
|
||||||
let withAndroidFineLocationArg = args[0] as! Bool
|
let withAndroidFineLocationArg = args[0] as! Bool
|
||||||
|
let withAndroidBluetoothAdvertiseArg = args[1] as! Bool
|
||||||
do {
|
do {
|
||||||
let result = try api.hasPermissions(withAndroidFineLocation: withAndroidFineLocationArg)
|
let result = try api.hasPermissions(withAndroidFineLocation: withAndroidFineLocationArg, withAndroidBluetoothAdvertise: withAndroidBluetoothAdvertiseArg)
|
||||||
reply(wrapResult(result))
|
reply(wrapResult(result))
|
||||||
} catch {
|
} catch {
|
||||||
reply(wrapError(error))
|
reply(wrapError(error))
|
||||||
@@ -690,7 +1048,8 @@ class UniversalBlePlatformChannelSetup {
|
|||||||
requestPermissionsChannel.setMessageHandler { message, reply in
|
requestPermissionsChannel.setMessageHandler { message, reply in
|
||||||
let args = message as! [Any?]
|
let args = message as! [Any?]
|
||||||
let withAndroidFineLocationArg = args[0] as! Bool
|
let withAndroidFineLocationArg = args[0] as! Bool
|
||||||
api.requestPermissions(withAndroidFineLocation: withAndroidFineLocationArg) { result in
|
let withAndroidBluetoothAdvertiseArg = args[1] as! Bool
|
||||||
|
api.requestPermissions(withAndroidFineLocation: withAndroidFineLocationArg, withAndroidBluetoothAdvertise: withAndroidBluetoothAdvertiseArg) { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
reply(wrapResult(nil))
|
reply(wrapResult(nil))
|
||||||
@@ -1017,6 +1376,90 @@ class UniversalBlePlatformChannelSetup {
|
|||||||
} else {
|
} else {
|
||||||
requestConnectionPriorityChannel.setMessageHandler(nil)
|
requestConnectionPriorityChannel.setMessageHandler(nil)
|
||||||
}
|
}
|
||||||
|
let isPeripheralSupportedChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPeripheralSupported\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
if let api = api {
|
||||||
|
isPeripheralSupportedChannel.setMessageHandler { _, reply in
|
||||||
|
do {
|
||||||
|
let result = try api.isPeripheralSupported()
|
||||||
|
reply(wrapResult(result))
|
||||||
|
} catch {
|
||||||
|
reply(wrapError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isPeripheralSupportedChannel.setMessageHandler(nil)
|
||||||
|
}
|
||||||
|
let startPeripheralChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startPeripheral\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
if let api = api {
|
||||||
|
startPeripheralChannel.setMessageHandler { message, reply in
|
||||||
|
let args = message as! [Any?]
|
||||||
|
let configArg = args[0] as! UniversalBlePeripheralConfig
|
||||||
|
api.startPeripheral(config: configArg) { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
reply(wrapResult(nil))
|
||||||
|
case .failure(let error):
|
||||||
|
reply(wrapError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
startPeripheralChannel.setMessageHandler(nil)
|
||||||
|
}
|
||||||
|
let stopPeripheralChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopPeripheral\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
if let api = api {
|
||||||
|
stopPeripheralChannel.setMessageHandler { _, reply in
|
||||||
|
api.stopPeripheral { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
reply(wrapResult(nil))
|
||||||
|
case .failure(let error):
|
||||||
|
reply(wrapError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stopPeripheralChannel.setMessageHandler(nil)
|
||||||
|
}
|
||||||
|
let updatePeripheralCharacteristicValueChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.updatePeripheralCharacteristicValue\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
if let api = api {
|
||||||
|
updatePeripheralCharacteristicValueChannel.setMessageHandler { message, reply in
|
||||||
|
let args = message as! [Any?]
|
||||||
|
let serviceArg = args[0] as! String
|
||||||
|
let characteristicArg = args[1] as! String
|
||||||
|
let valueArg = args[2] as! FlutterStandardTypedData
|
||||||
|
api.updatePeripheralCharacteristicValue(service: serviceArg, characteristic: characteristicArg, value: valueArg) { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
reply(wrapResult(nil))
|
||||||
|
case .failure(let error):
|
||||||
|
reply(wrapError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updatePeripheralCharacteristicValueChannel.setMessageHandler(nil)
|
||||||
|
}
|
||||||
|
let notifyPeripheralCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.notifyPeripheralCharacteristic\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
if let api = api {
|
||||||
|
notifyPeripheralCharacteristicChannel.setMessageHandler { message, reply in
|
||||||
|
let args = message as! [Any?]
|
||||||
|
let serviceArg = args[0] as! String
|
||||||
|
let characteristicArg = args[1] as! String
|
||||||
|
let valueArg = args[2] as! FlutterStandardTypedData
|
||||||
|
let indicateArg = args[3] as! Bool
|
||||||
|
api.notifyPeripheralCharacteristic(service: serviceArg, characteristic: characteristicArg, value: valueArg, indicate: indicateArg) { result in
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
reply(wrapResult(nil))
|
||||||
|
case .failure(let error):
|
||||||
|
reply(wrapError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
notifyPeripheralCharacteristicChannel.setMessageHandler(nil)
|
||||||
|
}
|
||||||
let setLogLevelChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setLogLevel\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
let setLogLevelChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setLogLevel\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
||||||
if let api = api {
|
if let api = api {
|
||||||
setLogLevelChannel.setMessageHandler { message, reply in
|
setLogLevelChannel.setMessageHandler { message, reply in
|
||||||
@@ -1043,6 +1486,9 @@ protocol UniversalBleCallbackChannelProtocol {
|
|||||||
func onScanResult(result resultArg: UniversalBleScanResult, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
func onScanResult(result resultArg: UniversalBleScanResult, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
||||||
func onValueChanged(deviceId deviceIdArg: String, characteristicId characteristicIdArg: String, value valueArg: FlutterStandardTypedData, timestamp timestampArg: Int64?, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
func onValueChanged(deviceId deviceIdArg: String, characteristicId characteristicIdArg: String, value valueArg: FlutterStandardTypedData, timestamp timestampArg: Int64?, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
||||||
func onConnectionChanged(deviceId deviceIdArg: String, connected connectedArg: Bool, error errorArg: String?, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
func onConnectionChanged(deviceId deviceIdArg: String, connected connectedArg: Bool, error errorArg: String?, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
||||||
|
func onPeripheralConnectionChanged(deviceId deviceIdArg: String, connected connectedArg: Bool, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
||||||
|
func onPeripheralWrite(event eventArg: UniversalBlePeripheralWriteEvent, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
||||||
|
func onPeripheralSubscriptionChanged(deviceId deviceIdArg: String, service serviceArg: String, characteristic characteristicArg: String, subscribed subscribedArg: Bool, completion: @escaping (Result<Void, PigeonError>) -> Void)
|
||||||
}
|
}
|
||||||
class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol {
|
class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol {
|
||||||
private let binaryMessenger: FlutterBinaryMessenger
|
private let binaryMessenger: FlutterBinaryMessenger
|
||||||
@@ -1144,4 +1590,58 @@ class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func onPeripheralConnectionChanged(deviceId deviceIdArg: String, connected connectedArg: Bool, completion: @escaping (Result<Void, PigeonError>) -> Void) {
|
||||||
|
let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPeripheralConnectionChanged\(messageChannelSuffix)"
|
||||||
|
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
channel.sendMessage([deviceIdArg, connectedArg] 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(PigeonError(code: code, message: message, details: details)))
|
||||||
|
} else {
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func onPeripheralWrite(event eventArg: UniversalBlePeripheralWriteEvent, completion: @escaping (Result<Void, PigeonError>) -> Void) {
|
||||||
|
let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPeripheralWrite\(messageChannelSuffix)"
|
||||||
|
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
channel.sendMessage([eventArg] 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(PigeonError(code: code, message: message, details: details)))
|
||||||
|
} else {
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func onPeripheralSubscriptionChanged(deviceId deviceIdArg: String, service serviceArg: String, characteristic characteristicArg: String, subscribed subscribedArg: Bool, completion: @escaping (Result<Void, PigeonError>) -> Void) {
|
||||||
|
let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPeripheralSubscriptionChanged\(messageChannelSuffix)"
|
||||||
|
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
channel.sendMessage([deviceIdArg, serviceArg, characteristicArg, subscribedArg] 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(PigeonError(code: code, message: message, details: details)))
|
||||||
|
} else {
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,11 +58,15 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasPermissions(withAndroidFineLocation _: Bool) throws -> Bool {
|
func hasPermissions(withAndroidFineLocation _: Bool, withAndroidBluetoothAdvertise _: Bool) throws -> Bool {
|
||||||
return CBCentralManager.authorization == .allowedAlways
|
return CBCentralManager.authorization == .allowedAlways
|
||||||
}
|
}
|
||||||
|
|
||||||
func requestPermissions(withAndroidFineLocation _: Bool, completion: @escaping (Result<Void, any Error>) -> Void) {
|
func requestPermissions(
|
||||||
|
withAndroidFineLocation _: Bool,
|
||||||
|
withAndroidBluetoothAdvertise _: Bool,
|
||||||
|
completion: @escaping (Result<Void, any Error>) -> Void
|
||||||
|
) {
|
||||||
if manager.state != .unknown {
|
if manager.state != .unknown {
|
||||||
completePermissionRequest(completion: completion)
|
completePermissionRequest(completion: completion)
|
||||||
} else {
|
} else {
|
||||||
@@ -379,6 +383,37 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
|
|||||||
completion(.failure(createFlutterError(code: .notSupported, message: "requestConnectionPriority is not supported on Apple platforms")))
|
completion(.failure(createFlutterError(code: .notSupported, message: "requestConnectionPriority is not supported on Apple platforms")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isPeripheralSupported() throws -> Bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
func startPeripheral(config _: UniversalBlePeripheralConfig, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
completion(.failure(createFlutterError(code: .notSupported, message: "BLE peripheral mode is not implemented on Apple platforms yet")))
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopPeripheral(completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
completion(.success(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatePeripheralCharacteristicValue(
|
||||||
|
service _: String,
|
||||||
|
characteristic _: String,
|
||||||
|
value _: FlutterStandardTypedData,
|
||||||
|
completion: @escaping (Result<Void, Error>) -> Void
|
||||||
|
) {
|
||||||
|
completion(.failure(createFlutterError(code: .notSupported, message: "BLE peripheral mode is not implemented on Apple platforms yet")))
|
||||||
|
}
|
||||||
|
|
||||||
|
func notifyPeripheralCharacteristic(
|
||||||
|
service _: String,
|
||||||
|
characteristic _: String,
|
||||||
|
value _: FlutterStandardTypedData,
|
||||||
|
indicate _: Bool,
|
||||||
|
completion: @escaping (Result<Void, Error>) -> Void
|
||||||
|
) {
|
||||||
|
completion(.failure(createFlutterError(code: .notSupported, message: "BLE peripheral mode is not implemented on Apple platforms yet")))
|
||||||
|
}
|
||||||
|
|
||||||
func readRssi(deviceId: String, completion: @escaping (Result<Int64, Error>) -> Void) {
|
func readRssi(deviceId: String, completion: @escaping (Result<Int64, Error>) -> Void) {
|
||||||
UniversalBleLogger.shared.logDebug("READ_RSSI -> \(deviceId)")
|
UniversalBleLogger.shared.logDebug("READ_RSSI -> \(deviceId)")
|
||||||
guard let peripheral = deviceId.findPeripheral(manager: manager) else {
|
guard let peripheral = deviceId.findPeripheral(manager: manager) else {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
|
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ class MockUniversalBle extends UniversalBlePlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<BleService>> discoverServices(
|
Future<List<BleService>> discoverServices(String deviceId, bool withDescriptors) async {
|
||||||
String deviceId, bool withDescriptors) async {
|
|
||||||
return [_mockService];
|
return [_mockService];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,11 +86,7 @@ class MockUniversalBle extends UniversalBlePlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> writeValue(
|
Future<void> writeValue(String deviceId, String service, String characteristic, Uint8List value,
|
||||||
String deviceId,
|
|
||||||
String service,
|
|
||||||
String characteristic,
|
|
||||||
Uint8List value,
|
|
||||||
BleOutputProperty bleOutputProperty) async {
|
BleOutputProperty bleOutputProperty) async {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
_serviceValue = value;
|
_serviceValue = value;
|
||||||
@@ -110,8 +105,8 @@ class MockUniversalBle extends UniversalBlePlatform {
|
|||||||
) async {}
|
) async {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setNotifiable(String deviceId, String service,
|
Future<void> setNotifiable(String deviceId, String service, String characteristic,
|
||||||
String characteristic, BleInputProperty bleInputProperty) async {}
|
BleInputProperty bleInputProperty) async {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isPaired(String deviceId) async {
|
Future<bool> isPaired(String deviceId) async {
|
||||||
@@ -141,7 +136,10 @@ class MockUniversalBle extends UniversalBlePlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> requestPermissions({bool withAndroidFineLocation = false}) {
|
Future<void> requestPermissions({
|
||||||
|
bool withAndroidFineLocation = false,
|
||||||
|
bool withAndroidBluetoothAdvertise = false,
|
||||||
|
}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ packages:
|
|||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "1.2.0"
|
version: "1.3.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:universal_ble/universal_ble.dart';
|
||||||
|
|
||||||
|
enum BlePeripheralCharacteristicPermission { read, write }
|
||||||
|
|
||||||
|
class BlePeripheralConfig {
|
||||||
|
BlePeripheralConfig({required this.advertisedName, required this.services});
|
||||||
|
|
||||||
|
final String advertisedName;
|
||||||
|
final List<BlePeripheralService> services;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlePeripheralService {
|
||||||
|
BlePeripheralService({required String uuid, required this.characteristics})
|
||||||
|
: uuid = BleUuidParser.string(uuid);
|
||||||
|
|
||||||
|
final String uuid;
|
||||||
|
final List<BlePeripheralCharacteristic> characteristics;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlePeripheralCharacteristic {
|
||||||
|
BlePeripheralCharacteristic({
|
||||||
|
required String uuid,
|
||||||
|
required this.properties,
|
||||||
|
required this.permissions,
|
||||||
|
this.descriptors = const [],
|
||||||
|
Uint8List? initialValue,
|
||||||
|
}) : uuid = BleUuidParser.string(uuid),
|
||||||
|
initialValue = initialValue == null ? null : Uint8List.fromList(initialValue);
|
||||||
|
|
||||||
|
final String uuid;
|
||||||
|
final List<CharacteristicProperty> properties;
|
||||||
|
final List<BlePeripheralCharacteristicPermission> permissions;
|
||||||
|
final List<BlePeripheralDescriptor> descriptors;
|
||||||
|
final Uint8List? initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlePeripheralDescriptor {
|
||||||
|
BlePeripheralDescriptor({
|
||||||
|
required String uuid,
|
||||||
|
required this.permissions,
|
||||||
|
Uint8List? initialValue,
|
||||||
|
}) : uuid = BleUuidParser.string(uuid),
|
||||||
|
initialValue = initialValue == null ? null : Uint8List.fromList(initialValue);
|
||||||
|
|
||||||
|
final String uuid;
|
||||||
|
final List<BlePeripheralCharacteristicPermission> permissions;
|
||||||
|
final Uint8List? initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlePeripheralWriteEvent {
|
||||||
|
BlePeripheralWriteEvent({
|
||||||
|
required this.deviceId,
|
||||||
|
required String service,
|
||||||
|
required String characteristic,
|
||||||
|
required Uint8List value,
|
||||||
|
}) : service = BleUuidParser.string(service),
|
||||||
|
characteristic = BleUuidParser.string(characteristic),
|
||||||
|
value = Uint8List.fromList(value);
|
||||||
|
|
||||||
|
final String deviceId;
|
||||||
|
final String service;
|
||||||
|
final String characteristic;
|
||||||
|
final Uint8List value;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlePeripheralConnectionEvent {
|
||||||
|
BlePeripheralConnectionEvent({required this.deviceId, required this.connected});
|
||||||
|
|
||||||
|
final String deviceId;
|
||||||
|
final bool connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlePeripheralSubscriptionEvent {
|
||||||
|
BlePeripheralSubscriptionEvent({
|
||||||
|
required this.deviceId,
|
||||||
|
required String service,
|
||||||
|
required String characteristic,
|
||||||
|
required this.subscribed,
|
||||||
|
}) : service = BleUuidParser.string(service),
|
||||||
|
characteristic = BleUuidParser.string(characteristic);
|
||||||
|
|
||||||
|
final String deviceId;
|
||||||
|
final String service;
|
||||||
|
final String characteristic;
|
||||||
|
final bool subscribed;
|
||||||
|
}
|
||||||
@@ -13,3 +13,4 @@ export 'package:universal_ble/src/models/ble_device.dart';
|
|||||||
export 'package:universal_ble/src/models/ble_command.dart';
|
export 'package:universal_ble/src/models/ble_command.dart';
|
||||||
export 'package:universal_ble/src/models/ble_capabilities.dart';
|
export 'package:universal_ble/src/models/ble_capabilities.dart';
|
||||||
export 'package:universal_ble/src/models/ble_connection_priority.dart';
|
export 'package:universal_ble/src/models/ble_connection_priority.dart';
|
||||||
|
export 'package:universal_ble/src/models/ble_peripheral.dart';
|
||||||
|
|||||||
+81
-110
@@ -14,8 +14,7 @@ class UniversalBle {
|
|||||||
static final BleCommandQueue _bleCommandQueue = BleCommandQueue();
|
static final BleCommandQueue _bleCommandQueue = BleCommandQueue();
|
||||||
|
|
||||||
/// Set custom platform specific implementation (e.g. for testing).
|
/// Set custom platform specific implementation (e.g. for testing).
|
||||||
static void setInstance(UniversalBlePlatform instance) =>
|
static void setInstance(UniversalBlePlatform instance) => _platform = instance;
|
||||||
_platform = instance;
|
|
||||||
|
|
||||||
/// Set global timeout for all commands.
|
/// Set global timeout for all commands.
|
||||||
/// Default timeout is 10 seconds.
|
/// Default timeout is 10 seconds.
|
||||||
@@ -47,40 +46,36 @@ class UniversalBle {
|
|||||||
static Stream<BleDevice> get scanStream => _platform.scanStream;
|
static Stream<BleDevice> get scanStream => _platform.scanStream;
|
||||||
|
|
||||||
/// Bluetooth availability state stream
|
/// Bluetooth availability state stream
|
||||||
static Stream<AvailabilityState> get availabilityStream =>
|
static Stream<AvailabilityState> get availabilityStream => _platform.availabilityStream;
|
||||||
_platform.availabilityStream;
|
|
||||||
|
|
||||||
/// Connection stream of a device
|
/// Connection stream of a device
|
||||||
static Stream<bool> connectionStream(String deviceId) =>
|
static Stream<bool> connectionStream(String deviceId) => _platform.connectionStream(deviceId);
|
||||||
_platform.connectionStream(deviceId);
|
|
||||||
|
|
||||||
/// Characteristic value stream
|
/// Characteristic value stream
|
||||||
static Stream<Uint8List> characteristicValueStream(
|
static Stream<Uint8List> characteristicValueStream(String deviceId, String characteristicId) =>
|
||||||
String deviceId,
|
_platform.characteristicValueStream(deviceId, characteristicId);
|
||||||
String characteristicId,
|
|
||||||
) => _platform.characteristicValueStream(deviceId, characteristicId);
|
|
||||||
|
|
||||||
/// Pairing state stream
|
/// Pairing state stream
|
||||||
static Stream<bool> pairingStateStream(String deviceId) =>
|
static Stream<bool> pairingStateStream(String deviceId) => _platform.pairingStateStream(deviceId);
|
||||||
_platform.pairingStateStream(deviceId);
|
|
||||||
|
|
||||||
/// Get Bluetooth availability state.
|
/// Get Bluetooth availability state.
|
||||||
/// To be notified of updates, set [onAvailabilityChange] listener.
|
/// To be notified of updates, set [onAvailabilityChange] listener.
|
||||||
static Future<AvailabilityState> getBluetoothAvailabilityState() async {
|
static Future<AvailabilityState> getBluetoothAvailabilityState() async {
|
||||||
return await _bleCommandQueue.queueCommand(
|
return await _bleCommandQueue.queueCommand(() => _platform.getBluetoothAvailabilityState());
|
||||||
() => _platform.getBluetoothAvailabilityState(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if has permissions.
|
/// Check if has permissions.
|
||||||
/// [withAndroidFineLocation] is used to check fine location permission on Android 12+ (API 31+).
|
/// [withAndroidFineLocation] is used to check fine location permission on Android 12+ (API 31+).
|
||||||
|
/// [withAndroidBluetoothAdvertise] is used to check Android 12+ advertise permission for peripheral mode.
|
||||||
/// On Android lower than 12, this method will check location permission regardless of the [withAndroidFineLocation] value.
|
/// On Android lower than 12, this method will check location permission regardless of the [withAndroidFineLocation] value.
|
||||||
/// `Windows`, `Linux` and `Web` will always return true.
|
/// `Windows`, `Linux` and `Web` will always return true.
|
||||||
static Future<bool> hasPermissions({
|
static Future<bool> hasPermissions({
|
||||||
bool withAndroidFineLocation = false,
|
bool withAndroidFineLocation = false,
|
||||||
|
bool withAndroidBluetoothAdvertise = false,
|
||||||
}) async {
|
}) async {
|
||||||
return _platform.hasPermissions(
|
return _platform.hasPermissions(
|
||||||
withAndroidFineLocation: withAndroidFineLocation,
|
withAndroidFineLocation: withAndroidFineLocation,
|
||||||
|
withAndroidBluetoothAdvertise: withAndroidBluetoothAdvertise,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,13 +83,16 @@ class UniversalBle {
|
|||||||
/// if all permissions are already granted or granted by user, this method will succeed.
|
/// if all permissions are already granted or granted by user, this method will succeed.
|
||||||
/// it will throw exception if permissions are denied by user.
|
/// it will throw exception if permissions are denied by user.
|
||||||
/// [withAndroidFineLocation] is used to request fine location permission on Android 12+ (API 31+).
|
/// [withAndroidFineLocation] is used to request fine location permission on Android 12+ (API 31+).
|
||||||
|
/// [withAndroidBluetoothAdvertise] is used to request Android 12+ advertise permission for peripheral mode.
|
||||||
/// on Android lower than 12, this method will request location permission regardless of the [withAndroidFineLocation] value.
|
/// on Android lower than 12, this method will request location permission regardless of the [withAndroidFineLocation] value.
|
||||||
/// `Windows`, `Linux` and `Web` will always succeed.
|
/// `Windows`, `Linux` and `Web` will always succeed.
|
||||||
static Future<void> requestPermissions({
|
static Future<void> requestPermissions({
|
||||||
bool withAndroidFineLocation = false,
|
bool withAndroidFineLocation = false,
|
||||||
|
bool withAndroidBluetoothAdvertise = false,
|
||||||
}) async {
|
}) async {
|
||||||
return _platform.requestPermissions(
|
return _platform.requestPermissions(
|
||||||
withAndroidFineLocation: withAndroidFineLocation,
|
withAndroidFineLocation: withAndroidFineLocation,
|
||||||
|
withAndroidBluetoothAdvertise: withAndroidBluetoothAdvertise,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,15 +100,9 @@ class UniversalBle {
|
|||||||
/// Scan results will arrive in [onScanResult] listener.
|
/// Scan results will arrive in [onScanResult] listener.
|
||||||
/// It might throw errors if Bluetooth is not available.
|
/// It might throw errors if Bluetooth is not available.
|
||||||
/// `webRequestOptions` is supported on Web only.
|
/// `webRequestOptions` is supported on Web only.
|
||||||
static Future<void> startScan({
|
static Future<void> startScan({ScanFilter? scanFilter, PlatformConfig? platformConfig}) async {
|
||||||
ScanFilter? scanFilter,
|
|
||||||
PlatformConfig? platformConfig,
|
|
||||||
}) async {
|
|
||||||
return await _bleCommandQueue.queueCommandWithoutTimeout(
|
return await _bleCommandQueue.queueCommandWithoutTimeout(
|
||||||
() => _platform.startScan(
|
() => _platform.startScan(scanFilter: scanFilter, platformConfig: platformConfig),
|
||||||
scanFilter: scanFilter,
|
|
||||||
platformConfig: platformConfig,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,9 +110,7 @@ class UniversalBle {
|
|||||||
/// Set [onScanResult] listener to `null` if you don't need it anymore.
|
/// Set [onScanResult] listener to `null` if you don't need it anymore.
|
||||||
/// It might throw errors if Bluetooth is not available.
|
/// It might throw errors if Bluetooth is not available.
|
||||||
static Future<void> stopScan() async {
|
static Future<void> stopScan() async {
|
||||||
return await _bleCommandQueue.queueCommandWithoutTimeout(
|
return await _bleCommandQueue.queueCommandWithoutTimeout(() => _platform.stopScan());
|
||||||
() => _platform.stopScan(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if currently scanning for devices.
|
/// Check if currently scanning for devices.
|
||||||
@@ -147,14 +137,11 @@ class UniversalBle {
|
|||||||
bool autoConnect = false,
|
bool autoConnect = false,
|
||||||
}) async {
|
}) async {
|
||||||
timeout ??= const Duration(seconds: 60);
|
timeout ??= const Duration(seconds: 60);
|
||||||
Completer<bool> completer = _connectionEventCompleter(
|
Completer<bool> completer = _connectionEventCompleter(deviceId, timeout: timeout);
|
||||||
deviceId,
|
|
||||||
timeout: timeout,
|
|
||||||
);
|
|
||||||
|
|
||||||
_platform
|
_platform.connect(deviceId, connectionTimeout: timeout, autoConnect: autoConnect).catchError((
|
||||||
.connect(deviceId, connectionTimeout: timeout, autoConnect: autoConnect)
|
error,
|
||||||
.catchError((error) {
|
) {
|
||||||
if (completer.isCompleted) return;
|
if (completer.isCompleted) return;
|
||||||
completer.completeError(ConnectionException(error));
|
completer.completeError(ConnectionException(error));
|
||||||
});
|
});
|
||||||
@@ -176,17 +163,10 @@ class UniversalBle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Completer<bool> completer = _connectionEventCompleter(
|
Completer<bool> completer = _connectionEventCompleter(deviceId, timeout: timeout);
|
||||||
deviceId,
|
|
||||||
timeout: timeout,
|
|
||||||
);
|
|
||||||
|
|
||||||
await _bleCommandQueue
|
await _bleCommandQueue
|
||||||
.queueCommand(
|
.queueCommand(() => _platform.disconnect(deviceId), timeout: timeout, deviceId: deviceId)
|
||||||
() => _platform.disconnect(deviceId),
|
|
||||||
timeout: timeout,
|
|
||||||
deviceId: deviceId,
|
|
||||||
)
|
|
||||||
.catchError((error) {
|
.catchError((error) {
|
||||||
if (completer.isCompleted) return;
|
if (completer.isCompleted) return;
|
||||||
completer.completeError(ConnectionException(error));
|
completer.completeError(ConnectionException(error));
|
||||||
@@ -204,9 +184,7 @@ class UniversalBle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (await completer.future.timeout(timeout)) {
|
if (await completer.future.timeout(timeout)) {
|
||||||
UniversalLogger.logError(
|
UniversalLogger.logError("Device $deviceId is still connected after disconnect attempt");
|
||||||
"Device $deviceId is still connected after disconnect attempt",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
UniversalLogger.logError("Disconnect failed: $e");
|
UniversalLogger.logError("Disconnect failed: $e");
|
||||||
@@ -315,9 +293,7 @@ class UniversalBle {
|
|||||||
BleUuidParser.string(service),
|
BleUuidParser.string(service),
|
||||||
BleUuidParser.string(characteristic),
|
BleUuidParser.string(characteristic),
|
||||||
value,
|
value,
|
||||||
withoutResponse
|
withoutResponse ? BleOutputProperty.withoutResponse : BleOutputProperty.withResponse,
|
||||||
? BleOutputProperty.withoutResponse
|
|
||||||
: BleOutputProperty.withResponse,
|
|
||||||
),
|
),
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
deviceId: deviceId,
|
deviceId: deviceId,
|
||||||
@@ -339,11 +315,7 @@ class UniversalBle {
|
|||||||
///
|
///
|
||||||
/// **Best Practices:** Design for default ATT MTU (23 bytes), treat requests as
|
/// **Best Practices:** Design for default ATT MTU (23 bytes), treat requests as
|
||||||
/// opportunistic, and implement fragmentation for larger payloads.
|
/// opportunistic, and implement fragmentation for larger payloads.
|
||||||
static Future<int> requestMtu(
|
static Future<int> requestMtu(String deviceId, int expectedMtu, {Duration? timeout}) async {
|
||||||
String deviceId,
|
|
||||||
int expectedMtu, {
|
|
||||||
Duration? timeout,
|
|
||||||
}) async {
|
|
||||||
return await _bleCommandQueue.queueCommand(
|
return await _bleCommandQueue.queueCommand(
|
||||||
() => _platform.requestMtu(deviceId, expectedMtu),
|
() => _platform.requestMtu(deviceId, expectedMtu),
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
@@ -445,11 +417,7 @@ class UniversalBle {
|
|||||||
///
|
///
|
||||||
/// On `Web/Windows` and `Web/Linux`, it does not work for devices that use `ConfirmOnly` pairing.
|
/// On `Web/Windows` and `Web/Linux`, it does not work for devices that use `ConfirmOnly` pairing.
|
||||||
/// Can throw `PairingException`, `ConnectionException` or `PlatformException`.
|
/// Can throw `PairingException`, `ConnectionException` or `PlatformException`.
|
||||||
static Future<void> pair(
|
static Future<void> pair(String deviceId, {BleCommand? pairingCommand, Duration? timeout}) async {
|
||||||
String deviceId, {
|
|
||||||
BleCommand? pairingCommand,
|
|
||||||
Duration? timeout,
|
|
||||||
}) async {
|
|
||||||
if (BleCapabilities.hasSystemPairingApi) {
|
if (BleCapabilities.hasSystemPairingApi) {
|
||||||
bool paired = await _bleCommandQueue.queueCommand(
|
bool paired = await _bleCommandQueue.queueCommand(
|
||||||
() => _platform.pair(deviceId),
|
() => _platform.pair(deviceId),
|
||||||
@@ -461,11 +429,7 @@ class UniversalBle {
|
|||||||
if (pairingCommand == null) {
|
if (pairingCommand == null) {
|
||||||
UniversalLogger.logWarning("PairingCommand required to get result");
|
UniversalLogger.logWarning("PairingCommand required to get result");
|
||||||
}
|
}
|
||||||
await _connectAndExecuteBleCommand(
|
await _connectAndExecuteBleCommand(deviceId, pairingCommand, timeout: timeout);
|
||||||
deviceId,
|
|
||||||
pairingCommand,
|
|
||||||
timeout: timeout,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,10 +461,7 @@ class UniversalBle {
|
|||||||
/// Returns connection state of the device.
|
/// Returns connection state of the device.
|
||||||
/// All platforms will return `Connected/Disconnected` states.
|
/// All platforms will return `Connected/Disconnected` states.
|
||||||
/// `Android` and `Apple` can also return `Connecting/Disconnecting` states.
|
/// `Android` and `Apple` can also return `Connecting/Disconnecting` states.
|
||||||
static Future<BleConnectionState> getConnectionState(
|
static Future<BleConnectionState> getConnectionState(String deviceId, {Duration? timeout}) async {
|
||||||
String deviceId, {
|
|
||||||
Duration? timeout,
|
|
||||||
}) async {
|
|
||||||
return await _bleCommandQueue.queueCommand(
|
return await _bleCommandQueue.queueCommand(
|
||||||
() => _platform.getConnectionState(deviceId),
|
() => _platform.getConnectionState(deviceId),
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
@@ -511,10 +472,7 @@ class UniversalBle {
|
|||||||
/// It might throw errors if Bluetooth is not available.
|
/// It might throw errors if Bluetooth is not available.
|
||||||
/// Not supported on `Web` and `Apple`.
|
/// Not supported on `Web` and `Apple`.
|
||||||
static Future<bool> enableBluetooth({Duration? timeout}) async {
|
static Future<bool> enableBluetooth({Duration? timeout}) async {
|
||||||
return await _bleCommandQueue.queueCommand(
|
return await _bleCommandQueue.queueCommand(() => _platform.enableBluetooth(), timeout: timeout);
|
||||||
() => _platform.enableBluetooth(),
|
|
||||||
timeout: timeout,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable Bluetooth.
|
/// Disable Bluetooth.
|
||||||
@@ -540,8 +498,7 @@ class UniversalBle {
|
|||||||
/// For this feature to work, you need to enable the `chrome://flags/#enable-experimental-web-platform-features` flag.
|
/// For this feature to work, you need to enable the `chrome://flags/#enable-experimental-web-platform-features` flag.
|
||||||
/// Not every browser supports this API yet.
|
/// Not every browser supports this API yet.
|
||||||
/// Even if the browser supports it, sometimes it won't fire any advertisement events even though the device may be sending them.
|
/// Even if the browser supports it, sometimes it won't fire any advertisement events even though the device may be sending them.
|
||||||
static bool receivesAdvertisements(String deviceId) =>
|
static bool receivesAdvertisements(String deviceId) => _platform.receivesAdvertisements(deviceId);
|
||||||
_platform.receivesAdvertisements(deviceId);
|
|
||||||
|
|
||||||
/// Get Bluetooth state availability.
|
/// Get Bluetooth state availability.
|
||||||
static set onAvailabilityChange(OnAvailabilityChange? onAvailabilityChange) {
|
static set onAvailabilityChange(OnAvailabilityChange? onAvailabilityChange) {
|
||||||
@@ -555,21 +512,14 @@ class UniversalBle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated("Use [subscribeNotifications] or [subscribeIndications] or [unsubscribe] instead")
|
||||||
"Use [subscribeNotifications] or [subscribeIndications] or [unsubscribe] instead",
|
|
||||||
)
|
|
||||||
static Future<void> setNotifiable(
|
static Future<void> setNotifiable(
|
||||||
String deviceId,
|
String deviceId,
|
||||||
String service,
|
String service,
|
||||||
String characteristic,
|
String characteristic,
|
||||||
BleInputProperty bleInputProperty,
|
BleInputProperty bleInputProperty,
|
||||||
) async {
|
) async {
|
||||||
return _sendBleInputPropertyCommand(
|
return _sendBleInputPropertyCommand(deviceId, service, characteristic, bleInputProperty);
|
||||||
deviceId,
|
|
||||||
service,
|
|
||||||
characteristic,
|
|
||||||
bleInputProperty,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Use [write] instead")
|
@Deprecated("Use [write] instead")
|
||||||
@@ -599,10 +549,7 @@ class UniversalBle {
|
|||||||
return read(deviceId, service, characteristic, timeout: timeout);
|
return read(deviceId, service, characteristic, timeout: timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Completer<bool> _connectionEventCompleter(
|
static Completer<bool> _connectionEventCompleter(String deviceId, {Duration? timeout}) {
|
||||||
String deviceId, {
|
|
||||||
Duration? timeout,
|
|
||||||
}) {
|
|
||||||
timeout ??= const Duration(seconds: 60);
|
timeout ??= const Duration(seconds: 60);
|
||||||
StreamSubscription? connectionSubscription;
|
StreamSubscription? connectionSubscription;
|
||||||
Completer<bool> completer = Completer();
|
Completer<bool> completer = Completer();
|
||||||
@@ -618,9 +565,7 @@ class UniversalBle {
|
|||||||
completer.completeError(ConnectionException(error));
|
completer.completeError(ConnectionException(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionSubscription = _platform
|
connectionSubscription = _platform.bleConnectionUpdateStreamController.stream
|
||||||
.bleConnectionUpdateStreamController
|
|
||||||
.stream
|
|
||||||
.where((e) => e.deviceId == deviceId)
|
.where((e) => e.deviceId == deviceId)
|
||||||
.listen(
|
.listen(
|
||||||
(e) {
|
(e) {
|
||||||
@@ -681,10 +626,7 @@ class UniversalBle {
|
|||||||
await connect(deviceId, timeout: timeout);
|
await connect(deviceId, timeout: timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<BleService> services = await discoverServices(
|
List<BleService> services = await discoverServices(deviceId, timeout: timeout);
|
||||||
deviceId,
|
|
||||||
timeout: timeout,
|
|
||||||
);
|
|
||||||
UniversalLogger.logInfo("Discovered services: ${services.length}");
|
UniversalLogger.logInfo("Discovered services: ${services.length}");
|
||||||
|
|
||||||
if (bleCommand == null) {
|
if (bleCommand == null) {
|
||||||
@@ -737,10 +679,7 @@ class UniversalBle {
|
|||||||
for (BleService service in services) {
|
for (BleService service in services) {
|
||||||
if (BleUuidParser.compareStrings(service.uuid, bleCommand.service)) {
|
if (BleUuidParser.compareStrings(service.uuid, bleCommand.service)) {
|
||||||
for (BleCharacteristic char in service.characteristics) {
|
for (BleCharacteristic char in service.characteristics) {
|
||||||
if (BleUuidParser.compareStrings(
|
if (BleUuidParser.compareStrings(char.uuid, bleCommand.characteristic)) {
|
||||||
char.uuid,
|
|
||||||
bleCommand.characteristic,
|
|
||||||
)) {
|
|
||||||
characteristic = char;
|
characteristic = char;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -756,16 +695,10 @@ class UniversalBle {
|
|||||||
bool? withoutResponse;
|
bool? withoutResponse;
|
||||||
if (characteristic.properties.contains(CharacteristicProperty.write)) {
|
if (characteristic.properties.contains(CharacteristicProperty.write)) {
|
||||||
withoutResponse = false;
|
withoutResponse = false;
|
||||||
} else if (characteristic.properties.contains(
|
} else if (characteristic.properties.contains(CharacteristicProperty.writeWithoutResponse)) {
|
||||||
CharacteristicProperty.writeWithoutResponse,
|
|
||||||
)) {
|
|
||||||
withoutResponse = true;
|
withoutResponse = true;
|
||||||
} else if (!characteristic.properties.contains(
|
} else if (!characteristic.properties.contains(CharacteristicProperty.read)) {
|
||||||
CharacteristicProperty.read,
|
throw PairingException("BleCommand does not support read or write operation");
|
||||||
)) {
|
|
||||||
throw PairingException(
|
|
||||||
"BleCommand does not support read or write operation",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8List? value = bleCommand.writeValue;
|
Uint8List? value = bleCommand.writeValue;
|
||||||
@@ -799,16 +732,14 @@ class UniversalBle {
|
|||||||
_bleCommandQueue.onQueueUpdate = onQueueUpdate;
|
_bleCommandQueue.onQueueUpdate = onQueueUpdate;
|
||||||
|
|
||||||
/// Get scan results.
|
/// Get scan results.
|
||||||
static set onScanResult(OnScanResult? onScanResult) =>
|
static set onScanResult(OnScanResult? onScanResult) => _platform.onScanResult = onScanResult;
|
||||||
_platform.onScanResult = onScanResult;
|
|
||||||
|
|
||||||
/// Get connection state changes.
|
/// Get connection state changes.
|
||||||
static set onConnectionChange(OnConnectionChange? onConnectionChange) =>
|
static set onConnectionChange(OnConnectionChange? onConnectionChange) =>
|
||||||
_platform.onConnectionChange = onConnectionChange;
|
_platform.onConnectionChange = onConnectionChange;
|
||||||
|
|
||||||
/// Get characteristic value updates, after calling [subscribeNotifications] or [subscribeIndications]
|
/// Get characteristic value updates, after calling [subscribeNotifications] or [subscribeIndications]
|
||||||
static set onValueChange(OnValueChange? onValueChange) =>
|
static set onValueChange(OnValueChange? onValueChange) => _platform.onValueChange = onValueChange;
|
||||||
_platform.onValueChange = onValueChange;
|
|
||||||
|
|
||||||
/// Get pair state changes.
|
/// Get pair state changes.
|
||||||
static set onPairingStateChange(OnPairingStateChange pairingStateChange) =>
|
static set onPairingStateChange(OnPairingStateChange pairingStateChange) =>
|
||||||
@@ -822,3 +753,43 @@ class UniversalBle {
|
|||||||
return UniversalBlePigeonChannel.instance;
|
return UniversalBlePigeonChannel.instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class UniversalBlePeripheral {
|
||||||
|
static Stream<BlePeripheralConnectionEvent> get connectionStream =>
|
||||||
|
UniversalBle._platform.peripheralConnectionStream;
|
||||||
|
|
||||||
|
static Stream<BlePeripheralWriteEvent> get writeStream =>
|
||||||
|
UniversalBle._platform.peripheralWriteStream;
|
||||||
|
|
||||||
|
static Stream<BlePeripheralSubscriptionEvent> get subscriptionStream =>
|
||||||
|
UniversalBle._platform.peripheralSubscriptionStream;
|
||||||
|
|
||||||
|
static Future<bool> isSupported() => UniversalBle._platform.isPeripheralSupported();
|
||||||
|
|
||||||
|
static Future<void> start(BlePeripheralConfig config) =>
|
||||||
|
UniversalBle._platform.startPeripheral(config);
|
||||||
|
|
||||||
|
static Future<void> stop() => UniversalBle._platform.stopPeripheral();
|
||||||
|
|
||||||
|
static Future<void> updateCharacteristicValue(
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
Uint8List value,
|
||||||
|
) => UniversalBle._platform.updatePeripheralCharacteristicValue(
|
||||||
|
BleUuidParser.string(service),
|
||||||
|
BleUuidParser.string(characteristic),
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
|
||||||
|
static Future<void> notify(
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
Uint8List value, {
|
||||||
|
bool indicate = false,
|
||||||
|
}) => UniversalBle._platform.notifyPeripheralCharacteristic(
|
||||||
|
BleUuidParser.string(service),
|
||||||
|
BleUuidParser.string(characteristic),
|
||||||
|
value,
|
||||||
|
indicate: indicate,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,7 @@ import 'package:universal_ble/universal_ble.dart';
|
|||||||
|
|
||||||
class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
||||||
static UniversalBlePigeonChannel? _instance;
|
static UniversalBlePigeonChannel? _instance;
|
||||||
static UniversalBlePigeonChannel get instance =>
|
static UniversalBlePigeonChannel get instance => _instance ??= UniversalBlePigeonChannel._();
|
||||||
_instance ??= UniversalBlePigeonChannel._();
|
|
||||||
late final UniversalBleFilterUtil _bleFilter = UniversalBleFilterUtil();
|
late final UniversalBleFilterUtil _bleFilter = UniversalBleFilterUtil();
|
||||||
|
|
||||||
UniversalBlePigeonChannel._() {
|
UniversalBlePigeonChannel._() {
|
||||||
@@ -17,9 +16,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<AvailabilityState> getBluetoothAvailabilityState() async {
|
Future<AvailabilityState> getBluetoothAvailabilityState() async {
|
||||||
int state = await _executeWithErrorHandling(
|
int state = await _executeWithErrorHandling(() => _channel.getBluetoothAvailabilityState());
|
||||||
() => _channel.getBluetoothAvailabilityState(),
|
|
||||||
);
|
|
||||||
return AvailabilityState.parse(state);
|
return AvailabilityState.parse(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,10 +37,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> startScan({
|
Future<void> startScan({ScanFilter? scanFilter, PlatformConfig? platformConfig}) async {
|
||||||
ScanFilter? scanFilter,
|
|
||||||
PlatformConfig? platformConfig,
|
|
||||||
}) async {
|
|
||||||
await _ensureInitialized(platformConfig);
|
await _ensureInitialized(platformConfig);
|
||||||
_bleFilter.scanFilter = scanFilter;
|
_bleFilter.scanFilter = scanFilter;
|
||||||
await _executeWithErrorHandling(
|
await _executeWithErrorHandling(
|
||||||
@@ -55,48 +49,32 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> stopScan() =>
|
Future<void> stopScan() => _executeWithErrorHandling(() => _channel.stopScan());
|
||||||
_executeWithErrorHandling(() => _channel.stopScan());
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isScanning() =>
|
Future<bool> isScanning() => _executeWithErrorHandling(() => _channel.isScanning());
|
||||||
_executeWithErrorHandling(() => _channel.isScanning());
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<BleConnectionState> getConnectionState(String deviceId) async {
|
Future<BleConnectionState> getConnectionState(String deviceId) async {
|
||||||
int state = await _executeWithErrorHandling(
|
int state = await _executeWithErrorHandling(() => _channel.getConnectionState(deviceId));
|
||||||
() => _channel.getConnectionState(deviceId),
|
|
||||||
);
|
|
||||||
return BleConnectionState.parse(state);
|
return BleConnectionState.parse(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> connect(
|
Future<void> connect(String deviceId, {Duration? connectionTimeout, bool autoConnect = false}) =>
|
||||||
String deviceId, {
|
_executeWithErrorHandling(() => _channel.connect(deviceId, autoConnect: autoConnect));
|
||||||
Duration? connectionTimeout,
|
|
||||||
bool autoConnect = false,
|
|
||||||
}) => _executeWithErrorHandling(
|
|
||||||
() => _channel.connect(deviceId, autoConnect: autoConnect),
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> disconnect(String deviceId) =>
|
Future<void> disconnect(String deviceId) =>
|
||||||
_executeWithErrorHandling(() => _channel.disconnect(deviceId));
|
_executeWithErrorHandling(() => _channel.disconnect(deviceId));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<BleService>> discoverServices(
|
Future<List<BleService>> discoverServices(String deviceId, bool withDescriptors) async {
|
||||||
String deviceId,
|
List<UniversalBleService?> universalBleServices = await _executeWithErrorHandling(
|
||||||
bool withDescriptors,
|
|
||||||
) async {
|
|
||||||
List<UniversalBleService?> universalBleServices =
|
|
||||||
await _executeWithErrorHandling(
|
|
||||||
() => _channel.discoverServices(deviceId, withDescriptors),
|
() => _channel.discoverServices(deviceId, withDescriptors),
|
||||||
);
|
);
|
||||||
return List<BleService>.from(
|
return List<BleService>.from(
|
||||||
universalBleServices
|
universalBleServices.where((e) => e != null).map((e) => e!.toBleService(deviceId)).toList(),
|
||||||
.where((e) => e != null)
|
|
||||||
.map((e) => e!.toBleService(deviceId))
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,12 +86,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
BleInputProperty bleInputProperty,
|
BleInputProperty bleInputProperty,
|
||||||
) {
|
) {
|
||||||
return _executeWithErrorHandling(
|
return _executeWithErrorHandling(
|
||||||
() => _channel.setNotifiable(
|
() => _channel.setNotifiable(deviceId, service, characteristic, bleInputProperty.index),
|
||||||
deviceId,
|
|
||||||
service,
|
|
||||||
characteristic,
|
|
||||||
bleInputProperty.index,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,9 +97,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
String characteristic, {
|
String characteristic, {
|
||||||
final Duration? timeout,
|
final Duration? timeout,
|
||||||
}) {
|
}) {
|
||||||
return _executeWithErrorHandling(
|
return _executeWithErrorHandling(() => _channel.readValue(deviceId, service, characteristic));
|
||||||
() => _channel.readValue(deviceId, service, characteristic),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -138,32 +109,51 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
BleOutputProperty bleOutputProperty,
|
BleOutputProperty bleOutputProperty,
|
||||||
) {
|
) {
|
||||||
return _executeWithErrorHandling(
|
return _executeWithErrorHandling(
|
||||||
() => _channel.writeValue(
|
() => _channel.writeValue(deviceId, service, characteristic, value, bleOutputProperty.index),
|
||||||
deviceId,
|
|
||||||
service,
|
|
||||||
characteristic,
|
|
||||||
value,
|
|
||||||
bleOutputProperty.index,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> requestMtu(String deviceId, int expectedMtu) =>
|
Future<int> requestMtu(String deviceId, int expectedMtu) =>
|
||||||
_executeWithErrorHandling(
|
_executeWithErrorHandling(() => _channel.requestMtu(deviceId, expectedMtu));
|
||||||
() => _channel.requestMtu(deviceId, expectedMtu),
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> readRssi(String deviceId) =>
|
Future<int> readRssi(String deviceId) =>
|
||||||
_executeWithErrorHandling(() => _channel.readRssi(deviceId));
|
_executeWithErrorHandling(() => _channel.readRssi(deviceId));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> requestConnectionPriority(
|
Future<void> requestConnectionPriority(String deviceId, BleConnectionPriority priority) =>
|
||||||
String deviceId,
|
_executeWithErrorHandling(() => _channel.requestConnectionPriority(deviceId, priority.index));
|
||||||
BleConnectionPriority priority,
|
|
||||||
|
@override
|
||||||
|
Future<bool> isPeripheralSupported() =>
|
||||||
|
_executeWithErrorHandling(() => _channel.isPeripheralSupported());
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> startPeripheral(BlePeripheralConfig config) => _executeWithErrorHandling(
|
||||||
|
() => _channel.startPeripheral(config.toUniversalPeripheralConfig()),
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> stopPeripheral() => _executeWithErrorHandling(() => _channel.stopPeripheral());
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> updatePeripheralCharacteristicValue(
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
Uint8List value,
|
||||||
) => _executeWithErrorHandling(
|
) => _executeWithErrorHandling(
|
||||||
() => _channel.requestConnectionPriority(deviceId, priority.index),
|
() => _channel.updatePeripheralCharacteristicValue(service, characteristic, value),
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> notifyPeripheralCharacteristic(
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
Uint8List value, {
|
||||||
|
bool indicate = false,
|
||||||
|
}) => _executeWithErrorHandling(
|
||||||
|
() => _channel.notifyPeripheralCharacteristic(service, characteristic, value, indicate),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -171,26 +161,29 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
_executeWithErrorHandling(() => _channel.isPaired(deviceId));
|
_executeWithErrorHandling(() => _channel.isPaired(deviceId));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> pair(String deviceId) =>
|
Future<bool> pair(String deviceId) => _executeWithErrorHandling(() => _channel.pair(deviceId));
|
||||||
_executeWithErrorHandling(() => _channel.pair(deviceId));
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> unpair(String deviceId) =>
|
Future<void> unpair(String deviceId) =>
|
||||||
_executeWithErrorHandling(() => _channel.unPair(deviceId));
|
_executeWithErrorHandling(() => _channel.unPair(deviceId));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> hasPermissions({bool withAndroidFineLocation = false}) async {
|
Future<bool> hasPermissions({
|
||||||
|
bool withAndroidFineLocation = false,
|
||||||
|
bool withAndroidBluetoothAdvertise = false,
|
||||||
|
}) async {
|
||||||
return await _executeWithErrorHandling(
|
return await _executeWithErrorHandling(
|
||||||
() => _channel.hasPermissions(withAndroidFineLocation),
|
() => _channel.hasPermissions(withAndroidFineLocation, withAndroidBluetoothAdvertise),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> requestPermissions({
|
Future<void> requestPermissions({
|
||||||
bool withAndroidFineLocation = false,
|
bool withAndroidFineLocation = false,
|
||||||
|
bool withAndroidBluetoothAdvertise = false,
|
||||||
}) async {
|
}) async {
|
||||||
await _executeWithErrorHandling(
|
await _executeWithErrorHandling(
|
||||||
() => _channel.requestPermissions(withAndroidFineLocation),
|
() => _channel.requestPermissions(withAndroidFineLocation, withAndroidBluetoothAdvertise),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,15 +192,12 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
var devices = await _executeWithErrorHandling(
|
var devices = await _executeWithErrorHandling(
|
||||||
() => _channel.getSystemDevices(withServices ?? []),
|
() => _channel.getSystemDevices(withServices ?? []),
|
||||||
);
|
);
|
||||||
return List<BleDevice>.from(
|
return List<BleDevice>.from(devices.map((e) => e.toBleDevice(isSystemDevice: true)).toList());
|
||||||
devices.map((e) => e.toBleDevice(isSystemDevice: true)).toList(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setLogLevel(BleLogLevel logLevel) => _executeWithErrorHandling(
|
Future<void> setLogLevel(BleLogLevel logLevel) =>
|
||||||
() => _channel.setLogLevel(logLevel.toUniversalBleLogLevel()),
|
_executeWithErrorHandling(() => _channel.setLogLevel(logLevel.toUniversalBleLogLevel()));
|
||||||
);
|
|
||||||
|
|
||||||
/// To set listeners
|
/// To set listeners
|
||||||
void _setupListeners() {
|
void _setupListeners() {
|
||||||
@@ -223,6 +213,9 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
connectionChanged: updateConnection,
|
connectionChanged: updateConnection,
|
||||||
valueChanged: updateCharacteristicValue,
|
valueChanged: updateCharacteristicValue,
|
||||||
pairStateChange: updatePairingState,
|
pairStateChange: updatePairingState,
|
||||||
|
peripheralConnectionChanged: updatePeripheralConnection,
|
||||||
|
peripheralWrite: updatePeripheralWrite,
|
||||||
|
peripheralSubscriptionChanged: updatePeripheralSubscription,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -246,8 +239,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform {
|
|||||||
defaultTargetPlatform == TargetPlatform.iOS ||
|
defaultTargetPlatform == TargetPlatform.iOS ||
|
||||||
defaultTargetPlatform == TargetPlatform.macOS) {
|
defaultTargetPlatform == TargetPlatform.macOS) {
|
||||||
await requestPermissions(
|
await requestPermissions(
|
||||||
withAndroidFineLocation:
|
withAndroidFineLocation: platformConfig?.android?.requestLocationPermission ?? false,
|
||||||
platformConfig?.android?.requestLocationPermission ?? false,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,12 +269,70 @@ extension _BleServiceExtension on UniversalBleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension _BlePeripheralConfigExtension on BlePeripheralConfig {
|
||||||
|
UniversalBlePeripheralConfig toUniversalPeripheralConfig() {
|
||||||
|
return UniversalBlePeripheralConfig(
|
||||||
|
advertisedName: advertisedName,
|
||||||
|
services: services.map((service) => service.toUniversalPeripheralService()).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _BlePeripheralServiceExtension on BlePeripheralService {
|
||||||
|
UniversalBlePeripheralService toUniversalPeripheralService() {
|
||||||
|
return UniversalBlePeripheralService(
|
||||||
|
uuid: uuid,
|
||||||
|
characteristics: characteristics
|
||||||
|
.map((characteristic) => characteristic.toUniversalPeripheralCharacteristic())
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _BlePeripheralCharacteristicExtension on BlePeripheralCharacteristic {
|
||||||
|
UniversalBlePeripheralCharacteristic toUniversalPeripheralCharacteristic() {
|
||||||
|
return UniversalBlePeripheralCharacteristic(
|
||||||
|
uuid: uuid,
|
||||||
|
properties: properties.map((property) => property.index).toList(),
|
||||||
|
permissions: permissions.map((permission) => permission.index).toList(),
|
||||||
|
descriptors: descriptors
|
||||||
|
.map((descriptor) => descriptor.toUniversalPeripheralDescriptor())
|
||||||
|
.toList(),
|
||||||
|
initialValue: initialValue,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _BlePeripheralDescriptorExtension on BlePeripheralDescriptor {
|
||||||
|
UniversalBlePeripheralDescriptor toUniversalPeripheralDescriptor() {
|
||||||
|
return UniversalBlePeripheralDescriptor(
|
||||||
|
uuid: uuid,
|
||||||
|
permissions: permissions.map((permission) => permission.index).toList(),
|
||||||
|
initialValue: initialValue,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _UniversalBlePeripheralWriteEventExtension on UniversalBlePeripheralWriteEvent {
|
||||||
|
BlePeripheralWriteEvent toBlePeripheralWriteEvent() {
|
||||||
|
return BlePeripheralWriteEvent(
|
||||||
|
deviceId: deviceId,
|
||||||
|
service: service,
|
||||||
|
characteristic: characteristic,
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _UniversalBleCallbackHandler extends UniversalBleCallbackChannel {
|
class _UniversalBleCallbackHandler extends UniversalBleCallbackChannel {
|
||||||
OnAvailabilityChange availabilityChange;
|
OnAvailabilityChange availabilityChange;
|
||||||
OnScanResult scanResult;
|
OnScanResult scanResult;
|
||||||
OnConnectionChange connectionChanged;
|
OnConnectionChange connectionChanged;
|
||||||
OnValueChange valueChanged;
|
OnValueChange valueChanged;
|
||||||
OnPairingStateChange pairStateChange;
|
OnPairingStateChange pairStateChange;
|
||||||
|
void Function(String deviceId, bool connected) peripheralConnectionChanged;
|
||||||
|
void Function(BlePeripheralWriteEvent event) peripheralWrite;
|
||||||
|
void Function(BlePeripheralSubscriptionEvent event) peripheralSubscriptionChanged;
|
||||||
|
|
||||||
_UniversalBleCallbackHandler({
|
_UniversalBleCallbackHandler({
|
||||||
required this.availabilityChange,
|
required this.availabilityChange,
|
||||||
@@ -290,31 +340,51 @@ class _UniversalBleCallbackHandler extends UniversalBleCallbackChannel {
|
|||||||
required this.connectionChanged,
|
required this.connectionChanged,
|
||||||
required this.valueChanged,
|
required this.valueChanged,
|
||||||
required this.pairStateChange,
|
required this.pairStateChange,
|
||||||
|
required this.peripheralConnectionChanged,
|
||||||
|
required this.peripheralWrite,
|
||||||
|
required this.peripheralSubscriptionChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onAvailabilityChanged(int state) =>
|
void onAvailabilityChanged(int state) => availabilityChange(AvailabilityState.parse(state));
|
||||||
availabilityChange(AvailabilityState.parse(state));
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onConnectionChanged(String deviceId, bool connected, String? error) =>
|
void onConnectionChanged(String deviceId, bool connected, String? error) =>
|
||||||
connectionChanged(deviceId, connected, error);
|
connectionChanged(deviceId, connected, error);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onScanResult(UniversalBleScanResult result) =>
|
void onScanResult(UniversalBleScanResult result) => scanResult(result.toBleDevice());
|
||||||
scanResult(result.toBleDevice());
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onValueChanged(
|
void onValueChanged(String deviceId, String characteristicId, Uint8List value, int? timestamp) =>
|
||||||
String deviceId,
|
valueChanged(deviceId, characteristicId, value, timestamp);
|
||||||
String characteristicId,
|
|
||||||
Uint8List value,
|
|
||||||
int? timestamp,
|
|
||||||
) => valueChanged(deviceId, characteristicId, value, timestamp);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onPairStateChange(String deviceId, bool isPaired, String? error) =>
|
void onPairStateChange(String deviceId, bool isPaired, String? error) =>
|
||||||
pairStateChange(deviceId, isPaired);
|
pairStateChange(deviceId, isPaired);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onPeripheralConnectionChanged(String deviceId, bool connected) =>
|
||||||
|
peripheralConnectionChanged(deviceId, connected);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onPeripheralWrite(UniversalBlePeripheralWriteEvent event) =>
|
||||||
|
peripheralWrite(event.toBlePeripheralWriteEvent());
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onPeripheralSubscriptionChanged(
|
||||||
|
String deviceId,
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
bool subscribed,
|
||||||
|
) => peripheralSubscriptionChanged(
|
||||||
|
BlePeripheralSubscriptionEvent(
|
||||||
|
deviceId: deviceId,
|
||||||
|
service: service,
|
||||||
|
characteristic: characteristic,
|
||||||
|
subscribed: subscribed,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _UniversalBleScanResultExtension on UniversalBleScanResult {
|
extension _UniversalBleScanResultExtension on UniversalBleScanResult {
|
||||||
@@ -339,8 +409,7 @@ extension _UniversalBleScanResultExtension on UniversalBleScanResult {
|
|||||||
|
|
||||||
extension _ScanFilterExtension on ScanFilter? {
|
extension _ScanFilterExtension on ScanFilter? {
|
||||||
UniversalScanFilter? toUniversalScanFilter() {
|
UniversalScanFilter? toUniversalScanFilter() {
|
||||||
List<UniversalManufacturerDataFilter>? manufacturerDataFilters = this
|
List<UniversalManufacturerDataFilter>? manufacturerDataFilters = this?.withManufacturerData
|
||||||
?.withManufacturerData
|
|
||||||
.map(
|
.map(
|
||||||
(e) => UniversalManufacturerDataFilter(
|
(e) => UniversalManufacturerDataFilter(
|
||||||
companyIdentifier: e.companyIdentifier,
|
companyIdentifier: e.companyIdentifier,
|
||||||
|
|||||||
@@ -17,21 +17,24 @@ abstract class UniversalBlePlatform {
|
|||||||
final _scanStreamController = UniversalBleStreamController<BleDevice>();
|
final _scanStreamController = UniversalBleStreamController<BleDevice>();
|
||||||
|
|
||||||
final bleConnectionUpdateStreamController =
|
final bleConnectionUpdateStreamController =
|
||||||
UniversalBleStreamController<
|
UniversalBleStreamController<({String deviceId, bool isConnected, String? error})>();
|
||||||
({String deviceId, bool isConnected, String? error})
|
|
||||||
>();
|
|
||||||
|
|
||||||
final _valueStreamController =
|
final _valueStreamController =
|
||||||
UniversalBleStreamController<
|
UniversalBleStreamController<({String deviceId, String characteristicId, Uint8List value})>();
|
||||||
({String deviceId, String characteristicId, Uint8List value})
|
|
||||||
>();
|
|
||||||
|
|
||||||
final _pairStateStreamController =
|
final _pairStateStreamController =
|
||||||
UniversalBleStreamController<({String deviceId, bool isPaired})>();
|
UniversalBleStreamController<({String deviceId, bool isPaired})>();
|
||||||
|
|
||||||
|
final _peripheralConnectionStreamController =
|
||||||
|
UniversalBleStreamController<BlePeripheralConnectionEvent>();
|
||||||
|
|
||||||
|
final _peripheralWriteStreamController = UniversalBleStreamController<BlePeripheralWriteEvent>();
|
||||||
|
|
||||||
|
final _peripheralSubscriptionStreamController =
|
||||||
|
UniversalBleStreamController<BlePeripheralSubscriptionEvent>();
|
||||||
|
|
||||||
/// Send latest availability state upon subscribing
|
/// Send latest availability state upon subscribing
|
||||||
late final _availabilityStreamController =
|
late final _availabilityStreamController = UniversalBleStreamController<AvailabilityState>(
|
||||||
UniversalBleStreamController<AvailabilityState>(
|
|
||||||
initialEvent: getBluetoothAvailabilityState,
|
initialEvent: getBluetoothAvailabilityState,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -41,35 +44,29 @@ abstract class UniversalBlePlatform {
|
|||||||
|
|
||||||
Future<bool> disableBluetooth();
|
Future<bool> disableBluetooth();
|
||||||
|
|
||||||
Future<bool> hasPermissions({bool withAndroidFineLocation = false}) async {
|
Future<bool> hasPermissions({
|
||||||
|
bool withAndroidFineLocation = false,
|
||||||
|
bool withAndroidBluetoothAdvertise = false,
|
||||||
|
}) async {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> requestPermissions({
|
Future<void> requestPermissions({
|
||||||
bool withAndroidFineLocation = false,
|
bool withAndroidFineLocation = false,
|
||||||
|
bool withAndroidBluetoothAdvertise = false,
|
||||||
}) async {}
|
}) async {}
|
||||||
|
|
||||||
Future<void> startScan({
|
Future<void> startScan({ScanFilter? scanFilter, PlatformConfig? platformConfig});
|
||||||
ScanFilter? scanFilter,
|
|
||||||
PlatformConfig? platformConfig,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> stopScan();
|
Future<void> stopScan();
|
||||||
|
|
||||||
Future<bool> isScanning();
|
Future<bool> isScanning();
|
||||||
|
|
||||||
Future<void> connect(
|
Future<void> connect(String deviceId, {Duration? connectionTimeout, bool autoConnect = false});
|
||||||
String deviceId, {
|
|
||||||
Duration? connectionTimeout,
|
|
||||||
bool autoConnect = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> disconnect(String deviceId);
|
Future<void> disconnect(String deviceId);
|
||||||
|
|
||||||
Future<List<BleService>> discoverServices(
|
Future<List<BleService>> discoverServices(String deviceId, bool withDescriptors);
|
||||||
String deviceId,
|
|
||||||
bool withDescriptors,
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<void> setNotifiable(
|
Future<void> setNotifiable(
|
||||||
String deviceId,
|
String deviceId,
|
||||||
@@ -97,10 +94,34 @@ abstract class UniversalBlePlatform {
|
|||||||
|
|
||||||
Future<int> readRssi(String deviceId);
|
Future<int> readRssi(String deviceId);
|
||||||
|
|
||||||
Future<void> requestConnectionPriority(
|
Future<void> requestConnectionPriority(String deviceId, BleConnectionPriority priority);
|
||||||
String deviceId,
|
|
||||||
BleConnectionPriority priority,
|
Future<bool> isPeripheralSupported() async => false;
|
||||||
);
|
|
||||||
|
Future<void> startPeripheral(BlePeripheralConfig config) {
|
||||||
|
throw UnsupportedError('BLE peripheral mode is not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> stopPeripheral() {
|
||||||
|
throw UnsupportedError('BLE peripheral mode is not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updatePeripheralCharacteristicValue(
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
Uint8List value,
|
||||||
|
) {
|
||||||
|
throw UnsupportedError('BLE peripheral mode is not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> notifyPeripheralCharacteristic(
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
Uint8List value, {
|
||||||
|
bool indicate = false,
|
||||||
|
}) {
|
||||||
|
throw UnsupportedError('BLE peripheral mode is not supported');
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> isPaired(String deviceId);
|
Future<bool> isPaired(String deviceId);
|
||||||
|
|
||||||
@@ -112,39 +133,39 @@ abstract class UniversalBlePlatform {
|
|||||||
|
|
||||||
Future<List<BleDevice>> getSystemDevices(List<String>? withServices);
|
Future<List<BleDevice>> getSystemDevices(List<String>? withServices);
|
||||||
|
|
||||||
Future<void> setLogLevel(BleLogLevel logLevel) async =>
|
Future<void> setLogLevel(BleLogLevel logLevel) async => UniversalLogger.setLogLevel(logLevel);
|
||||||
UniversalLogger.setLogLevel(logLevel);
|
|
||||||
|
|
||||||
bool receivesAdvertisements(String deviceId) => true;
|
bool receivesAdvertisements(String deviceId) => true;
|
||||||
|
|
||||||
/// Streams
|
/// Streams
|
||||||
Stream<BleDevice> get scanStream => _scanStreamController.stream;
|
Stream<BleDevice> get scanStream => _scanStreamController.stream;
|
||||||
|
|
||||||
Stream<AvailabilityState> get availabilityStream =>
|
Stream<AvailabilityState> get availabilityStream => _availabilityStreamController.stream;
|
||||||
_availabilityStreamController.stream;
|
|
||||||
|
|
||||||
Stream<bool> connectionStream(String deviceId) =>
|
Stream<bool> connectionStream(String deviceId) => bleConnectionUpdateStreamController.stream
|
||||||
bleConnectionUpdateStreamController.stream
|
|
||||||
.where((e) => e.deviceId == deviceId)
|
.where((e) => e.deviceId == deviceId)
|
||||||
.map((e) => e.isConnected);
|
.map((e) => e.isConnected);
|
||||||
|
|
||||||
Stream<Uint8List> characteristicValueStream(
|
Stream<Uint8List> characteristicValueStream(String deviceId, String characteristicId) {
|
||||||
String deviceId,
|
|
||||||
String characteristicId,
|
|
||||||
) {
|
|
||||||
characteristicId = BleUuidParser.string(characteristicId);
|
characteristicId = BleUuidParser.string(characteristicId);
|
||||||
return _valueStreamController.stream
|
return _valueStreamController.stream
|
||||||
.where((e) {
|
.where((e) {
|
||||||
return e.deviceId == deviceId &&
|
return e.deviceId == deviceId && e.characteristicId == characteristicId;
|
||||||
e.characteristicId == characteristicId;
|
|
||||||
})
|
})
|
||||||
.map((e) => e.value);
|
.map((e) => e.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<bool> pairingStateStream(String deviceId) => _pairStateStreamController
|
Stream<bool> pairingStateStream(String deviceId) =>
|
||||||
.stream
|
_pairStateStreamController.stream.where((e) => e.deviceId == deviceId).map((e) => e.isPaired);
|
||||||
.where((e) => e.deviceId == deviceId)
|
|
||||||
.map((e) => e.isPaired);
|
Stream<BlePeripheralConnectionEvent> get peripheralConnectionStream =>
|
||||||
|
_peripheralConnectionStreamController.stream;
|
||||||
|
|
||||||
|
Stream<BlePeripheralWriteEvent> get peripheralWriteStream =>
|
||||||
|
_peripheralWriteStreamController.stream;
|
||||||
|
|
||||||
|
Stream<BlePeripheralSubscriptionEvent> get peripheralSubscriptionStream =>
|
||||||
|
_peripheralSubscriptionStreamController.stream;
|
||||||
|
|
||||||
/// Update Handlers
|
/// Update Handlers
|
||||||
void updateScanResult(BleDevice bleDevice) {
|
void updateScanResult(BleDevice bleDevice) {
|
||||||
@@ -206,19 +227,27 @@ abstract class UniversalBlePlatform {
|
|||||||
onPairingStateChange?.call(deviceId, isPaired);
|
onPairingStateChange?.call(deviceId, isPaired);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updatePeripheralConnection(String deviceId, bool connected) {
|
||||||
|
_peripheralConnectionStreamController.add(
|
||||||
|
BlePeripheralConnectionEvent(deviceId: deviceId, connected: connected),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePeripheralWrite(BlePeripheralWriteEvent event) {
|
||||||
|
_peripheralWriteStreamController.add(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePeripheralSubscription(BlePeripheralSubscriptionEvent event) {
|
||||||
|
_peripheralSubscriptionStreamController.add(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback types
|
// Callback types
|
||||||
typedef OnConnectionChange =
|
typedef OnConnectionChange = void Function(String deviceId, bool isConnected, String? error);
|
||||||
void Function(String deviceId, bool isConnected, String? error);
|
|
||||||
|
|
||||||
typedef OnValueChange =
|
typedef OnValueChange =
|
||||||
void Function(
|
void Function(String deviceId, String characteristicId, Uint8List value, int? timestamp);
|
||||||
String deviceId,
|
|
||||||
String characteristicId,
|
|
||||||
Uint8List value,
|
|
||||||
int? timestamp,
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef OnScanResult = void Function(BleDevice scanResult);
|
typedef OnScanResult = void Function(BleDevice scanResult);
|
||||||
|
|
||||||
|
|||||||
+90
-65
@@ -6,8 +6,7 @@ import 'package:pigeon/pigeon.dart';
|
|||||||
dartPackageName: 'universal_ble',
|
dartPackageName: 'universal_ble',
|
||||||
dartOut: 'lib/src/universal_ble_pigeon/universal_ble.g.dart',
|
dartOut: 'lib/src/universal_ble_pigeon/universal_ble.g.dart',
|
||||||
dartOptions: DartOptions(),
|
dartOptions: DartOptions(),
|
||||||
kotlinOut:
|
kotlinOut: 'android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt',
|
||||||
'android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt',
|
|
||||||
swiftOut: 'darwin/universal_ble/Sources/universal_ble/UniversalBle.g.swift',
|
swiftOut: 'darwin/universal_ble/Sources/universal_ble/UniversalBle.g.swift',
|
||||||
kotlinOptions: KotlinOptions(package: 'com.navideck.universal_ble'),
|
kotlinOptions: KotlinOptions(package: 'com.navideck.universal_ble'),
|
||||||
swiftOptions: SwiftOptions(),
|
swiftOptions: SwiftOptions(),
|
||||||
@@ -17,17 +16,16 @@ import 'package:pigeon/pigeon.dart';
|
|||||||
debugGenerators: true,
|
debugGenerators: true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
/// Flutter -> Native
|
/// Flutter -> Native
|
||||||
@HostApi()
|
@HostApi()
|
||||||
abstract class UniversalBlePlatformChannel {
|
abstract class UniversalBlePlatformChannel {
|
||||||
@async
|
@async
|
||||||
int getBluetoothAvailabilityState();
|
int getBluetoothAvailabilityState();
|
||||||
|
|
||||||
bool hasPermissions(bool withAndroidFineLocation);
|
bool hasPermissions(bool withAndroidFineLocation, bool withAndroidBluetoothAdvertise);
|
||||||
|
|
||||||
@async
|
@async
|
||||||
void requestPermissions(bool withAndroidFineLocation);
|
void requestPermissions(bool withAndroidFineLocation, bool withAndroidBluetoothAdvertise);
|
||||||
|
|
||||||
@async
|
@async
|
||||||
bool enableBluetooth();
|
bool enableBluetooth();
|
||||||
@@ -46,25 +44,13 @@ abstract class UniversalBlePlatformChannel {
|
|||||||
void disconnect(String deviceId);
|
void disconnect(String deviceId);
|
||||||
|
|
||||||
@async
|
@async
|
||||||
void setNotifiable(
|
void setNotifiable(String deviceId, String service, String characteristic, int bleInputProperty);
|
||||||
String deviceId,
|
|
||||||
String service,
|
|
||||||
String characteristic,
|
|
||||||
int bleInputProperty,
|
|
||||||
);
|
|
||||||
|
|
||||||
@async
|
@async
|
||||||
List<UniversalBleService> discoverServices(
|
List<UniversalBleService> discoverServices(String deviceId, bool withDescriptors);
|
||||||
String deviceId,
|
|
||||||
bool withDescriptors,
|
|
||||||
);
|
|
||||||
|
|
||||||
@async
|
@async
|
||||||
Uint8List readValue(
|
Uint8List readValue(String deviceId, String service, String characteristic);
|
||||||
String deviceId,
|
|
||||||
String service,
|
|
||||||
String characteristic,
|
|
||||||
);
|
|
||||||
|
|
||||||
@async
|
@async
|
||||||
int requestMtu(String deviceId, int expectedMtu);
|
int requestMtu(String deviceId, int expectedMtu);
|
||||||
@@ -87,9 +73,7 @@ abstract class UniversalBlePlatformChannel {
|
|||||||
void unPair(String deviceId);
|
void unPair(String deviceId);
|
||||||
|
|
||||||
@async
|
@async
|
||||||
List<UniversalBleScanResult> getSystemDevices(
|
List<UniversalBleScanResult> getSystemDevices(List<String> withServices);
|
||||||
List<String> withServices,
|
|
||||||
);
|
|
||||||
|
|
||||||
int getConnectionState(String deviceId);
|
int getConnectionState(String deviceId);
|
||||||
|
|
||||||
@@ -99,6 +83,25 @@ abstract class UniversalBlePlatformChannel {
|
|||||||
@async
|
@async
|
||||||
void requestConnectionPriority(String deviceId, int priority);
|
void requestConnectionPriority(String deviceId, int priority);
|
||||||
|
|
||||||
|
bool isPeripheralSupported();
|
||||||
|
|
||||||
|
@async
|
||||||
|
void startPeripheral(UniversalBlePeripheralConfig config);
|
||||||
|
|
||||||
|
@async
|
||||||
|
void stopPeripheral();
|
||||||
|
|
||||||
|
@async
|
||||||
|
void updatePeripheralCharacteristicValue(String service, String characteristic, Uint8List value);
|
||||||
|
|
||||||
|
@async
|
||||||
|
void notifyPeripheralCharacteristic(
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
Uint8List value,
|
||||||
|
bool indicate,
|
||||||
|
);
|
||||||
|
|
||||||
void setLogLevel(UniversalBleLogLevel logLevel);
|
void setLogLevel(UniversalBleLogLevel logLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,17 +114,19 @@ abstract class UniversalBleCallbackChannel {
|
|||||||
|
|
||||||
void onScanResult(UniversalBleScanResult result);
|
void onScanResult(UniversalBleScanResult result);
|
||||||
|
|
||||||
void onValueChanged(
|
void onValueChanged(String deviceId, String characteristicId, Uint8List value, int? timestamp);
|
||||||
String deviceId,
|
|
||||||
String characteristicId,
|
|
||||||
Uint8List value,
|
|
||||||
int? timestamp,
|
|
||||||
);
|
|
||||||
|
|
||||||
void onConnectionChanged(
|
void onConnectionChanged(String deviceId, bool connected, String? error);
|
||||||
|
|
||||||
|
void onPeripheralConnectionChanged(String deviceId, bool connected);
|
||||||
|
|
||||||
|
void onPeripheralWrite(UniversalBlePeripheralWriteEvent event);
|
||||||
|
|
||||||
|
void onPeripheralSubscriptionChanged(
|
||||||
String deviceId,
|
String deviceId,
|
||||||
bool connected,
|
String service,
|
||||||
String? error,
|
String characteristic,
|
||||||
|
bool subscribed,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,14 +152,7 @@ class UniversalBleScanResult {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
enum UniversalBleLogLevel {
|
enum UniversalBleLogLevel { none, error, warning, info, debug, verbose }
|
||||||
none,
|
|
||||||
error,
|
|
||||||
warning,
|
|
||||||
info,
|
|
||||||
debug,
|
|
||||||
verbose,
|
|
||||||
}
|
|
||||||
|
|
||||||
class UniversalBleService {
|
class UniversalBleService {
|
||||||
String uuid;
|
String uuid;
|
||||||
@@ -174,14 +172,56 @@ class UniversalBleDescriptor {
|
|||||||
UniversalBleDescriptor(this.uuid);
|
UniversalBleDescriptor(this.uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class UniversalBlePeripheralConfig {
|
||||||
|
String advertisedName;
|
||||||
|
List<UniversalBlePeripheralService> services;
|
||||||
|
|
||||||
|
UniversalBlePeripheralConfig(this.advertisedName, this.services);
|
||||||
|
}
|
||||||
|
|
||||||
|
class UniversalBlePeripheralService {
|
||||||
|
String uuid;
|
||||||
|
List<UniversalBlePeripheralCharacteristic> characteristics;
|
||||||
|
|
||||||
|
UniversalBlePeripheralService(this.uuid, this.characteristics);
|
||||||
|
}
|
||||||
|
|
||||||
|
class UniversalBlePeripheralCharacteristic {
|
||||||
|
String uuid;
|
||||||
|
List<int> properties;
|
||||||
|
List<int> permissions;
|
||||||
|
List<UniversalBlePeripheralDescriptor> descriptors;
|
||||||
|
Uint8List? initialValue;
|
||||||
|
|
||||||
|
UniversalBlePeripheralCharacteristic(
|
||||||
|
this.uuid,
|
||||||
|
this.properties,
|
||||||
|
this.permissions,
|
||||||
|
this.descriptors,
|
||||||
|
this.initialValue,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class UniversalBlePeripheralDescriptor {
|
||||||
|
String uuid;
|
||||||
|
List<int> permissions;
|
||||||
|
Uint8List? initialValue;
|
||||||
|
|
||||||
|
UniversalBlePeripheralDescriptor(this.uuid, this.permissions, this.initialValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
class UniversalBlePeripheralWriteEvent {
|
||||||
|
String deviceId;
|
||||||
|
String service;
|
||||||
|
String characteristic;
|
||||||
|
Uint8List value;
|
||||||
|
|
||||||
|
UniversalBlePeripheralWriteEvent(this.deviceId, this.service, this.characteristic, this.value);
|
||||||
|
}
|
||||||
|
|
||||||
/// Scan config
|
/// Scan config
|
||||||
|
|
||||||
enum AndroidScanMode {
|
enum AndroidScanMode { balanced, lowLatency, lowPower, opportunistic }
|
||||||
balanced,
|
|
||||||
lowLatency,
|
|
||||||
lowPower,
|
|
||||||
opportunistic,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Android options to scan devices
|
/// Android options to scan devices
|
||||||
/// [requestLocationPermission] is used to request location permission on Android 12+ (API 31+).
|
/// [requestLocationPermission] is used to request location permission on Android 12+ (API 31+).
|
||||||
@@ -193,11 +233,7 @@ class AndroidOptions {
|
|||||||
bool? requestLocationPermission;
|
bool? requestLocationPermission;
|
||||||
AndroidScanMode? scanMode;
|
AndroidScanMode? scanMode;
|
||||||
int? reportDelayMillis;
|
int? reportDelayMillis;
|
||||||
AndroidOptions({
|
AndroidOptions({this.requestLocationPermission, this.scanMode, this.reportDelayMillis});
|
||||||
this.requestLocationPermission,
|
|
||||||
this.scanMode,
|
|
||||||
this.reportDelayMillis,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class UniversalScanConfig {
|
class UniversalScanConfig {
|
||||||
@@ -211,32 +247,21 @@ class UniversalScanFilter {
|
|||||||
final List<String> withNamePrefix;
|
final List<String> withNamePrefix;
|
||||||
final List<UniversalManufacturerDataFilter> withManufacturerData;
|
final List<UniversalManufacturerDataFilter> withManufacturerData;
|
||||||
|
|
||||||
UniversalScanFilter(
|
UniversalScanFilter(this.withServices, this.withNamePrefix, this.withManufacturerData);
|
||||||
this.withServices,
|
|
||||||
this.withNamePrefix,
|
|
||||||
this.withManufacturerData,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class UniversalManufacturerDataFilter {
|
class UniversalManufacturerDataFilter {
|
||||||
int companyIdentifier;
|
int companyIdentifier;
|
||||||
Uint8List? data;
|
Uint8List? data;
|
||||||
Uint8List? mask;
|
Uint8List? mask;
|
||||||
UniversalManufacturerDataFilter({
|
UniversalManufacturerDataFilter({required this.companyIdentifier, this.data, this.mask});
|
||||||
required this.companyIdentifier,
|
|
||||||
this.data,
|
|
||||||
this.mask,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class UniversalManufacturerData {
|
class UniversalManufacturerData {
|
||||||
final int companyIdentifier;
|
final int companyIdentifier;
|
||||||
final Uint8List data;
|
final Uint8List data;
|
||||||
|
|
||||||
UniversalManufacturerData({
|
UniversalManufacturerData({required this.companyIdentifier, required this.data});
|
||||||
required this.companyIdentifier,
|
|
||||||
required this.data,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unified error codes for all platforms
|
/// Unified error codes for all platforms
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ dependencies:
|
|||||||
plugin_platform_interface: ^2.1.8
|
plugin_platform_interface: ^2.1.8
|
||||||
flutter_web_bluetooth: ^1.1.0
|
flutter_web_bluetooth: ^1.1.0
|
||||||
bluez: ^0.8.3
|
bluez: ^0.8.3
|
||||||
|
dbus: ^0.7.11
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ void main() {
|
|||||||
group('BleCharacteristic Tests', () {
|
group('BleCharacteristic Tests', () {
|
||||||
test("DiscoverServices test", () async {
|
test("DiscoverServices test", () async {
|
||||||
debugPrint("Discovering services");
|
debugPrint("Discovering services");
|
||||||
List<BleService> services =
|
List<BleService> services = await UniversalBle.discoverServices(mockDeviceId);
|
||||||
await UniversalBle.discoverServices(mockDeviceId);
|
|
||||||
expect(services.length, 1);
|
expect(services.length, 1);
|
||||||
|
|
||||||
BleService service = services.first;
|
BleService service = services.first;
|
||||||
@@ -35,18 +34,9 @@ void main() {
|
|||||||
expect(service.characteristics.length, 1);
|
expect(service.characteristics.length, 1);
|
||||||
|
|
||||||
BleCharacteristic characteristic = service.characteristics.first;
|
BleCharacteristic characteristic = service.characteristics.first;
|
||||||
expect(
|
expect(BleUuidParser.compareStrings(characteristic.uuid, characteristicId), true);
|
||||||
BleUuidParser.compareStrings(characteristic.uuid, characteristicId),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
expect(characteristic.metaData?.deviceId, mockDeviceId);
|
expect(characteristic.metaData?.deviceId, mockDeviceId);
|
||||||
expect(
|
expect(BleUuidParser.compareStrings(characteristic.metaData!.serviceId, serviceId), true);
|
||||||
BleUuidParser.compareStrings(
|
|
||||||
characteristic.metaData!.serviceId,
|
|
||||||
serviceId,
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Subscription Test", () async {
|
test("Subscription Test", () async {
|
||||||
@@ -87,14 +77,17 @@ class _UniversalBleMock extends UniversalBlePlatformMock {
|
|||||||
Uint8List? charValue;
|
Uint8List? charValue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<BleService>> discoverServices(
|
Future<List<BleService>> discoverServices(String deviceId, bool withDescriptors) async {
|
||||||
String deviceId, bool withDescriptors) async {
|
|
||||||
return <BleService>[mockBleService];
|
return <BleService>[mockBleService];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setNotifiable(String deviceId, String service,
|
Future<void> setNotifiable(
|
||||||
String characteristic, BleInputProperty bleInputProperty) async {
|
String deviceId,
|
||||||
|
String service,
|
||||||
|
String characteristic,
|
||||||
|
BleInputProperty bleInputProperty,
|
||||||
|
) async {
|
||||||
if (bleInputProperty == BleInputProperty.disabled) {
|
if (bleInputProperty == BleInputProperty.disabled) {
|
||||||
notifierTimer?.cancel();
|
notifierTimer?.cancel();
|
||||||
notifierTimer = null;
|
notifierTimer = null;
|
||||||
@@ -117,19 +110,26 @@ class _UniversalBleMock extends UniversalBlePlatformMock {
|
|||||||
String service,
|
String service,
|
||||||
String characteristic,
|
String characteristic,
|
||||||
Uint8List value,
|
Uint8List value,
|
||||||
BleOutputProperty bleOutputProperty) async {
|
BleOutputProperty bleOutputProperty,
|
||||||
|
) async {
|
||||||
charValue = value;
|
charValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Uint8List> readValue(
|
Future<Uint8List> readValue(
|
||||||
String deviceId, String service, String characteristic,
|
String deviceId,
|
||||||
{Duration? timeout}) async {
|
String service,
|
||||||
|
String characteristic, {
|
||||||
|
Duration? timeout,
|
||||||
|
}) async {
|
||||||
return charValue ?? Uint8List(0);
|
return charValue ?? Uint8List(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> requestPermissions({bool withAndroidFineLocation = false}) {
|
Future<void> requestPermissions({
|
||||||
|
bool withAndroidFineLocation = false,
|
||||||
|
bool withAndroidBluetoothAdvertise = false,
|
||||||
|
}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:universal_ble/universal_ble.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('BlePeripheral models', () {
|
||||||
|
test('normalizes UUIDs and defensively copies characteristic values', () {
|
||||||
|
final initialValue = Uint8List.fromList([1, 2, 3]);
|
||||||
|
|
||||||
|
final characteristic = BlePeripheralCharacteristic(
|
||||||
|
uuid: 'fff1',
|
||||||
|
properties: const [CharacteristicProperty.read],
|
||||||
|
permissions: const [BlePeripheralCharacteristicPermission.read],
|
||||||
|
initialValue: initialValue,
|
||||||
|
);
|
||||||
|
|
||||||
|
initialValue[0] = 9;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
BleUuidParser.compareStrings(characteristic.uuid, '0000fff1-0000-1000-8000-00805f9b34fb'),
|
||||||
|
isTrue,
|
||||||
|
);
|
||||||
|
expect(characteristic.initialValue, [1, 2, 3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('normalizes write event UUIDs and defensively copies payloads', () {
|
||||||
|
final value = Uint8List.fromList([4, 5, 6]);
|
||||||
|
|
||||||
|
final event = BlePeripheralWriteEvent(
|
||||||
|
deviceId: 'client-1',
|
||||||
|
service: 'fff0',
|
||||||
|
characteristic: 'fff1',
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
|
||||||
|
value[0] = 8;
|
||||||
|
|
||||||
|
expect(event.deviceId, 'client-1');
|
||||||
|
expect(BleUuidParser.compareStrings(event.service, 'fff0'), isTrue);
|
||||||
|
expect(BleUuidParser.compareStrings(event.characteristic, 'fff1'), isTrue);
|
||||||
|
expect(event.value, [4, 5, 6]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
// Autogenerated from Pigeon (v26.1.4), do not edit directly.
|
// Autogenerated from Pigeon (v26.3.4), do not edit directly.
|
||||||
// See also: https://pub.dev/packages/pigeon
|
// See also: https://pub.dev/packages/pigeon
|
||||||
|
|
||||||
#ifndef PIGEON_UNIVERSAL_BLE_G_H_
|
#ifndef PIGEON_UNIVERSAL_BLE_G_H_
|
||||||
@@ -23,17 +23,17 @@ class FlutterError {
|
|||||||
: code_(code) {}
|
: code_(code) {}
|
||||||
explicit FlutterError(const std::string& code, const std::string& message)
|
explicit FlutterError(const std::string& code, const std::string& message)
|
||||||
: code_(code), message_(message) {}
|
: code_(code), message_(message) {}
|
||||||
explicit FlutterError(const std::string& code, const std::string& message, const flutter::EncodableValue& details)
|
explicit FlutterError(const std::string& code, const std::string& message, const ::flutter::EncodableValue& details)
|
||||||
: code_(code), message_(message), details_(details) {}
|
: code_(code), message_(message), details_(details) {}
|
||||||
|
|
||||||
const std::string& code() const { return code_; }
|
const std::string& code() const { return code_; }
|
||||||
const std::string& message() const { return message_; }
|
const std::string& message() const { return message_; }
|
||||||
const flutter::EncodableValue& details() const { return details_; }
|
const ::flutter::EncodableValue& details() const { return details_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string code_;
|
std::string code_;
|
||||||
std::string message_;
|
std::string message_;
|
||||||
flutter::EncodableValue details_;
|
::flutter::EncodableValue details_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> class ErrorOr {
|
template<class T> class ErrorOr {
|
||||||
@@ -152,9 +152,9 @@ class UniversalBleScanResult {
|
|||||||
const std::string* name,
|
const std::string* name,
|
||||||
const bool* is_paired,
|
const bool* is_paired,
|
||||||
const int64_t* rssi,
|
const int64_t* rssi,
|
||||||
const flutter::EncodableList* manufacturer_data_list,
|
const ::flutter::EncodableList* manufacturer_data_list,
|
||||||
const flutter::EncodableMap* service_data,
|
const ::flutter::EncodableMap* service_data,
|
||||||
const flutter::EncodableList* services,
|
const ::flutter::EncodableList* services,
|
||||||
const int64_t* timestamp);
|
const int64_t* timestamp);
|
||||||
|
|
||||||
const std::string& device_id() const;
|
const std::string& device_id() const;
|
||||||
@@ -172,25 +172,29 @@ class UniversalBleScanResult {
|
|||||||
void set_rssi(const int64_t* value_arg);
|
void set_rssi(const int64_t* value_arg);
|
||||||
void set_rssi(int64_t value_arg);
|
void set_rssi(int64_t value_arg);
|
||||||
|
|
||||||
const flutter::EncodableList* manufacturer_data_list() const;
|
const ::flutter::EncodableList* manufacturer_data_list() const;
|
||||||
void set_manufacturer_data_list(const flutter::EncodableList* value_arg);
|
void set_manufacturer_data_list(const ::flutter::EncodableList* value_arg);
|
||||||
void set_manufacturer_data_list(const flutter::EncodableList& value_arg);
|
void set_manufacturer_data_list(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
const flutter::EncodableMap* service_data() const;
|
const ::flutter::EncodableMap* service_data() const;
|
||||||
void set_service_data(const flutter::EncodableMap* value_arg);
|
void set_service_data(const ::flutter::EncodableMap* value_arg);
|
||||||
void set_service_data(const flutter::EncodableMap& value_arg);
|
void set_service_data(const ::flutter::EncodableMap& value_arg);
|
||||||
|
|
||||||
const flutter::EncodableList* services() const;
|
const ::flutter::EncodableList* services() const;
|
||||||
void set_services(const flutter::EncodableList* value_arg);
|
void set_services(const ::flutter::EncodableList* value_arg);
|
||||||
void set_services(const flutter::EncodableList& value_arg);
|
void set_services(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
const int64_t* timestamp() const;
|
const int64_t* timestamp() const;
|
||||||
void set_timestamp(const int64_t* value_arg);
|
void set_timestamp(const int64_t* value_arg);
|
||||||
void set_timestamp(int64_t value_arg);
|
void set_timestamp(int64_t value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBleScanResult& other) const;
|
||||||
|
bool operator!=(const UniversalBleScanResult& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static UniversalBleScanResult FromEncodableList(const flutter::EncodableList& list);
|
static UniversalBleScanResult FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
friend class PigeonInternalCodecSerializer;
|
friend class PigeonInternalCodecSerializer;
|
||||||
@@ -198,9 +202,9 @@ class UniversalBleScanResult {
|
|||||||
std::optional<std::string> name_;
|
std::optional<std::string> name_;
|
||||||
std::optional<bool> is_paired_;
|
std::optional<bool> is_paired_;
|
||||||
std::optional<int64_t> rssi_;
|
std::optional<int64_t> rssi_;
|
||||||
std::optional<flutter::EncodableList> manufacturer_data_list_;
|
std::optional<::flutter::EncodableList> manufacturer_data_list_;
|
||||||
std::optional<flutter::EncodableMap> service_data_;
|
std::optional<::flutter::EncodableMap> service_data_;
|
||||||
std::optional<flutter::EncodableList> services_;
|
std::optional<::flutter::EncodableList> services_;
|
||||||
std::optional<int64_t> timestamp_;
|
std::optional<int64_t> timestamp_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -214,23 +218,27 @@ class UniversalBleService {
|
|||||||
// Constructs an object setting all fields.
|
// Constructs an object setting all fields.
|
||||||
explicit UniversalBleService(
|
explicit UniversalBleService(
|
||||||
const std::string& uuid,
|
const std::string& uuid,
|
||||||
const flutter::EncodableList* characteristics);
|
const ::flutter::EncodableList* characteristics);
|
||||||
|
|
||||||
const std::string& uuid() const;
|
const std::string& uuid() const;
|
||||||
void set_uuid(std::string_view value_arg);
|
void set_uuid(std::string_view value_arg);
|
||||||
|
|
||||||
const flutter::EncodableList* characteristics() const;
|
const ::flutter::EncodableList* characteristics() const;
|
||||||
void set_characteristics(const flutter::EncodableList* value_arg);
|
void set_characteristics(const ::flutter::EncodableList* value_arg);
|
||||||
void set_characteristics(const flutter::EncodableList& value_arg);
|
void set_characteristics(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBleService& other) const;
|
||||||
|
bool operator!=(const UniversalBleService& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static UniversalBleService FromEncodableList(const flutter::EncodableList& list);
|
static UniversalBleService FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
friend class PigeonInternalCodecSerializer;
|
friend class PigeonInternalCodecSerializer;
|
||||||
std::string uuid_;
|
std::string uuid_;
|
||||||
std::optional<flutter::EncodableList> characteristics_;
|
std::optional<::flutter::EncodableList> characteristics_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -240,27 +248,31 @@ class UniversalBleCharacteristic {
|
|||||||
// Constructs an object setting all fields.
|
// Constructs an object setting all fields.
|
||||||
explicit UniversalBleCharacteristic(
|
explicit UniversalBleCharacteristic(
|
||||||
const std::string& uuid,
|
const std::string& uuid,
|
||||||
const flutter::EncodableList& properties,
|
const ::flutter::EncodableList& properties,
|
||||||
const flutter::EncodableList& descriptors);
|
const ::flutter::EncodableList& descriptors);
|
||||||
|
|
||||||
const std::string& uuid() const;
|
const std::string& uuid() const;
|
||||||
void set_uuid(std::string_view value_arg);
|
void set_uuid(std::string_view value_arg);
|
||||||
|
|
||||||
const flutter::EncodableList& properties() const;
|
const ::flutter::EncodableList& properties() const;
|
||||||
void set_properties(const flutter::EncodableList& value_arg);
|
void set_properties(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
const flutter::EncodableList& descriptors() const;
|
const ::flutter::EncodableList& descriptors() const;
|
||||||
void set_descriptors(const flutter::EncodableList& value_arg);
|
void set_descriptors(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBleCharacteristic& other) const;
|
||||||
|
bool operator!=(const UniversalBleCharacteristic& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static UniversalBleCharacteristic FromEncodableList(const flutter::EncodableList& list);
|
static UniversalBleCharacteristic FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
friend class PigeonInternalCodecSerializer;
|
friend class PigeonInternalCodecSerializer;
|
||||||
std::string uuid_;
|
std::string uuid_;
|
||||||
flutter::EncodableList properties_;
|
::flutter::EncodableList properties_;
|
||||||
flutter::EncodableList descriptors_;
|
::flutter::EncodableList descriptors_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -273,9 +285,13 @@ class UniversalBleDescriptor {
|
|||||||
const std::string& uuid() const;
|
const std::string& uuid() const;
|
||||||
void set_uuid(std::string_view value_arg);
|
void set_uuid(std::string_view value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBleDescriptor& other) const;
|
||||||
|
bool operator!=(const UniversalBleDescriptor& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static UniversalBleDescriptor FromEncodableList(const flutter::EncodableList& list);
|
static UniversalBleDescriptor FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
friend class PigeonInternalCodecSerializer;
|
friend class PigeonInternalCodecSerializer;
|
||||||
@@ -283,6 +299,195 @@ class UniversalBleDescriptor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
class UniversalBlePeripheralConfig {
|
||||||
|
public:
|
||||||
|
// Constructs an object setting all fields.
|
||||||
|
explicit UniversalBlePeripheralConfig(
|
||||||
|
const std::string& advertised_name,
|
||||||
|
const ::flutter::EncodableList& services);
|
||||||
|
|
||||||
|
const std::string& advertised_name() const;
|
||||||
|
void set_advertised_name(std::string_view value_arg);
|
||||||
|
|
||||||
|
const ::flutter::EncodableList& services() const;
|
||||||
|
void set_services(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBlePeripheralConfig& other) const;
|
||||||
|
bool operator!=(const UniversalBlePeripheralConfig& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
|
private:
|
||||||
|
static UniversalBlePeripheralConfig FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
|
friend class UniversalBlePlatformChannel;
|
||||||
|
friend class UniversalBleCallbackChannel;
|
||||||
|
friend class PigeonInternalCodecSerializer;
|
||||||
|
std::string advertised_name_;
|
||||||
|
::flutter::EncodableList services_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
class UniversalBlePeripheralService {
|
||||||
|
public:
|
||||||
|
// Constructs an object setting all fields.
|
||||||
|
explicit UniversalBlePeripheralService(
|
||||||
|
const std::string& uuid,
|
||||||
|
const ::flutter::EncodableList& characteristics);
|
||||||
|
|
||||||
|
const std::string& uuid() const;
|
||||||
|
void set_uuid(std::string_view value_arg);
|
||||||
|
|
||||||
|
const ::flutter::EncodableList& characteristics() const;
|
||||||
|
void set_characteristics(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBlePeripheralService& other) const;
|
||||||
|
bool operator!=(const UniversalBlePeripheralService& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
|
private:
|
||||||
|
static UniversalBlePeripheralService FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
|
friend class UniversalBlePlatformChannel;
|
||||||
|
friend class UniversalBleCallbackChannel;
|
||||||
|
friend class PigeonInternalCodecSerializer;
|
||||||
|
std::string uuid_;
|
||||||
|
::flutter::EncodableList characteristics_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
class UniversalBlePeripheralCharacteristic {
|
||||||
|
public:
|
||||||
|
// Constructs an object setting all non-nullable fields.
|
||||||
|
explicit UniversalBlePeripheralCharacteristic(
|
||||||
|
const std::string& uuid,
|
||||||
|
const ::flutter::EncodableList& properties,
|
||||||
|
const ::flutter::EncodableList& permissions,
|
||||||
|
const ::flutter::EncodableList& descriptors);
|
||||||
|
|
||||||
|
// Constructs an object setting all fields.
|
||||||
|
explicit UniversalBlePeripheralCharacteristic(
|
||||||
|
const std::string& uuid,
|
||||||
|
const ::flutter::EncodableList& properties,
|
||||||
|
const ::flutter::EncodableList& permissions,
|
||||||
|
const ::flutter::EncodableList& descriptors,
|
||||||
|
const std::vector<uint8_t>* initial_value);
|
||||||
|
|
||||||
|
const std::string& uuid() const;
|
||||||
|
void set_uuid(std::string_view value_arg);
|
||||||
|
|
||||||
|
const ::flutter::EncodableList& properties() const;
|
||||||
|
void set_properties(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
const ::flutter::EncodableList& permissions() const;
|
||||||
|
void set_permissions(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
const ::flutter::EncodableList& descriptors() const;
|
||||||
|
void set_descriptors(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
const std::vector<uint8_t>* initial_value() const;
|
||||||
|
void set_initial_value(const std::vector<uint8_t>* value_arg);
|
||||||
|
void set_initial_value(const std::vector<uint8_t>& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBlePeripheralCharacteristic& other) const;
|
||||||
|
bool operator!=(const UniversalBlePeripheralCharacteristic& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
|
private:
|
||||||
|
static UniversalBlePeripheralCharacteristic FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
|
friend class UniversalBlePlatformChannel;
|
||||||
|
friend class UniversalBleCallbackChannel;
|
||||||
|
friend class PigeonInternalCodecSerializer;
|
||||||
|
std::string uuid_;
|
||||||
|
::flutter::EncodableList properties_;
|
||||||
|
::flutter::EncodableList permissions_;
|
||||||
|
::flutter::EncodableList descriptors_;
|
||||||
|
std::optional<std::vector<uint8_t>> initial_value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
class UniversalBlePeripheralDescriptor {
|
||||||
|
public:
|
||||||
|
// Constructs an object setting all non-nullable fields.
|
||||||
|
explicit UniversalBlePeripheralDescriptor(
|
||||||
|
const std::string& uuid,
|
||||||
|
const ::flutter::EncodableList& permissions);
|
||||||
|
|
||||||
|
// Constructs an object setting all fields.
|
||||||
|
explicit UniversalBlePeripheralDescriptor(
|
||||||
|
const std::string& uuid,
|
||||||
|
const ::flutter::EncodableList& permissions,
|
||||||
|
const std::vector<uint8_t>* initial_value);
|
||||||
|
|
||||||
|
const std::string& uuid() const;
|
||||||
|
void set_uuid(std::string_view value_arg);
|
||||||
|
|
||||||
|
const ::flutter::EncodableList& permissions() const;
|
||||||
|
void set_permissions(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
const std::vector<uint8_t>* initial_value() const;
|
||||||
|
void set_initial_value(const std::vector<uint8_t>* value_arg);
|
||||||
|
void set_initial_value(const std::vector<uint8_t>& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBlePeripheralDescriptor& other) const;
|
||||||
|
bool operator!=(const UniversalBlePeripheralDescriptor& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
|
private:
|
||||||
|
static UniversalBlePeripheralDescriptor FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
|
friend class UniversalBlePlatformChannel;
|
||||||
|
friend class UniversalBleCallbackChannel;
|
||||||
|
friend class PigeonInternalCodecSerializer;
|
||||||
|
std::string uuid_;
|
||||||
|
::flutter::EncodableList permissions_;
|
||||||
|
std::optional<std::vector<uint8_t>> initial_value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Generated class from Pigeon that represents data sent in messages.
|
||||||
|
class UniversalBlePeripheralWriteEvent {
|
||||||
|
public:
|
||||||
|
// Constructs an object setting all fields.
|
||||||
|
explicit UniversalBlePeripheralWriteEvent(
|
||||||
|
const std::string& device_id,
|
||||||
|
const std::string& service,
|
||||||
|
const std::string& characteristic,
|
||||||
|
const std::vector<uint8_t>& value);
|
||||||
|
|
||||||
|
const std::string& device_id() const;
|
||||||
|
void set_device_id(std::string_view value_arg);
|
||||||
|
|
||||||
|
const std::string& service() const;
|
||||||
|
void set_service(std::string_view value_arg);
|
||||||
|
|
||||||
|
const std::string& characteristic() const;
|
||||||
|
void set_characteristic(std::string_view value_arg);
|
||||||
|
|
||||||
|
const std::vector<uint8_t>& value() const;
|
||||||
|
void set_value(const std::vector<uint8_t>& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalBlePeripheralWriteEvent& other) const;
|
||||||
|
bool operator!=(const UniversalBlePeripheralWriteEvent& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
|
private:
|
||||||
|
static UniversalBlePeripheralWriteEvent FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
|
friend class UniversalBlePlatformChannel;
|
||||||
|
friend class UniversalBleCallbackChannel;
|
||||||
|
friend class PigeonInternalCodecSerializer;
|
||||||
|
std::string device_id_;
|
||||||
|
std::string service_;
|
||||||
|
std::string characteristic_;
|
||||||
|
std::vector<uint8_t> value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Android options to scan devices
|
// Android options to scan devices
|
||||||
// [requestLocationPermission] is used to request location permission on Android 12+ (API 31+).
|
// [requestLocationPermission] is used to request location permission on Android 12+ (API 31+).
|
||||||
// [scanMode] is used to set the scan mode for for Bluetooth LE scan.
|
// [scanMode] is used to set the scan mode for for Bluetooth LE scan.
|
||||||
@@ -314,9 +519,13 @@ class AndroidOptions {
|
|||||||
void set_report_delay_millis(const int64_t* value_arg);
|
void set_report_delay_millis(const int64_t* value_arg);
|
||||||
void set_report_delay_millis(int64_t value_arg);
|
void set_report_delay_millis(int64_t value_arg);
|
||||||
|
|
||||||
|
bool operator==(const AndroidOptions& other) const;
|
||||||
|
bool operator!=(const AndroidOptions& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static AndroidOptions FromEncodableList(const flutter::EncodableList& list);
|
static AndroidOptions FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalScanConfig;
|
friend class UniversalScanConfig;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
@@ -345,9 +554,13 @@ class UniversalScanConfig {
|
|||||||
void set_android(const AndroidOptions* value_arg);
|
void set_android(const AndroidOptions* value_arg);
|
||||||
void set_android(const AndroidOptions& value_arg);
|
void set_android(const AndroidOptions& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalScanConfig& other) const;
|
||||||
|
bool operator!=(const UniversalScanConfig& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static UniversalScanConfig FromEncodableList(const flutter::EncodableList& list);
|
static UniversalScanConfig FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
friend class PigeonInternalCodecSerializer;
|
friend class PigeonInternalCodecSerializer;
|
||||||
@@ -362,28 +575,32 @@ class UniversalScanFilter {
|
|||||||
public:
|
public:
|
||||||
// Constructs an object setting all fields.
|
// Constructs an object setting all fields.
|
||||||
explicit UniversalScanFilter(
|
explicit UniversalScanFilter(
|
||||||
const flutter::EncodableList& with_services,
|
const ::flutter::EncodableList& with_services,
|
||||||
const flutter::EncodableList& with_name_prefix,
|
const ::flutter::EncodableList& with_name_prefix,
|
||||||
const flutter::EncodableList& with_manufacturer_data);
|
const ::flutter::EncodableList& with_manufacturer_data);
|
||||||
|
|
||||||
const flutter::EncodableList& with_services() const;
|
const ::flutter::EncodableList& with_services() const;
|
||||||
void set_with_services(const flutter::EncodableList& value_arg);
|
void set_with_services(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
const flutter::EncodableList& with_name_prefix() const;
|
const ::flutter::EncodableList& with_name_prefix() const;
|
||||||
void set_with_name_prefix(const flutter::EncodableList& value_arg);
|
void set_with_name_prefix(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
const flutter::EncodableList& with_manufacturer_data() const;
|
const ::flutter::EncodableList& with_manufacturer_data() const;
|
||||||
void set_with_manufacturer_data(const flutter::EncodableList& value_arg);
|
void set_with_manufacturer_data(const ::flutter::EncodableList& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalScanFilter& other) const;
|
||||||
|
bool operator!=(const UniversalScanFilter& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static UniversalScanFilter FromEncodableList(const flutter::EncodableList& list);
|
static UniversalScanFilter FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
friend class PigeonInternalCodecSerializer;
|
friend class PigeonInternalCodecSerializer;
|
||||||
flutter::EncodableList with_services_;
|
::flutter::EncodableList with_services_;
|
||||||
flutter::EncodableList with_name_prefix_;
|
::flutter::EncodableList with_name_prefix_;
|
||||||
flutter::EncodableList with_manufacturer_data_;
|
::flutter::EncodableList with_manufacturer_data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -410,9 +627,13 @@ class UniversalManufacturerDataFilter {
|
|||||||
void set_mask(const std::vector<uint8_t>* value_arg);
|
void set_mask(const std::vector<uint8_t>* value_arg);
|
||||||
void set_mask(const std::vector<uint8_t>& value_arg);
|
void set_mask(const std::vector<uint8_t>& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalManufacturerDataFilter& other) const;
|
||||||
|
bool operator!=(const UniversalManufacturerDataFilter& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static UniversalManufacturerDataFilter FromEncodableList(const flutter::EncodableList& list);
|
static UniversalManufacturerDataFilter FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
friend class PigeonInternalCodecSerializer;
|
friend class PigeonInternalCodecSerializer;
|
||||||
@@ -436,9 +657,13 @@ class UniversalManufacturerData {
|
|||||||
const std::vector<uint8_t>& data() const;
|
const std::vector<uint8_t>& data() const;
|
||||||
void set_data(const std::vector<uint8_t>& value_arg);
|
void set_data(const std::vector<uint8_t>& value_arg);
|
||||||
|
|
||||||
|
bool operator==(const UniversalManufacturerData& other) const;
|
||||||
|
bool operator!=(const UniversalManufacturerData& other) const;
|
||||||
|
/// Returns a hash code value for the object. This method is supported for the benefit of hash tables.
|
||||||
|
size_t Hash() const;
|
||||||
private:
|
private:
|
||||||
static UniversalManufacturerData FromEncodableList(const flutter::EncodableList& list);
|
static UniversalManufacturerData FromEncodableList(const ::flutter::EncodableList& list);
|
||||||
flutter::EncodableList ToEncodableList() const;
|
::flutter::EncodableList ToEncodableList() const;
|
||||||
friend class UniversalBlePlatformChannel;
|
friend class UniversalBlePlatformChannel;
|
||||||
friend class UniversalBleCallbackChannel;
|
friend class UniversalBleCallbackChannel;
|
||||||
friend class PigeonInternalCodecSerializer;
|
friend class PigeonInternalCodecSerializer;
|
||||||
@@ -447,7 +672,7 @@ class UniversalManufacturerData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PigeonInternalCodecSerializer : public flutter::StandardCodecSerializer {
|
class PigeonInternalCodecSerializer : public ::flutter::StandardCodecSerializer {
|
||||||
public:
|
public:
|
||||||
PigeonInternalCodecSerializer();
|
PigeonInternalCodecSerializer();
|
||||||
inline static PigeonInternalCodecSerializer& GetInstance() {
|
inline static PigeonInternalCodecSerializer& GetInstance() {
|
||||||
@@ -456,12 +681,12 @@ class PigeonInternalCodecSerializer : public flutter::StandardCodecSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WriteValue(
|
void WriteValue(
|
||||||
const flutter::EncodableValue& value,
|
const ::flutter::EncodableValue& value,
|
||||||
flutter::ByteStreamWriter* stream) const override;
|
::flutter::ByteStreamWriter* stream) const override;
|
||||||
protected:
|
protected:
|
||||||
flutter::EncodableValue ReadValueOfType(
|
::flutter::EncodableValue ReadValueOfType(
|
||||||
uint8_t type,
|
uint8_t type,
|
||||||
flutter::ByteStreamReader* stream) const override;
|
::flutter::ByteStreamReader* stream) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flutter -> Native
|
// Flutter -> Native
|
||||||
@@ -473,9 +698,12 @@ class UniversalBlePlatformChannel {
|
|||||||
UniversalBlePlatformChannel& operator=(const UniversalBlePlatformChannel&) = delete;
|
UniversalBlePlatformChannel& operator=(const UniversalBlePlatformChannel&) = delete;
|
||||||
virtual ~UniversalBlePlatformChannel() {}
|
virtual ~UniversalBlePlatformChannel() {}
|
||||||
virtual void GetBluetoothAvailabilityState(std::function<void(ErrorOr<int64_t> reply)> result) = 0;
|
virtual void GetBluetoothAvailabilityState(std::function<void(ErrorOr<int64_t> reply)> result) = 0;
|
||||||
virtual ErrorOr<bool> HasPermissions(bool with_android_fine_location) = 0;
|
virtual ErrorOr<bool> HasPermissions(
|
||||||
|
bool with_android_fine_location,
|
||||||
|
bool with_android_bluetooth_advertise) = 0;
|
||||||
virtual void RequestPermissions(
|
virtual void RequestPermissions(
|
||||||
bool with_android_fine_location,
|
bool with_android_fine_location,
|
||||||
|
bool with_android_bluetooth_advertise,
|
||||||
std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
||||||
virtual void EnableBluetooth(std::function<void(ErrorOr<bool> reply)> result) = 0;
|
virtual void EnableBluetooth(std::function<void(ErrorOr<bool> reply)> result) = 0;
|
||||||
virtual void DisableBluetooth(std::function<void(ErrorOr<bool> reply)> result) = 0;
|
virtual void DisableBluetooth(std::function<void(ErrorOr<bool> reply)> result) = 0;
|
||||||
@@ -497,7 +725,7 @@ class UniversalBlePlatformChannel {
|
|||||||
virtual void DiscoverServices(
|
virtual void DiscoverServices(
|
||||||
const std::string& device_id,
|
const std::string& device_id,
|
||||||
bool with_descriptors,
|
bool with_descriptors,
|
||||||
std::function<void(ErrorOr<flutter::EncodableList> reply)> result) = 0;
|
std::function<void(ErrorOr<::flutter::EncodableList> reply)> result) = 0;
|
||||||
virtual void ReadValue(
|
virtual void ReadValue(
|
||||||
const std::string& device_id,
|
const std::string& device_id,
|
||||||
const std::string& service,
|
const std::string& service,
|
||||||
@@ -522,8 +750,8 @@ class UniversalBlePlatformChannel {
|
|||||||
std::function<void(ErrorOr<bool> reply)> result) = 0;
|
std::function<void(ErrorOr<bool> reply)> result) = 0;
|
||||||
virtual std::optional<FlutterError> UnPair(const std::string& device_id) = 0;
|
virtual std::optional<FlutterError> UnPair(const std::string& device_id) = 0;
|
||||||
virtual void GetSystemDevices(
|
virtual void GetSystemDevices(
|
||||||
const flutter::EncodableList& with_services,
|
const ::flutter::EncodableList& with_services,
|
||||||
std::function<void(ErrorOr<flutter::EncodableList> reply)> result) = 0;
|
std::function<void(ErrorOr<::flutter::EncodableList> reply)> result) = 0;
|
||||||
virtual ErrorOr<int64_t> GetConnectionState(const std::string& device_id) = 0;
|
virtual ErrorOr<int64_t> GetConnectionState(const std::string& device_id) = 0;
|
||||||
virtual void ReadRssi(
|
virtual void ReadRssi(
|
||||||
const std::string& device_id,
|
const std::string& device_id,
|
||||||
@@ -532,20 +760,36 @@ class UniversalBlePlatformChannel {
|
|||||||
const std::string& device_id,
|
const std::string& device_id,
|
||||||
int64_t priority,
|
int64_t priority,
|
||||||
std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
||||||
|
virtual ErrorOr<bool> IsPeripheralSupported() = 0;
|
||||||
|
virtual void StartPeripheral(
|
||||||
|
const UniversalBlePeripheralConfig& config,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
||||||
|
virtual void StopPeripheral(std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
||||||
|
virtual void UpdatePeripheralCharacteristicValue(
|
||||||
|
const std::string& service,
|
||||||
|
const std::string& characteristic,
|
||||||
|
const std::vector<uint8_t>& value,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
||||||
|
virtual void NotifyPeripheralCharacteristic(
|
||||||
|
const std::string& service,
|
||||||
|
const std::string& characteristic,
|
||||||
|
const std::vector<uint8_t>& value,
|
||||||
|
bool indicate,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
||||||
virtual std::optional<FlutterError> SetLogLevel(const UniversalBleLogLevel& log_level) = 0;
|
virtual std::optional<FlutterError> SetLogLevel(const UniversalBleLogLevel& log_level) = 0;
|
||||||
|
|
||||||
// The codec used by UniversalBlePlatformChannel.
|
// The codec used by UniversalBlePlatformChannel.
|
||||||
static const flutter::StandardMessageCodec& GetCodec();
|
static const ::flutter::StandardMessageCodec& GetCodec();
|
||||||
// Sets up an instance of `UniversalBlePlatformChannel` to handle messages through the `binary_messenger`.
|
// Sets up an instance of `UniversalBlePlatformChannel` to handle messages through the `binary_messenger`.
|
||||||
static void SetUp(
|
static void SetUp(
|
||||||
flutter::BinaryMessenger* binary_messenger,
|
::flutter::BinaryMessenger* binary_messenger,
|
||||||
UniversalBlePlatformChannel* api);
|
UniversalBlePlatformChannel* api);
|
||||||
static void SetUp(
|
static void SetUp(
|
||||||
flutter::BinaryMessenger* binary_messenger,
|
::flutter::BinaryMessenger* binary_messenger,
|
||||||
UniversalBlePlatformChannel* api,
|
UniversalBlePlatformChannel* api,
|
||||||
const std::string& message_channel_suffix);
|
const std::string& message_channel_suffix);
|
||||||
static flutter::EncodableValue WrapError(std::string_view error_message);
|
static ::flutter::EncodableValue WrapError(std::string_view error_message);
|
||||||
static flutter::EncodableValue WrapError(const FlutterError& error);
|
static ::flutter::EncodableValue WrapError(const FlutterError& error);
|
||||||
protected:
|
protected:
|
||||||
UniversalBlePlatformChannel() = default;
|
UniversalBlePlatformChannel() = default;
|
||||||
};
|
};
|
||||||
@@ -554,11 +798,11 @@ class UniversalBlePlatformChannel {
|
|||||||
// Generated class from Pigeon that represents Flutter messages that can be called from C++.
|
// Generated class from Pigeon that represents Flutter messages that can be called from C++.
|
||||||
class UniversalBleCallbackChannel {
|
class UniversalBleCallbackChannel {
|
||||||
public:
|
public:
|
||||||
UniversalBleCallbackChannel(flutter::BinaryMessenger* binary_messenger);
|
UniversalBleCallbackChannel(::flutter::BinaryMessenger* binary_messenger);
|
||||||
UniversalBleCallbackChannel(
|
UniversalBleCallbackChannel(
|
||||||
flutter::BinaryMessenger* binary_messenger,
|
::flutter::BinaryMessenger* binary_messenger,
|
||||||
const std::string& message_channel_suffix);
|
const std::string& message_channel_suffix);
|
||||||
static const flutter::StandardMessageCodec& GetCodec();
|
static const ::flutter::StandardMessageCodec& GetCodec();
|
||||||
void OnAvailabilityChanged(
|
void OnAvailabilityChanged(
|
||||||
int64_t state,
|
int64_t state,
|
||||||
std::function<void(void)>&& on_success,
|
std::function<void(void)>&& on_success,
|
||||||
@@ -586,8 +830,24 @@ class UniversalBleCallbackChannel {
|
|||||||
const std::string* error,
|
const std::string* error,
|
||||||
std::function<void(void)>&& on_success,
|
std::function<void(void)>&& on_success,
|
||||||
std::function<void(const FlutterError&)>&& on_error);
|
std::function<void(const FlutterError&)>&& on_error);
|
||||||
|
void OnPeripheralConnectionChanged(
|
||||||
|
const std::string& device_id,
|
||||||
|
bool connected,
|
||||||
|
std::function<void(void)>&& on_success,
|
||||||
|
std::function<void(const FlutterError&)>&& on_error);
|
||||||
|
void OnPeripheralWrite(
|
||||||
|
const UniversalBlePeripheralWriteEvent& event,
|
||||||
|
std::function<void(void)>&& on_success,
|
||||||
|
std::function<void(const FlutterError&)>&& on_error);
|
||||||
|
void OnPeripheralSubscriptionChanged(
|
||||||
|
const std::string& device_id,
|
||||||
|
const std::string& service,
|
||||||
|
const std::string& characteristic,
|
||||||
|
bool subscribed,
|
||||||
|
std::function<void(void)>&& on_success,
|
||||||
|
std::function<void(const FlutterError&)>&& on_error);
|
||||||
private:
|
private:
|
||||||
flutter::BinaryMessenger* binary_messenger_;
|
::flutter::BinaryMessenger* binary_messenger_;
|
||||||
std::string message_channel_suffix_;
|
std::string message_channel_suffix_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -120,13 +120,14 @@ void UniversalBlePlugin::DisableBluetooth(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<bool>
|
ErrorOr<bool>
|
||||||
UniversalBlePlugin::HasPermissions(bool with_android_fine_location) {
|
UniversalBlePlugin::HasPermissions(bool with_android_fine_location,
|
||||||
|
bool with_android_bluetooth_advertise) {
|
||||||
// Windows does not require runtime permissions for Bluetooth
|
// Windows does not require runtime permissions for Bluetooth
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniversalBlePlugin::RequestPermissions(
|
void UniversalBlePlugin::RequestPermissions(
|
||||||
bool with_android_fine_location,
|
bool with_android_fine_location, bool with_android_bluetooth_advertise,
|
||||||
std::function<void(std::optional<FlutterError> reply)> result) {
|
std::function<void(std::optional<FlutterError> reply)> result) {
|
||||||
// Windows does not require runtime permissions for Bluetooth
|
// Windows does not require runtime permissions for Bluetooth
|
||||||
result(std::nullopt);
|
result(std::nullopt);
|
||||||
@@ -444,6 +445,39 @@ void UniversalBlePlugin::RequestConnectionPriority(
|
|||||||
"requestConnectionPriority is not supported on Windows platform"));
|
"requestConnectionPriority is not supported on Windows platform"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<bool> UniversalBlePlugin::IsPeripheralSupported() { return false; }
|
||||||
|
|
||||||
|
void UniversalBlePlugin::StartPeripheral(
|
||||||
|
const UniversalBlePeripheralConfig &config,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) {
|
||||||
|
result(create_flutter_error(
|
||||||
|
UniversalBleErrorCode::kNotSupported,
|
||||||
|
"BLE peripheral mode is not implemented on Windows platform yet"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UniversalBlePlugin::StopPeripheral(
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) {
|
||||||
|
result(std::nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UniversalBlePlugin::UpdatePeripheralCharacteristicValue(
|
||||||
|
const std::string &service, const std::string &characteristic,
|
||||||
|
const std::vector<uint8_t> &value,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) {
|
||||||
|
result(create_flutter_error(
|
||||||
|
UniversalBleErrorCode::kNotSupported,
|
||||||
|
"BLE peripheral mode is not implemented on Windows platform yet"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UniversalBlePlugin::NotifyPeripheralCharacteristic(
|
||||||
|
const std::string &service, const std::string &characteristic,
|
||||||
|
const std::vector<uint8_t> &value, bool indicate,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) {
|
||||||
|
result(create_flutter_error(
|
||||||
|
UniversalBleErrorCode::kNotSupported,
|
||||||
|
"BLE peripheral mode is not implemented on Windows platform yet"));
|
||||||
|
}
|
||||||
|
|
||||||
void UniversalBlePlugin::ReadRssi(
|
void UniversalBlePlugin::ReadRssi(
|
||||||
const std::string &device_id,
|
const std::string &device_id,
|
||||||
std::function<void(ErrorOr<int64_t> reply)> result) {
|
std::function<void(ErrorOr<int64_t> reply)> result) {
|
||||||
|
|||||||
@@ -184,9 +184,10 @@ private:
|
|||||||
ErrorOr<bool> IsScanning() override;
|
ErrorOr<bool> IsScanning() override;
|
||||||
std::optional<FlutterError> Connect(const std::string &device_id, const bool *auto_connect) override;
|
std::optional<FlutterError> Connect(const std::string &device_id, const bool *auto_connect) override;
|
||||||
std::optional<FlutterError> Disconnect(const std::string &device_id) override;
|
std::optional<FlutterError> Disconnect(const std::string &device_id) override;
|
||||||
ErrorOr<bool> HasPermissions(bool with_android_fine_location) override;
|
ErrorOr<bool> HasPermissions(bool with_android_fine_location,
|
||||||
|
bool with_android_bluetooth_advertise) override;
|
||||||
void RequestPermissions(
|
void RequestPermissions(
|
||||||
bool with_android_fine_location,
|
bool with_android_fine_location, bool with_android_bluetooth_advertise,
|
||||||
std::function<void(std::optional<FlutterError> reply)> result) override;
|
std::function<void(std::optional<FlutterError> reply)> result) override;
|
||||||
void
|
void
|
||||||
DiscoverServices(const std::string &device_id, bool with_descriptors,
|
DiscoverServices(const std::string &device_id, bool with_descriptors,
|
||||||
@@ -210,6 +211,20 @@ private:
|
|||||||
void RequestConnectionPriority(
|
void RequestConnectionPriority(
|
||||||
const std::string &device_id, int64_t priority,
|
const std::string &device_id, int64_t priority,
|
||||||
std::function<void(std::optional<FlutterError> reply)> result) override;
|
std::function<void(std::optional<FlutterError> reply)> result) override;
|
||||||
|
ErrorOr<bool> IsPeripheralSupported() override;
|
||||||
|
void StartPeripheral(
|
||||||
|
const UniversalBlePeripheralConfig &config,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) override;
|
||||||
|
void StopPeripheral(
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) override;
|
||||||
|
void UpdatePeripheralCharacteristicValue(
|
||||||
|
const std::string &service, const std::string &characteristic,
|
||||||
|
const std::vector<uint8_t> &value,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) override;
|
||||||
|
void NotifyPeripheralCharacteristic(
|
||||||
|
const std::string &service, const std::string &characteristic,
|
||||||
|
const std::vector<uint8_t> &value, bool indicate,
|
||||||
|
std::function<void(std::optional<FlutterError> reply)> result) override;
|
||||||
void ReadRssi(const std::string &device_id,
|
void ReadRssi(const std::string &device_id,
|
||||||
std::function<void(ErrorOr<int64_t> reply)> result) override;
|
std::function<void(ErrorOr<int64_t> reply)> result) override;
|
||||||
void IsPaired(const std::string &device_id,
|
void IsPaired(const std::string &device_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user