diff --git a/src/lib/parameters/param.h b/src/lib/parameters/param.h index 1fbbe018c9..9a6480d3b0 100644 --- a/src/lib/parameters/param.h +++ b/src/lib/parameters/param.h @@ -349,6 +349,17 @@ __EXPORT int param_import(int fd, bool mark_saved); */ __EXPORT int param_load(int fd); +/** + * Read saved parameters from file and dump to console. + * + * This function reads the file and dumps all contents to console + * values from a file. + * + * @param fd File descriptor to read from. + * @return Zero on success, nonzero if an error occurred during import. + */ +__EXPORT int param_dump(int fd); + /** * Apply a function to each parameter. * diff --git a/src/lib/parameters/parameters.cpp b/src/lib/parameters/parameters.cpp index 2362ea2752..ec52d2bf32 100644 --- a/src/lib/parameters/parameters.cpp +++ b/src/lib/parameters/parameters.cpp @@ -1405,6 +1405,38 @@ out: return result; } +static int +param_dump_callback(bson_decoder_t decoder, void *priv, bson_node_t node) +{ + switch (node->type) { + case BSON_EOO: + PX4_INFO_RAW("BSON_EOO\n"); + return 0; + + case BSON_DOUBLE: + PX4_INFO_RAW("BSON_DOUBLE: %s = %.6f\n", node->name, node->d); + return 1; + + case BSON_BOOL: + PX4_INFO_RAW("BSON_BOOL: %s = %d\n", node->name, node->b); + return 1; + + case BSON_INT32: + PX4_INFO_RAW("BSON_INT32: %s = %" PRIi32 "\n", node->name, node->i32); + return 1; + + case BSON_INT64: + PX4_INFO_RAW("BSON_INT64: %s = %" PRIi64 "\n", node->name, node->i64); + return 1; + + default: + PX4_INFO_RAW("ERROR %s unhandled bson type %d\n", node->name, node->type); + return 1; // just skip this entry + } + + return -1; +} + static int param_import_internal(int fd, bool mark_saved) { @@ -1468,6 +1500,43 @@ param_load(int fd) return param_import_internal(fd, true); } +int +param_dump(int fd) +{ + bson_decoder_s decoder{}; + param_import_state state; + + if (bson_decoder_init_file(&decoder, fd, param_dump_callback, &state) == 0) { + PX4_INFO_RAW("BSON document size %" PRId32 "\n", decoder.total_document_size); + + int result = -1; + + do { + result = bson_decoder_next(&decoder); + + } while (result > 0); + + if (result == 0) { + PX4_INFO_RAW("BSON decoded %" PRId32 " bytes (double:%" PRIu16 ", string:%" PRIu16 ", bin:%" PRIu16 ", bool:%" PRIu16 + ", int32:%" PRIu16 ", int64:%" PRIu16 ")\n", + decoder.total_decoded_size, + decoder.count_node_double, decoder.count_node_string, decoder.count_node_bindata, decoder.count_node_bool, + decoder.count_node_int32, decoder.count_node_int64); + + return 0; + + } else if (result == -ENODATA) { + PX4_WARN("BSON: no data"); + return 0; + + } else { + PX4_ERR("param dump failed (%d)", result); + } + } + + return -1; +} + void param_foreach(void (*func)(void *arg, param_t param), void *arg, bool only_changed, bool only_used) { diff --git a/src/systemcmds/param/param.cpp b/src/systemcmds/param/param.cpp index 68d204a174..a47ef5d127 100644 --- a/src/systemcmds/param/param.cpp +++ b/src/systemcmds/param/param.cpp @@ -83,6 +83,7 @@ enum class COMPARE_ERROR_LEVEL { static int do_save(const char *param_file_name); static int do_save_default(); +static int do_dump(const char *param_file_name); static int do_load(const char *param_file_name); static int do_import(const char *param_file_name = nullptr); static int do_show(const char *search_string, bool only_changed); @@ -135,6 +136,8 @@ $ reboot PRINT_MODULE_USAGE_ARG("", "File name (use default if not given)", true); PRINT_MODULE_USAGE_COMMAND_DESCR("save", "Save params to a file"); PRINT_MODULE_USAGE_ARG("", "File name (use default if not given)", true); + PRINT_MODULE_USAGE_COMMAND_DESCR("dump", "Dump params from a file"); + PRINT_MODULE_USAGE_ARG("", "File name (use default if not given)", true); PRINT_MODULE_USAGE_COMMAND_DESCR("select", "Select default file"); PRINT_MODULE_USAGE_ARG("", "File name (use /eeprom/parameters if not given)", true); @@ -206,6 +209,15 @@ param_main(int argc, char *argv[]) } } + if (!strcmp(argv[1], "dump")) { + if (argc >= 3) { + return do_dump(argv[2]); + + } else { + return do_dump(param_get_default_file()); + } + } + if (!strcmp(argv[1], "load")) { if (argc >= 3) { return do_load(argv[2]); @@ -423,6 +435,43 @@ do_save(const char *param_file_name) return 0; } +static int +do_dump(const char *param_file_name) +{ + int fd = -1; + + if (param_file_name) { // passing NULL means to select the flash storage + + fd = open(param_file_name, O_RDONLY); + + if (fd < 0) { + PX4_ERR("open '%s' failed (%i)", param_file_name, errno); + return 1; + } else { + PX4_INFO_RAW("[param] reading from %s\n\n", param_file_name); + } + } + + int result = param_dump(fd); + + if (fd >= 0) { + close(fd); + } + + if (result < 0) { + if (param_file_name) { + PX4_ERR("reading from '%s' failed (%i)", param_file_name, result); + + } else { + PX4_ERR("reading failed (%i)", result); + } + + return 1; + } + + return 0; +} + static int do_load(const char *param_file_name) {