DeviceMaster protocol, part 3: TCP protocol outline
With the UDP side of the protocol out of the way I moved on to the TCP side, which is used to actually communicate with the device (for example to use one of the serial ports).
Unfortunately, I haven’t got very far with this protocol yet. Currently I’m also in a different location to the device and can’t go and fetch it because of global pandemic reasons, so I can’t immediately answer some of the questions I still had while writing this up. There are a lot of questions because I wasn’t expecting to need to write this up based on my initial testing, which I didn’t put much effort into annotating. Because of that you will see some notes [written like this] in the text. I will be looking into resolving those when I am able.
Connect
When connecting the driver sends
05 00 08 00 00 00 00 00
To which the device responds with a message similar to the following
ip ip ip ip gg gg gg gg 00 00 00 00 sm sm sm sm
88 11 61 00 78 ee 1a 00 fw fw fw fw fw fw fw fw
fw fw fw fw fw fw fw fw fw fw 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 mm mm mm mm mm mm ?? ??
?? ?? 03 08 00 01 07 00 00 01 00 ff 0b 22 00 ff
02 01 01 03 01 2d 04 01 00 05 04 00 00 00 00 06
10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
xx 00 00
Some of these values are the same as you would receive in a UDP response from the device, so I’ll give the UDP identifier where possible. The value are:
ip
is the IPv4 address (likely DHCP, UDP 0x1c)gg
is the gateway address (likely DHCP, UDP 0x1e)sm
is the subnet mask (likely DHCP, UDP 0x1d)fw
is the firmware name (UDP 0x14)mm
is the MAC address (UDP 0x16)??
is an unknown value (UDP 0x2c)xx
is a value I observed to differ between connection attempts (0x00 and 0x02 were observed)
The other values don’t seem to match values in the UDP responses. I suspect the block of zeros after the firmware name could be IPv6 information, though I couldn’t get anything to appear there. The four zero bytes after the gateway address are suspiciously the same length as another IPv4 address, but again I couldn’t get anything to appear there.
The messages that follow are smaller and have fixed content as far as I’ve observed:
Source | Message |
---|---|
Driver | 73 |
Device | 74 |
Driver | 7b 0a 77 78 00 00 00 fd |
Device | fd |
I know, from other observations, that 0xfd
is a keepalive/ping message initiated by the driver, so the device sending that is likely in response to the 0xfd
on the end of the message sent by the driver. Furthermore, given the number of bytes in the 70s I’d hazard a guess that there are multiple messages sent in a single packet for convenience. Based on this, I’d say that the exchange is actually:
Source | Message |
---|---|
Driver | 73 |
Device | 74 |
Driver | 7b 0a |
Driver | 77 |
Driver | 78 00 00 00 |
Driver | fd |
Device | fd |
On some occasions the 0x77 and 0x78 messages are not sent. [Likely an abbreviated reconnect. Possibly determined by that 0x00/0x02 byte in the earlier response?]
[Is the 0xfd still sent in response to the shorter exchange?]
Open port
All the messages discussed in this section are prefixed with 62 pp
, where pp
is a port number (0-indexed), which selects the port that the message applies to. Where multiple messages are sent in a single packet there is only a single instance of 62 pp
preceeding all of them.
The start of the exchange is:
Source | Message |
---|---|
Driver | 76 01 |
Device | 76 10 00 00 or 76 10 38 00 if loopback cable attached and other port open |
Driver | 60 00 00 |
Driver | 66 03 00 |
Driver | 63 00 00 |
Driver | 64 03 00 |
Driver | 70 00 80 25 00 or 70 00 e1 00 00 |
Driver | 71 11 13 11 13 00 00 75 32 |
This is then followed by either:
Source | Message |
---|---|
Device | 60 00 00 (same as driver sent) |
Driver | 79 01 00 00 00 |
Device | 67 03 00 |
Or:
Source | Message |
---|---|
Device | 67 03 00 |
Device | 60 00 00 (optional) |
Driver | 79 01 00 00 00 |
Driver | 70 80 25 00 00 or 70 00 e1 00 00 * |
* (opposite to earlier, note the former option is subtly different)
The last driver message may be absent, which seems fairly common.
I have observed other variations that imply the sequence isn’t strict and there is some room for different sequencing. For example, in the first block after the device sends the 76 message I have observed it immediately sending the 60 message before the driver sends the 60, 66, 63, 64, 70, 71 sequence. It then followed the second form of the next block without the 60 message that was already sent or the final 70 message from the driver.
With a loopback cable connecting this port with the second port the device also sent 65 38 00
for the second port after the exchange above was complete, which presumably is part of emulating flow control. On the same lines, I have seen the device send 65 00 00
and 60 00 00
after the device’s 76 message. [This was sent for the first port?] This was after closing a different port before opening the port in question.
[The 38
byte in the 76 and 65 messages almost certainly means “connected” and a 00
in its place means closed (see “Close port” for additional examples).]
Send byte
To send a byte to be transmitted on the port, the driver sends 62 pp 61 ss 00 cc
, where ss
is the sequence number, and cc
is the character to send. The 61
appears to correspond to a send operation.
[Sequence number is two bytes?]
In response, the device sends back 62 pp 60 ss 00
, with values having the same meanings. The 60
appears to acknowledge the send.
With a cable attached as a loopback and the second port also opened by the driver the device also sends 62 qq 61 ss 00 cc 7a
, where qq
is the second port number. This second message was sent in the same packet as the first, presumably for efficiency. The meaning of the 7a
on the end is not known and is possibly a third message given how many start with a value in the 60s and 70s. The driver sends back an acknowledgement in the same format as the device sends.
[Have also observed the device sending 62 qq 7a
. Flow control? Will have same meaning as the 7a sent on its own.]
[How about sending multiple characters in one message? I’m pretty sure I did that while testing.]
[How about a send on a closed port? My notes imply you get something like a 62 pp 76 21
back. Similar to the 76 10
and 76 20
responses to opening and closing a port. 76
is a generic port status message?]
Close port
As noted previously all the messages discussed in this section are prefixed with 62 pp
, where pp
is a 0-indexed port number.
The exchange looks like:
Source | Message |
---|---|
Driver | 66 03 00 63 00 00 64 00 00 |
Device | 67 03 00 |
Driver | 76 02 |
Device | 76 20 |
As per my assumption throughout this post, I suspect that the first message is actually multiple messages preceeded by a port selector message, making the exchange more like:
Source | Message |
---|---|
Driver | 66 03 00 |
Driver | 63 00 00 |
Driver | 64 00 00 |
Device | 67 03 00 |
Driver | 76 02 |
Device | 76 20 |
If a loopback cable is connected and the second port is also open then the device also sends 62 qq 65 00 00
which may be interleaved with the messages above. I saw it before the 76 response. The 65 message presumably indicates that the remote port closed and relies on hardware flow control being available. [Does the config have anything that would affect this being possible?]
The 76 message appears at the start of opening a port and at the end of closing a port, so I suspect that this is the actual open or close request. The payload is 0x01
for open (with 0x10
in the reply) and 0x02
for close (with 0x20
in the reply).
[See also note about sending on a closed port, which gives a 76 message back.]
Keepalive / Ping
Initiated by the driver and sent every minute. The message is simply 0xfd
and it expects the device to send 0xfd
back. The timeout for a failed ping defaults to 120 seconds in the driver.