blob: f1bbaf5ee59cb664d46b9d97615096dd8ab02aa0 [file] [log] [blame]
/** -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2013, Regents of the University of California
* Alexander Afanasyev
*
* GNU 3.0 license, See the LICENSE file for more information
*
* Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "ndnsim.h"
using namespace std;
#include <ns3/header.h>
#include <ns3/packet.h>
#include <ns3/log.h>
#include "ndnsim/wire-ndnsim.h"
NS_LOG_COMPONENT_DEFINE ("ndn.wire.ndnSIM");
NDN_NAMESPACE_BEGIN
namespace wire {
namespace ndnSIM {
NS_OBJECT_ENSURE_REGISTERED (Interest);
NS_OBJECT_ENSURE_REGISTERED (Data);
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
Interest::Interest ()
: m_interest (Create<ndn::Interest> ())
{
}
Interest::Interest (Ptr<ndn::Interest> interest)
: m_interest (interest)
{
}
Ptr<ndn::Interest>
Interest::GetInterest ()
{
return m_interest;
}
TypeId
Interest::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::ndn::Interest::ndnSIM")
.SetGroupName ("Ndn")
.SetParent<Header> ()
.AddConstructor<Interest> ()
;
return tid;
}
TypeId
Interest::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
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;
}
uint32_t
Interest::GetSerializedSize (void) const
{
size_t size =
1/*version*/ + 1 /*type*/ + 2/*length*/ +
(4/*nonce*/ + 1/*scope*/ + 1/*nack type*/ + 2/*timestamp*/ +
NdnSim::SerializedSizeName (m_interest->GetName ()) +
(2 +
(m_interest->GetExclude () == 0 ? 0 : (1 + NdnSim::SerializedSizeExclude (*m_interest->GetExclude ())))
)/* selectors */ +
(2 + 0)/* options */);
NS_LOG_INFO ("Serialize size = " << size);
return size;
}
void
Interest::Serialize (Buffer::Iterator start) const
{
start.WriteU8 (0x80); // version
start.WriteU8 (0x00); // packet type
start.WriteU16 (GetSerializedSize () - 4);
start.WriteU32 (m_interest->GetNonce ());
start.WriteU8 (m_interest->GetScope ());
start.WriteU8 (m_interest->GetNack ());
NS_ASSERT_MSG (0 <= m_interest->GetInterestLifetime ().ToInteger (Time::S) && m_interest->GetInterestLifetime ().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_interest->GetInterestLifetime ().ToInteger (Time::S)));
NdnSim::SerializeName (start, m_interest->GetName ());
if (m_interest->GetExclude () == 0)
{
start.WriteU16 (0); // no selectors
}
else
{
start.WriteU16 (1 + NdnSim::SerializedSizeExclude (*m_interest->GetExclude ()));
start.WriteU8 (0x01);
NdnSim::SerializeExclude (start, *m_interest->GetExclude ());
}
start.WriteU16 (0); // no options
}
uint32_t
Interest::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
if (i.ReadU8 () != 0x80)
throw new InterestException ();
if (i.ReadU8 () != 0x00)
throw new InterestException ();
i.ReadU16 (); // length, don't need it right now
m_interest->SetNonce (i.ReadU32 ());
m_interest->SetScope (i.ReadU8 ());
m_interest->SetNack (i.ReadU8 ());
m_interest->SetInterestLifetime (Seconds (i.ReadU16 ()));
m_interest->SetName (NdnSim::DeserializeName (i));
uint32_t selectorsLen = i.ReadU16 ();
if (selectorsLen > 0)
{
if (i.ReadU8 () != 0x01) // exclude filter only
throw InterestException ();
m_interest->SetExclude (NdnSim::DeserializeExclude (i));
}
i.ReadU16 ();
NS_ASSERT (GetSerializedSize () == (i.GetDistanceFrom (start)));
return i.GetDistanceFrom (start);
}
void
Interest::Print (std::ostream &os) const
{
m_interest->Print (os);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
TypeId
Data::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::ndn::Data::ndnSIM")
.SetGroupName ("Ndn")
.SetParent<Header> ()
.AddConstructor<Data> ()
;
return tid;
}
TypeId
Data::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
Data::Data ()
: m_data (Create<ndn::Data> ())
{
}
Data::Data (Ptr<ndn::Data> data)
: m_data (data)
{
}
Ptr<ndn::Data>
Data::GetData ()
{
return m_data;
}
Ptr<Packet>
Data::ToWire (Ptr<const ndn::Data> data)
{
Ptr<const Packet> p = data->GetWire ();
if (!p)
{
Ptr<Packet> packet = Create<Packet> (*data->GetPayload ());
Data wireEncoding (ConstCast<ndn::Data> (data));
packet->AddHeader (wireEncoding);
data->SetWire (packet);
p = packet;
}
return p->Copy ();
}
Ptr<ndn::Data>
Data::FromWire (Ptr<Packet> packet)
{
Ptr<ndn::Data> data = Create<ndn::Data> ();
data->SetWire (packet->Copy ());
Data wireEncoding (data);
packet->RemoveHeader (wireEncoding);
data->SetPayload (packet);
return data;
}
uint32_t
Data::GetSerializedSize () const
{
uint32_t size = 1 + 1 + 2 +
((2 + 2) +
NdnSim::SerializedSizeName (m_data->GetName ()) +
(2 + 2 + 4 + 2 + 2 + (2 + 0)));
if (m_data->GetSignature () != 0)
size += 4;
NS_LOG_INFO ("Serialize size = " << size);
return size;
}
void
Data::Serialize (Buffer::Iterator start) const
{
start.WriteU8 (0x80); // version
start.WriteU8 (0x01); // packet type
start.WriteU16 (GetSerializedSize () - 4); // length
if (m_data->GetSignature () != 0)
{
start.WriteU16 (6); // signature length
start.WriteU16 (0xFF00); // "fake" simulator signature
start.WriteU32 (m_data->GetSignature ());
}
else
{
start.WriteU16 (2); // signature length
start.WriteU16 (0); // empty signature
}
// name
NdnSim::SerializeName (start, m_data->GetName ());
// 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_data->GetTimestamp ().ToInteger (Time::S)));
start.WriteU16 (static_cast<uint16_t> (m_data->GetFreshness ().ToInteger (Time::S)));
start.WriteU16 (0); // reserved
start.WriteU16 (0); // Length (ContentInfoOptions)
// that's it folks
}
uint32_t
Data::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
if (i.ReadU8 () != 0x80)
throw new DataException ();
if (i.ReadU8 () != 0x01)
throw new DataException ();
i.ReadU16 (); // length
uint32_t signatureLength = i.ReadU16 ();
if (signatureLength == 6)
{
if (i.ReadU16 () != 0xFF00) // signature type
throw new DataException ();
m_data->SetSignature (i.ReadU32 ());
}
else if (signatureLength == 2)
{
if (i.ReadU16 () != 0) // signature type
throw new DataException ();
m_data->SetSignature (0);
}
else
throw new DataException ();
m_data->SetName (NdnSim::DeserializeName (i));
if (i.ReadU16 () != (2 + 4 + 2 + 2 + (2 + 0))) // content length
throw new DataException ();
if (i.ReadU16 () != (4 + 2 + 2 + (2 + 0))) // Length (content Info)
throw new DataException ();
m_data->SetTimestamp (Seconds (i.ReadU32 ()));
m_data->SetFreshness (Seconds (i.ReadU16 ()));
if (i.ReadU16 () != 0) // Reserved
throw new DataException ();
if (i.ReadU16 () != 0) // Length (ContentInfoOptions)
throw new DataException ();
NS_ASSERT_MSG (i.GetDistanceFrom (start) == GetSerializedSize (),
"Something wrong with Data::Deserialize");
return i.GetDistanceFrom (start);
}
void
Data::Print (std::ostream &os) const
{
m_data->Print (os);
}
} // ndnSIM
} // wire
NDN_NAMESPACE_END