Packets/80221Bundle: renamed MIHTLVLengthParser to MIHLengthParser
[senf.git] / senf / Packets / 80221Bundle / TLVParser.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Thorsten Horstmann <tho@berlios.de>
27
28 /** \file
29     \brief TLVParser public header */
30
31 #ifndef HH_SENF_Packets_80221Bundle_TLVParser_
32 #define HH_SENF_Packets_80221Bundle_TLVParser_ 1
33
34 // Custom includes
35 #include <senf/Packets/Packets.hh>
36 #include "MIHTypes.hh"
37
38 //#include "TLVParser.mpp"
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40
41 namespace senf {
42
43     class MIHLengthParser
44         : public detail::packet::IntParserOps<MIHLengthParser, boost::uint32_t>,
45           public PacketParserBase
46     {
47     public:
48         MIHLengthParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
49
50         typedef boost::uint32_t value_type;
51         static const size_type init_bytes = 1;
52         static value_type const min_value = 0;
53         static value_type const max_value = 4294967295u;
54
55         value_type value() const;
56         void value(value_type const & v);
57
58         MIHLengthParser const & operator= (value_type other);
59         size_type bytes() const;
60         void init() const;
61
62 #       include SENF_PARSER()
63         SENF_PARSER_PRIVATE_FIELD ( length_field, UInt8Parser );
64         SENF_PARSER_GOTO( length_field );
65         SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1,  bool     );
66         SENF_PARSER_PRIVATE_BITFIELD ( underflow_flag,       1,  bool     );
67         SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field,   6,  unsigned );
68
69         void finalize();
70         void capacity(value_type v);
71         value_type capacity() const;
72
73     private:
74         void resize_(size_type size);
75     };
76
77
78     /** \brief Base class for MIH TLV parsers
79
80          MIHBaseTLVParser is the abstract base class for MIH TLV parsers. It defines the
81          \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a
82          MIHLengthParser. The length field is read-only.
83
84          To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't
85          forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example
86          the value is a vector of MacAddresses:
87          \code
88          struct MacAddressesTLVParser : public MIHBaseTLVParser {
89          #   include SENF_PARSER()
90              SENF_PARSER_INHERIT ( MIHBaseTLVParser );
91              SENF_PARSER_VECTOR  ( value, bytes(length), senf::MACAddressParser );
92              SENF_PARSER_FINALIZE( MacAddressesTLVParser );
93          };
94          \endcode
95
96          You have to adjust the maximum length value with the \ref maxLength function
97          before the length value is set. The default maximum value is 128. So, in the above
98          example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
99          if you don't call \c maxLength( \e some_value) before.
100
101          \see MIHLengthParser \n
102            MIHGenericTLVParser \n
103      */
104     class MIHBaseTLVParser : public PacketParserBase
105     {
106     public:
107 #       include SENF_PARSER()
108         SENF_PARSER_FIELD    ( type,   UInt8Parser        );
109         SENF_PARSER_FIELD_RO ( length, MIHLengthParser );
110         SENF_PARSER_FINALIZE ( MIHBaseTLVParser           );
111
112         /** \brief shrink size of the TLV length field to minimum
113
114             The size of the length field will be decreased to minimum necessary to hold
115             the current length value.
116          */
117         void finalize();
118
119         typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
120
121     protected:
122         /** \brief set maximum value of TLV length field
123
124             The size of the length field will be increased if necessary.
125             \param v maximum value of length field
126          */
127         void maxLength(MIHLengthParser::value_type maxl) const;
128
129         void validateType(boost::uint8_t type) const;
130         void validateTypeLength(boost::uint8_t type, MIHLengthParser::value_type length) const;
131     };
132
133
134
135     /** \brief Parser for a generic TLV packet
136      */
137     struct MIHGenericTLVParser
138         : public GenericTLVParserBase<MIHBaseTLVParser>
139     {
140         typedef senf::GenericTLVParserBase<MIHBaseTLVParser> base;
141         MIHGenericTLVParser(data_iterator i, state_type s) : base(i,s) {}
142
143         void init() const {
144             defaultInit();
145             maxLength( MIHLengthParser::max_value);
146         }
147
148         using base::init;
149         using base::maxLength;
150     };
151
152
153     /** \brief Base class for list TLV parser
154      */
155     struct MIHBaseListTLVParser
156         : public MIHBaseTLVParser
157     {
158     #   include SENF_PARSER()
159         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
160         SENF_PARSER_FIELD_RO ( listSize, MIHLengthParser );
161         SENF_PARSER_FINALIZE ( MIHBaseListTLVParser );
162
163         void maxListSize(MIHLengthParser::value_type maxl) const;
164     };
165
166     template <class Self>
167     struct MIHListTLVParserMixin
168     {
169         void finalize();
170     };
171
172
173     /** \brief Parse a MIHF_ID
174
175          Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
176          We could set maxLength in init(), but for the most MIHF_IDs the default
177          maximum length of 128 should be enough.
178
179          \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer
180              than 128.
181
182          \see MIHFId
183     */
184     class MIHFIdTLVParser : public MIHBaseTLVParser
185     {
186     #   include SENF_PARSER()
187         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
188         SENF_PARSER_FIELD_RO ( idLength, MIHLengthParser );
189         SENF_PARSER_LABEL    ( idValue          );
190         SENF_PARSER_SKIP     ( idLength(), 0    );
191         SENF_PARSER_FINALIZE ( MIHFIdTLVParser  );
192
193     public:
194         ///\name Value setters
195         //\{
196         void value( MIHFId const & id);
197
198         void value( std::string        const & id  );
199         void value( senf::MACAddress   const & addr);
200         void value( senf::INet4Address const & addr);
201         void value( senf::INet6Address const & addr);
202         void value( senf::EUI64        const & addr);
203         //\}
204
205         ///\name Value getters
206         //\{
207         MIHFId valueAs( MIHFId::Type type) const;
208
209         std::string        valueAsString()       const;
210         senf::MACAddress   valueAsMACAddress()   const;
211         senf::INet4Address valueAsINet4Address() const;
212         senf::INet6Address valueAsINet6Address() const;
213         senf::EUI64        valueAsEUI64()        const;
214         //\}
215
216         ///\name Value comparisons
217         //\{
218         bool valueEquals( MIHFId const & id) const;
219
220         bool valueEquals( std::string        const & id  ) const;
221         bool valueEquals( senf::MACAddress   const & addr) const;
222         bool valueEquals( senf::INet4Address const & addr) const;
223         bool valueEquals( senf::INet6Address const & addr) const;
224         bool valueEquals( senf::EUI64        const & addr) const;
225         //\}
226
227         void dump(std::ostream & os) const;
228         void maxIdLength(boost::uint8_t maxl) const;
229         void finalize();
230
231     private:
232         /// resize the packet after the length field to given size
233         senf::safe_data_iterator resizeValueField(MIHLengthParser::value_type size);
234
235         data_iterator valueBegin() const;
236         data_iterator valueEnd() const;
237
238         template <class OutputIterator>
239         struct binaryNAIEncoder {
240             binaryNAIEncoder(OutputIterator & i);
241             void operator()(boost::uint8_t v);
242             OutputIterator & i_;
243         };
244
245         template <class OutputIterator>
246         static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> >
247         getNAIEncodedOutputIterator(OutputIterator i);
248
249         struct binaryNAIDecoder {
250             binaryNAIDecoder();
251             bool operator()(boost::uint8_t v);
252             bool readNextByte_;
253         };
254
255         template <class Iterator>
256         static boost::filter_iterator<binaryNAIDecoder, Iterator>
257         getNAIDecodedIterator(Iterator begin, Iterator end);
258
259         struct ValueSetterVisitor : public boost::static_visitor<> {
260             MIHFIdTLVParser & parser;
261             ValueSetterVisitor( MIHFIdTLVParser & p) : parser(p) {}
262             void operator()( boost::blank ) const {
263                 parser.value( std::string());
264             }
265             template <typename MIHFIdType>
266             void operator()( MIHFIdType const & id ) const {
267                 parser.value( id);
268             }
269         };
270
271         struct ValueEqualsVisitor : public boost::static_visitor<bool> {
272             MIHFIdTLVParser const & parser;
273             ValueEqualsVisitor( MIHFIdTLVParser const & p) : parser(p) {}
274             bool operator()( boost::blank ) const {
275                 return parser.idLength() == 0;
276             }
277             template <typename MIHFIdType>
278             bool operator()( MIHFIdType const & id ) const {
279                 return parser.valueEquals( id);
280             }
281         };
282     };
283
284     /** \brief Parser for 802.21 source MIHF_ID TLV
285      */
286     struct MIHFSrcIdTLVParser : public MIHFIdTLVParser
287     {
288         MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
289
290         void init() const {
291             defaultInit();
292             type() << typeId+0;
293         }
294         static type_t::value_type const typeId = 1;
295         void dump(std::ostream & os) const;
296         void validate() const;
297     };
298
299     /** \brief Parser for 802.21 destination MIHF_ID TLV
300      */
301     struct MIHFDstIdTLVParser : public MIHFIdTLVParser
302     {
303         MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
304
305         void init() const {
306             defaultInit();
307             type() << typeId+0;
308         }
309         static type_t::value_type const typeId = 2;
310         void dump(std::ostream & os) const;
311         void validate() const;
312     };
313
314     /** \brief Parser for 802.21 Status TLV
315      */
316     struct MIHStatusTLVParser : public MIHBaseTLVParser
317     {
318     #   include SENF_PARSER()
319         SENF_PARSER_INHERIT ( MIHBaseTLVParser   );
320         SENF_PARSER_FIELD   ( value, UInt8Parser );
321         SENF_PARSER_FINALIZE( MIHStatusTLVParser );
322
323         SENF_PARSER_INIT() {
324             defaultInit();
325             type() << typeId+0;
326             length_() = 1;
327         }
328         static type_t::value_type const typeId = 3;
329         void dump(std::ostream & os) const; ///< dump string representation to given stream
330         void validate() const;
331
332         enum StatusCode {
333             Success, UnspecifiedFailure, Rejected, AuthorizationFailure, NetworkError };
334     };
335
336     struct MIHRegisterReqCodeTLVParser : public MIHBaseTLVParser
337     {
338     #   include SENF_PARSER()
339         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
340         SENF_PARSER_FIELD    ( value, UInt8Parser );
341         SENF_PARSER_FINALIZE ( MIHRegisterReqCodeTLVParser );
342
343         SENF_PARSER_INIT() {
344             defaultInit();
345             type() = typeId+0;
346             length_() = 1;
347         }
348         static type_t::value_type const typeId = 11;
349         void dump(std::ostream & os) const; ///< dump string representation to given stream
350         void validate() const;
351
352         enum RequestCode { Registration, ReRegistration };
353     };
354
355     struct MIHValidTimeIntervalTLVParser : public MIHBaseTLVParser
356     {
357     #   include SENF_PARSER()
358         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
359         SENF_PARSER_FIELD    ( value, UInt32Parser );
360         SENF_PARSER_FINALIZE ( MIHValidTimeIntervalTLVParser );
361
362         SENF_PARSER_INIT() {
363             defaultInit();
364             type() = typeId+0;
365             length_() = 4;
366         }
367         static type_t::value_type const typeId = 12;
368         void dump(std::ostream & os) const; ///< dump string representation to given stream
369         void validate() const;
370     };
371
372 }
373
374
375 //-/////////////////////////////////////////////////////////////////////////////////////////////////
376 #include "TLVParser.cci"
377 #include "TLVParser.ct"
378 #include "TLVParser.cti"
379 #endif
380
381 \f
382 // Local Variables:
383 // mode: c++
384 // fill-column: 100
385 // c-file-style: "senf"
386 // indent-tabs-mode: nil
387 // ispell-local-dictionary: "american"
388 // compile-command: "scons -u test"
389 // comment-column: 40
390 // End: