Skip to content

Commit

Permalink
feat: include Bluetooth metadata to parsing exceptions (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
matejglejtek committed Jul 19, 2024
2 parents 4d83d55 + 715e231 commit 89a29b6
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 23 deletions.
32 changes: 27 additions & 5 deletions android/src/main/java/cz/dronetag/flutter_opendroneid/Pigeon.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

Expand Down Expand Up @@ -222,25 +232,34 @@ 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);
pigeonReturn.setReceivedTimestamp(receivedTimestamp);
pigeonReturn.setMacAddress(macAddress);
pigeonReturn.setRssi(rssi);
pigeonReturn.setSource(source);
pigeonReturn.setBtName(btName);
return pigeonReturn;
}
}

@NonNull
ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(5);
ArrayList<Object> toListResult = new ArrayList<Object>(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;
}

Expand All @@ -256,6 +275,8 @@ ArrayList<Object> 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;
}
}
Expand Down Expand Up @@ -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<Object> getCodec() {
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class BluetoothScanner(
result.device.address,
source,
result.rssi.toLong(),
result.device.name,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,28 @@ 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)
builder.setReceivedTimestamp(receivedTimestamp)
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
Expand Down
6 changes: 3 additions & 3 deletions ios/Classes/Scanner/BluetoothScanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ class BluetoothScanner: NSObject, CBCentralManagerDelegate, DTGPayloadApi {
)
}

func buildPayloadRawData(_ rawData: FlutterStandardTypedData, source: DTGMessageSource, macAddress: String, rssi: NSNumber, receivedTimestamp: NSNumber, error: AutoreleasingUnsafeMutablePointer<FlutterError?>) -> 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<FlutterError?>) -> 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){
Expand All @@ -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)
}
Expand Down
6 changes: 4 additions & 2 deletions ios/Classes/pigeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -87,7 +89,7 @@ NSObject<FlutterMessageCodec> *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<FlutterBinaryMessenger> binaryMessenger, NSObject<DTGPayloadApi> *_Nullable api);
Expand Down
15 changes: 10 additions & 5 deletions ios/Classes/pigeon.m
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -68,6 +71,7 @@ - (NSArray *)toList {
(self.macAddress ?: [NSNull null]),
(self.rssi ?: [NSNull null]),
@(self.source),
(self.btName ?: [NSNull null]),
];
}
@end
Expand Down Expand Up @@ -341,16 +345,17 @@ void DTGPayloadApiSetup(id<FlutterBinaryMessenger> binaryMessenger, NSObject<DTG
binaryMessenger:binaryMessenger
codec:DTGPayloadApiGetCodec()];
if (api) {
NSCAssert([api respondsToSelector:@selector(buildPayloadRawData:source:macAddress:rssi:receivedTimestamp:error:)], @"DTGPayloadApi api (%@) doesn't respond to @selector(buildPayloadRawData:source:macAddress:rssi:receivedTimestamp:error:)", api);
NSCAssert([api respondsToSelector:@selector(buildPayloadRawData:source:macAddress:btName:rssi:receivedTimestamp:error:)], @"DTGPayloadApi api (%@) doesn't respond to @selector(buildPayloadRawData:source:macAddress:btName:rssi:receivedTimestamp:error:)", api);
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
NSArray *args = message;
FlutterStandardTypedData *arg_rawData = GetNullableObjectAtIndex(args, 0);
DTGMessageSource arg_source = [GetNullableObjectAtIndex(args, 1) integerValue];
NSString *arg_macAddress = GetNullableObjectAtIndex(args, 2);
NSNumber *arg_rssi = GetNullableObjectAtIndex(args, 3);
NSNumber *arg_receivedTimestamp = GetNullableObjectAtIndex(args, 4);
NSString *arg_btName = GetNullableObjectAtIndex(args, 3);
NSNumber *arg_rssi = GetNullableObjectAtIndex(args, 4);
NSNumber *arg_receivedTimestamp = GetNullableObjectAtIndex(args, 5);
FlutterError *error;
DTGODIDPayload *output = [api buildPayloadRawData:arg_rawData source:arg_source macAddress:arg_macAddress rssi:arg_rssi receivedTimestamp:arg_receivedTimestamp error:&error];
DTGODIDPayload *output = [api buildPayloadRawData:arg_rawData source:arg_source macAddress:arg_macAddress btName:arg_btName rssi:arg_rssi receivedTimestamp:arg_receivedTimestamp error:&error];
callback(wrapResult(output, error));
}];
} else {
Expand Down
25 changes: 25 additions & 0 deletions lib/exceptions/odid_message_parsing_exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:flutter_opendroneid/pigeon.dart';

class ODIDMessageParsingException implements Exception {
final Object relatedException;
final String macAddress;
final String? btName;
final MessageSource source;
final int? rssi;
final int receivedTimestamp;

ODIDMessageParsingException({
required this.relatedException,
required this.macAddress,
required this.btName,
required this.source,
required this.receivedTimestamp,
this.rssi,
});

@override
String toString() =>
'ODIDMessageParsingException{ exception: $relatedException, '
'mac: $macAddress, btName: $btName, source: $source, '
'rssi: $rssi, receivedTimestamp: $receivedTimestamp }';
}
17 changes: 16 additions & 1 deletion lib/flutter_opendroneid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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,
Expand Down
9 changes: 7 additions & 2 deletions lib/pigeon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class ODIDPayload {
required this.macAddress,
this.rssi,
required this.source,
this.btName,
});

Uint8List rawData;
Expand All @@ -61,13 +62,16 @@ class ODIDPayload {

MessageSource source;

String? btName;

Object encode() {
return <Object?>[
rawData,
receivedTimestamp,
macAddress,
rssi,
source.index,
btName,
];
}

Expand All @@ -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?,
);
}
}
Expand Down Expand Up @@ -426,12 +431,12 @@ class PayloadApi {

static const MessageCodec<Object?> codec = _PayloadApiCodec();

Future<ODIDPayload> buildPayload(Uint8List arg_rawData, MessageSource arg_source, String arg_macAddress, int arg_rssi, int arg_receivedTimestamp) async {
Future<ODIDPayload> buildPayload(Uint8List arg_rawData, MessageSource arg_source, String arg_macAddress, String? arg_btName, int arg_rssi, int arg_receivedTimestamp) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.flutter_opendroneid.PayloadApi.buildPayload', codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList =
await channel.send(<Object?>[arg_rawData, arg_source.index, arg_macAddress, arg_rssi, arg_receivedTimestamp]) as List<Object?>?;
await channel.send(<Object?>[arg_rawData, arg_source.index, arg_macAddress, arg_btName, arg_rssi, arg_receivedTimestamp]) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
Expand Down
5 changes: 4 additions & 1 deletion pigeon/schema.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
}

Expand Down Expand Up @@ -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);
}

0 comments on commit 89a29b6

Please sign in to comment.