--- a/src/wifi/model/interference-helper.cc Sat May 02 22:21:58 2015 +0200
+++ b/src/wifi/model/interference-helper.cc Sun May 03 16:06:01 2015 +0200
@@ -267,20 +267,13 @@
}
double
-InterferenceHelper::CalculatePer (Ptr<const InterferenceHelper::Event> event, NiChanges *ni) const
+InterferenceHelper::CalculatePlcpPayloadPer (Ptr<const InterferenceHelper::Event> event, NiChanges *ni) const
{
double psr = 1.0; /* Packet Success Rate */
NiChanges::iterator j = ni->begin ();
Time previous = (*j).GetTime ();
WifiMode payloadMode = event->GetPayloadMode ();
WifiPreamble preamble = event->GetPreambleType ();
- WifiMode MfHeaderMode ;
- if (preamble==WIFI_PREAMBLE_HT_MF)
- {
- MfHeaderMode = WifiPhy::GetMFPlcpHeaderMode (payloadMode, preamble); //return L-SIG mode
-
- }
- WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (payloadMode, preamble);
Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (payloadMode, preamble); //packet start time+ preamble
Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (payloadMode, preamble);//packet start time+ preamble+L SIG
Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble);//packet start time+ preamble+L SIG+HT SIG
@@ -309,74 +302,143 @@
{
//Case 2ai and 2aii: All formats
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ payloadMode),
+ current - plcpPayloadStart,
+ payloadMode);
+
+ }
+ }
+ //Case 3: previous is in HT-SIG: Non HT will not enter here since it didn't enter in the last two and they are all the same for non HT
+ else if (previous >= plcpHsigHeaderStart)
+ {
+ //Case 3a: cuurent after payload start
+ if (current >= plcpPayloadStart)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ payloadMode),
+ current - plcpPayloadStart,
+ payloadMode);
+
+ }
+
+ }
+ //Case 4: previous in L-SIG: GF will not reach here because it will execute the previous if and exit
+ else if (previous >= plcpHeaderStart)
+ {
+ //Case 4a: current after payload start
+ if (current >= plcpPayloadStart)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ payloadMode),
+ current - plcpPayloadStart,
+ payloadMode);
+
+ }
+ }
+ //Case 5: previous is in the preamble works for all cases
+ else
+ {
+ if (current >= plcpPayloadStart)
+ {
+ //for all
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
payloadMode),
current - plcpPayloadStart,
- payloadMode);
-
- }
+ payloadMode);
+
+ }
}
- //Case 3: previous is in HT-SIG: Non HT will not enter here since it didn't enter in the last two and they are all the same for non HT
- else if (previous >=plcpHsigHeaderStart)
+
+ noiseInterferenceW += (*j).GetDelta ();
+ previous = (*j).GetTime ();
+ j++;
+ }
+
+ double per = 1 - psr;
+ return per;
+}
+
+double
+InterferenceHelper::CalculatePlcpHeaderPer (Ptr<const InterferenceHelper::Event> event, NiChanges *ni) const
+{
+ double psr = 1.0; /* Packet Success Rate */
+ NiChanges::iterator j = ni->begin ();
+ Time previous = (*j).GetTime ();
+ WifiMode payloadMode = event->GetPayloadMode ();
+ WifiPreamble preamble = event->GetPreambleType ();
+ WifiMode MfHeaderMode ;
+ if (preamble == WIFI_PREAMBLE_HT_MF)
+ {
+ MfHeaderMode = WifiPhy::GetMFPlcpHeaderMode (payloadMode, preamble); //return L-SIG mode
+ }
+ WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (payloadMode, preamble);
+ Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (payloadMode, preamble); // packet start time + preamble
+ Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (payloadMode, preamble); // packet start time + preamble+L SIG
+ Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble); // packet start time + preamble + L SIG + HT SIG
+ Time plcpPayloadStart = plcpHtTrainingSymbolsStart + WifiPhy::GetPlcpHtTrainingSymbolDuration (preamble, event->GetTxVector()); // packet start time + preamble + L SIG + HT SIG + Training
+ double noiseInterferenceW = (*j).GetDelta ();
+ double powerW = event->GetRxPowerW ();
+ j++;
+ while (ni->end () != j)
+ {
+ Time current = (*j).GetTime ();
+ NS_ASSERT (current >= previous);
+ //Case 1: previous is in HT-SIG: Non HT will not enter here since it didn't enter in the last two and they are all the same for non HT
+ if (previous >= plcpHsigHeaderStart)
{
- //Case 3a: cuurent after payload start
- if (current >=plcpPayloadStart)
+ //Case 1a: cuurent after payload start
+ if (current >= plcpPayloadStart)
{
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- payloadMode),
- current - plcpPayloadStart,
- payloadMode);
+
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- headerMode),
- plcpHtTrainingSymbolsStart - previous,
- headerMode);
+ noiseInterferenceW,
+ headerMode),
+ plcpHtTrainingSymbolsStart - previous,
+ headerMode);
}
- //case 3b: current after HT training symbols start
+ //case 1b: current after HT training symbols start
else if (current >=plcpHtTrainingSymbolsStart)
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
headerMode),
- plcpHtTrainingSymbolsStart - previous,
- headerMode);
+ plcpHtTrainingSymbolsStart - previous,
+ headerMode);
}
- //Case 3c: current is with previous in HT sig
+ //Case 1c: current is with previous in HT sig
else
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
headerMode),
- current- previous,
- headerMode);
+ current - previous,
+ headerMode);
}
}
- //Case 4: previous in L-SIG: GF will not reach here because it will execute the previous if and exit
+ // Case 2: previous in L-SIG: GF will not reach here because it will execute the previous if and exit
else if (previous >= plcpHeaderStart)
{
- //Case 4a: current after payload start
- if (current >=plcpPayloadStart)
+ // Case 2a: current after payload start
+ if (current >= plcpPayloadStart)
{
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- payloadMode),
- current - plcpPayloadStart,
- payloadMode);
- //Case 4ai: Non HT format (No HT-SIG or Training Symbols)
+ // Case 2ai: Non HT format (No HT-SIG or Training Symbols)
if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT) //plcpHtTrainingSymbolsStart==plcpHeaderStart)
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- headerMode),
- plcpPayloadStart - previous,
- headerMode);
+ noiseInterferenceW,
+ headerMode),
+ plcpPayloadStart - previous,
+ headerMode);
}
-
- else{
+ else
+ {
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
headerMode),
@@ -389,8 +451,8 @@
MfHeaderMode);
}
}
- //Case 4b: current in HT training symbol. non HT will not come here since it went in previous if or if the previous ifis not true this will be not true
- else if (current >=plcpHtTrainingSymbolsStart)
+ // Case 2b: current in HT training symbol. non HT will not come here since it went in previous if or if the previous ifis not true this will be not true
+ else if (current >= plcpHtTrainingSymbolsStart)
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
@@ -403,8 +465,8 @@
plcpHsigHeaderStart - previous,
MfHeaderMode);
}
- //Case 4c: current in H sig.non HT will not come here since it went in previous if or if the previous ifis not true this will be not true
- else if (current >=plcpHsigHeaderStart)
+ // Case 2c: current in H sig. non HT will not come here since it went in previous if or if the previous ifis not true this will be not true
+ else if (current >= plcpHsigHeaderStart)
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
@@ -418,47 +480,40 @@
MfHeaderMode);
}
- //Case 4d: Current with prev in L SIG
+ // Case 2d: Current with prev in L SIG
else
{
- //Case 4di: Non HT format (No HT-SIG or Training Symbols)
+ // Case 4di: Non HT format (No HT-SIG or Training Symbols)
if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT) //plcpHtTrainingSymbolsStart==plcpHeaderStart)
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- headerMode),
- current - previous,
- headerMode);
+ noiseInterferenceW,
+ headerMode),
+ current - previous,
+ headerMode);
}
- else
+ else
{
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
MfHeaderMode),
- current - previous,
- MfHeaderMode);
+ current - previous,
+ MfHeaderMode);
}
}
}
- //Case 5: previous is in the preamble works for all cases
+ // Case 3: previous is in the preamble works for all cases
else
{
if (current >= plcpPayloadStart)
{
- //for all
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- payloadMode),
- current - plcpPayloadStart,
- payloadMode);
-
- // Non HT format (No HT-SIG or Training Symbols)
+ // Non HT format (No HT-SIG or Training Symbols)
if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- headerMode),
- plcpPayloadStart - plcpHeaderStart,
- headerMode);
+ headerMode),
+ plcpPayloadStart - plcpHeaderStart,
+ headerMode);
else
// Greenfield or Mixed format
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
@@ -473,24 +528,27 @@
plcpHsigHeaderStart-plcpHeaderStart,
MfHeaderMode);
}
- else if (current >=plcpHtTrainingSymbolsStart )
+ else if (current >= plcpHtTrainingSymbolsStart )
{
// Non HT format will not come here since it will execute prev if
// Greenfield or Mixed format
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- headerMode),
- plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
- headerMode);
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ headerMode),
+ plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
+ headerMode);
+ // Greenfield
if (preamble == WIFI_PREAMBLE_HT_MF)
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- MfHeaderMode),
- plcpHsigHeaderStart-plcpHeaderStart,
- MfHeaderMode);
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ MfHeaderMode),
+ plcpHsigHeaderStart-plcpHeaderStart,
+ MfHeaderMode);
+ }
}
- //non HT will not come here
- else if (current >=plcpHsigHeaderStart)
+ // non HT will not come here
+ else if (current >= plcpHsigHeaderStart)
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
@@ -513,17 +571,17 @@
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- headerMode),
- current - plcpHeaderStart,
- headerMode);
+ headerMode),
+ current - plcpHeaderStart,
+ headerMode);
}
else
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- MfHeaderMode),
- current - plcpHeaderStart,
- MfHeaderMode);
+ MfHeaderMode),
+ current - plcpHeaderStart,
+ MfHeaderMode);
}
}
}
@@ -537,9 +595,8 @@
return per;
}
-
struct InterferenceHelper::SnrPer
-InterferenceHelper::CalculateSnrPer (Ptr<InterferenceHelper::Event> event)
+InterferenceHelper::CalculatePlcpPayloadSnrPer (Ptr<InterferenceHelper::Event> event)
{
NiChanges ni;
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
@@ -550,7 +607,27 @@
/* calculate the SNIR at the start of the packet and accumulate
* all SNIR changes in the snir vector.
*/
- double per = CalculatePer (event, &ni);
+ double per = CalculatePlcpPayloadPer (event, &ni);
+
+ struct SnrPer snrPer;
+ snrPer.snr = snr;
+ snrPer.per = per;
+ return snrPer;
+}
+
+struct InterferenceHelper::SnrPer
+InterferenceHelper::CalculatePlcpHeaderSnrPer (Ptr<InterferenceHelper::Event> event)
+{
+ NiChanges ni;
+ double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
+ double snr = CalculateSnr (event->GetRxPowerW (),
+ noiseInterferenceW,
+ WifiPhy::GetPlcpHeaderMode (event->GetPayloadMode (), event->GetPreambleType ()));
+
+ /* calculate the SNIR at the start of the plcp header and accumulate
+ * all SNIR changes in the snir vector.
+ */
+ double per = CalculatePlcpHeaderPer (event, &ni);
struct SnrPer snrPer;
snrPer.snr = snr;
--- a/src/wifi/model/interference-helper.h Sat May 02 22:21:58 2015 +0200
+++ b/src/wifi/model/interference-helper.h Sun May 03 16:06:01 2015 +0200
@@ -182,13 +182,21 @@
Time duration, double rxPower, WifiTxVector txvector);
/**
- * Calculate the SNIR at the start of the packet and accumulate
+ * Calculate the SNIR at the start of the plcp payload and accumulate
* all SNIR changes in the snir vector.
*
- * \param event the event corresponding to the first time the packet arrives
+ * \param event the event corresponding to the first time the corresponding packet arrives
* \return struct of SNR and PER
*/
- struct InterferenceHelper::SnrPer CalculateSnrPer (Ptr<InterferenceHelper::Event> event);
+ struct InterferenceHelper::SnrPer CalculatePlcpPayloadSnrPer (Ptr<InterferenceHelper::Event> event);
+ /**
+ * Calculate the SNIR at the start of the plcp header and accumulate
+ * all SNIR changes in the snir vector.
+ *
+ * \param event the event corresponding to the first time the corresponding packet arrives
+ * \return struct of SNR and PER
+ */
+ struct InterferenceHelper::SnrPer CalculatePlcpHeaderSnrPer (Ptr<InterferenceHelper::Event> event);
/**
* Notify that RX has started.
*/
@@ -284,14 +292,23 @@
*/
double CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode) const;
/**
- * Calculate the error rate of the given packet. The packet can be divided into
+ * Calculate the error rate of the given plcp payload. The plcp payload can be divided into
* multiple chunks (e.g. due to interference from other transmissions).
*
* \param event
* \param ni
* \return the error rate of the packet
*/
- double CalculatePer (Ptr<const Event> event, NiChanges *ni) const;
+ double CalculatePlcpPayloadPer (Ptr<const Event> event, NiChanges *ni) const;
+ /**
+ * Calculate the error rate of the plcp header. The plcp header can be divided into
+ * multiple chunks (e.g. due to interference from other transmissions).
+ *
+ * \param event
+ * \param ni
+ * \return the error rate of the packet
+ */
+ double CalculatePlcpHeaderPer (Ptr<const Event> event, NiChanges *ni) const;
double m_noiseFigure; /**< noise figure (linear) */
Ptr<ErrorRateModel> m_errorRateModel;
--- a/src/wifi/model/wifi-phy.cc Sat May 02 22:21:58 2015 +0200
+++ b/src/wifi/model/wifi-phy.cc Sun May 03 16:06:01 2015 +0200
@@ -584,6 +584,16 @@
+ GetPayloadDuration (size, txvector, preamble, frequency, packetType, incFlag);
return duration;
}
+Time
+WifiPhy::CalculatePlcpDuration (WifiTxVector txvector, WifiPreamble preamble)
+{
+ WifiMode payloadMode=txvector.GetMode();
+ Time duration = GetPlcpPreambleDuration (payloadMode, preamble)
+ + GetPlcpHeaderDuration (payloadMode, preamble)
+ + GetPlcpHtSigHeaderDuration (preamble)
+ + GetPlcpHtTrainingSymbolDuration (preamble, txvector);
+ return duration;
+}
void
WifiPhy::NotifyTxBegin (Ptr<const Packet> packet)
--- a/src/wifi/model/wifi-phy.h Sat May 02 22:21:58 2015 +0200
+++ b/src/wifi/model/wifi-phy.h Sun May 03 16:06:01 2015 +0200
@@ -295,6 +295,13 @@
* the transmission of these bytes.
*/
Time CalculateTxDuration (uint32_t size, WifiTxVector txvector, enum WifiPreamble preamble, double frequency, uint8_t packetType, uint8_t incFlag);
+
+ /**
+ * \param txvector the transmission parameters used for this packet
+ * \param preamble the type of preamble to use for this packet.
+ * \return the total amount of time this PHY will stay busy for the transmission of the plcp.
+ */
+ Time CalculatePlcpDuration (WifiTxVector txvector, enum WifiPreamble preamble);
/**
* \param preamble the type of preamble
--- a/src/wifi/model/yans-wifi-channel.cc Sat May 02 22:21:58 2015 +0200
+++ b/src/wifi/model/yans-wifi-channel.cc Sun May 03 16:06:01 2015 +0200
@@ -125,7 +125,7 @@
YansWifiChannel::Receive (uint32_t i, Ptr<Packet> packet, double *atts,
WifiTxVector txVector, WifiPreamble preamble) const
{
- m_phyList[i]->StartReceivePacket (packet, *atts, txVector, preamble,*(atts+1), NanoSeconds(*(atts+2)));
+ m_phyList[i]->StartReceivePlcp (packet, *atts, txVector, preamble,*(atts+1), NanoSeconds(*(atts+2)));
delete[] atts;
}
--- a/src/wifi/model/yans-wifi-phy.cc Sat May 02 22:21:58 2015 +0200
+++ b/src/wifi/model/yans-wifi-phy.cc Sun May 03 16:06:01 2015 +0200
@@ -173,8 +173,10 @@
: m_initialized (false),
m_channelNumber (1),
m_endRxEvent (),
+ m_endPlcpRxEvent(),
m_channelStartingFrequency (0),
- m_mpdusNum(0)
+ m_mpdusNum(0),
+ m_plcpSuccess (false)
{
NS_LOG_FUNCTION (this);
m_random = CreateObject<UniformRandomVariable> ();
@@ -397,6 +399,7 @@
{
case YansWifiPhy::RX:
NS_LOG_DEBUG ("drop packet because of channel switching while reception");
+ m_endPlcpRxEvent.Cancel();
m_endRxEvent.Cancel ();
goto switchChannel;
break;
@@ -514,19 +517,24 @@
{
m_state->SetReceiveErrorCallback (callback);
}
+
void
-YansWifiPhy::StartReceivePacket (Ptr<Packet> packet,
- double rxPowerDbm,
- WifiTxVector txVector,
- enum WifiPreamble preamble,
- uint8_t packetType, Time rxDuration)
+YansWifiPhy::StartReceivePlcp (Ptr<Packet> packet,
+ double rxPowerDbm,
+ WifiTxVector txVector,
+ enum WifiPreamble preamble,
+ uint8_t packetType, Time rxDuration)
{
+ // This function should be later split to check separately wether plcp preamble and plcp header can be successfully received.
+ // Note: plcp preamble reception is not yet modeled.
NS_LOG_FUNCTION (this << packet << rxPowerDbm << txVector.GetMode()<< preamble << (uint32_t)packetType);
AmpduTag ampduTag;
+ WifiMode txMode = txVector.GetMode();
+
rxPowerDbm += m_rxGainDb;
double rxPowerW = DbmToW (rxPowerDbm);
- WifiMode txMode = txVector.GetMode();
Time endRx = Simulator::Now () + rxDuration;
+ Time plcpDuration = CalculatePlcpDuration (txVector, preamble);
Ptr<InterferenceHelper::Event> event;
event = m_interference.Add (packet->GetSize (),
@@ -534,13 +542,14 @@
preamble,
rxDuration,
rxPowerW,
- txVector); // we need it to calculate duration of HT training symbols
-
+ txVector);
+
switch (m_state->GetState ())
{
case YansWifiPhy::SWITCHING:
NS_LOG_DEBUG ("drop packet because of channel switching");
NotifyRxDrop (packet);
+ m_plcpSuccess = false;
/*
* Packets received on the upcoming channel are added to the event list
* during the switching state. This way the medium can be correctly sensed
@@ -580,71 +589,79 @@
break;
case YansWifiPhy::CCA_BUSY:
case YansWifiPhy::IDLE:
- if (rxPowerW > m_edThresholdW)
+ if (rxPowerW > m_edThresholdW) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration)
{
- if (IsModeSupported (txMode) || IsMcsSupported(txMode))
+ if (preamble == WIFI_PREAMBLE_NONE && m_mpdusNum == 0)
{
- if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
- {
- //received the first MPDU in an MPDU
- m_mpdusNum = ampduTag.GetNoOfMpdus()-1;
- }
- else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
- {
- //received the other MPDUs that are part of the A-MPDU
- if (ampduTag.GetNoOfMpdus() < m_mpdusNum)
- {
- NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetNoOfMpdus());
- m_mpdusNum = ampduTag.GetNoOfMpdus();
- }
- else
- m_mpdusNum--;
- }
- else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
- {
- NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
- m_mpdusNum = 0;
- }
- else if (preamble == WIFI_PREAMBLE_NONE && m_mpdusNum == 0)
- {
- NS_LOG_DEBUG ("drop packet because no preamble has been received");
- NotifyRxDrop (packet);
- goto maybeCcaBusy;
- }
- NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
- // sync to signal
- m_state->SwitchToRx (rxDuration);
- NS_ASSERT (m_endRxEvent.IsExpired ());
- NotifyRxBegin (packet);
- m_interference.NotifyRxStart ();
- m_endRxEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndReceive, this,
- packet,
- event);
+ NS_LOG_DEBUG ("drop packet because no preamble has been received");
+ NotifyRxDrop (packet);
+ goto maybeCcaBusy;
}
- else
+ else if (preamble == WIFI_PREAMBLE_NONE && m_plcpSuccess == false) // A-MPDU reception fails
{
- NS_LOG_DEBUG ("drop packet because it was sent using an unsupported mode (" << txMode << ")");
+ NS_LOG_DEBUG ("Drop MPDU because no plcp has been received");
NotifyRxDrop (packet);
goto maybeCcaBusy;
}
+ else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
+ {
+ //received the first MPDU in an MPDU
+ m_mpdusNum = ampduTag.GetNoOfMpdus()-1;
+ }
+ else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
+ {
+ //received the other MPDUs that are part of the A-MPDU
+ if (ampduTag.GetNoOfMpdus() < m_mpdusNum)
+ {
+ NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetNoOfMpdus());
+ m_mpdusNum = ampduTag.GetNoOfMpdus();
+ }
+ else
+ m_mpdusNum--;
+ }
+ else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 )
+ {
+ NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum);
+ m_mpdusNum = 0;
+ }
+
+ NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
+ // sync to signal
+ m_state->SwitchToRx (rxDuration);
+ NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
+ NotifyRxBegin (packet);
+ m_interference.NotifyRxStart ();
+
+ if (preamble != WIFI_PREAMBLE_NONE)
+ {
+ NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
+ m_endPlcpRxEvent = Simulator::Schedule (plcpDuration, &YansWifiPhy::StartReceivePacket, this,
+ packet, txVector, preamble, packetType, event);
+ }
+
+ NS_ASSERT (m_endRxEvent.IsExpired ());
+ m_endRxEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndReceive, this,
+ packet, preamble, packetType, event);
}
else
{
NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
rxPowerW << "<" << m_edThresholdW << ")");
NotifyRxDrop (packet);
+ m_plcpSuccess = false;
goto maybeCcaBusy;
}
break;
case YansWifiPhy::SLEEP:
NS_LOG_DEBUG ("drop packet because in sleep mode");
NotifyRxDrop (packet);
+ m_plcpSuccess = false;
break;
}
return;
-
-maybeCcaBusy:
+
+ maybeCcaBusy:
// We are here because we have received the first bit of a packet and we are
// not going to be able to synchronize on it
// In this model, CCA becomes busy when the aggregation of all signals as
@@ -656,6 +673,45 @@
m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
}
}
+void
+YansWifiPhy::StartReceivePacket (Ptr<Packet> packet,
+ WifiTxVector txVector,
+ enum WifiPreamble preamble,
+ uint8_t packetType,
+ Ptr<InterferenceHelper::Event> event)
+{
+ NS_LOG_FUNCTION (this << packet << txVector.GetMode()<< preamble << (uint32_t)packetType);
+ NS_ASSERT (IsStateRx ());
+ NS_ASSERT (m_endPlcpRxEvent.IsExpired ());
+ AmpduTag ampduTag;
+ WifiMode txMode = txVector.GetMode();
+
+ struct InterferenceHelper::SnrPer snrPer;
+ snrPer = m_interference.CalculatePlcpHeaderSnrPer (event);
+
+ NS_LOG_DEBUG ("snr=" << snrPer.snr << ", per=" << snrPer.per);
+
+ if (m_random->GetValue () > snrPer.per) //plcp reception succeeded
+ {
+ if (IsModeSupported (txMode) || IsMcsSupported(txMode))
+ {
+ NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
+ m_plcpSuccess = true;
+ }
+ else //mode is not allowed
+ {
+ NS_LOG_DEBUG ("drop packet because it was sent using an unsupported mode (" << txMode << ")");
+ NotifyRxDrop (packet);
+ m_plcpSuccess = false;
+ }
+ }
+ else //plcp reception failed
+ {
+ NS_LOG_DEBUG ("drop packet because plcp reception failed");
+ NotifyRxDrop (packet);
+ m_plcpSuccess = false;
+ }
+}
void
YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType)
@@ -668,7 +724,7 @@
* - we are idle
*/
NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
-
+
if (m_state->IsStateSleep ())
{
NS_LOG_DEBUG ("Dropping packet because in sleep mode");
@@ -679,6 +735,7 @@
Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble, GetFrequency(), packetType, 1);
if (m_state->IsStateRx ())
{
+ m_endPlcpRxEvent.Cancel ();
m_endRxEvent.Cancel ();
m_interference.NotifyRxEnd ();
}
@@ -948,19 +1005,22 @@
}
void
-YansWifiPhy::EndReceive (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event)
+YansWifiPhy::EndReceive (Ptr<Packet> packet, enum WifiPreamble preamble, uint8_t packetType, Ptr<InterferenceHelper::Event> event)
{
NS_LOG_FUNCTION (this << packet << event);
NS_ASSERT (IsStateRx ());
NS_ASSERT (event->GetEndTime () == Simulator::Now ());
struct InterferenceHelper::SnrPer snrPer;
- snrPer = m_interference.CalculateSnrPer (event);
+ snrPer = m_interference.CalculatePlcpPayloadSnrPer (event);
m_interference.NotifyRxEnd ();
-
- NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate ()) <<
- ", snr=" << snrPer.snr << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
- if (m_random->GetValue () > snrPer.per)
+
+ if (m_plcpSuccess == true)
+ {
+ NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate ()) <<
+ ", snr=" << snrPer.snr << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
+
+ if (m_random->GetValue () > snrPer.per)
{
NotifyRxEnd (packet);
uint32_t dataRate500KbpsUnits;
@@ -978,12 +1038,23 @@
NotifyMonitorSniffRx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, signalDbm, noiseDbm);
m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ());
}
- else
+ else
{
/* failure. */
NotifyRxDrop (packet);
m_state->SwitchFromRxEndError (packet, snrPer.snr);
}
+ }
+ else
+ {
+ m_state->SwitchFromRxEndError (packet, snrPer.snr); //notify rx end
+ }
+
+ if (preamble == WIFI_PREAMBLE_NONE && packetType == 2)
+ {
+ m_plcpSuccess = false;
+ }
+
}
int64_t
--- a/src/wifi/model/yans-wifi-phy.h Sat May 02 22:21:58 2015 +0200
+++ b/src/wifi/model/yans-wifi-phy.h Sun May 03 16:06:01 2015 +0200
@@ -100,21 +100,35 @@
double GetChannelFrequencyMhz () const;
/**
- * Starting receiving the packet (i.e. the first bit of the preamble has arrived).
+ * Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived).
*
* \param packet the arriving packet
* \param rxPowerDbm the receive power in dBm
* \param txVector the TXVECTOR of the arriving packet
* \param preamble the preamble of the arriving packet
* \param packetType The type of the received packet (values: 0 not an A-MPDU, 1 corresponds to any packets in an A-MPDU except the last one, 2 is the last packet in an A-MPDU)
- * \param rxDuration the duration needed for the reception of the arriving packet
+ * \param rxDuration the duration needed for the reception of the packet
+ */
+ void StartReceivePlcp (Ptr<Packet> packet,
+ double rxPowerDbm,
+ WifiTxVector txVector,
+ WifiPreamble preamble,
+ uint8_t packetType,
+ Time rxDuration);
+ /**
+ * Starting receiving the payload of a packet (i.e. the first bit of the packet has arrived).
+ *
+ * \param packet the arriving packet
+ * \param txVector the TXVECTOR of the arriving packet
+ * \param preamble the preamble of the arriving packet
+ * \param packetType The type of the received packet (values: 0 not an A-MPDU, 1 corresponds to any packets in an A-MPDU except the last one, 2 is the last packet in an A-MPDU)
+ * \param event the corresponding event of the first time the packet arrives
*/
void StartReceivePacket (Ptr<Packet> packet,
- double rxPowerDbm,
WifiTxVector txVector,
WifiPreamble preamble,
uint8_t packetType,
- Time rxDuration);
+ Ptr<InterferenceHelper::Event> event);
/**
* Sets the RX loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver.
@@ -462,13 +476,15 @@
* The last bit of the packet has arrived.
*
* \param packet the packet that the last bit has arrived
+ * \param preamble the preamble of the arriving packet
+ * \param packetType The type of the received packet (values: 0 not an A-MPDU, 1 corresponds to any packets in an A-MPDU except the last one, 2 is the last packet in an A-MPDU)
* \param event the corresponding event of the first time the packet arrives
*/
- void EndReceive (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event);
+ void EndReceive (Ptr<Packet> packet, enum WifiPreamble preamble, uint8_t packetType, Ptr<InterferenceHelper::Event> event);
private:
virtual void DoInitialize (void);
-
+
bool m_initialized; //!< Flag for runtime initialization
double m_edThresholdW; //!< Energy detection threshold in watts
double m_ccaMode1ThresholdW; //!< Clear channel assessment (CCA) threshold in watts
@@ -533,6 +549,7 @@
std::vector<uint32_t> m_bssMembershipSelectorSet;
std::vector<uint8_t> m_deviceMcsSet;
EventId m_endRxEvent;
+ EventId m_endPlcpRxEvent;
Ptr<UniformRandomVariable> m_random; //!< Provides uniform random variables.
double m_channelStartingFrequency; //!< Standard-dependent center frequency of 0-th channel in MHz
@@ -540,6 +557,7 @@
InterferenceHelper m_interference; //!< Pointer to InterferenceHelper
Time m_channelSwitchDelay; //!< Time required to switch between channel
uint16_t m_mpdusNum; //!< carries the number of expected mpdus that are part of an A-MPDU
+ bool m_plcpSuccess; //!< Flag if the PLCP of the packet or the first MPDU in an A-MPDU has been received
};
} // namespace ns3