if (p.data().size() < initSize())
return no_factory();
PkReg_Entry const * e (PacketRegistry<MIHMessageRegistry>::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_
// Custom includes
#include <senf/Packets/Packets.hh>
-#include <senf/Socket/Protocols/Raw/MACAddress.hh>
-#include <senf/Socket/Protocols/INet/INet4Address.hh>
-#include <senf/Socket/Protocols/INet/INet6Address.hh>
-#include "TLVPacket.hh"
-#include <boost/function_output_iterator.hpp>
-#include <boost/iterator/filter_iterator.hpp>
-#include <boost/variant.hpp>
-
+#include "TLVParser.hh"
//#include "MIHPacket.mpp"
///////////////////////////////hh.p////////////////////////////////////////
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<MIHFId>,
- public boost::equality_comparable<MIHFId>
- {
- 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> {
- 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<bool> {
- template <typename T, typename U>
- bool operator()(T const &, U const &) const {
- return false;
- }
- template <typename T>
- bool operator()( const T & lhs, const T & rhs ) const {
- return lhs == rhs;
- }
- };
- struct LessThanVisitor : public boost::static_visitor<bool> {
- template <typename T, typename U>
- bool operator()(T const &, U const &) const {
- return false;
- }
- template <typename T>
- 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 <class OutputIterator>
- struct binaryNAIEncoder {
- binaryNAIEncoder(OutputIterator &i) : i_(i) {}
- void operator()(const boost::uint8_t &v) const {
- *i_++ = '\\';
- *i_++ = v;
- }
- OutputIterator &i_;
- };
- template <class OutputIterator>
- static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> > getNAIEncodedOutputIterator(OutputIterator i) {
- return boost::make_function_output_iterator(binaryNAIEncoder<OutputIterator>(i));
- }
-
- struct binaryNAIDecoder {
- binaryNAIDecoder() : readNextByte_(true) {}
- bool operator()(const boost::uint8_t &v) {
- readNextByte_ = readNextByte_ ? false : true;
- return readNextByte_;
- }
- bool readNextByte_;
- };
- template <class Iterator>
- static boost::filter_iterator<binaryNAIDecoder, Iterator> getNAIDecodedIterator(Iterator begin, Iterator end) {
- return boost::make_filter_iterator<binaryNAIDecoder>(begin, end);
- }
- };
-
+
/** \brief Parse a MIH packet
Parser implementing the MIH header. The fields implemented are:
static factory_t nextPacketType(packet p);
};
- /** \brief MIH packet typedef */
+ /** \brief MIH packet typedef
+ \ingroup protocolbundle_80221
+ */
typedef ConcretePacket<MIHPacketType> 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<MIHPayloadPacketType>
+ public PacketTypeMixin<MIHGenericPayloadPacketType>
{
#ifndef DOXYGEN
- typedef PacketTypeMixin<MIHPayloadPacketType> mixin;
+ typedef PacketTypeMixin<MIHGenericPayloadPacketType> mixin;
#endif
- typedef ConcretePacket<MIHPayloadPacketType> packet; ///< MIH Payload packet typedef
- typedef MIHPayloadPacketParser parser; ///< typedef to the parser of MIH Payload packet
+ typedef ConcretePacket<MIHGenericPayloadPacketType> 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<MIHPayloadPacketType> MIHPayloadPacket;
+ /** \brief MIH Payload packet typedef
+ \ingroup protocolbundle_80221
+ */
+ typedef ConcretePacket<MIHGenericPayloadPacketType> MIHGenericPayloadPacket;
}
///////////////////////////////hh.e////////////////////////////////////////
-#include "MIHPacket.cci"
+//#include "MIHPacket.cci"
//#include "MIHPacket.ct"
//#include "MIHPacket.cti"
#endif
MIHPacket mihPacket (MIHPacket::create(data));
BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 42u);
- BOOST_REQUIRE( mihPacket.next().is<MIHPayloadPacket>() );
- MIHPayloadPacket mihPayload (mihPacket.next().as<MIHPayloadPacket>());
+ BOOST_REQUIRE( mihPacket.next().is<MIHGenericPayloadPacket>() );
+ MIHGenericPayloadPacket mihPayload (mihPacket.next().as<MIHGenericPayloadPacket>());
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);
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();
// 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
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_
\f
// 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:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Thorsten Horstmann <tho@berlios.de>
+//
+// 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 <senf/Socket/Protocols/Raw/MACAddress.hh>
+#include <senf/Socket/Protocols/INet/INet4Address.hh>
+#include <senf/Socket/Protocols/INet/INet6Address.hh>
+#include <boost/function_output_iterator.hpp>
+#include <boost/iterator/filter_iterator.hpp>
+#include <boost/variant.hpp>
+
+//#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<MIHFId>,
+ public boost::equality_comparable<MIHFId>
+ {
+ 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> {
+ 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<bool> {
+ template <typename T, typename U>
+ bool operator()(T const &, U const &) const {
+ return false;
+ }
+ template <typename T>
+ bool operator()( const T & lhs, const T & rhs ) const {
+ return lhs == rhs;
+ }
+ };
+ struct LessThanVisitor : public boost::static_visitor<bool> {
+ template <typename T, typename U>
+ bool operator()(T const &, U const &) const {
+ return false;
+ }
+ template <typename T>
+ bool operator()( const T & lhs, const T & rhs ) const {
+ return lhs < rhs;
+ }
+ };
+ };
+
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "MIHTypes.cci"
+//#include "MIHTypes.ct"
+//#include "MIHTypes.cti"
+#endif
+
+\f
+// 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:
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2007
-// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-// Thorsten Horstmann <tho@berlios.de>
-//
-// 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_
-
-\f
-// 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:
// 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 <iomanip>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+// MIHBaseTLVParser
+
prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
MIHTLVLengthParser::value_type size)
{
}
+///////////////////////////////////////////////////////////////////////////
+// MIHTLVLengthParser
+
prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const
{
switch (bytes() ) {
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);
}
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<MIHTLVLengthParser> 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);
}
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Thorsten Horstmann <tho@berlios.de>
+//
+// 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_
+
+\f
+// 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:
// 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 <algorithm>
#include <senf/Packets/Packets.hh>
+#include "MIHTypes.hh"
-//#include "TLVPacket.mpp"
+//#include "TLVParser.mpp"
///////////////////////////////hh.p////////////////////////////////////////
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.
SENF_PARSER_VECTOR ( value, bytes(length), senf::MACAddressParser );
SENF_PARSER_FINALIZE( MacAddressesTLVParser );
};
-
- struct MacAddressesTLVPacketType : public PacketTypeBase {
- typedef MacAddressesTLVParser parser;
- ...
- static void finalize(ConcretePacket<MacAddressesTLVPacketType> p) {
- p->finalizeLength();
- }
- };
\endcode
You have to adjust the maximum length value with the \ref maxLengthValue function
if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before.
\see MIHTLVLengthParser \n
- MIHGenericTLVPacketParser \n
+ MIHGenericTLVParser \n
*/
class MIHBaseTLVParser : public PacketParserBase
{
\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
the current length value.
*/
void finalizeLength() {
- length_().finalize();
+ protect(), length_().finalize();
};
protected:
/** \brief Parser for a generic TLV packet
-
- \see MIHGenericTLVPacketType
*/
- struct MIHGenericTLVPacketParser
+ struct MIHGenericTLVParser
: public GenericTLVParserBase<MIHBaseTLVParser>
{
typedef senf::GenericTLVParserBase<MIHBaseTLVParser> 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<MIHGenericTLVPacketType>
- {
-#ifndef DOXYGEN
- typedef PacketTypeMixin<MIHGenericTLVPacketType> mixin;
-#endif
- typedef ConcretePacket<MIHGenericTLVPacketType> 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 <class OutputIterator>
+ struct binaryNAIEncoder {
+ binaryNAIEncoder(OutputIterator &i) : i_(i) {}
+ void operator()(const boost::uint8_t &v) const {
+ *i_++ = '\\';
+ *i_++ = v;
+ }
+ OutputIterator &i_;
+ };
+ template <class OutputIterator>
+ static boost::function_output_iterator<binaryNAIEncoder<OutputIterator> > getNAIEncodedOutputIterator(OutputIterator i) {
+ return boost::make_function_output_iterator(binaryNAIEncoder<OutputIterator>(i));
+ }
+
+ struct binaryNAIDecoder {
+ binaryNAIDecoder() : readNextByte_(true) {}
+ bool operator()(const boost::uint8_t &v) {
+ readNextByte_ = readNextByte_ ? false : true;
+ return readNextByte_;
+ }
+ bool readNextByte_;
+ };
+ template <class Iterator>
+ static boost::filter_iterator<binaryNAIDecoder, Iterator> getNAIDecodedIterator(Iterator begin, Iterator end) {
+ return boost::make_filter_iterator<binaryNAIDecoder>(begin, end);
+ }
};
-
- /** \brief GenericTLV packet typedef
- \ingroup protocolbundle_80221
- */
- typedef ConcretePacket<MIHGenericTLVPacketType> MIHGenericTLVPacket;
+
+
}
///////////////////////////////hh.e////////////////////////////////////////
-#include "TLVPacket.cci"
-//#include "TLVPacket.ct"
-//#include "TLVPacket.cti"
+#include "TLVParser.cci"
+//#include "TLVParser.ct"
+//#include "TLVParser.cti"
#endif
\f
// 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 <senf/Packets/DefaultBundle/EthernetPacket.hh>
#include <senf/Utils/auto_unit_test.hh>
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<plength; i++) { \
- BOOST_CHECK_EQUAL( *dataIterator, i ); \
- dataIterator++; \
- } \
+ struct VoidPacket : public PacketTypeBase
+ {};
+
+#define CHECK_TLVParser(tlvParser, ptype, plength) \
+{ \
+ BOOST_CHECK_EQUAL( tlvParser.type(), ptype ); \
+ BOOST_CHECK_EQUAL( tlvParser.length(), plength ); \
+ BOOST_CHECK_EQUAL( tlvParser.value().size(), int(plength) ); \
+ senf::PacketData::iterator dataIterator (tlvParser.value().begin()); \
+ for (unsigned i=0; i<plength; i++) { \
+ BOOST_CHECK_EQUAL( *dataIterator, i ); \
+ dataIterator++; \
+ } \
}
}
-BOOST_AUTO_UNIT_TEST(MIHGenericTLVPacket_parse_packet_with_simple_length)
+BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_simple_length)
{
- unsigned char data[] = {
+ PacketInterpreterBase::byte data[] = {
0x01, // type
0x0A, // first bit not set, length=10
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
};
- MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create(data));
- CHECK_TLVPacket( tlvPacket, 0x01, 0x0Au );
+ PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::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)
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<VoidPacket>::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<VoidPacket>::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; i<sizeof(value); i++)
value[i] = i;
- MIHGenericTLVPacket tlvPacket (MIHGenericTLVPacket::create());
- tlvPacket->maxLengthValue( 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<VoidPacket>::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<VoidPacket>::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; i<sizeof(value); i++)
value[i] = i;
- BOOST_CHECK_THROW( tlvPacket->value( 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) );
}
template <class ForwardReadableRange>
prefix_ void senf::GenericTLVParserBase<Base>::value_(ForwardReadableRange const &range)
{
- unsigned int rangeSize = boost::size(range);
- std::cerr << "GenericTLVParserBase<Base>::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<ForwardReadableRange>::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(
template <class Base>
template <class Parser>
prefix_ Parser senf::GenericTLVParserBase<Base>::as()
+ const
{
return Parser(this->i(), this->state() );
}
template <class Base>
template <class Parser>
prefix_ bool senf::GenericTLVParserBase<Base>::is()
+ const
{
return this->type().value() == Parser::TYPEID;
}
\endcode
\see
- IPv6GenericOptionTLVParser, WLANGenericInfoElementParser, MIHGenericTLVPacketParser
+ IPv6GenericOptionTLVParser, WLANGenericInfoElementParser, MIHGenericTLVParser
*/
template <class Base>
class GenericTLVParserBase : public Base
Parser init();
template <class Parser>
- Parser as();
+ Parser as() const;
template <class Parser>
- bool is();
+ bool is() const;
senf::PacketInterpreterBase::range value() const;
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<PacketParserBase *>(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
{
#include "PacketTypes.hh"
#include "PacketData.hh"
#include "ParseHelpers.hh"
+#include "SafeIterator.hh"
//#include "PacketParser.mpp"
///////////////////////////////hh.p////////////////////////////////////////
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 <class _>
+ 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
PacketData * data_;
template <class Parser> friend class SafePacketParserWrapper;
+ friend class ParserProtector;
};
/** \brief Return raw size parsed by the given parser object