+static int parse_gasmixes(struct dive *dive, parser_t *parser, int ngases)
+{
+ int i;
+
+ for (i = 0; i < ngases; i++) {
+ int rc;
+ gasmix_t gasmix = {0};
+ int o2, he;
+
+ rc = parser_get_field(parser, FIELD_TYPE_GASMIX, i, &gasmix);
+ if (rc != PARSER_STATUS_SUCCESS && rc != PARSER_STATUS_UNSUPPORTED)
+ return rc;
+
+ if (i >= MAX_CYLINDERS)
+ continue;
+
+ o2 = gasmix.oxygen * 1000 + 0.5;
+ he = gasmix.helium * 1000 + 0.5;
+
+ /* Ignore bogus data - libdivecomputer does some crazy stuff */
+ if (o2 < 210 || o2 >= 1000)
+ o2 = 0;
+ if (he < 0 || he >= 800 || o2+he >= 1000)
+ he = 0;
+
+ dive->cylinder[i].gasmix.o2.permille = o2;
+ dive->cylinder[i].gasmix.he.permille = he;
+ }
+ return PARSER_STATUS_SUCCESS;
+}
+
+static void handle_event(struct dive *dive, struct sample *sample, parser_sample_value_t value)
+{
+ int type, time;
+ static const char *events[] = {
+ "none", "deco", "rbt", "ascent", "ceiling", "workload", "transmitter",
+ "violation", "bookmark", "surface", "safety stop", "gaschange",
+ "safety stop (voluntary)", "safety stop (mandatory)", "deepstop",
+ "ceiling (safety stop)", "unknown", "divetime", "maxdepth",
+ "OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning"
+ };
+ const int nr_events = sizeof(events) / sizeof(const char *);
+ const char *name;
+
+ /*
+ * Just ignore surface events. They are pointless. What "surface"
+ * means depends on the dive computer (and possibly even settings
+ * in the dive computer). It does *not* necessarily mean "depth 0",
+ * so don't even turn it into that.
+ */
+ if (value.event.type == SAMPLE_EVENT_SURFACE)
+ return;
+
+ /*
+ * Other evens might be more interesting, but for now we just print them out.
+ */
+ type = value.event.type;
+ name = "invalid event number";
+ if (type < nr_events)
+ name = events[type];
+
+ time = value.event.time;
+ if (sample)
+ time += sample->time.seconds;
+
+ add_event(dive, time, type, value.event.flags, value.event.value, name);
+}
+
+void
+sample_cb(parser_sample_type_t type, parser_sample_value_t value, void *userdata)
+{
+ int i;
+ struct dive **divep = userdata;
+ struct dive *dive = *divep;
+ struct sample *sample;
+
+ /*
+ * We fill in the "previous" sample - except for SAMPLE_TYPE_TIME,
+ * which creates a new one.
+ */
+ sample = dive->samples ? dive->sample+dive->samples-1 : NULL;
+
+ switch (type) {
+ case SAMPLE_TYPE_TIME:
+ sample = prepare_sample(divep);
+ sample->time.seconds = value.time;
+ finish_sample(*divep, sample);
+ break;
+ case SAMPLE_TYPE_DEPTH:
+ sample->depth.mm = value.depth * 1000 + 0.5;
+ break;
+ case SAMPLE_TYPE_PRESSURE:
+ sample->cylinderindex = value.pressure.tank;
+ sample->cylinderpressure.mbar = value.pressure.value * 1000 + 0.5;
+ break;
+ case SAMPLE_TYPE_TEMPERATURE:
+ sample->temperature.mkelvin = (value.temperature + 273.15) * 1000 + 0.5;
+ break;
+ case SAMPLE_TYPE_EVENT:
+ handle_event(dive, sample, value);
+ break;
+ case SAMPLE_TYPE_RBT:
+ printf(" <rbt>%u</rbt>\n", value.rbt);
+ break;
+ case SAMPLE_TYPE_HEARTBEAT:
+ printf(" <heartbeat>%u</heartbeat>\n", value.heartbeat);
+ break;
+ case SAMPLE_TYPE_BEARING:
+ printf(" <bearing>%u</bearing>\n", value.bearing);
+ break;
+ case SAMPLE_TYPE_VENDOR:
+ printf(" <vendor type=\"%u\" size=\"%u\">", value.vendor.type, value.vendor.size);
+ for (i = 0; i < value.vendor.size; ++i)
+ printf("%02X", ((unsigned char *) value.vendor.data)[i]);
+ printf("</vendor>\n");
+ break;
+ default:
+ break;
+ }
+}
+
+
+static int parse_samples(struct dive **divep, parser_t *parser)
+{
+ // Parse the sample data.
+ printf("Parsing the sample data.\n");
+ return parser_samples_foreach(parser, sample_cb, divep);
+}
+
+/*
+ * Check if this dive already existed before the import
+ */
+static int find_dive(struct dive *dive, device_data_t *devdata)
+{
+ int i;
+
+ for (i = 0; i < devdata->preexisting; i++) {
+ struct dive *old = dive_table.dives[i];
+
+ if (dive->when != old->when)
+ continue;
+ return 1;
+ }
+ return 0;
+}
+