6.0.0 (#74)
* 调整接口 * 临时提交 * 重构 Android 平台代码 * 临时提交 * 临时提交 * Android 6.0.0-dev.0 * 临时提交 * 实现 Windows 接口 * windows-6.0.0-dev.0 * Darwin 6.0.0-dev.0 * 临时提交 * 1 * 临时提交 * 调整接口 * windows-6.0.0-dev.1 * 临时提交 * interface-6.0.0-dev.7 * interface-6.0.0-dev.8 * 临时提交 * windows-6.0.0-dev.2 * 删除多余脚本 * interface-6.0.0-dev.9 * 临时提交 * 临时提交 * interface-6.0.0-dev.10 * android-6.0.0-dev.1 * windows-6.0.0-dev.3 * 临时提交 * interface-6.0.0-dev.11 * windows-6.0.0-dev.4 * 更新 pubspec.lock * 1 * interface-6.0.0-dev.12 * interface-6.0.0-dev.13 * interface-6.0.0-dev.14 * 临时提交 * interface-6.0.0-dev.15 * 临时提交 * interface-6.0.0-dev.16 * android-6.0.0-dev.2 * 临时提交 * windows-6.0.0-dev.5 * 临时提交 * 临时提交 * windows-6.0.0-dev.6 * 优化注释和代码样式 * 优化代码 * 临时提交 * 实现 Dart 接口 * darwin-6.0.0-dev.0 * linux-6.0.0-dev.0 * 修复已知问题 * 修复问题 * 6.0.0-dev.0 * 修改包名 * 更新版本 * 移除原生部分 * 临时提交 * 修复问题 * 更新 pigeon 19.0.0 * 更新 README,添加迁移文档 * linux-6.0.0-dev.1 * 解析扫描回复和扩展广播 * 修复 googletest 版本警告问题 * Use centralArgs instead of addressArgs * interface-6.0.0-dev.18 * android-6.0.0-dev.4 * linux-6.0.0-dev.2 * windows-6.0.0-dev.8 * darwin-6.0.0-dev.2 * 6.0.0-dev.1 * Update LICENSE * clang-format * Combine ADV_IND and SCAN_RES * TEMP commit: update exampe * Adjust advertisement combine logic * Implement `MyPeripheralMananger` on Windows * Added NuGet auto download and scan for names on peripheral (#67) * fetch nuget using other technique * move FetchContent to right location in CMakeLists.txt * also added hash for googletest --------- Co-authored-by: Kevin De Keyser <kevin@dekeyser.ch> * Fix errors. * Check BluetoothAdapter role supported state and implement PeripheralManager on Flutter side. * Sort code * Fix known errors * interface-6.0.0-dev.19 * windows-6.0.0-dev.9 * Optimize example * android-6.0.0-dev.5 * Optimize the Adverrtisement BottomSheet. * linux-6.0.0-dev.3 * Update dependency * Fix example errors. * Temp commit. * darwin-6.0.0-dev.3 * 6.0.0-dev.2 * Update README.md * 6.0.0 * darwin-6.0.0-dev.4 * android-6.0.0-dev.6 * 6.0.0-dev.3 * Update docs. * interface-6.0.0 * android-6.0.0 * darwin-6.0.0 * linux-6.0.0 * windows-6.0.0 * 6.0.0 * Update dependency --------- Co-authored-by: Kevin De Keyser <dekeyser.kevin97@gmail.com> Co-authored-by: Kevin De Keyser <kevin@dekeyser.ch>
This commit is contained in:
38
bluetooth_low_energy_darwin/darwin/.gitignore
vendored
Normal file
38
bluetooth_low_energy_darwin/darwin/.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
.idea/
|
||||
.vagrant/
|
||||
.sconsign.dblite
|
||||
.svn/
|
||||
|
||||
.DS_Store
|
||||
*.swp
|
||||
profile
|
||||
|
||||
DerivedData/
|
||||
build/
|
||||
GeneratedPluginRegistrant.h
|
||||
GeneratedPluginRegistrant.m
|
||||
|
||||
.generated/
|
||||
|
||||
*.pbxuser
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.perspectivev3
|
||||
|
||||
!default.pbxuser
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.perspectivev3
|
||||
|
||||
xcuserdata
|
||||
|
||||
*.moved-aside
|
||||
|
||||
*.pyc
|
||||
*sync/
|
||||
Icon?
|
||||
.tags*
|
||||
|
||||
/Flutter/Generated.xcconfig
|
||||
/Flutter/ephemeral/
|
||||
/Flutter/flutter_export_environment.sh
|
0
bluetooth_low_energy_darwin/darwin/Assets/.gitkeep
Normal file
0
bluetooth_low_energy_darwin/darwin/Assets/.gitkeep
Normal file
@ -8,7 +8,7 @@ import FlutterMacOS
|
||||
#error("Unsupported platform.")
|
||||
#endif
|
||||
|
||||
public class BluetoothLowEnergyDarwin: NSObject, FlutterPlugin {
|
||||
public class BluetoothLowEnergyDarwinPlugin: NSObject, FlutterPlugin {
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
#if os(iOS)
|
||||
let messenger = registrar.messenger()
|
||||
@ -19,7 +19,7 @@ public class BluetoothLowEnergyDarwin: NSObject, FlutterPlugin {
|
||||
#endif
|
||||
let centralManager = MyCentralManager(messenger: messenger)
|
||||
let peripheralManager = MyPeripheralManager(messenger: messenger)
|
||||
MyCentralManagerHostApiSetup.setUp(binaryMessenger: messenger, api: centralManager)
|
||||
MyPeripheralManagerHostApiSetup.setUp(binaryMessenger: messenger, api: peripheralManager)
|
||||
MyCentralManagerHostAPISetup.setUp(binaryMessenger: messenger, api: centralManager)
|
||||
MyPeripheralManagerHostAPISetup.setUp(binaryMessenger: messenger, api: peripheralManager)
|
||||
}
|
||||
}
|
1352
bluetooth_low_energy_darwin/darwin/Classes/MyAPI.g.swift
Normal file
1352
bluetooth_low_energy_darwin/darwin/Classes/MyAPI.g.swift
Normal file
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ import FlutterMacOS
|
||||
#endif
|
||||
|
||||
// ToObj
|
||||
extension [MyGattCharacteristicPropertyArgs] {
|
||||
extension [MyGATTCharacteristicPropertyArgs] {
|
||||
func toProperties() -> CBCharacteristicProperties {
|
||||
var properties: CBCharacteristicProperties = []
|
||||
for args in self {
|
||||
@ -36,24 +36,28 @@ extension [MyGattCharacteristicPropertyArgs] {
|
||||
}
|
||||
return properties
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension [MyGATTCharacteristicPermissionArgs] {
|
||||
func toPermissions() -> CBAttributePermissions {
|
||||
var permissions: CBAttributePermissions = []
|
||||
for args in self {
|
||||
switch args {
|
||||
case .read:
|
||||
permissions.insert(.readable)
|
||||
case .write, .writeWithoutResponse:
|
||||
case .readEncrypted:
|
||||
permissions.insert(.readEncryptionRequired)
|
||||
case .write:
|
||||
permissions.insert(.writeable)
|
||||
default:
|
||||
continue
|
||||
case .writeEncrypted:
|
||||
permissions.insert(.writeEncryptionRequired)
|
||||
}
|
||||
}
|
||||
return permissions
|
||||
}
|
||||
}
|
||||
|
||||
extension MyGattCharacteristicWriteTypeArgs {
|
||||
extension MyGATTCharacteristicWriteTypeArgs {
|
||||
func toWriteType() -> CBCharacteristicWriteType {
|
||||
switch self {
|
||||
case .withResponse:
|
||||
@ -64,7 +68,7 @@ extension MyGattCharacteristicWriteTypeArgs {
|
||||
}
|
||||
}
|
||||
|
||||
extension MyGattErrorArgs {
|
||||
extension MyATTErrorArgs {
|
||||
func toError() -> CBATTError.Code {
|
||||
switch self {
|
||||
case .success:
|
||||
@ -116,22 +120,15 @@ extension MyAdvertisementArgs {
|
||||
let name = nameArgs!
|
||||
advertisement[CBAdvertisementDataLocalNameKey] = name
|
||||
}
|
||||
if serviceUUIDsArgs.count > 0 {
|
||||
var serviceUUIDs = [CBUUID]()
|
||||
for args in serviceUUIDsArgs {
|
||||
guard let uuidArgs = args else {
|
||||
continue
|
||||
}
|
||||
let uuid = uuidArgs.toCBUUID()
|
||||
serviceUUIDs.append(uuid)
|
||||
}
|
||||
if !serviceUUIDsArgs.isEmpty {
|
||||
let serviceUUIDs = serviceUUIDsArgs.map { serviceUUIDArgs in serviceUUIDArgs!.toCBUUID() }
|
||||
advertisement[CBAdvertisementDataServiceUUIDsKey] = serviceUUIDs
|
||||
}
|
||||
return advertisement
|
||||
}
|
||||
}
|
||||
|
||||
extension MyGattDescriptorArgs {
|
||||
extension MyMutableGATTDescriptorArgs {
|
||||
func toDescriptor() -> CBMutableDescriptor {
|
||||
let type = uuidArgs.toCBUUID()
|
||||
let value = valueArgs?.data
|
||||
@ -139,30 +136,28 @@ extension MyGattDescriptorArgs {
|
||||
}
|
||||
}
|
||||
|
||||
extension MyGattCharacteristicArgs {
|
||||
extension MyMutableGATTCharacteristicArgs {
|
||||
func toCharacteristic() -> CBMutableCharacteristic {
|
||||
let type = uuidArgs.toCBUUID()
|
||||
var propertiesArgs = [MyGattCharacteristicPropertyArgs]()
|
||||
for args in propertyNumbersArgs {
|
||||
guard let propertyNumberArgs = args else {
|
||||
continue
|
||||
}
|
||||
let propertyNumber = propertyNumberArgs.toInt()
|
||||
guard let propertyArgs = MyGattCharacteristicPropertyArgs(rawValue: propertyNumber) else {
|
||||
continue
|
||||
}
|
||||
propertiesArgs.append(propertyArgs)
|
||||
let propertiesArgs = propertyNumbersArgs.map { propertyNumberArgs in
|
||||
let propertyNumber = propertyNumberArgs!.toInt()
|
||||
return MyGATTCharacteristicPropertyArgs(rawValue: propertyNumber)!
|
||||
}
|
||||
let properties = propertiesArgs.toProperties()
|
||||
let permissions = propertiesArgs.toPermissions()
|
||||
return CBMutableCharacteristic(type: type, properties: properties, value: nil, permissions: permissions)
|
||||
let value = valueArgs?.data
|
||||
let permissionsArgs = permissionNumbersArgs.map { permissionNumberArgs in
|
||||
let permissionNumber = permissionNumberArgs!.toInt()
|
||||
return MyGATTCharacteristicPermissionArgs(rawValue: permissionNumber)!
|
||||
}
|
||||
let permissions = permissionsArgs.toPermissions()
|
||||
return CBMutableCharacteristic(type: type, properties: properties, value: value, permissions: permissions)
|
||||
}
|
||||
}
|
||||
|
||||
extension MyGattServiceArgs {
|
||||
extension MyMutableGATTServiceArgs {
|
||||
func toService() -> CBMutableService {
|
||||
let type = uuidArgs.toCBUUID()
|
||||
let primary = true
|
||||
let primary = isPrimaryArgs
|
||||
return CBMutableService(type: type, primary: primary)
|
||||
}
|
||||
}
|
||||
@ -199,19 +194,6 @@ extension CBManagerState {
|
||||
}
|
||||
}
|
||||
|
||||
extension Data {
|
||||
func toManufacturerSpecificDataArgs() -> MyManufacturerSpecificDataArgs? {
|
||||
if count > 2 {
|
||||
let idArgs = Int64(self[0]) | (Int64(self[1]) << 8)
|
||||
let data = self[2...count - 1]
|
||||
let dataArgs = FlutterStandardTypedData(bytes: data)
|
||||
return MyManufacturerSpecificDataArgs(idArgs: idArgs, dataArgs: dataArgs)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension [String: Any] {
|
||||
func toAdvertisementArgs() -> MyAdvertisementArgs {
|
||||
let nameArgs = self[CBAdvertisementDataLocalNameKey] as? String
|
||||
@ -224,8 +206,8 @@ extension [String: Any] {
|
||||
return (uuidArgs, dataArgs)
|
||||
}
|
||||
let serviceDataArgs = [String?: FlutterStandardTypedData?](uniqueKeysWithValues: serviceDataArgsKeyWithValues)
|
||||
let manufacturerSpecificData = self[CBAdvertisementDataManufacturerDataKey] as? Data
|
||||
let manufacturerSpecificDataArgs = manufacturerSpecificData?.toManufacturerSpecificDataArgs()
|
||||
let manufacturerData = self[CBAdvertisementDataManufacturerDataKey] as? Data
|
||||
let manufacturerSpecificDataArgs = manufacturerData == nil ? nil : FlutterStandardTypedData(bytes: manufacturerData!)
|
||||
return MyAdvertisementArgs(nameArgs: nameArgs, serviceUUIDsArgs: serviceUUIDsArgs, serviceDataArgs: serviceDataArgs, manufacturerSpecificDataArgs: manufacturerSpecificDataArgs)
|
||||
}
|
||||
}
|
||||
@ -245,26 +227,26 @@ extension CBPeripheral {
|
||||
}
|
||||
|
||||
extension CBDescriptor {
|
||||
func toArgs() -> MyGattDescriptorArgs {
|
||||
func toArgs() -> MyGATTDescriptorArgs {
|
||||
let hashCodeArgs = hash.toInt64()
|
||||
let uuidArgs = uuid.toArgs()
|
||||
return MyGattDescriptorArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs)
|
||||
return MyGATTDescriptorArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs)
|
||||
}
|
||||
}
|
||||
|
||||
extension CBCharacteristic {
|
||||
func toArgs() -> MyGattCharacteristicArgs {
|
||||
func toArgs() -> MyGATTCharacteristicArgs {
|
||||
let hashCodeArgs = hash.toInt64()
|
||||
let uuidArgs = uuid.toArgs()
|
||||
let propertyNumbersArgs = properties.toArgs().map { args in args.rawValue.toInt64() }
|
||||
let descriptorsArgs = descriptors?.map { descriptor in descriptor.toArgs() } ?? []
|
||||
return MyGattCharacteristicArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, propertyNumbersArgs: propertyNumbersArgs, descriptorsArgs: descriptorsArgs)
|
||||
return MyGATTCharacteristicArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, propertyNumbersArgs: propertyNumbersArgs, descriptorsArgs: descriptorsArgs)
|
||||
}
|
||||
}
|
||||
|
||||
extension CBCharacteristicProperties {
|
||||
func toArgs() -> [MyGattCharacteristicPropertyArgs] {
|
||||
var args = [MyGattCharacteristicPropertyArgs]()
|
||||
func toArgs() -> [MyGATTCharacteristicPropertyArgs] {
|
||||
var args = [MyGATTCharacteristicPropertyArgs]()
|
||||
if contains(.read) {
|
||||
args.append(.read)
|
||||
}
|
||||
@ -285,11 +267,13 @@ extension CBCharacteristicProperties {
|
||||
}
|
||||
|
||||
extension CBService {
|
||||
func toArgs() -> MyGattServiceArgs {
|
||||
func toArgs() -> MyGATTServiceArgs {
|
||||
let hashCodeArgs = hash.toInt64()
|
||||
let uuidArgs = uuid.toArgs()
|
||||
let isPrimaryArgs = isPrimary
|
||||
let includedServicesArgs = includedServices?.map { includedService in includedService.toArgs() } ?? []
|
||||
let characteristicsArgs = characteristics?.map { characteristic in characteristic.toArgs() } ?? []
|
||||
return MyGattServiceArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, characteristicsArgs: characteristicsArgs)
|
||||
return MyGATTServiceArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, isPrimaryArgs: isPrimaryArgs, includedServicesArgs: includedServicesArgs, characteristicsArgs: characteristicsArgs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,24 +295,9 @@ extension CBUUID {
|
||||
}
|
||||
}
|
||||
|
||||
// This extension of Error is required to do use FlutterError in any Swift code.
|
||||
extension FlutterError: Error {}
|
||||
|
||||
extension String {
|
||||
var data: Data { data(using: String.Encoding.utf8)! }
|
||||
}
|
||||
|
||||
extension NSNumber {
|
||||
var data: Data {
|
||||
var source = self
|
||||
// TODO: resolve warning: Forming 'UnsafeRawPointer' to a variable of type 'NSNumber'; this is likely incorrect because 'NSNumber' may contain an object reference.
|
||||
return Data(bytes: &source, count: MemoryLayout<NSNumber>.size)
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt16 {
|
||||
var data: Data {
|
||||
var source = self
|
||||
return Data(bytes: &source, count: MemoryLayout<UInt16>.size)
|
||||
var bytes = self
|
||||
return Data(bytes: &bytes, count: MemoryLayout<UInt16>.size)
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -16,76 +16,142 @@ import FlutterMacOS
|
||||
#error("Unsupported platform.")
|
||||
#endif
|
||||
|
||||
class MyCentralManager: MyCentralManagerHostApi {
|
||||
private let _api: MyCentralManagerFlutterApi
|
||||
private let _centralManager: CBCentralManager
|
||||
class MyCentralManager: MyCentralManagerHostAPI {
|
||||
private let mAPI: MyCentralManagerFlutterAPI
|
||||
private let mCentralManager: CBCentralManager
|
||||
|
||||
private lazy var _centralManagerDelegate = MyCentralManagerDelegate(centralManager: self)
|
||||
private lazy var _peripheralDelegate = MyPeripheralDelegate(centralManager: self)
|
||||
private lazy var mCentralManagerDelegate = MyCentralManagerDelegate(centralManager: self)
|
||||
private lazy var peripheralDelegate = MyPeripheralDelegate(centralManager: self)
|
||||
|
||||
private var _peripherals: [String: CBPeripheral]
|
||||
private var _services: [String: [Int64: CBService]]
|
||||
private var _characteristics: [String: [Int64: CBCharacteristic]]
|
||||
private var _descriptors: [String: [Int64: CBDescriptor]]
|
||||
private var mPeripherals: [String: CBPeripheral]
|
||||
private var mServices: [String: [Int64: CBService]]
|
||||
private var mCharacteristics: [String: [Int64: CBCharacteristic]]
|
||||
private var mDescriptors: [String: [Int64: CBDescriptor]]
|
||||
|
||||
private var _connectCompletions: [String: (Result<Void, Error>) -> Void]
|
||||
private var _disconnectCompletions: [String: (Result<Void, Error>) -> Void]
|
||||
private var _readRssiCompletions: [String: (Result<Int64, Error>) -> Void]
|
||||
private var _discoverServicesCompletions: [String: (Result<[MyGattServiceArgs], Error>) -> Void]
|
||||
private var _discoverCharacteristicsCompletions: [String: [Int64: (Result<[MyGattCharacteristicArgs], Error>) -> Void]]
|
||||
private var _discoverDescriptorsCompletions: [String: [Int64: (Result<[MyGattDescriptorArgs], Error>) -> Void]]
|
||||
private var _readCharacteristicCompletions: [String: [Int64: (Result<FlutterStandardTypedData, Error>) -> Void]]
|
||||
private var _writeCharacteristicCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
|
||||
private var _setCharacteristicNotifyStateCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
|
||||
private var _readDescriptorCompletions: [String: [Int64: (Result<FlutterStandardTypedData, Error>) -> Void]]
|
||||
private var _writeDescriptorCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
|
||||
private var mConnectCompletions: [String: (Result<Void, Error>) -> Void]
|
||||
private var mDisconnectCompletions: [String: (Result<Void, Error>) -> Void]
|
||||
private var mReadRSSICompletions: [String: (Result<Int64, Error>) -> Void]
|
||||
private var mDiscoverServicesCompletions: [String: (Result<[MyGATTServiceArgs], Error>) -> Void]
|
||||
private var mDiscoverIncludedServicesCompletions: [String: [Int64: (Result<[MyGATTServiceArgs], Error>) -> Void]]
|
||||
private var mDiscoverCharacteristicsCompletions: [String: [Int64: (Result<[MyGATTCharacteristicArgs], Error>) -> Void]]
|
||||
private var mDiscoverDescriptorsCompletions: [String: [Int64: (Result<[MyGATTDescriptorArgs], Error>) -> Void]]
|
||||
private var mReadCharacteristicCompletions: [String: [Int64: (Result<FlutterStandardTypedData, Error>) -> Void]]
|
||||
private var mWriteCharacteristicCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
|
||||
private var mSetCharacteristicNotifyStateCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
|
||||
private var mReadDescriptorCompletions: [String: [Int64: (Result<FlutterStandardTypedData, Error>) -> Void]]
|
||||
private var mWriteDescriptorCompletions: [String: [Int64: (Result<Void, Error>) -> Void]]
|
||||
|
||||
init(messenger: FlutterBinaryMessenger) {
|
||||
_api = MyCentralManagerFlutterApi(binaryMessenger: messenger)
|
||||
_centralManager = CBCentralManager()
|
||||
mAPI = MyCentralManagerFlutterAPI(binaryMessenger: messenger)
|
||||
mCentralManager = CBCentralManager()
|
||||
|
||||
_peripherals = [:]
|
||||
_services = [:]
|
||||
_characteristics = [:]
|
||||
_descriptors = [:]
|
||||
mPeripherals = [:]
|
||||
mServices = [:]
|
||||
mCharacteristics = [:]
|
||||
mDescriptors = [:]
|
||||
|
||||
_connectCompletions = [:]
|
||||
_disconnectCompletions = [:]
|
||||
_readRssiCompletions = [:]
|
||||
_discoverServicesCompletions = [:]
|
||||
_discoverCharacteristicsCompletions = [:]
|
||||
_discoverDescriptorsCompletions = [:]
|
||||
_readCharacteristicCompletions = [:]
|
||||
_writeCharacteristicCompletions = [:]
|
||||
_setCharacteristicNotifyStateCompletions = [:]
|
||||
_readDescriptorCompletions = [:]
|
||||
_writeDescriptorCompletions = [:]
|
||||
mConnectCompletions = [:]
|
||||
mDisconnectCompletions = [:]
|
||||
mReadRSSICompletions = [:]
|
||||
mDiscoverServicesCompletions = [:]
|
||||
mDiscoverIncludedServicesCompletions = [:]
|
||||
mDiscoverCharacteristicsCompletions = [:]
|
||||
mDiscoverDescriptorsCompletions = [:]
|
||||
mReadCharacteristicCompletions = [:]
|
||||
mWriteCharacteristicCompletions = [:]
|
||||
mSetCharacteristicNotifyStateCompletions = [:]
|
||||
mReadDescriptorCompletions = [:]
|
||||
mWriteDescriptorCompletions = [:]
|
||||
}
|
||||
|
||||
func setUp() throws {
|
||||
_clearState()
|
||||
if _centralManager.delegate == nil {
|
||||
_centralManager.delegate = _centralManagerDelegate
|
||||
func initialize() throws {
|
||||
if(mCentralManager.isScanning) {
|
||||
mCentralManager.stopScan()
|
||||
}
|
||||
didUpdateState(central: _centralManager)
|
||||
|
||||
for peripheral in mPeripherals.values {
|
||||
if peripheral.state != .disconnected {
|
||||
mCentralManager.cancelPeripheralConnection(peripheral)
|
||||
}
|
||||
}
|
||||
|
||||
mPeripherals.removeAll()
|
||||
mServices.removeAll()
|
||||
mCharacteristics.removeAll()
|
||||
mDescriptors.removeAll()
|
||||
|
||||
mConnectCompletions.removeAll()
|
||||
mDisconnectCompletions.removeAll()
|
||||
mReadRSSICompletions.removeAll()
|
||||
mDiscoverServicesCompletions.removeAll()
|
||||
mDiscoverIncludedServicesCompletions.removeAll()
|
||||
mDiscoverCharacteristicsCompletions.removeAll()
|
||||
mDiscoverDescriptorsCompletions.removeAll()
|
||||
mReadCharacteristicCompletions.removeAll()
|
||||
mWriteCharacteristicCompletions.removeAll()
|
||||
mSetCharacteristicNotifyStateCompletions.removeAll()
|
||||
mReadDescriptorCompletions.removeAll()
|
||||
mWriteDescriptorCompletions.removeAll()
|
||||
|
||||
mCentralManager.delegate = mCentralManagerDelegate
|
||||
}
|
||||
|
||||
func startDiscovery() throws {
|
||||
func getState() throws -> MyBluetoothLowEnergyStateArgs {
|
||||
let state = mCentralManager.state
|
||||
let stateArgs = state.toArgs()
|
||||
return stateArgs
|
||||
}
|
||||
|
||||
func showAppSettings(completion: @escaping (Result<Void, any Error>) -> Void) {
|
||||
#if os(iOS)
|
||||
do {
|
||||
guard let url = URL(string: UIApplication.openSettingsURLString) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
UIApplication.shared.open(url) { success in
|
||||
if (success) {
|
||||
completion(.success(()))
|
||||
} else {
|
||||
completion(.failure(MyError.unknown))
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
#else
|
||||
completion(.failure(MyError.unsupported))
|
||||
#endif
|
||||
}
|
||||
|
||||
func startDiscovery(serviceUUIDsArgs: [String]) throws {
|
||||
let serviceUUIDs = serviceUUIDsArgs.isEmpty ? nil : serviceUUIDsArgs.map { serviceUUIDArgs in serviceUUIDArgs.toCBUUID() }
|
||||
let options = [CBCentralManagerScanOptionAllowDuplicatesKey: true]
|
||||
_centralManager.scanForPeripherals(withServices: nil, options: options)
|
||||
mCentralManager.scanForPeripherals(withServices: serviceUUIDs, options: options)
|
||||
}
|
||||
|
||||
func stopDiscovery() throws {
|
||||
_centralManager.stopScan()
|
||||
mCentralManager.stopScan()
|
||||
}
|
||||
|
||||
func retrieveConnectedPeripherals() throws -> [MyPeripheralArgs] {
|
||||
let peripherals = mCentralManager.retrieveConnectedPeripherals(withServices: [])
|
||||
let peripheralsArgs = peripherals.map { peripheral in
|
||||
let peripheralArgs = peripheral.toArgs()
|
||||
let uuidArgs = peripheralArgs.uuidArgs
|
||||
if peripheral.delegate == nil {
|
||||
peripheral.delegate = peripheralDelegate
|
||||
}
|
||||
self.mPeripherals[uuidArgs] = peripheral
|
||||
return peripheralArgs
|
||||
}
|
||||
return peripheralsArgs
|
||||
}
|
||||
|
||||
func connect(uuidArgs: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
_centralManager.connect(peripheral)
|
||||
_connectCompletions[uuidArgs] = completion
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
mCentralManager.connect(peripheral)
|
||||
mConnectCompletions[uuidArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
@ -93,79 +159,70 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
|
||||
func disconnect(uuidArgs: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
_centralManager.cancelPeripheralConnection(peripheral)
|
||||
_disconnectCompletions[uuidArgs] = completion
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
mCentralManager.cancelPeripheralConnection(peripheral)
|
||||
mDisconnectCompletions[uuidArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
func getMaximumWriteValueLength(uuidArgs: String, typeNumberArgs: Int64) throws -> Int64 {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let typeNumber = typeNumberArgs.toInt()
|
||||
guard let typeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: typeNumber) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
func getMaximumWriteLength(uuidArgs: String, typeArgs: MyGATTCharacteristicWriteTypeArgs) throws -> Int64 {
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let type = typeArgs.toWriteType()
|
||||
let maximumWriteValueLength = peripheral.maximumWriteValueLength(for: type)
|
||||
let maximumWriteValueLengthArgs = maximumWriteValueLength.toInt64()
|
||||
return maximumWriteValueLengthArgs
|
||||
let maximumWriteLength = peripheral.maximumWriteValueLength(for: type)
|
||||
let maximumWriteLengthArgs = maximumWriteLength.toInt64()
|
||||
return maximumWriteLengthArgs
|
||||
}
|
||||
|
||||
func readRSSI(uuidArgs: String, completion: @escaping (Result<Int64, Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
peripheral.readRSSI()
|
||||
_readRssiCompletions[uuidArgs] = completion
|
||||
mReadRSSICompletions[uuidArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
func discoverServices(uuidArgs: String, completion: @escaping (Result<[MyGattServiceArgs], Error>) -> Void) {
|
||||
func discoverServices(uuidArgs: String, completion: @escaping (Result<[MyGATTServiceArgs], Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
peripheral.discoverServices(nil)
|
||||
_discoverServicesCompletions[uuidArgs] = completion
|
||||
mDiscoverServicesCompletions[uuidArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
func discoverCharacteristics(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGattCharacteristicArgs], Error>) -> Void) {
|
||||
func discoverIncludedServices(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGATTServiceArgs], Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let service = _retrieveService(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let service = try retrieveService(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs)
|
||||
peripheral.discoverIncludedServices(nil, for: service)
|
||||
mDiscoverIncludedServicesCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
func discoverCharacteristics(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGATTCharacteristicArgs], Error>) -> Void) {
|
||||
do {
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let service = try retrieveService(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs)
|
||||
peripheral.discoverCharacteristics(nil, for: service)
|
||||
_discoverCharacteristicsCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
mDiscoverCharacteristicsCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
func discoverDescriptors(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGattDescriptorArgs], Error>) -> Void){
|
||||
func discoverDescriptors(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGATTDescriptorArgs], Error>) -> Void){
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let characteristic = try retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs)
|
||||
peripheral.discoverDescriptors(for: characteristic)
|
||||
_discoverDescriptorsCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
mDiscoverDescriptorsCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
@ -173,36 +230,24 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
|
||||
func readCharacteristic(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let characteristic = try retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs)
|
||||
peripheral.readValue(for: characteristic)
|
||||
_readCharacteristicCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
mReadCharacteristicCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
func writeCharacteristic(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, typeNumberArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func writeCharacteristic(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, typeArgs: MyGATTCharacteristicWriteTypeArgs, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let characteristic = try retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs)
|
||||
let data = valueArgs.data
|
||||
let typeNumber = typeNumberArgs.toInt()
|
||||
guard let typeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: typeNumber) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let type = typeArgs.toWriteType()
|
||||
peripheral.writeValue(data, for: characteristic, type: type)
|
||||
if type == .withResponse {
|
||||
_writeCharacteristicCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
mWriteCharacteristicCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
} else {
|
||||
completion(.success(()))
|
||||
}
|
||||
@ -213,15 +258,11 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
|
||||
func setCharacteristicNotifyState(uuidArgs: String, hashCodeArgs: Int64, stateArgs: Bool, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let characteristic = try retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs)
|
||||
let enabled = stateArgs
|
||||
peripheral.setNotifyValue(enabled, for: characteristic)
|
||||
_setCharacteristicNotifyStateCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
mSetCharacteristicNotifyStateCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
@ -229,14 +270,10 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
|
||||
func readDescriptor(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let descriptor = _retrieveDescriptor(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let descriptor = try retrieveDescriptor(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs)
|
||||
peripheral.readValue(for: descriptor)
|
||||
_readDescriptorCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
mReadDescriptorCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
@ -244,15 +281,11 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
|
||||
func writeDescriptor(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
guard let peripheral = _peripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let descriptor = _retrieveDescriptor(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let peripheral = try retrievePeripheral(uuidArgs: uuidArgs)
|
||||
let descriptor = try retrieveDescriptor(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs)
|
||||
let data = valueArgs.data
|
||||
peripheral.writeValue(data, for: descriptor)
|
||||
_writeDescriptorCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
mWriteDescriptorCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
@ -261,8 +294,7 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
func didUpdateState(central: CBCentralManager) {
|
||||
let state = central.state
|
||||
let stateArgs = state.toArgs()
|
||||
let stateNumberArgs = stateArgs.rawValue.toInt64()
|
||||
_api.onStateChanged(stateNumberArgs: stateNumberArgs) {_ in }
|
||||
mAPI.onStateChanged(stateArgs: stateArgs) { _ in }
|
||||
}
|
||||
|
||||
func didDiscover(central: CBCentralManager, peripheral: CBPeripheral, advertisementData: [String : Any], rssi: NSNumber) {
|
||||
@ -271,17 +303,18 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
let rssiArgs = rssi.int64Value
|
||||
let advertisementArgs = advertisementData.toAdvertisementArgs()
|
||||
if peripheral.delegate == nil {
|
||||
peripheral.delegate = _peripheralDelegate
|
||||
peripheral.delegate = peripheralDelegate
|
||||
}
|
||||
_peripherals[uuidArgs] = peripheral
|
||||
_api.onDiscovered(peripheralArgs: peripheralArgs, rssiArgs: rssiArgs, advertisementArgs: advertisementArgs) {_ in }
|
||||
mPeripherals[uuidArgs] = peripheral
|
||||
mAPI.onDiscovered(peripheralArgs: peripheralArgs, rssiArgs: rssiArgs, advertisementArgs: advertisementArgs) {_ in }
|
||||
}
|
||||
|
||||
func didConnect(central: CBCentralManager, peripheral: CBPeripheral) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let stateArgs = true
|
||||
_api.onConnectionStateChanged(uuidArgs: uuidArgs, stateArgs: stateArgs) {_ in }
|
||||
guard let completion = _connectCompletions.removeValue(forKey: uuidArgs) else {
|
||||
let peripheralArgs = peripheral.toArgs()
|
||||
let uuidArgs = peripheralArgs.uuidArgs
|
||||
let stateArgs = MyConnectionStateArgs.connected
|
||||
mAPI.onConnectionStateChanged(peripheralArgs: peripheralArgs, stateArgs: stateArgs) { _ in }
|
||||
guard let completion = mConnectCompletions.removeValue(forKey: uuidArgs) else {
|
||||
return
|
||||
}
|
||||
completion(.success(()))
|
||||
@ -289,74 +322,82 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
|
||||
func didFailToConnect(central: CBCentralManager, peripheral: CBPeripheral, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
guard let completion = _connectCompletions.removeValue(forKey: uuidArgs) else {
|
||||
guard let completion = mConnectCompletions.removeValue(forKey: uuidArgs) else {
|
||||
return
|
||||
}
|
||||
completion(.failure(error ?? MyError.unknown))
|
||||
}
|
||||
|
||||
func didDisconnectPeripheral(central: CBCentralManager, peripheral: CBPeripheral, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
_services.removeValue(forKey: uuidArgs)
|
||||
_characteristics.removeValue(forKey: uuidArgs)
|
||||
_descriptors.removeValue(forKey: uuidArgs)
|
||||
let peripheralArgs = peripheral.toArgs()
|
||||
let uuidArgs = peripheralArgs.uuidArgs
|
||||
mServices.removeValue(forKey: uuidArgs)
|
||||
mCharacteristics.removeValue(forKey: uuidArgs)
|
||||
mDescriptors.removeValue(forKey: uuidArgs)
|
||||
let errorNotNil = error ?? MyError.unknown
|
||||
let readRssiCompletion = _readRssiCompletions.removeValue(forKey: uuidArgs)
|
||||
let readRssiCompletion = mReadRSSICompletions.removeValue(forKey: uuidArgs)
|
||||
readRssiCompletion?(.failure(errorNotNil))
|
||||
let discoverServicesCompletion = _discoverServicesCompletions.removeValue(forKey: uuidArgs)
|
||||
let discoverServicesCompletion = mDiscoverServicesCompletions.removeValue(forKey: uuidArgs)
|
||||
discoverServicesCompletion?(.failure(errorNotNil))
|
||||
let discoverCharacteristicsCompletions = _discoverCharacteristicsCompletions.removeValue(forKey: uuidArgs)
|
||||
let discoverIncludedServicesCompletions = self.mDiscoverIncludedServicesCompletions.removeValue(forKey: uuidArgs)
|
||||
if discoverIncludedServicesCompletions != nil {
|
||||
let completions = discoverIncludedServicesCompletions!.values
|
||||
for completion in completions {
|
||||
completion(.failure(errorNotNil))
|
||||
}
|
||||
}
|
||||
let discoverCharacteristicsCompletions = self.mDiscoverCharacteristicsCompletions.removeValue(forKey: uuidArgs)
|
||||
if discoverCharacteristicsCompletions != nil {
|
||||
let completions = discoverCharacteristicsCompletions!.values
|
||||
for completion in completions {
|
||||
completion(.failure(errorNotNil))
|
||||
}
|
||||
}
|
||||
let discoverDescriptorsCompletions = _discoverDescriptorsCompletions.removeValue(forKey: uuidArgs)
|
||||
let discoverDescriptorsCompletions = self.mDiscoverDescriptorsCompletions.removeValue(forKey: uuidArgs)
|
||||
if discoverDescriptorsCompletions != nil {
|
||||
let completions = discoverDescriptorsCompletions!.values
|
||||
for completion in completions {
|
||||
completion(.failure(errorNotNil))
|
||||
}
|
||||
}
|
||||
let readCharacteristicCompletions = _readCharacteristicCompletions.removeValue(forKey: uuidArgs)
|
||||
let readCharacteristicCompletions = self.mReadCharacteristicCompletions.removeValue(forKey: uuidArgs)
|
||||
if readCharacteristicCompletions != nil {
|
||||
let completions = readCharacteristicCompletions!.values
|
||||
for completion in completions {
|
||||
completion(.failure(errorNotNil))
|
||||
}
|
||||
}
|
||||
let writeCharacteristicCompletions = _writeCharacteristicCompletions.removeValue(forKey: uuidArgs)
|
||||
let writeCharacteristicCompletions = self.mWriteCharacteristicCompletions.removeValue(forKey: uuidArgs)
|
||||
if writeCharacteristicCompletions != nil {
|
||||
let completions = writeCharacteristicCompletions!.values
|
||||
for completion in completions {
|
||||
completion(.failure(errorNotNil))
|
||||
}
|
||||
}
|
||||
let notifyCharacteristicCompletions = _setCharacteristicNotifyStateCompletions.removeValue(forKey: uuidArgs)
|
||||
let notifyCharacteristicCompletions = self.mSetCharacteristicNotifyStateCompletions.removeValue(forKey: uuidArgs)
|
||||
if notifyCharacteristicCompletions != nil {
|
||||
let completions = notifyCharacteristicCompletions!.values
|
||||
for completioin in completions {
|
||||
completioin(.failure(errorNotNil))
|
||||
}
|
||||
}
|
||||
let readDescriptorCompletions = _readDescriptorCompletions.removeValue(forKey: uuidArgs)
|
||||
let readDescriptorCompletions = self.mReadDescriptorCompletions.removeValue(forKey: uuidArgs)
|
||||
if readDescriptorCompletions != nil {
|
||||
let completions = readDescriptorCompletions!.values
|
||||
for completioin in completions {
|
||||
completioin(.failure(errorNotNil))
|
||||
}
|
||||
}
|
||||
let writeDescriptorCompletions = _writeDescriptorCompletions.removeValue(forKey: uuidArgs)
|
||||
let writeDescriptorCompletions = self.mWriteDescriptorCompletions.removeValue(forKey: uuidArgs)
|
||||
if writeDescriptorCompletions != nil {
|
||||
let completions = writeDescriptorCompletions!.values
|
||||
for completion in completions {
|
||||
completion(.failure(errorNotNil))
|
||||
}
|
||||
}
|
||||
let stateArgs = false
|
||||
_api.onConnectionStateChanged(uuidArgs: uuidArgs, stateArgs: stateArgs) {_ in }
|
||||
guard let completion = _disconnectCompletions.removeValue(forKey: uuidArgs) else {
|
||||
let stateArgs = MyConnectionStateArgs.disconnected
|
||||
mAPI.onConnectionStateChanged(peripheralArgs: peripheralArgs, stateArgs: stateArgs) { _ in }
|
||||
guard let completion = mDisconnectCompletions.removeValue(forKey: uuidArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
@ -368,7 +409,7 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
|
||||
func didReadRSSI(peripheral: CBPeripheral, rssi: NSNumber, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
guard let completion = _readRssiCompletions.removeValue(forKey: uuidArgs) else {
|
||||
guard let completion = mReadRSSICompletions.removeValue(forKey: uuidArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
@ -381,37 +422,57 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
|
||||
func didDiscoverServices(peripheral: CBPeripheral, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
guard let completion = _discoverServicesCompletions.removeValue(forKey: uuidArgs) else {
|
||||
guard let completion = mDiscoverServicesCompletions.removeValue(forKey: uuidArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
let services = peripheral.services ?? []
|
||||
let servicesArgs = services.map { service in service.toArgs() }
|
||||
let values = services.flatMap { service in
|
||||
let hashCodeArgs = service.hash.toInt64()
|
||||
return [hashCodeArgs: service]
|
||||
var servicesArgs = [MyGATTServiceArgs]()
|
||||
for service in services {
|
||||
let serviceArgs = service.toArgs()
|
||||
self.mServices[uuidArgs, default: [:]][serviceArgs.hashCodeArgs] = service
|
||||
servicesArgs.append(serviceArgs)
|
||||
}
|
||||
_services[uuidArgs] = Dictionary(uniqueKeysWithValues: values)
|
||||
completion(.success(servicesArgs))
|
||||
} else {
|
||||
completion(.failure(error!))
|
||||
}
|
||||
}
|
||||
|
||||
func didDiscoverIncludedServices(peripheral: CBPeripheral, service: CBService, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let hashCodeArgs = service.hash.toInt64()
|
||||
guard let completion = mDiscoverIncludedServicesCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
let includedServices = service.includedServices ?? []
|
||||
var includedServicesArgs = [MyGATTServiceArgs]()
|
||||
for includedService in includedServices {
|
||||
let includedServiceArgs = includedService.toArgs()
|
||||
self.mServices[uuidArgs, default: [:]][includedServiceArgs.hashCodeArgs] = includedService
|
||||
includedServicesArgs.append(includedServiceArgs)
|
||||
}
|
||||
completion(.success(includedServicesArgs))
|
||||
} else {
|
||||
completion(.failure(error!))
|
||||
}
|
||||
}
|
||||
|
||||
func didDiscoverCharacteristics(peripheral: CBPeripheral, service: CBService, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let hashCodeArgs = service.hash.toInt64()
|
||||
guard let completion = _discoverCharacteristicsCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
guard let completion = mDiscoverCharacteristicsCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
let characteristics = service.characteristics ?? []
|
||||
let characteristicsArgs = characteristics.map { characteristic in characteristic.toArgs() }
|
||||
let values = characteristics.flatMap { characteristic in
|
||||
let hashCodeArgs = characteristic.hash.toInt64()
|
||||
return [hashCodeArgs: characteristic]
|
||||
var characteristicsArgs = [MyGATTCharacteristicArgs]()
|
||||
for characteristic in characteristics {
|
||||
let characteristicArgs = characteristic.toArgs()
|
||||
self.mCharacteristics[uuidArgs, default: [:]][characteristicArgs.hashCodeArgs] = characteristic
|
||||
characteristicsArgs.append(characteristicArgs)
|
||||
}
|
||||
_characteristics[uuidArgs, default: [:]].merge(values) { value1, value2 in value2 }
|
||||
completion(.success(characteristicsArgs))
|
||||
} else {
|
||||
completion(.failure(error!))
|
||||
@ -421,17 +482,17 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
func didDiscoverDescriptors(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let hashCodeArgs = characteristic.hash.toInt64()
|
||||
guard let completion = _discoverDescriptorsCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
guard let completion = mDiscoverDescriptorsCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
let descriptors = characteristic.descriptors ?? []
|
||||
let descriptorsArgs = descriptors.map { descriptor in descriptor.toArgs() }
|
||||
let values = descriptors.flatMap { descriptor in
|
||||
let hashCodeArgs = descriptor.hash.toInt64()
|
||||
return [hashCodeArgs: descriptor]
|
||||
var descriptorsArgs = [MyGATTDescriptorArgs]()
|
||||
for descriptor in descriptors {
|
||||
let descriptorArgs = descriptor.toArgs()
|
||||
self.mDescriptors[uuidArgs, default: [:]][descriptorArgs.hashCodeArgs] = descriptor
|
||||
descriptorsArgs.append(descriptorArgs)
|
||||
}
|
||||
_descriptors[uuidArgs, default: [:]].merge(values) { value1, value2 in value2 }
|
||||
completion(.success(descriptorsArgs))
|
||||
} else {
|
||||
completion(.failure(error!))
|
||||
@ -439,12 +500,14 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
}
|
||||
|
||||
func didUpdateCharacteristicValue(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let hashCodeArgs = characteristic.hash.toInt64()
|
||||
let peripheralArgs = peripheral.toArgs()
|
||||
let uuidArgs = peripheralArgs.uuidArgs
|
||||
let characteristicArgs = characteristic.toArgs()
|
||||
let hashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
let value = characteristic.value ?? Data()
|
||||
let valueArgs = FlutterStandardTypedData(bytes: value)
|
||||
guard let completion = _readCharacteristicCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
_api.onCharacteristicNotified(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs, valueArgs: valueArgs) {_ in }
|
||||
guard let completion = mReadCharacteristicCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
mAPI.onCharacteristicNotified(peripheralArgs: peripheralArgs, characteristicArgs: characteristicArgs, valueArgs: valueArgs) { _ in }
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
@ -457,7 +520,7 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
func didWriteCharacteristicValue(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let hashCodeArgs = characteristic.hash.toInt64()
|
||||
guard let completion = _writeCharacteristicCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
guard let completion = mWriteCharacteristicCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
@ -470,7 +533,7 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
func didUpdateCharacteristicNotificationState(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let hashCodeArgs = characteristic.hash.toInt64()
|
||||
guard let completion = _setCharacteristicNotifyStateCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
guard let completion = mSetCharacteristicNotifyStateCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
@ -483,45 +546,24 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
func didUpdateDescriptorValue(peripheral: CBPeripheral, descriptor: CBDescriptor, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let hashCodeArgs = descriptor.hash.toInt64()
|
||||
guard let completion = _readDescriptorCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
guard let completion = mReadDescriptorCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
// TODO: confirm the corresponding descriptor types and values are correct.
|
||||
let valueArgs: FlutterStandardTypedData
|
||||
let value = descriptor.value
|
||||
do {
|
||||
switch descriptor.uuid.uuidString {
|
||||
case CBUUIDCharacteristicExtendedPropertiesString:
|
||||
fallthrough
|
||||
case CBUUIDClientCharacteristicConfigurationString:
|
||||
fallthrough
|
||||
case CBUUIDServerCharacteristicConfigurationString:
|
||||
guard let numberValue = value as? NSNumber else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
valueArgs = FlutterStandardTypedData(bytes: numberValue.data)
|
||||
case CBUUIDCharacteristicUserDescriptionString:
|
||||
fallthrough
|
||||
case CBUUIDCharacteristicAggregateFormatString:
|
||||
guard let stringValue = value as? String else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
valueArgs = FlutterStandardTypedData(bytes: stringValue.data)
|
||||
case CBUUIDCharacteristicFormatString:
|
||||
guard let bytes = value as? Data else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
valueArgs = FlutterStandardTypedData(bytes: bytes)
|
||||
case CBUUIDL2CAPPSMCharacteristicString:
|
||||
guard let uint16Value = value as? UInt16 else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
valueArgs = FlutterStandardTypedData(bytes: uint16Value.data)
|
||||
default:
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
} catch {
|
||||
switch descriptor.value {
|
||||
case let bytes as Data:
|
||||
valueArgs = FlutterStandardTypedData(bytes: bytes)
|
||||
case let value as String:
|
||||
let bytes = value.data(using: .utf8) ?? Data()
|
||||
valueArgs = FlutterStandardTypedData(bytes: bytes)
|
||||
case let value as UInt16:
|
||||
let bytes = value.data
|
||||
valueArgs = FlutterStandardTypedData(bytes: bytes)
|
||||
case let value as NSNumber:
|
||||
let bytes = withUnsafeBytes(of: value) { elements in Data(elements) }
|
||||
valueArgs = FlutterStandardTypedData(bytes: bytes)
|
||||
default:
|
||||
valueArgs = FlutterStandardTypedData()
|
||||
}
|
||||
completion(.success((valueArgs)))
|
||||
@ -533,7 +575,7 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
func didWriteDescriptorValue(peripheral: CBPeripheral, descriptor: CBDescriptor, error: Error?) {
|
||||
let uuidArgs = peripheral.identifier.toArgs()
|
||||
let hashCodeArgs = descriptor.hash.toInt64()
|
||||
guard let completion = _writeDescriptorCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
guard let completion = mWriteDescriptorCompletions[uuidArgs]?.removeValue(forKey: hashCodeArgs) else {
|
||||
return
|
||||
}
|
||||
if error == nil {
|
||||
@ -543,52 +585,40 @@ class MyCentralManager: MyCentralManagerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
private func _clearState() {
|
||||
if(_centralManager.isScanning) {
|
||||
_centralManager.stopScan()
|
||||
private func retrievePeripheral(uuidArgs: String) throws -> CBPeripheral {
|
||||
guard let peripheral = mPeripherals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
for peripheral in _peripherals.values {
|
||||
if peripheral.state != .disconnected {
|
||||
_centralManager.cancelPeripheralConnection(peripheral)
|
||||
}
|
||||
}
|
||||
|
||||
_peripherals.removeAll()
|
||||
_services.removeAll()
|
||||
_characteristics.removeAll()
|
||||
_descriptors.removeAll()
|
||||
|
||||
_connectCompletions.removeAll()
|
||||
_disconnectCompletions.removeAll()
|
||||
_readRssiCompletions.removeAll()
|
||||
_discoverServicesCompletions.removeAll()
|
||||
_discoverCharacteristicsCompletions.removeAll()
|
||||
_discoverDescriptorsCompletions.removeAll()
|
||||
_readCharacteristicCompletions.removeAll()
|
||||
_writeCharacteristicCompletions.removeAll()
|
||||
_setCharacteristicNotifyStateCompletions.removeAll()
|
||||
_readDescriptorCompletions.removeAll()
|
||||
_writeDescriptorCompletions.removeAll()
|
||||
return peripheral
|
||||
}
|
||||
|
||||
private func _retrieveService(uuidArgs: String, hashCodeArgs: Int64) -> CBService? {
|
||||
guard let services = _services[uuidArgs] else {
|
||||
return nil
|
||||
private func retrieveService(uuidArgs: String, hashCodeArgs: Int64) throws -> CBService {
|
||||
guard let services = self.mServices[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
return services[hashCodeArgs]
|
||||
guard let service = services[hashCodeArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
return service
|
||||
}
|
||||
|
||||
private func _retrieveCharacteristic(uuidArgs: String, hashCodeArgs: Int64) -> CBCharacteristic? {
|
||||
guard let characteristics = _characteristics[uuidArgs] else {
|
||||
return nil
|
||||
private func retrieveCharacteristic(uuidArgs: String, hashCodeArgs: Int64) throws -> CBCharacteristic {
|
||||
guard let characteristics = self.mCharacteristics[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
return characteristics[hashCodeArgs]
|
||||
guard let characteristic = characteristics[hashCodeArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
return characteristic
|
||||
}
|
||||
|
||||
private func _retrieveDescriptor(uuidArgs: String, hashCodeArgs: Int64) -> CBDescriptor? {
|
||||
guard let descriptors = _descriptors[uuidArgs] else {
|
||||
return nil
|
||||
private func retrieveDescriptor(uuidArgs: String, hashCodeArgs: Int64) throws -> CBDescriptor {
|
||||
guard let descriptors = self.mDescriptors[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
return descriptors[hashCodeArgs]
|
||||
guard let descriptor = descriptors[hashCodeArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
return descriptor
|
||||
}
|
||||
}
|
||||
|
@ -9,29 +9,29 @@ import Foundation
|
||||
import CoreBluetooth
|
||||
|
||||
class MyCentralManagerDelegate: NSObject, CBCentralManagerDelegate {
|
||||
private let _centralManager: MyCentralManager
|
||||
private let mCentralManager: MyCentralManager
|
||||
|
||||
init(centralManager: MyCentralManager) {
|
||||
_centralManager = centralManager
|
||||
self.mCentralManager = centralManager
|
||||
}
|
||||
|
||||
func centralManagerDidUpdateState(_ central: CBCentralManager) {
|
||||
_centralManager.didUpdateState(central: central)
|
||||
mCentralManager.didUpdateState(central: central)
|
||||
}
|
||||
|
||||
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
|
||||
_centralManager.didDiscover(central: central, peripheral: peripheral, advertisementData: advertisementData, rssi: RSSI)
|
||||
mCentralManager.didDiscover(central: central, peripheral: peripheral, advertisementData: advertisementData, rssi: RSSI)
|
||||
}
|
||||
|
||||
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
|
||||
_centralManager.didConnect(central: central, peripheral: peripheral)
|
||||
mCentralManager.didConnect(central: central, peripheral: peripheral)
|
||||
}
|
||||
|
||||
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
|
||||
_centralManager.didFailToConnect(central: central, peripheral: peripheral, error: error)
|
||||
mCentralManager.didFailToConnect(central: central, peripheral: peripheral, error: error)
|
||||
}
|
||||
|
||||
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
|
||||
_centralManager.didDisconnectPeripheral(central: central, peripheral: peripheral, error: error)
|
||||
mCentralManager.didDisconnectPeripheral(central: central, peripheral: peripheral, error: error)
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
// TODO: 优化错误内容
|
||||
enum MyError: Error {
|
||||
case illegalArgument
|
||||
case unknown
|
||||
case unsupported
|
||||
case illegalArgument
|
||||
}
|
||||
|
@ -9,45 +9,49 @@ import Foundation
|
||||
import CoreBluetooth
|
||||
|
||||
class MyPeripheralDelegate: NSObject, CBPeripheralDelegate {
|
||||
private let _centralManager: MyCentralManager
|
||||
private let mCentralManager: MyCentralManager
|
||||
|
||||
init(centralManager: MyCentralManager) {
|
||||
_centralManager = centralManager
|
||||
self.mCentralManager = centralManager
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
|
||||
_centralManager.didReadRSSI(peripheral: peripheral, rssi: RSSI, error: error)
|
||||
mCentralManager.didReadRSSI(peripheral: peripheral, rssi: RSSI, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
|
||||
_centralManager.didDiscoverServices(peripheral: peripheral, error: error)
|
||||
mCentralManager.didDiscoverServices(peripheral: peripheral, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didDiscoverIncludedServicesFor service: CBService, error: Error?) {
|
||||
mCentralManager.didDiscoverIncludedServices(peripheral: peripheral, service: service, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
|
||||
_centralManager.didDiscoverCharacteristics(peripheral: peripheral, service: service, error: error)
|
||||
mCentralManager.didDiscoverCharacteristics(peripheral: peripheral, service: service, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
|
||||
_centralManager.didDiscoverDescriptors(peripheral: peripheral, characteristic: characteristic, error: error)
|
||||
mCentralManager.didDiscoverDescriptors(peripheral: peripheral, characteristic: characteristic, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
_centralManager.didUpdateCharacteristicValue(peripheral: peripheral, characteristic: characteristic, error: error)
|
||||
mCentralManager.didUpdateCharacteristicValue(peripheral: peripheral, characteristic: characteristic, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
_centralManager.didWriteCharacteristicValue(peripheral: peripheral, characteristic: characteristic, error: error)
|
||||
mCentralManager.didWriteCharacteristicValue(peripheral: peripheral, characteristic: characteristic, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
|
||||
_centralManager.didUpdateCharacteristicNotificationState(peripheral: peripheral, characteristic: characteristic, error: error)
|
||||
mCentralManager.didUpdateCharacteristicNotificationState(peripheral: peripheral, characteristic: characteristic, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) {
|
||||
_centralManager.didUpdateDescriptorValue(peripheral: peripheral, descriptor: descriptor, error: error)
|
||||
mCentralManager.didUpdateDescriptorValue(peripheral: peripheral, descriptor: descriptor, error: error)
|
||||
}
|
||||
|
||||
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
|
||||
_centralManager.didWriteDescriptorValue(peripheral: peripheral, descriptor: descriptor, error: error)
|
||||
mCentralManager.didWriteDescriptorValue(peripheral: peripheral, descriptor: descriptor, error: error)
|
||||
}
|
||||
}
|
||||
|
@ -16,207 +16,180 @@ import FlutterMacOS
|
||||
#error("Unsupported platform.")
|
||||
#endif
|
||||
|
||||
class MyPeripheralManager: MyPeripheralManagerHostApi {
|
||||
private let _api: MyPeripheralManagerFlutterApi
|
||||
private let _peripheralManager: CBPeripheralManager
|
||||
class MyPeripheralManager: MyPeripheralManagerHostAPI {
|
||||
private let mAPI: MyPeripheralManagerFlutterAPI
|
||||
private let mPeripheralManager: CBPeripheralManager
|
||||
|
||||
private lazy var _peripheralManagerDelegate = MyPeripheralManagerDelegate(peripheralManager: self)
|
||||
private lazy var mPeripheralManagerDelegate = MyPeripheralManagerDelegate(peripheralManager: self)
|
||||
|
||||
private var _servicesArgs: [Int: MyGattServiceArgs]
|
||||
private var _characteristicsArgs: [Int: MyGattCharacteristicArgs]
|
||||
private var _descriptorsArgs: [Int: MyGattDescriptorArgs]
|
||||
private var mServicesArgs: [Int: MyMutableGATTServiceArgs]
|
||||
private var mCharacteristicsArgs: [Int: MyMutableGATTCharacteristicArgs]
|
||||
private var mDescriptorsArgs: [Int: MyMutableGATTDescriptorArgs]
|
||||
|
||||
private var _centrals: [String: CBCentral]
|
||||
private var _services: [Int64: CBMutableService]
|
||||
private var _characteristics: [Int64: CBMutableCharacteristic]
|
||||
private var _descriptors: [Int64: CBMutableDescriptor]
|
||||
private var _requests: [Int64: CBATTRequest]
|
||||
private var mCentrals: [String: CBCentral]
|
||||
private var mServices: [Int64: CBMutableService]
|
||||
private var mCharacteristics: [Int64: CBMutableCharacteristic]
|
||||
private var mDescriptors: [Int64: CBMutableDescriptor]
|
||||
private var mRequests: [Int64: CBATTRequest]
|
||||
|
||||
private var _addServiceCompletion: ((Result<Void, Error>) -> Void)?
|
||||
private var _startAdvertisingCompletion: ((Result<Void, Error>) -> Void)?
|
||||
private var _isReadyToUpdateSubscribersCallbacks: [() -> Void]
|
||||
private var mAddServiceCompletion: ((Result<Void, Error>) -> Void)?
|
||||
private var mStartAdvertisingCompletion: ((Result<Void, Error>) -> Void)?
|
||||
|
||||
init(messenger: FlutterBinaryMessenger) {
|
||||
_api = MyPeripheralManagerFlutterApi(binaryMessenger: messenger)
|
||||
_peripheralManager = CBPeripheralManager()
|
||||
mAPI = MyPeripheralManagerFlutterAPI(binaryMessenger: messenger)
|
||||
mPeripheralManager = CBPeripheralManager()
|
||||
|
||||
_servicesArgs = [:]
|
||||
_characteristicsArgs = [:]
|
||||
_descriptorsArgs = [:]
|
||||
mServicesArgs = [:]
|
||||
mCharacteristicsArgs = [:]
|
||||
mDescriptorsArgs = [:]
|
||||
|
||||
_centrals = [:]
|
||||
_services = [:]
|
||||
_characteristics = [:]
|
||||
_descriptors = [:]
|
||||
_requests = [:]
|
||||
mCentrals = [:]
|
||||
mServices = [:]
|
||||
mCharacteristics = [:]
|
||||
mDescriptors = [:]
|
||||
mRequests = [:]
|
||||
|
||||
_addServiceCompletion = nil
|
||||
_startAdvertisingCompletion = nil
|
||||
_isReadyToUpdateSubscribersCallbacks = []
|
||||
mAddServiceCompletion = nil
|
||||
mStartAdvertisingCompletion = nil
|
||||
}
|
||||
|
||||
func setUp() throws {
|
||||
_clearState()
|
||||
if _peripheralManager.delegate == nil {
|
||||
_peripheralManager.delegate = _peripheralManagerDelegate
|
||||
func initialize() throws {
|
||||
if(mPeripheralManager.isAdvertising) {
|
||||
mPeripheralManager.stopAdvertising()
|
||||
}
|
||||
didUpdateState(peripheral: _peripheralManager)
|
||||
}
|
||||
|
||||
func addService(serviceArgs: MyGattServiceArgs, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
let service = serviceArgs.toService()
|
||||
var characteristics = [CBMutableCharacteristic]()
|
||||
let characteristicsArgs = serviceArgs.characteristicsArgs
|
||||
for args in characteristicsArgs {
|
||||
guard let characteristicArgs = args else {
|
||||
continue
|
||||
}
|
||||
let characteristic = characteristicArgs.toCharacteristic()
|
||||
characteristics.append(characteristic)
|
||||
var descriptors = [CBMutableDescriptor]()
|
||||
let descriptorsArgs = characteristicArgs.descriptorsArgs
|
||||
for args in descriptorsArgs {
|
||||
guard let descriptorArgs = args else {
|
||||
continue
|
||||
}
|
||||
let descriptor = descriptorArgs.toDescriptor()
|
||||
descriptors.append(descriptor)
|
||||
let descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
|
||||
let descriptorHashCode = descriptor.hash
|
||||
_descriptorsArgs[descriptorHashCode] = descriptorArgs
|
||||
_descriptors[descriptorHashCodeArgs] = descriptor
|
||||
}
|
||||
characteristic.descriptors = descriptors
|
||||
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
let characteristicHashCode = characteristic.hash
|
||||
_characteristicsArgs[characteristicHashCode] = characteristicArgs
|
||||
_characteristics[characteristicHashCodeArgs] = characteristic
|
||||
}
|
||||
service.characteristics = characteristics
|
||||
let serviceHashCodeArgs = serviceArgs.hashCodeArgs
|
||||
let serviceHashCode = service.hash
|
||||
_servicesArgs[serviceHashCode] = serviceArgs
|
||||
_services[serviceHashCodeArgs] = service
|
||||
_peripheralManager.add(service)
|
||||
_addServiceCompletion = completion
|
||||
}
|
||||
|
||||
func removeService(hashCodeArgs: Int64) throws {
|
||||
guard let service = _services.removeValue(forKey: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
_peripheralManager.remove(service)
|
||||
let hashCode = service.hash
|
||||
guard let serviceArgs = _servicesArgs.removeValue(forKey: hashCode) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
for args in serviceArgs.characteristicsArgs {
|
||||
guard let characteristicArgs = args else {
|
||||
continue
|
||||
}
|
||||
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
guard let characteristic = _characteristics.removeValue(forKey: characteristicHashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let characteristicHashCode = characteristic.hash
|
||||
_characteristicsArgs.removeValue(forKey: characteristicHashCode)
|
||||
for args in characteristicArgs.descriptorsArgs {
|
||||
guard let descriptorArgs = args else {
|
||||
continue
|
||||
}
|
||||
let descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
|
||||
guard let descriptor = _descriptors.removeValue(forKey: descriptorHashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let descriptorHashCode = descriptor.hash
|
||||
_descriptorsArgs.removeValue(forKey: descriptorHashCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func clearServices() throws {
|
||||
_peripheralManager.removeAllServices()
|
||||
|
||||
_services.removeAll()
|
||||
_characteristics.removeAll()
|
||||
_descriptors.removeAll()
|
||||
mServicesArgs.removeAll()
|
||||
mCharacteristicsArgs.removeAll()
|
||||
mDescriptorsArgs.removeAll()
|
||||
|
||||
_servicesArgs.removeAll()
|
||||
_characteristicsArgs.removeAll()
|
||||
_descriptors.removeAll()
|
||||
mCentrals.removeAll()
|
||||
mServices.removeAll()
|
||||
mCharacteristics.removeAll()
|
||||
mDescriptors.removeAll()
|
||||
mRequests.removeAll()
|
||||
|
||||
mAddServiceCompletion = nil
|
||||
mStartAdvertisingCompletion = nil
|
||||
|
||||
mPeripheralManager.delegate = mPeripheralManagerDelegate
|
||||
}
|
||||
|
||||
func getState() throws -> MyBluetoothLowEnergyStateArgs {
|
||||
let state = mPeripheralManager.state
|
||||
let stateArgs = state.toArgs()
|
||||
return stateArgs
|
||||
}
|
||||
|
||||
func startAdvertising(advertisementArgs: MyAdvertisementArgs, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
let advertisement = advertisementArgs.toAdvertisement()
|
||||
_peripheralManager.startAdvertising(advertisement)
|
||||
_startAdvertisingCompletion = completion
|
||||
}
|
||||
|
||||
func stopAdvertising() throws {
|
||||
_peripheralManager.stopAdvertising()
|
||||
}
|
||||
|
||||
func getMaximumUpdateValueLength(uuidArgs: String) throws -> Int64 {
|
||||
guard let central = _centrals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let maximumUpdateValueLength = central.maximumUpdateValueLength
|
||||
let maximumUpdateValueLengthArgs = maximumUpdateValueLength.toInt64()
|
||||
return maximumUpdateValueLengthArgs
|
||||
}
|
||||
|
||||
func respond(idArgs: Int64, errorNumberArgs: Int64, valueArgs: FlutterStandardTypedData?) throws {
|
||||
guard let request = _requests.removeValue(forKey: idArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
if valueArgs != nil {
|
||||
request.value = valueArgs?.data
|
||||
}
|
||||
let errorArgsRawValue = errorNumberArgs.toInt()
|
||||
guard let errorArgs = MyGattErrorArgs(rawValue: errorArgsRawValue) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let result = errorArgs.toError()
|
||||
_peripheralManager.respond(to: request, withResult: result)
|
||||
}
|
||||
|
||||
func updateCharacteristic(hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, uuidsArgs: [String]?, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
func showAppSettings(completion: @escaping (Result<Void, any Error>) -> Void) {
|
||||
#if os(iOS)
|
||||
do {
|
||||
let centrals = try uuidsArgs?.map { uuidArgs in
|
||||
guard let central = _centrals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
return central
|
||||
}
|
||||
guard let characteristic = _characteristics[hashCodeArgs] else {
|
||||
guard let url = URL(string: UIApplication.openSettingsURLString) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let value = valueArgs.data
|
||||
let updated = _peripheralManager.updateValue(value, for: characteristic, onSubscribedCentrals: centrals)
|
||||
if updated {
|
||||
completion(.success(()))
|
||||
} else {
|
||||
_isReadyToUpdateSubscribersCallbacks.append {
|
||||
self.updateCharacteristic(hashCodeArgs: hashCodeArgs, valueArgs: valueArgs, uuidsArgs: uuidsArgs, completion: completion)
|
||||
UIApplication.shared.open(url) { success in
|
||||
if (success) {
|
||||
completion(.success(()))
|
||||
} else {
|
||||
completion(.failure(MyError.unknown))
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
#else
|
||||
completion(.failure(MyError.unsupported))
|
||||
#endif
|
||||
}
|
||||
|
||||
func addService(serviceArgs: MyMutableGATTServiceArgs, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
do {
|
||||
let service = try addServiceArgs(serviceArgs)
|
||||
mPeripheralManager.add(service)
|
||||
mAddServiceCompletion = completion
|
||||
} catch {
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
func removeService(hashCodeArgs: Int64) throws {
|
||||
guard let service = mServices[hashCodeArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let serviceArgs = mServicesArgs[service.hash] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
mPeripheralManager.remove(service)
|
||||
try removeServiceArgs(serviceArgs)
|
||||
}
|
||||
|
||||
func removeAllServices() throws {
|
||||
mPeripheralManager.removeAllServices()
|
||||
|
||||
mServices.removeAll()
|
||||
mCharacteristics.removeAll()
|
||||
mDescriptors.removeAll()
|
||||
|
||||
mServicesArgs.removeAll()
|
||||
mCharacteristicsArgs.removeAll()
|
||||
mDescriptors.removeAll()
|
||||
}
|
||||
|
||||
func startAdvertising(advertisementArgs: MyAdvertisementArgs, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
let advertisement = advertisementArgs.toAdvertisement()
|
||||
mPeripheralManager.startAdvertising(advertisement)
|
||||
mStartAdvertisingCompletion = completion
|
||||
}
|
||||
|
||||
func stopAdvertising() throws {
|
||||
mPeripheralManager.stopAdvertising()
|
||||
}
|
||||
|
||||
func getMaximumNotifyLength(uuidArgs: String) throws -> Int64 {
|
||||
guard let central = mCentrals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let maximumNotifyLength = central.maximumUpdateValueLength
|
||||
let maximumNotifyLengthArgs = maximumNotifyLength.toInt64()
|
||||
return maximumNotifyLengthArgs
|
||||
}
|
||||
|
||||
func respond(hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData?, errorArgs: MyATTErrorArgs) throws {
|
||||
guard let request = mRequests.removeValue(forKey: hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
if valueArgs != nil {
|
||||
request.value = valueArgs!.data
|
||||
}
|
||||
let error = errorArgs.toError()
|
||||
mPeripheralManager.respond(to: request, withResult: error)
|
||||
}
|
||||
|
||||
func updateValue(hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, uuidsArgs: [String]?) throws -> Bool {
|
||||
let centrals = try uuidsArgs?.map { uuidArgs in
|
||||
guard let central = self.mCentrals[uuidArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
return central
|
||||
}
|
||||
guard let characteristic = mCharacteristics[hashCodeArgs] else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let value = valueArgs.data
|
||||
let updated = mPeripheralManager.updateValue(value, for: characteristic, onSubscribedCentrals: centrals)
|
||||
return updated
|
||||
}
|
||||
|
||||
func didUpdateState(peripheral: CBPeripheralManager) {
|
||||
let state = peripheral.state
|
||||
let stateArgs = state.toArgs()
|
||||
let stateNumberArgs = stateArgs.rawValue.toInt64()
|
||||
_api.onStateChanged(stateNumberArgs: stateNumberArgs) {_ in }
|
||||
mAPI.onStateChanged(stateArgs: stateArgs) { _ in }
|
||||
}
|
||||
|
||||
func didAdd(peripheral: CBPeripheralManager, service: CBService, error: Error?) {
|
||||
guard let completion = _addServiceCompletion else {
|
||||
guard let completion = mAddServiceCompletion else {
|
||||
return
|
||||
}
|
||||
_addServiceCompletion = nil
|
||||
mAddServiceCompletion = nil
|
||||
if error == nil {
|
||||
completion(.success(()))
|
||||
} else {
|
||||
@ -225,10 +198,10 @@ class MyPeripheralManager: MyPeripheralManagerHostApi {
|
||||
}
|
||||
|
||||
func didStartAdvertising(peripheral: CBPeripheralManager, error: Error?) {
|
||||
guard let completion = _startAdvertisingCompletion else {
|
||||
guard let completion = mStartAdvertisingCompletion else {
|
||||
return
|
||||
}
|
||||
_startAdvertisingCompletion = nil
|
||||
mStartAdvertisingCompletion = nil
|
||||
if error == nil {
|
||||
completion(.success(()))
|
||||
} else {
|
||||
@ -237,107 +210,152 @@ class MyPeripheralManager: MyPeripheralManagerHostApi {
|
||||
}
|
||||
|
||||
func didReceiveRead(peripheral: CBPeripheralManager, request: CBATTRequest) {
|
||||
let hashCodeArgs = request.hash.toInt64()
|
||||
let central = request.central
|
||||
let centralArgs = central.toArgs()
|
||||
_centrals[centralArgs.uuidArgs] = central
|
||||
mCentrals[centralArgs.uuidArgs] = central
|
||||
let characteristic = request.characteristic
|
||||
let hashCode = characteristic.hash
|
||||
guard let characteristicArgs = _characteristicsArgs[hashCode] else {
|
||||
_peripheralManager.respond(to: request, withResult: .attributeNotFound)
|
||||
guard let characteristicArgs = mCharacteristicsArgs[characteristic.hash] else {
|
||||
mPeripheralManager.respond(to: request, withResult: .attributeNotFound)
|
||||
return
|
||||
}
|
||||
let hashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
let idArgs = request.hash.toInt64()
|
||||
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
let value = request.value
|
||||
let valueArgs = value == nil ? nil : FlutterStandardTypedData(bytes: value!)
|
||||
let offsetArgs = request.offset.toInt64()
|
||||
_requests[idArgs] = request
|
||||
_api.onCharacteristicReadRequest(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, idArgs: idArgs, offsetArgs: offsetArgs) {_ in }
|
||||
let requestArgs = MyATTRequestArgs(hashCodeArgs: hashCodeArgs, centralArgs: centralArgs, characteristicHashCodeArgs: characteristicHashCodeArgs, valueArgs: valueArgs, offsetArgs: offsetArgs)
|
||||
mRequests[hashCodeArgs] = request
|
||||
mAPI.didReceiveRead(requestArgs: requestArgs) { _ in }
|
||||
}
|
||||
|
||||
func didReceiveWrite(peripheral: CBPeripheralManager, requests: [CBATTRequest]) {
|
||||
// When you respond to a write request, note that the first parameter of the respond(to:with
|
||||
// Result:) method expects a single CBATTRequest object, even though you received an array of
|
||||
// them from the peripheralManager(_:didReceiveWrite:) method. To respond properly,
|
||||
// pass in the first request of the requests array.
|
||||
// see: https://developer.apple.com/documentation/corebluetooth/cbperipheralmanagerdelegate/1393315-peripheralmanager#discussion
|
||||
var requestsArgs = [MyATTRequestArgs]()
|
||||
for request in requests {
|
||||
let hashCodeArgs = request.hash.toInt64()
|
||||
let central = request.central
|
||||
let centralArgs = central.toArgs()
|
||||
mCentrals[centralArgs.uuidArgs] = central
|
||||
let characteristic = request.characteristic
|
||||
guard let characteristicArgs = mCharacteristicsArgs[characteristic.hash] else {
|
||||
mPeripheralManager.respond(to: request, withResult: .attributeNotFound)
|
||||
return
|
||||
}
|
||||
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
let value = request.value
|
||||
let valueArgs = value == nil ? nil : FlutterStandardTypedData(bytes: value!)
|
||||
let offsetArgs = request.offset.toInt64()
|
||||
let requestArgs = MyATTRequestArgs(hashCodeArgs: hashCodeArgs, centralArgs: centralArgs, characteristicHashCodeArgs: characteristicHashCodeArgs, valueArgs: valueArgs, offsetArgs: offsetArgs)
|
||||
requestsArgs.append(requestArgs)
|
||||
}
|
||||
guard let request = requests.first else {
|
||||
return
|
||||
}
|
||||
if requests.count > 1 {
|
||||
// TODO: 支持多写入请求,暂时不清楚此处应如何处理
|
||||
let result = CBATTError.requestNotSupported
|
||||
_peripheralManager.respond(to: request, withResult: result)
|
||||
guard let requestArgs = requestsArgs.first else {
|
||||
return
|
||||
}
|
||||
let central = request.central
|
||||
let centralArgs = central.toArgs()
|
||||
_centrals[centralArgs.uuidArgs] = central
|
||||
let characteristic = request.characteristic
|
||||
let hashCode = characteristic.hash
|
||||
guard let characteristicArgs = _characteristicsArgs[hashCode] else {
|
||||
_peripheralManager.respond(to: request, withResult: .attributeNotFound)
|
||||
return
|
||||
}
|
||||
let hashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
let idArgs = request.hash.toInt64()
|
||||
let offsetArgs = request.offset.toInt64()
|
||||
guard let value = request.value else {
|
||||
_peripheralManager.respond(to: request, withResult: .requestNotSupported)
|
||||
return
|
||||
}
|
||||
let valueArgs = FlutterStandardTypedData(bytes: value)
|
||||
_requests[idArgs] = request
|
||||
_api.onCharacteristicWriteRequest(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, idArgs: idArgs, offsetArgs: offsetArgs, valueArgs: valueArgs) {_ in }
|
||||
self.mRequests[requestArgs.hashCodeArgs] = request
|
||||
mAPI.didReceiveWrite(requestsArgs: requestsArgs) { _ in }
|
||||
}
|
||||
|
||||
func didSubscribeTo(peripheral: CBPeripheralManager, central: CBCentral, characteristic: CBCharacteristic) {
|
||||
let centralArgs = central.toArgs()
|
||||
_centrals[centralArgs.uuidArgs] = central
|
||||
mCentrals[centralArgs.uuidArgs] = central
|
||||
let hashCode = characteristic.hash
|
||||
guard let characteristicArgs = _characteristicsArgs[hashCode] else {
|
||||
guard let characteristicArgs = mCharacteristicsArgs[hashCode] else {
|
||||
return
|
||||
}
|
||||
let hashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
let stateArgs = true
|
||||
_api.onCharacteristicNotifyStateChanged(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, stateArgs: stateArgs) {_ in }
|
||||
mAPI.onCharacteristicNotifyStateChanged(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, stateArgs: stateArgs) { _ in }
|
||||
}
|
||||
|
||||
func didUnsubscribeFrom(peripheral: CBPeripheralManager, central: CBCentral, characteristic: CBCharacteristic) {
|
||||
let centralArgs = central.toArgs()
|
||||
_centrals[centralArgs.uuidArgs] = central
|
||||
mCentrals[centralArgs.uuidArgs] = central
|
||||
let hashCode = characteristic.hash
|
||||
guard let characteristicArgs = _characteristicsArgs[hashCode] else {
|
||||
guard let characteristicArgs = mCharacteristicsArgs[hashCode] else {
|
||||
return
|
||||
}
|
||||
let hashCodeArgs = characteristicArgs.hashCodeArgs
|
||||
let stateArgs = false
|
||||
_api.onCharacteristicNotifyStateChanged(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, stateArgs: stateArgs) {_ in }
|
||||
mAPI.onCharacteristicNotifyStateChanged(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, stateArgs: stateArgs) { _ in }
|
||||
}
|
||||
|
||||
func isReadyToUpdateSubscribers(peripheral: CBPeripheralManager) {
|
||||
let callbacks = _isReadyToUpdateSubscribersCallbacks
|
||||
_isReadyToUpdateSubscribersCallbacks.removeAll()
|
||||
for callback in callbacks {
|
||||
callback()
|
||||
}
|
||||
mAPI.isReady() { _ in }
|
||||
}
|
||||
|
||||
private func _clearState() {
|
||||
if(_peripheralManager.isAdvertising) {
|
||||
_peripheralManager.stopAdvertising()
|
||||
private func addServiceArgs(_ serviceArgs: MyMutableGATTServiceArgs) throws -> CBMutableService {
|
||||
let service = serviceArgs.toService()
|
||||
mServicesArgs[service.hash] = serviceArgs
|
||||
mServices[serviceArgs.hashCodeArgs] = service
|
||||
var includedServices = [CBService]()
|
||||
let includedServicesArgs = serviceArgs.includedServicesArgs
|
||||
for args in includedServicesArgs {
|
||||
guard let includedServiceArgs = args else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let includedService = try addServiceArgs(includedServiceArgs)
|
||||
self.mServicesArgs[includedService.hash] = includedServiceArgs
|
||||
self.mServices[includedServiceArgs.hashCodeArgs] = includedService
|
||||
includedServices.append(includedService)
|
||||
}
|
||||
|
||||
_servicesArgs.removeAll()
|
||||
_characteristicsArgs.removeAll()
|
||||
_descriptorsArgs.removeAll()
|
||||
|
||||
_centrals.removeAll()
|
||||
_services.removeAll()
|
||||
_characteristics.removeAll()
|
||||
_descriptors.removeAll()
|
||||
_requests.removeAll()
|
||||
|
||||
_addServiceCompletion = nil
|
||||
_startAdvertisingCompletion = nil
|
||||
_isReadyToUpdateSubscribersCallbacks.removeAll()
|
||||
service.includedServices = includedServices
|
||||
var characteristics = [CBMutableCharacteristic]()
|
||||
let characteristicsArgs = serviceArgs.characteristicsArgs
|
||||
for args in characteristicsArgs {
|
||||
guard let characteristicArgs = args else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
let characteristic = characteristicArgs.toCharacteristic()
|
||||
self.mCharacteristicsArgs[characteristic.hash] = characteristicArgs
|
||||
self.mCharacteristics[characteristicArgs.hashCodeArgs] = characteristic
|
||||
characteristics.append(characteristic)
|
||||
var descriptors = [CBMutableDescriptor]()
|
||||
let descriptorsArgs = characteristicArgs.descriptorsArgs
|
||||
for args in descriptorsArgs {
|
||||
guard let descriptorArgs = args else {
|
||||
continue
|
||||
}
|
||||
let descriptor = descriptorArgs.toDescriptor()
|
||||
self.mDescriptorsArgs[descriptor.hash] = descriptorArgs
|
||||
self.mDescriptors[descriptorArgs.hashCodeArgs] = descriptor
|
||||
descriptors.append(descriptor)
|
||||
}
|
||||
characteristic.descriptors = descriptors
|
||||
}
|
||||
service.characteristics = characteristics
|
||||
return service
|
||||
}
|
||||
|
||||
private func removeServiceArgs(_ serviceArgs: MyMutableGATTServiceArgs) throws {
|
||||
for args in serviceArgs.includedServicesArgs {
|
||||
guard let includedServiceArgs = args else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
try removeServiceArgs(includedServiceArgs)
|
||||
}
|
||||
for args in serviceArgs.characteristicsArgs {
|
||||
guard let characteristicArgs = args else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
for args in characteristicArgs.descriptorsArgs {
|
||||
guard let descriptorArgs = args else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
guard let descriptor = mDescriptors.removeValue(forKey: descriptorArgs.hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
mDescriptorsArgs.removeValue(forKey: descriptor.hash)
|
||||
}
|
||||
guard let characteristic = mCharacteristics.removeValue(forKey: characteristicArgs.hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
mCharacteristicsArgs.removeValue(forKey: characteristic.hash)
|
||||
}
|
||||
guard let service = mServices.removeValue(forKey: serviceArgs.hashCodeArgs) else {
|
||||
throw MyError.illegalArgument
|
||||
}
|
||||
mServicesArgs.removeValue(forKey: service.hash)
|
||||
}
|
||||
}
|
||||
|
@ -9,41 +9,41 @@ import Foundation
|
||||
import CoreBluetooth
|
||||
|
||||
class MyPeripheralManagerDelegate: NSObject, CBPeripheralManagerDelegate {
|
||||
private let _peripheralManager: MyPeripheralManager
|
||||
private let mPeripheralManager: MyPeripheralManager
|
||||
|
||||
init(peripheralManager: MyPeripheralManager) {
|
||||
_peripheralManager = peripheralManager
|
||||
self.mPeripheralManager = peripheralManager
|
||||
}
|
||||
|
||||
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
|
||||
_peripheralManager.didUpdateState(peripheral: peripheral)
|
||||
mPeripheralManager.didUpdateState(peripheral: peripheral)
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
|
||||
_peripheralManager.didAdd(peripheral: peripheral, service: service, error: error)
|
||||
mPeripheralManager.didAdd(peripheral: peripheral, service: service, error: error)
|
||||
}
|
||||
|
||||
func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {
|
||||
_peripheralManager.didStartAdvertising(peripheral: peripheral, error: error)
|
||||
mPeripheralManager.didStartAdvertising(peripheral: peripheral, error: error)
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
|
||||
_peripheralManager.didReceiveRead(peripheral: peripheral, request: request)
|
||||
mPeripheralManager.didReceiveRead(peripheral: peripheral, request: request)
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
|
||||
_peripheralManager.didReceiveWrite(peripheral: peripheral, requests: requests)
|
||||
mPeripheralManager.didReceiveWrite(peripheral: peripheral, requests: requests)
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
|
||||
_peripheralManager.didSubscribeTo(peripheral: peripheral, central: central, characteristic: characteristic)
|
||||
mPeripheralManager.didSubscribeTo(peripheral: peripheral, central: central, characteristic: characteristic)
|
||||
}
|
||||
|
||||
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) {
|
||||
_peripheralManager.didUnsubscribeFrom(peripheral: peripheral, central: central, characteristic: characteristic)
|
||||
mPeripheralManager.didUnsubscribeFrom(peripheral: peripheral, central: central, characteristic: characteristic)
|
||||
}
|
||||
|
||||
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
|
||||
_peripheralManager.isReadyToUpdateSubscribers(peripheral: peripheral)
|
||||
mPeripheralManager.isReadyToUpdateSubscribers(peripheral: peripheral)
|
||||
}
|
||||
}
|
||||
|
@ -4,24 +4,24 @@
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'bluetooth_low_energy_darwin'
|
||||
s.version = '2.0.2'
|
||||
s.summary = 'iOS and macOS implementation of the bluetooth_low_energy plugin.'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'A new Flutter plugin project.'
|
||||
s.description = <<-DESC
|
||||
iOS and macOS implementation of the bluetooth_low_energy plugin.
|
||||
A new Flutter plugin project.
|
||||
DESC
|
||||
s.homepage = 'https://github.com/yanshouwang/bluetooth_low_energy'
|
||||
s.homepage = 'http://example.com'
|
||||
s.license = { :file => '../LICENSE' }
|
||||
s.author = { 'yanshouwang' => 'yanshouwang@outlook.com' }
|
||||
|
||||
s.author = { 'Your Company' => 'email@example.com' }
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*'
|
||||
|
||||
s.ios.dependency 'Flutter'
|
||||
s.ios.deployment_target = '11.0'
|
||||
s.ios.deployment_target = '12.0'
|
||||
|
||||
s.osx.dependency 'FlutterMacOS'
|
||||
s.osx.deployment_target = '10.11'
|
||||
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
|
||||
s.swift_version = '5.0'
|
||||
end
|
||||
|
Reference in New Issue
Block a user