base implementation of the IEEE 802.11p standard

This commit is contained in:
Junling Bu
2013-12-03 11:25:59 -08:00
parent f1f6d27091
commit 044cba4bbd
33 changed files with 2842 additions and 57 deletions

View File

@@ -54,6 +54,18 @@ us a note on ns-developers mailing list.</p>
<h1>Changes from ns-3.18.1 to ns-3.19</h1>
<h2>New API:</h2>
<ul>
<li> A new wifi extension for vehicular simulation support is available in the
src/wave directory. The current code represents an interim capability to
realize an IEEE 802.11p-compliant device, but without the WAVE extensions
(which are planned for a later patch). The WaveNetDevice modelled herein
enforces that a WAVE-compliant physical layer (at 5.9 GHz) is selected, and
does not require any association between devices (similar to an adhoc WiFi
MAC), but is otherwise similar (at this time) to a WifiNetDevice. WAVE
capabililties of switching between control and service channels, or using
multiple radios, are not yet modelled.
</li>
</ul>
<h2>Changes to existing API:</h2>
<ul>

View File

@@ -22,6 +22,16 @@ Supported platforms
New user-visible features
-------------------------
- A new wifi extension for vehicular simulation support is available in src/wave
directory. The current code represents an interim capability to realize an
IEEE 802.11p-compliant device, but without the WAVE extensions (which
are planned for a later patch). The WaveNetDevice modelled herein enforces that
a WAVE-compliant physical layer (at 5.9 GHz) is selected, and does not require
any association between devices (similar to an adhoc WiFi MAC), but is
otherwise similar (at this time) to a WifiNetDevice. WAVE capabililties of
switching between control and service channels, or using multiple radios, are
not yet modelled.
Bugs fixed
----------
- Bug 1778 - Implement TapBridge::IsLinkUp() function

View File

@@ -78,6 +78,7 @@ SOURCES = \
$(SRC)/stats/doc/statistics.rst \
$(SRC)/netanim/doc/animation.rst \
$(SRC)/flow-monitor/doc/flow-monitor.rst \
$(SRC)/wave/doc/wave.rst \
# list all model library figure files that need to be copied to
# $SOURCETEMP/figures. For each figure to be included in all

View File

