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

(-)a/src/wifi/model/minstrel-ht-wifi-manager.cc (-2 / +1 lines)
 Lines 976-983    Link Here 
976
      uint32_t mcsIndex = station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex;
976
      uint32_t mcsIndex = station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex;
977
977
978
      WifiMode lastRate = GetMcsSupported (station, mcsIndex);
978
      WifiMode lastRate = GetMcsSupported (station, mcsIndex);
979
      uint8_t streams = m_minstrelGroups[groupId].streams;
979
      uint64_t lastDataRate = lastRate.GetNonHtReferenceRate ();
980
      uint64_t lastDataRate = lastRate.GetNonHtReferenceRate (streams);
981
      uint32_t nBasicRates = GetNBasicModes ();
980
      uint32_t nBasicRates = GetNBasicModes ();
982
981
983
      WifiMode rtsRate;
982
      WifiMode rtsRate;
(-)a/src/wifi/model/nist-error-rate-model.cc (-12 / +11 lines)
 Lines 250-264    Link Here 
250
NistErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
250
NistErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
251
{
251
{
252
  NS_LOG_FUNCTION (this << mode << txVector.GetMode () << snr << nbits);
252
  NS_LOG_FUNCTION (this << mode << txVector.GetMode () << snr << nbits);
253
  uint8_t nss = txVector.GetNss ();
254
  if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
253
  if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
255
      || mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
254
      || mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
256
      || mode.GetModulationClass () == WIFI_MOD_CLASS_HT
255
      || mode.GetModulationClass () == WIFI_MOD_CLASS_HT
257
      || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
256
      || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
258
    {
257
    {
259
      if (mode.GetConstellationSize (nss) == 2)
258
      if (mode.GetConstellationSize () == 2)
260
        {
259
        {
261
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_1_2)
260
          if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
262
            {
261
            {
263
              return GetFecBpskBer (snr,
262
              return GetFecBpskBer (snr,
264
                                    nbits,
263
                                    nbits,
 Lines 271-279    Link Here 
271
                                    3); //b value
270
                                    3); //b value
272
            }
271
            }
273
        }
272
        }
274
      else if (mode.GetConstellationSize (nss) == 4)
273
      else if (mode.GetConstellationSize () == 4)
275
        {
274
        {
276
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_1_2)
275
          if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
277
            {
276
            {
278
              return GetFecQpskBer (snr,
277
              return GetFecQpskBer (snr,
279
                                    nbits,
278
                                    nbits,
 Lines 286-294    Link Here 
286
                                    3); //b value
285
                                    3); //b value
287
            }
286
            }
288
        }
287
        }
289
      else if (mode.GetConstellationSize (nss) == 16)
288
      else if (mode.GetConstellationSize () == 16)
290
        {
289
        {
291
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_1_2)
290
          if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
292
            {
291
            {
293
              return GetFec16QamBer (snr,
292
              return GetFec16QamBer (snr,
294
                                     nbits,
293
                                     nbits,
 Lines 301-315    Link Here 
301
                                     3); //b value
300
                                     3); //b value
302
            }
301
            }
303
        }
302
        }
304
      else if (mode.GetConstellationSize (nss) == 64)
303
      else if (mode.GetConstellationSize () == 64)
305
        {
304
        {
306
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_2_3)
305
          if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
307
            {
306
            {
308
              return GetFec64QamBer (snr,
307
              return GetFec64QamBer (snr,
309
                                     nbits,
308
                                     nbits,
310
                                     2); //b value
309
                                     2); //b value
311
            }
310
            }
312
          else if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_5_6)
311
          else if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
313
            {
312
            {
314
              return GetFec64QamBer (snr,
313
              return GetFec64QamBer (snr,
315
                                     nbits,
314
                                     nbits,
 Lines 322-330    Link Here 
322
                                     3); //b value
321
                                     3); //b value
323
            }
322
            }
324
        }
323
        }
325
      else if (mode.GetConstellationSize (nss) == 256)
324
      else if (mode.GetConstellationSize () == 256)
