feat: 5.0.0 (#35)

* draft: 临时提交

* feat: 实现扫描功能

* fix: 优化广播逻辑

* feat: 添加协程方法

* fix: 修改宏定义

* draft: 临时提交

* feat: 调整接口

* fix: 修改版本号

* feat: 4.1.1

* draft: 临时提交

* feat: 5.0.0-dev.2

* fix: 修复版本号错误

* draft: 临时提交

* fix: 修复连接断开异常

* fix: 修复问题

* fix: 优化代码

* fix:  优化 short UUID 格式化逻辑

* fix: 尝试实现 read_rssi 接口,当前此接口不可用,会报异常

* feat: 删除 getMaximumWriteLength 方法

* fix: 更新 CHANGELOG.md

* feat: 5.0.0-dev.1

* fix: 更新依赖项

* feat: linux-5.0.0-dev.1

* fix: 更新 CHANGELOG.md

* fix: 开始搜索设备时清空设备列表

* fix: 开始扫描时清空设备列表

* feat: 5.0.0-dev.2

* fix: 优化 MyGattService 和 MyGattCharacteristic

* feat: 更新 interface 版本 -> 5.0.0-dev.4

* feat: 更新 interface 版本 -> 5.0.0-dev.4

* feat: 实现 flutter 部分 5.0.0

* fix: 移除 maximumWriteLength

* fix: 移除 rssi

* feat: 5.0.0-dev.1

* feat: 5.0.0-dev.2

* fix: 更新依赖项

* fix: 5.0.0-dev.4

* fix: 更新依赖项

* draft: 临时提交

* feat: 5.0.0-dev.5

* draft: 删除 MyCentralManager 和 MyPeripheralManager

* fix: 更新依赖项

* fix: 更新依赖项

* feat: 适配新接口

* feat: 5.0.0-dev.6

* draft: 临时提交

* feat: 5.0.0-dev.7

* fix: 修改版本号

* feat: 5.0.0-dev.8

* feat: 5.0.0-dev.9

* fix: 修复 trimGATT 错误

* feat: 5.0.0-dev.6

* feat: 5.0.0-dev.3

* feat: 5.0.0-dev.4

* fix: 更新 pubspec.lock

* feat: 5.0.0-dev.7

* feat: 5.0.0-dev.3

* fix: balabala

* fix: balabala

* draft: 5.0.0-dev.1

* fix: trim GATT when call the `writeCharacteristic` method.

* fix: make difference of `trim` and `fragment`.

* feat: 5.0.0-dev.1

* feat: 5.0.0-dev.1

* feat: 优化示例程序

* fix: 更新 README.md

* fix: 修复插件引用

* draft: XXXX

* feat: 增加调试信息

* fix: 更新 pubspec.lock

* feat: 5.0.0-dev.4

* feat: 5.0.0-dev.3

* feat: 5.0.0

* feat: 5.0.0

* feat: 5.0.0

* feat: 5.0.0

* feat: 5.0.0

* feat: 5.0.0
This commit is contained in:
iAMD
2023-12-31 00:53:48 +08:00
committed by GitHub
parent cfe0eda4a3
commit 87fe3e2447
137 changed files with 14108 additions and 8393 deletions

View File

@ -11,15 +11,15 @@ import FlutterMacOS
public class BluetoothLowEnergyDarwin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
#if os(iOS)
let binaryMessenger = registrar.messenger()
let messenger = registrar.messenger()
#elseif os(macOS)
let binaryMessenger = registrar.messenger
let messenger = registrar.messenger
#else
#error("Unsupported platform.")
#endif
let centralManager = MyCentralManager(binaryMessenger)
let peripheralManager = MyPeripheralManager(binaryMessenger)
MyCentralManagerHostApiSetup.setUp(binaryMessenger: binaryMessenger, api: centralManager)
MyPeripheralManagerHostApiSetup.setUp(binaryMessenger: binaryMessenger, api: peripheralManager)
let centralManager = MyCentralManager(messenger: messenger)
let peripheralManager = MyPeripheralManager(messenger: messenger)
MyCentralManagerHostApiSetup.setUp(binaryMessenger: messenger, api: centralManager)
MyPeripheralManagerHostApiSetup.setUp(binaryMessenger: messenger, api: peripheralManager)
}
}

View File

