The Code-Bin
Links
Home
Add your code!
All Listings
About
Latest Entry
Featured Scripts
Author's Website
Latest Entries
FFMPEG Thumbnail Scr...
PHP, 0.8KB
Jul. 29, 10:24pm
John
Z80 Assembler, 190 bytes
Feb. 17, 3:36am
John
Z80 Assembler, 176 bytes
Sep. 13, 2:19am
John
Z80 Assembler, 77 bytes
Sep. 13, 2:18am
John
Z80 Assembler, 209 bytes
Sep. 13, 2:17am
ns-3 simulation
Posted by: Johan Gall | December 20, 2010 @ 1:34am
C++ Code
[
Download
]
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2006, 2009 INRIA * Copyright (c) 2009 MIRKO BANCHI * * 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> */ #include "ap-wifi-mac.h" #include "ns3/assert.h" #include "ns3/log.h" #include "ns3/simulator.h" #include "ns3/string.h" #include "ns3/pointer.h" #include "ns3/boolean.h" #include "qos-tag.h" #include "wifi-phy.h" #include "dcf-manager.h" #include "mac-rx-middle.h" #include "mac-tx-middle.h" #include "mgt-headers.h" #include "mac-low.h" #include "amsdu-subframe-header.h" #include "msdu-aggregator.h" NS_LOG_COMPONENT_DEFINE ("ApWifiMac"); namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (ApWifiMac); TypeId ApWifiMac::GetTypeId (void) { static TypeId tid = TypeId ("ns3::ApWifiMac") .SetParent<RegularWifiMac> () .AddConstructor<ApWifiMac> () .AddAttribute ("BeaconInterval", "Delay between two beacons", TimeValue (MicroSeconds (102400)), MakeTimeAccessor (&ApWifiMac::GetBeaconInterval, &ApWifiMac::SetBeaconInterval), MakeTimeChecker ()) .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.", BooleanValue (true), MakeBooleanAccessor (&ApWifiMac::SetBeaconGeneration, &ApWifiMac::GetBeaconGeneration), MakeBooleanChecker ()) ; return tid; } ApWifiMac::ApWifiMac () { NS_LOG_FUNCTION (this); m_beaconDca = CreateObject<DcaTxop> (); m_beaconDca->SetAifsn(1); m_beaconDca->SetMinCw(0); m_beaconDca->SetMaxCw(0); m_beaconDca->SetLow (m_low); m_beaconDca->SetManager (m_dcfManager); // Let the lower layers know that we are acting as an AP. SetTypeOfStation (AP); m_enableBeaconGeneration = false; } ApWifiMac::~ApWifiMac () { NS_LOG_FUNCTION (this); } void ApWifiMac::DoDispose () { NS_LOG_FUNCTION (this); m_beaconDca = 0; m_enableBeaconGeneration = false; m_beaconEvent.Cancel (); RegularWifiMac::DoDispose (); } void ApWifiMac::SetAddress (Mac48Address address) { // As an AP, our MAC address is also the BSSID. Hence we are // overriding this function and setting both in our parent class. RegularWifiMac::SetAddress (address); RegularWifiMac::SetBssid (address); } void ApWifiMac::SetBeaconGeneration (bool enable) { NS_LOG_FUNCTION (this << enable); if (!enable) { m_beaconEvent.Cancel (); } else if (enable && !m_enableBeaconGeneration) { m_beaconEvent = Simulator::ScheduleNow (&ApWifiMac::SendOneBeacon, this); } m_enableBeaconGeneration = enable; } bool ApWifiMac::GetBeaconGeneration (void) const { return m_enableBeaconGeneration; } Time ApWifiMac::GetBeaconInterval (void) const { return m_beaconInterval; } void ApWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager) { NS_LOG_FUNCTION (this << stationManager); m_beaconDca->SetWifiRemoteStationManager (stationManager); RegularWifiMac::SetWifiRemoteStationManager (stationManager); } void ApWifiMac::SetLinkUpCallback (Callback<void> linkUp) { NS_LOG_FUNCTION (this); RegularWifiMac::SetLinkUpCallback (linkUp); // The approach taken here is that, from the point of view of an AP, // the link is always up, so we immediately invoke the callback if // one is set linkUp (); } void ApWifiMac::SetBeaconInterval (Time interval) { NS_LOG_FUNCTION (this << interval); if ((interval.GetMicroSeconds () % 1024) != 0) { NS_LOG_WARN ("beacon interval should be multiple of 1024us, see IEEE Std. 802.11-2007, section 11.1.1.1"); } m_beaconInterval = interval; } void ApWifiMac::StartBeaconing (void) { NS_LOG_FUNCTION (this); SendOneBeacon (); } void ApWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to) { // If we are not a QoS AP 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 we are a QoS AP then we attempt to get a TID for this packet if (m_qosSupported) { 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; } } ForwardDown (packet, from, to, tid); } void ApWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to, uint8_t tid) { NS_LOG_FUNCTION (this << packet << from << to); WifiMacHeader hdr; // For now, an AP that supports QoS does not support non-QoS // associations, and vice versa. In future the AP model should // support simultaneously associated QoS and non-QoS STAs, at which // point there will need to be per-association QoS state maintained // by the association state machine, and consulted here. if (m_qosSupported) { hdr.SetType (WIFI_MAC_QOSDATA); hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); hdr.SetQosNoEosp (); hdr.SetQosNoAmsdu (); // Transmission of multiple frames in the same TXOP is not // supported for now hdr.SetQosTxopLimit (0); // Fill in the QoS control field in the MAC header hdr.SetQosTid (tid); } else { hdr.SetTypeData (); } hdr.SetAddr1 (to); hdr.SetAddr2 (GetAddress ()); hdr.SetAddr3 (from); hdr.SetDsFrom (); 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); } } void ApWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from) { NS_LOG_FUNCTION (this << packet << to << from); if (to.IsBroadcast () || m_stationManager->IsAssociated (to)) { ForwardDown (packet, from, to); } } void ApWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to) { // We're sending this packet with a from address that is our own. We // get that address from the lower MAC and make use of the // from-spoofing Enqueue() method to avoid duplicated code. Enqueue (packet, to, m_low->GetAddress ()); } bool ApWifiMac::SupportsSendFrom (void) const { return true; } SupportedRates ApWifiMac::GetSupportedRates (void) const { // send the set of supported rates and make sure that we indicate // the Basic Rate set in this set of supported rates. SupportedRates rates; for (uint32_t i = 0; i < m_phy->GetNModes (); i++) { WifiMode mode = m_phy->GetMode (i); rates.AddSupportedRate (mode.GetDataRate ()); } // set the basic rates for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++) { WifiMode mode = m_stationManager->GetBasicMode (j); rates.SetBasicRate (mode.GetDataRate ()); } return rates; } void ApWifiMac::SendProbeResp (Mac48Address to) { NS_LOG_FUNCTION (this << to); WifiMacHeader hdr; hdr.SetProbeResp (); hdr.SetAddr1 (to); hdr.SetAddr2 (GetAddress ()); hdr.SetAddr3 (GetAddress ()); hdr.SetDsNotFrom (); hdr.SetDsNotTo (); Ptr<Packet> packet = Create<Packet> (); MgtProbeResponseHeader probe; probe.SetSsid (GetSsid ()); probe.SetSupportedRates (GetSupportedRates ()); probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ()); packet->AddHeader (probe); // The standard is not clear on the correct queue for management // frames if we are a QoS AP. The approach taken here is to always // use the DCF for these regardless of whether we have a QoS // association or not. m_dca->Queue (packet, hdr); } void ApWifiMac::SendAssocResp (Mac48Address to, bool success) { NS_LOG_FUNCTION (this << to << success); WifiMacHeader hdr; hdr.SetAssocResp (); hdr.SetAddr1 (to); hdr.SetAddr2 (GetAddress ()); hdr.SetAddr3 (GetAddress ()); hdr.SetDsNotFrom (); hdr.SetDsNotTo (); Ptr<Packet> packet = Create<Packet> (); MgtAssocResponseHeader assoc; StatusCode code; if (success) { code.SetSuccess (); } else { code.SetFailure (); } assoc.SetSupportedRates (GetSupportedRates ()); assoc.SetStatusCode (code); packet->AddHeader (assoc); // The standard is not clear on the correct queue for management // frames if we are a QoS AP. The approach taken here is to always // use the DCF for these regardless of whether we have a QoS // association or not. m_dca->Queue (packet, hdr); } void ApWifiMac::SendOneBeacon (void) { NS_LOG_FUNCTION (this); WifiMacHeader hdr; hdr.SetBeacon (); hdr.SetAddr1 (Mac48Address::GetBroadcast ()); hdr.SetAddr2 (GetAddress ()); hdr.SetAddr3 (GetAddress ()); hdr.SetDsNotFrom (); hdr.SetDsNotTo (); Ptr<Packet> packet = Create<Packet> (); MgtBeaconHeader beacon; beacon.SetSsid (GetSsid ()); beacon.SetSupportedRates (GetSupportedRates ()); beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ()); packet->AddHeader (beacon); // The beacon has it's own special queue, so we load it in there m_beaconDca->Queue (packet, hdr); m_beaconEvent = Simulator::Schedule (m_beaconInterval, &ApWifiMac::SendOneBeacon, this); } void ApWifiMac::TxOk (const WifiMacHeader &hdr) { NS_LOG_FUNCTION (this); RegularWifiMac::TxOk (hdr); if (hdr.IsAssocResp () && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) { NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ()); m_stationManager->RecordGotAssocTxOk (hdr.GetAddr1 ()); } } void ApWifiMac::TxFailed (const WifiMacHeader &hdr) { NS_LOG_FUNCTION (this); RegularWifiMac::TxFailed (hdr); if (hdr.IsAssocResp () && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) { NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ()); m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ()); } } void ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr) { NS_LOG_FUNCTION (this << packet << hdr); Mac48Address from = hdr->GetAddr2 (); if (hdr->IsData ()) { Mac48Address bssid = hdr->GetAddr1 (); if (!hdr->IsFromDs () && hdr->IsToDs () && bssid == GetAddress () && m_stationManager->IsAssociated (from)) { Mac48Address to = hdr->GetAddr3 (); if (to == GetAddress ()) { NS_LOG_DEBUG ("frame for me from="<<from); if (hdr->IsQosData ()) { if (hdr->IsQosAmsdu ()) { NS_LOG_DEBUG ("Received A-MSDU from="<<from<<", size="<<packet->GetSize ()); DeaggregateAmsduAndForward (packet, hdr); packet = 0; } else { ForwardUp (packet, from, bssid); } } else { ForwardUp (packet, from, bssid); } } else if (to.IsGroup () || m_stationManager->IsAssociated (to)) { NS_LOG_DEBUG ("forwarding frame from="<<from<<", to="<<to); Ptr<Packet> copy = packet->Copy (); // If the frame we are forwarding is of type QoS Data, // then we need to preserve the UP in the QoS control // header... if (hdr->IsQosData ()) { ForwardDown (packet, from, to, hdr->GetQosTid ()); } else { ForwardDown (packet, from, to); } ForwardUp (copy, from, to); } else { ForwardUp (packet, from, to); } } else if (hdr->IsFromDs () && hdr->IsToDs ()) { // this is an AP-to-AP frame // we ignore for now. NotifyRxDrop (packet); } else { // we can ignore these frames since // they are not targeted at the AP NotifyRxDrop (packet); } return; } else if (hdr->IsMgt ()) { if (hdr->IsProbeReq ()) { NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ()); SendProbeResp (from); return; } else if (hdr->GetAddr1 () == GetAddress ()) { if (hdr->IsAssocReq ()) { // first, verify that the the station's supported // rate set is compatible with our Basic Rate set MgtAssocRequestHeader assocReq; packet->RemoveHeader (assocReq); SupportedRates rates = assocReq.GetSupportedRates (); bool problem = false; for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++) { WifiMode mode = m_stationManager->GetBasicMode (i); if (!rates.IsSupportedRate (mode.GetDataRate ())) { problem = true; break; } } if (problem) { // one of the Basic Rate set mode is not // supported by the station. So, we return an assoc // response with an error status. SendAssocResp (hdr->GetAddr2 (), false); } else { // station supports all rates in Basic Rate Set. // record all its supported modes in its associated WifiRemoteStation for (uint32_t j = 0; j < m_phy->GetNModes (); j++) { WifiMode mode = m_phy->GetMode (j); if (rates.IsSupportedRate (mode.GetDataRate ())) { m_stationManager->AddSupportedMode (from, mode); } } m_stationManager->RecordWaitAssocTxOk (from); // send assoc response with success status. SendAssocResp (hdr->GetAddr2 (), true); } return; } else if (hdr->IsDisassociation ()) { m_stationManager->RecordDisassociated (from); return; } } else if(hdr->IsBeacon()) // WITHOUT MY PATCH BEACON WILL GO UP TO REGULAR_WIFI_MAC AND CRASSSH { NotifyRxDrop(packet); 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 ApWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiMacHeader *hdr) { MsduAggregator::DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket); for (MsduAggregator::DeaggregatedMsdusCI i = packets.begin (); i != packets.end (); ++i) { if ((*i).second.GetDestinationAddr () == GetAddress ()) { ForwardUp ((*i).first, (*i).second.GetSourceAddr (), (*i).second.GetDestinationAddr ()); } else { Mac48Address from = (*i).second.GetSourceAddr (); Mac48Address to = (*i).second.GetDestinationAddr (); NS_LOG_DEBUG ("forwarding QoS frame from="<<from<<", to="<<to); ForwardDown ((*i).first, from, to, hdr->GetQosTid ()); } } } void ApWifiMac::DoStart (void) { m_beaconDca->Start (); m_beaconEvent.Cancel (); if (m_enableBeaconGeneration) { m_beaconEvent = Simulator::ScheduleNow (&ApWifiMac::SendOneBeacon, this); } RegularWifiMac::DoStart (); } } // namespace ns3
Syntax Highlighting
[
Open in new window
]
Author Comments
none
Rating
4.50 / 8
78 Votes
http://codebin.yi.org/1021
page generated in 0.01 seconds