|
|
| 314 |
MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported, |
314 |
MakeBooleanAccessor (&WifiPhy::GetShortPlcpPreambleSupported, |
| 315 |
&WifiPhy::SetShortPlcpPreambleSupported), |
315 |
&WifiPhy::SetShortPlcpPreambleSupported), |
| 316 |
MakeBooleanChecker ()) |
316 |
MakeBooleanChecker ()) |
|
|
317 |
.AddAttribute ("PhysicalLayerCaptureEnabled", |
| 318 |
"Whether or not physical layer capture mode is enabled.", |
| 319 |
BooleanValue (false), |
| 320 |
MakeBooleanAccessor (&WifiPhy::GetPhysicalLayerCaptureEnabled, |
| 321 |
&WifiPhy::SetPhysicalLayerCaptureEnabled), |
| 322 |
MakeBooleanChecker ()) |
| 323 |
.AddAttribute ("PhysicalLayerCaptureMargin", |
| 324 |
"If physical layer capture mode is enabled, reception is switched " |
| 325 |
"if the newly arrived frame has a power higher than this value " |
| 326 |
"above the frame currently being received (expressed in dB).", |
| 327 |
DoubleValue (10), |
| 328 |
MakeDoubleAccessor (&WifiPhy::GetPhysicalLayerCaptureMargin, |
| 329 |
&WifiPhy::SetPhysicalLayerCaptureMargin), |
| 330 |
MakeDoubleChecker<double> ()) |
| 317 |
.AddTraceSource ("PhyTxBegin", |
331 |
.AddTraceSource ("PhyTxBegin", |
| 318 |
"Trace source indicating a packet " |
332 |
"Trace source indicating a packet " |
| 319 |
"has begun transmitting over the channel medium", |
333 |
"has begun transmitting over the channel medium", |
|
|
| 378 |
m_channelNumber (0), |
392 |
m_channelNumber (0), |
| 379 |
m_initialChannelNumber (0), |
393 |
m_initialChannelNumber (0), |
| 380 |
m_totalAmpduSize (0), |
394 |
m_totalAmpduSize (0), |
| 381 |
m_totalAmpduNumSymbols (0) |
395 |
m_totalAmpduNumSymbols (0), |
|
|
396 |
m_currentEvent (0) |
| 382 |
{ |
397 |
{ |
| 383 |
NS_LOG_FUNCTION (this); |
398 |
NS_LOG_FUNCTION (this); |
| 384 |
NS_UNUSED (m_numberOfTransmitters); |
399 |
NS_UNUSED (m_numberOfTransmitters); |
|
|
| 580 |
} |
595 |
} |
| 581 |
|
596 |
|
| 582 |
void |
597 |
void |
|
|
598 |
WifiPhy::SetPhysicalLayerCaptureEnabled (bool enable) |
| 599 |
{ |
| 600 |
NS_LOG_FUNCTION (this << enable); |
| 601 |
m_physicalLayerCaptureEnabled = enable; |
| 602 |
} |
| 603 |
|
| 604 |
bool |
| 605 |
WifiPhy::GetPhysicalLayerCaptureEnabled (void) const |
| 606 |
{ |
| 607 |
return m_physicalLayerCaptureEnabled; |
| 608 |
} |
| 609 |
|
| 610 |
void |
| 611 |
WifiPhy::SetPhysicalLayerCaptureMargin (double margin) |
| 612 |
{ |
| 613 |
NS_LOG_FUNCTION (this << margin); |
| 614 |
m_physicalLayerCaptureMargin = margin; |
| 615 |
} |
| 616 |
|
| 617 |
double |
| 618 |
WifiPhy::GetPhysicalLayerCaptureMargin (void) const |
| 619 |
{ |
| 620 |
return m_physicalLayerCaptureMargin; |
| 621 |
} |
| 622 |
|
| 623 |
void |
| 583 |
WifiPhy::SetLdpc (bool ldpc) |
624 |
WifiPhy::SetLdpc (bool ldpc) |
| 584 |
{ |
625 |
{ |
| 585 |
NS_LOG_FUNCTION (this << ldpc); |
626 |
NS_LOG_FUNCTION (this << ldpc); |
|
|
| 2356 |
//This function should be later split to check separately whether plcp preamble and plcp header can be successfully received. |
2397 |
//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. |
2398 |
//Note: plcp preamble reception is not yet modeled. |
| 2358 |
NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration); |
2399 |
NS_LOG_FUNCTION (this << packet << WToDbm (rxPowerW) << rxDuration); |
| 2359 |
AmpduTag ampduTag; |
|
|
| 2360 |
Time endRx = Simulator::Now () + rxDuration; |
2400 |
Time endRx = Simulator::Now () + rxDuration; |
| 2361 |
|
2401 |
|
| 2362 |
WifiPhyTag tag; |
2402 |
WifiPhyTag tag; |
|
|
| 2380 |
NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams"); |
2420 |
NS_FATAL_ERROR ("Reception ends in failure because of an unsupported number of spatial streams"); |
| 2381 |
} |
2421 |
} |
| 2382 |
|
2422 |
|
| 2383 |
WifiPreamble preamble = txVector.GetPreambleType (); |
|
|
| 2384 |
MpduType mpdutype = tag.GetMpduType (); |
| 2385 |
Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector); |
| 2386 |
|
| 2387 |
Ptr<InterferenceHelper::Event> event; |
2423 |
Ptr<InterferenceHelper::Event> event; |
| 2388 |
event = m_interference.Add (packet->GetSize (), |
2424 |
event = m_interference.Add (packet->GetSize (), |
| 2389 |
txVector, |
2425 |
txVector, |
| 2390 |
rxDuration, |
2426 |
rxDuration, |
| 2391 |
rxPowerW); |
2427 |
rxPowerW); |
| 2392 |
|
2428 |
|
|
|
2429 |
MpduType mpdutype = tag.GetMpduType (); |
| 2393 |
switch (m_state->GetState ()) |
2430 |
switch (m_state->GetState ()) |
| 2394 |
{ |
2431 |
{ |
| 2395 |
case WifiPhy::SWITCHING: |
2432 |
case WifiPhy::SWITCHING: |
|
|
| 2408 |
{ |
2445 |
{ |
| 2409 |
//that packet will be noise _after_ the completion of the |
2446 |
//that packet will be noise _after_ the completion of the |
| 2410 |
//channel switching. |
2447 |
//channel switching. |
| 2411 |
goto maybeCcaBusy; |
2448 |
MaybeCcaBusyDuration (); |
|
|
2449 |
return; |
| 2412 |
} |
2450 |
} |
| 2413 |
break; |
2451 |
break; |
| 2414 |
case WifiPhy::RX: |
2452 |
case WifiPhy::RX: |
| 2415 |
NS_LOG_DEBUG ("drop packet because already in Rx (power=" << |
2453 |
NS_ASSERT (m_currentEvent != 0); |
| 2416 |
rxPowerW << "W)"); |
2454 |
if (m_physicalLayerCaptureEnabled |
| 2417 |
NotifyRxDrop (packet); |
2455 |
&& txVector.GetPreambleType () != WIFI_PREAMBLE_NONE |
| 2418 |
if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) |
2456 |
&& WToDbm (m_currentEvent->GetRxPowerW ()) + m_physicalLayerCaptureMargin < WToDbm (rxPowerW) |
|
|
2457 |
&& m_currentEvent->GetStartTime () + GetPlcpPreambleDuration (m_currentEvent->GetTxVector ()) < Simulator::Now ()) |
| 2419 |
{ |
2458 |
{ |
| 2420 |
//that packet will be noise _after_ the reception of the |
2459 |
AbortCurrentReception (); |
| 2421 |
//currently-received packet. |
2460 |
NS_LOG_DEBUG ("Switch to new packet"); |
| 2422 |
goto maybeCcaBusy; |
2461 |
StartRx (packet, txVector, mpdutype, rxPowerW, rxDuration, event); |
|
|
2462 |
} |
| 2463 |
else |
| 2464 |
{ |
| 2465 |
NS_LOG_DEBUG ("drop packet because already in Rx (power=" << |
| 2466 |
rxPowerW << "W)"); |
| 2467 |
NotifyRxDrop (packet); |
| 2468 |
if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) |
| 2469 |
{ |
| 2470 |
//that packet will be noise _after_ the reception of the |
| 2471 |
//currently-received packet. |
| 2472 |
MaybeCcaBusyDuration (); |
| 2473 |
return; |
| 2474 |
} |
| 2423 |
} |
2475 |
} |
| 2424 |
break; |
2476 |
break; |
| 2425 |
case WifiPhy::TX: |
2477 |
case WifiPhy::TX: |
|
|
| 2430 |
{ |
2482 |
{ |
| 2431 |
//that packet will be noise _after_ the transmission of the |
2483 |
//that packet will be noise _after_ the transmission of the |
| 2432 |
//currently-transmitted packet. |
2484 |
//currently-transmitted packet. |
| 2433 |
goto maybeCcaBusy; |
2485 |
MaybeCcaBusyDuration (); |
|
|
2486 |
return; |
| 2434 |
} |
2487 |
} |
| 2435 |
break; |
2488 |
break; |
| 2436 |
case WifiPhy::CCA_BUSY: |
2489 |
case WifiPhy::CCA_BUSY: |
| 2437 |
case WifiPhy::IDLE: |
2490 |
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) |
2491 |
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; |
2492 |
break; |
| 2505 |
case WifiPhy::SLEEP: |
2493 |
case WifiPhy::SLEEP: |
| 2506 |
NS_LOG_DEBUG ("drop packet because in sleep mode"); |
2494 |
NS_LOG_DEBUG ("drop packet because in sleep mode"); |
|
|
| 2508 |
m_plcpSuccess = false; |
2496 |
m_plcpSuccess = false; |
| 2509 |
break; |
2497 |
break; |
| 2510 |
} |
2498 |
} |
| 2511 |
|
2499 |
} |
| 2512 |
return; |
2500 |
|
| 2513 |
|
2501 |
void |
| 2514 |
maybeCcaBusy: |
2502 |
WifiPhy::MaybeCcaBusyDuration () |
|
|
2503 |
{ |
| 2515 |
//We are here because we have received the first bit of a packet and we are |
2504 |
//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 |
2505 |
//not going to be able to synchronize on it |
| 2517 |
//In this model, CCA becomes busy when the aggregation of all signals as |
2506 |
//In this model, CCA becomes busy when the aggregation of all signals as |
|
|
| 2572 |
InterferenceHelper::SnrPer snrPer; |
2561 |
InterferenceHelper::SnrPer snrPer; |
| 2573 |
snrPer = m_interference.CalculatePlcpPayloadSnrPer (event); |
2562 |
snrPer = m_interference.CalculatePlcpPayloadSnrPer (event); |
| 2574 |
m_interference.NotifyRxEnd (); |
2563 |
m_interference.NotifyRxEnd (); |
|
|
2564 |
m_currentEvent = 0; |
| 2575 |
|
2565 |
|
| 2576 |
if (m_plcpSuccess == true) |
2566 |
if (m_plcpSuccess == true) |
| 2577 |
{ |
2567 |
{ |
|
|
| 3662 |
} |
3652 |
} |
| 3663 |
} |
3653 |
} |
| 3664 |
|
3654 |
|
|
|
3655 |
void |
| 3656 |
WifiPhy::AbortCurrentReception () |
| 3657 |
{ |
| 3658 |
NS_LOG_FUNCTION (this); |
| 3659 |
if (m_endPlcpRxEvent.IsRunning ()) |
| 3660 |
{ |
| 3661 |
m_endPlcpRxEvent.Cancel (); |
| 3662 |
} |
| 3663 |
if (m_endRxEvent.IsRunning ()) |
| 3664 |
{ |
| 3665 |
m_endRxEvent.Cancel (); |
| 3666 |
} |
| 3667 |
m_interference.NotifyRxEnd (); |
| 3668 |
m_state->SwitchFromRxAbort (); |
| 3669 |
m_currentEvent = 0; |
| 3670 |
} |
| 3671 |
|
| 3672 |
void |
| 3673 |
WifiPhy::StartRx (Ptr<Packet> packet, WifiTxVector txVector, MpduType mpdutype, double rxPowerW, Time rxDuration, Ptr<InterferenceHelper::Event> event) |
| 3674 |
{ |
| 3675 |
NS_LOG_FUNCTION (this << packet << txVector << (uint16_t)mpdutype << rxPowerW << rxDuration); |
| 3676 |
if (rxPowerW > GetEdThresholdW ()) //checked here, no need to check in the payload reception (current implementation assumes constant rx power over the packet duration) |
| 3677 |
{ |
| 3678 |
AmpduTag ampduTag; |
| 3679 |
WifiPreamble preamble = txVector.GetPreambleType (); |
| 3680 |
if (preamble == WIFI_PREAMBLE_NONE && (m_mpdusNum == 0 || m_plcpSuccess == false)) |
| 3681 |
{ |
| 3682 |
m_plcpSuccess = false; |
| 3683 |
m_mpdusNum = 0; |
| 3684 |
NS_LOG_DEBUG ("drop packet because no PLCP preamble/header has been received"); |
| 3685 |
NotifyRxDrop (packet); |
| 3686 |
MaybeCcaBusyDuration (); |
| 3687 |
return; |
| 3688 |
} |
| 3689 |
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0) |
| 3690 |
{ |
| 3691 |
//received the first MPDU in an MPDU |
| 3692 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 3693 |
m_rxMpduReferenceNumber++; |
| 3694 |
} |
| 3695 |
else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0) |
| 3696 |
{ |
| 3697 |
//received the other MPDUs that are part of the A-MPDU |
| 3698 |
if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1)) |
| 3699 |
{ |
| 3700 |
NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ()); |
| 3701 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 3702 |
} |
| 3703 |
else |
| 3704 |
{ |
| 3705 |
m_mpdusNum--; |
| 3706 |
} |
| 3707 |
} |
| 3708 |
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0) |
| 3709 |
{ |
| 3710 |
NS_LOG_DEBUG ("New A-MPDU started while " << m_mpdusNum << " MPDUs from previous are lost"); |
| 3711 |
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus (); |
| 3712 |
} |
| 3713 |
else if (preamble != WIFI_PREAMBLE_NONE && m_mpdusNum > 0 ) |
| 3714 |
{ |
| 3715 |
NS_LOG_DEBUG ("Didn't receive the last MPDUs from an A-MPDU " << m_mpdusNum); |
| 3716 |
m_mpdusNum = 0; |
| 3717 |
} |
| 3718 |
|
| 3719 |
NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)"); |
| 3720 |
m_currentEvent = event; |
| 3721 |
m_state->SwitchToRx (rxDuration); |
| 3722 |
NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); |
| 3723 |
NotifyRxBegin (packet); |
| 3724 |
m_interference.NotifyRxStart (); |
| 3725 |
|
| 3726 |
if (preamble != WIFI_PREAMBLE_NONE) |
| 3727 |
{ |
| 3728 |
NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); |
| 3729 |
Time preambleAndHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector); |
| 3730 |
m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &WifiPhy::StartReceivePacket, this, |
| 3731 |
packet, txVector, mpdutype, event); |
| 3732 |
} |
| 3733 |
|
| 3734 |
NS_ASSERT (m_endRxEvent.IsExpired ()); |
| 3735 |
m_endRxEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndReceive, this, |
| 3736 |
packet, preamble, mpdutype, event); |
| 3737 |
} |
| 3738 |
else |
| 3739 |
{ |
| 3740 |
NS_LOG_DEBUG ("drop packet because signal power too Small (" << |
| 3741 |
rxPowerW << "<" << GetEdThresholdW () << ")"); |
| 3742 |
NotifyRxDrop (packet); |
| 3743 |
m_plcpSuccess = false; |
| 3744 |
MaybeCcaBusyDuration (); |
| 3745 |
} |
| 3746 |
} |
| 3747 |
|
| 3665 |
int64_t |
3748 |
int64_t |
| 3666 |
WifiPhy::AssignStreams (int64_t stream) |
3749 |
WifiPhy::AssignStreams (int64_t stream) |
| 3667 |
{ |
3750 |
{ |