Fix documentation build under maverick (doxygen 1.7.1)
[senf.git] / senf / Packets / 80221Bundle / TLVParser.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Thorsten Horstmann <tho@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 TLVParser public header */
25
26 #ifndef HH_SENF_Packets_80221Bundle_TLVParser_
27 #define HH_SENF_Packets_80221Bundle_TLVParser_ 1
28
29 // Custom includes
30 #include <algorithm>
31 #include <senf/Packets/Packets.hh>
32 #include "MIHTypes.hh"
33
34 //#include "TLVParser.mpp"
35 //-/////////////////////////////////////////////////////////////////////////////////////////////////
36
37 namespace senf {
38
39     struct MIHTLVLengthException : public senf::Exception
40     {
41         MIHTLVLengthException()
42           : senf::Exception("MIHTLVLengthException") {}
43     };
44
45
46     class MIHTLVLengthParser
47         : public detail::packet::IntParserOps<MIHTLVLengthParser, boost::uint32_t>,
48           public PacketParserBase
49     {
50     public:
51         MIHTLVLengthParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
52
53         typedef boost::uint32_t value_type;
54         static const size_type init_bytes = 1;
55         static value_type const min_value = 0;
56         static value_type const max_value = 4294967295u;
57
58         value_type value() const;
59         void value(value_type const & v);
60
61         MIHTLVLengthParser const & operator= (value_type other);
62         size_type bytes() const;
63         void init() const;
64
65 #       include SENF_PARSER()
66         SENF_PARSER_PRIVATE_FIELD ( length_field, UInt8Parser );
67         SENF_PARSER_GOTO( length_field );
68         SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1,  bool     );
69         SENF_PARSER_PRIVATE_BITFIELD ( underflow_flag,       1,  bool     );
70         SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field,   6,  unsigned );
71
72         void finalize();
73         void capacity(value_type v);
74         value_type capacity() const;
75
76     private:
77         void resize_(size_type size);
78     };
79
80
81     /** \brief Base class for MIH TLV parsers
82
83          MIHBaseTLVParser is the abstract base class for MIH TLV parsers. It defines the
84          \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a
85          MIHTLVLengthParser. The length field is read-only.
86
87          To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't
88          forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example
89          the value is a vector of MacAddresses:
90          \code
91          struct MacAddressesTLVParser : public MIHBaseTLVParser {
92          #   include SENF_PARSER()
93              SENF_PARSER_INHERIT ( MIHBaseTLVParser );
94              SENF_PARSER_VECTOR  ( value, bytes(length), senf::MACAddressParser );
95              SENF_PARSER_FINALIZE( MacAddressesTLVParser );
96          };
97          \endcode
98
99          You have to adjust the maximum length value with the \ref maxLength function
100          before the length value is set. The default maximum value is 128. So, in the above
101          example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
102          if you don't call \c maxLength( \e some_value) before.
103
104          \see MIHTLVLengthParser \n
105            MIHGenericTLVParser \n
106      */
107     class MIHBaseTLVParser : public PacketParserBase
108     {
109     public:
110 #       include SENF_PARSER()
111         SENF_PARSER_FIELD    ( type,   UInt8Parser        );
112         SENF_PARSER_FIELD_RO ( length, MIHTLVLengthParser );
113         SENF_PARSER_FINALIZE ( MIHBaseTLVParser           );
114
115         /** \brief shrink size of the TLV length field to minimum
116
117             The size of the length field will be decreased to minimum necessary to hold
118             the current length value.
119          */
120         void finalize();
121
122         typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
123
124     protected:
125         /** \brief set maximum value of TLV length field
126
127             The size of the length field will be increased if necessary.
128             \param v maximum value of length field
129          */
130         void maxLength(MIHTLVLengthParser::value_type maxl) const;
131     };
132
133
134
135     /** \brief Parser for a generic TLV packet
136      */
137     struct MIHGenericTLVParser
138         : public GenericTLVParserBase<MIHBaseTLVParser>
139     {
140         typedef senf::GenericTLVParserBase<MIHBaseTLVParser> base;
141         MIHGenericTLVParser(data_iterator i, state_type s) : base(i,s) {}
142
143         void init() const {
144             defaultInit();
145             maxLength( MIHTLVLengthParser::max_value);
146         }
147
148         using base::init;
149         using base::maxLength;
150     };
151
152
153     /** \brief Base class for list TLV parser
154      */
155     struct MIHBaseListTLVParser
156         : public MIHBaseTLVParser
157     {
158     #   include SENF_PARSER()
159         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
160         SENF_PARSER_FIELD_RO ( listSize, MIHTLVLengthParser );
161         SENF_PARSER_FINALIZE ( MIHBaseListTLVParser );
162
163         void maxListSize(MIHTLVLengthParser::value_type maxl) const;
164     };
165
166     template <class Self>
167     struct MIHListTLVParserMixin
168     {
169         void finalize();
170     };
171
172
173     /** \brief Parse a MIHF_ID
174
175          Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
176          We could set maxLength in init(), but for the most MIHF_IDs the default
177          maximum length of 128 should be enough.
178
179          \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer
180              than 128.
181
182          \see MIHFId
183     */
184     class MIHFIdTLVParser : public MIHBaseTLVParser
185     {
186     #   include SENF_PARSER()
187         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
188         SENF_PARSER_FIELD_RO ( idLength, MIHTLVLengthParser );
189         SENF_PARSER_LABEL    ( idValue          );
190         SENF_PARSER_SKIP     ( idLength(), 0    );
191         SENF_PARSER_FINALIZE ( MIHFIdTLVParser  );
192
193     public:
194         ///\name Value setters
195         //\{
196         void value( MIHFId const & id);
197
198         void value( std::string        const & id  );
199         void value( senf::MACAddress   const & addr);
200         void value( senf::INet4Address const & addr);
201         void value( senf::INet6Address const & addr);
202         void value( senf::EUI64        const & addr);
203         //\}
204
205         ///\name Value getters
206         //\{
207         MIHFId valueAs( MIHFId::Type type) const;
208
209         std::string        valueAsString()       const;
210         senf::MACAddress   valueAsMACAddress()   const;
211         senf::INet4Address valueAsINet4Address() const;
212         senf::INet6Address valueAsINet6Address() const;
213         senf::EUI64        valueAsEUI64()        const;
214         //\}
215
216         ///\name Value comparisons
217         //\{
218         bool valueEquals( MIHFId const & id) const;
219
220         bool valueEquals( std::string        const & id  ) const;
221         bool valueEquals( senf::MACAddress   const & addr) const;
222         bool valueEquals( senf::INet4Address const & addr) const;
223         bool valueEquals( senf::INet6Address const & addr) const;
224         bool valueEquals( senf::EUI64        const & addr) const;
225         //\}
226
227         void dump(std::ostream & os) const;
228         void maxIdLength(boost::uint8_t maxl) const;
229         void finalize();
230
231     private:
232         /// resize the packet after the length field to given size
233         senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
234
235         data_iterator valueBegin() const;
236         data_iterator valueEnd() const;
237
238         template <class OutputIterator>
239         struct binaryNAIEncoder {
240             binaryNAIEncoder(OutputIterator & i);
241             void operator()(boost::uint8_t v);
242             OutputIterator & i_;
243         };
244
245         template <class OutputIterator>
246         static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> >
247         getNAIEncodedOutputIterator(OutputIterator i);
248
249         struct binaryNAIDecoder {
250             binaryNAIDecoder();
251             bool operator()(boost::uint8_t v);
252             bool readNextByte_;
253         };
254
255         template <class Iterator>
256         static boost::filter_iterator<binaryNAIDecoder, Iterator>
257         getNAIDecodedIterator(Iterator begin, Iterator end);
258
259         struct ValueSetterVisitor : public boost::static_visitor<> {
260             MIHFIdTLVParser & parser;
261             ValueSetterVisitor( MIHFIdTLVParser & p) : parser(p) {}
262             void operator()( boost::blank ) const {
263                 parser.value( std::string());
264             }
265             template <typename MIHFIdType>
266             void operator()( MIHFIdType const & id ) const {
267                 parser.value( id);
268             }
269         };
270
271         struct ValueEqualsVisitor : public boost::static_visitor<bool> {
272             MIHFIdTLVParser const & parser;
273             ValueEqualsVisitor( MIHFIdTLVParser const & p) : parser(p) {}
274             bool operator()( boost::blank ) const {
275                 return parser.idLength() == 0;
276             }
277             template <typename MIHFIdType>
278             bool operator()( MIHFIdType const & id ) const {
279                 return parser.valueEquals( id);
280             }
281         };
282     };
283
284     /** \brief Parser for 802.21 source MIHF_ID TLV
285      */
286     struct MIHFSrcIdTLVParser : public MIHFIdTLVParser
287     {
288         MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
289
290         void init() const {
291             defaultInit();
292             type() << typeId+0;
293         }
294         static type_t::value_type const typeId = 1;
295         void dump(std::ostream & os) const;
296     };
297
298     /** \brief Parser for 802.21 destination MIHF_ID TLV
299      */
300     struct MIHFDstIdTLVParser : public MIHFIdTLVParser
301     {
302         MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
303
304         void init() const {
305             defaultInit();
306             type() << typeId+0;
307         }
308         static type_t::value_type const typeId = 2;
309         void dump(std::ostream & os) const;
310     };
311
312     /** \brief Parser for 802.21 Status TLV
313      */
314     struct MIHStatusTLVParser : public MIHBaseTLVParser
315     {
316     #   include SENF_PARSER()
317         SENF_PARSER_INHERIT ( MIHBaseTLVParser   );
318         SENF_PARSER_FIELD   ( value, UInt8Parser );
319         SENF_PARSER_FINALIZE( MIHStatusTLVParser );
320
321         SENF_PARSER_INIT() {
322             defaultInit();
323             type() << typeId+0;
324             length_() = 1;
325         }
326         static type_t::value_type const typeId = 3;
327         void dump(std::ostream & os) const; ///< dump string representation to given stream
328
329         enum StatusCode {
330             Success, UnspecifiedFailure, Rejected, AuthorizationFailure, NetworkError };
331     };
332
333     struct MIHRegisterReqCodeTLVParser : public MIHBaseTLVParser
334     {
335     #   include SENF_PARSER()
336         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
337         SENF_PARSER_FIELD    ( value, UInt8Parser );
338         SENF_PARSER_FINALIZE ( MIHRegisterReqCodeTLVParser );
339
340         SENF_PARSER_INIT() {
341             defaultInit();
342             type() = typeId+0;
343             length_() = 1;
344         }
345         static type_t::value_type const typeId = 11;
346         void dump(std::ostream & os) const; ///< dump string representation to given stream
347
348         enum RequestCode { Registration, ReRegistration };
349     };
350
351     struct MIHValidTimeIntervalTLVParser : public MIHBaseTLVParser
352     {
353     #   include SENF_PARSER()
354         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
355         SENF_PARSER_FIELD    ( value, UInt32Parser );
356         SENF_PARSER_FINALIZE ( MIHValidTimeIntervalTLVParser );
357
358         SENF_PARSER_INIT() {
359             defaultInit();
360             type() = typeId+0;
361             length_() = 4;
362         }
363         static type_t::value_type const typeId = 12;
364         void dump(std::ostream & os) const; ///< dump string representation to given stream
365     };
366
367 }
368
369
370 //-/////////////////////////////////////////////////////////////////////////////////////////////////
371 #include "TLVParser.cci"
372 #include "TLVParser.ct"
373 #include "TLVParser.cti"
374 #endif
375
376 \f
377 // Local Variables:
378 // mode: c++
379 // fill-column: 100
380 // c-file-style: "senf"
381 // indent-tabs-mode: nil
382 // ispell-local-dictionary: "american"
383 // compile-command: "scons -u test"
384 // comment-column: 40
385 // End: