Packets/80221Bundle: fixed error in MIHF_ID-TLV; restructured TLV finalize()
tho [Wed, 16 Dec 2009 15:20:36 +0000 (15:20 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1539 270642c3-0616-0410-b53a-bc976706d245

senf/Packets/80221Bundle/MIHPacket.cc
senf/Packets/80221Bundle/MIHPacket.test.cc
senf/Packets/80221Bundle/MIHTypes.test.cc [new file with mode: 0644]
senf/Packets/80221Bundle/TLVParser.cc
senf/Packets/80221Bundle/TLVParser.cci
senf/Packets/80221Bundle/TLVParser.hh
senf/Packets/80221Bundle/TLVParser.test.cc

index 7f88528..e7fba5c 100644 (file)
@@ -62,8 +62,8 @@ prefix_ void senf::MIHPacketType::dump(packet p, std::ostream &os)
 
 prefix_ void senf::MIHPacketType::finalize(packet p)
 {
-    p->src_mihfId().finalizeLength();
-    p->dst_mihfId().finalizeLength();
+    p->src_mihfId().finalize();
+    p->dst_mihfId().finalize();
     p->payloadLength_() << p.size() - 8;
     p->messageId() << key(p.next(nothrow));
 }
@@ -94,7 +94,7 @@ prefix_ void senf::MIHGenericPayloadPacketType::finalize(packet p)
     typedef parser::tlvList_t::container tlvContainer_t;
     tlvContainer_t tlvs (p->tlvList() );
     for (tlvContainer_t::iterator i (tlvs.begin()); i != tlvs.end(); ++i)
-        i->finalizeLength();
+        i->finalize();
 }
 
 
index 444f576..2227b30 100644 (file)
 ///////////////////////////////cc.p////////////////////////////////////////
 using namespace senf;
 
-BOOST_AUTO_UNIT_TEST(MIHPacket_MIHFId)
-{
-    MIHFId id ( MACAddress::from_string("01:02:03:04:05:06"));
-    BOOST_CHECK_EQUAL( id.type(), MIHFId::MACAddress);
-    BOOST_CHECK_EQUAL( id, MIHFId( MACAddress::from_string("01:02:03:04:05:06")));
-    BOOST_CHECK( id != MIHFId( MACAddress::from_string("01:02:03:04:05:07")));
-    BOOST_CHECK( id != MIHFId( INet4Address::from_string("128.129.130.131")));
-    BOOST_CHECK( id < MIHFId( MACAddress::from_string("01:02:03:04:05:07")));
-    BOOST_CHECK( id < MIHFId( INet4Address::from_string("128.129.130.131")));
-}
-
 BOOST_AUTO_UNIT_TEST(MIHPacket_msgId)
 {
     MIHPacket mihPacket (MIHPacket::create());
@@ -76,34 +65,54 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_string)
     mihPacket->src_mihfId().value( "senf@berlios.de");
     mihPacket->dst_mihfId().value( "test");
     mihPacket.finalizeThis();
-
+    
     unsigned char data[] = {
             // MIH header
-            0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x17,
+            0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19,
             // source MIHF_ID TLV:
-            0x01, 0x0f, // type, length
+            0x01, 0x10, // type, length
+            0x0f,  // value-length
             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
             // destination MIHF_ID TLV:
-            0x02, 0x04, 0x74, 0x65, 0x73, 0x74
+            0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74
     };
-    BOOST_CHECK(equal( mihPacket.data().begin(), mihPacket.data().end(), data ));
+    SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
+            mihPacket.data().begin(), mihPacket.data().end() );
     BOOST_CHECK_EQUAL( mihPacket->src_mihfId().valueAsString(), "senf@berlios.de");
     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().valueAsString(), "test");
 
     // the maximum length of a MIHF_ID is 253 octets
     BOOST_CHECK_THROW( mihPacket->dst_mihfId().value( std::string(254, 'x')), std::length_error);
-
     // now expand a MIHF_ID