326
        {
325
        {
327
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_5_6)
326
          if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
328
            {
327
            {
329
              return GetFec256QamBer (snr,
328
              return GetFec256QamBer (snr,
330
                                      nbits,
329
                                      nbits,
(-)a/src/wifi/model/wifi-mode.cc (-17 / +93 lines)
 Lines 73-81    Link Here 
73
uint64_t
73
uint64_t
74
WifiMode::GetPhyRate (uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
74
WifiMode::GetPhyRate (uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
75
{
75
{
76
  //TODO: nss > 4 not supported yet
77
  NS_ASSERT (nss <= 4);
76
  uint32_t dataRate, phyRate;
78
  uint32_t dataRate, phyRate;
77
  dataRate = GetDataRate (channelWidth, isShortGuardInterval, nss);
79
  dataRate = GetDataRate (channelWidth, isShortGuardInterval, nss);
78
  switch (GetCodeRate (nss))
80
  switch (GetCodeRate ())
79
    {
81
    {
80
    case WIFI_CODE_RATE_5_6:
82
    case WIFI_CODE_RATE_5_6:
81
      phyRate = dataRate * 6 / 5;
83
      phyRate = dataRate * 6 / 5;
 Lines 106-120    Link Here 
106
uint64_t
108
uint64_t
107
WifiMode::GetDataRate (uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
109
WifiMode::GetDataRate (uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
108
{
110
{
111
  //TODO: nss > 4 not supported yet
112
  NS_ASSERT (nss <= 4);
109
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
113
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
110
  uint64_t dataRate = 0;
114
  uint64_t dataRate = 0;
111
  if (item->modClass == WIFI_MOD_CLASS_DSSS)
115
  if (item->modClass == WIFI_MOD_CLASS_DSSS)
112
    {
116
    {
113
      dataRate = (11000000 / 11) * log2 (GetConstellationSize (nss));
117
      dataRate = (11000000 / 11) * log2 (GetConstellationSize ());
114
    }
118
    }
115
  else if (item->modClass == WIFI_MOD_CLASS_HR_DSSS)
119
  else if (item->modClass == WIFI_MOD_CLASS_HR_DSSS)
116
    {
120
    {
117
      dataRate = (11000000 / 8) * log2 (GetConstellationSize (nss));
121
      dataRate = (11000000 / 8) * log2 (GetConstellationSize ());
118
    }
122
    }
119
  else if (item->modClass == WIFI_MOD_CLASS_OFDM || item->modClass == WIFI_MOD_CLASS_ERP_OFDM)
123
  else if (item->modClass == WIFI_MOD_CLASS_OFDM || item->modClass == WIFI_MOD_CLASS_ERP_OFDM)
120
    {
124
    {
 Lines 136-142    Link Here 
136
        }
140
        }
137
141
138
      double codingRate;
142
      double codingRate;
139
      switch (GetCodeRate (nss))
143
      switch (GetCodeRate ())
140
        {
144
        {
141
        case WIFI_CODE_RATE_3_4:
145
        case WIFI_CODE_RATE_3_4:
142
          codingRate = (3.0 / 4.0);
146
          codingRate = (3.0 / 4.0);
 Lines 153-159    Link Here 
153
          break;
157
          break;
154
        }
158
        }
155
159
156
      uint32_t numberOfBitsPerSubcarrier = log2 (GetConstellationSize (nss));
160
      uint32_t numberOfBitsPerSubcarrier = log2 (GetConstellationSize ());
157
161
158
      dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
162
      dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
159
    }
163
    }
 Lines 198-204    Link Here 
198
        }
202
        }
199
203
200
      double codingRate;
204
      double codingRate;
201
      switch (GetCodeRate (nss))
205
      switch (GetCodeRate ())
202
        {
206
        {
203
        case WIFI_CODE_RATE_5_6:
207
        case WIFI_CODE_RATE_5_6:
204
          codingRate = (5.0 / 6.0);
208
          codingRate = (5.0 / 6.0);
 Lines 218-224    Link Here 
218
          break;
222
          break;
219
        }
223
        }
220
224
221
      uint32_t numberOfBitsPerSubcarrier = log2 (GetConstellationSize (nss));
225
      uint32_t numberOfBitsPerSubcarrier = log2 (GetConstellationSize ());
222
226
223
      dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
227
      dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
224
    }
228
    }
 Lines 237-248    Link Here 
237
}
241
}
238
242
239
enum WifiCodeRate
243
enum WifiCodeRate
240
WifiMode::GetCodeRate (uint8_t nss) const
244
WifiMode::GetCodeRate (void) const
241
{
245
{
242
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
246
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
243
  if (item->modClass == WIFI_MOD_CLASS_HT)
247
  if (item->modClass == WIFI_MOD_CLASS_HT)
244
    {
248
    {
245
      NS_ASSERT (nss <= 4);
246
      switch (item->mcsValue % 8)
249
      switch (item->mcsValue % 8)
247
        {
250
        {
248
        case 0:
251
        case 0:
 Lines 263-269    Link Here 
263
    }
266
    }
264
  else if (item->modClass == WIFI_MOD_CLASS_VHT)
267
  else if (item->modClass == WIFI_MOD_CLASS_VHT)
265
    {
268
    {
266
      NS_ASSERT (nss <= 8);
267
      switch (item->mcsValue)
269
      switch (item->mcsValue)
268
        {
270
        {
269
        case 0:
271
        case 0:
 Lines 291-303    Link Here 
291
}
293
}
292
294
293
uint16_t
295
uint16_t
294
WifiMode::GetConstellationSize (uint8_t nss) const
296
WifiMode::GetConstellationSize (void) const
295
{
297
{
296
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
298
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
297
  if (item->modClass == WIFI_MOD_CLASS_HT)
299
  if (item->modClass == WIFI_MOD_CLASS_HT)
298
    {
300
    {
299
      NS_ASSERT (nss <= 4);
300
      NS_ASSERT ((item->mcsValue - (8 * (nss - 1))) >= 0 || (item->mcsValue - (8 * (nss - 1))) <= 7);
301
      switch (item->mcsValue % 8)
301
      switch (item->mcsValue % 8)
302
        {
302
        {
303
        case 0:
303
        case 0:
 Lines 318-324    Link Here 
318
    }
318
    }
319
  else if (item->modClass == WIFI_MOD_CLASS_VHT)
319
  else if (item->modClass == WIFI_MOD_CLASS_VHT)
320
    {
320
    {
321
      NS_ASSERT (nss <= 8);
322
      switch (item->mcsValue)
321
      switch (item->mcsValue)
323
        {
322
        {
324
        case 0:
323
        case 0:
 Lines 391-404    Link Here 
391
}
390
}
392
391
393
uint64_t
392
uint64_t
394
WifiMode::GetNonHtReferenceRate (uint8_t nss) const
393
WifiMode::GetNonHtReferenceRate (void) const
395
{
394
{
396
  uint64_t dataRate;
395
  uint64_t dataRate;
397
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
396
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
398
  if (item->modClass == WIFI_MOD_CLASS_HT || item->modClass == WIFI_MOD_CLASS_VHT)
397
  if (item->modClass == WIFI_MOD_CLASS_HT || item->modClass == WIFI_MOD_CLASS_VHT)
399
    {
398
    {
400
      WifiCodeRate codeRate = GetCodeRate(nss);
399
      WifiCodeRate codeRate = GetCodeRate();
401
      switch(GetConstellationSize(nss))
400
      switch(GetConstellationSize())
402
        {
401
        {
403
        case 2:
402
        case 2:
404
          if (codeRate == WIFI_CODE_RATE_1_2)
403
          if (codeRate == WIFI_CODE_RATE_1_2)
 Lines 449-454    Link Here 
449
  return dataRate;
448
  return dataRate;
450
}
449
}
451
450
451
bool
452
WifiMode::IsHigherCodeRate (WifiMode mode) const
453
{
454
  WifiCodeRate codeRate = mode.GetCodeRate ();
455
  switch (GetCodeRate ())
456
    {
457
    case WIFI_CODE_RATE_1_2:
458
      return false; //This is the smallest code rate.
459
    case WIFI_CODE_RATE_2_3:
460
      return (codeRate == WIFI_CODE_RATE_1_2);
461
    case WIFI_CODE_RATE_3_4:
462
      return (codeRate == WIFI_CODE_RATE_1_2 || codeRate == WIFI_CODE_RATE_2_3);
463
    case WIFI_CODE_RATE_5_6:
464
      return (codeRate == WIFI_CODE_RATE_1_2 || codeRate == WIFI_CODE_RATE_2_3 || codeRate == WIFI_CODE_RATE_3_4);
465
    default:
466
      NS_FATAL_ERROR ("Wifi Code Rate not defined");
467
      return false;
468
    }
469
}
470
471
bool
472
WifiMode::IsHigherDataRate (WifiMode mode) const
473
{
474
  struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
475
  switch(item->modClass)
476
    {
477
    case WIFI_MOD_CLASS_DSSS:
478
      if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS)
479
        {
480
          return (GetConstellationSize () > mode.GetConstellationSize ());
481
        }
482
      else
483
        {
484
          return false;
485
        }
486
    case WIFI_MOD_CLASS_HR_DSSS:
487
      if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS)
488
        {
489
          return true;
490
        }
491
      else
492
        {
493
          return (GetConstellationSize () > mode.GetConstellationSize ());
494
        }
495
    case WIFI_MOD_CLASS_ERP_OFDM:
496
    case WIFI_MOD_CLASS_OFDM:
497
    case WIFI_MOD_CLASS_HT:
498
    case WIFI_MOD_CLASS_VHT:
499
      if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS)
500
        {
501
          return true;
502
        }
503
      else if (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)
504
        {
505
          return (mode.GetConstellationSize () > GetConstellationSize ());
506
        }
507
      else
508
        {
509
          if (GetConstellationSize () > mode.GetConstellationSize ())
510
            {
511
              return true;
512
            }
513
          else if (GetConstellationSize () == mode.GetConstellationSize ())
514
            {
515
              return IsHigherCodeRate (mode);
516
            }
517
          else
518
            {
519
              return false;
520
            }
521
        }
522
    default:
523
      NS_FATAL_ERROR ("Modulation class not defined");
524
      return false;
525
    }
526
}
527
452
WifiMode::WifiMode ()
528
WifiMode::WifiMode ()
453
  : m_uid (0)
529
  : m_uid (0)
454
{
530
{
(-)a/src/wifi/model/wifi-mode.h (-9 / +13 lines)
 Lines 136-154    Link Here 
136
   */
136
   */
137
  uint64_t GetDataRate (WifiTxVector txVector) const;
137
  uint64_t GetDataRate (WifiTxVector txVector) const;
138
  /**
138
  /**
139
   *
140
   * \param nss the considered number of streams
141
   *
142
   * \returns the coding rate of this transmission mode
139
   * \returns the coding rate of this transmission mode
143
   */
140
   */
144
  enum WifiCodeRate GetCodeRate (uint8_t nss) const;
141
  enum WifiCodeRate GetCodeRate (void) const;
145
  /**
142
  /**
146
   *
147
   * \param nss the considered number of streams
148
   *
149
   * \returns the size of the modulation constellation.
143
   * \returns the size of the modulation constellation.
150
   */
144
   */
151
  uint16_t GetConstellationSize (uint8_t nss) const;
145
  uint16_t GetConstellationSize (void) const;
152
  /**
146
  /**
153
   * \returns the MCS value.
147
   * \returns the MCS value.
154
   */
148
   */
 Lines 185-191    Link Here 
185
   * use the modulation and coding rate of the HT MCS
179
   * use the modulation and coding rate of the HT MCS
186
   * and lookup in Table 9-5 of IEEE 802.11-2012.
180
   * and lookup in Table 9-5 of IEEE 802.11-2012.
187
   */
181
   */
188
  uint64_t GetNonHtReferenceRate (uint8_t nss) const;
182
  uint64_t GetNonHtReferenceRate (void) const;
183
  /**
184
   * \returns true if this WifiMode has a
185
   * a code rate strictly higher than mode.
186
   */
187
  bool IsHigherCodeRate (WifiMode mode) const;
188
  /**
189
   * \returns true if this WifiMode has a
190
   * a rate strictly higher than mode.
191
   */
192
  bool IsHigherDataRate (WifiMode mode) const;
189
193
190
  /**
194
  /**
191
   * Create an invalid WifiMode. Calling any method on the
195
   * Create an invalid WifiMode. Calling any method on the
(-)a/src/wifi/model/wifi-remote-station-manager.cc (-25 / +34 lines)
 Lines 1107-1112    Link Here 
1107
  return isLast;
1107
  return isLast;
1108
}
1108
}
1109
1109
1110
bool
1111
WifiRemoteStationManager::IsAllowedControlAnswerModulationClass (enum WifiModulationClass modClassReq, enum WifiModulationClass modClassAnswer) const
1112
{
1113
  switch (modClassReq)
1114
    {
1115
    case WIFI_MOD_CLASS_DSSS:
1116
      return (modClassAnswer == WIFI_MOD_CLASS_DSSS);
1117
    case WIFI_MOD_CLASS_HR_DSSS:
1118
      return (modClassAnswer == WIFI_MOD_CLASS_DSSS || modClassAnswer == WIFI_MOD_CLASS_HR_DSSS);
1119
    case WIFI_MOD_CLASS_ERP_OFDM:
1120
      return (modClassAnswer == WIFI_MOD_CLASS_DSSS || modClassAnswer == WIFI_MOD_CLASS_HR_DSSS || modClassAnswer == WIFI_MOD_CLASS_ERP_OFDM);
1121
    case WIFI_MOD_CLASS_OFDM:
1122
      return (modClassAnswer == WIFI_MOD_CLASS_OFDM);
1123
    case WIFI_MOD_CLASS_HT:
1124
    case WIFI_MOD_CLASS_VHT:
1125
      return true;
1126
    default:
1127
      NS_FATAL_ERROR ("Modulation class not defined");
1128
      return false;
1129
    }
1130
}
1131
1110
WifiMode
1132
WifiMode
1111
WifiRemoteStationManager::GetControlAnswerMode (Mac48Address address, WifiMode reqMode)
1133
WifiRemoteStationManager::GetControlAnswerMode (Mac48Address address, WifiMode reqMode)
1112
{
1134
{
 Lines 1127-1143    Link Here 
1127
  NS_LOG_FUNCTION (this << address << reqMode);
1149
  NS_LOG_FUNCTION (this << address << reqMode);
1128
  WifiMode mode = GetDefaultMode ();
1150
  WifiMode mode = GetDefaultMode ();
1129
  bool found = false;
1151
  bool found = false;
1130
  uint8_t nss = 1;  // Use one spatial stream for control response
1131
  //First, search the BSS Basic Rate set
1152
  //First, search the BSS Basic Rate set
1132
  for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++)
1153
  for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++)
1133
    {
1154
    {
1134
      if ((!found || i->GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss))
1155
      if ((!found || i->IsHigherDataRate (mode))
1135
          && (i->GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss))
1156
          && (!i->IsHigherDataRate (reqMode))
1136
          && (i->GetConstellationSize (nss) <= reqMode.GetConstellationSize (nss))
1157
          && (IsAllowedControlAnswerModulationClass (reqMode.GetModulationClass (), i->GetModulationClass ())))
1137
          && ((i->GetModulationClass () == reqMode.GetModulationClass ())
1138
              || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
1139
              || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)))
1140
1141
        {
1158
        {
1142
          mode = *i;
1159
          mode = *i;
1143
          //We've found a potentially-suitable transmit rate, but we
1160
          //We've found a potentially-suitable transmit rate, but we
 Lines 1146-1152    Link Here 
1146
          found = true;
1163
          found = true;
1147
        }
1164
        }
1148
    }
1165
    }
1149
  nss = 1;  // Continue the assumption that MIMO not used for control response
1150
  if (HasHtSupported () || HasVhtSupported ())
1166
  if (HasHtSupported () || HasVhtSupported ())
1151
    {
1167
    {
1152
      if (!found)
1168
      if (!found)
 Lines 1154-1162    Link Here 
1154
          mode = GetDefaultMcs ();
1170
          mode = GetDefaultMcs ();
1155
          for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++)
1171
          for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++)
1156
            {
1172
            {
1157
              if ((!found || i->GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss))
1173
              if ((!found || i->IsHigherDataRate (mode))
1158
                  && i->GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss))
1174
                  && (!i->IsHigherDataRate (reqMode))
1159
              //&& thismode.GetModulationClass () == reqMode.GetModulationClass ()) //TODO: check standard
1175
                  && (i->GetModulationClass () == reqMode.GetModulationClass ()))
1160
                {
1176
                {
1161
                  mode = *i;
1177
                  mode = *i;
1162
                  //We've found a potentially-suitable transmit rate, but we
1178
                  //We've found a potentially-suitable transmit rate, but we
 Lines 1192-1202    Link Here 
1192
   * \todo Note that we're ignoring the last sentence for now, because
1208
   * \todo Note that we're ignoring the last sentence for now, because
1193
   * there is not yet any manipulation here of PHY options.
1209
   * there is not yet any manipulation here of PHY options.
1194
   */
1210
   */
1195
  nss = 1;  // Continue the assumption that MIMO not used for control response
1196
  for (uint32_t idx = 0; idx < m_wifiPhy->GetNModes (); idx++)
1211
  for (uint32_t idx = 0; idx < m_wifiPhy->GetNModes (); idx++)
1197
    {
1212
    {
1198
      WifiMode thismode = m_wifiPhy->GetMode (idx);
1213
      WifiMode thismode = m_wifiPhy->GetMode (idx);
1199
1200
      /* If the rate:
1214
      /* If the rate:
1201
       *
1215
       *
1202
       *  - is a mandatory rate for the PHY, and
1216
       *  - is a mandatory rate for the PHY, and
 Lines 1207-1219    Link Here 
1207
       * ...then it's our best choice so far.
1221
       * ...then it's our best choice so far.
1208
       */
1222
       */
1209
      if (thismode.IsMandatory ()
1223
      if (thismode.IsMandatory ()
1210
          && (!found || thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss))
1224
          && (!found || thismode.IsHigherDataRate (mode))
1211
          && (thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss))
1225
          && (!thismode.IsHigherDataRate (reqMode))
1212
          && (thismode.GetConstellationSize (nss) <= reqMode.GetConstellationSize (nss))
1226
          && (IsAllowedControlAnswerModulationClass (reqMode.GetModulationClass (), thismode.GetModulationClass ())))
1213
          && ((thismode.GetModulationClass () == reqMode.GetModulationClass ())
1214
              || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
1215
              || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT)))
1216
1217
        {
1227
        {
1218
          mode = thismode;
1228
          mode = thismode;
1219
          //As above; we've found a potentially-suitable transmit
1229
          //As above; we've found a potentially-suitable transmit
 Lines 1222-1237    Link Here 
1222
          found = true;
1232
          found = true;
1223
        }
1233
        }
1224
    }
1234
    }
1225
  nss = 1;  // Continue the assumption that MIMO not used for control response
1226
  if (HasHtSupported () || HasVhtSupported ())
1235
  if (HasHtSupported () || HasVhtSupported ())
1227
    {
1236
    {
1228
      for (uint32_t idx = 0; idx < m_wifiPhy->GetNMcs (); idx++)
1237
      for (uint32_t idx = 0; idx < m_wifiPhy->GetNMcs (); idx++)
1229
        {
1238
        {
1230
          WifiMode thismode = m_wifiPhy->GetMcs (idx);
1239
          WifiMode thismode = m_wifiPhy->GetMcs (idx);
1231
          if (thismode.IsMandatory ()
1240
          if (thismode.IsMandatory ()
1232
              && (!found || thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss))
1241
              && (!found || thismode.IsHigherDataRate (mode))
1233
              && thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, nss))
1242
              && (!thismode.IsHigherCodeRate(reqMode))
1234
              //&& thismode.GetModulationClass () == reqMode.GetModulationClass ()) //TODO: check standard
1243
              && (thismode.GetModulationClass () == reqMode.GetModulationClass ()))
1235
            {
1244
            {
1236
              mode = thismode;
1245
              mode = thismode;
1237
              //As above; we've found a potentially-suitable transmit
1246
              //As above; we've found a potentially-suitable transmit
(-)a/src/wifi/model/wifi-remote-station-manager.h (+12 lines)
 Lines 1140-1145    Link Here 
1140
   */
1140
   */
1141
  WifiRemoteStation* Lookup (Mac48Address address, const WifiMacHeader *header) const;
1141
  WifiRemoteStation* Lookup (Mac48Address address, const WifiMacHeader *header) const;
1142
1142
1143
  /**
1144
   * Return whether the modulation class of the selected mode for the 
1145
   * control answer frame is allowed.
1146
   *
1147
   * \param modClassReq modulation class of the request frame
1148
   * \param modClassAnswer modulation class of the answer frame
1149
   *
1150
   * \return true if the modulation class of the selected mode for the 
1151
   * control answer frame is allowed, false otherwise
1152
   */
1153
  bool IsAllowedControlAnswerModulationClass (enum WifiModulationClass modClassReq, enum WifiModulationClass modClassAnswer) const;
1154
1143
  WifiMode GetControlAnswerMode (Mac48Address address, WifiMode reqMode);
1155
  WifiMode GetControlAnswerMode (Mac48Address address, WifiMode reqMode);
1144
1156
1145
  /**
1157
  /**
(-)a/src/wifi/model/yans-error-rate-model.cc (-12 / +11 lines)
 Lines 188-202    Link Here 
188
YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
188
YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
189
{
189
{
190
  NS_LOG_FUNCTION (this << mode << txVector.GetMode () << snr << nbits);
190
  NS_LOG_FUNCTION (this << mode << txVector.GetMode () << snr << nbits);
191
  uint8_t nss = txVector.GetNss ();
192
  if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
191
  if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
193
      || mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
192
      || mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
194
      || mode.GetModulationClass () == WIFI_MOD_CLASS_HT
193
      || mode.GetModulationClass () == WIFI_MOD_CLASS_HT
195
      || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
194
      || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
196
    {
195
    {
197
      if (mode.GetConstellationSize (nss) == 2)
196
      if (mode.GetConstellationSize () == 2)
198
        {
197
        {
199
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_1_2)
198
          if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
200
            {
199
            {
201
              return GetFecBpskBer (snr,
200
              return GetFecBpskBer (snr,
202
                                    nbits,
201
                                    nbits,
 Lines 215-223    Link Here 
215
                                    8); //adFree
214
                                    8); //adFree
216
            }
215
            }
217
        }
216
        }
218
      else if (mode.GetConstellationSize (nss) == 4)
217
      else if (mode.GetConstellationSize () == 4)
219
        {
218
        {
220
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_1_2)
219
          if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
221
            {
220
            {
222
              return GetFecQamBer (snr,
221
              return GetFecQamBer (snr,
223
                                   nbits,
222
                                   nbits,
 Lines 240-248    Link Here 
240
                                   31); //adFreePlusOne
239
                                   31); //adFreePlusOne
241
            }
240
            }
242
        }
241
        }
243
      else if (mode.GetConstellationSize (nss) == 16)
242
      else if (mode.GetConstellationSize () == 16)
244
        {
243
        {
245
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_1_2)
244
          if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
246
            {
245
            {
247
              return GetFecQamBer (snr,
246
              return GetFecQamBer (snr,
248
                                   nbits,
247
                                   nbits,
 Lines 265-273    Link Here 
265
                                   31); //adFreePlusOne
264
                                   31); //adFreePlusOne
266
            }
265
            }
267
        }
266
        }
268
      else if (mode.GetConstellationSize (nss) == 64)
267
      else if (mode.GetConstellationSize () == 64)
269
        {
268
        {
270
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_2_3)
269
          if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
271
            {
270
            {
272
              return GetFecQamBer (snr,
271
              return GetFecQamBer (snr,
273
                                   nbits,
272
                                   nbits,
 Lines 278-284    Link Here 
278
                                   1, //adFree
277
                                   1, //adFree
279
                                   16); //adFreePlusOne
278
                                   16); //adFreePlusOne
280
            }
279
            }
281
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_5_6)
280
          if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
282
            {
281
            {
283
              //Table B.32  in Pâl Frenger et al., "Multi-rate Convolutional Codes".
282
              //Table B.32  in Pâl Frenger et al., "Multi-rate Convolutional Codes".
284
              return GetFecQamBer (snr,
283
              return GetFecQamBer (snr,
 Lines 302-310    Link Here 
302
                                   31); //adFreePlusOne
301
                                   31); //adFreePlusOne
303
            }
302
            }
304
        }
303
        }
305
      else if (mode.GetConstellationSize (nss) == 256)
304
      else if (mode.GetConstellationSize () == 256)
306
        {
305
        {
307
          if (mode.GetCodeRate (nss) == WIFI_CODE_RATE_5_6)
306
          if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
308
            {
307
            {
309
              return GetFecQamBer (snr,
308
              return GetFecQamBer (snr,
310
                                   nbits,
309
                                   nbits,

Return to bug 2338