OSTCTools import support

Dirk Hohndel dirk at hohndel.org
Thu Apr 2 09:29:00 PDT 2015


On Sun, Mar 29, 2015 at 08:46:29PM +0200, Salvador Cuñat wrote:
> 
> Add function libdc_buffer_parser() intended to parse raw data buffers
> prepared for libdivecomputer. We have to commit elsewhere the
> necesary assembly tasks to achieve consistent data.
> 
> Actually only OSTCTools import makes use of this feature. Uwatec families
> have been included as I expect to make use of this function for sample
> parsing in datatrak import (and, may be in a far future, smartrak).

I think that we'll end up using something like this when doing the BT
device communication in Subsurface. So this should be done in a generic
way that allows us to take a buffer and hand it off to the correct parser.

> Adds errmsg() function taken as is from libdivecomputer's
> exaples/common.c to improve error management on libdc return codes.

Shouldn't that be its own patch?

> diff --git a/libdivecomputer.c b/libdivecomputer.c
> index 8b461ac..6a418c5 100644
> --- a/libdivecomputer.c
> +++ b/libdivecomputer.c
> @@ -9,6 +9,9 @@
>  #include "display.h"
>  
>  #include "libdivecomputer.h"
> +#include <libdivecomputer/uwatec.h>
> +#include <libdivecomputer/hw.h>
> +
>  
>  /* Christ. Libdivecomputer has the worst configuration system ever. */
>  #ifdef HW_FROG_H
> @@ -26,6 +29,40 @@ double progress_bar_fraction = 0.0;
>  static int stoptime, stopdepth, ndl, po2, cns;
>  static bool in_deco, first_temp_is_air;
>  
> +/*
> + * Directly taken from libdivecomputer's examples/common.c to improve
> + * the error messages resulting from libdc's return codes
> + */
> +const char *errmsg (dc_status_t rc)
> +{
> +	switch (rc) {
> +	case DC_STATUS_SUCCESS:
> +		return "Success";
> +	case DC_STATUS_UNSUPPORTED:
> +		return "Unsupported operation";
> +	case DC_STATUS_INVALIDARGS:
> +		return "Invalid arguments";
> +	case DC_STATUS_NOMEMORY:
> +		return "Out of memory";
> +	case DC_STATUS_NODEVICE:
> +		return "No device found";
> +	case DC_STATUS_NOACCESS:
> +		return "Access denied";
> +	case DC_STATUS_IO:
> +		return "Input/output error";
> +	case DC_STATUS_TIMEOUT:
> +		return "Timeout";
> +	case DC_STATUS_PROTOCOL:
> +		return "Protocol error";
> +	case DC_STATUS_DATAFORMAT:
> +		return "Data format error";
> +	case DC_STATUS_CANCELLED:
> +		return "Cancelled";
> +	default:
> +		return "Unknown error";
> +	}
> +}
> +

Yeah, this should be its own commit.

>  static dc_status_t create_parser(device_data_t *devdata, dc_parser_t **parser)
>  {
>  	return dc_parser_new(parser, devdata->device);
> @@ -905,3 +942,63 @@ const char *do_libdivecomputer_import(device_data_t *data)
>  
>  	return err;
>  }
> +
> +/*
> + * Parse data buffers instead of dc devices downloaded data.
> + * Intended to be used to parse profile data from binary files during import tasks.
> + * Actually included Uwatec families because of smartrak import and H&W families
> + * for future use in "OSTC TOOLS" .dive files import.
> + * For others, simply include them in the switch  (check parameters).
> + * Note that dc_descriptor_t in data  *must* have been filled using dc_descriptor_iterator()
> + * calls.
> + */
> +dc_status_t libdc_buffer_parser(struct dive *dive, device_data_t *data, unsigned char *buffer, int size)
> +{
> +	dc_status_t rc;
> +	dc_parser_t *parser = NULL;
> +
> +	switch (data->descriptor->type) {
> +	case DC_FAMILY_UWATEC_ALADIN:
> +	case DC_FAMILY_UWATEC_MEMOMOUSE:
> +		rc = uwatec_memomouse_parser_create(&parser, data->context, 0, 0);
> +		break;
> +	case DC_FAMILY_UWATEC_SMART:
> +	case DC_FAMILY_UWATEC_MERIDIAN:
> +		rc = uwatec_smart_parser_create (&parser, data->context, data->descriptor->model, 0, 0);
> +		break;
> +	case DC_FAMILY_HW_OSTC:
> +		rc = hw_ostc_parser_create (&parser, data->context, data->deviceid, 0);
> +		break;
> +	case DC_FAMILY_HW_FROG:
> +	case DC_FAMILY_HW_OSTC3:
> +		rc = hw_ostc_parser_create (&parser, data->context, data->deviceid, 1);
> +		break;
> +	}
> +	if  (rc != DC_STATUS_SUCCESS) {
> +		fprintf(stderr, "Error creating parser.\n");
> +		dc_parser_destroy (parser);
> +		return rc;
> +	}
> +	rc = dc_parser_set_data(parser, buffer, size);
> +	if (rc != DC_STATUS_SUCCESS) {
> +		fprintf(stderr, "Error registering the data.\n");
> +		dc_parser_destroy (parser);
> +		return rc;
> +	}
> +	// Do not parse Aladin/Memomouse headers as they are fakes
> +	// Do not return on error, we can still parse the samples
> +	if (data->descriptor->type != DC_FAMILY_UWATEC_ALADIN && data->descriptor->type != DC_FAMILY_UWATEC_MEMOMOUSE) {
> +		rc = libdc_header_parser (parser, data, dive);
> +		if (rc != DC_STATUS_SUCCESS) {
> +			fprintf(stderr, "Error parsing the dive header data. Dive # %d\n", dive->number);
> +		}
> +	}
> +	rc = dc_parser_samples_foreach (parser, sample_cb, &dive->dc);
> +	if (rc != DC_STATUS_SUCCESS) {
> +		fprintf(stderr, "Error parsing the sample data. Dive # %d\nStatus = %s\n", dive->number, errmsg(rc));
> +		dc_parser_destroy (parser);
> +		return rc;
> +	}
> +	dc_parser_destroy(parser);
> +	return(DC_STATUS_SUCCESS);
> +}

So the caller assembles a device_data_t buffer and then hands this to this
function... but that functionality already exists inside libdivecomputer.
I'm sure I'm missing something obvious, but why are we replicating this
here? Is it because of the "fake headers" in the Aladin/Memomouse case?
Why wouldn't you just call dc_parser_new() to get the correct parser?

/D


More information about the subsurface mailing list