Kemp’s Blog

A technical blog about technical things

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.