| 1 | // Copyright (C) 2016 The Qt Company Ltd. |
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
| 3 | |
| 4 | #ifndef QBLUETOOTHUUID_H |
| 5 | #define QBLUETOOTHUUID_H |
| 6 | |
| 7 | #include <QtBluetooth/qtbluetoothglobal.h> |
| 8 | |
| 9 | #include <QtCore/QtGlobal> |
| 10 | #include <QtCore/QMetaType> |
| 11 | #include <QtCore/QUuid> |
| 12 | |
| 13 | #include <QtCore/QDebug> |
| 14 | |
| 15 | #if defined(Q_OS_DARWIN) || defined(Q_QDOC) |
| 16 | Q_FORWARD_DECLARE_OBJC_CLASS(CBUUID); |
| 17 | #endif |
| 18 | |
| 19 | QT_BEGIN_NAMESPACE |
| 20 | |
| 21 | #if !defined(QT_SUPPORTS_INT128) |
| 22 | struct quint128 |
| 23 | { |
| 24 | quint8 data[16]; |
| 25 | }; |
| 26 | #endif |
| 27 | |
| 28 | class Q_BLUETOOTH_EXPORT QBluetoothUuid : public QUuid |
| 29 | { |
| 30 | public: |
| 31 | enum class ProtocolUuid { |
| 32 | Sdp = 0x0001, |
| 33 | Udp = 0x0002, |
| 34 | Rfcomm = 0x0003, |
| 35 | Tcp = 0x0004, |
| 36 | TcsBin = 0x0005, |
| 37 | TcsAt = 0x0006, |
| 38 | Att = 0x0007, |
| 39 | Obex = 0x0008, |
| 40 | Ip = 0x0009, |
| 41 | Ftp = 0x000A, |
| 42 | Http = 0x000C, |
| 43 | Wsp = 0x000E, |
| 44 | Bnep = 0x000F, |
| 45 | Upnp = 0x0010, |
| 46 | Hidp = 0x0011, |
| 47 | HardcopyControlChannel = 0x0012, |
| 48 | HardcopyDataChannel = 0x0014, |
| 49 | HardcopyNotification = 0x0016, |
| 50 | Avctp = 0x0017, |
| 51 | Avdtp = 0x0019, |
| 52 | Cmtp = 0x001B, |
| 53 | UdiCPlain = 0x001D, |
| 54 | McapControlChannel = 0x001E, |
| 55 | McapDataChannel = 0x001F, |
| 56 | L2cap = 0x0100 |
| 57 | }; |
| 58 | |
| 59 | enum class ServiceClassUuid { |
| 60 | ServiceDiscoveryServer = 0x1000, |
| 61 | BrowseGroupDescriptor = 0x1001, |
| 62 | PublicBrowseGroup = 0x1002, |
| 63 | SerialPort = 0x1101, |
| 64 | LANAccessUsingPPP = 0x1102, |
| 65 | DialupNetworking = 0x1103, |
| 66 | IrMCSync = 0x1104, |
| 67 | ObexObjectPush = 0x1105, |
| 68 | OBEXFileTransfer = 0x1106, |
| 69 | IrMCSyncCommand = 0x1107, |
| 70 | Headset = 0x1108, |
| 71 | AudioSource = 0x110a, |
| 72 | AudioSink = 0x110b, |
| 73 | AV_RemoteControlTarget = 0x110c, |
| 74 | AdvancedAudioDistribution = 0x110d, |
| 75 | AV_RemoteControl = 0x110e, |
| 76 | AV_RemoteControlController = 0x110f, |
| 77 | HeadsetAG = 0x1112, |
| 78 | PANU = 0x1115, |
| 79 | NAP = 0x1116, |
| 80 | GN = 0x1117, |
| 81 | DirectPrinting = 0x1118, |
| 82 | ReferencePrinting = 0x1119, |
| 83 | BasicImage = 0x111a, |
| 84 | ImagingResponder = 0x111b, |
| 85 | ImagingAutomaticArchive = 0x111c, |
| 86 | ImagingReferenceObjects = 0x111d, |
| 87 | Handsfree = 0x111e, |
| 88 | HandsfreeAudioGateway = 0x111f, |
| 89 | DirectPrintingReferenceObjectsService = 0x1120, |
| 90 | ReflectedUI = 0x1121, |
| 91 | BasicPrinting = 0x1122, |
| 92 | PrintingStatus = 0x1123, |
| 93 | HumanInterfaceDeviceService = 0x1124, |
| 94 | HardcopyCableReplacement = 0x1125, |
| 95 | HCRPrint = 0x1126, |
| 96 | HCRScan = 0x1127, |
| 97 | SIMAccess = 0x112d, |
| 98 | PhonebookAccessPCE = 0x112e, |
| 99 | PhonebookAccessPSE = 0x112f, |
| 100 | PhonebookAccess = 0x1130, |
| 101 | HeadsetHS = 0x1131, |
| 102 | MessageAccessServer = 0x1132, |
| 103 | MessageNotificationServer = 0x1133, |
| 104 | MessageAccessProfile = 0x1134, |
| 105 | GNSS = 0x1135, |
| 106 | GNSSServer = 0x1136, |
| 107 | Display3D = 0x1137, |
| 108 | Glasses3D = 0x1138, |
| 109 | Synchronization3D = 0x1139, |
| 110 | MPSProfile = 0x113a, |
| 111 | MPSService = 0x113b, |
| 112 | PnPInformation = 0x1200, |
| 113 | GenericNetworking = 0x1201, |
| 114 | GenericFileTransfer = 0x1202, |
| 115 | GenericAudio = 0x1203, |
| 116 | GenericTelephony = 0x1204, |
| 117 | VideoSource = 0x1303, |
| 118 | VideoSink = 0x1304, |
| 119 | VideoDistribution = 0x1305, |
| 120 | HDP = 0x1400, |
| 121 | HDPSource = 0x1401, |
| 122 | HDPSink = 0x1402, |
| 123 | GenericAccess = 0x1800, |
| 124 | GenericAttribute = 0x1801, |
| 125 | ImmediateAlert = 0x1802, |
| 126 | LinkLoss = 0x1803, |
| 127 | TxPower = 0x1804, |
| 128 | CurrentTimeService = 0x1805, |
| 129 | ReferenceTimeUpdateService = 0x1806, |
| 130 | NextDSTChangeService = 0x1807, |
| 131 | Glucose = 0x1808, |
| 132 | HealthThermometer = 0x1809, |
| 133 | DeviceInformation = 0x180a, |
| 134 | HeartRate = 0x180d, |
| 135 | PhoneAlertStatusService = 0x180e, |
| 136 | BatteryService = 0x180f, |
| 137 | BloodPressure = 0x1810, |
| 138 | AlertNotificationService = 0x1811, |
| 139 | HumanInterfaceDevice = 0x1812, |
| 140 | ScanParameters = 0x1813, |
| 141 | RunningSpeedAndCadence = 0x1814, |
| 142 | CyclingSpeedAndCadence = 0x1816, |
| 143 | CyclingPower = 0x1818, |
| 144 | LocationAndNavigation = 0x1819, |
| 145 | EnvironmentalSensing = 0x181a, |
| 146 | BodyComposition = 0x181b, |
| 147 | UserData = 0x181c, |
| 148 | WeightScale = 0x181d, |
| 149 | BondManagement = 0x181e, |
| 150 | ContinuousGlucoseMonitoring = 0x181f |
| 151 | }; |
| 152 | |
| 153 | enum class CharacteristicType { |
| 154 | DeviceName = 0x2a00, |
| 155 | Appearance = 0x2a01, |
| 156 | PeripheralPrivacyFlag = 0x2a02, |
| 157 | ReconnectionAddress = 0x2a03, |
| 158 | PeripheralPreferredConnectionParameters = 0x2a04, |
| 159 | ServiceChanged = 0x2a05, |
| 160 | AlertLevel = 0x2a06, |
| 161 | TxPowerLevel = 0x2a07, |
| 162 | DateTime = 0x2a08, |
| 163 | DayOfWeek = 0x2a09, |
| 164 | DayDateTime = 0x2a0a, |
| 165 | /* 0x2a0b not defined */ |
| 166 | ExactTime256 = 0x2a0c, |
| 167 | DSTOffset = 0x2a0d, |
| 168 | TimeZone = 0x2a0e, |
| 169 | LocalTimeInformation = 0x2a0f, |
| 170 | /* 0x2a10 not defined */ |
| 171 | TimeWithDST = 0x2a11, |
| 172 | TimeAccuracy = 0x2a12, |
| 173 | TimeSource = 0x2a13, |
| 174 | ReferenceTimeInformation = 0x2a14, |
| 175 | /* 0x2a15 not defined */ |
| 176 | TimeUpdateControlPoint = 0x2a16, |
| 177 | TimeUpdateState = 0x2a17, |
| 178 | GlucoseMeasurement = 0x2a18, |
| 179 | BatteryLevel = 0x2a19, |
| 180 | /* 0x2a1a not defined */ |
| 181 | /* 0x2a1b not defined */ |
| 182 | TemperatureMeasurement = 0x2a1c, |
| 183 | TemperatureType = 0x2a1d, |
| 184 | IntermediateTemperature = 0x2a1e, |
| 185 | /* 0x2a1f not defined */ |
| 186 | /* 0x2a20 not defined */ |
| 187 | MeasurementInterval = 0x2a21, |
| 188 | BootKeyboardInputReport = 0x2a22, |
| 189 | SystemID = 0x2a23, |
| 190 | ModelNumberString = 0x2a24, |
| 191 | SerialNumberString = 0x2a25, |
| 192 | FirmwareRevisionString = 0x2a26, |
| 193 | HardwareRevisionString = 0x2a27, |
| 194 | SoftwareRevisionString = 0x2a28, |
| 195 | ManufacturerNameString = 0x2a29, |
| 196 | IEEE1107320601RegulatoryCertificationDataList = 0x2a2a, |
| 197 | CurrentTime = 0x2a2b, |
| 198 | MagneticDeclination = 0x2a2c, |
| 199 | /* 0x2a2d not defined */ |
| 200 | /* 0x2a2e not defined */ |
| 201 | /* 0x2a2f not defined */ |
| 202 | /* 0x2a30 not defined */ |
| 203 | ScanRefresh = 0x2a31, |
| 204 | BootKeyboardOutputReport = 0x2a32, |
| 205 | BootMouseInputReport = 0x2a33, |
| 206 | GlucoseMeasurementContext = 0x2a34, |
| 207 | BloodPressureMeasurement = 0x2a35, |
| 208 | IntermediateCuffPressure = 0x2a36, |
| 209 | HeartRateMeasurement = 0x2a37, |
| 210 | BodySensorLocation = 0x2a38, |
| 211 | HeartRateControlPoint = 0x2a39, |
| 212 | /* 0x2a3a not defined */ |
| 213 | /* 0x2a3b not defined */ |
| 214 | /* 0x2a3c not defined */ |
| 215 | /* 0x2a3d not defined */ |
| 216 | /* 0x2a3e not defined */ |
| 217 | AlertStatus = 0x2a3f, |
| 218 | RingerControlPoint = 0x2a40, |
| 219 | RingerSetting = 0x2a41, |
| 220 | AlertCategoryIDBitMask = 0x2a42, |
| 221 | AlertCategoryID = 0x2a43, |
| 222 | AlertNotificationControlPoint = 0x2a44, |
| 223 | UnreadAlertStatus = 0x2a45, |
| 224 | NewAlert = 0x2a46, |
| 225 | SupportedNewAlertCategory = 0x2a47, |
| 226 | SupportedUnreadAlertCategory = 0x2a48, |
| 227 | BloodPressureFeature = 0x2a49, |
| 228 | HIDInformation = 0x2a4a, |
| 229 | ReportMap = 0x2a4b, |
| 230 | HIDControlPoint = 0x2a4c, |
| 231 | Report = 0x2a4d, |
| 232 | ProtocolMode = 0x2a4e, |
| 233 | ScanIntervalWindow = 0x2a4f, |
| 234 | PnPID = 0x2a50, |
| 235 | GlucoseFeature = 0x2a51, |
| 236 | RecordAccessControlPoint = 0x2a52, |
| 237 | RSCMeasurement = 0x2a53, |
| 238 | RSCFeature = 0x2a54, |
| 239 | SCControlPoint = 0x2a55, |
| 240 | /* 0x2a56 not defined */ |
| 241 | /* 0x2a57 not defined */ |
| 242 | /* 0x2a58 not defined */ |
| 243 | /* 0x2a59 not defined */ |
| 244 | /* 0x2a5a not defined */ |
| 245 | CSCMeasurement = 0x2a5b, |
| 246 | CSCFeature = 0x2a5c, |
| 247 | SensorLocation = 0x2a5d, |
| 248 | /* 0x2a5e not defined */ |
| 249 | /* 0x2a5f not defined */ |
| 250 | /* 0x2a60 not defined */ |
| 251 | /* 0x2a61 not defined */ |
| 252 | /* 0x2a62 not defined */ |
| 253 | CyclingPowerMeasurement = 0x2a63, |
| 254 | CyclingPowerVector = 0x2a64, |
| 255 | CyclingPowerFeature = 0x2a65, |
| 256 | CyclingPowerControlPoint = 0x2a66, |
| 257 | LocationAndSpeed = 0x2a67, |
| 258 | Navigation = 0x2a68, |
| 259 | PositionQuality = 0x2a69, |
| 260 | LNFeature = 0x2a6a, |
| 261 | LNControlPoint = 0x2a6b, |
| 262 | Elevation = 0x2a6c, |
| 263 | Pressure = 0x2a6d, |
| 264 | Temperature = 0x2a6e, |
| 265 | Humidity = 0x2a6f, |
| 266 | TrueWindSpeed = 0x2a70, |
| 267 | TrueWindDirection = 0x2a71, |
| 268 | ApparentWindSpeed = 0x2a72, |
| 269 | ApparentWindDirection = 0x2a73, |
| 270 | GustFactor = 0x2a74, |
| 271 | PollenConcentration = 0x2a75, |
| 272 | UVIndex = 0x2a76, |
| 273 | Irradiance = 0x2a77, |
| 274 | Rainfall = 0x2a78, |
| 275 | WindChill = 0x2a79, |
| 276 | HeatIndex = 0x2a7a, |
| 277 | DewPoint = 0x2a7b, |
| 278 | /* 0x2a7c not defined */ |
| 279 | DescriptorValueChanged = 0x2a7d, |
| 280 | AerobicHeartRateLowerLimit = 0x2a7e, |
| 281 | AerobicThreshold = 0x2a7f, |
| 282 | Age = 0x2a80, |
| 283 | AnaerobicHeartRateLowerLimit = 0x2a81, |
| 284 | AnaerobicHeartRateUpperLimit = 0x2a82, |
| 285 | AnaerobicThreshold = 0x2a83, |
| 286 | AerobicHeartRateUpperLimit = 0x2a84, |
| 287 | DateOfBirth = 0x2a85, |
| 288 | DateOfThresholdAssessment = 0x2a86, |
| 289 | EmailAddress = 0x2a87, |
| 290 | FatBurnHeartRateLowerLimit = 0x2a88, |
| 291 | FatBurnHeartRateUpperLimit = 0x2a89, |
| 292 | FirstName = 0x2a8a, |
| 293 | FiveZoneHeartRateLimits = 0x2a8b, |
| 294 | Gender = 0x2a8c, |
| 295 | HeartRateMax = 0x2a8d, |
| 296 | Height = 0x2a8e, |
| 297 | HipCircumference = 0x2a8f, |
| 298 | LastName = 0x2a90, |
| 299 | MaximumRecommendedHeartRate = 0x2a91, |
| 300 | RestingHeartRate = 0x2a92, |
| 301 | SportTypeForAerobicAnaerobicThresholds = 0x2a93, |
| 302 | ThreeZoneHeartRateLimits = 0x2a94, |
| 303 | TwoZoneHeartRateLimits = 0x2a95, |
| 304 | VO2Max = 0x2a96, |
| 305 | WaistCircumference = 0x2a97, |
| 306 | Weight = 0x2a98, |
| 307 | DatabaseChangeIncrement = 0x2a99, |
| 308 | UserIndex = 0x2a9a, |
| 309 | BodyCompositionFeature = 0x2a9b, |
| 310 | BodyCompositionMeasurement = 0x2a9c, |
| 311 | WeightMeasurement = 0x2a9d, |
| 312 | WeightScaleFeature = 0x2a9e, |
| 313 | UserControlPoint = 0x2a9f, |
| 314 | MagneticFluxDensity2D = 0x2aa0, |
| 315 | MagneticFluxDensity3D = 0x2aa1, |
| 316 | Language = 0x2aa2, |
| 317 | BarometricPressureTrend = 0x2aa3 |
| 318 | }; |
| 319 | |
| 320 | enum class DescriptorType { |
| 321 | UnknownDescriptorType = 0x0, |
| 322 | CharacteristicExtendedProperties = 0x2900, |
| 323 | CharacteristicUserDescription = 0x2901, |
| 324 | ClientCharacteristicConfiguration = 0x2902, |
| 325 | ServerCharacteristicConfiguration = 0x2903, |
| 326 | CharacteristicPresentationFormat = 0x2904, |
| 327 | CharacteristicAggregateFormat = 0x2905, |
| 328 | ValidRange = 0x2906, |
| 329 | ExternalReportReference = 0x2907, |
| 330 | ReportReference = 0x2908, |
| 331 | /* 0x2909 not defined */ |
| 332 | /* 0x290a not defined */ |
| 333 | EnvironmentalSensingConfiguration = 0x290b, |
| 334 | EnvironmentalSensingMeasurement = 0x290c, |
| 335 | EnvironmentalSensingTriggerSetting = 0x290d |
| 336 | }; |
| 337 | |
| 338 | constexpr QBluetoothUuid() noexcept {}; |
| 339 | |
| 340 | // values below are based on Bluetooth BASE_UUID |
| 341 | constexpr QBluetoothUuid(ProtocolUuid uuid) noexcept |
| 342 | : QBluetoothUuid(static_cast<quint32>(uuid)) {}; |
| 343 | constexpr QBluetoothUuid(ServiceClassUuid uuid) noexcept |
| 344 | : QBluetoothUuid(static_cast<quint32>(uuid)) {}; |
| 345 | constexpr QBluetoothUuid(CharacteristicType uuid) noexcept |
| 346 | : QBluetoothUuid(static_cast<quint32>(uuid)) {}; |
| 347 | constexpr QBluetoothUuid(DescriptorType uuid) noexcept |
| 348 | : QBluetoothUuid(static_cast<quint32>(uuid)) {}; |
| 349 | explicit constexpr QBluetoothUuid(quint16 uuid) noexcept |
| 350 | : QBluetoothUuid(quint32{uuid}) {}; |
| 351 | explicit constexpr QBluetoothUuid(quint32 uuid) noexcept |
| 352 | : QUuid(uuid, 0x0, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb) {}; |
| 353 | // end of bluetooth-specific constructors; rest is essentially `using QUuid::QUuid;` |
| 354 | |
| 355 | using QUuid::QUuid; |
| 356 | #if QT_BLUETOOTH_REMOVED_SINCE(6, 6) |
| 357 | explicit QBluetoothUuid(quint128 uuid); |
| 358 | #endif |
| 359 | QT6_ONLY(QT_POST_CXX17_API_IN_EXPORTED_CLASS) // quint128 changes based on QT_SUPPORTS_INT128! |
| 360 | explicit QBluetoothUuid(quint128 uuid, QSysInfo::Endian order = QSysInfo::BigEndian) noexcept |
| 361 | : QUuid{fromBytes(bytes: &uuid, order)} {} |
| 362 | #if QT_BLUETOOTH_REMOVED_SINCE(6, 6) // actually 6.3 (cf. QUuid) |
| 363 | explicit QBluetoothUuid(const QString &uuid); |
| 364 | #endif |
| 365 | QBluetoothUuid(const QBluetoothUuid &uuid) = default; |
| 366 | QT_BLUETOOTH_INLINE_SINCE(6, 6) |
| 367 | QBluetoothUuid(QUuid QT6_ONLY(const &)uuid); |
| 368 | ~QBluetoothUuid() = default; |
| 369 | |
| 370 | QBluetoothUuid &operator=(const QBluetoothUuid &other) = default; |
| 371 | friend bool operator==(const QBluetoothUuid &a, const QBluetoothUuid &b) |
| 372 | { |
| 373 | return static_cast<QUuid>(a) == static_cast<QUuid>(b); |
| 374 | } |
| 375 | friend bool operator!=(const QBluetoothUuid &a, const QBluetoothUuid &b) { return !(a == b); } |
| 376 | #ifndef QT_NO_DEBUG_STREAM |
| 377 | friend Q_BLUETOOTH_EXPORT QDebug operator<<(QDebug debug, const QBluetoothUuid &uuid); |
| 378 | #if QT_BLUETOOTH_REMOVED_SINCE(6, 6) |
| 379 | static QDebug streamingOperator(QDebug debug, const QBluetoothUuid &uuid); |
| 380 | #endif |
| 381 | #endif |
| 382 | |
| 383 | int minimumSize() const; |
| 384 | |
| 385 | quint16 toUInt16(bool *ok = nullptr) const; |
| 386 | quint32 toUInt32(bool *ok = nullptr) const; |
| 387 | |
| 388 | #if QT_BLUETOOTH_REMOVED_SINCE(6, 6) |
| 389 | quint128 toUInt128() const; |
| 390 | #endif |
| 391 | #if defined(Q_QDOC) || !defined(QT_SUPPORTS_INT128) // otherwise falls back to QUuid::toUint128() |
| 392 | quint128 toUInt128(QSysInfo::Endian order = QSysInfo::BigEndian) const noexcept; |
| 393 | #endif |
| 394 | |
| 395 | #if defined(Q_OS_DARWIN) || defined(Q_QDOC) |
| 396 | static QBluetoothUuid fromCBUUID(CBUUID *cbUuid); |
| 397 | CBUUID *toCBUUID() const Q_DECL_NS_RETURNS_AUTORELEASED; |
| 398 | #endif |
| 399 | |
| 400 | static QString serviceClassToString(ServiceClassUuid uuid); |
| 401 | static QString protocolToString(ProtocolUuid uuid); |
| 402 | static QString characteristicToString(CharacteristicType uuid); |
| 403 | static QString descriptorToString(DescriptorType uuid); |
| 404 | }; |
| 405 | |
| 406 | #if QT_BLUETOOTH_INLINE_IMPL_SINCE(6, 6) |
| 407 | QBluetoothUuid::QBluetoothUuid(QUuid QT6_ONLY(const &)uuid) |
| 408 | : QUuid(uuid) |
| 409 | { |
| 410 | } |
| 411 | #endif |
| 412 | |
| 413 | |
| 414 | #ifndef QT_NO_DATASTREAM |
| 415 | inline QDataStream &operator<<(QDataStream &s, const QBluetoothUuid &uuid) |
| 416 | { |
| 417 | return s << static_cast<const QUuid &>(uuid); |
| 418 | } |
| 419 | |
| 420 | inline QDataStream &operator>>(QDataStream &s, QBluetoothUuid &uuid) |
| 421 | { |
| 422 | return s >> static_cast<QUuid &>(uuid); |
| 423 | } |
| 424 | #endif |
| 425 | |
| 426 | QT_END_NAMESPACE |
| 427 | |
| 428 | QT_DECL_METATYPE_EXTERN(QBluetoothUuid, Q_BLUETOOTH_EXPORT) |
| 429 | |
| 430 | #endif |
| 431 | |