Skip to content
Snippets Groups Projects
Commit 8304a209 authored by tho's avatar tho
Browse files

more work on TLV & MIH Packet

parent de9da75d
No related branches found
No related tags found
No related merge requests found
......@@ -27,7 +27,6 @@
//#include "MIHPacket.ih"
// Custom includes
#include "MIHPacket.hh"
#include "../../Packets/Packets.hh"
#include <boost/io/ios_state.hpp>
......
......@@ -28,34 +28,58 @@
// Custom includes
#include "../../Packets/Packets.hh"
#include "TLVPacket.hh"
//#include "MIHPacket.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
struct MIHF_IdParser : public senf::PacketParserBase
{
# include SENF_FIXED_PARSER()
SENF_PARSER_FINALIZE ( MIHF_IdParser );
};
struct MIHPacketParser : public senf::PacketParserBase
{
# include SENF_PARSER()
SENF_PARSER_BITFIELD ( version, 4, unsigned );
SENF_PARSER_BITFIELD ( ackRequest, 1, bool );
SENF_PARSER_BITFIELD ( ackResponse, 1, bool );
SENF_PARSER_BITFIELD ( uir, 1, bool );
SENF_PARSER_BITFIELD ( moreFragment, 1, bool );
SENF_PARSER_BITFIELD ( fragmentNr, 7, unsigned );
SENF_PARSER_SKIP_BITS ( 1 );
SENF_PARSER_BITFIELD_RO ( version, 4, unsigned );
SENF_PARSER_BITFIELD ( ackRequest, 1, bool );
SENF_PARSER_BITFIELD ( ackResponse, 1, bool );
SENF_PARSER_BITFIELD ( uir, 1, bool );
SENF_PARSER_BITFIELD ( moreFragment, 1, bool );
SENF_PARSER_BITFIELD ( fragmentNr, 7, unsigned );
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_FIELD_RO ( payloadLength, UInt16Parser );
// Source MIHF Id
SENF_PARSER_PRIVATE_FIELD ( source_type, UInt8Parser );
SENF_PARSER_PRIVATE_FIELD ( source_length, DynamicTLVLengthParser );
SENF_PARSER_FIELD ( source_mihf_id, MIHF_IdParser );
// Destination MIHF Id
SENF_PARSER_PRIVATE_FIELD ( destination_type, UInt8Parser );
SENF_PARSER_PRIVATE_FIELD ( destination_length, DynamicTLVLengthParser );
SENF_PARSER_FIELD ( destination_mihf_id, MIHF_IdParser );
SENF_PARSER_FINALIZE ( MIHPacketParser );
SENF_PARSER_INIT() {
version_() = 1;
source_type() = 1;
destination_type() = 1;
}
};
......
......@@ -53,54 +53,38 @@ prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::v
prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v)
{
if (v > 4294967295u)
throw(UnsuportedTLVPacketException());
SafePacketParserWrapper<DynamicTLVLengthParser> safeThis (*this);
if (v < 128u) {
if (bytes() != 1) {
resize(1);
safeThis->extended_length_flag() = false;
}
if (bytes() != 1)
resize(1, safeThis);
safeThis->fixed_length_field() = v;
return;
}
if (v < 256u) {
if (bytes() != 2) {
resize(2);
safeThis->extended_length_flag() = true;
safeThis->fixed_length_field() = 1;
}
if (v <= UInt8Parser::max_value) {
if (bytes() != 2)
resize(2, safeThis);
safeThis->parse<UInt8Parser>(1) = v;
return;
}
if (v < 65536u) {
if (bytes() != 3) {
resize(3);
safeThis->extended_length_flag() = true;
safeThis->fixed_length_field() = 2;
}
if (v <= UInt16Parser::max_value) {
if (bytes() != 3)
resize(3, safeThis);
safeThis->parse<UInt16Parser>(1) = v;
return;
}
if (v < 16777216u) {
if (bytes() != 4) {
resize(4);
safeThis->extended_length_flag() = true;
safeThis->fixed_length_field() = 3;
}
if (v <= UInt24Parser::max_value) {
if (bytes() != 4)
resize(4, safeThis);
safeThis->parse<UInt24Parser>(1) = v;
return;
}
if (v <= 4294967295u) {
if (bytes() != 5) {
resize(5);
safeThis->extended_length_flag() = true;
safeThis->fixed_length_field() = 4;
}
if (v <= UInt32Parser::max_value) {
if (bytes() != 5)
resize(5, safeThis);
safeThis->parse<UInt32Parser>(1) = v;
return;
}
throw(UnsuportedTLVPacketException());
}
prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::operator= (value_type other)
......@@ -123,8 +107,17 @@ prefix_ void senf::DynamicTLVLengthParser::init() const
extended_length_flag() = 0;
}
prefix_ void senf::DynamicTLVLengthParser::resize(size_type size)
prefix_ void senf::DynamicTLVLengthParser::resize(
size_type size, SafePacketParserWrapper<DynamicTLVLengthParser> &safeThis)
{
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;
}
size_type current_size (bytes());
safe_data_iterator si (data(), i());
......@@ -134,6 +127,40 @@ prefix_ void senf::DynamicTLVLengthParser::resize(size_type size)
data().insert( si, size-current_size, 0);
}
prefix_ void senf::GenericTLVPacketType::dump(packet p, std::ostream & os)
{
boost::io::ios_all_saver ias(os);
os << "GenericTLVPacket:\n"
<< std::dec
<< " type: " << unsigned( p->type()) << "\n"
<< " 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() );
//}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
......
// $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 non-inline template implementation */
//#include "TLVPacket.ih"
// Custom includes
#include "TLVPacket.hh"
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
template <class TypeParser, class LengthParser>
prefix_ void senf::TLVPacketType<TypeParser, LengthParser>::dump(packet p, std::ostream & os)
{
os << "TLVPacket:"
<< std::dec
<< " type: " << unsigned(p->type()) << "\n"
<< " length: " << unsigned(p->length()) << "\n";
}
template <class TypeParser, class LengthParser>
prefix_ void senf::TLVPacketType<TypeParser, LengthParser>::finalize(packet p)
{
try {
PacketData::size_type size = p.next().data().size();
if ( size > LengthParser::max_value )
throw(UnsuportedTLVPacketException());
p->length() = size;
}
catch (InvalidPacketChainException & ex) {
;
}
}
template <class TypeParser, class LengthParser>
prefix_ senf::PacketParserBase::size_type senf::TLVPacketType<TypeParser, LengthParser>::initSize()
{
return senf::init_bytes<TypeParser>::value + senf::init_bytes<LengthParser>::value;
}
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() );
}
///////////////////////////////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:
......@@ -40,6 +40,7 @@ namespace senf {
\todo document me
\todo add usefull exceptions strings
\ingroup protocolbundle_80221
*/
struct UnsuportedTLVPacketException : public senf::Exception
{ UnsuportedTLVPacketException()
......@@ -47,6 +48,8 @@ namespace senf {
/** \brief xxx
\todo document me
\ingroup protocolbundle_80221
*/
class DynamicTLVLengthParser
: public detail::packet::IntParserOps<DynamicTLVLengthParser, boost::uint32_t>,
......@@ -67,19 +70,25 @@ namespace senf {
size_type bytes() const;
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 );
}
// 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);
void resize(size_type size, SafePacketParserWrapper<DynamicTLVLengthParser> &safeThis);
};
/** \brief parse TLVPacket Packet
......@@ -87,46 +96,50 @@ namespace senf {
\todo document me
\see TLVPacketType
\ingroup protocolbundle_80221
*/
template <class TypeParser, class LengthParser>
struct TLVPacketParser : public PacketParserBase
struct GenericTLVPacketParser : public PacketParserBase
{
# include SENF_PARSER()
SENF_PARSER_FIELD( type, TypeParser );
SENF_PARSER_FIELD( length, LengthParser );
SENF_PARSER_FIELD ( type, UInt8Parser );
SENF_PARSER_FIELD_RO ( length, DynamicTLVLengthParser );
SENF_PARSER_VECTOR ( value, bytes(length), UInt8Parser );
SENF_PARSER_FINALIZE(TLVPacketParser);
SENF_PARSER_FINALIZE( GenericTLVPacketParser );
};
/** \brief generic TLV Packet type
\todo document me
\ingroup protocolbundle_mpegdvb
\ingroup protocolbundle_80221
*/
template <class TypeParser, class LengthParser>
struct TLVPacketType
: public PacketTypeBase
struct GenericTLVPacketType
: public PacketTypeBase,
public PacketTypeMixin<GenericTLVPacketType>
{
typedef ConcretePacket<TLVPacketType<TypeParser, LengthParser> > packet;
typedef TLVPacketParser<TypeParser, LengthParser> parser;
static optional_range nextPacketRange(packet p);
static size_type initSize();
static void finalize(packet p);
typedef PacketTypeMixin<GenericTLVPacketType> mixin;
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 dump(packet p, std::ostream & os);
};
typedef ConcretePacket<TLVPacketType<UInt32Parser, DynamicTLVLengthParser> > MIHInfoElement;
typedef ConcretePacket<GenericTLVPacketType> GenericTLVPacket;
}
///////////////////////////////hh.e////////////////////////////////////////
//#include "TLVPacket.cci"
#include "TLVPacket.ct"
//#include "TLVPacket.ct"
//#include "TLVPacket.cti"
#endif
......
......@@ -39,97 +39,70 @@
using namespace senf;
template <class TLVPacketType>
void check_TLVPacket(TLVPacketType tlvPacket, boost::uint32_t type, boost::uint32_t length)
void check_TLVPacket(GenericTLVPacket &tlvPacket, boost::uint32_t type, boost::uint32_t length)
{
BOOST_CHECK_EQUAL( tlvPacket->type(), type );
BOOST_CHECK_EQUAL( tlvPacket->length(), length );
PacketData & tlvPacket_value (tlvPacket.next().data());
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_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(TLVPacket_static)
BOOST_AUTO_UNIT_TEST(GenericTLVPacket_static)
{
// check static values:
// number of bytes to allocate for a new TLVPacket should be 5
// BOOST_CHECK_EQUAL( TLVPacket::type::initSize(), 5u );
// number of bytes to allocate for a new GenericTLVPacket should be 2
BOOST_CHECK_EQUAL( GenericTLVPacket::type::initSize(), 2u );
}
BOOST_AUTO_UNIT_TEST(TLVPacket_parse_packet_with_simple_length)
BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_simple_length)
{
typedef ConcretePacket<TLVPacketType<UInt32Parser, DynamicTLVLengthParser> > TestTLVPacket;
unsigned char data[] = {
0x01, 0x23, 0x45, 0x67, // type
0x01, // type
0x0A, // first bit not set, length=10
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value (payload)
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
};
TestTLVPacket tlvPacket (TestTLVPacket::create(data));
check_TLVPacket( tlvPacket, 0x01234567u, 0x0Au );
GenericTLVPacket tlvPacket (GenericTLVPacket::create(data));
check_TLVPacket( tlvPacket, 0x01, 0x0Au );
}
BOOST_AUTO_UNIT_TEST(TLVPacket_parse_packet_with_extended_length)
BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length)
{
typedef ConcretePacket<TLVPacketType<UInt32Parser, DynamicTLVLengthParser> > TestTLVPacket;
unsigned char data[] = {
0x01, 0x23, 0x45, 0x67, // type
0x01, // type
0x81, // first and last bit set => one byte length following
0x0A, // length (10 bytes value)
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value (payload)
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
};
TestTLVPacket tlvPacket (TestTLVPacket::create(data));
check_TLVPacket( tlvPacket, 0x01234567u, 0x0Au );
GenericTLVPacket tlvPacket (GenericTLVPacket::create(data));
check_TLVPacket( tlvPacket, 0x01, 0x0Au );
}
BOOST_AUTO_UNIT_TEST(TLVPacket_create_packet_with_simple_length)
BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_simple_length)
{
typedef ConcretePacket<TLVPacketType<UInt32Parser, DynamicTLVLengthParser> > TestTLVPacket;
std::string payload ("Hello, world!");
TestTLVPacket tlvPacket (TestTLVPacket::create());
GenericTLVPacket tlvPacket (GenericTLVPacket::create());
tlvPacket->type() = 42u;
DataPacket::createAfter( tlvPacket, payload );
for (uint8_t i=0; i<10; i++)
tlvPacket->value().push_back( i);
tlvPacket.finalizeAll();
BOOST_CHECK_EQUAL( tlvPacket->type(), 42u);
BOOST_CHECK_EQUAL( tlvPacket->length(), 13u);
PacketData & tlvPacket_value (tlvPacket.next().data());
BOOST_CHECK( equal( tlvPacket_value.begin(), tlvPacket_value.end(), payload.begin() ));
check_TLVPacket( tlvPacket, 42u, 0x0Au );
}
/**
BOOST_AUTO_UNIT_TEST(TLVPacket_create_packet_with_extended_length)
{
typedef ConcretePacket<TLVPacketType<UInt32Parser, DynamicTLVLengthParser> > TestTLVPacket;
std::string payload (
"This is a very long string with more than 127 characters to check if the TLV-Packet "
"works correctly with an extended length. That's all." );
TestTLVPacket tlvPacket (TestTLVPacket::create());
GenericTLVPacket tlvPacket (GenericTLVPacket::create());
tlvPacket->type() = 42u;
DataPacket::createAfter( tlvPacket, payload );
tlvPacket.finalizeAll();
BOOST_CHECK_EQUAL( tlvPacket->type(), 42u );
BOOST_CHECK_EQUAL( tlvPacket->length(), payload.size() );
PacketData & tlvPacket_value (tlvPacket.next().data());
BOOST_CHECK( equal( tlvPacket_value.begin(), tlvPacket_value.end(), payload.begin() ));
payload = std::string("This is a short string with less than 127 characters. That's all.");
DataPacket::createAfter( tlvPacket, payload );
for (uint8_t i=0; i<129; i++)
tlvPacket->value().push_back( i);
tlvPacket.finalizeAll();
BOOST_CHECK_EQUAL( tlvPacket->type(), 42u );
BOOST_CHECK_EQUAL( tlvPacket->length(), payload.size() );
PacketData & tlvPacket_value2 (tlvPacket.next().data());
BOOST_CHECK( equal( tlvPacket_value2.begin(), tlvPacket_value2.end(), payload.begin() ));
check_TLVPacket( tlvPacket, 42u, 129u );
}
......@@ -230,6 +203,8 @@ BOOST_AUTO_UNIT_TEST(TLVFixPacket_create_invalid_packet)
test_invalid_TLVFixPacket_creating<TestTLVPacket24>( UInt24Parser::max_value);
}
*/
///////////////////////////////cc.e////////////////////////////////////////
#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