00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_FRAME_STATS_HH_
00023 # define WIFI_FRAME_STATS_HH_
00024
00025 # include <ostream>
00026 # include <map>
00027 # include <vector>
00028
00029 # include <boost/optional.hpp>
00030 # include <boost/tuple/tuple.hpp>
00031 # include <boost/tuple/tuple_comparison.hpp>
00032
00033 # include <wipal/wifi/frame/dissector/default_hooks.hh>
00034 # include <wipal/pcap/frame_descriptor.hh>
00035 # include <wipal/tool/microseconds.hh>
00036 # include <wipal/wifi/frame/seqctl.hh>
00037
00038 namespace wifi
00039 {
00040
00041 namespace frame
00042 {
00043
00044 namespace stats
00045 {
00046
00047
00048
00049
00050
00051 struct abstract_stats
00052 {
00053 virtual ~abstract_stats();
00054 virtual std::ostream& print(std::ostream& o) const = 0;
00055 };
00056
00057
00058
00059
00060
00061 struct simple_counters: public abstract_stats
00062 {
00063 simple_counters();
00064
00065 void operator () (unsigned type,
00066 unsigned subtype,
00067 bool retransmitted);
00068 std::ostream& print(std::ostream& o) const;
00069 unsigned total() const;
00070
00071 private:
00072 unsigned total_;
00073 unsigned retransmitted_;
00074 unsigned type_count_[4];
00075 unsigned subtype_count_[4][16];
00076 };
00077
00078
00079
00080
00081
00082 struct gap_lengths: public abstract_stats
00083 {
00084 gap_lengths();
00085
00086 void operator () (unsigned gap_length);
00087 std::ostream& print(std::ostream& o) const;
00088
00089 private:
00090 typedef std::vector<unsigned> gaplen_frequencies;
00091
00092 enum
00093 {
00094 gl_max = 2048,
00095 gl_freqs_resolution = 16,
00096 gl_freqs_size = gl_max / gl_freqs_resolution
00097 };
00098
00099 gaplen_frequencies gl_freqs_;
00100 unsigned gap_count_;
00101 };
00102
00103
00104
00105
00106
00107 struct missed_estimations: public abstract_stats
00108 {
00109 missed_estimations(const simple_counters& c);
00110
00111 void operator () ();
00112 void operator () (unsigned gap_length);
00113 std::ostream& print(std::ostream& o) const;
00114
00115 private:
00116 enum
00117 {
00118 threshold_steps = 16,
00119 missed_size = 2048 / threshold_steps
00120 };
00121
00122 unsigned missed_[missed_size];
00123 const simple_counters* c_;
00124 };
00125
00126
00127
00128
00129
00130 struct stats: public abstract_stats
00131 {
00132 stats();
00133
00134 template <class PhyHeader, class Frame>
00135 void
00136 account(const Frame& f);
00137
00138 void clear_states();
00139 std::ostream& print(std::ostream& o) const;
00140
00141 const simple_counters& counters() const;
00142 const gap_lengths& gaplens() const;
00143 const missed_estimations& missed() const;
00144
00145 private:
00146 enum
00147 {
00148 state_lifetime = 60 * 1000 * 1000
00149 };
00150
00151 struct state
00152 {
00153 state(unsigned last_frame_id,
00154 const seqctl& last_sc,
00155 const tool::microseconds& last_rx_stamp);
00156
00157 unsigned last_frame_id;
00158 seqctl last_sc;
00159 tool::microseconds last_rx_stamp;
00160 };
00161
00162 typedef boost::tuple<addr, addr, uint8_t> state_id;
00163 typedef std::map<state_id, state> states;
00164
00165 struct hooks: public dissector_default_hooks
00166 {
00167 hooks();
00168
00169 void addr_hook(const void*, size_t, unsigned, const addr&);
00170 void seq_ctl_hook(const void*, size_t, unsigned, unsigned);
00171 void qos_ctl_hook(const void*, size_t,
00172 unsigned, bool, unsigned, unsigned);
00173
00174 typedef boost::optional<seqctl> optional_seqctl;
00175 typedef boost::optional<state_id> optional_state_id;
00176
00177 unsigned type;
00178 unsigned subtype;
00179 bool retx;
00180 optional_seqctl sc;
00181 optional_state_id id;
00182
00183 private:
00184 const addr* receiver;
00185 };
00186
00187 private:
00188 states states_;
00189
00190 simple_counters counters_;
00191 gap_lengths gap_lengths_;
00192 missed_estimations missed_;
00193 };
00194
00195 std::ostream&
00196 operator << (std::ostream& os, const abstract_stats& s);
00197
00198 }
00199
00200 }
00201
00202 }
00203
00204 # include "stats.hxx"
00205
00206 #endif // ! WIFI_FRAME_STATS_HH_