00001 #ifndef _TOPOLOGY_H__
00002 #define _TOPOLOGY_H__
00003
00004 #include <map>
00005 #include <vector>
00006 #include <string>
00007
00008 #include <gea/Time.h>
00009 #include <gea/Blocker.h>
00010
00011 #include <awds/routing.h>
00012 #include <awds/NodeId.h>
00013 #include <awds/settings.h>
00014 #include <awds/Callback.h>
00015
00016 #include <awds/routing.h>
00017
00018 #include <iostream>
00019
00020 namespace awds {
00021
00022 class Metric;
00023
00024 class TopoPacket;
00025 class RTopology;
00026
00027
00032 class RTopology {
00033
00034 gea::Blocker cleanup_blocker;
00035
00036 public:
00037 bool verbose;
00038 Metric *metric;
00039
00040 char nodeName[32];
00041
00042 static void cleanup_nodes(gea::Handle *h, gea::AbsTime t, void *data);
00043
00044 typedef uint16_t link_quality_t;
00045 static link_quality_t max_quality() { return 0xFFFFu; }
00046
00047 class LinkList;
00048 class AdjList;
00049
00052 class LinkQuality {
00053 protected:
00054 public:
00055 LinkQuality *counterpart;
00056
00057 NodeId neighbor;
00059 link_quality_t quality;
00060 unsigned long metric_weight;
00062 LinkQuality &operator=(const LinkQuality& lq) {
00063 counterpart = lq.counterpart;
00064 neighbor = lq.neighbor;
00065 quality = lq.quality;
00066 metric_weight = lq.metric_weight;
00067
00068 if (counterpart) {
00069 counterpart->counterpart = this;
00070 }
00071 return *this;
00072 }
00073
00074 LinkQuality(LinkQuality const &lq) {
00075 *this = lq;
00076 }
00077
00078 LinkQuality():counterpart(0),quality(0),metric_weight(0) {}
00079
00080 LinkQuality(NodeId n, link_quality_t w):
00081 counterpart(0),
00082 neighbor(n),
00083 quality(w),
00084 metric_weight(0) {}
00085
00086 void remove_reference() {
00087 if (counterpart) {
00088 counterpart->counterpart = 0;
00089 counterpart = 0;
00090 }
00091 }
00092
00093 void set_counterpart(LinkQuality *lq) {
00094 if (lq)
00095 lq->counterpart = this;
00096 counterpart = lq;
00097 }
00098
00099 bool get_qualities(link_quality_t &f, link_quality_t &b) const;
00100
00101 double get_percentage() const {
00102 double v(quality);
00103 v = 100.0*((double)max_quality() - quality)/(double)max_quality();
00104 return v;
00105 }
00106
00107 void set_metric_weight(unsigned long mw) {
00108 metric_weight = mw;
00109 if (counterpart) {
00110 counterpart->metric_weight = mw;
00111 }
00112 }
00113
00114 };
00115
00117 class LinkList : public std::vector<LinkQuality> {
00118
00119 public:
00120
00121 LinkList():std::vector<LinkQuality>() {}
00122
00123 };
00124
00127 struct NDescr {
00128 LinkList linklist;
00129 NodeId nextHop;
00130 NodeId prevHop;
00131 gea::AbsTime validity;
00133 unsigned long distance;
00138 int index;
00139
00140 char nodeName[33];
00142 NDescr() : linklist()
00143 {
00144 nodeName[0]='\0';
00145 }
00146
00147 void update_validity(const gea::AbsTime& new_v) {
00148 if (this->validity < new_v)
00149 this->validity = new_v;
00150 }
00151
00152
00153 virtual LinkQuality *findLinkQuality(NodeId id);
00154 virtual const LinkQuality *findLinkQuality(NodeId id) const;
00155 virtual ~NDescr();
00156 };
00157
00160 class AdjList : public std::map<NodeId, NDescr> {
00161 public:
00162 friend bool operator==(std::pair<NodeId,NDescr> const &a,NodeId const &b);
00163 iterator find(NodeId const &nodeId) {
00164 return std::map<NodeId,NDescr>::find(nodeId);
00165 }
00166 const_iterator find(NodeId const &nodeId) const {
00167 return std::map<NodeId,NDescr>::find(nodeId);
00168 }
00169 bool find(NodeId const &from,NodeId const &to,LinkList::iterator &it);
00170 bool find(NodeId const &from,NodeId const &to) const;
00171
00173 void enumerateNodes() {
00174 int idx = 0;
00175 for (iterator i = begin(); i != end(); ++i)
00176 i->second.index = idx++;
00177 }
00178 };
00179
00180 void enumerateNodes() {
00181 adjList.enumerateNodes();
00182 }
00183
00184 AdjList adjList;
00186 bool dirty;
00187 bool locked;
00189 const NodeId myNodeId;
00192 Callback<std::string&> newDotTopology;
00193 Callback<std::string&> newXmlTopologyDelta;
00194
00195 int addTopoCmd();
00196
00197 RTopology(NodeId id,Routing *routing);
00198
00199 virtual ~RTopology();
00200
00201 void setLocked(bool t) { locked = t; };
00202 bool getLocked() const { return locked; }
00203 virtual void reset();
00204
00205 bool hasNode(const NodeId &node) const;
00206 virtual bool hasLink(const NodeId& from, const NodeId&to) const;
00207
00211 void feed(const TopoPacket& p);
00212
00213 virtual std::string getNameOfNode(const NodeId& id) const;
00214 virtual bool getNodeByName(NodeId& id, const char *name) const;
00215
00216 std::string getNameList() const;
00217
00221 int getNumNodes() const {
00222 return adjList.size();
00223 }
00224
00228 gea::AbsTime removeOldNodes();
00229
00230 void createRemoveMessages(const NodeId& node, const NDescr& nDescr );
00231
00232 AdjList::iterator getNodeEntry(const NodeId& id, gea::AbsTime t);
00233
00234 struct awds::Routing::NodesObserver *nodeObservers;
00235 struct awds::Routing::LinksObserver *linkObserver;
00236 protected:
00237 void sendNodesChanged() const;
00238 void sendNodeAdded(const NodeId& id) const;
00239 void sendNodeRemoved(const NodeId& id) const;
00240 void sendLinksChanged() const ;
00241 void sendLinkAdded(const NodeId& from, const NodeId& to) const;
00242 void sendLinkRemoved(const NodeId& from, const NodeId& to) const;
00243
00244 public:
00245
00246
00247
00248
00254 void getNextHop(const NodeId& dest, NodeId& nextHop, bool& found);
00255
00256 void calcNextHop(const NodeId& id);
00257 void calcRoutes();
00258
00259 typedef std::vector<AdjList::iterator> ToDo;
00260 ToDo todo;
00261
00262
00263 void print();
00264
00265 virtual std::string getDotString() const;
00266 virtual std::string getAdjString() const;
00267 virtual std::string getXmlString() const;
00268 };
00269
00270
00271
00272 static inline const NodeId& getNodeId(const RTopology::LinkQuality& lq) {
00273 return lq.neighbor;
00274 }
00275
00276
00277 }
00278
00279
00280
00281 #endif //TOPOLOGY_H__
00282
00283
00284
00285
00286
00287