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

(-)a/src/wifi/examples/ideal-wifi-manager-example.cc (-3 / +3 lines)
 Lines 59-67    Link Here 
59
}
59
}
60
60
61
void
61
void
62
RateChange (uint64_t oldVal, uint64_t newVal)
62
RateChange (uint64_t newVal, Mac48Address peer)
63
{
63
{
64
  NS_LOG_DEBUG ("Change from " << oldVal << " to " << newVal);
64
  NS_LOG_DEBUG ("Change to " << newVal << " for station " << peer);
65
  g_intervalRate = newVal;
65
  g_intervalRate = newVal;
66
}
66
}
67
67
 Lines 247-253    Link Here 
247
  serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
247
  serverDevice = wifi.Install (wifiPhy, wifiMac, serverNode);
248
  clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
248
  clientDevice = wifi.Install (wifiPhy, wifiMac, clientNode);
249
249
250
  Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::IdealWifiManager/Rate", MakeCallback(&RateChange)); 
250
  Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/RemoteStationManager/$ns3::IdealWifiManager/RateChange", MakeCallback(&RateChange)); 
251
  // Configure the mobility.
251
  // Configure the mobility.
252
  MobilityHelper mobility;
252
  MobilityHelper mobility;
253
 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
253
 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
(-)a/src/wifi/model/ideal-wifi-manager.cc (-131 / +297 lines)
 Lines 36-43    Link Here 
36
struct IdealWifiRemoteStation : public WifiRemoteStation
36
struct IdealWifiRemoteStation : public WifiRemoteStation
37
{
37
{
38
  double m_lastSnrObserved;  //!< SNR of most recently reported packet sent to the remote station
38
  double m_lastSnrObserved;  //!< SNR of most recently reported packet sent to the remote station
39
  double m_lastSnrCached;    //!< SNR most recently used to select a rate
39
  double m_lastSnrUsed;    //!< SNR most recently used to select a rate
40
  double m_nss;          //!< SNR most recently used to select a rate
40
  uint64_t m_lastRate;       //!< last data rate used towards the station
41
  double m_nss;              //!< nss most recently used towards the station
41
  WifiMode m_lastMode;       //!< Mode most recently used to the remote station
42
  WifiMode m_lastMode;       //!< Mode most recently used to the remote station
42
};
43
};
43
44
 Lines 57-72    Link Here 
57
                   DoubleValue (1e-5),
58
                   DoubleValue (1e-5),
58
                   MakeDoubleAccessor (&IdealWifiManager::m_ber),
59
                   MakeDoubleAccessor (&IdealWifiManager::m_ber),
59
                   MakeDoubleChecker<double> ())
60
                   MakeDoubleChecker<double> ())
60
    .AddTraceSource ("Rate",
61
    .AddTraceSource ("RateChange",
61
                     "Traced value for rate changes (b/s)",
62
                     "The transmission rate has changed",
62
                     MakeTraceSourceAccessor (&IdealWifiManager::m_currentRate),
63
                     MakeTraceSourceAccessor (&IdealWifiManager::m_rateChange),
63
                     "ns3::TracedValueCallback::Uint64")
64
                     "ns3::IdealWifiManager::RateChangeTracedCallback")
64
  ;
65
  ;
65
  return tid;
66
  return tid;
66
}
67
}
67
68
68
IdealWifiManager::IdealWifiManager ()
69
IdealWifiManager::IdealWifiManager ()
69
 : m_currentRate (0)
70
{
70
{
71
}
71
}
72
72
 Lines 118-124    Link Here 
118
                    " short GI " << GetPhy ()->GetGuardInterval ());
118
                    " short GI " << GetPhy ()->GetGuardInterval ());
119
      AddSnrThreshold (txVector, GetPhy ()->CalculateSnr (txVector, m_ber));
119
      AddSnrThreshold (txVector, GetPhy ()->CalculateSnr (txVector, m_ber));
120
    }
120
    }
121
  // Add all Ht and Vht MCSes 
121
  // Add all supported Ht and Vht MCSes 
122
  txVector.SetChannelWidth (GetPhy ()->GetChannelWidth ());
122
  txVector.SetChannelWidth (GetPhy ()->GetChannelWidth ());
