00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _DTN_PROPHET_CONTROLLER_
00018 #define _DTN_PROPHET_CONTROLLER_
00019
00020 #include <oasys/debug/Log.h>
00021 #include <oasys/util/Time.h>
00022 #include <oasys/util/BoundedPriorityQueue.h>
00023 #include "naming/EndpointID.h"
00024 #include "contacts/Link.h"
00025 #include <sys/types.h>
00026
00027 #include <set>
00028 #include <map>
00029 #include <vector>
00030
00031 #include "routing/ProphetEncounter.h"
00032
00033 #include "bundling/BundleList.h"
00034 #include "bundling/BundleActions.h"
00035
00036 #include "reg/Registration.h"
00037
00042 namespace dtn {
00043
00079 class ProphetController : public oasys::Logger,
00080 public ProphetOracle,
00081 public oasys::Singleton<ProphetController,false>
00082 {
00083 public:
00087 ProphetController();
00088
00092 void do_init(ProphetParams* params, const BundleList* bundles,
00093 BundleActions* actions, const char* logpath);
00094
00098 static void init(ProphetParams* params,
00099 const BundleList* bundles,
00100 BundleActions* actions,
00101 const char* logpath = "/dtn/route/prophet/controller")
00102 {
00103 ASSERTF(instance_ == NULL,"ProphetController already initialized");
00104 instance_ = new ProphetController();
00105 instance_->do_init(params,bundles,actions,logpath);
00106 }
00107
00108 virtual ~ProphetController();
00109
00110 Prophet::fwd_strategy_t fwd_strategy() const { return params_->fs_; }
00111 void set_fwd_strategy( Prophet::fwd_strategy_t f ) { params_->fs_ = f; }
00112
00113 Prophet::q_policy_t q_policy() const { return params_->qp_; }
00114 void set_q_policy( Prophet::q_policy_t q ) { params_->qp_ = q; }
00115
00119 void dump_state(oasys::StringBuffer*);
00120
00126 void handle_bundle_received(Bundle*,const ContactRef&);
00127
00131 void handle_bundle_expired(Bundle*);
00132
00136 void handle_bundle_delivered(Bundle*);
00137
00141 void handle_link_state_change_request(const ContactRef&);
00142
00146 void new_neighbor(const ContactRef&);
00147
00151 void neighbor_gone(const ContactRef&);
00152
00156 void handle_queue_policy_change(Prophet::q_policy_t qp)
00157 {
00158 if (qp != Prophet::INVALID_QP &&
00159 params_->qp_ != qp)
00160 {
00161 log_info("changing queue policy from %s to %s",
00162 Prophet::qp_to_str(params_->qp_),
00163 Prophet::qp_to_str(qp));
00164 params_->qp_ = qp;
00165 bundles_->set_comp(QueueComp::queuecomp(qp,&pstats_,&nodes_));
00166 }
00167 else
00168 {
00169 log_info("not changing queue_policy (no difference)");
00170 }
00171 }
00172
00176 void handle_hello_interval_change(u_int hello_interval)
00177 {
00178 if (hello_interval != params_->hello_interval_)
00179 {
00180 log_info("changing hello_interval from %u to %u",
00181 params_->hello_interval_,hello_interval);
00182 params_->hello_interval_ = hello_interval;
00183 }
00184 else
00185 {
00186 log_info("not changing hello_interval (no difference)");
00187 }
00188 for(enc_set::iterator i = encounters_.begin();
00189 i != encounters_.end();
00190 i++)
00191 {
00192 ProphetEncounter* pe = *i;
00193 pe->hello_interval_changed();
00194 }
00195 }
00196
00200 void handle_max_usage_change(u_int max_usage)
00201 {
00202 if (max_usage != params_->max_usage_)
00203 {
00204 log_info("changing max_usage from %u to %u",
00205 params_->max_usage_,max_usage);
00206 params_->max_usage_ = max_usage;
00207 bundles_->set_max(max_usage);
00208 }
00209 else
00210 {
00211 log_info("not changing max_usage (no difference)");
00212 }
00213 }
00214
00218 void shutdown();
00219
00221 ProphetParams* params() { return params_; }
00222 ProphetBundleQueue* bundles() { return bundles_; }
00223 ProphetTable* nodes() { return &nodes_; }
00224 BundleActions* actions() { return actions_; }
00225 ProphetAckList* acks() { return &acks_; }
00226 ProphetStats* stats() { return &pstats_; }
00228
00229 bool reg(ProphetEncounter* pe)
00230 {
00231 oasys::ScopeLock l(lock_,"reg");
00232 bool ok = (encounters_.insert(pe).second == true);
00233 if (ok)
00234 log_info("ProphetEncounter %d has registered",
00235 pe->local_instance());
00236 return ok;
00237 }
00238
00239 bool unreg(ProphetEncounter* pe)
00240 {
00241 oasys::ScopeLock l(lock_,"unreg");
00242 bool ok = (encounters_.erase(pe) == 1);
00243 if (ok)
00244 log_info("ProphetEncounter %d has unregistered",
00245 pe->local_instance());
00246 return ok;
00247 }
00248
00249 static bool is_init() { return instance_ != NULL; }
00250 protected:
00251
00256 double p_value(Bundle*);
00257
00258 typedef std::set<ProphetEncounter*> enc_set;
00259
00260 ProphetEncounter* find_instance(Link* link);
00261
00265 ProphetParams* params_;
00266
00270 enc_set encounters_;
00271
00275 oasys::SpinLock *lock_;
00276
00280 ProphetTable nodes_;
00281
00285 ProphetTableAgeTimer* node_age_timer_;
00286
00290 ProphetAckAgeTimer* ack_age_timer_;
00291
00295 ProphetAckList acks_;
00296
00300 ProphetStats pstats_;
00301
00305 BundleActions* actions_;
00306
00310 ProphetBundleQueue* bundles_;
00311
00315 EndpointID prophet_eid_;
00316
00317 };
00318
00319 };
00320
00321 #endif // _DTN_PROPHET_CONTROLLER_