1 /* 2 * Copyright (C) 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 <chrono> 20 #include <cstdint> 21 #include <list> 22 #include <memory> 23 #include <mutex> 24 #include <string> 25 #include <vector> 26 27 #include "hci/address.h" 28 #include "module.h" 29 #include "storage/config_cache.h" 30 #include "storage/device.h" 31 #include "storage/mutation.h" 32 33 namespace bluetooth { 34 35 namespace shim { 36 class BtifConfigInterface; 37 } 38 39 namespace security::internal { 40 class SecurityManagerImpl; 41 } 42 43 namespace hci { 44 class AclManager; 45 } 46 47 namespace storage { 48 49 class StorageModule : public bluetooth::Module { 50 public: 51 static const std::string kInfoSection; 52 static const std::string kFileSourceProperty; 53 static const std::string kTimeCreatedProperty; 54 static const std::string kTimeCreatedFormat; 55 56 static const std::string kAdapterSection; 57 58 StorageModule(); 59 StorageModule(os::Handler*); 60 StorageModule(const StorageModule&) = delete; 61 StorageModule& operator=(const StorageModule&) = delete; 62 63 ~StorageModule(); 64 static const ModuleFactory Factory; 65 66 void Start() override; 67 void Stop() override; 68 69 // Methods to access the storage layer via Device abstraction 70 // - Devices will be lazily created when methods below are called. Hence, no std::optional<> nor 71 // nullptr is used in 72 // the return type. User of the API can use the Device object's API to find out if the device 73 // has existed before 74 // - Devices with no config values will not be saved to config cache 75 // - Devices that are not paired will also be discarded when stack shutdown 76 77 // Concept: 78 // 79 // BR/EDR Address: 80 // -> Public static address only, begin with 3 byte IEEE assigned OUI number 81 // 82 // BLE Addresses 83 // -> Public Address: begin with IEEE assigned OUI number 84 // -> Static: static public address do not change 85 // -> Private/Variable: We haven't seen private/variable public address yet 86 // -> Random Address: randomly generated, does not begin with IEEE assigned OUI number 87 // -> Static: static random address do not change 88 // -> Private/Variable: private random address changes once so often 89 // -> Resolvable: this address can be resolved into a static address using identity 90 // resolving key (IRK) 91 // -> Non-resolvable: this address is for temporary use only, do not save this address 92 // 93 // MAC addresses are six bytes only and hence are only regionally unique 94 95 // Get a device object using the |legacy_key_address|. In legacy config, each device's config is 96 // stored in a config section keyed by a single MAC address. For BR/EDR device, this is 97 // straightforward as a BR/EDR device has only a single public static MAC address. However, for LE 98 // devices using private addresses, we only learn its real static address after pairing. Since we 99 // still need to store that device's information prior to pairing, we use the first-seen address 100 // of that device, no matter random private or static public, as a "key" to store that device's 101 // config. This method gives you a device object using this legacy key. If the key does not exist, 102 // the device will be lazily created in the config 103 Device GetDeviceByLegacyKey(hci::Address legacy_key_address); 104 105 // A classic (BR/EDR) or dual mode device can be uniquely located by its classic (BR/EDR) MAC 106 // address 107 Device GetDeviceByClassicMacAddress(hci::Address classic_address); 108 109 // A LE or dual mode device can be uniquely located by its identity address that is either: 110 // -> Public static address 111 // -> Random static address 112 // If remote device uses LE random private resolvable address, user of this API must resolve its 113 // identity address before calling this method to get the device object 114 // 115 // Note: A dual mode device's identity address is normally the same as its BR/EDR address, but 116 // they can also be different. Hence, please don't make such assumption and don't use 117 // GetDeviceByBrEdrMacAddress() interchangeably 118 Device GetDeviceByLeIdentityAddress(hci::Address le_identity_address); 119 120 // Get a list of bonded devices from config 121 std::vector<Device> GetBondedDevices(); 122 123 // Modify the underlying config by starting a mutation. All entries in the mutation will be 124 // applied atomically when Commit() is called. User should never touch ConfigCache() directly. 125 Mutation Modify(); 126 127 protected: 128 void ListDependencies(ModuleList* list) const override; 129 std::string ToString() const override; 130 131 friend shim::BtifConfigInterface; 132 friend hci::AclManager; 133 friend security::internal::SecurityManagerImpl; 134 // For unit test only 135 ConfigCache* GetMemoryOnlyConfigCache(); 136 // Normally, underlying config will be saved at most 3 seconds after the first config change in a 137 // series of changes This method triggers the delayed saving automatically, the delay is equal to 138 // |config_save_delay_| 139 void SaveDelayed(); 140 // In some cases, one may want to save the config immediately to disk. Call this method with 141 // caution as it runs immediately on the calling thread 142 void SaveImmediately(); 143 // remove all content in this config cache, restore it to the state after the explicit constructor 144 void Clear(); 145 146 // Create the storage module where: 147 // - config_file_path is the path to the config file on disk 148 // - config_save_delay is the duration after which to dump config to disk after SaveDelayed() is 149 // called 150 // - temp_devices_capacity is the number of temporary, typically unpaired devices to hold in a 151 // memory based LRU 152 // - is_restricted_mode and is_single_user_mode are flags from upper layer 153 StorageModule(os::Handler* handler, std::string config_file_path, 154 std::chrono::milliseconds config_save_delay, size_t temp_devices_capacity, 155 bool is_restricted_mode, bool is_single_user_mode); 156 157 void SetProperty(std::string section, std::string property, std::string value); 158 159 bool HasSection(const std::string& section) const; 160 bool HasProperty(const std::string& section, const std::string& property) const; 161 162 std::optional<std::string> GetProperty(const std::string& section, 163 const std::string& property) const; 164 165 std::vector<std::string> GetPersistentSections() const; 166 167 void RemoveSection(const std::string& section); 168 bool RemoveProperty(const std::string& section, const std::string& property); 169 void ConvertEncryptOrDecryptKeyIfNeeded(); 170 // Remove sections with |property| set 171 void RemoveSectionWithProperty(const std::string& property); 172 173 void SetBool(const std::string& section, const std::string& property, bool value); 174 std::optional<bool> GetBool(const std::string& section, const std::string& property) const; 175 void SetUint64(const std::string& section, const std::string& property, uint64_t value); 176 std::optional<uint64_t> GetUint64(const std::string& section, const std::string& property) const; 177 void SetUint32(const std::string& section, const std::string& property, uint32_t value); 178 std::optional<uint32_t> GetUint32(const std::string& section, const std::string& property) const; 179 void SetInt64(const std::string& section, const std::string& property, int64_t value); 180 std::optional<int64_t> GetInt64(const std::string& section, const std::string& property) const; 181 void SetInt(const std::string& section, const std::string& property, int value); 182 std::optional<int> GetInt(const std::string& section, const std::string& property) const; 183 void SetBin(const std::string& section, const std::string& property, 184 const std::vector<uint8_t>& value); 185 std::optional<std::vector<uint8_t>> GetBin(const std::string& section, 186 const std::string& property) const; 187 188 // Enable testing of internal methods 189 friend class StorageModuleTest; 190 191 private: 192 struct impl; 193 mutable std::recursive_mutex mutex_; 194 std::unique_ptr<impl> pimpl_; 195 std::string config_file_path_; 196 std::string config_backup_path_; 197 std::chrono::milliseconds config_save_delay_; 198 size_t temp_devices_capacity_; 199 bool is_restricted_mode_; 200 bool is_single_user_mode_; 201 static bool is_config_checksum_pass(int check_bit); 202 }; 203 204 } // namespace storage 205 } // namespace bluetooth 206