From 154f975857b1b881f52e40ac7399821bcb4add73 Mon Sep 17 00:00:00 2001 From: nina-grosheva Date: Thu, 18 Mar 2021 16:19:27 +0100 Subject: [PATCH] Minor fixes to the prerelease of v0.5 --- src/wifi/model/cbtraa-dmg-wifi-manager.cc | 8 +- src/wifi/model/cbtraa-dmg-wifi-manager.h | 2 +- src/wifi/model/codebook.cc | 8 +- src/wifi/model/codebook.h | 5 + .../constant-wifi-ack-policy-selector.cc | 42 +- src/wifi/model/dmg-wifi-mac.cc | 363 ++++++++---------- src/wifi/model/dmg-wifi-mac.h | 35 +- src/wifi/model/dmg-wifi-phy.cc | 4 +- src/wifi/model/ideal-dmg-wifi-manager.cc | 10 +- src/wifi/model/ideal-dmg-wifi-manager.h | 2 +- src/wifi/model/spectrum-dmg-wifi-phy.cc | 32 +- 11 files changed, 245 insertions(+), 266 deletions(-) diff --git a/src/wifi/model/cbtraa-dmg-wifi-manager.cc b/src/wifi/model/cbtraa-dmg-wifi-manager.cc index dabd9590..3fdf1387 100644 --- a/src/wifi/model/cbtraa-dmg-wifi-manager.cc +++ b/src/wifi/model/cbtraa-dmg-wifi-manager.cc @@ -152,16 +152,16 @@ CbtraaDmgWifiManager::DoReportRtsOk (WifiRemoteStation *st, void CbtraaDmgWifiManager::DoReportDataOk (WifiRemoteStation *st, double ackSnr, WifiMode ackMode, - double dataSnr, uint16_t dataChannelWidth, uint8_t) + double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss) { - NS_LOG_FUNCTION (this << st << ackSnr << ackMode.GetUniqueName () << dataSnr << dataChannelWidth); + NS_LOG_FUNCTION (this << st << ackSnr << ackMode.GetUniqueName () << dataSnr << dataChannelWidth << +dataNss); } void CbtraaDmgWifiManager::DoReportAmpduTxStatus (WifiRemoteStation *st, uint8_t nSuccessfulMpdus, - uint8_t nFailedMpdus, double rxSnr, double dataSnr) + uint8_t nFailedMpdus, double rxSnr, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss) { - NS_LOG_FUNCTION (this << st << +nSuccessfulMpdus << +nFailedMpdus << rxSnr << dataSnr); + NS_LOG_FUNCTION (this << st << +nSuccessfulMpdus << +nFailedMpdus << rxSnr << dataSnr << dataChannelWidth << +dataNss); } void diff --git a/src/wifi/model/cbtraa-dmg-wifi-manager.h b/src/wifi/model/cbtraa-dmg-wifi-manager.h index f926b510..b16b0108 100644 --- a/src/wifi/model/cbtraa-dmg-wifi-manager.h +++ b/src/wifi/model/cbtraa-dmg-wifi-manager.h @@ -57,7 +57,7 @@ class CbtraaDmgWifiManager : public WifiRemoteStationManager double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss); void DoReportAmpduTxStatus (WifiRemoteStation *station, uint8_t nSuccessfulMpdus, uint8_t nFailedMpdus, - double rxSnr, double dataSnr); + double rxSnr, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss); void DoReportFinalRtsFailed (WifiRemoteStation *station); void DoReportFinalDataFailed (WifiRemoteStation *station); WifiTxVector DoGetDataTxVector (WifiRemoteStation *station); diff --git a/src/wifi/model/codebook.cc b/src/wifi/model/codebook.cc index 0e365a05..b844cbdc 100644 --- a/src/wifi/model/codebook.cc +++ b/src/wifi/model/codebook.cc @@ -1256,8 +1256,8 @@ Codebook::GetSMBT_Subfields (Mac48Address from, std::vector antennaCa } m_mimoCombinations.push_back (newCombination); // Set the list of sectors that we want to train for each antenna - SetBeamformingSectorList (ReceiveSectorSweep, from, rxSectorCandidates); SetBeamformingSectorList (TransmitSectorSweep, from, txSectorCandidates); + SetBeamformingSectorList (ReceiveSectorSweep, from, rxSectorCandidates); // Count the number of subfields that we want to train uint16_t numberOfSubfields = CountMimoNumberOfSectors (rxSectorCandidates, m_useAWVsMimoBft); return numberOfSubfields; @@ -1505,4 +1505,10 @@ Codebook::GetTotalNumberOfReceiveSectorsOrAWVs (void) return CountMimoNumberOfSectors (m_rxBeamformingSectors, m_useAWVsMimoBft); } +Antenna2SectorList +Codebook::GetRxSectorsList (void) +{ + return m_rxBeamformingSectors; +} + } diff --git a/src/wifi/model/codebook.h b/src/wifi/model/codebook.h index 959a6497..9a15aae5 100644 --- a/src/wifi/model/codebook.h +++ b/src/wifi/model/codebook.h @@ -651,6 +651,11 @@ class Codebook : public Object * \param useAwvs */ void SetUseAWVsMimoBft (bool useAwvs); + /** + * Returns the list of the general receive sectors of the antenna. + * \return the list of general receive sectors + */ + Antenna2SectorList GetRxSectorsList (void); //// NINA //// private: diff --git a/src/wifi/model/constant-wifi-ack-policy-selector.cc b/src/wifi/model/constant-wifi-ack-policy-selector.cc index 8d05abd2..7f41f135 100644 --- a/src/wifi/model/constant-wifi-ack-policy-selector.cc +++ b/src/wifi/model/constant-wifi-ack-policy-selector.cc @@ -96,15 +96,25 @@ ConstantWifiAckPolicySelector::GetTemporaryParams (Ptr psdu, MacLowTra } // Worst case scenario we have to send a BlockAckRequest followed by a BlockAck. - if (m_qosTxop->GetBaBufferSize (receiver, tid) > 64) + //// WIGIG //// + if (m_qosTxop->IsEdmgSupported ()) { - NS_LOG_DEBUG ("Might need an Extended Compressed block ack request"); - tempParams.EnableBlockAckRequest (BlockAckType::EXTENDED_COMPRESSED_BLOCK_ACK); + NS_LOG_DEBUG ("Implicitly requesting an EDMG Compressed block ack"); + params.EnableBlockAck (BlockAckType::EDMG_COMPRESSED_BLOCK_ACK); } else + //// WIGIG //// { - NS_LOG_DEBUG ("Might need a Compressed block ack request"); - tempParams.EnableBlockAckRequest (BlockAckType::COMPRESSED_BLOCK_ACK); + if (m_qosTxop->GetBaBufferSize (receiver, tid) > 64) + { + NS_LOG_DEBUG ("Might need an Extended Compressed block ack request"); + tempParams.EnableBlockAckRequest (BlockAckType::EXTENDED_COMPRESSED_BLOCK_ACK); + } + else + { + NS_LOG_DEBUG ("Might need a Compressed block ack request"); + tempParams.EnableBlockAckRequest (BlockAckType::COMPRESSED_BLOCK_ACK); + } } return tempParams; } @@ -193,6 +203,28 @@ ConstantWifiAckPolicySelector::UpdateTxParams (Ptr psdu, MacLowTransmi { NS_LOG_DEBUG ("Scheduling a Compressed block ack request"); params.EnableBlockAckRequest (BlockAckType::COMPRESSED_BLOCK_ACK); + }//// WIGIG //// + if (m_qosTxop->IsEdmgSupported ()) + { + NS_LOG_DEBUG ("Implicitly requesting an EDMG Compressed block ack"); + params.EnableBlockAck (BlockAckType::EDMG_COMPRESSED_BLOCK_ACK); + } + else + //// WIGIG //// + { + // in case of single MPDU, there are previous unacknowledged frames, thus + // we cannot use Implicit Block Ack Request policy, otherwise we get a + // normal ack as response + if (m_qosTxop->GetBaBufferSize (receiver, tid) > 64) + { + NS_LOG_DEBUG ("Scheduling an Extended Compressed block ack request"); + params.EnableBlockAckRequest (BlockAckType::EXTENDED_COMPRESSED_BLOCK_ACK); + } + else + { + NS_LOG_DEBUG ("Scheduling a Compressed block ack request"); + params.EnableBlockAckRequest (BlockAckType::COMPRESSED_BLOCK_ACK); + } } return; } diff --git a/src/wifi/model/dmg-wifi-mac.cc b/src/wifi/model/dmg-wifi-mac.cc index 78765f56..186c8ab4 100644 --- a/src/wifi/model/dmg-wifi-mac.cc +++ b/src/wifi/model/dmg-wifi-mac.cc @@ -2255,30 +2255,20 @@ DmgWifiMac::SendMimoBrpFrame (Mac48Address receiver, BRP_Request_Field &requestF /* Set the best sector for transmission with this station */ - if (receiver != GetAddress ()) + /* MIMO BRP packets are send with spatial expansion and mapping a single stream across all transmit chains */ + m_codebook->SetCommunicationMode (MIMO_MODE); + for (auto const &txConfig : m_mimoConfigTraining) { - ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[receiver]); - m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); - NS_LOG_INFO ("Sending MIMO BRP Frame to " << receiver << " at " << Simulator::Now () - << " with AntennaID=" << static_cast (antennaConfigTx.first) - << " SectorID=" << static_cast (antennaConfigTx.second)); - } - else - { - /* During the MIMO phase training for MU-MIMO we send frames with spatial expansion in order to be able to reach all responders */ - m_codebook->SetCommunicationMode (MIMO_MODE); - for (auto const &txConfig : m_mimoConfigTraining) + NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (txConfig.first.first) + << ", to SectorID=" << static_cast (txConfig.first.second) + << ", AwvID=" << static_cast (txConfig.second)); + m_codebook->SetActiveTxSectorID (txConfig.first.first, txConfig.first.second); + if (txConfig.second != NO_AWV_ID) { - NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (txConfig.first.first) - << ", to SectorID=" << static_cast (txConfig.first.second) - << ", AwvID=" << static_cast (txConfig.second)); - m_codebook->SetActiveTxSectorID (txConfig.first.first, txConfig.first.second); - if (txConfig.second != NO_AWV_ID) - { - m_codebook->SetActiveTxAwvID (txConfig.second); - } + m_codebook->SetActiveTxAwvID (txConfig.second); } } + NS_LOG_INFO ("Sending MIMO BRP Frame to " << receiver << " at " << Simulator::Now ()); /* Transmit control frames directly without DCA + DCF Manager */ TransmitControlFrameImmediately (packet, hdr, MicroSeconds (0)); } @@ -2320,12 +2310,29 @@ DmgWifiMac::SendFeedbackMimoBrpFrame (Mac48Address receiver, BRP_Request_Field & packet->AddHeader (actionHdr); /* Set the best sector for transmission with this station */ - ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[receiver]); - m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); + if (m_muMimoBfPhase != MU_SISO_FBCK) + { + /* MIMO BRP packets are send with spatial expansion and mapping a single stream across all transmit chains */ + m_codebook->SetCommunicationMode (MIMO_MODE); + for (auto const &txConfig : m_mimoConfigTraining) + { + NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (txConfig.first.first) + << ", to SectorID=" << static_cast (txConfig.first.second) + << ", AwvID=" << static_cast (txConfig.second)); + m_codebook->SetActiveTxSectorID (txConfig.first.first, txConfig.first.second); + if (txConfig.second != NO_AWV_ID) + { + m_codebook->SetActiveTxAwvID (txConfig.second); + } + } + } + else + { + ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[receiver]); + m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); + } - NS_LOG_INFO ("Sending MIMO BRP Frame with Feedback to " << receiver << " at " << Simulator::Now () - << " with AntennaID=" << static_cast (antennaConfigTx.first) - << " SectorID=" << static_cast (antennaConfigTx.second)); + NS_LOG_INFO ("Sending MIMO BRP Frame with Feedback to " << receiver << " at " << Simulator::Now ()); /* Transmit control frames directly without DCA + DCF Manager */ TransmitControlFrameImmediately (packet, hdr, MicroSeconds (0)); @@ -2607,6 +2614,14 @@ DmgWifiMac::StartSuMimoBeamforming (Mac48Address responder, bool isBrpTxssNeeded m_codebook->SetUseAWVsMimoBft (useAwvs); } m_low->MIMO_BFT_Phase_Started (); + // Set the antenna configuration to be used for transmitting BRP frames with spatial expansion - we use the optimal configuration for the user with all antennas + for (auto & antenna: antennaIds) + { + ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[responder]); + ANTENNA_CONFIGURATION config = std::make_pair (antenna, antennaConfigTx.second); + AWV_CONFIGURATION pattern = std::make_pair (config, NO_AWV_ID); + m_mimoConfigTraining.push_back (pattern); + } if (isBrpTxssNeeded) StartMimoBrpTxssSetup (responder, antennaIds); else @@ -2874,10 +2889,18 @@ DmgWifiMac::StartSuMimoMimoPhase (Mac48Address from, MIMO_ANTENNA_COMBINATIONS_L * each other, on the Rx side the measurements done at an Rx antenna are completely independent of the antenna configuration of the second * antenna, allowing us to reduce the training time by only testing each combination once and determing all possible combinations in postprocessing * by combining the measurements */ + bool trainAllRxSectors = true; Antenna2SectorList rxCandidateSectors; - for (auto antenna : candidateAntennas) + if (trainAllRxSectors) { - rxCandidateSectors[antenna] = rxSectors; + rxCandidateSectors = m_codebook->GetRxSectorsList (); + } + else + { + for (auto antenna : candidateAntennas) + { + rxCandidateSectors[antenna] = rxSectors; + } } m_suMimomMimoCandidatesSelected (from, candidateSectors, rxCandidateSectors); double numberOfSubfields = m_codebook->GetSMBT_Subfields (from, candidateAntennas, candidateSectors, rxCandidateSectors); @@ -2937,12 +2960,21 @@ DmgWifiMac::SendSuMimoSetupFrame (void) packet->AddHeader (actionHdr); /* Set the best sector for transmission with this station */ - ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[m_peerStation]); - m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); + /* MIMO BF setup packets are send with spatial expansion and mapping a single stream across all transmit chains */ + m_codebook->SetCommunicationMode (MIMO_MODE); + for (auto const &txConfig : m_mimoConfigTraining) + { + NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (txConfig.first.first) + << ", to SectorID=" << static_cast (txConfig.first.second) + << ", AwvID=" << static_cast (txConfig.second)); + m_codebook->SetActiveTxSectorID (txConfig.first.first, txConfig.first.second); + if (txConfig.second != NO_AWV_ID) + { + m_codebook->SetActiveTxAwvID (txConfig.second); + } + } - NS_LOG_INFO ("Sending MIMO BF Setup frame to " << m_peerStation << " at " << Simulator::Now () - << " with AntennaID=" << static_cast (antennaConfigTx.first) - << " SectorID=" << static_cast (antennaConfigTx.second)); + NS_LOG_INFO ("Sending MIMO BF Setup frame to " << m_peerStation << " at " << Simulator::Now ()); /* Transmit control frames directly without TXOP + Channel Access Manager */ TransmitControlFrameImmediately (packet, hdr, MicroSeconds (0)); @@ -3143,12 +3175,21 @@ DmgWifiMac::SendSuMimoBfFeedbackFrame (void) packet->AddHeader (actionHdr); /* Set the best sector for transmission with this station */ - ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[m_peerStation]); - m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); + /* MIMO BF Feedback packets are send with spatial expansion and mapping a single stream across all transmit chains */ + m_codebook->SetCommunicationMode (MIMO_MODE); + for (auto const &txConfig : m_mimoConfigTraining) + { + NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (txConfig.first.first) + << ", to SectorID=" << static_cast (txConfig.first.second) + << ", AwvID=" << static_cast (txConfig.second)); + m_codebook->SetActiveTxSectorID (txConfig.first.first, txConfig.first.second); + if (txConfig.second != NO_AWV_ID) + { + m_codebook->SetActiveTxAwvID (txConfig.second); + } + } - NS_LOG_INFO ("Sending MIMO BF Feedback frame to " << m_peerStation - << " with AntennaID=" << static_cast (antennaConfigTx.first) - << " SectorID=" << static_cast (antennaConfigTx.second)); + NS_LOG_INFO ("Sending MIMO BF Feedback frame to " << m_peerStation); /* Transmit control frames directly without DCA + DCF Manager */ TransmitControlFrameImmediately (packet, hdr, MicroSeconds (0)); @@ -3351,150 +3392,6 @@ DmgWifiMac::FindKBestCombinations (uint16_t k, uint8_t numberOfStreams, uint8_t return kBestCombinations; } -MIMO_ANTENNA_COMBINATIONS_LIST -DmgWifiMac::FindKBestCombinations2x2MIMO (uint8_t k, MIMO_FEEDBACK_MAP &feedback) -{ - // Make a multi map with the SNR as key and sort it in descending order. -// SU_MIMO_FEEDBACK_SORTED_MAP sortedFeedback; -// for (SU_MIMO_FEEDBACK_MAP::iterator it = feedback.begin (); it != feedback.end (); it++) -// { -// sortedFeedback.insert (std::make_pair (it->second, it->first)); -// } - - MIMO_FEEDBACK_SORTED_MAPS combinations; - // Split the map into different maps according to the TX-RX Combinations. - for (int i = 0; i < 4; i++) - { - MIMO_FEEDBACK_SORTED_MAP TxRxCombination; - TX_ANTENNA_ID txId = std::get<0> (feedback.begin ()->first); - RX_ANTENNA_ID rxId = std::get<1> (feedback.begin ()->first); - for (MIMO_FEEDBACK_MAP::iterator it = feedback.begin (); it != feedback.end ();) - { - if ((std::get<0> (it->first) == txId) && (std::get<1> (it->first) == rxId)) - { - TxRxCombination.insert (std::make_pair (it->second, it->first)); - feedback.erase (it++); - } - else - { - ++it; - } - } - combinations.push_back (TxRxCombination); - } - - // Keep only the top K measurements for each tx-rx combination in order to reduce the number of calculations. - for (MIMO_FEEDBACK_SORTED_MAPS_I it = combinations.begin (); it!= combinations.end (); it++) - { - if ((*it).size () > k) - { - MIMO_FEEDBACK_SORTED_MAP_I iter = it->begin (); - std::advance (iter, k); - (*it).erase (iter, it->end ()); - } - } - - // Find all candidates of different Tx-Rx combinations and place them in a multimap sorted in desceding joint SNR order. - MIMO_CANDIDATE_MAP candidateCombinations; - for (MIMO_FEEDBACK_SORTED_MAPS_I it = combinations.begin (); it!= combinations.end (); it++) - { - bool foundNewConfig = false; - MIMO_FEEDBACK_SORTED_MAPS_I insideIt = it; - insideIt++; - while (!foundNewConfig) - { - if ((std::get<0> (insideIt->begin ()->second) != std::get<0> (it->begin ()->second)) - && (std::get<1> (insideIt->begin ()->second) != std::get<1> (it->begin ()->second))) - foundNewConfig = true; - else - insideIt++; - } - for (MIMO_FEEDBACK_SORTED_MAP_I MapIt = it->begin (); MapIt != it->end (); MapIt++) - { - MIMO_FEEDBACK_CONFIGURATION candidate1 = MapIt->second; - SNR combinationSnr = 0; - for (MIMO_FEEDBACK_SORTED_MAP_I insideMapIt = insideIt->begin (); - insideMapIt != insideIt->end (); insideMapIt++) - { - MIMO_FEEDBACK_COMBINATION combination; - combination.push_back (candidate1); - combination.push_back (insideMapIt->second); - combinationSnr = MapIt->first + insideMapIt->first; - candidateCombinations.insert (std::make_pair (combinationSnr, combination)); - } - } - combinations.erase (insideIt); - } - - // Create a list of the K best combinations according to the highest joint SNR, making sure to not have any duplicate combinations. - MIMO_ANTENNA_COMBINATIONS_LIST kBestCombinations; - for (MIMO_CANDIDATE_MAP_I it = candidateCombinations.begin (); it != candidateCombinations.end (); it++) - { - MIMO_ANTENNA_COMBINATION combinaton1; - MIMO_ANTENNA_COMBINATION combinaton2; - - ANTENNA_CONFIGURATION config1 = std::make_pair (std::get<0> (it->second.at (0)), std::get<2> (it->second.at (0))); - ANTENNA_CONFIGURATION config2 = std::make_pair (std::get<0> (it->second.at (1)), std::get<2> (it->second.at (1))); - - combinaton1.push_back (config1); - combinaton1.push_back (config2); - combinaton2.push_back (config2); - combinaton2.push_back (config1); - - MIMO_ANTENNA_COMBINATIONS_LIST::iterator sameConfig1 = std::find (kBestCombinations.begin (), kBestCombinations.end (), combinaton1); - MIMO_ANTENNA_COMBINATIONS_LIST::iterator sameConfig2 = std::find (kBestCombinations.begin (), kBestCombinations.end (), combinaton2); - - if ((sameConfig1 == kBestCombinations.end ()) && (sameConfig2 == kBestCombinations.end ())) - { - std::sort (combinaton1.begin (), combinaton1. end ()); - kBestCombinations.push_back (combinaton1); - } - if (kBestCombinations.size () == k) - break; - } - - return kBestCombinations; -} - -std::vector -DmgWifiMac::FindBestTxCombinations2x2MIMO (uint8_t numberOfTxCombinations, uint16_t rxCombinationsTested, MIMO_SNR_LIST measurements) -{ - std::vector minSnr; - std::vector bestCombinations; - uint16_t txCombinationsTested = measurements.size () / (rxCombinationsTested); - MIMO_SNR_LIST_I it = measurements.begin (); - MIMO_SNR_LIST_I insideIt = measurements.begin (); - MIMO_SNR_LIST_I txStartIt = measurements.begin (); - for (uint16_t i = 0; i < txCombinationsTested; i++) - { - txStartIt = it; - for (uint16_t j = 0; j < (rxCombinationsTested); j++) - { - insideIt = txStartIt; - for (uint16_t k = 0; k < (rxCombinationsTested); k++) - { - double min1 = std::min (it->second.at (0), insideIt->second.at (3)); - double min2 = std::min (insideIt->second.at (1), it->second.at (2)); - minSnr.push_back (std::max (min1, min2)); - insideIt++; - } - it++; - } - } - for (uint8_t i = 0; i < numberOfTxCombinations; i++) - { - uint32_t maxElement = std::distance (minSnr.begin (), std::max_element (minSnr.begin (), minSnr.end ())) + 1; - for (auto &combinations : bestCombinations) - { - if (maxElement >= combinations) - maxElement++; - } - bestCombinations.push_back (maxElement); - minSnr.erase (minSnr.begin () + std::distance (minSnr.begin (), std::max_element (minSnr.begin (), minSnr.end ()))); - } - return bestCombinations; -} - BEST_TX_COMBINATIONS_AWV_IDS DmgWifiMac::FindBestTxCombinations (uint8_t nBestCombinations, uint16_t rxCombinationsTested, uint8_t nTxAntennas, uint8_t nRxAntennas, MIMO_SNR_LIST measurements, bool differentRxCombinations) @@ -4120,12 +4017,24 @@ DmgWifiMac::SendMuMimoSetupFrame (void) /* For now we transmit as many setup frames as there are users in the MIMO group using the optimal sectors for each user. * Should be optimized in the future if multiple STAs can receive frames send with the same Tx sector. */ - ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[m_aidMap[*m_currentMuGroupMember]]); - m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); + /* MIMO BF setup packets are send with spatial expansion and mapping a single stream across all transmit chains */ + m_codebook->SetCommunicationMode (MIMO_MODE); + for (auto const &antenna : m_codebook->GetTotalAntennaIdList ()) + { + ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[m_aidMap[*m_currentMuGroupMember]]); + ANTENNA_CONFIGURATION config = std::make_pair (antenna, antennaConfigTx.second); + AWV_CONFIGURATION pattern = std::make_pair (config, NO_AWV_ID); + NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (pattern.first.first) + << ", to SectorID=" << static_cast (pattern.first.second) + << ", AwvID=" << static_cast (pattern.second)); + m_codebook->SetActiveTxSectorID (pattern.first.first, pattern.first.second); + if (pattern.second != NO_AWV_ID) + { + m_codebook->SetActiveTxAwvID (pattern.second); + } + } - NS_LOG_INFO ("Sending broadcast MIMO BF Setup frame at " << Simulator::Now () - << " with AntennaID=" << static_cast (antennaConfigTx.first) - << " SectorID=" << static_cast (antennaConfigTx.second)); + NS_LOG_INFO ("Sending broadcast MIMO BF Setup frame at " << Simulator::Now ()); /* Transmit control frames directly without DCA + DCF Manager */ TransmitControlFrameImmediately (packet, hdr, MicroSeconds (0)); @@ -4271,12 +4180,21 @@ DmgWifiMac::SendMimoBfPollFrame (void) packet->AddHeader (actionHdr); /* Set the best sector for transmission with this station */ - ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[receiver]); - m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); + /* MIMO BF poll packets are send with spatial expansion and mapping a single stream across all transmit chains */ + m_codebook->SetCommunicationMode (MIMO_MODE); + for (auto const &txConfig : m_mimoConfigTraining) + { + NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (txConfig.first.first) + << ", to SectorID=" << static_cast (txConfig.first.second) + << ", AwvID=" << static_cast (txConfig.second)); + m_codebook->SetActiveTxSectorID (txConfig.first.first, txConfig.first.second); + if (txConfig.second != NO_AWV_ID) + { + m_codebook->SetActiveTxAwvID (txConfig.second); + } + } - NS_LOG_INFO ("Sending MIMO BF Poll frame to " << receiver << " at " << Simulator::Now () - << " with AntennaID=" << static_cast (antennaConfigTx.first) - << " SectorID=" << static_cast (antennaConfigTx.second)); + NS_LOG_INFO ("Sending MIMO BF Poll frame to " << receiver << " at " << Simulator::Now ()); /* Transmit control frames directly without DCA + DCF Manager */ TransmitControlFrameImmediately (packet, hdr, MicroSeconds (0)); @@ -4403,13 +4321,21 @@ DmgWifiMac::SendMuMimoBfFeedbackFrame (Mac48Address station) packet->AddHeader (actionHdr); /* Set the best sector for transmission with this station */ - ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[station]); - m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); - - NS_LOG_INFO ("Sending MIMO BF Feedback frame to " << station - << " with AntennaID=" << static_cast (antennaConfigTx.first) - << " SectorID=" << static_cast (antennaConfigTx.second)); + /* MIMO BF Feedback packets are send with spatial expansion and mapping a single stream across all transmit chains */ + m_codebook->SetCommunicationMode (MIMO_MODE); + for (auto const &txConfig : m_mimoConfigTraining) + { + NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (txConfig.first.first) + << ", to SectorID=" << static_cast (txConfig.first.second) + << ", AwvID=" << static_cast (txConfig.second)); + m_codebook->SetActiveTxSectorID (txConfig.first.first, txConfig.first.second); + if (txConfig.second != NO_AWV_ID) + { + m_codebook->SetActiveTxAwvID (txConfig.second); + } + } + NS_LOG_INFO ("Sending MIMO BF Feedback frame to " << station << " at " << Simulator::Now ()); /* Transmit control frames directly without DCA + DCF Manager */ TransmitControlFrameImmediately (packet, hdr, MicroSeconds (0)); } @@ -4497,13 +4423,26 @@ DmgWifiMac::SendMuMimoBfSelectionFrame (void) packet->AddHeader (selectionFrame); packet->AddHeader (actionHdr); - /* Set the best sector for transmission with this station */ - ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[m_aidMap[*m_currentMuGroupMember]]); - m_codebook->SetActiveTxSectorID (antennaConfigTx.first, antennaConfigTx.second); + /* For now we transmit as many setup frames as there are users in the MIMO group using the optimal sectors for each user. + * Should be optimized in the future if multiple STAs can receive frames send with the same Tx sector. */ + /* MIMO BF Selection packets are send with spatial expansion and mapping a single stream across all transmit chains */ + m_codebook->SetCommunicationMode (MIMO_MODE); + for (auto const &antenna : m_codebook->GetCurrentMimoAntennaIdList ()) + { + ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[m_aidMap[*m_currentMuGroupMember]]); + ANTENNA_CONFIGURATION config = std::make_pair (antenna, antennaConfigTx.second); + AWV_CONFIGURATION pattern = std::make_pair (config, NO_AWV_ID); + NS_LOG_DEBUG ("Activate Transmit Antenna with AntennaID=" << static_cast (pattern.first.first) + << ", to SectorID=" << static_cast (pattern.first.second) + << ", AwvID=" << static_cast (pattern.second)); + m_codebook->SetActiveTxSectorID (pattern.first.first, pattern.first.second); + if (pattern.second != NO_AWV_ID) + { + m_codebook->SetActiveTxAwvID (pattern.second); + } + } - NS_LOG_INFO ("Sending broadcast MIMO BF Selection frame at " << Simulator::Now () - << " with AntennaID=" << static_cast (antennaConfigTx.first) - << " SectorID=" << static_cast (antennaConfigTx.second)); + NS_LOG_INFO ("Sending broadcast MIMO BF Selection frame at " << Simulator::Now ()); /* Transmit control frames directly without DCA + DCF Manager */ TransmitControlFrameImmediately (packet, hdr, MicroSeconds (0)); @@ -5201,6 +5140,7 @@ DmgWifiMac::FrameTxOkSuMimoBFT (const WifiMacHeader &hdr) m_codebook->SetReceivingInQuasiOmniMode (); m_dataCommunicationModeTable[hdr.GetAddr1 ()] = DATA_MODE_SU_MIMO; m_low->MIMO_BFT_Phase_Ended (); + m_mimoConfigTraining.clear (); m_suMimoMimoPhaseComplete (hdr.GetAddr1 ()); } } @@ -5335,6 +5275,7 @@ DmgWifiMac::FrameTxOkMuMimoBFT (const WifiMacHeader &hdr) GetDmgWifiPhy ()->SetMuMimoBeamformingTraining (false); m_muMimoBfPhase = MU_WAIT_MU_MIMO_BF_TRAINING; m_codebook->SetReceivingInQuasiOmniMode (); + m_mimoConfigTraining.clear (); for (auto user : m_edmgMuGroup.aidList) { m_dataCommunicationModeTable[m_aidMap[user]] = DATA_MODE_MU_MIMO; @@ -5688,6 +5629,13 @@ DmgWifiMac::Receive (Ptr mpdu) // Get a list of the antenna IDs of all the antennas in the codebook. std::vector antennaIds = m_codebook->GetTotalAntennaIdList (); edmgReplyRequestElement.SetTX_Antenna_Mask (antennaIds); + for (auto & antenna: antennaIds) + { + ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[from]); + ANTENNA_CONFIGURATION config = std::make_pair (antenna, antennaConfigTx.second); + AWV_CONFIGURATION pattern = std::make_pair (config, NO_AWV_ID); + m_mimoConfigTraining.push_back (pattern); + } /* Set up the antenna combinations to test in each packet of the MIMO BRP TXSS and calculate * the number of MIMO BRP TXSS packets that we need if there are multiple antennas which are connected * to the same RF Chain we need multiple BRP packets to train them, otherwise we just need one. */ @@ -6040,6 +5988,13 @@ DmgWifiMac::Receive (Ptr mpdu) // for now we train all receive sectors - can't choose candidates since no UL training was done in the SISO phase. bool firstCombination = true; m_codebook->InitializeMimoSectorSweeping (from, ReceiveSectorSweep, firstCombination); + for (auto & antenna: m_codebook->GetTotalAntennaIdList ()) + { + ANTENNA_CONFIGURATION_TX antennaConfigTx = std::get<0> (m_bestAntennaConfig[from]); + ANTENNA_CONFIGURATION config = std::make_pair (antenna, antennaConfigTx.second); + AWV_CONFIGURATION pattern = std::make_pair (config, NO_AWV_ID); + m_mimoConfigTraining.push_back (pattern); + } } } return; @@ -6162,6 +6117,7 @@ DmgWifiMac::Receive (Ptr mpdu) m_codebook->SetReceivingInQuasiOmniMode (); m_dataCommunicationModeTable[from] = DATA_MODE_SU_MIMO; m_low->MIMO_BFT_Phase_Ended (); + m_mimoConfigTraining.clear (); m_suMimoMimoPhaseComplete (from); } else if (m_muMimoBeamformingTraining) @@ -6243,6 +6199,7 @@ DmgWifiMac::Receive (Ptr mpdu) m_muMimoBfPhase = MU_WAIT_MU_MIMO_BF_TRAINING; m_codebook->SetReceivingInQuasiOmniMode (); m_dataCommunicationModeTable[from] = DATA_MODE_MU_MIMO; + m_mimoConfigTraining.clear (); m_low->MIMO_BFT_Phase_Ended (); m_muMimoMimoPhaseComplete (); } diff --git a/src/wifi/model/dmg-wifi-mac.h b/src/wifi/model/dmg-wifi-mac.h index 657161d7..9be04990 100644 --- a/src/wifi/model/dmg-wifi-mac.h +++ b/src/wifi/model/dmg-wifi-mac.h @@ -588,8 +588,6 @@ class DmgWifiMac : public RegularWifiMac * \param responder The MAC address of the STA that we are beamforming training with. */ void StartSuSisoFeedback (Mac48Address responder, std::vector antennaIds ); - //// NINA //// - /** * Starts the MIMO BRP TXSS after the setup procedure has been completed, as part of the SISO SU-MIMO phase. */ @@ -609,7 +607,6 @@ class DmgWifiMac : public RegularWifiMac * \param address The MAC address of the peer station. */ void SendSuMimoTxssFeedback (void); - //// NINA //// /** * \brief StartSuMimoMimoPhase * Starts the MIMO phase of SU-MIMO BFT. Receives a list of Tx candidates to try out which was generated based on the feedback @@ -620,7 +617,6 @@ class DmgWifiMac : public RegularWifiMac **/ void StartSuMimoMimoPhase (Mac48Address from, MIMO_ANTENNA_COMBINATIONS_LIST candidates, uint8_t txCombinationsRequested, bool useAwvs = true); - //// NINA //// /** * \brief SendSuMimoSetupFrame * Sends a MIMO BF Setup Frame to the peer station, specifying the requested parameters for the MIMO @@ -682,33 +678,6 @@ class DmgWifiMac : public RegularWifiMac */ MIMO_ANTENNA_COMBINATIONS_LIST FindKBestCombinations (uint16_t k, uint8_t numberOfStreams, uint8_t numberOfRxAntennas, MIMO_FEEDBACK_MAP feedback); - /** - * From a given feedback with measurements from the SISO phase of SU-MIMO Beamforming training for a 2x2 MIMO configuration - * find the K best candidates to test in the MIMO phase. - * \param k The number of candidates to test. - * \param feedback The feedback Map that contains all the measurements done in the SISO phase. - * \return A list of K best combinations of antenna configurations to test in the MIMO phase. - */ - static MIMO_ANTENNA_COMBINATIONS_LIST FindKBestCombinations2x2MIMO (uint8_t k, MIMO_FEEDBACK_MAP &feedback); - //// NINA //// - /** - * From a given measurement list from the MIMO phase of SU-MIMO Beamforming training find the best combinations (according to the - * number of requested combinations) to feedback to the peer station - * \param numberOfTxCombinations The number of combinations the peer station has requested to feedback. - * \param measurements The measurement list that contains all the measurements done in the MIMO phase. - * \return A list of numberOfTxCombinations measurements taken during the MIMO phase. - */ - static std::vector FindBestTxCombinations2x2MIMO (uint8_t numberOfTxCombinations, uint16_t rxCombinationsTested, - MIMO_SNR_LIST measurements); - /** - * From a given measurement list from the MIMO phase of SU-MIMO Beamforming training find the best combinations (according to the - * number of requested combinations) to feedback to the peer station - * \param numberOfTxCombinations The number of combinations the peer station has requested to feedback. - * \param measurements The measurement list that contains all the measurements done in the MIMO phase. - * \return A list of numberOfTxCombinations measurements taken during the MIMO phase. - */ - static std::vector > FindBestTxCombinationsMuMimo (uint8_t nBestCombinations, uint16_t rxCombinationsTested, - uint8_t nTxAntennas, uint8_t nRxAntennas, MIMO_SNR_LIST measurements); /** * From a given measurement list from the MIMO phase of MIMO Beamforming training find the best combinations (according to the * number of requested combinations) to feedback to the peer station. @@ -733,7 +702,6 @@ class DmgWifiMac : public RegularWifiMac * \return The Tx ID associated with the optimal antenna configuration. */ MIMO_FEEDBACK_COMBINATION FindOptimalMuMimoConfig (uint8_t nTx, uint8_t nRx, MIMO_FEEDBACK_MAP feedback, std::vector txAwvIds); - //// NINA //// /** * Get the current communication mode with the station (SISO, SU-MIMO or MU-MIMO) from the Data Communication * Mode table. In case there is no entry for the station the default mode is SISO. @@ -748,7 +716,7 @@ class DmgWifiMac : public RegularWifiMac * \return The number of streams that can be used for communication with the station. */ uint8_t GetStationNStreams (Mac48Address station); - + //// NINA //// /* EDMG MU-MIMO Beamforming functions */ //// NINA //// /** @@ -848,6 +816,7 @@ class DmgWifiMac : public RegularWifiMac * Returns the last EDMG Group ID set element that was send. */ Ptr GetEdmgGroupIdSetElement (void) const; + //// NINA //// protected: friend class MacLow; diff --git a/src/wifi/model/dmg-wifi-phy.cc b/src/wifi/model/dmg-wifi-phy.cc index 1c85fb98..27a2a979 100644 --- a/src/wifi/model/dmg-wifi-phy.cc +++ b/src/wifi/model/dmg-wifi-phy.cc @@ -1716,13 +1716,13 @@ DmgWifiPhy::StartReceivePreamble (Ptr ppdu, std::vector rxPowe * based on the maximum Rx power */ NS_LOG_INFO ("Receiving packet in MIMO mode"); rxPowerW = *(std::max_element (rxPowerList.begin (), rxPowerList.end ())); - /* During MU-MIMO BFT we transmit packets using multiple transmit chains and applying a spatial + /* During MIMO BFT we transmit packets using multiple transmit chains and applying a spatial * expansion with cyclic shift diversity - for now we model this by assuming the transmission is * equal to a SISO transmission using the * maximum Rx Power, since we are able decode the strongest path and remove the interference from * the other Tx antennas */ - if (m_muMimoBeamformingTraining) + if (txVector.Get_NUM_STS () == 1) event = m_interference.Add (ppdu, txVector, rxDuration, rxPowerW); else event = m_interference.Add (ppdu, txVector, rxDuration, rxPowerW, rxPowerList); diff --git a/src/wifi/model/ideal-dmg-wifi-manager.cc b/src/wifi/model/ideal-dmg-wifi-manager.cc index 05aecec2..c2d098b3 100644 --- a/src/wifi/model/ideal-dmg-wifi-manager.cc +++ b/src/wifi/model/ideal-dmg-wifi-manager.cc @@ -172,9 +172,9 @@ IdealDmgWifiManager::DoReportRtsOk (WifiRemoteStation *st, void IdealDmgWifiManager::DoReportDataOk (WifiRemoteStation *st, double ackSnr, WifiMode ackMode, - double dataSnr, uint16_t dataChannelWidth, uint8_t) + double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss) { - NS_LOG_FUNCTION (this << st << ackSnr << ackMode.GetUniqueName () << dataSnr << dataChannelWidth); + NS_LOG_FUNCTION (this << st << ackSnr << ackMode.GetUniqueName () << dataSnr << dataChannelWidth << +dataNss); IdealDmgWifiRemoteStation *station = static_cast (st); if (dataSnr == 0) { @@ -186,9 +186,9 @@ IdealDmgWifiManager::DoReportDataOk (WifiRemoteStation *st, double ackSnr, WifiM void IdealDmgWifiManager::DoReportAmpduTxStatus (WifiRemoteStation *st, uint8_t nSuccessfulMpdus, - uint8_t nFailedMpdus, double rxSnr, double dataSnr) + uint8_t nFailedMpdus, double rxSnr, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss) { - NS_LOG_FUNCTION (this << st << +nSuccessfulMpdus << +nFailedMpdus << rxSnr << dataSnr); + NS_LOG_FUNCTION (this << st << +nSuccessfulMpdus << +nFailedMpdus << rxSnr << dataSnr << dataChannelWidth << +dataNss); IdealDmgWifiRemoteStation *station = static_cast (st); if (dataSnr == 0) { @@ -203,6 +203,7 @@ IdealDmgWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *station) { NS_LOG_FUNCTION (this << station); Reset (station); + m_mcsChanged (station->m_state->m_address, GetDefaultMode ().GetMcsValue ()); } void @@ -210,6 +211,7 @@ IdealDmgWifiManager::DoReportFinalDataFailed (WifiRemoteStation *station) { NS_LOG_FUNCTION (this << station); Reset (station); + m_mcsChanged (station->m_state->m_address, GetDefaultMode ().GetMcsValue ()); } WifiTxVector diff --git a/src/wifi/model/ideal-dmg-wifi-manager.h b/src/wifi/model/ideal-dmg-wifi-manager.h index d710136a..e5ffb171 100644 --- a/src/wifi/model/ideal-dmg-wifi-manager.h +++ b/src/wifi/model/ideal-dmg-wifi-manager.h @@ -71,7 +71,7 @@ class IdealDmgWifiManager : public WifiRemoteStationManager double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss); void DoReportAmpduTxStatus (WifiRemoteStation *station, uint8_t nSuccessfulMpdus, uint8_t nFailedMpdus, - double rxSnr, double dataSnr); + double rxSnr, double dataSnr, uint16_t dataChannelWidth, uint8_t dataNss); void DoReportFinalRtsFailed (WifiRemoteStation *station); void DoReportFinalDataFailed (WifiRemoteStation *station); WifiTxVector DoGetDataTxVector (WifiRemoteStation *station); diff --git a/src/wifi/model/spectrum-dmg-wifi-phy.cc b/src/wifi/model/spectrum-dmg-wifi-phy.cc index ce34373b..bccf89dc 100644 --- a/src/wifi/model/spectrum-dmg-wifi-phy.cc +++ b/src/wifi/model/spectrum-dmg-wifi-phy.cc @@ -34,6 +34,7 @@ #include "wifi-utils.h" #include "wifi-ppdu.h" #include "wifi-psdu.h" +#include namespace ns3 { @@ -251,7 +252,21 @@ SpectrumDmgWifiPhy::StartRx (Ptr rxParams) uint16_t channelWidth = GetChannelWidth (); Ptr filter = WifiSpectrumValueHelper::CreateRfFilter (GetFrequency (), channelWidth, WIGIG_OFDM_SUBCARRIER_SPACING, GetGuardBandwidth ()); - double rxPowerW = FilterSignal (filter, receivedSignalPsd); + double rxPowerW; + std::vector rxPowerList; + if (rxParams->psdList.size () > 0) + { + for (auto &psd : rxParams->psdList) + { + rxPowerList.push_back (FilterSignal (filter, psd)); + } + rxPowerW = *std::max_element(rxPowerList.begin (), rxPowerList.end ()); + } + else + { + rxPowerW = FilterSignal (filter, receivedSignalPsd); + rxPowerList.push_back (rxPowerW); + } /* MIMO calculation */ // std::cout << "SISO: " << WToDbm (rxPowerW) << std::endl; @@ -294,18 +309,11 @@ SpectrumDmgWifiPhy::StartRx (Ptr rxParams) if (rxParams->psdList.size () > 0) { NS_LOG_INFO ("Received EDMG WiFi signal in MIMO mode"); - std::vector rxPowerList; - for (auto &psd : rxParams->psdList) - { - rxPowerList.push_back (FilterSignal (filter, psd)); - } StartReceivePreamble (ppdu, rxPowerList); } else { NS_LOG_INFO ("Received EDMG WiFi signal in SISO mode"); - std::vector rxPowerList; - rxPowerList.push_back (rxPowerW); StartReceivePreamble (ppdu, rxPowerList); } } @@ -329,12 +337,12 @@ SpectrumDmgWifiPhy::StartRx (Ptr rxParams) if (rxParams->psdList.size () > 0) { NS_LOG_INFO ("Received EDMG WiFi TRN-SF signal in MIMO mode"); - std::vector rxPowerList; - for (auto &psd : rxParams->psdList) + std::vector rxPowerListDbm; + for (auto &rxPower : rxPowerList) { - rxPowerList.push_back (WToDbm (FilterSignal (filter, psd))); + rxPowerListDbm.push_back (WToDbm (rxPower)); } - StartReceiveEdmgTrnSubfield (wifiRxParams->txVector, rxPowerList); + StartReceiveEdmgTrnSubfield (wifiRxParams->txVector, rxPowerListDbm); } else {