Skip to content
44 changes: 30 additions & 14 deletions Sources/BluetoothLinux/HCI/HCIDeviceFlag.swift
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
//
// HCIDeviceFlag.swift
//
//
//
// Created by Alsey Coleman Miller on 16/10/21.
//

import Bluetooth

/// HCI device flags
public enum HCIDeviceFlag: Int32, BitMaskOption, CaseIterable {

case up
case initialized
case running

case passiveScan
case interactiveScan
case authenticated
case encrypt
case inquiry

case raw
public struct HCIDeviceFlag: OptionSet, Equatable, Hashable, Sendable {

public let rawValue: UInt32

public init(rawValue: UInt32) {
self.rawValue = rawValue
}

public static let up = HCIDeviceFlag(rawValue: 1 << 0)
public static let initialized = HCIDeviceFlag(rawValue: 1 << 1)
public static let running = HCIDeviceFlag(rawValue: 1 << 2)

public static let passiveScan = HCIDeviceFlag(rawValue: 1 << 3)
public static let interactiveScan = HCIDeviceFlag(rawValue: 1 << 4)
public static let authenticated = HCIDeviceFlag(rawValue: 1 << 5)
public static let encrypt = HCIDeviceFlag(rawValue: 1 << 6)
public static let inquiry = HCIDeviceFlag(rawValue: 1 << 7)

public static let raw = HCIDeviceFlag(rawValue: 1 << 8)
}

public extension HCIDeviceFlag {

/// All defined HCI device flags.
static let all: HCIDeviceFlag = [
.up, .initialized, .running,
.passiveScan, .interactiveScan, .authenticated, .encrypt, .inquiry,
.raw
]
}
14 changes: 4 additions & 10 deletions Sources/BluetoothLinux/HCI/HCIDeviceOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,11 @@ public struct HCIDeviceOptions: RawRepresentable, Equatable, Hashable {

public extension HCIDeviceOptions {

var flags: BitMaskOptionSet<HCIDeviceFlag> {
var options = BitMaskOptionSet<HCIDeviceFlag>()
HCIDeviceFlag.allCases.forEach {
if contains($0) {
options.insert($0)
}
}
return options
var flags: HCIDeviceFlag {
HCIDeviceFlag(rawValue: rawValue).intersection(.all)
}

func contains(_ flag: HCIDeviceFlag) -> Bool {
return (self.rawValue + (UInt32(bitPattern: flag.rawValue) >> 5)) & (1 << (UInt32(bitPattern: flag.rawValue) & 31)) != 0
HCIDeviceFlag(rawValue: rawValue).isSuperset(of: flag)
}
}
24 changes: 15 additions & 9 deletions Sources/BluetoothLinux/HCI/IOCTL/HCIScan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public extension HostController {
func scan(duration: Int = 8,
limit: Int = 255,
deviceClass: (UInt8, UInt8, UInt8)? = nil,
options: BitMaskOptionSet<ScanOption> = []) throws -> [InquiryResult] {
options: ScanOption = []) throws -> [InquiryResult] {

assert(duration > 0, "Scan must be longer than 0 seconds")
assert(limit > 0, "Must scan at least one device")
Expand Down Expand Up @@ -66,12 +66,18 @@ public extension HostController {
public extension HostController {

/// Options for scanning Bluetooth devices
enum ScanOption: UInt16, BitMaskOption {

/// The cache of previously detected devices is flushed before performing the current inquiry.
/// Otherwise, if flags is set to 0, then the results of previous inquiries may be returned,
struct ScanOption: OptionSet, Equatable, Hashable, Sendable {

public let rawValue: UInt16

public init(rawValue: UInt16) {
self.rawValue = rawValue
}

/// The cache of previously detected devices is flushed before performing the current inquiry.
/// Otherwise, if flags is set to 0, then the results of previous inquiries may be returned,
/// even if the devices aren't in range anymore.
case flushCache = 0x0001
public static let flushCache = ScanOption(rawValue: 0x0001)
}

struct InquiryResult {
Expand Down Expand Up @@ -108,7 +114,7 @@ public extension HostControllerIO {

public var deviceClass: (UInt8, UInt8, UInt8)?

public var options: BitMaskOptionSet<HostController.ScanOption>
public var options: HostController.ScanOption

public private(set) var response: [HostController.InquiryResult]

Expand All @@ -117,7 +123,7 @@ public extension HostControllerIO {
duration: UInt8 = 8,
limit: UInt8 = 255,
deviceClass: (UInt8, UInt8, UInt8)? = nil,
options: BitMaskOptionSet<HostController.ScanOption> = []
options: HostController.ScanOption = []
) {
self.device = device
self.duration = duration
Expand Down Expand Up @@ -183,7 +189,7 @@ internal extension SocketDescriptor {
duration: UInt8 = 8,
limit: UInt8 = 255,
deviceClass: (UInt8, UInt8, UInt8)? = nil,
options: BitMaskOptionSet<HostController.ScanOption> = []
options: HostController.ScanOption = []
) throws -> [HostController.InquiryResult] {
var inquiry = HostControllerIO.Inquiry(
device: id,
Expand Down
6 changes: 3 additions & 3 deletions Sources/BluetoothLinux/RFCOMM/IOCTL/RFCOMMCreateDevice.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public extension RFCOMMIO {
@_alwaysEmitIntoClient
public init(
id: HostController.ID,
flags: BitMaskOptionSet<RFCOMMFlag>,
flags: RFCOMMFlag,
source: BluetoothAddress,
destination: BluetoothAddress,
channel: UInt8 = 1
Expand Down Expand Up @@ -59,7 +59,7 @@ public extension RFCOMMIO.CreateDevice {
}

@_alwaysEmitIntoClient
var flags: BitMaskOptionSet<RFCOMMFlag> {
var flags: RFCOMMFlag {
return .init(rawValue: bytes.flags)
}

Expand Down Expand Up @@ -87,7 +87,7 @@ internal extension SocketDescriptor {
@usableFromInline
func rfcommCreateDevice(
id: HostController.ID,
flags: BitMaskOptionSet<RFCOMMFlag> = [],
flags: RFCOMMFlag = [],
source: BluetoothAddress,
destination: BluetoothAddress,
channel: UInt8 = 1
Expand Down
6 changes: 3 additions & 3 deletions Sources/BluetoothLinux/RFCOMM/IOCTL/RFCOMMReleaseDevice.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public extension RFCOMMIO {
@_alwaysEmitIntoClient
public init(
id: HostController.ID,
flags: BitMaskOptionSet<RFCOMMFlag>
flags: RFCOMMFlag
) {
self.init(CInterop.RFCOMMDeviceRequest(
device: id.rawValue,
Expand Down Expand Up @@ -56,7 +56,7 @@ public extension RFCOMMIO.ReleaseDevice {
}

@_alwaysEmitIntoClient
var flags: BitMaskOptionSet<RFCOMMFlag> {
var flags: RFCOMMFlag {
return .init(rawValue: bytes.flags)
}
}
Expand All @@ -68,7 +68,7 @@ internal extension SocketDescriptor {
@usableFromInline
func rfcommReleaseDevice(
id: HostController.ID,
flags: BitMaskOptionSet<RFCOMMFlag> = []
flags: RFCOMMFlag = []
) throws {
var request = RFCOMMIO.ReleaseDevice(
id: id,
Expand Down
2 changes: 1 addition & 1 deletion Sources/BluetoothLinux/RFCOMM/RFCOMMDevice.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public struct RFCOMMDevice: Equatable, Hashable {

public let id: HostController.ID

public var flags: BitMaskOptionSet<RFCOMMFlag>
public var flags: RFCOMMFlag

public var state: RFCOMMState

Expand Down
20 changes: 13 additions & 7 deletions Sources/BluetoothLinux/RFCOMM/RFCOMMFlag.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// File.swift
//
//
//
// Created by Alsey Coleman Miller on 27/10/21.
//
Expand All @@ -9,10 +9,16 @@ import Bluetooth

/// RFCOMM Flags
@frozen
public enum RFCOMMFlag: UInt32, CaseIterable, BitMaskOption {

case reuseDLC = 0x01 // RFCOMM_REUSE_DLC
case releaseOnHangup = 0x02 // RFCOMM_RELEASE_ONHUP
case hangupNow = 0x04 // RFCOMM_HANGUP_NOW
case serialAttached = 0x08 // RFCOMM_TTY_ATTACHED
public struct RFCOMMFlag: OptionSet, Equatable, Hashable, Sendable {

public let rawValue: UInt32

public init(rawValue: UInt32) {
self.rawValue = rawValue
}

public static let reuseDLC = RFCOMMFlag(rawValue: 0x01) // RFCOMM_REUSE_DLC
public static let releaseOnHangup = RFCOMMFlag(rawValue: 0x02) // RFCOMM_RELEASE_ONHUP
public static let hangupNow = RFCOMMFlag(rawValue: 0x04) // RFCOMM_HANGUP_NOW
public static let serialAttached = RFCOMMFlag(rawValue: 0x08) // RFCOMM_TTY_ATTACHED
}
24 changes: 15 additions & 9 deletions Sources/BluetoothLinux/RFCOMM/RFCOMMLinkMode.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// RFCOMMLinkMode.swift
//
//
//
// Created by Alsey Coleman Miller on 27/10/21.
//
Expand All @@ -9,12 +9,18 @@ import Bluetooth

/// RFCOMM Link Mode
@frozen
public enum RFCOMMLinkMode: UInt16, CaseIterable, BitMaskOption {

case master = 0x0001
case authenticated = 0x0002
case encrypted = 0x0004
case trusted = 0x0008
case reliable = 0x0010
case secure = 0x0020
public struct RFCOMMLinkMode: OptionSet, Equatable, Hashable, Sendable {

public let rawValue: UInt16

public init(rawValue: UInt16) {
self.rawValue = rawValue
}

public static let master = RFCOMMLinkMode(rawValue: 0x0001)
public static let authenticated = RFCOMMLinkMode(rawValue: 0x0002)
public static let encrypted = RFCOMMLinkMode(rawValue: 0x0004)
public static let trusted = RFCOMMLinkMode(rawValue: 0x0008)
public static let reliable = RFCOMMLinkMode(rawValue: 0x0010)
public static let secure = RFCOMMLinkMode(rawValue: 0x0020)
}
4 changes: 2 additions & 2 deletions Sources/BluetoothLinux/RFCOMM/RFCOMMSocketOption.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ public extension RFCOMMSocketOption {
@_alwaysEmitIntoClient
public static var id: RFCOMMSocketOption { .connectionInfo }

public var linkMode: BitMaskOptionSet<RFCOMMLinkMode>
public var linkMode: RFCOMMLinkMode

public init(linkMode: BitMaskOptionSet<RFCOMMLinkMode> = []) {
public init(linkMode: RFCOMMLinkMode = []) {
self.linkMode = linkMode
}

Expand Down
Loading