16 Commits

Author SHA1 Message Date
Linus Torvalds
0099aeeb70 Merge git://git.libdivecomputer.org/libdivecomputer into Subsurface-branch
Merge with upstream libdivecomputer: USB HID fixes.

* git://git.libdivecomputer.org/libdivecomputer:
  Make the initialization thread-safe
  Initialize the usb library only once
2017-10-19 15:57:16 -04:00
Jef Driesen
f708eadcfd Make the initialization thread-safe
Perform the initialization inside a critical section.

Unfortunately Windows critical sections, which are the simplest
synchronization mechanism available on Windows, do not support static
initialization. A call to InitializeCriticalSection is required.
Therefore a simple spinlock, with an implementation based on atomic
operations, is used as a workaround.
2017-10-09 14:35:36 +02:00
Jef Driesen
7b920f5c42 Initialize the usb library only once
Initializing the hidapi library more than once is tricky. The hid_init()
function can be called multiple times, but the the hid_exit() function
will free the resources unconditionally, regardless of how many times
the hid_init() function has been called. The consequence is a premature
termination of the library.

To avoid this problem, the calls are reference counted. Note that this
workaround can't protect against calls made outside the libdivecomputer
code!

The libusb library doesn't suffer from this problem, because each
initialization returns a new context pointer. But for consistency, we
now also use a single reference counted libusb context.
2017-10-09 14:35:36 +02:00
Linus Torvalds
07f5777c71 Merge git://git.libdivecomputer.org/libdivecomputer into Subsurface-branch
Merge with upstream libdivecomputer:

 - workarounds for Windows libusb and hidapi issues

 - misc random cleanups/noise

 - rename DiveSystem to Ratio

 - make Cochran with better with FTDI

 - new support for: Suunto D4f, Ratio idive tank pressure, and Sherwood
   Insight temperature and Oceanic ndl/deco sample.

* git://git.libdivecomputer.org/libdivecomputer:
  Workaround for a Windows libusb issue
  Use a fixed size packet for sending
  Replace the size macro with the sizeof operator
  Use the correct printf format for the size_t type
  Move platform specific macros to a common header file
  Use the correct data type for the return value
  Rename the DiveSystem vendor to Ratio
  Fix the Sherwood Insight temperature
  Implement the ndl/deco sample
  Change communication parameter to work better with FTDI
  Retry read operations on failure
  Add support for the Suunto D4f
  Implement the tank pressure
2017-10-05 15:02:56 -07:00
Jef Driesen
bcb64b3297 Workaround for a Windows libusb issue
When libusb uses the Windows HID api internally, it does automatically
prepend a zero report ID to the data for devices which support only a
single report. But apparently it also returns a size of one byte extra!
As a workaround, the number of bytes is limited to the actual size.

See commit c9ed92d3f55c259931527a27d018eb5791a176dd for a similar issue
in the hidapi library.
2017-09-28 22:19:11 +02:00
Linus Torvalds
928be1f45b Merge git://git.libdivecomputer.org/libdivecomputer into Subsurface-branch
Merge with upstream libdivecomputer from Jef:

 - more Cochran work from John Van Ostrand

 - new 'timesync' interface to synchronize the clock on a dive computer

 - support for Aqualung i200

 - misc updates (Cressi Leonardo fix, OSTC 3+ renaming, fix surface pressure on iX3M, idive salinity parsing)

 - HIDAPI work.

It turns out that HIDAPI is not compatible with libusb in the actual
packet sending path, so this will need some more cleanups - Jef doesn't
see the issue because he doesn't have a generic packet IO layer and
doesn't share packets with the BLE code.

* git://git.libdivecomputer.org/libdivecomputer: (25 commits)
  Add basic timezone support
  Add time synchronization to the example application
  Implement the new api for the HW devices
  Add support for synchronizing the device clock
  Use hidapi as the default USB HID library
  Workaround for a Windows hidapi issue
  Reset the number of bytes to zero on error
  Add a zero report ID to the commands
  Fix compatibility issue with hidapi
  Implement the salinity field
  Fix the atmospheric pressure for the iX3M
  Rename the OSTC 3+ to OSTC Plus
  Locate the most recent dive using the logbook pointers
  Add support for the Aqualung i200
  Add event handling to TM model
  Fix profile buffer size and address size
  Add three event codes
  Add support for the Commander TM
  Dump function no longer assumes reads begin at byte 0
  Remove unneeded function
  ...
