base implementation of the IEEE 802.11p standard
authorJunling Bu <linlinjavaer@gmail.com>
Tue, 03 Dec 2013 11:25:59 -0800
changeset 10459 f2e90c12a44f
parent 10458 20987b07dbd4
child 10460 210b3cf4ea00
base implementation of the IEEE 802.11p standard
CHANGES.html
RELEASE_NOTES
doc/models/Makefile
doc/models/source/index.rst
src/wave/doc/wave.rst
src/wave/examples/wave-simple-80211p.cc
src/wave/examples/wscript
src/wave/helper/wave-mac-helper.cc
src/wave/helper/wave-mac-helper.h
src/wave/helper/wifi-80211p-helper.cc
src/wave/helper/wifi-80211p-helper.h
src/wave/model/higher-tx-tag.cc
src/wave/model/higher-tx-tag.h
src/wave/model/ocb-wifi-mac.cc
src/wave/model/ocb-wifi-mac.h
src/wave/model/vendor-specific-action.cc
src/wave/model/vendor-specific-action.h
src/wave/model/wave-mac-low.cc
src/wave/model/wave-mac-low.h
src/wave/test/examples-to-run.py
src/wave/test/ocb-test-suite.cc
src/wave/wscript
src/wifi/helper/nqos-wifi-mac-helper.h
src/wifi/helper/qos-wifi-mac-helper.h
src/wifi/helper/wifi-helper.h
src/wifi/model/edca-txop-n.h
src/wifi/model/mac-low.cc
src/wifi/model/mac-low.h
src/wifi/model/mgt-headers.cc
src/wifi/model/mgt-headers.h
src/wifi/model/regular-wifi-mac.h
src/wifi/model/wifi-mac-queue.h
src/wifi/model/wifi-net-device.h
--- a/CHANGES.html	Mon Dec 02 23:02:39 2013 +0100
+++ b/CHANGES.html	Tue Dec 03 11:25:59 2013 -0800
@@ -54,6 +54,18 @@
 <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>
--- a/RELEASE_NOTES	Mon Dec 02 23:02:39 2013 +0100
+++ b/RELEASE_NOTES	Tue Dec 03 11:25:59 2013 -0800
@@ -22,6 +22,16 @@
 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
--- a/doc/models/Makefile	Mon Dec 02 23:02:39 2013 +0100
+++ b/doc/models/Makefile	Tue Dec 03 11:25:59 2013 -0800
@@ -78,6 +78,7 @@
 	$(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
--- a/doc/models/source/index.rst	Mon Dec 02 23:02:39 2013 +0100
+++ b/doc/models/source/index.rst	Tue Dec 03 11:25:59 2013 -0800
@@ -45,5 +45,6 @@
    spectrum
    topology
    uan
+   wave
    wifi
    wimax
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/doc/wave.rst	Tue Dec 03 11:25:59 2013 -0800
@@ -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.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/examples/wave-simple-80211p.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/examples/wscript	Tue Dec 03 11:25:59 2013 -0800
@@ -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'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/helper/wave-mac-helper.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/helper/wave-mac-helper.h	Tue Dec 03 11:25:59 2013 -0800
@@ -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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/helper/wifi-80211p-helper.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/helper/wifi-80211p-helper.h	Tue Dec 03 11:25:59 2013 -0800
@@ -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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/model/higher-tx-tag.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/model/higher-tx-tag.h	Tue Dec 03 11:25:59 2013 -0800
@@ -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*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/model/ocb-wifi-mac.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/model/ocb-wifi-mac.h	Tue Dec 03 11:25:59 2013 -0800
@@ -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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/model/vendor-specific-action.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/model/vendor-specific-action.h	Tue Dec 03 11:25:59 2013 -0800
@@ -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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/model/wave-mac-low.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/model/wave-mac-low.h	Tue Dec 03 11:25:59 2013 -0800
@@ -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*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/test/examples-to-run.py	Tue Dec 03 11:25:59 2013 -0800
@@ -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 = []
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/test/ocb-test-suite.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -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;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wave/wscript	Tue Dec 03 11:25:59 2013 -0800
@@ -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()
+
--- a/src/wifi/helper/nqos-wifi-mac-helper.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/helper/nqos-wifi-mac-helper.h	Tue Dec 03 11:25:59 2013 -0800
@@ -72,7 +72,7 @@
    * 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 @@
                 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 @@
    * This method implements the pure virtual method defined in \ref ns3::WifiMacHelper.
    */
   virtual Ptr<WifiMac> Create (void) const;
-
-  ObjectFactory m_mac;
 };
 
 } // namespace ns3
