blob: 8d622a49e08b774978a47c1e8343c45e127f02cc [file] [log] [blame]
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2011 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* 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
*
* Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "../ccnb.h"
#include "wire-ccnb.h"
#include "ns3/log.h"
#include "ns3/unused.h"
#include "ns3/packet.h"
#include "ccnb-parser/visitors/name-visitor.h"
#include "ccnb-parser/visitors/non-negative-integer-visitor.h"
#include "ccnb-parser/visitors/timestamp-visitor.h"
#include "ccnb-parser/visitors/uint32t-blob-visitor.h"
#include "ccnb-parser/syntax-tree/block.h"
#include "ccnb-parser/syntax-tree/dtag.h"
#include <boost/foreach.hpp>
NS_LOG_COMPONENT_DEFINE ("ndn.wire.Ccnb.Interest");
NDN_NAMESPACE_BEGIN
namespace wire {
namespace ccnb {
NS_OBJECT_ENSURE_REGISTERED (Interest);
TypeId
Interest::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::ndn::Interest::Ccnb")
.SetGroupName ("Ndn")
.SetParent<Header> ()
.AddConstructor<Interest> ()
;
return tid;
}
TypeId
Interest::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
Interest::Interest ()
: m_interest (Create<ndn::Interest> ())
{
}
Interest::Interest (Ptr<ndn::Interest> interest)
: m_interest (interest)
{
}
Ptr<ndn::Interest>
Interest::GetInterest ()
{
return m_interest;
}
Ptr<Packet>
Interest::ToWire (Ptr<const ndn::Interest> interest)
{
Ptr<const Packet> p = interest->GetWire ();
if (!p)
{
Ptr<Packet> packet = Create<Packet> (*interest->GetPayload ());
Interest wireEncoding (ConstCast<ndn::Interest> (interest));
packet->AddHeader (wireEncoding);
interest->SetWire (packet);
p = packet;
}
return p->Copy ();
}
Ptr<ndn::Interest>
Interest::FromWire (Ptr<Packet> packet)
{
Ptr<ndn::Interest> interest = Create<ndn::Interest> ();
interest->SetWire (packet->Copy ());
Interest wireEncoding (interest);
packet->RemoveHeader (wireEncoding);
interest->SetPayload (packet);
return interest;
}
void
Interest::Serialize (Buffer::Iterator start) const
{
Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Interest, CcnbParser::CCN_DTAG); // <Interest>
Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG); // <Name>
Ccnb::SerializeName (start, m_interest->GetName()); // <Component>...</Component>...
Ccnb::AppendCloser (start); // </Name>
// if (m_interest->GetMinSuffixComponents() >= 0)
// {
// Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_MinSuffixComponents, CcnbParser::CCN_DTAG);
// Ccnb::AppendNumber (start, m_interest->GetMinSuffixComponents ());
// Ccnb::AppendCloser (start);
// }
// if (m_interest->GetMaxSuffixComponents() >= 0)
// {
// Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_MaxSuffixComponents, CcnbParser::CCN_DTAG);
// Ccnb::AppendNumber (start, m_interest->GetMaxSuffixComponents ());
// Ccnb::AppendCloser (start);
// }
// if (m_interest->IsEnabledExclude() && m_interest->GetExclude().size() > 0)
// {
// Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Exclude, CcnbParser::CCN_DTAG); // <Exclude>
// Ccnb::AppendName (start, m_interest->GetExclude()); // <Component>...</Component>...
// Ccnb::AppendCloser (start); // </Exclude>
// }
// if (m_interest->IsEnabledChildSelector())
// {
// Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_ChildSelector, CcnbParser::CCN_DTAG);
// Ccnb::AppendNumber (start, 1);
// Ccnb::AppendCloser (start);
// }
// if (m_interest->IsEnabledAnswerOriginKind())
// {
// Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_AnswerOriginKind, CcnbParser::CCN_DTAG);
// Ccnb::AppendNumber (start, 1);
// Ccnb::AppendCloser (start);
// }
if (m_interest->GetScope() >= 0)
{
Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Scope, CcnbParser::CCN_DTAG);
Ccnb::AppendNumber (start, m_interest->GetScope ());
Ccnb::AppendCloser (start);
}
if (!m_interest->GetInterestLifetime().IsZero())
{
Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_InterestLifetime, CcnbParser::CCN_DTAG);
Ccnb::AppendTimestampBlob (start, m_interest->GetInterestLifetime ());
Ccnb::AppendCloser (start);
}
if (m_interest->GetNonce()>0)
{
uint32_t nonce = m_interest->GetNonce();
Ccnb::AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Nonce, nonce);
}
if (m_interest->GetNack ()>0)
{
Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Nack, CcnbParser::CCN_DTAG);
Ccnb::AppendNumber (start, m_interest->GetNack ());
Ccnb::AppendCloser (start);
}
Ccnb::AppendCloser (start); // </Interest>
}
uint32_t
Interest::GetSerializedSize () const
{
size_t written = 0;
written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Interest); // <Interest>
written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name); // <Name>
written += Ccnb::SerializedSizeName (m_interest->GetName()); // <Component>...</Component>...
written += 1; // </Name>
// if (m_interest->GetMinSuffixComponents() >= 0)
// {
// written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_MinSuffixComponents);
// written += Ccnb::EstimateNumber (m_interest->GetMinSuffixComponents ());
// written += 1;
// }
// if (m_interest->GetMaxSuffixComponents() >= 0)
// {
// written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_MaxSuffixComponents);
// written += Ccnb::EstimateNumber (m_interest->GetMaxSuffixComponents ());
// written += 1;
// }
// if (m_interest->IsEnabledExclude() && m_interest->GetExclude().size() > 0)
// {
// written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Exclude);
// written += Ccnb::EstimateName (m_interest->GetExclude()); // <Component>...</Component>...
// written += 1; // </Exclude>
// }
// if (m_interest->IsEnabledChildSelector())
// {
// written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_ChildSelector);
// written += Ccnb::EstimateNumber (1);
// written += 1;
// }
// if (m_interest->IsEnabledAnswerOriginKind())
// {
// written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_AnswerOriginKind);
// written += Ccnb::EstimateNumber (1);
// written += 1;
// }
if (m_interest->GetScope() >= 0)
{
written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Scope);
written += Ccnb::EstimateNumber (m_interest->GetScope ());
written += 1;
}
if (!m_interest->GetInterestLifetime().IsZero())
{
written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_InterestLifetime);
written += Ccnb::EstimateTimestampBlob (m_interest->GetInterestLifetime());
written += 1;
}
if (m_interest->GetNonce()>0)
{
written += Ccnb::EstimateTaggedBlob (CcnbParser::CCN_DTAG_Nonce, sizeof(uint32_t));
}
if (m_interest->GetNack ()>0)
{
written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Nack);
written += Ccnb::EstimateNumber (m_interest->GetNack ());
written += 1;
}
written += 1; // </Interest>
return written;
}
class InterestVisitor : public CcnbParser::VoidDepthFirstVisitor
{
public:
virtual void visit (CcnbParser::Dtag &n, boost::any param/*should be CcnxInterest* */);
};
// We don't care about any other fields
void
InterestVisitor::visit (CcnbParser::Dtag &n, boost::any param/*should be Interest* */)
{
// uint32_t n.m_dtag;
// std::list<Ptr<Block> > n.m_nestedBlocks;
static CcnbParser::NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
static CcnbParser::NameVisitor nameVisitor;
static CcnbParser::TimestampVisitor timestampVisitor;
static CcnbParser::Uint32tBlobVisitor nonceVisitor;
ndn::Interest &interest = *(boost::any_cast<ndn::Interest*> (param));
switch (n.m_dtag)
{
case CcnbParser::CCN_DTAG_Interest:
NS_LOG_DEBUG ("Interest");
// process nested blocks
BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
{
block->accept (*this, param);
}
break;
case CcnbParser::CCN_DTAG_Name:
{
NS_LOG_DEBUG ("Name");
// process name components
Ptr<Name> name = Create<Name> ();
n.accept (nameVisitor, GetPointer (name));
interest.SetName (name);
break;
}
// case CcnbParser::CCN_DTAG_MinSuffixComponents:
// NS_LOG_DEBUG ("MinSuffixComponents");
// if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
// throw CcnbParser::CcnbDecodingException ();
// interest.SetMinSuffixComponents (
// boost::any_cast<uint32_t> (
// (*n.m_nestedTags.begin())->accept(
// nonNegativeIntegerVisitor
// )));
// break;
// case CcnbParser::CCN_DTAG_MaxSuffixComponents:
// NS_LOG_DEBUG ("MaxSuffixComponents");
// if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
// throw CcnbParser::CcnbDecodingException ();
// interest.SetMaxSuffixComponents (
// boost::any_cast<uint32_t> (
// (*n.m_nestedTags.begin())->accept(
// nonNegativeIntegerVisitor
// )));
// break;
// case CcnbParser::CCN_DTAG_Exclude:
// {
// NS_LOG_DEBUG ("Exclude");
// // process exclude components
// Ptr<Name> exclude = Create<Name> ();
// BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
// {
// block->accept (nameVisitor, &(*exclude));
// }
// interest.SetExclude (exclude);
// break;
// }
// case CcnbParser::CCN_DTAG_ChildSelector:
// NS_LOG_DEBUG ("ChildSelector");
// if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
// throw CcnbParser::CcnbDecodingException ();
// interest.SetChildSelector (
// 1 == boost::any_cast<uint32_t> (
// (*n.m_nestedTags.begin())->accept(
// nonNegativeIntegerVisitor
// )));
// break;
// case CCN_DTAG_AnswerOriginKind:
// NS_LOG_DEBUG ("AnswerOriginKind");
// if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
// throw CcnbParser::CcnbDecodingException ();
// interest.SetAnswerOriginKind (
// 1 == boost::any_cast<uint32_t> (
// (*n.m_nestedTags.begin())->accept(
// nonNegativeIntegerVisitor
// )));
// break;
case CcnbParser::CCN_DTAG_Scope:
NS_LOG_DEBUG ("Scope");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbParser::CcnbDecodingException ();
interest.SetScope (
boost::any_cast<uint32_t> (
(*n.m_nestedTags.begin())->accept(
nonNegativeIntegerVisitor
)));
break;
case CcnbParser::CCN_DTAG_InterestLifetime:
NS_LOG_DEBUG ("InterestLifetime");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbParser::CcnbDecodingException ();
interest.SetInterestLifetime (
boost::any_cast<Time> (
(*n.m_nestedTags.begin())->accept(
timestampVisitor
)));
break;
case CcnbParser::CCN_DTAG_Nonce:
NS_LOG_DEBUG ("Nonce");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbParser::CcnbDecodingException ();
interest.SetNonce (
boost::any_cast<uint32_t> (
(*n.m_nestedTags.begin())->accept(
nonceVisitor
)));
break;
case CcnbParser::CCN_DTAG_Nack:
NS_LOG_DEBUG ("Nack");
if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
throw CcnbParser::CcnbDecodingException ();
interest.SetNack (
boost::any_cast<uint32_t> (
(*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
break;
}
}
uint32_t
Interest::Deserialize (Buffer::Iterator start)
{
static InterestVisitor interestVisitor;
Buffer::Iterator i = start;
Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
root->accept (interestVisitor, GetPointer (m_interest));
return i.GetDistanceFrom (start);
}
void
Interest::Print (std::ostream &os) const
{
os << "I: " << m_interest->GetName ();
return;
// os << "<Interest>\n <Name>" << GetName () << "</Name>\n";
// if (GetNack ()>0)
// {
// os << " <NACK>";
// switch (GetNack ())
// {
// case NACK_LOOP:
// os << "loop";
// break;
// case NACK_CONGESTION:
// os << "congestion";
// break;
// default:
// os << "unknown";
// break;
// }
// 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";
// if ( !GetInterestLifetime ().IsZero() )
// os << " <InterestLifetime>" << GetInterestLifetime () << "</InterestLifetime>\n";
// if (GetNonce ()>0)
// os << " <Nonce>" << GetNonce () << "</Nonce>\n";
// os << "</Interest>";
}
} // ccnb
} // wire
NDN_NAMESPACE_END