From fa319416efa24861700069aa6adc3e48d781c3bb Mon Sep 17 00:00:00 2001 From: Rohit Sangwan Date: Thu, 11 Dec 2025 19:24:13 +0530 Subject: [PATCH] Implement timestamp in scanResult (#198) * Implement timestamp in scanResult * Update pigeon * implement windows * Update changelog * Fix Swift formatting * Remove android unused import * Format pigeon generated file --- CHANGELOG.md | 1 + .../navideck/universal_ble/UniversalBle.g.kt | 9 +- .../universal_ble/UniversalBlePlugin.kt | 4 +- darwin/Classes/UniversalBle.g.swift | 8 +- darwin/Classes/UniversalBlePlugin.swift | 6 +- .../lib/home/widgets/scanned_item_widget.dart | 2 + lib/src/models/ble_device.dart | 7 + .../universal_ble_linux.dart | 1 + .../universal_ble_pigeon/universal_ble.g.dart | 183 +++++++----------- .../universal_ble_pigeon_channel.dart | 1 + .../universal_ble_web/universal_ble_web.dart | 1 + pigeon/universal_ble.dart | 2 + pubspec.yaml | 2 +- windows/src/generated/universal_ble.g.cpp | 28 ++- windows/src/generated/universal_ble.g.h | 10 +- windows/src/universal_ble_plugin.cpp | 4 + 16 files changed, 141 insertions(+), 128 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6790c81..4c36dd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * `disconnect` now waits for disconnection confirmation before returning * Improve Windows disconnection event handling and cleanup * Add `withDescriptors` parameter in `discoverServices` API +* Add `timestamp` in `BleDevice` ## 0.21.1 * Fix device name resolution on Windows diff --git a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt index b05f816..16984aa 100644 --- a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt +++ b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v26.1.0), do not edit directly. +// Autogenerated from Pigeon (v26.1.4), do not edit directly. // See also: https://pub.dev/packages/pigeon @file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") @@ -159,7 +159,8 @@ data class UniversalBleScanResult ( val isPaired: Boolean? = null, val rssi: Long? = null, val manufacturerDataList: List? = null, - val services: List? = null + val services: List? = null, + val timestamp: Long? = null ) { companion object { @@ -170,7 +171,8 @@ data class UniversalBleScanResult ( val rssi = pigeonVar_list[3] as Long? val manufacturerDataList = pigeonVar_list[4] as List? val services = pigeonVar_list[5] as List? - return UniversalBleScanResult(deviceId, name, isPaired, rssi, manufacturerDataList, services) + val timestamp = pigeonVar_list[6] as Long? + return UniversalBleScanResult(deviceId, name, isPaired, rssi, manufacturerDataList, services, timestamp) } } fun toList(): List { @@ -181,6 +183,7 @@ data class UniversalBleScanResult ( rssi, manufacturerDataList, services, + timestamp, ) } override fun equals(other: Any?): Boolean { diff --git a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBlePlugin.kt b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBlePlugin.kt index feef1e1..6c28f4f 100644 --- a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBlePlugin.kt +++ b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBlePlugin.kt @@ -761,6 +761,7 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), isPaired = it.bondState == BOND_BONDED, manufacturerDataList = null, rssi = null, + timestamp = System.currentTimeMillis() ) } ) @@ -1020,7 +1021,8 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), isPaired = result.device.bondState == BOND_BONDED, manufacturerDataList = manufacturerDataList, rssi = result.rssi.toLong(), - services = serviceUuids.map { it.toString() }.toList() + services = serviceUuids.map { it.toString() }.toList(), + timestamp = System.currentTimeMillis() ) ) {} } diff --git a/darwin/Classes/UniversalBle.g.swift b/darwin/Classes/UniversalBle.g.swift index 026e2f1..c29c725 100644 --- a/darwin/Classes/UniversalBle.g.swift +++ b/darwin/Classes/UniversalBle.g.swift @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v26.1.0), do not edit directly. +// Autogenerated from Pigeon (v26.1.4), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation @@ -205,6 +205,7 @@ struct UniversalBleScanResult: Hashable { var rssi: Int64? = nil var manufacturerDataList: [UniversalManufacturerData]? = nil var services: [String]? = nil + var timestamp: Int64? = nil // swift-format-ignore: AlwaysUseLowerCamelCase @@ -215,6 +216,7 @@ struct UniversalBleScanResult: Hashable { let rssi: Int64? = nilOrValue(pigeonVar_list[3]) let manufacturerDataList: [UniversalManufacturerData]? = nilOrValue(pigeonVar_list[4]) let services: [String]? = nilOrValue(pigeonVar_list[5]) + let timestamp: Int64? = nilOrValue(pigeonVar_list[6]) return UniversalBleScanResult( deviceId: deviceId, @@ -222,7 +224,8 @@ struct UniversalBleScanResult: Hashable { isPaired: isPaired, rssi: rssi, manufacturerDataList: manufacturerDataList, - services: services + services: services, + timestamp: timestamp ) } func toList() -> [Any?] { @@ -233,6 +236,7 @@ struct UniversalBleScanResult: Hashable { rssi, manufacturerDataList, services, + timestamp, ] } static func == (lhs: UniversalBleScanResult, rhs: UniversalBleScanResult) -> Bool { diff --git a/darwin/Classes/UniversalBlePlugin.swift b/darwin/Classes/UniversalBlePlugin.swift index 402c30e..b99f89a 100644 --- a/darwin/Classes/UniversalBlePlugin.swift +++ b/darwin/Classes/UniversalBlePlugin.swift @@ -362,7 +362,8 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral let name = advertisementNameCache[id] ?? discoveredPeripherals[id]?.name ?? peripheral.name ?? "" return UniversalBleScanResult( deviceId: id, - name: name + name: name, + timestamp: Int64(Date().timeIntervalSince1970 * 1000) ) })) } @@ -415,7 +416,8 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral isPaired: nil, rssi: RSSI as? Int64, manufacturerDataList: manufacturerDataList, - services: services?.map { $0.uuidStr } + services: services?.map { $0.uuidStr }, + timestamp: Int64(Date().timeIntervalSince1970 * 1000) )) { _ in } } diff --git a/example/lib/home/widgets/scanned_item_widget.dart b/example/lib/home/widgets/scanned_item_widget.dart index 7608f30..37f5a82 100644 --- a/example/lib/home/widgets/scanned_item_widget.dart +++ b/example/lib/home/widgets/scanned_item_widget.dart @@ -30,6 +30,8 @@ class ScannedItemWidget extends StatelessWidget { visible: manufacturerData != null, child: Text(manufacturerData.toString()), ), + if (bleDevice.timestampDateTime != null) + Text("Last Seen: ${bleDevice.timestampDateTime}"), bleDevice.paired == true ? const Text( "Paired", diff --git a/lib/src/models/ble_device.dart b/lib/src/models/ble_device.dart index 2d34cff..c6640bf 100644 --- a/lib/src/models/ble_device.dart +++ b/lib/src/models/ble_device.dart @@ -8,6 +8,7 @@ class BleDevice { String? rawName; int? rssi; bool? paired; + int? timestamp; /// List of services advertised by the device. List services; @@ -38,11 +39,16 @@ class BleDevice { this.services = const [], this.isSystemDevice, this.manufacturerDataList = const [], + this.timestamp, }) { rawName = name; this.name = name?.replaceAll(RegExp(r'[^ -~]'), '').trim(); } + DateTime? get timestampDateTime => timestamp != null + ? DateTime.fromMillisecondsSinceEpoch(timestamp!) + : null; + @override String toString() { return 'BleDevice: ' @@ -52,6 +58,7 @@ class BleDevice { 'paired: $paired, ' 'services: $services, ' 'isSystemDevice: $isSystemDevice, ' + 'timestamp: $timestamp, ' 'manufacturerDataList: $manufacturerDataList'; } } diff --git a/lib/src/universal_ble_linux/universal_ble_linux.dart b/lib/src/universal_ble_linux/universal_ble_linux.dart index 474ba6f..a116126 100644 --- a/lib/src/universal_ble_linux/universal_ble_linux.dart +++ b/lib/src/universal_ble_linux/universal_ble_linux.dart @@ -677,6 +677,7 @@ extension BlueZDeviceExtension on BlueZDevice { isSystemDevice: isSystemDevice, services: uuids.map((e) => e.toString()).toList(), manufacturerDataList: manufacturerDataList, + timestamp: DateTime.now().millisecondsSinceEpoch, ); } } diff --git a/lib/src/universal_ble_pigeon/universal_ble.g.dart b/lib/src/universal_ble_pigeon/universal_ble.g.dart index e3e9bd3..caeb0d8 100644 --- a/lib/src/universal_ble_pigeon/universal_ble.g.dart +++ b/lib/src/universal_ble_pigeon/universal_ble.g.dart @@ -1,6 +1,6 @@ -// Autogenerated from Pigeon (v26.1.0), do not edit directly. +// Autogenerated from Pigeon (v26.1.4), do not edit directly. // See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, omit_obvious_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; @@ -114,6 +114,7 @@ class UniversalBleScanResult { this.rssi, this.manufacturerDataList, this.services, + this.timestamp, }); String deviceId; @@ -128,6 +129,8 @@ class UniversalBleScanResult { List? services; + int? timestamp; + List _toList() { return [ deviceId, @@ -136,6 +139,7 @@ class UniversalBleScanResult { rssi, manufacturerDataList, services, + timestamp, ]; } @@ -153,6 +157,7 @@ class UniversalBleScanResult { manufacturerDataList: (result[4] as List?)?.cast(), services: (result[5] as List?)?.cast(), + timestamp: result[6] as int?, ); } @@ -506,7 +511,7 @@ class _PigeonCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 129: - final int? value = readValue(buffer) as int?; + final value = readValue(buffer) as int?; return value == null ? null : UniversalBleErrorCode.values[value]; case 130: return UniversalBleScanResult.decode(readValue(buffer)!); @@ -545,17 +550,15 @@ class UniversalBlePlatformChannel { final String pigeonVar_messageChannelSuffix; Future getBluetoothAvailabilityState() async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -575,18 +578,16 @@ class UniversalBlePlatformChannel { } Future requestPermissions(bool withAndroidFineLocation) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestPermissions$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([withAndroidFineLocation]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -601,17 +602,15 @@ class UniversalBlePlatformChannel { } Future enableBluetooth() async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -631,17 +630,15 @@ class UniversalBlePlatformChannel { } Future disableBluetooth() async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disableBluetooth$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -661,18 +658,16 @@ class UniversalBlePlatformChannel { } Future startScan(UniversalScanFilter? filter) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([filter]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -687,17 +682,15 @@ class UniversalBlePlatformChannel { } Future stopScan() async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -712,17 +705,15 @@ class UniversalBlePlatformChannel { } Future isScanning() async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isScanning$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -742,18 +733,16 @@ class UniversalBlePlatformChannel { } Future connect(String deviceId) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -768,18 +757,16 @@ class UniversalBlePlatformChannel { } Future disconnect(String deviceId) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -795,18 +782,16 @@ class UniversalBlePlatformChannel { Future setNotifiable(String deviceId, String service, String characteristic, int bleInputProperty) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel .send([deviceId, service, characteristic, bleInputProperty]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -822,18 +807,16 @@ class UniversalBlePlatformChannel { Future> discoverServices( String deviceId, bool withDescriptors) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId, withDescriptors]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -855,18 +838,16 @@ class UniversalBlePlatformChannel { Future readValue( String deviceId, String service, String characteristic) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId, service, characteristic]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -886,18 +867,16 @@ class UniversalBlePlatformChannel { } Future requestMtu(String deviceId, int expectedMtu) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId, expectedMtu]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -918,18 +897,16 @@ class UniversalBlePlatformChannel { Future writeValue(String deviceId, String service, String characteristic, Uint8List value, int bleOutputProperty) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send( [deviceId, service, characteristic, value, bleOutputProperty]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -944,18 +921,16 @@ class UniversalBlePlatformChannel { } Future isPaired(String deviceId) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -975,18 +950,16 @@ class UniversalBlePlatformChannel { } Future pair(String deviceId) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1006,18 +979,16 @@ class UniversalBlePlatformChannel { } Future unPair(String deviceId) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1033,18 +1004,16 @@ class UniversalBlePlatformChannel { Future> getSystemDevices( List withServices) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getSystemDevices$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([withServices]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1065,18 +1034,16 @@ class UniversalBlePlatformChannel { } Future getConnectionState(String deviceId) async { - final String pigeonVar_channelName = + final pigeonVar_channelName = 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectionState$pigeonVar_messageChannelSuffix'; - final BasicMessageChannel pigeonVar_channel = - BasicMessageChannel( + final pigeonVar_channel = BasicMessageChannel( pigeonVar_channelName, pigeonChannelCodec, binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send([deviceId]); - final List? pigeonVar_replyList = - await pigeonVar_sendFuture as List?; + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; if (pigeonVar_replyList == null) { throw _createConnectionError(pigeonVar_channelName); } else if (pigeonVar_replyList.length > 1) { @@ -1119,9 +1086,7 @@ abstract class UniversalBleCallbackChannel { messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { - final BasicMessageChannel< - Object?> pigeonVar_channel = BasicMessageChannel< - Object?>( + final pigeonVar_channel = BasicMessageChannel( 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); @@ -1148,9 +1113,7 @@ abstract class UniversalBleCallbackChannel { } } { - final BasicMessageChannel< - Object?> pigeonVar_channel = BasicMessageChannel< - Object?>( + final pigeonVar_channel = BasicMessageChannel( 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); @@ -1181,9 +1144,7 @@ abstract class UniversalBleCallbackChannel { } } { - final BasicMessageChannel< - Object?> pigeonVar_channel = BasicMessageChannel< - Object?>( + final pigeonVar_channel = BasicMessageChannel( 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); @@ -1211,9 +1172,7 @@ abstract class UniversalBleCallbackChannel { } } { - final BasicMessageChannel< - Object?> pigeonVar_channel = BasicMessageChannel< - Object?>( + final pigeonVar_channel = BasicMessageChannel( 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); @@ -1247,9 +1206,7 @@ abstract class UniversalBleCallbackChannel { } } { - final BasicMessageChannel< - Object?> pigeonVar_channel = BasicMessageChannel< - Object?>( + final pigeonVar_channel = BasicMessageChannel( 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); diff --git a/lib/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart b/lib/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart index 5474d38..997d75e 100644 --- a/lib/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart +++ b/lib/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart @@ -270,6 +270,7 @@ extension _UniversalBleScanResultExtension on UniversalBleScanResult { paired: isPaired, isSystemDevice: isSystemDevice, services: services?.map(BleUuidParser.string).toList() ?? [], + timestamp: timestamp, manufacturerDataList: manufacturerDataList ?.map((e) => ManufacturerData(e.companyIdentifier, e.data)) .toList() ?? diff --git a/lib/src/universal_ble_web/universal_ble_web.dart b/lib/src/universal_ble_web/universal_ble_web.dart index 3a4924a..2a6bff5 100644 --- a/lib/src/universal_ble_web/universal_ble_web.dart +++ b/lib/src/universal_ble_web/universal_ble_web.dart @@ -499,6 +499,7 @@ extension _BluetoothDeviceExtension on BluetoothDevice { manufacturerDataList: manufacturerDataMap?.toManufacturerDataList() ?? [], rssi: rssi, services: services, + timestamp: DateTime.now().millisecondsSinceEpoch, ); } } diff --git a/pigeon/universal_ble.dart b/pigeon/universal_ble.dart index 76ac475..2dd3e57 100644 --- a/pigeon/universal_ble.dart +++ b/pigeon/universal_ble.dart @@ -121,6 +121,7 @@ class UniversalBleScanResult { final int? rssi; final List? manufacturerDataList; final List? services; + final int? timestamp; UniversalBleScanResult({ required this.name, @@ -129,6 +130,7 @@ class UniversalBleScanResult { required this.rssi, required this.manufacturerDataList, required this.services, + required this.timestamp, }); } diff --git a/pubspec.yaml b/pubspec.yaml index 730219a..e4a2ad7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,7 +38,7 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^6.0.0 - pigeon: ^26.1.0 + pigeon: ^26.1.4 flutter: plugin: diff --git a/windows/src/generated/universal_ble.g.cpp b/windows/src/generated/universal_ble.g.cpp index cd31525..6f63c0d 100644 --- a/windows/src/generated/universal_ble.g.cpp +++ b/windows/src/generated/universal_ble.g.cpp @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v26.1.0), do not edit directly. +// Autogenerated from Pigeon (v26.1.4), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS @@ -39,13 +39,15 @@ UniversalBleScanResult::UniversalBleScanResult( const bool* is_paired, const int64_t* rssi, const EncodableList* manufacturer_data_list, - const EncodableList* services) + const EncodableList* services, + const int64_t* timestamp) : device_id_(device_id), name_(name ? std::optional(*name) : std::nullopt), is_paired_(is_paired ? std::optional(*is_paired) : std::nullopt), rssi_(rssi ? std::optional(*rssi) : std::nullopt), manufacturer_data_list_(manufacturer_data_list ? std::optional(*manufacturer_data_list) : std::nullopt), - services_(services ? std::optional(*services) : std::nullopt) {} + services_(services ? std::optional(*services) : std::nullopt), + timestamp_(timestamp ? std::optional(*timestamp) : std::nullopt) {} const std::string& UniversalBleScanResult::device_id() const { return device_id_; @@ -121,15 +123,29 @@ void UniversalBleScanResult::set_services(const EncodableList& value_arg) { } +const int64_t* UniversalBleScanResult::timestamp() const { + return timestamp_ ? &(*timestamp_) : nullptr; +} + +void UniversalBleScanResult::set_timestamp(const int64_t* value_arg) { + timestamp_ = value_arg ? std::optional(*value_arg) : std::nullopt; +} + +void UniversalBleScanResult::set_timestamp(int64_t value_arg) { + timestamp_ = value_arg; +} + + EncodableList UniversalBleScanResult::ToEncodableList() const { EncodableList list; - list.reserve(6); + list.reserve(7); list.push_back(EncodableValue(device_id_)); list.push_back(name_ ? EncodableValue(*name_) : EncodableValue()); list.push_back(is_paired_ ? EncodableValue(*is_paired_) : EncodableValue()); list.push_back(rssi_ ? EncodableValue(*rssi_) : EncodableValue()); list.push_back(manufacturer_data_list_ ? EncodableValue(*manufacturer_data_list_) : EncodableValue()); list.push_back(services_ ? EncodableValue(*services_) : EncodableValue()); + list.push_back(timestamp_ ? EncodableValue(*timestamp_) : EncodableValue()); return list; } @@ -156,6 +172,10 @@ UniversalBleScanResult UniversalBleScanResult::FromEncodableList(const Encodable if (!encodable_services.IsNull()) { decoded.set_services(std::get(encodable_services)); } + auto& encodable_timestamp = list[6]; + if (!encodable_timestamp.IsNull()) { + decoded.set_timestamp(std::get(encodable_timestamp)); + } return decoded; } diff --git a/windows/src/generated/universal_ble.g.h b/windows/src/generated/universal_ble.g.h index 6216023..81df4b6 100644 --- a/windows/src/generated/universal_ble.g.h +++ b/windows/src/generated/universal_ble.g.h @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v26.1.0), do not edit directly. +// Autogenerated from Pigeon (v26.1.4), do not edit directly. // See also: https://pub.dev/packages/pigeon #ifndef PIGEON_UNIVERSAL_BLE_G_H_ @@ -136,7 +136,8 @@ class UniversalBleScanResult { const bool* is_paired, const int64_t* rssi, const flutter::EncodableList* manufacturer_data_list, - const flutter::EncodableList* services); + const flutter::EncodableList* services, + const int64_t* timestamp); const std::string& device_id() const; void set_device_id(std::string_view value_arg); @@ -161,6 +162,10 @@ class UniversalBleScanResult { void set_services(const flutter::EncodableList* value_arg); void set_services(const flutter::EncodableList& value_arg); + const int64_t* timestamp() const; + void set_timestamp(const int64_t* value_arg); + void set_timestamp(int64_t value_arg); + private: static UniversalBleScanResult FromEncodableList(const flutter::EncodableList& list); flutter::EncodableList ToEncodableList() const; @@ -173,6 +178,7 @@ class UniversalBleScanResult { std::optional rssi_; std::optional manufacturer_data_list_; std::optional services_; + std::optional timestamp_; }; diff --git a/windows/src/universal_ble_plugin.cpp b/windows/src/universal_ble_plugin.cpp index b0f99bc..ccbe88a 100644 --- a/windows/src/universal_ble_plugin.cpp +++ b/windows/src/universal_ble_plugin.cpp @@ -678,6 +678,10 @@ void UniversalBlePlugin::PushUniversalScanResult( // Filter final result before sending to Flutter if (is_connectable && filterDevice(scan_result)) { + scan_result.set_timestamp( + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count()); ui_thread_handler_.Post([scan_result] { callback_channel->OnScanResult(scan_result, SuccessCallback, ErrorCallback);