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