X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FPackets%2F80221Bundle%2FTLVParser.hh;h=f454d083ff125db0762fb2a21ffc3310a53139ef;hb=ddb2132be4265f8a0d7d4c954c7c9401e59d027c;hp=e6caf9c28add5d99ad63051a522168604931ac4a;hpb=482523171f06cf239fd7e8c991f81711c02cf0ba;p=senf.git diff --git a/senf/Packets/80221Bundle/TLVParser.hh b/senf/Packets/80221Bundle/TLVParser.hh index e6caf9c..f454d08 100644 --- a/senf/Packets/80221Bundle/TLVParser.hh +++ b/senf/Packets/80221Bundle/TLVParser.hh @@ -2,23 +2,28 @@ // // Copyright (C) 2007 // Fraunhofer Institute for Open Communication Systems (FOKUS) -// Competence Center NETwork research (NET), St. Augustin, GERMANY -// Thorsten Horstmann // -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. +// The contents of this file are subject to the Fraunhofer FOKUS Public License +// Version 1.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// http://senf.berlios.de/license.html // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// The Fraunhofer FOKUS Public License Version 1.0 is based on, +// but modifies the Mozilla Public License Version 1.1. +// See the full license text for the amendments. // -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// Software distributed under the License is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +// for the specific language governing rights and limitations under the License. +// +// The Original Code is Fraunhofer FOKUS code. +// +// The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. +// (registered association), Hansastraße 27 c, 80686 Munich, Germany. +// All Rights Reserved. +// +// Contributor(s): +// Thorsten Horstmann /** \file \brief TLVParser public header */ @@ -27,23 +32,15 @@ #define HH_SENF_Packets_80221Bundle_TLVParser_ 1 // Custom includes -#include #include #include "MIHTypes.hh" //#include "TLVParser.mpp" -///////////////////////////////hh.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { - struct MIHTLVLengthException : public senf::Exception - { - MIHTLVLengthException() - : senf::Exception("MIHTLVLengthException") {} - }; - - - class MIHTLVLengthParser + class MIHTLVLengthParser : public detail::packet::IntParserOps, public PacketParserBase { @@ -57,7 +54,7 @@ namespace senf { value_type value() const; void value(value_type const & v); - + MIHTLVLengthParser const & operator= (value_type other); size_type bytes() const; void init() const; @@ -70,37 +67,37 @@ namespace senf { SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 6, unsigned ); void finalize(); - void maxValue(value_type v); - value_type maxValue() const; - + void capacity(value_type v); + value_type capacity() const; + private: void resize_(size_type size); - }; - + }; + /** \brief Base class for MIH TLV parsers - + MIHBaseTLVParser is the abstract base class for MIH TLV parsers. It defines the - \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a - MIHTLVLengthParser. The length field is read-only. - - To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't - forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example - the value is a vector of MacAddresses: + \ref type() field as an \ref senf::UInt8Parser and the \ref length() field as a + MIHTLVLengthParser. The length field is read-only. + + To create your own \c TLVParser you have to inherit from MIHBaseTLVParser (don't + forget \ref SENF_PARSER_INHERIT) and define the \c value field. In the following example + the value is a vector of MacAddresses: \code struct MacAddressesTLVParser : public MIHBaseTLVParser { - # include SENF_PARSER() + # include SENF_PARSER() SENF_PARSER_INHERIT ( MIHBaseTLVParser ); SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser ); SENF_PARSER_FINALIZE( MacAddressesTLVParser ); }; \endcode - - You have to adjust the maximum length value with the \ref maxLengthValue function - before the length value is set. The default maximum value is 127. So, in the above + + You have to adjust the maximum length value with the \ref maxLength function + before the length value is set. The default maximum value is 128. So, in the above example adding more than 21 MACAddresses to the vector will throw a TLVLengthException - if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before. - + if you don't call \c maxLength( \e some_value) before. + \see MIHTLVLengthParser \n MIHGenericTLVParser \n */ @@ -111,33 +108,30 @@ namespace senf { SENF_PARSER_FIELD ( type, UInt8Parser ); SENF_PARSER_FIELD_RO ( length, MIHTLVLengthParser ); SENF_PARSER_FINALIZE ( MIHBaseTLVParser ); - - /** \brief set maximum value of length field - - The size of the length field will be increased if necessary. - \param v maximum value of length field - */ - void maxLengthValue(MIHTLVLengthParser::value_type v) const { - protect(), length_().maxValue(v); - } - - /** \brief shrink size of length field to minimum - + + /** \brief shrink size of the TLV length field to minimum + The size of the length field will be decreased to minimum necessary to hold the current length value. */ - void finalizeLength() { - protect(), length_().finalize(); - }; - - typedef GenericTLVParserRegistry Registry; - + void finalize(); + + typedef GenericTLVParserRegistry Registry; + protected: - /// resize the packet after the length field to given size - senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size); + /** \brief set maximum value of TLV length field + + The size of the length field will be increased if necessary. + \param v maximum value of length field + */ + void maxLength(MIHTLVLengthParser::value_type maxl) const; + + void validateType(boost::uint8_t type) const; + void validateTypeLength(boost::uint8_t type, MIHTLVLengthParser::value_type length) const; }; - + + /** \brief Parser for a generic TLV packet */ struct MIHGenericTLVParser @@ -148,109 +142,240 @@ namespace senf { void init() const { defaultInit(); - maxLengthValue( MIHTLVLengthParser::max_value); + maxLength( MIHTLVLengthParser::max_value); } - + using base::init; + using base::maxLength; + }; + + + /** \brief Base class for list TLV parser + */ + struct MIHBaseListTLVParser + : public MIHBaseTLVParser + { + # include SENF_PARSER() + SENF_PARSER_INHERIT ( MIHBaseTLVParser ); + SENF_PARSER_FIELD_RO ( listSize, MIHTLVLengthParser ); + SENF_PARSER_FINALIZE ( MIHBaseListTLVParser ); + + void maxListSize(MIHTLVLengthParser::value_type maxl) const; }; - + + template + struct MIHListTLVParserMixin + { + void finalize(); + }; + + /** \brief Parse a MIHF_ID - the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21) - we could set maxLengthValue in init(), but for the most MIHF_IDs the default - maximum length of 127 should be enough. - - \note you must call mihfIdPacket.maxLengthValue( 253) *before* - setting longer MIHF_IDs values. + Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21) + We could set maxLength in init(), but for the most MIHF_IDs the default + maximum length of 128 should be enough. + + \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer + than 128. + + \see MIHFId */ class MIHFIdTLVParser : public MIHBaseTLVParser { # include SENF_PARSER() SENF_PARSER_INHERIT ( MIHBaseTLVParser ); - SENF_PARSER_SKIP ( length(), 0 ); + SENF_PARSER_FIELD_RO ( idLength, MIHTLVLengthParser ); + SENF_PARSER_LABEL ( idValue ); + SENF_PARSER_SKIP ( idLength(), 0 ); SENF_PARSER_FINALIZE ( MIHFIdTLVParser ); - + public: - std::string asString() const; - void setString(std::string const &id); + ///\name Value setters + //\{ + void value( MIHFId const & id); + + void value( std::string const & id ); + void value( senf::MACAddress const & addr); + void value( senf::INet4Address const & addr); + void value( senf::INet6Address const & addr); + void value( senf::EUI64 const & addr); + //\} + + ///\name Value getters + //\{ + MIHFId valueAs( MIHFId::Type type) const; - senf::MACAddress asMACAddress() const; - void setMACAddress(senf::MACAddress const &mac); + std::string valueAsString() const; + senf::MACAddress valueAsMACAddress() const; + senf::INet4Address valueAsINet4Address() const; + senf::INet6Address valueAsINet6Address() const; + senf::EUI64 valueAsEUI64() const; + //\} - senf::INet4Address asINet4Address() const; - void setINet4Address(senf::INet4Address const &addr); + ///\name Value comparisons + //\{ + bool valueEquals( MIHFId const & id) const; - senf::INet6Address asINet6Address() const; - void setINet6Address(senf::INet6Address const &addr); - - senf::EUI64 asEUI64() const; - void setEUI64(senf::EUI64 const &addr); + bool valueEquals( std::string const & id ) const; + bool valueEquals( senf::MACAddress const & addr) const; + bool valueEquals( senf::INet4Address const & addr) const; + bool valueEquals( senf::INet6Address const & addr) const; + bool valueEquals( senf::EUI64 const & addr) const; + //\} - MIHFId valueAs(MIHFId::Type type) const; - void dump(std::ostream & os) const; + void maxIdLength(boost::uint8_t maxl) const; + void finalize(); private: + /// resize the packet after the length field to given size + senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size); + + data_iterator valueBegin() const; + data_iterator valueEnd() const; + template struct binaryNAIEncoder { - binaryNAIEncoder(OutputIterator &i) : i_(i) {} - void operator()(const boost::uint8_t &v) const { - *i_++ = '\\'; - *i_++ = v; - } - OutputIterator &i_; + binaryNAIEncoder(OutputIterator & i); + void operator()(boost::uint8_t v); + OutputIterator & i_; }; + template - static boost::function_output_iterator > getNAIEncodedOutputIterator(OutputIterator i) { - return boost::make_function_output_iterator(binaryNAIEncoder(i)); - } + static boost::function_output_iterator > + getNAIEncodedOutputIterator(OutputIterator i); struct binaryNAIDecoder { - binaryNAIDecoder() : readNextByte_(true) {} - bool operator()(const boost::uint8_t &v) { - readNextByte_ = readNextByte_ ? false : true; - return readNextByte_; - } + binaryNAIDecoder(); + bool operator()(boost::uint8_t v); bool readNextByte_; }; + template - static boost::filter_iterator getNAIDecodedIterator(Iterator begin, Iterator end) { - return boost::make_filter_iterator(begin, end); - } + static boost::filter_iterator + getNAIDecodedIterator(Iterator begin, Iterator end); + + struct ValueSetterVisitor : public boost::static_visitor<> { + MIHFIdTLVParser & parser; + ValueSetterVisitor( MIHFIdTLVParser & p) : parser(p) {} + void operator()( boost::blank ) const { + parser.value( std::string()); + } + template + void operator()( MIHFIdType const & id ) const { + parser.value( id); + } + }; + + struct ValueEqualsVisitor : public boost::static_visitor { + MIHFIdTLVParser const & parser; + ValueEqualsVisitor( MIHFIdTLVParser const & p) : parser(p) {} + bool operator()( boost::blank ) const { + return parser.idLength() == 0; + } + template + bool operator()( MIHFIdType const & id ) const { + return parser.valueEquals( id); + } + }; }; + /** \brief Parser for 802.21 source MIHF_ID TLV + */ struct MIHFSrcIdTLVParser : public MIHFIdTLVParser { MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {} - + void init() const { defaultInit(); type() << typeId+0; } static type_t::value_type const typeId = 1; - void dump(std::ostream & os) const; + void validate() const; }; - + + /** \brief Parser for 802.21 destination MIHF_ID TLV + */ struct MIHFDstIdTLVParser : public MIHFIdTLVParser { MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {} - + void init() const { defaultInit(); type() << typeId+0; } static type_t::value_type const typeId = 2; - void dump(std::ostream & os) const; + void validate() const; + }; + + /** \brief Parser for 802.21 Status TLV + */ + struct MIHStatusTLVParser : public MIHBaseTLVParser + { + # include SENF_PARSER() + SENF_PARSER_INHERIT ( MIHBaseTLVParser ); + SENF_PARSER_FIELD ( value, UInt8Parser ); + SENF_PARSER_FINALIZE( MIHStatusTLVParser ); + + SENF_PARSER_INIT() { + defaultInit(); + type() << typeId+0; + length_() = 1; + } + static type_t::value_type const typeId = 3; + void dump(std::ostream & os) const; ///< dump string representation to given stream + void validate() const; + + enum StatusCode { + Success, UnspecifiedFailure, Rejected, AuthorizationFailure, NetworkError }; + }; + + struct MIHRegisterReqCodeTLVParser : public MIHBaseTLVParser + { + # include SENF_PARSER() + SENF_PARSER_INHERIT ( MIHBaseTLVParser ); + SENF_PARSER_FIELD ( value, UInt8Parser ); + SENF_PARSER_FINALIZE ( MIHRegisterReqCodeTLVParser ); + + SENF_PARSER_INIT() { + defaultInit(); + type() = typeId+0; + length_() = 1; + } + static type_t::value_type const typeId = 11; + void dump(std::ostream & os) const; ///< dump string representation to given stream + void validate() const; + + enum RequestCode { Registration, ReRegistration }; }; + + struct MIHValidTimeIntervalTLVParser : public MIHBaseTLVParser + { + # include SENF_PARSER() + SENF_PARSER_INHERIT ( MIHBaseTLVParser ); + SENF_PARSER_FIELD ( value, UInt32Parser ); + SENF_PARSER_FINALIZE ( MIHValidTimeIntervalTLVParser ); + + SENF_PARSER_INIT() { + defaultInit(); + type() = typeId+0; + length_() = 4; + } + static type_t::value_type const typeId = 12; + void dump(std::ostream & os) const; ///< dump string representation to given stream + void validate() const; + }; + } -///////////////////////////////hh.e//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// #include "TLVParser.cci" -//#include "TLVParser.ct" -//#include "TLVParser.cti" +#include "TLVParser.ct" +#include "TLVParser.cti" #endif