123
  if (HasVhtSupported () == true || HasHtSupported () == true )
123
  if (HasVhtSupported () == true || HasHtSupported () == true )
124
    {
124
    {
 Lines 126-148    Link Here 
126
      for (uint32_t i = 0; i < nModes; i++)
126
      for (uint32_t i = 0; i < nModes; i++)
127
        {
127
        {
128
          mode = GetPhy ()->GetMcs (i);
128
          mode = GetPhy ()->GetMcs (i);
129
          if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
129
          txVector.SetMode (mode);
130
          for (uint8_t j = 1; j <= GetPhy ()->GetSupportedTxSpatialStreams (); j++)
130
            {
131
            {
131
              //derive NSS from the Mcs index
132
              if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
132
              nss = (mode.GetMcsValue () / 8) + 1;
133
                {
134
                  //derive NSS from the Mcs index
135
                  nss = (mode.GetMcsValue () / 8) + 1;
136
                  if (nss != j)
137
                    {
138
                      continue;
139
                    }
140
                }
141
              else
142
                {
143
                  nss = j;
144
                }
145
              txVector.SetNss (nss);
146
              if (IsSupportedTxVector (txVector) && WifiPhy::IsValidTxVector (txVector))
147
                {
148
                  NS_LOG_DEBUG ("Initialize, adding mode = " << mode.GetUniqueName () <<
149
                                " channel width " << GetPhy ()->GetChannelWidth () <<
150
                                " nss " << (uint16_t) nss << 
151
                               " short GI " << GetPhy ()->GetGuardInterval ());
152
                  AddSnrThreshold (txVector, GetPhy ()->CalculateSnr (txVector, m_ber));
153
                }
154
              else
155
                {
156
                  NS_LOG_DEBUG ("Skipping mode " << mode.GetUniqueName () << " as unsupported");
157
                }
133
            }
158
            }
134
          else
135
            {
136
              nss = GetPhy ()->GetSupportedTxSpatialStreams ();
137
            }
138
          NS_LOG_DEBUG ("Initialize, adding mode = " << mode.GetUniqueName () <<
139
                        " channel width " << GetPhy ()->GetChannelWidth () <<
140
                        " nss " << (uint16_t) nss << 
141
                        " short GI " << GetPhy ()->GetGuardInterval ());
142
          NS_LOG_DEBUG ("In SetupPhy, adding mode = " << mode.GetUniqueName ());
143
          txVector.SetNss (nss);
144
          txVector.SetMode (mode);
145
          AddSnrThreshold (txVector, GetPhy ()->CalculateSnr (txVector, m_ber));
146
        }
159
        }
147
    }
160
    }
148
}
161
}
 Lines 184-190    Link Here 
184
  NS_LOG_FUNCTION (this);
197
  NS_LOG_FUNCTION (this);
185
  IdealWifiRemoteStation *station = new IdealWifiRemoteStation ();
198
  IdealWifiRemoteStation *station = new IdealWifiRemoteStation ();
186
  station->m_lastSnrObserved = 0.0;
199
  station->m_lastSnrObserved = 0.0;
187
  station->m_lastSnrCached = 0.0;
200
  station->m_lastSnrUsed = -100.0;
201
  station->m_lastRate = 0;
188
  station->m_lastMode = GetDefaultMode ();
202
  station->m_lastMode = GetDefaultMode ();
189
  station->m_nss = 1;
203
  station->m_nss = 1;
190
  return station;
204
  return station;
 Lines 254-376    Link Here 
254
{
268
{
255
}
269
}
256
270
271
// This check is encapsulated in case any more sophisticated checks
272
// for applicability of cached data are added in the future
273
bool
274
IdealWifiManager::UseCachedDataTxVector (WifiRemoteStation *st) const
275
{
276
  NS_LOG_FUNCTION (this << st);
277
  IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
278
  if (station->m_lastSnrObserved == station->m_lastSnrUsed)
279
    {
280
      return true;
281
    }
282
  return false;
283
}
284
285
void
286
IdealWifiManager::UpdateCachedDataTxVector (WifiRemoteStation *st, WifiMode mode, uint8_t nss)
287
{
288
  NS_LOG_FUNCTION (this << st);
289
  IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
290
  NS_LOG_DEBUG ("Mode found; updating cached values for station to " <<  mode.GetUniqueName () << " snr " << station->m_lastSnrObserved);
291
  station->m_lastSnrUsed = station->m_lastSnrObserved;
292
  station->m_lastMode = mode;
293
  station->m_nss = nss;
294
  uint64_t dataRate = mode.GetDataRate (GetChannelWidth (station), GetPhy ()->GetGuardInterval (), nss);
295
  if (station->m_lastRate != dataRate)
296
    {
297
      NS_LOG_DEBUG ("Updated datarate: " << dataRate << " to station " << station->m_state->m_address);
298
      station->m_lastRate = dataRate;
299
      m_rateChange (dataRate, station->m_state->m_address);
300
    }
301
}
302
303
bool
304
IdealWifiManager::DoGetDataTxVectorVht (WifiRemoteStation *st)
305
{
306
  NS_LOG_FUNCTION (this << st);
307
  IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
308
  WifiMode mode;
309
  uint8_t nss = 1;
310
  WifiTxVector txVector;
311
  // channel width and guard interval are not variable within here
312
  txVector.SetChannelWidth (GetPhy ()->GetChannelWidth ());
313
  txVector.SetShortGuardInterval (GetPhy ()->GetGuardInterval ());
314
315
  // Search within the supported rate set for the mode corresponding
316
  // to the highest rate with an SNR threshold smaller than the last
317
  // SNR reported from the remote station
318
  WifiMode maxMode = GetDefaultMode ();
319
  uint8_t maxNss = 1;
320
  uint64_t maxDataRate = 0;
321
  
322
  bool found = false;
323
  for (uint32_t i = 0; i < GetNMcsSupported (station); i++)
324
    {
325
      mode = GetMcsSupported (station, i);
326
      if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
327
        {
328
          continue;
329
        }
330
      txVector.SetMode (mode);
331
      // For each VHT mode, we must consider multiple spatial streams
332
      for (uint8_t j = 1; j <= GetPhy ()->GetSupportedTxSpatialStreams (); j++)
333
        {
334
          txVector.SetNss (j);
335
          if (WifiPhy::IsValidTxVector (txVector) == false || IsSupportedTxVector (txVector) == false)
336
             {
337
               NS_LOG_DEBUG ("Skipping mode " << mode.GetUniqueName () <<
338
                             " nss " << (uint16_t) j << " width " << 
339
                             txVector.GetChannelWidth());
340
               continue;       
341
             }
342
          // Mode is a candidate
343
          double threshold = GetSnrThreshold (txVector);
344
          NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () <<
345
                        " threshold " << threshold  << 
346
                        " last snr observed " <<
347
                        station->m_lastSnrObserved << " cached " <<
348
                        station->m_lastSnrUsed);
349
          uint64_t candidateRate = mode.GetDataRate (GetPhy ()->GetChannelWidth (), GetPhy ()->GetGuardInterval (), nss);
350
          // Prefer a mode if its data rate exceeds previous candidate
351
          if (candidateRate > maxDataRate && threshold < station->m_lastSnrObserved) 
352
            {
353
              NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
354
                            " threshold " << threshold <<
355
                            " last snr observed " <<
356
                            station->m_lastSnrObserved);
357
              maxMode = mode;
358
              maxNss = nss;
359
              maxDataRate = candidateRate;
360
              found = true;
361
            }
362
        }
363
    }
364
  if (found)
365
    {
366
      UpdateCachedDataTxVector (st, maxMode, maxNss);
367
    }
368
  return found;
