ce4048148b1c81c90ac7b11cf385604860e9071d
[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 validateTL(boost::uint8_t type, MIHTLVLengthParser::value_type length) const;
137     };
138
139
140
141     /** \brief Parser for a generic TLV packet
142      */
143     struct MIHGenericTLVParser
144         : public GenericTLVParserBase<MIHBaseTLVParser>
145     {
146         typedef senf::GenericTLVParserBase<MIHBaseTLVParser> base;
147         MIHGenericTLVParser(data_iterator i, state_type s) : base(i,s) {}
148
149         void init() const {
150             defaultInit();
151             maxLength( MIHTLVLengthParser::max_value);
152         }
153
154         using base::init;
155         using base::maxLength;
156     };
157
158
159     /** \brief Base class for list TLV parser
160      */
161     struct MIHBaseListTLVParser
162         : public MIHBaseTLVParser
163     {
164     #   include SENF_PARSER()
165         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
166         SENF_PARSER_FIELD_RO ( listSize, MIHTLVLengthParser );
167         SENF_PARSER_FINALIZE ( MIHBaseListTLVParser );
168
169         void maxListSize(MIHTLVLengthParser::value_type maxl) const;
170     };
171
172     template <class Self>
173     struct MIHListTLVParserMixin
174     {
175         void finalize();
176     };
177
178
179     /** \brief Parse a MIHF_ID
180
181          Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
182          We could set maxLength in init(), but for the most MIHF_IDs the default
183          maximum length of 128 should be enough.
184
185          \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer
186              than 128.
187
188          \see MIHFId
189     */
190     class MIHFIdTLVParser : public MIHBaseTLVParser
191     {
192     #   include SENF_PARSER()
193         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
194         SENF_PARSER_FIELD_RO ( idLength, MIHTLVLengthParser );
195         SENF_PARSER_LABEL    ( idValue          );
196         SENF_PARSER_SKIP     ( idLength(), 0    );
197         SENF_PARSER_FINALIZE ( MIHFIdTLVParser  );
198
199     public:
200         ///\name Value setters
201         //\{
202         void value( MIHFId const & id);
203
204         void value( std::string        const & id  );
205         void value( senf::MACAddress   const & addr);
206         void value( senf::INet4Address const & addr);
207         void value( senf::INet6Address const & addr);
208         void value( senf::EUI64        const & addr);
209         //\}
210
211         ///\name Value getters
212         //\{
213         MIHFId valueAs( MIHFId::Type type) const;
214
215         std::string        valueAsString()       const;
216         senf::MACAddress   valueAsMACAddress()   const;
217         senf::INet4Address valueAsINet4Address() const;
218         senf::INet6Address valueAsINet6Address() const;
219         senf::EUI64        valueAsEUI64()        const;
220         //\}
221
222         ///\name Value comparisons
223         //\{
224         bool valueEquals( MIHFId const & id) const;
225
226         bool valueEquals( std::string        const & id  ) const;
227         bool valueEquals( senf::MACAddress   const & addr) const;
228         bool valueEquals( senf::INet4Address const & addr) const;
229         bool valueEquals( senf::INet6Address const & addr) const;
230         bool valueEquals( senf::EUI64        const & addr) const;
231         //\}
232
233         void dump(std::ostream & os) const;
234         void maxIdLength(boost::uint8_t maxl) const;
235         void finalize();
236
237     private:
238         /// resize the packet after the length field to given size
239         senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
240
241         data_iterator valueBegin() const;
242         data_iterator valueEnd() const;
243
244         template <class OutputIterator>
245         struct binaryNAIEncoder {
246             binaryNAIEncoder(OutputIterator & i);
247             void operator()(boost::uint8_t v);
248             OutputIterator & i_;
249         };
250
251         template <class OutputIterator>
252         static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> >
253         getNAIEncodedOutputIterator(OutputIterator i);
254
255         struct binaryNAIDecoder {
256             binaryNAIDecoder();
257             bool operator()(boost::uint8_t v);
258             bool readNextByte_;
259         };
260
261         template <class Iterator>
262         static boost::filter_iterator<binaryNAIDecoder, Iterator>
263         getNAIDecodedIterator(Iterator begin, Iterator end);
264
265         struct ValueSetterVisitor : public boost::static_visitor<> {
266             MIHFIdTLVParser & parser;
267             ValueSetterVisitor( MIHFIdTLVParser & p) : parser(p) {}
268             void operator()( boost::blank ) const {
269                 parser.value( std::string());
270             }
271             template <typename MIHFIdType>
272             void operator()( MIHFIdType const & id ) const {
273                 parser.value( id);
274             }
275         };
276
277         struct ValueEqualsVisitor : public boost::static_visitor<bool> {
278             MIHFIdTLVParser const & parser;
279             ValueEqualsVisitor( MIHFIdTLVParser const & p) : parser(p) {}
280             bool operator()( boost::blank ) const {
281                 return parser.idLength() == 0;
282             }
283             template <typename MIHFIdType>
284             bool operator()( MIHFIdType const & id ) const {
285                 return parser.valueEquals( id);
286             }
287         };
288     };
289
290     /** \brief Parser for 802.21 source MIHF_ID TLV
291      */
292     struct MIHFSrcIdTLVParser : public MIHFIdTLVParser
293     {
294         MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
295
296         void init() const {
297             defaultInit();
298             type() << typeId+0;
299         }
300         static type_t::value_type const typeId = 1;
301         void dump(std::ostream & os) const;
302         void validate() const;
303     };
304
305     /** \brief Parser for 802.21 destination MIHF_ID TLV
306      */
307     struct MIHFDstIdTLVParser : public MIHFIdTLVParser
308     {
309         MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
310
311         void init() const {
312             defaultInit();
313             type() << typeId+0;
314         }
315         static type_t::value_type const typeId = 2;
316         void dump(std::ostream & os) const;
317         void validate() const;
318     };
319
320     /** \brief Parser for 802.21 Status TLV
321      */
322     struct MIHStatusTLVParser : public MIHBaseTLVParser
323     {
324     #   include SENF_PARSER()
325         SENF_PARSER_INHERIT ( MIHBaseTLVParser   );
326         SENF_PARSER_FIELD   ( value, UInt8Parser );
327         SENF_PARSER_FINALIZE( MIHStatusTLVParser );
328
329         SENF_PARSER_INIT() {
330             defaultInit();
331             type() << typeId+0;
332             length_() = 1;
333         }
334         static type_t::value_type const typeId = 3;
335         void dump(std::ostream & os) const; ///< dump string representation to given stream
336         void validate() const;
337
338         enum StatusCode {
339             Success, UnspecifiedFailure, Rejected, AuthorizationFailure, NetworkError };
340     };
341
342     struct MIHRegisterReqCodeTLVParser : public MIHBaseTLVParser
343     {
344     #   include SENF_PARSER()
345         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
346         SENF_PARSER_FIELD    ( value, UInt8Parser );
347         SENF_PARSER_FINALIZE ( MIHRegisterReqCodeTLVParser );
348
349         SENF_PARSER_INIT() {
350             defaultInit();
351             type() = typeId+0;
352             length_() = 1;
353         }
354         static type_t::value_type const typeId = 11;
355         void dump(std::ostream & os) const; ///< dump string representation to given stream
356         void validate() const;
357
358         enum RequestCode { Registration, ReRegistration };
359     };
360
361     struct MIHValidTimeIntervalTLVParser : public MIHBaseTLVParser
362     {
363     #   include SENF_PARSER()
364         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
365         SENF_PARSER_FIELD    ( value, UInt32Parser );
366         SENF_PARSER_FINALIZE ( MIHValidTimeIntervalTLVParser );
367
368         SENF_PARSER_INIT() {
369             defaultInit();
370             type() = typeId+0;
371             length_() = 4;
372         }
373         static type_t::value_type const typeId = 12;
374         void dump(std::ostream & os) const; ///< dump string representation to given stream
375         void validate() const;
376     };
377
378 }
379
380
381 //-/////////////////////////////////////////////////////////////////////////////////////////////////
382 #include "TLVParser.cci"
383 #include "TLVParser.ct"
384 #include "TLVParser.cti"
385 #endif
386
387 \f
388 // Local Variables:
389 // mode: c++
390 // fill-column: 100
391 // c-file-style: "senf"
392 // indent-tabs-mode: nil
393 // ispell-local-dictionary: "american"
394 // compile-command: "scons -u test"
395 // comment-column: 40
396 // End: