diff --git a/Sources/BluetoothGAP/GAPFlags.swift b/Sources/BluetoothGAP/GAPFlags.swift index 421f1d71f..09f2edae4 100644 --- a/Sources/BluetoothGAP/GAPFlags.swift +++ b/Sources/BluetoothGAP/GAPFlags.swift @@ -8,27 +8,47 @@ import Bluetooth -/// GAP Flag +/** + GAP Flag + + The Flags data type contains one bit Boolean flags. The Flags data type shall be included when any of the Flag bits are non-zero and the advertising packet is connectable, otherwise the Flags data type may be omitted. All 0x00 octets after the last non-zero octet shall be omitted from the value transmitted. + + - Note: If the Flags AD type is not present in a non-connectable advertisement, the Flags should be considered as unknown and no assumptions should be made by the scanner. + + Flags used over the LE physical channel are: + + • Limited Discoverable Mode + + • General Discoverable Mode + + • BR/EDR Not Supported + + • Simultaneous LE and BR/EDR to Same Device Capable (Controller) + + • Simultaneous LE and BR/EDR to Same Device Capable (Host) + + The LE Limited Discoverable Mode and LE General Discoverable Mode flags shall be ignored when received over the BR/EDR physical channel. The ‘BR/ EDR Not Supported’ flag shall be set to 0 when sent over the BR/EDR physical channel. + + The Flags field may be zero or more octets long. This allows the Flags field to be extended while using the minimum number of octets within the data packet. + */ @frozen -public struct GAPFlags: GAPData, Equatable, Hashable { +public struct GAPFlags: GAPData, Equatable, Hashable, OptionSet, Sendable { public static var dataType: GAPDataType { .flags } - public var flags: BitMaskOptionSet + public var rawValue: UInt8 - public init(flags: BitMaskOptionSet = 0) { - self.flags = flags + public init(rawValue: UInt8) { + self.rawValue = rawValue } } public extension GAPFlags { init?(data: Data) where Data : Bluetooth.DataContainer { - guard data.count == 1 else { return nil } - - self.flags = BitMaskOptionSet(rawValue: data[0]) + self.init(rawValue: data[0]) } func append(to data: inout Data) where Data : Bluetooth.DataContainer { @@ -45,16 +65,7 @@ public extension GAPFlags { extension GAPFlags: DataConvertible { static func += (data: inout T, value: GAPFlags) { - data += value.flags.rawValue - } -} - -// MARK: - CustomStringConvertible - -extension GAPFlags: CustomStringConvertible { - - public var description: String { - return flags.description + data += value.rawValue } } @@ -62,48 +73,18 @@ extension GAPFlags: CustomStringConvertible { extension GAPFlags: ExpressibleByIntegerLiteral { - public init(integerLiteral rawValue: GAPFlag.RawValue) { - self.init(flags: BitMaskOptionSet(rawValue: rawValue)) + public init(integerLiteral rawValue: RawValue) { + self.init(rawValue: rawValue) } } // MARK: - ExpressibleByArrayLiteral -extension GAPFlags: ExpressibleByArrayLiteral { - - public init(arrayLiteral elements: GAPFlag...) { - - self.init(flags: BitMaskOptionSet(elements)) - } -} - -// MARK: - Supporting Types +extension GAPFlags: ExpressibleByArrayLiteral { } -/** - GAP Flag - - The Flags data type contains one bit Boolean flags. The Flags data type shall be included when any of the Flag bits are non-zero and the advertising packet is connectable, otherwise the Flags data type may be omitted. All 0x00 octets after the last non-zero octet shall be omitted from the value transmitted. - - - Note: If the Flags AD type is not present in a non-connectable advertisement, the Flags should be considered as unknown and no assumptions should be made by the scanner. - - Flags used over the LE physical channel are: - - • Limited Discoverable Mode - - • General Discoverable Mode - - • BR/EDR Not Supported - - • Simultaneous LE and BR/EDR to Same Device Capable (Controller) - - • Simultaneous LE and BR/EDR to Same Device Capable (Host) - - The LE Limited Discoverable Mode and LE General Discoverable Mode flags shall be ignored when received over the BR/EDR physical channel. The ‘BR/ EDR Not Supported’ flag shall be set to 0 when sent over the BR/EDR physical channel. - - The Flags field may be zero or more octets long. This allows the Flags field to be extended while using the minimum number of octets within the data packet. - */ +// MARK: - Constants -public enum GAPFlag: UInt8, BitMaskOption { +public extension GAPFlags { /** LE Limited Discoverable Mode @@ -112,47 +93,51 @@ public enum GAPFlag: UInt8, BitMaskOption { - SeeAlso: [Bluetooth Advertising Works](https://blog.bluetooth.com/advertising-works-part-2) */ - case lowEnergyLimitedDiscoverableMode = 0b00000001 + static var lowEnergyLimitedDiscoverableMode: GAPFlags { 0b00000001 } /// LE General Discoverable Mode /// /// Use general discoverable mode to advertise indefinitely. - case lowEnergyGeneralDiscoverableMode = 0b00000010 + static var lowEnergyGeneralDiscoverableMode: GAPFlags { 0b00000010 } /// BR/EDR Not Supported. /// /// Bit 37 of LMP Feature Mask Definitions (Page 0) - case notSupportedBREDR = 0b00000100 + static var notSupportedBREDR: GAPFlags { 0b00000100 } /// Simultaneous LE and BR/EDR to Same Device Capable (Controller). /// /// Bit 49 of LMP Feature Mask Definitions (Page 0) - case simultaneousController = 0b00001000 + static var simultaneousController: GAPFlags { 0b00001000 } /// Simultaneous LE and BR/EDR to Same Device Capable (Host). /// /// Bit 66 of LMP Feature Mask Definitions (Page 1) - case simultaneousHost = 0b00010000 - - public static let allCases: [GAPFlag] = [ - .lowEnergyLimitedDiscoverableMode, - .lowEnergyGeneralDiscoverableMode, - .notSupportedBREDR, - .simultaneousController, - .simultaneousHost - ] + static var simultaneousHost: GAPFlags { 0b00010000 } } -extension GAPFlag: CustomStringConvertible { +// MARK: - CustomStringConvertible + +extension GAPFlags: CustomStringConvertible, CustomDebugStringConvertible { + #if hasFeature(Embedded) + public var description: String { + rawValue.description + } + #else + @inline(never) public var description: String { - - switch self { - case .lowEnergyLimitedDiscoverableMode: return "LE Limited Discoverable Mode" - case .lowEnergyGeneralDiscoverableMode: return "LE General Discoverable Mode" - case .notSupportedBREDR: return "BR/EDR Not Supported" - case .simultaneousController: return "Simultaneous LE and BR/EDR Controller" - case .simultaneousHost: return "Simultaneous LE and BR/EDR Host" - } + let descriptions: [(GAPFlags, StaticString)] = [ + (.lowEnergyLimitedDiscoverableMode, ".lowEnergyLimitedDiscoverableMode"), + (.lowEnergyGeneralDiscoverableMode, ".lowEnergyGeneralDiscoverableMode"), + (.notSupportedBREDR, ".notSupportedBREDR"), + (.simultaneousController, ".simultaneousController"), + (.simultaneousHost, ".simultaneousHost") + ] + return buildDescription(descriptions) } + #endif + + /// A textual representation of the file permissions, suitable for debugging. + public var debugDescription: String { self.description } }