diff --git a/Sources/BluetoothGATT/ATTReadByTypeRequest.swift b/Sources/BluetoothGATT/ATTReadByTypeRequest.swift index 9727470a2..9463f629f 100644 --- a/Sources/BluetoothGATT/ATTReadByTypeRequest.swift +++ b/Sources/BluetoothGATT/ATTReadByTypeRequest.swift @@ -6,16 +6,16 @@ // Copyright © 2018 PureSwift. All rights reserved. // -import Foundation +import Bluetooth /// Read By Type Request /// /// The *Read By Type Request* is used to obtain the values of attributes where the /// attribute type is known but the handle is not known. @frozen -public struct ATTReadByTypeRequest: ATTProtocolDataUnit, Equatable { +public struct ATTReadByTypeRequest: ATTProtocolDataUnit, Equatable, Hashable, Sendable { - public static var attributeOpcode: ATTOpcode { return .readByTypeRequest } + public static var attributeOpcode: ATTOpcode { .readByTypeRequest } /// First requested handle number public var startHandle: UInt16 @@ -26,24 +26,26 @@ public struct ATTReadByTypeRequest: ATTProtocolDataUnit, Equatable { /// 2 or 16 octet UUID public var attributeType: BluetoothUUID - public init(startHandle: UInt16, - endHandle: UInt16, - attributeType: BluetoothUUID) { - - assert(attributeType.length != .bit32, "32-bit UUID not supported") - + public init( + startHandle: UInt16, + endHandle: UInt16, + attributeType: BluetoothUUID + ) { + assert(attributeType.dataLength != 4, "32-bit UUID not supported") self.startHandle = startHandle self.endHandle = endHandle self.attributeType = attributeType } } -public extension ATTReadByTypeRequest { +// MARK: - DataConvertible + +extension ATTReadByTypeRequest: DataConvertible { - init?(data: Data) { + public init?(data: Data) { guard let length = Length(rawValue: data.count), - type(of: self).validateOpcode(data) + Self.validateOpcode(data) else { return nil } self.startHandle = UInt16(littleEndian: UInt16(bytes: (data[1], data[2]))) @@ -54,31 +56,19 @@ public extension ATTReadByTypeRequest { let value = UInt16(littleEndian: UInt16(bytes: (data[5], data[6]))) self.attributeType = .bit16(value) case .uuid128: - self.attributeType = BluetoothUUID(littleEndian: BluetoothUUID(data: data.suffixNoCopy(from: 5))!) + self.attributeType = BluetoothUUID(littleEndian: BluetoothUUID(data: data.subdata(in: 5 ..< length.rawValue))!) } } - var data: Data { - - return Data(self) - } -} - -// MARK: - DataConvertible - -extension ATTReadByTypeRequest: DataConvertible { - - var dataLength: Int { - - return length.rawValue + public func append(to data: inout Data) where Data : DataContainer { + data += Self.attributeOpcode.rawValue + data += self.startHandle.littleEndian + data += self.endHandle.littleEndian + data += self.attributeType.littleEndian } - static func += (data: inout T, value: ATTReadByTypeRequest) { - - data += attributeOpcode.rawValue - data += value.startHandle.littleEndian - data += value.endHandle.littleEndian - data += value.attributeType.littleEndian + public var dataLength: Int { + length.rawValue } } @@ -93,11 +83,13 @@ internal extension ATTReadByTypeRequest { } private var length: Length { - switch attributeType { - case .bit16: return .uuid16 - case .bit128: return .uuid128 - case .bit32: fatalError() // FIXME: Do not allow 32-bit UUID for Blueooth LE + case .bit16: + return .uuid16 + case .bit128: + return .uuid128 + case .bit32: + fatalError() // Do not allow 32-bit UUID for Blueooth LE } } }