Skip to content

Collection of tools to work with electronic EVVA access components - for native iOS development.

License

Notifications You must be signed in to change notification settings

evva-sfw/abrevva-sdk-ios

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EVVA Abrevva iOS SDK

Package managers Package managers EVVA License Package managers Package managers

The EVVA Abrevva iOS SDK 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 Xcode Swift Status
iOS 16.0+ 15.3+ 5.10+ Fully Tested
watchOS 10.0+ 15.3+ 5.10+ Fully Tested

Installation

Cocoapods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate EVVA Abrevva iOS SDK into your Xcode project using CocoaPods, specify the pod in your Podfile and add a post_install hook to resolve a nasty CocoaPods limitation with XCFrameworks.

target 'App' do
  pod 'AbrevvaSDK'
end    

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

Swift Package Manager

See swiftpackageindex.com

Examples

Initialize BleManager

To start off first initialize the SDK BleManager. You can pass an init callback closure for success indication.

import AbrevvaSDK

public class Example {

    private var bleManager: BleManager?
    private var bleDeviceMap = [String: BleDevice]()

    func initialize() {
        self.bleManager = BleManager { success, message in
            debugPrint("BleManager initialized /w success=\(success)")
        }
    }
}

Scan for EVVA components

Use the BleManager to scan for components in range. You can pass several callback closures to react to the different events when scanning or connecting to components.

func scanForDevices() {
    let timeout = 10_000

    self.bleManager?.startScan(
        { device in
            debugPrint("Found device /w address=\(device.address)")
            self.bleDeviceMap[device.address] = device
        },
        { error in
            debugPrint("Scan started /w \(error ?? "success")")
        },
        { error in
            debugPrint("Scan stopped /w \(error ?? "success")")
        }, 
        nil,        // mac filter
        false,      // allow duplicates
        timeout
    )
}

Read EVVA component advertisement

Get the EVVA advertisement data from a scanned EVVA component.

let ad = device.advertisementData
debugPrint(ad?.rssi)
debugPrint(ad?.isConnectable)

let md = ad?.manufacturerData
debugPrint(md?.batteryStatus)
debugPrint(md?.isOnline)
debugPrint(md?.officeModeEnabled)
debugPrint(md?.officeModeActive)
// ...

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

public struct BleDeviceAdvertisementData {
    public let rssi: Int
    public let isConnectable: Bool?
    public let manufacturerData: BleDeviceManufacturerData?
}

public struct BleDeviceManufacturerData {
    public let companyIdentifier: UInt16
    public let version: UInt8
    public let componentType: UInt8
    public let mainFirmwareVersionMajor: UInt8
    public let mainFirmwareVersionMinor: UInt8
    public let mainFirmwareVersionPatch: UInt16
    public let componentHAL: Int
    public let batteryStatus: Bool
    public let mainConstructionMode: Bool
    public let subConstructionMode: Bool
    public let isOnline: Bool
    public let officeModeEnabled: Bool
    public let twoFactorRequired: Bool
    public let officeModeActive: Bool
    public let reservedBits: Int?
    public let identifier: String
    public let subFirmwareVersionMajor: UInt8?
    public let subFirmwareVersionMinor: UInt8?
    public let subFirmwareVersionPatch: UInt16?
    public let subComponentIdentifier: String?
}

Localize EVVA component

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

 func signalizeDevice(_ deviceId: String) async {
    guard let device = self.bleDeviceMap[deviceId] else { return }

    let success = await self.bleManager?.signalize(device)
    debugPrint("Signalized /w success=\(success)")
}

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 3.4.0 the mobileID string can be passed as is, without sha256 hashing the input first.

 func disengageDevice(_ deviceId: String) async {
    guard let device = self.bleDeviceMap[deviceId] else { return }

    let mobileId = ""               // `xsMobileId` string from medium blob data
    let mobileDeviceKey = ""        // `xsMOBDK` string from medium blob data
    let mobileGroupId = ""          // `xsMOBGID` string from medium blob data
    let mediumAccessData = ""       // `mediumDataFrame` string from medium blob data
    let isPermanentRelease = false  // office mode flag

    let result = await self.bleManager?.disengageWithXvnResponse(
        device,
        mobileId,
        mobileDeviceKey,
        mobileGroupId,
        mediumAccessData,
        isPermanentRelease,
    )
    debugPrint("status=\(result.0) xvnData=\(result.1)")
}

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

public enum DisengageStatusType: String {
    /// Component
    case AUTHORIZED
    case AUTHORIZED_PERMANENT_ENGAGE
    case AUTHORIZED_PERMANENT_DISENGAGE
    case AUTHORIZED_BATTERY_LOW
    case AUTHORIZED_OFFLINE
    case UNAUTHORIZED
    case UNAUTHORIZED_OFFLINE
    case SIGNAL_LOCALIZATION
    case MEDIUM_DEFECT_ONLINE
    case MEDIUM_BLACKLISTED
    case ERROR

    /// Interface
    case UNKNOWN_STATUS_CODE
    case UNABLE_TO_CONNECT
    case TIMEOUT
    case UNABLE_TO_SET_NOTIFICATIONS
    case UNABLE_TO_READ_CHALLENGE
    case ACCESS_CIPHER_ERROR
}

Coding Identification Media

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

class ExampleClass {
    private let cs = CodingStation()

    private let url = URL(string: "")!
    private let clientId = ""
    private let username = ""
    private let password = ""

    public func writeMedium() async throws {
        let cf: MqttConnectionOptions?
        
        cf = try await AuthManager.getMqttConfigForXS(
            url: url, clientId: clientId, username: username, password: password)
        try await cs.connect(cf!)
        try await cs.write()
        cs.disconnect()
    }
}

About

Collection of tools to work with electronic EVVA access components - for native iOS development.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages