From 658ca82fa74456142c38c9b2aacb9cc488d3e8fb Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Sun, 3 Dec 2017 01:54:44 -0500 Subject: [PATCH] Fixed BluetoothUUID endianess --- Sources/ATTProtocolDataUnit.swift | 6 ++- Sources/BluetoothUUID.swift | 48 ++++++++++++++++++----- Sources/Endianness.swift | 34 ---------------- Tests/BluetoothTests/BluetoothTests.swift | 31 ++++++++++++--- 4 files changed, 68 insertions(+), 51 deletions(-) delete mode 100644 Sources/Endianness.swift diff --git a/Sources/ATTProtocolDataUnit.swift b/Sources/ATTProtocolDataUnit.swift index 8633e958c..361f55424 100644 --- a/Sources/ATTProtocolDataUnit.swift +++ b/Sources/ATTProtocolDataUnit.swift @@ -349,7 +349,11 @@ public struct ATTFindInformationResponse: ATTProtocolDataUnit { let uuidBytes = Array(pairBytes[2 ... 17]) - let data = Foundation.Data(bytes: isBigEndian ? uuidBytes.reversed() : uuidBytes) + #if _endian(little) + let data = Foundation.Data(bytes: uuidBytes) + #else + let data = Foundation.Data(bytes: uuidBytes.reversed()) // byteSwapped + #endif let uuid = UUID(data: data)! diff --git a/Sources/BluetoothUUID.swift b/Sources/BluetoothUUID.swift index 881481def..f09a9a668 100644 --- a/Sources/BluetoothUUID.swift +++ b/Sources/BluetoothUUID.swift @@ -130,7 +130,7 @@ public extension BluetoothUUID { } } - public func toData() -> Data { + public var data: Data { switch self { @@ -154,22 +154,50 @@ public extension BluetoothUUID { public extension BluetoothUUID { /// Creates an UUID from its little-endian representation, changing the byte order if necessary. - init?(littleEndian: [UInt8]) { + init?(littleEndian byteValue: [UInt8]) { - let byteValue = isBigEndian ? littleEndian : littleEndian.reversed() - - guard let UUID = BluetoothUUID(data: Data(bytes: byteValue)) + guard let littleEndianUUID = BluetoothUUID(data: Data(bytes: byteValue)) else { return nil } - self = UUID + switch littleEndianUUID { + + case let .bit16(value): + + let currentEndian = UInt16(littleEndian: value) + + self = .bit16(currentEndian) + + case let .bit128(value): + + #if _endian(little) + let currentEndian = value + #else + let currentEndian = UUID(uuid: (value.bytes.5, value.bytes.4, value.bytes.3, value.bytes.2, value.bytes.1, value.bytes.0)) + #endif + + self = .bit128(currentEndian) + } } /// Exports the UUID bytes in its little endian representation, changing the byte order if necessary. var littleEndian: [UInt8] { - let byteValue = Array(self.toData()) - - return isBigEndian ? byteValue : byteValue.reversed() + switch self { + + case let .bit16(value): + + let bytes = value.littleEndian.bytes + + return [bytes.0, bytes.1] + + case let .bit128(value): + + #if _endian(little) + return [UInt8](value.toData()) + #else + return [UInt8](value.toData().reversed()) // byteSwapped + #endif + } } } @@ -221,7 +249,7 @@ public extension UUID { public func toCoreBluetooth() -> CBUUID { - return CBUUID(data: self.toData()) + return CBUUID(data: self.data) } } diff --git a/Sources/Endianness.swift b/Sources/Endianness.swift deleted file mode 100644 index 73e58a863..000000000 --- a/Sources/Endianness.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// Endianness.swift -// SwiftFoundation -// -// Created by Alsey Coleman Miller on 2/29/16. -// Copyright © 2016 PureSwift. All rights reserved. -// - -/// Number can be converted to little / big endian. -public protocol EndianConvertible: Equatable { - - var littleEndian: Self { get } - - var bigEndian: Self { get } -} - -extension Int: EndianConvertible { } -extension UInt16: EndianConvertible { } -extension Int16: EndianConvertible { } -extension UInt32: EndianConvertible { } -extension Int32: EndianConvertible { } -extension UInt64: EndianConvertible { } -extension Int64: EndianConvertible { } - -public extension EndianConvertible { - - /// Converts the number to the current endianness. - var currentEndian: Self { - - return isBigEndian ? bigEndian : littleEndian - } -} - -public let isBigEndian = 10.bigEndian == 10 diff --git a/Tests/BluetoothTests/BluetoothTests.swift b/Tests/BluetoothTests/BluetoothTests.swift index 806872d28..1b70d6de3 100755 --- a/Tests/BluetoothTests/BluetoothTests.swift +++ b/Tests/BluetoothTests/BluetoothTests.swift @@ -205,7 +205,7 @@ final class BluetoothTests: XCTestCase { do { - // bad response + // bad response / malformed data let data: [UInt8] = [16, 1, 0, 255, 255, 40, 0] guard let pdu = ATTReadByGroupTypeRequest(byteValue: data) @@ -213,20 +213,39 @@ final class BluetoothTests: XCTestCase { XCTAssert(pdu.startHandle == 0x0001) XCTAssert(pdu.endHandle == 0xFFFF) + XCTAssert(pdu.type == .bit16(0x0028)) + + // correct values //XCTAssert(pdu.type == GATT.UUID.PrimaryService.toUUID(), "\(pdu.type)") //XCTAssert(pdu.type == .bit16(0x2800)) - XCTAssert(pdu.type == .bit16(0x0028)) } do { - let data: [UInt8] = [16, 1, 0, 255, 255, 40, 0] + let pdu = ATTReadByGroupTypeRequest(startHandle: 0x0001, + endHandle: 0xFFFF, + type: GATT.UUID.PrimaryService.toUUID()) - guard let pdu = ATTReadByGroupTypeRequest(byteValue: data) + XCTAssert(pdu.type == GATT.UUID.PrimaryService.toUUID(), "\(pdu.type)") + XCTAssert(pdu.type == .bit16(0x2800)) + XCTAssert(pdu.type != .bit16(0x0028)) + + let data: [UInt8] = pdu.byteValue + + XCTAssert(data != [16, 1, 0, 255, 255, 40, 0], "Produced malformed data") + XCTAssert(data == [16, 1, 0, 255, 255, 0, 40]) + + guard let decoded = ATTReadByGroupTypeRequest(byteValue: pdu.byteValue) else { XCTFail("Could not parse"); return } - XCTAssert(pdu.startHandle == 0x0001) - XCTAssert(pdu.endHandle == 0xFFFF) + XCTAssert(decoded.startHandle == pdu.startHandle) + XCTAssert(decoded.endHandle == pdu.endHandle) + XCTAssert(decoded.type == pdu.type) + XCTAssert(decoded.type.data == pdu.type.data) + XCTAssert(decoded.type.littleEndian == pdu.type.littleEndian) + XCTAssert(decoded.type == GATT.UUID.PrimaryService.toUUID(), "\(decoded.type)") + XCTAssert(decoded.type == .bit16(0x2800)) + XCTAssert(decoded.type != .bit16(0x0028)) } } }