Hi Dirk. 2015-04-02 18:18 GMT+02:00 Dirk Hohndel <[email protected]>:
> > Here's what I'd like to see. Either don't do the datetime rename or if you > do it, have it in its own patch with nothing else mixed in. > Then, if you want to change all the error returns to show these errors to > the user, do that in one patch and nothing else. > As a third patch you can do the split out into a separate function, > explaining any logic changes that you are doing. > > Attached are the reworked patches. I've get rid of the fprintf messages as they should be shown to the user in mainwindow viia report_error(), erased renaming of datetime as it was pointless, and reworked all other considerations. Around the data thing in parse_gasmixes() with the pointer changed to NULL, explanation is in 0003 patch. For this point I've added 0007 patch which is not mandatory (but advisable, I think). All should apply on master - acaedee159abf Regards. Salva.
From 266323981429e4f02cd4cfee83815333dca984c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20Cu=C3=B1at?= <[email protected]> Date: Fri, 3 Apr 2015 21:02:55 +0200 Subject: [PATCH 1/7] (libdivecomputer)Add dc_descriptor_t structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While downloading from DC the user sets the vendor and model. In imports, this is not possible. Parser has to figure somehow, at least, the DC model used in a dive basis, as it can even change over time, and a log file can include several different models. Will use this structure in import tasks to ensure that data passed to libdc are consistent with what it expects to find. Signed-off-by: Salvador Cuñat <[email protected] --- libdivecomputer.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libdivecomputer.h b/libdivecomputer.h index 91548ba..eaaa998 100644 --- a/libdivecomputer.h +++ b/libdivecomputer.h @@ -13,6 +13,13 @@ extern "C" { #endif +struct dc_descriptor_t { + const char *vendor; + const char *product; + dc_family_t type; + unsigned int model; +}; + /* don't forget to include the UI toolkit specific display-XXX.h first to get the definition of progressbar_t */ typedef struct device_data_t -- 2.1.4
From 396b5a27103264d99f6921b7f887fd6a750528be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20Cu=C3=B1at?= <[email protected]> Date: Fri, 3 Apr 2015 21:33:10 +0200 Subject: [PATCH 2/7] (libdivecomputer) Add errmsg() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Taken as is from libdivecomputers exaples/common.c to improve verbosity on libdc return codes. Intended to be used on error messages shown to the user on main window complementarily to those messages managed by dev_info(). Signed-off-by: Salvador Cuñat <[email protected]> --- libdivecomputer.c | 34 ++++++++++++++++++++++++++++++++++ libdivecomputer.h | 1 + 2 files changed, 35 insertions(+) diff --git a/libdivecomputer.c b/libdivecomputer.c index 950b9da..27e3dbd 100644 --- a/libdivecomputer.c +++ b/libdivecomputer.c @@ -26,6 +26,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"; + } +} + static dc_status_t create_parser(device_data_t *devdata, dc_parser_t **parser) { return dc_parser_new(parser, devdata->device); diff --git a/libdivecomputer.h b/libdivecomputer.h index eaaa998..d1e4ad9 100644 --- a/libdivecomputer.h +++ b/libdivecomputer.h @@ -41,6 +41,7 @@ typedef struct device_data_t struct dive_table *download_table; } device_data_t; +const char *errmsg (dc_status_t rc); const char *do_libdivecomputer_import(device_data_t *data); const char *do_uemis_import(device_data_t *data); -- 2.1.4
From 9ff9f33fe0a9f7bc106fdf1cb195278ac085ace7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20Cu=C3=B1at?= <[email protected]> Date: Sat, 4 Apr 2015 00:44:01 +0200 Subject: [PATCH 3/7] (libdivecomputer) Split dive_cb() callback in two MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Actually dive_cb() needs a defined device to work as it's built for DC download tasks. Move part of the functionality of dive_cb() to a new function libdc_header_parser() which can be used to parse headers from raw data buffers with no device set. Obviously dive_cb() will call the new funtion for header parsing too. Two changes in logic: 1- In parse_gasmixes() set data pointer to NULL. This pointer is passed to the function, but it's not used. While this data pointer exists in DC import, via dive_cb(), it doesn't in file import as data has previously been set in the parser. 2- While parsing gas mixes do not return on rc = DC_STATUS_UNSUPORTED because it would end our dive parsing just if the device doesn't support gases, which seems undesirable in both, DC or file import. Signed-off-by: Salvador Cuñat <[email protected]> --- libdivecomputer.c | 98 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/libdivecomputer.c b/libdivecomputer.c index 27e3dbd..690cde0 100644 --- a/libdivecomputer.c +++ b/libdivecomputer.c @@ -434,45 +434,19 @@ static void parse_string_field(struct dive *dive, dc_field_string_t *str) } #endif -/* returns true if we want libdivecomputer's dc_device_foreach() to continue, - * false otherwise */ -static int dive_cb(const unsigned char *data, unsigned int size, - const unsigned char *fingerprint, unsigned int fsize, - void *userdata) +static dc_status_t libdc_header_parser(dc_parser_t *parser, struct device_data_t *devdata, struct dive *dive) { - int rc; - dc_parser_t *parser = NULL; - device_data_t *devdata = userdata; + dc_status_t rc = 0; dc_datetime_t dt = { 0 }; struct tm tm; - struct dive *dive = NULL; - /* reset the deco / ndl data */ - ndl = stoptime = stopdepth = 0; - in_deco = false; - - rc = create_parser(devdata, &parser); - if (rc != DC_STATUS_SUCCESS) { - dev_info(devdata, translate("gettextFromC", "Unable to create parser for %s %s"), devdata->vendor, devdata->product); - return false; - } - - rc = dc_parser_set_data(parser, data, size); - if (rc != DC_STATUS_SUCCESS) { - dev_info(devdata, translate("gettextFromC", "Error registering the data")); - goto error_exit; - } - - import_dive_number++; - dive = alloc_dive(); rc = dc_parser_get_datetime(parser, &dt); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error parsing the datetime")); - goto error_exit; + return rc; } - dive->dc.model = strdup(devdata->model); + dive->dc.deviceid = devdata->deviceid; - dive->dc.diveid = calculate_diveid(fingerprint, fsize); if (rc == DC_STATUS_SUCCESS) { tm.tm_year = dt.year; @@ -483,13 +457,14 @@ static int dive_cb(const unsigned char *data, unsigned int size, tm.tm_sec = dt.second; dive->when = dive->dc.when = utc_mktime(&tm); } + // Parse the divetime. dev_info(devdata, translate("gettextFromC", "Dive %d: %s"), import_dive_number, get_dive_date_c_string(dive->when)); unsigned int divetime = 0; rc = dc_parser_get_field(parser, DC_FIELD_DIVETIME, 0, &divetime); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error parsing the divetime")); - goto error_exit; + return rc; } if (rc == DC_STATUS_SUCCESS) dive->dc.duration.seconds = divetime; @@ -499,7 +474,7 @@ static int dive_cb(const unsigned char *data, unsigned int size, rc = dc_parser_get_field(parser, DC_FIELD_MAXDEPTH, 0, &maxdepth); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error parsing the maxdepth")); - goto error_exit; + return rc; } if (rc == DC_STATUS_SUCCESS) dive->dc.maxdepth.mm = rint(maxdepth * 1000); @@ -518,7 +493,7 @@ static int dive_cb(const unsigned char *data, unsigned int size, rc = dc_parser_get_field(parser, temp_fields[i], 0, &temperature); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error parsing temperature")); - goto error_exit; + return rc; } if (rc == DC_STATUS_SUCCESS) switch(i) { @@ -538,7 +513,7 @@ static int dive_cb(const unsigned char *data, unsigned int size, rc = dc_parser_get_field(parser, DC_FIELD_GASMIX_COUNT, 0, &ngases); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error parsing the gas mix count")); - goto error_exit; + return rc; } #if DC_VERSION_CHECK(0, 3, 0) @@ -550,7 +525,7 @@ static int dive_cb(const unsigned char *data, unsigned int size, rc = dc_parser_get_field(parser, DC_FIELD_SALINITY, 0, &salinity); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error obtaining water salinity")); - goto error_exit; + return rc; } if (rc == DC_STATUS_SUCCESS) dive->dc.salinity = rint(salinity.density * 10.0); @@ -559,7 +534,7 @@ static int dive_cb(const unsigned char *data, unsigned int size, rc = dc_parser_get_field(parser, DC_FIELD_ATMOSPHERIC, 0, &surface_pressure); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error obtaining surface pressure")); - goto error_exit; + return rc; } if (rc == DC_STATUS_SUCCESS) dive->dc.surface_pressure.mbar = rint(surface_pressure * 1000.0); @@ -584,7 +559,7 @@ static int dive_cb(const unsigned char *data, unsigned int size, rc = dc_parser_get_field(parser, DC_FIELD_DIVEMODE, 0, &divemode); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error obtaining divemode")); - goto error_exit; + return rc; } if (rc == DC_STATUS_SUCCESS) switch(divemode) { @@ -601,12 +576,57 @@ static int dive_cb(const unsigned char *data, unsigned int size, } #endif - rc = parse_gasmixes(devdata, dive, parser, ngases, data); - if (rc != DC_STATUS_SUCCESS) { + rc = parse_gasmixes(devdata, dive, parser, ngases, NULL); + if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error parsing the gas mix")); + return rc; + } + + return DC_STATUS_SUCCESS; +} + +/* returns true if we want libdivecomputer's dc_device_foreach() to continue, + * false otherwise */ +static int dive_cb(const unsigned char *data, unsigned int size, + const unsigned char *fingerprint, unsigned int fsize, + void *userdata) +{ + int rc; + dc_parser_t *parser = NULL; + device_data_t *devdata = userdata; + dc_datetime_t dt = { 0 }; + struct tm tm; + struct dive *dive = NULL; + + /* reset the deco / ndl data */ + ndl = stoptime = stopdepth = 0; + in_deco = false; + + rc = create_parser(devdata, &parser); + if (rc != DC_STATUS_SUCCESS) { + dev_info(devdata, translate("gettextFromC", "Unable to create parser for %s %s"), devdata->vendor, devdata->product); + return false; + } + + rc = dc_parser_set_data(parser, data, size); + if (rc != DC_STATUS_SUCCESS) { + dev_info(devdata, translate("gettextFromC", "Error registering the data")); + goto error_exit; + } + + import_dive_number++; + dive = alloc_dive(); + + // Parse the dive's header data + rc = libdc_header_parser (parser, devdata, dive); + if (rc != DC_STATUS_SUCCESS) { + dev_info(devdata, translate("getextFromC", "Error parsing the header")); goto error_exit; } + dive->dc.model = strdup(devdata->model); + dive->dc.diveid = calculate_diveid(fingerprint, fsize); + // Initialize the sample data. rc = parse_samples(devdata, &dive->dc, parser); if (rc != DC_STATUS_SUCCESS) { -- 2.1.4
From 71aca766d0fb063be1ee348aa5af8099c87ff87c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20Cu=C3=B1at?= <[email protected]> Date: Sat, 4 Apr 2015 00:51:38 +0200 Subject: [PATCH 4/6] (libdivecomputer) Add support for raw data buffer parse using libdc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). Signed-off-by: Salvador Cuñat <[email protected]> --- libdivecomputer.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ libdivecomputer.h | 1 + 2 files changed, 64 insertions(+) diff --git a/libdivecomputer.c b/libdivecomputer.c index 690cde0..2b72461 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 @@ -930,3 +933,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 works on datatrak and smartrak logs + * and OSTC families for OSTCTools logs 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) { + report_error("Error creating parser."); + dc_parser_destroy (parser); + return rc; + } + rc = dc_parser_set_data(parser, buffer, size); + if (rc != DC_STATUS_SUCCESS) { + report_error("Error registering the data."); + 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) { + report_error("Error parsing the dive header data. Dive # %d\nStatus = %s", dive->number, errmsg(rc)); + } + } + rc = dc_parser_samples_foreach (parser, sample_cb, &dive->dc); + if (rc != DC_STATUS_SUCCESS) { + report_error("Error parsing the sample data. Dive # %d\nStatus = %s", dive->number, errmsg(rc)); + dc_parser_destroy (parser); + return rc; + } + dc_parser_destroy(parser); + return(DC_STATUS_SUCCESS); +} diff --git a/libdivecomputer.h b/libdivecomputer.h index d1e4ad9..2e4fb9a 100644 --- a/libdivecomputer.h +++ b/libdivecomputer.h @@ -44,6 +44,7 @@ typedef struct device_data_t const char *errmsg (dc_status_t rc); const char *do_libdivecomputer_import(device_data_t *data); const char *do_uemis_import(device_data_t *data); +dc_status_t libdc_buffer_parser(struct dive *dive, device_data_t *data, unsigned char *buffer, int size); extern int import_thread_cancelled; extern const char *progress_bar_text; -- 2.1.4
From 22512d5f898552a53c01e9819cc823d5e3934f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20Cu=C3=B1at?= <[email protected]> Date: Sat, 4 Apr 2015 01:04:08 +0200 Subject: [PATCH 5/7] (file) Move extern declaration to header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move extern declaration of function datatrak_import() to file.h, where fits better than in file.c Signed-off-by: Salvador Cuñat <[email protected]> --- file.c | 2 -- file.h | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/file.c b/file.c index 03eb41c..5be16a2 100644 --- a/file.c +++ b/file.c @@ -22,8 +22,6 @@ #define O_BINARY 0 #endif -extern void datatrak_import(const char *file, struct dive_table *table); - int readfile(const char *filename, struct memblock *mem) { int ret, fd; diff --git a/file.h b/file.h index d4c52fd..b1fb694 100644 --- a/file.h +++ b/file.h @@ -8,6 +8,7 @@ struct memblock { extern int try_to_open_cochran(const char *filename, struct memblock *mem); extern int try_to_open_liquivision(const char *filename, struct memblock *mem); +extern void datatrak_import(const char *file, struct dive_table *table); #ifdef __cplusplus extern "C" { -- 2.1.4
From 3517338102bca3c9d50a833ec3c3f078baf24522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20Cu=C3=B1at?= <[email protected]> Date: Sat, 4 Apr 2015 01:07:59 +0200 Subject: [PATCH 6/7] OSTCTools-Add support to import .dive files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OSTCTools is a windows based software by Robert Angeymar which performs configuration upgrade, memory analysis and download tasks for H&W OSTC devices. Downloaded dives are stored in files (one archive each) with the raw binary data heavily padded at the begining of the file, and some other data not included in H&W dive header protocol as the device's serial number. The import function, simply, takes the raw data part of the file and lets libdivecomputer do the parse. Then adds some additional info as OSTC reported dive number and serial device number. Please note that OSTCTools is *not* a real logging software, it simply gets the DC raw data, so there aren't infos about dive site, equipment and so. Signed-off-by: Salvador Cuñat <[email protected]> --- file.c | 6 ++ file.h | 1 + ostctools.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++ qt-ui/mainwindow.cpp | 1 + subsurface.pro | 3 +- 5 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 ostctools.c diff --git a/file.c b/file.c index 5be16a2..b0bc37a 100644 --- a/file.c +++ b/file.c @@ -460,6 +460,12 @@ int parse_file(const char *filename) return 0; } + /* OSTCtools */ + if (fmt && (!strcasecmp(fmt + 1, "DIVE"))) { + ostctools_import(filename, &dive_table); + return 0; + } + ret = parse_file_buffer(filename, &mem); free(mem.buffer); return ret; diff --git a/file.h b/file.h index b1fb694..baeb8e1 100644 --- a/file.h +++ b/file.h @@ -9,6 +9,7 @@ struct memblock { extern int try_to_open_cochran(const char *filename, struct memblock *mem); extern int try_to_open_liquivision(const char *filename, struct memblock *mem); extern void datatrak_import(const char *file, struct dive_table *table); +extern void ostctools_import(const char *file, struct dive_table *table); #ifdef __cplusplus extern "C" { diff --git a/ostctools.c b/ostctools.c new file mode 100644 index 0000000..4fa0ba5 --- /dev/null +++ b/ostctools.c @@ -0,0 +1,156 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "dive.h" +#include "gettext.h" +#include "divelist.h" +#include "libdivecomputer.h" + +/* + * Returns a dc_descriptor_t structure based on dc model's number and family. + */ + +static dc_descriptor_t *ostc_get_data_descriptor(int data_model, dc_family_t data_fam) +{ + dc_descriptor_t *descriptor = NULL, *current = NULL;; + dc_iterator_t *iterator = NULL; + dc_status_t rc; + + rc = dc_descriptor_iterator(&iterator); + if (rc != DC_STATUS_SUCCESS) { + fprintf(stderr,"Error creating the device descriptor iterator.\n"); + return current; + } + while ((dc_iterator_next(iterator, &descriptor)) == DC_STATUS_SUCCESS) { + int desc_model = dc_descriptor_get_model(descriptor); + dc_family_t desc_fam = dc_descriptor_get_type(descriptor); + if (data_model == desc_model && data_fam == desc_fam) { + current = descriptor; + break; + } + dc_descriptor_free(descriptor); + } + dc_iterator_free(iterator); + return current; +} + +/* + * Fills a device_data_t structure with known dc data and a descriptor. + */ +static void ostc_prepare_data(int data_model, dc_family_t dc_fam, device_data_t *dev_data) +{ + device_data_t *ldc_dat = calloc(1, sizeof(device_data_t)); + dc_descriptor_t *data_descriptor; + + *ldc_dat = *dev_data; + ldc_dat->device = NULL; + ldc_dat->context = NULL; + + data_descriptor = ostc_get_data_descriptor(data_model, dc_fam); + if (data_descriptor) { + ldc_dat->descriptor = data_descriptor; + ldc_dat->vendor = copy_string(data_descriptor->vendor); + ldc_dat->model = copy_string(data_descriptor->product); + *dev_data = *ldc_dat; + } + free(ldc_dat); +} + +/* + * OSTCTools stores the raw dive data in heavily padded files, one dive + * each file. So it's not necesary to iterate once and again on a parsing + * function. Actually there's only one kind of archive for every DC model. + */ +void ostctools_import(const char *file, struct dive_table *divetable) +{ + FILE *archive; + device_data_t *devdata = calloc(1, sizeof(device_data_t)); + dc_family_t dc_fam; + unsigned char *buffer = calloc(65536, 1), + *tmp; + struct dive *ostcdive = alloc_dive(); + dc_status_t rc = 0; + int model = 0, i = 0; + unsigned int serial; + struct extra_data *ptr; + + // Open the archive + if ((archive = subsurface_fopen(file, "rb")) == NULL) { + report_error(translate("gettextFromC", "Error: couldn't open the file")); + return; + } + + // Read dive number from the log + tmp = calloc(2,1); + fseek(archive, 258, 0); + fread(tmp, 1, 2, archive); + ostcdive->number = tmp[0] + (tmp[1] << 8); + free(tmp); + + // Read device's serial number + tmp = calloc(2, 1); + fseek(archive, 265, 0); + fread(tmp, 1, 2, archive); + serial = tmp[0] + (tmp[1] << 8); + free(tmp); + + // Read dive's raw data, header + profile + fseek(archive, 456, 0); + while (!feof(archive)) { + fread(buffer+i, 1, 1, archive); + if (buffer[i] == 0xFD && buffer[i-1] == 0xFD) + break; + i++; + } + + // Try to determine the dc family based on the header type + switch (buffer[2]) { + case 0x20: + case 0x21: + dc_fam = DC_FAMILY_HW_OSTC; + break; + case 0x22: + dc_fam = DC_FAMILY_HW_FROG; + break; + case 0x23: + dc_fam = DC_FAMILY_HW_OSTC3; + break; + } + + // Prepare data to pass to libdivecomputer. OSTC protocol doesn't include + // a model number so will use 0. + ostc_prepare_data(model, dc_fam, devdata); + tmp = calloc(strlen(devdata->vendor)+strlen(devdata->model)+28,1); + sprintf(tmp,"%s %s (Imported from OSTCTools)", devdata->vendor, devdata->model); + ostcdive->dc.model = copy_string(tmp); + free(tmp); + + // Parse the dive data + rc = libdc_buffer_parser(ostcdive, devdata, buffer, i+1); + if (rc != DC_STATUS_SUCCESS) + report_error("Libdc returned error -%s- for dive %d", errmsg(rc), ostcdive->number); + + // Serial number is not part of the header nor the profile, so libdc won't + // catch it. If Serial is part of the extra_data, and set to zero, remove + // it from the list and add again. + tmp = calloc(12,1); + sprintf(tmp, "%d", serial); + ostcdive->dc.serial = copy_string(tmp); + free(tmp); + + ptr = ostcdive->dc.extra_data; + while (strcmp(ptr->key, "Serial")) + ptr = ptr->next; + if (!strcmp(ptr->value, "0")) { + add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial); + *ptr = *(ptr)->next; + } + + free(devdata); + free(buffer); + record_dive_to_table(ostcdive, divetable); + mark_divelist_changed(true); + sort_table(divetable); + fclose(archive); +} diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 76cfc85..19c2e21 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -1463,6 +1463,7 @@ void MainWindow::on_actionImportDiveLog_triggered() "XML files (*.xml *.XML);;" "APD log viewer (*.apd *.APD);;" "Datatrak/WLog Files (*.log *.LOG);;" + "OSTCtools Files (*.dive *.DIVE);;" "All files (*)")); if (fileNames.isEmpty()) diff --git a/subsurface.pro b/subsurface.pro index cedc926..bec7d65 100644 --- a/subsurface.pro +++ b/subsurface.pro @@ -213,7 +213,8 @@ SOURCES = \ qt-ui/diveshareexportdialog.cpp \ qt-ui/filtermodels.cpp \ qt-ui/undocommands.cpp \ - qt-ui/notificationwidget.cpp + qt-ui/notificationwidget.cpp \ + ostctools.c android: SOURCES += android.cpp else: win32: SOURCES += windows.c -- 2.1.4
From 1dd4128105d9a6cf30f8b3287d3a193ab2e8b7c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20Cu=C3=B1at?= <[email protected]> Date: Sat, 4 Apr 2015 01:11:35 +0200 Subject: [PATCH 7/7] (libdivecomputer) Remove unused param in parse_gasmixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit data pointer is not used, so it can be safely removed. Signed-off-by: Salvador Cuñat <[email protected]> --- libdivecomputer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libdivecomputer.c b/libdivecomputer.c index 2b72461..069e87b 100644 --- a/libdivecomputer.c +++ b/libdivecomputer.c @@ -68,8 +68,7 @@ static dc_status_t create_parser(device_data_t *devdata, dc_parser_t **parser) return dc_parser_new(parser, devdata->device); } -static int parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_parser_t *parser, int ngases, - const unsigned char *data) +static int parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_parser_t *parser, int ngases) { static bool shown_warning = false; int i, rc; @@ -579,7 +578,7 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, struct device_data_t } #endif - rc = parse_gasmixes(devdata, dive, parser, ngases, NULL); + rc = parse_gasmixes(devdata, dive, parser, ngases); if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { dev_info(devdata, translate("gettextFromC", "Error parsing the gas mix")); return rc; -- 2.1.4
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
