
All links in the system have a state variable, described in the enum
(copied from Link.h):

typedef enum {
    UNAVAILABLE,    ///< The link is closed and not able to be
                    ///  opened currently.

    AVAILABLE,      ///< The link is closed but is able to be
                    ///  opened, either because it is an on demand
                    ///  link, or because an opportunistic peer
                    ///  node is in close proximity but no
                    ///  convergence layer session has yet been
                    ///  opened.
    
    OPENING,        ///< A convergence layer session is in the
                    ///  process of being established.
    
    OPEN,           ///< A convergence layer session has been
                    ///  established, and the link has capacity
                    ///  for a bundle to be sent on it. This may
                    ///  be because no bundle is currently being
                    ///  sent, or because the convergence layer
                    ///  can handle multiple simultaneous bundle
                    ///  transmissions.
    
    BUSY,           ///< The link is busy, i.e. a bundle is
                    ///  currently being sent on it by the
                    ///  convergence layer and no more bundles may
                    ///  be delivered to the link.

   CLOSED           ///< Bogus state that's never actually used in
                    ///  the Link state_ variable, but is used for
                    ///  signalling the daemon thread with a
                    ///  LinkStateChangeRequest
    
} state_t;

To enforce coordination between the threads and correct notification
of events to routers, only the BundleDaemon thread can change the
state of a link directly. All other threads should post a
LinkStateChangeRequest event to the bundle daemon queue. 

One exception to this is the setting up of the initial link state when
a link is created. For OPPORTUNISTIC and SCHEDULED links, the initial
state is UNAVAILABLE. For ONDEMAND and ALWAYSON links, the initial
state is AVAILABLE. ALWAYSON links also immediately post an event to
attempt to open the link by posting a link state change request of
OPENING.

XXX/demmer this isn't really true -- the connection reestablishement
code in the TCPCL currently sets the state to OPENING from UNAVAILABLE
before sending a ContactUpEvent. This should be fixed.

---

Link state changes can be broadly divided into two classes: top-down
and bottom-up. The former refers to cases where a control or
management layer determines that a link should open (or close), i.e. a
user configuration command, or a scheduled link timer (when that gets
implemented). The latter refers to cases where the underlying
transport or convergence layer determines that either a link has
opened opportunistically or that link is closed due to a network
timeout, error, or an idle ONDEMAND connection.

When the link availability changes, a LinkAvailableEvent /
LinkUnavailableEvent is delivered to the router(s).

---

There is also the Contact structure, which is conceptually a tuple of
[link, time interval] for open links. Currently, a contact is created
in Link::open and deleted (i.e. dereferenced) in Link::close. A
Contact is also created by convergence layers when opportunistic
connections are established. These contacts are then attached to
existing idle opportunistic links, or if none exist, new opportunistic
links are created.

At the beginning and end of a contact opportunity, a ContactUpEvent
and ContactDownEvent are delivered to inform the router(s). These plus
the link availability events are all the notifications that the
router(s) see currently. When a link goes down unexpectedly, 

---

To effect some flow control between the network layer(s) and the main
bundle daemon, the link has a BUSY state that should be respected by
the routers in that they should not call send_bundle on a busy link.
For connection oriented CLs, the queue that manages bundle flow
between the main thread and the CL thread can be capped at a maximum
depth, which when exceeded, will put the link into BUSY state. The
connection thread should check for this state when a bundle is sent
out and deliver a LinkAvailableEvent to re-enable the link and inform
the router(s) that there is a new opportunity to send bundles.

XXX/demmer this is strange w.r.t. the router interface since they
don't get notified when the link becomes busy, but they do get
notified when the link is available again... i should really add a
LinkBusyEvent

---

The following 
