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 <boost/optional.hpp>
00026
00027 # include <wipal/tool/gmp_64_wrapper.hh>
00028
00029 # include "mactime_tracker.hh"
00030
00031 namespace wifi
00032 {
00033
00034 template <class Bottom>
00035 mactime_tracker<Bottom>::mactime_tracker(): last_stamp_ (0),
00036 ms_count_ (0)
00037 {
00038 }
00039
00040 template <class Bottom>
00041 template <class UIntType>
00042 void
00043 mactime_tracker<Bottom>::tick_uint(UIntType ts)
00044 {
00045 const UIntType half_range (UIntType (1)
00046 << (sizeof (ts) * 8 - 1));
00047 const tool::microseconds ms_ts (ts);
00048 const tool::microseconds ms_last_stamp (last_stamp_);
00049
00050 ms_count_ += ms_ts - ms_last_stamp;
00051 if (ts < last_stamp_ and last_stamp_ - ts > half_range)
00052 {
00053 static boost::optional<tool::microseconds> range;
00054
00055 if (not range)
00056 {
00057 range = 1;
00058 *range <<= sizeof (ts) * 8;
00059 }
00060
00061 ms_count_ += *range;
00062 }
00063 last_stamp_ = ts;
00064 }
00065
00066 template <class Bottom>
00067 void
00068 mactime_tracker<Bottom>::tick_tv(const struct timeval& tv)
00069 {
00070 ms_count_ = tool::microseconds (tv);
00071 }
00072
00073 namespace internals
00074 {
00075
00076 template <class I, class B>
00077 struct tick_switch
00078 {
00079 template <class D>
00080 static void tick(mactime_tracker<B>& trk,
00081 const pcapxx::frame_descriptor<D>& fd,
00082 const I& )
00083 {
00084 trk.tick_tv(fd.pcap_header()->ts);
00085 }
00086 };
00087
00088 template <class B>
00089 struct tick_switch<uint32_t, B>
00090 {
00091 template <class D>
00092 static void tick(mactime_tracker<B>& trk,
00093 const pcapxx::frame_descriptor<D>& ,
00094 uint32_t ts)
00095 {
00096 trk.tick_uint(ts);
00097 }
00098 };
00099
00100 template <class B>
00101 struct tick_switch<uint64_t, B>
00102 {
00103 template <class D>
00104 static void tick(mactime_tracker<B>& trk,
00105 const pcapxx::frame_descriptor<D>& ,
00106 uint64_t ts)
00107 {
00108 trk.tick_uint(ts);
00109 }
00110 };
00111
00112 template <class B>
00113 struct tick_switch<struct timeval, B>
00114 {
00115 template <class D>
00116 static void tick(mactime_tracker<B>& trk,
00117 const pcapxx::frame_descriptor<D>& ,
00118 const struct timeval& tv)
00119 {
00120 trk.tick_tv(tv);
00121 }
00122 };
00123
00124 }
00125
00126 template <class Bottom>
00127 template <class HT, class D>
00128 void
00129 mactime_tracker<Bottom>::tick(const pcapxx::frame_descriptor<D>& frame,
00130 tool::endian::endianness phy_end)
00131 {
00132 const pcapxx::pkthdr& pcap = *frame.pcap_header();
00133 const bool swap = tool::endian::need_swap(phy_end,
00134 frame.swapped());
00135 const HT* const bytes = (reinterpret_cast<const HT*>
00136 (frame.bytes().get()));
00137
00138 if (pcap.caplen < bytes->len(pcap.caplen, swap))
00139 return;
00140
00141 internals::tick_switch<typename HT::time_type::impl_type, Bottom>::
00142 tick(*this, frame, bytes->time_get(swap).get());
00143 }
00144
00145 template <class Bottom>
00146 tool::microseconds
00147 mactime_tracker<Bottom>::microseconds() const
00148 {
00149 return ms_count_;
00150 }
00151
00152 }
00153
00154 #endif // ! WIFI_MACTIME_TRACKER_HXX_