• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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