2017-08-19 13:51:56 -07:00
Jef Driesen
eea02126a4 Use hidapi as the default USB HID library
On Windows, the hidapi library uses the standard Microsoft USB HID
driver, while libusb requires the installation of a different driver
(WinUSB or libusbK). But installing one of the libusb drivers breaks
compatibility with other applications using hidapi (Scubapro LogTRAK and
Suunto DM5) because only one driver can be active. Switching
libdivecomputer to hidapi avoids this problem.

On Linux, the hidapi library doesn't seem to offer any advantages over
libusb. Most distributions don't even have the hidapi library installed
by default. Because there are usually two variants of the hidapi library
available on Linux (hidapi-libusb and hidapi-hidraw), the autotools
build system won't be able to detect it out-of-the-box, and will
automatically fallback to the libusb implementation.

On Mac OS X, hidapi is already the default (and also the only option).
2017-08-18 23:15:55 +02:00
Jef Driesen
c9ed92d3f5 Workaround for a Windows hidapi issue
The Windows HID api always expects to receive a fixed size buffer
(corresponding to the largest report supported by the device). Therefore
the hidapi library internally pads the buffer with zeros to the expected
size, but apparently it also returns the size of the padded buffer! As a
workaround the number of bytes is limited to the actual size.
2017-08-18 23:15:55 +02:00
Jef Driesen
b82d5fcfff Reset the number of bytes to zero on error
The hidapi read and write functions return a negative value if an error
occurs. Those negative values should not be returned to the caller as
the actual number of bytes (or used in the logging). The value is reset
to zero instead.
2017-08-18 23:15:55 +02:00
Jef Driesen
05c858bf96 Fix compatibility issue with hidapi
The hidapi library requires that the first byte contains the report ID.
For devices which support only a single report, the report ID byte
should be zero. The remaining bytes contain the actual report data.

Now, when hidapi uses libusb internally, it strips the zero report ID
byte again before passing the data to libusb. Thus in order to remain
compatible with the hidapi based implementation, our libusb based
implementation should do the same.
2017-08-18 23:15:55 +02:00
Linus Torvalds
208807180a Update the operations in 'custom_io' to consistent calling conventions
The serial ops used a legacy calling convention that passed in just the
pointer to the userdata pointer (ie the first argument to the functions
was "void **userdata").

That's actually very inconvenient, because the custom IO data can not
only contain other interesting information that was filled in by the
custom IO provider, it also made it harder to chain these things
together, as exemplified by the core to emulate serial over the packet
interface in the subsurface bluetooth code.

This also adds the 'dc_context_t' field that is passed to the packet
routine open.  That can allow the open routine to override the
'custom_io' details of the context at open time (to allow nested
custom_io operation).

Note that callers of the open function need to be aware that the
'custom_io' can be changed by the act of opening a custom_io, and the
value shouldn't be cached in some local variable.

Finally, this adds a new user-supplied opaque pointer

	dc_user_device_t *user_device;

to the custom_io descriptor.

The 'user_device' data is filled in when registering the custom_io with
data that the custom IO open() routines can use.  This is different from
the existing 'userdata' in that the 'user_device' is filled in before
dc_open_device() is called (and "open" can then use it to limit what
kinds of devices it looks for, for example).

In contrast, the existing 'userdata' field is filled in by the
"xyz_open()" routines, and contains the data necessary for the IO
itself.

The SSRF_CUSTOM_IO define is updated to v2 to indicate the new
interfaces.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2017-06-27 13:38:45 -07:00
Linus Torvalds
e590739260 usbhid: add helper function to create a usbhid 'custom_io_t'
Basically, this alows us to hide the usbhid code behind the custom_io
abstraction, so that a dive computer could either be given a supplied
custom_io structure, of if none is given, would create one for a USBHID
device.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2017-06-18 16:28:35 +09:00
Jef Driesen
57ffb2ba7a Fix some more null pointer dereferences 2017-03-08 08:47:04 +01:00
Jef Driesen
6c6b144fe0 Add a dummy backend for systems without USB HID support.
This dummy implemantion is used when building without libusb and hidapi.
2016-09-19 15:04:48 +02:00
Jef Driesen
ed2a7c91fe Use the hidapi library on Mac OS X.
On Mac OS X, libusb doesn't work for USB HID devices. We can use the
hidapi library instead. Although the hidapi library supports Linux and
Windows too, we keep using libusb there to avoid the extra dependency.
2016-09-19 15:04:48 +02:00
Jef Driesen
bae6cb856e Add a new USB HID communication backend. 2016-09-19 15:04:48 +02:00