Beispiel #1
0
static int
encode(bson_encoder_t encoder)
{
	if (bson_encoder_append_bool(encoder, "bool1", sample_bool) != 0)
		warnx("FAIL: encoder: append bool failed");
	if (bson_encoder_append_int(encoder, "int1", sample_small_int) != 0)
		warnx("FAIL: encoder: append int failed");
	if (bson_encoder_append_int(encoder, "int2", sample_big_int) != 0)
		warnx("FAIL: encoder: append int failed");
	if (bson_encoder_append_double(encoder, "double1", sample_double) != 0)
		warnx("FAIL: encoder: append double failed");
	if (bson_encoder_append_string(encoder, "string1", sample_string) != 0)
		warnx("FAIL: encoder: append string failed");
	if (bson_encoder_append_binary(encoder, "data1", BSON_BIN_BINARY, sizeof(sample_data), sample_data) != 0)
		warnx("FAIL: encoder: append data failed");

	bson_encoder_fini(encoder);

	return 0;
}
Beispiel #2
0
int
param_export(int fd, bool only_unsaved)
{
	struct param_wbuf_s *s = NULL;
	struct bson_encoder_s encoder;
	int	result = -1;

	param_lock();

	bson_encoder_init_file(&encoder, fd);

	/* no modified parameters -> we are done */
	if (param_values == NULL) {
		result = 0;
		goto out;
	}

	while ((s = (struct param_wbuf_s *)utarray_next(param_values, s)) != NULL) {

		int32_t	i;
		float	f;

		/*
		 * If we are only saving values changed since last save, and this
		 * one hasn't, then skip it
		 */
		if (only_unsaved && !s->unsaved) {
			continue;
		}

		s->unsaved = false;

		/* append the appropriate BSON type object */

		switch (param_type(s->param)) {

		case PARAM_TYPE_INT32:
			param_get(s->param, &i);

			if (bson_encoder_append_int(&encoder, param_name(s->param), i)) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		case PARAM_TYPE_FLOAT:
			param_get(s->param, &f);

			if (bson_encoder_append_double(&encoder, param_name(s->param), f)) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		case PARAM_TYPE_STRUCT ... PARAM_TYPE_STRUCT_MAX:
			if (bson_encoder_append_binary(&encoder,
						       param_name(s->param),
						       BSON_BIN_BINARY,
						       param_size(s->param),
						       param_get_value_ptr(s->param))) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		default:
			debug("unrecognized parameter type");
			goto out;
		}
	}

	result = 0;

out:
	param_unlock();

	if (result == 0) {
		result = bson_encoder_fini(&encoder);
	}

	return result;
}
Beispiel #3
0
int
param_export(int fd, bool only_unsaved)
{
	perf_begin(param_export_perf);

	struct param_wbuf_s *s = NULL;
	int	result = -1;

	struct bson_encoder_s encoder;

	int shutdown_lock_ret = px4_shutdown_lock();

	if (shutdown_lock_ret) {
		PX4_ERR("px4_shutdown_lock() failed (%i)", shutdown_lock_ret);
	}

	// take the file lock
	do {} while (px4_sem_wait(&param_sem_save) != 0);

	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 == NULL) {
		result = 0;
		goto out;
	}

	while ((s = (struct param_wbuf_s *)utarray_next(param_values, s)) != NULL) {
		/*
		 * If we are only saving values changed since last save, and this
		 * one hasn't, then skip it
		 */
		if (only_unsaved && !s->unsaved) {
			continue;
		}

		s->unsaved = false;

		const char *name = param_name(s->param);
		const size_t size = param_size(s->param);

		/* append the appropriate BSON type object */
		switch (param_type(s->param)) {

		case PARAM_TYPE_INT32: {
				const int32_t i = s->val.i;

				debug("exporting: %s (%d) size: %d val: %d", name, s->param, size, i);

				if (bson_encoder_append_int(&encoder, name, i)) {
					PX4_ERR("BSON append failed for '%s'", name);
					goto out;
				}
			}
			break;

		case PARAM_TYPE_FLOAT: {
				const float f = s->val.f;

				debug("exporting: %s (%d) size: %d val: %.3f", name, s->param, size, (double)f);

				if (bson_encoder_append_double(&encoder, name, f)) {
					PX4_ERR("BSON append failed for '%s'", name);
					goto out;
				}
			}
			break;

		case PARAM_TYPE_STRUCT ... PARAM_TYPE_STRUCT_MAX: {
				const void *value_ptr = param_get_value_ptr(s->param);

				/* lock as short as possible */
				if (bson_encoder_append_binary(&encoder,
							       name,
							       BSON_BIN_BINARY,
							       size,
							       value_ptr)) {

					PX4_ERR("BSON append failed for '%s'", name);
					goto out;
				}
			}
			break;

		default:
			PX4_ERR("unrecognized parameter type");
			goto out;
		}
	}

	result = 0;

