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