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