-    mihPacket->dst_mihfId().maxLengthValue(253);
-    mihPacket->dst_mihfId().value( std::string(200, 'x'));
+    // first the tricky one: when setting the maximum id length to 128 the TLV length field
+    // is set to 129 and therefore expanded to 2 bytes; the id-length field is still 1 byte long
+    mihPacket->dst_mihfId().maxIdLength(128);
+    mihPacket->dst_mihfId().value( std::string(128, 'x'));
     mihPacket.finalizeThis();
-
-    BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 17 + 203));
-    BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 17 + 203);
-    BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 200u);
-    BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 203u);
-
+    // packet size is now MIH header (8 bytes) + src MIHIFId TLV (18 bytes) + 
+    // dst MIHIFId TLV (1 byte type + 2 byte TLV length + 1 byte id length + 128 id value) 
+    BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 18 + 1+2+1+128));  
+    BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 18 + 1+2+1+128);
+    BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 1+128);
+    BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 1+2+1+128);
+    // now we extend the dst id to 129 bytes; than we have 2 bytes tlv length and 2 bytes
+    // id-length field
+    mihPacket->dst_mihfId().maxIdLength(129);
+    mihPacket->dst_mihfId().value( std::string(129, 'x'));
+    mihPacket.finalizeThis();
+    // packet size is now MIH header (8 bytes) + src MIHIFId TLV (18 bytes) + 
+    // dst MIHIFId TLV (1 byte type + 2 byte TLV length + 2 byte id length + 128 id value) 
+    BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 18 + 1+2+2+129));  
+    BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 18 + 1+2+2+129);
+    BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 2+129);
+    BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 1+2+2+129);
+    // finally we shrink to dst id field
+    mihPacket->dst_mihfId().value( "test");
+    mihPacket.finalizeThis();
+    SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
+            mihPacket.data().begin(), mihPacket.data().end() );
+    
     std::ostringstream oss (std::ostringstream::out);
     SENF_CHECK_NO_THROW( mihPacket.dump( oss));
 }
@@ -123,12 +132,14 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_mac)
 
     unsigned char data[] = {
             // MIH header
-            0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x1c,
+            0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x1e,
             // source MIHF_ID TLV:
-            0x01, 0x0c, // type, length
+            0x01, 0x0d, // type, length
+            0x0c,       // value-length
             0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04, 0x5c, 0x05, 0x5c, 0x06, // value (nai-encoded)
             // destination MIHF_ID TLV:
-            0x02, 0x0c,  // type, length
+            0x02, 0x0d, // type, length
+            0x0c,       // value-length
             0x5c, 0x07, 0x5c, 0x08, 0x5c, 0x09, 0x5c, 0x0a, 0x5c, 0x0b, 0x5c, 0x0c  // value (nai-encoded)
     };
     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
@@ -152,12 +163,14 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_inet4)
 
     unsigned char data[] = {
             // MIH header
-            0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x14,
+            0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x16,
             // source MIHF_ID TLV:
-            0x01, 0x08, // type, length
+            0x01, 0x09, // type, length
+            0x08,       // value-length
             0x5c, 0x80, 0x5c, 0x81, 0x5c, 0x82, 0x5c, 0x83, // value (nai-encoded)
             // destination MIHF_ID TLV:
-            0x02, 0x08, // type, length
+            0x02, 0x09, // type, length
+            0x08,       // value-length
             0x5c, 0x84, 0x5c, 0x85, 0x5c, 0x86, 0x5c, 0x87  // value (nai-encoded)
     };
     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
@@ -183,16 +196,18 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_inet6)
 
     unsigned char data[] = {
             // MIH header
-            0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x44,
+            0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x46,
             // source MIHF_ID TLV:
-            0x01, 0x20, // type, length
+            0x01, 0x21, // type, length
+            0x20,       // value-length
             // value (nai-encoded):
             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff,
             0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04,
             // destination MIHF_ID TLV:
-            0x02, 0x20, // type, length
+            0x02, 0x21, // type, length
+            0x20,       // value-length
             // value (nai-encoded):
             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
@@ -218,11 +233,12 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_parse)
             // variable payload length:
             0x00, 0x29,
             // source MIHF_ID TLV:
