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