diff --git a/android/src/main/java/cz/dronetag/flutter_opendroneid/Pigeon.java b/android/src/main/java/cz/dronetag/flutter_opendroneid/Pigeon.java index 3d0b020..a476299 100644 --- a/android/src/main/java/cz/dronetag/flutter_opendroneid/Pigeon.java +++ b/android/src/main/java/cz/dronetag/flutter_opendroneid/Pigeon.java @@ -182,6 +182,16 @@ public void setSource(@NonNull MessageSource setterArg) { this.source = setterArg; } + private @Nullable String btName; + + public @Nullable String getBtName() { + return btName; + } + + public void setBtName(@Nullable String setterArg) { + this.btName = setterArg; + } + /** Constructor is non-public to enforce null safety; use Builder. */ ODIDPayload() {} @@ -222,6 +232,13 @@ public static final class Builder { return this; } + private @Nullable String btName; + + public @NonNull Builder setBtName(@Nullable String setterArg) { + this.btName = setterArg; + return this; + } + public @NonNull ODIDPayload build() { ODIDPayload pigeonReturn = new ODIDPayload(); pigeonReturn.setRawData(rawData); @@ -229,18 +246,20 @@ public static final class Builder { pigeonReturn.setMacAddress(macAddress); pigeonReturn.setRssi(rssi); pigeonReturn.setSource(source); + pigeonReturn.setBtName(btName); return pigeonReturn; } } @NonNull ArrayList toList() { - ArrayList toListResult = new ArrayList(5); + ArrayList toListResult = new ArrayList(6); toListResult.add(rawData); toListResult.add(receivedTimestamp); toListResult.add(macAddress); toListResult.add(rssi); toListResult.add(source == null ? null : source.index); + toListResult.add(btName); return toListResult; } @@ -256,6 +275,8 @@ ArrayList toList() { pigeonResult.setRssi((rssi == null) ? null : ((rssi instanceof Integer) ? (Integer) rssi : (Long) rssi)); Object source = list.get(4); pigeonResult.setSource(source == null ? null : MessageSource.values()[(int) source]); + Object btName = list.get(5); + pigeonResult.setBtName((String) btName); return pigeonResult; } } @@ -658,7 +679,7 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { public interface PayloadApi { @NonNull - ODIDPayload buildPayload(@NonNull byte[] rawData, @NonNull MessageSource source, @NonNull String macAddress, @NonNull Long rssi, @NonNull Long receivedTimestamp); + ODIDPayload buildPayload(@NonNull byte[] rawData, @NonNull MessageSource source, @NonNull String macAddress, @Nullable String btName, @NonNull Long rssi, @NonNull Long receivedTimestamp); /** The codec used by PayloadApi. */ static @NonNull MessageCodec getCodec() { @@ -678,10 +699,11 @@ static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable PayloadApi byte[] rawDataArg = (byte[]) args.get(0); MessageSource sourceArg = args.get(1) == null ? null : MessageSource.values()[(int) args.get(1)]; String macAddressArg = (String) args.get(2); - Number rssiArg = (Number) args.get(3); - Number receivedTimestampArg = (Number) args.get(4); + String btNameArg = (String) args.get(3); + Number rssiArg = (Number) args.get(4); + Number receivedTimestampArg = (Number) args.get(5); try { - ODIDPayload output = api.buildPayload(rawDataArg, sourceArg, macAddressArg, (rssiArg == null) ? null : rssiArg.longValue(), (receivedTimestampArg == null) ? null : receivedTimestampArg.longValue()); + ODIDPayload output = api.buildPayload(rawDataArg, sourceArg, macAddressArg, btNameArg, (rssiArg == null) ? null : rssiArg.longValue(), (receivedTimestampArg == null) ? null : receivedTimestampArg.longValue()); wrapped.add(0, output); } catch (Throwable exception) { diff --git a/android/src/main/kotlin/cz/dronetag/flutter_opendroneid/scanner/BluetoothScanner.kt b/android/src/main/kotlin/cz/dronetag/flutter_opendroneid/scanner/BluetoothScanner.kt index 11f3665..1214297 100644 --- a/android/src/main/kotlin/cz/dronetag/flutter_opendroneid/scanner/BluetoothScanner.kt +++ b/android/src/main/kotlin/cz/dronetag/flutter_opendroneid/scanner/BluetoothScanner.kt @@ -60,6 +60,7 @@ class BluetoothScanner( result.device.address, source, result.rssi.toLong(), + result.device.name, ) } diff --git a/android/src/main/kotlin/cz/dronetag/flutter_opendroneid/scanner/ODIDScanner.kt b/android/src/main/kotlin/cz/dronetag/flutter_opendroneid/scanner/ODIDScanner.kt index b7d5dbe..6266fcf 100644 --- a/android/src/main/kotlin/cz/dronetag/flutter_opendroneid/scanner/ODIDScanner.kt +++ b/android/src/main/kotlin/cz/dronetag/flutter_opendroneid/scanner/ODIDScanner.kt @@ -34,7 +34,7 @@ abstract class ODIDScanner( abstract fun onAdapterStateReceived() - override fun buildPayload(rawData: ByteArray, source: Pigeon.MessageSource, macAddress: String, rssi: Long, receivedTimestamp: Long): Pigeon.ODIDPayload { + override fun buildPayload(rawData: ByteArray, source: Pigeon.MessageSource, macAddress: String, btName: String?, rssi: Long, receivedTimestamp: Long): Pigeon.ODIDPayload { val builder = Pigeon.ODIDPayload.Builder() builder.setRawData(rawData) @@ -42,19 +42,20 @@ abstract class ODIDScanner( builder.setMacAddress(macAddress) builder.setSource(source) builder.setRssi(rssi) + builder.setBtName(btName) return builder.build() } /// receive data and metadata, create [ODIDPayload] and sent to stream fun receiveData( - data: ByteArray, macAddress: String, source: Pigeon.MessageSource, rssi: Long = 0 + data: ByteArray, macAddress: String, source: Pigeon.MessageSource, rssi: Long = 0, btName: String? = null, ) { val payload = buildPayload( - data, source, macAddress, rssi, System.currentTimeMillis() + data, source, macAddress, btName, rssi, System.currentTimeMillis() ) - odidPayloadStreamHandler.send(payload?.toList() as Any) + odidPayloadStreamHandler.send(payload.toList() as Any) } /// returns ByteArray without first offset elements diff --git a/ios/Classes/Scanner/BluetoothScanner.swift b/ios/Classes/Scanner/BluetoothScanner.swift index c392f2e..20564b3 100644 --- a/ios/Classes/Scanner/BluetoothScanner.swift +++ b/ios/Classes/Scanner/BluetoothScanner.swift @@ -95,8 +95,8 @@ class BluetoothScanner: NSObject, CBCentralManagerDelegate, DTGPayloadApi { ) } - func buildPayloadRawData(_ rawData: FlutterStandardTypedData, source: DTGMessageSource, macAddress: String, rssi: NSNumber, receivedTimestamp: NSNumber, error: AutoreleasingUnsafeMutablePointer) -> DTGODIDPayload? { - return DTGODIDPayload.make(withRawData: rawData, receivedTimestamp: receivedTimestamp, macAddress: macAddress, rssi: rssi, source: source) + func buildPayloadRawData(_ rawData: FlutterStandardTypedData, source: DTGMessageSource, macAddress: String, btName: String?, rssi: NSNumber, receivedTimestamp: NSNumber, error: AutoreleasingUnsafeMutablePointer) -> DTGODIDPayload? { + return DTGODIDPayload.make(withRawData: rawData, receivedTimestamp: receivedTimestamp, macAddress: macAddress, rssi: rssi, source: source, btName: btName) } private func handleOdidMessage(advertisementData: [String : Any], didDiscover peripheral: CBPeripheral, rssi RSSI: NSNumber, offset: NSNumber){ @@ -106,7 +106,7 @@ class BluetoothScanner: NSObject, CBCentralManagerDelegate, DTGPayloadApi { } var err: FlutterError? let systimestamp = Int(Date().timeIntervalSince1970 * 1000) - let payload = buildPayloadRawData(data, source: DTGMessageSource.bluetoothLegacy, macAddress: peripheral.identifier.uuidString, rssi: RSSI.intValue as NSNumber, receivedTimestamp: systimestamp as NSNumber, error: &err) + let payload = buildPayloadRawData(data, source: DTGMessageSource.bluetoothLegacy, macAddress: peripheral.identifier.uuidString, btName: peripheral.name, rssi: RSSI.intValue as NSNumber, receivedTimestamp: systimestamp as NSNumber, error: &err) odidPayloadStreamHandler.send(payload!.toList() as Any) } diff --git a/ios/Classes/pigeon.h b/ios/Classes/pigeon.h index 6cfb743..1700adc 100644 --- a/ios/Classes/pigeon.h +++ b/ios/Classes/pigeon.h @@ -54,12 +54,14 @@ typedef NS_ENUM(NSUInteger, DTGWifiState) { receivedTimestamp:(NSNumber *)receivedTimestamp macAddress:(NSString *)macAddress rssi:(nullable NSNumber *)rssi - source:(DTGMessageSource)source; + source:(DTGMessageSource)source + btName:(nullable NSString *)btName; @property(nonatomic, strong) FlutterStandardTypedData * rawData; @property(nonatomic, strong) NSNumber * receivedTimestamp; @property(nonatomic, copy) NSString * macAddress; @property(nonatomic, strong, nullable) NSNumber * rssi; @property(nonatomic, assign) DTGMessageSource source; +@property(nonatomic, copy, nullable) NSString * btName; @end /// The codec used by DTGApi. @@ -87,7 +89,7 @@ NSObject *DTGPayloadApiGetCodec(void); @protocol DTGPayloadApi /// @return `nil` only when `error != nil`. -- (nullable DTGODIDPayload *)buildPayloadRawData:(FlutterStandardTypedData *)rawData source:(DTGMessageSource)source macAddress:(NSString *)macAddress rssi:(NSNumber *)rssi receivedTimestamp:(NSNumber *)receivedTimestamp error:(FlutterError *_Nullable *_Nonnull)error; +- (nullable DTGODIDPayload *)buildPayloadRawData:(FlutterStandardTypedData *)rawData source:(DTGMessageSource)source macAddress:(NSString *)macAddress btName:(nullable NSString *)btName rssi:(NSNumber *)rssi receivedTimestamp:(NSNumber *)receivedTimestamp error:(FlutterError *_Nullable *_Nonnull)error; @end extern void DTGPayloadApiSetup(id binaryMessenger, NSObject *_Nullable api); diff --git a/ios/Classes/pigeon.m b/ios/Classes/pigeon.m index f7350ff..4d66412 100644 --- a/ios/Classes/pigeon.m +++ b/ios/Classes/pigeon.m @@ -37,13 +37,15 @@ + (instancetype)makeWithRawData:(FlutterStandardTypedData *)rawData receivedTimestamp:(NSNumber *)receivedTimestamp macAddress:(NSString *)macAddress rssi:(nullable NSNumber *)rssi - source:(DTGMessageSource)source { + source:(DTGMessageSource)source + btName:(nullable NSString *)btName { DTGODIDPayload* pigeonResult = [[DTGODIDPayload alloc] init]; pigeonResult.rawData = rawData; pigeonResult.receivedTimestamp = receivedTimestamp; pigeonResult.macAddress = macAddress; pigeonResult.rssi = rssi; pigeonResult.source = source; + pigeonResult.btName = btName; return pigeonResult; } + (DTGODIDPayload *)fromList:(NSArray *)list { @@ -56,6 +58,7 @@ + (DTGODIDPayload *)fromList:(NSArray *)list { NSAssert(pigeonResult.macAddress != nil, @""); pigeonResult.rssi = GetNullableObjectAtIndex(list, 3); pigeonResult.source = [GetNullableObjectAtIndex(list, 4) integerValue]; + pigeonResult.btName = GetNullableObjectAtIndex(list, 5); return pigeonResult; } + (nullable DTGODIDPayload *)nullableFromList:(NSArray *)list { @@ -68,6 +71,7 @@ - (NSArray *)toList { (self.macAddress ?: [NSNull null]), (self.rssi ?: [NSNull null]), @(self.source), + (self.btName ?: [NSNull null]), ]; } @end @@ -341,16 +345,17 @@ void DTGPayloadApiSetup(id binaryMessenger, NSObject + 'ODIDMessageParsingException{ exception: $relatedException, ' + 'mac: $macAddress, btName: $btName, source: $source, ' + 'rssi: $rssi, receivedTimestamp: $receivedTimestamp }'; +} diff --git a/lib/flutter_opendroneid.dart b/lib/flutter_opendroneid.dart index 248bb1b..a9abf64 100644 --- a/lib/flutter_opendroneid.dart +++ b/lib/flutter_opendroneid.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:dart_opendroneid/dart_opendroneid.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_opendroneid/exceptions/odid_message_parsing_exception.dart'; import 'package:flutter_opendroneid/models/message_container.dart'; import 'package:flutter_opendroneid/models/permissions_missing_exception.dart'; @@ -106,8 +107,22 @@ class FlutterOpenDroneId { lastUpdate: DateTime.fromMillisecondsSinceEpoch(payload.receivedTimestamp), ); - final message = parseODIDMessage(payload.rawData); + ODIDMessage? message; + try { + message = parseODIDMessage(payload.rawData); + } catch (e) { + throw ODIDMessageParsingException( + relatedException: e, + macAddress: payload.macAddress, + rssi: payload.rssi, + receivedTimestamp: payload.receivedTimestamp, + source: payload.source, + btName: payload.btName, + ); + } + if (message == null) return; + final updatedPack = storedPack.update( message: message, receivedTimestamp: payload.receivedTimestamp, diff --git a/lib/pigeon.dart b/lib/pigeon.dart index 05bb9b7..40e3235 100644 --- a/lib/pigeon.dart +++ b/lib/pigeon.dart @@ -49,6 +49,7 @@ class ODIDPayload { required this.macAddress, this.rssi, required this.source, + this.btName, }); Uint8List rawData; @@ -61,6 +62,8 @@ class ODIDPayload { MessageSource source; + String? btName; + Object encode() { return [ rawData, @@ -68,6 +71,7 @@ class ODIDPayload { macAddress, rssi, source.index, + btName, ]; } @@ -79,6 +83,7 @@ class ODIDPayload { macAddress: result[2]! as String, rssi: result[3] as int?, source: MessageSource.values[result[4]! as int], + btName: result[5] as String?, ); } } @@ -426,12 +431,12 @@ class PayloadApi { static const MessageCodec codec = _PayloadApiCodec(); - Future buildPayload(Uint8List arg_rawData, MessageSource arg_source, String arg_macAddress, int arg_rssi, int arg_receivedTimestamp) async { + Future buildPayload(Uint8List arg_rawData, MessageSource arg_source, String arg_macAddress, String? arg_btName, int arg_rssi, int arg_receivedTimestamp) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.flutter_opendroneid.PayloadApi.buildPayload', codec, binaryMessenger: _binaryMessenger); final List? replyList = - await channel.send([arg_rawData, arg_source.index, arg_macAddress, arg_rssi, arg_receivedTimestamp]) as List?; + await channel.send([arg_rawData, arg_source.index, arg_macAddress, arg_btName, arg_rssi, arg_receivedTimestamp]) as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', diff --git a/pigeon/schema.dart b/pigeon/schema.dart index 007a4d9..cafba6c 100644 --- a/pigeon/schema.dart +++ b/pigeon/schema.dart @@ -45,12 +45,15 @@ class ODIDPayload { final MessageSource source; + final String? btName; + ODIDPayload( this.rawData, this.receivedTimestamp, this.macAddress, this.rssi, this.source, + this.btName, ); } @@ -86,5 +89,5 @@ abstract class Api { @HostApi() abstract class PayloadApi { ODIDPayload buildPayload(Uint8List rawData, MessageSource source, - String macAddress, int rssi, int receivedTimestamp); + String macAddress, String? btName, int rssi, int receivedTimestamp); }