--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <hal/hal-device-board.h>
+
+#define BOARD_PARAM_PARAMS_LEN 2
+
+struct board_param_getter {
+ char *param_name;
+ char *description;
+ int (*getter)(char **params, size_t params_len, char *buffer, size_t buffer_size);
+};
+
+static int boot_mode_getter(char **params, size_t params_len, char *buffer, size_t buffer_size)
+{
+ assert(buffer != NULL);
+
+ return hal_device_board_get_boot_mode(buffer, buffer_size);
+}
+
+static int current_partition_getter(char **params, size_t params_len, char *buffer, size_t buffer_size)
+{
+ assert(buffer != NULL);
+ assert(buffer_size >= 2);
+
+ int ret = 0;
+ char partition_ab;
+
+ ret = hal_device_board_get_current_partition(&partition_ab);
+ if (ret != 0)
+ return ret;
+
+ buffer[0] = partition_ab;
+ buffer[1] = '\0';
+
+ return 0;
+}
+
+static int partition_ab_cloned_getter(char **params, size_t params_len, char *buffer, size_t buffer_size)
+{
+ assert(buffer != NULL);
+ assert(buffer_size >= 2);
+
+ int ret = 0;
+ int cloned = 0;
+
+ ret = hal_device_board_get_partition_ab_cloned(&cloned);
+ if (ret != 0)
+ return ret;
+
+ ret = snprintf(buffer, buffer_size, "%d", !!cloned);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int partition_status_getter(char **params, size_t params_len, char *buffer, size_t buffer_size)
+{
+ assert(params != NULL);
+ assert(buffer != NULL);
+
+ char partition_ab = '\0';
+
+ if (params_len != 1)
+ return -EINVAL;
+
+ if (params[0] == NULL)
+ return -EINVAL;
+
+ partition_ab = params[0][0];
+ if (partition_ab != 'a' && partition_ab != 'b')
+ return -EINVAL;
+
+ return hal_device_board_get_partition_status(partition_ab, buffer, buffer_size);
+}
+
+static int upgrade_progress_status_getter(char **params, size_t params_len, char *buffer, size_t buffer_size)
+{
+ assert(buffer != NULL);
+
+ int ret = 0;
+ int progress_status = 0;
+
+ ret = hal_device_board_get_upgrade_progress_status(&progress_status);
+ if (ret < 0)
+ return ret;
+
+ ret = snprintf(buffer, buffer_size, "%d", progress_status);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int upgrade_state_getter(char **params, size_t params_len, char *buffer, size_t buffer_size)
+{
+ assert(buffer != NULL);
+
+ return hal_device_board_get_upgrade_state(buffer, buffer_size);
+}
+
+static int upgrade_type_getter(char **params, size_t params_len, char *buffer, size_t buffer_size)
+{
+ assert(buffer != NULL);
+
+ return hal_device_board_get_upgrade_type(buffer, buffer_size);
+}
+
+static struct board_param_getter getters[] = {
+ {
+ .param_name = "boot-mode",
+ .description = "Get boot mode.",
+ .getter = boot_mode_getter
+ }, {
+ .param_name = "current-partition",
+ .description = "Get current partition (a or b)",
+ .getter = current_partition_getter
+ }, {
+ .param_name = "partition-ab-cloned",
+ .description = "Get partition is cloned or not: 1 is cloned, 0 is not cloned.",
+ .getter = partition_ab_cloned_getter
+ }, {
+ .param_name = "partition-status",
+ .description = "Get partition status. 1 param is required: 'a' or 'b'.",
+ .getter = partition_status_getter
+ }, {
+ .param_name = "upgrade-progress-status",
+ .description = "Get current upgrade progress status: -1 ~ 100",
+ .getter = upgrade_progress_status_getter
+ }, {
+ .param_name = "upgrade-state",
+ .description = "Get current upgrade state.",
+ .getter = upgrade_state_getter
+ }, {
+ .param_name = "upgrade-type",
+ .description = "Get current upgrade type: offline or online",
+ .getter = upgrade_type_getter
+ }, {
+ /* sentinel for this array */
+ .param_name = NULL,
+ .description = NULL,
+ .getter = NULL
+ },
+};
+
+static int get_board_param_getter(const char *param_name, struct board_param_getter **board_param_getter)
+{
+ size_t param_name_len = strlen(param_name);
+
+ for (int i = 0; getters[i].param_name != NULL; ++i) {
+ if (strncmp(getters[i].param_name, param_name, param_name_len + 1) == 0) {
+ *board_param_getter = &getters[i];
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static void print_board_param_getters(void)
+{
+ printf("Available getter board params:\n");
+ for (int i = 0; getters[i].param_name != NULL; ++i) {
+ if (getters[i].getter == NULL)
+ continue;
+ printf(" %s: %s\n", getters[i].param_name, getters[i].description);
+ }
+
+ printf("\n"
+ " * Parameters should be provided separated with ','.\n"
+ " * e.g. \"partition-status,a\"\n");
+}
+
+static size_t split_params(char **params, size_t params_len, const char *delim, char *params_str)
+{
+ assert(params_len > 0);
+
+ char *strtok_saveptr = NULL;
+ size_t params_index = 0;
+
+ params[0] = strtok_r(params_str, delim, &strtok_saveptr);
+ if (params[0] == NULL)
+ return 0;
+
+ for (params_index = 1; params_index < params_len; ++params_index) {
+ params[params_index] = strtok_r(NULL, delim, &strtok_saveptr);
+ if (params[params_index] == NULL)
+ break;
+ }
+
+ return params_index;
+}
+
+int do_get_board_param(const char *params_str)
+{
+ int ret = 0;
+ char *params_str_dup = NULL;
+ struct board_param_getter *board_param_getter = NULL;
+ char result_buffer[1024] = { 0, };
+
+ char *params[BOARD_PARAM_PARAMS_LEN] = { NULL, };
+ size_t params_len = BOARD_PARAM_PARAMS_LEN;
+ char *param_name = NULL;
+
+ params_str_dup = strdup(params_str);
+ if (params_str_dup == NULL) {
+ printf("Failed to allocate memory for params.\n");
+ return 1;
+ }
+
+ params_len = split_params(params, params_len, ",", params_str_dup);
+ if (params_len < 1) {
+ printf("Invalid parameter.\n");
+ ret = -1;
+ goto release_and_exit;
+ }
+ param_name = params[0];
+
+ if (strncmp(param_name, "help", sizeof("help")) == 0) {
+ print_board_param_getters();
+ ret = 0;
+ goto release_and_exit;
+ }
+
+ ret = get_board_param_getter(param_name, &board_param_getter);
+ if (ret != 0) {
+ printf("Invalid board param: %s\n", params_str);
+ print_board_param_getters();
+ goto release_and_exit;
+ }
+
+ ret = (board_param_getter->getter)(params + 1, params_len - 1, result_buffer, sizeof(result_buffer));
+ if (ret != 0) {
+ printf("Failed to get board param %s: %d\n", param_name, ret);
+ printf("%s: %s\n", param_name, board_param_getter->description);
+ goto release_and_exit;
+ }
+
+ ret = 0;
+ printf("%s\n", result_buffer);
+
+release_and_exit:
+ free(params_str_dup);
+
+ return ret;
+}
#include "resize.h"
#include "update.h"
+#include "board-params.h"
struct arguments {
bool resize;
bool update;
bool online;
+ bool get_board_param;
+ char *board_param;
};
static void print_help(char*);
args->resize = false;
args->update = false;
args->online = false;
+ args->get_board_param = false;
+ args->board_param = NULL;
struct option long_options[] = {
{"resize", no_argument, NULL, 'r'},
{"update", no_argument, NULL, 'u'},
{"offline-update", no_argument, NULL, 'f'},
{"online-update", no_argument, NULL, 'n'},
+ {"get-board-param", required_argument, NULL, 'g'},
{"help", no_argument, NULL, 'h'},
{}
};
args->online = true;
return 0;
}
+ case 'g': {
+ args->get_board_param = true;
+ args->board_param = optarg;
+ return 0;
+ }
case 'h': {
args->help = true;
return 0;
printf("Usage:\n"
" %s [--help|--resize|--update]\n\n"
"Possible arguments:\n"
- " --help Print this help\n"
- " --update Trigger the OS Upgrade (Offline Upgrade)\n"
- " --offline-update Trigger the OS Offline Upgrade\n"
- " --online-update Trigger the OS Online Upgrade\n"
- " --resize Run resize2fs on the rootfs partition.\n"
- " After that, performing the OS Upgrade will be impossible.\n\n" ,my_name);
+ " --help Print this help\n"
+ " --update Trigger the OS Upgrade (Offline Upgrade)\n"
+ " --offline-update Trigger the OS Offline Upgrade\n"
+ " --online-update Trigger the OS Online Upgrade\n"
+ " --resize Run resize2fs on the rootfs partition.\n"
+ " After that, performing the OS Upgrade will be impossible.\n"
+ " --get-board-param <param name>[,<param>...] Print value of a board param\n"
+ " Use <param name> as 'help' for details.\n"
+ "\n" ,my_name);
}
int main(int argc, char **argv)
if (args.update)
return do_update(args.online);
+ if (args.get_board_param)
+ return do_get_board_param(args.board_param);
+
print_help(argv[0]);
return 1;