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 {
45 InvalidMIHPacketException(std::string const & description)
46 : senf::Exception("Invalid MIH message: ") { append(description); }
50 class MIHTLVLengthParser
51 : public detail::packet::IntParserOps<MIHTLVLengthParser, boost::uint32_t>,
52 public PacketParserBase
55 MIHTLVLengthParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
57 typedef boost::uint32_t value_type;
58 static const size_type init_bytes = 1;
59 static value_type const min_value = 0;
60 static value_type const max_value = 4294967295u;
62 value_type value() const;
63 void value(value_type const & v);
65 MIHTLVLengthParser const & operator= (value_type other);
66 size_type bytes() const;
69 # include SENF_PARSER()
70 SENF_PARSER_PRIVATE_FIELD ( length_field, UInt8Parser );
71 SENF_PARSER_GOTO( length_field );
72 SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1, bool );
73 SENF_PARSER_PRIVATE_BITFIELD ( underflow_flag, 1, bool );
74 SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 6, unsigned );
77 void capacity(value_type v);
78 value_type capacity() const;
81 void resize_(size_type size);
85 /** \brief Base class for MIH TLV parsers
87 MIHBaseTLVParser is the abstract base class for MIH TLV parsers. It defines the
88 \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a
89 MIHTLVLengthParser. The length field is read-only.
91 To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't
92 forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example
93 the value is a vector of MacAddresses:
95 struct MacAddressesTLVParser : public MIHBaseTLVParser {
96 # include SENF_PARSER()
97 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
98 SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser );
99 SENF_PARSER_FINALIZE( MacAddressesTLVParser );
103 You have to adjust the maximum length value with the \ref maxLength function
104 before the length value is set. The default maximum value is 128. So, in the above
105 example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
106 if you don't call \c maxLength( \e some_value) before.
108 \see MIHTLVLengthParser \n
109 MIHGenericTLVParser \n
111 class MIHBaseTLVParser : public PacketParserBase
114 # include SENF_PARSER()
115 SENF_PARSER_FIELD ( type, UInt8Parser );
116 SENF_PARSER_FIELD_RO ( length, MIHTLVLengthParser );
117 SENF_PARSER_FINALIZE ( MIHBaseTLVParser );
119 /** \brief shrink size of the TLV length field to minimum
121 The size of the length field will be decreased to minimum necessary to hold
122 the current length value.
126 typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
129 /** \brief set maximum value of TLV length field
131 The size of the length field will be increased if necessary.
132 \param v maximum value of length field
134 void maxLength(MIHTLVLengthParser::value_type maxl) const;
136 void validateType(boost::uint8_t type) const;
137 void validateTypeLength(boost::uint8_t type, MIHTLVLengthParser::value_type length) const;
142 /** \brief Parser for a generic TLV packet
144 struct MIHGenericTLVParser
145 : public GenericTLVParserBase<MIHBaseTLVParser>
147 typedef senf::GenericTLVParserBase<MIHBaseTLVParser> base;
148 MIHGenericTLVParser(data_iterator i, state_type s) : base(i,s) {}
152 maxLength( MIHTLVLengthParser::max_value);
156 using base::maxLength;
160 /** \brief Base class for list TLV parser
162 struct MIHBaseListTLVParser
163 : public MIHBaseTLVParser
165 # include SENF_PARSER()
166 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
167 SENF_PARSER_FIELD_RO ( listSize, MIHTLVLengthParser );
168 SENF_PARSER_FINALIZE ( MIHBaseListTLVParser );
170 void maxListSize(MIHTLVLengthParser::value_type maxl) const;
173 template <class Self>
174 struct MIHListTLVParserMixin
180 /** \brief Parse a MIHF_ID
182 Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
183 We could set maxLength in init(), but for the most MIHF_IDs the default
184 maximum length of 128 should be enough.
186 \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer
191 class MIHFIdTLVParser : public MIHBaseTLVParser
193 # include SENF_PARSER()
194 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
195 SENF_PARSER_FIELD_RO ( idLength, MIHTLVLengthParser );
196 SENF_PARSER_LABEL ( idValue );
197 SENF_PARSER_SKIP ( idLength(), 0 );
198 SENF_PARSER_FINALIZE ( MIHFIdTLVParser );
201 ///\name Value setters
203 void value( MIHFId const & id);
205 void value( std::string const & id );
206 void value( senf::MACAddress const & addr);
207 void value( senf::INet4Address const & addr);
208 void value( senf::INet6Address const & addr);
209 void value( senf::EUI64 const & addr);
212 ///\name Value getters
214 MIHFId valueAs( MIHFId::Type type) const;
216 std::string valueAsString() const;
217 senf::MACAddress valueAsMACAddress() const;
218 senf::INet4Address valueAsINet4Address() const;
219 senf::INet6Address valueAsINet6Address() const;
220 senf::EUI64 valueAsEUI64() const;
223 ///\name Value comparisons
225 bool valueEquals( MIHFId const & id) const;
227 bool valueEquals( std::string const & id ) const;
228 bool valueEquals( senf::MACAddress const & addr) const;
229 bool valueEquals( senf::INet4Address const & addr) const;
230 bool valueEquals( senf::INet6Address const & addr) const;
231 bool valueEquals( senf::EUI64 const & addr) const;
234 void dump(std::ostream & os) const;
235 void maxIdLength(boost::uint8_t maxl) const;
239 /// resize the packet after the length field to given size
240 senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
242 data_iterator valueBegin() const;
243 data_iterator valueEnd() const;
245 template <class OutputIterator>
246 struct binaryNAIEncoder {
247 binaryNAIEncoder(OutputIterator & i);
248 void operator()(boost::uint8_t v);
252 template <class OutputIterator>
253 static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> >
254 getNAIEncodedOutputIterator(OutputIterator i);
256 struct binaryNAIDecoder {
258 bool operator()(boost::uint8_t v);
262 template <class Iterator>
263 static boost::filter_iterator<binaryNAIDecoder, Iterator>
264 getNAIDecodedIterator(Iterator begin, Iterator end);
266 struct ValueSetterVisitor : public boost::static_visitor<> {
267 MIHFIdTLVParser & parser;
268 ValueSetterVisitor( MIHFIdTLVParser & p) : parser(p) {}
269 void operator()( boost::blank ) const {
270 parser.value( std::string());
272 template <typename MIHFIdType>
273 void operator()( MIHFIdType const & id ) const {
278 struct ValueEqualsVisitor : public boost::static_visitor<bool> {
279 MIHFIdTLVParser const & parser;
280 ValueEqualsVisitor( MIHFIdTLVParser const & p) : parser(p) {}
281 bool operator()( boost::blank ) const {
282 return parser.idLength() == 0;
284 template <typename MIHFIdType>
285 bool operator()( MIHFIdType const & id ) const {
286 return parser.valueEquals( id);
291 /** \brief Parser for 802.21 source MIHF_ID TLV
293 struct MIHFSrcIdTLVParser : public MIHFIdTLVParser
295 MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
301 static type_t::value_type const typeId = 1;
302 void dump(std::ostream & os) const;
303 void validate() const;
306 /** \brief Parser for 802.21 destination MIHF_ID TLV
308 struct MIHFDstIdTLVParser : public MIHFIdTLVParser
310 MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
316 static type_t::value_type const typeId = 2;
317 void dump(std::ostream & os) const;
318 void validate() const;
321 /** \brief Parser for 802.21 Status TLV
323 struct MIHStatusTLVParser : public MIHBaseTLVParser
325 # include SENF_PARSER()
326 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
327 SENF_PARSER_FIELD ( value, UInt8Parser );
328 SENF_PARSER_FINALIZE( MIHStatusTLVParser );
335 static type_t::value_type const typeId = 3;
336 void dump(std::ostream & os) const; ///< dump string representation to given stream
337 void validate() const;
340 Success, UnspecifiedFailure, Rejected, AuthorizationFailure, NetworkError };
343 struct MIHRegisterReqCodeTLVParser : public MIHBaseTLVParser
345 # include SENF_PARSER()
346 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
347 SENF_PARSER_FIELD ( value, UInt8Parser );
348 SENF_PARSER_FINALIZE ( MIHRegisterReqCodeTLVParser );
355 static type_t::value_type const typeId = 11;
356 void dump(std::ostream & os) const; ///< dump string representation to given stream
357 void validate() const;
359 enum RequestCode { Registration, ReRegistration };
362 struct MIHValidTimeIntervalTLVParser : public MIHBaseTLVParser
364 # include SENF_PARSER()
365 SENF_PARSER_INHERIT ( MIHBaseTLVParser );
366 SENF_PARSER_FIELD ( value, UInt32Parser );
367 SENF_PARSER_FINALIZE ( MIHValidTimeIntervalTLVParser );
374 static type_t::value_type const typeId = 12;
375 void dump(std::ostream & os) const; ///< dump string representation to given stream
376 void validate() const;
382 //-/////////////////////////////////////////////////////////////////////////////////////////////////
383 #include "TLVParser.cci"
384 #include "TLVParser.ct"
385 #include "TLVParser.cti"
392 // c-file-style: "senf"
393 // indent-tabs-mode: nil
394 // ispell-local-dictionary: "american"
395 // compile-command: "scons -u test"
396 // comment-column: 40