Skip to content

Commit

Permalink
Fixed BluetoothUUID endianess
Browse files Browse the repository at this point in the history
  • Loading branch information
colemancda committed Dec 3, 2017
1 parent f1ef54b commit 658ca82
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 51 deletions.
6 changes: 5 additions & 1 deletion Sources/ATTProtocolDataUnit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)!

Expand Down
48 changes: 38 additions & 10 deletions Sources/BluetoothUUID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public extension BluetoothUUID {
}
}

public func toData() -> Data {
public var data: Data {

switch self {

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

Expand Down Expand Up @@ -221,7 +249,7 @@ public extension UUID {

public func toCoreBluetooth() -> CBUUID {

return CBUUID(data: self.toData())
return CBUUID(data: self.data)
}
}

Expand Down
34 changes: 0 additions & 34 deletions Sources/Endianness.swift

This file was deleted.

31 changes: 25 additions & 6 deletions Tests/BluetoothTests/BluetoothTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -205,28 +205,47 @@ 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)
else { XCTFail("Could not parse"); return }

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))
}
}
}
Expand Down

0 comments on commit 658ca82

Please sign in to comment.