1 /* 2 * Copyright 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <functional> 19 #include <limits> 20 #include <optional> 21 #include <string> 22 #include <type_traits> 23 #include <unordered_set> 24 #include <utility> 25 26 #include "hci/address.h" 27 #include "hci/address_with_type.h" 28 #include "hci/class_of_device.h" 29 #include "hci/enum_helper.h" 30 #include "hci/uuid.h" 31 #include "storage/config_cache.h" 32 #include "storage/config_cache_helper.h" 33 #include "storage/config_keys.h" 34 #include "storage/mutation_entry.h" 35 #include "storage/serializable.h" 36 37 namespace bluetooth { 38 namespace storage { 39 40 class LeDevice; 41 class ClassicDevice; 42 43 // Make sure our macro is used 44 #ifdef GENERATE_PROPERTY_GETTER_SETTER_REMOVER 45 static_assert( 46 false, 47 "GENERATE_PROPERTY_GETTER_SETTER_REMOVER() must be uniquely defined once in this file"); 48 #endif 49 50 #define GENERATE_PROPERTY_GETTER_SETTER_REMOVER(NAME, RETURN_TYPE, PROPERTY_KEY) \ 51 public: \ 52 std::optional<RETURN_TYPE> Get##NAME() const { \ 53 return ConfigCacheHelper(*config_).Get<RETURN_TYPE>(section_, PROPERTY_KEY); \ 54 } \ 55 MutationEntry Set##NAME(const RETURN_TYPE& value) { \ 56 return MutationEntry::Set<RETURN_TYPE>(MutationEntry::PropertyType::NORMAL, section_, \ 57 PROPERTY_KEY, value); \ 58 } \ 59 MutationEntry Remove##NAME() { \ 60 return MutationEntry::Remove(MutationEntry::PropertyType::NORMAL, section_, PROPERTY_KEY); \ 61 } 62 63 // Make sure our macro is used 64 #ifdef GENERATE_PROPERTY_GETTER_SETTER_REMOVER_WITH_CUSTOM_SETTER 65 static_assert(false, 66 "GENERATE_PROPERTY_GETTER_SETTER_REMOVER_WITH_CUSTOM_SETTER() must be uniquely " 67 "defined once in this file"); 68 #endif 69 70 // FUNC is bracketed function definition that takes a const RETURN_TYPE& value and return 71 // RETURN_TYPE e.g. { return value + 1; } 72 #define GENERATE_PROPERTY_GETTER_SETTER_REMOVER_WITH_CUSTOM_SETTER(NAME, RETURN_TYPE, \ 73 PROPERTY_KEY, FUNC) \ 74 public: \ 75 std::optional<RETURN_TYPE> Get##NAME() const { \ 76 return ConfigCacheHelper(*config_).Get<RETURN_TYPE>(section_, PROPERTY_KEY); \ 77 } \ 78 MutationEntry Set##NAME(const RETURN_TYPE& value) { \ 79 auto new_value = [this](const RETURN_TYPE& value) -> RETURN_TYPE FUNC(value); \ 80 return MutationEntry::Set<RETURN_TYPE>(MutationEntry::PropertyType::NORMAL, section_, \ 81 PROPERTY_KEY, new_value); \ 82 } \ 83 MutationEntry Remove##NAME() { \ 84 return MutationEntry::Remove(MutationEntry::PropertyType::NORMAL, section_, PROPERTY_KEY); \ 85 } 86 87 // Make sure our macro is used 88 #ifdef GENERATE_TEMP_PROPERTY_GETTER_SETTER_REMOVER 89 static_assert(false, 90 "GENERATE_TEMP_PROPERTY_GETTER_SETTER_REMOVER() must be uniquely defined once in " 91 "this file"); 92 #endif 93 94 // Macro to generate tempoarary property that exists in memory only 95 // It is subjected to a limit of 10,000 devices 96 // It will be cleared when the stack is restarted 97 #define GENERATE_TEMP_PROPERTY_GETTER_SETTER_REMOVER(NAME, RETURN_TYPE, PROPERTY_KEY) \ 98 public: \ 99 std::optional<RETURN_TYPE> GetTemp##NAME() const { \ 100 return ConfigCacheHelper(*memory_only_config_).Get<RETURN_TYPE>(section_, PROPERTY_KEY); \ 101 } \ 102 MutationEntry SetTemp##NAME(const RETURN_TYPE& value) { \ 103 return MutationEntry::Set<RETURN_TYPE>(MutationEntry::PropertyType::MEMORY_ONLY, section_, \ 104 PROPERTY_KEY, value); \ 105 } \ 106 MutationEntry RemoveTemp##NAME() { \ 107 return MutationEntry::Remove(MutationEntry::PropertyType::MEMORY_ONLY, section_, \ 108 PROPERTY_KEY); \ 109 } 110 111 // A think wrapper of device in ConfigCache, allowing easy access to various predefined properties 112 // of a Bluetooth device 113 // 114 // Device, LeDevice, and Classic device objects are fully copyable, comparable hashable 115 // 116 // A newly created device does not have any DeviceType information and user can only read or write 117 // the values in this common Device abstraction layer. 118 // 119 // As soon as a user determines the type of device, they should call SetDeviceType() to assign 120 // device to a type After that, Classic() or Le() will return interfaces that allows access to 121 // deeper layer properties 122 class Device { 123 public: 124 enum ConfigKeyAddressType { 125 LEGACY_KEY_ADDRESS, 126 CLASSIC_ADDRESS, 127 LE_IDENTITY_ADDRESS, 128 LE_LEGACY_PSEUDO_ADDRESS 129 }; 130 131 Device(ConfigCache* config, ConfigCache* memory_only_config, const hci::Address& key_address, 132 ConfigKeyAddressType key_address_type); 133 Device(ConfigCache* config, ConfigCache* memory_only_config, std::string section); 134 135 // for move 136 Device(Device&& other) noexcept = default; 137 Device& operator=(Device&& other) noexcept = default; 138 139 // for copy 140 Device(const Device& other) noexcept = default; 141 Device& operator=(const Device& other) noexcept = default; 142 143 // operators 144 bool operator==(const Device& other) const { 145 return config_ == other.config_ && memory_only_config_ == other.memory_only_config_ && 146 section_ == other.section_; 147 } 148 bool operator!=(const Device& other) const { return !(*this == other); } 149 bool operator<(const Device& other) const { 150 if (config_ != other.config_) { 151 return config_ < other.config_; 152 } 153 if (memory_only_config_ != other.memory_only_config_) { 154 return memory_only_config_ < other.memory_only_config_; 155 } 156 return section_ < other.section_; 157 } 158 bool operator>(const Device& rhs) const { return rhs < *this; } 159 bool operator<=(const Device& rhs) const { return !(*this > rhs); } 160 bool operator>=(const Device& rhs) const { return !(*this < rhs); } 161 162 // A newly created Device object may not be backed by any properties in the ConfigCache, where 163 // Exists() will return false. As soon as a property value is added to the device. Exists() will 164 // become true. 165 bool Exists(); 166 167 // Remove device and all its properties from config and memory-only temp config 168 MutationEntry RemoveFromConfig(); 169 // Remove device and all its properties from memory-only temp config, but keep items in normal 170 // config 171 MutationEntry RemoveFromTempConfig(); 172 173 // Only works when GetDeviceType() returns BR_EDR or DUAL, will crash otherwise 174 // For first time use, please SetDeviceType() to the right value 175 ClassicDevice Classic(); 176 177 // Only works when GetDeviceType() returns LE or DUAL, will crash otherwise 178 // For first time use, please SetDeviceType() to the right value 179 LeDevice Le(); 180 181 // For logging purpose only, you can't get a Device object from parsing a std::string 182 std::string ToLogString() const; 183 184 hci::Address GetAddress() const; 185 186 // Property names that correspond to a link key used in Bluetooth Classic and LE device 187 static const std::unordered_set<std::string_view> kLinkKeyProperties; 188 189 private: 190 ConfigCache* config_; 191 ConfigCache* memory_only_config_; 192 std::string section_; 193 friend std::hash<Device>; 194 195 public: 196 // Macro generate getters, setters and removers 197 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(Name, std::string, BTIF_STORAGE_KEY_NAME); 198 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(ClassOfDevice, hci::ClassOfDevice, 199 BTIF_STORAGE_KEY_DEV_CLASS); 200 GENERATE_PROPERTY_GETTER_SETTER_REMOVER_WITH_CUSTOM_SETTER( 201 DeviceType, hci::DeviceType, BTIF_STORAGE_KEY_DEV_TYPE, { 202 return static_cast<hci::DeviceType>(value | 203 GetDeviceType().value_or(hci::DeviceType::UNKNOWN)); 204 }); 205 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(ServiceUuids, std::vector<hci::Uuid>, 206 BTIF_STORAGE_KEY_REMOTE_SERVICE); 207 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(ManufacturerCode, uint16_t, "Manufacturer"); 208 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(LmpVersion, uint8_t, "LmpVer"); 209 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(LmpSubVersion, uint16_t, "LmpSubVer"); 210 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(SdpDiManufacturer, uint16_t, "SdpDiManufacturer"); 211 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(SdpDiModel, uint16_t, "SdpDiModel"); 212 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(SdpDiHardwareVersion, uint16_t, "SdpDiHardwareVersion"); 213 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(SdpDiVendorIdSource, uint16_t, "SdpDiVendorIdSource"); 214 215 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(MetricsId, int, "MetricsId"); 216 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(PinLength, int, "PinLength"); 217 // unix timestamp in seconds from epoch 218 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(CreationUnixTimestamp, int, BTIF_STORAGE_KEY_DEV_CLASS); 219 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(IsAuthenticated, int, "IsAuthenticated"); 220 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(RequiresMitmProtection, int, "RequiresMitmProtection"); 221 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(IsEncryptionRequired, int, "IsEncryptionRequired"); 222 }; 223 224 } // namespace storage 225 } // namespace bluetooth 226 227 namespace std { 228 template <> 229 struct hash<bluetooth::storage::Device> { 230 std::size_t operator()(const bluetooth::storage::Device& val) const noexcept { 231 std::size_t pointer_hash_1 = std::hash<bluetooth::storage::ConfigCache*>{}(val.config_); 232 std::size_t pointer_hash_2 = std::hash<bluetooth::storage::ConfigCache*>{}(val.config_); 233 std::size_t addr_hash = std::hash<std::string>{}(val.section_); 234 return addr_hash ^ (pointer_hash_1 << 1) ^ (pointer_hash_2 << 2); 235 } 236 }; 237 } // namespace std 238