-            0x01, 0x0f, // type, length
+            0x01, 0x10, // type, length
+            0x0f,  // value-length
             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
-            0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value ("senf@berlios.de")
+            0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
             // destination MIHF_ID TLV:
-            0x02, 0x04, 0x74, 0x65, 0x73, 0x74,  // type, length, value ("test")
+            0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74,
             // MIH Payload (two test tlvs)
             // first test tlv
             0x42, // type
@@ -289,13 +305,14 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_create)
             // MIH header
             0x10, 0x54, 0x00, 0x00, 0x00, 0x15,
             // variable payload length:
-            0x00, 0x29,
+            0x00, 0x2b,
             // source MIHF_ID TLV:
-            0x01, 0x0f, // type, length
+            0x01, 0x10, // type, length
+            0x0f,  // value-length
             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
-            0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value ("senf@berlios.de")
+            0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
             // destination MIHF_ID TLV:
-            0x02, 0x04, 0x74, 0x65, 0x73, 0x74,  // type, length, value ("test")
+            0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74,
             // MIH Payload (two test tlvs)
             // first test tlv
             0x42, // type
diff --git a/senf/Packets/80221Bundle/MIHTypes.test.cc b/senf/Packets/80221Bundle/MIHTypes.test.cc
new file mode 100644 (file)
index 0000000..4f2c71d
--- /dev/null
@@ -0,0 +1,62 @@
+// $Id$
+//
+// Copyright (C) 2009
+// 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 MIHTypes unit tests */
+
+//#include "MIHTypes.test.hh"
+//#include "MIHTypes.test.ih"
+
+// Custom includes
+#include "MIHTypes.hh"
+
+#include <senf/Utils/auto_unit_test.hh>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+using namespace senf;
+
+BOOST_AUTO_UNIT_TEST(mihfId)
+{
+    MIHFId id ( MACAddress::from_string("01:02:03:04:05:06"));
+    BOOST_CHECK_EQUAL( id.type(), MIHFId::MACAddress);
+    BOOST_CHECK_EQUAL( id, MIHFId( MACAddress::from_string("01:02:03:04:05:06")));
+    BOOST_CHECK( id != MIHFId( MACAddress::from_string("01:02:03:04:05:07")));
+    BOOST_CHECK( id != MIHFId( INet4Address::from_string("128.129.130.131")));
+    BOOST_CHECK( id < MIHFId( MACAddress::from_string("01:02:03:04:05:07")));
+    BOOST_CHECK( id < MIHFId( INet4Address::from_string("128.129.130.131")));
+}
+
+///////////////////////////////cc.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:
index 80d2ce7..db7ef8b 100644 (file)
@@ -53,6 +53,37 @@ prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
     hexdump(src_mihfId.begin(), src_mihfId.end(), os);
 }
 
