Skip to content

Commit

Permalink
chore: clean and remove unused code
Browse files Browse the repository at this point in the history
DT-2604
  • Loading branch information
matejglejtek committed Aug 31, 2023
1 parent 7b43b50 commit 2283f42
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,51 @@ class BluetoothScanner(
private val bluetoothStateHandler: StreamHandler,
) : ODIDScanner(odidPayloadStreamHandler) {
private val TAG: String = BluetoothScanner::class.java.getSimpleName()
private val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()

private var scanMode = ScanSettings.SCAN_MODE_LOW_LATENCY

var scanMode = ScanSettings.SCAN_MODE_LOW_LATENCY
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()

/// OpenDroneID Bluetooth beacons identify themselves by setting the GAP AD Type to
/// "Service Data - 16-bit UUID" and the value to 0xFFFA for ASTM International, ASTM Remote ID.
/// https://www.bluetooth.com/specifications/assigned-numbers/ -> "Generic Access Profile"
/// https://www.bluetooth.com/specifications/assigned-numbers/ -> "16-bit UUIDs"
/// Vol 3, Part B, Section 2.5.1 of the Bluetooth 5.1 Core Specification
/// The AD Application Code is set to 0x0D = Open Drone ID.

private val serviceUuid = UUID.fromString("0000fffa-0000-1000-8000-00805f9b34fb")
private val serviceParcelUuid = ParcelUuid(serviceUuid)
private val odidAdCode = byteArrayOf(0x0D.toByte())

/// Callback for receiving data: read data from ScanRecord and call receiveData
private val scanCallback: ScanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
val scanRecord: ScanRecord = result.scanRecord ?: return
val bytes = scanRecord.bytes ?: return
var source = Pigeon.MessageSource.BLUETOOTH_LEGACY;

if (bytes.size < BT_OFFSET + MAX_MESSAGE_SIZE) return

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && bluetoothAdapter.isLeCodedPhySupported()) {
if (result.getPrimaryPhy() == BluetoothDevice.PHY_LE_CODED)
source = Pigeon.MessageSource.BLUETOOTH_LONG_RANGE;
}

receiveData(
offsetData(bytes, BT_OFFSET),
result.device.address,
source,
result.rssi.toLong(),
)
}

override fun onBatchScanResults(results: List<ScanResult?>?) {
Log.e(TAG, "Got batch scan results, unable to handle")
}

override fun onScanFailed(errorCode: Int) {
Log.e(TAG, "Scan failed: $errorCode")
}
}

@RequiresApi(Build.VERSION_CODES.O)
override fun scan() {
if (!bluetoothAdapter.isEnabled) return
Expand Down Expand Up @@ -112,36 +142,6 @@ class BluetoothScanner(
}
}

private val scanCallback: ScanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult) {
val scanRecord: ScanRecord = result.scanRecord ?: return
val bytes = scanRecord.bytes ?: return
var source = Pigeon.MessageSource.BLUETOOTH_LEGACY;

if (bytes.size < BT_OFFSET + MAX_MESSAGE_SIZE) return

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && bluetoothAdapter.isLeCodedPhySupported()) {
if (result.getPrimaryPhy() == BluetoothDevice.PHY_LE_CODED)
source = Pigeon.MessageSource.BLUETOOTH_LONG_RANGE;
}

receiveData(
offsetData(bytes, BT_OFFSET),
result.device.address,
source,
result.rssi.toLong(),
)
}

override fun onBatchScanResults(results: List<ScanResult?>?) {
Log.e(TAG, "Got batch scan results, unable to handle")
}

override fun onScanFailed(errorCode: Int) {
Log.e(TAG, "Scan failed: $errorCode")
}
}

private fun logAdapterInfo(bluetoothAdapter: BluetoothAdapter) {
Log.i(TAG, "bluetooth LE extended supported: " + bluetoothAdapter.isLeExtendedAdvertisingSupported.toString())
Log.i(TAG, "bluetooth LE coded phy supported: " + bluetoothAdapter.isLeCodedPhySupported.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import android.content.Context
import android.content.Intent

/// Contains common functinality for ODID scanners
/// Creates [ODIDPayload] instances implementin Pigeon PayloadAPI
/// Derived scanners should use receiveData method that takes raw data and metadata
/// and sends it to stream
/// Creates [ODIDPayload] instances implementing Pigeon PayloadAPI
abstract class ODIDScanner(
val odidPayloadStreamHandler: StreamHandler
private val odidPayloadStreamHandler: StreamHandler
) : Pigeon.PayloadApi {

companion object {
Expand Down Expand Up @@ -58,6 +60,6 @@ abstract class ODIDScanner(
odidPayloadStreamHandler.send(payload?.toList() as Any)
}

/// returs [ByteArray] without first offset elements
/// returns ByteArray without first offset elements
inline fun offsetData(data: ByteArray, offset: Int) : ByteArray = data.copyOfRange(offset, data.size)
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,47 @@ class WifiNaNScanner (
private val context: Context
) : ODIDScanner(odidPayloadStreamHandler) {
private val TAG: String = WifiNaNScanner::class.java.getSimpleName()

private var wifiAwareSession: WifiAwareSession? = null
private val wifiScanEnabled = true
private var wifiAwareSupported = true

private var wifiAwareSession: WifiAwareSession? = null

// callback for Wi-Fi Aware session advertisement
private val attachCallback: AttachCallback = @RequiresApi(Build.VERSION_CODES.O)
object : AttachCallback() {
override fun onAttached(session: WifiAwareSession) {
if (!wifiAwareSupported) return
wifiAwareSession = session
val config = SubscribeConfig.Builder()
.setServiceName("org.opendroneid.remoteid")
.build()
wifiAwareSession!!.subscribe(config, object : DiscoverySessionCallback() {
override fun onServiceDiscovered(
peerHandle: PeerHandle?,
serviceSpecificInfo: ByteArray?,
matchFilter: MutableList<ByteArray>?
) {
if (serviceSpecificInfo != null)
receiveData(
offsetData(serviceSpecificInfo, WIFI_NAN_OFFSET),
peerHandle.hashCode().toString(),
Pigeon.MessageSource.WIFI_NAN,
)
}
}, null)
}
}

@TargetApi(Build.VERSION_CODES.O)
private val identityChangedListener: IdentityChangedListener =
object : IdentityChangedListener() {
override fun onIdentityChanged(mac: ByteArray) {
val macAddress = arrayOfNulls<Byte>(mac.size)
var i = 0
for (b in mac) macAddress[i++] = b
}
}

init{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O ||
!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)) {
Expand All @@ -51,9 +87,6 @@ class WifiNaNScanner (
}

override fun scan() {
if (!wifiScanEnabled) {
return
}
isScanning = true
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O ||
!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)) {
Expand Down Expand Up @@ -81,42 +114,6 @@ class WifiNaNScanner (
}
}

private val attachCallback: AttachCallback = @RequiresApi(Build.VERSION_CODES.O)
object : AttachCallback() {
override fun onAttached(session: WifiAwareSession) {
if (!wifiAwareSupported) return
wifiAwareSession = session
val config = SubscribeConfig.Builder()
.setServiceName("org.opendroneid.remoteid")
.build()
wifiAwareSession!!.subscribe(config, object : DiscoverySessionCallback() {
override fun onServiceDiscovered(
peerHandle: PeerHandle?,
serviceSpecificInfo: ByteArray?,
matchFilter: MutableList<ByteArray>?
) {
if (serviceSpecificInfo != null)
receiveData(
offsetData(serviceSpecificInfo, WIFI_NAN_OFFSET),
peerHandle.hashCode().toString(),
Pigeon.MessageSource.WIFI_NAN,
)
}
}, null)
}

}

@TargetApi(Build.VERSION_CODES.O)
private val identityChangedListener: IdentityChangedListener =
object : IdentityChangedListener() {
override fun onIdentityChanged(mac: ByteArray) {
val macAddress = arrayOfNulls<Byte>(mac.size)
var i = 0
for (b in mac) macAddress[i++] = b
}
}

fun isWifiAwareSupported(): Boolean
{
return wifiAwareSupported;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,31 @@ import android.os.CountDownTimer
import java.nio.ByteOrder
import java.util.*

/// Wi-Fi Beacons Scanner
/// There are 2 ways to control WiFi scan:
/// Continuous scan: Calls startScan() from scan completion callback
/// Periodic scan: countdown timer triggers startScan after expiry of the timer.
/// If phone is debug mode and scan throttling is off, scan is triggered from onReceive() callback.
/// But if scan throttling is turned on on the phone (default setting on the phone), then scan throttling kick in.
/// In case of throttling, startScan() fails. We need timer thread to periodically kick off scanning.
class WifiScanner (
odidPayloadStreamHandler: StreamHandler,
private val wifiStateHandler: StreamHandler,
private val wifiManager: WifiManager?,
private val context: Context
) : ODIDScanner(odidPayloadStreamHandler) {
private val TAG: String = WifiScanner::class.java.getSimpleName()

private val CIDLen = 3
private val DRICID = intArrayOf(0xFA, 0x0B, 0xBC)
private val vendorTypeLen = 1
private val vendorTypeValue = 0x0D
private var scanSuccess = 0
private var scanFailed = 0
private val scanTimerInterval = 2

private var countDownTimer: CountDownTimer? = null

// callback for receiving Wi-Fi scan results
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(contxt: Context?, intent: Intent?) {
if (wifiManager == null) {
Expand All @@ -47,7 +55,8 @@ class WifiScanner (
e.printStackTrace()
}
}
scan()
if(isScanning)
scan()
}
}
}
Expand Down Expand Up @@ -154,20 +163,15 @@ class WifiScanner (
&& vendorType[0] == vendorTypeValue.toByte()
}

// There are 2 ways to control WiFi scan:
// Continuous scan: Calls startSCan() from scan completion callback
// Periodic scan: countdown timer triggers startScan after expiry of the timer.
// If phone is debug mode and scan throttling is off, scan is triggered from onReceive() callback.
// But if scan throttling is turned on on the phone (default setting on the phone), then scan throttling kick in.
// In case of throttling, startScan() fails. We need timer thread to periodically kick off scanning.
private fun startCountDownTimer() {
countDownTimer = object : CountDownTimer(
Long.MAX_VALUE,
(scanTimerInterval * 1000).toLong()
) {
// This is called after every ScanTimerInterval sec.
override fun onTick(millisUntilFinished: Long) {
scan()
if(isScanning)
scan()
}

override fun onFinish() {}
Expand Down
7 changes: 3 additions & 4 deletions lib/flutter_opendroneid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class FlutterOpenDroneId {
static const _wifiStateEventChannel =
const EventChannel('flutter_odid_wifi_state');

static StreamSubscription? _rawDataSubscription;
static StreamSubscription? _odidDataSubscription;

static final _packController = StreamController<MessageContainer>.broadcast();
static Map<String, MessageContainer> _storedPacks = {};
Expand Down Expand Up @@ -55,7 +55,7 @@ class FlutterOpenDroneId {
/// To further receive data, listen to
/// streams.
static Future<void> startScan(UsedTechnologies usedTechnologies) async {
_rawDataSubscription = odidPayloadEventChannel
_odidDataSubscription = odidPayloadEventChannel
.receiveBroadcastStream()
.listen((payload) => _updatePacks(pigeon.ODIDPayload.decode(payload)));

Expand All @@ -75,7 +75,7 @@ class FlutterOpenDroneId {
static Future<void> stopScan() async {
if (await _api.isScanningBluetooth()) await _api.stopScanBluetooth();
if (await _api.isScanningWifi()) await _api.stopScanWifi();
_rawDataSubscription?.cancel();
_odidDataSubscription?.cancel();
}

static Future<void> setBtScanPriority(pigeon.ScanPriority priority) async {
Expand Down Expand Up @@ -104,7 +104,6 @@ class FlutterOpenDroneId {
lastUpdate:
DateTime.fromMillisecondsSinceEpoch(payload.receivedTimestamp),
);
// TODO: check for duplicate messages
final message = parseODIDMessage(payload.rawData);
if (message == null) return;
final updatedPack = storedPack.update(
Expand Down
28 changes: 3 additions & 25 deletions lib/models/message_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ class MessageContainer {
this.systemDataMessage,
});

static const colorMax = 120;
static const colorOffset = 90;

MessageContainer copyWith({
String? macAddress,
int? lastMessageRssi,
Expand All @@ -60,6 +57,9 @@ class MessageContainer {
systemDataMessage: systemDataMessage ?? this.systemDataMessage,
);

/// Returns new MessageContainer updated with message.
/// Null is returned if update is refused, because it contains duplicate or
/// corrupted data.
MessageContainer? update({
required ODIDMessage message,
required int receivedTimestamp,
Expand Down Expand Up @@ -147,28 +147,6 @@ class MessageContainer {

pigeon.MessageSource getPackSource() => source;

/// Calculates a color from mac address, that uniquely identifies the device
Color getPackColor() {
final len = macAddress.length;
return Color.fromARGB(
locationMessage?.status != OperationalStatus.airborne ? 80 : 255,
colorOffset +
32 +
macAddress
.substring(0, len ~/ 2)
.codeUnits
.reduce((sum, e) => sum + e) %
(colorMax - 32),
colorOffset +
macAddress.codeUnits.reduce((sum, e) => (sum * e) % colorMax),
colorOffset +
macAddress
.substring(len ~/ 2)
.codeUnits
.fold(255, (sum, e) => sum - e % colorMax),
);
}

bool operatorIDSet() {
return operatorIdMessage != null &&
operatorIdMessage!.operatorID != OPERATOR_ID_NOT_SET;
Expand Down

0 comments on commit 2283f42

Please sign in to comment.