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:
string
)int32
)int64
)boolean
)binary
)smap
)sarray
)The null value is not authorized.
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.
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:
_docid
the id of the message, assumed to be unique
_date
the date of reception of the message (a string containing a 64-bit integer equals to the number of ms since Unix EPOCH, e.g., "1516183647000")
_dline
the date of expiration of the message (a string containing a 64-bit integer equals to the number of ms since Unix EPOCH)
{"_docid":"35465tr5", "_date":"1516183647000", "topic":"general", "type":"PDF"}
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
name : ping (string)
tkn : <token> (string)
Pings the server.
The server should reply to this command with a pong
PDU.
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.
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.
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.
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.
name : pong (string)
tkn : <token> (string)
Example (in JSON):
{"name":"pong", "tkn":"r1234"}
Reply to a ping request (used for keepalive implementation).
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.
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.
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.
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.
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.
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.
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).
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.
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).