out:

	if (result == 0) {
		if (bson_encoder_fini(&encoder) != PX4_OK) {
			PX4_ERR("bson encoder finish failed");
		}
	}

	param_unlock_reader();

	px4_sem_post(&param_sem_save);

	if (shutdown_lock_ret == 0) {
		px4_shutdown_unlock();
	}

	perf_end(param_export_perf);

	return result;
}
Beispiel #4
0
int
param_export(int fd, bool only_unsaved)
{
	struct param_wbuf_s *s = NULL;
	struct bson_encoder_s encoder;
	int	result = -1;

	param_lock();

	param_bus_lock(true);
	bson_encoder_init_file(&encoder, fd);
	param_bus_lock(false);

	/* no modified parameters -> we are done */
	if (param_values == NULL) {
		result = 0;
		goto out;
	}

	while ((s = (struct param_wbuf_s *)utarray_next(param_values, s)) != NULL) {

		int32_t	i;
		float	f;

		/*
		 * If we are only saving values changed since last save, and this
		 * one hasn't, then skip it
		 */
		if (only_unsaved && !s->unsaved) {
			continue;
		}

		s->unsaved = false;

		/* append the appropriate BSON type object */


		switch (param_type(s->param)) {

		case PARAM_TYPE_INT32: {
				param_get(s->param, &i);
				const char *name = param_name(s->param);

				/* lock as short as possible */
				param_bus_lock(true);

				if (bson_encoder_append_int(&encoder, name, i)) {
					param_bus_lock(false);
					debug("BSON append failed for '%s'", name);
					goto out;
				}
			}
			break;

		case PARAM_TYPE_FLOAT: {

				param_get(s->param, &f);
				const char *name = param_name(s->param);

				/* lock as short as possible */
				param_bus_lock(true);

				if (bson_encoder_append_double(&encoder, name, f)) {
					param_bus_lock(false);
					debug("BSON append failed for '%s'", name);
					goto out;
				}
			}
			break;

		case PARAM_TYPE_STRUCT ... PARAM_TYPE_STRUCT_MAX: {

				const char *name = param_name(s->param);
				const size_t size = param_size(s->param);
				const void *value_ptr = param_get_value_ptr(s->param);

				/* lock as short as possible */
				param_bus_lock(true);

				if (bson_encoder_append_binary(&encoder,
							       name,
							       BSON_BIN_BINARY,
							       size,
							       value_ptr)) {
					param_bus_lock(false);
					debug("BSON append failed for '%s'", name);
					goto out;
				}
			}
			break;

		default:
			debug("unrecognized parameter type");
			goto out;
		}

		param_bus_lock(false);

		/* allow this process to be interrupted by another process / thread */
		usleep(5);
	}

	result = 0;

out:
	param_unlock();

	if (result == 0) {
		result = bson_encoder_fini(&encoder);
	}

	return result;
}
Beispiel #5
0
static int
param_export_internal(bool only_unsaved)
{
	struct param_wbuf_s *s = NULL;
	struct bson_encoder_s encoder;
	int     result = -1;

	param_lock();

	/* Use realloc */

	bson_encoder_init_buf(&encoder, NULL, 0);

	/* no modified parameters -> we are done */
	if (param_values == NULL) {
		result = 0;
		goto out;
	}

	while ((s = (struct param_wbuf_s *)utarray_next(param_values, s)) != NULL) {

		int32_t i;
		float   f;

		/*
		 * If we are only saving values changed since last save, and this
		 * one hasn't, then skip it
		 */
		if (only_unsaved && !s->unsaved) {
			continue;
		}

		s->unsaved = false;

		/* append the appropriate BSON type object */

		switch (param_type(s->param)) {

		case PARAM_TYPE_INT32:
			param_get(s->param, &i);

			if (bson_encoder_append_int(&encoder, param_name(s->param), i)) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		case PARAM_TYPE_FLOAT:
			param_get(s->param, &f);

			if (bson_encoder_append_double(&encoder, param_name(s->param), f)) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		case PARAM_TYPE_STRUCT ... PARAM_TYPE_STRUCT_MAX:
			if (bson_encoder_append_binary(&encoder,
						       param_name(s->param),
						       BSON_BIN_BINARY,
						       param_size(s->param),
						       param_get_value_ptr_external(s->param))) {
				debug("BSON append failed for '%s'", param_name(s->param));
				goto out;
			}

			break;

		default:
			debug("unrecognized parameter type");
			goto out;
		}
	}

	result = 0;

out:
	param_unlock();

	if (result == 0) {

		/* Finalize the bison encoding*/

		bson_encoder_fini(&encoder);

		/* Get requiered space */

		size_t buf_size = bson_encoder_buf_size(&encoder);

		/* Get a buffer from the flash driver with enough space */

		uint8_t *buffer;
		result = parameter_flashfs_alloc(parameters_token, &buffer, &buf_size);

		if (result == OK) {

			/* Check for a write that has no changes */

			uint8_t *was_buffer;
			size_t was_buf_size;
			int was_result = parameter_flashfs_read(parameters_token, &was_buffer, &was_buf_size);

			void *enc_buff = bson_encoder_buf_data(&encoder);

			bool commit = was_result < OK || was_buf_size != buf_size || 0 != memcmp(was_buffer, enc_buff, was_buf_size);

			if (commit) {

				memcpy(buffer, enc_buff, buf_size);
				result = parameter_flashfs_write(parameters_token, buffer, buf_size);
				result = result == buf_size ? OK : -EFBIG;

			}

			free(enc_buff);
		}
	}

	return result;
}