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 <awds/linuxbasicCallback.h>
00019
00020 #include <iostream>
00021
00022 namespace awds {
00023
00024 class Metric;
00025
00026 class TopoPacket;
00027 class RTopology;
00028
00029
00034 class RTopology {
00035
00036 gea::Blocker cleanup_blocker;
00037
00038 public:
00039 bool verbose;
00040 Metric *metric;
00041
00042 char nodeName[32];
00043
00044
00045 linuxbasic_cb* linux_cb;
00046
00047 static void cleanup_nodes(gea::Handle *h, gea::AbsTime t, void *data);
00048
00049 typedef uint16_t link_quality_t;
00050 static link_quality_t max_quality() { return 0xFFFFu; }
00051
00052 class LinkList;
00053 class AdjList;
00054
00057 class LinkQuality {
00058 protected:
00059 public:
00060 LinkQuality *counterpart;
00061
00062 NodeId neighbor;
00064 link_quality_t quality;
00065 uint32_t metric_weight;
00067 LinkQuality &operator=(const LinkQuality& lq) {
00068 counterpart = lq.counterpart;
00069 neighbor = lq.neighbor;
00070 quality = lq.quality;
00071 metric_weight = lq.metric_weight;
00072
00073 if (counterpart) {
00074 counterpart->counterpart = this;
00075 }
00076 return *this;
00077 }
00078
00079 LinkQuality(LinkQuality const &lq) {
00080 *this = lq;
00081 }
00082
00083 LinkQuality():
00084 counterpart(0),
00085 quality(0),
00086 metric_weight(0)
00087 {}
00088
00089 LinkQuality(NodeId n, link_quality_t w):
00090 counterpart(0),
00091 neighbor(n),
00092 quality(w),
00093 metric_weight(0)
00094 {}
00095
00096 void remove_reference() {
00097 if (counterpart) {
00098 counterpart->counterpart = 0;
00099 counterpart = 0;
00100 }
00101 }
00102
00103 void set_counterpart(LinkQuality *lq) {
00104 if (lq)
00105 lq->counterpart = this;
00106 counterpart = lq;
00107 }
00108
00109 bool get_qualities(link_quality_t &f, link_quality_t &b) const;
00110
00111 double get_percentage() const {
00112 double v(quality);
00113 v = 100.0 * ((double)max_quality() - quality)/(double)max_quality();
00114 return v;
00115 }
00116
00117 void set_metric_weight(uint32_t mw) {
00118 metric_weight = mw;
00119 if (counterpart) {
00120 counterpart->metric_weight = mw;
00121 }
00122 }
00123
00124 };
00125
00127 class LinkList : public std::vector<LinkQuality> {
00128
00129 public:
00130
00131 LinkList():std::vector<LinkQuality>() {}
00132
00133 };
00134
00137 struct NDescr {
00138 LinkList linklist;
00139 NodeId nextHop;
00140 NodeId prevHop;
00141 gea::AbsTime nodeValidity;
00142 gea::AbsTime edgeValidity;
00144 unsigned long distance;
00149 int index;
00150
00151 char nodeName[33];
00153 NDescr() : linklist()
00154 {
00155 nodeName[0]='\0';
00156 }
00157
00158 void update_nodeValidity(const gea::AbsTime& new_v) {
00159 if (this->nodeValidity < new_v) {
00160 this->nodeValidity = new_v;
00161 }
00162 }
00163
00164
00165 virtual LinkQuality *findLinkQuality(NodeId id);
00166 virtual const LinkQuality *findLinkQuality(NodeId id) const;
00167 virtual ~NDescr();
00168 };
00169
00172 class AdjList : public std::map<NodeId, NDescr> {
00173 public:
00174 friend bool operator==(std::pair<NodeId,NDescr> const &a,NodeId const &b);
00175 iterator find(NodeId const &nodeId) {
00176 return std::map<NodeId,NDescr>::find(nodeId);
00177 }
00178 const_iterator find(NodeId const &nodeId) const {
00179 return std::map<NodeId,NDescr>::find(nodeId);
00180 }
00181 bool find(NodeId const &from,NodeId const &to,LinkList::iterator &it);
00182 bool find(NodeId const &from,NodeId const &to) const;
00183
00185 inline void enumerateNodes() {
00186 int idx = 0;
00187 for (AdjList::iterator i = this->begin(); i != this->end(); ++i)
00188 i->second.index = idx++;
00189 }
00190 };
00191
00192 void enumerateNodes() {
00193 adjList.enumerateNodes();
00194 }
00195
00196 AdjList adjList;
00198 bool dirty;
00199 bool locked;
00201 const NodeId myNodeId;
00204 Callback<std::string&> newDotTopology;
00205 Callback<std::string&> newXmlTopologyDelta;
00206
00207 int addTopoCmd();
00208
00209 RTopology(NodeId id,Routing *routing);
00210
00211 virtual ~RTopology();
00212
00213 void setLocked(bool t) { locked = t; };
00214 bool getLocked() const { return locked; }
00215 virtual void reset();
00216
00217 virtual bool hasNode(const NodeId &node) const;
00218 virtual bool hasLink(const NodeId& from, const NodeId&to) const;
00219
00223 void feed(const TopoPacket& p);
00224
00225 virtual std::string getNameOfNode(const NodeId& id) const;
00226 virtual bool getNodeByName(NodeId& id, const char *name) const;
00227
00228 std::string getNameList() const;
00229
00233 int getNumNodes() const {
00234 return adjList.size();
00235 }
00236
00240 gea::AbsTime removeOldNodes();
00241
00242 void createRemoveMessages(const NodeId& node, const NDescr& nDescr );
00243
00244 AdjList::iterator getNodeEntry(const NodeId& id, gea::AbsTime t);
00245
00246 struct awds::Routing::NodesObserver *nodeObservers;
00247 struct awds::Routing::LinksObserver *linkObserver;
00248 protected:
00249 void sendNodesChanged() const;
00250 void sendNodeAdded(const NodeId& id) const;
00251 void sendNodeRemoved(const NodeId& id) const;
00252 void sendLinksChanged() const ;
00253 void sendLinkAdded(const NodeId& from, const NodeId& to) const;
00254 void sendLinkRemoved(const NodeId& from, const NodeId& to) const;
00255
00256 void updateTopology();
00257
00258 public:
00259
00260
00261
00262
00268 void getNextHop(const NodeId& dest, NodeId& nextHop, bool& found);
00269
00270 void calcNextHop(const NodeId& id);
00271 void calcRoutes();
00272
00273 typedef std::vector<AdjList::iterator> ToDo;
00274 ToDo todo;
00275
00276
00277 void print();
00278
00279 void dumpNextHops(std::ostream& os);
00280
00281 virtual std::string getDotString() const;
00282 virtual std::string getAdjString() const;
00283 virtual std::string getXmlString() const;
00284 };
00285
00286
00287
00288 static inline const NodeId& getNodeId(const RTopology::LinkQuality& lq) {
00289 return lq.neighbor;
00290 }
00291
00292
00293 typedef RTopology Topology;
00294
00295 }
00296
00297
00298
00299 #endif //TOPOLOGY_H__
00300
00301
00302
00303
00304
00305