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