Fix SCons 1.2.0 build failure
[senf.git] / Packets / 80211Bundle / RadiotapPacket.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Christian Niephaus <cni@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Radiotap header */
25
26 #ifndef HH_SENF_Packets_80211Bundle_RadiotapPacket_
27 #define HH_SENF_Packets_80211Bundle_RadiotapPacket_ 1
28
29 #include "../../Packets/Packets.hh"
30
31 namespace senf
32 {
33
34     /** \brief Parse Flag field in Radiotap header
35
36         <b>Re-ordering of bits due to LSB byte order</b>
37      */
38     struct RadiotapPacketParser_Flags : public PacketParserBase
39     {
40     #   include SENF_FIXED_PARSER()
41
42         SENF_PARSER_BITFIELD ( shortGI,        1, bool );
43         SENF_PARSER_BITFIELD ( badFCS,         1, bool );
44         SENF_PARSER_BITFIELD ( padding,        1, bool );
45         SENF_PARSER_BITFIELD_RO ( fcsAtEnd,    1, bool ); // Cannot change this (change packet size)
46         SENF_PARSER_BITFIELD ( fragmentation,  1, bool );
47         SENF_PARSER_BITFIELD ( wep,            1, bool );
48         SENF_PARSER_BITFIELD ( shortPreamble,  1, bool );
49         SENF_PARSER_BITFIELD ( cfp,            1, bool );
50
51         SENF_PARSER_FINALIZE ( RadiotapPacketParser_Flags );
52     };
53
54     /** \brief Parse in Radiotap Header channel frequency and flag field
55
56         <b>Re-ordering of bits due to LSB byte order</b>
57      */
58     struct RadiotapPacketParser_ChannelOptions : public PacketParserBase
59     {
60     #   include SENF_FIXED_PARSER()
61
62         SENF_PARSER_FIELD     ( freq,          UInt16LSBParser );
63
64         SENF_PARSER_BITFIELD  ( flag2ghz,             1, bool  );
65         SENF_PARSER_BITFIELD  ( ofdm,                 1, bool  );
66         SENF_PARSER_BITFIELD  ( cck,                  1, bool  );
67         SENF_PARSER_BITFIELD  ( turbo,                1, bool  );
68         SENF_PARSER_SKIP_BITS ( 4                              ); //currently unused in radiotap
69         SENF_PARSER_BITFIELD  ( quarterRateChannel,   1, bool  );
70         SENF_PARSER_BITFIELD  ( halfRateChannel,      1, bool  );
71         SENF_PARSER_BITFIELD  ( gsm,                  1, bool  );
72         SENF_PARSER_BITFIELD  ( staticTurbo,          1, bool  );
73         SENF_PARSER_BITFIELD  ( gfsk,                 1, bool  );
74         SENF_PARSER_BITFIELD  ( cckOfdm,              1, bool  );
75         SENF_PARSER_BITFIELD  ( passive,              1, bool  );
76         SENF_PARSER_BITFIELD  ( flag5ghz,             1, bool  );
77
78         SENF_PARSER_FINALIZE ( RadiotapPacketParser_ChannelOptions );
79     };
80
81     /** \brief Parse an Radiotap header
82
83         Parser implementing the Radiotap header
84
85         Radiotap requires that all fields in the radiotap header
86         are aligned to natural boundaries. For radiotap,
87         that means all 8-, 16-, 32-, and 64-bit fields
88         must begin on 8-, 16-, 32-, and 64-bit boundaries, respectively.
89         In this way, generators and parsers can avoid unaligned
90         accesses to radiotap capture fields. Radiotap-compliant
91         generators must insert padding before a capture field
92         to ensure its natural alignment.
93
94         \see <a href="http://www.radiotap.org">Radiotap.org</a>
95
96         \todo extended present field (bit 31 of present field is set)
97     */
98     struct RadiotapPacketParser : public PacketParserBase
99     {
100     #   include SENF_PARSER()
101
102         /*
103          * mandatory fields
104          */
105         SENF_PARSER_FIELD ( version, UInt8Parser     );
106         //padding bits, currently unused, it simply aligns the fields onto natural word boundaries.
107         SENF_PARSER_SKIP  ( 1,1                      );
108         SENF_PARSER_FIELD ( length,  UInt16LSBParser );
109
110         /*
111          * present flags
112          * indicate which data field are contained in the packet
113          */
114         SENF_PARSER_BITFIELD_RO ( lockQualityPresent,      1, bool );
115         SENF_PARSER_BITFIELD_RO ( dbmAntennaNoisePresent,  1, bool );
116         SENF_PARSER_BITFIELD_RO ( dbmAntennaSignalPresent, 1, bool );
117         SENF_PARSER_BITFIELD_RO ( fhssPresent,             1, bool );
118         SENF_PARSER_BITFIELD_RO ( channelOptionsPresent,   1, bool );
119         SENF_PARSER_BITFIELD_RO ( ratePresent,             1, bool );
120         SENF_PARSER_BITFIELD_RO ( flagsPresent,            1, bool );
121         SENF_PARSER_BITFIELD_RO ( tsftPresent,             1, bool );
122         SENF_PARSER_SKIP_BITS   ( 1                                ); //currently unused bits
123         SENF_PARSER_BITFIELD_RO ( headerFcsPresent,        1, bool );
124         SENF_PARSER_BITFIELD_RO ( dbAntennaNoisePresent,   1, bool );
125         SENF_PARSER_BITFIELD_RO ( dbAntennaSignalPresent,  1, bool );
126         SENF_PARSER_BITFIELD_RO ( antennaPresent,          1, bool );
127         SENF_PARSER_BITFIELD_RO ( dbmTxAttenuationPresent, 1, bool );
128         SENF_PARSER_BITFIELD_RO ( dbTxAttenuationPresent,  1, bool );
129         SENF_PARSER_BITFIELD_RO ( txAttenuationPresent,    1, bool );
130         SENF_PARSER_SKIP_BITS   ( 8                                ); //currently unused bits
131         //if bit is set,another 32 bit present flag is attached (not implemented yet)
132         SENF_PARSER_BITFIELD    ( extendedBitmaskPresent,  1, bool );
133         SENF_PARSER_SKIP_BITS   ( 7                                ); //currently unused bits
134
135         SENF_PARSER_LABEL( headerEnd_ );
136
137         /*
138          * Radiotap data
139          * parsing data according to present flags
140          *
141          * PARSER_SKIP required to skip correct length of padding bits
142          */
143
144         /* macro to create required variant parser */
145         #define OPTIONAL_FIELD(name, parser) SENF_PARSER_VARIANT \
146             ( name##_, name##Present, \
147               ( novalue( disable_##name, VoidPacketParser )) \
148               (      id( name,           parser           )) )
149
150         /* macro to create padding parser */
151         #define SKIP_OPTIONAL_PADDING(cond, parser, size) \
152             SENF_PARSER_SKIP( \
153                     (cond ? (size - (parser##__offset() + \
154                             senf::bytes(parser##_())) % size) % size : 0) , 0  );
155
156         OPTIONAL_FIELD        ( tsft,                     UInt64LSBParser                     );
157         OPTIONAL_FIELD        ( flags,                    RadiotapPacketParser_Flags          ); //<pkgdraw: size=8
158         OPTIONAL_FIELD        ( rate,                     UInt8Parser                         );
159         SKIP_OPTIONAL_PADDING ( channelOptionsPresent(),  rate, 2                             );
160         OPTIONAL_FIELD        ( channelOptions,           RadiotapPacketParser_ChannelOptions ); //<pkgdraw: size=32
161         SKIP_OPTIONAL_PADDING ( fhssPresent(),            channelOptions, 2                   );
162         OPTIONAL_FIELD        ( fhss,                     UInt16LSBParser                     );
163         OPTIONAL_FIELD        ( dbmAntennaSignal,         Int8Parser                          );
164         OPTIONAL_FIELD        ( dbmAntennaNoise,          Int8Parser                          );
165         SKIP_OPTIONAL_PADDING ( lockQualityPresent(),     dbmAntennaNoise, 2                  );
166         OPTIONAL_FIELD        ( lockQuality,              UInt16LSBParser                     );
167         SKIP_OPTIONAL_PADDING ( txAttenuationPresent(),   lockQuality, 2                      );
168         OPTIONAL_FIELD        ( txAttenuation,            UInt16LSBParser                     );
169         SKIP_OPTIONAL_PADDING ( dbTxAttenuationPresent(), txAttenuation, 2                    );
170         OPTIONAL_FIELD        ( dbTxAttenuation,          UInt16LSBParser                     );
171         OPTIONAL_FIELD        ( dbmTxAttenuation,         Int8Parser                          );
172         OPTIONAL_FIELD        ( antenna,                  UInt8Parser                         );
173         OPTIONAL_FIELD        ( dbAntennaSignal,          UInt8Parser                         );
174         OPTIONAL_FIELD        ( dbAntennaNoise,           UInt8Parser                         );
175         SKIP_OPTIONAL_PADDING ( headerFcsPresent(),       dbAntennaNoise, 4                   );
176         OPTIONAL_FIELD        ( headerFcs,                UInt32Parser                        );
177
178         SENF_PARSER_LABEL( packetEnd_ );
179
180         size_type calculateSize() { return packetEnd__offset(); }
181
182         // Ouch ... changing the flags().fcsAtEnd() field needs to resize the packet ... !!!
183         // Need to think, if I can do this with a variant parser ...
184         SENF_PARSER_CUSTOM_FIELD( fcs, senf::UInt32Parser, 0, 0 ) {
185             return parse<senf::UInt32Parser>(data().end()-4);
186         }
187
188         SENF_PARSER_INIT() {
189             version() = 0;
190         }
191
192         // The headers length is to be taken from the 'length' value
193         SENF_PARSER_GOTO_OFFSET( length(), headerEnd__init_bytes );
194
195         SENF_PARSER_FINALIZE( RadiotapPacketParser );
196
197         SENF_PARSER_SKIP_BITS( 4 );
198         SENF_PARSER_BITFIELD_RO ( frameType, 2, unsigned );
199         SENF_PARSER_SKIP_BITS( 2 );
200             
201     };
202
203     /** \brief Radiotap packet
204
205         \par Packet type (typedef):
206             \ref RadiotapPacket
207
208         \par Fields:
209             \ref RadiotapPacketParser
210             \image html RadiotapPacket.png
211         
212         \see http://www.radiotap.org/
213         
214         \ingroup protocolbundle_80211
215      */
216     struct RadiotapPacketType
217         : public PacketTypeBase,
218           public PacketTypeMixin<RadiotapPacketType>
219     {
220         typedef PacketTypeMixin<RadiotapPacketType> mixin;
221         typedef ConcretePacket<RadiotapPacketType> packet;
222         typedef RadiotapPacketParser parser;
223
224         using mixin::init;
225         using mixin::initSize;
226
227         static void dump(packet p, std::ostream &os);
228         static void finalize(packet p);
229         static factory_t nextPacketType(packet p);
230         static optional_range nextPacketRange(packet p);
231     };
232
233     typedef ConcretePacket<RadiotapPacketType> RadiotapPacket;
234 }
235
236 #endif
237
238 \f
239 // Local Variables:
240 // mode: c++
241 // fill-column: 100
242 // comment-column: 40
243 // c-file-style: "senf"
244 // indent-tabs-mode: nil
245 // ispell-local-dictionary: "american"
246 // compile-command: "scons -u test"
247 // End: