Skip to content

Commit

Permalink
Fixed event parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
colemancda committed Nov 30, 2017
1 parent 8e47867 commit 4a08004
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 21 deletions.
11 changes: 5 additions & 6 deletions Sources/HCIGeneralEventParameter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,16 @@ public extension HCIGeneralEvent {
public static let event = HCIGeneralEvent.LowEnergyMeta
public static let length = 1 // 1 ... HCI.maximumEventSize

public var subevent: UInt8 = 0
public var data = [UInt8]()

public init() { }
public let subevent: LowEnergyEvent
public let data: [UInt8]

public init?(byteValue: [UInt8]) {

guard byteValue.count >= LowEnergyMetaParameter.length
guard byteValue.count >= LowEnergyMetaParameter.length,
let subevent = LowEnergyEvent(rawValue: byteValue[0])
else { return nil }

self.subevent = byteValue[0]
self.subevent = subevent

if byteValue.count > 1 {

Expand Down
14 changes: 3 additions & 11 deletions Sources/LowEnergyEventParameter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ public extension LowEnergyEvent {
guard let status = Status(rawValue: statusByte),
let role = Role(rawValue: roleByte),
let peerAddressType = LowEnergyAddressType(rawValue: peerAddressTypeByte),
let interval = ConnectionInterval(rawValue: intervalRawValue),
let latency = ConnectionInterval(rawValue: latencyRawValue),
let supervisionTimeout = SupervisionTimeout(rawValue: supervisionTimeoutRaw),
let masterClockAccuracy = MasterClockAccuracy(rawValue: masterClockAccuracyByte)
else { return nil }
Expand All @@ -128,8 +126,8 @@ public extension LowEnergyEvent {
self.role = role
self.peerAddressType = peerAddressType
self.peerAddress = peerAddress
self.interval = interval
self.latency = latency
self.interval = ConnectionInterval(rawValue: intervalRawValue)
self.latency = ConnectionInterval(rawValue: latencyRawValue)
self.supervisionTimeout = supervisionTimeout
self.masterClockAccuracy = masterClockAccuracy
}
Expand Down Expand Up @@ -159,13 +157,7 @@ public extension LowEnergyEvent {

public let rawValue: UInt16

public init?(rawValue: UInt16) {

guard rawValue >= ConnectionInterval.min.rawValue,
rawValue <= ConnectionInterval.max.rawValue
else { return nil }

assert((ConnectionInterval.min.rawValue ... ConnectionInterval.max.rawValue).contains(rawValue))
public init(rawValue: UInt16) {

self.rawValue = rawValue
}
Expand Down
56 changes: 52 additions & 4 deletions Tests/BluetoothTests/BluetoothTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ final class BluetoothTests: XCTestCase {
static let allTests = [
("testAddress", testAddress),
("testParseAdvertisingReportData", testParseAdvertisingReportData),
("testCommandStatusEvent", testCommandStatusEvent)
("testCommandStatusEvent", testCommandStatusEvent),
("testLEConnection", testLEConnection)
]

func testAddress() {
Expand All @@ -39,11 +40,10 @@ final class BluetoothTests: XCTestCase {

let eventData = Array(data[3 ..< readBytes])

guard let meta = HCIGeneralEvent.LowEnergyMetaParameter(byteValue: eventData),
let lowEnergyEvent = LowEnergyEvent(rawValue: meta.subevent)
guard let meta = HCIGeneralEvent.LowEnergyMetaParameter(byteValue: eventData)
else { XCTFail("Could not parse"); return [] }

XCTAssert(lowEnergyEvent == .advertisingReport, "Invalid event type \(lowEnergyEvent)")
XCTAssert(meta.subevent == .advertisingReport, "Invalid event type \(meta.subevent)")

guard let advertisingReport = LowEnergyEvent.AdvertisingReportEventParameter(byteValue: meta.data)
else { XCTFail("Could not parse"); return [] }
Expand Down Expand Up @@ -100,6 +100,54 @@ final class BluetoothTests: XCTestCase {
XCTAssert(event.status == HCIError.aclConnectionExists.rawValue)
}
}

func testLEConnection() {

do {

let readBytes = 7
let data: [UInt8] = [4, 15, 4, 0, 1, 13, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

guard let event: HCIGeneralEvent.CommandStatusParameter = parseEvent(readBytes, data)
else { XCTFail("Could not parse"); return }

XCTAssert(event.status == 0x00)
}

do {

let readBytes = 22
let data: [UInt8] = [4, 62, 19, 1, 0, 71, 0, 0, 0, 66, 103, 166, 50, 188, 172, 15, 0, 0, 0, 128, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

guard let metaEvent: HCIGeneralEvent.LowEnergyMetaParameter = parseEvent(readBytes, data)
else { XCTFail("Could not parse"); return }

XCTAssert(metaEvent.subevent == .connectionComplete)

guard let event = LowEnergyEvent.ConnectionCompleteParameter(byteValue: metaEvent.data)
else { XCTFail("Could not parse"); return }

XCTAssert(event.status == .success)

print("Connection handle: ", event.handle)
}
}
}

internal func parseEvent <T: HCIEventParameter> (_ actualBytesRead: Int, _ eventBuffer: [UInt8]) -> T? {

let headerData = Array(eventBuffer[1 ..< 1 + HCIEventHeader.length])
let eventData = Array(eventBuffer[(1 + HCIEventHeader.length) ..< actualBytesRead])

guard let eventHeader = HCIEventHeader(bytes: headerData)
else { return nil }

XCTAssert(eventHeader.event == T.event.rawValue)

guard let event = T(byteValue: eventData)
else { return nil }

return event
}

/// HCI Event Packet Header
Expand Down

0 comments on commit 4a08004

Please sign in to comment.