Skip to content

Commit

Permalink
#161 Add DataConvertible to ATTReadByTypeRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
colemancda committed Nov 8, 2024
1 parent 542f130 commit 9f9da5e
Showing 1 changed file with 28 additions and 36 deletions.
64 changes: 28 additions & 36 deletions Sources/BluetoothGATT/ATTReadByTypeRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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: DataContainer>(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])))
Expand All @@ -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<Data>(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 += <T: DataContainer> (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
}
}

Expand All @@ -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
}
}
}

0 comments on commit 9f9da5e

Please sign in to comment.