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