|
|
| 30 |
#include "wifi-phy-tag.h" |
30 |
#include "wifi-phy-tag.h" |
| 31 |
#include "ampdu-tag.h" |
31 |
#include "ampdu-tag.h" |
| 32 |
#include "wifi-utils.h" |
32 |
#include "wifi-utils.h" |
|
|
33 |
#include "frame-capture-model.h" |
| 33 |
|
34 |
|
| 34 |
namespace ns3 { |
35 |
namespace ns3 { |
| 35 |
|
36 |
|
|
|
| 314 |
MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported, |
315 |
MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported, |
| 315 |
&WifiPhy::SetShortPlcpPreambleSupported), |
316 |
&WifiPhy::SetShortPlcpPreambleSupported), |
| 316 |
MakeBooleanChecker ()) |
317 |
MakeBooleanChecker ()) |
|
|
318 |
.AddAttribute ("FrameCaptureModel", |
| 319 |
"Ptr to an object that implements the frame capture model", |
| 320 |
PointerValue (0), //StringValue ("ns3::SimpleFrameCaptureModel"), |
| 321 |
MakePointerAccessor (&WifiPhy::GetFrameCaptureModel, |
| 322 |
&WifiPhy::SetFrameCaptureModel), |
| 323 |
MakePointerChecker <FrameCaptureModel>()) |
| 317 |
.AddTraceSource ("PhyTxBegin", |
324 |
.AddTraceSource ("PhyTxBegin", |
| 318 |
"Trace source indicating a packet " |
325 |
"Trace source indicating a packet " |
| 319 |
"has begun transmitting over the channel medium", |
326 |
"has begun transmitting over the channel medium", |
|
|
| 378 |
m_channelNumber (0), |
385 |
m_channelNumber (0), |
| 379 |
m_initialChannelNumber (0), |
386 |
m_initialChannelNumber (0), |
| 380 |
m_totalAmpduSize (0), |
387 |
m_totalAmpduSize (0), |
| 381 |
m_totalAmpduNumSymbols (0) |
388 |
m_totalAmpduNumSymbols (0), |
|
|
389 |
m_currentEvent (0) |
| 382 |
{ |
390 |
{ |
| 383 |
NS_LOG_FUNCTION (this); |
391 |
NS_LOG_FUNCTION (this); |
| 384 |
NS_UNUSED (m_numberOfTransmitters); |
392 |
NS_UNUSED (m_numberOfTransmitters); |
|
|
| 702 |
return m_interference.GetErrorRateModel (); |
710 |
return m_interference.GetErrorRateModel (); |
| 703 |
} |
711 |
} |
| 704 |
|
712 |
|
|
|
713 |
void |
| 714 |
WifiPhy::SetFrameCaptureModel (Ptr<FrameCaptureModel> model) |
| 715 |
{ |
| 716 |
m_frameCaptureModel = model; |
| 717 |
} |
| 718 |
|
| 719 |
Ptr<FrameCaptureModel> |
| 720 |
WifiPhy::GetFrameCaptureModel (void) const |
| 721 |
{ |
| 722 |
return m_frameCaptureModel; |
| 723 |
} |
| 724 |
|
| 705 |
double |
725 |
double |
| 706 |
WifiPhy::GetPowerDbm (uint8_t power) const |
726 |
WifiPhy::GetPowerDbm (uint8_t power) const |
| 707 |
{ |
727 |
{ |
|
|
| 2356 |
//This function should be later split to check separately whether plcp preamble and plcp header can be successfully received. |
2376 |
//This function should be later split to check separately whether plcp preamble and plcp header can be successfully received. |
| 2357 |
//Note: plcp preamble reception is not yet modeled. |
2377 |
//Note: plcp preamble reception is not yet modeled. |
| 2358 |
NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration); |
2378 |
NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration); |
| 2359 |
AmpduTag ampduTag; |
|
|
| 2360 |
Time endRx = Simulator::Now () + rxDuration; |
2379 |
Time endRx = Simulator::Now () + rxDuration; |
| 2361 |
|
2380 |
|
| 2362 |
WifiPhyTag tag; |
2381 |
WifiPhyTag tag; |
|
|
| 2380 |
NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams"); |
2399 |
NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams"); |
| 2381 |
} |
2400 |
} |
| 2382 |
|
2401 |
|
| 2383 |
WifiPreamble preamble = txVector.GetPreambleType (); |
|
|
| 2384 |
MpduType mpdutype = tag.GetMpduType (); |
| 2385 |
Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector); |
| 2386 |
|
| 2387 |
Ptr<InterferenceHelper::Event> event; |
2402 |
Ptr<InterferenceHelper::Event> event; |
| 2388 |
event = m_interference.Add (packet->GetSize (), |
2403 |
event = m_interference.Add (packet, |
| 2389 |
txVector, |
2404 |
txVector, |
| 2390 |
rxDuration, |
2405 |
rxDuration, |
| 2391 |
rxPowerW); |
2406 |
rxPowerW); |
| 2392 |
|
2407 |
|
|
|
2408 |
MpduType mpdutype = tag.GetMpduType (); |
| 2393 |
switch (m_state->GetState ()) |
2409 |
switch (m_state->GetState ()) |
| 2394 |
{ |
2410 |
{ |
| 2395 |
case WifiPhy::SWITCHING: |
2411 |
case WifiPhy::SWITCHING: |
|
|
| 2408 |
{ |
2424 |
{ |
| 2409 |
//that packet will be noise _after_ the completion of the |
2425 |
//that packet will be noise _after_ the completion of the |
| 2410 |
//channel switching. |
2426 |
//channel switching. |
| 2411 |
goto maybeCcaBusy; |
2427 |
MaybeCcaBusyDuration (); |
|
|
2428 |
return; |
| 2412 |
} |
2429 |
} |
| 2413 |
break; |
2430 |
break; |
| 2414 |
case WifiPhy::RX: |
2431 |
case WifiPhy::RX: |
| 2415 |
NS_LOG_DEBUG ("drop packet because already in Rx (power=" << |
2432 |
NS_ASSERT (m_currentEvent != 0); |
| 2416 |
rxPowerW << "W)"); |
2433 |
if (m_frameCaptureModel != 0 && |
| 2417 |
NotifyRxDrop (packet); |
2434 |
m_frameCaptureModel->CaptureNewFrame(m_currentEvent, event)) |
| 2418 |
if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) |
|
|
| 2419 |
{ |
2435 |
{ |
| 2420 |
//that packet will be noise _after_ the reception of the |
2436 |
AbortCurrentReception (); |
| 2421 |
//currently-received packet. |
2437 |
NS_LOG_DEBUG ("Switch to new packet"); |
| 2422 |
goto maybeCcaBusy; |
2438 |
StartRx (packet, txVector, mpdutype, rxPowerW, rxDuration, event); |
|
|
2439 |
} |
| 2440 |
else |
| 2441 |
{ |
| 2442 |
NS_LOG_DEBUG ("drop packet because already in Rx (power=" << |
| 2443 |
rxPowerW << "W)"); |
| 2444 |
NotifyRxDrop (packet); |
| 2445 |
if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) |
| 2446 |
{ |
| 2447 |
//that packet will be noise _after_ the reception of the |
| 2448 |
//currently-received packet. |
| 2449 |
MaybeCcaBusyDuration (); |
| 2450 |
return; |
| 2451 |
} |
| 2423 |
} |
2452 |
} |
| 2424 |
break; |
2453 |
break; |
| 2425 |
case WifiPhy::TX: |
2454 |
case WifiPhy::TX: |
|
|
| 2430 |
{ |
2459 |
{ |
| 2431 |
//that packet will be noise _after_ the transmission of the |
2460 |
//that packet will be noise _after_ the transmission of the |
| 2432 |
//currently-transmitted packet. |
2461 |
//currently-transmitted packet. |
| 2433 |
goto maybeCcaBusy; |
2462 |
MaybeCcaBusyDuration (); |
|
|
2463 |
return; |
| 2434 |
} |
2464 |
} |
| 2435 |
break; |
2465 |
break; |
| 2436 |
case WifiPhy::CCA_BUSY: |
2466 |
case WifiPhy::CCA_BUSY: |
| 2437 |
case WifiPhy::IDLE: |
2467 |
case WifiPhy::IDLE: |
| 2438 |
if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration) |
2468 |
StartRx (packet, txVector, mpdutype, rxPowerW, rxDuration, event); |
| 2439 |
{ |
|
|
| 2440 |
if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false)) |
| 2441 |
{ |
| 2442 |
m_plcpSuccess = false; |
| 2443 |
m_mpdusNum = 0; |
| 2444 |
NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received"); |
| 2445 |
NotifyRxDrop (packet); |
| 2446 |
goto maybeCcaBusy; |
| 2447 |
} |
| 2448 |
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0) |
| 2449 |
{ |
| 2450 |
//received the first MPDU in an MPDU |
| 2451 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 2452 |
m_rxMpduReferenceNumber++; |
| 2453 |
} |
| 2454 |
else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0) |
| 2455 |
{ |
| 2456 |
//received the other MPDUs that are part of the A-MPDU |
| 2457 |
if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1)) |
| 2458 |
{ |
| 2459 |
NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ()); |
| 2460 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 2461 |
} |
| 2462 |
else |
| 2463 |
{ |
| 2464 |
m_mpdusNum--; |
| 2465 |
} |
| 2466 |
} |
| 2467 |
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0) |
| 2468 |
{ |
| 2469 |
NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost"); |
| 2470 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 2471 |
} |
| 2472 |
else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 ) |
| 2473 |
{ |
| 2474 |
NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum); |
| 2475 |
m_mpdusNum = 0; |
| 2476 |
} |
| 2477 |
|
| 2478 |
NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)"); |
| 2479 |
//sync to signal |
| 2480 |
m_state->SwitchToRx (rxDuration); |
| 2481 |
NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); |
| 2482 |
NotifyRxBegin (packet); |
| 2483 |
m_interference.NotifyRxStart (); |
| 2484 |
|
| 2485 |
if (preamble != WIFI_PREAMBLE_NONE) |
| 2486 |
{ |
| 2487 |
NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); |
| 2488 |
m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this, |
| 2489 |
packet, txVector, mpdutype, event); |
| 2490 |
} |
| 2491 |
|
| 2492 |
NS_ASSERT (m_endRxEvent.IsExpired ()); |
| 2493 |
m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, |
| 2494 |
packet, preamble, mpdutype, event); |
| 2495 |
} |
| 2496 |
else |
| 2497 |
{ |
| 2498 |
NS_LOG_DEBUG ("drop packet because signal power too Small (" << |
| 2499 |
rxPowerW << "<" << GetEdThresholdW () << ")"); |
| 2500 |
NotifyRxDrop (packet); |
| 2501 |
m_plcpSuccess = false; |
| 2502 |
goto maybeCcaBusy; |
| 2503 |
} |
| 2504 |
break; |
2469 |
break; |
| 2505 |
case WifiPhy::SLEEP: |
2470 |
case WifiPhy::SLEEP: |
| 2506 |
NS_LOG_DEBUG ("drop packet because in sleep mode"); |
2471 |
NS_LOG_DEBUG ("drop packet because in sleep mode"); |
|
|
| 2508 |
m_plcpSuccess = false; |
2473 |
m_plcpSuccess = false; |
| 2509 |
break; |
2474 |
break; |
| 2510 |
} |
2475 |
} |
| 2511 |
|
2476 |
} |
| 2512 |
return; |
2477 |
|
| 2513 |
|
2478 |
void |
| 2514 |
maybeCcaBusy: |
2479 |
WifiPhy::MaybeCcaBusyDuration () |
|
|
2480 |
{ |
| 2515 |
//We are here because we have received the first bit of a packet and we are |
2481 |
//We are here because we have received the first bit of a packet and we are |
| 2516 |
//not going to be able to synchronize on it |
2482 |
//not going to be able to synchronize on it |
| 2517 |
//In this model, CCA becomes busy when the aggregation of all signals as |
2483 |
//In this model, CCA becomes busy when the aggregation of all signals as |
|
|
| 2572 |
InterferenceHelper::SnrPer snrPer; |
2538 |
InterferenceHelper::SnrPer snrPer; |
| 2573 |
snrPer = m_interference.CalculatePlcpPayloadSnrPer (event); |
2539 |
snrPer = m_interference.CalculatePlcpPayloadSnrPer (event); |
| 2574 |
m_interference.NotifyRxEnd (); |
2540 |
m_interference.NotifyRxEnd (); |
|
|
2541 |
m_currentEvent = 0; |
| 2575 |
|
2542 |
|
| 2576 |
if (m_plcpSuccess == true) |
2543 |
if (m_plcpSuccess == true) |
| 2577 |
{ |
2544 |
{ |
|
|
| 3662 |
} |
3629 |
} |
| 3663 |
} |
3630 |
} |
| 3664 |
|
3631 |
|
|
|
3632 |
void |
| 3633 |
WifiPhy::AbortCurrentReception () |
| 3634 |
{ |
| 3635 |
NS_LOG_FUNCTION (this); |
| 3636 |
if (m_endPlcpRxEvent.IsRunning ()) |
| 3637 |
{ |
| 3638 |
m_endPlcpRxEvent.Cancel (); |
| 3639 |
} |
| 3640 |
if (m_endRxEvent.IsRunning ()) |
| 3641 |
{ |
| 3642 |
m_endRxEvent.Cancel (); |
| 3643 |
} |
| 3644 |
NotifyRxDrop (m_currentEvent->GetPacket ()); |
| 3645 |
m_interference.NotifyRxEnd (); |
| 3646 |
m_state->SwitchFromRxAbort (); |
| 3647 |
m_currentEvent = 0; |
| 3648 |
} |
| 3649 |
|
| 3650 |
void |
| 3651 |
WifiPhy::StartRx (Ptr<Packet> packet, WifiTxVector txVector, MpduType mpdutype, double rxPowerW, Time rxDuration, Ptr<InterferenceHelper::Event> event) |
| 3652 |
{ |
| 3653 |
NS_LOG_FUNCTION (this << packet << txVector << (uint16_t)mpdutype << rxPowerW << rxDuration); |
| 3654 |
if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration) |
| 3655 |
{ |
| 3656 |
AmpduTag ampduTag; |
| 3657 |
WifiPreamble preamble = txVector.GetPreambleType (); |
| 3658 |
if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false)) |
| 3659 |
{ |
| 3660 |
m_plcpSuccess = false; |
| 3661 |
m_mpdusNum = 0; |
| 3662 |
NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received"); |
| 3663 |
NotifyRxDrop (packet); |
| 3664 |
MaybeCcaBusyDuration (); |
| 3665 |
return; |
| 3666 |
} |
| 3667 |
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0) |
| 3668 |
{ |
| 3669 |
//received the first MPDU in an MPDU |
| 3670 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 3671 |
m_rxMpduReferenceNumber++; |
| 3672 |
} |
| 3673 |
else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0) |
| 3674 |
{ |
| 3675 |
//received the other MPDUs that are part of the A-MPDU |
| 3676 |
if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1)) |
| 3677 |
{ |
| 3678 |
NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ()); |
| 3679 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 3680 |
} |
| 3681 |
else |
| 3682 |
{ |
| 3683 |
m_mpdusNum--; |
| 3684 |
} |
| 3685 |
} |
| 3686 |
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0) |
| 3687 |
{ |
| 3688 |
NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost"); |
| 3689 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 3690 |
} |
| 3691 |
else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 ) |
| 3692 |
{ |
| 3693 |
NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum); |
| 3694 |
m_mpdusNum = 0; |
| 3695 |
} |
| 3696 |
|
| 3697 |
NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)"); |
| 3698 |
m_currentEvent = event; |
| 3699 |
m_state->SwitchToRx (rxDuration); |
| 3700 |
NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); |
| 3701 |
NotifyRxBegin (packet); |
| 3702 |
m_interference.NotifyRxStart (); |
| 3703 |
|
| 3704 |
if (preamble != WIFI_PREAMBLE_NONE) |
| 3705 |
{ |
| 3706 |
NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); |
| 3707 |
Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector); |
| 3708 |
m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this, |
| 3709 |
packet, txVector, mpdutype, event); |
| 3710 |
} |
| 3711 |
|
| 3712 |
NS_ASSERT (m_endRxEvent.IsExpired ()); |
| 3713 |
m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, |
| 3714 |
packet, preamble, mpdutype, event); |
| 3715 |
} |
| 3716 |
else |
| 3717 |
{ |
| 3718 |
NS_LOG_DEBUG ("drop packet because signal power too Small (" << |
| 3719 |
rxPowerW << "<" << GetEdThresholdW () << ")"); |
| 3720 |
NotifyRxDrop (packet); |
| 3721 |
m_plcpSuccess = false; |
| 3722 |
MaybeCcaBusyDuration (); |
| 3723 |
} |
| 3724 |
} |
| 3725 |
|
| 3665 |
int64_t |
3726 |
int64_t |
| 3666 |
WifiPhy::AssignStreams (int64_t stream) |
3727 |
WifiPhy::AssignStreams (int64_t stream) |
| 3667 |
{ |
3728 |
{ |