--- /dev/null
+// $Id$
+//
+// Copyright (C) 2011
+// 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 MIH Message-Registry non-inline non-template implementation */
+
+#include "MIHMessageRegistry.hh"
+//#include "MIHMessageRegistry.ih"
+
+// Custom includes
+
+#define prefix_
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
+// senf::MIHMessageRegistry
+
+#if BOOST_VERSION < 103400
+# define PTRMAP_GET_CONTENTS(v) (v)
+#else
+# define PTRMAP_GET_CONTENTS(v) (*(v).second)
+#endif
+
+prefix_ std::pair<bool, std::string> senf::MIHMessageRegistry::validate(key_t messageId, senf::Packet message)
+{
+ Map::const_iterator i (map_.find( messageId));
+ if (i != map_.end())
+ return PTRMAP_GET_CONTENTS(*i).validate( message);
+ return std::make_pair(true, "");
+}
+
+#undef PTRMAP_GET_CONTENTS
+
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
+#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:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2011
+// 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 MIH Message-Registry non-inline template implementation */
+
+// Custom includes
+
+#define prefix_
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
+// senf::MIHMessageRegistry
+
+template <typename MIHPacket>
+prefix_ void senf::MIHMessageRegistry::registerMessageType()
+{
+ key_t key (MIHPacket::type::MESSAGE_ID+0);
+ map_.insert(key, new detail::MIHMessageRegistryEntry<MIHPacket>() );
+}
+
+template <typename MIHPacket>
+prefix_ senf::MIHMessageRegistry::RegistrationProxy<MIHPacket>::RegistrationProxy()
+{
+ MIHMessageRegistry::instance().registerMessageType<MIHPacket>();
+}
+
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
+#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"
+// End:
// $Id$
//
-// Copyright (C) 2009
+// Copyright (C) 2010
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Thorsten Horstmann <tho@berlios.de>
#define HH_SENF_Packets_80221Bundle_MIHMessageRegistry_ 1
// Custom includes
+#include <boost/ptr_container/ptr_map.hpp>
+#include <senf/Utils/singleton.hh>
#include <senf/Packets/Packets.hh>
-//#include "MIHPacket.mpp"
+//#include "MIHMessageRegistry.mpp"
//-/////////////////////////////////////////////////////////////////////////////////////////////////
namespace senf {
- struct MIHMessageRegistry {
- // MIH messages registry
+ namespace detail {
+
+ template<class T, typename Signature>
+ struct has_static_validate_member
+ {
+ template<Signature *>
+ struct helper;
+
+ template<class U>
+ static char test(helper<&U::validate> *);
+
+ template<class U>
+ static char (&test(...))[2];
+
+ static const bool value = sizeof(test<T>(0))==1;
+ };
+
+ struct MIHMessageRegistry_EntryBase {
+ virtual ~MIHMessageRegistry_EntryBase() {}
+ virtual std::pair<bool, std::string> validate(senf::Packet message) const = 0;
+ };
+
+ template <class MIHPacket,
+ bool use_validate_member = has_static_validate_member<typename MIHPacket::type, std::pair<bool, std::string>(MIHPacket)>::value>
+ struct MIHMessageRegistryEntry : MIHMessageRegistry_EntryBase
+ {
+ virtual std::pair<bool, std::string> validate(senf::Packet message) const {
+ return std::make_pair(true, "");
+ }
+ };
+
+ template <class MIHPacket>
+ struct MIHMessageRegistryEntry<MIHPacket, true> : MIHMessageRegistry_EntryBase
+ {
+ virtual std::pair<bool, std::string> validate(senf::Packet message) const {
+ return MIHPacket::type::validate(message.as<MIHPacket>());
+ }
+ };
+ }
+
+
+ class MIHMessageRegistry
+ : public senf::singleton<MIHMessageRegistry>
+ {
+ public:
typedef boost::uint16_t key_t;
+
+ using senf::singleton<MIHMessageRegistry>::instance;
+ friend class senf::singleton<MIHMessageRegistry>;
+
+ template <typename MIHPacket>
+ struct RegistrationProxy {
+ RegistrationProxy();
+ };
+
+ template <typename MIHPacket>
+ void registerMessageType();
+
+ std::pair<bool, std::string> validate(key_t messageId, senf::Packet message);
+
+ private:
+ typedef boost::ptr_map<key_t, detail::MIHMessageRegistry_EntryBase > Map;
+ Map map_;
+
+ MIHMessageRegistry() {};
};
-# define SENF_MIH_PACKET_REGISTRY_REGISTER( packet ) \
- SENF_PACKET_REGISTRY_REGISTER( \
- senf::MIHMessageRegistry, packet::type::MESSAGE_ID, packet )
+
+# define SENF_MIH_PACKET_REGISTRY_REGISTER( packet ) \
+ SENF_PACKET_REGISTRY_REGISTER( \
+ senf::MIHMessageRegistry, packet::type::MESSAGE_ID, packet ) \
+ namespace { \
+ senf::MIHMessageRegistry::RegistrationProxy< packet > \
+ BOOST_PP_CAT(mihPacketRegistration_, __LINE__); \
+ }
}
//-/////////////////////////////////////////////////////////////////////////////////////////////////
-//#include "MIHPacket.cci"
-//#include "MIHPacket.ct"
-//#include "MIHPacket.cti"
+//#include "MIHMessageRegistry.cci"
+#include "MIHMessageRegistry.ct"
+//#include "MIHMessageRegistry.cti"
#endif
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2011
+// 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 MIH Message-Registry unit tests */
+
+//#include "MIHPacket.test.hh"
+//#include "MIHPacket.test.ih"
+
+// Custom includes
+#include "MIHMessageRegistry.hh"
+#include "MIHPacket.hh"
+
+#include <senf/Utils/auto_unit_test.hh>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
+using namespace senf;
+
+namespace {
+
+ class TestMessagePacketParser
+ : public senf::PacketParserBase
+ {
+ # include SENF_PARSER()
+ SENF_PARSER_FIELD ( registerRequestCodeTLV, senf::MIHRegisterReqCodeTLVParser );
+ SENF_PARSER_FINALIZE ( TestMessagePacketParser );
+ };
+
+
+ struct TestMessagePacketType
+ : public senf::PacketTypeBase,
+ public senf::PacketTypeMixin<TestMessagePacketType>
+ {
+ typedef senf::ConcretePacket<TestMessagePacketType> packet;
+ typedef senf::PacketTypeMixin<TestMessagePacketType> mixin;
+ typedef TestMessagePacketParser parser;
+
+ using mixin::nextPacketRange;
+ using mixin::init;
+ using mixin::initSize;
+
+ static const boost::uint16_t MESSAGE_ID;
+ };
+
+ struct ValidatedTestMessagePacketType
+ : public senf::PacketTypeBase,
+ public senf::PacketTypeMixin<ValidatedTestMessagePacketType>
+ {
+ typedef senf::ConcretePacket<ValidatedTestMessagePacketType> packet;
+ typedef senf::PacketTypeMixin<ValidatedTestMessagePacketType> mixin;
+ typedef TestMessagePacketParser parser;
+
+ using mixin::nextPacketRange;
+ using mixin::init;
+ using mixin::initSize;
+
+ static const boost::uint16_t MESSAGE_ID;
+
+ static std::pair<bool, std::string> validate(packet message) {
+ return std::make_pair(message->registerRequestCodeTLV().value() == 1, "");
+ }
+ };
+
+ typedef senf::ConcretePacket<TestMessagePacketType> TestMessagePacket;
+ typedef senf::ConcretePacket<ValidatedTestMessagePacketType> ValidatedTestMessagePacket;
+
+ const boost::uint16_t TestMessagePacketType::MESSAGE_ID = 42;
+ const boost::uint16_t ValidatedTestMessagePacketType::MESSAGE_ID = 43;
+
+ SENF_MIH_PACKET_REGISTRY_REGISTER( TestMessagePacket );
+ SENF_MIH_PACKET_REGISTRY_REGISTER( ValidatedTestMessagePacket );
+}
+
+
+SENF_AUTO_UNIT_TEST(MIHMessageRegistry_validate)
+{
+ MIHPacket mihPacket (MIHPacket::create());
+ mihPacket->transactionId() = 21;
+ mihPacket->src_mihfId().value( "senf@berlios.de");
+ mihPacket->dst_mihfId().value( "test");
+
+ BOOST_CHECK(! MIHPacketType::validate( mihPacket).first);
+
+ mihPacket.finalizeThis();
+ BOOST_CHECK( MIHPacketType::validate( mihPacket).first);
+
+ {
+ TestMessagePacket testMessage (TestMessagePacket::createAfter(mihPacket));
+ mihPacket.finalizeAll();
+ BOOST_CHECK( MIHPacketType::validate( mihPacket).first);
+ }
+ {
+ ValidatedTestMessagePacket testMessage (ValidatedTestMessagePacket::createAfter(mihPacket));
+ mihPacket.finalizeAll();
+ BOOST_CHECK(! MIHPacketType::validate( mihPacket).first);
+ testMessage->registerRequestCodeTLV().value() << 1;
+ BOOST_CHECK( MIHPacketType::validate( mihPacket).first);
+ }
+}
+
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
+#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:
// Custom includes
#include <boost/io/ios_state.hpp>
+#include <senf/Utils/String.hh>
#include <senf/Packets/DefaultBundle/EthernetPacket.hh>
#define prefix_
return e ? e->factory() : MIHGenericPayloadPacket::factory();
}
+prefix_ std::pair<bool, std::string> senf::MIHPacketType::validate(packet p)
+{
+ if (p.data().size() < initSize())
+ return std::make_pair(false, "truncated MIH message");
+ if (p->version() != 1)
+ return std::make_pair(false, "invalid MIH version: " + senf::str(p->version()) );
+ if (p->payloadLength() != p.size()-8)
+ return std::make_pair(false, "wrong MIH length: " + senf::str(p->payloadLength()) );
+ if (p.next(senf::nothrow))
+ return MIHMessageRegistry::instance().validate( p->messageId(), p.next());
+ return std::make_pair(true, "");
+}
+
//-/////////////////////////////////////////////////////////////////////////////////////////////////
// MIHGenericPayloadPacketType
: public PacketTypeBase,
public PacketTypeMixin<MIHPacketType, MIHMessageRegistry>
{
-#ifndef DOXYGEN
typedef PacketTypeMixin<MIHPacketType, MIHMessageRegistry> mixin;
-#endif
typedef ConcretePacket<MIHPacketType> packet; ///< MIH packet typedef
typedef MIHPacketParser parser; ///< typedef to the parser of MIH packet
static void dump(packet p, std::ostream &os);
static void finalize(packet p);
static factory_t nextPacketType(packet p);
+
+ static std::pair<bool, std::string> validate(packet p);
};
/** \brief MIH packet typedef
: public PacketTypeBase,
public PacketTypeMixin<MIHGenericPayloadPacketType>
{
-#ifndef DOXYGEN
typedef PacketTypeMixin<MIHGenericPayloadPacketType> mixin;
-#endif
typedef ConcretePacket<MIHGenericPayloadPacketType> packet; ///< MIH Payload packet typedef
typedef MIHGenericPayloadPacketParser parser; ///< typedef to the parser of MIH Payload packet
#include <iomanip>
#include <senf/Utils/hexdump.hh>
#include <senf/Utils/Format.hh>
+#include <senf/Utils/String.hh>
#define prefix_
//-/////////////////////////////////////////////////////////////////////////////////////////////////
os << " (???; invalid value!)" << std::endl;
}
+prefix_ std::pair<bool, std::string> senf::MIHRegisterReqCodeTLVParser::validate()
+ const
+{
+ if (length() != 1) return std::make_pair(false, "invalid length in MIHRegisterReqCodeTLV " + senf::str(length()));
+ if (value() >= 2) return std::make_pair(false, "invalid value in MIHRegisterReqCodeTLV " + senf::str(value()));
+ return std::make_pair(true, "");
+}
+
//-/////////////////////////////////////////////////////////////////////////////////////////////////
// senf::MIHValidTimeIntervalTLVParser
<< ( value()==0 ? " (infinite)" : " seconds") << std::endl;
}
+prefix_ std::pair<bool, std::string> senf::MIHValidTimeIntervalTLVParser::validate()
+ const
+{
+ if (length() != 4) return std::make_pair(false, "invalid length in MIHValidTimeIntervalTLV " + senf::str(length()));
+ return std::make_pair(true, "");
+}
+
//-/////////////////////////////////////////////////////////////////////////////////////////////////
// senf::MIHTLVLengthParser
}
static type_t::value_type const typeId = 11;
void dump(std::ostream & os) const; ///< dump string representation to given stream
+ std::pair<bool, std::string> validate() const;
enum RequestCode { Registration, ReRegistration };
};
}
static type_t::value_type const typeId = 12;
void dump(std::ostream & os) const; ///< dump string representation to given stream
+ std::pair<bool, std::string> validate() const;
};
}
#define HH_SENF_Packets_PacketRegistry_ 1
// Custom includes
-#include <map>
-#include <boost/utility.hpp> // for boost::noncopyable
#include <boost/optional.hpp>
#include <boost/preprocessor/cat.hpp>
#include <senf/Utils/Exception.hh>
#define IH_SENF_Packets_PacketRegistry_ 1
// Custom includes
-#include <ext/functional>
#include <limits>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/intrusive_ptr.hpp>
-#include <boost/iterator/transform_iterator.hpp>
+#include <boost/utility.hpp> // for boost::noncopyable
#include <senf/Utils/TypeIdValue.hh>
//-/////////////////////////////////////////////////////////////////////////////////////////////////