/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005 INRIA
*
* 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: Wenying Dai <daiwenying927@gmail.com>
*/
#ifndef PATCH_L3_PROTOCOL_H
#define PATCH_L3_PROTOCOL_H
#include "ns3/object.h"
#include "ns3/ptr.h"
#include "ns3/node.h"
#include "ns3/address.h"
namespace ns3 {
/**
* \ingroup patch
* \brief An implementation of the Patch-l3-protocol protocol.
*/
class PatchL3Protocol : public Object
{
public:
static const uint16_t PROT_NUMBER; //!< PATCH protocol number (0x0099)
PatchL3Protocol ();
virtual ~PatchL3Protocol ();
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId (void);
/**
* \brief Set the node the Patch L3 protocol is associated with
* \param node the node
*/
void SetNode (Ptr<Node> node);
/**
* \brief Set the device and Register the protocol handler to the node
* \param device the device the node associated with
*/
void AddDevice (Ptr<NetDevice> device);
/**
* \brief Receive a packet
* \param device the source NetDevice
* \param p the packet
* \param protocol the protocol
* \param from the source address
* \param to the destination address
* \param packetType type of packet (i.e., unicast, multicast, etc.)
*/
void Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to,
NetDevice::PacketType packetType);
/**
* \brief Send a packet
* \param toMac the destination address
* \param data the data to send
*/
void Send (const Address &toMac, uint32_t data);
protected:
virtual void DoDispose (void);
virtual void NotifyNewAggregate ();
private:
Ptr<Node> m_node; //!< node the Patch L3 protocol is associated with
Ptr<NetDevice> m_device;
};
} //namespace ns3
#endif /* PATCH_L3_PROTOCOL_H */
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005 INRIA
*
* 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: Wenying Dai <daiwenying927@gmail.com>
*/
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/traffic-control-layer.h"
#include "patch-l3-protocol.h"
#include "patch-header.h"
namespace ns3{
NS_LOG_COMPONENT_DEFINE ("PatchL3Protocol");
const uint16_t PatchL3Protocol::PROT_NUMBER = 0x0099;
NS_OBJECT_ENSURE_REGISTERED (PatchL3Protocol);
PatchL3Protocol::PatchL3Protocol ()
{
NS_LOG_FUNCTION (this);
}
PatchL3Protocol::~PatchL3Protocol ()
{
NS_LOG_FUNCTION (this);
}
TypeId PatchL3Protocol::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::PatchL3Protocol")
.SetParent<Object> ()
.AddConstructor<PatchL3Protocol> ()
.SetGroupName ("Internet")
;
return tid;
}
void PatchL3Protocol::SetNode (Ptr<Node> node)
{
NS_LOG_FUNCTION (this << node);
m_node = node;
}
void PatchL3Protocol::AddDevice (Ptr<NetDevice> device)
{
NS_LOG_FUNCTION (this << device);
m_device = device;
m_node->RegisterProtocolHandler (MakeCallback (&PatchL3Protocol::Receive, this),
PatchL3Protocol::PROT_NUMBER, device);
}
void PatchL3Protocol::NotifyNewAggregate ()
{
NS_LOG_FUNCTION (this);
if (m_node == 0)
{
Ptr<Node>node = this->GetObject<Node> ();
//verify that it's a valid node and that
//the node was not set before
if (node != 0)
{
this->SetNode (node);
}
}
Object::NotifyNewAggregate ();
}
void PatchL3Protocol::DoDispose (void)
{
NS_LOG_FUNCTION (this);
m_node = 0;
Object::DoDispose ();
}
/*
* to implement the minimal requirement about a ping-like protocol
* the sender need to send a packet with data 0x00 carried in patch-header
* the receiver need to reply a packet with data 0x01 carried in patch-header
* in the receive method we check the validation of the data, if the data neither 0x00 nor 0x01, we consider it was invalid
*/
/*
* this method is called to receive data
*/
void PatchL3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to,
NetDevice::PacketType packetType)
{
NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
Ptr<Packet> packet = p->Copy ();
PatchHeader patchHeader;
// copy the header from the packet
packet->RemoveHeader (patchHeader);
uint32_t data = patchHeader.GetData ();
if(data == 0x00)
{
NS_LOG_INFO("At time " << Simulator::Now ().GetSeconds () << "s" <<
" device " << to << " receive a packet with data " << data <<
" from device " << from);
Send(from, 0x01);
}
else if(data == 0x01)
{
NS_LOG_INFO("At time " << Simulator::Now ().GetSeconds () << "s" <<
" device " << to << " receive a call-back packet with data " << data <<
" from device " << from);
}else
{
NS_LOG_INFO("invalid data " << data);
}
}
/*
* this method is called to send data
*/
void PatchL3Protocol::Send (const Address &toMac, uint32_t data){
NS_LOG_FUNCTION (this << toMac << data);
Ptr<Packet> packet = Create<Packet> ();
PatchHeader patchHeader;
patchHeader.SetData (data);
// copy the header into the packet
packet->AddHeader (patchHeader);
m_device->Send(packet, toMac, PROT_NUMBER);
}
} // namespace ns3
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005 INRIA
*
* 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: Wenying Dai <daiwenying927@gmail.com>
*/
#ifndef PATCH_HEADER_H
#define PATCH_HEADER_H
#include "ns3/header.h"
#include "ns3/address.h"
#include <string>
namespace ns3 {
/**
* \ingroup patch
* \brief The packet header for an Patch packet
*/
class PatchHeader : public Header
{
public:
PatchHeader ();
virtual ~PatchHeader ();
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual void Print (std::ostream &os) const;
virtual uint32_t GetSerializedSize (void) const;
virtual void Serialize (Buffer::Iterator start) const;
virtual uint32_t Deserialize (Buffer::Iterator start);
// allow protocol-specific access to the header data.
void SetData (uint32_t data);
uint32_t GetData (void) const;
private:
uint32_t m_data;
};
} // namespace ns3
#endif /* PATCH_HEADER_H */
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005 INRIA
*
* 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: Wenying Dai <daiwenying927@gmail.com>
*/
#include "ns3/assert.h"
#include "ns3/address-utils.h"
#include "patch-header.h"
#include "ns3/log.h"
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("PatchHeader");
NS_OBJECT_ENSURE_REGISTERED (PatchHeader);
PatchHeader::PatchHeader ()
: m_data (0)
{
NS_LOG_FUNCTION (this);
}
PatchHeader::~PatchHeader ()
{
NS_LOG_FUNCTION (this);
}
TypeId PatchHeader::GetTypeId (void)
{
static TypeId tid = TypeId ("PatchHeader")
.SetParent<Header> ()
.SetGroupName ("Internet")
.AddConstructor<PatchHeader> ()
;
return tid;
}
TypeId PatchHeader::GetInstanceTypeId () const
{
NS_LOG_FUNCTION (this);
return GetTypeId ();
}
uint32_t PatchHeader::GetData () const
{
NS_LOG_FUNCTION (this);
return m_data;
}
void PatchHeader::SetData (uint32_t data)
{
NS_LOG_FUNCTION (this << static_cast<uint32_t> (data));
m_data = data;
}
uint32_t PatchHeader::GetSerializedSize () const
{
NS_LOG_FUNCTION (this);
return 6;
}
void PatchHeader::Serialize (Buffer::Iterator start) const
{
NS_LOG_FUNCTION (this << &start);
// The 2 byte-constant
start.WriteU8 (0xfe);
start.WriteU8 (0xef);
// The data.
start.WriteHtonU32 (m_data);
}
uint32_t PatchHeader::Deserialize (Buffer::Iterator start)
{
uint8_t tmp;
tmp = start.ReadU8 ();
NS_ASSERT (tmp == 0xfe);
tmp = start.ReadU8 ();
NS_ASSERT (tmp == 0xef);
m_data = start.ReadNtohU32 ();
return 6; // the number of bytes consumed.
}
void
PatchHeader::Print (std::ostream &os) const
{
os << "data=" << m_data;
}
} //namespace ns3