@ -1,4 +1,4 @@
// Autogenerated from Pigeon (v12.0.1), do not edit directly.
// Autogenerated from Pigeon (v15.0.2), do not edit directly.
// See also: https://pub.dev/packages/pigeon
import Foundation
@ -10,10 +10,6 @@ import FlutterMacOS
#error("Unsupported platform.")
#endif
private func isNullish(_ value: Any?) -> Bool {
return value is NSNull || value == nil
}
private func wrapResult(_ result: Any?) -> [Any?] {
return [result]
}
@ -33,6 +29,14 @@ private func wrapError(_ error: Any) -> [Any?] {
]
}
private func createConnectionError(withChannelName channelName: String) -> FlutterError {
return FlutterError(code: "channel-error", message: "Unable to establish connection on channel: '\(channelName)'.", details: "")
}
private func isNullish(_ value: Any?) -> Bool {
return value is NSNull || value == nil
}
private func nilOrValue<T>(_ value: Any?) -> T? {
if value is NSNull { return nil }
return value as! T?
@ -40,10 +44,11 @@ private func nilOrValue<T>(_ value: Any?) -> T? {
enum MyBluetoothLowEnergyStateArgs: Int {
case unknown = 0
case unsupported = 1
case unauthorized = 2
case poweredOff = 3
case poweredOn = 4
case resetting = 1
case unsupported = 2
case unauthorized = 3
case poweredOff = 4
case poweredOn = 5
}
enum MyGattCharacteristicPropertyArgs: Int {
@ -59,82 +64,45 @@ enum MyGattCharacteristicWriteTypeArgs: Int {
case withoutResponse = 1
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyCentralManagerArgs {
var stateNumberArgs: Int64
static func fromList(_ list: [Any?]) -> MyCentralManagerArgs? {
let stateNumberArgs = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
return MyCentralManagerArgs(
stateNumberArgs: stateNumberArgs
)
}
func toList() -> [Any?] {
return [
stateNumberArgs,
]
}
enum MyGattErrorArgs: Int {
case success = 0
case invalidHandle = 1
case readNotPermitted = 2
case writeNotPermitted = 3
case invalidPDU = 4
case insufficientAuthentication = 5
case requestNotSupported = 6
case invalidOffset = 7
case insufficientAuthorization = 8
case prepareQueueFull = 9
case attributeNotFound = 10
case attributeNotLong = 11
case insufficientEncryptionKeySize = 12
case invalidAttributeValueLength = 13
case unlikelyError = 14
case insufficientEncryption = 15
case unsupportedGroupType = 16
case insufficientResources = 17
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyPeripheralManagerArgs {
var stateNumberArgs: Int64
struct MyManufacturerSpecificDataArgs {
var idArgs: Int64
var dataArgs: FlutterStandardTypedData
static func fromList(_ list: [Any?]) -> MyPeripheralManagerArgs? {
let stateNumberArgs = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
static func fromList(_ list: [Any?]) -> MyManufacturerSpecificDataArgs? {
let idArgs = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let dataArgs = list[1] as! FlutterStandardTypedData
return MyPeripheralManagerArgs(
stateNumberArgs: stateNumberArgs
return MyManufacturerSpecificDataArgs(
idArgs: idArgs,
dataArgs: dataArgs
)
}
func toList() -> [Any?] {
return [
stateNumberArgs,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyCentralArgs {
var hashCodeArgs: Int64
var uuidArgs: String
static func fromList(_ list: [Any?]) -> MyCentralArgs? {
let hashCodeArgs = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let uuidArgs = list[1] as! String
return MyCentralArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs
)
}
func toList() -> [Any?] {
return [
hashCodeArgs,
uuidArgs,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyPeripheralArgs {
var hashCodeArgs: Int64
var uuidArgs: String
static func fromList(_ list: [Any?]) -> MyPeripheralArgs? {
let hashCodeArgs = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let uuidArgs = list[1] as! String
return MyPeripheralArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs
)
}
func toList() -> [Any?] {
return [
hashCodeArgs,
uuidArgs,
idArgs,
dataArgs,
]
}
}
@ -173,49 +141,63 @@ struct MyAdvertisementArgs {
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyManufacturerSpecificDataArgs {
var idArgs: Int64
var dataArgs: FlutterStandardTypedData
struct MyCentralArgs {
var uuidArgs: String
static func fromList(_ list: [Any?]) -> MyManufacturerSpecificDataArgs? {
let idArgs = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let dataArgs = list[1] as! FlutterStandardTypedData
static func fromList(_ list: [Any?]) -> MyCentralArgs? {
let uuidArgs = list[0] as! String
return MyManufacturerSpecificDataArgs(
idArgs: idArgs,
dataArgs: dataArgs
return MyCentralArgs(
uuidArgs: uuidArgs
)
}
func toList() -> [Any?] {
return [
idArgs,
dataArgs,
uuidArgs,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyGattServiceArgs {
struct MyPeripheralArgs {
var uuidArgs: String
static func fromList(_ list: [Any?]) -> MyPeripheralArgs? {
let uuidArgs = list[0] as! String
return MyPeripheralArgs(
uuidArgs: uuidArgs
)
}
func toList() -> [Any?] {
return [
uuidArgs,
]
}
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyGattDescriptorArgs {
var hashCodeArgs: Int64
var uuidArgs: String
var characteristicsArgs: [MyGattCharacteristicArgs?]
var valueArgs: FlutterStandardTypedData? = nil
static func fromList(_ list: [Any?]) -> MyGattServiceArgs? {
static func fromList(_ list: [Any?]) -> MyGattDescriptorArgs? {
let hashCodeArgs = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let uuidArgs = list[1] as! String
let characteristicsArgs = list[2] as! [MyGattCharacteristicArgs?]
let valueArgs: FlutterStandardTypedData? = nilOrValue(list[2])
return MyGattServiceArgs(
return MyGattDescriptorArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs,
characteristicsArgs: characteristicsArgs
valueArgs: valueArgs
)
}
func toList() -> [Any?] {
return [
hashCodeArgs,
uuidArgs,
characteristicsArgs,
valueArgs,
]
}
}
@ -251,27 +233,27 @@ struct MyGattCharacteristicArgs {
}
/// Generated class from Pigeon that represents data sent in messages.
struct MyGattDescriptorArgs {
struct MyGattServiceArgs {
var hashCodeArgs: Int64
var uuidArgs: String
var valueArgs: FlutterStandardTypedData? = nil
var characteristicsArgs: [MyGattCharacteristicArgs?]
static func fromList(_ list: [Any?]) -> MyGattDescriptorArgs? {
static func fromList(_ list: [Any?]) -> MyGattServiceArgs? {
let hashCodeArgs = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32)
let uuidArgs = list[1] as! String
let valueArgs: FlutterStandardTypedData? = nilOrValue(list[2])
let characteristicsArgs = list[2] as! [MyGattCharacteristicArgs?]
return MyGattDescriptorArgs(
return MyGattServiceArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs,
valueArgs: valueArgs
characteristicsArgs: characteristicsArgs
)
}
func toList() -> [Any?] {
return [
hashCodeArgs,
uuidArgs,
valueArgs,
characteristicsArgs,
]
}
}
@ -280,12 +262,10 @@ private class MyCentralManagerHostApiCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
case 128:
return MyCentralManagerArgs.fromList(self.readValue() as! [Any?])
case 129:
return MyGattCharacteristicArgs.fromList(self.readValue() as! [Any?])
case 130:
case 129:
return MyGattDescriptorArgs.fromList(self.readValue() as! [Any?])
case 131:
case 130:
return MyGattServiceArgs.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
@ -295,17 +275,14 @@ private class MyCentralManagerHostApiCodecReader: FlutterStandardReader {
private class MyCentralManagerHostApiCodecWriter: FlutterStandardWriter {
override func writeValue(_ value: Any) {
if let value = value as? MyCentralManagerArgs {
if let value = value as? MyGattCharacteristicArgs {
super.writeByte(128)
super.writeValue(value.toList())
} else if let value = value as? MyGattCharacteristicArgs {
} else if let value = value as? MyGattDescriptorArgs {
super.writeByte(129)
super.writeValue(value.toList())
} else if let value = value as? MyGattDescriptorArgs {
super.writeByte(130)
super.writeValue(value.toList())
} else if let value = value as? MyGattServiceArgs {
super.writeByte(131)
super.writeByte(130)
super.writeValue(value.toList())
} else {
super.writeValue(value)
@ -329,19 +306,21 @@ class MyCentralManagerHostApiCodec: FlutterStandardMessageCodec {
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol MyCentralManagerHostApi {
func setUp(completion: @escaping (Result<MyCentralManagerArgs, Error>) -> Void)
func setUp() throws
func startDiscovery() throws
func stopDiscovery() throws
func connect(peripheralHashCodeArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void)
func disconnect(peripheralHashCodeArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void)
func getMaximumWriteLength(peripheralHashCodeArgs: Int64, typeNumberArgs: Int64) throws -> Int64
func readRSSI(peripheralHashCodeArgs: Int64, completion: @escaping (Result<Int64, Error>) -> Void)
func discoverGATT(peripheralHashCodeArgs: Int64, completion: @escaping (Result<[MyGattServiceArgs], Error>) -> Void)
func readCharacteristic(peripheralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void)
func writeCharacteristic(peripheralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, typeNumberArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void)
func notifyCharacteristic(peripheralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, stateArgs: Bool, completion: @escaping (Result<Void, Error>) -> Void)
func readDescriptor(peripheralHashCodeArgs: Int64, descriptorHashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void)
func writeDescriptor(peripheralHashCodeArgs: Int64, descriptorHashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void)
func connect(uuidArgs: String, completion: @escaping (Result<Void, Error>) -> Void)
func disconnect(uuidArgs: String, completion: @escaping (Result<Void, Error>) -> Void)
func getMaximumWriteValueLength(uuidArgs: String, typeNumberArgs: Int64) throws -> Int64
func readRSSI(uuidArgs: String, completion: @escaping (Result<Int64, Error>) -> Void)
func discoverServices(uuidArgs: String, completion: @escaping (Result<[MyGattServiceArgs], Error>) -> Void)
func discoverCharacteristics(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGattCharacteristicArgs], Error>) -> Void)
func discoverDescriptors(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGattDescriptorArgs], Error>) -> Void)
func readCharacteristic(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void)
func writeCharacteristic(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, typeNumberArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void)
func setCharacteristicNotifyState(uuidArgs: String, hashCodeArgs: Int64, stateArgs: Bool, completion: @escaping (Result<Void, Error>) -> Void)
func readDescriptor(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void)
func writeDescriptor(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void)
}
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
@ -353,13 +332,11 @@ class MyCentralManagerHostApiSetup {
let setUpChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.setUp", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
setUpChannel.setMessageHandler { _, reply in
api.setUp() { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
do {
try api.setUp()
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
}
}
} else {
@ -395,8 +372,8 @@ class MyCentralManagerHostApiSetup {
if let api = api {
connectChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
api.connect(peripheralHashCodeArgs: peripheralHashCodeArgsArg) { result in
let uuidArgsArg = args[0] as! String
api.connect(uuidArgs: uuidArgsArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
@ -412,8 +389,8 @@ class MyCentralManagerHostApiSetup {
if let api = api {
disconnectChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
api.disconnect(peripheralHashCodeArgs: peripheralHashCodeArgsArg) { result in
let uuidArgsArg = args[0] as! String
api.disconnect(uuidArgs: uuidArgsArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
@ -425,28 +402,28 @@ class MyCentralManagerHostApiSetup {
} else {
disconnectChannel.setMessageHandler(nil)
}
let getMaximumWriteLengthChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.getMaximumWriteLength", binaryMessenger: binaryMessenger, codec: codec)
let getMaximumWriteValueLengthChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.getMaximumWriteValueLength", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getMaximumWriteLengthChannel.setMessageHandler { message, reply in
getMaximumWriteValueLengthChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let uuidArgsArg = args[0] as! String
let typeNumberArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
do {
let result = try api.getMaximumWriteLength(peripheralHashCodeArgs: peripheralHashCodeArgsArg, typeNumberArgs: typeNumberArgsArg)
let result = try api.getMaximumWriteValueLength(uuidArgs: uuidArgsArg, typeNumberArgs: typeNumberArgsArg)
reply(wrapResult(result))
} catch {
reply(wrapError(error))
}
}
} else {
getMaximumWriteLengthChannel.setMessageHandler(nil)
getMaximumWriteValueLengthChannel.setMessageHandler(nil)
}
let readRSSIChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.readRSSI", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
readRSSIChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
api.readRSSI(peripheralHashCodeArgs: peripheralHashCodeArgsArg) { result in
let uuidArgsArg = args[0] as! String
api.readRSSI(uuidArgs: uuidArgsArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
@ -458,12 +435,12 @@ class MyCentralManagerHostApiSetup {
} else {
readRSSIChannel.setMessageHandler(nil)
}
let discoverGATTChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.discoverGATT", binaryMessenger: binaryMessenger, codec: codec)
let discoverServicesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.discoverServices", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
discoverGATTChannel.setMessageHandler { message, reply in
discoverServicesChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
api.discoverGATT(peripheralHashCodeArgs: peripheralHashCodeArgsArg) { result in
let uuidArgsArg = args[0] as! String
api.discoverServices(uuidArgs: uuidArgsArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
@ -473,15 +450,51 @@ class MyCentralManagerHostApiSetup {
}
}
} else {
discoverGATTChannel.setMessageHandler(nil)
discoverServicesChannel.setMessageHandler(nil)
}
let discoverCharacteristicsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.discoverCharacteristics", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
discoverCharacteristicsChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let uuidArgsArg = args[0] as! String
let hashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
api.discoverCharacteristics(uuidArgs: uuidArgsArg, hashCodeArgs: hashCodeArgsArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
discoverCharacteristicsChannel.setMessageHandler(nil)
}
let discoverDescriptorsChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.discoverDescriptors", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
discoverDescriptorsChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let uuidArgsArg = args[0] as! String
let hashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
api.discoverDescriptors(uuidArgs: uuidArgsArg, hashCodeArgs: hashCodeArgsArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
discoverDescriptorsChannel.setMessageHandler(nil)
}
let readCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.readCharacteristic", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
readCharacteristicChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let characteristicHashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
api.readCharacteristic(peripheralHashCodeArgs: peripheralHashCodeArgsArg, characteristicHashCodeArgs: characteristicHashCodeArgsArg) { result in
let uuidArgsArg = args[0] as! String
let hashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
api.readCharacteristic(uuidArgs: uuidArgsArg, hashCodeArgs: hashCodeArgsArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
@ -497,11 +510,11 @@ class MyCentralManagerHostApiSetup {
if let api = api {
writeCharacteristicChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let characteristicHashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let uuidArgsArg = args[0] as! String
let hashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let valueArgsArg = args[2] as! FlutterStandardTypedData
let typeNumberArgsArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32)
api.writeCharacteristic(peripheralHashCodeArgs: peripheralHashCodeArgsArg, characteristicHashCodeArgs: characteristicHashCodeArgsArg, valueArgs: valueArgsArg, typeNumberArgs: typeNumberArgsArg) { result in
api.writeCharacteristic(uuidArgs: uuidArgsArg, hashCodeArgs: hashCodeArgsArg, valueArgs: valueArgsArg, typeNumberArgs: typeNumberArgsArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
@ -513,14 +526,14 @@ class MyCentralManagerHostApiSetup {
} else {
writeCharacteristicChannel.setMessageHandler(nil)
}
let notifyCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.notifyCharacteristic", binaryMessenger: binaryMessenger, codec: codec)
let setCharacteristicNotifyStateChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.setCharacteristicNotifyState", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
notifyCharacteristicChannel.setMessageHandler { message, reply in
setCharacteristicNotifyStateChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let characteristicHashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let uuidArgsArg = args[0] as! String
let hashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let stateArgsArg = args[2] as! Bool
api.notifyCharacteristic(peripheralHashCodeArgs: peripheralHashCodeArgsArg, characteristicHashCodeArgs: characteristicHashCodeArgsArg, stateArgs: stateArgsArg) { result in
api.setCharacteristicNotifyState(uuidArgs: uuidArgsArg, hashCodeArgs: hashCodeArgsArg, stateArgs: stateArgsArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
@ -530,15 +543,15 @@ class MyCentralManagerHostApiSetup {
}
}
} else {
notifyCharacteristicChannel.setMessageHandler(nil)
setCharacteristicNotifyStateChannel.setMessageHandler(nil)
}
let readDescriptorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerHostApi.readDescriptor", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
readDescriptorChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let descriptorHashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
api.readDescriptor(peripheralHashCodeArgs: peripheralHashCodeArgsArg, descriptorHashCodeArgs: descriptorHashCodeArgsArg) { result in
let uuidArgsArg = args[0] as! String
let hashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
api.readDescriptor(uuidArgs: uuidArgsArg, hashCodeArgs: hashCodeArgsArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
@ -554,10 +567,10 @@ class MyCentralManagerHostApiSetup {
if let api = api {
writeDescriptorChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let peripheralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let descriptorHashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let uuidArgsArg = args[0] as! String
let hashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let valueArgsArg = args[2] as! FlutterStandardTypedData
api.writeDescriptor(peripheralHashCodeArgs: peripheralHashCodeArgsArg, descriptorHashCodeArgs: descriptorHashCodeArgsArg, valueArgs: valueArgsArg) { result in
api.writeDescriptor(uuidArgs: uuidArgsArg, hashCodeArgs: hashCodeArgsArg, valueArgs: valueArgsArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
@ -577,12 +590,8 @@ private class MyCentralManagerFlutterApiCodecReader: FlutterStandardReader {
case 128:
return MyAdvertisementArgs.fromList(self.readValue() as! [Any?])
case 129:
return MyGattCharacteristicArgs.fromList(self.readValue() as! [Any?])
case 130:
return MyGattDescriptorArgs.fromList(self.readValue() as! [Any?])
case 131:
return MyManufacturerSpecificDataArgs.fromList(self.readValue() as! [Any?])
case 132:
case 130:
return MyPeripheralArgs.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
@ -595,17 +604,11 @@ private class MyCentralManagerFlutterApiCodecWriter: FlutterStandardWriter {
if let value = value as? MyAdvertisementArgs {
super.writeByte(128)
super.writeValue(value.toList())
} else if let value = value as? MyGattCharacteristicArgs {
} else if let value = value as? MyManufacturerSpecificDataArgs {
super.writeByte(129)
super.writeValue(value.toList())
} else if let value = value as? MyGattDescriptorArgs {
super.writeByte(130)
super.writeValue(value.toList())
} else if let value = value as? MyManufacturerSpecificDataArgs {
super.writeByte(131)
super.writeValue(value.toList())
} else if let value = value as? MyPeripheralArgs {
super.writeByte(132)
super.writeByte(130)
super.writeValue(value.toList())
} else {
super.writeValue(value)
@ -629,10 +632,10 @@ class MyCentralManagerFlutterApiCodec: FlutterStandardMessageCodec {
/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift.
protocol MyCentralManagerFlutterApiProtocol {
func onStateChanged(stateNumberArgs stateNumberArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onDiscovered(peripheralArgs peripheralArgsArg: MyPeripheralArgs, rssiArgs rssiArgsArg: Int64, advertisementArgs advertisementArgsArg: MyAdvertisementArgs, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onPeripheralStateChanged(peripheralArgs peripheralArgsArg: MyPeripheralArgs, stateArgs stateArgsArg: Bool, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onCharacteristicValueChanged(characteristicArgs characteristicArgsArg: MyGattCharacteristicArgs, valueArgs valueArgsArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onStateChanged(stateNumberArgs stateNumberArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onDiscovered(peripheralArgs peripheralArgsArg: MyPeripheralArgs, rssiArgs rssiArgsArg: Int64, advertisementArgs advertisementArgsArg: MyAdvertisementArgs, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onConnectionStateChanged(uuidArgs uuidArgsArg: String, stateArgs stateArgsArg: Bool, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onCharacteristicNotified(uuidArgs uuidArgsArg: String, hashCodeArgs hashCodeArgsArg: Int64, valueArgs valueArgsArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void)
}
class MyCentralManagerFlutterApi: MyCentralManagerFlutterApiProtocol {
private let binaryMessenger: FlutterBinaryMessenger
@ -642,28 +645,76 @@ class MyCentralManagerFlutterApi: MyCentralManagerFlutterApiProtocol {
var codec: FlutterStandardMessageCodec {
return MyCentralManagerFlutterApiCodec.shared
}
func onStateChanged(stateNumberArgs stateNumberArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerFlutterApi.onStateChanged", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([stateNumberArgsArg] as [Any?]) { _ in
completion(.success(Void()))
func onStateChanged(stateNumberArgs stateNumberArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channelName: String = "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerFlutterApi.onStateChanged"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([stateNumberArgsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName:channelName)))
return
}
if (listResponse.count > 1) {
let code: String = listResponse[0] as! String
let message: String? = nilOrValue(listResponse[1])
let details: String? = nilOrValue(listResponse[2])
completion(.failure(FlutterError(code: code, message: message, details: details)));
} else {
completion(.success(Void()))
}
}
}
func onDiscovered(peripheralArgs peripheralArgsArg: MyPeripheralArgs, rssiArgs rssiArgsArg: Int64, advertisementArgs advertisementArgsArg: MyAdvertisementArgs, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerFlutterApi.onDiscovered", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([peripheralArgsArg, rssiArgsArg, advertisementArgsArg] as [Any?]) { _ in
completion(.success(Void()))
func onDiscovered(peripheralArgs peripheralArgsArg: MyPeripheralArgs, rssiArgs rssiArgsArg: Int64, advertisementArgs advertisementArgsArg: MyAdvertisementArgs, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channelName: String = "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerFlutterApi.onDiscovered"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([peripheralArgsArg, rssiArgsArg, advertisementArgsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName:channelName)))
return
}
if (listResponse.count > 1) {
let code: String = listResponse[0] as! String
let message: String? = nilOrValue(listResponse[1])
let details: String? = nilOrValue(listResponse[2])
completion(.failure(FlutterError(code: code, message: message, details: details)));
} else {
completion(.success(Void()))
}
}
}
func onPeripheralStateChanged(peripheralArgs peripheralArgsArg: MyPeripheralArgs, stateArgs stateArgsArg: Bool, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerFlutterApi.onPeripheralStateChanged", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([peripheralArgsArg, stateArgsArg] as [Any?]) { _ in
completion(.success(Void()))
func onConnectionStateChanged(uuidArgs uuidArgsArg: String, stateArgs stateArgsArg: Bool, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channelName: String = "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerFlutterApi.onConnectionStateChanged"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([uuidArgsArg, stateArgsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName:channelName)))
return
}
if (listResponse.count > 1) {
let code: String = listResponse[0] as! String
let message: String? = nilOrValue(listResponse[1])
let details: String? = nilOrValue(listResponse[2])
completion(.failure(FlutterError(code: code, message: message, details: details)));
} else {
completion(.success(Void()))
}
}
}
func onCharacteristicValueChanged(characteristicArgs characteristicArgsArg: MyGattCharacteristicArgs, valueArgs valueArgsArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerFlutterApi.onCharacteristicValueChanged", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([characteristicArgsArg, valueArgsArg] as [Any?]) { _ in
completion(.success(Void()))
func onCharacteristicNotified(uuidArgs uuidArgsArg: String, hashCodeArgs hashCodeArgsArg: Int64, valueArgs valueArgsArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channelName: String = "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralManagerFlutterApi.onCharacteristicNotified"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([uuidArgsArg, hashCodeArgsArg, valueArgsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName:channelName)))
return
}
if (listResponse.count > 1) {
let code: String = listResponse[0] as! String
let message: String? = nilOrValue(listResponse[1])
let details: String? = nilOrValue(listResponse[2])
completion(.failure(FlutterError(code: code, message: message, details: details)));
} else {
completion(.success(Void()))
}
}
}
}
@ -680,8 +731,6 @@ private class MyPeripheralManagerHostApiCodecReader: FlutterStandardReader {
return MyGattServiceArgs.fromList(self.readValue() as! [Any?])
case 132:
return MyManufacturerSpecificDataArgs.fromList(self.readValue() as! [Any?])
case 133:
return MyPeripheralManagerArgs.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
@ -705,9 +754,6 @@ private class MyPeripheralManagerHostApiCodecWriter: FlutterStandardWriter {
} else if let value = value as? MyManufacturerSpecificDataArgs {
super.writeByte(132)
super.writeValue(value.toList())
} else if let value = value as? MyPeripheralManagerArgs {
super.writeByte(133)
super.writeValue(value.toList())
} else {
super.writeValue(value)
}
@ -730,16 +776,15 @@ class MyPeripheralManagerHostApiCodec: FlutterStandardMessageCodec {
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol MyPeripheralManagerHostApi {
func setUp(completion: @escaping (Result<MyPeripheralManagerArgs, Error>) -> Void)
func setUp() throws
func addService(serviceArgs: MyGattServiceArgs, completion: @escaping (Result<Void, Error>) -> Void)
func removeService(serviceHashCodeArgs: Int64) throws
func removeService(hashCodeArgs: Int64) throws
func clearServices() throws
func startAdvertising(advertisementArgs: MyAdvertisementArgs, completion: @escaping (Result<Void, Error>) -> Void)
func stopAdvertising() throws
func getMaximumWriteLength(centralHashCodeArgs: Int64) throws -> Int64
func sendReadCharacteristicReply(centralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, idArgs: Int64, offsetArgs: Int64, statusArgs: Bool, valueArgs: FlutterStandardTypedData) throws
func sendWriteCharacteristicReply(centralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, idArgs: Int64, offsetArgs: Int64, statusArgs: Bool) throws
func notifyCharacteristicValueChanged(centralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void)
func getMaximumUpdateValueLength(uuidArgs: String) throws -> Int64
func respond(idArgs: Int64, errorNumberArgs: Int64, valueArgs: FlutterStandardTypedData?) throws
func updateCharacteristic(hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, uuidsArgs: [String]?, completion: @escaping (Result<Void, Error>) -> Void)
}
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
@ -751,13 +796,11 @@ class MyPeripheralManagerHostApiSetup {
let setUpChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerHostApi.setUp", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
setUpChannel.setMessageHandler { _, reply in
api.setUp() { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
do {
try api.setUp()
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
}
}
} else {
@ -784,9 +827,9 @@ class MyPeripheralManagerHostApiSetup {
if let api = api {
removeServiceChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let serviceHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let hashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
do {
try api.removeService(serviceHashCodeArgs: serviceHashCodeArgsArg)
try api.removeService(hashCodeArgs: hashCodeArgsArg)
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
@ -838,68 +881,46 @@ class MyPeripheralManagerHostApiSetup {
} else {
stopAdvertisingChannel.setMessageHandler(nil)
}
let getMaximumWriteLengthChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerHostApi.getMaximumWriteLength", binaryMessenger: binaryMessenger, codec: codec)
let getMaximumUpdateValueLengthChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerHostApi.getMaximumUpdateValueLength", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
getMaximumWriteLengthChannel.setMessageHandler { message, reply in
getMaximumUpdateValueLengthChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let centralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let uuidArgsArg = args[0] as! String
do {
let result = try api.getMaximumWriteLength(centralHashCodeArgs: centralHashCodeArgsArg)
let result = try api.getMaximumUpdateValueLength(uuidArgs: uuidArgsArg)
reply(wrapResult(result))
} catch {
reply(wrapError(error))
}
}
} else {
getMaximumWriteLengthChannel.setMessageHandler(nil)
getMaximumUpdateValueLengthChannel.setMessageHandler(nil)
}
let sendReadCharacteristicReplyChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerHostApi.sendReadCharacteristicReply", binaryMessenger: binaryMessenger, codec: codec)
let respondChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerHostApi.respond", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
sendReadCharacteristicReplyChannel.setMessageHandler { message, reply in
respondChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let centralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let characteristicHashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let idArgsArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32)
let offsetArgsArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32)
let statusArgsArg = args[4] as! Bool
let valueArgsArg = args[5] as! FlutterStandardTypedData
let idArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let errorNumberArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let valueArgsArg: FlutterStandardTypedData? = nilOrValue(args[2])
do {
try api.sendReadCharacteristicReply(centralHashCodeArgs: centralHashCodeArgsArg, characteristicHashCodeArgs: characteristicHashCodeArgsArg, idArgs: idArgsArg, offsetArgs: offsetArgsArg, statusArgs: statusArgsArg, valueArgs: valueArgsArg)
try api.respond(idArgs: idArgsArg, errorNumberArgs: errorNumberArgsArg, valueArgs: valueArgsArg)
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
}
}
} else {
sendReadCharacteristicReplyChannel.setMessageHandler(nil)
respondChannel.setMessageHandler(nil)
}
let sendWriteCharacteristicReplyChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerHostApi.sendWriteCharacteristicReply", binaryMessenger: binaryMessenger, codec: codec)
let updateCharacteristicChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerHostApi.updateCharacteristic", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
sendWriteCharacteristicReplyChannel.setMessageHandler { message, reply in
updateCharacteristicChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let centralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let characteristicHashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let idArgsArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32)
let offsetArgsArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32)
let statusArgsArg = args[4] as! Bool
do {
try api.sendWriteCharacteristicReply(centralHashCodeArgs: centralHashCodeArgsArg, characteristicHashCodeArgs: characteristicHashCodeArgsArg, idArgs: idArgsArg, offsetArgs: offsetArgsArg, statusArgs: statusArgsArg)
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
}
}
} else {
sendWriteCharacteristicReplyChannel.setMessageHandler(nil)
}
let notifyCharacteristicValueChangedChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerHostApi.notifyCharacteristicValueChanged", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
notifyCharacteristicValueChangedChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let centralHashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let characteristicHashCodeArgsArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32)
let valueArgsArg = args[2] as! FlutterStandardTypedData
api.notifyCharacteristicValueChanged(centralHashCodeArgs: centralHashCodeArgsArg, characteristicHashCodeArgs: characteristicHashCodeArgsArg, valueArgs: valueArgsArg) { result in
let hashCodeArgsArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32)
let valueArgsArg = args[1] as! FlutterStandardTypedData
let uuidsArgsArg: [String]? = nilOrValue(args[2])
api.updateCharacteristic(hashCodeArgs: hashCodeArgsArg, valueArgs: valueArgsArg, uuidsArgs: uuidsArgsArg) { result in
switch result {
case .success:
reply(wrapResult(nil))
@ -909,7 +930,7 @@ class MyPeripheralManagerHostApiSetup {
}
}
} else {
notifyCharacteristicValueChangedChannel.setMessageHandler(nil)
updateCharacteristicChannel.setMessageHandler(nil)
}
}
}
@ -918,10 +939,6 @@ private class MyPeripheralManagerFlutterApiCodecReader: FlutterStandardReader {
switch type {
case 128:
return MyCentralArgs.fromList(self.readValue() as! [Any?])
case 129:
return MyGattCharacteristicArgs.fromList(self.readValue() as! [Any?])
case 130:
return MyGattDescriptorArgs.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
@ -933,12 +950,6 @@ private class MyPeripheralManagerFlutterApiCodecWriter: FlutterStandardWriter {
if let value = value as? MyCentralArgs {
super.writeByte(128)
super.writeValue(value.toList())
} else if let value = value as? MyGattCharacteristicArgs {
super.writeByte(129)
super.writeValue(value.toList())
} else if let value = value as? MyGattDescriptorArgs {
super.writeByte(130)
super.writeValue(value.toList())
} else {
super.writeValue(value)
}
@ -961,10 +972,10 @@ class MyPeripheralManagerFlutterApiCodec: FlutterStandardMessageCodec {
/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift.
protocol MyPeripheralManagerFlutterApiProtocol {
func onStateChanged(stateNumberArgs stateNumberArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onReadCharacteristicCommandReceived(centralArgs centralArgsArg: MyCentralArgs, characteristicArgs characteristicArgsArg: MyGattCharacteristicArgs, idArgs idArgsArg: Int64, offsetArgs offsetArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onWriteCharacteristicCommandReceived(centralArgs centralArgsArg: MyCentralArgs, characteristicArgs characteristicArgsArg: MyGattCharacteristicArgs, idArgs idArgsArg: Int64, offsetArgs offsetArgsArg: Int64, valueArgs valueArgsArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onNotifyCharacteristicCommandReceived(centralArgs centralArgsArg: MyCentralArgs, characteristicArgs characteristicArgsArg: MyGattCharacteristicArgs, stateArgs stateArgsArg: Bool, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onStateChanged(stateNumberArgs stateNumberArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onCharacteristicReadRequest(centralArgs centralArgsArg: MyCentralArgs, hashCodeArgs hashCodeArgsArg: Int64, idArgs idArgsArg: Int64, offsetArgs offsetArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onCharacteristicWriteRequest(centralArgs centralArgsArg: MyCentralArgs, hashCodeArgs hashCodeArgsArg: Int64, idArgs idArgsArg: Int64, offsetArgs offsetArgsArg: Int64, valueArgs valueArgsArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void)
func onCharacteristicNotifyStateChanged(centralArgs centralArgsArg: MyCentralArgs, hashCodeArgs hashCodeArgsArg: Int64, stateArgs stateArgsArg: Bool, completion: @escaping (Result<Void, FlutterError>) -> Void)
}
class MyPeripheralManagerFlutterApi: MyPeripheralManagerFlutterApiProtocol {
private let binaryMessenger: FlutterBinaryMessenger
@ -974,28 +985,76 @@ class MyPeripheralManagerFlutterApi: MyPeripheralManagerFlutterApiProtocol {
var codec: FlutterStandardMessageCodec {
return MyPeripheralManagerFlutterApiCodec.shared
}
func onStateChanged(stateNumberArgs stateNumberArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerFlutterApi.onStateChanged", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([stateNumberArgsArg] as [Any?]) { _ in
completion(.success(Void()))
func onStateChanged(stateNumberArgs stateNumberArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channelName: String = "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerFlutterApi.onStateChanged"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([stateNumberArgsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName:channelName)))
return
}
if (listResponse.count > 1) {
let code: String = listResponse[0] as! String
let message: String? = nilOrValue(listResponse[1])
let details: String? = nilOrValue(listResponse[2])
completion(.failure(FlutterError(code: code, message: message, details: details)));
} else {
completion(.success(Void()))
}
}
}
func onReadCharacteristicCommandReceived(centralArgs centralArgsArg: MyCentralArgs, characteristicArgs characteristicArgsArg: MyGattCharacteristicArgs, idArgs idArgsArg: Int64, offsetArgs offsetArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerFlutterApi.onReadCharacteristicCommandReceived", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([centralArgsArg, characteristicArgsArg, idArgsArg, offsetArgsArg] as [Any?]) { _ in
completion(.success(Void()))
func onCharacteristicReadRequest(centralArgs centralArgsArg: MyCentralArgs, hashCodeArgs hashCodeArgsArg: Int64, idArgs idArgsArg: Int64, offsetArgs offsetArgsArg: Int64, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channelName: String = "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerFlutterApi.onCharacteristicReadRequest"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([centralArgsArg, hashCodeArgsArg, idArgsArg, offsetArgsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName:channelName)))
return
}
if (listResponse.count > 1) {
let code: String = listResponse[0] as! String
let message: String? = nilOrValue(listResponse[1])
let details: String? = nilOrValue(listResponse[2])
completion(.failure(FlutterError(code: code, message: message, details: details)));
} else {
completion(.success(Void()))
}
}
}
func onWriteCharacteristicCommandReceived(centralArgs centralArgsArg: MyCentralArgs, characteristicArgs characteristicArgsArg: MyGattCharacteristicArgs, idArgs idArgsArg: Int64, offsetArgs offsetArgsArg: Int64, valueArgs valueArgsArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerFlutterApi.onWriteCharacteristicCommandReceived", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([centralArgsArg, characteristicArgsArg, idArgsArg, offsetArgsArg, valueArgsArg] as [Any?]) { _ in
completion(.success(Void()))
func onCharacteristicWriteRequest(centralArgs centralArgsArg: MyCentralArgs, hashCodeArgs hashCodeArgsArg: Int64, idArgs idArgsArg: Int64, offsetArgs offsetArgsArg: Int64, valueArgs valueArgsArg: FlutterStandardTypedData, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channelName: String = "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerFlutterApi.onCharacteristicWriteRequest"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([centralArgsArg, hashCodeArgsArg, idArgsArg, offsetArgsArg, valueArgsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName:channelName)))
return
}
if (listResponse.count > 1) {
let code: String = listResponse[0] as! String
let message: String? = nilOrValue(listResponse[1])
let details: String? = nilOrValue(listResponse[2])
completion(.failure(FlutterError(code: code, message: message, details: details)));
} else {
completion(.success(Void()))
}
}
}
func onNotifyCharacteristicCommandReceived(centralArgs centralArgsArg: MyCentralArgs, characteristicArgs characteristicArgsArg: MyGattCharacteristicArgs, stateArgs stateArgsArg: Bool, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerFlutterApi.onNotifyCharacteristicCommandReceived", binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([centralArgsArg, characteristicArgsArg, stateArgsArg] as [Any?]) { _ in
completion(.success(Void()))
func onCharacteristicNotifyStateChanged(centralArgs centralArgsArg: MyCentralArgs, hashCodeArgs hashCodeArgsArg: Int64, stateArgs stateArgsArg: Bool, completion: @escaping (Result<Void, FlutterError>) -> Void) {
let channelName: String = "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyPeripheralManagerFlutterApi.onCharacteristicNotifyStateChanged"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([centralArgsArg, hashCodeArgsArg, stateArgsArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName:channelName)))
return
}
if (listResponse.count > 1) {
let code: String = listResponse[0] as! String
let message: String? = nilOrValue(listResponse[1])
let details: String? = nilOrValue(listResponse[2])
completion(.failure(FlutterError(code: code, message: message, details: details)));
} else {
completion(.success(Void()))
}
}
}
}

View File

@ -16,85 +16,40 @@ import FlutterMacOS
#error("Unsupported platform.")
#endif
// This extension of Error is required to do use FlutterError in any Swift code.
extension FlutterError: Error {}
extension CBManagerState {
func toArgs() -> MyBluetoothLowEnergyStateArgs {
switch self {
case .unauthorized:
return .unauthorized
case .poweredOff:
return .poweredOff
case .poweredOn:
return .poweredOn
default:
return .unsupported
// ToObj
extension [MyGattCharacteristicPropertyArgs] {
func toProperties() -> CBCharacteristicProperties {
var properties: CBCharacteristicProperties = []
for args in self {
switch args {
case .read:
properties.insert(.read)
case .write:
properties.insert(.write)
case .writeWithoutResponse:
properties.insert(.writeWithoutResponse)
case .notify:
properties.insert(.notify)
case .indicate:
properties.insert(.indicate)
}
}
}
}
extension CBPeer {
var uuidArgs: String { identifier.uuidString }
}
extension CBCentral {
func toArgs() -> MyCentralArgs {
let hashCodeArgs = Int64(hash)
return MyCentralArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs)
}
}
extension CBPeripheral {
func toArgs() -> MyPeripheralArgs {
let hashCodeArgs = Int64(hash)
return MyPeripheralArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs)
}
}
extension CBAttribute {
var uuidArgs: String { uuid.uuidString }
}
extension CBService {
func toArgs(_ characteristicsArgs: [MyGattCharacteristicArgs]) -> MyGattServiceArgs {
let hashCodeArgs = Int64(hash)
return MyGattServiceArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, characteristicsArgs: characteristicsArgs)
}
}
extension CBCharacteristic {
func toArgs(_ descriptorsArgs: [MyGattDescriptorArgs]) -> MyGattCharacteristicArgs {
let hashCodeArgs = Int64(hash)
return MyGattCharacteristicArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, propertyNumbersArgs: propertyNumbersArgs, descriptorsArgs: descriptorsArgs)
return properties
}
var propertyNumbersArgs: [Int64] {
var propertiesArgs = [MyGattCharacteristicPropertyArgs]()
let properties = self.properties
if properties.contains(.read) {
propertiesArgs.append(.read)
func toPermissions() -> CBAttributePermissions {
var permissions: CBAttributePermissions = []
for args in self {
switch args {
case .read:
permissions.insert(.readable)
case .write, .writeWithoutResponse:
permissions.insert(.writeable)
default:
continue
}
}
if properties.contains(.write) {
propertiesArgs.append(.write)
}
if properties.contains(.writeWithoutResponse) {
propertiesArgs.append(.writeWithoutResponse)
}
if properties.contains(.notify) {
propertiesArgs.append(.notify)
}
if properties.contains(.indicate) {
propertiesArgs.append(.indicate)
}
return propertiesArgs.map { args in Int64(args.rawValue) }
}
}
extension CBDescriptor {
func toArgs() -> MyGattDescriptorArgs {
let hashCodeArgs = Int64(hash)
return MyGattDescriptorArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs)
return permissions
}
}
@ -109,21 +64,151 @@ extension MyGattCharacteristicWriteTypeArgs {
}
}
extension String {
var data: Data { data(using: String.Encoding.utf8)! }
}
extension NSNumber {
var data: Data {
var source = self
return Data(bytes: &source, count: MemoryLayout<NSNumber>.size)
extension MyGattErrorArgs {
func toError() -> CBATTError.Code {
switch self {
case .success:
return .success
case .invalidHandle:
return .invalidHandle
case .readNotPermitted:
return .readNotPermitted
case .writeNotPermitted:
return .writeNotPermitted
case .invalidPDU:
return .invalidPdu
case .insufficientAuthentication:
return .insufficientAuthentication
case .requestNotSupported:
return .requestNotSupported
case .invalidOffset:
return .invalidOffset
case .insufficientAuthorization:
return .insufficientAuthorization
case .prepareQueueFull:
return .prepareQueueFull
case .attributeNotFound:
return .attributeNotFound
case .attributeNotLong:
return .attributeNotLong
case .insufficientEncryptionKeySize:
return .insufficientEncryptionKeySize
case .invalidAttributeValueLength:
return .invalidAttributeValueLength
case .unlikelyError:
return .unlikelyError
case .insufficientEncryption:
return .insufficientEncryption
case .unsupportedGroupType:
return .unsupportedGroupType
case .insufficientResources:
return .insufficientResources
}
}
}
extension UInt16 {
var data: Data {
var source = self
return Data(bytes: &source, count: MemoryLayout<UInt16>.size)
extension MyAdvertisementArgs {
func toAdvertisement() -> [String : Any] {
// CoreBluetooth only support `CBAdvertisementDataLocalNameKey` and `CBAdvertisementDataServiceUUIDsKey`
// see https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager/1393252-startadvertising
var advertisement = [String: Any]()
if nameArgs != nil {
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)
}
advertisement[CBAdvertisementDataServiceUUIDsKey] = serviceUUIDs
}
return advertisement
}
}
extension MyGattDescriptorArgs {
func toDescriptor() -> CBMutableDescriptor {
let type = uuidArgs.toCBUUID()
let value = valueArgs?.data
return CBMutableDescriptor(type: type, value: value)
}
}
extension MyGattCharacteristicArgs {
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 properties = propertiesArgs.toProperties()
let permissions = propertiesArgs.toPermissions()
return CBMutableCharacteristic(type: type, properties: properties, value: nil, permissions: permissions)
}
}
extension MyGattServiceArgs {
func toService() -> CBMutableService {
let type = uuidArgs.toCBUUID()
let primary = true
return CBMutableService(type: type, primary: primary)
}
}
extension Int64 {
func toInt() -> Int {
return Int(self)
}
}
extension String {
func toCBUUID() -> CBUUID {
return CBUUID(string: self)
}
}
// ToArgs
extension CBManagerState {
func toArgs() -> MyBluetoothLowEnergyStateArgs {
switch self {
case .resetting:
return .resetting
case .unsupported:
return .unsupported
case .unauthorized:
return .unauthorized
case .poweredOff:
return .poweredOff
case .poweredOn:
return .poweredOn
default:
return .unknown
}
}
}
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
}
}
}
@ -145,160 +230,105 @@ extension [String: Any] {
}
}
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 CBCentral {
func toArgs() -> MyCentralArgs {
let uuidArgs = identifier.toArgs()
return MyCentralArgs(uuidArgs: uuidArgs)
}
}
extension MyAdvertisementArgs {
func toAdvertisement() throws -> [String : Any] {
// CoreBluetooth only support `CBAdvertisementDataLocalNameKey` and `CBAdvertisementDataServiceUUIDsKey`, see https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager/1393252-startadvertising
var advertisement = [String: Any]()
if nameArgs != nil {
let name = nameArgs!
advertisement[CBAdvertisementDataLocalNameKey] = name
}
if serviceUUIDsArgs.count > 0 {
var serviceUUIDs = [CBUUID]()
for args in serviceUUIDsArgs {
guard let uuidArgs = args else {
throw MyError.illegalArgument
}
let uuid = CBUUID(string: uuidArgs)
serviceUUIDs.append(uuid)
}
advertisement[CBAdvertisementDataServiceUUIDsKey] = serviceUUIDs
}
// if serviceDataArgs.count > 0 {
// var serviceData = [CBUUID: Data]()
// for args in serviceDataArgs {
// guard let uuidArgs = args.key else {
// throw MyError.illegalArgument
// }
// guard let dataArgs = args.value else {
// throw MyError.illegalArgument
// }
// let uuid = CBUUID(string: uuidArgs)
// let data = dataArgs.data
// serviceData[uuid] = data
// }
// advertisement[CBAdvertisementDataServiceDataKey] = serviceData
// }
// if manufacturerSpecificDataArgs != nil {
// let manufacturerSpecificData = manufacturerSpecificDataArgs!.toManufacturerSpecificData()
// advertisement[CBAdvertisementDataManufacturerDataKey] = manufacturerSpecificData
// }
return advertisement
extension CBPeripheral {
func toArgs() -> MyPeripheralArgs {
let uuidArgs = identifier.toArgs()
return MyPeripheralArgs(uuidArgs: uuidArgs)
}
}
//extension MyManufacturerSpecificDataArgs {
// func toManufacturerSpecificData() -> Data {
// let id = UInt16(idArgs).data
// let data = dataArgs.data
// return id + data
// }
//}
extension MyGattServiceArgs {
func toService() -> CBMutableService {
let type = CBUUID(string: uuidArgs)
let primary = true
return CBMutableService(type: type, primary: primary)
extension CBDescriptor {
func toArgs() -> MyGattDescriptorArgs {
let hashCodeArgs = hash.toInt64()
let uuidArgs = uuid.toArgs()
return MyGattDescriptorArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs)
}
}
extension MyGattCharacteristicArgs {
func toCharacteristic() -> CBMutableCharacteristic {
let type = CBUUID(string: uuidArgs)
return CBMutableCharacteristic(type: type, properties: properties, value: nil, permissions: permissions)
}
var properties: CBCharacteristicProperties {
var properties: CBCharacteristicProperties = []
for args in propertyNumbersArgs {
guard let rawArgs = args else {
continue
}
let rawValue = Int(rawArgs)
let property = MyGattCharacteristicPropertyArgs(rawValue: rawValue)
switch property {
case .read:
properties.insert(.read)
case .write:
properties.insert(.write)
case .writeWithoutResponse:
properties.insert(.writeWithoutResponse)
case .notify:
properties.insert(.notify)
case .indicate:
properties.insert(.indicate)
default:
continue
}
}
return properties
}
var permissions: CBAttributePermissions {
var permissions: CBAttributePermissions = []
for args in propertyNumbersArgs {
guard let rawArgs = args else {
continue
}
let rawValue = Int(rawArgs)
let property = MyGattCharacteristicPropertyArgs(rawValue: rawValue)
switch property {
case .read:
permissions.insert(.readable)
case .write, .writeWithoutResponse:
permissions.insert(.writeable)
default:
continue
}
}
return permissions
extension CBCharacteristic {
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)
}
}
extension MyGattDescriptorArgs {
func toDescriptor() -> CBMutableDescriptor {
let type = CBUUID(string: uuidArgs)
let value = valueArgs?.data
return CBMutableDescriptor(type: type, value: value)
extension CBCharacteristicProperties {
func toArgs() -> [MyGattCharacteristicPropertyArgs] {
var args = [MyGattCharacteristicPropertyArgs]()
if contains(.read) {
args.append(.read)
}
if contains(.write) {
args.append(.write)
}
if contains(.writeWithoutResponse) {
args.append(.writeWithoutResponse)
}
if contains(.notify) {
args.append(.notify)
}
if contains(.indicate) {
args.append(.indicate)
}
return args
}
}
extension CBService {
func toArgs() -> MyGattServiceArgs {
let hashCodeArgs = hash.toInt64()
let uuidArgs = uuid.toArgs()
let characteristicsArgs = characteristics?.map { characteristic in characteristic.toArgs() } ?? []
return MyGattServiceArgs(hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, characteristicsArgs: characteristicsArgs)
}
}
extension Int {
func coerceIn(_ minimum: Int, _ maximum: Int) throws -> Int {
if minimum > maximum {
throw MyError.illegalArgument
}
if self < minimum {
return minimum
}
if self > maximum {
return maximum
}
return self
func toInt64() -> Int64 {
return Int64(self)
}
}
extension Dictionary {
mutating func getOrPut(_ key: Key, _ defaultValue: () -> Value) -> Value {
guard let value = self[key] else {
let value1 = defaultValue()
self[key] = value1
return value1
}
return value
extension UUID {
func toArgs() -> String {
return uuidString.lowercased()
}
}
extension CBUUID {
func toArgs() -> String {
return uuidString.lowercased()
}
}
// 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)
}
}

View File

@ -17,220 +17,192 @@ import FlutterMacOS
#endif
class MyCentralManager: MyCentralManagerHostApi {
init(_ binaryMessenger: FlutterBinaryMessenger) {
self.binaryMessenger = binaryMessenger
private let _api: MyCentralManagerFlutterApi
private let _centralManager: CBCentralManager
private lazy var _centralManagerDelegate = 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 _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]]
init(messenger: FlutterBinaryMessenger) {
_api = MyCentralManagerFlutterApi(binaryMessenger: messenger)
_centralManager = CBCentralManager()
_peripherals = [:]
_services = [:]
_characteristics = [:]
_descriptors = [:]
_connectCompletions = [:]
_disconnectCompletions = [:]
_readRssiCompletions = [:]
_discoverServicesCompletions = [:]
_discoverCharacteristicsCompletions = [:]
_discoverDescriptorsCompletions = [:]
_readCharacteristicCompletions = [:]
_writeCharacteristicCompletions = [:]
_setCharacteristicNotifyStateCompletions = [:]
_readDescriptorCompletions = [:]
_writeDescriptorCompletions = [:]
}
private let binaryMessenger: FlutterBinaryMessenger
private let centralManager = CBCentralManager()
private lazy var api = MyCentralManagerFlutterApi(binaryMessenger: binaryMessenger)
private lazy var centralManagerDelegate = MyCentralManagerDelegate(self)
private lazy var peripheralDelegate = MyPeripheralDelegate(self)
private var peripherals = [Int64: CBPeripheral]()
private var services = [Int64: CBService]()
private var characteristics = [Int64: CBCharacteristic]()
private var descriptors = [Int64: CBDescriptor]()
private var peripheralsArgs = [Int: MyPeripheralArgs]()
private var servicesArgsOfPeripheralsArgs = [Int64: [MyGattServiceArgs]]()
private var servicesArgs = [Int: MyGattServiceArgs]()
private var characteristicsArgs = [Int: MyGattCharacteristicArgs]()
private var descriptorsArgs = [Int: MyGattDescriptorArgs]()
private var setUpCompletion: ((Result<MyCentralManagerArgs, Error>) -> Void)?
private var connectCompletions = [Int64: (Result<Void, Error>) -> Void]()
private var disconnectCompletions = [Int64: (Result<Void, Error>) -> Void]()
private var readRssiCompletions = [Int64: (Result<Int64, Error>) -> Void]()
private var discoverGattCompletions = [Int64: (Result<[MyGattServiceArgs], Error>) -> Void]()
private var unfinishedServices = [Int64: [CBService]]()
private var unfinishedCharacteristics = [Int64: [CBCharacteristic]]()
private var readCharacteristicCompletions = [Int64: (Result<FlutterStandardTypedData, Error>) -> Void]()
private var writeCharacteristicCompletions = [Int64: (Result<Void, Error>) -> Void]()
private var notifyCharacteristicCompletions = [Int64: (Result<Void, Error>) -> Void]()
private var readDescriptorCompletions = [Int64: (Result<FlutterStandardTypedData, Error>) -> Void]()
private var writeDescriptorCompletions = [Int64: (Result<Void, Error>) -> Void]()
func setUp(completion: @escaping (Result<MyCentralManagerArgs, Error>) -> Void) {
do {
if setUpCompletion != nil {
throw MyError.illegalState
}
try tearDown()
centralManager.delegate = centralManagerDelegate
if centralManager.state == .unknown {
setUpCompletion = completion
} else {
let stateArgs = centralManager.state.toArgs()
let stateNumberArgs = Int64(stateArgs.rawValue)
let args = MyCentralManagerArgs(stateNumberArgs: stateNumberArgs)
completion(.success(args))
}
} catch {
completion(.failure(error))
func setUp() throws {
_clearState()
if _centralManager.delegate == nil {
_centralManager.delegate = _centralManagerDelegate
}
}
func tearDown() throws {
if(centralManager.isScanning) {
centralManager.stopScan()
}
for peripheral in peripherals.values {
if peripheral.state != .disconnected {
centralManager.cancelPeripheralConnection(peripheral)
}
}
peripherals.removeAll()
services.removeAll()
characteristics.removeAll()
descriptors.removeAll()
peripheralsArgs.removeAll()
servicesArgsOfPeripheralsArgs.removeAll()
servicesArgs.removeAll()
characteristicsArgs.removeAll()
descriptorsArgs.removeAll()
setUpCompletion = nil
connectCompletions.removeAll()
disconnectCompletions.removeAll()
readRssiCompletions.removeAll()
discoverGattCompletions.removeAll()
unfinishedServices.removeAll()
unfinishedCharacteristics.removeAll()
readCharacteristicCompletions.removeAll()
writeCharacteristicCompletions.removeAll()
notifyCharacteristicCompletions.removeAll()
readDescriptorCompletions.removeAll()
writeDescriptorCompletions.removeAll()
_onStateChanged()
}
func startDiscovery() throws {
let options = [CBCentralManagerScanOptionAllowDuplicatesKey: true]
centralManager.scanForPeripherals(withServices: nil, options: options)
_centralManager.scanForPeripherals(withServices: nil, options: options)
}
func stopDiscovery() throws {
centralManager.stopScan()
_centralManager.stopScan()
}
func connect(peripheralHashCodeArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
func connect(uuidArgs: String, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let unfinishedCompletion = connectCompletions[peripheralHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
centralManager.connect(peripheral)
connectCompletions[peripheralHashCodeArgs] = completion
_centralManager.connect(peripheral)
_connectCompletions[uuidArgs] = completion
} catch {
completion(.failure(error))
}
}
func disconnect(peripheralHashCodeArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
func disconnect(uuidArgs: String, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let unfinishedCompletion = disconnectCompletions[peripheralHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
centralManager.cancelPeripheralConnection(peripheral)
disconnectCompletions[peripheralHashCodeArgs] = completion
_centralManager.cancelPeripheralConnection(peripheral)
_disconnectCompletions[uuidArgs] = completion
} catch {
completion(.failure(error))
}
}
func getMaximumWriteLength(peripheralHashCodeArgs: Int64, typeNumberArgs: Int64) throws -> Int64 {
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
func getMaximumWriteValueLength(uuidArgs: String, typeNumberArgs: Int64) throws -> Int64 {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
let typeRawValue = Int(typeNumberArgs)
guard let typeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: typeRawValue) else {
let typeNumber = typeNumberArgs.toInt()
guard let typeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: typeNumber) else {
throw MyError.illegalArgument
}
let type = typeArgs.toWriteType()
let maximumWriteLength = try peripheral.maximumWriteValueLength(for: type).coerceIn(20, 512)
let maximumWriteLengthArgs = Int64(maximumWriteLength)
return maximumWriteLengthArgs
let maximumWriteValueLength = peripheral.maximumWriteValueLength(for: type)
let maximumWriteValueLengthArgs = maximumWriteValueLength.toInt64()
return maximumWriteValueLengthArgs
}
func readRSSI(peripheralHashCodeArgs: Int64, completion: @escaping (Result<Int64, Error>) -> Void) {
func readRSSI(uuidArgs: String, completion: @escaping (Result<Int64, Error>) -> Void) {
do {
let unfinishedCompletion = readRssiCompletions[peripheralHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
peripheral.readRSSI()
readRssiCompletions[peripheralHashCodeArgs] = completion
_readRssiCompletions[uuidArgs] = completion
} catch {
completion(.failure(error))
}
}
func discoverGATT(peripheralHashCodeArgs: Int64, completion: @escaping (Result<[MyGattServiceArgs], Error>) -> Void) {
func discoverServices(uuidArgs: String, completion: @escaping (Result<[MyGattServiceArgs], Error>) -> Void) {
do {
let unfinishedCompletion = discoverGattCompletions[peripheralHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
peripheral.discoverServices(nil)
discoverGattCompletions[peripheralHashCodeArgs] = completion
_discoverServicesCompletions[uuidArgs] = completion
} catch {
completion(.failure(error))
}
}
func readCharacteristic(peripheralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
func discoverCharacteristics(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<[MyGattCharacteristicArgs], Error>) -> Void) {
do {
let unfinishedCompletion = readCharacteristicCompletions[characteristicHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let characteristic = characteristics[characteristicHashCodeArgs] else {
guard let service = _retrieveService(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
peripheral.discoverCharacteristics(nil, for: service)
_discoverCharacteristicsCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
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
}
peripheral.discoverDescriptors(for: characteristic)
_discoverDescriptorsCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
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
}
peripheral.readValue(for: characteristic)
readCharacteristicCompletions[characteristicHashCodeArgs] = completion
_readCharacteristicCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func writeCharacteristic(peripheralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, typeNumberArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
func writeCharacteristic(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, typeNumberArgs: Int64, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let unfinishedCompletion = writeCharacteristicCompletions[characteristicHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let characteristic = characteristics[characteristicHashCodeArgs] else {
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
let data = valueArgs.data
let typeRawValue = Int(typeNumberArgs)
guard let typeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: typeRawValue) else {
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[characteristicHashCodeArgs] = completion
_writeCharacteristicCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} else {
completion(.success(()))
}
@ -239,159 +211,149 @@ class MyCentralManager: MyCentralManagerHostApi {
}
}
func notifyCharacteristic(peripheralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, stateArgs: Bool, completion: @escaping (Result<Void, Error>) -> Void) {
func setCharacteristicNotifyState(uuidArgs: String, hashCodeArgs: Int64, stateArgs: Bool, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let unfinishedCompletion = notifyCharacteristicCompletions[characteristicHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let characteristic = characteristics[characteristicHashCodeArgs] else {
guard let characteristic = _retrieveCharacteristic(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
let enabled = stateArgs
peripheral.setNotifyValue(enabled, for: characteristic)
notifyCharacteristicCompletions[characteristicHashCodeArgs] = completion
_setCharacteristicNotifyStateCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func readDescriptor(peripheralHashCodeArgs: Int64, descriptorHashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
func readDescriptor(uuidArgs: String, hashCodeArgs: Int64, completion: @escaping (Result<FlutterStandardTypedData, Error>) -> Void) {
do {
let unfinishedCompletion = readDescriptorCompletions[descriptorHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let descriptor = descriptors[descriptorHashCodeArgs] else {
guard let descriptor = _retrieveDescriptor(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
peripheral.readValue(for: descriptor)
readDescriptorCompletions[descriptorHashCodeArgs] = completion
_readDescriptorCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func writeDescriptor(peripheralHashCodeArgs: Int64, descriptorHashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void) {
func writeDescriptor(uuidArgs: String, hashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void) {
do {
let unfinishedCompletion = writeDescriptorCompletions[descriptorHashCodeArgs]
if unfinishedCompletion != nil {
throw MyError.illegalState
}
guard let peripheral = peripherals[peripheralHashCodeArgs] else {
guard let peripheral = _peripherals[uuidArgs] else {
throw MyError.illegalArgument
}
guard let descriptor = descriptors[descriptorHashCodeArgs] else {
guard let descriptor = _retrieveDescriptor(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs) else {
throw MyError.illegalArgument
}
let data = valueArgs.data
peripheral.writeValue(data, for: descriptor)
writeDescriptorCompletions[descriptorHashCodeArgs] = completion
_writeDescriptorCompletions[uuidArgs, default: [:]][hashCodeArgs] = completion
} catch {
completion(.failure(error))
}
}
func didUpdateState() {
let state = centralManager.state
let stateArgs = state.toArgs()
let stateNumberArgs = Int64(stateArgs.rawValue)
if state != .unknown && setUpCompletion != nil {
let args = MyCentralManagerArgs(stateNumberArgs: stateNumberArgs)
setUpCompletion!(.success(args))
setUpCompletion = nil
}
api.onStateChanged(stateNumberArgs: stateNumberArgs) {_ in }
func didUpdateState(central: CBCentralManager) {
_onStateChanged()
}
func didDiscover(_ peripheral: CBPeripheral, _ advertisementData: [String : Any], _ rssi: NSNumber) {
func didDiscover(central: CBCentralManager, peripheral: CBPeripheral, advertisementData: [String : Any], rssi: NSNumber) {
let peripheralArgs = peripheral.toArgs()
let peripheralHashCode = peripheral.hash
let peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
peripheral.delegate = peripheralDelegate
peripherals[peripheralHashCodeArgs] = peripheral
peripheralsArgs[peripheralHashCode] = peripheralArgs
let uuidArgs = peripheralArgs.uuidArgs
let rssiArgs = rssi.int64Value
let advertisementArgs = advertisementData.toAdvertisementArgs()
api.onDiscovered(peripheralArgs: peripheralArgs, rssiArgs: rssiArgs, advertisementArgs: advertisementArgs) {_ in }
if peripheral.delegate == nil {
peripheral.delegate = _peripheralDelegate
}
_peripherals[uuidArgs] = peripheral
_api.onDiscovered(peripheralArgs: peripheralArgs, rssiArgs: rssiArgs, advertisementArgs: advertisementArgs) {_ in }
}
func didConnect(_ peripheral: CBPeripheral) {
let peripheralHashCode = peripheral.hash
guard let peripheralArgs = peripheralsArgs[peripheralHashCode] else {
return
}
let peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
func didConnect(central: CBCentralManager, peripheral: CBPeripheral) {
let uuidArgs = peripheral.identifier.toArgs()
let stateArgs = true
api.onPeripheralStateChanged(peripheralArgs: peripheralArgs, stateArgs: stateArgs) {_ in }
guard let completion = connectCompletions.removeValue(forKey: peripheralHashCodeArgs) else {
_api.onConnectionStateChanged(uuidArgs: uuidArgs, stateArgs: stateArgs) {_ in }
guard let completion = _connectCompletions.removeValue(forKey: uuidArgs) else {
return
}
completion(.success(()))
}
func didFailToConnect(_ peripheral: CBPeripheral, _ error: Error?) {
let peripheralHashCode = peripheral.hash
guard let peripheralArgs = peripheralsArgs[peripheralHashCode] else {
func didFailToConnect(central: CBCentralManager, peripheral: CBPeripheral, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
guard let completion = _connectCompletions.removeValue(forKey: uuidArgs) else {
return
}
let peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
let completion = connectCompletions.removeValue(forKey: peripheralHashCodeArgs)
completion?(.failure(error ?? MyError.unknown))
completion(.failure(error ?? MyError.unknown))
}
func didDisconnectPeripheral(_ peripheral: CBPeripheral, _ error: Error?) {
let peripheralHashCode = peripheral.hash
guard let peripheralArgs = peripheralsArgs[peripheralHashCode] else {
return
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 errorNotNil = error ?? MyError.unknown
let readRssiCompletion = _readRssiCompletions.removeValue(forKey: uuidArgs)
readRssiCompletion?(.failure(errorNotNil))
let discoverServicesCompletion = _discoverServicesCompletions.removeValue(forKey: uuidArgs)
discoverServicesCompletion?(.failure(errorNotNil))
let discoverCharacteristicsCompletions = _discoverCharacteristicsCompletions.removeValue(forKey: uuidArgs)
if discoverCharacteristicsCompletions != nil {
let completions = discoverCharacteristicsCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
let readRssiCompletion = readRssiCompletions.removeValue(forKey: peripheralHashCodeArgs)
readRssiCompletion?(.failure(error ?? MyError.unknown))
let discoverGattCompletion = discoverGattCompletions.removeValue(forKey: peripheralHashCodeArgs)
discoverGattCompletion?(.failure(error ?? MyError.unknown))
unfinishedServices.removeValue(forKey: peripheralHashCodeArgs)
unfinishedCharacteristics.removeValue(forKey: peripheralHashCodeArgs)
let servicesArgs = servicesArgsOfPeripheralsArgs.removeValue(forKey: peripheralHashCodeArgs) ?? []
for serviceArgs in servicesArgs {
let serviceHashCodeArgs = serviceArgs.hashCodeArgs
let service = services.removeValue(forKey: serviceHashCodeArgs)!
let serviceHashCode = service.hash
self.servicesArgs.removeValue(forKey: serviceHashCode)
let characteristicsArgs = serviceArgs.characteristicsArgs.map { args in args! }
for characteristicArgs in characteristicsArgs {
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
let characteristic = characteristics.removeValue(forKey: characteristicHashCodeArgs)!
let characteristicHashCode = characteristic.hash
self.characteristicsArgs.removeValue(forKey: characteristicHashCode)
let readCharacteristicCompletion = readCharacteristicCompletions.removeValue(forKey: characteristicHashCodeArgs)
let writeCharacteristicCompletion = writeCharacteristicCompletions.removeValue(forKey: characteristicHashCodeArgs)
let notifyCharacteristicCompletion = notifyCharacteristicCompletions.removeValue(forKey: characteristicHashCodeArgs)
readCharacteristicCompletion?(.failure(error ?? MyError.unknown))
writeCharacteristicCompletion?(.failure(error ?? MyError.unknown))
notifyCharacteristicCompletion?(.failure(error ?? MyError.unknown))
let descriptorsArgs = characteristicArgs.descriptorsArgs.map { args in args! }
for descriptorArgs in descriptorsArgs {
let descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
let descriptor = descriptors.removeValue(forKey: descriptorHashCodeArgs)!
let descriptorHashCode = descriptor.hash
self.descriptorsArgs.removeValue(forKey: descriptorHashCode)
let readDescriptorCompletion = readDescriptorCompletions.removeValue(forKey: descriptorHashCodeArgs)
let writeDescriptorCompletion = writeDescriptorCompletions.removeValue(forKey: descriptorHashCodeArgs)
readDescriptorCompletion?(.failure(error ?? MyError.unknown))
writeDescriptorCompletion?(.failure(error ?? MyError.unknown))
}
let discoverDescriptorsCompletions = _discoverDescriptorsCompletions.removeValue(forKey: uuidArgs)
if discoverDescriptorsCompletions != nil {
let completions = discoverDescriptorsCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let readCharacteristicCompletions = _readCharacteristicCompletions.removeValue(forKey: uuidArgs)
if readCharacteristicCompletions != nil {
let completions = readCharacteristicCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let writeCharacteristicCompletions = _writeCharacteristicCompletions.removeValue(forKey: uuidArgs)
if writeCharacteristicCompletions != nil {
let completions = writeCharacteristicCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let notifyCharacteristicCompletions = _setCharacteristicNotifyStateCompletions.removeValue(forKey: uuidArgs)
if notifyCharacteristicCompletions != nil {
let completions = notifyCharacteristicCompletions!.values
for completioin in completions {
completioin(.failure(errorNotNil))
}
}
let readDescriptorCompletions = _readDescriptorCompletions.removeValue(forKey: uuidArgs)
if readDescriptorCompletions != nil {
let completions = readDescriptorCompletions!.values
for completioin in completions {
completioin(.failure(errorNotNil))
}
}
let writeDescriptorCompletions = _writeDescriptorCompletions.removeValue(forKey: uuidArgs)
if writeDescriptorCompletions != nil {
let completions = writeDescriptorCompletions!.values
for completion in completions {
completion(.failure(errorNotNil))
}
}
let stateArgs = false
api.onPeripheralStateChanged(peripheralArgs: peripheralArgs, stateArgs: stateArgs) {_ in }
guard let completion = disconnectCompletions.removeValue(forKey: peripheralHashCodeArgs) else {
_api.onConnectionStateChanged(uuidArgs: uuidArgs, stateArgs: stateArgs) {_ in }
guard let completion = _disconnectCompletions.removeValue(forKey: uuidArgs) else {
return
}
if error == nil {
@ -401,13 +363,9 @@ class MyCentralManager: MyCentralManagerHostApi {
}
}
func didReadRSSI(_ peripheral: CBPeripheral, _ rssi: NSNumber, _ error: Error?) {
let peripheralHashCode = peripheral.hash
guard let peripheralArgs = peripheralsArgs[peripheralHashCode] else {
return
}
let peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
guard let completion = readRssiCompletions.removeValue(forKey: peripheralHashCodeArgs) else {
func didReadRSSI(peripheral: CBPeripheral, rssi: NSNumber, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
guard let completion = _readRssiCompletions.removeValue(forKey: uuidArgs) else {
return
}
if error == nil {
@ -418,157 +376,110 @@ class MyCentralManager: MyCentralManagerHostApi {
}
}
func didDiscoverServices(_ peripheral: CBPeripheral, _ error: Error?) {
let peripheralHashCode = peripheral.hash
guard let peripheralArgs = peripheralsArgs[peripheralHashCode] else {
return
}
let peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
if error == nil {
var services = peripheral.services ?? []
if services.isEmpty {
didDiscoverGATT(peripheral, error)
} else {
let service = services.removeFirst()
unfinishedServices[peripheralHashCodeArgs] = services
peripheral.discoverCharacteristics(nil, for: service)
}
} else {
didDiscoverGATT(peripheral, error)
}
}
func didDiscoverCharacteristics(_ peripheral: CBPeripheral, _ service: CBService, _ error: Error?) {
let peripheralHashCode = peripheral.hash
guard let peripheralArgs = peripheralsArgs[peripheralHashCode] else {
return
}
let peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
if error == nil {
var characteristics = service.characteristics ?? []
if characteristics.isEmpty {
var services = unfinishedServices.removeValue(forKey: peripheralHashCodeArgs) ?? []
if services.isEmpty {
didDiscoverGATT(peripheral, error)
} else {
let service = services.removeFirst()
unfinishedServices[peripheralHashCodeArgs] = services
peripheral.discoverCharacteristics(nil, for: service)
}
} else {
let characteristic = characteristics.removeFirst()
unfinishedCharacteristics[peripheralHashCodeArgs] = characteristics
peripheral.discoverDescriptors(for: characteristic)
}
} else {
didDiscoverGATT(peripheral, error)
}
}
func didDiscoverDescriptors(_ peripheral: CBPeripheral, _ characteristic: CBCharacteristic, _ error: Error?) {
let peripheralHashCode = peripheral.hash
guard let peripheralArgs = peripheralsArgs[peripheralHashCode] else {
return
}
let peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
if error == nil {
var characteristics = unfinishedCharacteristics.removeValue(forKey: peripheralHashCodeArgs) ?? []
if (characteristics.isEmpty) {
var services = unfinishedServices.removeValue(forKey: peripheralHashCodeArgs) ?? []
if services.isEmpty {
didDiscoverGATT(peripheral, error)
} else {
let service = services.removeFirst()
unfinishedServices[peripheralHashCodeArgs] = services
peripheral.discoverCharacteristics(nil, for: service)
}
} else {
let characteristic = characteristics.removeFirst()
unfinishedCharacteristics[peripheralHashCodeArgs] = characteristics
peripheral.discoverDescriptors(for: characteristic)
}
} else {
didDiscoverGATT(peripheral, error)
}
}
private func didDiscoverGATT(_ peripheral: CBPeripheral, _ error: Error?) {
let peripheralHashCode = peripheral.hash
guard let peripheralArgs = peripheralsArgs[peripheralHashCode] else {
return
}
let peripheralhashCodeArgs = peripheralArgs.hashCodeArgs
guard let completion = discoverGattCompletions.removeValue(forKey: peripheralhashCodeArgs) else {
func didDiscoverServices(peripheral: CBPeripheral, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
guard let completion = _discoverServicesCompletions.removeValue(forKey: uuidArgs) else {
return
}
if error == nil {
let services = peripheral.services ?? []
var servicesArgs = [MyGattServiceArgs]()
for service in services {
let characteristics = service.characteristics ?? []
var characteristicsArgs = [MyGattCharacteristicArgs]()
for characteristic in characteristics {
let descriptors = characteristic.descriptors ?? []
var descriptorsArgs = [MyGattDescriptorArgs]()
for descriptor in descriptors {
let descriptorArgs = descriptor.toArgs()
let descriptorHashCode = descriptor.hash
let descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
self.descriptors[descriptorHashCodeArgs] = descriptor
self.descriptorsArgs[descriptorHashCode] = descriptorArgs
descriptorsArgs.append(descriptorArgs)
}
let characteristicArgs = characteristic.toArgs(descriptorsArgs)
let characteristicHashCode = characteristic.hash
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
self.characteristics[characteristicHashCodeArgs] = characteristic
self.characteristicsArgs[characteristicHashCode] = characteristicArgs
characteristicsArgs.append(characteristicArgs)
}
let serviceArgs = service.toArgs(characteristicsArgs)
let serviceHashCode = service.hash
let servcieHashCodeArgs = serviceArgs.hashCodeArgs
self.services[servcieHashCodeArgs] = service
self.servicesArgs[serviceHashCode] = serviceArgs
servicesArgs.append(serviceArgs)
let servicesArgs = services.map { service in service.toArgs() }
let elements = services.flatMap { service in
let hashCodeArgs = service.hash.toInt64()
return [hashCodeArgs: service]
}
servicesArgsOfPeripheralsArgs[peripheralhashCodeArgs] = servicesArgs
completion(.success((servicesArgs)))
var items = _services[uuidArgs]
if items == nil {
_services[uuidArgs] = Dictionary(uniqueKeysWithValues: elements)
} else {
items!.merge(elements) { service1, service2 in service2 }
}
completion(.success(servicesArgs))
} else {
completion(.failure(error!))
unfinishedServices.removeValue(forKey: peripheralhashCodeArgs)
unfinishedCharacteristics.removeValue(forKey: peripheralhashCodeArgs)
}
}
func didUpdateCharacteristicValue(_ characteristic: CBCharacteristic, _ error: Error?) {
let characteristicHashCode = characteristic.hash
guard let characteristicArgs = characteristicsArgs[characteristicHashCode] else {
func didDiscoverCharacteristics(peripheral: CBPeripheral, service: CBService, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = service.hash.toInt64()
guard var completions = _discoverCharacteristicsCompletions[uuidArgs] else {
return
}
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
guard let completion = readCharacteristicCompletions.removeValue(forKey: characteristicHashCodeArgs) else {
let value = characteristic.value ?? Data()
let valueArgs = FlutterStandardTypedData(bytes: value)
api.onCharacteristicValueChanged(characteristicArgs: characteristicArgs, valueArgs: valueArgs) {_ in }
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
let characteristics = service.characteristics ?? []
let characteristicsArgs = characteristics.map { characteristic in characteristic.toArgs() }
let elements = characteristics.flatMap { characteristic in
let hashCodeArgs = characteristic.hash.toInt64()
return [hashCodeArgs: characteristic]
}
var items = _characteristics[uuidArgs]
if items == nil {
_characteristics[uuidArgs] = Dictionary(uniqueKeysWithValues: elements)
} else {
items!.merge(elements) { characteristic1, characteristic2 in characteristic2 }
}
completion(.success(characteristicsArgs))
} else {
completion(.failure(error!))
}
}
func didDiscoverDescriptors(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = characteristic.hash.toInt64()
guard var completions = _discoverDescriptorsCompletions[uuidArgs] else {
return
}
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
let descriptors = characteristic.descriptors ?? []
let descriptorsArgs = descriptors.map { descriptor in descriptor.toArgs() }
let elements = descriptors.flatMap { descriptor in
let hashCodeArgs = descriptor.hash.toInt64()
return [hashCodeArgs: descriptor]
}
var items = _descriptors[uuidArgs]
if items == nil {
_descriptors[uuidArgs] = Dictionary(uniqueKeysWithValues: elements)
} else {
items!.merge(elements) { descriptor1, descriptor2 in descriptor2 }
}
completion(.success(descriptorsArgs))
} else {
completion(.failure(error!))
}
}
func didUpdateCharacteristicValue(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = characteristic.hash.toInt64()
let value = characteristic.value ?? Data()
let valueArgs = FlutterStandardTypedData(bytes: value)
var completions = _readCharacteristicCompletions[uuidArgs]
guard let completion = completions?.removeValue(forKey: hashCodeArgs) else {
_api.onCharacteristicNotified(uuidArgs: uuidArgs, hashCodeArgs: hashCodeArgs, valueArgs: valueArgs) {_ in }
return
}
if error == nil {
let value = characteristic.value ?? Data()
let valueArgs = FlutterStandardTypedData(bytes: value)
completion(.success(valueArgs))
} else {
completion(.failure(error!))
}
}
func didWriteCharacteristicValue(_ characteristic: CBCharacteristic, _ error: Error?) {
let characteristicHashCode = characteristic.hash
guard let characteristicArgs = characteristicsArgs[characteristicHashCode] else {
func didWriteCharacteristicValue(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = characteristic.hash.toInt64()
guard var completions = _writeCharacteristicCompletions[uuidArgs] else {
return
}
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
guard let completion = writeCharacteristicCompletions.removeValue(forKey: characteristicHashCodeArgs) else {
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
@ -578,13 +489,13 @@ class MyCentralManager: MyCentralManagerHostApi {
}
}
func didUpdateNotificationState(_ characteristic: CBCharacteristic, _ error: Error?) {
let characteristicHashCode = characteristic.hash
guard let characteristicArgs = characteristicsArgs[characteristicHashCode] else {
func didUpdateCharacteristicNotificationState(peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = characteristic.hash.toInt64()
guard var completions = _setCharacteristicNotifyStateCompletions[uuidArgs] else {
return
}
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
guard let completion = notifyCharacteristicCompletions.removeValue(forKey: characteristicHashCodeArgs) else {
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
@ -594,17 +505,17 @@ class MyCentralManager: MyCentralManagerHostApi {
}
}
func didUpdateDescriptorValue(_ descriptor: CBDescriptor, _ error: Error?) {
let descriptorHashCode = descriptor.hash
guard let descriptorArgs = descriptorsArgs[descriptorHashCode] else {
func didUpdateDescriptorValue(peripheral: CBPeripheral, descriptor: CBDescriptor, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = descriptor.hash.toInt64()
guard var completions = _readDescriptorCompletions[uuidArgs] else {
return
}
let descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
guard let completion = readDescriptorCompletions.removeValue(forKey: descriptorHashCodeArgs) else {
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
// TODO: Need to confirm wheather the corresponding descriptor type and value is correct.
// TODO: confirm the corresponding descriptor types and values are correct.
let valueArgs: FlutterStandardTypedData
let value = descriptor.value
do {
@ -647,13 +558,13 @@ class MyCentralManager: MyCentralManagerHostApi {
}
}
func didWriteDescriptorValue(_ descriptor: CBDescriptor, _ error: Error?) {
let descriptorHashCode = descriptor.hash
guard let descriptorArgs = descriptorsArgs[descriptorHashCode] else {
func didWriteDescriptorValue(peripheral: CBPeripheral, descriptor: CBDescriptor, error: Error?) {
let uuidArgs = peripheral.identifier.toArgs()
let hashCodeArgs = descriptor.hash.toInt64()
guard var completions = _writeDescriptorCompletions[uuidArgs] else {
return
}
let descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
guard let completion = writeDescriptorCompletions.removeValue(forKey: descriptorHashCodeArgs) else {
guard let completion = completions.removeValue(forKey: hashCodeArgs) else {
return
}
if error == nil {
@ -662,4 +573,60 @@ class MyCentralManager: MyCentralManagerHostApi {
completion(.failure(error!))
}
}
private func _clearState() {
if(_centralManager.isScanning) {
_centralManager.stopScan()
}
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()
}
private func _retrieveService(uuidArgs: String, hashCodeArgs: Int64) -> CBService? {
guard let services = _services[uuidArgs] else {
return nil
}
return services[hashCodeArgs]
}
private func _retrieveCharacteristic(uuidArgs: String, hashCodeArgs: Int64) -> CBCharacteristic? {
guard let characteristics = _characteristics[uuidArgs] else {
return nil
}
return characteristics[hashCodeArgs]
}
private func _retrieveDescriptor(uuidArgs: String, hashCodeArgs: Int64) -> CBDescriptor? {
guard let descriptors = _descriptors[uuidArgs] else {
return nil
}
return descriptors[hashCodeArgs]
}
private func _onStateChanged() {
let state = _centralManager.state
let stateArgs = state.toArgs()
let stateNumberArgs = stateArgs.rawValue.toInt64()
_api.onStateChanged(stateNumberArgs: stateNumberArgs) {_ in }
}
}

View File

@ -9,29 +9,29 @@ import Foundation
import CoreBluetooth
class MyCentralManagerDelegate: NSObject, CBCentralManagerDelegate {
init(_ centralManager: MyCentralManager) {
self.centralManager = centralManager
private let _centralManager: MyCentralManager
init(centralManager: MyCentralManager) {
_centralManager = centralManager
}
private let centralManager: MyCentralManager
func centralManagerDidUpdateState(_ central: CBCentralManager) {
centralManager.didUpdateState()
_centralManager.didUpdateState(central: central)
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
centralManager.didDiscover(peripheral, advertisementData, RSSI)
_centralManager.didDiscover(central: central, peripheral: peripheral, advertisementData: advertisementData, rssi: RSSI)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
centralManager.didConnect(peripheral)
_centralManager.didConnect(central: central, peripheral: peripheral)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
centralManager.didFailToConnect(peripheral, error)
_centralManager.didFailToConnect(central: central, peripheral: peripheral, error: error)
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
centralManager.didDisconnectPeripheral(peripheral, error)
_centralManager.didDisconnectPeripheral(central: central, peripheral: peripheral, error: error)
}
}

View File

@ -10,6 +10,5 @@ import Foundation
// TODO:
enum MyError: Error {
case illegalArgument
case illegalState
case unknown
}

View File

@ -9,45 +9,45 @@ import Foundation
import CoreBluetooth
class MyPeripheralDelegate: NSObject, CBPeripheralDelegate {
private let centralManager: MyCentralManager
private let _centralManager: MyCentralManager
init(_ centralManager: MyCentralManager) {
self.centralManager = centralManager
init(centralManager: MyCentralManager) {
_centralManager = centralManager
}
func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
centralManager.didReadRSSI(peripheral, RSSI, error)
_centralManager.didReadRSSI(peripheral: peripheral, rssi: RSSI, error: error)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
centralManager.didDiscoverServices(peripheral, error)
_centralManager.didDiscoverServices(peripheral: peripheral, error: error)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
centralManager.didDiscoverCharacteristics(peripheral, service, error)
_centralManager.didDiscoverCharacteristics(peripheral: peripheral, service: service, error: error)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
centralManager.didDiscoverDescriptors(peripheral, characteristic, error)
_centralManager.didDiscoverDescriptors(peripheral: peripheral, characteristic: characteristic, error: error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
centralManager.didUpdateCharacteristicValue(characteristic, error)
_centralManager.didUpdateCharacteristicValue(peripheral: peripheral, characteristic: characteristic, error: error)
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
centralManager.didWriteCharacteristicValue(characteristic, error)
_centralManager.didWriteCharacteristicValue(peripheral: peripheral, characteristic: characteristic, error: error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
centralManager.didUpdateNotificationState(characteristic, error)
_centralManager.didUpdateCharacteristicNotificationState(peripheral: peripheral, characteristic: characteristic, error: error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) {
centralManager.didUpdateDescriptorValue(descriptor, error)
_centralManager.didUpdateDescriptorValue(peripheral: peripheral, descriptor: descriptor, error: error)
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
centralManager.didWriteDescriptorValue(descriptor, error)
_centralManager.didWriteDescriptorValue(peripheral: peripheral, descriptor: descriptor, error: error)
}
}

View File

@ -17,138 +17,308 @@ import FlutterMacOS
#endif
class MyPeripheralManager: MyPeripheralManagerHostApi {
init(_ binaryMessenger: FlutterBinaryMessenger) {
self.binaryMessenger = binaryMessenger
private let _api: MyPeripheralManagerFlutterApi
private let _peripheralManager: CBPeripheralManager
private lazy var _peripheralManagerDelegate = MyPeripheralManagerDelegate(peripheralManager: self)
private var _servicesArgs: [Int: MyGattServiceArgs]
private var _characteristicsArgs: [Int: MyGattCharacteristicArgs]
private var _descriptorsArgs: [Int: MyGattDescriptorArgs]
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 _addServiceCompletion: ((Result<Void, Error>) -> Void)?
private var _startAdvertisingCompletion: ((Result<Void, Error>) -> Void)?
private var _isReadyToUpdateSubscribersCallbacks: [() -> Void]
init(messenger: FlutterBinaryMessenger) {
_api = MyPeripheralManagerFlutterApi(binaryMessenger: messenger)
_peripheralManager = CBPeripheralManager()
_servicesArgs = [:]
_characteristicsArgs = [:]
_descriptorsArgs = [:]
_centrals = [:]
_services = [:]
_characteristics = [:]
_descriptors = [:]
_requests = [:]
_addServiceCompletion = nil
_startAdvertisingCompletion = nil
_isReadyToUpdateSubscribersCallbacks = []
}
private let binaryMessenger: FlutterBinaryMessenger
private let peripheralManager = CBPeripheralManager()
private lazy var api = MyPeripheralManagerFlutterApi(binaryMessenger: binaryMessenger)
private lazy var peripheralManagerDelegate = MyPeripheralManagerDelegate(self)
private var centrals = [Int64: CBCentral]()
private var services = [Int64: CBMutableService]()
private var characteristics = [Int64: CBMutableCharacteristic]()
private var descriptors = [Int64: CBMutableDescriptor]()
private var requests = [Int64: CBATTRequest]()
private var centralsArgs = [Int: MyCentralArgs]()
private var servicesArgs = [Int: MyGattServiceArgs]()
private var characteristicsArgs = [Int: MyGattCharacteristicArgs]()
private var descriptorsArgs = [Int: MyGattDescriptorArgs]()
private var setUpCompletion: ((Result<MyPeripheralManagerArgs, Error>) -> Void)?
private var addServiceCompletion: ((Result<Void, Error>) -> Void)?
private var startAdvertisingCompletion: ((Result<Void, Error>) -> Void)?
private var notifyCharacteristicValueChangedCallbacks = [() -> Void]()
func setUp(completion: @escaping (Result<MyPeripheralManagerArgs, Error>) -> Void) {
do {
if setUpCompletion != nil {
throw MyError.illegalState
}
try tearDown()
peripheralManager.delegate = peripheralManagerDelegate
if peripheralManager.state == .unknown {
setUpCompletion = completion
} else {
let stateArgs = peripheralManager.state.toArgs()
let stateNumberArgs = Int64(stateArgs.rawValue)
let args = MyPeripheralManagerArgs(stateNumberArgs: stateNumberArgs)
completion(.success(args))
}
} catch {
completion(.failure(error))
func setUp() throws {
_clearState()
if _peripheralManager.delegate == nil {
_peripheralManager.delegate = _peripheralManagerDelegate
}
}
func tearDown() throws {
if(peripheralManager.isAdvertising) {
peripheralManager.stopAdvertising()
}
centrals.removeAll()
services.removeAll()
characteristics.removeAll()
descriptors.removeAll()
requests.removeAll()
centralsArgs.removeAll()
servicesArgs.removeAll()
characteristicsArgs.removeAll()
descriptorsArgs.removeAll()
setUpCompletion = nil
addServiceCompletion = nil
startAdvertisingCompletion = nil
notifyCharacteristicValueChangedCallbacks.removeAll()
_onStateChanged()
}
func addService(serviceArgs: MyGattServiceArgs, completion: @escaping (Result<Void, Error>) -> Void) {
do {
if addServiceCompletion != nil {
throw MyError.illegalState
let service = serviceArgs.toService()
var characteristics = [CBMutableCharacteristic]()
let characteristicsArgs = serviceArgs.characteristicsArgs
for args in characteristicsArgs {
guard let characteristicArgs = args else {
continue
}
let service = serviceArgs.toService()
var characteristics = [CBMutableCharacteristic]()
let characteristicsArgs = serviceArgs.characteristicsArgs
for args in characteristicsArgs {
guard let characteristicArgs = args else {
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 characteristic = characteristicArgs.toCharacteristic()
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
self.descriptorsArgs[descriptorHashCode] = descriptorArgs
self.descriptors[descriptorHashCodeArgs] = descriptor
}
characteristic.descriptors = descriptors
characteristics.append(characteristic)
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
let characteristicHashCode = characteristic.hash
self.characteristicsArgs[characteristicHashCode] = characteristicArgs
self.characteristics[characteristicHashCodeArgs] = characteristic
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[hashCodeArgs] else {
throw MyError.illegalArgument
}
let hashCode = service.hash
guard let serviceArgs = _servicesArgs[hashCode] else {
throw MyError.illegalArgument
}
_peripheralManager.remove(service)
_clearService(serviceArgs: serviceArgs)
}
func clearServices() throws {
_peripheralManager.removeAllServices()
let servicesArgs = _servicesArgs.values
for serviceArgs in servicesArgs {
_clearService(serviceArgs: serviceArgs)
}
}
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) {
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 {
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)
}
}
service.characteristics = characteristics
let serviceHashCodeArgs = serviceArgs.hashCodeArgs
let serviceHashCode = service.hash
self.servicesArgs[serviceHashCode] = serviceArgs
self.services[serviceHashCodeArgs] = service
peripheralManager.add(service)
addServiceCompletion = completion
} catch {
freeService(serviceArgs)
completion(.failure(error))
}
}
func removeService(serviceHashCodeArgs: Int64) throws {
guard let service = services[serviceHashCodeArgs] else {
throw MyError.illegalArgument
}
let serviceHashCode = service.hash
guard let serviceArgs = servicesArgs[serviceHashCode] else {
throw MyError.illegalArgument
}
peripheralManager.remove(service)
freeService(serviceArgs)
func didUpdateState(peripheral: CBPeripheralManager) {
_onStateChanged()
}
func clearServices() throws {
peripheralManager.removeAllServices()
let servicesArgs = self.servicesArgs.values
for serviceArgs in servicesArgs {
freeService(serviceArgs)
func didAdd(peripheral: CBPeripheralManager, service: CBService, error: Error?) {
guard let completion = _addServiceCompletion else {
return
}
_addServiceCompletion = nil
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
let hashCode = service.hash
guard let serviceArgs = _servicesArgs[hashCode] else {
return
}
_clearService(serviceArgs: serviceArgs)
}
}
private func freeService(_ serviceArgs: MyGattServiceArgs) {
func didStartAdvertising(peripheral: CBPeripheralManager, error: Error?) {
guard let completion = _startAdvertisingCompletion else {
return
}
_startAdvertisingCompletion = nil
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
func didReceiveRead(peripheral: CBPeripheralManager, request: CBATTRequest) {
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()
_requests[idArgs] = request
_api.onCharacteristicReadRequest(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, idArgs: idArgs, offsetArgs: offsetArgs) {_ 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
guard let request = requests.first else {
return
}
if requests.count > 1 {
// TODO:
let result = CBATTError.requestNotSupported
_peripheralManager.respond(to: request, withResult: result)
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 }
}
func didSubscribeTo(peripheral: CBPeripheralManager, central: CBCentral, characteristic: CBCharacteristic) {
let centralArgs = central.toArgs()
_centrals[centralArgs.uuidArgs] = central
let hashCode = characteristic.hash
guard let characteristicArgs = _characteristicsArgs[hashCode] else {
return
}
let hashCodeArgs = characteristicArgs.hashCodeArgs
let stateArgs = true
_api.onCharacteristicNotifyStateChanged(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, stateArgs: stateArgs) {_ in }
}
func didUnsubscribeFrom(peripheral: CBPeripheralManager, central: CBCentral, characteristic: CBCharacteristic) {
let centralArgs = central.toArgs()
_centrals[centralArgs.uuidArgs] = central
let hashCode = characteristic.hash
guard let characteristicArgs = _characteristicsArgs[hashCode] else {
return
}
let hashCodeArgs = characteristicArgs.hashCodeArgs
let stateArgs = false
_api.onCharacteristicNotifyStateChanged(centralArgs: centralArgs, hashCodeArgs: hashCodeArgs, stateArgs: stateArgs) {_ in }
}
func isReadyToUpdateSubscribers(peripheral: CBPeripheralManager) {
let callbacks = _isReadyToUpdateSubscribersCallbacks
_isReadyToUpdateSubscribersCallbacks.removeAll()
for callback in callbacks {
callback()
}
}
private func _clearState() {
if(_peripheralManager.isAdvertising) {
_peripheralManager.stopAdvertising()
}
_servicesArgs.removeAll()
_characteristicsArgs.removeAll()
_descriptorsArgs.removeAll()
_centrals.removeAll()
_services.removeAll()
_characteristics.removeAll()
_descriptors.removeAll()
_requests.removeAll()
_addServiceCompletion = nil
_startAdvertisingCompletion = nil
_isReadyToUpdateSubscribersCallbacks.removeAll()
}
private func _clearService(serviceArgs: MyGattServiceArgs) {
let characteristicsArgs = serviceArgs.characteristicsArgs
for args in characteristicsArgs {
guard let characteristicArgs = args else {
@ -160,223 +330,31 @@ class MyPeripheralManager: MyPeripheralManagerHostApi {
continue
}
let descriptorHashCodeArgs = descriptorArgs.hashCodeArgs
guard let descriptor = self.descriptors.removeValue(forKey: descriptorHashCodeArgs) else {
guard let descriptor = _descriptors.removeValue(forKey: descriptorHashCodeArgs) else {
continue
}
let descriptorHashCode = descriptor.hash
self.descriptorsArgs.removeValue(forKey: descriptorHashCode)
_descriptorsArgs.removeValue(forKey: descriptorHashCode)
}
let characteristicHashCodeArgs = characteristicArgs.hashCodeArgs
guard let characteristic = self.characteristics.removeValue(forKey: characteristicHashCodeArgs) else {
guard let characteristic = _characteristics.removeValue(forKey: characteristicHashCodeArgs) else {
continue
}
let characteristicHashCode = characteristic.hash
self.characteristicsArgs.removeValue(forKey: characteristicHashCode)
_characteristicsArgs.removeValue(forKey: characteristicHashCode)
}
let serviceHashCodeArgs = serviceArgs.hashCodeArgs
guard let service = self.services.removeValue(forKey: serviceHashCodeArgs) else {
guard let service = _services.removeValue(forKey: serviceHashCodeArgs) else {
return
}
let serviceHashCode = service.hash
self.servicesArgs.removeValue(forKey: serviceHashCode)
_servicesArgs.removeValue(forKey: serviceHashCode)
}
func startAdvertising(advertisementArgs: MyAdvertisementArgs, completion: @escaping (Result<Void, Error>) -> Void) {
do {
if startAdvertisingCompletion != nil {
throw MyError.illegalState
}
let advertisement = try advertisementArgs.toAdvertisement()
peripheralManager.startAdvertising(advertisement)
startAdvertisingCompletion = completion
} catch {
completion(.failure(error))
}
}
func stopAdvertising() throws {
peripheralManager.stopAdvertising()
}
func getMaximumWriteLength(centralHashCodeArgs: Int64) throws -> Int64 {
guard let central = centrals[centralHashCodeArgs] else {
throw MyError.illegalArgument
}
let maximumWriteLength = try central.maximumUpdateValueLength.coerceIn(20, 512)
let maximumWriteLengthArgs = Int64(maximumWriteLength)
return maximumWriteLengthArgs
}
func sendReadCharacteristicReply(centralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, idArgs: Int64, offsetArgs: Int64, statusArgs: Bool, valueArgs: FlutterStandardTypedData) throws {
guard let request = requests.removeValue(forKey: idArgs) else {
throw MyError.illegalArgument
}
request.value = valueArgs.data
let result = statusArgs ? CBATTError.Code.success : CBATTError.Code.requestNotSupported
peripheralManager.respond(to: request, withResult: result)
}
func sendWriteCharacteristicReply(centralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, idArgs: Int64, offsetArgs: Int64, statusArgs: Bool) throws {
guard let request = requests.removeValue(forKey: idArgs) else {
throw MyError.illegalArgument
}
let result = statusArgs ? CBATTError.Code.success : CBATTError.Code.requestNotSupported
peripheralManager.respond(to: request, withResult: result)
}
func notifyCharacteristicValueChanged(centralHashCodeArgs: Int64, characteristicHashCodeArgs: Int64, valueArgs: FlutterStandardTypedData, completion: @escaping (Result<Void, Error>) -> Void) {
do {
if notifyCharacteristicValueChangedCallbacks.count > 0 {
throw MyError.illegalState
}
let value = valueArgs.data
guard let characteristic = characteristics[characteristicHashCodeArgs] else {
throw MyError.illegalArgument
}
guard let central = centrals[centralHashCodeArgs] else {
throw MyError.illegalArgument
}
let centrals = [central]
let updated = peripheralManager.updateValue(value, for: characteristic, onSubscribedCentrals: centrals)
if updated {
completion(.success(()))
} else {
notifyCharacteristicValueChangedCallbacks.append {
let updated = self.peripheralManager.updateValue(value, for: characteristic, onSubscribedCentrals: centrals)
if updated {
completion(.success(()))
} else {
completion(.failure(MyError.unknown))
}
}
}
} catch {
completion(.failure(error))
}
}
func didUpdateState() {
let state = peripheralManager.state
private func _onStateChanged() {
let state = _peripheralManager.state
let stateArgs = state.toArgs()
let stateNumberArgs = Int64(stateArgs.rawValue)
if state != .unknown && setUpCompletion != nil {
let args = MyPeripheralManagerArgs(stateNumberArgs: stateNumberArgs)
setUpCompletion!(.success(args))
setUpCompletion = nil
}
api.onStateChanged(stateNumberArgs: stateNumberArgs) {_ in }
}
func didAdd(_ service: CBService, _ error: Error?) {
guard let completion = addServiceCompletion else {
return
}
addServiceCompletion = nil
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
let serviceHashCode = service.hash
guard let serviceArgs = servicesArgs[serviceHashCode] else {
return
}
freeService(serviceArgs)
}
}
func didStartAdvertising(_ error: Error?) {
guard let completion = startAdvertisingCompletion else {
return
}
startAdvertisingCompletion = nil
if error == nil {
completion(.success(()))
} else {
completion(.failure(error!))
}
}
func didReceiveRead(_ request: CBATTRequest) {
let central = request.central
let centralHashCode = central.hash
let centralArgs = centralsArgs.getOrPut(centralHashCode) { central.toArgs() }
let centralHashCodeArgs = centralArgs.hashCodeArgs
centrals[centralHashCodeArgs] = central
let characteristic = request.characteristic
let characteristicHashCode = characteristic.hash
guard let characteristicArgs = characteristicsArgs[characteristicHashCode] else {
peripheralManager.respond(to: request, withResult: .attributeNotFound)
return
}
let idArgs = Int64(request.hash)
requests[idArgs] = request
let offsetArgs = Int64(request.offset)
api.onReadCharacteristicCommandReceived(centralArgs: centralArgs, characteristicArgs: characteristicArgs, idArgs: idArgs, offsetArgs: offsetArgs) {_ in }
}
func didReceiveWrite(_ requests: [CBATTRequest]) {
//
guard let request = requests.first else {
return
}
if requests.count > 1 {
// TODO:
let result = CBATTError.requestNotSupported
peripheralManager.respond(to: request, withResult: result)
}
let central = request.central
let centralHashCode = central.hash
let centralArgs = centralsArgs.getOrPut(centralHashCode) { central.toArgs() }
let centralHashCodeArgs = centralArgs.hashCodeArgs
centrals[centralHashCodeArgs] = central
let characteristic = request.characteristic
let characteristicHashCode = characteristic.hash
guard let characteristicArgs = characteristicsArgs[characteristicHashCode] else {
peripheralManager.respond(to: request, withResult: .attributeNotFound)
return
}
let idArgs = Int64(request.hash)
self.requests[idArgs] = request
let offsetArgs = Int64(request.offset)
guard let value = request.value else {
peripheralManager.respond(to: request, withResult: .requestNotSupported)
return
}
let valueArgs = FlutterStandardTypedData(bytes: value)
api.onWriteCharacteristicCommandReceived(centralArgs: centralArgs, characteristicArgs: characteristicArgs, idArgs: idArgs, offsetArgs: offsetArgs, valueArgs: valueArgs) {_ in }
}
func didSubscribeTo(_ central: CBCentral, _ characteristic: CBCharacteristic) {
let centralHashCode = central.hash
let centralArgs = centralsArgs.getOrPut(centralHashCode) { central.toArgs() }
let centralHashCodeArgs = centralArgs.hashCodeArgs
centrals[centralHashCodeArgs] = central
let characteristicHashCode = characteristic.hash
guard let characteristicArgs = characteristicsArgs[characteristicHashCode] else {
return
}
let stateArgs = true
api.onNotifyCharacteristicCommandReceived(centralArgs: centralArgs, characteristicArgs: characteristicArgs, stateArgs: stateArgs) {_ in }
}
func didUnsubscribeFrom(_ central: CBCentral, _ characteristic: CBCharacteristic) {
let centralHashCode = central.hash
let centralArgs = centralsArgs.getOrPut(centralHashCode) { central.toArgs() }
let centralHashCodeArgs = centralArgs.hashCodeArgs
centrals[centralHashCodeArgs] = central
let characteristicHashCode = characteristic.hash
guard let characteristicArgs = characteristicsArgs[characteristicHashCode] else {
return
}
let stateArgs = false
api.onNotifyCharacteristicCommandReceived(centralArgs: centralArgs, characteristicArgs: characteristicArgs, stateArgs: stateArgs) {_ in }
}
func isReadyToUpdateSubscribers() {
let callbacks = notifyCharacteristicValueChangedCallbacks
notifyCharacteristicValueChangedCallbacks.removeAll()
for callback in callbacks {
callback()
}
let stateNumberArgs = stateArgs.rawValue.toInt64()
_api.onStateChanged(stateNumberArgs: stateNumberArgs) {_ in }
}
}

View File

@ -9,41 +9,41 @@ import Foundation
import CoreBluetooth
class MyPeripheralManagerDelegate: NSObject, CBPeripheralManagerDelegate {
init(_ peripheralManager: MyPeripheralManager) {
self.peripheralManager = peripheralManager
private let _peripheralManager: MyPeripheralManager
init(peripheralManager: MyPeripheralManager) {
_peripheralManager = peripheralManager
}
private let peripheralManager: MyPeripheralManager
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
peripheralManager.didUpdateState()
_peripheralManager.didUpdateState(peripheral: peripheral)
}
func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
peripheralManager.didAdd(service, error)
_peripheralManager.didAdd(peripheral: peripheral, service: service, error: error)
}
func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {
peripheralManager.didStartAdvertising(error)
_peripheralManager.didStartAdvertising(peripheral: peripheral, error: error)
}
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
peripheralManager.didReceiveRead(request)
_peripheralManager.didReceiveRead(peripheral: peripheral, request: request)
}
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
peripheralManager.didReceiveWrite(requests)
_peripheralManager.didReceiveWrite(peripheral: peripheral, requests: requests)
}
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
peripheralManager.didSubscribeTo(central, characteristic)
_peripheralManager.didSubscribeTo(peripheral: peripheral, central: central, characteristic: characteristic)
}
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) {
peripheralManager.didUnsubscribeFrom(central, characteristic)
_peripheralManager.didUnsubscribeFrom(peripheral: peripheral, central: central, characteristic: characteristic)
}
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
peripheralManager.isReadyToUpdateSubscribers()
_peripheralManager.isReadyToUpdateSubscribers(peripheral: peripheral)
}
}