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