IBR-DTNSuite  0.8
daemon/src/routing/NodeHandshake.h
Go to the documentation of this file.
00001 /*
00002  * NodeHandshake.h
00003  *
00004  *  Created on: 09.12.2011
00005  *      Author: morgenro
00006  */
00007 
00008 #ifndef NODEHANDSHAKE_H_
00009 #define NODEHANDSHAKE_H_
00010 
00011 #include "routing/SummaryVector.h"
00012 #include <ibrdtn/data/SDNV.h>
00013 #include <iostream>
00014 #include <sstream>
00015 #include <list>
00016 #include <set>
00017 #include <map>
00018 
00019 namespace dtn
00020 {
00021         namespace routing
00022         {
00023                 class NodeHandshakeItem
00024                 {
00025                 public:
00026                         enum IDENTIFIER
00027                         {
00028                                 BLOOM_FILTER_SUMMARY_VECTOR = 1,
00029                                 BLOOM_FILTER_PURGE_VECTOR = 2,
00030                                 DELIVERY_PREDICTABILITY_MAP = 3,
00031                                 PROPHET_ACKNOWLEDGEMENT_SET = 4
00032                         };
00033 
00034                         virtual ~NodeHandshakeItem() { };
00035                         virtual size_t getIdentifier() const = 0;
00036                         virtual size_t getLength() const = 0;
00037                         virtual std::ostream& serialize(std::ostream&) const = 0;
00038                         virtual std::istream& deserialize(std::istream&) = 0;
00039                 };
00040 
00041                 class BloomFilterSummaryVector : public NodeHandshakeItem
00042                 {
00043                 public:
00044                         BloomFilterSummaryVector();
00045                         BloomFilterSummaryVector(const SummaryVector &vector);
00046                         virtual ~BloomFilterSummaryVector();
00047                         size_t getIdentifier() const;
00048                         size_t getLength() const;
00049                         std::ostream& serialize(std::ostream&) const;
00050                         std::istream& deserialize(std::istream&);
00051                         static size_t identifier;
00052 
00053                         const SummaryVector& getVector() const;
00054 
00055                 private:
00056                         SummaryVector _vector;
00057                 };
00058 
00059                 class BloomFilterPurgeVector : public NodeHandshakeItem
00060                 {
00061                 public:
00062                         BloomFilterPurgeVector();
00063                         BloomFilterPurgeVector(const SummaryVector &vector);
00064                         virtual ~BloomFilterPurgeVector();
00065                         size_t getIdentifier() const;
00066                         size_t getLength() const;
00067                         std::ostream& serialize(std::ostream&) const;
00068                         std::istream& deserialize(std::istream&);
00069                         static size_t identifier;
00070 
00071                         const SummaryVector& getVector() const;
00072 
00073                 private:
00074                         SummaryVector _vector;
00075                 };
00076 
00077                 class NodeHandshake
00078                 {
00079                 public:
00080                         enum MESSAGE_TYPE
00081                         {
00082                                 HANDSHAKE_INVALID = 0,
00083                                 HANDSHAKE_REQUEST = 1,
00084                                 HANDSHAKE_RESPONSE = 2
00085                         };
00086 
00087                         NodeHandshake();
00088                         NodeHandshake(MESSAGE_TYPE type, size_t lifetime = 60);
00089 
00090                         virtual ~NodeHandshake();
00091 
00092                         void addRequest(const size_t identifier);
00093                         bool hasRequest(const size_t identifier) const;
00094                         void addItem(NodeHandshakeItem *item);
00095                         bool hasItem(const size_t identifier) const;
00096 
00097                         size_t getType() const;
00098                         size_t getLifetime() const;
00099 
00100                         friend std::ostream& operator<<(std::ostream&, const NodeHandshake&);
00101                         friend std::istream& operator>>(std::istream&, NodeHandshake&);
00102 
00103                         template<class T>
00104                         T& get();
00105 
00106                 private:
00107                         class StreamMap
00108                         {
00109                         public:
00110                                 StreamMap();
00111                                 ~StreamMap();
00112                                 void clear();
00113                                 std::stringstream& get(size_t identifier);
00114                                 void remove(size_t identifier);
00115                                 bool has(size_t identifier);
00116 
00117                         private:
00118                                 std::map<size_t, std::stringstream* > _map;
00119                         };
00120 
00121                         NodeHandshakeItem* getItem(const size_t identifier) const;
00122                         void clear();
00123 
00124                         size_t _type;
00125                         size_t _lifetime;
00126 
00127                         std::set<size_t> _requests;
00128                         std::list<NodeHandshakeItem*> _items;
00129                         StreamMap _raw_items;
00130 
00131                         // deny copying
00132                         NodeHandshake& operator=( const NodeHandshake& ) { return *this; };
00133                 };
00134 
00135                 template<class T>
00136                 T& NodeHandshake::get()
00137                 {
00138                         NodeHandshakeItem *item = getItem(T::identifier);
00139 
00140                         if (item == NULL)
00141                         {
00142                                 // check if the item exists
00143                                 if (!_raw_items.has(T::identifier))
00144                                         throw ibrcommon::Exception("item not available");
00145 
00146                                 T *item_template = new T();
00147                                 item_template->deserialize( _raw_items.get(T::identifier) );
00148 
00149                                 // remove the raw item
00150                                 _raw_items.remove(T::identifier);
00151 
00152                                 // put item into the itemMap
00153                                 _items.push_back(item_template);
00154 
00155                                 return (*item_template);
00156                         }
00157 
00158                         return dynamic_cast<T&>(*item);
00159                 }
00160         } /* namespace routing */
00161 } /* namespace dtn */
00162 #endif /* NODEHANDSHAKE_H_ */