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