|
|
|
@ -1183,7 +1183,7 @@ static int param_save_file_internal(const char *filename)
@@ -1183,7 +1183,7 @@ static int param_save_file_internal(const char *filename)
|
|
|
|
|
|
|
|
|
|
while (res != OK && attempts > 0) { |
|
|
|
|
// write parameters to file
|
|
|
|
|
int fd = ::open(filename, O_WRONLY | O_CREAT, PX4_O_MODE_666); |
|
|
|
|
int fd = ::open(filename, O_RDWR | O_CREAT, PX4_O_MODE_666); |
|
|
|
|
|
|
|
|
|
if (fd > -1) { |
|
|
|
|
res = param_export(fd, nullptr); |
|
|
|
@ -1272,10 +1272,111 @@ param_load_default()
@@ -1272,10 +1272,111 @@ param_load_default()
|
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int param_verify_callback(bson_decoder_t decoder, bson_node_t node) |
|
|
|
|
{ |
|
|
|
|
if (node->type == BSON_EOO) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// find the parameter this node represents
|
|
|
|
|
param_t param = param_find_no_notification(node->name); |
|
|
|
|
|
|
|
|
|
if (param == PARAM_INVALID) { |
|
|
|
|
PX4_ERR("verify: invalid parameter '%s'", node->name); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// handle verifying the parameter from the node
|
|
|
|
|
switch (node->type) { |
|
|
|
|
case BSON_INT32: { |
|
|
|
|
if (param_type(param) != PARAM_TYPE_INT32) { |
|
|
|
|
PX4_ERR("verify: invalid param type %d for '%s' (BSON_INT32)", param_type(param), node->name); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int32_t value; |
|
|
|
|
|
|
|
|
|
if (param_get(param, &value) == 0) { |
|
|
|
|
if (value == node->i32) { |
|
|
|
|
return 1; // valid
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
PX4_ERR("verify: '%s' invalid BSON value %" PRIi32 "(expected %" PRIi32 ")", node->name, node->i32, value); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case BSON_DOUBLE: { |
|
|
|
|
if (param_type(param) != PARAM_TYPE_FLOAT) { |
|
|
|
|
PX4_ERR("verify: invalid param type %d for '%s' (BSON_DOUBLE)", param_type(param), node->name); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
float value; |
|
|
|
|
|
|
|
|
|
if (param_get(param, &value) == 0) { |
|
|
|
|
if (fabsf(value - (float)node->d) <= FLT_EPSILON) { |
|
|
|
|
return 1; // valid
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
PX4_ERR("verify: '%s' invalid BSON value %.3f (expected %.3f)", node->name, node->d, (double)value); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
PX4_ERR("verify: '%s' invalid node type %d", node->name, node->type); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int param_verify(int fd) |
|
|
|
|
{ |
|
|
|
|
if (fd < 0) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (lseek(fd, 0, SEEK_SET) != 0) { |
|
|
|
|
PX4_ERR("verify: seek failed"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bson_decoder_s decoder{}; |
|
|
|
|
|
|
|
|
|
if (bson_decoder_init_file(&decoder, fd, param_verify_callback) == 0) { |
|
|
|
|
int result = -1; |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
result = bson_decoder_next(&decoder); |
|
|
|
|
|
|
|
|
|
} while (result > 0); |
|
|
|
|
|
|
|
|
|
if (result == 0) { |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
} else if (result == -ENODATA) { |
|
|
|
|
PX4_ERR("verify: no BSON data"); |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
PX4_ERR("verify: failed (%d)", result); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
param_export(int fd, param_filter_func filter) |
|
|
|
|
{ |
|
|
|
|
int result = -1; |
|
|
|
|
/* no modified parameters -> we are done */ |
|
|
|
|
if (param_values == nullptr) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int result = -1; |
|
|
|
|
perf_begin(param_export_perf); |
|
|
|
|
|
|
|
|
|
if (fd < 0) { |
|
|
|
@ -1303,11 +1404,9 @@ param_export(int fd, param_filter_func filter)
@@ -1303,11 +1404,9 @@ param_export(int fd, param_filter_func filter)
|
|
|
|
|
param_lock_reader(); |
|
|
|
|
|
|
|
|
|
uint8_t bson_buffer[256]; |
|
|
|
|
bson_encoder_init_buf_file(&encoder, fd, &bson_buffer, sizeof(bson_buffer)); |
|
|
|
|
|
|
|
|
|
/* no modified parameters -> we are done */ |
|
|
|
|
if (param_values == nullptr) { |
|
|
|
|
result = 0; |
|
|
|
|
if (bson_encoder_init_buf_file(&encoder, fd, &bson_buffer, sizeof(bson_buffer)) != 0) { |
|
|
|
|
result = -1; |
|
|
|
|
goto out; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1323,7 +1422,7 @@ param_export(int fd, param_filter_func filter)
@@ -1323,7 +1422,7 @@ param_export(int fd, param_filter_func filter)
|
|
|
|
|
param_get_default_value_internal(s->param, &default_value); |
|
|
|
|
|
|
|
|
|
if (s->val.i == default_value) { |
|
|
|
|
PX4_DEBUG("skipping %s %d export", param_name(s->param), default_value); |
|
|
|
|
PX4_DEBUG("skipping %s %" PRIi32 " export", param_name(s->param), default_value); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -1348,7 +1447,7 @@ param_export(int fd, param_filter_func filter)
@@ -1348,7 +1447,7 @@ param_export(int fd, param_filter_func filter)
|
|
|
|
|
switch (param_type(s->param)) { |
|
|
|
|
case PARAM_TYPE_INT32: { |
|
|
|
|
const int32_t i = s->val.i; |
|
|
|
|
PX4_DEBUG("exporting: %s (%d) size: %lu val: %d", name, s->param, (long unsigned int)size, i); |
|
|
|
|
PX4_DEBUG("exporting: %s (%d) size: %lu val: %" PRIi32, name, s->param, (long unsigned int)size, i); |
|
|
|
|
|
|
|
|
|
if (bson_encoder_append_int(&encoder, name, i) != 0) { |
|
|
|
|
PX4_ERR("BSON append failed for '%s'", name); |
|
|
|
@ -1379,12 +1478,18 @@ out:
@@ -1379,12 +1478,18 @@ out:
|
|
|
|
|
|
|
|
|
|
if (result == 0) { |
|
|
|
|
if (bson_encoder_fini(&encoder) == PX4_OK) { |
|
|
|
|
if (!filter) { |
|
|
|
|
params_unsaved.reset(); |
|
|
|
|
// verify exported bson
|
|
|
|
|
if (param_verify(fd) == 0) { |
|
|
|
|
if (!filter) { |
|
|
|
|
params_unsaved.reset(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
result = -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
PX4_ERR("BSON encoder finialize failed"); |
|
|
|
|
PX4_ERR("BSON encoder finalize failed"); |
|
|
|
|
result = -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|