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

Packets/80221Bundle: fix for TLVs to support latest version of the standard :-/

parent 1e1ed908
No related branches found
No related tags found
No related merge requests found
...@@ -46,7 +46,7 @@ prefix_ void senf::MIHFId_TLVParser::setString(std::string const &id) ...@@ -46,7 +46,7 @@ prefix_ void senf::MIHFId_TLVParser::setString(std::string const &id)
// the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21) // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
if (str_size > 253) if (str_size > 253)
throw std::length_error("maximum length of a MIHF_ID is 253 octets"); throw std::length_error("maximum length of a MIHF_ID is 253 octets");
safe_data_iterator si = resizeValue( str_size); safe_data_iterator si = resizeValueField( str_size);
std::copy( id.begin(), id.end(), si); std::copy( id.begin(), id.end(), si);
} }
...@@ -59,7 +59,7 @@ prefix_ senf::MACAddress senf::MIHFId_TLVParser::asMACAddress() ...@@ -59,7 +59,7 @@ prefix_ senf::MACAddress senf::MIHFId_TLVParser::asMACAddress()
prefix_ void senf::MIHFId_TLVParser::setMACAddress(senf::MACAddress const &mac) prefix_ void senf::MIHFId_TLVParser::setMACAddress(senf::MACAddress const &mac)
{ {
safe_data_iterator si = resizeValue(12); safe_data_iterator si = resizeValueField(12);
std::copy( mac.begin(), mac.end(), getNAIEncodedOutputIterator(si)); std::copy( mac.begin(), mac.end(), getNAIEncodedOutputIterator(si));
} }
...@@ -73,7 +73,7 @@ prefix_ senf::INet4Address senf::MIHFId_TLVParser::asINet4Address() ...@@ -73,7 +73,7 @@ prefix_ senf::INet4Address senf::MIHFId_TLVParser::asINet4Address()
prefix_ void senf::MIHFId_TLVParser::setINet4Address(senf::INet4Address const &addr) prefix_ void senf::MIHFId_TLVParser::setINet4Address(senf::INet4Address const &addr)
{ {
safe_data_iterator si = resizeValue(8); safe_data_iterator si = resizeValueField(8);
std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si)); std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
} }
...@@ -86,7 +86,7 @@ prefix_ senf::INet6Address senf::MIHFId_TLVParser::asINet6Address() ...@@ -86,7 +86,7 @@ prefix_ senf::INet6Address senf::MIHFId_TLVParser::asINet6Address()
prefix_ void senf::MIHFId_TLVParser::setINet6Address(senf::INet6Address const &addr) prefix_ void senf::MIHFId_TLVParser::setINet6Address(senf::INet6Address const &addr)
{ {
safe_data_iterator si = resizeValue(32); safe_data_iterator si = resizeValueField(32);
std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si)); std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
} }
......
...@@ -46,11 +46,9 @@ namespace senf { ...@@ -46,11 +46,9 @@ namespace senf {
typedef boost::uint16_t key_t; typedef boost::uint16_t key_t;
}; };
# define SENF_MIH_PACKET_REGISTRY_REGISTER( sid, opcode, aid, type ) \ # define SENF_MIH_PACKET_REGISTRY_REGISTER( packetType ) \
SENF_PACKET_REGISTRY_REGISTER( \ SENF_PACKET_REGISTRY_REGISTER( \
senf::MIHMessageRegistry, \ senf::MIHMessageRegistry, packetType::type::MESSAGE_ID, packetType )
boost::uint16_t((boost::uint16_t(sid) << 12) | (boost::uint16_t(opcode) << 10) | aid), \
type )
/** \brief Parse a MIHF_ID /** \brief Parse a MIHF_ID
...@@ -138,7 +136,8 @@ namespace senf { ...@@ -138,7 +136,8 @@ namespace senf {
SENF_PARSER_SKIP_BITS ( 4 ); SENF_PARSER_SKIP_BITS ( 4 );
SENF_PARSER_BITFIELD ( transactionId, 12, unsigned ); SENF_PARSER_BITFIELD ( transactionId, 12, unsigned );
SENF_PARSER_FIELD_RO ( payloadLength, UInt16Parser ); SENF_PARSER_FIELD_RO ( payloadLength, UInt16Parser );
SENF_PARSER_GOTO_OFFSET( 8, 8); // just to limit the offset calculation
// Source MIHF Id // Source MIHF Id
SENF_PARSER_FIELD ( src_mihfId, MIHFId_TLVParser ); SENF_PARSER_FIELD ( src_mihfId, MIHFId_TLVParser );
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define prefix_ #define prefix_
///////////////////////////////cc.p//////////////////////////////////////// ///////////////////////////////cc.p////////////////////////////////////////
prefix_ senf::safe_data_iterator senf::BaseTLVPacketParser::resizeValue( prefix_ senf::safe_data_iterator senf::BaseTLVPacketParser::resizeValueField(
DynamicTLVLengthParser::value_type size) DynamicTLVLengthParser::value_type size)
{ {
DynamicTLVLengthParser::value_type current_length ( length()); DynamicTLVLengthParser::value_type current_length ( length());
...@@ -52,15 +52,15 @@ prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::v ...@@ -52,15 +52,15 @@ prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::v
{ {
switch (bytes() ) { switch (bytes() ) {
case 1: case 1:
return fixed_length_field().value(); return length_field().value();
case 2: case 2:
return parse<UInt8Parser>( 1 ).value(); return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
case 3: case 3:
return parse<UInt16Parser>( 1 ).value(); return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
case 4: case 4:
return parse<UInt24Parser>( 1 ).value(); return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
case 5: case 5:
return parse<UInt32Parser>( 1 ).value(); return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
default: default:
throw(TLVLengthException()); throw(TLVLengthException());
}; };
...@@ -71,27 +71,28 @@ prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v) ...@@ -71,27 +71,28 @@ prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v)
{ {
switch (bytes() ) { switch (bytes() ) {
case 1: case 1:
if (v > 127) throw( TLVLengthException()); if (v > 128) throw( TLVLengthException());
fixed_length_field() = v; fixed_length_field() = v;
return; return;
case 2: case 2:
if (v > UInt8Parser::max_value) throw( TLVLengthException()); if (v > UInt8Parser::max_value + 128) throw( TLVLengthException());
parse<UInt8Parser>(1) = v; parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
return; break;
case 3: case 3:
if (v > UInt16Parser::max_value) throw( TLVLengthException()); if (v > UInt16Parser::max_value + 128) throw( TLVLengthException());
parse<UInt16Parser>(1) = v; parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
return; break;;
case 4: case 4:
if (v > UInt24Parser::max_value) throw( TLVLengthException()); if (v > UInt24Parser::max_value + 128) throw( TLVLengthException());
parse<UInt24Parser>(1) = v; parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
return; break;
case 5: case 5:
parse<UInt32Parser>(1) = v; parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
return; break;
default: default:
throw( TLVLengthException()); throw( TLVLengthException());
}; };
underflow_flag() = v < 128;
} }
...@@ -102,15 +103,6 @@ prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::opera ...@@ -102,15 +103,6 @@ prefix_ senf::DynamicTLVLengthParser const & senf::DynamicTLVLengthParser::opera
} }
prefix_ senf::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const
{
if ( extended_length_flag() )
return 1 + fixed_length_field();
else
return 1;
}
prefix_ void senf::DynamicTLVLengthParser::init() const prefix_ void senf::DynamicTLVLengthParser::init() const
{ {
defaultInit(); defaultInit();
...@@ -122,19 +114,19 @@ prefix_ void senf::DynamicTLVLengthParser::shrink() ...@@ -122,19 +114,19 @@ prefix_ void senf::DynamicTLVLengthParser::shrink()
{ {
value_type v = value(); value_type v = value();
size_type b = bytes(); size_type b = bytes();
if (v <= 127) { if (v <= 128) {
if (b != 1) resize(1); if (b != 1) resize(1);
return; return;
} }
if (v <= UInt8Parser::max_value) { if (v <= UInt8Parser::max_value + 128) {
if (b != 2) resize(2); if (b != 2) resize(2);
return; return;
} }
if (v <= UInt16Parser::max_value) { if (v <= UInt16Parser::max_value + 128) {
if (b != 3) resize(3); if (b != 3) resize(3);
return; return;
} }
if (v <= UInt24Parser::max_value) { if (v <= UInt24Parser::max_value + 128 ){
if (b != 4) resize(4); if (b != 4) resize(4);
return; return;
} }
...@@ -144,18 +136,18 @@ prefix_ void senf::DynamicTLVLengthParser::shrink() ...@@ -144,18 +136,18 @@ prefix_ void senf::DynamicTLVLengthParser::shrink()
prefix_ void senf::DynamicTLVLengthParser:: maxValue(DynamicTLVLengthParser::value_type v) prefix_ void senf::DynamicTLVLengthParser:: maxValue(DynamicTLVLengthParser::value_type v)
{ {
if (v <= 127) if (v <= 128)
return; return;
size_type b = bytes(); size_type b = bytes();
if (v <= UInt8Parser::max_value) { if (v <= UInt8Parser::max_value + 128) {
if (b < 2) resize(2); if (b < 2) resize(2);
return; return;
} }
if (v <= UInt16Parser::max_value) { if (v <= UInt16Parser::max_value + 128) {
if (b < 3) resize(3); if (b < 3) resize(3);
return; return;
} }
if (v <= UInt24Parser::max_value) { if (v <= UInt24Parser::max_value + 128) {
if (b < 4) resize(4); if (b < 4) resize(4);
return; return;
} }
......
// $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::DynamicTLVLengthParser::size_type senf::DynamicTLVLengthParser::bytes() const
{
return 1 + ( length_field()<=128 ? 0 : fixed_length_field());
}
///////////////////////////////cci.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:
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
template <class ForwardReadableRange> template <class ForwardReadableRange>
prefix_ void senf::GenericTLVPacketParser::value(ForwardReadableRange const &range) prefix_ void senf::GenericTLVPacketParser::value(ForwardReadableRange const &range)
{ {
safe_data_iterator si = resizeValue( boost::size(range) ); safe_data_iterator si = resizeValueField( boost::size(range) );
std::copy( boost::begin(range), boost::end(range), si); std::copy( boost::begin(range), boost::end(range), si);
} }
......
...@@ -62,8 +62,11 @@ namespace senf { ...@@ -62,8 +62,11 @@ namespace senf {
void init() const; void init() const;
# include SENF_PARSER() # include SENF_PARSER()
SENF_PARSER_PRIVATE_FIELD ( length_field, UInt8Parser );
SENF_PARSER_GOTO( length_field );
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 ( underflow_flag, 1, bool );
SENF_PARSER_PRIVATE_BITFIELD ( fixed_length_field, 6, unsigned );
void shrink(); void shrink();
void maxValue(DynamicTLVLengthParser::value_type v); void maxValue(DynamicTLVLengthParser::value_type v);
...@@ -138,7 +141,7 @@ namespace senf { ...@@ -138,7 +141,7 @@ namespace senf {
/// set length field to given value /// set length field to given value
void length(DynamicTLVLengthParser::value_type &v) { length_() = v; }; void length(DynamicTLVLengthParser::value_type &v) { length_() = v; };
/// resize the Packet after the length field to given size /// resize the Packet after the length field to given size
senf::safe_data_iterator resizeValue(DynamicTLVLengthParser::value_type size); senf::safe_data_iterator resizeValueField(DynamicTLVLengthParser::value_type size);
}; };
...@@ -200,7 +203,7 @@ namespace senf { ...@@ -200,7 +203,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
......
...@@ -40,18 +40,18 @@ using namespace senf; ...@@ -40,18 +40,18 @@ using namespace senf;
namespace { namespace {
void check_TLVPacket(GenericTLVPacket &tlvPacket, boost::uint8_t type, boost::uint32_t length) #define CHECK_TLVPacket(tlvPacket, ptype, plength) \
{ { \
BOOST_CHECK_EQUAL( tlvPacket->type(), type ); BOOST_CHECK_EQUAL( tlvPacket->type(), ptype ); \
BOOST_CHECK_EQUAL( tlvPacket->length(), length ); BOOST_CHECK_EQUAL( tlvPacket->length(), plength ); \
BOOST_CHECK_EQUAL( tlvPacket->value().size(), int(length) ); BOOST_CHECK_EQUAL( tlvPacket->value().size(), int(plength) ); \
std::ostringstream oss (std::ostringstream::out); std::ostringstream oss (std::ostringstream::out); \
SENF_CHECK_NO_THROW( tlvPacket.dump( oss)); SENF_CHECK_NO_THROW( tlvPacket.dump( oss)); \
senf::PacketData::iterator dataIterator (tlvPacket->value().begin()); senf::PacketData::iterator dataIterator (tlvPacket->value().begin()); \
for (unsigned i=0; i<length; i++) { for (unsigned i=0; i<plength; i++) { \
BOOST_CHECK_EQUAL( *dataIterator, i ); BOOST_CHECK_EQUAL( *dataIterator, i ); \
dataIterator++; dataIterator++; \
} } \
} }
} }
...@@ -64,7 +64,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_simple_length) ...@@ -64,7 +64,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_simple_length)
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
}; };
GenericTLVPacket tlvPacket (GenericTLVPacket::create(data)); GenericTLVPacket tlvPacket (GenericTLVPacket::create(data));
check_TLVPacket( tlvPacket, 0x01, 0x0Au ); CHECK_TLVPacket( tlvPacket, 0x01, 0x0Au );
} }
...@@ -73,11 +73,24 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length) ...@@ -73,11 +73,24 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_parse_packet_with_extended_length)
unsigned char data[] = { unsigned char data[] = {
0x01, // type 0x01, // type
0x81, // first and last bit set => one byte length following 0x81, // first and last bit set => one byte length following
0x0A, // length (10 bytes value) 0x0A, // length (10 = 138 bytes value follows)
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81,
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89
}; };
GenericTLVPacket tlvPacket (GenericTLVPacket::create(data)); GenericTLVPacket tlvPacket (GenericTLVPacket::create(data));
check_TLVPacket( tlvPacket, 0x01, 0x0Au ); CHECK_TLVPacket( tlvPacket, 0x01, 0x8au );
} }
...@@ -91,7 +104,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_simple_length) ...@@ -91,7 +104,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_simple_length)
tlvPacket->value( value); tlvPacket->value( value);
tlvPacket.finalizeThis(); tlvPacket.finalizeThis();
check_TLVPacket( tlvPacket, 42u, 0x0Au ); CHECK_TLVPacket( tlvPacket, 42u, 0x0Au );
unsigned char data[] = { unsigned char data[] = {
0x2a, // type 0x2a, // type
...@@ -109,16 +122,16 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_extended_length) ...@@ -109,16 +122,16 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_extended_length)
value[i] = i; value[i] = i;
GenericTLVPacket tlvPacket (GenericTLVPacket::create()); GenericTLVPacket tlvPacket (GenericTLVPacket::create());
tlvPacket->maxLengthValue( DynamicTLVLengthParser::max_value); tlvPacket->maxLengthValue( DynamicTLVLengthParser::max_value);
tlvPacket->type() = 42u; SENF_CHECK_NO_THROW( tlvPacket->type() = 42u);
tlvPacket->value( value); SENF_CHECK_NO_THROW( tlvPacket->value( value));
tlvPacket.finalizeThis(); SENF_CHECK_NO_THROW( tlvPacket.finalizeThis());
check_TLVPacket( tlvPacket, 42u, sizeof(value) ); CHECK_TLVPacket( tlvPacket, 42u, sizeof(value) );
unsigned char data[] = { unsigned char data[] = {
0x2a, // type 0x2a, // type
0x81, // first and last bit set => one byte length following 0x81, // first and last bit set => one byte length following
0xff, // length (255 bytes value) 0x7f, // length (127 = 255 bytes value)
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // first bytes of value 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // first bytes of value
}; };
BOOST_CHECK( equal( BOOST_CHECK( equal(
...@@ -142,7 +155,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_invalid_packet) ...@@ -142,7 +155,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_invalid_packet)
tlvPacket->maxLengthValue( sizeof(value)); tlvPacket->maxLengthValue( sizeof(value));
tlvPacket->value( value); tlvPacket->value( value);
tlvPacket.finalizeThis(); tlvPacket.finalizeThis();
check_TLVPacket( tlvPacket, 42u, sizeof(value) ); CHECK_TLVPacket( tlvPacket, 42u, sizeof(value) );
} }
......
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