369
}
370
371
bool
372
IdealWifiManager::DoGetDataTxVectorHt (WifiRemoteStation *st)
373
{
374
  NS_LOG_FUNCTION (this << st);
375
  IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
376
  WifiMode mode;
377
  uint8_t nss = 1;
378
  WifiTxVector txVector;
379
  // channel width and guard interval are not variable within here
380
  txVector.SetChannelWidth (GetPhy ()->GetChannelWidth ());
381
  txVector.SetShortGuardInterval (GetPhy ()->GetGuardInterval ());
382
383
  // Search within the supported rate set for the mode corresponding
384
  // to the highest rate with an SNR threshold smaller than the last
385
  // SNR reported from the remote station
386
  WifiMode maxMode = GetDefaultMode ();
387
  uint8_t maxNss = 1;
388
  uint64_t maxDataRate = 0;
389
  
390
  bool found = false;
391
  for (uint32_t i = 0; i < GetNMcsSupported (station); i++)
392
    {
393
      mode = GetMcsSupported (station, i);
394
      if (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
395
        {
396
          continue;
397
        }
398
      txVector.SetMode (mode);
399
      // For each HT mode, we can derive the nss from the MCS number
400
      nss = (mode.GetMcsValue () / 8) + 1;
401
      txVector.SetNss (nss);
402
      if (WifiPhy::IsValidTxVector (txVector) == false || IsSupportedTxVector (txVector) == false)
403
         {
404
           NS_LOG_DEBUG ("Skipping mode " << mode.GetUniqueName () <<
405
                         " nss " << (uint16_t) nss << " width " << 
406
                         txVector.GetChannelWidth());
407
           continue;       
408
         }
409
      // Mode is a candidate
410
      double threshold = GetSnrThreshold (txVector);
411
      NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () <<
412
                    " threshold " << threshold  << " last snr observed " <<
413
                    station->m_lastSnrObserved << " cached " <<
414
                    station->m_lastSnrUsed);
415
      uint64_t candidateRate = mode.GetDataRate (GetPhy ()->GetChannelWidth (), GetPhy ()->GetGuardInterval (), nss);
416
      // Prefer a mode if its data rate exceeds previous candidate
417
      if (candidateRate > maxDataRate && threshold < station->m_lastSnrObserved) 
418
        {
419
          NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
420
                        " threshold " << threshold  << " last snr observed " <<
421
                        station->m_lastSnrObserved);
422
          maxMode = mode;
423
          maxNss = nss;
424
          maxDataRate = candidateRate;
425
          found = true;
426
        }
427
    }
428
  if (found)
429
    {
430
      UpdateCachedDataTxVector (st, maxMode, maxNss);
431
    }
432
  return found;
433
}
434
435
bool
436
IdealWifiManager::DoGetDataTxVectorLegacy (WifiRemoteStation *st)
437
{
438
  NS_LOG_FUNCTION (this << st);
439
  IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
440
  WifiMode mode;
441
  uint8_t nss = 1;
442
  WifiTxVector txVector;
443
  // channel width and guard interval are not variable within here
444
  txVector.SetChannelWidth (GetPhy ()->GetChannelWidth ());
445
  txVector.SetShortGuardInterval (GetPhy ()->GetGuardInterval ());
446
447
  // Search within the supported rate set for the mode corresponding
448
  // to the highest rate with an SNR threshold smaller than the last
449
  // SNR reported from the remote station
450
  WifiMode maxMode = GetDefaultMode ();
451
  uint8_t maxNss = 1;
452
  uint64_t maxDataRate = 0;
453
454
  bool found = false;
455
  for (uint32_t i = 0; i < GetNSupported (station); i++)
456
    {
457
      mode = GetSupported (station, i);
458
      txVector.SetMode (mode);
459
      txVector.SetNss (nss);
460
      txVector.SetChannelWidth (GetChannelWidthForMode (mode));
461
      double threshold = GetSnrThreshold (txVector);
462
      NS_LOG_DEBUG ("mode = " << mode.GetUniqueName () <<
463
                    " threshold " << threshold  <<
464
                    " last snr observed " <<
465
                    station->m_lastSnrObserved);
466
      uint64_t candidateRate = mode.GetDataRate (GetPhy ()->GetChannelWidth (), GetPhy ()->GetGuardInterval (), nss);
467
      // Prefer a mode if its data rate exceeds previous candidate
468
      if (candidateRate > maxDataRate && threshold < station->m_lastSnrObserved) 
469
        {
470
          NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
471
                        " threshold " << threshold  << " last snr observed " <<
472
                        station->m_lastSnrObserved);
473
          maxMode = mode;
474
          maxNss = nss;
475
          maxDataRate = candidateRate;
476
          found = true;
477
        }
478
    }
479
  if (found)
480
    {
481
      UpdateCachedDataTxVector (st, maxMode, maxNss);
482
    }
483
  return found;
