1 //
2 // Copyright (C) 2016 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 #include "nvram/hal/tests/scoped_nvram_device.h"
18 
19 #include <android-base/logging.h>
20 #include <hardware/hardware.h>
21 #include <hardware/nvram.h>
22 
23 namespace {
24 
StringToBytePtr(const std::string & s)25 const uint8_t* StringToBytePtr(const std::string& s) {
26   return s.empty() ? nullptr : reinterpret_cast<const uint8_t*>(s.data());
27 }
28 
StringToMutableBytePtr(std::string * s)29 uint8_t* StringToMutableBytePtr(std::string* s) {
30   return reinterpret_cast<uint8_t*>(&s->front());
31 }
32 
33 }  // namespace
34 
35 namespace nvram {
36 
ScopedNvramDevice()37 ScopedNvramDevice::ScopedNvramDevice() {
38   const hw_module_t* module = nullptr;
39   int result = hw_get_module(NVRAM_HARDWARE_MODULE_ID, &module);
40   if (result) {
41     LOG(ERROR) << "Failed to load NVRAM module: " << result;
42     return;
43   }
44   result = nvram_open(module, &device_);
45   if (result) {
46     LOG(ERROR) << "Failed to open NVRAM device: " << result;
47     device_ = nullptr;
48     return;
49   }
50   if (device_->common.version != NVRAM_DEVICE_API_VERSION_1_1) {
51     LOG(ERROR) << "Unsupported NVRAM HAL version.";
52     nvram_close(device_);
53     device_ = nullptr;
54     return;
55   }
56 }
57 
~ScopedNvramDevice()58 ScopedNvramDevice::~ScopedNvramDevice() {
59   if (device_) {
60     int result = nvram_close(device_);
61     if (result) {
62       LOG(WARNING) << "Failed to close NVRAM device: " << result;
63       return;
64     }
65   }
66 }
67 
GetTotalSizeInBytes(uint64_t * total_size)68 nvram_result_t ScopedNvramDevice::GetTotalSizeInBytes(uint64_t* total_size) {
69   if (!device_) {
70     return NV_RESULT_INTERNAL_ERROR;
71   }
72   return device_->get_total_size_in_bytes(device_, total_size);
73 }
74 
GetAvailableSizeInBytes(uint64_t * available_size)75 nvram_result_t ScopedNvramDevice::GetAvailableSizeInBytes(
76     uint64_t* available_size) {
77   if (!device_) {
78     return NV_RESULT_INTERNAL_ERROR;
79   }
80   return device_->get_available_size_in_bytes(device_, available_size);
81 }
82 
GetMaxSpaceSizeInBytes(uint64_t * max_space_size)83 nvram_result_t ScopedNvramDevice::GetMaxSpaceSizeInBytes(
84     uint64_t* max_space_size) {
85   if (!device_) {
86     return NV_RESULT_INTERNAL_ERROR;
87   }
88   return device_->get_max_space_size_in_bytes(device_, max_space_size);
89 }
90 
GetMaxSpaces(uint32_t * num_spaces)91 nvram_result_t ScopedNvramDevice::GetMaxSpaces(uint32_t* num_spaces) {
92   if (!device_) {
93     return NV_RESULT_INTERNAL_ERROR;
94   }
95   return device_->get_max_spaces(device_, num_spaces);
96 }
97 
GetSpaceList(std::vector<uint32_t> * space_index_list)98 nvram_result_t ScopedNvramDevice::GetSpaceList(
99     std::vector<uint32_t>* space_index_list) {
100   if (!device_) {
101     return NV_RESULT_INTERNAL_ERROR;
102   }
103   uint32_t max_spaces = 0;
104   nvram_result_t result = device_->get_max_spaces(device_, &max_spaces);
105   if (result) {
106     return result;
107   }
108   space_index_list->resize(max_spaces);
109   uint32_t list_size = 0;
110   result = device_->get_space_list(device_, max_spaces,
111                                    space_index_list->data(), &list_size);
112   if (result) {
113     return result;
114   }
115   space_index_list->resize(list_size);
116   return NV_RESULT_SUCCESS;
117 }
118 
GetSpaceSize(uint32_t index,uint64_t * size)119 nvram_result_t ScopedNvramDevice::GetSpaceSize(uint32_t index, uint64_t* size) {
120   if (!device_) {
121     return NV_RESULT_INTERNAL_ERROR;
122   }
123   return device_->get_space_size(device_, index, size);
124 }
125 
GetSpaceControls(uint32_t index,std::vector<nvram_control_t> * control_list)126 nvram_result_t ScopedNvramDevice::GetSpaceControls(
127     uint32_t index,
128     std::vector<nvram_control_t>* control_list) {
129   constexpr uint32_t kMaxControls = 16;
130   if (!device_) {
131     return NV_RESULT_INTERNAL_ERROR;
132   }
133   control_list->resize(kMaxControls);
134   uint32_t list_size = 0;
135   nvram_result_t result = device_->get_space_controls(
136       device_, index, kMaxControls, control_list->data(), &list_size);
137   if (result) {
138     return result;
139   }
140   control_list->resize(list_size);
141   return NV_RESULT_SUCCESS;
142 }
143 
IsSpaceLocked(uint32_t index,int * write_lock_enabled,int * read_lock_enabled)144 nvram_result_t ScopedNvramDevice::IsSpaceLocked(uint32_t index,
145                                                 int* write_lock_enabled,
146                                                 int* read_lock_enabled) {
147   if (!device_) {
148     return NV_RESULT_INTERNAL_ERROR;
149   }
150   return device_->is_space_locked(device_, index, write_lock_enabled,
151                                   read_lock_enabled);
152 }
153 
CreateSpace(uint32_t index,uint64_t size_in_bytes,const std::vector<nvram_control_t> & control_list,const std::string & authorization_value)154 nvram_result_t ScopedNvramDevice::CreateSpace(
155     uint32_t index,
156     uint64_t size_in_bytes,
157     const std::vector<nvram_control_t>& control_list,
158     const std::string& authorization_value) {
159   if (!device_) {
160     return NV_RESULT_INTERNAL_ERROR;
161   }
162   return device_->create_space(
163       device_, index, size_in_bytes, control_list.data(), control_list.size(),
164       StringToBytePtr(authorization_value), authorization_value.size());
165 }
166 
DeleteSpace(uint32_t index,const std::string & authorization_value)167 nvram_result_t ScopedNvramDevice::DeleteSpace(
168     uint32_t index,
169     const std::string& authorization_value) {
170   return device_->delete_space(device_, index,
171                                StringToBytePtr(authorization_value),
172                                authorization_value.size());
173 }
174 
DisableCreate()175 nvram_result_t ScopedNvramDevice::DisableCreate() {
176   if (!device_) {
177     return NV_RESULT_INTERNAL_ERROR;
178   }
179   return device_->disable_create(device_);
180 }
181 
WriteSpace(uint32_t index,const std::string & data,const std::string & authorization_value)182 nvram_result_t ScopedNvramDevice::WriteSpace(
183     uint32_t index,
184     const std::string& data,
185     const std::string& authorization_value) {
186   if (!device_) {
187     return NV_RESULT_INTERNAL_ERROR;
188   }
189   return device_->write_space(device_, index, StringToBytePtr(data),
190                               data.size(), StringToBytePtr(authorization_value),
191                               authorization_value.size());
192 }
193 
ReadSpace(uint32_t index,uint64_t num_bytes_to_read,const std::string & authorization_value,std::string * data)194 nvram_result_t ScopedNvramDevice::ReadSpace(
195     uint32_t index,
196     uint64_t num_bytes_to_read,
197     const std::string& authorization_value,
198     std::string* data) {
199   if (!device_) {
200     return NV_RESULT_INTERNAL_ERROR;
201   }
202   data->resize(num_bytes_to_read);
203   uint64_t bytes_read = 0;
204   nvram_result_t result = device_->read_space(
205       device_, index, num_bytes_to_read, StringToBytePtr(authorization_value),
206       authorization_value.size(), StringToMutableBytePtr(data), &bytes_read);
207   if (result) {
208     return result;
209   }
210   data->resize(bytes_read);
211   return NV_RESULT_SUCCESS;
212 }
213 
EnableWriteLock(uint32_t index,const std::string & authorization_value)214 nvram_result_t ScopedNvramDevice::EnableWriteLock(
215     uint32_t index,
216     const std::string& authorization_value) {
217   if (!device_) {
218     return NV_RESULT_INTERNAL_ERROR;
219   }
220   return device_->enable_write_lock(device_, index,
221                                     StringToBytePtr(authorization_value),
222                                     authorization_value.size());
223 }
224 
EnableReadLock(uint32_t index,const std::string & authorization_value)225 nvram_result_t ScopedNvramDevice::EnableReadLock(
226     uint32_t index,
227     const std::string& authorization_value) {
228   if (!device_) {
229     return NV_RESULT_INTERNAL_ERROR;
230   }
231   return device_->enable_read_lock(device_, index,
232                                    StringToBytePtr(authorization_value),
233                                    authorization_value.size());
234 }
235 
236 }  // namespace nvram
237