View | Details | Raw Unified | Return to bug 2831
Collapse All | Expand All

(-)a/src/wifi/model/ap-wifi-mac.cc (-18 / +216 lines)
 Lines 719-729    Link Here 
719
}
719
}
720
720
721
void
721
void
722
ApWifiMac::SendAssocResp (Mac48Address to, bool success)
722
ApWifiMac::SendAssocResp (Mac48Address to, bool success, bool isReassoc)
723
{
723
{
724
  NS_LOG_FUNCTION (this << to << success);
724
  NS_LOG_FUNCTION (this << to << success << isReassoc);
725
  WifiMacHeader hdr;
725
  WifiMacHeader hdr;
726
  hdr.SetType (WIFI_MAC_MGT_ASSOCIATION_RESPONSE);
726
  hdr.SetType (isReassoc ? WIFI_MAC_MGT_REASSOCIATION_RESPONSE : WIFI_MAC_MGT_ASSOCIATION_RESPONSE);
727
  hdr.SetAddr1 (to);
727
  hdr.SetAddr1 (to);
728
  hdr.SetAddr2 (GetAddress ());
728
  hdr.SetAddr2 (GetAddress ());
729
  hdr.SetAddr3 (GetAddress ());
729
  hdr.SetAddr3 (GetAddress ());
 Lines 736-743    Link Here 
736
  if (success)
736
  if (success)
737
    {
737
    {
738
      code.SetSuccess ();
738
      code.SetSuccess ();
739
      uint16_t aid = GetNextAssociationId ();
739
      uint16_t aid;
740
      m_staList.insert (std::make_pair (aid, to));
740
      bool found = false;
741
      if (isReassoc)
742
        {
743
          for (std::map<uint16_t, Mac48Address>::const_iterator i = m_staList.begin (); i != m_staList.end (); ++i)
744
            {
745
              if (i->second == to)
746
                {
747
                      aid = i->first;
748
                      found = true;
749
                      break;
750
                }
751
            }
752
        }
753
      if (!found)
754
        {
755
          aid = GetNextAssociationId ();
756
          m_staList.insert (std::make_pair (aid, to));
757
        }
741
      assoc.SetAssociationId (aid);
758
      assoc.SetAssociationId (aid);
742
    }
759
    }
743
  else
760
  else
 Lines 857-864    Link Here 
857
{
874
{
858
  NS_LOG_FUNCTION (this);
875
  NS_LOG_FUNCTION (this);
859
  RegularWifiMac::TxOk (hdr);
876
  RegularWifiMac::TxOk (hdr);
860
877
  if ((hdr.IsAssocResp () || hdr.IsReassocResp ())
861
  if (hdr.IsAssocResp ()
862
      && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
878
      && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
863
    {
879
    {
864
      NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ());
880
      NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ());
 Lines 872-881    Link Here 
872
  NS_LOG_FUNCTION (this);
888
  NS_LOG_FUNCTION (this);
873
  RegularWifiMac::TxFailed (hdr);
889
  RegularWifiMac::TxFailed (hdr);
874
890
875
  if (hdr.IsAssocResp ()
891
  if ((hdr.IsAssocResp () || hdr.IsReassocResp ())
876
      && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
892
      && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
877
    {
893
    {
878
      NS_LOG_DEBUG ("assoc failed with sta=" << hdr.GetAddr1 ());
894
      NS_LOG_DEBUG ("association failed with sta=" << hdr.GetAddr1 ());
879
      m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
895
      m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
880
    }
896
    }
881
}
897
}
 Lines 884-892    Link Here 
884
ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
900
ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
885
{
901
{
886
  NS_LOG_FUNCTION (this << packet << hdr);
902
  NS_LOG_FUNCTION (this << packet << hdr);
887
888
  Mac48Address from = hdr->GetAddr2 ();
903
  Mac48Address from = hdr->GetAddr2 ();
889
890
  if (hdr->IsData ())
904
  if (hdr->IsData ())
891
    {
905
    {
892
      Mac48Address bssid = hdr->GetAddr1 ();
906
      Mac48Address bssid = hdr->GetAddr1 ();
 Lines 961-966    Link Here 
961
      if (hdr->IsProbeReq ())
975
      if (hdr->IsProbeReq ())
962
        {
976
        {
963
          NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
977
          NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
978
          NS_LOG_DEBUG ("Probe request received from " << from << ": send probe response");
964
          SendProbeResp (from);
979
          SendProbeResp (from);
965
          return;
980
          return;
966
        }
981
        }
 Lines 968-973    Link Here 
968
        {
983
        {
969
          if (hdr->IsAssocReq ())
984
          if (hdr->IsAssocReq ())
970
            {
985
            {
986
              NS_LOG_DEBUG ("Association request received from " << from);
971
              //first, verify that the the station's supported
987
              //first, verify that the the station's supported
972
              //rate set is compatible with our Basic Rate set
988
              //rate set is compatible with our Basic Rate set
973
              MgtAssocRequestHeader assocReq;
989
              MgtAssocRequestHeader assocReq;
 Lines 1074-1087    Link Here 
1074
                }
1090
                }
1075
              if (problem)
1091
              if (problem)
1076
                {
1092
                {
1077
                  //One of the Basic Rate set mode is not
1093
                  NS_LOG_DEBUG ("One of the Basic Rate set mode is not supported by the station: send association response with an error status");
1078
                  //supported by the station. So, we return an assoc
1094
                  SendAssocResp (hdr->GetAddr2 (), false, false);
1079
                  //response with an error status.
1080
                  SendAssocResp (hdr->GetAddr2 (), false);
1081
                }
1095
                }
1082
              else
1096
              else
1083
                {
1097
                {
1084
                  //station supports all rates in Basic Rate Set.
1098
                  NS_LOG_DEBUG ("The Basic Rate set modes are supported by the station");
1085
                  //record all its supported modes in its associated WifiRemoteStation
1099
                  //record all its supported modes in its associated WifiRemoteStation
1086
                  for (uint8_t j = 0; j < m_phy->GetNModes (); j++)
1100
                  for (uint8_t j = 0; j < m_phy->GetNModes (); j++)
1087
                    {
1101
                    {
 Lines 1136-1153    Link Here 
1136
                  if (!isHtStation)
1150
                  if (!isHtStation)
1137
                    {
1151
                    {
1138
                      m_nonHtStations.push_back (hdr->GetAddr2 ());
1152
                      m_nonHtStations.push_back (hdr->GetAddr2 ());
1153
                      m_nonHtStations.unique ();
1139
                    }
1154
                    }
1140
                  if (!isErpStation && isDsssStation)
1155
                  if (!isErpStation && isDsssStation)
1141
                    {
1156
                    {
1142
                      m_nonErpStations.push_back (hdr->GetAddr2 ());
1157
                      m_nonErpStations.push_back (hdr->GetAddr2 ());
1158
                      m_nonErpStations.unique ();
1143
                    }
1159
                    }
1144
                  // send assoc response with success status.
1160
                  NS_LOG_DEBUG ("Send association response with success status");
1145
                  SendAssocResp (hdr->GetAddr2 (), true);
1161
                  SendAssocResp (hdr->GetAddr2 (), true, false);
1162
                }
1163
              return;
1164
            }
1165
          else if (hdr->IsReassocReq ())
1166
            {
1167
              NS_LOG_DEBUG ("Reassociation request received from " << from);
1168
              //first, verify that the the station's supported
1169
              //rate set is compatible with our Basic Rate set
1170
              MgtReassocRequestHeader reassocReq;
1171
              packet->RemoveHeader (reassocReq);
1172
              CapabilityInformation capabilities = reassocReq.GetCapabilities ();
1173
              m_stationManager->AddSupportedPlcpPreamble (from, capabilities.IsShortPreamble ());
1174
              SupportedRates rates = reassocReq.GetSupportedRates ();
1175
              bool problem = false;
1176
              bool isHtStation = false;
1177
              bool isOfdmStation = false;
1178
              bool isErpStation = false;
1179
              bool isDsssStation = false;
1180
              for (uint8_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
1181
                {
1182
                  WifiMode mode = m_stationManager->GetBasicMode (i);
1183
                  if (!rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth ())))
1184
                    {
1185
                      if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS))
1186
                        {
1187
                          isDsssStation = false;
1188
                        }
1189
                      else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
1190
                        {
1191
                          isErpStation = false;
1192
                        }
1193
                      else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM)
1194
                        {
1195
                          isOfdmStation = false;
1196
                        }
1197
                      if (isDsssStation == false && isErpStation == false && isOfdmStation == false)
1198
                        {
1199
                          problem = true;
1200
                          break;
1201
                        }
1202
                    }
1203
                  else
1204
                    {
1205
                      if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS))
1206
                        {
1207
                          isDsssStation = true;
1208
                        }
1209
                      else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
1210
                        {
1211
                          isErpStation = true;
1212
                        }
1213
                      else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM)
1214
                        {
1215
                          isOfdmStation = true;
1216
                        }
1217
                    }
1218
                }
1219
              m_stationManager->AddSupportedErpSlotTime (from, capabilities.IsShortSlotTime () && isErpStation);
1220
              if (m_htSupported)
1221
                {
1222
                  //check whether the HT STA supports all MCSs in Basic MCS Set
1223
                  HtCapabilities htcapabilities = reassocReq.GetHtCapabilities ();
1224
                  if (htcapabilities.IsSupportedMcs (0))
1225
                    {
1226
                      isHtStation = true;
1227
                      for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
1228
                        {
1229
                          WifiMode mcs = m_stationManager->GetBasicMcs (i);
1230
                          if (!htcapabilities.IsSupportedMcs (mcs.GetMcsValue ()))
1231
                            {
1232
                              problem = true;
1233
                              break;
1234
                            }
1235
                        }
1236
                    }
1237
                }
1238
              if (m_vhtSupported)
1239
                {
1240
                  //check whether the VHT STA supports all MCSs in Basic MCS Set
1241
                  VhtCapabilities vhtcapabilities = reassocReq.GetVhtCapabilities ();
1242
                  if (vhtcapabilities.GetVhtCapabilitiesInfo () != 0)
1243
                    {
1244
                      for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
1245
                        {
1246
                          WifiMode mcs = m_stationManager->GetBasicMcs (i);
1247
                          if (!vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
1248
                            {
1249
                              problem = true;
1250
                              break;
1251
                            }
1252
                        }
1253
                    }
1254
                }
1255
              if (m_heSupported)
1256
                {
1257
                  //check whether the HE STA supports all MCSs in Basic MCS Set
1258
                  HeCapabilities hecapabilities = reassocReq.GetHeCapabilities ();
1259
                  if (hecapabilities.GetSupportedMcsAndNss () != 0)
1260
                    {
1261
                      for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
1262
                        {
1263
                          WifiMode mcs = m_stationManager->GetBasicMcs (i);
1264
                          if (!hecapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
1265
                            {
1266
                              problem = true;
1267
                              break;
1268
                            }
1269
                        }
1270
                    }
1271
                }
1272
              if (problem)
1273
                {
1274
                  NS_LOG_DEBUG ("One of the Basic Rate set mode is not supported by the station: send reassociation response with an error status");
1275
                  SendAssocResp (hdr->GetAddr2 (), false, true);
1276
                }
1277
              else
1278
                {
1279
                  NS_LOG_DEBUG ("The Basic Rate set modes are supported by the station");
1280
                  //update all its supported modes in its associated WifiRemoteStation
1281
                  for (uint8_t j = 0; j < m_phy->GetNModes (); j++)
1282
                    {
1283
                      WifiMode mode = m_phy->GetMode (j);
1284
                      if (rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth ())))
1285
                        {
1286
                          m_stationManager->AddSupportedMode (from, mode);
1287
                        }
1288
                    }
1289
                  if (m_htSupported)
1290
                    {
1291
                      HtCapabilities htCapabilities = reassocReq.GetHtCapabilities ();
1292
                      if (htCapabilities.IsSupportedMcs (0))
1293
                        {
1294
                          m_stationManager->AddStationHtCapabilities (from, htCapabilities);
1295
                        }
1296
                    }
1297
                  if (m_vhtSupported)
1298
                    {
1299
                      VhtCapabilities vhtCapabilities = reassocReq.GetVhtCapabilities ();
1300
                      //we will always fill in RxHighestSupportedLgiDataRate field at TX, so this can be used to check whether it supports VHT
1301
                      if (vhtCapabilities.GetRxHighestSupportedLgiDataRate () > 0)
1302
                        {
1303
                          m_stationManager->AddStationVhtCapabilities (from, vhtCapabilities);
1304
                          for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
1305
                            {
1306
                              WifiMode mcs = m_phy->GetMcs (i);
1307
                              if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VHT && vhtCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
1308
                                {
1309
                                  m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs);
1310
                                  //here should add a control to add basic MCS when it is implemented
1311
                                }
1312
                            }
1313
                        }
1314
                    }
1315
                  if (m_heSupported)
1316
                    {
1317
                      HeCapabilities heCapabilities = reassocReq.GetHeCapabilities ();
1318
                      //todo: once we support non constant rate managers, we should add checks here whether HE is supported by the peer
1319
                      m_stationManager->AddStationHeCapabilities (from, heCapabilities);
1320
                      for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
1321
                        {
1322
                          WifiMode mcs = m_phy->GetMcs (i);
1323
                          if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HE && heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
1324
                            {
1325
                              m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs);
1326
                              //here should add a control to add basic MCS when it is implemented
1327
                            }
1328
                        }
1329
                    }
1330
                  m_stationManager->RecordWaitAssocTxOk (from);
1331
                  if (!isHtStation)
1332
                    {
1333
                      m_nonHtStations.push_back (hdr->GetAddr2 ());
1334
                      m_nonHtStations.unique ();
1335
                    }
1336
                  if (!isErpStation && isDsssStation)
1337
                    {
1338
                      m_nonErpStations.push_back (hdr->GetAddr2 ());
1339
                      m_nonErpStations.unique ();
1340
                    }
1341
                  NS_LOG_DEBUG ("Send reassociation response with success status");
1342
                  SendAssocResp (hdr->GetAddr2 (), true, true);
1146
                }
1343
                }
1147
              return;
1344
              return;
1148
            }
1345
            }
1149
          else if (hdr->IsDisassociation ())
1346
          else if (hdr->IsDisassociation ())
1150
            {
1347
            {
1348
              NS_LOG_DEBUG ("Disassociation received from " << from);
1151
              m_stationManager->RecordDisassociated (from);
1349
              m_stationManager->RecordDisassociated (from);
1152
              for (std::map<uint16_t, Mac48Address>::const_iterator j = m_staList.begin (); j != m_staList.end (); j++)
1350
              for (std::map<uint16_t, Mac48Address>::const_iterator j = m_staList.begin (); j != m_staList.end (); j++)
1153
                {
1351
                {
(-)a/src/wifi/model/ap-wifi-mac.h (-3 / +5 lines)
 Lines 199-211    Link Here 
199
   */
199
   */
200
  void SendProbeResp (Mac48Address to);
200
  void SendProbeResp (Mac48Address to);
201
  /**
201
  /**
202
   * Forward an association response packet to the DCF. The standard is not clear on the correct
202
   * Forward an association or a reassociation response packet to the DCF.
203
   * queue for management frames if QoS is supported. We always use the DCF.
203
   * The standard is not clear on the correct queue for management frames if QoS is supported.
204
   * We always use the DCF.
204
   *
205
   *
205
   * \param to the address of the STA we are sending an association response to
206
   * \param to the address of the STA we are sending an association response to
206
   * \param success indicates whether the association was successful or not
207
   * \param success indicates whether the association was successful or not
208
   * \param isReassoc indicates whether it is a reassociation response
207
   */
209
   */
208
  void SendAssocResp (Mac48Address to, bool success);
210
  void SendAssocResp (Mac48Address to, bool success, bool isReassoc);
209
  /**
211
  /**
210
   * Forward a beacon packet to the beacon special DCF.
212
   * Forward a beacon packet to the beacon special DCF.
211
   */
213
   */
(-)a/src/wifi/model/mgt-headers.cc (-1 / +197 lines)
 Lines 686-692    Link Here 
686
686
687
687
688
/***********************************************************
688
/***********************************************************
689
 *          Assoc Response
689
 *          Ressoc Request
690
 ***********************************************************/
691
692
NS_OBJECT_ENSURE_REGISTERED (MgtReassocRequestHeader);
693
694
MgtReassocRequestHeader::MgtReassocRequestHeader ()
695
  : m_currentApAddr (Mac48Address ())
696
{
697
}
698
699
MgtReassocRequestHeader::~MgtReassocRequestHeader ()
700
{
701
}
702
703
void
704
MgtReassocRequestHeader::SetSsid (Ssid ssid)
705
{
706
  m_ssid = ssid;
707
}
708
709
void
710
MgtReassocRequestHeader::SetSupportedRates (SupportedRates rates)
711
{
712
  m_rates = rates;
713
}
714
715
void
716
MgtReassocRequestHeader::SetListenInterval (uint16_t interval)
717
{
718
  m_listenInterval = interval;
719
}
720
721
void
722
MgtReassocRequestHeader::SetCapabilities (CapabilityInformation capabilities)
723
{
724
  m_capability = capabilities;
725
}
726
727
CapabilityInformation
728
MgtReassocRequestHeader::GetCapabilities (void) const
729
{
730
  return m_capability;
731
}
732
733
void
734
MgtReassocRequestHeader::SetExtendedCapabilities (ExtendedCapabilities extendedcapabilities)
735
{
736
  m_extendedCapability = extendedcapabilities;
737
}
738
739
ExtendedCapabilities
740
MgtReassocRequestHeader::GetExtendedCapabilities (void) const
741
{
742
  return m_extendedCapability;
743
}
744
745
void
746
MgtReassocRequestHeader::SetHtCapabilities (HtCapabilities htcapabilities)
747
{
748
  m_htCapability = htcapabilities;
749
}
750
751
HtCapabilities
752
MgtReassocRequestHeader::GetHtCapabilities (void) const
753
{
754
  return m_htCapability;
755
}
756
757
void
758
MgtReassocRequestHeader::SetVhtCapabilities (VhtCapabilities vhtcapabilities)
759
{
760
  m_vhtCapability = vhtcapabilities;
761
}
762
763
VhtCapabilities
764
MgtReassocRequestHeader::GetVhtCapabilities (void) const
765
{
766
  return m_vhtCapability;
767
}
768
769
void
770
MgtReassocRequestHeader::SetHeCapabilities (HeCapabilities hecapabilities)
771
{
772
  m_heCapability = hecapabilities;
773
}
774
775
HeCapabilities
776
MgtReassocRequestHeader::GetHeCapabilities (void) const
777
{
778
  return m_heCapability;
779
}
780
781
Ssid
782
MgtReassocRequestHeader::GetSsid (void) const
783
{
784
  return m_ssid;
785
}
786
787
SupportedRates
788
MgtReassocRequestHeader::GetSupportedRates (void) const
789
{
790
  return m_rates;
791
}
792
793
uint16_t
794
MgtReassocRequestHeader::GetListenInterval (void) const
795
{
796
  return m_listenInterval;
797
}
798
799
void
800
MgtReassocRequestHeader::SetCurrentApAddress (Mac48Address currentApAddr)
801
{
802
  m_currentApAddr = currentApAddr;
803
}
804
805
TypeId
806
MgtReassocRequestHeader::GetTypeId (void)
807
{
808
  static TypeId tid = TypeId ("ns3::MgtReassocRequestHeader")
809
    .SetParent<Header> ()
810
    .SetGroupName ("Wifi")
811
    .AddConstructor<MgtReassocRequestHeader> ()
812
  ;
813
  return tid;
814
}
815
816
TypeId
817
MgtReassocRequestHeader::GetInstanceTypeId (void) const
818
{
819
  return GetTypeId ();
820
}
821
822
uint32_t
823
MgtReassocRequestHeader::GetSerializedSize (void) const
824
{
825
  uint32_t size = 0;
826
  size += m_capability.GetSerializedSize ();
827
  size += 2; //listen interval
828
  size += 6; //current AP address
829
  size += m_ssid.GetSerializedSize ();
830
  size += m_rates.GetSerializedSize ();
831
  size += m_rates.extended.GetSerializedSize ();
832
  size += m_extendedCapability.GetSerializedSize ();
833
  size += m_htCapability.GetSerializedSize ();
834
  size += m_vhtCapability.GetSerializedSize ();
835
  size += m_heCapability.GetSerializedSize ();
836
  return size;
837
}
838
839
void
840
MgtReassocRequestHeader::Print (std::ostream &os) const
841
{
842
  os << "current AP address=" << m_currentApAddr << ", "
843
     << "ssid=" << m_ssid << ", "
844
     << "rates=" << m_rates << ", "
845
     << "HT Capabilities=" << m_htCapability << " , "
846
     << "VHT Capabilities=" << m_vhtCapability << " , "
847
     << "HE Capabilities=" << m_heCapability;
848
}
849
850
void
851
MgtReassocRequestHeader::Serialize (Buffer::Iterator start) const
852
{
853
  Buffer::Iterator i = start;
854
  i = m_capability.Serialize (i);
855
  i.WriteHtolsbU16 (m_listenInterval);
856
  WriteTo (i, m_currentApAddr);
857
  i = m_ssid.Serialize (i);
858
  i = m_rates.Serialize (i);
859
  i = m_rates.extended.Serialize (i);
860
  i = m_extendedCapability.Serialize (i);
861
  i = m_htCapability.Serialize (i);
862
  i = m_vhtCapability.Serialize (i);
863
  i = m_heCapability.Serialize (i);
864
}
865
866
uint32_t
867
MgtReassocRequestHeader::Deserialize (Buffer::Iterator start)
868
{
869
  Buffer::Iterator i = start;
870
  i = m_capability.Deserialize (i);
871
  m_listenInterval = i.ReadLsbtohU16 ();
872
  ReadFrom (i, m_currentApAddr);
873
  i = m_ssid.Deserialize (i);
874
  i = m_rates.Deserialize (i);
875
  i = m_rates.extended.DeserializeIfPresent (i);
876
  i = m_extendedCapability.DeserializeIfPresent (i);
877
  i = m_htCapability.DeserializeIfPresent (i);
878
  i = m_vhtCapability.DeserializeIfPresent (i);
879
  i = m_heCapability.DeserializeIfPresent (i);
880
  return i.GetDistanceFrom (start);
881
}
882
883
884
/***********************************************************
885
 *          Assoc/Reassoc Response
690
 ***********************************************************/
886
 ***********************************************************/
691
887
692
NS_OBJECT_ENSURE_REGISTERED (MgtAssocResponseHeader);
888
NS_OBJECT_ENSURE_REGISTERED (MgtAssocResponseHeader);
(-)a/src/wifi/model/mgt-headers.h (-1 / +140 lines)
 Lines 37-42    Link Here 
37
#include "edca-parameter-set.h"
37
#include "edca-parameter-set.h"
38
#include "he-capabilities.h"
38
#include "he-capabilities.h"
39
#include "he-operation.h"
39
#include "he-operation.h"
40
#include "ns3/address-utils.h"
40
41
41
namespace ns3 {
42
namespace ns3 {
42
43
 Lines 173-179    Link Here 
173
174
174
/**
175
/**
175
 * \ingroup wifi
176
 * \ingroup wifi
176
 * Implement the header for management frames of type association response.
177
 * Implement the header for management frames of type reassociation request.
178
 */
179
class MgtReassocRequestHeader : public Header
180
{
181
public:
182
  MgtReassocRequestHeader ();
183
  ~MgtReassocRequestHeader ();
184
185
  /**
186
   * Set the Service Set Identifier (SSID).
187
   *
188
   * \param ssid SSID
189
   */
190
  void SetSsid (Ssid ssid);
191
  /**
192
   * Set the supported rates.
193
   *
194
   * \param rates the supported rates
195
   */
196
  void SetSupportedRates (SupportedRates rates);
197
  /**
198
   * Set the listen interval.
199
   *
200
   * \param interval the listen interval
201
   */
202
  void SetListenInterval (uint16_t interval);
203
  /**
204
   * Set the Capability information.
205
   *
206
   * \param capabilities Capability information
207
   */
208
  void SetCapabilities (CapabilityInformation capabilities);
209
  /**
210
   * Set the Extended Capabilities.
211
   *
212
   * \param extendedcapabilities the Extended Capabilities
213
   */
214
  void SetExtendedCapabilities (ExtendedCapabilities extendedcapabilities);
215
  /**
216
   * Set the HT capabilities.
217
   *
218
   * \param htcapabilities HT capabilities
219
   */
220
  void SetHtCapabilities (HtCapabilities htcapabilities);
221
  /**
222
   * Set the VHT capabilities.
223
   *
224
   * \param vhtcapabilities VHT capabilities
225
   */
226
  void SetVhtCapabilities (VhtCapabilities vhtcapabilities);
227
  /**
228
   * Set the HE capabilities.
229
   *
230
   * \param hecapabilities HE capabilities
231
   */
232
  void SetHeCapabilities (HeCapabilities hecapabilities);
233
  /**
234
   * Return the Capability information.
235
   *
236
   * \return Capability information
237
   */
238
  CapabilityInformation GetCapabilities (void) const;
239
  /**
240
   * Return the extended capabilities.
241
   *
242
   * \return the extended capabilities
243
   */
244
  ExtendedCapabilities GetExtendedCapabilities (void) const;
245
  /**
246
   * Return the HT capabilities.
247
   *
248
   * \return HT capabilities
249
   */
250
  HtCapabilities GetHtCapabilities (void) const;
251
  /**
252
   * Return the VHT capabilities.
253
   *
254
   * \return VHT capabilities
255
   */
256
  VhtCapabilities GetVhtCapabilities (void) const;
257
  /**
258
   * Return the HE capabilities.
259
   *
260
   * \return HE capabilities
261
   */
262
  HeCapabilities GetHeCapabilities (void) const;
263
  /**
264
   * Return the Service Set Identifier (SSID).
265
   *
266
   * \return SSID
267
   */
268
  Ssid GetSsid (void) const;
269
  /**
270
   * Return the supported rates.
271
   *
272
   * \return the supported rates
273
   */
274
  SupportedRates GetSupportedRates (void) const;
275
  /**
276
   * Return the listen interval.
277
   *
278
   * \return the listen interval
279
   */
280
  uint16_t GetListenInterval (void) const;
281
  /**
282
   * Set the address of the current access point.
283
   *
284
   * \param currentApAddr address of the current access point
285
   */
286
  void SetCurrentApAddress (Mac48Address currentApAddr);
287
288
  /**
289
   * Register this type.
290
   * \return The TypeId.
291
   */
292
  static TypeId GetTypeId (void);
293
  TypeId GetInstanceTypeId (void) const;
294
  void Print (std::ostream &os) const;
295
  uint32_t GetSerializedSize (void) const;
296
  void Serialize (Buffer::Iterator start) const;
297
  uint32_t Deserialize (Buffer::Iterator start);
298
299
300
private:
301
  Mac48Address m_currentApAddr;       //!< Address of the current access point
302
  Ssid m_ssid;                        //!< Service Set ID (SSID)
303
  SupportedRates m_rates;             //!< List of supported rates
304
  CapabilityInformation m_capability; //!< Capability information
305
  ExtendedCapabilities m_extendedCapability; //!< Extended capabilities
306
  HtCapabilities m_htCapability;      //!< HT capabilities
307
  VhtCapabilities m_vhtCapability;    //!< VHT capabilities
308
  HeCapabilities m_heCapability;      //!< HE capabilities
309
  uint16_t m_listenInterval;          //!< listen interval
310
};
311
312
313
/**
314
 * \ingroup wifi
315
 * Implement the header for management frames of type association and reassociation response.
177
 */
316
 */
178
class MgtAssocResponseHeader : public Header
317
class MgtAssocResponseHeader : public Header
179
{
318
{
(-)a/src/wifi/model/regular-wifi-mac.h (-1 / +1 lines)
 Lines 216-222    Link Here 
216
  /**
216
  /**
217
   * \param phy the physical layer attached to this MAC.
217
   * \param phy the physical layer attached to this MAC.
218
   */
218
   */
219
  void SetWifiPhy (const Ptr<WifiPhy> phy);
219
  virtual void SetWifiPhy (const Ptr<WifiPhy> phy);
220
  /**
220
  /**
221
   * \return the physical layer attached to this MAC.
221
   * \return the physical layer attached to this MAC.
222
   */
222
   */
(-)a/src/wifi/model/sta-wifi-mac.cc (-32 / +90 lines)
 Lines 58-64    Link Here 
58
                   TimeValue (Seconds (0.05)),
58
                   TimeValue (Seconds (0.05)),
59
                   MakeTimeAccessor (&StaWifiMac::m_probeRequestTimeout),
59
                   MakeTimeAccessor (&StaWifiMac::m_probeRequestTimeout),
60
                   MakeTimeChecker ())
60
                   MakeTimeChecker ())
61
    .AddAttribute ("AssocRequestTimeout", "The interval between two consecutive assoc request attempts.",
61
    .AddAttribute ("AssocRequestTimeout", "The interval between two consecutive association request attempts.",
62
                   TimeValue (Seconds (0.5)),
62
                   TimeValue (Seconds (0.5)),
63
                   MakeTimeAccessor (&StaWifiMac::m_assocRequestTimeout),
63
                   MakeTimeAccessor (&StaWifiMac::m_assocRequestTimeout),
64
                   MakeTimeChecker ())
64
                   MakeTimeChecker ())
 Lines 120-131    Link Here 
120
  m_activeProbing = enable;
120
  m_activeProbing = enable;
121
}
121
}
122
122
123
bool StaWifiMac::GetActiveProbing (void) const
123
bool
124
StaWifiMac::GetActiveProbing (void) const
124
{
125
{
125
  return m_activeProbing;
126
  return m_activeProbing;
126
}
127
}
127
128
128
void
129
void
130
StaWifiMac::SetWifiPhy (const Ptr<WifiPhy> phy)
131
{
132
  NS_LOG_FUNCTION (this << phy);
133
  RegularWifiMac::SetWifiPhy (phy);
134
  m_phy->SetCapabilitiesChangedCallback (MakeCallback (&StaWifiMac::PhyCapabilitiesChanged, this));
135
}
136
137
void
129
StaWifiMac::SendProbeRequest (void)
138
StaWifiMac::SendProbeRequest (void)
130
{
139
{
131
  NS_LOG_FUNCTION (this);
140
  NS_LOG_FUNCTION (this);
 Lines 171-181    Link Here 
171
}
180
}
172
181
173
void
182
void
174
StaWifiMac::SendAssociationRequest (void)
183
StaWifiMac::SendAssociationRequest (bool isReassoc)
175
{
184
{
176
  NS_LOG_FUNCTION (this << GetBssid ());
185
  NS_LOG_FUNCTION (this << GetBssid () << isReassoc);
177
  WifiMacHeader hdr;
186
  WifiMacHeader hdr;
178
  hdr.SetType (WIFI_MAC_MGT_ASSOCIATION_REQUEST);
187
  hdr.SetType (isReassoc ? WIFI_MAC_MGT_REASSOCIATION_REQUEST : WIFI_MAC_MGT_ASSOCIATION_REQUEST);
179
  hdr.SetAddr1 (GetBssid ());
188
  hdr.SetAddr1 (GetBssid ());
180
  hdr.SetAddr2 (GetAddress ());
189
  hdr.SetAddr2 (GetAddress ());
181
  hdr.SetAddr3 (GetBssid ());
190
  hdr.SetAddr3 (GetBssid ());
 Lines 183-206    Link Here 
183
  hdr.SetDsNotTo ();
192
  hdr.SetDsNotTo ();
184
  hdr.SetNoOrder ();
193
  hdr.SetNoOrder ();
185
  Ptr<Packet> packet = Create<Packet> ();
194
  Ptr<Packet> packet = Create<Packet> ();
186
  MgtAssocRequestHeader assoc;
195
  if (!isReassoc)
187
  assoc.SetSsid (GetSsid ());
188
  assoc.SetSupportedRates (GetSupportedRates ());
189
  assoc.SetCapabilities (GetCapabilities ());
190
  if (m_htSupported || m_vhtSupported || m_heSupported)
191
    {
196
    {
192
      assoc.SetExtendedCapabilities (GetExtendedCapabilities ());
197
      MgtAssocRequestHeader assoc;
193
      assoc.SetHtCapabilities (GetHtCapabilities ());
198
      assoc.SetSsid (GetSsid ());
199
      assoc.SetSupportedRates (GetSupportedRates ());
200
      assoc.SetCapabilities (GetCapabilities ());
201
      if (m_htSupported || m_vhtSupported || m_heSupported)
202
        {
203
          assoc.SetExtendedCapabilities (GetExtendedCapabilities ());
204
          assoc.SetHtCapabilities (GetHtCapabilities ());
205
        }
206
      if (m_vhtSupported || m_heSupported)
207
        {
208
          assoc.SetVhtCapabilities (GetVhtCapabilities ());
209
        }
210
      if (m_heSupported)
211
        {
212
          assoc.SetHeCapabilities (GetHeCapabilities ());
213
        }
214
      packet->AddHeader (assoc);
194
    }
215
    }
195
  if (m_vhtSupported || m_heSupported)
216
  else
196
    {
217
    {
197
      assoc.SetVhtCapabilities (GetVhtCapabilities ());
218
      MgtReassocRequestHeader reassoc;
219
      reassoc.SetCurrentApAddress (GetBssid ());
220
      reassoc.SetSsid (GetSsid ());
221
      reassoc.SetSupportedRates (GetSupportedRates ());
222
      reassoc.SetCapabilities (GetCapabilities ());
223
      if (m_htSupported || m_vhtSupported || m_heSupported)
224
        {
225
          reassoc.SetExtendedCapabilities (GetExtendedCapabilities ());
226
          reassoc.SetHtCapabilities (GetHtCapabilities ());
227
        }
228
      if (m_vhtSupported || m_heSupported)
229
        {
230
          reassoc.SetVhtCapabilities (GetVhtCapabilities ());
231
        }
232
      if (m_heSupported)
233
        {
234
          reassoc.SetHeCapabilities (GetHeCapabilities ());
235
        }
236
      packet->AddHeader (reassoc);
198
    }
237
    }
199
  if (m_heSupported)
200
    {
201
      assoc.SetHeCapabilities (GetHeCapabilities ());
202
    }
203
  packet->AddHeader (assoc);
204
238
205
  //The standard is not clear on the correct queue for management
239
  //The standard is not clear on the correct queue for management
206
  //frames if we are a QoS AP. The approach taken here is to always
240
  //frames if we are a QoS AP. The approach taken here is to always
 Lines 245-259    Link Here 
245
        }
279
        }
246
      break;
280
      break;
247
    case WAIT_ASSOC_RESP:
281
    case WAIT_ASSOC_RESP:
248
      /* we have sent an assoc request so we do not need to
282
      /* we have sent an association request so we do not need to
249
         re-send an assoc request right now. We just need to
283
         re-send an association request right now. We just need to
250
         wait until either assoc-request-timeout or until
284
         wait until either assoc-request-timeout or until
251
         we get an assoc response.
285
         we get an association response.
252
       */
286
       */
253
      break;
287
      break;
254
    case REFUSED:
288
    case REFUSED:
255
      /* we have sent an assoc request and received a negative
289
      /* we have sent an association request and received a negative
256
         assoc resp. We wait until someone restarts an
290
         association response. We wait until someone restarts an
257
         association with a given ssid.
291
         association with a given ssid.
258
       */
292
       */
259
      break;
293
      break;
 Lines 265-271    Link Here 
265
{
299
{
266
  NS_LOG_FUNCTION (this);
300
  NS_LOG_FUNCTION (this);
267
  SetState (WAIT_ASSOC_RESP);
301
  SetState (WAIT_ASSOC_RESP);
268
  SendAssociationRequest ();
302
  SendAssociationRequest (false);
269
}
303
}
270
304
271
void
305
void
 Lines 447-453    Link Here 
447
      return;
481
      return;
448
    }
482
    }
449
  else if (hdr->IsProbeReq ()
483
  else if (hdr->IsProbeReq ()
450
           || hdr->IsAssocReq ())
484
           || hdr->IsAssocReq ()
485
           || hdr->IsReassocReq ())
451
    {
486
    {
452
      //This is a frame aimed at an AP, so we can safely ignore it.
487
      //This is a frame aimed at an AP, so we can safely ignore it.
453
      NotifyRxDrop (packet);
488
      NotifyRxDrop (packet);
 Lines 455-460    Link Here 
455
    }
490
    }
456
  else if (hdr->IsBeacon ())
491
  else if (hdr->IsBeacon ())
457
    {
492
    {
493
      NS_LOG_DEBUG ("Beacon received");
458
      MgtBeaconHeader beacon;
494
      MgtBeaconHeader beacon;
459
      packet->RemoveHeader (beacon);
495
      packet->RemoveHeader (beacon);
460
      CapabilityInformation capabilities = beacon.GetCapabilities ();
496
      CapabilityInformation capabilities = beacon.GetCapabilities ();
 Lines 608-614    Link Here 
608
      if (goodBeacon && m_state == BEACON_MISSED)
644
      if (goodBeacon && m_state == BEACON_MISSED)
609
        {
645
        {
610
          SetState (WAIT_ASSOC_RESP);
646
          SetState (WAIT_ASSOC_RESP);
611
          SendAssociationRequest ();
647
          NS_LOG_DEBUG ("Good beacon received: send association request");
648
          SendAssociationRequest (false);
612
        }
649
        }
613
      return;
650
      return;
614
    }
651
    }
 Lines 616-627    Link Here 
616
    {
653
    {
617
      if (m_state == WAIT_PROBE_RESP)
654
      if (m_state == WAIT_PROBE_RESP)
618
        {
655
        {
656
          NS_LOG_DEBUG ("Probe response received");
619
          MgtProbeResponseHeader probeResp;
657
          MgtProbeResponseHeader probeResp;
620
          packet->RemoveHeader (probeResp);
658
          packet->RemoveHeader (probeResp);
621
          CapabilityInformation capabilities = probeResp.GetCapabilities ();
659
          CapabilityInformation capabilities = probeResp.GetCapabilities ();
622
          if (!probeResp.GetSsid ().IsEqual (GetSsid ()))
660
          if (!probeResp.GetSsid ().IsEqual (GetSsid ()))
623
            {
661
            {
624
              //not a probe resp for our ssid.
662
              NS_LOG_DEBUG ("Probe response is not for our SSID");
625
              return;
663
              return;
626
            }
664
            }
627
          SupportedRates rates = probeResp.GetSupportedRates ();
665
          SupportedRates rates = probeResp.GetSupportedRates ();
 Lines 630-635    Link Here 
630
              uint8_t selector = m_phy->GetBssMembershipSelector (i);
668
              uint8_t selector = m_phy->GetBssMembershipSelector (i);
631
              if (!rates.IsBssMembershipSelectorRate (selector))
669
              if (!rates.IsBssMembershipSelectorRate (selector))
632
                {
670
                {
671
                  NS_LOG_DEBUG ("Supported rates do not fit with the BSS membership selector");
633
                  return;
672
                  return;
634
                }
673
                }
635
            }
674
            }
 Lines 692-702    Link Here 
692
              m_probeRequestEvent.Cancel ();
731
              m_probeRequestEvent.Cancel ();
693
            }
732
            }
694
          SetState (WAIT_ASSOC_RESP);
733
          SetState (WAIT_ASSOC_RESP);
695
          SendAssociationRequest ();
734
          SendAssociationRequest (false);
696
        }
735
        }
697
      return;
736
      return;
698
    }
737
    }
699
  else if (hdr->IsAssocResp ())
738
  else if (hdr->IsAssocResp () || hdr->IsReassocResp ())
700
    {
739
    {
701
      if (m_state == WAIT_ASSOC_RESP)
740
      if (m_state == WAIT_ASSOC_RESP)
702
        {
741
        {
 Lines 709-715    Link Here 
709
          if (assocResp.GetStatusCode ().IsSuccess ())
748
          if (assocResp.GetStatusCode ().IsSuccess ())
710
            {
749
            {
711
              SetState (ASSOCIATED);
750
              SetState (ASSOCIATED);
712
              NS_LOG_DEBUG ("assoc completed");
751
              if (hdr->IsReassocResp ())
752
                {
753
                  NS_LOG_DEBUG ("reassociation done");
754
                }
755
              else
756
                {
757
                  NS_LOG_DEBUG ("association completed");
758
                }
713
              CapabilityInformation capabilities = assocResp.GetCapabilities ();
759
              CapabilityInformation capabilities = assocResp.GetCapabilities ();
714
              SupportedRates rates = assocResp.GetSupportedRates ();
760
              SupportedRates rates = assocResp.GetSupportedRates ();
715
              bool isShortPreambleEnabled = capabilities.IsShortPreamble ();
761
              bool isShortPreambleEnabled = capabilities.IsShortPreamble ();
 Lines 869-875    Link Here 
869
            }
915
            }
870
          else
916
          else
871
            {
917
            {
872
              NS_LOG_DEBUG ("assoc refused");
918
              NS_LOG_DEBUG ("association refused");
873
              SetState (REFUSED);
919
              SetState (REFUSED);
874
            }
920
            }
875
        }
921
        }
 Lines 938-941    Link Here 
938
  edca->SetTxopLimit (txopLimit);
984
  edca->SetTxopLimit (txopLimit);
939
}
985
}
940
986
987
void
988
StaWifiMac::PhyCapabilitiesChanged (void)
989
{
990
  NS_LOG_FUNCTION (this);
991
  if (IsAssociated ())
992
    {
993
      NS_LOG_DEBUG ("PHY capabilities changed: send reassociation request");
994
      SetState (WAIT_ASSOC_RESP);
995
      SendAssociationRequest (true);
996
    }
997
}
998
941
} //namespace ns3
999
} //namespace ns3
(-)a/src/wifi/model/sta-wifi-mac.h (-3 / +17 lines)
 Lines 58-63    Link Here 
