Protocol for the DoDWAN Network API

DoDWAN offers a network API accessible through the dodwand DoDWAN daemon.

The DoDWAN daemon implements a server to which application clients can connect. A transport session is established between the client and dodwand, during which Data Units (PDUs) are exchanged. The transport mechanism is not implemented by the dodwan-napi plugin itself but by a descendent plugin (e.g., dodwan-napi-tcp).

A PDU is a serialized map. The serialization method implemented by an instance of the NAPI plugin can be chosen among several methods (presently: JSON or BSON).

A PDU issued by a client is a command PDU (e.g., publish). It is expected that the server answers (promptly) to a command with a response PDU. A token is included in the command and is copied in the corresponding response by the server to ensure command-response matching.

A PDU issued by the DoDWAN server is a response to a command or a notification. A notification is not directly linked to a unique command, even if it is a consequence of a command.

PDUs are maps, composed of a series of key/value pairs. The order of these pairs is not relevant. For a given command, response or notification, a number of pairs are compulsory, and some are optional. Note that the pair with key name is always present in a PDU. Each value in a pair has a given type among the following seven types:

The null value is not authorized.

DoDWAN Descriptors

A DoDWAN message is composed of descriptor and a payload. A message descriptor is a list of attribute assignments, comprising each a key and a string value. The attributes are either system attributes (whose key starts with the undescore sign), or application attributes (whose key doesn't start the undescore sign).

The DoDWAN message descriptors used in the Network API commands of type smap.

When providing a descriptor (in the publish command) the user should provide only application attributes. Any number of application attributes can be provided (possibly no attribute at all).

Received decriptors may include also system attributes, set by the DoDWAN middleware. For example:

Example of a descriptor (in JSON)

{"_docid":"35465tr5", "_date":"1516183647000", "topic":"general", "type":"PDF"}

Commands (issued by the application client and received by the server)

Publish a message

name   : publish       (string)
tkn    : <token>       (string)
mid    : <msg_id>      (string) 
desc   : <descriptor>  (smap) 
file   : <file_path>   (string) 
data   : <payload>     (binary)
dummy  : <size>        (int32)
expire : <date>        (int64)

Examples (in pseudo-JSON):
  {"name":"publish", "tkn":"1234", "mid":"3f56fr67", "desc":{"topic":"general", "language":"en"}, "data":...0x5 0x00...}
  {"name":"publish", "tkn":"1234", "desc":{"topic":"DTN"}, "data":...0x5 0x00..., "expire":1516183647000}
  {"name":"publish", "tkn":"1234", "desc":{"type":"JPG"}, "file":"/tmp/myimage.jpg"}

Publishes a message. The message id should be unique. If no id is provided, the system will choose one itself. The descriptor is compulsory.

The payload of the message is either the content of a file (option file) whose name is provided, binary data (option data), or a dummy content of <size> bytes (option dummy). If more than one of these three options is present in the command, only one is taken into account, in the order file, data, dummy. At least one of these three options should be specified.

Optionally, one can specify an expiration date for the message, formatted as a long integer (number of ms since Unix EPOCH).

The server should reply to this command with an ok or error response PDU.

Add a subscription

name    : add_sub             (string)
tkn     : <token>             (string)
key     : <subs_key>          (string)
desc    : <descriptor>        (string)
dir     : <directory_path>    (string)

Examples (in JSON):
  {"name":"add_sub", "tkn":"1234", "key":"subscr42", "desc":{"name":".*PDF|.*pdf", "topic":".*DTN.*|Opportunistic","language":"en"}}
  {"name":"add_sub", "tkn":"1234", "key":"mysub", "desc":{"topic":"general"}, "dir":"/home/john/tmp", "naming":"fname"}

Adds a subscription with a pattern specified in the given <descriptor>. The subscription is identified by a key that is assumed to be unique. The syntax of this key is the same as the syntax of an attribute key in a message descriptor.

The specified pattern is a descriptor that contains a number of attributes (those we wish to base the selection upon), that carries each a value that is a standard Java regular expression that will be applied in order to find matching messages.

Optionally, a directory path can be specified with the dir option, in which case the payload of the message is to be written upon reception to a file in the given directory (see notification recv_msg). This option makes sense only if the given file is accessible both on the DoDWAN server and on the client (typically because they are on the same host). By default, the name of the file will be the id of the message. However if the file attribute is present in the descriptor of the received message, the value of this attribute will serve as a file name. Note that it is the responsiblity of the publisher to add this file attribute in the descriptor of the message to be sent. To prevent writing a file outside directory <directory_path>, a file name pointing to a parent directory (starting with ..) ---whether this file name results from a file attribute, or the message id--- will generate an error upon message reception (see option ferror of notification recv_msg).

The server should reply to this command with an ok or error response PDU.

Remove subscriptions

name : remove_sub    (string)
tkn  : <token>       (string)
subs : <keys_array>  (sarray)

Example (in JSON):
  {"name":"remove_sub", "tkn":"1234", "subs":["subscr42", "mysub", "sub56"]}

Removes a set of subscription, and so stops receiving the corresponding messages. The syntax of a key is the same as the syntax of an attribute key in a message descriptor.

The subscriptions are passed as an array of susbscription keys.

The server should reply to this command with an ok or error response PDU.

Obtain the descriptor of a msg

name : get_desc  (string)
tkn  : <token>   (string)
mid  : <msg_id>  (string) 

Example (in JSON):
  {"name":"get_desc", "tkn":"1234", "mid":"76rf41gh"}

Asks the DoDWAN server for the descriptor of a given message present in the cache.

The server should reply to this command with a recv_desc or error PDU.

Obtain the payload of a message

name : get_payload  (string)
tkn  : <token>      (string)
mid  : <msg_id>     (string) 
file : <file_path>  (string) 

Examples (in JSON):
  {"name":"get_payload", "tkn":"1234", "mid":"76rf41gh", "file":"/tmp/mypayload.dat"}
  {"name":"get_payload", "tkn":"1234", "mid":"76rf41gh"}

After being notified that a message is received, a client knows only the id of the message and its descriptor. In most cases (i.e. unless the payload is known to be empty or of no interest) the client should then try to obtain the payload of the message. For this, the client issues a get_payload command so that the DoDWAN server makes the payload available to the client.

This payload is transmitted as binary data, unless the option file is present, in which case the payload is written in the specified file.

The server should reply to this command with a recv_payload or error PDU.

If the dir option had been used in the subscription command, the payload should already be accessible in the given directory when the message reception notication has arrived at the client. So, in this case, there is no need for the client to issue a get_payload command.

Obtain the ids of messages matching some subscriptions

name : get_matching   (string)
tkn  : <token>        (string)
subs : <keys_array>   (sarray)

Example (in JSON):
  {"name":"get_matching", "req":"req1234", "subs":["subscr42", "mysub", "sub56"]}

Asks for the ids of the messages present in the DoDWAN cache that match one of the given subscriptions. The subscriptions must have been previoulsy added (see command add_sub).

The server should reply to this command with a recv_mids or error PDU.

Obtain the ids of the peers in contact

name : get_peers   (string)
tkn  : <token>     (string)

Example (in JSON):
  {"name":"get_peers", "tkn":"r1234"}

Asks for the ids of the peers that are currently in contact.

The server should reply to this command with a recv_peers or error PDU.

Obtain the id of the local peer

name : get_my_peer   (string)
tkn  : <token>       (string)

Example (in JSON):
  {"name":"get_my_peer", "tkn":"r1234"}

Asks for the id of the local peer.

The server should reply to this command with a recv_my_pid or error PDU.

Ping the server

name : ping     (string)
tkn  : <token>  (string)

Pings the server.

The server should reply to this command with a pong PDU.

Responses and notifications (issued by the server and received by the client)

Message descriptor received

name   : recv_desc     (string)
tkn    : <token>       (string)
mid    : <msg_id>      (string) 
desc   : <descriptor>  (smap) 
ferror : <reason>      (string)

Example (in JSON):
  {"name":"recv_msg", "mid":"3f56fr67", "desc":{"_docid":"3f56fr67", "_date":"1516183647000", "topic":"general", "language":"en"}}

When receiving this PDU, the client is notified that DoDWAN has received a message (resulting from a previous subscription). The message id and the full descriptor of the message are provided.

If option ferror is present, that means that the subscription stipulated that the payload of the message was to be written to a file (see option dir of command add_sub) but the writing of the file generated an error.

If a token is provided, that means that the PDU is received as a response to command from the client for a message descriptor (see command get_desc), command that bore this token.

Payload received

name : recv_payload      (string)
tkn  : <token>           (string)
mid  : <msg_id>          (string) 
data : <payload>         (binary)
expired : <msg_expired>  (boolean)


Examples (in pseudo-JSON):
  {"name":"recv_payload", "tkn":"r1234", "mid":"6fdhuy87", "data":...0x05 0x00...}
  {"name":"recv_payload", "tkn":"r1234", "mid":"6fdhuy87", "expired":true}

When receiving this PDU, the client is provided with the payload of a message, payload that was previously asked for by issuing a get_payload command. The id of the message is given, as well as the payload as binary data. If the data option is not present, that means that the payload has been written in a file, as specified in the get_payload command.

It may happen that the message has expired between the reception notification and the time at which the get_payload command was received by the DoDWAN server. In this case, the option expired is given in the command.

Message ids received

name : recv_mids    (string)
tkn  : <token>      (string)
mids : <mid_array>  (sarray)

Example (in JSON):
  {"name":"recv_ids", "tkn":"r1234", "mids":["6fdhuy87", "k8ytrfr65e", "memo_6"]}

This PDU is received in response to a get_matching command. It provides a list of message ids, the ids of the messages that matched one of the subscriptions specified in the request.

Pong

name : pong     (string)
tkn  : <token>  (string)

Example (in JSON):
  {"name":"pong", "tkn":"r1234"}

Reply to a ping request (used for keepalive implementation).

Local peer received

name : recv_my_pid  (string)
tkn  : <token>      (string)
pid  : <pid>        (string)

Example (in JSON):
  {"name":"recv_my_pid", "tkn":"r1234", "pid":"HT345422"}

This PDU is received in response to a get_my_peer request. It provides the id of the local peer.

Peer ids received

name : recv_pids  (string)
tkn  : <token>    (string)
pids : <pids>     (sarray)

Example (in JSON):
  {"name":"recv_pids", "tkn":"r1234", "pids":["HTC3456", "zeus", "tablet02"]}

This PDU is received in response to a get_peers request. It provides a list of peer ids, the ids of the peers that are currently in contact.

Peer added

name : add_peer    (string)
pid  : <peer_id>   (string)

Example (in JSON):
  {"name":"add_peer", "pid":"HT345422"}

This PDU is received when the server is informed that a new DoDWAN peer is in contact with DoDWAN. The unique id of this peer is provided.

Peer removed

name : remove_peer   (string)
pid  : <peer_id>     (string)

Example (in JSON):
  {"name":"remove_peer", "pid":"HT345422"}

This PDU is received when the server is informed that DoDWAN has lost contact with a peer. The unique id of this peer is provided. This peer should have been cited in a previoulsy received add_peer or recv_peers PDU.

Peers cleared

name : clear_peers   (string)

Example (in JSON):
  {"name":"clear_peers"}

This PDU is received when the client should consider that no peers are in contact.

Success response

name : ok       (string)
tkn  : <token>  (string)

Example (in JSON):
  {"name":"ok", "tkn":"r1234"}

This PDU is received in response to a command PDU that has been successfuly received and handled by the server.

Error response

name   : error     (string)
tkn    : <token>   (string)
reason : <reason>  (string)

Examples (in JSON):
  {"name":"error"} 
  {"name":"error", "tkn":"r1234", "reason":"Missing token in PDU"}

This PDU is received in response to a command PDU that has been received by the server but for which an error occured when the server tried to interpret or execute the command. Optionally, the server may provide a reason for this error. The token may not be present, in the case it was absent from the command (which is sufficient for generating the error).

Notes on PDU serialization

JSON

With the JSON serialization, a PDU is serialized as a plain JSON document whose top object is a map.

JSON makes no difference between numbers and JSON implementations may store numbers in various formats. The implemenation of the DoDWAN Network API should ensure that int32 and int64 values present in PDUs are stored with enough precision.

The binary data values (values of type binary) are encoded in Base64.

BSON

With the BSON serialization, a PDU is serialized as a plain BSON document (see http://bsonspec.org/spec.html).

Arrays of strings (values of type sarray) present in PDUs are coded as normal BSON maps (with integer values for indexes).

Binary data (values of type binary) are coded with the generic binary subtype (code Ox00).