Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[#3] Implement HCI LE Commands #21

Merged
merged 74 commits into from
Apr 11, 2018
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
661d9b7
Merge branch 'master' into feature/new_commads
colemancda Mar 31, 2018
7a70c74
Added `StartEncryptionParameter` with its events.
jmarkstar Apr 2, 2018
fe45777
Merge branch 'master' into feature/new_commads
colemancda Apr 2, 2018
adcbf2a
Updated SwiftLint
colemancda Apr 2, 2018
6d05b49
Added Method for `StartEncryptionParameter`
jmarkstar Apr 2, 2018
b56057c
Added comment the method `lowEnergyStartEncryption`
jmarkstar Apr 2, 2018
d7471d9
Merge branch 'master' into feature/new_commads
colemancda Apr 2, 2018
26d1fff
Added LE Long Term Key Request Reply Command
jmarkstar Apr 3, 2018
0fb68d2
Added LE Long Term Key Request Negative Reply Command
jmarkstar Apr 3, 2018
1d060ce
Added `ReceiverTestParameter` and `TransmitterTestParameter`
jmarkstar Apr 3, 2018
7c6a245
Added `LowEnergyState`
colemancda Apr 3, 2018
c7ee734
Added `LowEnergyState.name`
colemancda Apr 3, 2018
97dc096
Merge branch 'master' of github.com:PureSwift/Bluetooth into feature/…
jmarkstar Apr 3, 2018
312b9fd
Merge branch 'feature/new_commads' of github.com:PureSwift/Bluetooth …
jmarkstar Apr 3, 2018
1a3c6ad
Renamed file
colemancda Apr 3, 2018
7ba91d9
Merge branch 'feature/new_commads' of github.com:PureSwift/Bluetooth …
jmarkstar Apr 3, 2018
33ad345
Finished `LowEnergyState`
jmarkstar Apr 4, 2018
d6cc4cc
Added `TestEndReturnParameter`
jmarkstar Apr 4, 2018
3c300bb
Added Comments
jmarkstar Apr 4, 2018
3acd916
Added `AddDeviceToResolvingListParameter` and `RemoveDeviceFromResolv…
jmarkstar Apr 4, 2018
159fcc9
Added `ReadPeerResolvableAddressParameter `
jmarkstar Apr 5, 2018
b466ba2
Added `ReadLocalResolvableAddressParameter`
jmarkstar Apr 5, 2018
4b9e7e5
Swift 3 fixes
colemancda Apr 5, 2018
3f3865a
Merge remote-tracking branch 'origin/feature/new_commads' into featur…
jmarkstar Apr 5, 2018
fb82bb3
Merge branch 'master' into feature/new_commads
jmarkstar Apr 5, 2018
52f472a
Merge branch 'master' into feature/new_commads
colemancda Apr 5, 2018
f546c46
Swift 3 fixes
colemancda Apr 5, 2018
a03af89
Merge branch 'feature/new_commads' of github.com:PureSwift/Bluetooth …
jmarkstar Apr 6, 2018
90e8156
Added `SetAddressResolutionEnableParameter` and `SetResolvablePrivate…
jmarkstar Apr 6, 2018
94dbd2c
Merge branch 'master' into feature/new_commads
colemancda Apr 6, 2018
b972579
Updated `LowEnergyState`
colemancda Apr 6, 2018
77727c2
Added `ReadMaximumDataLengthReturnParameter` and Fixed `SetResolvable…
jmarkstar Apr 7, 2018
9c059ac
Added `ReadPHYParameter`
jmarkstar Apr 7, 2018
6ddebe7
Merge branch 'master' into feature/new_commads
colemancda Apr 8, 2018
afa3a1c
Added `SetDefaultPhyParameter`
jmarkstar Apr 8, 2018
3569b56
Added `SetPhyParameter`
jmarkstar Apr 8, 2018
ce59c30
Added `EnhancedReceiverTestParameter`
jmarkstar Apr 8, 2018
ac27074
Fixed Issues
jmarkstar Apr 9, 2018
14f6f2e
Added `EnhancedTransmitterTest`
jmarkstar Apr 9, 2018
ac8f1d2
Merge branch 'master' into feature/new_commads
colemancda Apr 9, 2018
3085333
Added `SetAdvertisingSetRandomAddress`
jmarkstar Apr 9, 2018
1b6c7b5
Adding `SetAdvertisingSetRandomAddress`
jmarkstar Apr 10, 2018
5dee62e
Merge branch 'master' into feature/new_commads
colemancda Apr 10, 2018
1c236f3
Merge branch 'master' into feature/new_commads
colemancda Apr 10, 2018
8285046
#27 Updated unit tests
colemancda Apr 10, 2018
17d018a
Added `LowEnergyFeaturesCommands.swift`
colemancda Apr 10, 2018
f96c6fb
Updated SwiftLint
colemancda Apr 10, 2018
da63216
SwiftLint fixes
colemancda Apr 10, 2018
9dffb28
Updated unit tests
colemancda Apr 10, 2018
fae4ea4
Updated unit tests
colemancda Apr 10, 2018
99e1ccb
Updated unit tests
colemancda Apr 10, 2018
2de6f72
Updated unit tests
colemancda Apr 10, 2018
794f97a
Updated unit tests
colemancda Apr 10, 2018
1204d75
Fixed typo
colemancda Apr 10, 2018
1af52a8
Updated unit tests
colemancda Apr 10, 2018
ead79d4
Updated `lowEnergyStartEncryption()`
colemancda Apr 10, 2018
9b5ab20
Updated HCI Events
colemancda Apr 10, 2018
6faea20
Updated unit tests
colemancda Apr 10, 2018
3867de2
#3 Fixed HCI Events
colemancda Apr 11, 2018
169598f
Fixed Travis and SwiftLint issues
jmarkstar Apr 11, 2018
ebb9c37
Updated unit tests
colemancda Apr 11, 2018
0fb9d7d
Merge branch 'master' into feature/new_commads
colemancda Apr 11, 2018
0ec0605
Swift 3 fixes
colemancda Apr 11, 2018
58dfb87
Merge branch 'master' into feature/new_commads
colemancda Apr 11, 2018
0fcf872
Added LE Set Random Address command
colemancda Apr 11, 2018
bf4a778
Swift 3 fixes
colemancda Apr 11, 2018
e78fe21
#3 Updated unit tests
colemancda Apr 11, 2018
05ee741
Updated unit tests
colemancda Apr 11, 2018
4e87d6e
Added `SetExtendedAdvertisingParametersParameter`
jmarkstar Apr 11, 2018
4492361
Adding `SetExtendedAdvertisingDataParameter`
jmarkstar Apr 11, 2018
ffa983d
Updated `setLowEnergySetExtendedAdvertisingParameters()`
colemancda Apr 11, 2018
93fef2d
Added HCI Informational Command
colemancda Apr 11, 2018
65c2fcd
Added `readDeviceAddress()`
colemancda Apr 11, 2018
aa8d76e
#3 Updated unit tests
colemancda Apr 11, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ disabled_rules: # rule identifiers to exclude from running
- unused_optional_binding
- redundant_discardable_let
- todo
- identifier_name
opt_in_rules: # some rules are only opt-in
- empty_count
# Find all the available rules by running:
Expand All @@ -38,11 +39,4 @@ type_name:
warning: 50
error: 60
excluded: iPhone # excluded via string
identifier_name:
min_length: # only min_length
error: 2 # only error
excluded: # excluded via string array
- id
- URL
- GlobalAPIKey
reporter: "xcode"
76 changes: 76 additions & 0 deletions Sources/LowEnergyCommandParameter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,82 @@ public extension LowEnergyCommand {
]
}
}

/// LE Start Encryption Command
///
/// command is used to authenticate the given encryption key associated with the remote device specified
/// by the Connection_Handle, and once authenticated will encrypt the connection.
///
/// If the connection is already encrypted then the Controller shall pause connection encryption
/// before attempting to authenticate the given encryption key, and then re-encrypt the connection.
/// While encryption is paused no user data shall be transmitted.
///
/// On an authentication failure, the connection shall be automatically disconnected
/// by the Link Layer. If this command succeeds, then the connection shall be encrypted.
///
/// This command shall only be used when the local device’s role is Master.
public struct StartEncryptionParameter: HCICommandParameter {

public static let command = LowEnergyCommand.startEncryption

/// Range 0x0000-0x0EFF (all other values reserved for future use)
public let connectionHandle: UInt16 //Connection_Handle

/// 64 bit random number.
public let randomNumber: UInt64 //Random_Number

/// 16 bit encrypted diversifier.
public let encryptedDiversifier: UInt16 //Encrypted_Diversifier

/// 128 bit long term key.
public let longTermKey: UInt128 //Long_Term_Key

public init(connectionHandle: UInt16, randomNumber: UInt64, encryptedDiversifier: UInt16, longTermKey: UInt128) {

self.connectionHandle = connectionHandle
self.randomNumber = randomNumber
self.encryptedDiversifier = encryptedDiversifier
self.longTermKey = longTermKey
}

public var byteValue: [UInt8] {
let connectionHandleBytes = connectionHandle.littleEndian.bytes
let randomNumberBytes = randomNumber.littleEndian.bytes
let encryptedDiversifierBytes = encryptedDiversifier.littleEndian.bytes
let longTermKeyBytes = longTermKey.littleEndian.bytes

return [
connectionHandleBytes.0,
connectionHandleBytes.1,
randomNumberBytes.0,
randomNumberBytes.1,
randomNumberBytes.2,
randomNumberBytes.3,
randomNumberBytes.4,
randomNumberBytes.5,
randomNumberBytes.6,
randomNumberBytes.7,
encryptedDiversifierBytes.0,
encryptedDiversifierBytes.1,
longTermKeyBytes.0,
longTermKeyBytes.1,
longTermKeyBytes.2,
longTermKeyBytes.3,
longTermKeyBytes.4,
longTermKeyBytes.5,
longTermKeyBytes.6,
longTermKeyBytes.7,
longTermKeyBytes.8,
longTermKeyBytes.9,
longTermKeyBytes.10,
longTermKeyBytes.11,
longTermKeyBytes.12,
longTermKeyBytes.13,
longTermKeyBytes.14,
longTermKeyBytes.15
]
}
}
}

// MARK: - Command Return Parameters
Expand Down
11 changes: 11 additions & 0 deletions Sources/LowEnergyEncryption.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,15 @@ public extension BluetoothHostControllerInterface {

return returnParameters.randomNumber
}

/// LE Start Encryption Command
///
/// The command is used to authenticate the given encryption key associated with the remote device specified
/// by the Connection_Handle, and once authenticated will encrypt the connection.
func lowEnergyStartEncryption(connectionHandle: UInt16, randomNumber: UInt64, encryptedDiversifier: UInt16, longTermKey: UInt128, timeout: HCICommandTimeout = .default) throws {

let command = LowEnergyCommand.StartEncryptionParameter(connectionHandle: connectionHandle,randomNumber: randomNumber, encryptedDiversifier: encryptedDiversifier, longTermKey: longTermKey)

try deviceRequest(command, timeout: timeout)
}
}
6 changes: 6 additions & 0 deletions Sources/LowEnergyEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ public enum LowEnergyEvent: UInt8, HCIEvent {

/// LE Long Term Key Request
case longTermKeyRequest = 0x05

/// LE Encryption Change
case encryptionChange = 0x08

/// LE Encryption Key Refresh Complete
case encryptionKeyRefreshComplete = 0x30
}

// MARK: - Name
Expand Down
101 changes: 101 additions & 0 deletions Sources/LowEnergyEventParameter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -426,4 +426,105 @@ public extension LowEnergyEvent {
self.features = LowEnergyFeatureSet(rawValue: featuresRawValue)
}
}

/// LE Encryption Change Event
///
/// The Encryption Change event is used to indicate that the change of the encryption mode has been completed.
///
/// This event will occur on both devices to notify the Hosts when Encryption has changed for all connections between the two devices.
/// Note: This event shall not be generated if encryption is paused or resumed; during a role switch, for example.
public struct EncryptionChangeParameter: HCIEventParameter {
public static let event = LowEnergyEvent.encryptionChange // 0x08

public static let length: Int = 4

public let status: HCIStatus

/// The Connection_Handle will be a Connection_Handle for an ACL connection and is used to identify the remote device.
public let handle: UInt16 // Connection_Handle

/// The Encryption_Enabled event parameter specifies the new Encryption_Enabled parameter
/// for the Connection_Handle specified by the Connection_Handle event parameter.
///
/// The meaning of the Encryption_Enabled parameter depends on whether the Host has indicated support for Secure Connections in the Secure_Connections_Host_Support parameter.
/// When Secure_Connections_Host_Support is ‘disabled’ or the Connection_Handle refers to an LE link, the Controller
/// shall only use Encryption_Enabled values 0x00 (OFF) and 0x01 (ON). When Secure_Connections_Host_Support is ‘enabled’ and
/// the Connection_Handle refers to a BR/EDR link, the Controller shall set Encryption_Enabled to 0x00 when encryption is off,
/// to 0x01 when encryption is on and using E0 and to 0x02 when encryption is on and using AES-CCM.
public let encryptionEnabled: EncryptionEnabled

public init?(byteValue: [UInt8]) {
guard byteValue.count == EncryptionChangeParameter.length
else { return nil }

let statusByte = byteValue[0]

let handle = UInt16(littleEndian: UInt16(bytes: (byteValue[1], byteValue[2])))

let encryptionEnabledByte = byteValue[3]

guard let status = HCIStatus(rawValue: statusByte)
else { return nil }

guard let encryptionEnabled = EncryptionEnabled(rawValue: encryptionEnabledByte)
else { return nil }

self.status = status
self.handle = handle
self.encryptionEnabled = encryptionEnabled
}

public enum EncryptionEnabled: UInt8 { // Encryption_Enabled

/// Link Level Encryption is OFF.
case off = 0x00

/// Link Level Encryption is ON with E0 for BR/EDR.
/// Link Level Encryption is ON with AES-CCM for LE.
case e0 = 0x01

/// Link Level Encryption is ON with AES-CCM for BR/EDR.
case aes = 0x02
}
}

/// LE Encryption Key Refresh Complete Event
///
/// The Encryption Key Refresh Complete event is used to indicate to the Host that the encryption key was
/// refreshed on the given Connection_Handle any time encryption is paused and then resumed.
/// The BR/EDR Controller shall send this event when the encryption key has been refreshed
/// due to encryption being started or resumed.
///
/// If the Encryption Key Refresh Complete event was generated due to an encryption pause
/// and resume operation embedded within a change connection link key procedure, t
/// he Encryption Key Refresh Complete event shall be sent prior to the Change Connection Link Key Complete event.
///
/// If the Encryption Key Refresh Complete event was generated due to an encryption pause and
/// resume operation embedded within a role switch procedure,
/// the Encryption Key Refresh Complete event shall be sent prior to the Role Change event.
public struct EncryptionKeyRefreshCompleteParameter: HCIEventParameter {

public static let event = LowEnergyEvent.encryptionKeyRefreshComplete // 0x30

public static let length: Int = 3

public let status: HCIStatus

public let handle: UInt16 // Connection_Handle

public init?(byteValue: [UInt8]) {
guard byteValue.count == EncryptionKeyRefreshCompleteParameter.length
else { return nil }

let statusByte = byteValue[0]

let handle = UInt16(littleEndian: UInt16(bytes: (byteValue[1], byteValue[2])))

guard let status = HCIStatus(rawValue: statusByte)
else { return nil }

self.status = status
self.handle = handle
}
}
}