diff -r 000000000000 -r 2b3e5ec03512 servlib/prophet/BaseTLV.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servlib/prophet/BaseTLV.h Thu Apr 21 14:57:45 2011 +0100 @@ -0,0 +1,132 @@ +/* + * 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_BASE_TLV_H_ +#define _PROPHET_BASE_TLV_H_ + +#include +#include + + +namespace prophet +{ + +template +struct TLVFactory +{ + /** + * Factory method for deserializing over-the-wire TLV into + * in-memory class representation + */ + static TLV* deserialize(const u_char* bp, size_t len) + { + TLV* t = new TLV(); + if (t->deserialize(bp,len)) + return t; + delete t; + return NULL; + } +}; + +/** + * The Prophet I-D (March 2006) dictates five bytecodes for router + * state exchange messages. This implementation introduces a sixth + * to help differentiate Bundle offers from Bundle responses. + * + * Each Prophet router is a state machine. Each encounter with + * another router requires an exchange of router state. This begins + * with a synchronization phase (Hello), followed by an exchange + * of route tables (Information Exchange). + * + * BaseTLV is the abstract base class from which each concrete + * class derives its API. + */ +class BaseTLV +{ +public: + /** + * Byte codes for TLV types + */ + typedef enum { + UNKNOWN_TLV = 0x00, + HELLO_TLV = 0x01, + ERROR_TLV = 0x02, + RIBD_TLV = 0xA0, + RIB_TLV = 0xA1, + OFFER_TLV = 0XA2, + RESPONSE_TLV = 0XA3, // not in spec + } prophet_tlv_t; + + /** + * Pretty print function for prophet_tlv_t. + */ + static const char* + tlv_to_str(prophet_tlv_t tlv) + { + switch(tlv) { + case HELLO_TLV: return "HELLO_TLV"; + case RIBD_TLV: return "RIBD_TLV"; + case RIB_TLV: return "RIB_TLV"; + case OFFER_TLV: return "OFFER_TLV"; + case RESPONSE_TLV: return "RESPONSE_TLV"; + case ERROR_TLV: + case UNKNOWN_TLV: + default: return "Unknown TLV type"; + } + } + + /** + * Destructor + */ + virtual ~BaseTLV() {} + + /** + * Write out TLV from in-memory representation into + * provided buffer, using no more than len bytes, returning + * bytes written + */ + virtual size_t serialize(u_char* bp, size_t len) const = 0; + + ///@{ Accessors + prophet_tlv_t typecode() const { return typecode_; } + u_int8_t flags() const { return flags_; } + u_int16_t length() const { return length_; } + ///@} + +protected: + + /** + * Constructor is protected to force use of factory + */ + BaseTLV(prophet_tlv_t typecode = UNKNOWN_TLV, + u_int8_t flags = 0, + u_int16_t length = 0) + : typecode_(typecode), flags_(flags), length_(length) {} + + /** + * Read a TLV in from transport and copy its contents into memory + */ + virtual bool deserialize(const u_char* bp, size_t len) = 0; + + prophet_tlv_t typecode_; ///< typecode for this TLV + u_int8_t flags_; ///< TLV-specific flags + mutable u_int16_t length_; ///< serialized length of TLV, mutable so it + /// can be assigned by serialize() const +}; // class BaseTLV + +}; // namespace prophet + +#endif // _PROPHET_BASE_TLV_H_