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.
This commit is contained in:
Jef Driesen 2017-04-21 21:32:15 +02:00
parent 44eba5515c
commit c50958495d
8 changed files with 385 additions and 44 deletions

View File

@ -19,6 +19,7 @@
* MA 02110-1301 USA
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@ -27,6 +28,11 @@
#include <fcntl.h>
#endif
#include <libdivecomputer/serial.h>
#include <libdivecomputer/bluetooth.h>
#include <libdivecomputer/irda.h>
#include <libdivecomputer/usbhid.h>
#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;
}
}

View File

@ -24,6 +24,7 @@
#include <libdivecomputer/context.h>
#include <libdivecomputer/descriptor.h>
#include <libdivecomputer/iostream.h>
#include <libdivecomputer/device.h>
#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 */

View File

@ -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 <name> Transport type\n"
" -o, --output <filename> Output filename\n"
" -p, --fingerprint <data> Fingerprint data (hexadecimal)\n"
" -c, --cache <directory> Cache directory\n"
@ -360,6 +383,7 @@ const dctool_command_t dctool_download = {
" -u, --units <units> Set units (metric or imperial)\n"
#else
" -h Show help message\n"
" -t <transport> Transport type\n"
" -o <filename> Output filename\n"
" -p <fingerprint> Fingerprint data (hexadecimal)\n"
" -c <directory> Cache directory\n"

View File

@ -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 <name> Transport type\n"
" -o, --output <filename> Output filename\n"
" -p, --fingerprint <data> Fingerprint data (hexadecimal)\n"
#else
" -h Show help message\n"
" -t <transport> Transport type\n"
" -o <filename> Output filename\n"
" -p <fingerprint> Fingerprint data (hexadecimal)\n"
#endif

View File

@ -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 <name> Transport type\n"
" -f, --firmware <filename> Firmware filename\n"
#else
" -h Show help message\n"
" -t <transport> Transport type\n"
" -f <filename> Firmware filename\n"
#endif
};

View File

@ -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 <name> Transport type\n"
" -a, --address <address> Memory address\n"
" -c, --count <count> Number of bytes\n"
" -o, --output <filename> Output filename\n"
#else
" -h Show help message\n"
" -t <transport> Transport type\n"
" -a <address> Memory address\n"
" -c <count> Number of bytes\n"
" -o <filename> Output filename\n"

View File

@ -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 <name> Transport type\n"
#else
" -h Show help message\n"
" -h Show help message\n"
" -t <transport> Transport type\n"
#endif
};

View File

@ -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 <name> Transport type\n"
" -a, --address <address> Memory address\n"
" -c, --count <count> Number of bytes\n"
" -i, --input <filename> Input filename\n"
#else
" -h Show help message\n"
" -t <transport> Transport type\n"
" -a <address> Memory address\n"
" -c <count> Number of bytes\n"
" -i <filename> Input filename\n"