1 /*
2  * Copyright 2019 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 
17 #define LOG_TAG "bt_shim_storage"
18 
19 #include <algorithm>
20 #include <cstdint>
21 #include <cstring>
22 #include <memory>
23 
24 #include "gd/os/log.h"
25 #include "gd/storage/config_cache_helper.h"
26 #include "gd/storage/storage_module.h"
27 #include "main/shim/config.h"
28 #include "main/shim/entry.h"
29 
30 using ::bluetooth::shim::GetStorage;
31 using ::bluetooth::storage::ConfigCacheHelper;
32 
33 namespace bluetooth {
34 namespace shim {
35 
HasSection(const std::string & section)36 bool BtifConfigInterface::HasSection(const std::string& section) {
37   return GetStorage()->GetConfigCache()->HasSection(section);
38 }
39 
HasProperty(const std::string & section,const std::string & property)40 bool BtifConfigInterface::HasProperty(const std::string& section,
41                                       const std::string& property) {
42   return GetStorage()->GetConfigCache()->HasProperty(section, property);
43 }
44 
GetInt(const std::string & section,const std::string & property,int * value)45 bool BtifConfigInterface::GetInt(const std::string& section,
46                                  const std::string& property, int* value) {
47   ASSERT(value != nullptr);
48   auto ret = ConfigCacheHelper::FromConfigCache(*GetStorage()->GetConfigCache())
49                  .GetInt(section, property);
50   if (ret) {
51     *value = *ret;
52   }
53   return ret.has_value();
54 }
55 
SetInt(const std::string & section,const std::string & property,int value)56 bool BtifConfigInterface::SetInt(const std::string& section,
57                                  const std::string& property, int value) {
58   ConfigCacheHelper::FromConfigCache(*GetStorage()->GetConfigCache())
59       .SetInt(section, property, value);
60   return true;
61 }
62 
GetUint64(const std::string & section,const std::string & property,uint64_t * value)63 bool BtifConfigInterface::GetUint64(const std::string& section,
64                                     const std::string& property,
65                                     uint64_t* value) {
66   ASSERT(value != nullptr);
67   auto ret = ConfigCacheHelper::FromConfigCache(*GetStorage()->GetConfigCache())
68                  .GetUint64(section, property);
69   if (ret) {
70     *value = *ret;
71   }
72   return ret.has_value();
73 }
74 
SetUint64(const std::string & section,const std::string & property,uint64_t value)75 bool BtifConfigInterface::SetUint64(const std::string& section,
76                                     const std::string& property,
77                                     uint64_t value) {
78   ConfigCacheHelper::FromConfigCache(*GetStorage()->GetConfigCache())
79       .SetUint64(section, property, value);
80   return true;
81 }
82 
GetStr(const std::string & section,const std::string & property,char * value,int * size_bytes)83 bool BtifConfigInterface::GetStr(const std::string& section,
84                                  const std::string& property, char* value,
85                                  int* size_bytes) {
86   ASSERT(value != nullptr);
87   ASSERT(size_bytes != nullptr);
88   auto str = GetStorage()->GetConfigCache()->GetProperty(section, property);
89   if (!str) {
90     return false;
91   }
92   if (*size_bytes == 0) {
93     return true;
94   }
95   // std::string::copy does not null-terminate resultant string by default
96   // avoided using strlcpy to prevent extra dependency
97   *size_bytes = str->copy(value, (*size_bytes - 1));
98   value[*size_bytes] = '\0';
99   *size_bytes += 1;
100   return true;
101 }
102 
GetStr(const std::string & section,const std::string & property)103 std::optional<std::string> BtifConfigInterface::GetStr(
104     const std::string& section, const std::string& property) {
105   return GetStorage()->GetConfigCache()->GetProperty(section, property);
106 }
107 
SetStr(const std::string & section,const std::string & property,const std::string & value)108 bool BtifConfigInterface::SetStr(const std::string& section,
109                                  const std::string& property,
110                                  const std::string& value) {
111   GetStorage()->GetConfigCache()->SetProperty(section, property, value);
112   return true;
113 }
114 
115 // TODO: implement encrypted read
GetBin(const std::string & section,const std::string & property,uint8_t * value,size_t * length)116 bool BtifConfigInterface::GetBin(const std::string& section,
117                                  const std::string& property, uint8_t* value,
118                                  size_t* length) {
119   ASSERT(value != nullptr);
120   ASSERT(length != nullptr);
121   auto value_vec =
122       ConfigCacheHelper::FromConfigCache(*GetStorage()->GetConfigCache())
123           .GetBin(section, property);
124   if (!value_vec) {
125     return false;
126   }
127   *length = std::min(value_vec->size(), *length);
128   std::memcpy(value, value_vec->data(), *length);
129   return true;
130 }
GetBinLength(const std::string & section,const std::string & property)131 size_t BtifConfigInterface::GetBinLength(const std::string& section,
132                                          const std::string& property) {
133   auto value_vec =
134       ConfigCacheHelper::FromConfigCache(*GetStorage()->GetConfigCache())
135           .GetBin(section, property);
136   if (!value_vec) {
137     return 0;
138   }
139   return value_vec->size();
140 }
SetBin(const std::string & section,const std::string & property,const uint8_t * value,size_t length)141 bool BtifConfigInterface::SetBin(const std::string& section,
142                                  const std::string& property,
143                                  const uint8_t* value, size_t length) {
144   ASSERT(value != nullptr);
145   std::vector<uint8_t> value_vec(value, value + length);
146   ConfigCacheHelper::FromConfigCache(*GetStorage()->GetConfigCache())
147       .SetBin(section, property, value_vec);
148   return true;
149 }
RemoveProperty(const std::string & section,const std::string & property)150 bool BtifConfigInterface::RemoveProperty(const std::string& section,
151                                          const std::string& property) {
152   return GetStorage()->GetConfigCache()->RemoveProperty(section, property);
153 }
154 
GetPersistentDevices()155 std::vector<std::string> BtifConfigInterface::GetPersistentDevices() {
156   return GetStorage()->GetConfigCache()->GetPersistentSections();
157 }
158 
Save()159 void BtifConfigInterface::Save() { GetStorage()->SaveDelayed(); }
160 
Flush()161 void BtifConfigInterface::Flush() { GetStorage()->SaveImmediately(); }
162 
Clear()163 void BtifConfigInterface::Clear() { GetStorage()->GetConfigCache()->Clear(); }
164 
165 }  // namespace shim
166 }  // namespace bluetooth
167