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