+prefix_ void senf::MIHFIdTLVParser::finalize()
+{
+    protect(), idLength_().finalize();
+    length_() << idLength() + idLength_().bytes();
+    MIHBaseTLVParser::finalize();
+}
+
+prefix_ void senf::MIHFIdTLVParser::maxIdLength(boost::uint8_t maxLength)
+{
+    // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
+    if (maxLength > 253) 
+        throw std::length_error("maximum length of a MIHF_ID is 253 octets");
+    protect(), idLength_().maxValue( maxLength);
+    maxLengthValue( maxLength + senf::bytes(idLength_()));
+}
+
+prefix_ senf::safe_data_iterator senf::MIHFIdTLVParser::resizeValueField(
+        MIHTLVLengthParser::value_type size) 
+{
+    MIHTLVLengthParser::value_type current_length ( idLength());
+    idLength_() << size;
+    length_() << size + idLength_().bytes();
+
+    safe_data_iterator si (data(), valueBegin());
+    if (current_length > size)
+        data().erase( si, boost::next(si, current_length-size));
+    else
+        data().insert( si, size-current_length, 0);
+    return si;
+}
+
 prefix_ void senf::MIHFIdTLVParser::value(std::string const & id)
 {
     size_type str_size (id.size());
@@ -65,25 +96,25 @@ prefix_ void senf::MIHFIdTLVParser::value(std::string const & id)
 
 prefix_ void senf::MIHFIdTLVParser::value(senf::MACAddress const & addr)
 {
-    safe_data_iterator si = resizeValueField(12);
+    safe_data_iterator si = resizeValueField(6*2);
     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
 }
 
 prefix_ void senf::MIHFIdTLVParser::value(senf::INet4Address const & addr)
 {
-    safe_data_iterator si = resizeValueField(8);
+    safe_data_iterator si = resizeValueField(4*2);
     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
 }
 
 prefix_ void senf::MIHFIdTLVParser::value(senf::INet6Address const & addr)
 {
-    safe_data_iterator si = resizeValueField(32);
+    safe_data_iterator si = resizeValueField(16*2);
     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
 }
 
 prefix_ void senf::MIHFIdTLVParser::value(senf::EUI64 const & addr)
 {
-    safe_data_iterator si = resizeValueField(16);
+    safe_data_iterator si = resizeValueField(8*2);
     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
 }
 
@@ -206,25 +237,6 @@ prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os)
        << ( value()==0 ? " (infinite)" : " seconds") << std::endl;
 }
 
-
-///////////////////////////////////////////////////////////////////////////
-// senf::MIHBaseTLVParser
-
-prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
-        MIHTLVLengthParser::value_type size) 
-{
-    MIHTLVLengthParser::value_type current_length ( length());
-    length_() << size;
-
-    safe_data_iterator si (data(), boost::next(i(), 1 + length_().bytes() ));
-    if (current_length > size)
-        data().erase( si, boost::next(si, current_length-size));
-    else
-        data().insert( si, size-current_length, 0);
-    return si;
-}
-
-
 ///////////////////////////////////////////////////////////////////////////
 // senf::MIHTLVLengthParser
 
@@ -328,7 +340,7 @@ prefix_ void senf::MIHTLVLengthParser::finalize()
     if (b != 5) resize_(5);
 }
 
-prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type v)
+prefix_ void senf::MIHTLVLengthParser::maxValue(MIHTLVLengthParser::value_type v)
 {
     if (v <= 128)
         return;
index 6a893be..b7bc869 100644 (file)
@@ -54,38 +54,54 @@ prefix_ bool senf::MIHFIdTLVParser::binaryNAIDecoder::operator()(boost::uint8_t
 ///////////////////////////////////////////////////////////////////////////
 // MIHFIdTLVParser
 
+prefix_ senf::PacketParserBase::data_iterator senf::MIHFIdTLVParser::valueBegin() 
+    const
+{
+    return i( idValue_offset());
+}
+
+prefix_ senf::PacketParserBase::data_iterator senf::MIHFIdTLVParser::valueEnd()
+    const
+{
+    return i( idValue_offset() + idLength());
+}
+
 prefix_ std::string senf::MIHFIdTLVParser::valueAsString()
     const
 {
-    return std::string( i(1+length_().bytes()), i(1+length_().bytes()+length()) );
+    return std::string( valueBegin(), valueEnd());
 }
 
 prefix_ senf::MACAddress senf::MIHFIdTLVParser::valueAsMACAddress()
     const
 {
-    return MACAddress::from_data( 
-            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+12) ));
+    if (idLength() != 6*2) throw WrapException<std::bad_cast>(std::bad_cast())
+        << "length of MIHF_ID does not match for a MAC address";
+    return MACAddress::from_data( getNAIDecodedIterator( valueBegin(), valueEnd()));
 }
 
 prefix_ senf::INet4Address senf::MIHFIdTLVParser::valueAsINet4Address()
     const
 {
-    return INet4Address::from_data( 
-            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+8) ));
+    if (idLength() != 4*2) throw WrapException<std::bad_cast>(std::bad_cast())
+        << "length of MIHF_ID does not match for a INet4 address";
+    return INet4Address::from_data( getNAIDecodedIterator( valueBegin(), valueEnd()));
 }
 
 prefix_ senf::INet6Address senf::MIHFIdTLVParser::valueAsINet6Address()
     const
 {
-    return INet6Address::from_data( 
-            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+32) ));
+    if (idLength() != 16*2) throw WrapException<std::bad_cast>(std::bad_cast())
+        << "length of MIHF_ID does not match for a INet6 address";
+    return INet6Address::from_data( getNAIDecodedIterator( valueBegin(), valueEnd()));
 }
 
 prefix_ senf::EUI64 senf::MIHFIdTLVParser::valueAsEUI64()
     const
 {
-    return EUI64::from_data( 
-            getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+16) ));
+    if (idLength() != 8*2) throw WrapException<std::bad_cast>(std::bad_cast())
+        << "length of MIHF_ID does not match for a EUI64 address";
+    return EUI64::from_data( getNAIDecodedIterator( valueBegin(), valueEnd()));
 }
 
 prefix_ bool senf::MIHFIdTLVParser::valueEquals( std::string const &id) 
