Merge branch 'master' into Subsurface-branch

This commit is contained in:
Dirk Hohndel 2016-04-09 08:29:44 -07:00
commit 8356e22e61
7 changed files with 139 additions and 27 deletions

View File

@ -246,6 +246,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto
dc_status_t status = DC_STATUS_SUCCESS;
dc_buffer_t *fingerprint = NULL;
dctool_output_t *output = NULL;
dctool_units_t units = DCTOOL_UNITS_METRIC;
// Default option values.
unsigned int help = 0;
@ -256,7 +257,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto
// Parse the command-line options.
int opt = 0;
const char *optstring = "ho:p:c:f:";
const char *optstring = "ho:p:c:f:u:";
#ifdef HAVE_GETOPT_LONG
struct option options[] = {
{"help", no_argument, 0, 'h'},
@ -264,6 +265,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto
{"fingerprint", required_argument, 0, 'p'},
{"cache", required_argument, 0, 'c'},
{"format", required_argument, 0, 'f'},
{"units", required_argument, 0, 'u'},
{0, 0, 0, 0 }
};
while ((opt = getopt_long (argc, argv, optstring, options, NULL)) != -1) {
@ -286,6 +288,12 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto
case 'f':
format = optarg;
break;
case 'u':
if (strcmp (optarg, "metric") == 0)
units = DCTOOL_UNITS_METRIC;
if (strcmp (optarg, "imperial") == 0)
units = DCTOOL_UNITS_IMPERIAL;
break;
default:
return EXIT_FAILURE;
}
@ -307,7 +315,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto
if (strcasecmp(format, "raw") == 0) {
output = dctool_raw_output_new (filename);
} else if (strcasecmp(format, "xml") == 0) {
output = dctool_xml_output_new (filename);
output = dctool_xml_output_new (filename, units);
} else {
message ("Unknown output format: %s\n", format);
exitcode = EXIT_FAILURE;
@ -348,12 +356,14 @@ const dctool_command_t dctool_download = {
" -p, --fingerprint <data> Fingerprint data (hexadecimal)\n"
" -c, --cache <directory> Cache directory\n"
" -f, --format <format> Output format\n"
" -u, --units <units> Set units (metric or imperial)\n"
#else
" -h Show help message\n"
" -o <filename> Output filename\n"
" -p <fingerprint> Fingerprint data (hexadecimal)\n"
" -c <directory> Cache directory\n"
" -f <format> Output format\n"
" -u <units> Set units (metric or imperial)\n"
#endif
"\n"
"Supported output formats:\n"

View File

@ -26,6 +26,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
@ -196,6 +197,7 @@ dctool_parse_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t
dc_status_t status = DC_STATUS_SUCCESS;
dc_buffer_t *buffer = NULL;
dctool_output_t *output = NULL;
dctool_units_t units = DCTOOL_UNITS_METRIC;
// Default option values.
unsigned int help = 0;
@ -205,13 +207,14 @@ dctool_parse_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t
// Parse the command-line options.
int opt = 0;
const char *optstring = "ho:d:s:";
const char *optstring = "ho:d:s:u:";
#ifdef HAVE_GETOPT_LONG
struct option options[] = {
{"help", no_argument, 0, 'h'},
{"output", required_argument, 0, 'o'},
{"devtime", required_argument, 0, 'd'},
{"systime", required_argument, 0, 's'},
{"units", required_argument, 0, 'u'},
{0, 0, 0, 0 }
};
while ((opt = getopt_long (argc, argv, optstring, options, NULL)) != -1) {
@ -231,6 +234,12 @@ dctool_parse_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t
case 's':
systime = strtoll (optarg, NULL, 0);
break;
case 'u':
if (strcmp (optarg, "metric") == 0)
units = DCTOOL_UNITS_METRIC;
if (strcmp (optarg, "imperial") == 0)
units = DCTOOL_UNITS_IMPERIAL;
break;
default:
return EXIT_FAILURE;
}
@ -246,7 +255,7 @@ dctool_parse_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t
}
// Create the output.
output = dctool_xml_output_new (filename);
output = dctool_xml_output_new (filename, units);
if (output == NULL) {
message ("Failed to create the output.\n");
exitcode = EXIT_FAILURE;
@ -295,10 +304,12 @@ const dctool_command_t dctool_parse = {
" -o, --output <filename> Output filename\n"
" -d, --devtime <timestamp> Device time\n"
" -s, --systime <timestamp> System time\n"
" -u, --units <units> Set units (metric or imperial)\n"
#else
" -h Show help message\n"
" -o <filename> Output filename\n"
" -d <devtime> Device time\n"
" -s <systime> System time\n"
" -u <units> Set units (metric or imperial)\n"
#endif
};

View File

@ -31,8 +31,13 @@ extern "C" {
typedef struct dctool_output_t dctool_output_t;
typedef enum dctool_units_t {
DCTOOL_UNITS_METRIC,
DCTOOL_UNITS_IMPERIAL
} dctool_units_t;
dctool_output_t *
dctool_xml_output_new (const char *filename);
dctool_xml_output_new (const char *filename, dctool_units_t units);
dctool_output_t *
dctool_raw_output_new (const char *template);

View File

@ -23,6 +23,8 @@
#include <string.h>
#include <stdio.h>
#include <libdivecomputer/units.h>
#include "output-private.h"
#include "utils.h"
@ -32,6 +34,7 @@ static dc_status_t dctool_xml_output_free (dctool_output_t *output);
typedef struct dctool_xml_output_t {
dctool_output_t base;
FILE *ostream;
dctool_units_t units;
} dctool_xml_output_t;
static const dctool_output_vtable_t xml_vtable = {
@ -42,9 +45,50 @@ static const dctool_output_vtable_t xml_vtable = {
typedef struct sample_data_t {
FILE *ostream;
dctool_units_t units;
unsigned int nsamples;
} sample_data_t;
static double
convert_depth (double value, dctool_units_t units)
{
if (units == DCTOOL_UNITS_IMPERIAL) {
return value / FEET;
} else {
return value;
}
}
static double
convert_temperature (double value, dctool_units_t units)
{
if (units == DCTOOL_UNITS_IMPERIAL) {
return value * (9.0 / 5.0) + 32.0;
} else {
return value;
}
}
static double
convert_pressure (double value, dctool_units_t units)
{
if (units == DCTOOL_UNITS_IMPERIAL) {
return value * BAR / PSI;
} else {
return value;
}
}
static double
convert_volume (double value, dctool_units_t units)
{
if (units == DCTOOL_UNITS_IMPERIAL) {
return value / 1000.0 / CUFT;
} else {
return value;
}
}
static void
sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
{
@ -68,13 +112,17 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
fprintf (sampledata->ostream, " <time>%02u:%02u</time>\n", value.time / 60, value.time % 60);
break;
case DC_SAMPLE_DEPTH:
fprintf (sampledata->ostream, " <depth>%.2f</depth>\n", value.depth);
fprintf (sampledata->ostream, " <depth>%.2f</depth>\n",
convert_depth(value.depth, sampledata->units));
break;
case DC_SAMPLE_PRESSURE:
fprintf (sampledata->ostream, " <pressure tank=\"%u\">%.2f</pressure>\n", value.pressure.tank, value.pressure.value);
fprintf (sampledata->ostream, " <pressure tank=\"%u\">%.2f</pressure>\n",
value.pressure.tank,
convert_pressure(value.pressure.value, sampledata->units));
break;
case DC_SAMPLE_TEMPERATURE:
fprintf (sampledata->ostream, " <temperature>%.2f</temperature>\n", value.temperature);
fprintf (sampledata->ostream, " <temperature>%.2f</temperature>\n",
convert_temperature(value.temperature, sampledata->units));
break;
case DC_SAMPLE_EVENT:
if (value.event.type != SAMPLE_EVENT_GASCHANGE && value.event.type != SAMPLE_EVENT_GASCHANGE2) {
@ -108,7 +156,9 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
break;
case DC_SAMPLE_DECO:
fprintf (sampledata->ostream, " <deco time=\"%u\" depth=\"%.2f\">%s</deco>\n",
value.deco.time, value.deco.depth, decostop[value.deco.type]);
value.deco.time,
convert_depth(value.deco.depth, sampledata->units),
decostop[value.deco.type]);
break;
case DC_SAMPLE_GASMIX:
fprintf (sampledata->ostream, " <gasmix>%u</gasmix>\n", value.gasmix);
@ -119,7 +169,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
}
dctool_output_t *
dctool_xml_output_new (const char *filename)
dctool_xml_output_new (const char *filename, dctool_units_t units)
{
dctool_xml_output_t *output = NULL;
@ -138,6 +188,8 @@ dctool_xml_output_new (const char *filename)
goto error_free;
}
output->units = units;
fprintf (output->ostream, "<device>\n");
return (dctool_output_t *) output;
@ -154,6 +206,12 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
dctool_xml_output_t *output = (dctool_xml_output_t *) abstract;
dc_status_t status = DC_STATUS_SUCCESS;
// Initialize the sample data.
sample_data_t sampledata = {0};
sampledata.nsamples = 0;
sampledata.ostream = output->ostream;
sampledata.units = output->units;
fprintf (output->ostream, "<dive>\n<number>%u</number>\n<size>%u</size>\n", abstract->number, size);
if (fingerprint) {
@ -198,7 +256,7 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
}
fprintf (output->ostream, "<maxdepth>%.2f</maxdepth>\n",
maxdepth);
convert_depth(maxdepth, output->units));
// Parse the temperature.
message ("Parsing the temperature.\n");
@ -217,7 +275,8 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
if (status != DC_STATUS_UNSUPPORTED) {
fprintf (output->ostream, "<temperature type=\"%s\">%.1f</temperature>\n",
names[i], temperature);
names[i],
convert_temperature(temperature, output->units));
}
}
@ -279,13 +338,16 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
" <type>%s</type>\n"
" <volume>%.1f</volume>\n"
" <workpressure>%.2f</workpressure>\n",
names[tank.type], tank.volume, tank.workpressure);
names[tank.type],
convert_volume(tank.volume, output->units),
convert_pressure(tank.workpressure, output->units));
}
fprintf (output->ostream,
" <beginpressure>%.2f</beginpressure>\n"
" <endpressure>%.2f</endpressure>\n"
"</tank>\n",
tank.beginpressure, tank.endpressure);
convert_pressure(tank.beginpressure, output->units),
convert_pressure(tank.endpressure, output->units));
}
// Parse the dive mode.
@ -328,14 +390,9 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
if (status != DC_STATUS_UNSUPPORTED) {
fprintf (output->ostream, "<atmospheric>%.5f</atmospheric>\n",
atmospheric);
convert_pressure(atmospheric, output->units));
}
// Initialize the sample data.
sample_data_t sampledata = {0};
sampledata.nsamples = 0;
sampledata.ostream = output->ostream;
// Parse the sample data.
message ("Parsing the sample data.\n");
status = dc_parser_samples_foreach (parser, sample_cb, &sampledata);
@ -344,11 +401,12 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
goto cleanup;
}
cleanup:
if (sampledata.nsamples)
fprintf (output->ostream, "</sample>\n");
fprintf (output->ostream, "</dive>\n");
cleanup:
return status;
}

