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_SIMPLE_MERGE_HXX_
00023 # define WIFI_FRAME_FILTER_SIMPLE_MERGE_HXX_
00024
00025 # include "simple_merge.hh"
00026
00027 # include <trace-tools/prism_header.hh>
00028 # include <trace-tools/wifi/frame/filter/time_adjuster.hh>
00029
00030 namespace wifi
00031 {
00032 namespace frame
00033 {
00034 namespace filter
00035 {
00036
00037 namespace internals
00038 {
00039
00040 template <class HT, class I1, class I2, class B1, class B2>
00041 simple_merge_iterator<HT, I1, I2, B1, B2>::
00042 simple_merge_iterator(const iterable_type& i, bool end):
00043 iterable_ (&i),
00044 next1_ (end ? i.last1_ : i.first1_),
00045 next2_ (end ? i.last2_ : i.first2_),
00046 current_ (first_packet())
00047 {
00048 }
00049
00050 template <class HT, class I1, class I2, class B1, class B2>
00051 bool
00052 simple_merge_iterator<HT, I1, I2, B1, B2>::
00053 equal(const simple_merge_iterator& rhs) const
00054 {
00055 return next1_ == rhs.next1_ and next2_ == rhs.next2_;
00056 }
00057
00058 template <class HT, class I1, class I2, class B1, class B2>
00059 void
00060 simple_merge_iterator<HT, I1, I2, B1, B2>::increment()
00061 {
00062 assert(current_ == 0 or current_ == 1);
00063
00064 if (next1_ == iterable_->last1_)
00065 ++next2_;
00066 else if (next2_ == iterable_->last2_)
00067 ++next1_;
00068 else if (internals::equal<HT>(*next1_, *next2_, iterable_->phy_end_))
00069 {
00070 ++next1_;
00071 ++next2_;
00072 }
00073 else
00074 {
00075 if (current_)
00076 ++next2_;
00077 else
00078 ++next1_;
00079 }
00080 current_ = first_packet();
00081 }
00082
00083 template <class HT, class I1, class I2, class B1, class B2>
00084 const typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type&
00085 simple_merge_iterator<HT, I1, I2, B1, B2>::get() const
00086 {
00087 assert(current_ == 0 or current_ == 1);
00088
00089 if (current_)
00090 return *next2_;
00091 else
00092 return *next1_;
00093 }
00094
00095 template <class HT, class I1, class I2, class B1, class B2>
00096 typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type&
00097 simple_merge_iterator<HT, I1, I2, B1, B2>::get()
00098 {
00099 assert(current_ == 0 or current_ == 1);
00100
00101 if (current_)
00102 return next2_.get();
00103 else
00104 return next1_.get();
00105 }
00106
00107 template <class HT, class I1, class I2, class B1, class B2>
00108 const typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type*
00109 simple_merge_iterator<HT, I1, I2, B1, B2>::get_ptr() const
00110 {
00111 assert(current_ == 0 or current_ == 1);
00112
00113 if (current_)
00114 return next2_.get_ptr();
00115 else
00116 return next1_.get_ptr();
00117 }
00118
00119 template <class HT, class I1, class I2, class B1, class B2>
00120 typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type*
00121 simple_merge_iterator<HT, I1, I2, B1, B2>::get_ptr()
00122 {
00123 assert(current_ == 0 or current_ == 1);
00124
00125 if (current_)
00126 return next2_.get_ptr();
00127 else
00128 return next1_.get_ptr();
00129 }
00130
00131 template <class HT, class I1, class I2, class B1, class B2>
00132 int
00133 simple_merge_iterator<HT, I1, I2, B1, B2>::first_packet() const
00134 {
00135 const bool first_at_end = next1_ == iterable_->last1_;
00136 const bool second_at_end = next2_ == iterable_->last2_;
00137
00138 if (first_at_end)
00139 return second_at_end ? -1 : 1;
00140 if (second_at_end)
00141 return 0;
00142
00143 return next1_->microseconds() < next2_->microseconds() ? 0 : 1;
00144 }
00145
00146 template <>
00147 inline
00148 bool
00149 equal<prism::header>(const pcapxx::frame_descriptor& lhs,
00150 const pcapxx::frame_descriptor& rhs,
00151 tool::endian::endianness phy_end)
00152 {
00153 using tool::endian::need_swap;
00154
00155 typedef prism::header bt;
00156 typedef pcapxx::pkthdr pt;
00157
00158 const pt* const lp = lhs.pcap_header().get();
00159 const bool ls = need_swap(phy_end, lp->swapped);
00160 const bt* const lb = reinterpret_cast<const bt*> (lhs.bytes().get());
00161
00162 const pt* const rp = rhs.pcap_header().get();
00163 const bool rs = need_swap(phy_end, rp->swapped);
00164 const bt* const rb = reinterpret_cast<const bt*> (rhs.bytes().get());
00165
00166 return eq_time_and_80211(lb, lp->caplen, ls,
00167 rb, rp->caplen, rs);
00168 }
00169
00170 }
00171
00172
00173 template <class HeaderType,
00174 class InputIterator1,
00175 class InputIterator2,
00176 class Bottom>
00177 simple_merge<HeaderType, InputIterator1, InputIterator2, Bottom>::
00178 simple_merge(const InputIterator1& first1, const InputIterator1& last1,
00179 const InputIterator2& first2, const InputIterator2& last2,
00180 tool::endian::endianness phy_end):
00181 phy_end_ (phy_end),
00182 first1_ (first1),
00183 last1_ (last1),
00184 first2_ (first2),
00185 last2_ (last2)
00186 {
00187 }
00188
00189 namespace internals
00190 {
00191
00192 template <class HT, class I, class F>
00193 struct provide_simple_merge
00194 {
00195 provide_simple_merge(const I& first1,
00196 const I& last1,
00197 F& func,
00198 bool filter_prism,
00199 tool::endian::endianness phy_end):
00200 first1_ (first1),
00201 last1_ (last1),
00202 func_ (func),
00203 filter_prism_ (filter_prism),
00204 phy_end_ (phy_end)
00205 {
00206 }
00207
00208 template <class TimeAdjuster>
00209 void
00210 operator () (const TimeAdjuster& a)
00211 {
00212 if (filter_prism_)
00213 {
00214 typedef non_noisy_prism<I> nnp;
00215 typedef typename nnp::const_iterator n_iterator;
00216 typedef microseconds_stamper<n_iterator, HT> us_stamper;
00217 typedef typename us_stamper::const_iterator u_iterator;
00218 typedef typename TimeAdjuster::const_iterator a_iterator;
00219 typedef simple_merge<HT, u_iterator, a_iterator> merger;
00220
00221 nnp n (first1_, last1_);
00222 us_stamper s (n.begin(), n.end(), phy_end_);
00223 merger m (s.begin(), s.end(),
00224 a.begin(), a.end(), phy_end_);
00225
00226 func_(m);
00227 }
00228 else
00229 {
00230 typedef microseconds_stamper<I, HT> us_stamper;
00231 typedef typename us_stamper::const_iterator u_iterator;
00232 typedef typename TimeAdjuster::const_iterator a_iterator;
00233 typedef simple_merge<HT, u_iterator, a_iterator> merger;
00234
00235 us_stamper s (first1_, last1_, phy_end_);
00236 merger m (s.begin(), s.end(),
00237 a.begin(), a.end(), phy_end_);
00238
00239 func_(m);
00240 }
00241 }
00242
00243 private:
00244 const I& first1_;
00245 const I& last1_;
00246 F& func_;
00247 bool filter_prism_;
00248 tool::endian::endianness phy_end_;
00249 };
00250
00251 }
00252
00253 template <class U, class HT, template <class, class, class> class Int,
00254 class I1, class I2, class F>
00255 void
00256 provide_simple_merge(const I1& first1, const I1& last1,
00257 const I2& first2, const I2& last2,
00258 addr_mapping& mapping,
00259 F& func,
00260 bool filter_prism,
00261 tool::endian::endianness phy_end)
00262 {
00263 internals::provide_simple_merge<HT, I1, F> func2 (first1, last1,
00264 func,
00265 filter_prism,
00266 phy_end);
00267
00268 provide_time_adjuster<U, HT, Int>(first1, last1,
00269 first2, last2,
00270 mapping, func2,
00271 filter_prism, phy_end);
00272 }
00273
00274 }
00275
00276 }
00277
00278 }
00279
00280 #endif // ! WIFI_FRAME_FILTER_SIMPLE_MERGE_HXX_