484
}
485
257
WifiTxVector
486
WifiTxVector
258
IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
487
IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
259
{
488
{
260
  NS_LOG_FUNCTION (this << st);
489
  NS_LOG_FUNCTION (this << st);
261
  IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
490
  IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
262
  //We search within the Supported rate set the mode with the
491
  
263
  //highest snr threshold possible which is smaller than m_lastSnr
492
  if (UseCachedDataTxVector (st))
264
  //to ensure correct packet delivery.
265
  double maxThreshold = 0.0;
266
  WifiMode maxMode = GetDefaultMode ();
267
  std::vector<WifiTxVector> candidateTxVectors;
268
  WifiTxVector txVector;
269
  WifiMode mode;
270
  uint8_t nss = 1;
271
  txVector.SetChannelWidth (GetPhy ()->GetChannelWidth ());
272
  txVector.SetShortGuardInterval (GetPhy ()->GetGuardInterval ());
273
  if (station->m_lastSnrObserved == station->m_lastSnrCached)
274
    {
493
    {
275
      // SNR has not changed, so skip the search and use the last
494
      NS_LOG_DEBUG ("Using cached WifiTxVector to station " << station->m_state->m_address);
276
      // mode selected
495
      NS_LOG_DEBUG ("Returning cached mode: " << 
277
      maxMode = station->m_lastMode;      
496
                    station->m_lastMode.GetUniqueName () << 
278
      nss = station->m_nss;
497
                    " channelWidth: " << GetChannelWidth (station) <<
279
      NS_LOG_DEBUG ("Using cached mode = " << maxMode.GetUniqueName () <<
498
                    " nss " << (uint16_t) station->m_nss << " dataRate: " << 
280
                    " last snr observed " << station->m_lastSnrObserved <<
499
                    station->m_lastRate);
281
                    " cached " << station->m_lastSnrCached);
500
      return WifiTxVector (station->m_lastMode, GetDefaultTxPowerLevel (), 
501
                           GetLongRetryCount (station), false, station->m_nss, 
502
                           0, GetChannelWidth (station), 
503
                           GetAggregation (station), false);
504
    }
505
  bool found = false;
506
  if (HasVhtSupported () == true && GetVhtSupported (st))
507
    {
508
      NS_LOG_DEBUG ("Searching VHT modes to station " << station->m_state->m_address);
509
      found = DoGetDataTxVectorVht (st);
510
    }
511
  if (!found && HasHtSupported () == true && GetHtSupported (st))
512
    {
513
      NS_LOG_DEBUG ("Searching HT modes to station " << station->m_state->m_address);
514
      found = DoGetDataTxVectorHt (st);
515
    }
516
  if (!found)
517
    {
518
      NS_LOG_DEBUG ("Searching legacy modes to station " << station->m_state->m_address);
519
      found = DoGetDataTxVectorLegacy (st);
520
    }
521
  if (found)
522
    {
523
      return WifiTxVector (station->m_lastMode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, station->m_nss, 0, GetChannelWidth (station), GetAggregation (station), false);
282
    }
524
    }
283
  else
525
  else
284
    {
526
    {
285
      if (HasVhtSupported () == true || HasHtSupported () == true)
527
      NS_LOG_DEBUG ("Suitable mode not found; returning default mode");
286
        {
528
      return WifiTxVector (GetDefaultMode (), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, GetChannelWidth (station), GetAggregation (station), false);
287
          for (uint32_t i = 0; i < GetNMcsSupported (station); i++)
288
            {
289
              mode = GetMcsSupported (station, i);
290
              txVector.SetMode (mode);
291
              if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
292
                {
293
                  //derive NSS from the Mcs index
294
                  nss = (mode.GetMcsValue () / 8) + 1;
295
                }
296
              else
297
                {
298
                  nss = GetPhy ()->GetSupportedTxSpatialStreams ();
299
                }
300
              txVector.SetNss (nss);
301
              if (WifiPhy::IsValidTxVector (txVector) == false)
302
                 {
303
                   NS_LOG_DEBUG ("Skipping mode " << mode.GetUniqueName () <<
304
                                 " nss " << nss << " width " << 
305
                                 txVector.GetChannelWidth());
306
                   continue;       
307
                 }
308
              double threshold = GetSnrThreshold (txVector);
309
              // If the node and peer are both VHT capable, only search VHT modes 
310
              if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT && HasVhtSupported () && GetVhtSupported (st))
311
                { 
312
                  continue;
313
                }
314
              // If the node and peer are not both VHT capable, only search HT modes 
315
              if (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT && (!HasVhtSupported () || !GetVhtSupported (st)))
316
                { 
317
                  continue;
318
                }
319
              NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () <<
320
                            " threshold " << threshold  << " maxThreshold " <<
321
                            maxThreshold << " last snr observed " <<
322
                            station->m_lastSnrObserved << " cached " <<
323
                            station->m_lastSnrCached);
324
              if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
325
                {
326
                  NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
327
                                " threshold " << threshold  <<
328
                                " last snr observed " <<
329
                                station->m_lastSnrObserved);
330
                  maxThreshold = threshold;
331
                  maxMode = mode;
332
                }
333
            }
334
        }
335
      else 
336
        {
337
          // Non-HT selection
338
          nss = 1;
339
          for (uint32_t i = 0; i < GetNSupported (station); i++)
340
            {
341
              mode = GetSupported (station, i);
342
              txVector.SetMode (mode);
343
              txVector.SetNss (nss);
344
              txVector.SetChannelWidth (GetChannelWidthForMode (mode));
345
              double threshold = GetSnrThreshold (txVector);
346
              NS_LOG_DEBUG ("mode = " << mode.GetUniqueName () <<
347
                            " threshold " << threshold  <<
348
                            " last snr observed " <<
349
                            station->m_lastSnrObserved);
350
              if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
351
                {
352
                  NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
353
                                " threshold " << threshold  <<
354
                                " last snr observed " <<
355
                                station->m_lastSnrObserved);
356
                  maxThreshold = threshold;
357
                  maxMode = mode;
358
                }
359
            }
360
        }
