servlib/prophet/HelloTLV.h
changeset 0 2b3e5ec03512
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servlib/prophet/HelloTLV.h	Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,159 @@
+/*
+ *    Copyright 2007 Baylor University
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef _PROPHET_HELLO_TLV_H_
+#define _PROPHET_HELLO_TLV_H_
+
+#include <string>
+#include "BaseTLV.h"
+
+namespace prophet
+{
+
+class HelloTLV : public BaseTLV
+{
+public:
+    /**
+     * Hello TLV header<br>
+     * p. 25, 4.4.1<br>
+     * <br>
+     * The Hello TLV is used to set up and maintain a link between two
+     * PRoPHET nodes.  Hello messages with the SYN function are transmitted
+     * periodically as beacons.  The Hello TLV is the first TLV exchanged
+     * between two PRoPHET nodes when they encounter each other.  No other
+     * TLVs can be exchanged until the first Hello sequenece is completed.<br>
+     * <br>
+     * Once a communication link is established between two PRoPHET nodes,
+     * the Hello TLV will be sent once for each interval as defined in the
+     * interval timer.  If a node experiences the lapse of HELLO_DEAD Hello
+     * intervals without receiving a Hello TLV on an ESTAB connection (as
+     * defined in the state machine in Section 5.2), the connection SHOULD
+     * be assumed broken.
+     */
+    struct HelloTLVHeader {
+        u_int8_t type; ///< defined as 0x01
+        u_int8_t unused__:5;
+        /**
+         * Specifies the function of the Hello TLV.  Four functions are
+         * specified for the Hello TLV:
+         * <br>
+         *       SYN:     HF = 1<br>
+         *       SYNACK:  HF = 2<br>
+         *       ACK:     HF = 3<br>
+         *       RSTACK:  HF = 4.<br>
+         */
+        u_int8_t HF:3;
+        /**
+         * Length of the TLV in octets, including the TLV header and any
+         * nested TLVs.
+         */
+        u_int16_t length;
+        /**
+         * The Timer field is used to inform the receiver of the timer
+         * value used in the Hello processing of the sender.  The timer
+         * specifies the nominal time between periodic Hello messages.  It
+         * is a constant for the duration of a session.  The timer field is
+         * specified in units of 100ms.
+         */
+        u_int8_t timer;
+        /**
+         * The Name Length field is used to specify the length of the
+         * Sender Name field in octets.  If the name has already been sent
+         * at least once in a message with the current Sender Instance, a
+         * node MAY choose to set this field to zero, omitting the Sender
+         * Name from the Hello TLV.
+         */
+        u_int8_t name_length;
+        /**
+         * The Sender Name field specifies the routable DTN name of the
+         * sender that is to be used in updating routing information and
+         * making forwarding decisions.
+         */
+        u_char sender_name[0];
+    } __attribute__((packed));
+
+    static const size_t HelloTLVHeaderSize = sizeof(struct HelloTLVHeader);
+
+    /**
+     * Legal values for HelloTLVHeader.HF (hello function)
+     * p. 25, 4.4.1
+     */
+    typedef enum {
+        HF_UNKNOWN  = 0x0,
+        SYN         = 0x1,
+        SYNACK      = 0x2,
+        ACK         = 0x3,
+        RSTACK      = 0x4
+    } hello_hf_t;
+
+    static const char*
+    hf_to_str(hello_hf_t hf)
+    {
+        switch(hf) {
+            case SYN:    return "SYN";
+            case SYNACK: return "SYNACK";
+            case ACK:    return "ACK";
+            case RSTACK: return "RSTACK";
+            case HF_UNKNOWN:
+            default:              return "Unrecognized prophet HF code";
+        }
+    }
+
+    /**
+     * Constructor.
+     */
+    HelloTLV(hello_hf_t hf,
+             u_int8_t timer,
+             const std::string& sender);
+ 
+    /**
+     * Destructor
+     */
+    virtual ~HelloTLV() {}
+
+    /**
+     * Virtual from BaseTLV.
+     */
+    size_t serialize(u_char* bp, size_t len) const;
+
+    ///@{ Accessors
+    hello_hf_t  hf()     const { return hf_; }
+    const char* hf_str() const { return hf_to_str(hf_); }
+    u_int8_t    timer()  const { return timer_; }
+    std::string sender() const { return sender_; }
+    ///@}
+
+protected:
+    friend class TLVFactory<HelloTLV>;
+
+    /**
+     * Constructor.  Protected to force access through TLVFactory.
+     */
+    HelloTLV();
+
+    /**
+     * Virtual from BaseTLV.
+     */
+    bool deserialize(const u_char* bp, size_t len);
+
+    hello_hf_t hf_; ///< Hello function bytecode
+    u_int8_t   timer_; ///< Units of 100ms between Hello messages
+    std::string sender_; ///< endpoint id of sender
+}; // class HelloTLV
+
+}; // namespace prophet
+
+#endif // _PROPHET_HELLO_TLV_H_