--- a/src/wifi/helper/qos-wifi-mac-helper.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/helper/qos-wifi-mac-helper.h	Tue Dec 03 11:25:59 2013 -0800
@@ -77,7 +77,7 @@
    * 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 @@
    * \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 @@
   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
--- a/src/wifi/helper/wifi-helper.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/helper/wifi-helper.h	Tue Dec 03 11:25:59 2013 -0800
@@ -140,7 +140,7 @@
    * \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 @@
    * \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 @@
    * \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 @@
    *
    * 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 @@
   */
   int64_t AssignStreams (NetDeviceContainer c, int64_t stream);
 
-private:
+protected:
   ObjectFactory m_stationManager;
   enum WifiPhyStandard m_standard;
 };
--- a/src/wifi/model/edca-txop-n.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/model/edca-txop-n.h	Tue Dec 03 11:25:59 2013 -0800
@@ -61,7 +61,8 @@
   MESH,
   HT_STA,
   HT_AP,
-  HT_ADHOC_STA
+  HT_ADHOC_STA,
+  OCB
 };
 
 
--- a/src/wifi/model/mac-low.cc	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/model/mac-low.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -295,7 +295,9 @@
     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 @@
    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 @@
 {
   return m_bssid;
 }
+bool
+MacLow::IsPromisc (void) const
+{
+  return m_promisc;
+}
 
 void
 MacLow::SetRxCallback (Callback<void,Ptr<Packet>,const WifiMacHeader *> callback)
--- a/src/wifi/model/mac-low.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/model/mac-low.h	Tue Dec 03 11:25:59 2013 -0800
@@ -411,6 +411,7 @@
   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 @@
    * 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 @@
   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;
--- a/src/wifi/model/mgt-headers.cc	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/model/mgt-headers.cc	Tue Dec 03 11:25:59 2013 -0800
@@ -505,6 +505,7 @@
     case MESH_INTERWORKING:
     case MESH_RESOURCE_COORDINATION:
     case MESH_PROXY_FORWARDING:
+    case VENDOR_SPECIFIC_ACTION:
       break;
     }
 }
@@ -527,6 +528,8 @@
       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 @@
           retval.peerLink = PEER_LINK_OPEN; /* quiet compiler */
         }
       break ;
-      
+    case VENDOR_SPECIFIC_ACTION:
+      break ;
     case MESH_LINK_METRIC:
     // not yet supported
     case MESH_INTERWORKING:
--- a/src/wifi/model/mgt-headers.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/model/mgt-headers.h	Tue Dec 03 11:25:59 2013 -0800
@@ -204,6 +204,9 @@
     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
--- a/src/wifi/model/regular-wifi-mac.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/model/regular-wifi-mac.h	Tue Dec 03 11:25:59 2013 -0800
@@ -259,6 +259,18 @@
   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 @@
    */
   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;
 };
--- a/src/wifi/model/wifi-mac-queue.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/model/wifi-mac-queue.h	Tue Dec 03 11:25:59 2013 -0800
@@ -30,8 +30,6 @@
 #include "wifi-mac-header.h"
 
 namespace ns3 {
-
-class WifiMacParameters;
 class QosBlockedDestinations;
 
 /**
@@ -120,14 +118,15 @@
 
   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
--- a/src/wifi/model/wifi-net-device.h	Mon Dec 02 23:02:39 2013 +0100
+++ b/src/wifi/model/wifi-net-device.h	Tue Dec 03 11:25:59 2013 -0800
@@ -109,14 +109,14 @@
   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;