361
      NS_LOG_DEBUG ("Updating cached values for station to " <<  maxMode.GetUniqueName () << " snr " << station->m_lastSnrObserved);
362
      station->m_lastSnrCached = station->m_lastSnrObserved;
363
      station->m_lastMode = maxMode;
364
      station->m_nss = nss;
365
    }
529
    }
366
  uint32_t channelWidth = GetChannelWidth (station);
367
  NS_LOG_DEBUG ("Found maxMode: " << maxMode << " channelWidth: " << channelWidth);
368
  if (m_currentRate != maxMode.GetDataRate (channelWidth, GetPhy ()->GetGuardInterval (), nss))
369
    {
370
      NS_LOG_DEBUG ("New datarate: " << maxMode.GetDataRate (channelWidth, GetPhy ()->GetGuardInterval (), nss));
371
      m_currentRate = maxMode.GetDataRate (channelWidth, GetPhy ()->GetGuardInterval (), nss);
372
    }
373
  return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, nss, 0, channelWidth, GetAggregation (station), false);
374
}
530
}
375
531
376
WifiTxVector
532
WifiTxVector
 Lines 411-414    Link Here 
411
  return true;
567
  return true;
412
}
568
}
413
569
570
bool 
571
IdealWifiManager::IsSupportedTxVector (const WifiTxVector txVector) const
572
{
573
  if (txVector.GetNss () > GetPhy ()->GetSupportedTxSpatialStreams ())
574
    {
575
      return false;
576
    } 
577
  return true;
578
}
579
414
} //namespace ns3
580
} //namespace ns3
(-)a/src/wifi/model/ideal-wifi-manager.h (-1 / +56 lines)
 Lines 43-48    Link Here 
43
 * and uses it to pick a transmission mode based on a set
43
 * and uses it to pick a transmission mode based on a set
44
 * of snr thresholds built from a target ber and transmission
44
 * of snr thresholds built from a target ber and transmission
45
 * mode-specific snr/ber curves.
45
 * mode-specific snr/ber curves.
46
 *
47
 * This model does not presently account for WifiPhy configuration 
48
 * changes that may occur during runtime (after object initialization time),
49
 * including changing the number of antennas, the guard interval, or the
50
 * channel width.
46
 */
51
 */
