00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include <algorithm>
00022 #include <oasys/util/OptParser.h>
00023
00024 #include "Bundle.h"
00025 #include "BundleDaemon.h"
00026 #include "BundleEvent.h"
00027 #include "CustodyTimer.h"
00028
00029 namespace dtn {
00030
00038 CustodyTimerSpec CustodyTimerSpec::defaults_(30 * 60, 25, 0);
00039
00040
00041 u_int32_t
00042 CustodyTimerSpec::calculate_timeout(const Bundle* bundle) const
00043 {
00044 u_int32_t timeout = min_;
00045 timeout += (u_int32_t)((double)lifetime_pct_ * bundle->expiration() / 100.0);
00046
00047 if (max_ != 0) {
00048 timeout = std::min(timeout, max_);
00049 }
00050
00051 log_debug_p("/dtn/bundle/custody_timer", "calculate_timeout: "
00052 "min %u, lifetime_pct %u, expiration %u, max %u: timeout %u",
00053 min_, lifetime_pct_, bundle->expiration(), max_, timeout);
00054 return timeout;
00055 }
00056
00057
00058 int
00059 CustodyTimerSpec::parse_options(int argc, const char* argv[],
00060 const char** invalidp)
00061 {
00062 oasys::OptParser p;
00063 p.addopt(new oasys::UIntOpt("custody_timer_min", &min_));
00064 p.addopt(new oasys::UIntOpt("custody_timer_lifetime_pct", &lifetime_pct_));
00065 p.addopt(new oasys::UIntOpt("custody_timer_max", &max_));
00066 return p.parse_and_shift(argc, argv, invalidp);
00067 }
00068
00069
00070 void
00071 CustodyTimerSpec::serialize(oasys::SerializeAction* a)
00072 {
00073 a->process("min", &min_);
00074 a->process("lifetime_pct", &lifetime_pct_);
00075 a->process("max", &max_);
00076 }
00077
00078
00079 CustodyTimer::CustodyTimer(const oasys::Time& xmit_time,
00080 const CustodyTimerSpec& spec,
00081 Bundle* bundle, const LinkRef& link)
00082 : Logger("CustodyTimer", "/dtn/bundle/custody_timer"),
00083 bundle_(bundle, "CustodyTimer"), link_(link.object(), "CustodyTimer")
00084 {
00085 oasys::Time time(xmit_time);
00086 u_int32_t delay = spec.calculate_timeout(bundle);
00087 time.sec_ += delay;
00088
00089 log_info("scheduling timer: xmit_time %u.%u delay %u secs "
00090 "(in %u msecs) for *%p",
00091 xmit_time.sec_, xmit_time.usec_, delay,
00092 (time - oasys::Time::now()).in_milliseconds(), bundle);
00093
00094
00095 struct timeval tv;
00096 tv.tv_sec = time.sec_;
00097 tv.tv_usec = time.usec_;
00098 schedule_at(&tv);
00099 }
00100
00101
00102 void
00103 CustodyTimer::timeout(const struct timeval& now)
00104 {
00105 (void)now;
00106 log_info("CustodyTimer::timeout");
00107 BundleDaemon::post(new CustodyTimeoutEvent(bundle_.object(), link_));
00108 }
00109
00110 }