1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 #include <array> 17 #include <initializer_list> 18 #include <string> 19 #include <unordered_set> 20 21 namespace bt { 22 23 // Represents a 24-bit "Class of Device/Service" field. 24 // This data structure can be directly serialized into HCI command payloads. 25 // See the Bluetooth SIG Assigned Numbers for the Baseband 26 // (https://www.bluetooth.com/specifications/assigned-numbers/baseband) 27 // for the format. 28 class DeviceClass { 29 public: 30 using Bytes = std::array<uint8_t, 3>; 31 32 enum class MajorClass : uint8_t { 33 kMiscellaneous = 0x00, 34 kComputer = 0x01, 35 kPhone = 0x02, 36 kLAN = 0x03, 37 kAudioVideo = 0x04, 38 kPeripheral = 0x05, 39 kImaging = 0x06, 40 kWearable = 0x07, 41 kToy = 0x08, 42 kHealth = 0x09, 43 kUnspecified = 0x1F, 44 }; 45 46 enum class ServiceClass : uint8_t { 47 kLimitedDiscoverableMode = 13, 48 kLEAudio = 14, 49 kReserved = 15, 50 kPositioning = 16, 51 kNetworking = 17, 52 kRendering = 18, 53 kCapturing = 19, 54 kObjectTransfer = 20, 55 kAudio = 21, 56 kTelephony = 22, 57 kInformation = 23, 58 }; 59 60 // Initializes the device to an uncategorized device with no services. 61 DeviceClass(); 62 63 // Initializes the contents from |bytes|, as they are represented from the 64 // controller (little-endian) 65 DeviceClass(std::initializer_list<uint8_t> bytes); 66 67 // Initializes the contents from |uint32_t| 68 explicit DeviceClass(uint32_t value); 69 70 // Initializes the contents using the given |major_class|. 71 explicit DeviceClass(MajorClass major_class); 72 major_class()73 MajorClass major_class() const { return MajorClass(bytes_[1] & 0b1'1111); } 74 75 uint8_t minor_class() const { return (bytes_[0] >> 2) & 0b11'1111; } 76 bytes()77 const Bytes& bytes() const { return bytes_; } 78 79 // Converts the DeviceClass into an integer with host-endianness. Only the 80 // lower 24 bits are used, and the highest 8 bits will be 0. 81 uint32_t to_int() const; 82 83 // Sets the major service classes of this. 84 // Clears any service classes that are not set. 85 void SetServiceClasses(const std::unordered_set<ServiceClass>& classes); 86 87 // Gets a set representing the major service classes that are set. 88 std::unordered_set<ServiceClass> GetServiceClasses() const; 89 90 // Returns a string describing the device, like "Computer" or "Headphones" 91 std::string ToString() const; 92 93 // Equality operators 94 bool operator==(const DeviceClass& rhs) const { return rhs.bytes_ == bytes_; } 95 bool operator!=(const DeviceClass& rhs) const { return rhs.bytes_ != bytes_; } 96 97 // TODO(jamuraa): add MinorClass 98 private: 99 Bytes bytes_; 100 }; 101 102 static_assert(sizeof(DeviceClass) == 3, 103 "DeviceClass must take up exactly 3 bytes"); 104 105 } // namespace bt 106