We were re-using the header byte of the stroke header to count the bits.
Where that header is anything but 0xff we got out of sync and raised an
error. Fix this by renaming things so we don't accidentally use the
wrong fields.
Fixes#283
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If the device name is longer than one reply, the registration will crash.
This adds support for a variable number of replies until the reply ends
with `0x0a`.
0xb3 is the generic error code (or success, where applicable). Let's handle
those by default so that the rest of the messages only have to care about
replies with message-specific opcodes.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reproduced on the Spark, first bytes in a new file recording were
- file header: 0x62, 0x38, 0x62, 0x74
- stroke point: 0xbf, 0xff, 0xff, 0x4a, 0x14, 0x29, 0x31, 0x6a
- stroke delta: 0xa8, 0x02, 0x04, 0xc3,
The initial point thus has a delta pressure value 0x6a which must be added to
*something*. And zero is the most sensible *something* that I can think of.
Fixes#111
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Deprecated, but still exists on the Slate so let's wrap the connect attempt
so we throw the right error.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
It's caused by a timeout but the underlying issue is that we never got the
reply that we wanted.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
0xc3 is 'download the oldest file'
0xca is 'delete the oldest file' (usually the one we just received) from the tablet.
0xc1 is 'how many files are there'
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This is a slightly different model as the messages, primarily because it's not
quite as model-specific. So there's only one parse function and it can handle
both file types that we currently support (intuos pro and the spark/slate
bits).
All wrapped into their own classes to make future extensions a bit easier.
It's not a 1:1 implementation of the tuhi/wacom.py bits either because we now
know about a few extra bits like the flags in stroke headers.
Most importantly though, this can be easily tested now, with one test case
searching for raw logs in $XDG_DATA_HOME/tuhi/raw and parsing all of those. So
the more files are sitting in there (i.e. the more the tablet is used), the
better the test suite becomes.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The dimensions of the tablet are in device units, the point size tells us how
big the actual tablet is.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
A few messages where we assumed the argument is a single byte are actually
little-endian 16 bits. let's add easy-to-use wrappers.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
It's the same message with a different argument, let's try not to do
gymnastics in the Msg code just so we can return a tuple.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We can hook into the ProtocolVersion here, so let's de-duplicate this.
Should be backwards-compatible for config files but new config files will have
the uppercase name written now.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This is still a bit awkward because the communication of the spark especially
is so strange. It sends a (rejected) uuid, then a single command to register
that UUID. The Slate and the IntuosPro are more sensible, they seem to have a
special message to register a UUID - that one either fails or succeeds.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The default timeout is too short for registering a button, let's control this
from the message.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This is only the framework for a new protocol handler that should simplify
adding, extending and debugging the actual protocol messages.
The summary is:
- each protocol interaction is a subclass of Msg() that handles the data sent
and received from the device.
- the list of messages for each device is stored in a dictionary the caller
initializes by providing the protocol version
- those messages are addressable via the Interactions enum through the
Protocol class
- the messages can be run via execute(), taking and setting the obvious
properties on the object
- actual communication is done via a single callback that takes/returns a
NordicData object for the request/reply.
So after the basic setup, the caller can do this:
p = Protocol(ProtocolVersion.INTUOS_PRO)
name = p.execute(Interactions.GET_NAME).name
p.execute(Interactions.SET_TIME, time.time())
This completely separates the protocol from the implementation where we want
the result of that exchange, ideally paving the way for better testing and
easier debugging of what's happening on the wire. Well, ether.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>