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 <chrono> 20 #include <cstdint> 21 #include <list> 22 #include <memory> 23 #include <mutex> 24 #include <string> 25 26 #include "hci/address.h" 27 #include "module.h" 28 #include "storage/adapter_config.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 storage { 40 41 class StorageModule : public bluetooth::Module { 42 public: 43 static const std::string kInfoSection; 44 static const std::string kFileSourceProperty; 45 static const std::string kTimeCreatedProperty; 46 static const std::string kTimeCreatedFormat; 47 48 static const std::string kAdapterSection; 49 50 StorageModule(const StorageModule&) = delete; 51 StorageModule& operator=(const StorageModule&) = delete; 52 53 ~StorageModule(); 54 static const ModuleFactory Factory; 55 56 // Methods to access the storage layer via Device abstraction 57 // - Devices will be lazily created when methods below are called. Hence, no std::optional<> nor nullptr is used in 58 // the return type. User of the API can use the Device object's API to find out if the device has existed before 59 // - Devices with no config values will not be saved to config cache 60 // - Devices that are not paired will also be discarded when stack shutdown 61 62 // Concept: 63 // 64 // BR/EDR Address: 65 // -> Public static address only, begin with 3 byte IEEE assigned OUI number 66 // 67 // BLE Addresses 68 // -> Public Address: begin with IEEE assigned OUI number 69 // -> Static: static public address do not change 70 // -> Private/Variable: We haven't seen private/variable public address yet 71 // -> Random Address: randomly generated, does not begin with IEEE assigned OUI number 72 // -> Static: static random address do not change 73 // -> Private/Variable: private random address changes once so often 74 // -> Resolvable: this address can be resolved into a static address using identity resolving key (IRK) 75 // -> Non-resolvable: this address is for temporary use only, do not save this address 76 // 77 // MAC addresses are six bytes only and hence are only regionally unique 78 79 // Get a device object using the |legacy_key_address|. In legacy config, each device's config is stored in a config 80 // section keyed by a single MAC address. For BR/EDR device, this is straightforward as a BR/EDR device has only a 81 // single public static MAC address. However, for LE devices using private addresses, we only learn its real static 82 // address after pairing. Since we still need to store that device's information prior to pairing, we use the 83 // first-seen address of that device, no matter random private or static public, as a "key" to store that device's 84 // config. This method gives you a device object using this legacy key. If the key does not exist, the device will 85 // be lazily created in the config 86 Device GetDeviceByLegacyKey(hci::Address legacy_key_address); 87 88 // A classic (BR/EDR) or dual mode device can be uniquely located by its classic (BR/EDR) MAC address 89 Device GetDeviceByClassicMacAddress(hci::Address classic_address); 90 91 // A LE or dual mode device can be uniquely located by its identity address that is either: 92 // -> Public static address 93 // -> Random static address 94 // If remote device uses LE random private resolvable address, user of this API must resolve its identity address 95 // before calling this method to get the device object 96 // 97 // Note: A dual mode device's identity address is normally the same as its BR/EDR address, but they can also be 98 // different. Hence, please don't make such assumption and don't use GetDeviceByBrEdrMacAddress() interchangeably 99 Device GetDeviceByLeIdentityAddress(hci::Address le_identity_address); 100 101 // A think copyable, movable, comparable object that is used to access adapter level information 102 AdapterConfig GetAdapterConfig(); 103 104 // Get a list of bonded devices from config 105 std::vector<Device> GetBondedDevices(); 106 107 // Modify the underlying config by starting a mutation. All entries in the mutation will be applied atomically when 108 // Commit() is called. User should never touch ConfigCache() directly. 109 Mutation Modify(); 110 111 protected: 112 void ListDependencies(ModuleList* list) const override; 113 void Start() override; 114 void Stop() override; 115 std::string ToString() const override; 116 117 friend shim::BtifConfigInterface; 118 // For shim layer only 119 ConfigCache* GetConfigCache(); 120 // For unit test only 121 ConfigCache* GetMemoryOnlyConfigCache(); 122 // Normally, underlying config will be saved at most 3 seconds after the first config change in a series of changes 123 // This method triggers the delayed saving automatically, the delay is equal to |config_save_delay_| 124 void SaveDelayed(); 125 // In some cases, one may want to save the config immediately to disk. Call this method with caution as it runs 126 // immediately on the calling thread 127 void SaveImmediately(); 128 129 // Create the storage module where: 130 // - config_file_path is the path to the config file on disk, a .bak file will be created with the original 131 // - config_save_delay is the duration after which to dump config to disk after SaveDelayed() is called 132 // - temp_devices_capacity is the number of temporary, typically unpaired devices to hold in a memory based LRU 133 // - is_restricted_mode and is_single_user_mode are flags from upper layer 134 StorageModule( 135 std::string config_file_path, 136 std::chrono::milliseconds config_save_delay, 137 size_t temp_devices_capacity, 138 bool is_restricted_mode, 139 bool is_single_user_mode); 140 141 private: 142 struct impl; 143 mutable std::recursive_mutex mutex_; 144 std::unique_ptr<impl> pimpl_; 145 std::string config_file_path_; 146 std::string config_backup_path_; 147 std::chrono::milliseconds config_save_delay_; 148 size_t temp_devices_capacity_; 149 bool is_restricted_mode_; 150 bool is_single_user_mode_; 151 static bool is_config_checksum_pass(int check_bit); 152 }; 153 154 } // namespace storage 155 } // namespace bluetooth 156