Tuesday, November 17, 2009

Advanced Digi Discovery Protocol

When you work with microcontrollers you most often use some type of serial protocol to communicate between devices or with a computer. This is not always suitable, especially when doing so over longer distances. To solve this you get a very useful device called the Digi Connect ME or Digi Connect WiME (which is the same, except it uses WiFi where the other uses ethernet).

This device basically converts all types of serial protocols to ethernet and is very customizable. We, for instance, have it configured to persistently attempt to establish a connection to our server. Any data sent/received to the serial port or the ethernet connection will be transferred to the other side. So it basically allows ethernet communication without the effort or complexity of implementing any of the numerous protocols needed to do TCP/IP communication.

Since you don't have a computer screen or some display, to configure/manage these devices require some extra utilities. Imagine having changed the IP address of the device, it's not configured to do any communication automatically and you forget what you configured? How would you figure this out other than doing a lengthy and complex IP scan? You can also not reset the device to it's default, which will not help you in any case, because it's default is to use DHCP and you don't have a DHCP server on your network? This is just one of the many difficulties with electronics. With a computer you can jump in front of the keyboard and configure an IP address. So what to do?

The developers of the Digi device also made a utility called Digi Device Discovery. It uses their proprietary ADDP (Advanced Digi Discover Protocol) protocol to send a UDP multicast. All Digi devices will then respond with their configured IP address and some other bits of information. It also allows you to configure the IP address using these same multicast packets. On top of this they also give a C header file and library so you can have this functionality in your own applications. I'm sure you can see the amazing benefits of this, especially if you have a distributed network of electronic devices with these embedded Digi units.

Unfortunately this application is only for Windows, and the header only for C and again only for Windows. From what I can gather the Digi folks haven't found the time to document the protocol either, and I couldn't find anything useful on the internet. I did, however, find a short description of one of the packets and a few of the fields after I completed my analysis of the first 4 packets. What timing as this could have saved me 3 hours.

I needed to use these packets though. It can be very useful to manage your devices. And obviously the fact that I didn't know how it works was unacceptable and inspired me to go to any length to learn it. So armed with Wireshark (previously called Ethereal) and using Wine to run Digi Device Discovery, I set out a few evenings and analyzed the protocol. After a few hours total I had a working Java implementation running which discovers all Digi devices and lists their public configuration (the bits available in the discovery packets) as well as being able to change their IP addresses using the same protocol. I haven't completed all the features of the configuration yet, so I'm not publishing it today. It should be done by the end of this weekend (by the 22nd November 2009), at which time I'll release it under Apache License 2.0 (edit: See my new post 'Advanced Digi Discovery Protocol Explained').

For now, here is a description of the protocol.

Advanced Digi Discovery Protocol
ADDP works with UDP multicast datagrams on multicast address 224.0.5.128 and port 2362. The same address is used for sending and receiving datagrams.

All packets whether sent/received have the same basic form. It has a header of 8 bytes and a variably sized payload which consist of a variable number of fields.

General Packet Structure of Responses
A packet has the format of header followed by payload.

The header starts with 4 magic bytes consisting of the ASCII bytes 'D', 'I', 'G', 'I'. Very creative. After the magic bytes follows a 2 byte packet identifier, and then a 2 byte integer for the payload size (in bytes).

The payload for request packets are unique to each type of request, where the payload of responses all have the same basic form, which is a variable number of fields. Each field starts with a 1 byte field type identifier, followed by a 1 byte data length, followed by the data.

And that's the packet structure. Simple.

Packet Types
So far I've identified 4 packet types, nl.
Discovery Request: 0x0001
Discovery Response: 0x0002
Configuration Request: 0x0003
Configuration Response: 0x0004

Field Types
I've also identified the following field types:
Mac Address: 0x01
IP Address: 0x02
IP Subnet: 0x03
IP Gateway: 0x0b
Network Name: 0x04
Device Name: 0x0d
Dhcp Enabled: 0x10
Some Unknown IP: 0x0f
Firmware Version: 0x08
Encrypted Real Port Number: 0x13
Real Port: 0x0e
Serial Ports: 0x12
UNKNOWN1: 0x07
Configuration Error: 0x0c

