DoDWAN   Documentation Download About

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 so called NAPI connection is a transport session established between the client and dodwand, during which NAPI Protocol Data Units (NAPI 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. There are two types of notifications: the notifications related to the changes of neighborhood (peers appearing and disapearing), and notifications related to the arrival of DoDWAN messages, resulting from subscriptions.

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.

Connections and sessions

A client opens a NAPI connection to the server using the underlying transport protocol (presently websocket or TCP).

The client uses the NAPI protocol on this connection. The first NAPI PDU issued by the client should be the hello command in which the client passes its (unique) id to the server. Any other command received by the server before a hello command will be answered to with an error PDU.

The reception by the server of a hello command marks the beginning of a session. During a session, the notifications generated by DoDWAN are transmitted to the client that initiated the session, on the current underlying connection, if the session is active. A session is made active once the client has issued a start command. It is made inactive when the client has issued a stop command.

Notifications generated by DoDWAN when no connection is opened or when an opened connection is non active are lost. The client may retrieve later missed subscription notifications with the get_matching command.

A connection may be closed for several reasons (unexpectedly or not). When closed, the connection is automatically considered inactive. The client is expected to retry to open the connection within the session, and, on this connection, to first issue a hello command with the continuation option set.

A session is ended explicitely by the client when this client issues a bye command.

On the server's side, the sessions are not persistent. This means that no sessions are considered opened by the server when the server restarts after having been stopped (or after a crash). The client can be aware that the server has restarted when the server responds to a hello command (with the continuation option set) with an error.

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 with 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)

Open a session

name    : hello           (string)
tkn     : <token>         (string)
client  : <client_id>     (string)
cont    : <continuation>  (boolean)

Examples (in JSON):
    {"name":"hello", "tkn":"1234", "client":"jeronimo"}
    {"name":"hello", "tkn":"1234", "client":"jeronimo", "cont":true}

After a connection has been established with the server, the first PDU the client should issue is a hello command, passing its unique client id with option 'client', in order to initiate a new session. If the hello command is used for initating a new session although the previous one has not been closed (cf. command bye), the new session overrides the old one after all current subscriptions have been deleted.

Option cont should be set to true if the client wants to continue an already initiated session, keeping all the subscriptions already set.

The server should reply to this command with an ok, or error PDU, namely when the passed client id is unknown when the session is continued.

Close a session

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

Examples (in JSON):
    {"name":"bye", "tkn":"1234"}

The client closes a session when it no longer wants to interact with the server. The server will forget the client id, remove all the subscriptions set by this client, and close the underlying connection.

The server will not send any reply to this command, unless an internal error occurs, in which case and error response PDU will be issued.

Start the reception of notifications

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

Example (in JSON):
    {"name":"start", "tkn":"1234"}

Indicates to the server that DoDWAN notifications should now be transmitted to the client. Note that notification generated previously by DoDWAN are not transmitted.

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

Stop the reception of notifications

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

Example (in JSON):
    {"name":"stop", "tkn":"1234"}

Indicates to the server that DoDWAN should now stop transmitting notifications to the client.

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

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.

Send a D2D message to a given peer

name   : send_to_peer  (string)
tkn    : <token>       (string)
mid    : <msg_id>      (string) 
dest   : <pid>         (string)
desc   : <descriptor>  (smap) 
expire : <date>        (int64)

Immediatly sends a message (only descriptor) to the given peer provided this peer is actually a neighbor.

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

Broadcast a D2D message to all the current peers

name   : broadcast_to_peers  (string)
tkn    : <token>             (string)
mid    : <msg_id>            (string)
desc   : <descriptor>        (smap) 
expire : <date>              (int64)

Immediatly broadcast a message (only descriptor) to all the current neighbors.

The server should reply to this command with an ok or error response PDU (only if all the sendings failed).

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_pids 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) 
key    : <subs_key>    (string)
desc   : <descriptor>  (smap) 
ferror : <reason>      (string)

Example (in JSON):
    {"name":"recv_msg", "mid":"3f56fr67", "key":"subscr42", "desc":{"_docid":"3f56fr67", "_date":"1516183647000", "topic":"general", "language":"en"}} 
    {"name":"recv_msg", "tkn":"r1234",  "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, as well as the key of the subscription that has induced the message reception.

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 a command from the client for a message descriptor (see command get_desc), command that bore this token. In this case, the key option is not present.

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.

D2D message received

name   : recv_from_peer  (string)
tkn    : <token>         (string)
mid    : <msg_id>        (string) 
desc   : <descriptor>    (smap)

This PDU is received when a D2D message is received from a neighbor, either sent to the local peer or broadcasted to all the current neighbors.

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_pids 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 implementation 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 0x00).