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_FILTER_SYNCHRONIZER_HXX_
00023 # define WIFI_FRAME_FILTER_SYNCHRONIZER_HXX_
00024
00025 # include "linear_regression_synchronizer.hh"
00026
00027 # include <wipal/tool/linear_regression.hh>
00028 # include <wipal/tool/window.hh>
00029 # include <wipal/wifi/frame/filter/intersector.hh>
00030 # include <wipal/wifi/frame/filter/reference_blacklist.hh>
00031
00032 namespace wifi
00033 {
00034 namespace frame
00035 {
00036 namespace filter
00037 {
00038
00039 template <class OriginalFrameType, class ImplType>
00040 synchronized_frame<OriginalFrameType, ImplType>::
00041 synchronized_frame(const OriginalFrameType& orig,
00042 const coefs_type& coefs):
00043 OriginalFrameType (orig),
00044 coefs (coefs)
00045 {
00046 }
00047
00048 namespace internals
00049 {
00050
00051 template <class I, class B1, class B2>
00052 lr_sync_iterator<I, B1, B2>::
00053 lr_sync_iterator(const iterable_type& iterable, bool end):
00054 super_type (),
00055 iterable_ (&iterable),
00056 next_ (end ? iterable.last_ : iterable.first_),
00057 next_wpos_ (0)
00058 {
00059 if (not end)
00060 increment();
00061 }
00062
00063 template <class I, class B1, class B2>
00064 bool
00065 lr_sync_iterator<I, B1, B2>::equal(const exact_type& rhs) const
00066 {
00067 if (not rhs.value())
00068 return not this->value();
00069 return next_wpos_ == rhs.next_wpos_ and next_ == rhs.next_;
00070 }
00071
00072 template <class I, class B1, class B2>
00073 void
00074 lr_sync_iterator<I, B1, B2>::increment()
00075 {
00076 typedef typename value_type::impl_type impl_type;
00077
00078 typedef
00079 typename tool::lr::pair_with_microseconds<impl_type>
00080 adapter_type;
00081
00082 const I& last = iterable_->last_;
00083 const size_t window_size = next_->size();
00084
00085 bool acceptable = false;
00086
00087 while (not acceptable)
00088 {
00089 if (next_wpos_ == window_size and next_ == last)
00090 {
00091 this->value() = boost::none_t ();
00092 return;
00093 }
00094
00095 try
00096 {
00097 typedef typename I::value_type::value_type ref_type;
00098
00099 const std::pair<impl_type, impl_type> p =
00100 tool::linear_regression<impl_type, adapter_type>
00101 (next_->begin(), next_->end());
00102
00103 const ref_type& ref = next_[next_wpos_];
00104 const impl_type t1 = ref.first.microseconds();
00105 const impl_type t2 = ref.second.microseconds();
00106 const impl_type error = t2 - t1 * p.first - p.second;
00107
00108 if (error < -acceptable_error_threshold or
00109 acceptable_error_threshold < error)
00110 std::cerr << "WARNING: Ignoring ref. "
00111 << ref.first << '-' << ref.second
00112 << " because of a high sync. error ("
00113 << error << ")." << std::endl;
00114 else
00115 {
00116 if (p.first < 0.9 or 1.1 < p.first)
00117 std::cerr << "WARNING: Dubious sync. coef. of "
00118 << p.first << " for "
00119 << ref.first << '-' << ref.second
00120 << '.' << std::endl;
00121
00122 this->value() = value_type (ref, p);
00123 acceptable = true;
00124 }
00125 }
00126 catch (const std::invalid_argument& i)
00127 {
00128 typedef
00129 typename I::value_type::const_iterator
00130 const_iterator;
00131
00132 std::ostringstream o;
00133 const const_iterator b = next_->begin();
00134 const_iterator e = next_->end();
00135
00136 if (b != e)
00137 {
00138 --e;
00139 o << ".\nERROR: Between "
00140 << b->first << '-' << b->second << " and "
00141 << e->first << '-' << e->second;
00142 }
00143 throw std::runtime_error (i.what() + o.str());
00144 }
00145
00146 if (next_wpos_ < window_size / 2)
00147 ++next_wpos_;
00148 else
00149 {
00150 if (next_ != last)
00151 ++next_;
00152 if (next_ == last)
00153 ++next_wpos_;
00154 }
00155 }
00156 }
00157
00158 }
00159
00160 template <class I, class B>
00161 linear_regression_synchronizer<I, B>::
00162 linear_regression_synchronizer(const I& first, const I& last):
00163 first_ (first),
00164 last_ (last)
00165 {
00166 }
00167
00168 namespace internals
00169 {
00170
00171 template <class F, class BL>
00172 struct provide_lr_synchronizer
00173 {
00174 enum
00175 {
00176 window_size =
00177
00178 #ifdef WP_LRSYNC_WINDOW_SIZE
00179 WP_LRSYNC_WINDOW_SIZE
00180 #else // ! WP_LRSYNC_WINDOW_SIZE
00181 3
00182 #endif
00183
00184 };
00185
00186 typedef BL blacklist;
00187
00188 provide_lr_synchronizer(F& func, const blacklist& blist):
00189 func_ (func),
00190 blist_ (blist)
00191 {
00192 }
00193
00194 template <class Intersector>
00195 void
00196 operator () (const Intersector& i)
00197 {
00198 typedef typename Intersector::const_iterator i_iterator;
00199 typedef reference_blacklist<i_iterator> blist;
00200 typedef typename blist::const_iterator b_iterator;
00201 typedef tool::window_maker<b_iterator, window_size> window_maker;
00202 typedef typename window_maker::const_iterator w_iterator;
00203 typedef linear_regression_synchronizer<w_iterator> synchronizer;
00204
00205 blist l (i.begin(), i.end(), blist_);
00206 window_maker w (l.begin(), l.end());
00207 synchronizer s (w.begin(), w.end());
00208
00209 func_(s);
00210 }
00211
00212 private:
00213 F& func_;
00214 const blacklist& blist_;
00215 };
00216
00217 }
00218
00219 template <class U, class HT, template <class, class, class> class Int,
00220 class I1, class I2, class F, class BL>
00221 void
00222 provide_lr_synchronizer(const I1& first1, const I1& last1,
00223 const I2& first2, const I2& last2,
00224 addr_mapping& mapping,
00225 F& func,
00226 bool filter_prism,
00227 tool::endian::endianness phy_end,
00228 const BL& blist)
00229 {
00230 internals::provide_lr_synchronizer<F, BL> func2 (func, blist);
00231
00232 provide_intersector<U, HT, Int>(first1, last1,
00233 first2, last2,
00234 mapping, func2, filter_prism, phy_end);
00235 }
00236
00237
00238 }
00239
00240 }
00241
00242 }
00243
00244 #endif // ! WIFI_FRAME_FILTER_SYNCHRONIZER_HXX_