From: tho Date: Thu, 9 Jul 2009 16:23:38 +0000 (+0000) Subject: Packets/80221Bundle: fix for TLVs to support latest version of the standard :-/ X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=ef7165e64d4b315ed1ca9604ee9114887938f0ee;p=senf.git Packets/80221Bundle: fix for TLVs to support latest version of the standard :-/ git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1265 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/80221Bundle/MIHPacket.cc b/Packets/80221Bundle/MIHPacket.cc index e221b59..d4e2e61 100644 --- a/Packets/80221Bundle/MIHPacket.cc +++ b/Packets/80221Bundle/MIHPacket.cc @@ -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) if (str_size > 253) 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); } @@ -59,7 +59,7 @@ prefix_ senf::MACAddress senf::MIHFId_TLVParser::asMACAddress() 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)); } @@ -73,7 +73,7 @@ prefix_ senf::INet4Address senf::MIHFId_TLVParser::asINet4Address() 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)); } @@ -86,7 +86,7 @@ prefix_ senf::INet6Address senf::MIHFId_TLVParser::asINet6Address() 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)); } diff --git a/Packets/80221Bundle/MIHPacket.hh b/Packets/80221Bundle/MIHPacket.hh index 90765c3..b5c7f94 100644 --- a/Packets/80221Bundle/MIHPacket.hh +++ b/Packets/80221Bundle/MIHPacket.hh @@ -46,11 +46,9 @@ namespace senf { 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::MIHMessageRegistry, \ - boost::uint16_t((boost::uint16_t(sid) << 12) | (boost::uint16_t(opcode) << 10) | aid), \ - type ) + senf::MIHMessageRegistry, packetType::type::MESSAGE_ID, packetType ) /** \brief Parse a MIHF_ID @@ -138,7 +136,8 @@ namespace senf { SENF_PARSER_SKIP_BITS ( 4 ); SENF_PARSER_BITFIELD ( transactionId, 12, unsigned ); SENF_PARSER_FIELD_RO ( payloadLength, UInt16Parser ); - + + SENF_PARSER_GOTO_OFFSET( 8, 8); // just to limit the offset calculation // Source MIHF Id SENF_PARSER_FIELD ( src_mihfId, MIHFId_TLVParser ); diff --git a/Packets/80221Bundle/TLVPacket.cc b/Packets/80221Bundle/TLVPacket.cc index 12d9bfd..0b94056 100644 --- a/Packets/80221Bundle/TLVPacket.cc +++ b/Packets/80221Bundle/TLVPacket.cc @@ -33,7 +33,7 @@ #define prefix_ ///////////////////////////////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 current_length ( length()); @@ -52,15 +52,15 @@ prefix_ senf::DynamicTLVLengthParser::value_type senf::DynamicTLVLengthParser::v { switch (bytes() ) { case 1: - return fixed_length_field().value(); + return length_field().value(); case 2: - return parse( 1 ).value(); + return parse( 1 ).value() + (underflow_flag() ? 0 : 128u); case 3: - return parse( 1 ).value(); + return parse( 1 ).value() + (underflow_flag() ? 0 : 128u); case 4: - return parse( 1 ).value(); + return parse( 1 ).value() + (underflow_flag() ? 0 : 128u); case 5: - return parse( 1 ).value(); + return parse( 1 ).value() + (underflow_flag() ? 0 : 128u); default: throw(TLVLengthException()); }; @@ -71,27 +71,28 @@ prefix_ void senf::DynamicTLVLengthParser::value(value_type const & v) { switch (bytes() ) { case 1: - if (v > 127) throw( TLVLengthException()); + if (v > 128) throw( TLVLengthException()); fixed_length_field() = v; return; case 2: - if (v > UInt8Parser::max_value) throw( TLVLengthException()); - parse(1) = v; - return; + if (v > UInt8Parser::max_value + 128) throw( TLVLengthException()); + parse(1) = v - (v>128 ? 128 : 0); + break; case 3: - if (v > UInt16Parser::max_value) throw( TLVLengthException()); - parse(1) = v; - return; + if (v > UInt16Parser::max_value + 128) throw( TLVLengthException()); + parse(1) = v - (v>128 ? 128 : 0); + break;; case 4: - if (v > UInt24Parser::max_value) throw( TLVLengthException()); - parse(1) = v; - return; + if (v > UInt24Parser::max_value + 128) throw( TLVLengthException()); + parse(1) = v - (v>128 ? 128 : 0); + break; case 5: - parse(1) = v; - return; + parse(1) = v - (v>128 ? 128 : 0); + break; default: throw( TLVLengthException()); }; + underflow_flag() = v < 128; } @@ -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 { defaultInit(); @@ -122,19 +114,19 @@ prefix_ void senf::DynamicTLVLengthParser::shrink() { value_type v = value(); size_type b = bytes(); - if (v <= 127) { + if (v <= 128) { if (b != 1) resize(1); return; } - if (v <= UInt8Parser::max_value) { + if (v <= UInt8Parser::max_value + 128) { if (b != 2) resize(2); return; } - if (v <= UInt16Parser::max_value) { + if (v <= UInt16Parser::max_value + 128) { if (b != 3) resize(3); return; } - if (v <= UInt24Parser::max_value) { + if (v <= UInt24Parser::max_value + 128 ){ if (b != 4) resize(4); return; } @@ -144,18 +136,18 @@ prefix_ void senf::DynamicTLVLengthParser::shrink() prefix_ void senf::DynamicTLVLengthParser:: maxValue(DynamicTLVLengthParser::value_type v) { - if (v <= 127) + if (v <= 128) return; size_type b = bytes(); - if (v <= UInt8Parser::max_value) { + if (v <= UInt8Parser::max_value + 128) { if (b < 2) resize(2); return; } - if (v <= UInt16Parser::max_value) { + if (v <= UInt16Parser::max_value + 128) { if (b < 3) resize(3); return; } - if (v <= UInt24Parser::max_value) { + if (v <= UInt24Parser::max_value + 128) { if (b < 4) resize(4); return; } diff --git a/Packets/80221Bundle/TLVPacket.cci b/Packets/80221Bundle/TLVPacket.cci new file mode 100644 index 0000000..1ca1885 --- /dev/null +++ b/Packets/80221Bundle/TLVPacket.cci @@ -0,0 +1,51 @@ +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Thorsten Horstmann +// +// 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: diff --git a/Packets/80221Bundle/TLVPacket.ct b/Packets/80221Bundle/TLVPacket.ct index efae0f6..41276ad 100644 --- a/Packets/80221Bundle/TLVPacket.ct +++ b/Packets/80221Bundle/TLVPacket.ct @@ -33,7 +33,7 @@ template 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); } diff --git a/Packets/80221Bundle/TLVPacket.hh b/Packets/80221Bundle/TLVPacket.hh index 4c1a588..ac2ece4 100644 --- a/Packets/80221Bundle/TLVPacket.hh +++ b/Packets/80221Bundle/TLVPacket.hh @@ -62,8 +62,11 @@ namespace senf { void init() const; # 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 ( 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 maxValue(DynamicTLVLengthParser::value_type v); @@ -138,7 +141,7 @@ namespace senf { /// set length field to given value void length(DynamicTLVLengthParser::value_type &v) { length_() = v; }; /// 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 { ///////////////////////////////hh.e//////////////////////////////////////// -//#include "TLVPacket.cci" +#include "TLVPacket.cci" #include "TLVPacket.ct" //#include "TLVPacket.cti" #endif diff --git a/Packets/80221Bundle/TLVPacket.test.cc b/Packets/80221Bundle/TLVPacket.test.cc index 8dc8df2..4e5af46 100644 --- a/Packets/80221Bundle/TLVPacket.test.cc +++ b/Packets/80221Bundle/TLVPacket.test.cc @@ -40,18 +40,18 @@ using namespace senf; namespace { -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(), int(length) ); - std::ostringstream oss (std::ostringstream::out); - SENF_CHECK_NO_THROW( tlvPacket.dump( oss)); - senf::PacketData::iterator dataIterator (tlvPacket->value().begin()); - for (unsigned i=0; itype(), ptype ); \ + BOOST_CHECK_EQUAL( tlvPacket->length(), plength ); \ + BOOST_CHECK_EQUAL( tlvPacket->value().size(), int(plength) ); \ + std::ostringstream oss (std::ostringstream::out); \ + SENF_CHECK_NO_THROW( tlvPacket.dump( oss)); \ + senf::PacketData::iterator dataIterator (tlvPacket->value().begin()); \ + for (unsigned i=0; i one byte length following - 0x0A, // length (10 bytes value) - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value + 0x0A, // length (10 = 138 bytes value follows) + 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)); - check_TLVPacket( tlvPacket, 0x01, 0x0Au ); + CHECK_TLVPacket( tlvPacket, 0x01, 0x8au ); } @@ -91,7 +104,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_simple_length) tlvPacket->value( value); tlvPacket.finalizeThis(); - check_TLVPacket( tlvPacket, 42u, 0x0Au ); + CHECK_TLVPacket( tlvPacket, 42u, 0x0Au ); unsigned char data[] = { 0x2a, // type @@ -109,16 +122,16 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_packet_with_extended_length) value[i] = i; GenericTLVPacket tlvPacket (GenericTLVPacket::create()); tlvPacket->maxLengthValue( DynamicTLVLengthParser::max_value); - tlvPacket->type() = 42u; - tlvPacket->value( value); - tlvPacket.finalizeThis(); + SENF_CHECK_NO_THROW( tlvPacket->type() = 42u); + SENF_CHECK_NO_THROW( tlvPacket->value( value)); + SENF_CHECK_NO_THROW( tlvPacket.finalizeThis()); - check_TLVPacket( tlvPacket, 42u, sizeof(value) ); + CHECK_TLVPacket( tlvPacket, 42u, sizeof(value) ); unsigned char data[] = { 0x2a, // type 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 }; BOOST_CHECK( equal( @@ -142,7 +155,7 @@ BOOST_AUTO_UNIT_TEST(GenericTLVPacket_create_invalid_packet) tlvPacket->maxLengthValue( sizeof(value)); tlvPacket->value( value); tlvPacket.finalizeThis(); - check_TLVPacket( tlvPacket, 42u, sizeof(value) ); + CHECK_TLVPacket( tlvPacket, 42u, sizeof(value) ); }