From c50958495dd2b0f99aa621cc65007c60c747d9f9 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 21 Apr 2017 21:32:15 +0200 Subject: [PATCH] Update the example application The dctool example application is updated to the latest changes: - The I/O stream is opened and closed by the application. - A new (mandatory) option is added to select the desired transport type. This is nessecary because several dive computers support multiple transport types now. --- examples/common.c | 190 +++++++++++++++++++++++++++++++++++++ examples/common.h | 10 ++ examples/dctool_download.c | 38 ++++++-- examples/dctool_dump.c | 38 ++++++-- examples/dctool_fwupdate.c | 38 ++++++-- examples/dctool_read.c | 38 ++++++-- examples/dctool_timesync.c | 39 ++++++-- examples/dctool_write.c | 38 ++++++-- 8 files changed, 385 insertions(+), 44 deletions(-) diff --git a/examples/common.c b/examples/common.c index 1024fde..bda07f2 100644 --- a/examples/common.c +++ b/examples/common.c @@ -19,6 +19,7 @@ * MA 02110-1301 USA */ +#include #include #include @@ -27,6 +28,11 @@ #include #endif +#include +#include +#include +#include + #include "common.h" #include "utils.h" @@ -44,6 +50,11 @@ typedef struct backend_table_t { unsigned int model; } backend_table_t; +typedef struct transport_table_t { + const char *name; + dc_transport_t type; +} transport_table_t; + static const backend_table_t g_backends[] = { {"solution", DC_FAMILY_SUUNTO_SOLUTION, 0}, {"eon", DC_FAMILY_SUUNTO_EON, 0}, @@ -81,6 +92,14 @@ static const backend_table_t g_backends[] = { {"cochran", DC_FAMILY_COCHRAN_COMMANDER, 0}, }; +static const transport_table_t g_transports[] = { + {"serial", DC_TRANSPORT_SERIAL}, + {"usb", DC_TRANSPORT_USB}, + {"usbhid", DC_TRANSPORT_USBHID}, + {"irda", DC_TRANSPORT_IRDA}, + {"bluetooth", DC_TRANSPORT_BLUETOOTH}, +}; + const char * dctool_errmsg (dc_status_t status) { @@ -145,6 +164,28 @@ dctool_family_model (dc_family_t type) return 0; } +dc_transport_t +dctool_transport_type (const char *name) +{ + for (size_t i = 0; i < C_ARRAY_SIZE (g_transports); ++i) { + if (strcmp (name, g_transports[i].name) == 0) + return g_transports[i].type; + } + + return DC_TRANSPORT_NONE; +} + +const char * +dctool_transport_name (dc_transport_t type) +{ + for (size_t i = 0; i < C_ARRAY_SIZE (g_transports); ++i) { + if (g_transports[i].type == type) + return g_transports[i].name; + } + + return NULL; +} + void dctool_event_cb (dc_device_t *device, dc_event_type_t event, const void *data, void *userdata) { @@ -340,3 +381,152 @@ dctool_file_read (const char *filename) return buffer; } + +static dc_status_t +dctool_usbhid_open (dc_iostream_t **out, dc_context_t *context, dc_descriptor_t *descriptor) +{ + dc_status_t status = DC_STATUS_SUCCESS; + dc_iostream_t *iostream = NULL; + unsigned int vid = 0, pid = 0; + + // Discover the usbhid device. + dc_iterator_t *iterator = NULL; + dc_usbhid_device_t *device = NULL; + dc_usbhid_iterator_new (&iterator, context, descriptor); + while (dc_iterator_next (iterator, &device) == DC_STATUS_SUCCESS) { + vid = dc_usbhid_device_get_vid (device); + pid = dc_usbhid_device_get_pid (device); + dc_usbhid_device_free (device); + break; + } + dc_iterator_free (iterator); + + if (vid == 0 && pid == 0) { + ERROR ("No dive computer found."); + status = DC_STATUS_NODEVICE; + goto cleanup; + } + + // Open the usbhid device. + status = dc_usbhid_open (&iostream, context, vid, pid); + if (status != DC_STATUS_SUCCESS) { + ERROR ("Failed to open the usbhid device."); + goto cleanup; + } + + *out = iostream; + +cleanup: + return status; +} + +static dc_status_t +dctool_irda_open (dc_iostream_t **out, dc_context_t *context, dc_descriptor_t *descriptor, const char *devname) +{ + dc_status_t status = DC_STATUS_SUCCESS; + dc_iostream_t *iostream = NULL; + unsigned int address = 0; + + if (devname) { + // Use the address. + address = strtoul(devname, NULL, 0); + } else { + // Discover the device address. + dc_iterator_t *iterator = NULL; + dc_irda_device_t *device = NULL; + dc_irda_iterator_new (&iterator, context, descriptor); + while (dc_iterator_next (iterator, &device) == DC_STATUS_SUCCESS) { + address = dc_irda_device_get_address (device); + dc_irda_device_free (device); + break; + } + dc_iterator_free (iterator); + } + + if (address == 0) { + if (devname) { + ERROR ("No valid device address specified."); + } else { + ERROR ("No dive computer found."); + } + status = DC_STATUS_NODEVICE; + goto cleanup; + } + + // Open the irda socket. + status = dc_irda_open (&iostream, context, address, 1); + if (status != DC_STATUS_SUCCESS) { + ERROR ("Failed to open the irda socket."); + goto cleanup; + } + + *out = iostream; + +cleanup: + return status; +} + +static dc_status_t +dctool_bluetooth_open (dc_iostream_t **out, dc_context_t *context, dc_descriptor_t *descriptor, const char *devname) +{ + dc_status_t status = DC_STATUS_SUCCESS; + dc_iostream_t *iostream = NULL; + dc_bluetooth_address_t address = 0; + + if (devname) { + // Use the address. + address = dc_bluetooth_str2addr(devname); + } else { + // Discover the device address. + dc_iterator_t *iterator = NULL; + dc_bluetooth_device_t *device = NULL; + dc_bluetooth_iterator_new (&iterator, context, descriptor); + while (dc_iterator_next (iterator, &device) == DC_STATUS_SUCCESS) { + address = dc_bluetooth_device_get_address (device); + dc_bluetooth_device_free (device); + break; + } + dc_iterator_free (iterator); + } + + if (address == 0) { + if (devname) { + ERROR ("No valid device address specified."); + } else { + ERROR ("No dive computer found."); + } + status = DC_STATUS_NODEVICE; + goto cleanup; + } + + // Open the bluetooth socket. + status = dc_bluetooth_open (&iostream, context, address, 0); + if (status != DC_STATUS_SUCCESS) { + ERROR ("Failed to open the bluetooth socket."); + goto cleanup; + } + + *out = iostream; + +cleanup: + return status; +} + +dc_status_t +dctool_iostream_open (dc_iostream_t **iostream, dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname) +{ + switch (transport) { + case DC_TRANSPORT_SERIAL: + return dc_serial_open (iostream, context, devname); + case DC_TRANSPORT_USB: + return DC_STATUS_SUCCESS; + case DC_TRANSPORT_USBHID: + return dctool_usbhid_open(iostream, context, descriptor); + case DC_TRANSPORT_IRDA: + return dctool_irda_open (iostream, context, descriptor, devname); + case DC_TRANSPORT_BLUETOOTH: + return dctool_bluetooth_open (iostream, context, descriptor, devname); + default: + return DC_STATUS_UNSUPPORTED; + } +} diff --git a/examples/common.h b/examples/common.h index edb7872..6f79402 100644 --- a/examples/common.h +++ b/examples/common.h @@ -24,6 +24,7 @@ #include #include +#include #include #ifdef __cplusplus @@ -42,6 +43,12 @@ dctool_family_name (dc_family_t type); unsigned int dctool_family_model (dc_family_t type); +dc_transport_t +dctool_transport_type (const char *name); + +const char * +dctool_transport_name (dc_transport_t type); + void dctool_event_cb (dc_device_t *device, dc_event_type_t event, const void *data, void *userdata); @@ -57,6 +64,9 @@ dctool_file_write (const char *filename, dc_buffer_t *buffer); dc_buffer_t * dctool_file_read (const char *filename); +dc_status_t +dctool_iostream_open (dc_iostream_t **iostream, dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/examples/dctool_download.c b/examples/dctool_download.c index 56f36b1..6a6ccc0 100644 --- a/examples/dctool_download.c +++ b/examples/dctool_download.c @@ -152,18 +152,27 @@ event_cb (dc_device_t *device, dc_event_type_t event, const void *data, void *us } static dc_status_t -download (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname, const char *cachedir, dc_buffer_t *fingerprint, dctool_output_t *output) +download (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname, const char *cachedir, dc_buffer_t *fingerprint, dctool_output_t *output) { dc_status_t rc = DC_STATUS_SUCCESS; dc_iostream_t *iostream = NULL; dc_device_t *device = NULL; dc_buffer_t *ofingerprint = NULL; - // Open the device. - message ("Opening the device (%s %s, %s).\n", - dc_descriptor_get_vendor (descriptor), - dc_descriptor_get_product (descriptor), + // Open the I/O stream. + message ("Opening the I/O stream (%s, %s).\n", + dctool_transport_name (transport), devname ? devname : "null"); + rc = dctool_iostream_open (&iostream, context, descriptor, transport, devname); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error opening the I/O stream."); + goto cleanup; + } + + // Open the device. + message ("Opening the device (%s %s).\n", + dc_descriptor_get_vendor (descriptor), + dc_descriptor_get_product (descriptor)); rc = dc_device_open (&device, context, descriptor, iostream); if (rc != DC_STATUS_SUCCESS) { ERROR ("Error opening the device."); @@ -237,6 +246,7 @@ download (dc_context_t *context, dc_descriptor_t *descriptor, const char *devnam cleanup: dc_buffer_free (ofingerprint); dc_device_close (device); + dc_iostream_close (iostream); return rc; } @@ -248,6 +258,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto dc_buffer_t *fingerprint = NULL; dctool_output_t *output = NULL; dctool_units_t units = DCTOOL_UNITS_METRIC; + dc_transport_t transport = DC_TRANSPORT_NONE; // Default option values. unsigned int help = 0; @@ -258,10 +269,11 @@ 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:u:"; + const char *optstring = "ht:o:p:c:f:u:"; #ifdef HAVE_GETOPT_LONG struct option options[] = { {"help", no_argument, 0, 'h'}, + {"transport", required_argument, 0, 't'}, {"output", required_argument, 0, 'o'}, {"fingerprint", required_argument, 0, 'p'}, {"cache", required_argument, 0, 'c'}, @@ -277,6 +289,9 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto case 'h': help = 1; break; + case 't': + transport = dctool_transport_type (optarg); + break; case 'o': filename = optarg; break; @@ -309,6 +324,13 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto return EXIT_SUCCESS; } + // Check the transport type. + if (transport == DC_TRANSPORT_NONE) { + message ("No valid transport type specified.\n"); + exitcode = EXIT_FAILURE; + goto cleanup; + } + // Convert the fingerprint to binary. fingerprint = dctool_convert_hex2bin (fphex); @@ -329,7 +351,7 @@ dctool_download_run (int argc, char *argv[], dc_context_t *context, dc_descripto } // Download the dives. - status = download (context, descriptor, argv[0], cachedir, fingerprint, output); + status = download (context, descriptor, transport, argv[0], cachedir, fingerprint, output); if (status != DC_STATUS_SUCCESS) { message ("ERROR: %s\n", dctool_errmsg (status)); exitcode = EXIT_FAILURE; @@ -353,6 +375,7 @@ const dctool_command_t dctool_download = { "Options:\n" #ifdef HAVE_GETOPT_LONG " -h, --help Show help message\n" + " -t, --transport Transport type\n" " -o, --output Output filename\n" " -p, --fingerprint Fingerprint data (hexadecimal)\n" " -c, --cache Cache directory\n" @@ -360,6 +383,7 @@ const dctool_command_t dctool_download = { " -u, --units Set units (metric or imperial)\n" #else " -h Show help message\n" + " -t Transport type\n" " -o Output filename\n" " -p Fingerprint data (hexadecimal)\n" " -c Cache directory\n" diff --git a/examples/dctool_dump.c b/examples/dctool_dump.c index 26450f4..90c4105 100644 --- a/examples/dctool_dump.c +++ b/examples/dctool_dump.c @@ -40,17 +40,26 @@ #include "utils.h" static dc_status_t -dump (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname, dc_buffer_t *fingerprint, dc_buffer_t *buffer) +dump (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname, dc_buffer_t *fingerprint, dc_buffer_t *buffer) { dc_status_t rc = DC_STATUS_SUCCESS; dc_iostream_t *iostream = NULL; dc_device_t *device = NULL; - // Open the device. - message ("Opening the device (%s %s, %s).\n", - dc_descriptor_get_vendor (descriptor), - dc_descriptor_get_product (descriptor), + // Open the I/O stream. + message ("Opening the I/O stream (%s, %s).\n", + dctool_transport_name (transport), devname ? devname : "null"); + rc = dctool_iostream_open (&iostream, context, descriptor, transport, devname); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error opening the I/O stream."); + goto cleanup; + } + + // Open the device. + message ("Opening the device (%s %s).\n", + dc_descriptor_get_vendor (descriptor), + dc_descriptor_get_product (descriptor)); rc = dc_device_open (&device, context, descriptor, iostream); if (rc != DC_STATUS_SUCCESS) { ERROR ("Error opening the device."); @@ -94,6 +103,7 @@ dump (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname, d cleanup: dc_device_close (device); + dc_iostream_close (iostream); return rc; } @@ -104,6 +114,7 @@ dctool_dump_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t dc_status_t status = DC_STATUS_SUCCESS; dc_buffer_t *fingerprint = NULL; dc_buffer_t *buffer = NULL; + dc_transport_t transport = DC_TRANSPORT_NONE; // Default option values. unsigned int help = 0; @@ -112,10 +123,11 @@ dctool_dump_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t // Parse the command-line options. int opt = 0; - const char *optstring = "ho:p:"; + const char *optstring = "ht:o:p:"; #ifdef HAVE_GETOPT_LONG struct option options[] = { {"help", no_argument, 0, 'h'}, + {"transport", required_argument, 0, 't'}, {"output", required_argument, 0, 'o'}, {"fingerprint", required_argument, 0, 'p'}, {0, 0, 0, 0 } @@ -128,6 +140,9 @@ dctool_dump_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t case 'h': help = 1; break; + case 't': + transport = dctool_transport_type (optarg); + break; case 'o': filename = optarg; break; @@ -148,6 +163,13 @@ dctool_dump_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t return EXIT_SUCCESS; } + // Check the transport type. + if (transport == DC_TRANSPORT_NONE) { + message ("No valid transport type specified.\n"); + exitcode = EXIT_FAILURE; + goto cleanup; + } + // Convert the fingerprint to binary. fingerprint = dctool_convert_hex2bin (fphex); @@ -155,7 +177,7 @@ dctool_dump_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t buffer = dc_buffer_new (0); // Download the memory dump. - status = dump (context, descriptor, argv[0], fingerprint, buffer); + status = dump (context, descriptor, transport, argv[0], fingerprint, buffer); if (status != DC_STATUS_SUCCESS) { message ("ERROR: %s\n", dctool_errmsg (status)); exitcode = EXIT_FAILURE; @@ -182,10 +204,12 @@ const dctool_command_t dctool_dump = { "Options:\n" #ifdef HAVE_GETOPT_LONG " -h, --help Show help message\n" + " -t, --transport Transport type\n" " -o, --output Output filename\n" " -p, --fingerprint Fingerprint data (hexadecimal)\n" #else " -h Show help message\n" + " -t Transport type\n" " -o Output filename\n" " -p Fingerprint data (hexadecimal)\n" #endif diff --git a/examples/dctool_fwupdate.c b/examples/dctool_fwupdate.c index 022724e..acecb3e 100644 --- a/examples/dctool_fwupdate.c +++ b/examples/dctool_fwupdate.c @@ -41,17 +41,26 @@ #include "utils.h" static dc_status_t -fwupdate (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname, const char *hexfile) +fwupdate (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname, const char *hexfile) { dc_status_t rc = DC_STATUS_SUCCESS; dc_iostream_t *iostream = NULL; dc_device_t *device = NULL; - // Open the device. - message ("Opening the device (%s %s, %s).\n", - dc_descriptor_get_vendor (descriptor), - dc_descriptor_get_product (descriptor), + // Open the I/O stream. + message ("Opening the I/O stream (%s, %s).\n", + dctool_transport_name (transport), devname ? devname : "null"); + rc = dctool_iostream_open (&iostream, context, descriptor, transport, devname); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error opening the I/O stream."); + goto cleanup; + } + + // Open the device. + message ("Opening the device (%s %s).\n", + dc_descriptor_get_vendor (descriptor), + dc_descriptor_get_product (descriptor)); rc = dc_device_open (&device, context, descriptor, iostream); if (rc != DC_STATUS_SUCCESS) { ERROR ("Error opening the device."); @@ -95,6 +104,7 @@ fwupdate (dc_context_t *context, dc_descriptor_t *descriptor, const char *devnam cleanup: dc_device_close (device); + dc_iostream_close (iostream); return rc; } @@ -103,6 +113,7 @@ dctool_fwupdate_run (int argc, char *argv[], dc_context_t *context, dc_descripto { int exitcode = EXIT_SUCCESS; dc_status_t status = DC_STATUS_SUCCESS; + dc_transport_t transport = DC_TRANSPORT_NONE; // Default option values. unsigned int help = 0; @@ -110,10 +121,11 @@ dctool_fwupdate_run (int argc, char *argv[], dc_context_t *context, dc_descripto // Parse the command-line options. int opt = 0; - const char *optstring = "hf:"; + const char *optstring = "ht:f:"; #ifdef HAVE_GETOPT_LONG struct option options[] = { {"help", no_argument, 0, 'h'}, + {"transport", required_argument, 0, 't'}, {"firmware", required_argument, 0, 'f'}, {0, 0, 0, 0 } }; @@ -125,6 +137,9 @@ dctool_fwupdate_run (int argc, char *argv[], dc_context_t *context, dc_descripto case 'f': filename = optarg; break; + case 't': + transport = dctool_transport_type (optarg); + break; case 'h': help = 1; break; @@ -142,6 +157,13 @@ dctool_fwupdate_run (int argc, char *argv[], dc_context_t *context, dc_descripto return EXIT_SUCCESS; } + // Check the transport type. + if (transport == DC_TRANSPORT_NONE) { + message ("No valid transport type specified.\n"); + exitcode = EXIT_FAILURE; + goto cleanup; + } + // Check mandatory arguments. if (!filename) { message ("No firmware file specified.\n"); @@ -150,7 +172,7 @@ dctool_fwupdate_run (int argc, char *argv[], dc_context_t *context, dc_descripto } // Update the firmware. - status = fwupdate (context, descriptor, argv[0], filename); + status = fwupdate (context, descriptor, transport, argv[0], filename); if (status != DC_STATUS_SUCCESS) { message ("ERROR: %s\n", dctool_errmsg (status)); exitcode = EXIT_FAILURE; @@ -172,9 +194,11 @@ const dctool_command_t dctool_fwupdate = { "Options:\n" #ifdef HAVE_GETOPT_LONG " -h, --help Show help message\n" + " -t, --transport Transport type\n" " -f, --firmware Firmware filename\n" #else " -h Show help message\n" + " -t Transport type\n" " -f Firmware filename\n" #endif }; diff --git a/examples/dctool_read.c b/examples/dctool_read.c index 4e71660..769b7c6 100644 --- a/examples/dctool_read.c +++ b/examples/dctool_read.c @@ -39,17 +39,26 @@ #include "utils.h" static dc_status_t -doread (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname, unsigned int address, dc_buffer_t *buffer) +doread (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname, unsigned int address, dc_buffer_t *buffer) { dc_status_t rc = DC_STATUS_SUCCESS; dc_iostream_t *iostream = NULL; dc_device_t *device = NULL; - // Open the device. - message ("Opening the device (%s %s, %s).\n", - dc_descriptor_get_vendor (descriptor), - dc_descriptor_get_product (descriptor), + // Open the I/O stream. + message ("Opening the I/O stream (%s, %s).\n", + dctool_transport_name (transport), devname ? devname : "null"); + rc = dctool_iostream_open (&iostream, context, descriptor, transport, devname); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error opening the I/O stream."); + goto cleanup; + } + + // Open the device. + message ("Opening the device (%s %s).\n", + dc_descriptor_get_vendor (descriptor), + dc_descriptor_get_product (descriptor)); rc = dc_device_open (&device, context, descriptor, iostream); if (rc != DC_STATUS_SUCCESS) { ERROR ("Error opening the device."); @@ -83,6 +92,7 @@ doread (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname, cleanup: dc_device_close (device); + dc_iostream_close (iostream); return rc; } @@ -92,6 +102,7 @@ dctool_read_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t int exitcode = EXIT_SUCCESS; dc_status_t status = DC_STATUS_SUCCESS; dc_buffer_t *buffer = NULL; + dc_transport_t transport = DC_TRANSPORT_NONE; // Default option values. unsigned int help = 0; @@ -101,10 +112,11 @@ dctool_read_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t // Parse the command-line options. int opt = 0; - const char *optstring = "ha:c:o:"; + const char *optstring = "ht:a:c:o:"; #ifdef HAVE_GETOPT_LONG struct option options[] = { {"help", no_argument, 0, 'h'}, + {"transport", required_argument, 0, 't'}, {"address", required_argument, 0, 'a'}, {"count", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, @@ -118,6 +130,9 @@ dctool_read_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t case 'h': help = 1; break; + case 't': + transport = dctool_transport_type (optarg); + break; case 'a': address = strtoul (optarg, NULL, 0); have_address = 1; @@ -143,6 +158,13 @@ dctool_read_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t return EXIT_SUCCESS; } + // Check the transport type. + if (transport == DC_TRANSPORT_NONE) { + message ("No valid transport type specified.\n"); + exitcode = EXIT_FAILURE; + goto cleanup; + } + // Check mandatory arguments. if (!have_address || !have_count) { message ("No memory address or byte count specified.\n"); @@ -160,7 +182,7 @@ dctool_read_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t } // Read data from the internal memory. - status = doread (context, descriptor, argv[0], address, buffer); + status = doread (context, descriptor, transport, argv[0], address, buffer); if (status != DC_STATUS_SUCCESS) { message ("ERROR: %s\n", dctool_errmsg (status)); exitcode = EXIT_FAILURE; @@ -186,11 +208,13 @@ const dctool_command_t dctool_read = { "Options:\n" #ifdef HAVE_GETOPT_LONG " -h, --help Show help message\n" + " -t, --transport Transport type\n" " -a, --address
Memory address\n" " -c, --count Number of bytes\n" " -o, --output Output filename\n" #else " -h Show help message\n" + " -t Transport type\n" " -a
Memory address\n" " -c Number of bytes\n" " -o Output filename\n" diff --git a/examples/dctool_timesync.c b/examples/dctool_timesync.c index 6ef42ff..c0384e4 100644 --- a/examples/dctool_timesync.c +++ b/examples/dctool_timesync.c @@ -39,17 +39,26 @@ #include "utils.h" static dc_status_t -do_timesync (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname, const dc_datetime_t *datetime) +do_timesync (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname, const dc_datetime_t *datetime) { dc_status_t rc = DC_STATUS_SUCCESS; dc_iostream_t *iostream = NULL; dc_device_t *device = NULL; - // Open the device. - message ("Opening the device (%s %s, %s).\n", - dc_descriptor_get_vendor (descriptor), - dc_descriptor_get_product (descriptor), + // Open the I/O stream. + message ("Opening the I/O stream (%s, %s).\n", + dctool_transport_name (transport), devname ? devname : "null"); + rc = dctool_iostream_open (&iostream, context, descriptor, transport, devname); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error opening the I/O stream."); + goto cleanup; + } + + // Open the device. + message ("Opening the device (%s %s).\n", + dc_descriptor_get_vendor (descriptor), + dc_descriptor_get_product (descriptor)); rc = dc_device_open (&device, context, descriptor, iostream); if (rc != DC_STATUS_SUCCESS) { ERROR ("Error opening the device."); @@ -83,6 +92,7 @@ do_timesync (dc_context_t *context, dc_descriptor_t *descriptor, const char *dev cleanup: dc_device_close (device); + dc_iostream_close (iostream); return rc; } @@ -91,16 +101,18 @@ dctool_timesync_run (int argc, char *argv[], dc_context_t *context, dc_descripto { int exitcode = EXIT_SUCCESS; dc_status_t status = DC_STATUS_SUCCESS; + dc_transport_t transport = DC_TRANSPORT_NONE; // Default option values. unsigned int help = 0; // Parse the command-line options. int opt = 0; - const char *optstring = "h"; + const char *optstring = "ht:"; #ifdef HAVE_GETOPT_LONG struct option options[] = { {"help", no_argument, 0, 'h'}, + {"transport", required_argument, 0, 't'}, {0, 0, 0, 0 } }; while ((opt = getopt_long (argc, argv, optstring, options, NULL)) != -1) { @@ -125,6 +137,13 @@ dctool_timesync_run (int argc, char *argv[], dc_context_t *context, dc_descripto return EXIT_SUCCESS; } + // Check the transport type. + if (transport == DC_TRANSPORT_NONE) { + message ("No valid transport type specified.\n"); + exitcode = EXIT_FAILURE; + goto cleanup; + } + // Get the system time. dc_datetime_t datetime = {0}; dc_ticks_t now = dc_datetime_now (); @@ -135,7 +154,7 @@ dctool_timesync_run (int argc, char *argv[], dc_context_t *context, dc_descripto } // Synchronize the device clock. - status = do_timesync (context, descriptor, argv[0], &datetime); + status = do_timesync (context, descriptor, transport, argv[0], &datetime); if (status != DC_STATUS_SUCCESS) { message ("ERROR: %s\n", dctool_errmsg (status)); exitcode = EXIT_FAILURE; @@ -156,8 +175,10 @@ const dctool_command_t dctool_timesync = { "\n" "Options:\n" #ifdef HAVE_GETOPT_LONG - " -h, --help Show help message\n" + " -h, --help Show help message\n" + " -t, --transport Transport type\n" #else - " -h Show help message\n" + " -h Show help message\n" + " -t Transport type\n" #endif }; diff --git a/examples/dctool_write.c b/examples/dctool_write.c index 7b6e050..98d4028 100644 --- a/examples/dctool_write.c +++ b/examples/dctool_write.c @@ -39,17 +39,26 @@ #include "utils.h" static dc_status_t -dowrite (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname, unsigned int address, dc_buffer_t *buffer) +dowrite (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport, const char *devname, unsigned int address, dc_buffer_t *buffer) { dc_status_t rc = DC_STATUS_SUCCESS; dc_iostream_t *iostream = NULL; dc_device_t *device = NULL; - // Open the device. - message ("Opening the device (%s %s, %s).\n", - dc_descriptor_get_vendor (descriptor), - dc_descriptor_get_product (descriptor), + // Open the I/O stream. + message ("Opening the I/O stream (%s, %s).\n", + dctool_transport_name (transport), devname ? devname : "null"); + rc = dctool_iostream_open (&iostream, context, descriptor, transport, devname); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error opening the I/O stream."); + goto cleanup; + } + + // Open the device. + message ("Opening the device (%s %s).\n", + dc_descriptor_get_vendor (descriptor), + dc_descriptor_get_product (descriptor)); rc = dc_device_open (&device, context, descriptor, iostream); if (rc != DC_STATUS_SUCCESS) { ERROR ("Error opening the device."); @@ -83,6 +92,7 @@ dowrite (dc_context_t *context, dc_descriptor_t *descriptor, const char *devname cleanup: dc_device_close (device); + dc_iostream_close (iostream); return rc; } @@ -92,6 +102,7 @@ dctool_write_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t int exitcode = EXIT_SUCCESS; dc_status_t status = DC_STATUS_SUCCESS; dc_buffer_t *buffer = NULL; + dc_transport_t transport = DC_TRANSPORT_NONE; // Default option values. unsigned int help = 0; @@ -101,10 +112,11 @@ dctool_write_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t // Parse the command-line options. int opt = 0; - const char *optstring = "ha:c:i:"; + const char *optstring = "ht:a:c:i:"; #ifdef HAVE_GETOPT_LONG struct option options[] = { {"help", no_argument, 0, 'h'}, + {"transport", required_argument, 0, 't'}, {"address", required_argument, 0, 'a'}, {"count", required_argument, 0, 'c'}, {"input", required_argument, 0, 'i'}, @@ -118,6 +130,9 @@ dctool_write_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t case 'h': help = 1; break; + case 't': + transport = dctool_transport_type (optarg); + break; case 'a': address = strtoul (optarg, NULL, 0); have_address = 1; @@ -143,6 +158,13 @@ dctool_write_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t return EXIT_SUCCESS; } + // Check the transport type. + if (transport == DC_TRANSPORT_NONE) { + message ("No valid transport type specified.\n"); + exitcode = EXIT_FAILURE; + goto cleanup; + } + // Check mandatory arguments. if (!have_address) { message ("No memory address specified.\n"); @@ -166,7 +188,7 @@ dctool_write_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t } // Write data to the internal memory. - status = dowrite (context, descriptor, argv[0], address, buffer); + status = dowrite (context, descriptor, transport, argv[0], address, buffer); if (status != DC_STATUS_SUCCESS) { message ("ERROR: %s\n", dctool_errmsg (status)); exitcode = EXIT_FAILURE; @@ -189,11 +211,13 @@ const dctool_command_t dctool_write = { "Options:\n" #ifdef HAVE_GETOPT_LONG " -h, --help Show help message\n" + " -t, --transport Transport type\n" " -a, --address
Memory address\n" " -c, --count Number of bytes\n" " -i, --input Input filename\n" #else " -h Show help message\n" + " -t Transport type\n" " -a
Memory address\n" " -c Number of bytes\n" " -i Input filename\n"