From bfbb56c781f209694b51904572888132faeeef63 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 28 Dec 2015 19:08:57 +0100 Subject: [PATCH] Add the dump command. --- examples/Makefile.am | 1 + examples/dctool.c | 1 + examples/dctool.h | 1 + examples/dctool_dump.c | 191 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 194 insertions(+) create mode 100644 examples/dctool_dump.c diff --git a/examples/Makefile.am b/examples/Makefile.am index 0356d90..fffc238 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -12,5 +12,6 @@ dctool_SOURCES = \ dctool_help.c \ dctool_version.c \ dctool_list.c \ + dctool_dump.c \ utils.h \ utils.c diff --git a/examples/dctool.c b/examples/dctool.c index 7cf6728..24f14c9 100644 --- a/examples/dctool.c +++ b/examples/dctool.c @@ -51,6 +51,7 @@ static const dctool_command_t *g_commands[] = { &dctool_help, &dctool_version, &dctool_list, + &dctool_dump, NULL }; diff --git a/examples/dctool.h b/examples/dctool.h index c1239a0..064ea9b 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_dump; const dctool_command_t * dctool_command_find (const char *name); diff --git a/examples/dctool_dump.c b/examples/dctool_dump.c new file mode 100644 index 0000000..ce59899 --- /dev/null +++ b/examples/dctool_dump.c @@ -0,0 +1,191 @@ +/* + * libdivecomputer + * + * Copyright (C) 2015 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 +#include +#ifdef HAVE_GETOPT_H +#include +#endif + +#include +#include +#include + +#include "dctool.h" +#include "common.h" +#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) +{ + dc_status_t rc = DC_STATUS_SUCCESS; + 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), + devname ? devname : "null"); + rc = dc_device_open (&device, context, descriptor, devname); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error opening the device."); + goto cleanup; + } + + // Register the event handler. + message ("Registering the event handler.\n"); + int events = DC_EVENT_WAITING | DC_EVENT_PROGRESS | DC_EVENT_DEVINFO | DC_EVENT_CLOCK | DC_EVENT_VENDOR; + rc = dc_device_set_events (device, events, dctool_event_cb, NULL); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error registering the event handler."); + goto cleanup; + } + + // Register the cancellation handler. + message ("Registering the cancellation handler.\n"); + rc = dc_device_set_cancel (device, dctool_cancel_cb, NULL); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error registering the cancellation handler."); + goto cleanup; + } + + // Register the fingerprint data. + if (fingerprint) { + message ("Registering the fingerprint data.\n"); + rc = dc_device_set_fingerprint (device, dc_buffer_get_data (fingerprint), dc_buffer_get_size (fingerprint)); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error registering the fingerprint data."); + goto cleanup; + } + } + + // Download the memory dump. + message ("Downloading the memory dump.\n"); + rc = dc_device_dump (device, buffer); + if (rc != DC_STATUS_SUCCESS) { + ERROR ("Error downloading the memory dump."); + goto cleanup; + } + +cleanup: + dc_device_close (device); + return rc; +} + +static int +dctool_dump_run (int argc, char *argv[], dc_context_t *context, dc_descriptor_t *descriptor) +{ + int exitcode = EXIT_SUCCESS; + dc_status_t status = DC_STATUS_SUCCESS; + dc_buffer_t *fingerprint = NULL; + dc_buffer_t *buffer = NULL; + + // Default option values. + unsigned int help = 0; + const char *fphex = NULL; + const char *filename = NULL; + + // Parse the command-line options. + int opt = 0; + const char *optstring = "ho:p:"; +#ifdef HAVE_GETOPT_LONG + struct option options[] = { + {"help", no_argument, 0, 'h'}, + {"output", required_argument, 0, 'o'}, + {"fingerprint", required_argument, 0, 'p'}, + {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 'o': + filename = optarg; + break; + case 'p': + fphex = optarg; + break; + default: + return EXIT_FAILURE; + } + } + + argc -= optind; + argv += optind; + + // Show help message. + if (help) { + dctool_command_showhelp (&dctool_dump); + return EXIT_SUCCESS; + } + + // Convert the fingerprint to binary. + fingerprint = dctool_convert_hex2bin (fphex); + + // Allocate a memory buffer. + buffer = dc_buffer_new (0); + + // Download the memory dump. + status = dump (context, descriptor, argv[0], fingerprint, buffer); + if (status != DC_STATUS_SUCCESS) { + message ("ERROR: %s\n", dctool_errmsg (status)); + exitcode = EXIT_FAILURE; + goto cleanup; + } + + // Write the memory dump to disk. + dctool_file_write (filename, buffer); + +cleanup: + dc_buffer_free (buffer); + dc_buffer_free (fingerprint); + return exitcode; +} + +const dctool_command_t dctool_dump = { + dctool_dump_run, + DCTOOL_CONFIG_DESCRIPTOR, + "dump", + "Download a memory dump", + "Usage:\n" + " dctool dump [options] \n" + "\n" + "Options:\n" +#ifdef HAVE_GETOPT_LONG + " -h, --help Show help message\n" + " -o, --output Output filename\n" + " -p, --fingerprint Fingerprint data (hexadecimal)\n" +#else + " -h Show help message\n" + " -o Output filename\n" + " -p Fingerprint data (hexadecimal)\n" +#endif +};