Skip to content
Snippets Groups Projects
Commit 775457bd authored by tho's avatar tho
Browse files

uff. nearly completely new TLVPacket implementation.

parent 8b8dfd3f
No related branches found
No related tags found
No related merge requests found
...@@ -38,7 +38,7 @@ namespace senf { ...@@ -38,7 +38,7 @@ namespace senf {
struct MIHF_IdParser : public senf::PacketParserBase struct MIHF_IdParser : public senf::PacketParserBase
{ {
# include SENF_FIXED_PARSER() # include SENF_FIXED_PARSER()
SENF_PARSER_FINALIZE ( MIHF_IdParser ); SENF_PARSER_FINALIZE ( MIHF_IdParser );
}; };
...@@ -55,9 +55,9 @@ namespace senf { ...@@ -55,9 +55,9 @@ namespace senf {
SENF_PARSER_SKIP_BITS ( 1 ); SENF_PARSER_SKIP_BITS ( 1 );
// MIH message ID (MID) // MIH message ID (MID)
SENF_PARSER_BITFIELD ( sid, 4, unsigned ); SENF_PARSER_BITFIELD ( sid, 4, unsigned );
SENF_PARSER_BITFIELD ( opcode, 2, unsigned ); SENF_PARSER_BITFIELD ( opcode, 2, unsigned );
SENF_PARSER_BITFIELD ( aid, 10, unsigned ); SENF_PARSER_BITFIELD ( aid, 10, unsigned );
SENF_PARSER_SKIP_BITS ( 4 ); SENF_PARSER_SKIP_BITS ( 4 );
SENF_PARSER_BITFIELD ( transactionId, 12, unsigned ); SENF_PARSER_BITFIELD ( transactionId, 12, unsigned );
...@@ -78,7 +78,7 @@ namespace senf { ...@@ -78,7 +78,7 @@ namespace senf {
SENF_PARSER_INIT() { SENF_PARSER_INIT() {
version_() = 1; version_() = 1;
source_type() = 1; source_type() = 1;
destination_type() = 1; destination_type() = 2;
} }
}; };
......
...@@ -47,52 +47,46 @@ prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::v ...@@ -47,52 +47,46 @@ prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::v
case 5: case 5:
return parse<UInt32Parser>( 1 ).value(); return parse<UInt32Parser>( 1 ).value();
default: default:
throw(UnsuportedTLVPacketException()); throw(TLVLengthException());
}; };
} }
prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v) prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v)
{ {
SafePacketParserWrapper<DynamicTLVLengthParser> safeThis (*this); switch (bytes() ) {
if (v < 128u) { case 1:
if (bytes() != 1) if (v > 127) throw( TLVLengthException());
resize(1, safeThis); fixed_length_field() = v;
safeThis->fixed_length_field() = v;
return; return;
} case 2:
if (v <= UInt8Parser::max_value) { if (v > UInt8Parser::max_value) throw( TLVLengthException());
if (bytes() != 2) parse<UInt8Parser>(1) = v;
resize(2, safeThis);
safeThis->parse<UInt8Parser>(1) = v;
return; return;
} case 3:
if (v <= UInt16Parser::max_value) { if (v > UInt16Parser::max_value) throw( TLVLengthException());
if (bytes() != 3) parse<UInt16Parser>(1) = v;
resize(3, safeThis);
safeThis->parse<UInt16Parser>(1) = v;
return; return;
} case 4:
if (v <= UInt24Parser::max_value) { if (v > UInt24Parser::max_value) throw( TLVLengthException());
if (bytes() != 4) parse<UInt24Parser>(1) = v;
resize(4, safeThis);
safeThis->parse<UInt24Parser>(1) = v;
return; return;
} case 5:
if (v <= UInt32Parser::max_value) { parse<UInt32Parser>(1) = v;
if (bytes() != 5)
resize(5, safeThis);
safeThis->parse<UInt32Parser>(1) = v;
return; return;
} default:
throw(UnsuportedTLVPacketException()); throw( TLVLengthException());
};
} }
prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::operator= (value_type other) prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::operator= (value_type other)
{ {
value(other); value(other);
return *this; return *this;
} }
prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const
{ {
if ( extended_length_flag() ) if ( extended_length_flag() )
...@@ -101,32 +95,91 @@ prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::by ...@@ -101,32 +95,91 @@ prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::by
return 1; return 1;
} }
prefix_ void senf::DynamicTLVLengthParser::init() const prefix_ void senf::DynamicTLVLengthParser::init() const
{ {
defaultInit(); 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"; value_type v = value();
if (size > 1) { size_type b = bytes();
safeThis->extended_length_flag() = true; if (v <= 127) {
safeThis->fixed_length_field() = size - 1; if (b != 1) resize(1);
} else { return;
safeThis->extended_length_flag() = false;
} }
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()); 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) if (current_size > size)
data().erase( si, boost::next(si, current_size-size)); data().erase( si, boost::next(si, current_size-size));
else else
data().insert( si, size-current_size, 0); 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) prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os)
{ {
boost::io::ios_all_saver ias(os); boost::io::ios_all_saver ias(os);
...@@ -136,30 +189,11 @@ prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os) ...@@ -136,30 +189,11 @@ prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os)
<< " length: " << unsigned( p->length()) << "\n"; << " length: " << unsigned( p->length()) << "\n";
} }
//prefix_ void senf::GenericTLVPacketType::finalize(packet p)
//{ prefix_ void senf::GenericTLVPacketType::finalize(packet p)
// try { {
// PacketData::size_type size = p.next().data().size(); p->shrinkLength();
// 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() );
//}
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
......
// $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_
// 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:
...@@ -35,22 +35,12 @@ ...@@ -35,22 +35,12 @@
namespace senf { namespace senf {
/** \brief xxx
struct TLVLengthException : public senf::Exception
\todo document me { TLVLengthException()
\todo add usefull exceptions strings : senf::Exception("TLVLengthException"){} };
\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
*/
class DynamicTLVLengthParser class DynamicTLVLengthParser
: public detail::packet::IntParserOps<DynamicTLVLengthParser, boost::uint32_t>, : public detail::packet::IntParserOps<DynamicTLVLengthParser, boost::uint32_t>,
public PacketParserBase public PacketParserBase
...@@ -71,51 +61,46 @@ namespace senf { ...@@ -71,51 +61,46 @@ namespace senf {
void init() const; void init() const;
# include SENF_PARSER() # include SENF_PARSER()
SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1, bool ); SENF_PARSER_PRIVATE_BITFIELD ( extended_length_flag, 1, bool );
SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 7, unsigned ); SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 7, unsigned );
private:
// typedef FlagParser < 0 > ExtendedLengthFlagParser; void resize(size_type size);
// typedef UIntFieldParser < 1, 8 > FixedLengthParser; void shrink();
//
// 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);
}; };
/** \brief parse TLVPacket Packet
class BaseTLVPacketParser : public PacketParserBase
\todo document me
\see TLVPacketType
\ingroup protocolbundle_80221
*/
struct GenericTLVPacketParser : public PacketParserBase
{ {
# include SENF_PARSER() # include SENF_PARSER()
SENF_PARSER_FIELD ( type, UInt8Parser );
SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser );
SENF_PARSER_FINALIZE ( BaseTLVPacketParser );
SENF_PARSER_FIELD ( type, UInt8Parser ); void maxLengthValue(DynamicTLVLengthParser::value_type v) const;
SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser ); void shrinkLength() { length_().shrink(); };
SENF_PARSER_VECTOR ( value, bytes(length), UInt8Parser );
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 struct GenericTLVPacketType
: public PacketTypeBase, : public PacketTypeBase,
public PacketTypeMixin<GenericTLVPacketType> public PacketTypeMixin<GenericTLVPacketType>
...@@ -124,12 +109,11 @@ namespace senf { ...@@ -124,12 +109,11 @@ namespace senf {
typedef ConcretePacket<GenericTLVPacketType> packet; typedef ConcretePacket<GenericTLVPacketType> packet;
typedef GenericTLVPacketParser parser; typedef GenericTLVPacketParser parser;
// static optional_range nextPacketRange(packet p);
using mixin::nextPacketRange; using mixin::nextPacketRange;
using mixin::init; using mixin::init;
using mixin::initSize; using mixin::initSize;
// static void finalize(packet p); static void finalize(packet p);
static void dump(packet p, std::ostream & os); static void dump(packet p, std::ostream & os);
}; };
...@@ -139,7 +123,7 @@ namespace senf { ...@@ -139,7 +123,7 @@ namespace senf {
///////////////////////////////hh.e//////////////////////////////////////// ///////////////////////////////hh.e////////////////////////////////////////
//#include "TLVPacket.cci" //#include "TLVPacket.cci"
//#include "TLVPacket.ct" #include "TLVPacket.ct"
//#include "TLVPacket.cti" //#include "TLVPacket.cti"
#endif #endif
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include "../../Utils/auto_unit_test.hh" #include "../../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
#include <vector>
#define prefix_ #define prefix_
///////////////////////////////cc.p//////////////////////////////////////// ///////////////////////////////cc.p////////////////////////////////////////
...@@ -39,22 +38,16 @@ ...@@ -39,22 +38,16 @@
using namespace senf; 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->type(), type );
BOOST_CHECK_EQUAL( tlvPacket->length(), length ); BOOST_CHECK_EQUAL( tlvPacket->length(), length );
BOOST_CHECK_EQUAL( tlvPacket->value().size(), length );
BOOST_CHECK_EQUAL( tlvPacket->value().size(), length); senf::PacketData::iterator dataIterator (tlvPacket->value().begin());
for (int i=0, j=tlvPacket->value().size(); i<j; i++) for (unsigned i=0; i<length; i++) {
BOOST_CHECK_EQUAL( tlvPacket->value()[i], i ); BOOST_CHECK_EQUAL( *dataIterator, i );
} dataIterator++;
}
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 );
} }
...@@ -69,6 +62,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_simple_length) ...@@ -69,6 +62,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_simple_length)
check_TLVPacket( tlvPacket, 0x01, 0x0Au ); check_TLVPacket( tlvPacket, 0x01, 0x0Au );
} }
BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length) BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length)
{ {
unsigned char data[] = { unsigned char data[] = {
...@@ -84,16 +78,25 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length) ...@@ -84,16 +78,25 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length)
BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_simple_length) 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()); GenericTLVPacket tlvPacket (GenericTLVPacket::create());
tlvPacket->type() = 42u; tlvPacket->type() = 42u;
for (uint8_t i=0; i<10; i++) tlvPacket->value( value);
tlvPacket->value().push_back( i); tlvPacket.finalizeThis();
tlvPacket.finalizeAll();
check_TLVPacket( tlvPacket, 42u, 0x0Au ); 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) BOOST_AUTO_UNIT_TEST(TLVPacket_create_packet_with_extended_length)
{ {
GenericTLVPacket tlvPacket (GenericTLVPacket::create()); GenericTLVPacket tlvPacket (GenericTLVPacket::create());
...@@ -203,8 +206,7 @@ BOOST_AUTO_UNIT_TEST(TLVFixPacket_create_invalid_packet) ...@@ -203,8 +206,7 @@ BOOST_AUTO_UNIT_TEST(TLVFixPacket_create_invalid_packet)
test_invalid_TLVFixPacket_creating<TestTLVPacket24>( UInt24Parser::max_value); test_invalid_TLVFixPacket_creating<TestTLVPacket24>( UInt24Parser::max_value);
} }
*/ #endif
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_ #undef prefix_
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment