Files
universal_ble/darwin/Classes/UniversalBleHelper.swift
T
2024-01-24 14:23:49 +01:00

173 lines
4.9 KiB
Swift

//
// UniversalBleHelper.swift
// universal_ble
//
// Created by Rohit Sangwan on 25/10/23.
//
import CoreBluetooth
import Foundation
#if os(iOS)
import Flutter
#elseif os(OSX)
import FlutterMacOS
#endif
enum BleInputProperty: Int {
case disabled = 0
case notification = 1
case indication = 2
}
enum BleOutputProperty: Int {
case withResponse = 0
case withoutResponse = 1
}
enum BlueConnectionState: Int64 {
case connected = 0
case disconnected = 1
}
enum AvailabilityState: Int64 {
case unknown = 0
case resetting = 1
case unsupported = 2
case unauthorized = 3
case poweredOff = 4
case poweredOn = 5
}
enum CharacteristicProperty: Int64 {
case broadcast = 0
case read = 1
case writeWithoutResponse = 2
case write = 3
case notify = 4
case indicate = 5
case authenticatedSignedWrites = 6
case extendedProperties = 7
}
extension CBCharacteristicProperties {
var toCharacteristicProperty: [Int64] {
var properties = [Int64]()
if contains(.broadcast) {
properties.append(CharacteristicProperty.broadcast.rawValue)
}
if contains(.read) {
properties.append(CharacteristicProperty.read.rawValue)
}
if contains(.writeWithoutResponse) {
properties.append(CharacteristicProperty.writeWithoutResponse.rawValue)
}
if contains(.write) {
properties.append(CharacteristicProperty.write.rawValue)
}
if contains(.notify) {
properties.append(CharacteristicProperty.notify.rawValue)
}
if contains(.indicate) {
properties.append(CharacteristicProperty.indicate.rawValue)
}
if contains(.authenticatedSignedWrites) {
properties.append(CharacteristicProperty.authenticatedSignedWrites.rawValue)
}
if contains(.extendedProperties) {
properties.append(CharacteristicProperty.extendedProperties.rawValue)
}
return properties
}
}
extension CBManagerState {
func toAvailabilityState() -> AvailabilityState {
switch self {
case .unknown:
return AvailabilityState.unknown
case .resetting:
return AvailabilityState.resetting
case .unsupported:
return AvailabilityState.unsupported
case .unauthorized:
return AvailabilityState.unauthorized
case .poweredOff:
return AvailabilityState.poweredOff
case .poweredOn:
return AvailabilityState.poweredOn
@unknown default:
return AvailabilityState.unknown
}
}
}
public extension CBUUID {
var uuidStr: String {
uuidString.lowercased()
}
}
public extension CBPeripheral {
// FIXME: https://forums.developer.apple.com/thread/84375
var uuid: UUID {
value(forKey: "identifier") as! NSUUID as UUID
}
func getCharacteristic(_ characteristic: String, of service: String) -> CBCharacteristic? {
let GSS_SUFFIX = "0000-1000-8000-00805f9b34fb"
let s = services?.first {
$0.uuid.uuidStr.lowercased() == service.lowercased() || service.lowercased() == "0000\($0.uuid.uuidStr)-\(GSS_SUFFIX)".lowercased()
}
let c = s?.characteristics?.first {
$0.uuid.uuidStr.lowercased() == characteristic.lowercased() || characteristic.lowercased() == "0000\($0.uuid.uuidStr)-\(GSS_SUFFIX)".lowercased()
}
return c
}
func setNotifiable(_ bleInputProperty: String, for characteristic: String, of service: String) {
guard let characteristic = getCharacteristic(characteristic, of: service) else {
return
}
setNotifyValue(bleInputProperty != "disabled", for: characteristic)
}
}
// Future classes
class CharacteristicReadFuture {
let deviceId: String
let characteristicId: String
let serviceId: String?
let result: (Result<FlutterStandardTypedData, Error>) -> Void
init(deviceId: String, characteristicId: String, serviceId: String?, result: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
self.deviceId = deviceId
self.characteristicId = characteristicId
self.serviceId = serviceId
self.result = result
}
}
class CharacteristicWriteFuture {
let deviceId: String
let characteristicId: String
let serviceId: String?
let result: (Result<Void, Error>) -> Void
init(deviceId: String, characteristicId: String, serviceId: String?, result: @escaping (Result<Void, Error>) -> Void) {
self.deviceId = deviceId
self.characteristicId = characteristicId
self.serviceId = serviceId
self.result = result
}
}
class DiscoverServicesFuture {
let deviceId: String
let result: (Result<[UniversalBleService], Error>) -> Void
init(deviceId: String, result: @escaping (Result<[UniversalBleService], Error>) -> Void) {
self.deviceId = deviceId
self.result = result
}
}