Abrevva Flutter Plugin

Pub Version Pub Points GitHub last commit GitHub branch check runs EVVA License

The EVVA Abrevva Flutter Plugin is a collection of tools to work with electronical EVVA access components. It allows for scanning and connecting via BLE.

Features

  • BLE Scanner for EVVA components
  • Localize scanned EVVA components
  • Disengage scanned EVVA components
  • Read / Write data via BLE

Requirements

Platform Version
Flutter 3.3.0+
Java 17+
Android 11+
Android API 30+
Kotlin 2.x
iOS 16.0+
Xcode 15.3+
Swift 5.10+

Installation

flutter pub add abrevva

iOS

In your app add a post_install hook in your Podfile to resolve a nasty CocoaPods limitation with XCFrameworks.

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
    end
  end
end

Execute pod install inside of your projects ios/ folder.

Android

Perform a gradle sync.

Examples

Initialize and scan for EVVA components

To start off first import the abrevva Package

import 'package:abrevva/abrevva.dart';

async function scanForBleDevices(androidNeverForLocation: Boolean = true, timeout: Number) {
  await AbrevvaBle.initialize(androidNeverForLocation);

  AbrevvaBle.startScan(
    (scanResult: ScanResult) => {
      print("Discovered Device: ${scanResult.bleDevice.deviceId}");
    },
    (success: bool) => {
      print("onScanStart status=${success}");
    },
    (success: bool) => {
      print("onScanStop status=${success}");
    },
    null,  // macFilter
    false, // allowDuplicates
    10_000 // timeout
  );
}

Read EVVA component advertisement

Get the EVVA advertisement data from a scanned EVVA component.

final ad = device.advertisementData;
print(ad?.rssi);
print(ad?.isConnectable);

final md = ad?.manufacturerData;
print(md.batteryStatus);
print(md.isOnline);
print(md.officeModeEnabled);
print(md.officeModeActive);
// ...

There are several properties that can be accessed from the advertisement.

class BleDeviceAdvertisementData {
  int? rssi;
  bool? isConnectable;
  BleDeviceManufacturerData? manufacturerData;
  Map<String, dynamic>? rawData;
}

class BleDeviceManufacturerData {
  int? companyIdentifier;
  int? version;
  ComponentType? componentType;
  int? mainFirmwareVersionMajor;
  int? mainFirmwareVersionMinor;
  int? mainFirmwareVersionPatch;
  int? componentHAL;
  BatteryStatus? batteryStatus;
  bool? mainConstructionMode;
  bool? subConstructionMode;
  bool? isOnline;
  bool? officeModeEnabled;
  bool? twoFactorRequired;
  bool? officeModeActive;
  String? identifier;
  int? subFirmwareVersionMajor;
  int? subFirmwareVersionMinor;
  int? subFirmwareVersionPatch;
  String? subComponentIdentifier;
}

Localize EVVA component

With the signalize method you can localize EVVA components. On a successful signalization the component will emit a melody indicating its location.

final success = await AbrevvaBle.signalize('deviceId');

Disengage EVVA components

For the component disengage you have to provide access credentials to the EVVA component. Those are generally acquired from the Xesar software.

Note: Since 2.0.0 the mobileId string can be passed as is, without sha256 hashing the input first.

final result = await AbrevvaBle.disengageWithXvnResponse(
  'deviceId',
  'mobileId',
  'mobileDeviceKey',
  'mobileGroupId',
  'mobileAccessData',
  true
);

print("status=${result.status} xvnData=${result.xvnData}");

There are several access status types upon attempting the component disengage.

enum DisengageStatusType {
  /// Component
  authorized, 
  authorizedPermanentDisengage, 
  authorizedPermanentEngage, 
  authorizedBatteryLow, 
  authorizedOffline, 
  unauthorized, 
  unauthorizedOffline, 
  signalLocalization, 
  mediumDefectOnline,
  mediumBlacklisted, 
  error,

  /// Interface
  unableToConnect,
  unableToSetNotifications,
  unableToReadChallenge,
  unableToWriteMDF,
  accessCipherError,
  bleAdapterDisabled,
  unknownDevice,
  unknownStatusCode,
  timeout,
}

Coding Identification Media

Use the CodingStation to write or update access data onto an EVVA identification medium.

class ExampleClass {
  String url = "";
  String clientId = "";
  String username = "";
  String password = "";
  
  void writeMedium() async {
    try {
      await AbrevvaCodingStation.register(url, clientId, username, password);
      await AbrevvaCodingStation.connect();
      await AbrevvaCodingStation.write();
      await AbrevvaCodingStation.disconnect();
    } catch (e) {
      debugPrint("Error $e");
    }
  }
}