コード例 #1
0
ファイル: hw_ostc_parser.c プロジェクト: claudiuolteanu/libdc
static dc_status_t
hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
{
	hw_ostc_parser_t *parser = (hw_ostc_parser_t *) abstract;
	const unsigned char *data = abstract->data;
	unsigned int size = abstract->size;

	// Cache the header data.
	dc_status_t rc = hw_ostc_parser_cache (parser);
	if (rc != DC_STATUS_SUCCESS)
		return rc;

	unsigned int version = parser->version;
	const hw_ostc_layout_t *layout = parser->layout;

	unsigned int divetime = 0;
	if (version > 0x20) {
		// Use the dive time stored in the extended header, rounded down towards
		// the nearest minute, to match the value displayed by the ostc.
		divetime = (array_uint16_le (data + layout->duration) / 60) * 60;
	} else {
		// Use the normal dive time (excluding the shallow parts of the dive).
		divetime = array_uint16_le (data + layout->divetime) * 60 + data[layout->divetime + 2];
	}

	const unsigned char *p = data + layout->datetime;

	dc_datetime_t dt;
	if (version == 0x23) {
		dt.year   = p[0] + 2000;
		dt.month  = p[1];
		dt.day    = p[2];
	} else {
		dt.year   = p[2] + 2000;
		dt.month  = p[0];
		dt.day    = p[1];
	}
	dt.hour   = p[3];
	dt.minute = p[4];
	dt.second = 0;

	dc_ticks_t ticks = dc_datetime_mktime (&dt);
	if (ticks == (dc_ticks_t) -1)
		return DC_STATUS_DATAFORMAT;

	ticks -= divetime;

	if (!dc_datetime_localtime (datetime, ticks))
		return DC_STATUS_DATAFORMAT;

	return DC_STATUS_SUCCESS;
}
コード例 #2
0
ファイル: libdc_parser.c プロジェクト: asymworks/benthos-dc
int libdc_parser_parse_header(parser_handle_t abstract, const void * buffer, uint32_t size, header_callback_fn_t cb, void * userdata)
{
	libdc_parser_t parser = (libdc_parser_t)(abstract);
	if (parser == NULL)
	{
		errno = EINVAL;
		return -1;
	}

	dc_status_t rc = dc_parser_set_data(parser->parser, buffer, size);
	if (rc != DC_STATUS_SUCCESS)
	{
		parser->dev->errcode = DRIVER_ERR_PARSER;
		parser->dev->errmsg = "Failed to set parser data";
		return -1;
	}

	// Parse Dive Date/Time
	dc_datetime_t dt = {0};
	rc = dc_parser_get_datetime(parser->parser, & dt);
	if ((rc != DC_STATUS_SUCCESS) && (rc != DC_STATUS_UNSUPPORTED))
	{
		parser->dev->errcode = DRIVER_ERR_PARSER;
		parser->dev->errmsg = "Failed to retrieve dive date/time";
		return -1;
	}

	if ((rc == DC_STATUS_SUCCESS) && (cb != NULL))
	{
		dc_ticks_t ts = dc_datetime_mktime(& dt);
		cb(userdata, DIVE_HEADER_START_TIME, (time_t)ts, 0, 0);
	}

	// Parse Dive Duration
	unsigned int duration = 0;
	rc = dc_parser_get_field (parser->parser, DC_FIELD_DIVETIME, 0, & duration);
	if ((rc != DC_STATUS_SUCCESS) && (rc != DC_STATUS_UNSUPPORTED))
	{
		parser->dev->errcode = DRIVER_ERR_PARSER;
		parser->dev->errmsg = "Failed to retrieve dive duration";
		return -1;
	}

	if ((rc == DC_STATUS_SUCCESS) && (cb != NULL))
		cb(userdata, DIVE_HEADER_DURATION, duration / 60, 0, 0);

	// Parse Maximum Depth
	double maxdepth = 0.0;
	rc = dc_parser_get_field (parser->parser, DC_FIELD_MAXDEPTH, 0, & maxdepth);
	if ((rc != DC_STATUS_SUCCESS) && (rc != DC_STATUS_UNSUPPORTED))
	{
		parser->dev->errcode = DRIVER_ERR_PARSER;
		parser->dev->errmsg = "Failed to retrieve maximum depth";
		return -1;
	}

	if ((rc == DC_STATUS_SUCCESS) && (cb != NULL))
		cb(userdata, DIVE_HEADER_MAX_DEPTH, (uint32_t)round(maxdepth * 100), 0, 0);

	// Parse Gas Mixes
	unsigned int ngasses = 0;
	rc = dc_parser_get_field(parser->parser, DC_FIELD_GASMIX_COUNT, 0, & ngasses);
	if ((rc != DC_STATUS_SUCCESS) && (rc != DC_STATUS_UNSUPPORTED))
	{
		parser->dev->errcode = DRIVER_ERR_PARSER;
		parser->dev->errmsg = "Failed to retrieve gas mix count";
		return -1;
	}

	unsigned int i;
	for (i = 0; i < ngasses; ++i)
	{
		dc_gasmix_t gasmix = {0};
		rc = dc_parser_get_field(parser->parser, DC_FIELD_GASMIX, i, & gasmix);
		if ((rc != DC_STATUS_SUCCESS) && (rc != DC_STATUS_UNSUPPORTED))
		{
			parser->dev->errcode = DRIVER_ERR_PARSER;
			parser->dev->errmsg = "Failed to retrieve gas mix data";
			return -1;
		}

		if ((rc == DC_STATUS_SUCCESS) && (cb != NULL))
		{
			uint32_t pmHe = (uint32_t)round(gasmix.helium * 1000.0);
			uint32_t pmO2 = (uint32_t)round(gasmix.oxygen * 1000.0);

			cb(userdata, DIVE_HEADER_PMO2, pmO2, i, 0);
			cb(userdata, DIVE_HEADER_PMHe, pmHe, i, 0);
		}
	}

	return 0;
}