Add 'USB storage' transport enumeration
We now have at least two dive computers that enumerate as USB storage devices: the Uemis Zurich and the Garmin Descent Mk1. The Uemis is handled purely inside of subsurface, with no libdivecomputer support. That was likely a mistake, but it was not practical to do a libdivecomputer backend for it at the time. The Garmin Descent Mk1 support would be much nicer to have natively in libdivecomputer, and looks much more relevant and practical than the Uemis situation was. So start off with defining a new transport type. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
bb985eedbb
commit
8735156e89
@ -98,6 +98,7 @@ static const transport_table_t g_transports[] = {
|
||||
{"irda", DC_TRANSPORT_IRDA},
|
||||
{"bluetooth", DC_TRANSPORT_BLUETOOTH},
|
||||
{"ble", DC_TRANSPORT_BLE},
|
||||
{"usbstorage",DC_TRANSPORT_USBSTORAGE},
|
||||
};
|
||||
|
||||
const char *
|
||||
@ -536,6 +537,8 @@ dctool_iostream_open (dc_iostream_t **iostream, dc_context_t *context, dc_descri
|
||||
return dctool_irda_open (iostream, context, descriptor, devname);
|
||||
case DC_TRANSPORT_BLUETOOTH:
|
||||
return dctool_bluetooth_open (iostream, context, descriptor, devname);
|
||||
case DC_TRANSPORT_USBSTORAGE:
|
||||
return dc_usb_storage_open (iostream, context, devname);
|
||||
default:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -48,9 +48,13 @@ typedef enum dc_transport_t {
|
||||
DC_TRANSPORT_USBHID = (1 << 2),
|
||||
DC_TRANSPORT_IRDA = (1 << 3),
|
||||
DC_TRANSPORT_BLUETOOTH = (1 << 4),
|
||||
DC_TRANSPORT_BLE = (1 << 5)
|
||||
DC_TRANSPORT_BLE = (1 << 5),
|
||||
DC_TRANSPORT_USBSTORAGE= (1 << 6),
|
||||
} dc_transport_t;
|
||||
|
||||
// Idiotic enums can't be queried
|
||||
#define DC_TRANSPORT_USBSTORAGE DC_TRANSPORT_USBSTORAGE
|
||||
|
||||
typedef enum dc_family_t {
|
||||
DC_FAMILY_NULL = 0,
|
||||
/* Suunto */
|
||||
|
||||
@ -282,6 +282,9 @@ dc_iostream_sleep (dc_iostream_t *iostream, unsigned int milliseconds);
|
||||
dc_status_t
|
||||
dc_iostream_close (dc_iostream_t *iostream);
|
||||
|
||||
dc_status_t
|
||||
dc_usb_storage_open (dc_iostream_t **out, dc_context_t *context, const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@ -75,6 +75,7 @@ libdivecomputer_la_SOURCES = \
|
||||
irda.c \
|
||||
usbhid.c \
|
||||
bluetooth.c \
|
||||
usb_storage.c \
|
||||
custom.c
|
||||
|
||||
if OS_WIN32
|
||||
|
||||
@ -334,6 +334,7 @@ dc_context_get_transports (dc_context_t *context)
|
||||
#elif defined(HAVE_LIBUSB) && !defined(__APPLE__)
|
||||
| DC_TRANSPORT_USBHID
|
||||
#endif
|
||||
| DC_TRANSPORT_USBSTORAGE
|
||||
#ifdef _WIN32
|
||||
#ifdef HAVE_AF_IRDA_H
|
||||
| DC_TRANSPORT_IRDA
|
||||
|
||||
109
src/usb_storage.c
Normal file
109
src/usb_storage.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Dummy "stream" operations for USB storage
|
||||
*
|
||||
* Copyright (C) 2018 Linus Torvalds
|
||||
*
|
||||
* 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 <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common-private.h"
|
||||
#include "context-private.h"
|
||||
#include "iostream-private.h"
|
||||
#include "iterator-private.h"
|
||||
#include "descriptor-private.h"
|
||||
#include "timer.h"
|
||||
|
||||
// Fake "device" that just contains the directory name that
|
||||
// you can read out of the iostream. All the actual IO is
|
||||
// up to you.
|
||||
typedef struct dc_usbstorage_t {
|
||||
dc_iostream_t base;
|
||||
char pathname[PATH_MAX];
|
||||
} dc_usbstorage_t;
|
||||
|
||||
static dc_status_t
|
||||
dc_usb_storage_read (dc_iostream_t *iostream, void *data, size_t size, size_t *actual);
|
||||
|
||||
static const dc_iostream_vtable_t dc_usbstorage_vtable = {
|
||||
sizeof(dc_usbstorage_t),
|
||||
NULL, /* set_timeout */
|
||||
NULL, /* set_latency */
|
||||
NULL, /* set_break */
|
||||
NULL, /* set_dtr */
|
||||
NULL, /* set_rts */
|
||||
NULL, /* get_lines */
|
||||
NULL, /* get_available */
|
||||
NULL, /* configure */
|
||||
dc_usb_storage_read, /* read */
|
||||
NULL, /* write */
|
||||
NULL, /* flush */
|
||||
NULL, /* purge */
|
||||
NULL, /* sleep */
|
||||
NULL, /* close */
|
||||
};
|
||||
|
||||
dc_status_t
|
||||
dc_usb_storage_open (dc_iostream_t **out, dc_context_t *context, const char *name)
|
||||
{
|
||||
dc_usbstorage_t *device = NULL;
|
||||
struct stat st;
|
||||
|
||||
if (out == NULL || name == NULL)
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
|
||||
INFO (context, "Open: name=%s", name);
|
||||
if (stat(name, &st) < 0 || !S_ISDIR(st.st_mode))
|
||||
return DC_STATUS_NODEVICE;
|
||||
|
||||
// Allocate memory.
|
||||
device = (dc_usbstorage_t *) dc_iostream_allocate (context, &dc_usbstorage_vtable, DC_TRANSPORT_USBSTORAGE);
|
||||
if (device == NULL) {
|
||||
SYSERROR (context, ENOMEM);
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
strncpy(device->pathname, name, PATH_MAX);
|
||||
device->pathname[PATH_MAX-1] = 0;
|
||||
|
||||
*out = (dc_iostream_t *) device;
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
dc_usb_storage_read (dc_iostream_t *iostream, void *data, size_t size, size_t *actual)
|
||||
{
|
||||
dc_usbstorage_t *device = (dc_usbstorage_t *) iostream;
|
||||
size_t len = strlen(device->pathname);
|
||||
|
||||
if (size <= len)
|
||||
return DC_STATUS_IO;
|
||||
memcpy(data, device->pathname, len+1);
|
||||
if (actual)
|
||||
*actual = len;
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user