47
class IdealWifiManager : public WifiRemoteStationManager
52
class IdealWifiManager : public WifiRemoteStationManager
48
{
53
{
 Lines 51-58    Link Here 
51
  IdealWifiManager ();
56
  IdealWifiManager ();
52
  virtual ~IdealWifiManager ();
57
  virtual ~IdealWifiManager ();
53
58
59
  // Inherited from WifiRemoteStationManager
54
  virtual void SetupPhy (Ptr<WifiPhy> phy);
60
  virtual void SetupPhy (Ptr<WifiPhy> phy);
55
61
62
  typedef void (*RateChangeTracedCallback)(const uint64_t rate, const Mac48Address remoteAddress);
56
63
57
private:
64
private:
58
  //overriden from base class
65
  //overriden from base class
 Lines 92-97    Link Here 
92
  void AddSnrThreshold (WifiTxVector txVector, double snr);
99
  void AddSnrThreshold (WifiTxVector txVector, double snr);
93
100
94
  /**
101
  /**
102
   * Return true or false depending on whether the txVector is supported 
103
   * for transmitting.  The list of supported modes stored in the 
104
   * WifiPhy may be larger than the list of usable modes for sending data 
105
   * because the number of transmit antennas and receive antennas may 
106
   * be unequal.
107
   *
108
   * Note that WifiPhy has a similar IsValidTxVector() that may be used
109
   * to check whether the standard allows the combination of channel width,
110
   * NSS, and MCS.
111
   *
112
   * \param txVector the txVector to check
113
   * \return true if the station can transmit using this txVector
114
   */
115
  bool IsSupportedTxVector (const WifiTxVector txVector) const;
116
  /**
95
   * Convenience function for selecting a channel width for legacy mode
117
   * Convenience function for selecting a channel width for legacy mode
96
   * \param non-(V)HT WifiMode
118
   * \param non-(V)HT WifiMode
97
   * \return the channel width (MHz) for the selected mode
119
   * \return the channel width (MHz) for the selected mode
 Lines 99-104    Link Here 
99
  uint32_t GetChannelWidthForMode (WifiMode mode) const;
121
  uint32_t GetChannelWidthForMode (WifiMode mode) const;
100
122
101
  /**
123
  /**
124
   * \param st Station under consideration
125
   * \return true if cached values may be reused
126
   */
127
  bool UseCachedDataTxVector (WifiRemoteStation* st) const;
128
  /**
129
   * \param st Station under consideration
130
   * \mode WifiMode value to update the cached value to
131
   * \mode nss value to update the cached value to
132
   */
133
  void UpdateCachedDataTxVector (WifiRemoteStation* st, WifiMode mode, uint8_t nss);
134
135
  /**
136
   * \param st Station under consideration
137
   * \return true if suitable VHT MCS is found
138
   */
139
  bool DoGetDataTxVectorVht (WifiRemoteStation* st);
140
141
  /**
142
   * \param st Station under consideration
143
   * \return true if suitable HT MCS is found
144
   */
145
  bool DoGetDataTxVectorHt (WifiRemoteStation* st);
146
147
  /**
148
   * \param st Station under consideration
149
   * \return true if suitable legacy mode is found
150
   */
151
  bool DoGetDataTxVectorLegacy (WifiRemoteStation* st);
152
153
  /**
102
   * A vector of <snr, WifiTxVector> pair holding the minimum SNR for the 
154
   * A vector of <snr, WifiTxVector> pair holding the minimum SNR for the 
103
   * WifiTxVector
155
   * WifiTxVector
104
   */
156
   */
 Lines 107-113    Link Here 
107
  double m_ber;             //!< The maximum Bit Error Rate acceptable at any transmission mode
159
  double m_ber;             //!< The maximum Bit Error Rate acceptable at any transmission mode
108
  Thresholds m_thresholds;  //!< List of WifiTxVector and the minimum SNR pair
160
  Thresholds m_thresholds;  //!< List of WifiTxVector and the minimum SNR pair
109
161
110
  TracedValue<uint64_t> m_currentRate; //!< Trace rate changes
162
  /**
163
   * The trace source fired when the transmission rate change.
164
   */
165
  TracedCallback<uint64_t, Mac48Address> m_rateChange;
111
};
166
};
112
167
113
} //namespace ns3
168
} //namespace ns3

Return to bug 2385