4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Thorsten Horstmann <tho@berlios.de>
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.
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.
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.
24 \brief TLVParser public header */
26 #ifndef HH_SENF_Packets_80221Bundle_TLVParser_
27 #define HH_SENF_Packets_80221Bundle_TLVParser_ 1
30 #include <senf/Packets/Packets.hh>
31 #include "MIHTypes.hh"
33 //#include "TLVParser.mpp"
34 //-/////////////////////////////////////////////////////////////////////////////////////////////////
38 struct MIHTLVLengthException : public senf::Exception
40 MIHTLVLengthException()
41 : senf::Exception("MIHTLVLengthException") {}
44 struct InvalidMIHPacketException : public senf::Exception
46 InvalidMIHPacketException(std::string const & description)
47 : senf::Exception("Invalid MIH message: ") { append(description); }
51 class MIHTLVLengthParser
52 : public detail::packet::IntParserOps<MIHTLVLengthParser, boost::uint32_t>,
53 public PacketParserBase
56 MIHTLVLengthParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
58 typedef boost::uint32_t value_type;
59 static const size_type init_bytes = 1;
60 static value_type const min_value = 0;
61 static value_type const max_value = 4294967295u;
63 value_type value() const;
64 void value(value_type const & v);
66 MIHTLVLengthParser const & operator= (value_type other);
67 size_type bytes() const;
70 # include SENF_PARSER()
71 SENF_PARSER_PRIVATE_FIELD ( length_field, UInt8Parser );
72 SENF_PARSER_GOTO( length_field );
73 SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1, bool );
74 SENF_PARSER_PRIVATE_BITFIELD ( underflow_flag, 1, bool );
75 SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 6, unsigned );
78 void capacity(value_type v);
79 value_type capacity() const;
82 void resize_(size_type size);
86 /** \brief Base class for MIH TLV parsers
88 MIHBaseTLVParser is the abstract base class for MIH TLV parsers. It defines the
89 \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a
90 MIHTLVLengthParser. The length field is read-only.
92 To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't
93 forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example
94 the value is a vector of MacAddresses:
96 struct MacAddressesTLVParser : public MIHBaseTLVParser {
97 # include SENF_PARSER()
98 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
99 SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser );
100 SENF_PARSER_FINALIZE( MacAddressesTLVParser );
104 You have to adjust the maximum length value with the \ref maxLength function
105 before the length value is set. The default maximum value is 128. So, in the above
106 example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
107 if you don't call \c maxLength( \e some_value) before.
109 \see MIHTLVLengthParser \n
110 MIHGenericTLVParser \n
112 class MIHBaseTLVParser : public PacketParserBase
115 # include SENF_PARSER()
116 SENF_PARSER_FIELD ( type, UInt8Parser );
117 SENF_PARSER_FIELD_RO ( length, MIHTLVLengthParser );
118 SENF_PARSER_FINALIZE ( MIHBaseTLVParser );
120 /** \brief shrink size of the TLV length field to minimum
122 The size of the length field will be decreased to minimum necessary to hold
123 the current length value.
127 typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
130 /** \brief set maximum value of TLV length field
132 The size of the length field will be increased if necessary.
133 \param v maximum value of length field
135 void maxLength(MIHTLVLengthParser::value_type maxl) const;
137 void validateType(boost::uint8_t type) const;
138 void validateTypeLength(boost::uint8_t type, MIHTLVLengthParser::value_type length) const;
143 /** \brief Parser for a generic TLV packet
145 struct MIHGenericTLVParser
146 : public GenericTLVParserBase<MIHBaseTLVParser>
148 typedef senf::GenericTLVParserBase<MIHBaseTLVParser> base;
149 MIHGenericTLVParser(data_iterator i, state_type s) : base(i,s) {}
153 maxLength( MIHTLVLengthParser::max_value);
157 using base::maxLength;
161 /** \brief Base class for list TLV parser
163 struct MIHBaseListTLVParser
164 : public MIHBaseTLVParser
166 # include SENF_PARSER()
167 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
168 SENF_PARSER_FIELD_RO ( listSize, MIHTLVLengthParser );
169 SENF_PARSER_FINALIZE ( MIHBaseListTLVParser );
171 void maxListSize(MIHTLVLengthParser::value_type maxl) const;
174 template <class Self>
175 struct MIHListTLVParserMixin
181 /** \brief Parse a MIHF_ID
183 Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
184 We could set maxLength in init(), but for the most MIHF_IDs the default
185 maximum length of 128 should be enough.
187 \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer
192 class MIHFIdTLVParser : public MIHBaseTLVParser
194 # include SENF_PARSER()
195 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
196 SENF_PARSER_FIELD_RO ( idLength, MIHTLVLengthParser );
197 SENF_PARSER_LABEL ( idValue );
198 SENF_PARSER_SKIP ( idLength(), 0 );
199 SENF_PARSER_FINALIZE ( MIHFIdTLVParser );
202 ///\name Value setters
204 void value( MIHFId const & id);
206 void value( std::string const & id );
207 void value( senf::MACAddress const & addr);
208 void value( senf::INet4Address const & addr);
209 void value( senf::INet6Address const & addr);
210 void value( senf::EUI64 const & addr);
213 ///\name Value getters
215 MIHFId valueAs( MIHFId::Type type) const;
217 std::string valueAsString() const;
218 senf::MACAddress valueAsMACAddress() const;
219 senf::INet4Address valueAsINet4Address() const;
220 senf::INet6Address valueAsINet6Address() const;
221 senf::EUI64 valueAsEUI64() const;
224 ///\name Value comparisons
226 bool valueEquals( MIHFId const & id) const;
228 bool valueEquals( std::string const & id ) const;
229 bool valueEquals( senf::MACAddress const & addr) const;
230 bool valueEquals( senf::INet4Address const & addr) const;
231 bool valueEquals( senf::INet6Address const & addr) const;
232 bool valueEquals( senf::EUI64 const & addr) const;
235 void dump(std::ostream & os) const;
236 void maxIdLength(boost::uint8_t maxl) const;
240 /// resize the packet after the length field to given size
241 senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
243 data_iterator valueBegin() const;
244 data_iterator valueEnd() const;
246 template <class OutputIterator>
247 struct binaryNAIEncoder {
248 binaryNAIEncoder(OutputIterator & i);
249 void operator()(boost::uint8_t v);
253 template <class OutputIterator>
254 static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> >
255 getNAIEncodedOutputIterator(OutputIterator i);
257 struct binaryNAIDecoder {
259 bool operator()(boost::uint8_t v);
263 template <class Iterator>
264 static boost::filter_iterator<binaryNAIDecoder, Iterator>
265 getNAIDecodedIterator(Iterator begin, Iterator end);
267 struct ValueSetterVisitor : public boost::static_visitor<> {
268 MIHFIdTLVParser & parser;
269 ValueSetterVisitor( MIHFIdTLVParser & p) : parser(p) {}
270 void operator()( boost::blank ) const {
271 parser.value( std::string());
273 template <typename MIHFIdType>
274 void operator()( MIHFIdType const & id ) const {
279 struct ValueEqualsVisitor : public boost::static_visitor<bool> {
280 MIHFIdTLVParser const & parser;
281 ValueEqualsVisitor( MIHFIdTLVParser const & p) : parser(p) {}
282 bool operator()( boost::blank ) const {
283 return parser.idLength() == 0;
285 template <typename MIHFIdType>
286 bool operator()( MIHFIdType const & id ) const {
287 return parser.valueEquals( id);
292 /** \brief Parser for 802.21 source MIHF_ID TLV
294 struct MIHFSrcIdTLVParser : public MIHFIdTLVParser
296 MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
302 static type_t::value_type const typeId = 1;
303 void dump(std::ostream & os) const;
304 void validate() const;
307 /** \brief Parser for 802.21 destination MIHF_ID TLV
309 struct MIHFDstIdTLVParser : public MIHFIdTLVParser
311 MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
317 static type_t::value_type const typeId = 2;
318 void dump(std::ostream & os) const;
319 void validate() const;
322 /** \brief Parser for 802.21 Status TLV
324 struct MIHStatusTLVParser : public MIHBaseTLVParser
326 # include SENF_PARSER()
327 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
328 SENF_PARSER_FIELD ( value, UInt8Parser );
329 SENF_PARSER_FINALIZE( MIHStatusTLVParser );
336 static type_t::value_type const typeId = 3;
337 void dump(std::ostream & os) const; ///< dump string representation to given stream
338 void validate() const;
341 Success, UnspecifiedFailure, Rejected, AuthorizationFailure, NetworkError };
344 struct MIHRegisterReqCodeTLVParser : public MIHBaseTLVParser
346 # include SENF_PARSER()
347 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
348 SENF_PARSER_FIELD ( value, UInt8Parser );
349 SENF_PARSER_FINALIZE ( MIHRegisterReqCodeTLVParser );
356 static type_t::value_type const typeId = 11;
357 void dump(std::ostream & os) const; ///< dump string representation to given stream
358 void validate() const;
360 enum RequestCode { Registration, ReRegistration };
363 struct MIHValidTimeIntervalTLVParser : public MIHBaseTLVParser
365 # include SENF_PARSER()
366 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
367 SENF_PARSER_FIELD ( value, UInt32Parser );
368 SENF_PARSER_FINALIZE ( MIHValidTimeIntervalTLVParser );
375 static type_t::value_type const typeId = 12;
376 void dump(std::ostream & os) const; ///< dump string representation to given stream
377 void validate() const;
383 //-/////////////////////////////////////////////////////////////////////////////////////////////////
384 #include "TLVParser.cci"
385 #include "TLVParser.ct"
386 #include "TLVParser.cti"
393 // c-file-style: "senf"
394 // indent-tabs-mode: nil
395 // ispell-local-dictionary: "american"
396 // compile-command: "scons -u test"
397 // comment-column: 40