00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <oasys/thread/SpinLock.h>
00019 #include <oasys/util/StringBuffer.h>
00020 #include "conv_layers/ConvergenceLayer.h"
00021 #include "contacts/Link.h"
00022 #include "ForwardingLog.h"
00023
00024 namespace dtn {
00025
00026
00027 ForwardingLog::ForwardingLog(oasys::SpinLock* lock)
00028 : lock_(lock)
00029 {
00030 }
00031
00032
00033 bool
00034 ForwardingLog::get_latest_entry(Link* link, ForwardingInfo* info) const
00035 {
00036 oasys::ScopeLock l(lock_, "ForwardingLog::get_latest_state");
00037
00038 Log::const_reverse_iterator iter;
00039 for (iter = log_.rbegin(); iter != log_.rend(); ++iter)
00040 {
00041 if (iter->nexthop_ == link->nexthop() &&
00042 iter->clayer_ == link->clayer()->name())
00043 {
00044 *info = *iter;
00045 return true;
00046 }
00047 }
00048
00049 return false;
00050 }
00051
00052
00053 ForwardingLog::state_t
00054 ForwardingLog::get_latest_entry(Link* link) const
00055 {
00056 ForwardingInfo info;
00057 if (! get_latest_entry(link, &info)) {
00058 return ForwardingInfo::NONE;
00059 }
00060
00061 return static_cast<ForwardingLog::state_t>(info.state_);
00062 }
00063
00064
00065 size_t
00066 ForwardingLog::get_transmission_count(ForwardingInfo::action_t action,
00067 bool include_inflight) const
00068 {
00069 size_t ret = 0;
00070
00071 oasys::ScopeLock l(lock_, "ForwardingLog::get_transmission_count");
00072
00073 Log::const_iterator iter;
00074 for (iter = log_.begin(); iter != log_.end(); ++iter)
00075 {
00076 if (iter->state_ == ForwardingInfo::TRANSMITTED ||
00077 (include_inflight && (iter->state_ == ForwardingInfo::IN_FLIGHT)))
00078 {
00079 if ((action == iter->action_) ||
00080 (action == ForwardingInfo::INVALID_ACTION))
00081 {
00082 ++ret;
00083 }
00084 }
00085 }
00086
00087 return ret;
00088 }
00089
00090
00091 size_t
00092 ForwardingLog::get_count(state_t state) const
00093 {
00094 size_t ret = 0;
00095
00096 oasys::ScopeLock l(lock_, "ForwardingLog::get_count");
00097
00098 Log::const_iterator iter;
00099 for (iter = log_.begin(); iter != log_.end(); ++iter)
00100 {
00101 if (iter->state_ == state) {
00102 ++ret;
00103 }
00104 }
00105
00106 return ret;
00107 }
00108
00109
00110 void
00111 ForwardingLog::dump(oasys::StringBuffer* buf) const
00112 {
00113 oasys::ScopeLock l(lock_, "ForwardingLog::dump");
00114 buf->appendf("forwarding log:\n");
00115 Log::const_iterator iter;
00116 for (iter = log_.begin(); iter != log_.end(); ++iter)
00117 {
00118 const ForwardingInfo* info = &(*iter);
00119
00120 buf->appendf("\t%s -> %s %u.%u [%s cl:%s] [custody min %d pct %d max %d]\n",
00121 ForwardingInfo::state_to_str(
00122 static_cast<ForwardingInfo::state_t>(info->state_)),
00123 info->clayer_.c_str(),
00124 (u_int)info->timestamp_.tv_sec,
00125 (u_int)info->timestamp_.tv_usec,
00126 ForwardingInfo::action_to_str(
00127 static_cast<ForwardingInfo::action_t>(info->action_)),
00128 info->nexthop_.c_str(),
00129 info->custody_timer_.min_,
00130 info->custody_timer_.lifetime_pct_,
00131 info->custody_timer_.max_);
00132 }
00133 }
00134
00135
00136 void
00137 ForwardingLog::add_entry(Link* link,
00138 ForwardingInfo::action_t action,
00139 state_t state,
00140 const CustodyTimerSpec& custody_timer)
00141 {
00142 oasys::ScopeLock l(lock_, "ForwardingLog::add_entry");
00143
00144 log_.push_back(ForwardingInfo(state, action, link->clayer()->name(),
00145 link->nexthop(), custody_timer));
00146 }
00147
00148
00149 bool
00150 ForwardingLog::update(Link* link, state_t state)
00151 {
00152 oasys::ScopeLock l(lock_, "ForwardingLog::update");
00153
00154 Log::reverse_iterator iter;
00155 for (iter = log_.rbegin(); iter != log_.rend(); ++iter)
00156 {
00157 if (iter->nexthop_ == link->nexthop() &&
00158 iter->clayer_ == link->clayer()->name())
00159 {
00160 iter->set_state(state);
00161 return true;
00162 }
00163 }
00164
00165 return false;
00166 }
00167
00168 }