6LoWPAN module
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -81,6 +81,7 @@ Marco Miozzo (mmiozzo@cttc.es)
|
||||
Faker Moatamri (faker.moatamri@inria.fr)
|
||||
Edvin Močibob <edvin.mocibob@gmail.com>
|
||||
Mike Moreton (mjvm_ns@hotmail.com)
|
||||
Michele Muccio <michelemuccio@virgilio.it>
|
||||
Sidharth Nabar (snabar@uw.edu)
|
||||
Hemanth Narra (hemanth@ittc.ku.edu)
|
||||
Andreas Nilsson <andrnils@gmail.com>
|
||||
|
||||
@@ -80,6 +80,15 @@ us a note on ns-developers mailing list.</p>
|
||||
their simulation program. The imlpementation previously
|
||||
provided by the EpcHelper class has been moved to the new
|
||||
derived class PointToPointEpcHelper.</li>
|
||||
<li>New SixLowPanNetDevice class providing a shim between
|
||||
IPv6 and real NetDevices. The new module implements 6LoWPAN:
|
||||
"Transmission of IPv6 Packets over IEEE 802.15.4 Networks" (see
|
||||
<a href="http://www.ietf.org/rfc/rfc4944.txt">RFC 4944</a> and
|
||||
<a href="http://www.ietf.org/rfc/rfc6262.txt">RFC 6262</a>),
|
||||
resulting in a heavy header compression for IPv6 packets.
|
||||
The module is intended to be used on 802.15.4 NetDevices, but
|
||||
it can be used over other NetDevices. See the manual for
|
||||
further discussion.</li>
|
||||
</ul>
|
||||
<h2>Changes to build system:</h2>
|
||||
|
||||
|
||||
@@ -21,6 +21,12 @@ Supported platforms
|
||||
|
||||
New user-visible features
|
||||
-------------------------
|
||||
- new SixLowPanNetDevice model, headers and associated helpers. The
|
||||
SixLowPanNetDevice is able to act as a shim between IPv6 and a NetDevice,
|
||||
compressing IPv6 headers according to RFCs 4944 and 6262.
|
||||
The SixLowPanNetDevice is meant to be used over 802.15.4 NetDevices,
|
||||
but it can be used on other NetDevices as well (see the manual for full
|
||||
details).
|
||||
|
||||
- A new wifi extension for vehicular simulation support is available in src/wave
|
||||
directory. The current code represents an interim capability to realize an
|
||||
|
||||
@@ -79,6 +79,7 @@ SOURCES = \
|
||||
$(SRC)/netanim/doc/animation.rst \
|
||||
$(SRC)/flow-monitor/doc/flow-monitor.rst \
|
||||
$(SRC)/wave/doc/wave.rst \
|
||||
$(SRC)/sixlowpan/doc/sixlowpan.rst \
|
||||
|
||||
# list all model library figure files that need to be copied to
|
||||
# $SOURCETEMP/figures. For each figure to be included in all
|
||||
|
||||
@@ -33,7 +33,8 @@ NS_OBJECT_ENSURE_REGISTERED (UdpHeader)
|
||||
UdpHeader::UdpHeader ()
|
||||
: m_sourcePort (0xfffd),
|
||||
m_destinationPort (0xfffd),
|
||||
m_payloadSize (0xfffd),
|
||||
m_payloadSize (0),
|
||||
m_checksum (0),
|
||||
m_calcChecksum (false),
|
||||
m_goodChecksum (true)
|
||||
{
|
||||
@@ -108,7 +109,7 @@ UdpHeader::CalculateHeaderChecksum (uint16_t size) const
|
||||
|
||||
WriteTo (it, m_source);
|
||||
WriteTo (it, m_destination);
|
||||
if (Ipv4Address::IsMatchingType(m_source))
|
||||
if (Ipv4Address::IsMatchingType (m_source))
|
||||
{
|
||||
it.WriteU8 (0); /* protocol */
|
||||
it.WriteU8 (m_protocol); /* protocol */
|
||||
@@ -116,7 +117,7 @@ UdpHeader::CalculateHeaderChecksum (uint16_t size) const
|
||||
it.WriteU8 (size & 0xff); /* length */
|
||||
hdrSize = 12;
|
||||
}
|
||||
else if (Ipv6Address::IsMatchingType(m_source))
|
||||
else if (Ipv6Address::IsMatchingType (m_source))
|
||||
{
|
||||
it.WriteU16 (0);
|
||||
it.WriteU8 (size >> 8); /* length */
|
||||
@@ -138,6 +139,17 @@ UdpHeader::IsChecksumOk (void) const
|
||||
return m_goodChecksum;
|
||||
}
|
||||
|
||||
void
|
||||
UdpHeader::ForceChecksum (uint16_t checksum)
|
||||
{
|
||||
m_checksum = checksum;
|
||||
}
|
||||
|
||||
void
|
||||
UdpHeader::ForcePayloadSize (uint16_t payloadSize)
|
||||
{
|
||||
m_payloadSize = payloadSize;
|
||||
}
|
||||
|
||||
TypeId
|
||||
UdpHeader::GetTypeId (void)
|
||||
@@ -175,18 +187,33 @@ UdpHeader::Serialize (Buffer::Iterator start) const
|
||||
|
||||
i.WriteHtonU16 (m_sourcePort);
|
||||
i.WriteHtonU16 (m_destinationPort);
|
||||
i.WriteHtonU16 (start.GetSize ());
|
||||
i.WriteU16 (0);
|
||||
|
||||
if (m_calcChecksum)
|
||||
if (m_payloadSize == 0)
|
||||
{
|
||||
uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ());
|
||||
i = start;
|
||||
uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksum);
|
||||
i.WriteHtonU16 (start.GetSize ());
|
||||
}
|
||||
else
|
||||
{
|
||||
i.WriteHtonU16 (m_payloadSize);
|
||||
}
|
||||
|
||||
i = start;
|
||||
i.Next (6);
|
||||
i.WriteU16 (checksum);
|
||||
if ( m_checksum == 0)
|
||||
{
|
||||
i.WriteU16 (0);
|
||||
|
||||
if (m_calcChecksum)
|
||||
{
|
||||
uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ());
|
||||
i = start;
|
||||
uint16_t checksum = i.CalculateIpChecksum (start.GetSize (), headerChecksum);
|
||||
|
||||
i = start;
|
||||
i.Next (6);
|
||||
i.WriteU16 (checksum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i.WriteU16 (m_checksum);
|
||||
}
|
||||
}
|
||||
uint32_t
|
||||
@@ -196,9 +223,9 @@ UdpHeader::Deserialize (Buffer::Iterator start)
|
||||
m_sourcePort = i.ReadNtohU16 ();
|
||||
m_destinationPort = i.ReadNtohU16 ();
|
||||
m_payloadSize = i.ReadNtohU16 () - GetSerializedSize ();
|
||||
i.Next (2);
|
||||
m_checksum = i.ReadU16 ();
|
||||
|
||||
if(m_calcChecksum)
|
||||
if (m_calcChecksum)
|
||||
{
|
||||
uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ());
|
||||
i = start;
|
||||
@@ -210,5 +237,10 @@ UdpHeader::Deserialize (Buffer::Iterator start)
|
||||
return GetSerializedSize ();
|
||||
}
|
||||
|
||||
uint16_t
|
||||
UdpHeader::GetChecksum ()
|
||||
{
|
||||
return m_checksum;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -131,6 +131,41 @@ public:
|
||||
*/
|
||||
bool IsChecksumOk (void) const;
|
||||
|
||||
/**
|
||||
* \brief Force the UDP checksum to a given value.
|
||||
*
|
||||
* This might be useful for test purposes or to
|
||||
* restore the UDP checksum when the UDP header
|
||||
* has been compressed (e.g., in 6LoWPAN).
|
||||
* Note that, normally, the header checksum is
|
||||
* calculated on the fly when the packet is
|
||||
* serialized.
|
||||
*
|
||||
* When this option is used, the UDP checksum is written in
|
||||
* the header, regardless of the global ChecksumEnabled option.
|
||||
*
|
||||
* \note The checksum value must be a big endian number.
|
||||
*
|
||||
* \param checksum the checksum to use (big endian).
|
||||
*/
|
||||
void ForceChecksum (uint16_t checksum);
|
||||
|
||||
/**
|
||||
* \brief Force the UDP payload length to a given value.
|
||||
*
|
||||
* This might be useful when forging a packet for test
|
||||
* purposes.
|
||||
*
|
||||
* \param payloadSize the payload length to use.
|
||||
*/
|
||||
void ForcePayloadSize (uint16_t payloadSize);
|
||||
|
||||
/**
|
||||
* \brief Return the checksum (only known after a Deserialize)
|
||||
* \return The checksum for this UdpHeader
|
||||
*/
|
||||
uint16_t GetChecksum ();
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Calculate the header checksum
|
||||
@@ -145,6 +180,7 @@ private:
|
||||
Address m_source; //!< Source IP address
|
||||
Address m_destination; //!< Destination IP address
|
||||
uint8_t m_protocol; //!< Protocol number
|
||||
uint16_t m_checksum; //!< Forced Checksum value
|
||||
bool m_calcChecksum; //!< Flag to calculate checksum
|
||||
bool m_goodChecksum; //!< Flag to indicate that checksum is correct
|
||||
};
|
||||
|
||||
147
src/sixlowpan/doc/sixlowpan.rst
Normal file
147
src/sixlowpan/doc/sixlowpan.rst
Normal file
@@ -0,0 +1,147 @@
|
||||
PageBreak
|
||||
|
||||
Transmission of IPv6 Packets over IEEE 802.15.4 Networks (6LoWPAN)
|
||||
------------------------------------------------------------------
|
||||
|
||||
This chapter describes the implementation of |ns3| model for the
|
||||
compression of IPv6 packets over IEEE 802.15.4-Based Networks
|
||||
as specified by RFC 4944 and RFC 6262.
|
||||
|
||||
Model Description
|
||||
*****************
|
||||
|
||||
The source code for the sixlowpan module lives in the directory ``src/sixlowpan``.
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
The model design does not follow strictly the standard from an architectural
|
||||
standpoint, as it does extend it beyond the original scope by supporting also
|
||||
other kinds of networks.
|
||||
|
||||
Other than that, the module strictly follows RFCs 4944 and 6262, with the
|
||||
following exceptions:
|
||||
* MESH and LOWPAN_BC0 dispatch types are not supported
|
||||
* HC2 encoding is not supported
|
||||
* IPHC's SAC and DAC are not supported
|
||||
|
||||
The MESH and LOWPAN_BC0 are not supported as they do apply only to mesh-under
|
||||
architecture, which is not one of the goals of the module development.
|
||||
|
||||
The HC2 encoding is not supported, as it has been superseded by IPHC and NHC
|
||||
compression type (RFC 6262).
|
||||
|
||||
IPHC SAC and DAC are not yet supported, as they do require RFC 6775 for full
|
||||
compliance. It is planned to support them in the future.
|
||||
|
||||
NetDevice
|
||||
#########
|
||||
|
||||
The whole module is developed as a transparent NetDevice, which can act as a
|
||||
proxy between IPv6 and any NetDevice (the module has been successfully tested
|
||||
with PointToPointNedevice, CsmaNetDevice and LrWpanNetDevice).
|
||||
|
||||
For this reason, the module implements a virtual NetDevice, and all the calls are passed
|
||||
without modifications to the underlying NetDevice. The only important difference is in
|
||||
GetMtu behaviour. It will always return *at least* 1280 bytes, as is the minumum IPv6 MTU.
|
||||
|
||||
The module does provide some attributes and some tracesources.
|
||||
The attributes are:
|
||||
* Rfc6282 (boolean, default true), used to activate HC1 (RFC 4944) or IPHC (RFC 6282) compression.
|
||||
* OmitUdpChecksum (boolean, default true), used to activate UDP checksum compression in IPHC.
|
||||
* FragmentReassemblyListSize (integer, default 0), indicating the number of packets that can be reassembled at the same time. If the limit is reached, the oldest packet is discarded. Zero means infinite.
|
||||
* FragmentExpirationTimeout (Time, default 60 seconds), being the timeout to wait for further fragments before discarding a partial packet.
|
||||
* ForceEtherType (boolean, default false), and
|
||||
* EtherType (unsigned 16 bits integer, default 0xFFFF), to force a particular L2 EtherType.
|
||||
|
||||
The last two attributes are needed to use the module with a NetDevice other than 802.15.4, as
|
||||
neither IANA or IEEE did reserve an EtherType for 6LoWPAN. As a consequence there might be a
|
||||
conflict with the L2 multiplexer/demultiplexer which is based on EtherType. The default
|
||||
value is 0xFFFF, which is reserved by IEEE.
|
||||
The default module behaviour is to not change the EtherType, however this would not work with
|
||||
any NetDevice actually understanding and using the EtherType.
|
||||
|
||||
Note that the `ForceEtherType` parameter have also a direct effect on the MAC address kind the
|
||||
module is expecting to handle:
|
||||
* ForceEtherType true: Mac48Address (Ethernet, WiFi, etc.).
|
||||
* ForceEtherType false: Mac16Address or Mac64Address (IEEE 802.15.4).
|
||||
|
||||
Note that using 6LoWPAN over any NetDevice other than 802.15.4 will produce valid .pcap files,
|
||||
but they will not be correctly dissected by Wireshark.
|
||||
The reason lies on the fact that 6LoWPAN was really meant to be used only over 802.15.4, so
|
||||
Wireshark dissectors will not even try to decode 6LoWPAN headers on top of protocols other than
|
||||
802.15.4.
|
||||
|
||||
The Trace sources are:
|
||||
* Tx - exposing packet (including 6LoWPAN header), SixLoWPanNetDevice Ptr, interface index.
|
||||
* Rx - exposing packet (including 6LoWPAN header), SixLoWPanNetDevice Ptr, interface index.
|
||||
* Drop - exposing DropReason, packet (including 6LoWPAN header), SixLoWPanNetDevice Ptr, interface index.
|
||||
|
||||
The Tx and Rx traces are called as soon as a packet is received or sent. The Drop trace is
|
||||
invoked when a packet (or a fragment) is discarded.
|
||||
|
||||
|
||||
Scope and Limitations
|
||||
=====================
|
||||
|
||||
Future versions of this module will support RFC 6775, however no timeframe is guaranteed.
|
||||
|
||||
Using 6LoWPAN with IPv4 (or other L3 protocols)
|
||||
###############################################
|
||||
|
||||
As the name implies, 6LoWPAN can handle only IPv6 packets. Any other protocol will be discarded.
|
||||
Moreover, 6LoWPAN assumes that the network is uniform, as is all the devices connected by the
|
||||
same same channel are using 6LoWPAN. Mixed environments are not supported by the standard.
|
||||
The reason is simple: 802.15.4 frame doesn't have a "protocol" field. As a consequence,
|
||||
there is no demultiplexing at MAC layer and the protocol carried by L2 frames must be known
|
||||
in advance.
|
||||
|
||||
In the |ns3| implementation it is possible, but not advisable, to violate this requirement
|
||||
if the underlying NetDevice is capable of discriminating different protocols. As an example,
|
||||
CsmaNetDevice can carry IPv4 and 6LoWPAN at the same time. However, this configuration has
|
||||
not been tested.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
* RFC 4944, "Transmission of IPv6 Packets over IEEE 802.15.4 Networks".
|
||||
* RFC 6282, "Compression Format for IPv6 Datagrams over IEEE 802.15.4-Based Networks".
|
||||
* http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xml
|
||||
* http://standards.ieee.org/develop/regauth/ethertype/eth.txt
|
||||
|
||||
Usage
|
||||
*****
|
||||
|
||||
Enabling sixlowpan
|
||||
==================
|
||||
|
||||
Add ``sixlowpan`` to the list of modules built with |ns3|.
|
||||
|
||||
Helper
|
||||
======
|
||||
|
||||
The helper is patterned after other device helpers.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
The following example can be found in ``src/sixlowpan/examples/``:
|
||||
|
||||
* ``example-sixlowpan.cc``: A simple example showing end-to-end data transfer.
|
||||
|
||||
In particular, the example enables a very simplified end-to-end data
|
||||
transfer scenario, with a CSMA network forced to carry 6LoWPAN compressed packets.
|
||||
|
||||
|
||||
Tests
|
||||
=====
|
||||
|
||||
The test provided checks the connection between two UDP clients and the correctness of the received packets.
|
||||
|
||||
Validation
|
||||
**********
|
||||
|
||||
The model has been validated against WireShark, checking whatever the packets are correctly
|
||||
interpreted and validated.
|
||||
|
||||
|
||||
139
src/sixlowpan/examples/example-sixlowpan.cc
Normal file
139
src/sixlowpan/examples/example-sixlowpan.cc
Normal file
@@ -0,0 +1,139 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
|
||||
// Network topology
|
||||
//
|
||||
// n0 n1
|
||||
// +---------+ +--------+
|
||||
// | UDP | r | UDP |
|
||||
// +---------+ +---------+--------+ +--------+
|
||||
// | IPv6 | | IPv6 | IPv6 | | IPv6 |
|
||||
// +---------+ +---------+ | | |
|
||||
// | 6LoWPAN | | 6LoWPAN | | | |
|
||||
// +---------+ +---------+--------+ +--------+
|
||||
// | CSMA | | CSMA | CSMA | | CSMA |
|
||||
// +---------+ +---------+--------+ +--------+
|
||||
// | | | |
|
||||
// ================ =================
|
||||
//
|
||||
// - Tracing of queues and packet receptions to file "example-sixlowpan.tr"
|
||||
// Note that the Pcap packet dissection will not be very meaningful.
|
||||
// See the module's documentation for a discussion about this.
|
||||
|
||||
#include <fstream>
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/internet-module.h"
|
||||
#include "ns3/csma-module.h"
|
||||
#include "ns3/applications-module.h"
|
||||
#include "ns3/ipv6-static-routing-helper.h"
|
||||
|
||||
#include "ns3/ipv6-routing-table-entry.h"
|
||||
#include "ns3/sixlowpan-module.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("ExampleSixlowpan")
|
||||
;
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
bool verbose = false;
|
||||
|
||||
CommandLine cmd;
|
||||
cmd.AddValue ("verbose", "turn on some relevant log components", verbose);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
LogComponentEnable ("SixLowPanNetDevice", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
|
||||
}
|
||||
|
||||
Packet::EnablePrinting ();
|
||||
Packet::EnableChecking ();
|
||||
|
||||
NS_LOG_INFO ("Create nodes.");
|
||||
Ptr<Node> n0 = CreateObject<Node> ();
|
||||
Ptr<Node> r = CreateObject<Node> ();
|
||||
Ptr<Node> n1 = CreateObject<Node> ();
|
||||
|
||||
|
||||
NodeContainer net1 (n0, r);
|
||||
NodeContainer net2 (r, n1);
|
||||
NodeContainer all (n0, r, n1);
|
||||
|
||||
NS_LOG_INFO ("Create IPv6 Internet Stack");
|
||||
InternetStackHelper internetv6;
|
||||
internetv6.Install (all);
|
||||
|
||||
NS_LOG_INFO ("Create channels.");
|
||||
CsmaHelper csma;
|
||||
csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
|
||||
csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
|
||||
NetDeviceContainer d2 = csma.Install (net2);
|
||||
csma.SetDeviceAttribute ("Mtu", UintegerValue (150));
|
||||
NetDeviceContainer d1 = csma.Install (net1);
|
||||
|
||||
SixLowPanHelper sixlowpan;
|
||||
sixlowpan.SetDeviceAttribute ("ForceEtherType", BooleanValue (true) );
|
||||
NetDeviceContainer six1 = sixlowpan.Install (d1);
|
||||
|
||||
NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
|
||||
Ipv6AddressHelper ipv6;
|
||||
ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
|
||||
Ipv6InterfaceContainer i1 = ipv6.Assign (six1);
|
||||
i1.SetForwarding (1, true);
|
||||
i1.SetDefaultRouteInAllNodes (1);
|
||||
|
||||
ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
|
||||
Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
|
||||
i2.SetForwarding (0, true);
|
||||
i2.SetDefaultRouteInAllNodes (0);
|
||||
|
||||
/* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via r */
|
||||
uint32_t packetSize = 200;
|
||||
uint32_t maxPacketCount = 50;
|
||||
Time interPacketInterval = Seconds (1.);
|
||||
Ping6Helper ping6;
|
||||
|
||||
ping6.SetLocal (i1.GetAddress (0, 1));
|
||||
ping6.SetRemote (i2.GetAddress (1, 1));
|
||||
|
||||
ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
|
||||
ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
|
||||
ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
|
||||
ApplicationContainer apps = ping6.Install (net1.Get (0));
|
||||
|
||||
apps.Start (Seconds (5.0));
|
||||
apps.Stop (Seconds (15.0));
|
||||
|
||||
|
||||
AsciiTraceHelper ascii;
|
||||
csma.EnableAsciiAll (ascii.CreateFileStream ("example-sixlowpan.tr"));
|
||||
csma.EnablePcapAll (std::string ("example-sixlowpan"), true);
|
||||
|
||||
Simulator::Stop (Seconds (100));
|
||||
NS_LOG_INFO ("Run Simulation.");
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
NS_LOG_INFO ("Done.");
|
||||
}
|
||||
|
||||
9
src/sixlowpan/examples/wscript
Normal file
9
src/sixlowpan/examples/wscript
Normal file
@@ -0,0 +1,9 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
if not bld.env['ENABLE_EXAMPLES']:
|
||||
return;
|
||||
|
||||
obj = bld.create_ns3_program('example-sixlowpan',
|
||||
['network', 'sixlowpan', 'internet', 'csma'])
|
||||
obj.source = 'example-sixlowpan.cc'
|
||||
83
src/sixlowpan/helper/sixlowpan-helper.cc
Normal file
83
src/sixlowpan/helper/sixlowpan-helper.cc
Normal file
@@ -0,0 +1,83 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
#include "sixlowpan-helper.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/sixlowpan-net-device.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/names.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("SixLowPanHelper")
|
||||
;
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
SixLowPanHelper::SixLowPanHelper ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_deviceFactory.SetTypeId ("ns3::SixLowPanNetDevice");
|
||||
}
|
||||
|
||||
void SixLowPanHelper::SetDeviceAttribute (std::string n1,
|
||||
const AttributeValue &v1)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_deviceFactory.Set (n1, v1);
|
||||
}
|
||||
|
||||
NetDeviceContainer SixLowPanHelper::Install (const NetDeviceContainer c)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
NetDeviceContainer devs;
|
||||
|
||||
for (uint32_t i = 0; i < c.GetN (); ++i)
|
||||
{
|
||||
Ptr<NetDevice> device = c.Get (i);
|
||||
NS_ASSERT_MSG (device != 0, "No NetDevice found in the node " << int(i) );
|
||||
|
||||
Ptr<Node> node = device->GetNode ();
|
||||
NS_LOG_LOGIC ("**** Install 6LoWPAN on node " << node->GetId ());
|
||||
|
||||
Ptr<SixLowPanNetDevice> dev = m_deviceFactory.Create<SixLowPanNetDevice> ();
|
||||
devs.Add (dev);
|
||||
node->AddDevice (dev);
|
||||
dev->SetNetDevice (device);
|
||||
}
|
||||
return devs;
|
||||
}
|
||||
|
||||
int64_t SixLowPanHelper::AssignStreams (NetDeviceContainer c, int64_t stream)
|
||||
{
|
||||
int64_t currentStream = stream;
|
||||
Ptr<NetDevice> netDevice;
|
||||
for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
|
||||
{
|
||||
netDevice = (*i);
|
||||
Ptr<SixLowPanNetDevice> dev = DynamicCast<SixLowPanNetDevice> (netDevice);
|
||||
if (dev)
|
||||
{
|
||||
currentStream += dev->AssignStreams (currentStream);
|
||||
}
|
||||
}
|
||||
return (currentStream - stream);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
102
src/sixlowpan/helper/sixlowpan-helper.h
Normal file
102
src/sixlowpan/helper/sixlowpan-helper.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_HELPER_H
|
||||
#define SIXLOWPAN_HELPER_H
|
||||
|
||||
#include "ns3/net-device-container.h"
|
||||
#include "ns3/object-factory.h"
|
||||
#include <string>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Node;
|
||||
class AttributeValue;
|
||||
|
||||
/**
|
||||
* \ingroup sixlowpan
|
||||
*
|
||||
* \brief Setup a sixlowpan stack to be used as a shim between IPv6 and a generic NetDevice.
|
||||
*/
|
||||
class SixLowPanHelper
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* Construct a SixlowpanHelper
|
||||
*/
|
||||
SixLowPanHelper ();
|
||||
/**
|
||||
* Set an attribute on each ns3::SixlowpanNetDevice created by
|
||||
* SixlowpanHelper::Install.
|
||||
*
|
||||
* \param n1 the name of the attribute to set
|
||||
* \param v1 the value of the attribute to set
|
||||
*/
|
||||
void SetDeviceAttribute (std::string n1,
|
||||
const AttributeValue &v1);
|
||||
|
||||
/**
|
||||
* \brief Install the SixLoWPAN stack on top of an existing NetDevice.
|
||||
*
|
||||
* This function requires a set of properly configured NetDevices
|
||||
* passed in as the parameter "c". The new NetDevices will have to
|
||||
* be used instead of the original ones. In this way these
|
||||
* SixLoWPAN devices will behave as shims between the NetDevices
|
||||
* passed in and IPv6.
|
||||
*
|
||||
* Note that only IPv6 (and related protocols, such as ICMPv6) can
|
||||
* be transmitted over a 6LoWPAN interface.
|
||||
* Any other protocol (e.g., IPv4) will be discarded by 6LoWPAN.
|
||||
*
|
||||
* Other protocols (e.g., IPv4) could be used on the original NetDevices
|
||||
* with some limitations.
|
||||
* See the manual for a complete discussion.
|
||||
*
|
||||
* \note IPv6 stack must be installed \a after SixLoWPAN,
|
||||
* using the SixLoWPAN NetDevices. See the example in the
|
||||
* examples directory.
|
||||
*
|
||||
*
|
||||
* \param c the NetDevice container
|
||||
* \return a container with the newly created SixLowPanNetDevices
|
||||
*/
|
||||
NetDeviceContainer Install (NetDeviceContainer c);
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams (possibly zero) that
|
||||
* have been assigned. The Install() method should have previously been
|
||||
* called by the user.
|
||||
*
|
||||
* \param c NetDeviceContainer of the set of net devices for which the
|
||||
* SixLowPanNetDevice should be modified to use a fixed stream
|
||||
* \param stream first stream index to use
|
||||
* \return the number of stream indices assigned by this helper
|
||||
*/
|
||||
int64_t AssignStreams (NetDeviceContainer c, int64_t stream);
|
||||
|
||||
private:
|
||||
ObjectFactory m_deviceFactory; //!< Object factory
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#endif /* SIXLOWPAN_HELPER_H */
|
||||
1747
src/sixlowpan/model/sixlowpan-header.cc
Normal file
1747
src/sixlowpan/model/sixlowpan-header.cc
Normal file
File diff suppressed because it is too large
Load Diff
1214
src/sixlowpan/model/sixlowpan-header.h
Normal file
1214
src/sixlowpan/model/sixlowpan-header.h
Normal file
File diff suppressed because it is too large
Load Diff
2118
src/sixlowpan/model/sixlowpan-net-device.cc
Normal file
2118
src/sixlowpan/model/sixlowpan-net-device.cc
Normal file
File diff suppressed because it is too large
Load Diff
455
src/sixlowpan/model/sixlowpan-net-device.h
Normal file
455
src/sixlowpan/model/sixlowpan-net-device.h
Normal file
@@ -0,0 +1,455 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
* Michele Muccio <michelemuccio@virgilio.it>
|
||||
*/
|
||||
|
||||
#ifndef SIXLOWPAN_NET_DEVICE_H
|
||||
#define SIXLOWPAN_NET_DEVICE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "ns3/traced-callback.h"
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "sixlowpan-header.h"
|
||||
#include "ns3/random-variable-stream.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Node;
|
||||
|
||||
/**
|
||||
* \defgroup sixlowpan 6LoWPAN
|
||||
* \brief Performs 6LoWPAN compression of IPv6 packets as specified by RFC 4944 and RFC 6262
|
||||
*
|
||||
* This module acts as a shim between IPv6 and a generic NetDevice.
|
||||
*
|
||||
* The module implements RFCs 4944 and 6262, with the following exceptions:
|
||||
* <ul>
|
||||
* <li> MESH and LOWPAN_BC0 dispatch types are not supported </li>
|
||||
* <li> HC2 encoding is not supported </li>
|
||||
* <li> IPHC's SAC and DAC are not supported </li>
|
||||
*</ul>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \ingroup sixlowpan
|
||||
*
|
||||
* \brief Shim performing 6LoWPAN compression, decompression and fragmentation.
|
||||
*
|
||||
* This class implements the shim between IPv6 and a generic NetDevice,
|
||||
* performing packet compression, decompression and fragmentation in a transparent way.
|
||||
* To this end, the class pretend to be a normal NetDevice, masquerading some functions
|
||||
* of the underlying NetDevice.
|
||||
*/
|
||||
class SixLowPanNetDevice : public NetDevice
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Enumeration of the dropping reasons in SixLoWPAN.
|
||||
*/
|
||||
enum DropReason
|
||||
{
|
||||
DROP_FRAGMENT_TIMEOUT = 1, /**< Fragment timeout exceeded */
|
||||
DROP_FRAGMENT_BUFFER_FULL, /**< Fragment buffer size exceeded */
|
||||
DROP_UNKNOWN_EXTENSION /**< Unsupported compression kind */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* Constructor for the SixLowPanNetDevice.
|
||||
*/
|
||||
SixLowPanNetDevice ();
|
||||
|
||||
// inherited from NetDevice base class
|
||||
virtual void SetIfIndex (const uint32_t index);
|
||||
virtual uint32_t GetIfIndex (void) const;
|
||||
virtual Ptr<Channel> GetChannel (void) const;
|
||||
virtual void SetAddress (Address address);
|
||||
virtual Address GetAddress (void) const;
|
||||
virtual bool SetMtu (const uint16_t mtu);
|
||||
|
||||
/**
|
||||
* \brief Returns the link-layer MTU for this interface.
|
||||
* If the link-layer MTU is smaller than IPv6's minimum MTU (RFC 4944),
|
||||
* 1280 will be returned.
|
||||
*
|
||||
* \return the link-level MTU in bytes for this interface.
|
||||
*/
|
||||
virtual uint16_t GetMtu (void) const;
|
||||
virtual bool IsLinkUp (void) const;
|
||||
virtual void AddLinkChangeCallback (Callback<void> callback);
|
||||
virtual bool IsBroadcast (void) const;
|
||||
virtual Address GetBroadcast (void) const;
|
||||
virtual bool IsMulticast (void) const;
|
||||
virtual Address GetMulticast (Ipv4Address multicastGroup) const;
|
||||
virtual bool IsPointToPoint (void) const;
|
||||
virtual bool IsBridge (void) const;
|
||||
virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
|
||||
virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
|
||||
virtual Ptr<Node> GetNode (void) const;
|
||||
virtual void SetNode (Ptr<Node> node);
|
||||
virtual bool NeedsArp (void) const;
|
||||
virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
|
||||
virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
|
||||
virtual bool SupportsSendFrom () const;
|
||||
virtual Address GetMulticast (Ipv6Address addr) const;
|
||||
|
||||
/**
|
||||
* \brief Returns a smart pointer to the underlying NetDevice.
|
||||
*
|
||||
* \return a smart pointer to the underlying NetDevice.
|
||||
*/
|
||||
Ptr<NetDevice> GetNetDevice () const;
|
||||
|
||||
/**
|
||||
* \brief Setup SixLowPan to be a proxy for the specified NetDevice.
|
||||
* All the packets incoming and outgoing from the NetDevice will be
|
||||
* processed by SixLowPanNetDevice.
|
||||
*
|
||||
* \param device a smart pointer to the NetDevice to be proxied.
|
||||
*/
|
||||
void SetNetDevice (Ptr<NetDevice> device);
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams (possibly zero) that
|
||||
* have been assigned.
|
||||
*
|
||||
* \param stream first stream index to use
|
||||
* \return the number of stream indices assigned by this model
|
||||
*/
|
||||
int64_t AssignStreams (int64_t stream);
|
||||
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief receives all the packets from a NetDevice for further processing.
|
||||
* \param device the NetDevice the packet ws received from
|
||||
* \param packet the received packet
|
||||
* \param protocol the protocol (if known)
|
||||
* \param source the source address
|
||||
* \param destination the destination address
|
||||
* \param packetType the packet kind (e.g., HOST, BROADCAST, etc.)
|
||||
* \return the IPv6 link-local address
|
||||
*/
|
||||
void ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
|
||||
Address const &source, Address const &destination, PacketType packetType);
|
||||
|
||||
/**
|
||||
* The callback used to notify higher layers that a packet has been received.
|
||||
*/
|
||||
NetDevice::ReceiveCallback m_rxCallback;
|
||||
|
||||
/**
|
||||
* The callback used to notify higher layers that a packet has been received in promiscuous mode.
|
||||
*/
|
||||
NetDevice::PromiscReceiveCallback m_promiscRxCallback;
|
||||
|
||||
/**
|
||||
* \brief Callback to trace TX (transmission) packets.
|
||||
*
|
||||
* Data passed:
|
||||
* \li Packet received (including 6LoWPAN header)
|
||||
* \li Ptr to SixLowPanNetDevice
|
||||
* \li interface index
|
||||
*/
|
||||
TracedCallback<Ptr<const Packet>, Ptr<SixLowPanNetDevice>, uint32_t> m_txTrace;
|
||||
|
||||
/**
|
||||
* \brief Callback to trace RX (reception) packets.
|
||||
*
|
||||
* Data passed:
|
||||
* \li Packet received (including 6LoWPAN header)
|
||||
* \li Ptr to SixLowPanNetDevice
|
||||
* \li interface index
|
||||
*/
|
||||
TracedCallback<Ptr<const Packet>, Ptr<SixLowPanNetDevice>, uint32_t> m_rxTrace;
|
||||
|
||||
/**
|
||||
* \brief Callback to trace drop packets.
|
||||
*
|
||||
* Data passed:
|
||||
* \li DropReason
|
||||
* \li Packet dropped (including 6LoWPAN header)
|
||||
* \li Ptr to SixLowPanNetDevice
|
||||
* \li interface index
|
||||
*/
|
||||
TracedCallback<DropReason, Ptr<const Packet>, Ptr<SixLowPanNetDevice>, uint32_t> m_dropTrace;
|
||||
|
||||
/**
|
||||
* \brief make a link-local address from a MAC address.
|
||||
* \param addr the MAC address
|
||||
* \return the IPv6 link-local address
|
||||
*/
|
||||
Ipv6Address MakeLinkLocalAddressFromMac (Address const &addr);
|
||||
|
||||
/**
|
||||
* \brief make a global address from a MAC address.
|
||||
* \param addr the MAC address
|
||||
* \param prefix the address prefix
|
||||
* \return the IPv6 address
|
||||
*/
|
||||
Ipv6Address MakeGlobalAddressFromMac (Address const &addr, Ipv6Address prefix);
|
||||
|
||||
/**
|
||||
* \brief Compress the headers according to HC1 compression.
|
||||
* \param packet the packet to be compressed
|
||||
* \param src the MAC source address
|
||||
* \param dst the MAC destination address
|
||||
* \return the size of the removed headers
|
||||
*/
|
||||
uint32_t CompressLowPanHc1 (Ptr<Packet> packet, Address const &src, Address const &dst);
|
||||
|
||||
/**
|
||||
* \brief Decompress the headers according to HC1 compression.
|
||||
* \param packet the packet to be compressed
|
||||
* \param src the MAC source address
|
||||
* \param dst the MAC destination address
|
||||
*/
|
||||
void DecompressLowPanHc1 (Ptr<Packet> packet, Address const &src, Address const &dst);
|
||||
|
||||
/**
|
||||
* \brief Compress the headers according to IPHC compression.
|
||||
* \param packet the packet to be compressed
|
||||
* \param src the MAC source address
|
||||
* \param dst the MAC destination address
|
||||
* \return the size of the removed headers
|
||||
*/
|
||||
uint32_t CompressLowPanIphc (Ptr<Packet> packet, Address const &src, Address const &dst);
|
||||
|
||||
/**
|
||||
* \brief Checks if the next header can be compressed using NHC.
|
||||
* \param headerType the header kind to be compressed
|
||||
* \return true if the header can be compressed
|
||||
*/
|
||||
bool CanCompressLowPanNhc (uint8_t headerType);
|
||||
|
||||
/**
|
||||
* \brief Decompress the headers according to IPHC compression.
|
||||
* \param packet the packet to be compressed
|
||||
* \param src the MAC source address
|
||||
* \param dst the MAC destination address
|
||||
*/
|
||||
void DecompressLowPanIphc (Ptr<Packet> packet, Address const &src, Address const &dst);
|
||||
|
||||
/**
|
||||
* \brief Compress the headers according to NHC compression.
|
||||
* \param packet the packet to be compressed
|
||||
* \param headerType the header type
|
||||
* \param src the MAC source address
|
||||
* \param dst the MAC destination address
|
||||
* \return the size of the removed headers
|
||||
*/
|
||||
uint32_t CompressLowPanNhc (Ptr<Packet> packet, uint8_t headerType, Address const &src, Address const &dst);
|
||||
|
||||
/**
|
||||
* \brief Decompress the headers according to NHC compression.
|
||||
* \param packet the packet to be compressed
|
||||
* \param src the MAC source address
|
||||
* \param dst the MAC destination address
|
||||
* \param srcAddress the IPv6 source address
|
||||
* \param dstAddress the IPv6 destination address
|
||||
* \return the decompressed header type
|
||||
*/
|
||||
uint8_t DecompressLowPanNhc (Ptr<Packet> packet, Address const &src, Address const &dst, Ipv6Address srcAddress, Ipv6Address dstAddress);
|
||||
|
||||
/**
|
||||
* \brief Compress the headers according to NHC compression.
|
||||
* \param packet the packet to be compressed
|
||||
* \param omitChecksum omit UDP checksum (if true)
|
||||
* \return the size of the removed headers
|
||||
*/
|
||||
uint32_t CompressLowPanUdpNhc (Ptr<Packet> packet, bool omitChecksum);
|
||||
|
||||
/**
|
||||
* \brief Decompress the headers according to NHC compression.
|
||||
* \param packet the packet to be compressed
|
||||
* \param saddr the IPv6 source address
|
||||
* \param daddr the IPv6 destination address
|
||||
*/
|
||||
void DecompressLowPanUdpNhc (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr);
|
||||
|
||||
/**
|
||||
* Fragment identifier type: src/dst address src/dst port
|
||||
*/
|
||||
typedef std::pair< std::pair<Address, Address>, std::pair<uint16_t, uint16_t> > FragmentKey;
|
||||
|
||||
/**
|
||||
* \class Fragments
|
||||
* \brief A Set of Fragment
|
||||
*/
|
||||
class Fragments : public SimpleRefCount<Fragments>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Constructor.
|
||||
*/
|
||||
Fragments ();
|
||||
|
||||
/**
|
||||
* \brief Destructor.
|
||||
*/
|
||||
~Fragments ();
|
||||
|
||||
/**
|
||||
* \brief Add a fragment to the pool.
|
||||
* \param fragment the fragment
|
||||
* \param fragmentOffset the offset of the fragment
|
||||
*/
|
||||
void AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset);
|
||||
|
||||
/**
|
||||
* \brief Add the first packet fragment. The first fragment is needed to
|
||||
* allow the post-defragmentation decompression.
|
||||
* \param fragment the fragment
|
||||
*/
|
||||
void AddFirstFragment (Ptr<Packet> fragment);
|
||||
|
||||
/**
|
||||
* \brief If all fragments have been added.
|
||||
* \returns true if the packet is entire
|
||||
*/
|
||||
bool IsEntire () const;
|
||||
|
||||
/**
|
||||
* \brief Get the entire packet.
|
||||
* \return the entire packet
|
||||
*/
|
||||
Ptr<Packet> GetPacket () const;
|
||||
|
||||
/**
|
||||
* \brief Set the packet-to-be-defragmented size.
|
||||
* \param packetSize the packet size (bytes)
|
||||
*/
|
||||
void SetPacketSize (uint32_t packetSize);
|
||||
|
||||
/**
|
||||
* \brief Get a list of the current stored fragments.
|
||||
*/
|
||||
std::list< Ptr<Packet> > GetFraments () const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief The size of the reconstructed packet (bytes).
|
||||
*/
|
||||
uint32_t m_packetSize;
|
||||
|
||||
/**
|
||||
* \brief The current fragments.
|
||||
*/
|
||||
std::list<std::pair<Ptr<Packet>, uint16_t> > m_fragments;
|
||||
|
||||
/**
|
||||
* \brief The very first fragment
|
||||
*/
|
||||
Ptr<Packet> m_firstFragment;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the instance type identifier.
|
||||
* \param packet the packet to be fragmented (with headers already compressed with 6LoWPAN)
|
||||
* \param origPacketSize the size of the IP packet before the 6LoWPAN header compression, including the IP/L4 headers
|
||||
* \param origHdrSize the size of the IP header before the 6LoWPAN header compression
|
||||
* \param listFragments a reference to the list of the resulting packets, all with the proper headers in place
|
||||
*/
|
||||
void DoFragmentation (Ptr<Packet> packet, uint32_t origPacketSize, uint32_t origHdrSize,
|
||||
std::list<Ptr<Packet> >& listFragments);
|
||||
|
||||
/**
|
||||
* \brief Process a packet fragment
|
||||
* \param packet the packet
|
||||
* \param src the source MAC address
|
||||
* \param dst the destination MAC address
|
||||
* \param isFirst true if it is the first fragment, false otherwise
|
||||
* \return true is the fragment completed the packet
|
||||
*/
|
||||
bool ProcessFragment (Ptr<Packet>& packet, Address const &src, Address const &dst, bool isFirst);
|
||||
|
||||
/**
|
||||
* \brief Process the timeout for packet fragments
|
||||
* \param key representing the packet fragments
|
||||
* \param iif Input Interface
|
||||
*/
|
||||
void HandleFragmentsTimeout ( FragmentKey key, uint32_t iif);
|
||||
|
||||
/**
|
||||
* \brief Drops the oldest fragment set
|
||||
*/
|
||||
void DropOldestFragmentSet ();
|
||||
|
||||
/**
|
||||
* Container for fragment key -> fragments
|
||||
*/
|
||||
typedef std::map< FragmentKey, Ptr<Fragments> > MapFragments_t;
|
||||
/**
|
||||
* Container Iterator for fragment key -> fragments
|
||||
*/
|
||||
typedef std::map< FragmentKey, Ptr<Fragments> >::iterator MapFragmentsI_t;
|
||||
/**
|
||||
* Container for fragment key -> exiration event
|
||||
*/
|
||||
typedef std::map< FragmentKey, EventId > MapFragmentsTimers_t;
|
||||
/**
|
||||
* Container Iterator for fragment key -> exiration event
|
||||
*/
|
||||
typedef std::map< FragmentKey, EventId >::iterator MapFragmentsTimersI_t;
|
||||
|
||||
MapFragments_t m_fragments; /**< Fragments hold to be rebuilt */
|
||||
MapFragmentsTimers_t m_fragmentsTimers; /**< Timers related to fragment rebuilding */
|
||||
Time m_fragmentExpirationTimeout; /**< Time limit for fragment rebuilding */
|
||||
|
||||
/**
|
||||
* \brief How many packets can be rebuilt at the same time.
|
||||
* Some real implementation do limit this. Zero means no limit.
|
||||
*/
|
||||
uint16_t m_fragmentReassemblyListSize;
|
||||
|
||||
bool m_useIphc; /**< Use IPHC or HC1 */
|
||||
|
||||
Ptr<Node> m_node; /**< Smart pointer to the Node */
|
||||
Ptr<NetDevice> m_netDevice; /**< Smart pointer to the underlying NetDevice */
|
||||
uint32_t m_ifIndex; /**< Interface index */
|
||||
|
||||
/**
|
||||
* \brief Force the EtherType number.
|
||||
* Also implying that the underlying NetDevice is using 48-bit Addresses, e.g., Ethernet, WiFi, etc.
|
||||
*/
|
||||
bool m_forceEtherType;
|
||||
|
||||
uint16_t m_etherType; /**< EtherType number (used only if m_forceEtherType is true) */
|
||||
bool m_omitUdpChecksum; /**< Omit UDP checksum in NC1 encoding */
|
||||
|
||||
Ptr<UniformRandomVariable> m_rng; //!< Rng for the fragments tag.
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* SIXLOWPAN_NET_DEVICE_H */
|
||||
196
src/sixlowpan/test/error-channel-sixlow.cc
Normal file
196
src/sixlowpan/test/error-channel-sixlow.cc
Normal file
@@ -0,0 +1,196 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
#include "error-channel-sixlow.h"
|
||||
#include "ns3/simple-net-device.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("ErrorChannelSixlow")
|
||||
;
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (ErrorChannelSixlow)
|
||||
;
|
||||
|
||||
TypeId
|
||||
ErrorChannelSixlow::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::ErrorChannelSixlow")
|
||||
.SetParent<Channel> ()
|
||||
.AddConstructor<ErrorChannelSixlow> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
ErrorChannelSixlow::ErrorChannelSixlow ()
|
||||
{
|
||||
m_jumpingTime = Seconds (0.5);
|
||||
m_jumping = false;
|
||||
m_jumpingState = 0;
|
||||
m_duplicateTime = Seconds (0.1);
|
||||
m_duplicate = false;
|
||||
}
|
||||
|
||||
void
|
||||
ErrorChannelSixlow::SetJumpingTime (Time delay)
|
||||
{
|
||||
m_jumpingTime = delay;
|
||||
}
|
||||
|
||||
void
|
||||
ErrorChannelSixlow::SetJumpingMode (bool mode)
|
||||
{
|
||||
m_jumping = mode;
|
||||
m_jumpingState = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ErrorChannelSixlow::SetDuplicateTime (Time delay)
|
||||
{
|
||||
m_duplicateTime = delay;
|
||||
}
|
||||
|
||||
void
|
||||
ErrorChannelSixlow::SetDuplicateMode (bool mode)
|
||||
{
|
||||
m_duplicate = mode;
|
||||
m_duplicateState = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ErrorChannelSixlow::Send (Ptr<Packet> p, uint16_t protocol,
|
||||
Mac48Address to, Mac48Address from,
|
||||
Ptr<SimpleNetDevice> sender)
|
||||
{
|
||||
NS_LOG_FUNCTION (p << protocol << to << from << sender);
|
||||
for (std::vector<Ptr<SimpleNetDevice> >::const_iterator i = m_devices.begin (); i != m_devices.end (); ++i)
|
||||
{
|
||||
Ptr<SimpleNetDevice> tmp = *i;
|
||||
if (tmp == sender)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (m_jumping)
|
||||
{
|
||||
if (m_jumpingState % 2)
|
||||
{
|
||||
Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), Seconds (0),
|
||||
&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
|
||||
}
|
||||
else
|
||||
{
|
||||
Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), m_jumpingTime,
|
||||
&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
|
||||
}
|
||||
m_jumpingState++;
|
||||
}
|
||||
else if (m_duplicate)
|
||||
{
|
||||
if (m_duplicateState % 2)
|
||||
{
|
||||
Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), Seconds (0),
|
||||
&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
|
||||
}
|
||||
else
|
||||
{
|
||||
Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), Seconds (0),
|
||||
&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
|
||||
Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), m_duplicateTime,
|
||||
&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
|
||||
}
|
||||
m_duplicateState++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Simulator::ScheduleWithContext (tmp->GetNode ()->GetId (), Seconds (0),
|
||||
&SimpleNetDevice::Receive, tmp, p->Copy (), protocol, to, from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ErrorChannelSixlow::Add (Ptr<SimpleNetDevice> device)
|
||||
{
|
||||
m_devices.push_back (device);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ErrorChannelSixlow::GetNDevices (void) const
|
||||
{
|
||||
return m_devices.size ();
|
||||
}
|
||||
Ptr<NetDevice>
|
||||
ErrorChannelSixlow::GetDevice (uint32_t i) const
|
||||
{
|
||||
return m_devices[i];
|
||||
}
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (BinaryErrorSixlowModel)
|
||||
;
|
||||
|
||||
TypeId BinaryErrorSixlowModel::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::BinaryErrorSixlowModel")
|
||||
.SetParent<ErrorModel> ()
|
||||
.AddConstructor<BinaryErrorSixlowModel> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
BinaryErrorSixlowModel::BinaryErrorSixlowModel ()
|
||||
{
|
||||
m_counter = 0;
|
||||
}
|
||||
|
||||
BinaryErrorSixlowModel::~BinaryErrorSixlowModel ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BinaryErrorSixlowModel::DoCorrupt (Ptr<Packet> p)
|
||||
{
|
||||
if (!IsEnabled ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool ret = m_counter % 2;
|
||||
m_counter++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
BinaryErrorSixlowModel::Reset (void)
|
||||
{
|
||||
DoReset ();
|
||||
}
|
||||
|
||||
void
|
||||
BinaryErrorSixlowModel::DoReset (void)
|
||||
{
|
||||
m_counter = 0;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
107
src/sixlowpan/test/error-channel-sixlow.h
Normal file
107
src/sixlowpan/test/error-channel-sixlow.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
#ifndef ERROR_CHANNEL_SIXLOW_H
|
||||
#define ERROR_CHANNEL_SIXLOW_H
|
||||
|
||||
#include "ns3/channel.h"
|
||||
#include "ns3/simple-channel.h"
|
||||
#include "ns3/error-model.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class SimpleNetDevice;
|
||||
class Packet;
|
||||
|
||||
/**
|
||||
* \ingroup channel
|
||||
* \brief A Error channel, introducing deterministic delays on even/odd packets. Used for testing
|
||||
*/
|
||||
class ErrorChannelSixlow : public SimpleChannel
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
ErrorChannelSixlow ();
|
||||
|
||||
virtual void Send (Ptr<Packet> p, uint16_t protocol, Mac48Address to, Mac48Address from,
|
||||
Ptr<SimpleNetDevice> sender);
|
||||
|
||||
virtual void Add (Ptr<SimpleNetDevice> device);
|
||||
|
||||
// inherited from ns3::Channel
|
||||
virtual uint32_t GetNDevices (void) const;
|
||||
virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
|
||||
|
||||
/**
|
||||
* \brief Set the delay for the odd packets (even ones are not delayed)
|
||||
* \param delay Delay for the odd packets.
|
||||
*/
|
||||
void SetJumpingTime (Time delay);
|
||||
|
||||
/**
|
||||
* \brief Set if the odd packets are delayed (even ones are not delayed ever)
|
||||
* \param mode true if the odd packets should be delayed.
|
||||
*/
|
||||
void SetJumpingMode (bool mode);
|
||||
|
||||
/**
|
||||
* \brief Set the delay for the odd duplicate packets (even ones are not duplicated)
|
||||
* \param delay Delay for the odd packets.
|
||||
*/
|
||||
void SetDuplicateTime (Time delay);
|
||||
|
||||
/**
|
||||
* \brief Set if the odd packets are duplicated (even ones are not duplicated ever)
|
||||
* \param mode true if the odd packets should be duplicated.
|
||||
*/
|
||||
void SetDuplicateMode (bool mode);
|
||||
|
||||
private:
|
||||
std::vector<Ptr<SimpleNetDevice> > m_devices;
|
||||
Time m_jumpingTime;
|
||||
uint8_t m_jumpingState;
|
||||
bool m_jumping;
|
||||
Time m_duplicateTime;
|
||||
bool m_duplicate;
|
||||
uint8_t m_duplicateState;
|
||||
};
|
||||
|
||||
class BinaryErrorSixlowModel : public ErrorModel
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
BinaryErrorSixlowModel ();
|
||||
virtual ~BinaryErrorSixlowModel ();
|
||||
void Reset (void);
|
||||
|
||||
private:
|
||||
virtual bool DoCorrupt (Ptr<Packet> p);
|
||||
virtual void DoReset (void);
|
||||
|
||||
uint8_t m_counter;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* ERROR_CHANNEL_SIXLOW_H */
|
||||
463
src/sixlowpan/test/sixlowpan-fragmentation-test.cc
Normal file
463
src/sixlowpan/test/sixlowpan-fragmentation-test.cc
Normal file
@@ -0,0 +1,463 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
#define NS3_LOG_ENABLE 1
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/config.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/socket-factory.h"
|
||||
#include "ns3/ipv6-raw-socket-factory.h"
|
||||
#include "ns3/udp-socket-factory.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "error-channel-sixlow.h"
|
||||
#include "ns3/simple-net-device.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/udp-socket.h"
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/inet-socket-address.h"
|
||||
#include "ns3/boolean.h"
|
||||
|
||||
#include "ns3/ipv6-static-routing.h"
|
||||
#include "ns3/ipv6-list-routing.h"
|
||||
#include "ns3/inet6-socket-address.h"
|
||||
#include "ns3/sixlowpan-net-device.h"
|
||||
|
||||
#include "ns3/udp-l4-protocol.h"
|
||||
|
||||
#include "ns3/ipv6-l3-protocol.h"
|
||||
#include "ns3/icmpv6-l4-protocol.h"
|
||||
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <netinet/in.h>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
class UdpSocketImpl;
|
||||
|
||||
static void
|
||||
AddInternetStack (Ptr<Node> node)
|
||||
{
|
||||
//IPV6
|
||||
Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
|
||||
|
||||
//Routing for Ipv6
|
||||
Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting> ();
|
||||
ipv6->SetRoutingProtocol (ipv6Routing);
|
||||
Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting> ();
|
||||
ipv6Routing->AddRoutingProtocol (ipv6staticRouting, 0);
|
||||
node->AggregateObject (ipv6);
|
||||
|
||||
//ICMPv6
|
||||
Ptr<Icmpv6L4Protocol> icmp6 = CreateObject<Icmpv6L4Protocol> ();
|
||||
node->AggregateObject (icmp6);
|
||||
|
||||
//Ipv6 Extensions
|
||||
ipv6->RegisterExtensions ();
|
||||
ipv6->RegisterOptions ();
|
||||
|
||||
//UDP
|
||||
Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
|
||||
node->AggregateObject (udp);
|
||||
}
|
||||
|
||||
|
||||
class SixlowpanFragmentationTest : public TestCase
|
||||
{
|
||||
Ptr<Packet> m_sentPacketClient;
|
||||
Ptr<Packet> m_receivedPacketClient;
|
||||
Ptr<Packet> m_receivedPacketServer;
|
||||
|
||||
|
||||
Ptr<Socket> m_socketServer;
|
||||
Ptr<Socket> m_socketClient;
|
||||
uint32_t m_dataSize;
|
||||
uint8_t *m_data;
|
||||
uint32_t m_size;
|
||||
uint8_t m_icmpType;
|
||||
uint8_t m_icmpCode;
|
||||
|
||||
public:
|
||||
virtual void DoRun (void);
|
||||
SixlowpanFragmentationTest ();
|
||||
~SixlowpanFragmentationTest ();
|
||||
|
||||
// server part
|
||||
void StartServer (Ptr<Node> ServerNode);
|
||||
void HandleReadServer (Ptr<Socket> socket);
|
||||
|
||||
// client part
|
||||
void StartClient (Ptr<Node> ClientNode);
|
||||
void HandleReadClient (Ptr<Socket> socket);
|
||||
void HandleReadIcmpClient (Ipv6Address icmpSource, uint8_t icmpTtl, uint8_t icmpType,
|
||||
uint8_t icmpCode,uint32_t icmpInfo);
|
||||
|
||||
void SetFill (uint8_t *fill, uint32_t fillSize, uint32_t dataSize);
|
||||
Ptr<Packet> SendClient (void);
|
||||
|
||||
};
|
||||
|
||||
|
||||
SixlowpanFragmentationTest::SixlowpanFragmentationTest ()
|
||||
: TestCase ("Verify the 6LoWPAN protocol fragmentation and reassembly")
|
||||
{
|
||||
m_socketServer = 0;
|
||||
m_data = 0;
|
||||
m_dataSize = 0;
|
||||
}
|
||||
|
||||
SixlowpanFragmentationTest::~SixlowpanFragmentationTest ()
|
||||
{
|
||||
if ( m_data )
|
||||
{
|
||||
delete[] m_data;
|
||||
}
|
||||
m_data = 0;
|
||||
m_dataSize = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SixlowpanFragmentationTest::StartServer (Ptr<Node> ServerNode)
|
||||
{
|
||||
|
||||
if (m_socketServer == 0)
|
||||
{
|
||||
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
|
||||
m_socketServer = Socket::CreateSocket (ServerNode, tid);
|
||||
Inet6SocketAddress local = Inet6SocketAddress (Ipv6Address ("2001:0100::1"), 9);
|
||||
m_socketServer->Bind (local);
|
||||
Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket> (m_socketServer);
|
||||
}
|
||||
|
||||
m_socketServer->SetRecvCallback (MakeCallback (&SixlowpanFragmentationTest::HandleReadServer, this));
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanFragmentationTest::HandleReadServer (Ptr<Socket> socket)
|
||||
{
|
||||
Ptr<Packet> packet;
|
||||
Address from;
|
||||
while ((packet = socket->RecvFrom (from)))
|
||||
{
|
||||
if (Inet6SocketAddress::IsMatchingType (from))
|
||||
{
|
||||
packet->RemoveAllPacketTags ();
|
||||
packet->RemoveAllByteTags ();
|
||||
|
||||
m_receivedPacketServer = packet->Copy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanFragmentationTest::StartClient (Ptr<Node> ClientNode)
|
||||
{
|
||||
|
||||
if (m_socketClient == 0)
|
||||
{
|
||||
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
|
||||
m_socketClient = Socket::CreateSocket (ClientNode, tid);
|
||||
m_socketClient->Bind (Inet6SocketAddress (Ipv6Address::GetAny (), 9));
|
||||
m_socketClient->Connect (Inet6SocketAddress (Ipv6Address ("2001:0100::1"), 9));
|
||||
CallbackValue cbValue = MakeCallback (&SixlowpanFragmentationTest::HandleReadIcmpClient, this);
|
||||
m_socketClient->SetAttribute ("IcmpCallback6", cbValue);
|
||||
}
|
||||
|
||||
m_socketClient->SetRecvCallback (MakeCallback (&SixlowpanFragmentationTest::HandleReadClient, this));
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanFragmentationTest::HandleReadClient (Ptr<Socket> socket)
|
||||
{
|
||||
Ptr<Packet> packet;
|
||||
Address from;
|
||||
while ((packet = socket->RecvFrom (from)))
|
||||
{
|
||||
if (Inet6SocketAddress::IsMatchingType (from))
|
||||
{
|
||||
m_receivedPacketClient = packet->Copy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanFragmentationTest::HandleReadIcmpClient (Ipv6Address icmpSource,
|
||||
uint8_t icmpTtl, uint8_t icmpType,
|
||||
uint8_t icmpCode, uint32_t icmpInfo)
|
||||
{
|
||||
m_icmpType = icmpType;
|
||||
m_icmpCode = icmpCode;
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanFragmentationTest::SetFill (uint8_t *fill, uint32_t fillSize, uint32_t dataSize)
|
||||
{
|
||||
if (dataSize != m_dataSize)
|
||||
{
|
||||
delete [] m_data;
|
||||
m_data = new uint8_t [dataSize];
|
||||
m_dataSize = dataSize;
|
||||
}
|
||||
|
||||
if (fillSize >= dataSize)
|
||||
{
|
||||
memcpy (m_data, fill, dataSize);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t filled = 0;
|
||||
while (filled + fillSize < dataSize)
|
||||
{
|
||||
memcpy (&m_data[filled], fill, fillSize);
|
||||
filled += fillSize;
|
||||
}
|
||||
|
||||
memcpy (&m_data[filled], fill, dataSize - filled);
|
||||
|
||||
m_size = dataSize;
|
||||
}
|
||||
|
||||
Ptr<Packet> SixlowpanFragmentationTest::SendClient (void)
|
||||
{
|
||||
Ptr<Packet> p;
|
||||
if (m_dataSize)
|
||||
{
|
||||
p = Create<Packet> (m_data, m_dataSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = Create<Packet> (m_size);
|
||||
}
|
||||
m_socketClient->Send (p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanFragmentationTest::DoRun (void)
|
||||
{
|
||||
// Create topology
|
||||
|
||||
// Receiver Node
|
||||
Ptr<Node> serverNode = CreateObject<Node> ();
|
||||
AddInternetStack (serverNode);
|
||||
Ptr<SimpleNetDevice> serverDev;
|
||||
Ptr<BinaryErrorSixlowModel> serverDevErrorModel = CreateObject<BinaryErrorSixlowModel> ();
|
||||
{
|
||||
serverDev = CreateObject<SimpleNetDevice> ();
|
||||
serverDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
|
||||
serverDev->SetMtu (1500);
|
||||
serverDev->SetReceiveErrorModel (serverDevErrorModel);
|
||||
serverDevErrorModel->Disable ();
|
||||
serverNode->AddDevice (serverDev);
|
||||
|
||||
Ptr<SixLowPanNetDevice> serverSix = CreateObject<SixLowPanNetDevice> ();
|
||||
serverSix->SetAttribute ("ForceEtherType", BooleanValue (true) );
|
||||
serverNode->AddDevice (serverSix);
|
||||
serverSix->SetNetDevice (serverDev);
|
||||
|
||||
Ptr<Ipv6> ipv6 = serverNode->GetObject<Ipv6> ();
|
||||
ipv6->AddInterface (serverDev);
|
||||
uint32_t netdev_idx = ipv6->AddInterface (serverSix);
|
||||
Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100::1"), Ipv6Prefix (64));
|
||||
ipv6->AddAddress (netdev_idx, ipv6Addr);
|
||||
ipv6->SetUp (netdev_idx);
|
||||
|
||||
Ptr<Icmpv6L4Protocol> icmpv6l4 = serverNode->GetObject<Icmpv6L4Protocol> ();
|
||||
icmpv6l4->SetAttribute ("DAD", BooleanValue (false));
|
||||
}
|
||||
StartServer (serverNode);
|
||||
|
||||
// Sender Node
|
||||
Ptr<Node> clientNode = CreateObject<Node> ();
|
||||
AddInternetStack (clientNode);
|
||||
Ptr<SimpleNetDevice> clientDev;
|
||||
Ptr<BinaryErrorSixlowModel> clientDevErrorModel = CreateObject<BinaryErrorSixlowModel> ();
|
||||
{
|
||||
clientDev = CreateObject<SimpleNetDevice> ();
|
||||
clientDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
|
||||
clientDev->SetMtu (150);
|
||||
clientDev->SetReceiveErrorModel (clientDevErrorModel);
|
||||
clientDevErrorModel->Disable ();
|
||||
clientNode->AddDevice (clientDev);
|
||||
|
||||
Ptr<SixLowPanNetDevice> clientSix = CreateObject<SixLowPanNetDevice> ();
|
||||
clientSix->SetAttribute ("ForceEtherType", BooleanValue (true) );
|
||||
serverNode->AddDevice (clientSix);
|
||||
clientSix->SetNetDevice (clientDev);
|
||||
|
||||
Ptr<Ipv6> ipv6 = clientNode->GetObject<Ipv6> ();
|
||||
ipv6->AddInterface (clientDev);
|
||||
uint32_t netdev_idx = ipv6->AddInterface (clientSix);
|
||||
Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100::2"), Ipv6Prefix (64));
|
||||
ipv6->AddAddress (netdev_idx, ipv6Addr);
|
||||
ipv6->SetUp (netdev_idx);
|
||||
|
||||
Ptr<Icmpv6L4Protocol> icmpv6l4 = clientNode->GetObject<Icmpv6L4Protocol> ();
|
||||
icmpv6l4->SetAttribute ("DAD", BooleanValue (false));
|
||||
}
|
||||
StartClient (clientNode);
|
||||
|
||||
// link the two nodes
|
||||
Ptr<ErrorChannelSixlow> channel = CreateObject<ErrorChannelSixlow> ();
|
||||
serverDev->SetChannel (channel);
|
||||
clientDev->SetChannel (channel);
|
||||
|
||||
|
||||
// some small packets, some rather big ones
|
||||
uint32_t packetSizes[5] = {200, 300, 400, 500, 600};
|
||||
|
||||
// using the alphabet
|
||||
uint8_t fillData[78];
|
||||
for ( uint32_t k = 48; k <= 125; k++ )
|
||||
{
|
||||
fillData[k - 48] = k;
|
||||
}
|
||||
|
||||
// First test: normal channel, no errors, no delays
|
||||
for ( int i = 0; i < 5; i++)
|
||||
{
|
||||
uint32_t packetSize = packetSizes[i];
|
||||
|
||||
SetFill (fillData, 78, packetSize);
|
||||
|
||||
m_receivedPacketServer = Create<Packet> ();
|
||||
Simulator::ScheduleWithContext (m_socketClient->GetNode ()->GetId (), Seconds (0),
|
||||
&SixlowpanFragmentationTest::SendClient, this);
|
||||
Simulator::Run ();
|
||||
|
||||
uint8_t recvBuffer[65000];
|
||||
|
||||
uint16_t recvSize = m_receivedPacketServer->GetSize ();
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ (recvSize, packetSizes[i],
|
||||
"Packet size not correct: recvSize: " << recvSize << " packetSizes[" << i << "]: " << packetSizes[i] );
|
||||
|
||||
m_receivedPacketServer->CopyData (recvBuffer, 65000);
|
||||
NS_TEST_EXPECT_MSG_EQ (memcmp (m_data, recvBuffer, m_receivedPacketServer->GetSize ()),
|
||||
0, "Packet content differs");
|
||||
}
|
||||
|
||||
// Second test: normal channel, no errors, delays each 2 packets.
|
||||
// Each other fragment will arrive out-of-order.
|
||||
// The packets should be received correctly since reassembly will reorder the fragments.
|
||||
channel->SetJumpingMode (true);
|
||||
for ( int i = 0; i < 5; i++)
|
||||
{
|
||||
uint32_t packetSize = packetSizes[i];
|
||||
|
||||
SetFill (fillData, 78, packetSize);
|
||||
|
||||
m_receivedPacketServer = Create<Packet> ();
|
||||
Simulator::ScheduleWithContext (m_socketClient->GetNode ()->GetId (), Seconds (0),
|
||||
&SixlowpanFragmentationTest::SendClient, this);
|
||||
Simulator::Run ();
|
||||
|
||||
uint8_t recvBuffer[65000];
|
||||
|
||||
uint16_t recvSize = m_receivedPacketServer->GetSize ();
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ (recvSize, packetSizes[i],
|
||||
"Packet size not correct: recvSize: " << recvSize << " packetSizes[" << i << "]: " << packetSizes[i] );
|
||||
|
||||
m_receivedPacketServer->CopyData (recvBuffer, 65000);
|
||||
NS_TEST_EXPECT_MSG_EQ (memcmp (m_data, recvBuffer, m_receivedPacketServer->GetSize ()),
|
||||
0, "Packet content differs");
|
||||
}
|
||||
channel->SetJumpingMode (false);
|
||||
|
||||
|
||||
// Third test: normal channel, some packets are duplicate.
|
||||
// The duplicate fragments should be discarded, so no error should be fired.
|
||||
channel->SetDuplicateMode (true);
|
||||
for ( int i = 1; i < 5; i++)
|
||||
{
|
||||
uint32_t packetSize = packetSizes[i];
|
||||
|
||||
SetFill (fillData, 78, packetSize);
|
||||
|
||||
// reset the model, we want to receive the very first fragment.
|
||||
serverDevErrorModel->Reset ();
|
||||
|
||||
m_receivedPacketServer = Create<Packet> ();
|
||||
m_icmpType = 0;
|
||||
m_icmpCode = 0;
|
||||
Simulator::ScheduleWithContext (m_socketClient->GetNode ()->GetId (), Seconds (0),
|
||||
&SixlowpanFragmentationTest::SendClient, this);
|
||||
Simulator::Run ();
|
||||
|
||||
uint8_t recvBuffer[65000];
|
||||
|
||||
uint16_t recvSize = m_receivedPacketServer->GetSize ();
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ (recvSize, packetSizes[i],
|
||||
"Packet size not correct: recvSize: " << recvSize << " packetSizes[" << i << "]: " << packetSizes[i] );
|
||||
|
||||
m_receivedPacketServer->CopyData (recvBuffer, 65000);
|
||||
NS_TEST_EXPECT_MSG_EQ (memcmp (m_data, recvBuffer, m_receivedPacketServer->GetSize ()),
|
||||
0, "Packet content differs");
|
||||
}
|
||||
channel->SetDuplicateMode (false);
|
||||
|
||||
// Fourth test: normal channel, some errors, no delays.
|
||||
// The reassembly procedure does NOT fire any ICMP, so we do not expect any reply from the server.
|
||||
// Client -> Server : errors enabled
|
||||
// Server -> Client : errors disabled
|
||||
clientDevErrorModel->Disable ();
|
||||
serverDevErrorModel->Enable ();
|
||||
for ( int i = 1; i < 5; i++)
|
||||
{
|
||||
uint32_t packetSize = packetSizes[i];
|
||||
|
||||
SetFill (fillData, 78, packetSize);
|
||||
|
||||
// reset the model, we want to receive the very first fragment.
|
||||
serverDevErrorModel->Reset ();
|
||||
|
||||
m_receivedPacketServer = Create<Packet> ();
|
||||
m_icmpType = 0;
|
||||
m_icmpCode = 0;
|
||||
Simulator::ScheduleWithContext (m_socketClient->GetNode ()->GetId (), Seconds (0),
|
||||
&SixlowpanFragmentationTest::SendClient, this);
|
||||
Simulator::Run ();
|
||||
|
||||
uint16_t recvSize = m_receivedPacketServer->GetSize ();
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ ((recvSize == 0), true, "Server got a packet, something wrong");
|
||||
// Note that a 6LoWPAN fragment timeout does NOT send any ICMPv6.
|
||||
}
|
||||
|
||||
|
||||
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
class SixlowpanFragmentationTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
SixlowpanFragmentationTestSuite () : TestSuite ("sixlowpan-fragmentation", UNIT)
|
||||
{
|
||||
AddTestCase (new SixlowpanFragmentationTest, TestCase::QUICK);
|
||||
}
|
||||
} g_sixlowpanFragmentationTestSuite;
|
||||
216
src/sixlowpan/test/sixlowpan-hc1-test.cc
Normal file
216
src/sixlowpan/test/sixlowpan-hc1-test.cc
Normal file
@@ -0,0 +1,216 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/socket-factory.h"
|
||||
#include "ns3/udp-socket-factory.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/simple-channel.h"
|
||||
#include "ns3/simple-net-device.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/boolean.h"
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/inet6-socket-address.h"
|
||||
|
||||
#include "ns3/ipv6-l3-protocol.h"
|
||||
#include "ns3/icmpv6-l4-protocol.h"
|
||||
#include "ns3/udp-l4-protocol.h"
|
||||
#include "ns3/ipv6-list-routing.h"
|
||||
#include "ns3/ipv6-static-routing.h"
|
||||
|
||||
#include "ns3/sixlowpan-net-device.h"
|
||||
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
static void
|
||||
AddInternetStack6 (Ptr<Node> node)
|
||||
{
|
||||
//IPV6
|
||||
Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
|
||||
//Routing for Ipv6
|
||||
Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting> ();
|
||||
ipv6->SetRoutingProtocol (ipv6Routing);
|
||||
Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting> ();
|
||||
ipv6Routing->AddRoutingProtocol (ipv6staticRouting, 0);
|
||||
node->AggregateObject (ipv6);
|
||||
//ICMP
|
||||
Ptr<Icmpv6L4Protocol> icmp = CreateObject<Icmpv6L4Protocol> ();
|
||||
node->AggregateObject (icmp);
|
||||
//Ipv6 Extensions
|
||||
ipv6->RegisterExtensions ();
|
||||
ipv6->RegisterOptions ();
|
||||
//UDP
|
||||
Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
|
||||
node->AggregateObject (udp);
|
||||
}
|
||||
|
||||
|
||||
class SixlowpanHc1ImplTest : public TestCase
|
||||
{
|
||||
Ptr<Packet> m_receivedPacket;
|
||||
void DoSendData (Ptr<Socket> socket, std::string to);
|
||||
void SendData (Ptr<Socket> socket, std::string to);
|
||||
|
||||
public:
|
||||
virtual void DoRun (void);
|
||||
SixlowpanHc1ImplTest ();
|
||||
|
||||
void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
|
||||
void ReceivePkt (Ptr<Socket> socket);
|
||||
};
|
||||
|
||||
SixlowpanHc1ImplTest::SixlowpanHc1ImplTest ()
|
||||
: TestCase ("Sixlowpan implementation")
|
||||
{
|
||||
}
|
||||
|
||||
void SixlowpanHc1ImplTest::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
|
||||
{
|
||||
m_receivedPacket = packet;
|
||||
}
|
||||
|
||||
void SixlowpanHc1ImplTest::ReceivePkt (Ptr<Socket> socket)
|
||||
{
|
||||
uint32_t availableData;
|
||||
availableData = socket->GetRxAvailable ();
|
||||
m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max (), 0);
|
||||
NS_ASSERT (availableData == m_receivedPacket->GetSize ());
|
||||
//cast availableData to void, to suppress 'availableData' set but not used
|
||||
//compiler warning
|
||||
(void) availableData;
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanHc1ImplTest::DoSendData (Ptr<Socket> socket, std::string to)
|
||||
{
|
||||
Address realTo = Inet6SocketAddress (Ipv6Address (to.c_str ()), 1234);
|
||||
uint8_t buffer [] = "\"Can you tell me where my country lies?\" \\ said the unifaun to his true love's eyes. \\ \"It lies with me!\" cried the Queen of Maybe \\ - for her merchandise, he traded in his prize.";
|
||||
|
||||
Ptr<Packet> packet = Create<Packet> (buffer, 180);
|
||||
NS_TEST_EXPECT_MSG_EQ (socket->SendTo (packet, 0, realTo),
|
||||
180, "200");
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanHc1ImplTest::SendData (Ptr<Socket> socket, std::string to)
|
||||
{
|
||||
m_receivedPacket = Create<Packet> ();
|
||||
Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0),
|
||||
&SixlowpanHc1ImplTest::DoSendData, this, socket, to);
|
||||
Simulator::Run ();
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanHc1ImplTest::DoRun (void)
|
||||
{
|
||||
// Create topology
|
||||
|
||||
// Receiver Node
|
||||
Ptr<Node> rxNode = CreateObject<Node> ();
|
||||
AddInternetStack6 (rxNode);
|
||||
Ptr<SimpleNetDevice> rxDev;
|
||||
{ // first interface
|
||||
rxDev = CreateObject<SimpleNetDevice> ();
|
||||
rxDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
|
||||
rxNode->AddDevice (rxDev);
|
||||
|
||||
Ptr<SixLowPanNetDevice> rxSix = CreateObject<SixLowPanNetDevice> ();
|
||||
rxSix->SetAttribute ("ForceEtherType", BooleanValue (true) );
|
||||
rxSix->SetAttribute ("Rfc6282", BooleanValue (false) );
|
||||
rxNode->AddDevice (rxSix);
|
||||
rxSix->SetNetDevice (rxDev);
|
||||
|
||||
Ptr<Ipv6> ipv6 = rxNode->GetObject<Ipv6> ();
|
||||
ipv6->AddInterface (rxDev);
|
||||
uint32_t netdev_idx = ipv6->AddInterface (rxSix);
|
||||
Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100::1"), Ipv6Prefix (64));
|
||||
ipv6->AddAddress (netdev_idx, ipv6Addr);
|
||||
ipv6->SetUp (netdev_idx);
|
||||
}
|
||||
|
||||
// Sender Node
|
||||
Ptr<Node> txNode = CreateObject<Node> ();
|
||||
AddInternetStack6 (txNode);
|
||||
Ptr<SimpleNetDevice> txDev;
|
||||
{
|
||||
txDev = CreateObject<SimpleNetDevice> ();
|
||||
txDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
|
||||
txNode->AddDevice (txDev);
|
||||
|
||||
Ptr<SixLowPanNetDevice> txSix = CreateObject<SixLowPanNetDevice> ();
|
||||
txSix->SetAttribute ("ForceEtherType", BooleanValue (true) );
|
||||
txSix->SetAttribute ("Rfc6282", BooleanValue (false) );
|
||||
txNode->AddDevice (txSix);
|
||||
txSix->SetNetDevice (txDev);
|
||||
|
||||
Ptr<Ipv6> ipv6 = txNode->GetObject<Ipv6> ();
|
||||
ipv6->AddInterface (txDev);
|
||||
uint32_t netdev_idx = ipv6->AddInterface (txSix);
|
||||
Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100::2"), Ipv6Prefix (64));
|
||||
ipv6->AddAddress (netdev_idx, ipv6Addr);
|
||||
ipv6->SetUp (netdev_idx);
|
||||
}
|
||||
|
||||
// link the two nodes
|
||||
Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> ();
|
||||
rxDev->SetChannel (channel1);
|
||||
txDev->SetChannel (channel1);
|
||||
|
||||
// Create the UDP sockets
|
||||
Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
|
||||
Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
|
||||
NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (Inet6SocketAddress (Ipv6Address ("2001:0100::1"), 1234)), 0, "trivial");
|
||||
rxSocket->SetRecvCallback (MakeCallback (&SixlowpanHc1ImplTest::ReceivePkt, this));
|
||||
|
||||
Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
|
||||
Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
|
||||
txSocket->SetAllowBroadcast (true);
|
||||
// ------ Now the tests ------------
|
||||
|
||||
// Unicast test
|
||||
SendData (txSocket, "2001:0100::1");
|
||||
NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 180, "trivial");
|
||||
uint8_t rxBuffer [180];
|
||||
uint8_t txBuffer [180] = "\"Can you tell me where my country lies?\" \\ said the unifaun to his true love's eyes. \\ \"It lies with me!\" cried the Queen of Maybe \\ - for her merchandise, he traded in his prize.";
|
||||
m_receivedPacket->CopyData (rxBuffer, 180);
|
||||
NS_TEST_EXPECT_MSG_EQ (memcmp (rxBuffer, txBuffer, 180), 0, "trivial");
|
||||
|
||||
m_receivedPacket->RemoveAllByteTags ();
|
||||
|
||||
Simulator::Destroy ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class SixlowpanHc1TestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
SixlowpanHc1TestSuite () : TestSuite ("sixlowpan-hc1", UNIT)
|
||||
{
|
||||
AddTestCase (new SixlowpanHc1ImplTest, TestCase::QUICK);
|
||||
}
|
||||
} g_sixlowpanHc1TestSuite;
|
||||
214
src/sixlowpan/test/sixlowpan-iphc-test.cc
Normal file
214
src/sixlowpan/test/sixlowpan-iphc-test.cc
Normal file
@@ -0,0 +1,214 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Universita' di Firenze, Italy
|
||||
*
|
||||
* 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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
|
||||
*/
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/socket-factory.h"
|
||||
#include "ns3/udp-socket-factory.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/simple-channel.h"
|
||||
#include "ns3/simple-net-device.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/boolean.h"
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/inet6-socket-address.h"
|
||||
|
||||
#include "ns3/ipv6-l3-protocol.h"
|
||||
#include "ns3/icmpv6-l4-protocol.h"
|
||||
#include "ns3/udp-l4-protocol.h"
|
||||
#include "ns3/ipv6-list-routing.h"
|
||||
#include "ns3/ipv6-static-routing.h"
|
||||
|
||||
#include "ns3/sixlowpan-net-device.h"
|
||||
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
static void
|
||||
AddInternetStack6 (Ptr<Node> node)
|
||||
{
|
||||
//IPV6
|
||||
Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
|
||||
//Routing for Ipv6
|
||||
Ptr<Ipv6ListRouting> ipv6Routing = CreateObject<Ipv6ListRouting> ();
|
||||
ipv6->SetRoutingProtocol (ipv6Routing);
|
||||
Ptr<Ipv6StaticRouting> ipv6staticRouting = CreateObject<Ipv6StaticRouting> ();
|
||||
ipv6Routing->AddRoutingProtocol (ipv6staticRouting, 0);
|
||||
node->AggregateObject (ipv6);
|
||||
//ICMP
|
||||
Ptr<Icmpv6L4Protocol> icmp = CreateObject<Icmpv6L4Protocol> ();
|
||||
node->AggregateObject (icmp);
|
||||
//Ipv6 Extensions
|
||||
ipv6->RegisterExtensions ();
|
||||
ipv6->RegisterOptions ();
|
||||
//UDP
|
||||
Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
|
||||
node->AggregateObject (udp);
|
||||
}
|
||||
|
||||
|
||||
class SixlowpanIphcImplTest : public TestCase
|
||||
{
|
||||
Ptr<Packet> m_receivedPacket;
|
||||
void DoSendData (Ptr<Socket> socket, std::string to);
|
||||
void SendData (Ptr<Socket> socket, std::string to);
|
||||
|
||||
public:
|
||||
virtual void DoRun (void);
|
||||
SixlowpanIphcImplTest ();
|
||||
|
||||
void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
|
||||
void ReceivePkt (Ptr<Socket> socket);
|
||||
};
|
||||
|
||||
SixlowpanIphcImplTest::SixlowpanIphcImplTest ()
|
||||
: TestCase ("Sixlowpan implementation")
|
||||
{
|
||||
}
|
||||
|
||||
void SixlowpanIphcImplTest::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
|
||||
{
|
||||
m_receivedPacket = packet;
|
||||
}
|
||||
|
||||
void SixlowpanIphcImplTest::ReceivePkt (Ptr<Socket> socket)
|
||||
{
|
||||
uint32_t availableData;
|
||||
availableData = socket->GetRxAvailable ();
|
||||
m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max (), 0);
|
||||
NS_ASSERT (availableData == m_receivedPacket->GetSize ());
|
||||
//cast availableData to void, to suppress 'availableData' set but not used
|
||||
//compiler warning
|
||||
(void) availableData;
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanIphcImplTest::DoSendData (Ptr<Socket> socket, std::string to)
|
||||
{
|
||||
Address realTo = Inet6SocketAddress (Ipv6Address (to.c_str ()), 1234);
|
||||
uint8_t buffer [] = "\"Can you tell me where my country lies?\" \\ said the unifaun to his true love's eyes. \\ \"It lies with me!\" cried the Queen of Maybe \\ - for her merchandise, he traded in his prize.";
|
||||
|
||||
Ptr<Packet> packet = Create<Packet> (buffer, 180);
|
||||
NS_TEST_EXPECT_MSG_EQ (socket->SendTo (packet, 0, realTo),
|
||||
180, "200");
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanIphcImplTest::SendData (Ptr<Socket> socket, std::string to)
|
||||
{
|
||||
m_receivedPacket = Create<Packet> ();
|
||||
Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0),
|
||||
&SixlowpanIphcImplTest::DoSendData, this, socket, to);
|
||||
Simulator::Run ();
|
||||
}
|
||||
|
||||
void
|
||||
SixlowpanIphcImplTest::DoRun (void)
|
||||
{
|
||||
// Create topology
|
||||
|
||||
// Receiver Node
|
||||
Ptr<Node> rxNode = CreateObject<Node> ();
|
||||
AddInternetStack6 (rxNode);
|
||||
Ptr<SimpleNetDevice> rxDev;
|
||||
{ // first interface
|
||||
rxDev = CreateObject<SimpleNetDevice> ();
|
||||
rxDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
|
||||
rxNode->AddDevice (rxDev);
|
||||
|
||||
Ptr<SixLowPanNetDevice> rxSix = CreateObject<SixLowPanNetDevice> ();
|
||||
rxSix->SetAttribute ("ForceEtherType", BooleanValue (true) );
|
||||
rxNode->AddDevice (rxSix);
|
||||
rxSix->SetNetDevice (rxDev);
|
||||
|
||||
Ptr<Ipv6> ipv6 = rxNode->GetObject<Ipv6> ();
|
||||
ipv6->AddInterface (rxDev);
|
||||
uint32_t netdev_idx = ipv6->AddInterface (rxSix);
|
||||
Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100::1"), Ipv6Prefix (64));
|
||||
ipv6->AddAddress (netdev_idx, ipv6Addr);
|
||||
ipv6->SetUp (netdev_idx);
|
||||
}
|
||||
|
||||
// Sender Node
|
||||
Ptr<Node> txNode = CreateObject<Node> ();
|
||||
AddInternetStack6 (txNode);
|
||||
Ptr<SimpleNetDevice> txDev;
|
||||
{
|
||||
txDev = CreateObject<SimpleNetDevice> ();
|
||||
txDev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
|
||||
txNode->AddDevice (txDev);
|
||||
|
||||
Ptr<SixLowPanNetDevice> txSix = CreateObject<SixLowPanNetDevice> ();
|
||||
txSix->SetAttribute ("ForceEtherType", BooleanValue (true) );
|
||||
txNode->AddDevice (txSix);
|
||||
txSix->SetNetDevice (txDev);
|
||||
|
||||
Ptr<Ipv6> ipv6 = txNode->GetObject<Ipv6> ();
|
||||
ipv6->AddInterface (txDev);
|
||||
uint32_t netdev_idx = ipv6->AddInterface (txSix);
|
||||
Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (Ipv6Address ("2001:0100::2"), Ipv6Prefix (64));
|
||||
ipv6->AddAddress (netdev_idx, ipv6Addr);
|
||||
ipv6->SetUp (netdev_idx);
|
||||
}
|
||||
|
||||
// link the two nodes
|
||||
Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> ();
|
||||
rxDev->SetChannel (channel1);
|
||||
txDev->SetChannel (channel1);
|
||||
|
||||
// Create the UDP sockets
|
||||
Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
|
||||
Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
|
||||
NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (Inet6SocketAddress (Ipv6Address ("2001:0100::1"), 1234)), 0, "trivial");
|
||||
rxSocket->SetRecvCallback (MakeCallback (&SixlowpanIphcImplTest::ReceivePkt, this));
|
||||
|
||||
Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
|
||||
Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
|
||||
txSocket->SetAllowBroadcast (true);
|
||||
// ------ Now the tests ------------
|
||||
|
||||
// Unicast test
|
||||
SendData (txSocket, "2001:0100::1");
|
||||
NS_TEST_EXPECT_MSG_EQ (m_receivedPacket->GetSize (), 180, "trivial");
|
||||
uint8_t rxBuffer [180];
|
||||
uint8_t txBuffer [180] = "\"Can you tell me where my country lies?\" \\ said the unifaun to his true love's eyes. \\ \"It lies with me!\" cried the Queen of Maybe \\ - for her merchandise, he traded in his prize.";
|
||||
m_receivedPacket->CopyData (rxBuffer, 180);
|
||||
NS_TEST_EXPECT_MSG_EQ (memcmp (rxBuffer, txBuffer, 180), 0, "trivial");
|
||||
|
||||
m_receivedPacket->RemoveAllByteTags ();
|
||||
|
||||
Simulator::Destroy ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class SixlowpanIphcTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
SixlowpanIphcTestSuite () : TestSuite ("sixlowpan-iphc", UNIT)
|
||||
{
|
||||
AddTestCase (new SixlowpanIphcImplTest, TestCase::QUICK);
|
||||
}
|
||||
} g_sixlowpanIphcTestSuite;
|
||||
33
src/sixlowpan/wscript
Normal file
33
src/sixlowpan/wscript
Normal file
@@ -0,0 +1,33 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_ns3_module('sixlowpan', ['internet', 'network', 'core'])
|
||||
module.includes = '.'
|
||||
module.source = [
|
||||
'model/sixlowpan-net-device.cc',
|
||||
'model/sixlowpan-header.cc',
|
||||
'helper/sixlowpan-helper.cc',
|
||||
]
|
||||
|
||||
module_test = bld.create_ns3_module_test_library('sixlowpan')
|
||||
module_test.source = [
|
||||
'test/sixlowpan-hc1-test.cc',
|
||||
'test/sixlowpan-iphc-test.cc',
|
||||
'test/error-channel-sixlow.cc',
|
||||
'test/sixlowpan-fragmentation-test.cc',
|
||||
|
||||
]
|
||||
|
||||
headers = bld(features=['ns3header'])
|
||||
headers.module = 'sixlowpan'
|
||||
headers.source = [
|
||||
'model/sixlowpan-net-device.h',
|
||||
'model/sixlowpan-header.h',
|
||||
'helper/sixlowpan-helper.h',
|
||||
]
|
||||
|
||||
|
||||
if (bld.env['ENABLE_EXAMPLES']):
|
||||
bld.recurse('examples')
|
||||
|
||||
bld.ns3_python_bindings()
|
||||
Reference in New Issue
Block a user