[PATCH 08/10] Turn serial_ftdi.c into a custom_serial

Anton Lundin glance at acc.umu.se
Thu Aug 20 15:19:44 PDT 2015


This cleans up serial_ftdi.c from being a libdivecomputer source and
making it into a subsurface custom_serial.

Signed-off-by: Anton Lundin <glance at acc.umu.se>
---
 CMakeLists.txt |   2 +
 serial_ftdi.c  | 357 ++++++++++++++++++++++++++++++---------------------------
 2 files changed, 193 insertions(+), 166 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index deec8b3..92f9e94 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -260,6 +260,8 @@ endif()
 if(ANDROID)
 	set(PLATFORM_SRC android.cpp)
 	set(SUBSURFACE_TARGET subsurface)
+	# To allow us to debug log to logcat
+	set(SUBSURFACE_LINK_LIBRARIES ${SUBSURFACE_LINK_LIBRARIES} -llog)
 endif()
 if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
 	set(SUBSURFACE_TARGET Subsurface)
diff --git a/serial_ftdi.c b/serial_ftdi.c
index 065cc88..ab74b9a 100644
--- a/serial_ftdi.c
+++ b/serial_ftdi.c
@@ -2,6 +2,8 @@
  * libdivecomputer
  *
  * Copyright (C) 2008 Jef Driesen
+ * Copyright (C) 2014 Venkatesh Shukla
+ * Copyright (C) 2015 Anton Lundin
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,10 +21,6 @@
  * MA 02110-1301 USA
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #include <stdlib.h> // malloc, free
 #include <string.h>     // strerror
 #include <errno.h>      // errno
@@ -33,20 +31,51 @@
 #include <libusb.h>
 #include <ftdi.h>
 
-#include "serial.h"
-#include "context-private.h"
-
-#define MODEM_DCD 0b10000000
-#define MODEM_RNG 0b01000000
-#define MODEM_DSR 0b00100000
-#define MODEM_CTS 0b00010000
+#ifndef __ANDROID__
+#define INFO(context, fmt, ...)	fprintf(stderr, "INFO: " fmt "\n", ##__VA_ARGS__)
+#define ERROR(context, fmt, ...)	fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__)
+#else
+#include <android/log.h>
+#define INFO(context, fmt, ...)	__android_log_print(ANDROID_LOG_DEBUG, __FILE__, "INFO: " fmt "\n", ##__VA_ARGS__)
+#define ERROR(context, fmt, ...)	__android_log_print(ANDROID_LOG_DEBUG, __FILE__, "ERROR: " fmt "\n", ##__VA_ARGS__)
+#endif
+//#define SYSERROR(context, errcode)	ERROR(__FILE__ ":" __LINE__ ": %s", strerror(errcode))
+#define SYSERROR(context, errcode)	;
+
+#include <libdivecomputer/custom_serial.h>
+
+/* Verbatim copied libdivecomputer enums to support configure */
+typedef enum serial_parity_t {
+	SERIAL_PARITY_NONE,
+	SERIAL_PARITY_EVEN,
+	SERIAL_PARITY_ODD
+} serial_parity_t;
+
+typedef enum serial_flowcontrol_t {
+	SERIAL_FLOWCONTROL_NONE,
+	SERIAL_FLOWCONTROL_HARDWARE,
+	SERIAL_FLOWCONTROL_SOFTWARE
+} serial_flowcontrol_t;
+
+typedef enum serial_queue_t {
+	SERIAL_QUEUE_INPUT = 0x01,
+	SERIAL_QUEUE_OUTPUT = 0x02,
+	SERIAL_QUEUE_BOTH = SERIAL_QUEUE_INPUT | SERIAL_QUEUE_OUTPUT
+} serial_queue_t;
+
+typedef enum serial_line_t {
+	SERIAL_LINE_DCD, // Data carrier detect
+	SERIAL_LINE_CTS, // Clear to send
+	SERIAL_LINE_DSR, // Data set ready
+	SERIAL_LINE_RNG, // Ring indicator
+} serial_line_t;
 
 #define VID 0x0403 // Vendor ID of FTDI
 
 #define MAX_BACKOFF 500 // Max milliseconds to wait before timing out.
 
