Packets/80211Bundle: Read-only radiotap reimplementation
[senf.git] / senf / Packets / 80211Bundle / RadiotapPacket.cc
index b27bd13..ceff474 100644 (file)
 // Free Software Foundation, Inc.,
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
-// Definition of non-inline non-template functions
+// Definition of RadiotapPacket non-inline non-template functions
 
-// Custom includes
 #include "RadiotapPacket.hh"
+//#include "RadiotapPacket.ih"
+
+// Custom includes
 #include "WLANPacket.hh"
-#include <senf/Packets/Packets.hh>
 #include <boost/io/ios_state.hpp>
 
+extern "C" {
+#   include "radiotap/radiotap_iter.h"
+}
+
 #define prefix_
+///////////////////////////////cc.p//////////////////////////////////////
 
+prefix_ void senf::RadiotapPacketParser::fillOffsetTable(boost::uint8_t * data, int maxLength,
+                                                         OffsetTable & table)
+{
+    struct ieee80211_radiotap_iterator iter;
+    ieee80211_radiotap_iterator_init(&iter,
+                                     (struct ieee80211_radiotap_header *)data,
+                                     maxLength,
+                                     0);
+    while (ieee80211_radiotap_iterator_next(&iter)==0) {
+        if (iter.is_radiotap_ns &&
+            iter.this_arg_index <= int(senf::RadiotapPacketParser::MAX_INDEX)) {
+            table[iter.this_arg_index] = iter.this_arg - data;
+            std::cerr << ">> " << iter.this_arg_index << " " << table[iter.this_arg_index] << "\n";
+        }
+    }
+    table[MAX_INDEX+1] = iter.this_arg - data + iter.this_arg_size;
+    std::cerr << ">> size " << table[MAX_INDEX+1] << "\n";
+}
+
+prefix_ senf::RadiotapPacketParser::OffsetTable const &
+senf::RadiotapPacketParser::offsetTable(boost::uint32_t presentFlags)
+{
+    typedef std::map<boost::uint32_t, OffsetTable> OffsetMap;
+    static OffsetMap offsetMap;
+
+    OffsetMap::iterator i (offsetMap.find(presentFlags));
+    if (i == offsetMap.end()) {
+        OffsetTable table;
+        fillOffsetTable(&(*data().begin()), data().size(), table);
+        i = offsetMap.insert(std::make_pair(presentFlags, table)).first;
+    }
+    return i->second;
+}
+
+
+#define DUMP_OPTIONAL_FIELD(name, sign, desc)                           \
+    if (p->name ## Present())                                           \
+        os << senf::fieldName(desc) << sign(p->name())                  \
+           << std::endl;
 
 prefix_ void senf::RadiotapPacketType::dump(packet p, std::ostream &os)
 {
     boost::io::ios_all_saver ias(os);
     os << "Radiotap:\n"
-       << senf::fieldName("version")                  << unsigned( p->version()) << "\n"
-       << senf::fieldName("length")                   << unsigned( p->length()) << "\n";
-    if (p->has_tsft())
-        os << senf::fieldName("MAC timestamp")                << unsigned( p->tsft()) << "\n";
-    // TODO: flags
-    if (p->has_rate())
-        os << senf::fieldName("rate")                 << unsigned( p->rate()) << "\n";
-    // TODO: channelOptions
-    if (p->has_fhss())
-       os << senf::fieldName("FHSS")                  << unsigned( p->fhss()) << "\n";
-    if (p->has_dbmAntennaSignal())
-        os << senf::fieldName("antenna signal (dBm)")  << signed( p->dbmAntennaSignal()) << "\n";
-    if (p->has_dbmAntennaNoise())
-        os << senf::fieldName("antenna noise (dBm)")   << signed( p->dbmAntennaNoise()) << "\n";
-    if (p->has_lockQuality())
-        os << senf::fieldName("lock quality")         << unsigned( p->lockQuality()) << "\n";
-    if (p->has_txAttenuation())
-        os << senf::fieldName("tx attenuation")        << unsigned( p->txAttenuation()) << "\n";
-    if (p->has_dbTxAttenuation())
-        os << senf::fieldName("tx attenuation (dB)")   << unsigned( p->dbTxAttenuation()) << "\n";
-    if (p->has_dbmTxAttenuation())
-        os << senf::fieldName("tx attenuation (dBm)")  << signed( p->dbmTxAttenuation()) << "\n";
-    if (p->has_antenna())
-        os << senf::fieldName("antenna")              << unsigned( p->antenna()) << "\n";
-    if (p->has_dbAntennaSignal())
-        os << senf::fieldName("antenna signal (dB)")   << unsigned( p->dbAntennaSignal()) << "\n";
-    if (p->has_dbAntennaNoise())
-        os << senf::fieldName("antenna noise (dB)")    << unsigned( p->dbAntennaNoise()) << "\n";
-    if (p->has_headerFcs())
-        os << senf::fieldName("FCS")                  << unsigned( p->fcs()) << "\n";
+       << senf::fieldName("version") << unsigned(p->version()) << "\n"
+       << senf::fieldName("length")  << unsigned(p->length()) << "\n";
+    // TODO: flags, channelOptions
+    DUMP_OPTIONAL_FIELD( tsft,              unsigned, "MAC timestamp"        );
+    DUMP_OPTIONAL_FIELD( rate,              unsigned, "rate"                 );
+    DUMP_OPTIONAL_FIELD( fhss,              unsigned, "FHSS"                 );
+    DUMP_OPTIONAL_FIELD( dbmAntennaSignal,  signed,   "antenna signal (dBm)" );
+    DUMP_OPTIONAL_FIELD( dbmAntennaNoise,   signed,   "antenna noise (dBm)"  );
+    DUMP_OPTIONAL_FIELD( lockQuality,       unsigned, "lock quality"         );
+    DUMP_OPTIONAL_FIELD( txAttenuation,     unsigned, "tx attenuation"       );
+    DUMP_OPTIONAL_FIELD( dbTxAttenuation,   unsigned, "tx attenuation (dB)"  );
+    DUMP_OPTIONAL_FIELD( dbmTxAttenuation,  signed,   "tx attenuation (dBm)" );
+    DUMP_OPTIONAL_FIELD( antenna,           unsigned, "antenna"              );
+    DUMP_OPTIONAL_FIELD( dbAntennaSignal,   unsigned, "antenna signal (dB)"  );
+    DUMP_OPTIONAL_FIELD( dbAntennaNoise,    unsigned, "antenna noise (dB)"   );
+    DUMP_OPTIONAL_FIELD( headerFcs,         unsigned, "FCS (in header)"      );
+    if (p->flagsPresent() && p->flags().fcsAtEnd())
+        os << senf::fieldName("FCS (at end)") << unsigned(p->fcs()) << "\n";
 }
 
+#undef DUMP_OPTIONAL_FIELD
+
 prefix_ void senf::RadiotapPacketType::finalize(packet p)
 {
     p->length() << p->calculateSize();
@@ -86,9 +121,21 @@ senf::RadiotapPacketType::nextPacketRange(packet p)
 {
     size_type h (senf::bytes(p.parser()));
     size_type t (p->flagsPresent() && p->flags().fcsAtEnd() ? 4 : 0);
-    return p.size() < h+t 
-        ? no_range() 
+    return p.size() < h+t
+        ? no_range()
         : optional_range( range(p.data().begin() + h, p.data().end() - t) );
 }
 
+///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End: