00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_STATS_ON_OFF_DATA_HXX_
00023 # define WIFI_STATS_ON_OFF_DATA_HXX_
00024
00025 # include <wipal/wifi/stats/on_off_data.hh>
00026
00027 namespace wpl
00028 {
00029
00030 namespace wifi
00031 {
00032
00033 namespace stats
00034 {
00035
00036 on_off_data::on_off_data(const void*): trace_ (0),
00037 last_stamps_ (1, 0)
00038 {
00039 }
00040
00041 template <class Frame>
00042 void
00043 on_off_data::account_frame(const Frame& frame,
00044 const size_t& ,
00045 const type::frame_type& ,
00046 const unsigned& ,
00047 const bool& ,
00048 const addr* const& ,
00049 const addr* const& transmitter,
00050 const bool& )
00051 {
00052 const tool::microseconds& t = frame.microseconds();
00053
00054 last_stamps_[trace_] = t;
00055
00056 if (not transmitter)
00057 return;
00058
00059 const state_id id (trace_, *transmitter);
00060 const states::iterator i = states_.find(id);
00061
00062 if (i == states_.end())
00063 {
00064 states_.insert(std::make_pair(id, t));
00065 return;
00066 }
00067
00068 state& s = i->second;
00069 tool::microseconds& last_seen = s.last_seen;
00070 const tool::microseconds expiration_time = (last_seen +
00071 state::lifetime);
00072
00073 if (expiration_time < t)
00074 {
00075 s.events.push_back(expiration_time);
00076 s.events.push_back(t);
00077 }
00078 last_seen = t;
00079 }
00080
00081 inline
00082 void
00083 on_off_data::restart()
00084 {
00085 ++trace_;
00086 last_stamps_.push_back(0);
00087 }
00088
00089 inline
00090 std::ostream&
00091 on_off_data::print(std::ostream& os) const
00092 {
00093 os << "begin ON/OFF events\n\n";
00094
00095 BOOST_FOREACH(const states::const_iterator::value_type& p, states_)
00096 {
00097 os << " begin ON/OFF T" << p.first.first
00098 << " STA " << p.first.second << '\n';
00099
00100 bool state (false);
00101
00102 BOOST_FOREACH(const tool::microseconds& t, p.second.events)
00103 {
00104 state = not state;
00105 os << " " << t << '\t' << state << '\n';
00106 }
00107 assert(state);
00108
00109 const tool::microseconds expiration_time = (p.second.last_seen +
00110 state::lifetime);
00111 if (expiration_time < last_stamps_[p.first.first])
00112 os << " " << expiration_time << "\t0\n";
00113
00114 os << " end ON/OFF T" << p.first.first
00115 << " STA " << p.first.second << "\n\n";
00116 }
00117 return os << "end ON/OFF events" << std::endl;
00118 }
00119
00120 inline
00121 tool::microseconds
00122 on_off_data::time_on(const addr& sta) const
00123 {
00124 typedef std::vector<tool::microseconds> events_type;
00125 typedef events_type::const_iterator events_iterator;
00126
00127 tool::microseconds r = 0;
00128
00129 for (unsigned t = 0; t <= trace_; ++t)
00130 {
00131 const states::const_iterator s = states_.find(state_id (t, sta));
00132
00133 if (s == states_.end())
00134 continue;
00135
00136 const events_type& events = s->second.events;
00137
00138 assert(not events.empty());
00139
00140 events_iterator e = events.begin();
00141 tool::microseconds start = *e++;
00142
00143 while (e != events.end())
00144 {
00145 r += *e++ - start;
00146 assert(e != events.end());
00147 start = *e++;
00148 }
00149
00150
00151
00152
00153
00154
00155 r += std::min(tool::microseconds (s->second.last_seen +
00156 state::lifetime),
00157 last_stamps_[t]) - start;
00158 }
00159 return r;
00160 }
00161
00162 inline
00163 on_off_data::state::state(const tool::microseconds& first_seen):
00164 last_seen (first_seen)
00165 {
00166 events.push_back(first_seen);
00167 }
00168
00169 }
00170
00171 }
00172
00173 }
00174
00175 #endif // ! WIFI_STATS_ON_OFF_DATA_HXX_