-struct serial_t {
-	/* Library ftdi_ctx. */
+typedef struct serial_t {
+	/* Library context. */
 	dc_context_t *context;
 	/*
 	 * The file descriptor corresponding to the serial port.
@@ -66,10 +95,55 @@ struct serial_t {
 	int halfduplex;
 	unsigned int baudrate;
 	unsigned int nbits;
-};
+} serial_t;
+
+static int serial_ftdi_get_received (serial_t *device)
+{
+	if (device == NULL)
+		return -1; // EINVAL (Invalid argument)
+
+	// Direct access is not encouraged. But function implementation
+	// is not available. The return quantity might be anything.
+	// Find out further about its possible values and correct way of
+	// access.
+	int bytes = device->ftdi_ctx->readbuffer_remaining;
+
+	return bytes;
+}
+
+static int serial_ftdi_get_transmitted (serial_t *device)
+{
+	if (device == NULL)
+		return -1; // EINVAL (Invalid argument)
+
+	// This is not possible using libftdi. Look further into it.
+	return -1;
+}
+
+static int serial_ftdi_sleep (serial_t *device, unsigned long timeout)
+{
+	if (device == NULL)
+		return -1;
+
+	INFO (device->context, "Sleep: value=%lu", timeout);
+
+	struct timespec ts;
+	ts.tv_sec  = (timeout / 1000);
+	ts.tv_nsec = (timeout % 1000) * 1000000;
+
+	while (nanosleep (&ts, &ts) != 0) {
+		if (errno != EINTR ) {
+			SYSERROR (device->context, errno);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
 
 // Used internally for opening ftdi devices
-int open_ftdi_device (struct ftdi_context *ftdi_ctx)
+static int serial_ftdi_open_device (struct ftdi_context *ftdi_ctx)
 {
 	int accepted_pids[] = { 0x6001, 0x6010, 0x6011, // Suunto (Smart Interface), Heinrichs Weikamp
 		0xF460, // Oceanic
@@ -90,18 +164,13 @@ int open_ftdi_device (struct ftdi_context *ftdi_ctx)
 	return ret;
 }
 
-int serial_enumerate (serial_callback_t callback, void *userdata)
-{
-	// Unimplemented.
-	return -1;
-}
-
-
 //
 // Open the serial port.
 // Initialise ftdi_context and use it to open the device
 //
-int serial_open (serial_t **out, dc_context_t *context, const char* name)
+//FIXME: ugly forward declaration of serial_ftdi_configure, util we support configure for real...
+static dc_status_t serial_ftdi_configure (serial_t *device, int baudrate, int databits, int parity, int stopbits, int flowcontrol);
+static dc_status_t serial_ftdi_open (serial_t **out, dc_context_t *context, const char* name)
 {
 	if (out == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -112,13 +181,13 @@ int serial_open (serial_t **out, dc_context_t *context, const char* name)
 	serial_t *device = (serial_t *) malloc (sizeof (serial_t));
 	if (device == NULL) {
 		SYSERROR (context, errno);
-		return -1; // ENOMEM (Not enough space)
+		return DC_STATUS_NOMEMORY;
 	}
 
 	struct ftdi_context *ftdi_ctx = ftdi_new();
 	if (ftdi_ctx == NULL) {
 		SYSERROR (context, errno);
-		return -1; // ENOMEM (Not enough space)
+		return DC_STATUS_NOMEMORY;
 	}
 
 	// Library context.
@@ -136,35 +205,39 @@ int serial_open (serial_t **out, dc_context_t *context, const char* name)
 	ftdi_init(ftdi_ctx);
 
 	if (ftdi_set_interface(ftdi_ctx,INTERFACE_ANY)) {
-		ERROR (context, ftdi_get_error_string(ftdi_ctx));
-		return -1;
+		ERROR (context, "%s", ftdi_get_error_string(ftdi_ctx));
+		return DC_STATUS_IO;
 	}
 
-	if (open_ftdi_device(ftdi_ctx) < 0) {
-		ERROR (context, ftdi_get_error_string(ftdi_ctx));
-		return -1;
+	if (serial_ftdi_open_device(ftdi_ctx) < 0) {
+		ERROR (context, "%s", ftdi_get_error_string(ftdi_ctx));
+		return DC_STATUS_IO;
 	}
 
 	if (ftdi_usb_reset(ftdi_ctx)) {
-		ERROR (context, ftdi_get_error_string(ftdi_ctx));
-		return -1;
+		ERROR (context, "%s", ftdi_get_error_string(ftdi_ctx));
+		return DC_STATUS_IO;
 	}
 
 	if (ftdi_usb_purge_buffers(ftdi_ctx)) {
-		ERROR (context, ftdi_get_error_string(ftdi_ctx));
-		return -1;
+		ERROR (context, "%s", ftdi_get_error_string(ftdi_ctx));
+		return DC_STATUS_IO;
 	}
 
 	device->ftdi_ctx = ftdi_ctx;
+
+	//FIXME: remove this when custom-serial have support for configure calls
+	serial_ftdi_configure (device, 115200, 8, 0, 1, 0);
+
 	*out = device;
 
-	return 0;
+	return DC_STATUS_SUCCESS;
 }
 
 //
 // Close the serial port.
 //
-int serial_close (serial_t *device)
+static int serial_ftdi_close (serial_t *device)
 {
 	if (device == NULL)
 		return 0;
@@ -190,7 +263,7 @@ int serial_close (serial_t *device)
 //
 // Configure the serial port (baudrate, databits, parity, stopbits and flowcontrol).
 //
-int serial_configure (serial_t *device, int baudrate, int databits, int parity, int stopbits, int flowcontrol)
+static dc_status_t serial_ftdi_configure (serial_t *device, int baudrate, int databits, int parity, int stopbits, int flowcontrol)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -203,7 +276,7 @@ int serial_configure (serial_t *device, int baudrate, int databits, int parity,
 	enum ftdi_parity_type ft_parity;
 
 	if (ftdi_set_baudrate(device->ftdi_ctx, baudrate) < 0) {
-		ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
+		ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
 		return -1;
 	}
 
@@ -216,7 +289,7 @@ int serial_configure (serial_t *device, int baudrate, int databits, int parity,
 		ft_bits = BITS_8;
 		break;
 	default:
-		return -1;
+		return DC_STATUS_INVALIDARGS;
 	}
 
 	// Set the parity type.
@@ -231,8 +304,7 @@ int serial_configure (serial_t *device, int baudrate, int databits, int parity,
 		ft_parity = ODD;
 		break;
 	default:
-
-		return -1;
+		return DC_STATUS_INVALIDARGS;
 	}
 
 	// Set the number of stop bits.
@@ -244,49 +316,49 @@ int serial_configure (serial_t *device, int baudrate, int databits, int parity,
 		ft_stopbits = STOP_BIT_2;
 		break;
 	default:
-		return -1;
+		return DC_STATUS_INVALIDARGS;
 	}
 
 	// Set the attributes
 	if (ftdi_set_line_property(device->ftdi_ctx, ft_bits, ft_stopbits, ft_parity)) {
-		ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
-		return -1;
+		ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
+		return DC_STATUS_IO;
 	}
 
 	// Set the flow control.
 	switch (flowcontrol) {
 	case SERIAL_FLOWCONTROL_NONE: // No flow control.
 		if (ftdi_setflowctrl(device->ftdi_ctx, SIO_DISABLE_FLOW_CTRL) < 0) {
-			ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
-			return -1;
+			ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
+			return DC_STATUS_IO;
 		}
 		break;
 	case SERIAL_FLOWCONTROL_HARDWARE: // Hardware (RTS/CTS) flow control.
 		if (ftdi_setflowctrl(device->ftdi_ctx, SIO_RTS_CTS_HS) < 0) {
-			ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
-			return -1;
+			ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
+			return DC_STATUS_IO;
 		}
 		break;
 	case SERIAL_FLOWCONTROL_SOFTWARE: // Software (XON/XOFF) flow control.
 		if (ftdi_setflowctrl(device->ftdi_ctx, SIO_XON_XOFF_HS) < 0) {
-			ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
-			return -1;
+			ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
+			return DC_STATUS_IO;
 		}
 		break;
 	default:
-		return -1;
+		return DC_STATUS_INVALIDARGS;
 	}
 
 	device->baudrate = baudrate;
 	device->nbits = 1 + databits + stopbits + (parity ? 1 : 0);
 
-	return 0;
+	return DC_STATUS_SUCCESS;
 }
 
 //
 // Configure the serial port (timeouts).
 //
-int serial_set_timeout (serial_t *device, long timeout)
+static int serial_ftdi_set_timeout (serial_t *device, long timeout)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -298,22 +370,7 @@ int serial_set_timeout (serial_t *device, long timeout)
 	return 0;
 }
 
-
-//
-// Configure the serial port (recommended size of the input/output buffers).
-//
-int serial_set_queue_size (serial_t *device, unsigned int input, unsigned int output)
-{
-	if (device == NULL)
-		return -1; // ERROR_INVALID_PARAMETER (The parameter is incorrect)
-
-	ftdi_read_data_set_chunksize(device->ftdi_ctx, output);
-	ftdi_write_data_set_chunksize(device->ftdi_ctx, input);
-
-	return 0;
-}
-
-int serial_set_halfduplex (serial_t *device, int value)
+static int serial_ftdi_set_halfduplex (serial_t *device, int value)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -326,22 +383,7 @@ int serial_set_halfduplex (serial_t *device, int value)
 	return 0;
 }
 
-int serial_set_latency (serial_t *device, unsigned int milliseconds)
-{
-	if (device == NULL)
-		return -1; // EINVAL (Invalid argument)
-
-	// Default for ftdi device is 16ms and can be set in the range
-	// 1 - 255 ms with 1ms least count.
-
-	if (milliseconds < 1 || milliseconds > 255)
-		return -1;
-	ftdi_set_latency_timer(device->ftdi_ctx, milliseconds);
-
-	return 0;
-}
-
-int serial_read (serial_t *device, void *data, unsigned int size)
+static int serial_ftdi_read (serial_t *device, void *data, unsigned int size)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -386,15 +428,15 @@ int serial_read (serial_t *device, void *data, unsigned int size)
 		if (n < 0) {
 			if (n == LIBUSB_ERROR_INTERRUPTED)
 				continue; //Retry.
-			ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
+			ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
 			return -1; //Error during read call.
 		} else if (n == 0) {
 			// Exponential backoff.
 			if (backoff > MAX_BACKOFF) {
-				ERROR(device->context, "FTDI read timed out.");
+				ERROR(device->context, "%s", "FTDI read timed out.");
 				return -1;
 			}
-			serial_sleep(device, backoff);
+			serial_ftdi_sleep (device, backoff);
 			backoff *= 2;
 		} else {
 			// Reset backoff to 1 on success.
@@ -404,12 +446,12 @@ int serial_read (serial_t *device, void *data, unsigned int size)
 		nbytes += n;
 	}
 
-	HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Read", (unsigned char *) data, nbytes);
+	INFO (device->context, "Read %d bytes", nbytes);
 
 	return nbytes;
 }
 
-int serial_write (serial_t *device, const void *data, unsigned int size)
+static int serial_ftdi_write (serial_t *device, const void *data, unsigned int size)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -430,7 +472,7 @@ int serial_write (serial_t *device, const void *data, unsigned int size)
 		if (n < 0) {
 			if (n == LIBUSB_ERROR_INTERRUPTED)
 				continue; // Retry.
-			ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
+			ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
 			return -1; // Error during write call.
 		} else if (n == 0) {
 			break; // EOF.
@@ -462,40 +504,40 @@ int serial_write (serial_t *device, const void *data, unsigned int size)
 			// The remaining time is rounded up to the nearest millisecond to
 			// match the Windows implementation. The higher resolution is
 			// pointless anyway, since we already added a fudge factor above.
-			serial_sleep (device, (remaining + 999) / 1000);
+			serial_ftdi_sleep (device, (remaining + 999) / 1000);
 		}
 	}
 
-	HEXDUMP (device->context, DC_LOGLEVEL_INFO, "Write", (unsigned char *) data, nbytes);
+	INFO (device->context, "Wrote %d bytes", nbytes);
 
 	return nbytes;
 }
 
-int serial_flush (serial_t *device, int queue)
+static int serial_ftdi_flush (serial_t *device, int queue)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
 
 	INFO (device->context, "Flush: queue=%u, input=%i, output=%i", queue,
-	      serial_get_received (device),
-	      serial_get_transmitted (device));
+	      serial_ftdi_get_received (device),
+	      serial_ftdi_get_transmitted (device));
 
 	switch (queue) {
 	case SERIAL_QUEUE_INPUT:
 		if (ftdi_usb_purge_tx_buffer(device->ftdi_ctx)) {
-			ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
+			ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
 			return -1;
 		}
 		break;
 	case SERIAL_QUEUE_OUTPUT:
 		if (ftdi_usb_purge_rx_buffer(device->ftdi_ctx)) {
-			ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
+			ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
 			return -1;
 		}
 		break;
 	default:
 		if (ftdi_usb_purge_buffers(device->ftdi_ctx)) {
-			ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
+			ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
 			return -1;
 		}
 		break;
@@ -504,7 +546,7 @@ int serial_flush (serial_t *device, int queue)
 	return 0;
 }
 
-int serial_send_break (serial_t *device)
+static int serial_ftdi_send_break (serial_t *device)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)a
@@ -519,7 +561,7 @@ int serial_send_break (serial_t *device)
 	return -1;
 }
 
-int serial_set_break (serial_t *device, int level)
+static int serial_ftdi_set_break (serial_t *device, int level)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -531,7 +573,7 @@ int serial_set_break (serial_t *device, int level)
 	return -1;
 }
 
-int serial_set_dtr (serial_t *device, int level)
+static int serial_ftdi_set_dtr (serial_t *device, int level)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -539,14 +581,14 @@ int serial_set_dtr (serial_t *device, int level)
 	INFO (device->context, "DTR: value=%i", level);
 
 	if (ftdi_setdtr(device->ftdi_ctx, level)) {
-		ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
+		ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
 		return -1;
 	}
 
 	return 0;
 }
 
-int serial_set_rts (serial_t *device, int level)
+static int serial_ftdi_set_rts (serial_t *device, int level)
 {
 	if (device == NULL)
 		return -1; // EINVAL (Invalid argument)
@@ -554,82 +596,65 @@ int serial_set_rts (serial_t *device, int level)
 	INFO (device->context, "RTS: value=%i", level);
 
 	if (ftdi_setrts(device->ftdi_ctx, level)) {
-		ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
+		ERROR (device->context, "%s", ftdi_get_error_string(device->ftdi_ctx));
 		return -1;
 	}
 
 	return 0;
 }
 
-int serial_get_received (serial_t *device)
-{
-	if (device == NULL)
-		return -1; // EINVAL (Invalid argument)
-
-	// Direct access is not encouraged. But function implementation
-	// is not available. The return quantity might be anything.
-	// Find out further about its possible values and correct way of
-	// access.
-	int bytes = device->ftdi_ctx->readbuffer_remaining;
-
-	return bytes;
-}
-
-int serial_get_transmitted (serial_t *device)
-{
-	if (device == NULL)
-		return -1; // EINVAL (Invalid argument)
-
-	// This is not possible using libftdi. Look further into it.
-	return -1;
-}
+const dc_serial_operations_t serial_ftdi_ops = {
+	.open = serial_ftdi_open,
+	.close = serial_ftdi_close,
+	.read = serial_ftdi_read,
+	.write = serial_ftdi_write,
+	.flush = serial_ftdi_flush,
+	.get_received = serial_ftdi_get_received,
+	.get_transmitted = NULL, /*NOT USED ANYWHERE! serial_ftdi_get_transmitted  */
+	.set_timeout = serial_ftdi_set_timeout
+#ifdef FIXED_SSRF_CUSTOM_SERIAL
+	,
+	.configure = serial_ftdi_configure,
+//static int serial_ftdi_configure (serial_t *device, int baudrate, int databits, int parity, int stopbits, int flowcontrol)
+	.set_halfduplex = serial_ftdi_set_halfduplex,
+//static int serial_ftdi_set_halfduplex (serial_t *device, int value)
+	.send_break = serial_ftdi_send_break,
+//static int serial_ftdi_send_break (serial_t *device)
+	.set_break = serial_ftdi_set_break,
+//static int serial_ftdi_set_break (serial_t *device, int level)
+	.set_dtr = serial_ftdi_set_dtr,
+//static int serial_ftdi_set_dtr (serial_t *device, int level)
+	.set_rts = serial_ftdi_set_rts
+//static int serial_ftdi_set_rts (serial_t *device, int level)
+#endif
+};
 
-int serial_get_line (serial_t *device, int line)
+dc_status_t dc_serial_ftdi_open(dc_serial_t **out, dc_context_t *context)
 {
-	if (device == NULL)
-		return -1; // EINVAL (Invalid argument)
-
-	unsigned short int status[2] = {0};
+	if (out == NULL)
+		return DC_STATUS_INVALIDARGS;
 
-	if(ftdi_poll_modem_status(device->ftdi_ctx, status)) {
-		ERROR (device->context, ftdi_get_error_string(device->ftdi_ctx));
-		return -1;
-	}
+	// Allocate memory.
+	dc_serial_t *serial_device = (dc_serial_t *) malloc (sizeof (dc_serial_t));
 
-	switch (line) {
-	case SERIAL_LINE_DCD:
-		return (status[0] & MODEM_DCD) == MODEM_DCD;
-	case SERIAL_LINE_CTS:
-		return (status[0] & MODEM_CTS) == MODEM_CTS;
-	case SERIAL_LINE_DSR:
-		return (status[0] & MODEM_DSR) == MODEM_DSR;
-	case SERIAL_LINE_RNG:
-		return (status[0] & MODEM_RNG) == MODEM_RNG;
-	default:
-		return -1;
+	if (serial_device == NULL) {
+		return DC_STATUS_NOMEMORY;
 	}
 
-	return 0;
-}
-
-int serial_sleep (serial_t *device, unsigned long timeout)
-{
-	if (device == NULL)
-		return -1;
+	// Initialize data and function pointers
+	dc_serial_init(serial_device, NULL, &serial_ftdi_ops);
 
-	INFO (device->context, "Sleep: value=%lu", timeout);
-
-	struct timespec ts;
-	ts.tv_sec  = (timeout / 1000);
-	ts.tv_nsec = (timeout % 1000) * 1000000;
-
-	while (nanosleep (&ts, &ts) != 0) {
-		if (errno != EINTR ) {
-			SYSERROR (device->context, errno);
-			return -1;
-		}
+	// Open the serial device.
+	dc_status_t rc = (dc_status_t) serial_ftdi_open (&serial_device->port, context, NULL);
+	if (rc != DC_STATUS_SUCCESS) {
+		free (serial_device);
+		return rc;
 	}
 
+	// Set the type of the device
+	serial_device->type = DC_TRANSPORT_USB;;
 
-	return 0;
+	*out = serial_device;
+
+	return DC_STATUS_SUCCESS;
 }
-- 
2.1.4



More information about the subsurface mailing list