58
   */
58
   */
59
  void Enqueue (Ptr<const Packet> packet, Mac48Address to);
59
  void Enqueue (Ptr<const Packet> packet, Mac48Address to);
60
60
61
  /**
62
   * \param phy the physical layer attached to this MAC.
63
   */
64
  void SetWifiPhy (const Ptr<WifiPhy> phy);
65
61
66
62
private:
67
private:
63
  /**
68
  /**
 Lines 93-102    Link Here 
93
   */
98
   */
94
  void SendProbeRequest (void);
99
  void SendProbeRequest (void);
95
  /**
100
  /**
96
   * Forward an association request packet to the DCF. The standard is not clear on the correct
101
   * Forward an association or reassociation request packet to the DCF.
97
   * queue for management frames if QoS is supported. We always use the DCF.
102
   * The standard is not clear on the correct queue for management frames if QoS is supported.
103
   * We always use the DCF.
104
   *
105
   * \param isReassoc flag whether it is a reassociation request
106
   *
98
   */
107
   */
99
  void SendAssociationRequest (void);
108
  void SendAssociationRequest (bool isReassoc);
100
  /**
109
  /**
101
   * Try to ensure that we are associated with an AP by taking an appropriate action
110
   * Try to ensure that we are associated with an AP by taking an appropriate action
102
   * depending on the current association status.
111
   * depending on the current association status.
 Lines 164-169    Link Here 
164
   */
