% Cafnet
% Yang Zhang <yang@csail.mit.edu>

Overview
========

CafNet (carry and forward network) is a delay-tolerant stack that enables
mobile data muling and allows data to be sent across an intermittently
connected network.  The CafNet protocols allow cars to serve as data mules,
delivering data between nodes that are otherwise not connected to one another.
For example, these protocols could be used to deliver data from sensor
networks deployed in the field to Internet servers without requiring anything
other than short-range radio connectivity on the sensors (or at the sensor
gateway node).

Setup
=====

Requirements
------------

Cafnet depends on:

- [Python 2.5](http://python.org/)
- [setuptools 0.1](http://peak.telecommunity.com/DevCenter/setuptools)
- [Twisted](http://twistedmatrix.com/)
- [Twisted Web2](http://twistedmatrix.com/trac/wiki/TwistedWeb2/): Twisted's
  new plugin system is quirky and depends on Web2, but it is incompatible with
  Twisted 2.5.0; please use the SVN HEAD.
- [Python Commons 0.1](http://assorted.sf.net/python-commons/)

Download
--------

Download the latest release of CafNet from
<http://cartel.csail.mit.edu/cafnet/cafnet-0.1.tgz>.

Installation
------------

Cafnet is a standard setuptools package. To install it with the default
options, simply run `setup.py install`.

Usage
=====

Cafnet is a Twisted daemon plugin. Start it by running `twistd cafnet <args>`.
See `cafnet-server.bash` and `cafnet-client.bash` for examples. To see all
options and their default values, look at the file `cafnet/tap.py`.

RPC Interface
-------------

All Cafnet addresses are strings.

The **RPC interface** to Cafnet consists of the following functions.

`bind(addr: str, url: str): int`

> The client must call this after its own RPC server starts listening and
> before calling any other Cafnet procedures. `bind` registers the given
> Cafnet address `addr` with the given RPC callback URL `url` so that Cafnet
> knows where to direct its callbacks. Always returns the integer 0.

`schedule(src_addr: str, dst_addr: str, priority: int, ack_type: str, size:
          int): int`

> Schedules an ADU for delivery and returns an integer handle to the ADU.
>
> - `src_addr` must be the application's previously bound Cafnet
>   address.
> - `dst_addr` is the destination Cafnet address.
> - `priority` is an integer where a larger value corresponds to higher
>   priority.
> - `ack_type` is a string, either 'END-TO-END' or 'NONE'.
> - `size` is the length of the ADU in bytes.

The following **user callback RPC interface** is expected by Cafnet.

`get_msg(id: int): binary`

> Must return the actual ADU bytes associated with `id`, as bound by
> the `schedule` call.

`msg_received(src_addr: str, dst_addr: str, priority: int, ack_type: str, id:
              int, msg: binary): int`

> Called when an incoming ADU is received. Must return 0.
> 
> - `src_addr` is the sender's Cafnet address.
> - `dst_addr` is the destination's Cafnet address (should be the local Cafnet
>   address).
> - `priority` is the priority of the incoming message.
> - `ack_type` is a string, either 'END-TO-END' or 'NONE'.
> - `id` is the integer ID of the ADU.
> - `msg` is the body of the ADU.

`ack_received(id: int): int`

> `id` is the integer ID of the message that was returned. Must return 0.

RPC Protocol
------------

Each RPC invocation consists of the name of the procedure and the arguments,
followed by the return value from the callee to the caller. The name is a
string, and arguments and return values can only be integers or (byte)
strings. All integers are 4 bytes and big-endian. All strings consist of an
integer length followed by that many bytes.

A single TCP connection is maintained for the duration of the RPC; this may be
lazily established (i.e., the first time a call needs to be made, establish
the connection). The order of return results must correspond to the order of
their respective calls.

The protocol was designed to be fast and simple. Once upon a time, Cafnet used
XMLRPC, but that proved to be too slow on the CPU-constrained Soekris boxes,
particularly since binary blobs had to be sent around and thus base64-encoded,
and since a separate TCP connection was made per call. FastRPC was also
considered, but it bears overhead in its use of HTTP and thus per-invocation
TCP connections, as well as the extra serialization of type information.

Connectivity Updates
--------------------

To notify Cafnet that network connectivity has been lost, send the Cafnet
daemon the signal `RTMAX-9`. To notify it when connectivity has been
re-established, send signal `RTMAX-10`. The `cell-down.bash` and
`cell-up.bash` scripts do this.

Contact
=======

- Yang Zhang: <http://www.mit.edu/~y_z/>
- The CafNet homepage: <http://cartel.csail.mit.edu/cafnet/>
- The CarTel project: <http://cartel.csail.mit.edu/>

<!--
vim:et:sw=2:ts=2
-->
