00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _PROPHET_BUNDLE_CORE_FACADE_H_
00018 #define _PROPHET_BUNDLE_CORE_FACADE_H_
00019
00020 #include "Alarm.h"
00021 #include "Node.h"
00022 #include "Bundle.h"
00023 #include "BundleImpl.h"
00024 #include "BundleList.h"
00025 #include "Link.h"
00026
00027 #include <stdarg.h>
00028 #include <string>
00029 #include <list>
00030
00031 #if defined(__GNUC__)
00032 # define PRINTFLIKE(fmt, arg) __attribute__((format (printf, fmt, arg)))
00033 #else
00034 # define PRINTFLIKE(a, b)
00035 #endif
00036
00037 namespace prophet
00038 {
00039
00048 class BundleCore
00049 {
00050 public:
00051
00055 virtual ~BundleCore() {}
00056
00060 virtual bool is_route(const std::string& dest_id,
00061 const std::string& route) const = 0;
00062
00066 virtual bool should_fwd(const Bundle* bundle,
00067 const Link* link) const = 0;
00068
00072 virtual std::string get_route(const std::string& dest_id) const = 0;
00073
00077 virtual std::string get_route_pattern(const std::string& dest_id) const = 0;
00078
00082 virtual u_int64_t max_bundle_quota() const = 0;
00083
00088 virtual bool custody_accepted() const = 0;
00089
00093 virtual const BundleList& bundles() const = 0;
00094
00099 virtual void drop_bundle(const Bundle* bundle) = 0;
00100
00104 virtual bool send_bundle(const Bundle* bundle,
00105 const Link* link) = 0;
00106
00113 virtual bool write_bundle(const Bundle* bundle,
00114 const u_char* buf,
00115 size_t len) = 0;
00116
00125 virtual bool read_bundle(const Bundle* bundle,
00126 u_char* buffer,
00127 size_t& len) const = 0;
00128
00135 virtual Bundle* create_bundle(const std::string& src,
00136 const std::string& dst,
00137 u_int exp) = 0;
00138
00143 virtual const Bundle* find(const BundleList& list, const std::string& eid,
00144 u_int32_t creation_ts, u_int32_t seqno) const = 0;
00145
00149 virtual void update_node(const Node* node) = 0;
00150
00154 virtual void delete_node(const Node* node) = 0;
00155
00159 virtual std::string local_eid() const = 0;
00160
00165 virtual std::string prophet_id(const Link* link) const = 0;
00166
00170 virtual std::string prophet_id() const = 0;
00171
00177 virtual Alarm* create_alarm(ExpirationHandler* handler,
00178 u_int timeout, bool jitter = false) = 0;
00179
00181 static const int LOG_DEBUG = 1;
00182 static const int LOG_INFO = 2;
00183 static const int LOG_NOTICE = 3;
00184 static const int LOG_WARN = 4;
00185 static const int LOG_ERR = 5;
00186 static const int LOG_CRIT = 6;
00187 static const int LOG_ALWAYS = 7;
00189
00194 virtual void print_log(const char* name, int level, const char* fmt, ...)
00195 PRINTFLIKE(4,5) = 0;
00196
00197 };
00198
00202 class AlarmImpl : public Alarm
00203 {
00204 public:
00205 AlarmImpl(ExpirationHandler* h)
00206 : Alarm(h), pending_(false), cancelled_(false) {}
00207
00208 virtual ~AlarmImpl() {}
00209
00210 void schedule(u_int) { pending_ = true; }
00211 u_int time_remaining() const { return 0; }
00212 void cancel() { cancelled_ = true; }
00213 bool pending() const { return pending_; }
00214 bool cancelled() const { return cancelled_; }
00215 bool pending_, cancelled_;
00216 };
00217
00222 class BundleCoreTestImpl : public BundleCore
00223 {
00224 public:
00225 typedef std::string BundleBuffer;
00226 BundleCoreTestImpl(const std::string& str = "dtn://somehost")
00227 : str_(str), max_(0xffff) {}
00228 virtual ~BundleCoreTestImpl()
00229 {
00230 while (!alarms_.empty())
00231 {
00232 delete alarms_.front();
00233 alarms_.pop_front();
00234 }
00235 }
00237 bool is_route(const std::string& dest,const std::string& route) const
00238 {
00239 if (route.length() > dest.length()) return false;
00240 return route.compare(0,route.length(),dest) == 0;
00241 }
00242 bool should_fwd(const Bundle*,const Link*) const { return true; }
00243 std::string get_route(const std::string& str ) const { return str; }
00244 std::string get_route_pattern(const std::string& str ) const { return str + "/*"; }
00245 u_int64_t max_bundle_quota() const { return max_; }
00246 bool custody_accepted() const { return true; }
00247 void drop_bundle(const Bundle* b)
00248 {
00249 for (std::list<bundle>::iterator i = rcvd_.begin();
00250 i != rcvd_.end(); i++)
00251 {
00252 if (b->destination_id() == (*i).first->destination_id() &&
00253 b->creation_ts() == (*i).first->creation_ts() &&
00254 b->sequence_num() == (*i).first->sequence_num())
00255 {
00256 rcvd_.erase(i);
00257 break;
00258 }
00259 }
00260 }
00261 bool send_bundle(const Bundle* b,const Link*)
00262 {
00263 sent_.push_back(b);
00264 return true;
00265 }
00266 bool write_bundle(const Bundle* b,const u_char* buf,size_t len)
00267 {
00268 BundleBuffer bunbuf((char*)buf,len);
00269 written_.push_back(std::make_pair<const Bundle*,BundleBuffer>(b,bunbuf));
00270 return written_.back().second.size() <= len;
00271 }
00272 bool read_bundle(const Bundle* b,u_char* buf,size_t& len) const
00273 {
00274 for (std::list<bundle>::const_iterator i = rcvd_.begin();
00275 i != rcvd_.end(); i++)
00276 {
00277 if (b->destination_id() == (*i).first->destination_id() &&
00278 b->creation_ts() == (*i).first->creation_ts() &&
00279 b->sequence_num() == (*i).first->sequence_num())
00280 {
00281 size_t blen = (*i).second.size();
00282 if (blen < len) return false;
00283 len = blen;
00284 memcpy(buf,(*i).second.data(),len);
00285 return true;
00286 }
00287 }
00288 return false;
00289 }
00290 Bundle* create_bundle(const std::string& src, const std::string& dst,u_int exp=3600)
00291 { return new BundleImpl(src,dst,0,0,exp); }
00292 const Bundle* find(const BundleList&,const std::string&,u_int32_t,
00293 u_int32_t) const
00294 { return NULL; }
00295 const BundleList& bundles() const { return list_; }
00296 void update_node(const Node*) {}
00297 void delete_node(const Node*) {}
00298 std::string local_eid() const { return str_; }
00299 #define PROPHESY(_str) do { \
00300 size_t pos = _str.size() - 1; \
00301 if (_str[pos] == '/') \
00302 _str += "prophet"; \
00303 else \
00304 _str += "/prophet"; \
00305 } while (0)
00306 std::string prophet_id(const Link* link) const
00307 {
00308 remote_.assign(link->nexthop());
00309 PROPHESY(remote_);
00310 return remote_;
00311 }
00312 std::string prophet_id() const
00313 {
00314 if (local_ == "")
00315 {
00316 local_.assign(str_);
00317 PROPHESY(local_);
00318 }
00319 return local_;
00320 }
00321 #undef PROPHESY
00322 Alarm* create_alarm(ExpirationHandler* handler, u_int timeout,bool)
00323 {
00324 AlarmImpl* alarm = new AlarmImpl(handler);
00325 alarm->schedule(timeout);
00326 alarms_.push_back(alarm);
00327 return alarm;
00328 }
00329 void print_log(const char* name, int level, const char* fmt, ...)
00330 PRINTFLIKE(4,5);
00331
00333 void set_max(u_int64_t max) { max_ = max; }
00334 void set_eid(const std::string& id) { str_.assign(id); }
00335 std::string str_;
00336 mutable std::string local_, remote_;
00337 u_int64_t max_;
00338 std::list<const Bundle*> sent_;
00339 typedef std::pair<const Bundle*,BundleBuffer> bundle;
00340 std::list<bundle> written_;
00341 std::list<bundle> rcvd_;
00342 std::list<Alarm*> alarms_;
00343 prophet::BundleList list_;
00344 };
00345
00346 inline void
00347 BundleCoreTestImpl::print_log(const char* name, int level, const char* fmt, ...)
00348 {
00349 printf("[%s][%d]\n",name,level);
00350 va_list ap;
00351 va_start(ap, fmt);
00352 vprintf(fmt, ap);
00353 va_end(ap);
00354 printf("\n");
00355 }
00356
00357 };
00358
00359 #endif // _PROPHET_BUNDLE_CORE_FACADE_H_