[PATCH 007/007] Modified dctool_download to add for ascent rate warning and stream variable change. Adapted Cochran code to use new device vtable (added size) and to rely on dc_device_allocate/deallocate.

John Van Ostrand john at vanostrand.com
Fri Jan 8 11:23:49 PST 2016


---
 examples/dctool_download.c     |  2 +-
 src/cochran_commander.c        | 23 ++++++++-------------
 src/cochran_commander_parser.c | 47 +++++++++++++++++++++---------------------
 3 files changed, 33 insertions(+), 39 deletions(-)

diff --git a/examples/dctool_download.c b/examples/dctool_download.c
index 02f2be6..ffcdc41 100644
--- a/examples/dctool_download.c
+++ b/examples/dctool_download.c
@@ -126,7 +126,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
 		fprintf (sampledata->ostream, "   <gasmix>%u</gasmix>\n", value.gasmix);
 		break;
 	case DC_SAMPLE_ASCENT_RATE:
-		fprintf (sampledata->fp, "   <ascent_rate>%.2f</ascent_rate>\n",
+		fprintf (sampledata->ostream, "   <ascent_rate>%.2f</ascent_rate>\n",
 			value.ascent_rate);
 		break;
 	default:
diff --git a/src/cochran_commander.c b/src/cochran_commander.c
index 036ca6c..3ba3786 100644
--- a/src/cochran_commander.c
+++ b/src/cochran_commander.c
@@ -138,6 +138,7 @@ static cochran_layout_t cochran_layout_emc14 = {
 };
 
 static const dc_device_vtable_t cochran_commander_device_vtable = {
+	sizeof(cochran_device_t),
 	DC_FAMILY_COCHRAN_COMMANDER,
 	cochran_commander_device_set_fingerprint,	/* set_fingerprint */
 	cochran_commander_device_read,				/* read */
@@ -187,7 +188,6 @@ cochran_packet (cochran_device_t *device, dc_event_progress_t *progress,
 						SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE);
 		if (rc == -1) {
 			ERROR (abstract->context, "Failed to set the high baud rate.");
-			free (device);
 			return DC_STATUS_IO;
 		}
 	}
@@ -230,7 +230,6 @@ cochran_commander_serial_setup (cochran_device_t *device, dc_context_t *context)
 	if (rc == -1) {
 		ERROR (context, "Failed to set the terminal attributes.");
 		serial_close (device->port);
-		free (device);
 		return DC_STATUS_IO;
 	}
 
@@ -249,7 +248,6 @@ cochran_commander_serial_setup (cochran_device_t *device, dc_context_t *context)
 	if (serial_set_timeout (device->port, 5000) == -1) {
 		ERROR (context, "Failed to set the timeout.");
 		serial_close (device->port);
-		free (device);
 		return DC_STATUS_IO;
 	}
 
@@ -272,7 +270,6 @@ cochran_commander_serial_open(cochran_device_t *device, dc_context_t *context)
 	int rc = serial_open (&device->port, context, device->name);
 	if (rc == -1) {
 		ERROR (context, "Failed to open the serial port.");
-		free (device);
 		return DC_STATUS_IO;
 	}
 
@@ -284,6 +281,7 @@ dc_status_t
 cochran_commander_device_open (dc_device_t **out, dc_context_t *context,
 		const char *name)
 {
+	cochran_device_t *device = NULL;
 	dc_status_t rc;
 	cochran_layout_t *layout;
 
@@ -291,16 +289,13 @@ cochran_commander_device_open (dc_device_t **out, dc_context_t *context,
 		return DC_STATUS_INVALIDARGS;
 
 	// Allocate memory.
-	cochran_device_t *device = (cochran_device_t *) malloc (
-			sizeof (cochran_device_t));
+	device = (cochran_device_t *)
+		dc_device_allocate(context, &cochran_commander_device_vtable);
 	if (device == NULL) {
 		ERROR (context, "Failed to allocate memory.");
 		return DC_STATUS_NOMEMORY;
 	}
 
-	// Initialize the base class.
-	device_init (&device->base, context, &cochran_commander_device_vtable);
-
 	// Set the default values.
 	device->port = NULL;
 	device->name = name;
@@ -310,8 +305,10 @@ cochran_commander_device_open (dc_device_t **out, dc_context_t *context,
 		NULL, 0);
 
 	rc = cochran_commander_serial_open(device, context);
-	if (rc != DC_STATUS_SUCCESS)
+	if (rc != DC_STATUS_SUCCESS) {
+		dc_device_deallocate((dc_device_t *) device);
 		return rc;
+	}
 
 	// Read ID from the device
 	rc = cochran_read_id((dc_device_t *) device);
@@ -319,7 +316,7 @@ cochran_commander_device_open (dc_device_t **out, dc_context_t *context,
 	if (rc != DC_STATUS_SUCCESS) {
 		ERROR (context, "Device not responding.");
 		serial_close (device->port);
-		free (device);
+		dc_device_deallocate((dc_device_t *) device);
 		return rc;
 	}
 
@@ -336,7 +333,7 @@ cochran_commander_device_open (dc_device_t **out, dc_context_t *context,
 			device->model_string[4], device->model_string[5],
 			device->model_string[6], device->model_string[7]);
 		serial_close (device->port);
-		free (device);
+		dc_device_deallocate((dc_device_t *) device);
 		return DC_STATUS_UNSUPPORTED;
 	}
 
@@ -353,14 +350,12 @@ cochran_commander_device_close (dc_device_t *abstract)
 
 	// Close the device.
 	if (serial_close (device->port) == -1) {
-		free (device);
 		return DC_STATUS_IO;
 	}
 
 	// Free memory.
 	free (device->data.logbook);
 	free (device->data.sample);
-	free (device);
 
 	return DC_STATUS_SUCCESS;
 }
diff --git a/src/cochran_commander_parser.c b/src/cochran_commander_parser.c
index 434d332..bce3cad 100644
--- a/src/cochran_commander_parser.c
+++ b/src/cochran_commander_parser.c
@@ -40,7 +40,6 @@ dc_status_t cochran_commander_parser_get_datetime (dc_parser_t *abstract,
 		dc_datetime_t *datetime);
 static dc_status_t cochran_commander_parser_get_field (dc_parser_t *abstract,
 		dc_field_type_t type, unsigned int flags, void *value);
-dc_status_t cochran_commander_parser_destroy (dc_parser_t *abstract);
 static dc_status_t cochran_commander_parser_samples_foreach
 		(dc_parser_t *abstract, dc_sample_callback_t callback,
 		void *userdata);
@@ -48,14 +47,21 @@ int cochran_commander_handle_event (dc_parser_t *abstract,
 		dc_sample_callback_t callback, void *userdata, unsigned char code,
 		unsigned int offset, unsigned int time);
 
+typedef struct cochran_commander_parser_t cochran_commander_parser_t;
+
+struct cochran_commander_parser_t {
+	dc_parser_t base;
+	cochran_layout_t *layout;
+};
 
 static dc_parser_vtable_t cochran_commander_parser_vtable = {
+	sizeof(cochran_commander_parser_t),
 	DC_FAMILY_COCHRAN_COMMANDER,
 	cochran_commander_parser_set_data,			/* set_data */
 	cochran_commander_parser_get_datetime,		/* datetime */
 	cochran_commander_parser_get_field,		/* fields */
 	cochran_commander_parser_samples_foreach,	/* samples_foreach */
-	cochran_commander_parser_destroy			/* destroy */
+	NULL			/* destroy */
 };
 
 
@@ -63,29 +69,18 @@ static dc_parser_vtable_t cochran_commander_parser_vtable = {
 dc_status_t
 cochran_commander_parser_create (dc_parser_t **out, dc_context_t *context)
 {
+	cochran_commander_parser_t *parser = NULL;
 	if (out == NULL)
 		return DC_STATUS_INVALIDARGS;
 
 	// Allocate memory.
-	dc_parser_t *parser = (dc_parser_t *) malloc (sizeof (dc_parser_t));
+	parser = (cochran_commander_parser_t *) dc_parser_allocate(context, &cochran_commander_parser_vtable);
 	if (parser == NULL) {
 		ERROR (context, "Failed to allocate memory.");
 		return DC_STATUS_NOMEMORY;
 	}
 
-	parser_init (parser, context, &cochran_commander_parser_vtable);
-
-	*out = parser;
-
-	return DC_STATUS_SUCCESS;
-}
-
-
-dc_status_t
-cochran_commander_parser_destroy (dc_parser_t *abstract)
-{
-	// Free memory.
-	free (abstract);
+	*out = (dc_parser_t *) parser;
 
 	return DC_STATUS_SUCCESS;
 }
@@ -95,11 +90,16 @@ dc_status_t
 cochran_commander_parser_set_data (dc_parser_t *abstract,
 		const unsigned char *data, unsigned int size)
 {
+	cochran_commander_parser_t *parser = (cochran_commander_parser_t *) abstract;
 	abstract->data = data;
 	abstract->size = size;
 
+	// Determine cochran data format
+	// abstract->data is prefixed by the model string
+	parser->layout = cochran_commander_get_layout(data);
+
 	return DC_STATUS_SUCCESS;
-}
+} 
 
 
 // There are two date formats used by Cochran
@@ -107,12 +107,11 @@ dc_status_t
 cochran_commander_parser_get_datetime (dc_parser_t *abstract,
 		dc_datetime_t *datetime)
 {
+	cochran_commander_parser_t *parser = (cochran_commander_parser_t *) abstract;
 	const unsigned char *data = abstract->data;
 	const unsigned char *log = data + COCHRAN_MODEL_SIZE;
-	// abstract->data is prefixed by the model string
-	cochran_layout_t *layout = cochran_commander_get_layout(data);
 
-	if (layout->date_format == DATE_SMHDMY) {
+	if (parser->layout->date_format == DATE_SMHDMY) {
 		datetime->second = log[0];
 		datetime->minute = log[1];
 		datetime->hour = log[2];
@@ -135,9 +134,9 @@ static dc_status_t
 cochran_commander_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
 			unsigned int flags, void *value)
 {
-	cochran_layout_t *layout = cochran_commander_get_layout(abstract->data);
+	cochran_commander_parser_t *parser = (cochran_commander_parser_t *) abstract;
 
-	switch (layout->model & 0xFF0000)
+	switch (parser->layout->model & 0xFF0000)
 	{
 	case COCHRAN_MODEL_COMMANDER_FAMILY:
 		return cochran_cmdr_parser_get_field(abstract, type, flags, value);
@@ -154,9 +153,9 @@ static dc_status_t
 cochran_commander_parser_samples_foreach (dc_parser_t *abstract,
 			dc_sample_callback_t callback, void *userdata)
 {
-	cochran_layout_t *layout = cochran_commander_get_layout(abstract->data);
+	cochran_commander_parser_t *parser = (cochran_commander_parser_t *) abstract;
 
-	switch (layout->model & 0xFF0000)
+	switch (parser->layout->model & 0xFF0000)
 	{
 	case COCHRAN_MODEL_COMMANDER_FAMILY:
 		return cochran_cmdr_parser_samples_foreach(abstract, callback,
-- 
2.4.3



More information about the devel mailing list