173
   */
165
  CapabilityInformation GetCapabilities (void) const;
174
  CapabilityInformation GetCapabilities (void) const;
166
175
176
  /**
177
   * Indicate that PHY capabilities have changed.
178
   */
179
  void PhyCapabilitiesChanged (void);
180
167
  MacState m_state;            ///< MAC state
181
  MacState m_state;            ///< MAC state
168
  Time m_probeRequestTimeout;  ///< probe request timeout
182
  Time m_probeRequestTimeout;  ///< probe request timeout
169
  Time m_assocRequestTimeout;  ///< assoc request timeout
183
  Time m_assocRequestTimeout;  ///< assoc request timeout
(-)a/src/wifi/model/wifi-net-device.cc (+1 lines)
 Lines 98-103    Link Here 
98
void
98
void
99
WifiNetDevice::DoInitialize (void)
99
WifiNetDevice::DoInitialize (void)
100
{
100
{
101
  NS_LOG_FUNCTION_NOARGS ();
101
  m_phy->Initialize ();
102
  m_phy->Initialize ();
102
  m_mac->Initialize ();
103
  m_mac->Initialize ();
103
  m_stationManager->Initialize ();
104
  m_stationManager->Initialize ();
(-)a/src/wifi/model/wifi-phy.cc (+22 lines)
 Lines 435-440    Link Here 
435
}
435
}
436
436
437
void
437
void
438
WifiPhy::SetCapabilitiesChangedCallback (Callback<void> callback)
439
{
440
  m_capabilitiesChangedCallback = callback;
441
}
442
443
void
438
WifiPhy::InitializeFrequencyChannelNumber (void)
444
WifiPhy::InitializeFrequencyChannelNumber (void)
439
{
445
{
440
  NS_LOG_FUNCTION (this);
446
  NS_LOG_FUNCTION (this);
 Lines 1267-1275    Link Here 
1267
void
1273
void
1268
WifiPhy::SetChannelWidth (uint8_t channelwidth)
1274
WifiPhy::SetChannelWidth (uint8_t channelwidth)
1269
{
1275
{
1276
  NS_LOG_FUNCTION (this << static_cast<uint16_t>(channelwidth));
1270
  NS_ASSERT_MSG (channelwidth == 5 || channelwidth == 10 || channelwidth == 20 || channelwidth == 22 || channelwidth == 40 || channelwidth == 80 || channelwidth == 160, "wrong channel width value");
1277
  NS_ASSERT_MSG (channelwidth == 5 || channelwidth == 10 || channelwidth == 20 || channelwidth == 22 || channelwidth == 40 || channelwidth == 80 || channelwidth == 160, "wrong channel width value");
1278
  bool changed = (m_channelWidth == channelwidth);
1271
  m_channelWidth = channelwidth;
1279
  m_channelWidth = channelwidth;
1272
  AddSupportedChannelWidth (channelwidth);
1280
  AddSupportedChannelWidth (channelwidth);
1281
  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1282
    {
1283
      m_capabilitiesChangedCallback ();
1284
    }
1273
}
1285
}
1274
1286
1275
uint8_t
1287
uint8_t
 Lines 1296-1303    Link Here 
1296
WifiPhy::SetMaxSupportedTxSpatialStreams (uint8_t streams)
1308
WifiPhy::SetMaxSupportedTxSpatialStreams (uint8_t streams)
1297
{
1309
{
1298
  NS_ASSERT (streams <= GetNumberOfAntennas ());
1310
  NS_ASSERT (streams <= GetNumberOfAntennas ());
1311
  bool changed = (m_txSpatialStreams == streams);
1299
  m_txSpatialStreams = streams;
1312
  m_txSpatialStreams = streams;
1300
  ConfigureHtDeviceMcsSet ();
1313
  ConfigureHtDeviceMcsSet ();
1314
  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1315
    {
1316
      m_capabilitiesChangedCallback ();
1317
    }
1301
}
1318
}
1302
1319
1303
uint8_t
1320
uint8_t
 Lines 1310-1316    Link Here 
1310
WifiPhy::SetMaxSupportedRxSpatialStreams (uint8_t streams)
1327
WifiPhy::SetMaxSupportedRxSpatialStreams (uint8_t streams)
1311
{
1328
{
1312
  NS_ASSERT (streams <= GetNumberOfAntennas ());
1329
  NS_ASSERT (streams <= GetNumberOfAntennas ());
1330
  bool changed = (m_rxSpatialStreams == streams);
1313
  m_rxSpatialStreams = streams;
1331
  m_rxSpatialStreams = streams;
1332
  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1333
    {
1334
      m_capabilitiesChangedCallback ();
1335
    }
1314
}
1336
}
1315
1337
1316
uint8_t
1338
uint8_t
(-)a/src/wifi/model/wifi-phy.h (+7 lines)
 Lines 258-263    Link Here 
258
  void UnregisterListener (WifiPhyListener *listener);
258
  void UnregisterListener (WifiPhyListener *listener);
259
259
260
  /**
260
  /**
261
   * \param callback the callback to invoke when PHY capabilities have changed.
262
   */
263
  void SetCapabilitiesChangedCallback (Callback<void> callback);
264
265
  /**
261
   * Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived).
266
   * Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived).
262
   *
267
   *
263
   * \param packet the arriving packet
268
   * \param packet the arriving packet
 Lines 1987-1992    Link Here 
1987
  Ptr<InterferenceHelper::Event> m_currentEvent; //!< Hold the current event
1992
  Ptr<InterferenceHelper::Event> m_currentEvent; //!< Hold the current event
1988
  Ptr<FrameCaptureModel> m_frameCaptureModel; //!< Frame capture model
1993
  Ptr<FrameCaptureModel> m_frameCaptureModel; //!< Frame capture model
1989
  Ptr<WifiRadioEnergyModel> m_wifiRadioEnergyModel; //!< Wifi radio energy model
1994
  Ptr<WifiRadioEnergyModel> m_wifiRadioEnergyModel; //!< Wifi radio energy model
1995
  
1996
  Callback<void> m_capabilitiesChangedCallback; //!< Callback when PHY capabilities changed
1990
};
1997
};
1991
1998
1992
/**
1999
/**
(-)a/src/wifi/test/wifi-test.cc (+164 lines)
 Lines 1343-1348    Link Here 
1343
  NS_TEST_ASSERT_MSG_EQ (std::get<3> (m_distinctTuples[1]), WifiModulationClass::WIFI_MOD_CLASS_VHT, "Second tuple should be VHT_OFDM");
1343
  NS_TEST_ASSERT_MSG_EQ (std::get<3> (m_distinctTuples[1]), WifiModulationClass::WIFI_MOD_CLASS_VHT, "Second tuple should be VHT_OFDM");
1344
}
1344
}
1345
1345
1346
//-----------------------------------------------------------------------------
1347
/**
1348
 * Make sure that the channel width and the channel number can be changed at runtime.
1349
 *
1350
 * The scenario considers an access point and a station using a 20 MHz channel width.
1351
 * After 1s, we change the channel width and the channel number to use a 40 MHz channel.
1352
 * The tests checks the operational channel width sent in Beacon frames
1353
 * and verify that a reassociation procedure is executed.
1354
 *
1355
 * See \bugid{2831}
1356
 */
1357
1358
class Bug2831TestCase : public TestCase
1359
{
1360
public:
1361
  Bug2831TestCase ();
1362
  virtual ~Bug2831TestCase ();
1363
  virtual void DoRun (void);
1364
1365
private:
1366
  void ChangeSupportedChannelWidth (void);
1367
  void RxCallback (std::string context, Ptr<const Packet> p);
1368
1369
  Ptr<YansWifiPhy> m_apPhy;
1370
  Ptr<YansWifiPhy> m_staPhy;
1371
1372
  uint8_t m_reassocReqCount;
1373
  uint8_t m_reassocRespCount;
1374
  uint8_t m_countOperationalChannelWidth20;
1375
  uint8_t m_countOperationalChannelWidth40;
1376
};
1377
1378
Bug2831TestCase::Bug2831TestCase ()
1379
  : TestCase ("Test case for Bug 2831"),
1380
    m_reassocReqCount (0),
1381
    m_reassocRespCount (0),
1382
    m_countOperationalChannelWidth20 (0),
1383
    m_countOperationalChannelWidth40 (0)
1384
{
1385
}
1386
1387
Bug2831TestCase::~Bug2831TestCase ()
1388
{
1389
}
1390
1391
void
1392
Bug2831TestCase::ChangeSupportedChannelWidth ()
1393
{
1394
  m_apPhy->SetChannelNumber (38);
1395
  m_apPhy->SetChannelWidth (40);
1396
  m_staPhy->SetChannelNumber (38);
1397
  m_staPhy->SetChannelWidth (40);
1398
}
1399
1400
void
1401
Bug2831TestCase::RxCallback (std::string context, Ptr<const Packet> p)
1402
{
1403
  Ptr<Packet> packet = p->Copy ();
1404
  WifiMacHeader hdr;
1405
  packet->RemoveHeader(hdr);
1406
  if (hdr.IsReassocReq ())
1407
    {
1408
      m_reassocReqCount++;
1409
    }
1410
  else if (hdr.IsReassocResp ())
1411
    {
1412
      m_reassocRespCount++;
1413
    }
1414
  else if (hdr.IsBeacon ())
1415
    {
1416
      MgtBeaconHeader beacon;
1417
      packet->RemoveHeader (beacon);
1418
      HtOperation htOperation = beacon.GetHtOperation ();
1419
      if (htOperation.GetStaChannelWidth () > 0)
1420
        {
1421
          m_countOperationalChannelWidth40++;
1422
        }
1423
      else
1424
        {
1425
          m_countOperationalChannelWidth20++;
1426
        }
1427
    }
1428
}
1429
1430
void
1431
Bug2831TestCase::DoRun (void)
1432
{
1433
  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
1434
  ObjectFactory propDelay;
1435
  propDelay.SetTypeId ("ns3::ConstantSpeedPropagationDelayModel");
1436
  Ptr<PropagationDelayModel> propagationDelay = propDelay.Create<PropagationDelayModel> ();
1437
  Ptr<PropagationLossModel> propagationLoss = CreateObject<RandomPropagationLossModel> ();
1438
  channel->SetPropagationDelayModel (propagationDelay);
1439
  channel->SetPropagationLossModel (propagationLoss);
1440
1441
  Ptr<Node> apNode = CreateObject<Node> ();
1442
  Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
1443
  ObjectFactory mac;
1444
  mac.SetTypeId ("ns3::ApWifiMac");
1445
  Ptr<WifiMac> apMac = mac.Create<WifiMac> ();
1446
  apMac->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
1447
  
1448
  Ptr<Node> staNode = CreateObject<Node> ();
1449
  Ptr<WifiNetDevice> staDev = CreateObject<WifiNetDevice> ();
1450
  mac.SetTypeId ("ns3::StaWifiMac");
1451
  Ptr<WifiMac> staMac = mac.Create<WifiMac> ();
1452
  staMac->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
1453
1454
  Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
1455
  apMobility->SetPosition (Vector (0.0, 0.0, 0.0));
1456
  apNode->AggregateObject (apMobility);
1457
1458
  Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
1459
  m_apPhy = CreateObject<YansWifiPhy> ();
1460
  m_apPhy->SetErrorRateModel (error);
1461
  m_apPhy->SetChannel (channel);
1462
  m_apPhy->SetMobility (apMobility);
1463
  m_apPhy->SetDevice (apDev);
1464
  m_apPhy->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
1465
  m_apPhy->SetChannelNumber (36);
1466
  m_apPhy->SetChannelWidth (20);
1467
1468
  Ptr<ConstantPositionMobilityModel> staMobility = CreateObject<ConstantPositionMobilityModel> ();
1469
  staMobility->SetPosition (Vector (1.0, 0.0, 0.0));
1470
  staNode->AggregateObject (staMobility);
1471
1472
  m_staPhy = CreateObject<YansWifiPhy> ();
1473
  m_staPhy->SetErrorRateModel (error);
1474
  m_staPhy->SetChannel (channel);
1475
  m_staPhy->SetMobility (staMobility);
1476
  m_staPhy->SetDevice (apDev);
1477
  m_staPhy->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
1478
  m_staPhy->SetChannelNumber (36);
1479
  m_staPhy->SetChannelWidth (20);
1480
1481
  apMac->SetAddress (Mac48Address::Allocate ());
1482
  apDev->SetMac (apMac);
1483
  apDev->SetPhy (m_apPhy);
1484
  ObjectFactory manager;
1485
  manager.SetTypeId ("ns3::ConstantRateWifiManager");
1486
  apDev->SetRemoteStationManager (manager.Create<WifiRemoteStationManager> ());
1487
  apNode->AddDevice (apDev);
1488
1489
  staMac->SetAddress (Mac48Address::Allocate ());
1490
  staDev->SetMac (staMac);
1491
  staDev->SetPhy (m_staPhy);
1492
  staDev->SetRemoteStationManager (manager.Create<WifiRemoteStationManager> ());
1493
  staNode->AddDevice (staDev);
1494
1495
  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin", MakeCallback (&Bug2831TestCase::RxCallback, this));
1496
1497
  Simulator::Schedule (Seconds (1.0), &Bug2831TestCase::ChangeSupportedChannelWidth, this);
1498
1499
  Simulator::Stop (Seconds (3.0));
1500
  Simulator::Run ();
1501
  Simulator::Destroy ();
1502
1503
  NS_TEST_ASSERT_MSG_EQ (m_reassocReqCount, 1, "Reassociation request not received");
1504
  NS_TEST_ASSERT_MSG_EQ (m_reassocRespCount, 1, "Reassociation response not received");
1505
  NS_TEST_ASSERT_MSG_EQ (m_countOperationalChannelWidth20, 10, "Incorrect operational channel width before channel change");
1506
  NS_TEST_ASSERT_MSG_EQ (m_countOperationalChannelWidth40, 20, "Incorrect operational channel width after channel change");
1507
}
1508
1346
/**
1509
/**
1347
 * \ingroup wifi-test
1510
 * \ingroup wifi-test
1348
 * \ingroup tests
1511
 * \ingroup tests
 Lines 1366-1371    Link Here 
1366
  AddTestCase (new SetChannelFrequencyTest, TestCase::QUICK);
1529
  AddTestCase (new SetChannelFrequencyTest, TestCase::QUICK);
1367
  AddTestCase (new Bug2222TestCase, TestCase::QUICK); //Bug 2222
1530
  AddTestCase (new Bug2222TestCase, TestCase::QUICK); //Bug 2222
1368
  AddTestCase (new Bug2483TestCase, TestCase::QUICK); //Bug 2483
1531
  AddTestCase (new Bug2483TestCase, TestCase::QUICK); //Bug 2483
1532
  AddTestCase (new Bug2831TestCase, TestCase::QUICK); //Bug 2831
1369
}
1533
}
1370
1534
1371
static WifiTestSuite g_wifiTestSuite; ///< the test suite
1535
static WifiTestSuite g_wifiTestSuite; ///< the test suite

Return to bug 2831