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