00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _LINK_H_
00018 #define _LINK_H_
00019
00020 #include <set>
00021 #include <oasys/debug/Formatter.h>
00022 #include <oasys/serialize/Serialize.h>
00023 #include <oasys/thread/SpinLock.h>
00024 #include <oasys/util/Ref.h>
00025 #include <oasys/util/RefCountedObject.h>
00026
00027 #include "bundling/BundleList.h"
00028 #include "naming/EndpointID.h"
00029
00030 #include "Contact.h"
00031 #include "NamedAttribute.h"
00032
00033 namespace dtn {
00034
00035 class ConvergenceLayer;
00036 class CLInfo;
00037 class Contact;
00038 class Link;
00039 class RouterInfo;
00040
00044 typedef oasys::Ref<Link> LinkRef;
00045
00049 class LinkSet : public std::set<LinkRef> {};
00050
00103 class Link : public oasys::RefCountedObject,
00104 public oasys::Logger,
00105 public oasys::SerializableObject {
00106 public:
00110 typedef enum
00111 {
00112 LINK_INVALID = -1,
00113
00119 ALWAYSON = 1,
00120
00128 ONDEMAND = 2,
00129
00133 SCHEDULED = 3,
00134
00141 OPPORTUNISTIC = 4
00142 }
00143 link_type_t;
00144
00148 static inline const char*
00149 link_type_to_str(link_type_t type)
00150 {
00151 switch(type) {
00152 case ALWAYSON: return "ALWAYSON";
00153 case ONDEMAND: return "ONDEMAND";
00154 case SCHEDULED: return "SCHEDULED";
00155 case OPPORTUNISTIC: return "OPPORTUNISTIC";
00156 default: PANIC("bogus link_type_t");
00157 }
00158 }
00159
00160 static inline link_type_t
00161 str_to_link_type(const char* str)
00162 {
00163 if (strcasecmp(str, "ALWAYSON") == 0)
00164 return ALWAYSON;
00165
00166 if (strcasecmp(str, "ONDEMAND") == 0)
00167 return ONDEMAND;
00168
00169 if (strcasecmp(str, "SCHEDULED") == 0)
00170 return SCHEDULED;
00171
00172 if (strcasecmp(str, "OPPORTUNISTIC") == 0)
00173 return OPPORTUNISTIC;
00174
00175 return LINK_INVALID;
00176 }
00177
00183 typedef enum {
00184 UNAVAILABLE = 1,
00185
00186
00187 AVAILABLE = 2,
00188
00189
00190
00191
00192
00193
00194 OPENING = 4,
00195
00196
00197 OPEN = 8,
00198
00199
00200
00201
00202
00203
00204
00205 CLOSED = 16
00206
00207
00208
00209
00210 } state_t;
00211
00215 static inline const char*
00216 state_to_str(state_t state)
00217 {
00218 switch(state) {
00219 case UNAVAILABLE: return "UNAVAILABLE";
00220 case AVAILABLE: return "AVAILABLE";
00221 case OPENING: return "OPENING";
00222 case OPEN: return "OPEN";
00223 case CLOSED: return "CLOSED";
00224 }
00225
00226 NOTREACHED;
00227 }
00228
00232 static LinkRef create_link(const std::string& name, link_type_t type,
00233 ConvergenceLayer* cl, const char* nexthop,
00234 int argc, const char* argv[],
00235 const char** invalid_argp = NULL);
00236
00240 Link(const std::string& name, link_type_t type,
00241 ConvergenceLayer* cl, const char* nexthop);
00242
00246 Link(const oasys::Builder& b);
00247
00251 virtual void delete_link();
00252
00256 virtual bool reconfigure_link(int argc, const char* argv[]);
00257
00258 virtual void reconfigure_link(AttributeVector& params);
00259
00263 void serialize(oasys::SerializeAction* action);
00264
00268 virtual int parse_args(int argc, const char* argv[],
00269 const char** invalidp = NULL);
00270
00275 virtual void set_initial_state();
00276
00280 link_type_t type() const { return static_cast<link_type_t>(type_); }
00281
00285 const char* type_str() const { return link_type_to_str(type()); }
00286
00290 bool isopen() const { return ( (state_ == OPEN) ); }
00291
00295 bool isavailable() const { return (state_ != UNAVAILABLE); }
00296
00300 bool isopening() const { return (state_ == OPENING); }
00301
00305 bool isdeleted() const;
00306
00310 state_t state() const { return static_cast<state_t>(state_); }
00311
00325 void set_state(state_t state);
00326
00330 void set_create_pending(bool create_pending = true)
00331 { create_pending_ = create_pending; }
00332 bool is_create_pending() const { return create_pending_; }
00333
00337 void set_usable(bool usable = true) { usable_ = usable; }
00338 bool is_usable() const { return usable_; }
00339
00343 const ContactRef& contact() const { return contact_; }
00344
00348 void set_contact(Contact* contact)
00349 {
00350
00351 ASSERT(contact_ == NULL);
00352 contact_ = contact;
00353 }
00354
00358 void set_cl_info(CLInfo* cl_info)
00359 {
00360 ASSERT((cl_info_ == NULL && cl_info != NULL) ||
00361 (cl_info_ != NULL && cl_info == NULL));
00362
00363 cl_info_ = cl_info;
00364 }
00365
00369 CLInfo* cl_info() const { return cl_info_; }
00370
00374 void set_router_info(RouterInfo* router_info)
00375 {
00376 ASSERT((router_info_ == NULL && router_info != NULL) ||
00377 (router_info_ != NULL && router_info == NULL));
00378
00379 router_info_ = router_info;
00380 }
00381
00385 RouterInfo* router_info() const { return router_info_; }
00386
00390 ConvergenceLayer* clayer() const { return clayer_; }
00391
00395 const char* name() const { return name_.c_str(); }
00396
00400 const std::string& name_str() const { return name_; }
00401
00405 const char* nexthop() const { return nexthop_.c_str(); }
00406
00410 const std::string& nexthop_str() const { return nexthop_; }
00411
00415 void set_nexthop(const std::string& nexthop) { nexthop_.assign(nexthop); }
00416
00420 bool is_reliable() const { return reliable_; }
00421
00425 void set_reliable(bool r) { reliable_ = r; }
00426
00430 void set_remote_eid(const EndpointID& remote) {
00431 remote_eid_.assign(remote);
00432 }
00433
00437 const EndpointID& remote_eid() { return remote_eid_; }
00438
00443 const BundleList* queue() { return &queue_; }
00444
00449 bool queue_is_full() const;
00450
00455 bool queue_has_space() const;
00456
00462 const BundleList* inflight() { return &inflight_; }
00463
00465
00470 bool add_to_queue(const BundleRef& bundle, size_t total_len);
00471 bool del_from_queue(const BundleRef& bundle, size_t total_len);
00472 bool add_to_inflight(const BundleRef& bundle, size_t total_len);
00473 bool del_from_inflight(const BundleRef& bundle, size_t total_len);
00475
00479 int format(char* buf, size_t sz) const;
00480
00484 void dump(oasys::StringBuffer* buf);
00485
00486
00487
00488
00489 struct Params {
00493 Params();
00494
00498 u_int mtu_;
00499
00507 u_int min_retry_interval_;
00508
00516 u_int max_retry_interval_;
00517
00525 u_int idle_close_time_;
00526
00534 u_int potential_downtime_;
00535
00540 bool prevhop_hdr_;
00541
00546 u_int cost_;
00547
00560 u_int qlimit_bundles_high_;
00561 u_int64_t qlimit_bytes_high_;
00562 u_int qlimit_bundles_low_;
00563 u_int64_t qlimit_bytes_low_;
00565 };
00566
00572 u_int retry_interval_;
00573
00577 const Params& params() const { return params_; }
00578 Params& params() { return params_; }
00579
00580
00581
00582
00583 struct Stats {
00587 u_int contact_attempts_;
00588
00593 u_int contacts_;
00594
00598 u_int bundles_transmitted_;
00599
00603 u_int bytes_transmitted_;
00604
00608 u_int bundles_cancelled_;
00609
00614 u_int uptime_;
00615
00620 u_int availability_;
00621
00628 u_int reliability_;
00629 };
00630
00634 Stats* stats() { return &stats_; }
00635
00639 void reset_stats() const
00640 {
00641 memset(&stats_, 0, sizeof(stats_));
00642 }
00643
00647 void dump_stats(oasys::StringBuffer* buf);
00648
00650 u_int bundles_queued() { return bundles_queued_; }
00651 u_int bytes_queued() { return bytes_queued_; }
00652 u_int bundles_inflight() { return bundles_inflight_; }
00653 u_int bytes_inflight() { return bytes_inflight_; }
00655
00659 oasys::Lock* lock() { return &lock_; }
00660
00661 protected:
00662 friend class BundleActions;
00663 friend class BundleDaemon;
00664 friend class ContactManager;
00665 friend class ParamCommand;
00666
00672 virtual void open();
00673
00679 virtual void close();
00680
00682 int type_;
00683
00685 u_int32_t state_;
00686
00688 bool deleted_;
00689
00694 bool create_pending_;
00695
00698 bool usable_;
00699
00701 std::string nexthop_;
00702
00704 std::string name_;
00705
00707 bool reliable_;
00708
00710 Params params_;
00711
00713 static Params default_params_;
00714
00716 oasys::SpinLock lock_;
00717
00719 BundleList queue_;
00720
00722 BundleList inflight_;
00723
00732 u_int bundles_queued_;
00733 u_int bytes_queued_;
00734 u_int bundles_inflight_;
00735 u_int bytes_inflight_;
00738
00739 mutable Stats stats_;
00740
00742 ContactRef contact_;
00743
00745 ConvergenceLayer* clayer_;
00746
00748 CLInfo* cl_info_;
00749
00751 RouterInfo* router_info_;
00752
00754 EndpointID remote_eid_;
00755
00757 virtual ~Link();
00758 };
00759
00760 }
00761
00762 #endif