From: tho Date: Wed, 14 Oct 2009 12:50:40 +0000 (+0000) Subject: Packets/80221Bundle: more GenericTLVBase integration; removed GenericTLVPacket; some... X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=f723d7852a8195072eee387ea9ca77156b58438b;p=senf.git Packets/80221Bundle: more GenericTLVBase integration; removed GenericTLVPacket; some code refactoring Packets/PacketParserBase: added protect() member; thx g0dil git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1496 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/80221Bundle/MIHPacket.cc b/senf/Packets/80221Bundle/MIHPacket.cc index c1a151d..409f9b8 100644 --- a/senf/Packets/80221Bundle/MIHPacket.cc +++ b/senf/Packets/80221Bundle/MIHPacket.cc @@ -144,16 +144,28 @@ prefix_ senf::PacketInterpreterBase::factory_t senf::MIHPacketType::nextPacketTy if (p.data().size() < initSize()) return no_factory(); PkReg_Entry const * e (PacketRegistry::lookup( p->messageId(), nothrow )); - return e ? e->factory() : MIHPayloadPacket::factory(); + return e ? e->factory() : MIHGenericPayloadPacket::factory(); } -prefix_ void senf::MIHPayloadPacketType::dump(packet p, std::ostream &os) +/////////////////////////////////////////////////////////////////////////// +// MIHGenericPayloadPacketType + +prefix_ void senf::MIHGenericPayloadPacketType::dump(packet p, std::ostream &os) { boost::io::ios_all_saver ias(os); os << "MIH Payload (service specific TLVs):\n" << " ToDo!\n"; } +prefix_ void senf::MIHGenericPayloadPacketType::finalize(packet p) +{ + typedef parser::tlv_list_t::container tlvContainer_t; + tlvContainer_t tlvs (p->tlv_list() ); + for (tlvContainer_t::iterator i (tlvs.begin()); i != tlvs.end(); ++i) + i->finalizeLength(); +} + + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/senf/Packets/80221Bundle/MIHPacket.hh b/senf/Packets/80221Bundle/MIHPacket.hh index 1d1c226..e9f6f3c 100644 --- a/senf/Packets/80221Bundle/MIHPacket.hh +++ b/senf/Packets/80221Bundle/MIHPacket.hh @@ -28,14 +28,7 @@ // Custom includes #include -#include -#include -#include -#include "TLVPacket.hh" -#include -#include -#include - +#include "TLVParser.hh" //#include "MIHPacket.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -51,121 +44,7 @@ namespace senf { SENF_PACKET_REGISTRY_REGISTER( \ senf::MIHMessageRegistry, packet::type::MESSAGE_ID, packet ) - class MIHFId - : public boost::variant< boost::blank, senf::MACAddress, senf::INet4Address, - senf::INet6Address, std::string, senf::EUI64 >, - public boost::less_than_comparable, - public boost::equality_comparable - { - public: - enum Type { Empty, MACAddress, INet4Address, INet6Address, String, EUI64 }; - - MIHFId(); ///< Create empty instance. - MIHFId(senf::MACAddress const & addr); ///< Construct id with given MACAddress - MIHFId(senf::INet4Address const & addr); ///< Construct id with given INet4Address - MIHFId(senf::INet6Address const & addr); ///< Construct id with given INet6Address - MIHFId(std::string const & addr); ///< Construct id with given String - MIHFId(senf::EUI64 const & addr); ///< Construct id with given EUI64 - - Type type() const; - bool operator==(MIHFId const & other) const; - bool operator<(MIHFId const & other) const; - - private: - struct GetTypeVisitor : public boost::static_visitor { - Type operator()(boost::blank const &) const { return Empty; } - Type operator()(senf::MACAddress const &) const { return MACAddress; } - Type operator()(senf::INet4Address const &) const { return INet4Address; } - Type operator()(senf::INet6Address const &) const { return INet6Address; } - Type operator()(std::string const & ) const { return String; } - Type operator()(senf::EUI64 const &) const { return EUI64; } - }; - struct EqualsVisitor : public boost::static_visitor { - template - bool operator()(T const &, U const &) const { - return false; - } - template - bool operator()( const T & lhs, const T & rhs ) const { - return lhs == rhs; - } - }; - struct LessThanVisitor : public boost::static_visitor { - template - bool operator()(T const &, U const &) const { - return false; - } - template - bool operator()( const T & lhs, const T & rhs ) const { - return lhs < rhs; - } - }; - }; - - - /** \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. - */ - class MIHFId_TLVParser : public MIHBaseTLVParser - { - # include SENF_PARSER() - SENF_PARSER_INHERIT ( MIHBaseTLVParser ); - SENF_PARSER_SKIP ( length(), 0 ); - SENF_PARSER_FINALIZE ( MIHFId_TLVParser ); - - public: - std::string asString() const; - void setString(std::string const &id); - - senf::MACAddress asMACAddress() const; - void setMACAddress(senf::MACAddress const &mac); - - senf::INet4Address asINet4Address() const; - void setINet4Address(senf::INet4Address const &addr); - - senf::INet6Address asINet6Address() const; - void setINet6Address(senf::INet6Address const &addr); - - senf::EUI64 asEUI64() const; - void setEUI64(senf::EUI64 const &addr); - - MIHFId valueAs(MIHFId::Type type) const; - - private: - template - struct binaryNAIEncoder { - binaryNAIEncoder(OutputIterator &i) : i_(i) {} - void operator()(const boost::uint8_t &v) const { - *i_++ = '\\'; - *i_++ = v; - } - OutputIterator &i_; - }; - template - static boost::function_output_iterator > getNAIEncodedOutputIterator(OutputIterator i) { - return boost::make_function_output_iterator(binaryNAIEncoder(i)); - } - - struct binaryNAIDecoder { - binaryNAIDecoder() : readNextByte_(true) {} - bool operator()(const boost::uint8_t &v) { - readNextByte_ = readNextByte_ ? false : true; - return readNextByte_; - } - bool readNextByte_; - }; - template - static boost::filter_iterator getNAIDecodedIterator(Iterator begin, Iterator end) { - return boost::make_filter_iterator(begin, end); - } - }; - + /** \brief Parse a MIH packet Parser implementing the MIH header. The fields implemented are: @@ -244,42 +123,47 @@ namespace senf { static factory_t nextPacketType(packet p); }; - /** \brief MIH packet typedef */ + /** \brief MIH packet typedef + \ingroup protocolbundle_80221 + */ typedef ConcretePacket MIHPacket; - struct MIHPayloadPacketParser : public PacketParserBase + struct MIHGenericPayloadPacketParser : public PacketParserBase { # include SENF_PARSER() - SENF_PARSER_LIST ( tlv_list, packetSize(), MIHGenericTLVPacketParser ); - SENF_PARSER_FINALIZE ( MIHPayloadPacketParser ); + SENF_PARSER_LIST ( tlv_list, packetSize(), MIHGenericTLVParser ); + SENF_PARSER_FINALIZE ( MIHGenericPayloadPacketParser ); }; - struct MIHPayloadPacketType + struct MIHGenericPayloadPacketType : public PacketTypeBase, - public PacketTypeMixin + public PacketTypeMixin { #ifndef DOXYGEN - typedef PacketTypeMixin mixin; + typedef PacketTypeMixin mixin; #endif - typedef ConcretePacket packet; ///< MIH Payload packet typedef - typedef MIHPayloadPacketParser parser; ///< typedef to the parser of MIH Payload packet + typedef ConcretePacket packet; ///< MIH Payload packet typedef + typedef MIHGenericPayloadPacketParser parser; ///< typedef to the parser of MIH Payload packet using mixin::nextPacketRange; using mixin::init; using mixin::initSize; - /** \brief Dump given MIHPayload in readable form to given output stream */ + /** \brief Dump given MIHGenericPayload in readable form to given output stream */ static void dump(packet p, std::ostream &os); + static void finalize(packet p); }; - /** \brief MIH Payload packet typedef */ - typedef ConcretePacket MIHPayloadPacket; + /** \brief MIH Payload packet typedef + \ingroup protocolbundle_80221 + */ + typedef ConcretePacket MIHGenericPayloadPacket; } ///////////////////////////////hh.e//////////////////////////////////////// -#include "MIHPacket.cci" +//#include "MIHPacket.cci" //#include "MIHPacket.ct" //#include "MIHPacket.cti" #endif diff --git a/senf/Packets/80221Bundle/MIHPacket.test.cc b/senf/Packets/80221Bundle/MIHPacket.test.cc index 31a7cdb..1a84a82 100644 --- a/senf/Packets/80221Bundle/MIHPacket.test.cc +++ b/senf/Packets/80221Bundle/MIHPacket.test.cc @@ -234,18 +234,19 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_parse) MIHPacket mihPacket (MIHPacket::create(data)); BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 42u); - BOOST_REQUIRE( mihPacket.next().is() ); - MIHPayloadPacket mihPayload (mihPacket.next().as()); + BOOST_REQUIRE( mihPacket.next().is() ); + MIHGenericPayloadPacket mihPayload (mihPacket.next().as()); BOOST_CHECK_EQUAL( mihPayload->tlv_list().size(), 2u); - MIHPayloadPacketParser::tlv_list_t::container tlv_list_container (mihPayload->tlv_list()); + MIHGenericPayloadPacket::Parser::tlv_list_t::container tlv_list_container ( + mihPayload->tlv_list()); - MIHGenericTLVPacket::Parser tlv1 = *tlv_list_container.begin(); + MIHGenericTLVParser tlv1 = *tlv_list_container.begin(); BOOST_CHECK_EQUAL( tlv1.type(), 0x42); BOOST_CHECK_EQUAL( tlv1.length(), 0x0au); BOOST_CHECK_EQUAL( tlv1.value().size(), 0x0a); - MIHGenericTLVPacket::Parser tlv2 = *boost::next(tlv_list_container.begin()); + MIHGenericTLVParser tlv2 = *boost::next(tlv_list_container.begin()); BOOST_CHECK_EQUAL( tlv2.type(), 0x43); BOOST_CHECK_EQUAL( tlv2.length(), 0x05u); BOOST_CHECK_EQUAL( tlv2.value().size(), 0x05); @@ -260,23 +261,21 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_create) mihPacket->src_mihfId().setString( "senf@berlios.de"); mihPacket->dst_mihfId().setString( "test"); - MIHPayloadPacket mihPayload (MIHPayloadPacket::createAfter(mihPacket)); - + MIHGenericPayloadPacket mihPayload (MIHGenericPayloadPacket::createAfter(mihPacket)); + MIHGenericPayloadPacket::Parser::tlv_list_t::container tlvContainer ( + mihPayload->tlv_list() ); + unsigned char tlv1_value[] = { - 0x1a, 0x2b, 0x3c, 0x4d, 0x5e }; - MIHGenericTLVPacket tlv2 = (MIHGenericTLVPacket::create()); - tlv2->type() = 0x43; - tlv2->value( tlv1_value); - tlv2.finalizeThis(); - mihPayload->tlv_list().push_front( tlv2); + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; + MIHGenericTLVParser tlv1 ( tlvContainer.push_back_space()); + tlv1.type() = 0x42; + tlv1.value( tlv1_value); unsigned char tlv2_value[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; - MIHGenericTLVPacket tlv1 (MIHGenericTLVPacket::create()); - tlv1->type() = 0x42; - tlv1->value( tlv2_value); - tlv1.finalizeThis(); - mihPayload->tlv_list().push_front( tlv1); + 0x1a, 0x2b, 0x3c, 0x4d, 0x5e }; + MIHGenericTLVParser tlv2 ( tlvContainer.push_back_space()); + tlv2.type() = 0x43; + tlv2.value( tlv2_value); mihPacket.finalizeAll(); diff --git a/senf/Packets/80221Bundle/MIHPacket.cci b/senf/Packets/80221Bundle/MIHTypes.cci similarity index 73% rename from senf/Packets/80221Bundle/MIHPacket.cci rename to senf/Packets/80221Bundle/MIHTypes.cci index 00a70bf..33b8cab 100644 --- a/senf/Packets/80221Bundle/MIHPacket.cci +++ b/senf/Packets/80221Bundle/MIHTypes.cci @@ -21,14 +21,14 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief MIH protocol inline non-template implementation */ + \brief MIHTypes inline non-template implementation */ -//#include "MIHPacket.ih" +//#include "MIHTypes.ih" // Custom includes #define prefix_ inline -///////////////////////////////cci.p//////////////////////////////////////// +///////////////////////////////cci.p/////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // MIHFId @@ -81,53 +81,17 @@ prefix_ bool senf::MIHFId::operator<(senf::MIHFId const & other) return boost::apply_visitor( LessThanVisitor(), *this, other); } -/////////////////////////////////////////////////////////////////////////// -// MIHFId_TLVParser - -prefix_ std::string senf::MIHFId_TLVParser::asString() - const -{ - return std::string( i(1+length_().bytes()), i(1+length_().bytes()+length()) ); -} - -prefix_ senf::MACAddress senf::MIHFId_TLVParser::asMACAddress() - const -{ - return MACAddress::from_data( - getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+12) )); -} -prefix_ senf::INet4Address senf::MIHFId_TLVParser::asINet4Address() - const -{ - return INet4Address::from_data( - getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+8) )); -} - -prefix_ senf::INet6Address senf::MIHFId_TLVParser::asINet6Address() - const -{ - return INet6Address::from_data( - getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+32) )); -} - -prefix_ senf::EUI64 senf::MIHFId_TLVParser::asEUI64() - const -{ - return EUI64::from_data( - getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+16) )); -} - -///////////////////////////////cci.e//////////////////////////////////////// +///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ // Local Variables: // mode: c++ // fill-column: 100 +// comment-column: 40 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" -// comment-column: 40 // End: diff --git a/senf/Packets/80221Bundle/MIHTypes.hh b/senf/Packets/80221Bundle/MIHTypes.hh new file mode 100644 index 0000000..ea8b5b2 --- /dev/null +++ b/senf/Packets/80221Bundle/MIHTypes.hh @@ -0,0 +1,110 @@ +// $Id$ +// +// Copyright (C) 2009 +// 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. +// +// 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. +// +// 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. + +/** \file + \brief MIHTypes public header */ + +#ifndef HH_SENF_Packets_80221Bundle_MIHTypes_ +#define HH_SENF_Packets_80221Bundle_MIHTypes_ 1 + +// Custom includes +#include +#include +#include +#include +#include +#include + +//#include "MIHTypes.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { + + class MIHFId + : public boost::variant< boost::blank, senf::MACAddress, senf::INet4Address, + senf::INet6Address, std::string, senf::EUI64 >, + public boost::less_than_comparable, + public boost::equality_comparable + { + public: + enum Type { Empty, MACAddress, INet4Address, INet6Address, String, EUI64 }; + + MIHFId(); ///< Create empty instance. + MIHFId(senf::MACAddress const & addr); ///< Construct id with given MACAddress + MIHFId(senf::INet4Address const & addr); ///< Construct id with given INet4Address + MIHFId(senf::INet6Address const & addr); ///< Construct id with given INet6Address + MIHFId(std::string const & addr); ///< Construct id with given String + MIHFId(senf::EUI64 const & addr); ///< Construct id with given EUI64 + + Type type() const; + bool operator==(MIHFId const & other) const; + bool operator<(MIHFId const & other) const; + + private: + struct GetTypeVisitor : public boost::static_visitor { + Type operator()(boost::blank const &) const { return Empty; } + Type operator()(senf::MACAddress const &) const { return MACAddress; } + Type operator()(senf::INet4Address const &) const { return INet4Address; } + Type operator()(senf::INet6Address const &) const { return INet6Address; } + Type operator()(std::string const & ) const { return String; } + Type operator()(senf::EUI64 const &) const { return EUI64; } + }; + struct EqualsVisitor : public boost::static_visitor { + template + bool operator()(T const &, U const &) const { + return false; + } + template + bool operator()( const T & lhs, const T & rhs ) const { + return lhs == rhs; + } + }; + struct LessThanVisitor : public boost::static_visitor { + template + bool operator()(T const &, U const &) const { + return false; + } + template + bool operator()( const T & lhs, const T & rhs ) const { + return lhs < rhs; + } + }; + }; + +} + +///////////////////////////////hh.e//////////////////////////////////////// +#include "MIHTypes.cci" +//#include "MIHTypes.ct" +//#include "MIHTypes.cti" +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/senf/Packets/80221Bundle/TLVPacket.cci b/senf/Packets/80221Bundle/TLVPacket.cci deleted file mode 100644 index 17a2c76..0000000 --- a/senf/Packets/80221Bundle/TLVPacket.cci +++ /dev/null @@ -1,55 +0,0 @@ -// $Id$ -// -// 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. -// -// 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. -// -// 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. - -/** \file - \brief TLVPacket inline non-template implementation */ - -//#include "TLVPacket.ih" - -// Custom includes - -#define prefix_ inline -///////////////////////////////cci.p//////////////////////////////////////// - -prefix_ senf::MIHTLVLengthParser::size_type senf::MIHTLVLengthParser::bytes() const -{ - return 1 + ( length_field()<=128 ? 0 : fixed_length_field()); -} - -prefix_ void senf::MIHGenericTLVPacketType::finalize(packet p) -{ - p->finalizeLength(); -} - -///////////////////////////////cci.e//////////////////////////////////////// -#undef prefix_ - - -// Local Variables: -// mode: c++ -// fill-column: 100 -// c-file-style: "senf" -// indent-tabs-mode: nil -// ispell-local-dictionary: "american" -// compile-command: "scons -u test" -// comment-column: 40 -// End: diff --git a/senf/Packets/80221Bundle/TLVPacket.cc b/senf/Packets/80221Bundle/TLVParser.cc similarity index 74% rename from senf/Packets/80221Bundle/TLVPacket.cc rename to senf/Packets/80221Bundle/TLVParser.cc index e37c1a0..43ba4c2 100644 --- a/senf/Packets/80221Bundle/TLVPacket.cc +++ b/senf/Packets/80221Bundle/TLVParser.cc @@ -21,10 +21,10 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief TLVPacket non-inline non-template implementation */ + \brief TLVParser non-inline non-template implementation */ -#include "TLVPacket.hh" -//#include "TLVPacket.ih" +#include "TLVParser.hh" +//#include "TLVParser.ih" // Custom includes #include @@ -33,6 +33,9 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// MIHBaseTLVParser + prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField( MIHTLVLengthParser::value_type size) { @@ -48,6 +51,9 @@ prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField( } +/////////////////////////////////////////////////////////////////////////// +// MIHTLVLengthParser + prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const { switch (bytes() ) { @@ -135,22 +141,22 @@ prefix_ void senf::MIHTLVLengthParser::finalize() value_type v = value(); size_type b = bytes(); if (v <= 128) { - if (b != 1) resize(1); + if (b != 1) resize_(1); return; } if (v <= UInt8Parser::max_value + 128) { - if (b != 2) resize(2); + if (b != 2) resize_(2); return; } if (v <= UInt16Parser::max_value + 128) { - if (b != 3) resize(3); + if (b != 3) resize_(3); return; } if (v <= UInt24Parser::max_value + 128 ) { - if (b != 4) resize(4); + if (b != 4) resize_(4); return; } - if (b != 5) resize(5); + if (b != 5) resize_(5); } @@ -160,60 +166,32 @@ prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type return; size_type b = bytes(); if (v <= UInt8Parser::max_value + 128) { - if (b < 2) resize(2); + if (b < 2) resize_(2); return; } if (v <= UInt16Parser::max_value + 128) { - if (b < 3) resize(3); + if (b < 3) resize_(3); return; } if (v <= UInt24Parser::max_value + 128) { - if (b < 4) resize(4); + if (b < 4) resize_(4); return; } - if (b < 5) resize(5); + if (b < 5) resize_(5); } -prefix_ void senf::MIHTLVLengthParser::resize(size_type size) +prefix_ void senf::MIHTLVLengthParser::resize_(size_type size) { value_type v = value(); - size_type current_size (bytes()); - SafePacketParserWrapper safeThis (*this); - - if (current_size > size) - data().erase( i(), boost::next(i(), current_size-size)); - else - data().insert( i(), size-current_size, 0); - + resize(bytes(), size); if (size > 1) { - safeThis->extended_length_flag() = true; - safeThis->fixed_length_field() = size - 1; + extended_length_flag() = true; + fixed_length_field() = size - 1; } else { - safeThis->extended_length_flag() = false; + extended_length_flag() = false; } - safeThis->value(v); -} - - -//prefix_ senf::PacketInterpreterBase::range senf::MIHGenericTLVPacketParser::value() -// const -//{ -// senf::PacketData::iterator begin (boost::next(data().begin(), 1 + length_().bytes() )); -// return PacketInterpreterBase::range( -// begin, boost::next( begin, length()) ); -//} - - -prefix_ void senf::MIHGenericTLVPacketType::dump(packet p, std::ostream & os) -{ - boost::io::ios_all_saver ias(os); - os << "MIH GenericTLV Packet:\n" - << std::dec - << senf::fieldName("type") << unsigned( p->type()) << "\n" - << senf::fieldName("length") << unsigned( p->length()) << "\n" - << " value:\n"; - senf::hexdump( p->value().begin(), p->value().end(), os); + value(v); } diff --git a/senf/Packets/80221Bundle/TLVParser.cci b/senf/Packets/80221Bundle/TLVParser.cci new file mode 100644 index 0000000..467a732 --- /dev/null +++ b/senf/Packets/80221Bundle/TLVParser.cci @@ -0,0 +1,90 @@ +// $Id$ +// +// 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. +// +// 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. +// +// 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. + +/** \file + \brief TLVParser inline non-template implementation */ + +//#include "TLVParser.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p//////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// MIHTLVLengthParser + +prefix_ senf::MIHTLVLengthParser::size_type senf::MIHTLVLengthParser::bytes() const +{ + return 1 + ( length_field()<=128 ? 0 : fixed_length_field()); +} + +/////////////////////////////////////////////////////////////////////////// +// MIHFId_TLVParser + +prefix_ std::string senf::MIHFId_TLVParser::asString() + const +{ + return std::string( i(1+length_().bytes()), i(1+length_().bytes()+length()) ); +} + +prefix_ senf::MACAddress senf::MIHFId_TLVParser::asMACAddress() + const +{ + return MACAddress::from_data( + getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+12) )); +} + +prefix_ senf::INet4Address senf::MIHFId_TLVParser::asINet4Address() + const +{ + return INet4Address::from_data( + getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+8) )); +} + +prefix_ senf::INet6Address senf::MIHFId_TLVParser::asINet6Address() + const +{ + return INet6Address::from_data( + getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+32) )); +} + +prefix_ senf::EUI64 senf::MIHFId_TLVParser::asEUI64() + const +{ + return EUI64::from_data( + getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+16) )); +} + +///////////////////////////////cci.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// comment-column: 40 +// End: diff --git a/senf/Packets/80221Bundle/TLVPacket.hh b/senf/Packets/80221Bundle/TLVParser.hh similarity index 63% rename from senf/Packets/80221Bundle/TLVPacket.hh rename to senf/Packets/80221Bundle/TLVParser.hh index bcaecae..1ee9bfa 100644 --- a/senf/Packets/80221Bundle/TLVPacket.hh +++ b/senf/Packets/80221Bundle/TLVParser.hh @@ -21,16 +21,17 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief TLVPacket public header */ + \brief TLVParser public header */ -#ifndef HH_SENF_Packets_80221Bundle_TLVPacket_ -#define HH_SENF_Packets_80221Bundle_TLVPacket_ 1 +#ifndef HH_SENF_Packets_80221Bundle_TLVParser_ +#define HH_SENF_Packets_80221Bundle_TLVParser_ 1 // Custom includes #include #include +#include "MIHTypes.hh" -//#include "TLVPacket.mpp" +//#include "TLVParser.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { @@ -71,14 +72,15 @@ namespace senf { void finalize(); void maxValue(value_type v); value_type maxValue() const; + private: - void resize(size_type size); + void resize_(size_type size); }; - /** \brief Base class for TLV-Packet-Parsers + /** \brief Base class for MIH TLV parsers - MIHBaseTLVParser is the abstract base class for TLV-Packet-Parsers. It defines the + 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. @@ -92,14 +94,6 @@ namespace senf { SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser ); SENF_PARSER_FINALIZE( MacAddressesTLVParser ); }; - - struct MacAddressesTLVPacketType : public PacketTypeBase { - typedef MacAddressesTLVParser parser; - ... - static void finalize(ConcretePacket p) { - p->finalizeLength(); - } - }; \endcode You have to adjust the maximum length value with the \ref maxLengthValue function @@ -108,7 +102,7 @@ namespace senf { if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before. \see MIHTLVLengthParser \n - MIHGenericTLVPacketParser \n + MIHGenericTLVParser \n */ class MIHBaseTLVParser : public PacketParserBase { @@ -124,7 +118,7 @@ namespace senf { \param v maximum value of length field */ void maxLengthValue(MIHTLVLengthParser::value_type v) const { - length_().maxValue(v); + protect(), length_().maxValue(v); } /** \brief shrink size of length field to minimum @@ -133,7 +127,7 @@ namespace senf { the current length value. */ void finalizeLength() { - length_().finalize(); + protect(), length_().finalize(); }; protected: @@ -143,62 +137,92 @@ namespace senf { /** \brief Parser for a generic TLV packet - - \see MIHGenericTLVPacketType */ - struct MIHGenericTLVPacketParser + struct MIHGenericTLVParser : public GenericTLVParserBase { typedef senf::GenericTLVParserBase base; - MIHGenericTLVPacketParser(data_iterator i, state_type s) : base(i,s) {} + MIHGenericTLVParser(data_iterator i, state_type s) : base(i,s) {} void init() const { defaultInit(); maxLengthValue( MIHTLVLengthParser::max_value); - } + } + + using base::init; }; - - /** \brief Generic TLV packet + + /** \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. + */ + class MIHFId_TLVParser : public MIHBaseTLVParser + { + # include SENF_PARSER() + SENF_PARSER_INHERIT ( MIHBaseTLVParser ); + SENF_PARSER_SKIP ( length(), 0 ); + SENF_PARSER_FINALIZE ( MIHFId_TLVParser ); + + public: + std::string asString() const; + void setString(std::string const &id); + + senf::MACAddress asMACAddress() const; + void setMACAddress(senf::MACAddress const &mac); - \par Packet type (typedef): - \ref MIHGenericTLVPacket + senf::INet4Address asINet4Address() const; + void setINet4Address(senf::INet4Address const &addr); - \image html TLV.png + senf::INet6Address asINet6Address() const; + void setINet6Address(senf::INet6Address const &addr); - \ingroup protocolbundle_80221 - */ - struct MIHGenericTLVPacketType - : public PacketTypeBase, - public PacketTypeMixin - { -#ifndef DOXYGEN - typedef PacketTypeMixin mixin; -#endif - typedef ConcretePacket packet; ///< GenericTLV packet typedef - typedef MIHGenericTLVPacketParser parser; ///< typedef to the parser of GenericTLV packet + senf::EUI64 asEUI64() const; + void setEUI64(senf::EUI64 const &addr); - using mixin::nextPacketRange; - using mixin::init; - using mixin::initSize; + MIHFId valueAs(MIHFId::Type type) const; - /** \brief Dump given MIHGenericTLVPacket in readable form to given output stream */ - static void dump(packet p, std::ostream & os); - static void finalize(packet p); ///< Finalize packet. - /**< shrink size of length field to minimum - \see MIHBaseTLVParser::finalizeLength() */ + private: + template + struct binaryNAIEncoder { + binaryNAIEncoder(OutputIterator &i) : i_(i) {} + void operator()(const boost::uint8_t &v) const { + *i_++ = '\\'; + *i_++ = v; + } + OutputIterator &i_; + }; + template + static boost::function_output_iterator > getNAIEncodedOutputIterator(OutputIterator i) { + return boost::make_function_output_iterator(binaryNAIEncoder(i)); + } + + struct binaryNAIDecoder { + binaryNAIDecoder() : readNextByte_(true) {} + bool operator()(const boost::uint8_t &v) { + readNextByte_ = readNextByte_ ? false : true; + return readNextByte_; + } + bool readNextByte_; + }; + template + static boost::filter_iterator getNAIDecodedIterator(Iterator begin, Iterator end) { + return boost::make_filter_iterator(begin, end); + } }; - - /** \brief GenericTLV packet typedef - \ingroup protocolbundle_80221 - */ - typedef ConcretePacket MIHGenericTLVPacket; + + } ///////////////////////////////hh.e//////////////////////////////////////// -#include "TLVPacket.cci" -//#include "TLVPacket.ct" -//#include "TLVPacket.cti" +#include "TLVParser.cci" +//#include "TLVParser.ct" +//#include "TLVParser.cti" #endif diff --git a/senf/Packets/80221Bundle/TLVPacket.test.cc b/senf/Packets/80221Bundle/TLVParser.test.cc similarity index 63% rename from senf/Packets/80221Bundle/TLVPacket.test.cc rename to senf/Packets/80221Bundle/TLVParser.test.cc index 9743718..bea19dd 100644 --- a/senf/Packets/80221Bundle/TLVPacket.test.cc +++ b/senf/Packets/80221Bundle/TLVParser.test.cc @@ -21,13 +21,13 @@ // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** \file - \brief TLVPacket unit tests */ + \brief TLVParser unit tests */ -//#include "TLVPacket.test.hh" -//#include "TLVPacket.test.ih" +//#include "TLVParser.test.hh" +//#include "TLVParser.test.ih" // Custom includes -#include "TLVPacket.hh" +#include "TLVParser.hh" #include #include @@ -39,38 +39,39 @@ using namespace senf; namespace { - -#define CHECK_TLVPacket(tlvPacket, ptype, plength) \ -{ \ - BOOST_CHECK_EQUAL( tlvPacket->type(), ptype ); \ - BOOST_CHECK_EQUAL( tlvPacket->length(), plength ); \ - BOOST_CHECK_EQUAL( tlvPacket->value().size(), int(plength) ); \ - std::ostringstream oss (std::ostringstream::out); \ - SENF_CHECK_NO_THROW( tlvPacket.dump( oss)); \ - senf::PacketData::iterator dataIterator (tlvPacket->value().begin()); \ - for (unsigned i=0; i::create(data)); + MIHGenericTLVParser tlvParser( p->data().begin(), &p->data()); + CHECK_TLVParser( tlvParser, 0x01, 0x0Au ); } -BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_parse_packet_with_extended_length) +BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_extended_length) { - unsigned char data[] = { + PacketInterpreterBase::byte data[] = { 0x01, // type 0x81, // first and last bit set => one byte length following 0x0A, // length (10 = 138 bytes value follows) @@ -89,73 +90,76 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_parse_packet_with_extended_length) 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89 }; - MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create(data)); - CHECK_TLVPacket( tlvPacket, 0x01, 0x8au ); + PacketInterpreterBase::ptr p (PacketInterpreter::create(data)); + MIHGenericTLVParser tlvParser( p->data().begin(), &p->data()); + CHECK_TLVParser( tlvParser, 0x01, 0x8au ); } -BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_packet_with_simple_length) +BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_simple_length) { - unsigned char value[] = { + PacketInterpreterBase::byte value[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; - MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create()); - tlvPacket->type() = 42u; - tlvPacket->value( value); - tlvPacket.finalizeThis(); + PacketInterpreterBase::ptr p (PacketInterpreter::create(2u)); + MIHGenericTLVParser tlvParser( p->data().begin(), &p->data()); + tlvParser.type() = 42u; + tlvParser.value( value); + tlvParser.finalizeLength(); - CHECK_TLVPacket( tlvPacket, 42u, 0x0Au ); + CHECK_TLVParser( tlvParser, 42u, 0x0Au ); - unsigned char data[] = { + PacketInterpreterBase::byte data[] = { 0x2a, // type 0x0A, // first bit not set, length=10 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value }; - BOOST_CHECK( equal( tlvPacket.data().begin(), tlvPacket.data().end(), data )); + SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), + p->data().begin(), p->data().end() ); } -BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_packet_with_extended_length) +BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_extended_length) { - unsigned char value[255]; + PacketInterpreterBase::byte value[255]; for (unsigned i=0; imaxLengthValue( MIHTLVLengthParser::max_value); - SENF_CHECK_NO_THROW( tlvPacket->type() = 42u); - SENF_CHECK_NO_THROW( tlvPacket->value( value)); - SENF_CHECK_NO_THROW( tlvPacket.finalizeThis()); + PacketInterpreterBase::ptr p (PacketInterpreter::create(2u)); + MIHGenericTLVParser tlvParser( p->data().begin(), &p->data()); + tlvParser.maxLengthValue( MIHTLVLengthParser::max_value); + tlvParser.type() = 42u; + tlvParser.value( value); + tlvParser.finalizeLength(); - CHECK_TLVPacket( tlvPacket, 42u, sizeof(value) ); + CHECK_TLVParser( tlvParser, 42u, sizeof(value) ); - unsigned char data[] = { + PacketInterpreterBase::byte data[] = { 0x2a, // type 0x81, // first and last bit set => one byte length following 0x7f, // length (127 = 255 bytes value) 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // first bytes of value }; - BOOST_CHECK( equal( - tlvPacket.data().begin(), - boost::next( tlvPacket.data().begin(), sizeof(data)), - data )); + SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), + p->data().begin(), boost::next( p->data().begin(), sizeof(data)) ); } -BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_create_invalid_packet) +BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid) { - MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create()); - tlvPacket->type() = 42u; - tlvPacket.finalizeThis(); + PacketInterpreterBase::ptr p (PacketInterpreter::create(2u)); + MIHGenericTLVParser tlvParser( p->data().begin(), &p->data()); + tlvParser.type() = 42u; + tlvParser.finalizeLength(); - unsigned char value[255]; + PacketInterpreterBase::byte value[255]; for (unsigned i=0; ivalue( value), MIHTLVLengthException); - tlvPacket->maxLengthValue( sizeof(value)); - tlvPacket->value( value); - tlvPacket.finalizeThis(); - CHECK_TLVPacket( tlvPacket, 42u, sizeof(value) ); + BOOST_CHECK_THROW( tlvParser.value( value), MIHTLVLengthException); + tlvParser.maxLengthValue( sizeof(value)); + tlvParser.value( value); + tlvParser.finalizeLength(); + CHECK_TLVParser( tlvParser, 42u, sizeof(value) ); } diff --git a/senf/Packets/GenericTLV.ct b/senf/Packets/GenericTLV.ct index 75debb1..110b3ed 100644 --- a/senf/Packets/GenericTLV.ct +++ b/senf/Packets/GenericTLV.ct @@ -56,10 +56,8 @@ template template prefix_ void senf::GenericTLVParserBase::value_(ForwardReadableRange const &range) { - unsigned int rangeSize = boost::size(range); - std::cerr << "GenericTLVParserBase::value_() rangeSize=" << - unsigned( rangeSize) << " length()=" << unsigned( this->length()) << " bytes(self)=" << - unsigned( senf::bytes(self())) << " bytes()=" << unsigned( senf::bytes(*this)) << std::endl; + //typename boost::range_difference::type rangeSize ( boost::size(range)); + unsigned rangeSize ( boost::size(range)); if ( rangeSize != this->length() ) resize( bytes(), rangeSize + senf::bytes(self()) ); std::copy( boost::begin(range), boost::end(range), boost::next( diff --git a/senf/Packets/GenericTLV.cti b/senf/Packets/GenericTLV.cti index de01ab2..a5d39b5 100644 --- a/senf/Packets/GenericTLV.cti +++ b/senf/Packets/GenericTLV.cti @@ -46,6 +46,7 @@ prefix_ void senf::GenericTLVParserBase::init() template template prefix_ Parser senf::GenericTLVParserBase::as() + const { return Parser(this->i(), this->state() ); } @@ -53,6 +54,7 @@ prefix_ Parser senf::GenericTLVParserBase::as() template template prefix_ bool senf::GenericTLVParserBase::is() + const { return this->type().value() == Parser::TYPEID; } diff --git a/senf/Packets/GenericTLV.hh b/senf/Packets/GenericTLV.hh index 3c4f12d..6f89e82 100644 --- a/senf/Packets/GenericTLV.hh +++ b/senf/Packets/GenericTLV.hh @@ -124,7 +124,7 @@ namespace senf { \endcode \see - IPv6GenericOptionTLVParser, WLANGenericInfoElementParser, MIHGenericTLVPacketParser + IPv6GenericOptionTLVParser, WLANGenericInfoElementParser, MIHGenericTLVParser */ template class GenericTLVParserBase : public Base @@ -140,10 +140,10 @@ namespace senf { Parser init(); template - Parser as(); + Parser as() const; template - bool is(); + bool is() const; senf::PacketInterpreterBase::range value() const; diff --git a/senf/Packets/PacketParser.cci b/senf/Packets/PacketParser.cci index 510c2a6..0fa3347 100644 --- a/senf/Packets/PacketParser.cci +++ b/senf/Packets/PacketParser.cci @@ -49,8 +49,29 @@ prefix_ senf::PacketParserBase::data_iterator senf::PacketParserBase::end() return data_->end(); } +prefix_ senf::PacketParserBase::ParserProtector::ParserProtector(PacketParserBase const * p) + : safe_i_( *p), parser_(p) +{} + +prefix_ senf::PacketParserBase::ParserProtector::ParserProtector(ParserProtector const & other_) + : safe_i_( *other_.parser_), parser_(other_.parser_) +{ + other_.parser_ = 0; +} + +prefix_ senf::PacketParserBase::ParserProtector::~ParserProtector() +{ + if (parser_) const_cast(parser_)->i_ = safe_i_; +} + // protected members +prefix_ senf::PacketParserBase::ParserProtector senf::PacketParserBase::protect() + const +{ + return ParserProtector(this); +} + prefix_ bool senf::PacketParserBase::check(size_type size) const { diff --git a/senf/Packets/PacketParser.hh b/senf/Packets/PacketParser.hh index e22bf18..3eb5d6a 100644 --- a/senf/Packets/PacketParser.hh +++ b/senf/Packets/PacketParser.hh @@ -161,6 +161,7 @@ #include "PacketTypes.hh" #include "PacketData.hh" #include "ParseHelpers.hh" +#include "SafeIterator.hh" //#include "PacketParser.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -290,7 +291,21 @@ namespace senf { implementation. Re-implement this member in your own parsers if needed. */ + private: + struct ParserProtector { + senf::safe_data_iterator safe_i_; + mutable PacketParserBase const * parser_; + + ParserProtector( PacketParserBase const * parser); + ParserProtector(ParserProtector const & other_); + ~ParserProtector(); + + template + void operator()(_ const &) const {} + }; protected: + ParserProtector protect() const; + PacketParserBase(data_iterator i, state_type s); ///< Standard constructor /**< This is the constructor used by most parsers. The parameters are just forwarded from the derived classes @@ -371,6 +386,7 @@ namespace senf { PacketData * data_; template friend class SafePacketParserWrapper; + friend class ParserProtector; }; /** \brief Return raw size parsed by the given parser object