Two of the fields I haven't identified yet. I do, however, suspect the 0x0f field is the SNMP traps host as it once contained this value, though I haven't been able to reproduce this.

These are only the fields for the discovery response. I haven't documented the fields/type IDs for the configuration request/response.

Strings, Data Types and Byte Order

Byte ordering is done like it is on any standard Intel based computer. So if you've done any network programming on these architectures you should be comfortable with this protocol.

Items like integers and numbers are in Little Endian byte order, so it's most significant byte first. The number 0x0219 is decimal 537, and can be calculated as ((0x02 << 8) + 0x19).

IP Addresses are done with the host byte order, so they are read as they are in the packet. So the bytes: 0x0a, 0x00, 0x00, 0x65 is the IP address: 10.0.0.101.

Further strings are (as they are usually) just a character array and has no terminator. The field's value is it's complete data part. So a string field with length 9, will have 9 data bytes which is a string of length 9. Strings are always composed of single byte ASCII characters.

Discovery Request Payload Structure
The discovery request has a single field to specify the target mac address for which you want to request the discovery. If this has as a value the MAC address ff:ff:ff:ff:ff:ff (the broadcast MAC) then all Digis will respond. You specify a specific MAC address if you want to request a response from a specific device. This field, however, has a special structure in that it doesn't have a field ID or a size. It's simply the 6 bytes for the MAC address. This is because, as I mentioned, request packets each have their own unique structure.

Here is a sample discovery request packet (header then payload):
DIGI{0x00, 0x01}{0x00, 0x06}
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}

To explain again, the header has the magic bytes DIGI, then the packet type of 0x0001, then the payload size of 0x0006 and the single field of target mac, which is the broadcast mac of ff:ff:ff:ff:ff:ff.

Discovery Response Payload Structure
The discovery response has multiple fields for each of the configuration entries. Not all of the responses contain all the fields, so these packets have their sizes differ from device to device, all depending on the configuration of the device.

A sample packet would be as follows. I broke it down into lines to demonstrate the different parts of the packet.
Total packet size: 104 bytes (8 byte header, 96 byte payload)
44 49 47 49  DIGI       - Magic
00 02  ..         - Packet type (0002)
00 60  .`         - Payload size (96 bytes)
01 06 00 40 9d 31 a9 0a  ...@.1..   - Mac address: 00:40:9D:31:A9:0A
02 04 0a 00 00 e7  ......     - IP Address: 10.0.0.231
03 04 ff ff ff 00  ......     - Subnet Mask: 255.255.255.0
0b 04 0a 00 00 01  ......     - Gateway Address: 10.0.0.1
0d
0f 44 69 67 69 20 43 6f  .Digi Co
6e 6e 65 63 74 20 4d 45  nnect ME   - Device Name: Digi Connect ME
10 01 00  ...        - DHCP Disabled
07 01 00  ...        - Unknown - never seen a non-0x00 value.
08 1e 56 65 72 73 69 6f  ..Versio
6e 20 38 32 30 30 30 38  n 820008 
35 36 5f 46 36 20 30 37  56_F6 07 
2f 32 31 2f 32 30 30 36  /21/2006   - Firmware: Version 82000856_F6 07/21/2006
0e 04 00 00 03 03  ......     - Real Port: 771
13 04 00 00 04 03  ......     - Encrypted Real Port: 1027
12 01 01  .          - Serial port count: 1
Conclusion
This is in no way the official specification of the protocol. I discovered all of this by analyzing the protocol using Wireshark and some common sense. Like I mentioned I'm also not completely done, and even if I were there might be some misinterpretations. I'll document the other packets and have the Java implementation of the protocol and utility up around the 22nd of November 2009 (edit: See my new post 'Advanced Digi Discovery Protocol Explained').

This is a proprietary protocol developed by and it's copyright owned by Digi International Inc. Use of the protocol is limited to their terms. I released this purely because I noticed a need for implementing it in your own non C and non Windows applications for managing your Digi devices. For more information see http://www.digi.com/.

1 comment:

guest said...

Actually, Digi has had a Linux version for quite some time:

http://ftp1.digi.com/support/utilities/40002188_G.src.rpm