model: Initial attempt to optimize Interest/Data encoding/decoding via a custom packet format
diff --git a/model/ndn-content-object-header.cc b/model/ndn-content-object-header.cc
index 1a31abb..3688a89 100644
--- a/model/ndn-content-object-header.cc
+++ b/model/ndn-content-object-header.cc
@@ -22,20 +22,6 @@
#include "ndn-content-object-header.h"
#include "ns3/log.h"
-#include "../helper/ndn-encoding-helper.h"
-#include "../helper/ndn-decoding-helper.h"
-
-#include "../helper/ccnb-parser/common.h"
-#include "../helper/ccnb-parser/visitors/void-depth-first-visitor.h"
-#include "../helper/ccnb-parser/visitors/name-components-visitor.h"
-#include "../helper/ccnb-parser/visitors/non-negative-integer-visitor.h"
-#include "../helper/ccnb-parser/visitors/timestamp-visitor.h"
-#include "../helper/ccnb-parser/visitors/string-visitor.h"
-#include "../helper/ccnb-parser/visitors/uint32t-blob-visitor.h"
-#include "../helper/ccnb-parser/visitors/content-type-visitor.h"
-
-#include "../helper/ccnb-parser/syntax-tree/block.h"
-#include "../helper/ccnb-parser/syntax-tree/dtag.h"
#include <boost/foreach.hpp>
@@ -44,10 +30,6 @@
namespace ns3 {
namespace ndn {
-using namespace CcnbParser;
-
-const std::string ContentObjectHeader::Signature::DefaultDigestAlgorithm = "2.16.840.1.101.3.4.2.1";
-
NS_OBJECT_ENSURE_REGISTERED (ContentObjectHeader);
NS_OBJECT_ENSURE_REGISTERED (ContentObjectTail);
@@ -85,323 +67,78 @@
return m_name;
}
-#define CCNB EncodingHelper // just to simplify writing
+uint32_t
+ContentObjectHeader::GetSerializedSize () const
+{
+ uint32_t size = 2 + ((2 + 1) + (m_name->GetSerializedSize ()) + (2 + 2 + 4 + 2 + 2 + (2 + 0)));
+ NS_LOG_INFO ("Serialize size = " << size);
+ return size;
+}
void
ContentObjectHeader::Serialize (Buffer::Iterator start) const
{
- size_t written = 0;
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_ContentObject, CCN_DTAG); // <ContentObject>
+ start.WriteU8 (0x80); // version
+ start.WriteU8 (0x01); // packet type
- // fake signature
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_Signature, CCN_DTAG); // <Signature>
- // Signature ::= √DigestAlgorithm?
- // Witness?
- // √SignatureBits
- if (GetSignature ().GetDigestAlgorithm () != Signature::DefaultDigestAlgorithm)
- {
- written += CCNB::AppendString (start, CCN_DTAG_DigestAlgorithm, GetSignature ().GetDigestAlgorithm ());
- }
- written += CCNB::AppendTaggedBlob (start, CCN_DTAG_SignatureBits, GetSignature ().GetSignatureBits ()); // <SignatureBits />
- written += CCNB::AppendCloser (start); // </Signature>
+ start.WriteU16 (2); // signature length
+ start.WriteU16 (0); // empty signature
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_Name, CCN_DTAG); // <Name>
- written += CCNB::AppendNameComponents (start, GetName()); // <Component>...</Component>...
- written += CCNB::AppendCloser (start); // </Name>
+ // name
+ uint32_t offset = m_name->Serialize (start);
+ start.Next (offset);
- // fake signature
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_SignedInfo, CCN_DTAG); // <SignedInfo>
- // SignedInfo ::= √PublisherPublicKeyDigest
- // √Timestamp
- // √Type?
- // √FreshnessSeconds?
- // FinalBlockID?
- // KeyLocator?
- written += CCNB::AppendTaggedBlob (start, CCN_DTAG_PublisherPublicKeyDigest, // <PublisherPublicKeyDigest>...
- GetSignedInfo ().GetPublisherPublicKeyDigest ());
-
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_Timestamp, CCN_DTAG); // <Timestamp>...
- written += CCNB::AppendTimestampBlob (start, GetSignedInfo ().GetTimestamp ());
- written += CCNB::AppendCloser (start);
+ // content
+ // for now assume that contentdata length is zero
+ start.WriteU16 (2 + 4 + 2 + 2 + (2 + 0));
+ start.WriteU16 (4 + 2 + 2 + (2 + 0));
+ start.WriteU32 (static_cast<uint32_t> (m_timestamp.ToInteger (Time::S)));
+ start.WriteU16 (static_cast<uint16_t> (m_freshness.ToInteger (Time::S)));
+ start.WriteU16 (0); // reserved
+ start.WriteU16 (0); // Length (ContentInfoOptions)
- if (GetSignedInfo ().GetContentType () != DATA)
- {
- uint8_t type[3];
- type[0] = (GetSignedInfo ().GetContentType () >> 16) & 0xFF;
- type[1] = (GetSignedInfo ().GetContentType () >> 8 ) & 0xFF;
- type[2] = (GetSignedInfo ().GetContentType () ) & 0xFF;
-
- written += CCNB::AppendTaggedBlob (start, CCN_DTAG_Type, type, 3);
- }
- if (GetSignedInfo ().GetFreshness () > Seconds(0))
- {
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_FreshnessSeconds, CCN_DTAG);
- written += CCNB::AppendNumber (start, GetSignedInfo ().GetFreshness ().ToInteger (Time::S));
- written += CCNB::AppendCloser (start);
- }
- if (GetSignedInfo ().GetKeyLocator () != 0)
- {
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_KeyLocator, CCN_DTAG); // <KeyLocator>
- {
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_KeyName, CCN_DTAG); // <KeyName>
- {
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_Name, CCN_DTAG); // <Name>
- written += CCNB::AppendNameComponents (start, GetName()); // <Component>...</Component>...
- written += CCNB::AppendCloser (start); // </Name>
- }
- written += CCNB::AppendCloser (start); // </KeyName>
- }
- written += CCNB::AppendCloser (start); // </KeyLocator>
- }
-
- written += CCNB::AppendCloser (start); // </SignedInfo>
-
- written += CCNB::AppendBlockHeader (start, CCN_DTAG_Content, CCN_DTAG); // <Content>
-
- // there are no closing tags !!!
- // The closing tag is handled by ContentObjectTail
+ // that's it folks
}
-uint32_t
-ContentObjectHeader::GetSerializedSize () const
-{
- size_t written = 0;
- written += CCNB::EstimateBlockHeader (CCN_DTAG_ContentObject); // <ContentObject>
-
- // fake signature
- written += CCNB::EstimateBlockHeader (CCN_DTAG_Signature); // <Signature>
- // Signature ::= DigestAlgorithm?
- // Witness?
- // SignatureBits
- if (GetSignature ().GetDigestAlgorithm () != Signature::DefaultDigestAlgorithm)
- {
- written += CCNB::EstimateString (CCN_DTAG_DigestAlgorithm, GetSignature ().GetDigestAlgorithm ());
- }
- written += CCNB::EstimateTaggedBlob (CCN_DTAG_SignatureBits,
- sizeof (GetSignature ().GetSignatureBits ())); // <SignatureBits />
- written += 1; // </Signature>
-
- written += CCNB::EstimateBlockHeader (CCN_DTAG_Name); // <Name>
- written += CCNB::EstimateNameComponents (GetName()); // <Component>...</Component>...
- written += 1; // </Name>
-
- // fake signature
- written += CCNB::EstimateBlockHeader (CCN_DTAG_SignedInfo); // <SignedInfo>
- // SignedInfo ::= √PublisherPublicKeyDigest
- // √Timestamp
- // √Type?
- // √FreshnessSeconds?
- // FinalBlockID?
- // KeyLocator?
-
- written += CCNB::EstimateTaggedBlob (CCN_DTAG_PublisherPublicKeyDigest, // <PublisherPublicKeyDigest>...
- sizeof (GetSignedInfo ().GetPublisherPublicKeyDigest ()));
-
- written += CCNB::EstimateBlockHeader (CCN_DTAG_Timestamp); // <Timestamp>...
- written += CCNB::EstimateTimestampBlob (GetSignedInfo ().GetTimestamp ());
- written += 1;
-
- if (GetSignedInfo ().GetContentType () != DATA)
- {
- written += CCNB::EstimateTaggedBlob (CCN_DTAG_Type, 3);
- }
- if (GetSignedInfo ().GetFreshness () > Seconds(0))
- {
- written += CCNB::EstimateBlockHeader (CCN_DTAG_FreshnessSeconds);
- written += CCNB::EstimateNumber (GetSignedInfo ().GetFreshness ().ToInteger (Time::S));
- written += 1;
- }
-
- if (GetSignedInfo ().GetKeyLocator () != 0)
- {
- written += CCNB::EstimateBlockHeader (CCN_DTAG_KeyLocator); // <KeyLocator>
- {
- written += CCNB::EstimateBlockHeader (CCN_DTAG_KeyName); // <KeyName>
- {
- written += CCNB::EstimateBlockHeader (CCN_DTAG_Name); // <Name>
- written += CCNB::EstimateNameComponents (GetName()); // <Component>...</Component>...
- written += 1; // </Name>
- }
- written += 1; // </KeyName>
- }
- written += 1; // </KeyLocator>
- }
-
- written += 1; // </SignedInfo>
-
- written += CCNB::EstimateBlockHeader (CCN_DTAG_Content); // <Content>
-
- // there are no closing tags !!!
- // The closing tag is handled by ContentObjectTail
- return written;
-}
-#undef CCNB
-
-class ContentObjectVisitor : public VoidDepthFirstVisitor
-{
-public:
- virtual void visit (Dtag &n, boost::any param/*should be ContentObjectHeader* */)
- {
- // uint32_t n.m_dtag;
- // std::list<Ptr<Block> > n.m_nestedBlocks;
- static NameComponentsVisitor nameComponentsVisitor;
- static NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
- static TimestampVisitor timestampVisitor;
- static StringVisitor stringVisitor;
- static Uint32tBlobVisitor uint32tBlobVisitor;
- static ContentTypeVisitor contentTypeVisitor;
-
- ContentObjectHeader &contentObject = *(boost::any_cast<ContentObjectHeader*> (param));
-
- switch (n.m_dtag)
- {
- case CCN_DTAG_ContentObject:
- // process nested blocks
- BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
- {
- block->accept (*this, param);
- }
- break;
- case CCN_DTAG_Name:
- {
- // process name components
- Ptr<NameComponents> name = Create<NameComponents> ();
-
- BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
- {
- block->accept (nameComponentsVisitor, &(*name));
- }
- contentObject.SetName (name);
- break;
- }
-
- case CCN_DTAG_Signature:
- // process nested blocks
- BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
- {
- block->accept (*this, param);
- }
- break;
-
- case CCN_DTAG_DigestAlgorithm:
- NS_LOG_DEBUG ("DigestAlgorithm");
- if (n.m_nestedTags.size ()!=1) // should be exactly one UDATA inside this tag
- throw CcnbDecodingException ();
-
- contentObject.GetSignature ().SetDigestAlgorithm
- (boost::any_cast<std::string> ((*n.m_nestedTags.begin())->accept
- (stringVisitor)));
- break;
-
- case CCN_DTAG_SignatureBits:
- NS_LOG_DEBUG ("SignatureBits");
- if (n.m_nestedTags.size ()!=1) // should be only one nested tag
- throw CcnbDecodingException ();
-
- contentObject.GetSignature ().SetSignatureBits
- (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
- (uint32tBlobVisitor)));
- break;
-
- case CCN_DTAG_SignedInfo:
- // process nested blocks
- BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
- {
- block->accept (*this, param);
- }
- break;
-
- case CCN_DTAG_PublisherPublicKeyDigest:
- NS_LOG_DEBUG ("PublisherPublicKeyDigest");
- if (n.m_nestedTags.size ()!=1) // should be only one nested tag
- throw CcnbDecodingException ();
-
- contentObject.GetSignedInfo ().SetPublisherPublicKeyDigest
- (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
- (uint32tBlobVisitor)));
- break;
-
- case CCN_DTAG_Timestamp:
- NS_LOG_DEBUG ("Timestamp");
- if (n.m_nestedTags.size()!=1) // should be exactly one nested tag
- throw CcnbDecodingException ();
-
- contentObject.GetSignedInfo ().SetTimestamp
- (boost::any_cast<Time> ((*n.m_nestedTags.begin())->accept
- (timestampVisitor)));
- break;
-
- case CCN_DTAG_Type:
- NS_LOG_DEBUG ("Type");
- if (n.m_nestedTags.size ()!=1) // should be only one nested tag
- throw CcnbDecodingException ();
-
- contentObject.GetSignedInfo ().SetContentType
- (static_cast<ContentObjectHeader::ContentType>
- (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
- (contentTypeVisitor))));
- break;
-
- case CCN_DTAG_FreshnessSeconds:
- NS_LOG_DEBUG ("FreshnessSeconds");
-
- if (n.m_nestedTags.size()!=1) // should be exactly one nested tag
- throw CcnbDecodingException ();
-
- contentObject.GetSignedInfo ().SetFreshness
- (Seconds
- (boost::any_cast<uint32_t> ((*n.m_nestedTags.begin())->accept
- (nonNegativeIntegerVisitor))));
- break;
-
- case CCN_DTAG_KeyLocator:
- // process nested blocks
- BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
- {
- block->accept (*this, param);
- }
- break;
-
- case CCN_DTAG_KeyName:
- {
- if (n.m_nestedTags.size ()!=1) // should be exactly one nested tag
- throw CcnbDecodingException ();
-
- Ptr<BaseTag> nameTag = DynamicCast<BaseTag>(n.m_nestedTags.front ());
- if (nameTag == 0)
- throw CcnbDecodingException ();
-
- // process name components
- Ptr<NameComponents> name = Create<NameComponents> ();
-
- BOOST_FOREACH (Ptr<Block> block, nameTag->m_nestedTags)
- {
- block->accept (nameComponentsVisitor, &(*name));
- }
- contentObject.GetSignedInfo ().SetKeyLocator (name);
- break;
- }
-
- case CCN_DTAG_Content: // !!! HACK
- // This hack was necessary for memory optimizations (i.e., content is virtual payload)
- NS_ASSERT_MSG (n.m_nestedTags.size() == 0, "Parser should have stopped just after processing <Content> tag");
- break;
-
- default: // ignore all other stuff
- break;
- }
- }
-};
uint32_t
ContentObjectHeader::Deserialize (Buffer::Iterator start)
{
- static ContentObjectVisitor contentObjectVisitor;
-
Buffer::Iterator i = start;
- Ptr<Block> root = Block::ParseBlock (i);
- root->accept (contentObjectVisitor, this);
+ if (i.ReadU8 () != 0x80)
+ throw new ContentObjectHeaderException ();
+
+ if (i.ReadU8 () != 0x01)
+ throw new ContentObjectHeaderException ();
+
+ if (i.ReadU16 () != 2) // signature length
+ throw new ContentObjectHeaderException ();
+
+ if (i.ReadU16 () != 0) // signature type
+ throw new ContentObjectHeaderException ();
+
+ m_name = Create<NameComponents> ();
+ uint32_t offset = m_name->Deserialize (start);
+ i.Next (offset);
+
+ if (i.ReadU16 () != (2 + 4 + 2 + 2 + (2 + 0))) // content length
+ throw new ContentObjectHeaderException ();
+
+ if (i.ReadU16 () != (4 + 2 + 2 + (2 + 0))) // Length (content Info)
+ throw new ContentObjectHeaderException ();
+
+ m_timestamp = Seconds (i.ReadU32 ());
+ m_freshness = Seconds (i.ReadU16 ());
+
+ if (i.ReadU16 () != 0) // Reserved
+ throw new ContentObjectHeaderException ();
+ if (i.ReadU16 () != 0) // Length (ContentInfoOptions)
+ throw new ContentObjectHeaderException ();
+
+ NS_ASSERT_MSG (i.GetDistanceFrom (start) != GetSerializedSize (),
+ "Something wrong with ContentObjectHeader::Deserialize");
+
return i.GetDistanceFrom (start);
}
@@ -443,112 +180,24 @@
void
ContentObjectTail::Print (std::ostream &os) const
{
- os << "</Content></ContentObject>";
+ // os << "</Content></ContentObject>";
}
uint32_t
ContentObjectTail::GetSerializedSize (void) const
{
- return 2;
+ return 0;
}
void
ContentObjectTail::Serialize (Buffer::Iterator start) const
{
- Buffer::Iterator i = start;
- i.Prev (2); // Trailer interface requires us to go backwards
-
- i.WriteU8 (0x00); // </Content>
- i.WriteU8 (0x00); // </ContentObject>
}
uint32_t
ContentObjectTail::Deserialize (Buffer::Iterator start)
{
- Buffer::Iterator i = start;
- i.Prev (2); // Trailer interface requires us to go backwards
-
- uint8_t closing_tag_content = i.ReadU8 ();
- NS_ASSERT_MSG (closing_tag_content==0, "Should be a closing tag </Content> (0x00)");
-
- uint8_t closing_tag_content_object = i.ReadU8 ();
- NS_ASSERT_MSG (closing_tag_content_object==0, "Should be a closing tag </ContentObject> (0x00)");
-
- return 2;
-}
-
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////
-
-ContentObjectHeader::SignedInfo::SignedInfo ()
- : m_publisherPublicKeyDigest (0)
- // , m_timestamp
- , m_type (DATA)
- // , m_freshness
- // , FinalBlockID
- // , KeyLocator
-{
-}
-
-void
-ContentObjectHeader::SignedInfo::SetPublisherPublicKeyDigest (uint32_t digest)
-{
- m_publisherPublicKeyDigest = digest;
-}
-
-uint32_t
-ContentObjectHeader::SignedInfo::GetPublisherPublicKeyDigest () const
-{
- return m_publisherPublicKeyDigest;
-}
-
-void
-ContentObjectHeader::SignedInfo::SetTimestamp (const Time ×tamp)
-{
- m_timestamp = timestamp;
-}
-
-Time
-ContentObjectHeader::SignedInfo::GetTimestamp () const
-{
- return m_timestamp;
-}
-
-void
-ContentObjectHeader::SignedInfo::SetContentType (ContentObjectHeader::ContentType type)
-{
- m_type = type;
-}
-
-ContentObjectHeader::ContentType
-ContentObjectHeader::SignedInfo::GetContentType () const
-{
- return m_type;
-}
-
-void
-ContentObjectHeader::SignedInfo::SetFreshness (const Time &freshness)
-{
- m_freshness = freshness;
-}
-
-Time
-ContentObjectHeader::SignedInfo::GetFreshness () const
-{
- return m_freshness;
-}
-
-void
-ContentObjectHeader::SignedInfo::SetKeyLocator (Ptr<const NameComponents> keyLocator)
-{
- m_keyLocator = keyLocator;
-}
-
-Ptr<const NameComponents>
-ContentObjectHeader::SignedInfo::GetKeyLocator () const
-{
- return m_keyLocator;
+ return 0;
}
} // namespace ndn
diff --git a/model/ndn-content-object-header.h b/model/ndn-content-object-header.h
index 64fc3e5..79f04df 100644
--- a/model/ndn-content-object-header.h
+++ b/model/ndn-content-object-header.h
@@ -38,14 +38,19 @@
namespace ndn {
/**
- * Ndn XML definition of ContentObject
+ * ContentObject header
*
* Only few important fields are actually implemented in the simulation
*
- *
* ContentObjectHeader serializes/deserializes header up-to and including <Content> tags
* Necessary closing tags should be added using ContentObjectTail
*
+ * Optimized and simplified formatting of Interest packets
+ *
+ * ContentObject ::= Signature
+ * Name
+ * Content
+ *
* This hacks are necessary to optimize memory use (i.e., virtual payload)
*
* "<ContentObject><Signature>..</Signature><Name>...</Name><SignedInfo>...</SignedInfo><Content>"
@@ -54,173 +59,6 @@
class ContentObjectHeader : public SimpleRefCount<ContentObjectHeader,Header>
{
public:
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- /**
- * @brief Class representing Signature section of the content object
- */
- class Signature
- {
- public:
- /**
- * @brief Default constructor. Creates a fake-type signature
- */
- inline Signature ();
-
- /**
- * @brief Get digest algorithm
- */
- inline const std::string &
- GetDigestAlgorithm () const;
-
- /**
- * @brief Set digest algorithm
- */
- inline void
- SetDigestAlgorithm (const std::string &digestAlgorithm);
-
- /**
- * @brief Get signature bits
- */
- inline uint32_t
- GetSignatureBits () const;
-
- /**
- * @brief Set signature bits
- */
- inline void
- SetSignatureBits (uint32_t signatureBits);
-
- /**
- * @brief Default digest algorithm ("2.16.840.1.101.3.4.2.1")
- */
- static const std::string DefaultDigestAlgorithm; // = "2.16.840.1.101.3.4.2.1";
-
- private:
- std::string m_digestAlgorithm; // if value is `2.16.840.1.101.3.4.2.1`, then SHA-256 (not supported)
- // in NS-3 value `99.0` represents a fake digest
- // Witness // not used in NS-3
- uint32_t m_signatureBits; // in NS-3 a fake signature is a just 32-bits
- };
-
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
-
- /**
- * @brief Options for the data packet Type
- */
- enum ContentType
- {
- DATA = 0x0C04C0, // default value. If ContentObject is type of DATA, then ContentType tag will be omitted
- ENCR = 0x10D091,
- GONE = 0x18E344,
- KEY = 0x28463F,
- LINK = 0x2C834A,
- NACK = 0x34008A
- };
-
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
-
- /**
- * @brief Class representing SignedInfo section of the content object
- */
- class SignedInfo
- {
- public:
- /**
- * @brief Default constructor
- */
- SignedInfo ();
-
- /**
- * @brief Set PublisherPublicKey digest
- * @param digest a fake 32-bit digest is supported
- */
- void
- SetPublisherPublicKeyDigest (uint32_t digest);
-
- /**
- * @brief Get PublisherPublicKey digest
- */
- uint32_t
- GetPublisherPublicKeyDigest () const;
-
- /**
- * @brief Set content object timestamp
- * @param timestamp timestamp
- */
- void
- SetTimestamp (const Time ×tamp);
-
- /**
- * @brief Get timestamp of the content object
- */
- Time
- GetTimestamp () const;
-
- /**
- * @brief Set ContentObject type
- * @param type type of the content object
- */
- void
- SetContentType (ContentType type);
-
- /**
- * @brief Get ContentObject type
- */
- ContentType
- GetContentType () const;
-
- /**
- * @brief Set freshness of the content object
- * @param freshness Freshness, 0s means infinity
- */
- void
- SetFreshness (const Time &freshness);
-
- /**
- * @brief Get freshness of the content object
- */
- Time
- GetFreshness () const;
-
- /**
- * @brief Set key locator
- * @param keyLocator name of the key
- *
- * Note that only <KeyName> option for the key locator is supported
- */
- void
- SetKeyLocator (Ptr<const NameComponents> keyLocator);
-
- /**
- * @brief Get key locator
- *
- * Note that only <KeyName> option for the key locator is supported
- */
- Ptr<const NameComponents>
- GetKeyLocator () const;
-
- private:
- uint32_t m_publisherPublicKeyDigest; // fake publisher key digest
- Time m_timestamp;
- ContentType m_type;
- Time m_freshness;
- // FinalBlockID
- Ptr<const NameComponents> m_keyLocator; // support only <KeyName> option for KeyLocator
- };
-
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
-
/**
* Constructor
*
@@ -249,28 +87,30 @@
GetNamePtr () const;
/**
- * @brief Get editable reference to content object's Signature
+ * @brief Set content object timestamp
+ * @param timestamp timestamp
*/
- inline Signature &
- GetSignature ();
+ void
+ SetTimestamp (const Time ×tamp);
/**
- * @brief Get read-only reference to content object's Signature
+ * @brief Get timestamp of the content object
*/
- inline const Signature &
- GetSignature () const;
+ Time
+ GetTimestamp () const;
+
+ /**
+ * @brief Set freshness of the content object
+ * @param freshness Freshness, 0s means infinity
+ */
+ void
+ SetFreshness (const Time &freshness);
/**
- * @brief Get editable reference to content object's SignedInfo
+ * @brief Get freshness of the content object
*/
- inline SignedInfo &
- GetSignedInfo ();
-
- /**
- * @brief Get read-only reference to content object's SignedInfo
- */
- inline const SignedInfo &
- GetSignedInfo () const;
+ Time
+ GetFreshness () const;
//////////////////////////////////////////////////////////////////
@@ -282,14 +122,13 @@
virtual uint32_t Deserialize (Buffer::Iterator start); ///< @brief Deserialize the Header
private:
- Signature m_signature;
Ptr<NameComponents> m_name;
- SignedInfo m_signedInfo;
+ Time m_freshness;
+ Time m_timestamp;
};
/**
- * ContentObjectTail should always be 2 bytes, representing two closing tags:
- * "</Content><ContentObject>"
+ * ContentObjectTail for compatibility with other packet formats
*/
class ContentObjectTail : public Trailer
{
@@ -306,61 +145,6 @@
};
-ContentObjectHeader::Signature::Signature ()
- : m_digestAlgorithm ("99.0")
- , m_signatureBits (0)
-{
-}
-
-const std::string &
-ContentObjectHeader::Signature::GetDigestAlgorithm () const
-{
- return m_digestAlgorithm;
-}
-
-void
-ContentObjectHeader::Signature::SetDigestAlgorithm (const std::string &digestAlgorithm)
-{
- m_digestAlgorithm = digestAlgorithm;
-}
-
-uint32_t
-ContentObjectHeader::Signature::GetSignatureBits () const
-{
- return m_signatureBits;
-}
-
-inline void
-ContentObjectHeader::Signature::SetSignatureBits (uint32_t signature)
-{
- m_signatureBits = signature;
-}
-
-
-ContentObjectHeader::Signature &
-ContentObjectHeader::GetSignature ()
-{
- return m_signature;
-}
-
-const ContentObjectHeader::Signature &
-ContentObjectHeader::GetSignature () const
-{
- return m_signature;
-}
-
-ContentObjectHeader::SignedInfo &
-ContentObjectHeader::GetSignedInfo ()
-{
- return m_signedInfo;
-}
-
-const ContentObjectHeader::SignedInfo &
-ContentObjectHeader::GetSignedInfo () const
-{
- return m_signedInfo;
-}
-
/**
* @ingroup ndn-exceptions
* @brief Class for ContentObject parsing exception
diff --git a/model/ndn-interest-header.cc b/model/ndn-interest-header.cc
index d0ebaab..f128821 100644
--- a/model/ndn-interest-header.cc
+++ b/model/ndn-interest-header.cc
@@ -15,21 +15,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
- * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
-///< #CCN_PR_SCOPE0 (0x20) local scope,
-///< #CCN_PR_SCOPE1 (0x40) this host,
-///< #CCN_PR_SCOPE2 (0x80) immediate neighborhood
-
#include "ndn-interest-header.h"
#include "ns3/log.h"
#include "ns3/unused.h"
#include "ns3/packet.h"
-#include "../helper/ndn-encoding-helper.h"
-#include "../helper/ndn-decoding-helper.h"
NS_LOG_COMPONENT_DEFINE ("ndn.InterestHeader");
@@ -52,12 +45,7 @@
InterestHeader::InterestHeader ()
: m_name ()
- , m_minSuffixComponents (-1)
- , m_maxSuffixComponents (-1)
- , m_exclude ()
- , m_childSelector (false)
- , m_answerOriginKind (false)
- , m_scope (-1)
+ , m_scope (0xFF)
, m_interestLifetime (Seconds (0))
, m_nonce (0)
, m_nackType (NORMAL_INTEREST)
@@ -66,11 +54,6 @@
InterestHeader::InterestHeader (const InterestHeader &interest)
: m_name (Create<NameComponents> (interest.GetName ()))
- , m_minSuffixComponents (interest.m_minSuffixComponents)
- , m_maxSuffixComponents (interest.m_maxSuffixComponents)
- , m_exclude (interest.IsEnabledExclude () ? Create<NameComponents> (interest.GetExclude ()) : 0)
- , m_childSelector (interest.m_childSelector)
- , m_answerOriginKind (interest.m_answerOriginKind)
, m_scope (interest.m_scope)
, m_interestLifetime (interest.m_interestLifetime)
, m_nonce (interest.m_nonce)
@@ -107,73 +90,6 @@
}
void
-InterestHeader::SetMinSuffixComponents (int32_t value)
-{
- m_minSuffixComponents = value;
-}
-
-int32_t
-InterestHeader::GetMinSuffixComponents () const
-{
- return m_minSuffixComponents;
-}
-
-void
-InterestHeader::SetMaxSuffixComponents (int32_t value)
-{
- m_maxSuffixComponents = value;
-}
-
-int32_t
-InterestHeader::GetMaxSuffixComponents () const
-{
- return m_maxSuffixComponents;
-}
-
-void
-InterestHeader::SetExclude (Ptr<NameComponents> exclude)
-{
- m_exclude = exclude;
-}
-
-bool
-InterestHeader::IsEnabledExclude () const
-{
- return m_exclude!=0;
-}
-
-const NameComponents&
-InterestHeader::GetExclude () const
-{
- if (m_exclude==0) throw InterestHeaderException();
- return *m_exclude;
-}
-
-void
-InterestHeader::SetChildSelector (bool value)
-{
- m_childSelector = value;
-}
-
-bool
-InterestHeader::IsEnabledChildSelector () const
-{
- return m_childSelector;
-}
-
-void
-InterestHeader::SetAnswerOriginKind (bool value)
-{
- m_answerOriginKind = value;
-}
-
-bool
-InterestHeader::IsEnabledAnswerOriginKind () const
-{
- return m_answerOriginKind;
-}
-
-void
InterestHeader::SetScope (int8_t scope)
{
m_scope = scope;
@@ -210,12 +126,12 @@
}
void
-InterestHeader::SetNack (uint32_t nackType)
+InterestHeader::SetNack (uint8_t nackType)
{
m_nackType = nackType;
}
-uint32_t
+uint8_t
InterestHeader::GetNack () const
{
return m_nackType;
@@ -224,22 +140,61 @@
uint32_t
InterestHeader::GetSerializedSize (void) const
{
- // unfortunately, we don't know exact header size in advance
- return EncodingHelper::GetSerializedSize (*this);
+ size_t size = 2 + (1 + 4 + 2 + 1 + (m_name->GetSerializedSize ()) + (2 + 0) + (2 + 0));
+ NS_LOG_INFO ("Serialize size = " << size);
+
+ return size;
}
void
InterestHeader::Serialize (Buffer::Iterator start) const
{
- size_t size = EncodingHelper::Serialize (start, *this);
- NS_UNUSED (size);
- NS_LOG_INFO ("Serialize size = " << size);
+ start.WriteU8 (0x80); // version
+ start.WriteU8 (0x00); // packet type
+
+ start.WriteU32 (m_nonce);
+ start.WriteU8 (m_scope);
+ start.WriteU8 (m_nackType);
+
+ NS_ASSERT_MSG (0 <= m_interestLifetime.ToInteger (Time::S) && m_interestLifetime.ToInteger (Time::S) < 65535,
+ "Incorrect InterestLifetime (should not be smaller than 0 and larger than 65535");
+
+ // rounding timestamp value to seconds
+ start.WriteU16 (static_cast<uint16_t> (m_interestLifetime.ToInteger (Time::S)));
+
+ uint32_t offset = m_name->Serialize (start);
+ start.Next (offset);
+
+ start.WriteU16 (0); // no selectors
+ start.WriteU16 (0); // no options
}
uint32_t
InterestHeader::Deserialize (Buffer::Iterator start)
{
- return DecodingHelper::Deserialize (start, *this); // \todo Debugging is necessary
+ Buffer::Iterator i = start;
+
+ if (i.ReadU8 () != 0x80)
+ throw new InterestHeaderException ();
+
+ if (i.ReadU8 () != 0x00)
+ throw new InterestHeaderException ();
+
+ m_scope = i.ReadU8 ();
+ m_nackType = i.ReadU8 ();
+ m_interestLifetime = Seconds (i.ReadU16 ());
+
+ m_name = Create<NameComponents> ();
+ uint32_t offset = m_name->Deserialize (start);
+ i.Next (offset);
+
+ i.ReadU16 ();
+ i.ReadU16 ();
+
+ NS_ASSERT (GetSerializedSize () == (i.GetDistanceFrom (start)));
+
+ return i.GetDistanceFrom (start);
+ // return DecodingHelper::Deserialize (start, *this); // \todo Debugging is necessary
}
TypeId
@@ -272,18 +227,7 @@
}
os << "</NACK>\n";
}
- if (GetMinSuffixComponents () >= 0)
- os << " <MinSuffixComponents>" << GetMinSuffixComponents () << "</MinSuffixComponents>\n";
- if (GetMaxSuffixComponents () >= 0)
- os << " <MaxSuffixComponents>" << m_maxSuffixComponents << "</MaxSuffixComponents>\n";
- if (IsEnabledExclude () && GetExclude ().size()>0)
- os << " <Exclude>" << GetExclude () << "</Exclude>\n";
- if (IsEnabledChildSelector ())
- os << " <ChildSelector />\n";
- if (IsEnabledAnswerOriginKind ())
- os << " <AnswerOriginKind />\n";
- if (GetScope () >= 0)
- os << " <Scope>" << GetScope () << "</Scope>\n";
+ os << " <Scope>" << GetScope () << "</Scope>\n";
if ( !GetInterestLifetime ().IsZero() )
os << " <InterestLifetime>" << GetInterestLifetime () << "</InterestLifetime>\n";
if (GetNonce ()>0)
diff --git a/model/ndn-interest-header.h b/model/ndn-interest-header.h
index f645255..096dc7b 100644
--- a/model/ndn-interest-header.h
+++ b/model/ndn-interest-header.h
@@ -38,97 +38,51 @@
class Packet;
namespace ndn {
-
-/**
- * Ndn XML definition of Interest
- *
- * Only few important fields are actually implemented in the simulation
- *
- * <xs:element name="Interest" type="InterestType"/>
- * <xs:complexType name="InterestType">
- * <xs:sequence>
- * <xs:element name="Name" type="NameType"/>
- * <xs:element name="MinSuffixComponents" type="xs:nonNegativeInteger"
- * minOccurs="0" maxOccurs="1"/>
- * <xs:element name="MaxSuffixComponents" type="xs:nonNegativeInteger"
- * minOccurs="0" maxOccurs="1"/>
- * <xs:choice minOccurs="0" maxOccurs="1">
- * <xs:element name="PublisherPublicKeyDigest" type="DigestType"/>
- * <xs:element name="PublisherCertificateDigest" type="DigestType"/>
- * <xs:element name="PublisherIssuerKeyDigest" type="DigestType"/>
- * <xs:element name="PublisherIssuerCertificateDigest" type="DigestType"/>
- * </xs:choice>
- * <xs:element name="Exclude" type="ExcludeType"
- * minOccurs="0" maxOccurs="1"/>
- * <xs:element name="ChildSelector" type="xs:nonNegativeInteger"
- * minOccurs="0" maxOccurs="1"/>
- * <xs:element name="AnswerOriginKind" type="xs:nonNegativeInteger"
- * minOccurs="0" maxOccurs="1"/>
- * <xs:element name="Scope" type="xs:nonNegativeInteger"
- * minOccurs="0" maxOccurs="1"/>
- * <xs:element name="InterestLifetime" type="FinegrainLifetimeType"
- * minOccurs="0" maxOccurs="1"/>
- * <xs:element name="Nonce" type="Base64BinaryType"
- * minOccurs="0" maxOccurs="1"/>
- * </xs:sequence>
- * </xs:complexType>
- *
- * <xs:complexType name="NameType">
- * <xs:sequence>
- * <xs:element name="Component" type="Base64BinaryType"
- * minOccurs="0" maxOccurs="unbounded"/>
- * </xs:sequence>
- * </xs:complexType>
- *
- * <xs:complexType name="ExcludeType">
- * <xs:sequence>
- * <xs:choice minOccurs="0" maxOccurs="1">
- * <xs:element name="Any" type="EmptyType"/>
- * <xs:element name="Bloom" type="Base64BinaryType"/> <!-- Bloom is deprecated --!>
- * </xs:choice>
- * <xs:sequence minOccurs="0" maxOccurs="unbounded">
- * <xs:element name="Component" type="Base64BinaryType"/>
- * <xs:choice minOccurs="0" maxOccurs="1">
- * <xs:element name="Any" type="EmptyType"/>
- * <xs:element name="Bloom" type="Base64BinaryType"/> <!-- Bloom is deprecated --!>
- * </xs:choice>
- * </xs:sequence>
- * </xs:sequence>
- * </xs:complexType>
- *
- * <!-- Binary representation of time, Unix time epoch, units 2**-12 sec (0.000244140625 sec) -->
- * <!-- The length limit limit of 6 bytes is not actually to be enforced, but
- * it will be a loooooooong time before anyone cares. -->
- *
- * <!-- Binary representation of relative time, relative to "now" -->
- * <xs:complexType name="FinegrainLifetimeType">
- * <xs:simpleContent>
- * <xs:extension base="BinaryTime12">
- * <xs:attribute name="ccnbencoding" type="xs:string" fixed="base64Binary"/>
- * </xs:extension>
- * </xs:simpleContent>
- * </xs:complexType>
- *
- * <xs:simpleType name="BinaryTime12">
- * <xs:restriction base="xs:base64Binary">
- * <xs:length value="6" fixed="true"/>
- * </xs:restriction>
- * </xs:simpleType>
- *
- **/
/**
* @brief NDN InterestHeader and routines to serialize/deserialize
*
- * Simplifications:
- * - Name: binary name components are not supported
- * - MinSuffixComponents and MasSuffixComponents: if value is negative (default), will not be serialized
- * - ChildSelector, AnswerOriginKind: 0 - false, 1 - true, -1 not set
- * - Publisher* elements are not supported
- * - Exclude: only simple name matching is supported (Bloom support has been deprecated in Ndn)
- * - InterestLifetime: ?
- * - Nonce: 32 bit random integer. If value is 0, will not be serialized
- **/
+ * Optimized and simplified formatting of Interest packets
+ *
+ * Interest ::= Nonce
+ * Scope
+ * InterestLifetime
+ * Name
+ * Selectors
+ * Options
+ *
+ * Minumum size of the Interest packet: 1 + 4 + 2 + 1 + (2 + 0) + (2 + 0) + (2 + 0) = 14
+ *
+ * Maximum size of the Interest packet: 1 + 4 + 2 + 1 + (2 + 65535) + (2 + 65535) + (2 + 65535) = 196619
+ *
+ * ::
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Nonce |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Scope | Reserved | InterestLifetime |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Length | |
+ * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ * ~ ~
+ * ~ Name ~
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Length | |
+ * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ * ~ ~
+ * ~ Selectors ~
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Length | |
+ * |-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ * ~ ~
+ * ~ Options ~
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * **/
class InterestHeader : public SimpleRefCount<InterestHeader, Header>
{
public:
@@ -153,7 +107,6 @@
void
SetName (Ptr<NameComponents> name);
-
/**
* \brief Get interest name
*
@@ -169,105 +122,6 @@
GetNamePtr () const;
/**
- * \brief Set interest MinSuffixComponents
- *
- * MinSuffixComponents refer to the number of name components beyond those in the prefix,
- * and counting the implicit digest, that may occur in the matching ContentObject.
- * \see http://www.ndn.org/releases/latest/doc/technical/InterestMessage.html for more information.
- * @param[in] value minimum length of suffix components
- **/
- void
- SetMinSuffixComponents (int32_t value);
-
- /**
- * \brief Get interest MinSuffixComponents
- *
- * MinSuffixComponents refer to the number of name components beyond those in the prefix,
- * and counting the implicit digest, that may occur in the matching ContentObject.
- * For more information, see http://www.ndn.org/releases/latest/doc/technical/InterestMessage.html
- **/
- int32_t
- GetMinSuffixComponents () const;
-
-
- /**
- * \brief Set interest MaxSuffixComponents
- *
- * MaxSuffixComponents refer to the number of name components beyond those in the prefix,
- * and counting the implicit digest, that may occur in the matching ContentObject.
- * \see http://www.ndn.org/releases/latest/doc/technical/InterestMessage.html for more information.
- * @param[in] value maximum length of suffix components
- **/
- void
- SetMaxSuffixComponents (int32_t value);
-
- /**
- * \brief Get interest MaxSuffixComponents
- *
- * MaxSuffixComponents refer to the number of name components beyond those in the prefix,
- * and counting the implicit digest, that may occur in the matching ContentObject.
- * For more information, see http://www.ndn.org/releases/latest/doc/technical/InterestMessage.html
- **/
- int32_t
- GetMaxSuffixComponents () const;
-
- /**
- * \brief Set exclude filer
- *
- * For example, SetExclude (ndnNameComponents("exclude1")("exclude2")("exclude3"))
- * @param[in] exclude const pointer to ndnNameComponents to be excluded
- **/
- void
- SetExclude (Ptr<NameComponents> exclude);
-
- /**
- * \brief Check if interest conatins exclude filter
- *
- */
- bool
- IsEnabledExclude () const;
-
- /**
- * \brief Get exclude filter
- */
- const NameComponents&
- GetExclude () const;
-
- /**
- * \brief Set ChildSelector
- * Often a given interest will match more than one ContentObject within a given content store.
- * The ChildSelector provides a way of expressing a preference for which of these should be returned.
- * If the value is false, the leftmost child is preferred. If true, the rightmost child is preferred.
- * \see http://www.ndn.org/releases/latest/doc/technical/InterestMessage.html for more information.
- * @param[in] value boolean ChildSelector value
- */
- void
- SetChildSelector (bool value);
-
- /**
- * \brief Return ChildSelector value
- * \see http://www.ndn.org/releases/latest/doc/technical/InterestMessage.html for more information.
- *
- */
- bool
- IsEnabledChildSelector () const;
-
- /**
- * \brief Set AnswerOriginKind
- * Default value for AnswerOriginKind is false.
- * @param[in] value boolean AnswerOriginKind value
- */
- void
- SetAnswerOriginKind (bool value);
-
- /**
- * \brief Check the value of AnswerOriginKind
- *
- */
- bool
- IsEnabledAnswerOriginKind () const;
-
- /**
* \brief Set Scope
* Scope limits where the Interest may propagate.
* Scope 0 prevents propagation beyond the local ccnd (even to other applications on the same host).
@@ -348,14 +202,14 @@
* @param[in] nackType NACK_LOOP or NACK_CONGESTION or NACK_GIVEUP_PIT or NORMAL_INTEREST
*/
void
- SetNack (uint32_t nackType);
+ SetNack (uint8_t nackType); //using reserved field
/**
* \brief Get NACK type
* Returns NACK_LOOP, NACK_CONGESTION or NACK_GIVEUP_PIT.
* Otherwise, in case of normal interest packet, returns NORMAL_INTEREST (equals 0).
*/
- uint32_t
+ uint8_t
GetNack () const;
//////////////////////////////////////////////////////////////////
@@ -396,15 +250,10 @@
private:
Ptr<NameComponents> m_name; ///< Interest name
- int32_t m_minSuffixComponents; ///< Minimum suffix components. not used if negative
- int32_t m_maxSuffixComponents; ///< Maximum suffix components. not used if negative
- Ptr<NameComponents> m_exclude; ///< Exclude filter
- bool m_childSelector; ///< Default value for ChildSelector is false
- bool m_answerOriginKind; ///< Default value for AnswerOriginKind is false
- int8_t m_scope; ///< -1 not set, 0 local scope, 1 this host, 2 immediate neighborhood
+ uint8_t m_scope; ///< 0xFF not set, 0 local scope, 1 this host, 2 immediate neighborhood
Time m_interestLifetime; ///< InterestLifetime
uint32_t m_nonce; ///< Nonce. not used if zero
- uint32_t m_nackType; ///< Negative Acknowledgement type
+ uint8_t m_nackType; ///< Negative Acknowledgement type
};
/**
diff --git a/model/ndn-name-components.cc b/model/ndn-name-components.cc
index d5ac498..6e44b12 100644
--- a/model/ndn-name-components.cc
+++ b/model/ndn-name-components.cc
@@ -105,6 +105,59 @@
return retval;
}
+size_t
+NameComponents::GetSerializedSize () const
+{
+ size_t nameSerializedSize = 2;
+ for (std::list<std::string>::const_iterator i = this->begin ();
+ i != this->end ();
+ i++)
+ {
+ nameSerializedSize += 2 + i->size ();
+ }
+ NS_ASSERT_MSG (nameSerializedSize < 30000, "Name is too long (> 30kbytes)");
+
+ return nameSerializedSize;
+}
+
+uint32_t
+NameComponents::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU16 (static_cast<uint16_t> (this->GetSerializedSize ()-2));
+
+ for (std::list<std::string>::const_iterator item = this->begin ();
+ item != this->end ();
+ item++)
+ {
+ i.WriteU16 (static_cast<uint16_t> (item->size ()));
+ i.Write (reinterpret_cast<const uint8_t*> (item->c_str ()), item->size ());
+ }
+
+ return i.GetDistanceFrom (start);
+}
+
+uint32_t
+NameComponents::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ uint16_t nameLength = i.ReadU16 ();
+ while (nameLength > 0)
+ {
+ uint16_t length = i.ReadU16 ();
+ nameLength = nameLength - 2 - length;
+
+ uint8_t tmp[length];
+ i.Read (tmp, length);
+
+ this->Add (string (reinterpret_cast<const char*> (tmp), length));
+ }
+
+ return i.GetDistanceFrom (start);
+}
+
void
NameComponents::Print (std::ostream &os) const
{
diff --git a/model/ndn-name-components.h b/model/ndn-name-components.h
index 4a479ac..c2076d1 100644
--- a/model/ndn-name-components.h
+++ b/model/ndn-name-components.h
@@ -30,6 +30,7 @@
#include <algorithm>
#include <list>
#include "ns3/object.h"
+#include "ns3/buffer.h"
#include <boost/ref.hpp>
@@ -128,6 +129,26 @@
void Print (std::ostream &os) const;
/**
+ * @brief Get serialized size for ndnSIM packet encoding
+ */
+ size_t
+ GetSerializedSize () const;
+
+ /**
+ * @brief Serialize Name in ndnSIM packet encoding
+ * @param[in] start buffer to contain serialized name
+ */
+ uint32_t
+ Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize Name in ndnSIM packet encoding
+ * @param[in] start buffer that contains serialized name
+ */
+ uint32_t
+ Deserialize (Buffer::Iterator start);
+
+ /**
* \brief Returns the size of NameComponents
*/
inline size_t