View File

@ -184,6 +184,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Aeris", "A300CS", DC_FAMILY_OCEANIC_ATOM2, 0x454C},
{"Oceanic", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4554},
{"Oceanic", "VTX", DC_FAMILY_OCEANIC_ATOM2, 0x4557},
{"Aqualung", "i450T", DC_FAMILY_OCEANIC_ATOM2, 0x4641},
/* Mares Nemo */
{"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0},
{"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0},
@ -228,6 +229,7 @@ static const dc_descriptor_t g_descriptors[] = {
/* Cressi Leonardo */
{"Cressi", "Leonardo", DC_FAMILY_CRESSI_LEONARDO, 1},
{"Cressi", "Giotto", DC_FAMILY_CRESSI_LEONARDO, 4},
{"Cressi", "Newton", DC_FAMILY_CRESSI_LEONARDO, 5},
/* Zeagle N2iTiON3 */
{"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0},
{"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0},

View File

@ -180,6 +180,10 @@ static const oceanic_common_version_t aeris_a300cs_version[] = {
{"OCEANVTX \0\0 2048"},
};
static const oceanic_common_version_t aqualung_i450t_version[] = {
{"AQUAI450 \0\0 2048"},
};
static const oceanic_common_layout_t aeris_f10_layout = {
0x10000, /* memsize */
0x0000, /* cf_devinfo */
@ -401,6 +405,18 @@ static const oceanic_common_layout_t aeris_a300cs_layout = {
1 /* pt_mode_logbook */
};
static const oceanic_common_layout_t aqualung_i450t_layout = {
0x40000, /* memsize */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x10C0, /* rb_logbook_begin */
0x1400, /* rb_logbook_end */
16, /* rb_logbook_entry_size */
0x1400, /* rb_profile_begin */
0x3FE00, /* rb_profile_end */
0, /* pt_mode_global */
1 /* pt_mode_logbook */
};
static dc_status_t
oceanic_atom2_packet (oceanic_atom2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, unsigned int crc_size)
@ -634,6 +650,8 @@ oceanic_atom2_device_open2 (dc_device_t **out, dc_context_t *context, const char
} else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_a300cs_version)) {
device->base.layout = &aeris_a300cs_layout;
device->bigpage = 16;
} else if (OCEANIC_COMMON_MATCH (device->base.version, aqualung_i450t_version)) {
device->base.layout = &aqualung_i450t_layout;
} else {
device->base.layout = &oceanic_default_layout;
}

View File

@ -77,6 +77,7 @@
#define A300CS 0x454C
#define F11B 0x4554
#define VTX 0x4557
#define I450T 0x4641
#define NORMAL 0
#define GAUGE 1
@ -161,7 +162,7 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
} else if (model == F11A || model == F11B) {
parser->headersize = 5 * PAGESIZE;
parser->footersize = 0;
} else if (model == A300CS || model == VTX) {
} else if (model == A300CS || model == VTX || model == I450T) {
parser->headersize = 5 * PAGESIZE;
}
@ -287,6 +288,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
break;
case A300CS:
case VTX:
case I450T:
datetime->year = (p[10]) + 2000;
datetime->month = (p[8]);
datetime->day = (p[9]);
@ -412,6 +414,9 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser)
} else {
ngasmixes = 4;
}
} else if (parser->model == I450T) {
o2_offset = 0x30;
ngasmixes = 3;
} else {
o2_offset = header + 4;
ngasmixes = 3;
@ -616,7 +621,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
} else if (parser->model == OC1A || parser->model == OC1B ||
parser->model == OC1C || parser->model == OCI ||
parser->model == TX1 || parser->model == A300CS ||
parser->model == VTX) {
parser->model == VTX || parser->model == I450T) {
samplesize = PAGESIZE;
}
@ -741,7 +746,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
} else if (parser->model == GEO20 || parser->model == VEO20 ||
parser->model == VEO30 || parser->model == OC1A ||
parser->model == OC1B || parser->model == OC1C ||
parser->model == OCI || parser->model == A300) {
parser->model == OCI || parser->model == A300 ||
parser->model == I450T) {
temperature = data[offset + 3];
} else if (parser->model == OCS || parser->model == TX1) {
temperature = data[offset + 1];
@ -775,7 +781,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
// Tank Pressure (psi)
if (have_pressure) {
if (parser->model == OC1A || parser->model == OC1B ||
parser->model == OC1C || parser->model == OCI)
parser->model == OC1C || parser->model == OCI ||
parser->model == I450T)
pressure = (data[offset + 10] + (data[offset + 11] << 8)) & 0x0FFF;
else if (parser->model == VT4 || parser->model == VT41||
parser->model == ATOM3 || parser->model == ATOM31 ||
@ -799,7 +806,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
else if (parser->model == GEO20 || parser->model == VEO20 ||
parser->model == VEO30 || parser->model == OC1A ||
parser->model == OC1B || parser->model == OC1C ||
parser->model == OCI || parser->model == A300)
parser->model == OCI || parser->model == A300 ||
parser->model == I450T)
depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF;
else if (parser->model == ATOM1)
depth = data[offset + 3] * 16;
@ -837,7 +845,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
// NDL / Deco
unsigned int have_deco = 0;
unsigned int decostop = 0, decotime = 0;
if (parser->model == A300CS || parser->model == VTX) {
if (parser->model == A300CS || parser->model == VTX || parser->model == I450T) {
decostop = (data[offset + 15] & 0x70) >> 4;
decotime = array_uint16_le(data + offset + 6) & 0x03FF;
have_deco = 1;