From 630b5e7c3cdf4402e2814026cd5929470f0f58d2 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Wed, 8 Mar 2017 16:38:52 +0100 Subject: [PATCH] Add support for the scan command --- examples/Makefile.am | 1 + examples/dctool.c | 1 + examples/dctool.h | 1 + examples/dctool_scan.c | 192 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 examples/dctool_scan.c diff --git a/examples/Makefile.am b/examples/Makefile.am index 6b70f99..3cc556e 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -12,6 +12,7 @@ dctool_SOURCES = \ dctool_help.c \ dctool_version.c \ dctool_list.c \ + dctool_scan.c \ dctool_download.c \ dctool_dump.c \ dctool_parse.c \ diff --git a/examples/dctool.c b/examples/dctool.c index 52eb67b..ddcd596 100644 --- a/examples/dctool.c +++ b/examples/dctool.c @@ -58,6 +58,7 @@ static const dctool_command_t *g_commands[] = { &dctool_help, &dctool_version, &dctool_list, + &dctool_scan, &dctool_download, &dctool_dump, &dctool_parse, diff --git a/examples/dctool.h b/examples/dctool.h index 06e58a8..a79cf75 100644 --- a/examples/dctool.h +++ b/examples/dctool.h @@ -45,6 +45,7 @@ typedef struct dctool_command_t { extern const dctool_command_t dctool_help; extern const dctool_command_t dctool_version; extern const dctool_command_t dctool_list; +extern const dctool_command_t dctool_scan; extern const dctool_command_t dctool_download; extern const dctool_command_t dctool_dump; extern const dctool_command_t dctool_parse; diff --git a/examples/dctool_scan.c b/examples/dctool_scan.c new file mode 100644 index 0000000..9f46fc6 --- /dev/null +++ b/examples/dctool_scan.c @@ -0,0 +1,192 @@ +/* + * libdivecomputer + * + * Copyright (C) 2017 Jef Driesen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#ifdef HAVE_GETOPT_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "dctool.h" +#include "common.h" +#include "utils.h" + +static dc_status_t +scan (dc_context_t *context, dc_descriptor_t *descriptor, dc_transport_t transport) +{ + dc_status_t status = DC_STATUS_SUCCESS; + dc_iterator_t *iterator = NULL; + + // Create the device iterator. + switch (transport) { + case DC_TRANSPORT_SERIAL: + status = dc_serial_iterator_new (&iterator, context, descriptor); + break; + case DC_TRANSPORT_IRDA: + status = dc_irda_iterator_new (&iterator, context, descriptor); + break; + case DC_TRANSPORT_BLUETOOTH: + status = dc_bluetooth_iterator_new (&iterator, context, descriptor); + break; + case DC_TRANSPORT_USBHID: + status = dc_usbhid_iterator_new (&iterator, context, descriptor); + break; + default: + status = DC_STATUS_UNSUPPORTED; + break; + } + if (status != DC_STATUS_SUCCESS) { + ERROR ("Failed to create the device iterator."); + goto cleanup; + } + + // Enumerate the devices. + void *device = NULL; + while ((status = dc_iterator_next (iterator, &device)) == DC_STATUS_SUCCESS) { + char buffer[DC_BLUETOOTH_SIZE]; + switch (transport) { + case DC_TRANSPORT_SERIAL: + printf ("%s\n", dc_serial_device_get_name (device)); + dc_serial_device_free (device); + break; + case DC_TRANSPORT_IRDA: + printf ("%08x\t%s\n", dc_irda_device_get_address (device), dc_irda_device_get_name (device)); + dc_irda_device_free (device); + break; + case DC_TRANSPORT_BLUETOOTH: + printf ("%s\t%s\n", + dc_bluetooth_addr2str(dc_bluetooth_device_get_address (device), buffer, sizeof(buffer)), + dc_bluetooth_device_get_name (device)); + dc_bluetooth_device_free (device); + break; + case DC_TRANSPORT_USBHID: + printf ("%04x:%04x\n", dc_usbhid_device_get_vid (device), dc_usbhid_device_get_pid (device)); + dc_usbhid_device_free (device); + break; + default: + break; + } + } + if (status != DC_STATUS_SUCCESS && status != DC_STATUS_DONE) { + ERROR ("Failed to enumerate the devices."); + goto cleanup; + } + + status = DC_STATUS_SUCCESS; + +cleanup: + dc_iterator_free (iterator); + return status; +} + +static int +dctool_scan_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t *descriptor) +{ + int exitcode = EXIT_SUCCESS; + dc_status_t status = DC_STATUS_SUCCESS; + + // Default option values. + unsigned int help = 0; + dc_transport_t transport = DC_TRANSPORT_NONE; + + // Parse the command-line options. + int opt = 0; + 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) { +#else + while ((opt = getopt (argc, argv, optstring)) != -1) { +#endif + switch (opt) { + case 'h': + help = 1; + break; + case 't': + transport = dctool_transport_type (optarg); + break; + default: + return EXIT_FAILURE; + } + } + + argc -= optind; + argv += optind; + + // Show help message. + if (help) { + dctool_command_showhelp (&dctool_list); + return EXIT_SUCCESS; + } + + // Check the transport type. + if (transport == DC_TRANSPORT_NONE) { + message ("No valid transport type specified.\n"); + exitcode = EXIT_FAILURE; + goto cleanup; + } + + // Scan for supported devices. + status = scan (context, descriptor, transport); + if (status != DC_STATUS_SUCCESS) { + message ("ERROR: %s\n", dctool_errmsg (status)); + exitcode = EXIT_FAILURE; + goto cleanup; + } + +cleanup: + return exitcode; +} + +const dctool_command_t dctool_scan = { + dctool_scan_run, + DCTOOL_CONFIG_NONE, + "scan", + "Scan for supported devices", + "Usage:\n" + " dctool scan [options]\n" + "\n" + "Options:\n" +#ifdef HAVE_GETOPT_LONG + " -h, --help Show help message\n" + " -t, --transport Transport type\n" +#else + " -h Show help message\n" + " -t Transport type\n" +#endif +};