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 <array> 19 #include <optional> 20 #include <string> 21 #include <unordered_set> 22 23 #include "hci/link_key.h" 24 #include "storage/config_cache.h" 25 #include "storage/config_cache_helper.h" 26 #include "storage/device.h" 27 28 namespace bluetooth { 29 namespace storage { 30 31 class ClassicDevice { 32 public: 33 ClassicDevice(ConfigCache* config, ConfigCache* memory_only_config, std::string section); 34 35 // for move 36 ClassicDevice(ClassicDevice&& other) noexcept = default; 37 ClassicDevice& operator=(ClassicDevice&& other) noexcept = default; 38 39 // for copy 40 ClassicDevice(const ClassicDevice& other) noexcept = default; 41 ClassicDevice& operator=(const ClassicDevice& other) noexcept = default; 42 43 // operators 44 bool operator==(const ClassicDevice& other) const { 45 return config_ == other.config_ && memory_only_config_ == other.memory_only_config_ && 46 section_ == other.section_; 47 } 48 bool operator!=(const ClassicDevice& other) const { return !(*this == other); } 49 bool operator<(const ClassicDevice& other) const { 50 if (config_ != other.config_) { 51 return config_ < other.config_; 52 } 53 if (memory_only_config_ != other.memory_only_config_) { 54 return memory_only_config_ < other.memory_only_config_; 55 } 56 return section_ < other.section_; 57 } 58 bool operator>(const ClassicDevice& rhs) const { return rhs < *this; } 59 bool operator<=(const ClassicDevice& rhs) const { return !(*this > rhs); } 60 bool operator>=(const ClassicDevice& rhs) const { return !(*this < rhs); } 61 62 // Get the parent device 63 Device Parent(); 64 65 // For logging purpose only, you can't get a ClassicDevice object from parsing a std::string 66 std::string ToLogString() const; 67 68 // Get address of this classic device, it must exist 69 hci::Address GetAddress() const; 70 71 // Return true if device has a link key in one of |kLinkKeyProperties| 72 bool IsPaired() const; 73 74 // Property names that correspond to a link key used in Bluetooth classic device 75 static const std::unordered_set<std::string_view> kLinkKeyProperties; 76 77 private: 78 ConfigCache* config_; 79 ConfigCache* memory_only_config_; 80 std::string section_; 81 friend std::hash<ClassicDevice>; 82 83 public: 84 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(LinkKey, hci::LinkKey, "LinkKey"); 85 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(LinkKeyType, hci::KeyType, "LinkKeyType"); 86 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(SdpDiManufacturer, uint16_t, "SdpDiManufacturer"); 87 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(SdpDiModel, uint16_t, "SdpDiModel"); 88 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(SdpDiHardwareVersion, uint16_t, "SdpDiHardwareVersion"); 89 GENERATE_PROPERTY_GETTER_SETTER_REMOVER(SdpDiVendorIdSource, uint16_t, "SdpDiVendorIdSource"); 90 }; 91 92 } // namespace storage 93 } // namespace bluetooth 94 95 namespace std { 96 template <> 97 struct hash<bluetooth::storage::ClassicDevice> { 98 std::size_t operator()(const bluetooth::storage::ClassicDevice& val) const noexcept { 99 std::size_t pointer_hash_1 = std::hash<bluetooth::storage::ConfigCache*>{}(val.config_); 100 std::size_t pointer_hash_2 = std::hash<bluetooth::storage::ConfigCache*>{}(val.config_); 101 std::size_t addr_hash = std::hash<std::string>{}(val.section_); 102 return addr_hash ^ (pointer_hash_1 << 1) ^ (pointer_hash_2 << 2); 103 } 104 }; 105 } // namespace std 106