From e96654aefeaa8fba58d926c31d220b4e6acb4ba6 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Wed, 22 Mar 2023 02:27:33 -0700 Subject: [PATCH] Update `PeripheralManager.add()` --- Sources/DarwinGATT/DarwinPeripheral.swift | 23 +++++++++++------------ Sources/GATT/GATTPeripheral.swift | 21 ++++++++++++++++----- Sources/GATT/PeripheralProtocol.swift | 4 ++-- Tests/GATTTests/GATTTests.swift | 13 +++++++------ 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/Sources/DarwinGATT/DarwinPeripheral.swift b/Sources/DarwinGATT/DarwinPeripheral.swift index 3228be2..e136449 100644 --- a/Sources/DarwinGATT/DarwinPeripheral.swift +++ b/Sources/DarwinGATT/DarwinPeripheral.swift @@ -103,7 +103,7 @@ public final class DarwinPeripheral: PeripheralManager { } } - public func add(service: GATTAttribute.Service) async throws -> UInt16 { + public func add(service: GATTAttribute.Service) async throws -> (UInt16, [UInt16]) { let serviceObject = service.toCoreBluetooth() // add service try await withCheckedThrowingContinuation { [unowned self] (continuation: CheckedContinuation<(), Error>) in @@ -574,24 +574,23 @@ private extension DarwinPeripheral { return lastHandle } - mutating func add(service: GATTAttribute.Service, _ coreService: CBMutableService) -> UInt16 { + mutating func add(service: GATTAttribute.Service, _ coreService: CBMutableService) -> (UInt16, [UInt16]) { let serviceHandle = newHandle() - + var characteristicHandles = [UInt16]() + characteristicHandles.reserveCapacity((coreService.characteristics ?? []).count) services[coreService] = Service(handle: serviceHandle) - for (index, characteristic) in ((coreService.characteristics ?? []) as! [CBMutableCharacteristic]).enumerated() { - let data = service.characteristics[index].value - let characteristicHandle = newHandle() - - characteristics[characteristic] = Characteristic(handle: characteristicHandle, - serviceHandle: serviceHandle, - value: data) + characteristics[characteristic] = Characteristic( + handle: characteristicHandle, + serviceHandle: serviceHandle, + value: data + ) + characteristicHandles.append(characteristicHandle) } - - return serviceHandle + return (serviceHandle, characteristicHandles) } mutating func remove(service handle: UInt16) { diff --git a/Sources/GATT/GATTPeripheral.swift b/Sources/GATT/GATTPeripheral.swift index e4cfc55..51304b3 100644 --- a/Sources/GATT/GATTPeripheral.swift +++ b/Sources/GATT/GATTPeripheral.swift @@ -82,7 +82,7 @@ public final class GATTPeripheral UInt16 { + public func add(service: BluetoothGATT.GATTAttribute.Service) async throws -> (UInt16, [UInt16]) { return await storage.add(service: service) } @@ -294,8 +294,19 @@ internal extension GATTPeripheral { self.task = task } - func add(service: BluetoothGATT.GATTAttribute.Service) -> UInt16 { - return database.add(service: service) + func add(service: GATTAttribute.Service) -> (UInt16, [UInt16]) { + var includedServicesHandles = [UInt16]() + var characteristicDeclarationHandles = [UInt16]() + var characteristicValueHandles = [UInt16]() + var descriptorHandles = [[UInt16]]() + let serviceHandle = database.add( + service: service, + includedServicesHandles: &includedServicesHandles, + characteristicDeclarationHandles: &characteristicDeclarationHandles, + characteristicValueHandles: &characteristicValueHandles, + descriptorHandles: &descriptorHandles + ) + return (serviceHandle, characteristicValueHandles) } func remove(service handle: UInt16) { diff --git a/Sources/GATT/PeripheralProtocol.swift b/Sources/GATT/PeripheralProtocol.swift index 109146f..0473ab1 100644 --- a/Sources/GATT/PeripheralProtocol.swift +++ b/Sources/GATT/PeripheralProtocol.swift @@ -32,8 +32,8 @@ public protocol PeripheralManager: AnyObject { /// Attempts to add the specified service to the GATT database. /// - /// - Returns: Attribute handle. - func add(service: BluetoothGATT.GATTAttribute.Service) async throws -> UInt16 + /// - Returns: Handle for service declaration and handles for characteristic value handles. + func add(service: BluetoothGATT.GATTAttribute.Service) async throws -> (UInt16, [UInt16]) /// Removes the service with the specified handle. func remove(service: UInt16) async diff --git a/Tests/GATTTests/GATTTests.swift b/Tests/GATTTests/GATTTests.swift index 684625a..0e4b9ad 100644 --- a/Tests/GATTTests/GATTTests.swift +++ b/Tests/GATTTests/GATTTests.swift @@ -261,9 +261,10 @@ final class GATTTests: XCTestCase { try await connect( server: { peripheral in - serviceAttribute = try await peripheral.add(service: service) + let (serviceAttributeHandle, characteristicValueHandles) = try await peripheral.add(service: service) + serviceAttribute = serviceAttributeHandle XCTAssertEqual(serviceAttribute, 1) - characteristicValueHandle = await peripheral.characteristics(for: .batteryLevel)[0] + characteristicValueHandle = characteristicValueHandles[0] peripheralDatabaseValue = { await peripheral[characteristic: characteristicValueHandle] } let currentValue = await peripheralDatabaseValue() XCTAssertEqual(currentValue, characteristics[0].value) @@ -336,9 +337,9 @@ final class GATTTests: XCTestCase { serverOptions: .init(maximumTransmissionUnit: .default, maximumPreparedWrites: 1000), clientOptions: .init(maximumTransmissionUnit: .max), server: { peripheral in - let serviceAttribute = try await peripheral.add(service: service) + let (serviceAttribute, characteristicValueHandles) = try await peripheral.add(service: service) XCTAssertEqual(serviceAttribute, 1) - let characteristicValueHandle = await peripheral.characteristics(for: .batteryLevel)[0] + let characteristicValueHandle = characteristicValueHandles[0] Task { try await Task.sleep(nanoseconds: 1_000_000_000) await peripheral.write(newValue.data, forCharacteristic: characteristicValueHandle) @@ -401,9 +402,9 @@ final class GATTTests: XCTestCase { serverOptions: .init(maximumTransmissionUnit: .default, maximumPreparedWrites: 1000), clientOptions: .init(maximumTransmissionUnit: .max), server: { peripheral in - let serviceAttribute = try await peripheral.add(service: service) + let (serviceAttribute, characteristicValueHandles) = try await peripheral.add(service: service) XCTAssertEqual(serviceAttribute, 1) - let characteristicValueHandle = await peripheral.characteristics(for: .batteryLevel)[0] + let characteristicValueHandle = characteristicValueHandles[0] Task { try await Task.sleep(nanoseconds: 1_000_000_000) await peripheral.write(newValue.data, forCharacteristic: characteristicValueHandle)