@@ -97,25 +113,25 @@ prefix_ bool senf::MIHFIdTLVParser::valueEquals( std::string const &id)
 prefix_ bool senf::MIHFIdTLVParser::valueEquals( senf::MACAddress const & addr)
     const
 {
-    return length()==12 && addr==valueAsMACAddress();
+    return idLength()==12 && addr==valueAsMACAddress();
 }
 
 prefix_ bool senf::MIHFIdTLVParser::valueEquals( senf::INet4Address const & addr)
     const
 {
-    return length()==8 && addr==valueAsINet4Address();
+    return idLength()==8 && addr==valueAsINet4Address();
 }
 
 prefix_ bool senf::MIHFIdTLVParser::valueEquals( senf::INet6Address const & addr)
     const
 {
-    return length()==32 && addr==valueAsINet6Address();
+    return idLength()==32 && addr==valueAsINet6Address();
 }
 
 prefix_ bool senf::MIHFIdTLVParser::valueEquals( senf::EUI64 const & addr)
     const
 {
-    return length()==16 && addr==valueAsEUI64();
+    return idLength()==16 && addr==valueAsEUI64();
 }
 
 prefix_ bool senf::MIHFIdTLVParser::valueEquals( MIHFId const & id)
index 2df7440..f04adff 100644 (file)
@@ -97,9 +97,9 @@ namespace senf {
          \endcode
          
          You have to adjust the maximum length value with the \ref maxLengthValue function 
-         before the length value is set. The default maximum value is 127. So, in the above
+         before the length value is set. The default maximum value is 128. So, in the above
          example adding more than 21 MACAddresses to the vector will throw a TLVLengthException
-         if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before.
+         if you don't call \c maxLengthValue( \e some_value) before.
          
          \see MIHTLVLengthParser \n
            MIHGenericTLVParser \n
@@ -126,17 +126,14 @@ namespace senf {
             The size of the length field will be decreased to minimum necessary to hold
             the current length value.
          */
-        void finalizeLength() { 
+        void finalize() { 
             protect(), length_().finalize();
         };
     
         typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
-        
-    protected:
-        /// resize the packet after the length field to given size
-        senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
     };
 
+    
         
     /** \brief Parser for a generic TLV packet
      */
@@ -156,22 +153,26 @@ namespace senf {
         
     /** \brief Parse a MIHF_ID
 
-         the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
-         we could set maxLengthValue in init(), but for the most MIHF_IDs the default
-         maximum length of 127 should be enough.
+         Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
+         We could set maxLengthValue in init(), but for the most MIHF_IDs the default
+         maximum length of 128 should be enough.
          
-         \note you must call mihfIdPacket.maxLengthValue( 253) *before*
-         setting longer MIHF_IDs values.
+         \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer
+             than 128.
+                  
+         \see MIHFId
     */
     class MIHFIdTLVParser : public MIHBaseTLVParser
     {
     #   include SENF_PARSER()
         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
-        SENF_PARSER_SKIP     ( length(), 0      );
+        SENF_PARSER_FIELD_RO ( idLength, MIHTLVLengthParser );
+        SENF_PARSER_LABEL    ( idValue          );
+        SENF_PARSER_SKIP     ( idLength(), 0    );
         SENF_PARSER_FINALIZE ( MIHFIdTLVParser  );
         
     public:
-        ///\name value setters
+        ///\name Value setters
         ///@{
         void value( MIHFId const & id);
         
@@ -182,7 +183,7 @@ namespace senf {
         void value( senf::EUI64        const & addr);    
         ///@}
 
-        ///\name value getters
+        ///\name Value getters
         ///@{
         MIHFId valueAs( MIHFId::Type type) const;
         
@@ -193,7 +194,7 @@ namespace senf {
         senf::EUI64        valueAsEUI64()        const;
         ///@}
         
-        ///\name value comparisons
+        ///\name Value comparisons
         ///@{
         bool valueEquals( MIHFId const & id) const;
         
@@ -205,8 +206,16 @@ namespace senf {
         ///@}
         
         void dump(std::ostream & os) const;
+        void maxIdLength(boost::uint8_t maxLength);
+        void finalize();
 
     private:
+        /// resize the packet after the length field to given size
+        senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size);
+        
+        data_iterator valueBegin() const;
+        data_iterator valueEnd() const;
+
         template <class OutputIterator>
         struct binaryNAIEncoder {
             binaryNAIEncoder(OutputIterator & i);
@@ -253,6 +262,8 @@ namespace senf {
         };
     };
 
+    /** \brief Parser for 802.21 source MIHF_ID TLV
+     */
     struct MIHFSrcIdTLVParser : public MIHFIdTLVParser
     {
         MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
@@ -265,6 +276,8 @@ namespace senf {
         void dump(std::ostream & os) const;
     };
     
+    /** \brief Parser for 802.21 destination MIHF_ID TLV
+     */
     struct MIHFDstIdTLVParser : public MIHFIdTLVParser
     {
         MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
index 5270580..4b949b7 100644 (file)
@@ -41,7 +41,8 @@ using namespace senf;
 namespace {
     struct VoidPacket : public PacketTypeBase
     {};
-                           
+}
+
 #define CHECK_TLVParser(tlvParser, ptype, plength)                          \
 {                                                                           \
     BOOST_CHECK_EQUAL( tlvParser.type(),         ptype   );                 \
@@ -53,7 +54,6 @@ namespace {
         dataIterator++;                                                     \
     }                                                                       \
 }
-}
 
 
 BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_simple_length)
@@ -106,7 +106,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_simple_length)
     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
     tlvParser.type() = 42u;
     tlvParser.value( value);
-    tlvParser.finalizeLength();
+    tlvParser.finalize();
 
     CHECK_TLVParser( tlvParser, 42u, 0x0Au );
 
@@ -131,7 +131,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_extended_length)
     tlvParser.maxLengthValue( MIHTLVLengthParser::max_value);
     tlvParser.type() = 42u;
     tlvParser.value( value);
-    tlvParser.finalizeLength();
+    tlvParser.finalize();
 
     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
 
@@ -152,7 +152,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid)
             senf::PacketInterpreterBase::size_type(2u)));
     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
     tlvParser.type() = 42u;
-    tlvParser.finalizeLength();
+    tlvParser.finalize();
 
     PacketInterpreterBase::byte value[255];
     for (unsigned i=0; i<sizeof(value); i++)
@@ -161,7 +161,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid)
     BOOST_CHECK_THROW( tlvParser.value( value), MIHTLVLengthException);
     tlvParser.maxLengthValue( sizeof(value));
     tlvParser.value( value);
-    tlvParser.finalizeLength();
+    tlvParser.finalize();
     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
 }
 
@@ -188,7 +188,7 @@ namespace {
         using mixin::initSize;
 
         static void finalize(ConcretePacket<TestMacAddressTLVPacketType> p) {
-            p->finalizeLength();
+            p->finalize();
         }
     };
     typedef ConcretePacket<TestMacAddressTLVPacketType> TestMacAddressTLVPacket;