xref: /aosp_15_r20/system/nvram/client/nvram_client.c (revision 7ba4dab5cc5e3c8f3eb594dcf3b33f99d9214aee)
1*7ba4dab5SXin Li /*
2*7ba4dab5SXin Li  * Copyright (C) 2016 The Android Open Source Project
3*7ba4dab5SXin Li  *
4*7ba4dab5SXin Li  * Licensed under the Apache License, Version 2.0 (the "License");
5*7ba4dab5SXin Li  * you may not use this file except in compliance with the License.
6*7ba4dab5SXin Li  * You may obtain a copy of the License at
7*7ba4dab5SXin Li  *
8*7ba4dab5SXin Li  *      http://www.apache.org/licenses/LICENSE-2.0
9*7ba4dab5SXin Li  *
10*7ba4dab5SXin Li  * Unless required by applicable law or agreed to in writing, software
11*7ba4dab5SXin Li  * distributed under the License is distributed on an "AS IS" BASIS,
12*7ba4dab5SXin Li  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*7ba4dab5SXin Li  * See the License for the specific language governing permissions and
14*7ba4dab5SXin Li  * limitations under the License.
15*7ba4dab5SXin Li  */
16*7ba4dab5SXin Li 
17*7ba4dab5SXin Li #include <inttypes.h>
18*7ba4dab5SXin Li #include <stdint.h>
19*7ba4dab5SXin Li #include <stdio.h>
20*7ba4dab5SXin Li #include <stdlib.h>
21*7ba4dab5SXin Li #include <string.h>
22*7ba4dab5SXin Li 
23*7ba4dab5SXin Li #include <hardware/nvram.h>
24*7ba4dab5SXin Li 
25*7ba4dab5SXin Li #define countof(array) (sizeof(array) / sizeof((array)[0]))
26*7ba4dab5SXin Li 
27*7ba4dab5SXin Li // Exit status codes. These are all negative as the positive ones are used for
28*7ba4dab5SXin Li // the NV_RESULT_ codes.
29*7ba4dab5SXin Li enum StatusCode {
30*7ba4dab5SXin Li   kStatusInvalidArg = -1,
31*7ba4dab5SXin Li   kStatusHALError = -2,
32*7ba4dab5SXin Li   kStatusAllocationFailure = -3,
33*7ba4dab5SXin Li };
34*7ba4dab5SXin Li 
35*7ba4dab5SXin Li static struct {
36*7ba4dab5SXin Li   int status;
37*7ba4dab5SXin Li   const char* description;
38*7ba4dab5SXin Li } kStatusStringTable[] = {
39*7ba4dab5SXin Li     {kStatusInvalidArg, "Bad parameter"},
40*7ba4dab5SXin Li     {kStatusHALError, "NVRAM HAL initialization error"},
41*7ba4dab5SXin Li     {kStatusAllocationFailure, "Memory allocation error"},
42*7ba4dab5SXin Li     {NV_RESULT_SUCCESS, "Success"},
43*7ba4dab5SXin Li     {NV_RESULT_INTERNAL_ERROR, "Internal error"},
44*7ba4dab5SXin Li     {NV_RESULT_ACCESS_DENIED, "Access denied"},
45*7ba4dab5SXin Li     {NV_RESULT_INVALID_PARAMETER, "Invalid NVRAM parameter"},
46*7ba4dab5SXin Li     {NV_RESULT_SPACE_DOES_NOT_EXIST, "Space does not exist"},
47*7ba4dab5SXin Li     {NV_RESULT_SPACE_ALREADY_EXISTS, "Space already exists"},
48*7ba4dab5SXin Li     {NV_RESULT_OPERATION_DISABLED, "Operation disabled"},
49*7ba4dab5SXin Li };
50*7ba4dab5SXin Li 
51*7ba4dab5SXin Li // Returns a string describing |status|.
StatusToString(int status)52*7ba4dab5SXin Li static const char* StatusToString(int status) {
53*7ba4dab5SXin Li   for (size_t i = 0; i < countof(kStatusStringTable); ++i) {
54*7ba4dab5SXin Li     if (kStatusStringTable[i].status == status) {
55*7ba4dab5SXin Li       return kStatusStringTable[i].description;
56*7ba4dab5SXin Li     }
57*7ba4dab5SXin Li   }
58*7ba4dab5SXin Li 
59*7ba4dab5SXin Li   return "unknown error";
60*7ba4dab5SXin Li }
61*7ba4dab5SXin Li 
62*7ba4dab5SXin Li // A table mapping control values to names.
63*7ba4dab5SXin Li static struct {
64*7ba4dab5SXin Li   nvram_control_t control;
65*7ba4dab5SXin Li   const char* name;
66*7ba4dab5SXin Li } kControlNameTable[] = {
67*7ba4dab5SXin Li     {NV_CONTROL_PERSISTENT_WRITE_LOCK, "PERSISTENT_WRITE_LOCK"},
68*7ba4dab5SXin Li     {NV_CONTROL_BOOT_WRITE_LOCK, "BOOT_WRITE_LOCK"},
69*7ba4dab5SXin Li     {NV_CONTROL_BOOT_READ_LOCK, "BOOT_READ_LOCK"},
70*7ba4dab5SXin Li     {NV_CONTROL_WRITE_AUTHORIZATION, "WRITE_AUTHORIZATION"},
71*7ba4dab5SXin Li     {NV_CONTROL_READ_AUTHORIZATION, "READ_AUTHORIZATION"},
72*7ba4dab5SXin Li     {NV_CONTROL_WRITE_EXTEND, "WRITE_EXTEND"},
73*7ba4dab5SXin Li };
74*7ba4dab5SXin Li 
75*7ba4dab5SXin Li // Returns the string representation of |control|, or NULL if |control| isn't a
76*7ba4dab5SXin Li // valid control value.
ControlToString(nvram_control_t control)77*7ba4dab5SXin Li static const char* ControlToString(nvram_control_t control) {
78*7ba4dab5SXin Li   for (size_t i = 0; i < countof(kControlNameTable); ++i) {
79*7ba4dab5SXin Li     if (kControlNameTable[i].control == control) {
80*7ba4dab5SXin Li       return kControlNameTable[i].name;
81*7ba4dab5SXin Li     }
82*7ba4dab5SXin Li   }
83*7ba4dab5SXin Li 
84*7ba4dab5SXin Li   return NULL;
85*7ba4dab5SXin Li }
86*7ba4dab5SXin Li 
87*7ba4dab5SXin Li // Sets |control| to the NV_CONTROL_ value corresponding to the string control
88*7ba4dab5SXin Li // representation found in |name|. Returns 0 if successful, 1 if name doesn't
89*7ba4dab5SXin Li // match any control string.
StringToControl(const char * name,nvram_control_t * control)90*7ba4dab5SXin Li static int StringToControl(const char* name, nvram_control_t* control) {
91*7ba4dab5SXin Li   for (size_t i = 0; i < countof(kControlNameTable); ++i) {
92*7ba4dab5SXin Li     if (strcmp(kControlNameTable[i].name, name) == 0) {
93*7ba4dab5SXin Li       *control = kControlNameTable[i].control;
94*7ba4dab5SXin Li       return 0;
95*7ba4dab5SXin Li     }
96*7ba4dab5SXin Li   }
97*7ba4dab5SXin Li 
98*7ba4dab5SXin Li   return 1;
99*7ba4dab5SXin Li }
100*7ba4dab5SXin Li 
HandleGetTotalSize(nvram_device_t * device,char * args[])101*7ba4dab5SXin Li static int HandleGetTotalSize(nvram_device_t* device, char* args[]) {
102*7ba4dab5SXin Li   (void)args;
103*7ba4dab5SXin Li   uint64_t total_size = 0;
104*7ba4dab5SXin Li   nvram_result_t result = device->get_total_size_in_bytes(device, &total_size);
105*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
106*7ba4dab5SXin Li     return result;
107*7ba4dab5SXin Li   }
108*7ba4dab5SXin Li 
109*7ba4dab5SXin Li   printf("%" PRIu64 "\n", total_size);
110*7ba4dab5SXin Li   return 0;
111*7ba4dab5SXin Li }
112*7ba4dab5SXin Li 
HandleGetAvailableSize(nvram_device_t * device,char * args[])113*7ba4dab5SXin Li static int HandleGetAvailableSize(nvram_device_t* device, char* args[]) {
114*7ba4dab5SXin Li   (void)args;
115*7ba4dab5SXin Li   uint64_t available_size = 0;
116*7ba4dab5SXin Li   nvram_result_t result =
117*7ba4dab5SXin Li       device->get_available_size_in_bytes(device, &available_size);
118*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
119*7ba4dab5SXin Li     return result;
120*7ba4dab5SXin Li   }
121*7ba4dab5SXin Li 
122*7ba4dab5SXin Li   printf("%" PRIu64 "\n", available_size);
123*7ba4dab5SXin Li   return 0;
124*7ba4dab5SXin Li }
125*7ba4dab5SXin Li 
HandleGetMaxSpaceSize(nvram_device_t * device,char * args[])126*7ba4dab5SXin Li static int HandleGetMaxSpaceSize(nvram_device_t* device, char* args[]) {
127*7ba4dab5SXin Li   (void)args;
128*7ba4dab5SXin Li   uint64_t max_space_size = 0;
129*7ba4dab5SXin Li   nvram_result_t result =
130*7ba4dab5SXin Li       device->get_max_space_size_in_bytes(device, &max_space_size);
131*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
132*7ba4dab5SXin Li     return result;
133*7ba4dab5SXin Li   }
134*7ba4dab5SXin Li 
135*7ba4dab5SXin Li   printf("%" PRIu64 "\n", max_space_size);
136*7ba4dab5SXin Li   return 0;
137*7ba4dab5SXin Li }
138*7ba4dab5SXin Li 
HandleGetMaxSpaces(nvram_device_t * device,char * args[])139*7ba4dab5SXin Li static int HandleGetMaxSpaces(nvram_device_t* device, char* args[]) {
140*7ba4dab5SXin Li   (void)args;
141*7ba4dab5SXin Li   uint32_t max_spaces = 0;
142*7ba4dab5SXin Li   nvram_result_t result = device->get_max_spaces(device, &max_spaces);
143*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
144*7ba4dab5SXin Li     return result;
145*7ba4dab5SXin Li   }
146*7ba4dab5SXin Li 
147*7ba4dab5SXin Li   printf("%" PRIu32 "\n", max_spaces);
148*7ba4dab5SXin Li   return 0;
149*7ba4dab5SXin Li }
150*7ba4dab5SXin Li 
HandleGetSpaceList(nvram_device_t * device,char * args[])151*7ba4dab5SXin Li static int HandleGetSpaceList(nvram_device_t* device, char* args[]) {
152*7ba4dab5SXin Li   (void)args;
153*7ba4dab5SXin Li   uint32_t list_size = 0;
154*7ba4dab5SXin Li   nvram_result_t result = device->get_space_list(device, 0, NULL, &list_size);
155*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
156*7ba4dab5SXin Li     return result;
157*7ba4dab5SXin Li   }
158*7ba4dab5SXin Li 
159*7ba4dab5SXin Li   uint32_t* space_index_list = calloc(list_size, sizeof(uint32_t));
160*7ba4dab5SXin Li   if (!space_index_list) {
161*7ba4dab5SXin Li     return kStatusAllocationFailure;
162*7ba4dab5SXin Li   }
163*7ba4dab5SXin Li 
164*7ba4dab5SXin Li   result =
165*7ba4dab5SXin Li       device->get_space_list(device, list_size, space_index_list, &list_size);
166*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
167*7ba4dab5SXin Li     free(space_index_list);
168*7ba4dab5SXin Li     return result;
169*7ba4dab5SXin Li   }
170*7ba4dab5SXin Li 
171*7ba4dab5SXin Li   for (uint32_t i = 0; i < list_size; ++i) {
172*7ba4dab5SXin Li     if (i != 0) {
173*7ba4dab5SXin Li       fputs(",", stdout);
174*7ba4dab5SXin Li     }
175*7ba4dab5SXin Li     printf("%" PRIu32, space_index_list[i]);
176*7ba4dab5SXin Li   }
177*7ba4dab5SXin Li   fputs("\n", stdout);
178*7ba4dab5SXin Li 
179*7ba4dab5SXin Li   free(space_index_list);
180*7ba4dab5SXin Li   return 0;
181*7ba4dab5SXin Li }
182*7ba4dab5SXin Li 
HandleGetSpaceSize(nvram_device_t * device,char * args[])183*7ba4dab5SXin Li static int HandleGetSpaceSize(nvram_device_t* device, char* args[]) {
184*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
185*7ba4dab5SXin Li   uint64_t space_size = 0;
186*7ba4dab5SXin Li   nvram_result_t result = device->get_space_size(device, index, &space_size);
187*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
188*7ba4dab5SXin Li     return result;
189*7ba4dab5SXin Li   }
190*7ba4dab5SXin Li 
191*7ba4dab5SXin Li   printf("%" PRIu64 "\n", space_size);
192*7ba4dab5SXin Li   return 0;
193*7ba4dab5SXin Li }
194*7ba4dab5SXin Li 
HandleGetSpaceControls(nvram_device_t * device,char * args[])195*7ba4dab5SXin Li static int HandleGetSpaceControls(nvram_device_t* device, char* args[]) {
196*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
197*7ba4dab5SXin Li   uint32_t list_size = 0;
198*7ba4dab5SXin Li   nvram_result_t result =
199*7ba4dab5SXin Li       device->get_space_controls(device, index, 0, NULL, &list_size);
200*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
201*7ba4dab5SXin Li     return result;
202*7ba4dab5SXin Li   }
203*7ba4dab5SXin Li 
204*7ba4dab5SXin Li   uint32_t* controls_list = calloc(list_size, sizeof(nvram_control_t));
205*7ba4dab5SXin Li   if (!controls_list) {
206*7ba4dab5SXin Li     return kStatusAllocationFailure;
207*7ba4dab5SXin Li   }
208*7ba4dab5SXin Li 
209*7ba4dab5SXin Li   result = device->get_space_controls(device, index, list_size, controls_list,
210*7ba4dab5SXin Li                                       &list_size);
211*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
212*7ba4dab5SXin Li     free(controls_list);
213*7ba4dab5SXin Li     return result;
214*7ba4dab5SXin Li   }
215*7ba4dab5SXin Li 
216*7ba4dab5SXin Li   for (uint32_t i = 0; i < list_size; ++i) {
217*7ba4dab5SXin Li     if (i != 0) {
218*7ba4dab5SXin Li       fputs(",", stdout);
219*7ba4dab5SXin Li     }
220*7ba4dab5SXin Li     const char* name = ControlToString(controls_list[i]);
221*7ba4dab5SXin Li     if (name) {
222*7ba4dab5SXin Li       fputs(name, stdout);
223*7ba4dab5SXin Li     } else {
224*7ba4dab5SXin Li       printf("<unknown_control_%" PRIu32 ">", controls_list[i]);
225*7ba4dab5SXin Li     }
226*7ba4dab5SXin Li   }
227*7ba4dab5SXin Li   fputs("", stdout);
228*7ba4dab5SXin Li 
229*7ba4dab5SXin Li   free(controls_list);
230*7ba4dab5SXin Li   return 0;
231*7ba4dab5SXin Li }
232*7ba4dab5SXin Li 
HandleIsSpaceReadLocked(nvram_device_t * device,char * args[])233*7ba4dab5SXin Li static int HandleIsSpaceReadLocked(nvram_device_t* device, char* args[]) {
234*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
235*7ba4dab5SXin Li   int read_locked = 0;
236*7ba4dab5SXin Li   int write_locked = 0;
237*7ba4dab5SXin Li   nvram_result_t result =
238*7ba4dab5SXin Li       device->is_space_locked(device, index, &read_locked, &write_locked);
239*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
240*7ba4dab5SXin Li     return result;
241*7ba4dab5SXin Li   }
242*7ba4dab5SXin Li 
243*7ba4dab5SXin Li   printf("%d\n", read_locked);
244*7ba4dab5SXin Li   return 0;
245*7ba4dab5SXin Li }
246*7ba4dab5SXin Li 
HandleIsSpaceWriteLocked(nvram_device_t * device,char * args[])247*7ba4dab5SXin Li static int HandleIsSpaceWriteLocked(nvram_device_t* device, char* args[]) {
248*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
249*7ba4dab5SXin Li   int read_locked = 0;
250*7ba4dab5SXin Li   int write_locked = 0;
251*7ba4dab5SXin Li   nvram_result_t result =
252*7ba4dab5SXin Li       device->is_space_locked(device, index, &read_locked, &write_locked);
253*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
254*7ba4dab5SXin Li     return result;
255*7ba4dab5SXin Li   }
256*7ba4dab5SXin Li 
257*7ba4dab5SXin Li   printf("%d\n", write_locked);
258*7ba4dab5SXin Li   return 0;
259*7ba4dab5SXin Li }
260*7ba4dab5SXin Li 
HandleCreateSpace(nvram_device_t * device,char * args[])261*7ba4dab5SXin Li static int HandleCreateSpace(nvram_device_t* device, char* args[]) {
262*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
263*7ba4dab5SXin Li   uint64_t size = strtoull(args[1], NULL, 0);
264*7ba4dab5SXin Li   uint32_t list_size = 0;
265*7ba4dab5SXin Li   nvram_control_t* controls_list = NULL;
266*7ba4dab5SXin Li   char* tail = args[2];
267*7ba4dab5SXin Li   while (tail) {
268*7ba4dab5SXin Li     ++list_size;
269*7ba4dab5SXin Li     nvram_control_t* new_controls_list =
270*7ba4dab5SXin Li         realloc(controls_list, sizeof(nvram_control_t) * list_size);
271*7ba4dab5SXin Li     if (new_controls_list) {
272*7ba4dab5SXin Li       controls_list = new_controls_list;
273*7ba4dab5SXin Li     } else {
274*7ba4dab5SXin Li       free(controls_list);
275*7ba4dab5SXin Li       return kStatusAllocationFailure;
276*7ba4dab5SXin Li     }
277*7ba4dab5SXin Li 
278*7ba4dab5SXin Li     if (StringToControl(strsep(&tail, ","), &(controls_list[list_size - 1]))) {
279*7ba4dab5SXin Li       free(controls_list);
280*7ba4dab5SXin Li       return kStatusInvalidArg;
281*7ba4dab5SXin Li     }
282*7ba4dab5SXin Li   }
283*7ba4dab5SXin Li 
284*7ba4dab5SXin Li   return device->create_space(device, index, size, controls_list, list_size,
285*7ba4dab5SXin Li                               (uint8_t*)args[3], strlen(args[3]));
286*7ba4dab5SXin Li }
287*7ba4dab5SXin Li 
HandleDeleteSpace(nvram_device_t * device,char * args[])288*7ba4dab5SXin Li static int HandleDeleteSpace(nvram_device_t* device, char* args[]) {
289*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
290*7ba4dab5SXin Li   return device->delete_space(device, index, (uint8_t*)args[3],
291*7ba4dab5SXin Li                               strlen(args[3]));
292*7ba4dab5SXin Li }
293*7ba4dab5SXin Li 
HandleDisableCreate(nvram_device_t * device,char * args[])294*7ba4dab5SXin Li static int HandleDisableCreate(nvram_device_t* device, char* args[]) {
295*7ba4dab5SXin Li   (void)args;
296*7ba4dab5SXin Li   return device->disable_create(device);
297*7ba4dab5SXin Li }
298*7ba4dab5SXin Li 
HandleWriteSpace(nvram_device_t * device,char * args[])299*7ba4dab5SXin Li static int HandleWriteSpace(nvram_device_t* device, char* args[]) {
300*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
301*7ba4dab5SXin Li   return device->write_space(device, index, (uint8_t*)args[1], strlen(args[1]),
302*7ba4dab5SXin Li                              (uint8_t*)args[2], strlen(args[2]));
303*7ba4dab5SXin Li }
304*7ba4dab5SXin Li 
HandleReadSpace(nvram_device_t * device,char * args[])305*7ba4dab5SXin Li static int HandleReadSpace(nvram_device_t* device, char* args[]) {
306*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
307*7ba4dab5SXin Li   uint64_t size = 0;
308*7ba4dab5SXin Li   nvram_result_t result = device->get_space_size(device, index, &size);
309*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
310*7ba4dab5SXin Li     return result;
311*7ba4dab5SXin Li   }
312*7ba4dab5SXin Li 
313*7ba4dab5SXin Li   uint8_t* buffer = calloc(sizeof(uint8_t), size);
314*7ba4dab5SXin Li   if (!buffer) {
315*7ba4dab5SXin Li     return kStatusAllocationFailure;
316*7ba4dab5SXin Li   }
317*7ba4dab5SXin Li 
318*7ba4dab5SXin Li   result = device->read_space(device, index, size, (uint8_t*)args[1],
319*7ba4dab5SXin Li                               strlen(args[1]), buffer, &size);
320*7ba4dab5SXin Li   if (result != NV_RESULT_SUCCESS) {
321*7ba4dab5SXin Li     free(buffer);
322*7ba4dab5SXin Li     return result;
323*7ba4dab5SXin Li   }
324*7ba4dab5SXin Li 
325*7ba4dab5SXin Li   fwrite(buffer, sizeof(uint8_t), size, stdout);
326*7ba4dab5SXin Li   fputs("\n", stdout);
327*7ba4dab5SXin Li   free(buffer);
328*7ba4dab5SXin Li   return 0;
329*7ba4dab5SXin Li }
330*7ba4dab5SXin Li 
HandleEnableWriteLock(nvram_device_t * device,char * args[])331*7ba4dab5SXin Li static int HandleEnableWriteLock(nvram_device_t* device, char* args[]) {
332*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
333*7ba4dab5SXin Li   return device->enable_write_lock(device, index, (uint8_t*)args[1],
334*7ba4dab5SXin Li                                    strlen(args[1]));
335*7ba4dab5SXin Li }
336*7ba4dab5SXin Li 
HandleEnableReadLock(nvram_device_t * device,char * args[])337*7ba4dab5SXin Li static int HandleEnableReadLock(nvram_device_t* device, char* args[]) {
338*7ba4dab5SXin Li   uint32_t index = strtoul(args[0], NULL, 0);
339*7ba4dab5SXin Li   return device->enable_read_lock(device, index, (uint8_t*)args[1],
340*7ba4dab5SXin Li                                   strlen(args[1]));
341*7ba4dab5SXin Li }
342*7ba4dab5SXin Li 
343*7ba4dab5SXin Li struct CommandHandler {
344*7ba4dab5SXin Li   const char* name;
345*7ba4dab5SXin Li   const char* params_desc;
346*7ba4dab5SXin Li   int nparams;
347*7ba4dab5SXin Li   int (*run)(nvram_device_t*, char* args[]);
348*7ba4dab5SXin Li };
349*7ba4dab5SXin Li 
350*7ba4dab5SXin Li struct CommandHandler kCommandHandlers[] = {
351*7ba4dab5SXin Li     {"get_total_size", "", 0, &HandleGetTotalSize},
352*7ba4dab5SXin Li     {"get_available_size", "", 0, &HandleGetAvailableSize},
353*7ba4dab5SXin Li     {"get_max_space_size", "", 0, &HandleGetMaxSpaceSize},
354*7ba4dab5SXin Li     {"get_max_spaces", "", 0, &HandleGetMaxSpaces},
355*7ba4dab5SXin Li     {"get_space_list", "", 0, &HandleGetSpaceList},
356*7ba4dab5SXin Li     {"get_space_size", "<index>", 1, &HandleGetSpaceSize},
357*7ba4dab5SXin Li     {"get_space_controls", "<index>", 1, &HandleGetSpaceControls},
358*7ba4dab5SXin Li     {"is_space_read_locked", "<index>", 1, &HandleIsSpaceReadLocked},
359*7ba4dab5SXin Li     {"is_space_write_locked", "<index>", 1, &HandleIsSpaceWriteLocked},
360*7ba4dab5SXin Li     {"create_space", "<index> <size> <controls> <auth>", 4, &HandleCreateSpace},
361*7ba4dab5SXin Li     {"delete_space", "<index> <auth>", 2, &HandleDeleteSpace},
362*7ba4dab5SXin Li     {"disable_create", "", 0, &HandleDisableCreate},
363*7ba4dab5SXin Li     {"write_space", "<index> <data> <auth>", 3, &HandleWriteSpace},
364*7ba4dab5SXin Li     {"read_space", "<index> <auth>", 2, &HandleReadSpace},
365*7ba4dab5SXin Li     {"enable_write_lock", "<index> <auth>", 2, &HandleEnableWriteLock},
366*7ba4dab5SXin Li     {"enable_read_lock", "<index> <auth>", 2, &HandleEnableReadLock},
367*7ba4dab5SXin Li };
368*7ba4dab5SXin Li 
main(int argc,char * argv[])369*7ba4dab5SXin Li int main(int argc, char* argv[]) {
370*7ba4dab5SXin Li   if (argc < 2) {
371*7ba4dab5SXin Li     fprintf(stderr, "Usage: %s <command> <command-args>\n", argv[0]);
372*7ba4dab5SXin Li     fprintf(stderr, "Valid commands are:\n");
373*7ba4dab5SXin Li     for (size_t i = 0; i < countof(kCommandHandlers); ++i) {
374*7ba4dab5SXin Li       fprintf(stderr, "  %s %s\n", kCommandHandlers[i].name,
375*7ba4dab5SXin Li               kCommandHandlers[i].params_desc);
376*7ba4dab5SXin Li     }
377*7ba4dab5SXin Li     return kStatusInvalidArg;
378*7ba4dab5SXin Li   }
379*7ba4dab5SXin Li 
380*7ba4dab5SXin Li   const struct CommandHandler* cmd = NULL;
381*7ba4dab5SXin Li   for (size_t i = 0; i < countof(kCommandHandlers); ++i) {
382*7ba4dab5SXin Li     if (strcmp(kCommandHandlers[i].name, argv[1]) == 0) {
383*7ba4dab5SXin Li       cmd = &kCommandHandlers[i];
384*7ba4dab5SXin Li     }
385*7ba4dab5SXin Li   }
386*7ba4dab5SXin Li 
387*7ba4dab5SXin Li   if (!cmd) {
388*7ba4dab5SXin Li     fprintf(stderr, "Bad command: %s\n", argv[1]);
389*7ba4dab5SXin Li     return kStatusInvalidArg;
390*7ba4dab5SXin Li   }
391*7ba4dab5SXin Li 
392*7ba4dab5SXin Li   if (argc - 2 != cmd->nparams) {
393*7ba4dab5SXin Li     fprintf(stderr, "Command %s takes %d parameters, %d given.\n", argv[1],
394*7ba4dab5SXin Li             cmd->nparams, argc - 2);
395*7ba4dab5SXin Li     return kStatusInvalidArg;
396*7ba4dab5SXin Li   }
397*7ba4dab5SXin Li 
398*7ba4dab5SXin Li   const hw_module_t* module = NULL;
399*7ba4dab5SXin Li   nvram_device_t* nvram_device = NULL;
400*7ba4dab5SXin Li   if (hw_get_module(NVRAM_HARDWARE_MODULE_ID, &module) != 0 ||
401*7ba4dab5SXin Li       module->methods->open(module, NVRAM_HARDWARE_DEVICE_ID,
402*7ba4dab5SXin Li                             (hw_device_t**)&nvram_device) != 0) {
403*7ba4dab5SXin Li     fprintf(stderr, "Failed to open NVRAM HAL.\n");
404*7ba4dab5SXin Li     return kStatusHALError;
405*7ba4dab5SXin Li   }
406*7ba4dab5SXin Li 
407*7ba4dab5SXin Li   if (nvram_device->common.version != NVRAM_DEVICE_API_VERSION_1_1) {
408*7ba4dab5SXin Li     fprintf(stderr, "Unsupported NVRAM HAL version.\n");
409*7ba4dab5SXin Li     nvram_device->common.close(&nvram_device->common);
410*7ba4dab5SXin Li     return kStatusHALError;
411*7ba4dab5SXin Li   }
412*7ba4dab5SXin Li 
413*7ba4dab5SXin Li   int ret = cmd->run(nvram_device, argv + 2);
414*7ba4dab5SXin Li   if (ret != 0) {
415*7ba4dab5SXin Li     fprintf(stderr, "Command execution failure: %s (%d).\n",
416*7ba4dab5SXin Li             StatusToString(ret), ret);
417*7ba4dab5SXin Li   }
418*7ba4dab5SXin Li 
419*7ba4dab5SXin Li   nvram_device->common.close(&nvram_device->common);
420*7ba4dab5SXin Li   return ret;
421*7ba4dab5SXin Li }
422