struct MIHF_IdParser : public senf::PacketParserBase
{
# include SENF_FIXED_PARSER()
-
+
SENF_PARSER_FINALIZE ( MIHF_IdParser );
};
SENF_PARSER_SKIP_BITS ( 1 );
// MIH message ID (MID)
- SENF_PARSER_BITFIELD ( sid, 4, unsigned );
- SENF_PARSER_BITFIELD ( opcode, 2, unsigned );
- SENF_PARSER_BITFIELD ( aid, 10, unsigned );
+ SENF_PARSER_BITFIELD ( sid, 4, unsigned );
+ SENF_PARSER_BITFIELD ( opcode, 2, unsigned );
+ SENF_PARSER_BITFIELD ( aid, 10, unsigned );
SENF_PARSER_SKIP_BITS ( 4 );
SENF_PARSER_BITFIELD ( transactionId, 12, unsigned );
SENF_PARSER_INIT() {
version_() = 1;
source_type() = 1;
- destination_type() = 1;
+ destination_type() = 2;
}
};
case 5:
return parse<UInt32Parser>( 1 ).value();
default:
- throw(UnsuportedTLVPacketException());
+ throw(TLVLengthException());
};
}
+
prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v)
{
- SafePacketParserWrapper<DynamicTLVLengthParser> safeThis (*this);
- if (v < 128u) {
- if (bytes() != 1)
- resize(1, safeThis);
- safeThis->fixed_length_field() = v;
+ switch (bytes() ) {
+ case 1:
+ if (v > 127) throw( TLVLengthException());
+ fixed_length_field() = v;
return;
- }
- if (v <= UInt8Parser::max_value) {
- if (bytes() != 2)
- resize(2, safeThis);
- safeThis->parse<UInt8Parser>(1) = v;
+ case 2:
+ if (v > UInt8Parser::max_value) throw( TLVLengthException());
+ parse<UInt8Parser>(1) = v;
return;
- }
- if (v <= UInt16Parser::max_value) {
- if (bytes() != 3)
- resize(3, safeThis);
- safeThis->parse<UInt16Parser>(1) = v;
+ case 3:
+ if (v > UInt16Parser::max_value) throw( TLVLengthException());
+ parse<UInt16Parser>(1) = v;
return;
- }
- if (v <= UInt24Parser::max_value) {
- if (bytes() != 4)
- resize(4, safeThis);
- safeThis->parse<UInt24Parser>(1) = v;
+ case 4:
+ if (v > UInt24Parser::max_value) throw( TLVLengthException());
+ parse<UInt24Parser>(1) = v;
return;
- }
- if (v <= UInt32Parser::max_value) {
- if (bytes() != 5)
- resize(5, safeThis);
- safeThis->parse<UInt32Parser>(1) = v;
+ case 5:
+ parse<UInt32Parser>(1) = v;
return;
- }
- throw(UnsuportedTLVPacketException());
+ default:
+ throw( TLVLengthException());
+ };
}
+
prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::operator= (value_type other)
{
value(other);
return *this;
}
+
prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const
{
if ( extended_length_flag() )
return 1;
}
+
prefix_ void senf::DynamicTLVLengthParser::init() const
{
defaultInit();
- extended_length_flag() = 0;
+ extended_length_flag() = false;
}
-prefix_ void senf::DynamicTLVLengthParser::resize(
- size_type size, SafePacketParserWrapper<DynamicTLVLengthParser> &safeThis)
+
+prefix_ void senf::DynamicTLVLengthParser::shrink()
{
- std::cout << "DynamicTLVLengthParser::resize " << unsigned( size) << "\n";
- if (size > 1) {
- safeThis->extended_length_flag() = true;
- safeThis->fixed_length_field() = size - 1;
- } else {
- safeThis->extended_length_flag() = false;
+ value_type v = value();
+ size_type b = bytes();
+ if (v <= 127) {
+ if (b != 1) resize(1);
+ return;
}
-
+ if (v <= UInt8Parser::max_value) {
+ if (b != 2) resize(2);
+ return;
+ }
+ if (v <= UInt16Parser::max_value) {
+ if (b != 3) resize(3);
+ return;
+ }
+ if (v <= UInt24Parser::max_value) {
+ if (b != 4) resize(4);
+ return;
+ }
+ if (b != 5) resize(5);
+}
+
+
+prefix_ void senf::BaseTLVPacketParser:: maxLengthValue(DynamicTLVLengthParser::value_type v)
+ const
+{
+ if (v <= 127)
+ return;
+ size_type b = senf::bytes( length_());
+ if (v <= UInt8Parser::max_value) {
+ if (b < 2) length_().resize(2);
+ return;
+ }
+ if (v <= UInt16Parser::max_value) {
+ if (b < 3) length_().resize(3);
+ return;
+ }
+ if (v <= UInt24Parser::max_value) {
+ if (b < 4) length_().resize(4);
+ return;
+ }
+ if (b < 5) length_().resize(5);
+}
+
+
+prefix_ senf::PacketInterpreterBase::range senf::GenericTLVPacketParser::value()
+ const
+{
+ senf::PacketData::iterator begin (boost::next(data().begin(), 1 + length_bytes() ));
+ return PacketInterpreterBase::range(
+ begin, boost::next( begin, length()) );
+}
+
+
+prefix_ void senf::DynamicTLVLengthParser::resize(size_type size)
+{
+ value_type v = value();
size_type current_size (bytes());
- safe_data_iterator si (data(), i());
+ SafePacketParserWrapper<DynamicTLVLengthParser> safeThis (*this);
+ safe_data_iterator si (data(), i());
if (current_size > size)
data().erase( si, boost::next(si, current_size-size));
else
data().insert( si, size-current_size, 0);
+
+ if (size > 1) {
+ safeThis->extended_length_flag() = true;
+ safeThis->fixed_length_field() = size - 1;
+ } else {
+ safeThis->extended_length_flag() = false;
+ }
+ value(v);
}
+
prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os)
{
boost::io::ios_all_saver ias(os);
<< " length: " << unsigned( p->length()) << "\n";
}
-//prefix_ void senf::GenericTLVPacketType::finalize(packet p)
-//{
-// try {
-// PacketData::size_type size = p.next().data().size();
-// if ( size > DynamicTLVLengthParser::max_value )
-// throw(UnsuportedTLVPacketException());
-// p->length() = size;
-// }
-// catch (InvalidPacketChainException & ex) {
-// ;
-// }
-//}
-
-
-//template <class TypeParser, class LengthParser>
-//prefix_ senf::PacketInterpreterBase::optional_range
-//senf::TLVPacketType<TypeParser, LengthParser>::nextPacketRange(packet p)
-//{
-// if (p.data().size() < 5)
-// return no_range();
-// return range(
-// boost::next(p.data().begin(), 4 + senf::bytes(p->length()) ),
-// p.data().end() );
-//}
+
+prefix_ void senf::GenericTLVPacketType::finalize(packet p)
+{
+ p->shrinkLength();
+}
///////////////////////////////cc.e////////////////////////////////////////
--- /dev/null
+// $Id: TLVPacket.ct 1029 2008-12-19 13:08:19Z tho $
+//
+// 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 non-inline template implementation */
+
+//#include "TLVPacket.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class ForwardReadableRange>
+prefix_ void senf::GenericTLVPacketParser::value(ForwardReadableRange const &range)
+{
+ size_type range_size ( boost::size(range));
+ size_type current_length ( length());
+ length( range_size);
+
+ safe_data_iterator si (data(), boost::next(i(), 1 + length_bytes() ));
+ if (current_length > range_size)
+ data().erase( si, boost::next(si, current_length-range_size));
+ else
+ data().insert( si, range_size-current_length, 0);
+
+ std::copy( boost::begin(range), boost::end(range), si);
+}
+
+///////////////////////////////ct.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:
namespace senf {
- /** \brief xxx
-
- \todo document me
- \todo add usefull exceptions strings
-
- \ingroup protocolbundle_80221
- */
- struct UnsuportedTLVPacketException : public senf::Exception
- { UnsuportedTLVPacketException()
- : senf::Exception("length of length can be max. 4 bytes. Sorry."){} };
-
- /** \brief xxx
- \todo document me
-
- \ingroup protocolbundle_80221
- */
+
+ struct TLVLengthException : public senf::Exception
+ { TLVLengthException()
+ : senf::Exception("TLVLengthException"){} };
+
+
class DynamicTLVLengthParser
: public detail::packet::IntParserOps<DynamicTLVLengthParser, boost::uint32_t>,
public PacketParserBase
void init() const;
# include SENF_PARSER()
-
SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1, bool );
SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 7, unsigned );
-
- private:
-// typedef FlagParser < 0 > ExtendedLengthFlagParser;
-// typedef UIntFieldParser < 1, 8 > FixedLengthParser;
-//
-// ExtendedLengthFlagParser extended_length_flag() const {
-// return parse<ExtendedLengthFlagParser>( 0 );
-// }
-//
-// FixedLengthParser fixed_length_field() const {
-// return parse<FixedLengthParser>( 0 );
-// }
-
- void resize(size_type size, SafePacketParserWrapper<DynamicTLVLengthParser> &safeThis);
+ void resize(size_type size);
+ void shrink();
};
- /** \brief parse TLVPacket Packet
-
- \todo document me
-
- \see TLVPacketType
-
- \ingroup protocolbundle_80221
- */
- struct GenericTLVPacketParser : public PacketParserBase
+
+ class BaseTLVPacketParser : public PacketParserBase
{
# include SENF_PARSER()
+ SENF_PARSER_FIELD ( type, UInt8Parser );
+ SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser );
+ SENF_PARSER_FINALIZE ( BaseTLVPacketParser );
- SENF_PARSER_FIELD ( type, UInt8Parser );
- SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser );
- SENF_PARSER_VECTOR ( value, bytes(length), UInt8Parser );
+ void maxLengthValue(DynamicTLVLengthParser::value_type v) const;
+ void shrinkLength() { length_().shrink(); };
- SENF_PARSER_FINALIZE( GenericTLVPacketParser );
+ protected:
+ size_type length_bytes() const { return length_().bytes(); };
+ void length(DynamicTLVLengthParser::value_type &v) { length_() = v; };
};
-
- /** \brief generic TLV Packet type
+
- \todo document me
+ struct GenericTLVPacketParser : public BaseTLVPacketParser
+ {
+# include SENF_PARSER()
+ SENF_PARSER_INHERIT( BaseTLVPacketParser )
+ SENF_PARSER_FINALIZE( GenericTLVPacketParser );
+
+ SENF_PARSER_INIT() {
+ maxLengthValue( DynamicTLVLengthParser::max_value);
+ }
+
+ senf::PacketInterpreterBase::range value() const;
- \ingroup protocolbundle_80221
- */
+ template <class ForwardReadableRange>
+ void value(ForwardReadableRange const &range);
+ };
+
struct GenericTLVPacketType
: public PacketTypeBase,
public PacketTypeMixin<GenericTLVPacketType>
typedef ConcretePacket<GenericTLVPacketType> packet;
typedef GenericTLVPacketParser parser;
-// static optional_range nextPacketRange(packet p);
using mixin::nextPacketRange;
using mixin::init;
using mixin::initSize;
-// static void finalize(packet p);
+ static void finalize(packet p);
static void dump(packet p, std::ostream & os);
};
///////////////////////////////hh.e////////////////////////////////////////
//#include "TLVPacket.cci"
-//#include "TLVPacket.ct"
+#include "TLVPacket.ct"
//#include "TLVPacket.cti"
#endif
#include "../../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp>
-#include <vector>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
using namespace senf;
-void check_TLVPacket(GenericTLVPacket &tlvPacket, boost::uint32_t type, boost::uint32_t length)
+void check_TLVPacket(GenericTLVPacket &tlvPacket, boost::uint8_t type, boost::uint32_t length)
{
- BOOST_CHECK_EQUAL( tlvPacket->type(), type );
- BOOST_CHECK_EQUAL( tlvPacket->length(), length );
-
- BOOST_CHECK_EQUAL( tlvPacket->value().size(), length);
- for (int i=0, j=tlvPacket->value().size(); i<j; i++)
- BOOST_CHECK_EQUAL( tlvPacket->value()[i], i );
-}
-
-
-BOOST_AUTO_UNIT_TEST(GenericTLVPacket_static)
-{
- // check static values:
- // number of bytes to allocate for a new GenericTLVPacket should be 2
- BOOST_CHECK_EQUAL( GenericTLVPacket::type::initSize(), 2u );
+ BOOST_CHECK_EQUAL( tlvPacket->type(), type );
+ BOOST_CHECK_EQUAL( tlvPacket->length(), length );
+ BOOST_CHECK_EQUAL( tlvPacket->value().size(), length );
+ senf::PacketData::iterator dataIterator (tlvPacket->value().begin());
+ for (unsigned i=0; i<length; i++) {
+ BOOST_CHECK_EQUAL( *dataIterator, i );
+ dataIterator++;
+ }
}
check_TLVPacket( tlvPacket, 0x01, 0x0Au );
}
+
BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length)
{
unsigned char data[] = {
BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_simple_length)
{
+ unsigned char value[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
+ };
GenericTLVPacket tlvPacket (GenericTLVPacket::create());
tlvPacket->type() = 42u;
- for (uint8_t i=0; i<10; i++)
- tlvPacket->value().push_back( i);
- tlvPacket.finalizeAll();
+ tlvPacket->value( value);
+ tlvPacket.finalizeThis();
check_TLVPacket( tlvPacket, 42u, 0x0Au );
+
+ unsigned char 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 ));
}
-/**
+#if 0
BOOST_AUTO_UNIT_TEST(TLVPacket_create_packet_with_extended_length)
{
GenericTLVPacket tlvPacket (GenericTLVPacket::create());
test_invalid_TLVFixPacket_creating<TestTLVPacket24>( UInt24Parser::max_value);
}
-*/
-
+#endif
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_