00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_MACTIME_TRACKER_HXX_
00023 # define WIFI_MACTIME_TRACKER_HXX_
00024
00025 # include "mactime_tracker.hh"
00026
00027 namespace wifi
00028 {
00029
00030 template <class Bottom>
00031 mactime_tracker<Bottom>::mactime_tracker(): low_bits_ (0),
00032 wrap_count_ (0)
00033 {
00034 }
00035
00036 template <class Bottom>
00037 void
00038 mactime_tracker<Bottom>::tick_32(uint32_t ts)
00039 {
00040 if (ts < low_bits_)
00041 ++wrap_count_;
00042 low_bits_ = ts;
00043 }
00044
00045 template <class Bottom>
00046 void
00047 mactime_tracker<Bottom>::tick_64(uint64_t ts)
00048 {
00049 low_bits_ = uint32_t (ts);
00050 wrap_count_ = ts >> (sizeof (low_bits_) * 8);
00051 }
00052
00053 template <class Bottom>
00054 void
00055 mactime_tracker<Bottom>::tick_tv(const struct timeval& tv)
00056 {
00057 const size_t low_len = sizeof (low_bits_) * 8;
00058 const mpz_class low_mask = uint32_t (-1);
00059
00060 mpz_class t (tv.tv_sec);
00061 t *= 1000000;
00062 t += tv.tv_usec;
00063
00064 low_bits_ = mpz_class (t & low_mask).get_ui();
00065 wrap_count_ = mpz_class (t >> low_len).get_ui();
00066 }
00067
00068 namespace internals
00069 {
00070
00071 template <class I, class B>
00072 struct tick_switch
00073 {
00074 static void tick(mactime_tracker<B>& trk,
00075 const pcapxx::frame_descriptor& fd,
00076 const I& )
00077 {
00078 trk.tick_tv(fd.pcap_header()->ts);
00079 }
00080 };
00081
00082 template <class B>
00083 struct tick_switch<uint32_t, B>
00084 {
00085 static void tick(mactime_tracker<B>& trk,
00086 const pcapxx::frame_descriptor& ,
00087 uint32_t ts)
00088 {
00089 trk.tick_32(ts);
00090 }
00091 };
00092
00093 template <class B>
00094 struct tick_switch<uint64_t, B>
00095 {
00096 static void tick(mactime_tracker<B>& trk,
00097 const pcapxx::frame_descriptor& ,
00098 uint64_t ts)
00099 {
00100 trk.tick_64(ts);
00101 }
00102 };
00103
00104 template <class B>
00105 struct tick_switch<struct timeval, B>
00106 {
00107 static void tick(mactime_tracker<B>& trk,
00108 const pcapxx::frame_descriptor& ,
00109 const struct timeval& tv)
00110 {
00111 trk.tick_tv(tv);
00112 }
00113 };
00114
00115 }
00116
00117 template <class Bottom>
00118 template <class HT>
00119 void
00120 mactime_tracker<Bottom>::tick(const pcapxx::frame_descriptor& frame,
00121 tool::endian::endianness phy_end)
00122 {
00123 const pcapxx::pkthdr& pcap = *frame.pcap_header();
00124 const bool swap = tool::endian::need_swap(phy_end,
00125 pcap.swapped);
00126 const HT* const bytes = (reinterpret_cast<const HT*>
00127 (frame.bytes().get()));
00128
00129 if (pcap.caplen < bytes->len(pcap.caplen, swap))
00130 return;
00131
00132 internals::tick_switch<typename HT::time_type::impl_type, Bottom>::
00133 tick(*this, frame, bytes->time_get(swap).get());
00134 }
00135
00136 template <class Bottom>
00137 tool::microseconds
00138 mactime_tracker<Bottom>::microseconds() const
00139 {
00140 return tool::microseconds(wrap_count_, low_bits_);
00141 }
00142
00143 }
00144
00145 #endif // ! WIFI_MACTIME_TRACKER_HXX_