8 Commits

Author SHA1 Message Date
Linus Torvalds
54ba49b1b3 iostream: add 'get_name()' function
Some of the transport types have meaningful names.

The BLE transport has a device name that was exposed during device
discovery, for example, and some back-ends (ok, right now only the
Aqualung i300C and i770R) need to know what that device name was in
order to handshake with the device properly.

Other transports, like the USBSTORAGE one, could usefully use this to
get the basename of the path to the storage, although right now that
transport makes do with simply doing a "dc_iostream_read()" on the
transport instead.

For now, this is just the infrastructure, ready to get hooked into.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-10-05 15:04:37 -07:00
Linus Torvalds
e97886a994 Fix dc_iostream_{read,write} debugging implementation
The dc_iostream_{read,write}() implementation had multiple issues:

 (a) it would return DC_STATUS_SUCCESS even if no iostream
     implementation existed.

     Yes, it would also return a zero "actual" bytes, but most backends
     don't even pass an "actual" pointer, so returning success was still
     completely insane.

     This one probably didn't matter, because all iostreams should have
     read and write members, but the return value was completely wrong
     if that ever were to happen.

 (b) The write side actually tested not whether a write function
     existed, but whether a read one existed.

     Again, this one probably didn't matter in practice, since an
     iostream without a read and write member doesn't make much sense,
     but the test was completely wrong regardless.

 (c) If the user passed in a NULL 'actual' pointer, the wrapper would
     ignore that, and pass in its own pointer instead, in order to know
     how many bytes to print for the debug message.

     But that means that the low-level read/write functions cannot know
     whether the user actually is able to handle a partial read or not.

     This one _definitely_ matters, because some protocols need to have
     a buffer for the whole incoming packet, but packerts may not always
     be full-size. The low-level protocol needs to know whether to wait
     for further packets (in order to fill the buffer) or to just return
     the partial data.

This fixes all of these issues.  If the user passes in a NULL actual
pointer (indicating that it needs all-or-nothing and is not ready to
handle a partial success), just loop over the IO until the buffer is
fully exhausted.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-09-26 11:22:23 -07:00
Jef Driesen
56d194d377 Use a NULL pointer for the no-op implementation
For most I/O stream implementations the serial communication specific
functions are meaningless. Implementing them as no-ops allows the dive
computer backends the call the I/O stream functions unconditionally.

However, implementing the no-op with a dummy function returning
DC_STATUS_SUCCESS, does not only add some (small) overhead at runtime,
but also requires many such functions. This is inconvenient and the same
result can easily be obtained by using a NULL pointer instead.

The consequence is that the logic is reversed now. To obtain the
previous behaviour of returning the DC_STATUS_UNSUPPORTED error code
again, you'll need to implement a dummy function. But that's fine
because it's the less common case.
2018-04-17 08:18:35 +02:00
Jef Driesen
1908394af4 Add some extra logging 2018-04-12 10:07:53 +02:00
Jef Driesen
945898f8fd Always initialize the output parameters
I/O functions with output parameters, should always initialize those
output parameters, even when an error is returned. This prevents the
(accidental) use of uninitialized variables, whenever the caller forgets
to check the return code.

As a nice side effect, the use of a local variable guarantees that the
underlying I/O implementation will always receive a valid pointer.
2018-04-12 10:07:30 +02:00
Jef Driesen
3230387fff Add the transport type to the I/O stream
Add a function to query the underlying transport type. This allows the
dive computer backends to implement transport specific behaviour where
necessary.

For the built-in I/O implementations, the transport type is obviously
always hardcoded, but for a custom I/O implementation the application
needs to provide the correct type. Hence the transport type can't be
hardcoded in the vtable and needs to be passed as a parameter.
2018-04-03 21:11:06 +02:00
Jef Driesen
38ff1f75dd Remove the half-duplex emulation from the I/O api
Now that the half-duplex emulation code isn't used anymore, it can be
removed from the I/O stream api.
2018-03-05 09:08:21 +01:00
Jef Driesen
3ca27995e1 Add a new abstract I/O interface
The purpose of the new I/O interface is to provide a common interface
for all existing I/O implementations (serial, IrDA, bluetooth and USB
HID). With a common interface the dive computer backends can more easily
use different I/O implementations at runtime, without needing
significant code changes. For example bluetooth enabled devices can
easily switch between native bluetooth communication and serial port
emulation mode.

The new interface is modelled after the existing serial communication
api. Implementations where some of those functions are meaningless (e.g.
IrDA, bluetooth and USB), can just leave those functions unimplemented
(causing the call to fail with DC_STATUS_UNSUPPORTED), or implement it
as a no-op (always return DC_STATUS_SUCCESS).
2017-11-25 10:26:49 +01:00