@@ -45,5 +45,6 @@ This document is written in `reStructuredText <http://docutils.sourceforge.net/r
spectrum
topology
uan
wave
wifi
wimax

311
src/wave/doc/wave.rst Normal file
View File

@@ -0,0 +1,311 @@
WAVE models
-----------
WAVE is a system architecture for wireless-based vehicular communications,
specified by the IEEE. This chapter documents available models for WAVE
within |ns3|. The focus is on the MAC layer and MAC extension layer
defined by [ieee80211p]_.
.. include:: replace.txt
.. heading hierarchy:
------------- Chapter
************* Section (#.#)
============= Subsection (#.#.#)
############# Paragraph (no number)
Model Description
*****************
WAVE is an overall system architecture for vehicular communications.
The standards for specifying WAVE include a set of extensions to the IEEE
802.11 standard, found in IEEE Std 802.11p-2010 [ieee80211p]_, and
the IEEE 1609 standard set, consisting of four documents:
resource manager: IEEE 1609.1 [ieee1609dot1]_,
security services: IEEE 1609.2 [ieee1609dot2]_,
network and transport layer services: IEEE 1609.3 [ieee1609dot3]_,
and multi-channel coordination: IEEE 1609.4 [ieee1609dot4]_.
In |ns3|, the focus of the ``wave`` module is on the MAC layer.
The key design aspect of WAVE-compilant MACs is that they allow
communications outside the context of a basic service set (BSS).
The literature uses the acronym OCB to denote "outside the context
of a BSS", and the class ``ns3::OcbWifiMac`` models this in |ns3|.
Many management frames will not be used, but when used, the BSSID field
needs to be set to a wildcard BSSID value.
Management information is transmitted by what is called a vendor specific
action frame.
With these changes, the packet transmissions (for a moving vehicle) can
be fast with small delay. At the physical layer, the biggest difference is
to use the 5.9 GHz band with a channel bandwidth of 10 MHz. These physical
layer changes can make the wireless signal relatively more stable,
without degrading throughput too much (ranging from 3 Mbps to 27 Mbps),
although 20 MHz channel bandwidth is still supported.
The source code for the WAVE MAC models lives in the directory
``src/wave``.
The current code represents an interim capability to realize an
802.11p-compliant device, but without the WAVE extensions (which
are planned for a later patch). In vehicular communications using
WAVE, radios have the capability of switching between control and
service channels, or using multiple radios. These aspects are not
yet modelled. The WaveNetDevice modelled herein enforces that
a WAVE-compliant physical layer (at 5.9 GHz) is selected, and
does not require any association between devices (similar to an
adhoc WiFi MAC), but is otherwise similar (at this time) to a
WifiNetDevice.
Design
======
In |ns3|, support for 802.11p involves the MAC and PHY layers.
To use an 802.11p NetDevice, ``ns3::Wifi80211pHelper`` is suggested.
MAC layer
#########
The classes used to model the MAC layer are ``ns3::OrganizationIdentifier``,
``ns3::VendorSpecificActionHeader``, ``ns3::HigherDataTxVectorTag``,
``ns3::WaveMacLow``, and ``ns3::OcbWifiMac``.
The OrganizationIdentifier and VendorSpecificActionHeader are used to support
the sending of a Vendor Specific Action frame. The HigherDataTxVectorTag
and WaveMacLow are used to support higher control transmission parameters.
These classes are all used in OcbWifiMac.
OcbWifiMac is very similar to AdhocWifiMac, with some modifications.
(|ns3| AdhocWifiMac class is implemented very close to the 802.11p OCB
mode rather than a real 802.11 ad-hoc mode. The AdhocWifiMac has no BSS
context that is defined in 802.11 standard, so it will not take time to
send beacon and authenticate.)
1. SetBssid, GetBssid, SetSsid, GetSsid
these methods are related to 802.11 BSS context which is unused in OCB context.
2. SetLinkUpCallback, SetLinkDownCallback
WAVE device can send packets directly, so the WiFi link is never down.
3. SendVsc, AddReceiveVscCallback
WAVE management information shall be sent by vendor specific action frame,
and it will be called by upper layer 1609.4 standard to send WSA
(WAVE Service Advertisement) packets or other vendor specific information.
4. SendTimingAdvertisement (not implemented)
Although Timing Advertisement is very important and specifically defined in
802.11p standard, it is not useful in a simulation environment.
Every node in |ns3| vehicular simulation is assumed to be already time
synchronized (perhaps by GPS).
5. ConfigureEdca
This method will allow the user to set EDCA parameters of WAVE channeles
including CCH ans SCHs. And the OcbWifiMac itself also uses this method
to configure default 802.11p EDCA parameters.
6. WILDCARD BSSID
The WILDCARD BSSID is set to "ff:ff:ff:ff:ff:ff".
As defined in 802.11-2007, a wildcard BSSID shall not be used in the
BSSID field except for management frames of subtype probe request. But Adhoc
mode of |ns3| simplifies this mechanism: when stations receive packets,
packets regardless of BSSID will be forwarded up to the higher layer.
This process is very close
to OCB mode as defined in 802.11p-2010, in which stations use the wildcard
BSSID to allow the higher layer of other stations to hear directly.
7. Enqueue, Receive
The most important methods are send and receive methods. According to the
standard, we should filter the frames that are not permitted. However here we
just identify the frames we care about; the other frames will be discarded.
PHY layer
#########
Actually, no modification or extension happens in the |ns3| PHY layer
corresponding to this model.
In the 802.11p standard, the PHY layer wireless technology is still 80211a OFDM with 10MHz channel width,
so Wifi80211pHelper will only allow the user to set the standard
to WIFI_PHY_STANDARD_80211_10MHZ or WIFI_PHY_STANDARD_80211_20MHZ
(WIFI_PHY_STANDARD_80211a with 20MHz is supported, but not recommended.)
The maximum station transmit power and maximum permitted EIRP defined in
802.11p is larger
than that of WiFi, so transmit range can normally become longer than
usual WiFi. However, this feature will
not be implemented. Users who want to obtain longer range should configure
attributes "TxPowerStart",
"TxPowerEnd" and "TxPowerLevels" of the YansWifiPhy class.
Scope and Limitations
=====================
1. Does the model involve vehicular mobility of some sort?
Vehicular networks involve not only communication protocols, but also
a communication environment
including vehicular mobility and propagation models. Because of specific
features of the latter, the protocols need to change. The MAC layer model
in this
project just adapts MAC changes to vehicular environment. However this model
does not involve any
vehicular mobility with time limit. Users can use any mobility model in |ns3|,
but should understand that vehicular mobility is out of scope for the
current WAVE module.
2. Is this model going to use different propagation models?
Referring to the first issue, some more realistic propagation models
for vehicualr environment
are suggested and welcome. And some existing propagation models in |ns3| are
also suitable.
Normally, users can use Friis, Two-Ray Ground, and Nakagami models.
3. Are there any vehicular application models to drive the code?
About vehicular application models, SAE J2375 depends on WAVE architecture and
is an application message set in US; CAM and DENM in Europe between network
and application layer, but is very close to application model. The BSM in
J2375 and CAM send alert messages that every
vehicle node will sent periodicity about its status information to
cooperate with others.
Fow now, a vehicular application model is not within scope.
References
==========
.. [ieee80211p] IEEE Std 802.11p-2010 "IEEE Standard for Information technology-- Local and metropolitan area networks-- Specific requirements-- Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications Amendment 6: Wireless Access in Vehicular Environments"
.. [ieee1609dot1] IEEE Std 1609.1-2010 "IEEE Standard for Wireless Access in Vehicular Environments (WAVE) - Resource Manager, 2010"
.. [ieee1609dot2] IEEE Std 1609.2-2010 "IEEE Standard for Wireless Access in Vehicular Environments (WAVE) - Security Services for Applications and Management Messages, 2010"
.. [ieee1609dot3] IEEE Std 1609.3-2010 "IEEE Standard for Wireless Access in Vehicular Environments (WAVE) - Networking Services, 2010"
.. [ieee1609dot4] IEEE Std 1609.4-2010 "IEEE Standard for Wireless Access in Vehicular Environments (WAVE) - Multi-Channel Operation, 2010"
Usage
*****
Helpers
=======
The helpers include ``ns3::NqosWaveMacHelper``, ``ns3::QosWaveMacHelper``,
``ns3::Wifi80211pHelper`` and ``ns3::WaveHelper``. Wifi80211pHelper is used
to create
802.11p devices that follow the 802.11p-2010 standard. WaveHelper is
used to create WAVE devices that follow the 802.11p-2010 and 1609.4-2010
standards which are the MAC and PHY layers of the WAVE architecture.
The relation of them is described as below:
::
WifiHelper ----------use----------> WifiMacHelper
^ ^ ^
| | |
| inherit inherit
| | |
| QosWifiMacHelper NqosWifiMacHelper
| ^ ^
| | |
inherit inherit inherit
| | |
Wifi80211pHelper QosWaveMacHelper NqosWaveHelper
Although Wifi80211Helper can use any subclasses inheriting from
WifiMacHelper, we force users to use subclasses inheriting from
QosWaveMacHelper or NqosWaveHelper.
Although the functions of WiFi 802.11p device can be achieved by
WaveNetDevice's ContinuousAccess assignment, Wifi80211pHelper is recommeneded
if there is no need for multiple channel operation.
Usage is as follows:
::
NodeContainer nodes;
NetDeviceContainer devices;
nodes.Create (2);
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
NqosWave80211pMacHelper wifi80211pMac = NqosWaveMacHelper::Default();
Wifi80211pHelper 80211pHelper = Wifi80211pHelper::Default ();
devices = 80211pHelper.Install (wifiPhy, wifi80211pMac, nodes);
APIs
====
The 802.11p device can allow the upper layer to send different information
over Vendor Specific Action management frames by using different
OrganizationIdentifier fields to identify differences.
1. already create a Node object and WifiNetDevice object
2. define an OrganizationIdentifier
::
uint8_t oi_bytes[5] = {0x00, 0x50, 0xC2, 0x4A, 0x40};
OrganizationIdentifier oi(oi_bytes,5);
3. define a Callback for the defined OrganizationIdentifier
::
VscCallback vsccall = MakeCallback (&VsaExample::GetWsaAndOi, this);
4. OcbWifiMac of 802.11p device registers this identifier and function
::
Ptr<WifiNetDevice> device1 = DynamicCast<WifiNetDevice>(nodes.Get (i)->GetDevice (0));
Ptr<OcbWifiMac> ocb1 = DynamicCast<OcbWifiMac>(device->GetMac ());
ocb1->AddReceiveVscCallback (oi, vsccall);
5. now one can send management packets over VSA frames
::
Ptr<Packet> vsc = Create<Packet> ();
ocb2->SendVsc (vsc, Mac48Address::GetBroadcast (), m_16093oi);
6. then registered callbacks in other devices will be called.
Attributes
==========
The current classes do not provide any additional attributes beyond those
in the WiFi module.
Output
======
The current classes provide output of the same type as WiFi devices;
namely, ASCII and pcap traces, and logging output. The WAVE logging
components can be enabled globally via the call to
::
Wifi80211pHelper::EnableLogComponents ();
Advanced Usage
==============
To be defined.
Examples
========
A basic example exists called ``wave-simple-80211p.cc``.
This example shows basic construction of an 802.11p node. Two nodes
are constructed with 802.11p devices, and by default, one node sends a single
packet to another node (the number of packets and interval between
them can be configured by command-line arguments). The example shows
typical usage of the helper classes for this mode of WiFi.
Troubleshooting
===============
To be defined.
Validation
**********
A single test suite named ``wifi-80211p-ocb`` is defined. This test
case consists of a stationary node and a mobile node. The mobile
node moves towards the stationary mode, and time points are checked
at which time the physical layer starts to receive packets (and
whether the MAC becomes associated, if applicable). The same physical
experiment is repeated for normal WiFi NetDevices in AP/STA mode, in
Adhoc mode, and the new OCB mode.

View File

@@ -0,0 +1,174 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006,2007 INRIA
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Junling Bu <linlinjavaer@gmail.com>
*
*/
/**
* This example shows basic construction of an 802.11p node. Two nodes
* are constructed with 802.11p devices, and by default, one node sends a single
* packet to another node (the number of packets and interval between
* them can be configured by command-line arguments). The example shows
* typical usage of the helper classes for this mode of WiFi (where "OCB" refers
* to "Outside the Context of a BSS")."
*/
#include "ns3/vector.h"
#include "ns3/string.h"
#include "ns3/socket.h"
#include "ns3/double.h"
#include "ns3/config.h"
#include "ns3/log.h"
#include "ns3/command-line.h"
#include "ns3/mobility-model.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/position-allocator.h"
#include "ns3/mobility-helper.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-interface-container.h"
#include <iostream>
#include "ns3/ocb-wifi-mac.h"
#include "ns3/wifi-80211p-helper.h"
#include "ns3/wave-mac-helper.h"
NS_LOG_COMPONENT_DEFINE ("WifiSimpleOcb");
using namespace ns3;
/*
* In WAVE module, there is no net device class named like "Wifi80211pNetDevice",
* instead, we need to use Wifi80211pHelper to create an object of
* WifiNetDevice class.
*
* usage:
* NodeContainer nodes;
* NetDeviceContainer devices;
* nodes.Create (2);
* YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
* YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
* wifiPhy.SetChannel (wifiChannel.Create ());
* NqosWaveMacHelper wifi80211pMac = NqosWave80211pMacHelper::Default();
* Wifi80211pHelper wifi80211p = Wifi80211pHelper::Default ();
* devices = wifi80211p.Install (wifiPhy, wifi80211pMac, nodes);
*
* The reason of not providing a 802.11p class is that most of modeling
* 802.11p standard has been done in wifi module, so we only need a high
* MAC class that enables OCB mode.
*/
void ReceivePacket (Ptr<Socket> socket)
{
NS_LOG_UNCOND ("Received one packet!");
}
static void GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize,
uint32_t pktCount, Time pktInterval )
{
if (pktCount > 0)
{
socket->Send (Create<Packet> (pktSize));
Simulator::Schedule (pktInterval, &GenerateTraffic,
socket, pktSize,pktCount - 1, pktInterval);
}
else
{
socket->Close ();
}
}
int main (int argc, char *argv[])
{
std::string phyMode ("OfdmRate6MbpsBW10MHz");
uint32_t packetSize = 1000; // bytes
uint32_t numPackets = 1;
double interval = 1.0; // seconds
bool verbose = false;
CommandLine cmd;
cmd.AddValue ("phyMode", "Wifi Phy mode", phyMode);
cmd.AddValue ("packetSize", "size of application packet sent", packetSize);
cmd.AddValue ("numPackets", "number of packets generated", numPackets);
cmd.AddValue ("interval", "interval (seconds) between packets", interval);
cmd.AddValue ("verbose", "turn on all WifiNetDevice log components", verbose);
cmd.Parse (argc, argv);
// Convert to time object
Time interPacketInterval = Seconds (interval);
NodeContainer c;
c.Create (2);
// The below set of helpers will help us to put together the wifi NICs we want
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
Ptr<YansWifiChannel> channel = wifiChannel.Create ();
wifiPhy.SetChannel (channel);
// ns-3 supports generate a pcap trace
wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11);
NqosWaveMacHelper wifi80211pMac = NqosWaveMacHelper::Default ();
Wifi80211pHelper wifi80211p = Wifi80211pHelper::Default ();
if (verbose)
{
wifi80211p.EnableLogComponents (); // Turn on all Wifi 802.11p logging
}
wifi80211p.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode",StringValue (phyMode),
"ControlMode",StringValue (phyMode));
NetDeviceContainer devices = wifi80211p.Install (wifiPhy, wifi80211pMac, c);
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (5.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (c);
InternetStackHelper internet;
internet.Install (c);
Ipv4AddressHelper ipv4;
NS_LOG_INFO ("Assign IP Addresses.");
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer i = ipv4.Assign (devices);
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
Ptr<Socket> recvSink = Socket::CreateSocket (c.Get (0), tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
recvSink->Bind (local);
recvSink->SetRecvCallback (MakeCallback (&ReceivePacket));
Ptr<Socket> source = Socket::CreateSocket (c.Get (1), tid);
InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), 80);
source->SetAllowBroadcast (true);
source->Connect (remote);
Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
Seconds (1.0), &GenerateTraffic,
source, packetSize, numPackets, interPacketInterval);
Simulator::Run ();
Simulator::Destroy ();
return 0;
}

View File

@@ -0,0 +1,6 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def build(bld):
obj = bld.create_ns3_program('wave-simple-80211p',
['core', 'applications', 'mobility', 'network', 'wifi','wave'])
obj.source = 'wave-simple-80211p.cc'

View File

@@ -0,0 +1,125 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2009 MIRKO BANCHI
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Mirko Banchi <mk.banchi@gmail.com>
* Author: Junling Bu <linlinjavaer@gmail.com>
*/
#include "ns3/wifi-mac.h"
#include "ns3/wifi-phy.h"
#include "ns3/log.h"
#include "ns3/pointer.h"
#include "ns3/boolean.h"
#include "ns3/string.h"
#include "wave-mac-helper.h"
namespace ns3 {
NqosWaveMacHelper::NqosWaveMacHelper (void)
{
}
NqosWaveMacHelper::~NqosWaveMacHelper (void)
{
}
NqosWaveMacHelper
NqosWaveMacHelper::Default (void)
{
NqosWaveMacHelper helper;
// We're making non QoS-enabled Wi-Fi MACs here, so we set the
// necessary attribute. I've carefully positioned this here so that
// someone who knows what they're doing can override with explicit
// attributes.
helper.SetType ("ns3::OcbWifiMac", "QosSupported", BooleanValue (false));
return helper;
}
void
NqosWaveMacHelper::SetType (std::string type,
std::string n0, const AttributeValue &v0,
std::string n1, const AttributeValue &v1,
std::string n2, const AttributeValue &v2,
std::string n3, const AttributeValue &v3,
std::string n4, const AttributeValue &v4,
std::string n5, const AttributeValue &v5,
std::string n6, const AttributeValue &v6,
std::string n7, const AttributeValue &v7)
{
if (type.compare ("ns3::OcbWifiMac") != 0)
{
NS_FATAL_ERROR ("QosWaveMacHelper shall set OcbWifiMac");
}
NqosWifiMacHelper::SetType ("ns3::OcbWifiMac",
n0, v0,
n1, v1,
n2, v2,
n3, v3,
n4, v4,
n5, v5,
n6, v6,
n7, v7);
}
/********** QosWifi80211pMacHelper *********/
QosWaveMacHelper::QosWaveMacHelper ()
{
}
QosWaveMacHelper::~QosWaveMacHelper ()
{
}
QosWaveMacHelper
QosWaveMacHelper::Default (void)
{
QosWaveMacHelper helper;
// We're making QoS-enabled Wi-Fi MACs here, so we set the necessary
// attribute. I've carefully positioned this here so that someone
// who knows what they're doing can override with explicit
// attributes.
helper.SetType ("ns3::OcbWifiMac", "QosSupported", BooleanValue (true));
return helper;
}
void
QosWaveMacHelper::SetType (std::string type,
std::string n0, const AttributeValue &v0,
std::string n1, const AttributeValue &v1,
std::string n2, const AttributeValue &v2,
std::string n3, const AttributeValue &v3,
std::string n4, const AttributeValue &v4,
std::string n5, const AttributeValue &v5,
std::string n6, const AttributeValue &v6,
std::string n7, const AttributeValue &v7)
{
if (type.compare ("ns3::OcbWifiMac") != 0)
{
NS_FATAL_ERROR ("QosWaveMacHelper shall set OcbWifiMac");
}
QosWifiMacHelper::SetType ("ns3::OcbWifiMac",
n0, v0,
n1, v1,
n2, v2,
n3, v3,
n4, v4,
n5, v5,
n6, v6,
n7, v7);
}
} // namespace ns3

View File

@@ -0,0 +1,144 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2009 MIRKO BANCHI
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Mirko Banchi <mk.banchi@gmail.com>
* Author: Junling Bu <linlinjavaer@gmail.com>
*/
#ifndef WAVE_MAC_HELPER_H
#define WAVE_MAC_HELPER_H
#include "ns3/qos-wifi-mac-helper.h"
#include "ns3/nqos-wifi-mac-helper.h"
namespace ns3 {
class NqosWaveMacHelper : public NqosWifiMacHelper
{
public:
/**
* Create a NqosWaveMacHelper to make life easier for people who want to
* work with non-QOS Wave MAC layers.
*/
NqosWaveMacHelper (void);
/**
* \internal
* Destroy a NqosWaveMacHelper.
*/
virtual ~NqosWaveMacHelper (void);
/**
* Create a mac helper in a default working state.
* i.e., this is an ocb mac by default.
*/
static NqosWaveMacHelper Default (void);
/**
* \param type the type of ns3::WifiMac to create.
* \param n0 the name of the attribute to set
* \param v0 the value of the attribute to set
* \param n1 the name of the attribute to set
* \param v1 the value of the attribute to set
* \param n2 the name of the attribute to set
* \param v2 the value of the attribute to set
* \param n3 the name of the attribute to set
* \param v3 the value of the attribute to set
* \param n4 the name of the attribute to set
* \param v4 the value of the attribute to set
* \param n5 the name of the attribute to set
* \param v5 the value of the attribute to set
* \param n6 the name of the attribute to set
* \param v6 the value of the attribute to set
* \param n7 the name of the attribute to set
* \param v7 the value of the attribute to set
*
* All the attributes specified in this method should exist
* in the requested mac.
*
* note: Here we require users set type with OcbWifiMac or its
* subclass, otherwise it will become error
*/
virtual void SetType (std::string type,
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
};
class QosWaveMacHelper : public QosWifiMacHelper
{
public:
/**
* Create a QosWaveMacHelper that is used to make life easier when working
* with Wifi 802.11p devices using a QOS MAC layer.
*/
QosWaveMacHelper (void);
/**
* \internal
* Destroy a QosWaveMacHelper
*/
virtual ~QosWaveMacHelper (void);
/**
* Create a mac helper in a default working state.
*/
static QosWaveMacHelper Default (void);
/**
* \param type the type of ns3::WifiMac to create.
* \param n0 the name of the attribute to set
* \param v0 the value of the attribute to set
* \param n1 the name of the attribute to set
* \param v1 the value of the attribute to set
* \param n2 the name of the attribute to set
* \param v2 the value of the attribute to set
* \param n3 the name of the attribute to set
* \param v3 the value of the attribute to set
* \param n4 the name of the attribute to set
* \param v4 the value of the attribute to set
* \param n5 the name of the attribute to set
* \param v5 the value of the attribute to set
* \param n6 the name of the attribute to set
* \param v6 the value of the attribute to set
* \param n7 the name of the attribute to set
* \param v7 the value of the attribute to set
*
* All the attributes specified in this method should exist
* in the requested mac.
*
* note: Here we require users set type with OcbWifiMac or its
* subclass, otherwise it will become error
*/
virtual void SetType (std::string type,
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
};
}
#endif /* WAVE_MAC_HELPER_H */

View File

@@ -0,0 +1,117 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2009 MIRKO BANCHI
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Mirko Banchi <mk.banchi@gmail.com>
* Author: Junling Bu <linlinjavaer@gmail.com>
*/
#include "ns3/string.h"
#include "ns3/log.h"
#include <typeinfo>
#include "wave-mac-helper.h"
#include "wifi-80211p-helper.h"
namespace ns3 {
Wifi80211pHelper::Wifi80211pHelper ()
{
}
Wifi80211pHelper::~Wifi80211pHelper ()
{
}
Wifi80211pHelper
Wifi80211pHelper::Default (void)
{
Wifi80211pHelper helper;
helper.SetStandard (WIFI_PHY_STANDARD_80211_10MHZ);
helper.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode", StringValue ("OfdmRate6MbpsBW10MHz"),
"ControlMode",StringValue ("OfdmRate6MbpsBW10MHz"));
return helper;
}
void
Wifi80211pHelper::SetStandard (enum WifiPhyStandard standard)
{
if ((standard == WIFI_PHY_STANDARD_80211a) || (standard == WIFI_PHY_STANDARD_80211_10MHZ))
{
WifiHelper::SetStandard (standard);
}
else
{
NS_FATAL_ERROR ("802.11p only use 802.11 standard with 10MHz or 20MHz");
}
}
void
Wifi80211pHelper::EnableLogComponents (void)
{
WifiHelper::EnableLogComponents ();
LogComponentEnable ("OcbWifiMac", LOG_LEVEL_ALL);
LogComponentEnable ("VendorSpecificAction", LOG_LEVEL_ALL);
}
NetDeviceContainer
Wifi80211pHelper::Install (const WifiPhyHelper &phyHelper, const WifiMacHelper &macHelper, NodeContainer c) const
{
bool isWaveMacHelper = false;
try
{
const QosWaveMacHelper& qosMac = dynamic_cast<const QosWaveMacHelper&> (macHelper);
isWaveMacHelper = true;
// below check will never fail, just used for survive from
// gcc warn "-Wunused-but-set-variable"
if (&qosMac == 0)
{
NS_FATAL_ERROR ("it could never get here");
}
}
catch (const std::bad_cast &)
{
}
try
{
const NqosWaveMacHelper& nqosMac = dynamic_cast<const NqosWaveMacHelper&> (macHelper);
isWaveMacHelper = true;
if (&nqosMac == 0)
{
NS_FATAL_ERROR ("it could never get here");
}
}
catch (const std::bad_cast &)
{
}
if (!isWaveMacHelper)
{
NS_FATAL_ERROR ("the macHelper should be either QosWaveMacHelper or NqosWaveMacHelper"
", or should be the subclass of QosWaveMacHelper or NqosWaveMacHelper");
}
return WifiHelper::Install (phyHelper, macHelper, c);
}
} // namespace ns3

View File

@@ -0,0 +1,79 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2009 MIRKO BANCHI
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Mirko Banchi <mk.banchi@gmail.com>
* Author: Junling Bu <linlinjavaer@gmail.com>
*/
#ifndef WIFI_802_11P_HELPER_H
#define WIFI_802_11P_HELPER_H
#include "ns3/wifi-helper.h"
namespace ns3 {
/**
* \brief helps to create wifi 802.11p objects of
* WifiNetDevice class
*
* This class can help to create a large set of similar
* wifi 802.11p objects and to configure a large set of
* their attributes during creation.
*/
class Wifi80211pHelper : public WifiHelper
{
public:
Wifi80211pHelper ();
virtual ~Wifi80211pHelper ();
/**
* \returns a new Wifi80211pHelper in a default state
*
* The default state is defined as being an OcbWifiMac MAC
* layer with constant rate OfdmRate6MbpsBW10MHz
* and both objects using their default attribute values.
*/
static Wifi80211pHelper Default (void);
/**
* \param standard the phy standard to configure during installation
*
* Users can only configure 802.11a with 10MHz channel bandwidth indicated by
* WIFI_PHY_STANDARD_80211_10MHZ or 20MHz channel bandwidth indicated by
* WIFI_PHY_STANDARD_80211a, other standard types will be not allowed.
* The default standard is 10MHz.
*/
virtual void SetStandard (enum WifiPhyStandard standard);
/**
* \param phy the PHY helper to create PHY objects
* \param mac the MAC helper to create MAC objects
* \param c the set of nodes on which a wifi device must be created
* \returns a device container which contains all the devices created by this method.
*/
virtual NetDeviceContainer Install (const WifiPhyHelper &phy, const WifiMacHelper &macHelper,NodeContainer c) const;
/**
* Helper to enable all WifiNetDevice log components with one statement
*/
static void EnableLogComponents (void);
};
}
#endif /* WIFI_802_11P_HELPER_H */

View File

@@ -0,0 +1,104 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Junling Bu <linlinjavaer@gmail.com>
*/
#include "higher-tx-tag.h"
#include "ns3/tag.h"
#include "ns3/log.h"
#include "ns3/uinteger.h"
NS_LOG_COMPONENT_DEFINE ("HigherDataTxVectorTag");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (HigherDataTxVectorTag);
TypeId
HigherDataTxVectorTag::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::HigherDataTxVectorTag")
.SetParent<Tag> ()
.AddConstructor<HigherDataTxVectorTag> ()
;
return tid;
}
HigherDataTxVectorTag::HigherDataTxVectorTag (void)
: m_adapter (false)
{
NS_LOG_FUNCTION (this);
}
HigherDataTxVectorTag::HigherDataTxVectorTag (WifiTxVector dataTxVector, bool adapter)
: m_dataTxVector (dataTxVector),
m_adapter (adapter)
{
NS_LOG_FUNCTION (this);
}
HigherDataTxVectorTag::~HigherDataTxVectorTag (void)
{
NS_LOG_FUNCTION (this);
}
TypeId
HigherDataTxVectorTag::GetInstanceTypeId (void) const
{
NS_LOG_FUNCTION (this);
return GetTypeId ();
}
WifiTxVector
HigherDataTxVectorTag::GetDataTxVector (void) const
{
NS_LOG_FUNCTION (this);
return m_dataTxVector;
}
bool
HigherDataTxVectorTag::IsAdapter (void) const
{
NS_LOG_FUNCTION (this);
return m_adapter;
}
uint32_t
HigherDataTxVectorTag::GetSerializedSize (void) const
{
NS_LOG_FUNCTION (this);
return (sizeof (WifiTxVector) + 1);
}
void
HigherDataTxVectorTag::Serialize (TagBuffer i) const
{
NS_LOG_FUNCTION (this << &i);
i.Write ((uint8_t *)&m_dataTxVector, sizeof (WifiTxVector));
i.WriteU8 (static_cast<uint8_t> (m_adapter));
}
void
HigherDataTxVectorTag::Deserialize (TagBuffer i)
{
NS_LOG_FUNCTION (this << &i);
i.Read ((uint8_t *)&m_dataTxVector, sizeof (WifiTxVector));
m_adapter = i.ReadU8 ();
}
void
HigherDataTxVectorTag::Print (std::ostream &os) const
{
NS_LOG_FUNCTION (this << &os);
os << " Data=" << m_dataTxVector << " Adapter=" << m_adapter;
}
} // namespace ns3

View File

@@ -0,0 +1,59 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Junling Bu <linlinjavaer@gmail.com>
*/
#ifndef HIGHER_DATA_TXVECTOR_TAG_H
#define HIGHER_DATA_TXVECTOR_TAG_H
#include "ns3/packet.h"
#include "ns3/wifi-tx-vector.h"
namespace ns3 {
class Tag;
/**
* This tag will be used to support higher layer control data rate
* and tx power level.
*/
class HigherDataTxVectorTag : public Tag
{
public:
HigherDataTxVectorTag (void);
HigherDataTxVectorTag (WifiTxVector dataTxVector, bool adapter);
virtual ~HigherDataTxVectorTag (void);
WifiTxVector GetDataTxVector (void) const;
bool IsAdapter (void) const;
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual uint32_t GetSerializedSize (void) const;
virtual void Serialize (TagBuffer i) const;
virtual void Deserialize (TagBuffer i);
virtual void Print (std::ostream &os) const;
private:
WifiTxVector m_dataTxVector;
bool m_adapter;
};
} // namespace ns3
#endif /* HIGHER_DATA_TXVECTOR_TAG_H*/

View File

@@ -0,0 +1,372 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Junling Bu <linlinjavaer@gmail.com>
*/
#include "ns3/pointer.h"
#include "ns3/log.h"
#include "ns3/string.h"
#include "ns3/qos-tag.h"
#include "ns3/mac-low.h"
#include "ns3/dcf-manager.h"
#include "ns3/mac-rx-middle.h"
#include "ns3/mgt-headers.h"
#include "wave-mac-low.h"
#include "ocb-wifi-mac.h"
#include "vendor-specific-action.h"
#include "higher-tx-tag.h"
NS_LOG_COMPONENT_DEFINE ("OcbWifiMac");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (OcbWifiMac);
const static Mac48Address WILDCARD_BSSID = Mac48Address::GetBroadcast ();
TypeId
OcbWifiMac::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::OcbWifiMac")
.SetParent<RegularWifiMac> ()
.AddConstructor<OcbWifiMac> ()
;
return tid;
}
OcbWifiMac::OcbWifiMac (void)
{
NS_LOG_FUNCTION (this);
// use WaveMacLow instead of MacLow
m_low = CreateObject<WaveMacLow> ();
m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
m_dcfManager->SetupLowListener (m_low);
m_dca->SetLow (m_low);
for (EdcaQueues::iterator i = m_edca.begin (); i != m_edca.end (); ++i)
{
i->second->SetLow (m_low);
}
// Let the lower layers know that we are acting as an OCB node
SetTypeOfStation (OCB);
// BSSID is still needed in the low part of MAC
RegularWifiMac::SetBssid (WILDCARD_BSSID);
}
OcbWifiMac::~OcbWifiMac (void)
{
NS_LOG_FUNCTION (this);
}
void
OcbWifiMac::SendVsc (Ptr<Packet> vsc, Mac48Address peer, OrganizationIdentifier oi)
{
NS_LOG_FUNCTION (this << vsc << peer << oi);
WifiMacHeader hdr;
hdr.SetAction ();
hdr.SetAddr1 (peer);
hdr.SetAddr2 (GetAddress ());
hdr.SetAddr3 (WILDCARD_BSSID);
hdr.SetDsNotFrom ();
hdr.SetDsNotTo ();
VendorSpecificActionHeader vsa;
vsa.SetOrganizationIdentifier (oi);
vsc->AddHeader (vsa);
if (m_qosSupported)
{
uint8_t tid = QosUtilsGetTidForPacket (vsc);
tid = tid > 7 ? 0 : tid;
m_edca[QosUtilsMapTidToAc (tid)]->Queue (vsc, hdr);
}
else
{
m_dca->Queue (vsc, hdr);
}
}
void
OcbWifiMac::AddReceiveVscCallback (OrganizationIdentifier oi, VscCallback cb)
{
NS_LOG_FUNCTION (this << oi << &cb);
m_vscManager.RegisterVscCallback (oi, cb);
}
void
OcbWifiMac::RemoveReceiveVscCallback (OrganizationIdentifier oi)
{
NS_LOG_FUNCTION (this << oi);
m_vscManager.DeregisterVscCallback (oi);
}
void
OcbWifiMac::SetSsid (Ssid ssid)
{
NS_LOG_WARN ("in OCB mode we should not call SetSsid");
}
Ssid
OcbWifiMac::GetSsid (void) const
{
NS_FATAL_ERROR ("in OCB mode we should not call GetSsid");
// we really do not want to return ssid, however we have to provide
return RegularWifiMac::GetSsid ();
}
void
OcbWifiMac::SetBssid (Mac48Address bssid)
{
NS_FATAL_ERROR ("in OCB mode we should not call SetBsid");
}
Mac48Address
OcbWifiMac::GetBssid (void) const
{
NS_FATAL_ERROR ("in OCB mode we should not call GetBssid");
return WILDCARD_BSSID;
}
void
OcbWifiMac::SetLinkUpCallback (Callback<void> linkUp)
{
NS_LOG_FUNCTION (this << &linkUp);
RegularWifiMac::SetLinkUpCallback (linkUp);
// The approach taken here is that, from the point of view of a STA
// in OCB mode, the link is always up, so we immediately invoke the
// callback if one is set
linkUp ();
}
void
OcbWifiMac::SetLinkDownCallback (Callback<void> linkDown)
{
NS_LOG_FUNCTION (this << &linkDown);
RegularWifiMac::SetLinkDownCallback (linkDown);
NS_LOG_WARN ("in OCB mode the like will never down, so linkDown will never be called");
}
void
OcbWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
{
NS_LOG_FUNCTION (this << packet << to);
if (m_stationManager->IsBrandNew (to))
{
// In ocb mode, we assume that every destination supports all
// the rates we support.
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
m_stationManager->AddSupportedMode (to, m_phy->GetMode (i));
}
m_stationManager->RecordDisassociated (to);
}
WifiMacHeader hdr;
// If we are not a QoS STA then we definitely want to use AC_BE to
// transmit the packet. A TID of zero will map to AC_BE (through \c
// QosUtilsMapTidToAc()), so we use that as our default here.
uint8_t tid = 0;
if (m_qosSupported)
{
hdr.SetType (WIFI_MAC_QOSDATA);
hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
hdr.SetQosNoEosp ();
hdr.SetQosNoAmsdu ();
// About transmission of multiple frames,
// in Ad-hoc mode TXOP is not supported for now, so TxopLimit=0;
// however in OCB mode, 802.11p do not allow transmit multiple frames
// so TxopLimit must equal 0
hdr.SetQosTxopLimit (0);
// Fill in the QoS control field in the MAC header
tid = QosUtilsGetTidForPacket (packet);
// Any value greater than 7 is invalid and likely indicates that
// the packet had no QoS tag, so we revert to zero, which'll
// mean that AC_BE is used.
if (tid >= 7)
{
tid = 0;
}
hdr.SetQosTid (tid);
}
else
{
hdr.SetTypeData ();
}
hdr.SetAddr1 (to);
hdr.SetAddr2 (GetAddress ());
hdr.SetAddr3 (WILDCARD_BSSID);
hdr.SetDsNotFrom ();
hdr.SetDsNotTo ();
if (m_qosSupported)
{
// Sanity check that the TID is valid
NS_ASSERT (tid < 8);
m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr);
}
else
{
m_dca->Queue (packet, hdr);
}
}
/*
* see 802.11p-2010 chapter 11.19
* here we only care about data packet and vsa management frame
*/
void
OcbWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
{
NS_LOG_FUNCTION (this << packet << hdr);
NS_ASSERT (!hdr->IsCtl ());
NS_ASSERT (hdr->GetAddr3 () == WILDCARD_BSSID);
Mac48Address from = hdr->GetAddr2 ();
Mac48Address to = hdr->GetAddr1 ();
if (hdr->IsData ())
{
if (hdr->IsQosData () && hdr->IsQosAmsdu ())
{
NS_LOG_DEBUG ("Received A-MSDU from" << from);
DeaggregateAmsduAndForward (packet, hdr);
}
else
{
ForwardUp (packet, from, to);
}
return;
}
// why put check here, not before "if (hdr->IsData ())" ?
// because WifiNetDevice::ForwardUp needs to m_promiscRx data packet
// and will filter data packet for itself
// so we need to filter management frame
if (to != GetAddress () && !to.IsGroup ())
{
NS_LOG_LOGIC ("the management frame is not for us");
NotifyRxDrop (packet);
return;
}
if (hdr->IsMgt () && hdr->IsAction ())
{
// yes, we only care about VendorSpecificAction frame in OCB mode
// other management frames will be handled by RegularWifiMac::Receive
VendorSpecificActionHeader vsaHdr;
packet->PeekHeader (vsaHdr);
if (vsaHdr.GetCategory () == CATEGORY_OF_VSA)
{
VendorSpecificActionHeader vsa;
packet->RemoveHeader (vsa);
OrganizationIdentifier oi = vsa.GetOrganizationIdentifier ();
VscCallback cb = m_vscManager.FindVscCallback (oi);
if (cb.IsNull ())
{
NS_LOG_DEBUG ("cannot find VscCallback for OrganizationIdentifier=" << oi);
return;
}
bool succeed = cb (this, oi,packet, from);
if (!succeed)
{
NS_LOG_DEBUG ("vsc callback could not handle the packet successfully");
}
return;
}
}
// Invoke the receive handler of our parent class to deal with any
// other frames. Specifically, this will handle Block Ack-related
// Management Action frames.
RegularWifiMac::Receive (packet, hdr);
}
void
OcbWifiMac::ConfigureEdca (uint32_t cwmin, uint32_t cwmax, uint32_t aifsn, enum AcIndex ac)
{
Ptr<Dcf> dcf;
switch (ac)
{
case AC_VO:
dcf = RegularWifiMac::GetVOQueue ();
dcf->SetMinCw ((cwmin + 1) / 4 - 1);
dcf->SetMaxCw ((cwmin + 1) / 2 - 1);
dcf->SetAifsn (aifsn);
break;
case AC_VI:
dcf = RegularWifiMac::GetVIQueue ();
dcf->SetMinCw ((cwmin + 1) / 2 - 1);
dcf->SetMaxCw (cwmin);
dcf->SetAifsn (aifsn);
break;
case AC_BE:
dcf = RegularWifiMac::GetBEQueue ();
dcf->SetMinCw (cwmin);
dcf->SetMaxCw (cwmax);
dcf->SetAifsn (aifsn);
break;
case AC_BK:
dcf = RegularWifiMac::GetBKQueue ();
dcf->SetMinCw (cwmin);
dcf->SetMaxCw (cwmax);
dcf->SetAifsn (aifsn);
break;
case AC_BE_NQOS:
dcf = RegularWifiMac::GetDcaTxop ();
dcf->SetMinCw (cwmin);
dcf->SetMaxCw (cwmax);
dcf->SetAifsn (aifsn);
break;
case AC_UNDEF:
NS_FATAL_ERROR ("I don't know what to do with this");
break;
}
}
void
OcbWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
{
NS_ASSERT ((standard == WIFI_PHY_STANDARD_80211_10MHZ)
|| (standard == WIFI_PHY_STANDARD_80211a));
uint32_t cwmin = 15;
uint32_t cwmax = 1023;
// The special value of AC_BE_NQOS which exists in the Access
// Category enumeration allows us to configure plain old DCF.
ConfigureEdca (cwmin, cwmax, 2, AC_BE_NQOS);
// Now we configure the EDCA functions
// see IEEE802.11p-2010 section 7.3.2.29
// Wave CCH and SCHs set default 802.11p EDCA
ConfigureEdca (cwmin, cwmax, 2, AC_VO);
ConfigureEdca (cwmin, cwmax, 3, AC_VI);
ConfigureEdca (cwmin, cwmax, 6, AC_BE);
ConfigureEdca (cwmin, cwmax, 9, AC_BK);
}
} // namespace ns3

View File

@@ -0,0 +1,141 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Junling Bu <linlinjavaer@gmail.com>
*/
#ifndef OCB_WIFI_MAC_H
#define OCB_WIFI_MAC_H
#include "ns3/object-factory.h"
#include "ns3/regular-wifi-mac.h"
#include "ns3/wifi-mac-queue.h"
#include "ns3/qos-utils.h"
#include "vendor-specific-action.h"
namespace ns3 {
class OrganizationIdentifier;
class WifiMacQueue;
/**
* \brief STAs communicate with each directly outside the context of a BSS
* \ingroup wave
*
* In OCB mac mode,synchronization, association, dis-association
* and authentication of normal wifi are not used for wireless access in
* vehicular environments.
*
* Although Timing Advertisement frame is a specific management frame defined
* in 802.11p. It is mainly used by IEEE Std 1609.4 for channel switch synchronization.
* However in simulation nodes are supposed to have GPS synchronization ability,
* so we will not implement this feature.
*/
class OcbWifiMac : public RegularWifiMac
{
public:
static TypeId GetTypeId (void);
OcbWifiMac (void);
virtual ~OcbWifiMac (void);
/**
* \param vsc management packet to send.
* \param peer the address to which the packet should be sent.
* \param oi Organization Identifier field
* see 7.3.1.31 Organization Identifier field and 10.3.29 Vendor-specific action
*
* management information can be transmitted over vender specific action frame.
* This will be mainly called by IEEE Std 1609.4 to send WSA from IEEE Std 1609.3
*/
void SendVsc (Ptr<Packet> vsc, Mac48Address peer, OrganizationIdentifier oi);
/**
* \param oi Organization Identifier
* \param cb callback to invoke whenever a vender specific action frame has been received and must
* be forwarded to the higher layers.
* every node shall register first if it wants to receive specific vendor specific content.
*/
void AddReceiveVscCallback (OrganizationIdentifier oi, VscCallback cb);
void RemoveReceiveVscCallback (OrganizationIdentifier oi);
/**
* \returns the ssid which this MAC layer is going to try to stay in.
*
* This method shall not be used in WAVE environment and
* here it will overloaded to log warn message
*/
virtual Ssid GetSsid (void) const;
/**
* \param ssid the current ssid of this MAC layer.
*
* This method shall not be used in WAVE environment and
* here it will overloaded to log warn message
*/
virtual void SetSsid (Ssid ssid);
/**
* \param bssid the BSSID of the network that this device belongs to.
* This method shall not be used in WAVE environment and
* here it will overloaded to log warn message
*/
virtual void SetBssid (Mac48Address bssid);
/**
* \param bssid the BSSID of the network that this device belongs to.
*
* This method shall not be used in WAVE environment and
* here it will overloaded to log warn message
*/
virtual Mac48Address GetBssid (void) const;
/**
* SetLinkUpCallback and SetLinkDownCallback will be overloaded
* In OCB mode, stations can send packets directly whenever they want
* so the link is always up and never down even during channel switch
*/
/**
* \param linkUp the callback to invoke when the link becomes up.
*/
virtual void SetLinkUpCallback (Callback<void> linkUp);
/**
* \param linkDown the callback to invoke when the link becomes down.
*/
virtual void SetLinkDownCallback (Callback<void> linkDown);
/**
* \param packet the packet to send.
* \param to the address to which the packet should be sent.
*
* The packet should be enqueued in a tx queue, and should be
* dequeued as soon as the channel access function determines that
* access is granted to this MAC.
*/
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
/**
* \param cwmin the min contention window
* \param cwmax the max contention window
* \param aifsn the arbitration inter-frame space
* \param ac the access category index
*
* configure EDCA queue parameters
*/
void ConfigureEdca (uint32_t cwmin, uint32_t cwmax, uint32_t aifsn, enum AcIndex ac);
protected:
virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
private:
virtual void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
VendorSpecificContentManager m_vscManager;
};
}
#endif /* OCB_WIFI_MAC_H */

View File

@@ -0,0 +1,346 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013 Dalian University of Technology
* 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: Junling Bu <linlinjavaer@gmail.com>
*/
#include <iomanip>
#include <iostream>
#include <cstring>
#include "ns3/log.h"
#include "ns3/assert.h"
#include "vendor-specific-action.h"
NS_LOG_COMPONENT_DEFINE ("VendorSpecificAction");
namespace ns3 {
/*********** OrganizationIdentifier *******/
ATTRIBUTE_HELPER_CPP (OrganizationIdentifier);
OrganizationIdentifier::OrganizationIdentifier (void)
: m_type (Unknown)
{
NS_LOG_FUNCTION (this);
m_type = Unknown;
std::memset (m_oi, 0, 5);
}
OrganizationIdentifier::OrganizationIdentifier (const uint8_t *str, uint32_t length)
{
NS_LOG_FUNCTION (this << str << length);
if (length == 3)
{
m_type = OUI24;
std::memcpy (m_oi, str, length);
}
else if (length == 5)
{
m_type = OUI36;
std::memcpy (m_oi, str, length);
}
else
{
m_type = Unknown;
NS_FATAL_ERROR ("cannot support organization identifier with length=" << length);
}
}
OrganizationIdentifier&
OrganizationIdentifier::operator= (const OrganizationIdentifier& oi)
{
this->m_type = oi.m_type;
std::memcpy (this->m_oi, oi.m_oi, 5);
return (*this);
}
OrganizationIdentifier::~OrganizationIdentifier (void)
{
NS_LOG_FUNCTION (this);
}
uint8_t
OrganizationIdentifier::GetManagementId (void) const
{
NS_LOG_FUNCTION (this);
NS_ASSERT (m_type == OUI36);
return (m_oi[4] & 0x0f);
}
bool
OrganizationIdentifier::IsNull (void) const
{
NS_LOG_FUNCTION (this);
return m_type == Unknown;
}
uint32_t
OrganizationIdentifier::GetSerializedSize (void) const
{
NS_LOG_FUNCTION (this);
switch (m_type)
{
case OUI24:
return 3;
case OUI36:
return 5;
case Unknown:
default:
NS_FATAL_ERROR_NO_MSG ();
return 0;
}
}
void
OrganizationIdentifier::SetType (enum OrganizationIdentifierType type)
{
NS_LOG_FUNCTION (this);
m_type = type;
}
enum OrganizationIdentifier::OrganizationIdentifierType
OrganizationIdentifier::GetType (void) const
{
NS_LOG_FUNCTION (this);
return m_type;
}
void
OrganizationIdentifier::Serialize (Buffer::Iterator start) const
{
NS_LOG_FUNCTION (this << &start);
start.Write (m_oi, GetSerializedSize ());
}
/* because OrganizationIdentifier field is not standard
* and the length of OrganizationIdentifier is variable
* so data parse here is troublesome
*/
uint32_t
OrganizationIdentifier::Deserialize (Buffer::Iterator start)
{
NS_LOG_FUNCTION (this << &start);
// first try to parse OUI24 with 3 bytes
start.Read (m_oi, 3);
for (std::vector<OrganizationIdentifier>::iterator i = OrganizationIdentifiers.begin (); i != OrganizationIdentifiers.end (); ++i)
{
if ((i->m_type == OUI24)
&& (std::memcmp (i->m_oi, m_oi, 3) == 0 ))
{
m_type = OUI24;
return 3;
}
}
// then try to parse OUI36 with 5 bytes
start.Read (m_oi + 3, 2);
for (std::vector<OrganizationIdentifier>::iterator i = OrganizationIdentifiers.begin (); i != OrganizationIdentifiers.end (); ++i)
{
if ((i->m_type == OUI36)
&& (std::memcmp (i->m_oi, m_oi, 4) == 0 ))
{
// OUI36 first check 4 bytes, then check half of the 5th byte
if ((i->m_oi[4] & 0xf0) == (m_oi[4] & 0xf0))
{
m_type = OUI36;
return 5;
}
}
}
// if we cannot deserialize the organization identifier field,
// we will fail
NS_FATAL_ERROR ("cannot deserialize the organization identifier field successfully");
return 0;
}
bool operator == (const OrganizationIdentifier& a, const OrganizationIdentifier& b)
{
if (a.m_type != b.m_type)
{
return false;
}
if (a.m_type == OrganizationIdentifier::OUI24)
{
return memcmp (a.m_oi, b.m_oi, 3) == 0;
}
if (a.m_type == OrganizationIdentifier::OUI36)
{
return (memcmp (a.m_oi, b.m_oi, 4) == 0)
&& ((a.m_oi[4] & 0xf0) == (b.m_oi[4] & 0xf0));
}
return false;
}
bool operator != (const OrganizationIdentifier& a, const OrganizationIdentifier& b)
{
return !(a == b);
}
bool operator < (const OrganizationIdentifier& a, const OrganizationIdentifier& b)
{
return memcmp (a.m_oi, b.m_oi, std::min (a.m_type, b.m_type)) < 0;
}
std::ostream& operator << (std::ostream& os, const OrganizationIdentifier& oi)
{
for (uint32_t i = 0; i < oi.m_type; i++)
{
os << "0x" << std::hex << static_cast<int> (oi.m_oi[i]) << " ";
}
os << std::endl;
return os;
}
std::istream& operator >> (std::istream& is, const OrganizationIdentifier& oi)
{
return is;
}
/*********** VendorSpecificActionHeader *******/
NS_OBJECT_ENSURE_REGISTERED (VendorSpecificActionHeader);
VendorSpecificActionHeader::VendorSpecificActionHeader (void)
: m_oi (),
m_category (CATEGORY_OF_VSA)
{
NS_LOG_FUNCTION (this);
}
VendorSpecificActionHeader::~VendorSpecificActionHeader (void)
{
NS_LOG_FUNCTION (this);
}
void
VendorSpecificActionHeader::SetOrganizationIdentifier (OrganizationIdentifier oi)
{
NS_LOG_FUNCTION (this << oi);
m_oi = oi;
}
OrganizationIdentifier
VendorSpecificActionHeader::GetOrganizationIdentifier (void) const
{
NS_LOG_FUNCTION (this);
return m_oi;
}
TypeId
VendorSpecificActionHeader::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::VendorSpecificActionHeader")
.SetParent<Header> ()
.AddConstructor<VendorSpecificActionHeader> ()
;
return tid;
}
uint8_t
VendorSpecificActionHeader::GetCategory (void) const
{
NS_LOG_FUNCTION (this);
return m_category;
}
TypeId
VendorSpecificActionHeader::GetInstanceTypeId (void) const
{
NS_LOG_FUNCTION (this);
return GetTypeId ();
}
void
VendorSpecificActionHeader::Print (std::ostream &os) const
{
NS_LOG_FUNCTION (this << &os);
os << "VendorSpecificActionHeader[ "
<< "category = 0x" << std::hex << (int)m_category
<< "organization identifier = " << m_oi
<< std::dec;
}
uint32_t
VendorSpecificActionHeader::GetSerializedSize (void) const
{
NS_LOG_FUNCTION (this);
return sizeof(m_category) + m_oi.GetSerializedSize ();
}
void
VendorSpecificActionHeader::Serialize (Buffer::Iterator start) const
{
NS_LOG_FUNCTION (this << &start);
start.WriteU8 (m_category);
m_oi.Serialize (start);
}
uint32_t
VendorSpecificActionHeader::Deserialize (Buffer::Iterator start)
{
NS_LOG_FUNCTION (this << &start);
m_category = start.ReadU8 ();
if (m_category != CATEGORY_OF_VSA)
{
return 0;
}
m_oi.Deserialize (start);
return GetSerializedSize ();
}
/********* VendorSpecificContentManager ***********/
VendorSpecificContentManager::VendorSpecificContentManager (void)
{
NS_LOG_FUNCTION (this);
}
VendorSpecificContentManager::~VendorSpecificContentManager (void)
{
NS_LOG_FUNCTION (this);
}
void
VendorSpecificContentManager::RegisterVscCallback (OrganizationIdentifier oi, VscCallback cb)
{
NS_LOG_FUNCTION (this << oi << &cb);
m_callbacks.insert (std::make_pair (oi, cb));
OrganizationIdentifiers.push_back (oi);
}
void
VendorSpecificContentManager::DeregisterVscCallback (OrganizationIdentifier &oi)
{
NS_LOG_FUNCTION (this << oi);
m_callbacks.erase (oi);
}
static VscCallback null_callback = MakeNullCallback<bool, Ptr<WifiMac>, const OrganizationIdentifier &,Ptr<const Packet>,const Address &> ();
VscCallback
VendorSpecificContentManager::FindVscCallback (OrganizationIdentifier &oi)
{
NS_LOG_FUNCTION (this << oi);
VscCallbacksI i;
i = m_callbacks.find (oi);
return (i == m_callbacks.end ()) ? null_callback : i->second;
}
} // namespace ns3

View File

@@ -0,0 +1,191 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013 Dalian University of Technology
* 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: Junling Bu <linlinjavaer@gmail.com>
*/
#ifndef Vendor_Specific_Action_H
#define Vendor_Specific_Action_H
#include <ostream>
#include <map>
#include "ns3/header.h"
#include "ns3/packet.h"
#include "ns3/pointer.h"
#include "ns3/attribute.h"
#include "ns3/attribute-helper.h"
#include "ns3/address.h"
#include "ns3/wifi-mac.h"
namespace ns3 {
class VendorSpecificContentManager;
/**
* \brief the organization identifier is a public organizationally
* unique identifier assigned by the IEEE.
* \ingroup wave
*
* Similar to protocol field of data packets that indicates which
* entity of higher layer should handle received packets, Organization
* Identifier field is used in Vendor Specific Action frames to
* indicate which entity or higher layer should handle vendor specific
* content.
* Normally the value is assigned by IEEE and the length of field is
* either 24 bits or 36 bits.
* For more, see IEEE802.11p-2010 section 7.3.1.31 and 7.4.5
*/
class OrganizationIdentifier
{
public:
OrganizationIdentifier (void);
OrganizationIdentifier (const uint8_t *str, uint32_t length);
OrganizationIdentifier& operator= (const OrganizationIdentifier& oi);
virtual ~OrganizationIdentifier (void);
enum OrganizationIdentifierType
{
OUI24 = 3, // 3 bytes
OUI36 = 5, // 5 bytes
Unknown = 0,
};
/**
* \returns last 4 bits when OrganizationIdentifier is OUI36
*/
uint8_t GetManagementId (void) const;
/**
* \returns whether current OrganizationIdentifier is initial state
*/
bool IsNull (void) const;
void SetType (enum OrganizationIdentifierType type);
enum OrganizationIdentifierType GetType () const;
// below methods will be called by VendorSpecificActionHeader
uint32_t GetSerializedSize (void) const;
void Serialize (Buffer::Iterator start) const;
uint32_t Deserialize (Buffer::Iterator start);
private:
friend bool operator == (const OrganizationIdentifier& a, const OrganizationIdentifier& b);
friend bool operator != (const OrganizationIdentifier& a, const OrganizationIdentifier& b);
friend bool operator < (const OrganizationIdentifier& a, const OrganizationIdentifier& b);
friend std::ostream& operator << (std::ostream& os, const OrganizationIdentifier& oi);
friend std::istream& operator >> (std::istream& is, const OrganizationIdentifier& oi);
enum OrganizationIdentifierType m_type;
uint8_t m_oi[5];
};
ATTRIBUTE_HELPER_HEADER (OrganizationIdentifier);
bool operator == (const OrganizationIdentifier& a, const OrganizationIdentifier& b);
bool operator != (const OrganizationIdentifier& a, const OrganizationIdentifier& b);
bool operator < (const OrganizationIdentifier& a, const OrganizationIdentifier& b);
std::ostream& operator << (std::ostream& os, const OrganizationIdentifier& oi);
std::istream& operator >> (std::istream& is, const OrganizationIdentifier& oi);
/**
* see IEEE 802.11-2007 chapter 7.3.1.11
* Table 7-24—Category values
*/
const static uint8_t CATEGORY_OF_VSA = 127;
/**
* \ingroup wave
* See IEEE 802.11-2007 chapter 7.3.1.11 and 7.4.5
* also IEEE 802.11p-2010 chapter 7.4.5
* Although WifiActionHeader has been defined in wifi mgt-header.h/.cc,
* it is not a good way to inherit from it or add vendor specific action support.
* The reason is Action field. Other Action frames contains Action field, and
* the VSA frame contains OUI or variable OrganizationIdentifier instead of one byte Action field.
* Header format: | Category | Organization IdentifierType | Vendor Specific content |
* Octets: 1 j Variable
*
* In ns-3, VSA frame will be divided into VendorSpecificActionHeader vsaHeader
* and Packet vsc that indicates vendor specific content.
*
* This frame is used by IEEE 1609.4 to send WSA packet of IEEE 1609.3,
* and if users want to send management information without customized management
* frames, he can use VSA frames.
*/
class VendorSpecificActionHeader : public Header
{
public:
VendorSpecificActionHeader (void);
virtual ~VendorSpecificActionHeader (void);
/**
* \param oi the OrganizationIdentifier of current VSA header
*/
void SetOrganizationIdentifier (OrganizationIdentifier oi);
/**
* \returns current OrganizationIdentifier of the VSA header
*/
OrganizationIdentifier GetOrganizationIdentifier (void) const;
/**
* the category field shall be CATEGORY_OF_VSA
*/
uint8_t GetCategory () const;
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);
private:
OrganizationIdentifier m_oi;
uint8_t m_category;
};
/**
* \param mac a pointer to the mac object which is calling this callback
* \param oi the organization identifier of vendor specific action frame
* \param packet the vendor specifc content packet received
* \param sender the address of the sender
* \returns true if the callback could handle the packet successfully;
* false otherwise.
*/
typedef Callback<bool, Ptr<WifiMac>, const OrganizationIdentifier &, Ptr<const Packet>,const Address &> VscCallback;
class VendorSpecificContentManager
{
public:
VendorSpecificContentManager (void);
virtual ~VendorSpecificContentManager (void);
/**
* \param oi the specific OrganizationIdentifier when receive management information
* by VendorSpecificAction management frame.
* \param cb the receive callback when oi related management packets are received
*/
void RegisterVscCallback (OrganizationIdentifier oi, VscCallback cb);
void DeregisterVscCallback (OrganizationIdentifier &oi);
VscCallback FindVscCallback (OrganizationIdentifier &oi);
private:
typedef std::map<OrganizationIdentifier,VscCallback> VscCallbacks;
typedef std::map<OrganizationIdentifier,VscCallback>::iterator VscCallbacksI;
VscCallbacks m_callbacks;
friend class OrganizationIdentifier;
};
static std::vector<OrganizationIdentifier> OrganizationIdentifiers;
}
#endif /* Vendor_Specific_Action_H */

View File

@@ -0,0 +1,86 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Junling Bu <linlinjavaer@gmail.com>
*/
#include "ns3/log.h"
#include "wave-mac-low.h"
#include "higher-tx-tag.h"
NS_LOG_COMPONENT_DEFINE ("WaveMacLow");
namespace ns3 {
NS_OBJECT_ENSURE_REGISTERED (WaveMacLow);
TypeId
WaveMacLow::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::WaveMacLow")
.SetParent<MacLow> ()
.AddConstructor<WaveMacLow> ()
;
return tid;
}
WaveMacLow::WaveMacLow (void)
{
NS_LOG_FUNCTION (this);
}
WaveMacLow::~WaveMacLow (void)
{
NS_LOG_FUNCTION (this);
}
WifiTxVector
WaveMacLow::GetDataTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
{
NS_LOG_FUNCTION (this << packet << *hdr);
HigherDataTxVectorTag datatag;
bool found;
found = ConstCast<Packet> (packet)->PeekPacketTag (datatag);
if (!found)
{
return MacLow::GetDataTxVector (packet, hdr);
}
if (!datatag.IsAdapter ())
{
return datatag.GetDataTxVector ();
}
WifiTxVector txHigher = datatag.GetDataTxVector ();
WifiTxVector txMac = MacLow::GetDataTxVector (packet, hdr);
WifiTxVector txAdapter;
// if adapter is true, DataRate set by higher layer is the minimum data rate
// that sets the lower bound for the actual data rate.
if (txHigher.GetMode ().GetDataRate () > txMac.GetMode ().GetDataRate ())
{
txAdapter.SetMode (txHigher.GetMode ());
}
else
{
txAdapter.SetMode (txMac.GetMode ());
}
// if adapter is true, TxPwr_Level set by higher layer is the maximum
// transmit power that sets the upper bound for the actual transmit power;
txAdapter.SetTxPowerLevel (std::min (txHigher.GetTxPowerLevel (), txMac.GetTxPowerLevel ()));
return txAdapter;
}
} // namespace ns3

View File

@@ -0,0 +1,51 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2008 INRIA
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Junling Bu <linlinjavaer@gmail.com>
*/
#ifndef WAVE_MAC_LOW_H
#define WAVE_MAC_LOW_H
#include "ns3/mac-low.h"
namespace ns3 {
/**
* \ingroup wave
* This class allows higher layer control data rate and tx power level.
* If higher layer do not select, it will select by WifiRemoteStationManager
* of MAC layer;
* If higher layer selects tx arguments without adapter set, the data rate
* and tx power level will be used to send the packet.
* If higher layer selects tx arguments with adapter set, the data rate
* will be lower bound for the actual data rate, and the power level
* will be upper bound for the actual transmit power.
*/
class WaveMacLow : public MacLow
{
public:
static TypeId GetTypeId (void);
WaveMacLow (void);
virtual ~WaveMacLow (void);
private:
virtual WifiTxVector GetDataTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
};
} // namespace ns3
#endif /* WAVE_MAC_LOW_H*/

View File

@@ -0,0 +1,20 @@
#! /usr/bin/env python
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains
#
# (example_name, do_run, do_valgrind_run).
#
# See test.py for more information.
cpp_examples = [
("wave-simple-80211p", "True", "True"),
]
# A list of Python examples to run in order to ensure that they remain
# runnable over time. Each tuple in the list contains
#
# (example_name, do_run).
#
# See test.py for more information.
python_examples = []

View File

@@ -0,0 +1,396 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013 Dalian University of Technology
*
* 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: Junling Bu <linlinjavaer@gmail.com>
*/
#include "ns3/test.h"
#include "ns3/rng-seed-manager.h"
#include "ns3/config.h"
#include "ns3/data-rate.h"
#include "ns3/vector.h"
#include "ns3/string.h"
#include "ns3/ssid.h"
#include "ns3/packet-socket-address.h"
#include "ns3/mobility-model.h"
#include "ns3/on-off-helper.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/position-allocator.h"
#include "ns3/packet-socket-helper.h"
#include "ns3/mobility-helper.h"
#include "ns3/nqos-wifi-mac-helper.h"
#include "ns3/wifi-net-device.h"
#include <iostream>
#include "ns3/ocb-wifi-mac.h"
#include "ns3/wifi-80211p-helper.h"
#include "ns3/wave-mac-helper.h"
using namespace ns3;
// helper function to assign streams to random variables, to control
// randomness in the tests
static void
AssignWifiRandomStreams (Ptr<WifiMac> mac, int64_t stream)
{
int64_t currentStream = stream;
Ptr<RegularWifiMac> rmac = DynamicCast<RegularWifiMac> (mac);
if (rmac)
{
PointerValue ptr;
rmac->GetAttribute ("DcaTxop", ptr);
Ptr<DcaTxop> dcaTxop = ptr.Get<DcaTxop> ();
currentStream += dcaTxop->AssignStreams (currentStream);
rmac->GetAttribute ("VO_EdcaTxopN", ptr);
Ptr<EdcaTxopN> vo_edcaTxopN = ptr.Get<EdcaTxopN> ();
currentStream += vo_edcaTxopN->AssignStreams (currentStream);
rmac->GetAttribute ("VI_EdcaTxopN", ptr);
Ptr<EdcaTxopN> vi_edcaTxopN = ptr.Get<EdcaTxopN> ();
currentStream += vi_edcaTxopN->AssignStreams (currentStream);
rmac->GetAttribute ("BE_EdcaTxopN", ptr);
Ptr<EdcaTxopN> be_edcaTxopN = ptr.Get<EdcaTxopN> ();
currentStream += be_edcaTxopN->AssignStreams (currentStream);
rmac->GetAttribute ("BK_EdcaTxopN", ptr);
Ptr<EdcaTxopN> bk_edcaTxopN = ptr.Get<EdcaTxopN> ();
currentStream += bk_edcaTxopN->AssignStreams (currentStream);
}
}
class OcbWifiMacTestCase : public TestCase
{
public:
OcbWifiMacTestCase (void);
virtual ~OcbWifiMacTestCase (void);
private:
virtual void DoRun (void);
void MacAssoc (std::string context,Mac48Address bssid);
void PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble);
void PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower);
Vector GetCurrentPosition (uint32_t i);
void AdvancePosition (Ptr<Node> node);
void PreRandomConfiguration (void);
void ConfigureApStaMode (Ptr<Node> static_node, Ptr<Node> mobile_node);
void ConfigureAdhocMode (Ptr<Node> static_node, Ptr<Node> mobile_node);
void ConfigureOcbMode (Ptr<Node> static_node, Ptr<Node> mobile_node);
void PostDeviceConfiguration (Ptr<Node> static_node, Ptr<Node> mobile_node);
Time phytx_time;
Vector phytx_pos;
Time macassoc_time;
Vector macassoc_pos;
Time phyrx_time;
Vector phyrx_pos;
// nodes.Get (0) is static node
// nodes.Get (1) is mobile node
NodeContainer nodes;
};
OcbWifiMacTestCase::OcbWifiMacTestCase (void)
: TestCase ("Association time: Ap+Sta mode vs Adhoc mode vs Ocb mode")
{
}
OcbWifiMacTestCase::~OcbWifiMacTestCase (void)
{
}
// mobility is like walk on line with velocity 5 m/s
// We prefer to update 0.5m every 0.1s rather than 5m every 1s
void
OcbWifiMacTestCase::AdvancePosition (Ptr<Node> node)
{
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
Vector pos = mobility->GetPosition ();
pos.x -= 0.5;
if (pos.x < 1.0 )
{
pos.x = 1.0;
return;
}
mobility->SetPosition (pos);
Simulator::Schedule (Seconds (0.1), &OcbWifiMacTestCase::AdvancePosition, this, node);
}
// here are only two nodes, a stationary and a mobile one
// the i value of the first = 0; the i value of second = 1.
Vector
OcbWifiMacTestCase::GetCurrentPosition (uint32_t i)
{
NS_ASSERT (i < 2);
Ptr<Node> node = nodes.Get (i);
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
Vector pos = mobility->GetPosition ();
return pos;
}
void
OcbWifiMacTestCase::MacAssoc (std::string context,Mac48Address bssid)
{
if (macassoc_time == Time (0))
{
macassoc_time = Now ();
macassoc_pos = GetCurrentPosition (1);
std::cout << "MacAssoc time = " << macassoc_time.GetNanoSeconds ()
<< " position = " << macassoc_pos
<< std::endl;
}
}
// We want to get the time that sta receives the first beacon frame from AP
// it means that in this time this sta has ability to receive frame
void
OcbWifiMacTestCase::PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble)
{
if (phyrx_time == Time (0))
{
phyrx_time = Now ();
phyrx_pos = GetCurrentPosition (1);
std::cout << "PhyRxOk time = " << phyrx_time.GetNanoSeconds ()
<< " position = " << phyrx_pos
<< std::endl;
}
}
// We want to get the time that STA sends the first data packet successfully
void
OcbWifiMacTestCase::PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower)
{
WifiMacHeader h;
packet->PeekHeader (h);
if ((phytx_time == Time (0)) && h.IsData ())
{
phytx_time = Now ();
phytx_pos = GetCurrentPosition (1);
std::cout << "PhyTx data time = " << phytx_time.GetNanoSeconds ()
<< " position = " << phytx_pos
<< std::endl;
}
}
void
OcbWifiMacTestCase::ConfigureApStaMode (Ptr<Node> static_node, Ptr<Node> mobile_node)
{
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
Ssid ssid = Ssid ("wifi-default");
NqosWifiMacHelper wifiStaMac = NqosWifiMacHelper::Default ();
wifiStaMac.SetType ("ns3::StaWifiMac", "Ssid", SsidValue (ssid));
NqosWifiMacHelper wifiApMac = NqosWifiMacHelper::Default ();
wifiApMac.SetType ("ns3::ApWifiMac","Ssid", SsidValue (ssid));
WifiHelper wifi = WifiHelper::Default ();
wifi.SetStandard (WIFI_PHY_STANDARD_80211_10MHZ);
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode", StringValue ("OfdmRate6MbpsBW10MHz"),
"ControlMode",StringValue ("OfdmRate6MbpsBW10MHz"));
wifi.Install (wifiPhy, wifiStaMac, mobile_node);
wifi.Install (wifiPhy, wifiApMac, static_node);
}
void
OcbWifiMacTestCase::ConfigureAdhocMode (Ptr<Node> static_node, Ptr<Node> mobile_node)
{
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
wifiMac.SetType ("ns3::AdhocWifiMac");
WifiHelper wifi = WifiHelper::Default ();
wifi.SetStandard (WIFI_PHY_STANDARD_80211_10MHZ);
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode", StringValue ("OfdmRate6MbpsBW10MHz"),
"ControlMode",StringValue ("OfdmRate6MbpsBW10MHz"));
wifi.Install (wifiPhy, wifiMac, mobile_node);
wifi.Install (wifiPhy, wifiMac, static_node);
}
void
OcbWifiMacTestCase::ConfigureOcbMode (Ptr<Node> static_node, Ptr<Node> mobile_node)
{
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
NqosWaveMacHelper wifi80211pMac = NqosWaveMacHelper::Default ();
Wifi80211pHelper wifi80211p = Wifi80211pHelper::Default ();
wifi80211p.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode", StringValue ("OfdmRate6MbpsBW10MHz"),
"ControlMode",StringValue ("OfdmRate6MbpsBW10MHz"));
wifi80211p.Install (wifiPhy, wifi80211pMac, mobile_node);
wifi80211p.Install (wifiPhy, wifi80211pMac, static_node);
}
void
OcbWifiMacTestCase::PostDeviceConfiguration (Ptr<Node> static_node, Ptr<Node> mobile_node)
{
Ptr<WifiNetDevice> static_device = DynamicCast<WifiNetDevice> (static_node->GetDevice (0));
Ptr<WifiNetDevice> mobile_device = DynamicCast<WifiNetDevice> (mobile_node->GetDevice (0));
// Fix the stream assignment to the Dcf Txop objects (backoffs)
// The below stream assignment will result in the DcaTxop object
// using a backoff value of zero for this test when the
// DcaTxop::EndTxNoAck() calls to StartBackoffNow()
AssignWifiRandomStreams (static_device->GetMac (), 21);
AssignWifiRandomStreams (mobile_device->GetMac (), 22);
// setup mobility
// the initial position of static node is at 0,
// and the initial position of mobile node is 350.
MobilityHelper mobility;
mobility.Install (mobile_node);
mobility.Install (static_node);
Ptr<MobilityModel> mm = mobile_node->GetObject<MobilityModel> ();
Vector possta = mm->GetPosition ();
possta.x = 350;
mm->SetPosition (possta);
Simulator::Schedule (Seconds (1.0), &OcbWifiMacTestCase::AdvancePosition, this, mobile_node);
PacketSocketAddress socket;
socket.SetSingleDevice (mobile_device->GetIfIndex ());
socket.SetPhysicalAddress (static_device->GetAddress ());
socket.SetProtocol (1);
// give packet socket powers to nodes.
PacketSocketHelper packetSocket;
packetSocket.Install (static_node);
packetSocket.Install (mobile_node);
OnOffHelper onoff ("ns3::PacketSocketFactory", Address (socket));
onoff.SetConstantRate (DataRate ("500kb/s"));
ApplicationContainer apps = onoff.Install (mobile_node);
apps.Start (Seconds (0.5));
apps.Stop (Seconds (70.0));
phytx_time = macassoc_time = phyrx_time = Time ();
phytx_pos = macassoc_pos = phyrx_pos = Vector ();
Config::Connect ("/NodeList/1/DeviceList/*/Mac/Assoc", MakeCallback (&OcbWifiMacTestCase::MacAssoc, this));
Config::Connect ("/NodeList/1/DeviceList/*/Phy/State/RxOk", MakeCallback (&OcbWifiMacTestCase::PhyRxOkTrace, this));
Config::Connect ("/NodeList/1/DeviceList/*/Phy/State/Tx", MakeCallback (&OcbWifiMacTestCase::PhyTxTrace, this));
}
/**
*
* static-node:0 <---- mobile-node:1
* * ------ 350m ------- *
*
* the node transmit range is less than 150m
*
* Ap+Sta mode vs Adhoc mode vs Ocb mode
* first test the time point when the stationary node is
* an AP and the mobile node is a Sta
* then test when one Ad-hoc node and another Ad-hoc node
* last test when one OCB node and another OCB node
*/
void
OcbWifiMacTestCase::DoRun ()
{
std::cout << "test time point for Ap-Sta mode" << std::endl;
PreRandomConfiguration ();
nodes = NodeContainer ();
nodes.Create (2);
Ptr<Node> static_node = nodes.Get (0);
Ptr<Node> mobile_node = nodes.Get (1);
ConfigureApStaMode (static_node, mobile_node);
PostDeviceConfiguration (static_node, mobile_node);
Simulator::Stop (Seconds (71.0));
Simulator::Run ();
Simulator::Destroy ();
NS_TEST_ASSERT_MSG_LT (phyrx_time, macassoc_time, "In Sta mode with AP, you cannot associate until receive beacon or AssocResponse frame" );
NS_TEST_ASSERT_MSG_LT (macassoc_time, phytx_time, "In Sta mode with AP, you cannot send data packet until associate" );
NS_TEST_ASSERT_MSG_GT ((phyrx_pos.x - macassoc_pos.x), 0.0, "");
//actually macassoc_pos.x - phytx_pos.x is greater than 0
//however associate switch to send is so fast with less than 100ms
//and in our mobility model that every 0.1s update position,
//so turn out to be that macassoc_pos.x - phytx_pos.x is equal to 0
//NS_TEST_ASSERT_MSG_GT ((macassoc_pos.x - phytx_pos.x), 0.0, "");
std::cout << "test time point for Adhoc mode" << std::endl;
PreRandomConfiguration ();
nodes = NodeContainer ();
nodes.Create (2);
static_node = nodes.Get (0);
mobile_node = nodes.Get (1);
ConfigureAdhocMode (static_node, mobile_node);
PostDeviceConfiguration (static_node, mobile_node);
Simulator::Stop (Seconds (71.0));
Simulator::Run ();
Simulator::Destroy ();
// below test assert will fail, because AdhocWifiMac has not implement state machine.
// if someone takes a look at the output in adhoc mode and in Ocb mode
// he will find these two outputs are almost same.
//NS_TEST_ASSERT_MSG_LT (phyrx_time, macassoc_time, "In Adhoc mode, you cannot associate until receive beacon or AssocResponse frame" );
//NS_TEST_ASSERT_MSG_LT (macassoc_time, phytx_time, "In Adhoc mode, you cannot send data packet until associate" );
//NS_TEST_ASSERT_MSG_GT ((phyrx_pos.x - macassoc_pos.x), 0.0, "");
// below test assert result refer to Ap-Sta mode
//NS_TEST_ASSERT_MSG_GT ((macassoc_pos.x - phytx_pos.x), 0.0, "");
std::cout << "test time point for Ocb mode" << std::endl;
PreRandomConfiguration ();
nodes = NodeContainer ();
nodes.Create (2);
static_node = nodes.Get (0);
mobile_node = nodes.Get (1);
ConfigureOcbMode (static_node, mobile_node);
PostDeviceConfiguration (static_node, mobile_node);
Simulator::Stop (Seconds (71.0));
Simulator::Run ();
Simulator::Destroy ();
NS_TEST_ASSERT_MSG_EQ (macassoc_time.GetNanoSeconds (), 0, "In Ocb mode, there is no associate state machine" );
NS_TEST_ASSERT_MSG_LT (phytx_time, phyrx_time, "before mobile node receives frames from far static node, it can send data packet directly" );
NS_TEST_ASSERT_MSG_EQ (macassoc_pos.x, 0.0, "");
NS_TEST_ASSERT_MSG_GT ((phytx_pos.x - phyrx_pos.x), 0.0, "");
}
void
OcbWifiMacTestCase::PreRandomConfiguration ()
{
// Assign a seed and run number, and later fix the assignment of streams to
// WiFi random variables, so that the first backoff used is zero slots
RngSeedManager::SetSeed (1);
RngSeedManager::SetRun (17);
// the WiFi random variables is set in PostDeviceConfiguration method.
}
class OcbTestSuite : public TestSuite
{
public:
OcbTestSuite ();
};
OcbTestSuite::OcbTestSuite ()
: TestSuite ("wifi-80211p-ocb", UNIT)
{
// TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
AddTestCase (new OcbWifiMacTestCase, TestCase::QUICK);
}
// Do not forget to allocate an instance of this TestSuite
static OcbTestSuite ocbTestSuite;

40
src/wave/wscript Normal file
View File

@@ -0,0 +1,40 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# def options(opt):
# pass
# def configure(conf):
# conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H')
def build(bld):
module = bld.create_ns3_module('wave', ['core','wifi', 'propagation'])
module.source = [
'model/wave-mac-low.cc',
'model/ocb-wifi-mac.cc',
'model/vendor-specific-action.cc',
'model/higher-tx-tag.cc',
'helper/wave-mac-helper.cc',
'helper/wifi-80211p-helper.cc',
]
module_test = bld.create_ns3_module_test_library('wave')
module_test.source = [
'test/ocb-test-suite.cc',
]
headers = bld(features='ns3header')
headers.module = 'wave'
headers.source = [
'model/wave-mac-low.h',
'model/ocb-wifi-mac.h',
'model/vendor-specific-action.h',
'model/higher-tx-tag.h',
'helper/wave-mac-helper.h',
'helper/wifi-80211p-helper.h',
]
if bld.env.ENABLE_EXAMPLES:
bld.recurse('examples')
# bld.ns3_python_bindings()

View File

@@ -72,7 +72,7 @@ public:
* All the attributes specified in this method should exist
* in the requested mac.
*/
void SetType (std::string type,
virtual void SetType (std::string type,
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
@@ -81,6 +81,8 @@ public:
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
protected:
ObjectFactory m_mac;
private:
/**
* \internal
@@ -89,8 +91,6 @@ private:
* This method implements the pure virtual method defined in \ref ns3::WifiMacHelper.
*/
virtual Ptr<WifiMac> Create (void) const;
ObjectFactory m_mac;
};
} // namespace ns3

View File

@@ -77,7 +77,7 @@ public:
* All the attributes specified in this method should exist
* in the requested mac.
*/
void SetType (std::string type,
virtual void SetType (std::string type,
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
@@ -131,6 +131,8 @@ public:
* \param timeout number of block of 1024 microseconds.
*/
void SetBlockAckInactivityTimeoutForAc (enum AcIndex ac, uint16_t timeout);
protected:
ObjectFactory m_mac;
private:
/**
* \internal
@@ -141,8 +143,6 @@ private:
virtual Ptr<WifiMac> Create (void) const;
void Setup (Ptr<WifiMac> mac, enum AcIndex ac, std::string dcaAttrName) const;
ObjectFactory m_mac;
std::map<AcIndex, ObjectFactory> m_aggregators;
/*
* Next maps contain, for every access category, the values for

View File

@@ -140,7 +140,7 @@ public:
* \param c the set of nodes on which a wifi device must be created
* \returns a device container which contains all the devices created by this method.
*/
NetDeviceContainer Install (const WifiPhyHelper &phy,
virtual NetDeviceContainer Install (const WifiPhyHelper &phy,
const WifiMacHelper &mac, NodeContainer c) const;
/**
* \param phy the PHY helper to create PHY objects
@@ -148,7 +148,7 @@ public:
* \param node the node on which a wifi device must be created
* \returns a device container which contains all the devices created by this method.
*/
NetDeviceContainer Install (const WifiPhyHelper &phy,
virtual NetDeviceContainer Install (const WifiPhyHelper &phy,
const WifiMacHelper &mac, Ptr<Node> node) const;
/**
* \param phy the PHY helper to create PHY objects
@@ -156,7 +156,7 @@ public:
* \param nodeName the name of node on which a wifi device must be created
* \returns a device container which contains all the devices created by this method.
*/
NetDeviceContainer Install (const WifiPhyHelper &phy,
virtual NetDeviceContainer Install (const WifiPhyHelper &phy,
const WifiMacHelper &mac, std::string nodeName) const;
/**
@@ -164,7 +164,7 @@ public:
*
* By default, all objects are configured for 802.11a
*/
void SetStandard (enum WifiPhyStandard standard);
virtual void SetStandard (enum WifiPhyStandard standard);
/**
* Helper to enable all WifiNetDevice log components with one statement
@@ -187,7 +187,7 @@ public:
*/
int64_t AssignStreams (NetDeviceContainer c, int64_t stream);
private:
protected:
ObjectFactory m_stationManager;
enum WifiPhyStandard m_standard;
};

View File

@@ -61,7 +61,8 @@ enum TypeOfStation
MESH,
HT_STA,
HT_AP,
HT_ADHOC_STA
HT_ADHOC_STA,
OCB
};

View File

@@ -295,7 +295,9 @@ MacLow::MacLow ()
m_waitSifsEvent (),
m_endTxNoAckEvent (),
m_currentPacket (0),
m_listener (0)
m_listener (0),
m_phyMacLowListener (0),
m_ctsToSelfSupported (false)
{
NS_LOG_FUNCTION (this);
m_lastNavDuration = Seconds (0);
@@ -334,8 +336,11 @@ MacLow::DoDispose (void)
m_waitRifsEvent.Cancel();
m_phy = 0;
m_stationManager = 0;
delete m_phyMacLowListener;
m_phyMacLowListener = 0;
if (m_phyMacLowListener != 0)
{
delete m_phyMacLowListener;
m_phyMacLowListener = 0;
}
}
void
@@ -539,6 +544,11 @@ MacLow::GetBssid (void) const
{
return m_bssid;
}
bool
MacLow::IsPromisc (void) const
{
return m_promisc;
}
void
MacLow::SetRxCallback (Callback<void,Ptr<Packet>,const WifiMacHeader *> callback)

View File

@@ -411,6 +411,7 @@ public:
Time GetPifs (void) const;
Time GetRifs (void) const;
Mac48Address GetBssid (void) const;
bool IsPromisc (void) const;
/**
* \param callback the callback which receives every incoming packet.
@@ -512,6 +513,8 @@ public:
* associated to this AC.
*/
void RegisterBlockAckListenerForAc (enum AcIndex ac, MacLowBlockAckEventListener *listener);
protected:
virtual WifiTxVector GetDataTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
private:
void CancelAllEvents (void);
uint32_t GetAckSize (void) const;
@@ -522,7 +525,6 @@ private:
void ForwardDown (Ptr<const Packet> packet, const WifiMacHeader *hdr,
WifiTxVector txVector, WifiPreamble preamble);
WifiTxVector GetRtsTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
WifiTxVector GetDataTxVector (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
WifiTxVector GetCtsTxVector (Mac48Address to, WifiMode rtsTxMode) const;
WifiTxVector GetAckTxVector (Mac48Address to, WifiMode dataTxMode) const;
WifiTxVector GetBlockAckTxVector (Mac48Address to, WifiMode dataTxMode) const;

View File

@@ -505,6 +505,7 @@ WifiActionHeader::SetAction (WifiActionHeader::CategoryValue type,
case MESH_INTERWORKING:
case MESH_RESOURCE_COORDINATION:
case MESH_PROXY_FORWARDING:
case VENDOR_SPECIFIC_ACTION:
break;
}
}
@@ -527,6 +528,8 @@ WifiActionHeader::GetCategory ()
return MESH_RESOURCE_COORDINATION;
case MESH_PROXY_FORWARDING:
return MESH_PROXY_FORWARDING;
case VENDOR_SPECIFIC_ACTION:
return VENDOR_SPECIFIC_ACTION;
default:
NS_FATAL_ERROR ("Unknown action value");
return MESH_PEERING_MGT;
@@ -583,7 +586,8 @@ WifiActionHeader::GetAction ()
retval.peerLink = PEER_LINK_OPEN; /* quiet compiler */
}
break ;
case VENDOR_SPECIFIC_ACTION:
break ;
case MESH_LINK_METRIC:
// not yet supported
case MESH_INTERWORKING:

View File

@@ -204,6 +204,9 @@ public:
MESH_INTERWORKING = 33,
MESH_RESOURCE_COORDINATION = 34,
MESH_PROXY_FORWARDING = 35,
// since vendor specific action has no stationary Action value,the parse process is not here.
// refer to vendor-specific-action in wave module.
VENDOR_SPECIFIC_ACTION = 127,
};
/* Compatible with open80211s implementation */
enum PeerLinkMgtActionValue

View File

@@ -259,6 +259,18 @@ protected:
channel access function */
EdcaQueues m_edca;
/** Accessor for the DCF object */
Ptr<DcaTxop> GetDcaTxop (void) const;
/** Accessor for the AC_VO channel access function */
Ptr<EdcaTxopN> GetVOQueue (void) const;
/** Accessor for the AC_VI channel access function */
Ptr<EdcaTxopN> GetVIQueue (void) const;
/** Accessor for the AC_BE channel access function */
Ptr<EdcaTxopN> GetBEQueue (void) const;
/** Accessor for the AC_BK channel access function */
Ptr<EdcaTxopN> GetBKQueue (void) const;
/**
* \param standard the phy standard to be used
*
@@ -408,38 +420,6 @@ private:
*/
void SetupEdcaQueue (enum AcIndex ac);
/**
* Return the DCF.
*
* \return a DCF instance
*/
Ptr<DcaTxop> GetDcaTxop (void) const;
/**
* Return the EDCAF instance for the voice access class.
*
* \return a AC_VO EDCAF instance
*/
Ptr<EdcaTxopN> GetVOQueue (void) const;
/**
* Return the EDCAF instance for the video access class.
*
* \return a AC_VI EDCAF instance
*/
Ptr<EdcaTxopN> GetVIQueue (void) const;
/**
* Return the EDCAF instance for the best effort access class.
*
* \return a AC_BE EDCAF instance
*/
Ptr<EdcaTxopN> GetBEQueue (void) const;
/**
* Return the EDCAF instance for the background access class.
*
* \return a AC_BK EDCAF instance
*/
Ptr<EdcaTxopN> GetBKQueue (void) const;
TracedCallback<const WifiMacHeader &> m_txOkCallback;
TracedCallback<const WifiMacHeader &> m_txErrCallback;
};

View File

@@ -30,8 +30,6 @@
#include "wifi-mac-header.h"
namespace ns3 {
class WifiMacParameters;
class QosBlockedDestinations;
/**
@@ -120,14 +118,15 @@ public:
bool IsEmpty (void);
uint32_t GetSize (void);
private:
protected:
virtual void Cleanup (void);
struct Item;
typedef std::list<struct Item> PacketQueue;
typedef std::list<struct Item>::reverse_iterator PacketQueueRI;
typedef std::list<struct Item>::iterator PacketQueueI;
void Cleanup (void);
Mac48Address GetAddressForPacket (enum WifiMacHeader::AddressType type, PacketQueueI);
struct Item

View File

@@ -109,14 +109,14 @@ public:
virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
virtual bool SupportsSendFrom (void) const;
protected:
virtual void DoDispose (void);
virtual void DoInitialize (void);
void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
private:
// This value conforms to the 802.11 specification
static const uint16_t MAX_MSDU_SIZE = 2304;
virtual void DoDispose (void);
virtual void DoInitialize (void);
void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
void LinkUp (void);
void LinkDown (void);
Ptr<WifiChannel> DoGetChannel (void) const;