-
Notifications
You must be signed in to change notification settings - Fork 62
dtntrigger
The dtntrigger tool can be used to receive bundles and executing programs to act on them. Different from dtnrecv, dtntrigger will continue to listen forever, and since dtntrigger skripts can also call the dtnsend tool, allows interactive applications.
As an example we will write small pager application: dtnsend is used to send small snippets of text to a master node, that will display them. So the users should be able to do
echo "Hello World" | dtnsend dtn://master/pager
the dtn://master node will have a program that listens to the pager application and display received text. To do this we invoke dtntrigger on the master node as follows
dtntrigger pager ./sink.sh
"pager" ist the application endpoint, so this is an arbitrary string, but it should be the same wu used for dtnsend. Now when you send bundles to dtn://master/pager , dtntrigger will try to execute the sink.sh script and fail, because it does not exist. (but afterwards it will listen again, so you can make it fail again, and again, and again...)
In fact the second parameter for dtntrigger can be any executable no matter ist is a C Program, a shell script, a Python script... As long as it is executable it is fine for dtntrigger. dtgntrigger calls that executable, where the first parameter is the dtn source endpoint where a bundle comes form and the second parameter is the path of a file where the bundle payload is stored. So in our example we will do some safety checks and display the Content (or part of it) in the console
dtntrigger will call the skript sequentially for every received bundle. There is no parallelism.
#!/bin/bash
#
# sikn.sh example Called from dtntrigger
#
# Print received messages. Does some sanity checks...
#
MAXPREVIEW=250
#First parameter is source EID, second is path to palyload
src=$1
payload=$2
toprint=$(head -c $MAXPREVIEW $payload | strings -n 1 -e S )
actualsize=$(wc -c "$payload" | cut -f 1 -d ' ')
echo -n "$src said: $toprint"
if [ "$actualsize" -gt "$MAXPREVIEW" ]
then
echo -n "..."
fi
echo " ($actualsize bytes)"
It is not necessary (but does not hurt) to delete the payload file after the application is done with it.
Example output when sending a bundle with
echo "Hello World" | dtnsend dtn://master/pager
echo "In fact, DTN is cool" | dtnsend dtn://master/pager
$ dtntrigger pager ./sink.sh
dtn://node1/wpHZDQoTvKOHFtHi said: Hello World (12 bytes)
dtn://node1/ULnizzySqKtvTVaY said: In fact, DTN is cool (22 bytes)
It is easy to build interactive applications, in the example the script could use the $src parameter to do that:
echo "I hear you" | dtnsend $src
However, as you could see form the example output, dtnsend usually uses a random sender endpoint. Therefore the original sender would not know on which endpoint to listen for replies. This is easily remedied by dtnsends src parameter
echo "In fact, DTN is cool" | dtnsend --src replyme dtn://master/pager
which gives
dtn://node1/replyme said: In fact, DTN is cool (22 bytes)
So node1 could have dtntrigger script (or an application linked with IBR-DTN) listening on the "replyme" application endpoint to receive answers form the script
dtntrigger can also listen to groups. The --g paramter binds it to a group. However, there is a catch: Due to API reasons, you still need to give an normal application endpoint also. To make the script listen to a group start dtntrigger
dtntrigger pager -g dtn://mygroup ./sink.sh
and dtnsend like this
echo "In fact, DTN is cool" | dtnsend -g dtn://mygroup
Because we were still required to give a normal endpoint in dtntrigger it will not only listen to the dtn://mygroup endpoint, but also to the pager application endpoint
dtntrigger starts the executable for every bundle that arrives. If your application is a 300MB Java Monster that needs DTN access, it is not feasible to let dtntrigger start it every time. Common patterns for this use case are a a named pipe in the filesystem or a socket opened by the main application. Then the dtntrigger script will only do simple preprocessing and then stuff the necessary application data to the running application using the pipe or the socket.
However, for more comprehensive access to the DTN capabilities or better performance for more complex tasks you should look at the appropriate C++ or Java APIs for IBR-DTN