src/devices/wifi/yans-wifi-phy.cc
author Pavel Boyko <boyko@iitp.ru>
Fri Nov 13 14:51:59 2009 +0300 (2009-11-13)
changeset 5511 d77201fa5ee2
parent 5495 7f6bb3ad07b4
child 5512 28bccc88b34c
permissions -rw-r--r--
ChannelNumber attribute added to YansWifiPhy. Now it is possible to setup wifi channel using WifiPhyHelper::Set() method.
mathieu@1889
     1
/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
mathieu@1889
     2
/*
mathieu@1889
     3
 * Copyright (c) 2005,2006 INRIA
mathieu@1889
     4
 *
mathieu@1889
     5
 * This program is free software; you can redistribute it and/or modify
mathieu@1889
     6
 * it under the terms of the GNU General Public License version 2 as 
mathieu@1889
     7
 * published by the Free Software Foundation;
mathieu@1889
     8
 *
mathieu@1889
     9
 * This program is distributed in the hope that it will be useful,
mathieu@1889
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
mathieu@1889
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
mathieu@1889
    12
 * GNU General Public License for more details.
mathieu@1889
    13
 *
mathieu@1889
    14
 * You should have received a copy of the GNU General Public License
mathieu@1889
    15
 * along with this program; if not, write to the Free Software
mathieu@1889
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
mathieu@1889
    17
 *
mathieu@1889
    18
 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
mathieu@1889
    19
 */
mathieu@1889
    20
mathieu@3888
    21
#include "yans-wifi-phy.h"
mathieu@3900
    22
#include "yans-wifi-channel.h"
mathieu@1891
    23
#include "wifi-mode.h"
mathieu@1920
    24
#include "wifi-preamble.h"
mathieu@3900
    25
#include "wifi-phy-state-helper.h"
mathieu@3902
    26
#include "error-rate-model.h"
mathieu@1889
    27
#include "ns3/simulator.h"
mathieu@1889
    28
#include "ns3/packet.h"
mathieu@1889
    29
#include "ns3/random-variable.h"
mathieu@1974
    30
#include "ns3/assert.h"
mathieu@1979
    31
#include "ns3/log.h"
mathieu@2524
    32
#include "ns3/double.h"
mathieu@2524
    33
#include "ns3/uinteger.h"
mathieu@2524
    34
#include "ns3/enum.h"
mathieu@3900
    35
#include "ns3/pointer.h"
mathieu@3912
    36
#include "ns3/net-device.h"
craigdo@4263
    37
#include "ns3/trace-source-accessor.h"
mathieu@1889
    38
#include <math.h>
mathieu@1889
    39
mathieu@3888
    40
NS_LOG_COMPONENT_DEFINE ("YansWifiPhy");
mathieu@1891
    41
mathieu@1889
    42
namespace ns3 {
mathieu@1889
    43
mathieu@3888
    44
NS_OBJECT_ENSURE_REGISTERED (YansWifiPhy);
mathieu@2524
    45
mathieu@2524
    46
TypeId 
mathieu@3888
    47
YansWifiPhy::GetTypeId (void)
mathieu@2524
    48
{
mathieu@3888
    49
  static TypeId tid = TypeId ("ns3::YansWifiPhy")
mathieu@3888
    50
    .SetParent<WifiPhy> ()
mathieu@3888
    51
    .AddConstructor<YansWifiPhy> ()
mathieu@2524
    52
    .AddAttribute ("EnergyDetectionThreshold",
mathieu@2524
    53
                   "The energy of a received signal should be higher than "
mathieu@2524
    54
                   "this threshold (dbm) to allow the PHY layer to detect the signal.",
boyko@5495
    55
                   DoubleValue (-96.0),
mathieu@3888
    56
                   MakeDoubleAccessor (&YansWifiPhy::SetEdThreshold,
mathieu@3888
    57
                                       &YansWifiPhy::GetEdThreshold),
mathieu@2524
    58
                   MakeDoubleChecker<double> ())
mathieu@3905
    59
    .AddAttribute ("CcaMode1Threshold",
mathieu@3905
    60
                   "The energy of a received signal should be higher than "
mathieu@3905
    61
                   "this threshold (dbm) to allow the PHY layer to declare CCA BUSY state",
boyko@5495
    62
                   DoubleValue (-99.0),
mathieu@3905
    63
                   MakeDoubleAccessor (&YansWifiPhy::SetCcaMode1Threshold,
mathieu@3905
    64
                                       &YansWifiPhy::GetCcaMode1Threshold),
mathieu@3905
    65
                   MakeDoubleChecker<double> ())
mathieu@2524
    66
    .AddAttribute ("TxGain",
mathieu@2524
    67
                   "Transmission gain (dB).",
mathieu@2965
    68
                   DoubleValue (1.0),
mathieu@3888
    69
                   MakeDoubleAccessor (&YansWifiPhy::SetTxGain,
mathieu@3888
    70
                                       &YansWifiPhy::GetTxGain),
mathieu@2524
    71
                   MakeDoubleChecker<double> ())
mathieu@2524
    72
    .AddAttribute ("RxGain",
mathieu@2524
    73
                   "Reception gain (dB).",
mathieu@2965
    74
                   DoubleValue (1.0),
mathieu@3888
    75
                   MakeDoubleAccessor (&YansWifiPhy::SetRxGain,
mathieu@3888
    76
                                       &YansWifiPhy::GetRxGain),
mathieu@2524
    77
                   MakeDoubleChecker<double> ())
mathieu@2524
    78
    .AddAttribute ("TxPowerLevels",
mathieu@2524
    79
                   "Number of transmission power levels available between "
mathieu@2524
    80
                   "TxPowerBase and TxPowerEnd included.",
mathieu@2965
    81
                   UintegerValue (1),
mathieu@3888
    82
                   MakeUintegerAccessor (&YansWifiPhy::m_nTxPower),
mathieu@2524
    83
                   MakeUintegerChecker<uint32_t> ())
mathieu@2524
    84
    .AddAttribute ("TxPowerEnd",
mathieu@2524
    85
                   "Maximum available transmission level (dbm).",
mathieu@2965
    86
                   DoubleValue (16.0206),
mathieu@3888
    87
                   MakeDoubleAccessor (&YansWifiPhy::SetTxPowerEnd, 
mathieu@3888
    88
                                       &YansWifiPhy::GetTxPowerEnd),
mathieu@2524
    89
                   MakeDoubleChecker<double> ())
mathieu@2524
    90
    .AddAttribute ("TxPowerStart",
mathieu@2524
    91
                   "Minimum available transmission level (dbm).",
mathieu@2965
    92
                   DoubleValue (16.0206),
mathieu@3888
    93
                   MakeDoubleAccessor (&YansWifiPhy::SetTxPowerStart, 
mathieu@3888
    94
                                       &YansWifiPhy::GetTxPowerStart),
mathieu@2524
    95
                   MakeDoubleChecker<double> ())
nbaldo@4315
    96
    .AddAttribute ("RxNoiseFigure",
nbaldo@4315
    97
                   "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
nbaldo@4315
    98
                   " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
nbaldo@4315
    99
                   "\"the difference in decibels (dB) between"
nbaldo@4315
   100
                   " the noise output of the actual receiver to the noise output of an "
nbaldo@4315
   101
                   " ideal receiver with the same overall gain and bandwidth when the receivers "
nbaldo@4315
   102
                   " are connected to sources at the standard noise temperature T0 (usually 290 K)\"."
nbaldo@4315
   103
                   " For",
mathieu@2965
   104
                   DoubleValue (7),
nbaldo@4315
   105
                   MakeDoubleAccessor (&YansWifiPhy::SetRxNoiseFigure,
nbaldo@4315
   106
                                       &YansWifiPhy::GetRxNoiseFigure),
mathieu@2524
   107
                   MakeDoubleChecker<double> ())
mathieu@3900
   108
    .AddAttribute ("State", "The state of the PHY layer",
mathieu@3900
   109
                   PointerValue (),
mathieu@3900
   110
                   MakePointerAccessor (&YansWifiPhy::m_state),
mathieu@3900
   111
                   MakePointerChecker<WifiPhyStateHelper> ())
boyko@4690
   112
    .AddAttribute ("ChannelSwitchDelay",
boyko@4690
   113
                   "Delay between two short frames transmitted on different frequencies. NOTE: Unused now.",
boyko@4690
   114
                   TimeValue (MicroSeconds (250)),
boyko@4690
   115
                   MakeTimeAccessor (&YansWifiPhy::m_channelSwitchDelay), 
boyko@4690
   116
                   MakeTimeChecker ())
boyko@5511
   117
    .AddAttribute ("ChannelNumber",
boyko@5511
   118
                   "Channel center frequency = Channel starting frequency + 5 MHz * (nch - 1)",
boyko@5511
   119
                   UintegerValue (1),
boyko@5511
   120
                   MakeUintegerAccessor (&YansWifiPhy::SetChannelNumber, 
boyko@5511
   121
                                         &YansWifiPhy::GetChannelNumber),
boyko@5511
   122
                   MakeUintegerChecker<uint16_t> ())
boyko@5511
   123
mathieu@2524
   124
    ;
mathieu@2524
   125
  return tid;
mathieu@2524
   126
}
mathieu@2524
   127
mathieu@3888
   128
YansWifiPhy::YansWifiPhy ()
boyko@5511
   129
  :  m_channelNumber (1),
boyko@5511
   130
     m_endSyncEvent (),
boyko@4690
   131
     m_random (0.0, 1.0),
boyko@4690
   132
     m_channelStartingFrequency (0)
mathieu@2985
   133
{
mathieu@2985
   134
  NS_LOG_FUNCTION (this);
mathieu@3900
   135
  m_state = CreateObject<WifiPhyStateHelper> ();
mathieu@2985
   136
}
mathieu@2524
   137
mathieu@3888
   138
YansWifiPhy::~YansWifiPhy ()
mathieu@2985
   139
{
mathieu@2985
   140
  NS_LOG_FUNCTION (this);
mathieu@2985
   141
}
mathieu@2530
   142
mathieu@2530
   143
void
mathieu@3888
   144
YansWifiPhy::DoDispose (void)
mathieu@1964
   145
{
mathieu@2985
   146
  NS_LOG_FUNCTION (this);
mathieu@2524
   147
  m_channel = 0;
mathieu@2524
   148
  m_modes.clear ();
mathieu@3912
   149
  m_device = 0;
mazo@5422
   150
  m_mobility = 0;
mazo@5422
   151
  m_state = 0;
mathieu@2524
   152
}
mathieu@2524
   153
mathieu@2524
   154
void
mathieu@4720
   155
YansWifiPhy::ConfigureStandard (enum WifiPhyStandard standard)
mathieu@2524
   156
{
mathieu@2985
   157
  NS_LOG_FUNCTION (this << standard);
mathieu@2524
   158
  switch (standard) {
federico@2166
   159
  case WIFI_PHY_STANDARD_80211a:
mathieu@2083
   160
    Configure80211a ();
mathieu@2083
   161
    break;
guangyu@4470
   162
  case WIFI_PHY_STANDARD_80211b:
guangyu@4470
   163
    Configure80211b ();
guangyu@4470
   164
    break;
monbauza@4680
   165
  case WIFI_PHY_STANDARD_80211_10Mhz: 
monbauza@4680
   166
    Configure80211_10Mhz ();
monbauza@4680
   167
    break;
monbauza@4680
   168
  case WIFI_PHY_STANDARD_80211_5Mhz:
monbauza@4680
   169
    Configure80211_5Mhz ();
boyko@4690
   170
    break; 
federico@2166
   171
  case WIFI_PHY_STANDARD_holland:
mathieu@2083
   172
    ConfigureHolland ();
mathieu@2083
   173
    break;
mathieu@2083
   174
  default:
mathieu@2083
   175
    NS_ASSERT (false);
mathieu@2083
   176
    break;
mathieu@2083
   177
  }
mathieu@1964
   178
}
mathieu@1889
   179
mathieu@2524
   180
mathieu@2524
   181
void 
nbaldo@4315
   182
YansWifiPhy::SetRxNoiseFigure (double noiseFigureDb)
mathieu@1889
   183
{
nbaldo@4315
   184
  NS_LOG_FUNCTION (this << noiseFigureDb);
nbaldo@4315
   185
  m_interference.SetNoiseFigure (DbToRatio (noiseFigureDb));
mathieu@2524
   186
}
mathieu@2524
   187
void 
mathieu@3888
   188
YansWifiPhy::SetTxPowerStart (double start)
mathieu@2524
   189
{
mathieu@2985
   190
  NS_LOG_FUNCTION (this << start);
mathieu@2524
   191
  m_txPowerBaseDbm = start;
mathieu@2524
   192
}
mathieu@2524
   193
void 
mathieu@3888
   194
YansWifiPhy::SetTxPowerEnd (double end)
mathieu@2524
   195
{
mathieu@2985
   196
  NS_LOG_FUNCTION (this << end);
mathieu@2524
   197
  m_txPowerEndDbm = end;
mathieu@2524
   198
}
mathieu@2524
   199
void 
mathieu@3888
   200
YansWifiPhy::SetNTxPower (uint32_t n)
mathieu@2524
   201
{
mathieu@2985
   202
  NS_LOG_FUNCTION (this << n);
mathieu@2524
   203
  m_nTxPower = n;
mathieu@2524
   204
}
mathieu@2524
   205
void 
mathieu@3888
   206
YansWifiPhy::SetTxGain (double gain)
mathieu@2524
   207
{
mathieu@2985
   208
  NS_LOG_FUNCTION (this << gain);
mathieu@2524
   209
  m_txGainDb = gain;
mathieu@2524
   210
}
mathieu@2524
   211
void 
mathieu@3888
   212
YansWifiPhy::SetRxGain (double gain)
mathieu@2524
   213
{
mathieu@2985
   214
  NS_LOG_FUNCTION (this << gain);
mathieu@2524
   215
  m_rxGainDb = gain;
mathieu@2524
   216
}
mathieu@2524
   217
void 
mathieu@3888
   218
YansWifiPhy::SetEdThreshold (double threshold)
mathieu@2524
   219
{
mathieu@2985
   220
  NS_LOG_FUNCTION (this << threshold);
mathieu@2524
   221
  m_edThresholdW = DbmToW (threshold);
mathieu@2524
   222
}
mathieu@3905
   223
void 
mathieu@3905
   224
YansWifiPhy::SetCcaMode1Threshold (double threshold)
mathieu@3905
   225
{
mathieu@3905
   226
  NS_LOG_FUNCTION (this << threshold);
mathieu@3905
   227
  m_ccaMode1ThresholdW = DbmToW (threshold);
mathieu@3905
   228
}
mathieu@3905
   229
void 
mathieu@3905
   230
YansWifiPhy::SetErrorRateModel (Ptr<ErrorRateModel> rate)
mathieu@3905
   231
{
mathieu@3905
   232
  m_interference.SetErrorRateModel (rate);
mathieu@3905
   233
}
mathieu@3912
   234
void 
mathieu@3912
   235
YansWifiPhy::SetDevice (Ptr<Object> device)
mathieu@3912
   236
{
mathieu@3912
   237
  m_device = device;
mathieu@3912
   238
}
mathieu@3912
   239
void 
mathieu@3912
   240
YansWifiPhy::SetMobility (Ptr<Object> mobility)
mathieu@3912
   241
{
mathieu@3912
   242
  m_mobility = mobility;
mathieu@3912
   243
}
mathieu@3912
   244
mathieu@2524
   245
double 
nbaldo@4315
   246
YansWifiPhy::GetRxNoiseFigure (void) const
mathieu@2524
   247
{
nbaldo@4315
   248
  return RatioToDb (m_interference.GetNoiseFigure ());
mathieu@2524
   249
}
mathieu@2524
   250
double 
mathieu@3888
   251
YansWifiPhy::GetTxPowerStart (void) const
mathieu@2524
   252
{
mathieu@2524
   253
  return m_txPowerBaseDbm;
mathieu@2524
   254
}
mathieu@2524
   255
double 
mathieu@3888
   256
YansWifiPhy::GetTxPowerEnd (void) const
mathieu@2524
   257
{
mathieu@2524
   258
  return m_txPowerEndDbm;
mathieu@2524
   259
}
mathieu@2524
   260
double 
mathieu@3888
   261
YansWifiPhy::GetTxGain (void) const
mathieu@2524
   262
{
mathieu@2524
   263
  return m_txGainDb;
mathieu@2524
   264
}
mathieu@2524
   265
double 
mathieu@3888
   266
YansWifiPhy::GetRxGain (void) const
mathieu@2524
   267
{
mathieu@2524
   268
  return m_rxGainDb;
mathieu@1889
   269
}
mathieu@1889
   270
mathieu@2524
   271
double 
mathieu@3888
   272
YansWifiPhy::GetEdThreshold (void) const
mathieu@2155
   273
{
mathieu@2524
   274
  return WToDbm (m_edThresholdW);
mathieu@2155
   275
}
mathieu@2155
   276
mathieu@3905
   277
double 
mathieu@3905
   278
YansWifiPhy::GetCcaMode1Threshold (void) const
mathieu@3905
   279
{
mathieu@3905
   280
  return WToDbm (m_ccaMode1ThresholdW);
mathieu@3905
   281
}
mathieu@3905
   282
mathieu@3905
   283
Ptr<ErrorRateModel> 
mathieu@3905
   284
YansWifiPhy::GetErrorRateModel (void) const
mathieu@3905
   285
{
mathieu@3905
   286
  return m_interference.GetErrorRateModel ();
mathieu@3905
   287
}
mathieu@3912
   288
Ptr<Object> 
mathieu@3912
   289
YansWifiPhy::GetDevice (void) const
mathieu@3912
   290
{
mathieu@3912
   291
  return m_device;
mathieu@3912
   292
}
mathieu@3912
   293
Ptr<Object> 
mathieu@3912
   294
YansWifiPhy::GetMobility (void)
mathieu@3912
   295
{
mathieu@3912
   296
  return m_mobility;
mathieu@3912
   297
}
mathieu@3905
   298
mathieu@3905
   299
double 
mathieu@3905
   300
YansWifiPhy::CalculateSnr (WifiMode txMode, double ber) const
mathieu@3905
   301
{
mathieu@3905
   302
  return m_interference.GetErrorRateModel ()->CalculateSnr (txMode, ber);
mathieu@3905
   303
}
mathieu@3905
   304
mathieu@2524
   305
Ptr<WifiChannel> 
mathieu@3888
   306
YansWifiPhy::GetChannel (void) const
mathieu@2055
   307
{
mathieu@2524
   308
  return m_channel;
mathieu@2055
   309
}
mathieu@1889
   310
void 
mathieu@3893
   311
YansWifiPhy::SetChannel (Ptr<YansWifiChannel> channel)
mathieu@1889
   312
{
mathieu@1891
   313
  m_channel = channel;
mathieu@3912
   314
  m_channel->Add (this);
boyko@4690
   315
}
boyko@4690
   316
boyko@4690
   317
void 
boyko@4690
   318
YansWifiPhy::SetChannelNumber (uint16_t nch)
boyko@4690
   319
{
Ramon@5189
   320
  NS_ASSERT(!IsStateSwitching()); 
Ramon@5189
   321
  switch (m_state->GetState ()) {
Ramon@5189
   322
  case YansWifiPhy::SYNC:
Ramon@5189
   323
    NS_LOG_DEBUG ("drop packet because of channel switching while reception");
Ramon@5189
   324
    m_endSyncEvent.Cancel();
Ramon@5189
   325
    goto switchChannel;
Ramon@5189
   326
    break;
Ramon@5189
   327
  case YansWifiPhy::TX:
Ramon@5189
   328
      NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
Ramon@5189
   329
      Simulator::Schedule (GetDelayUntilIdle(), &YansWifiPhy::SetChannelNumber, this, nch);
Ramon@5189
   330
    break;
Ramon@5189
   331
  case YansWifiPhy::CCA_BUSY:
Ramon@5189
   332
  case YansWifiPhy::IDLE:
Ramon@5189
   333
    goto switchChannel;
Ramon@5189
   334
    break;
Ramon@5189
   335
  default:
Ramon@5189
   336
    NS_ASSERT (false);
Ramon@5189
   337
    break;
Ramon@5189
   338
  }
boyko@4690
   339
Ramon@5189
   340
  return;
Ramon@5189
   341
Ramon@5189
   342
  switchChannel: 
Ramon@5189
   343
Ramon@5189
   344
  NS_LOG_DEBUG("switching channel " << m_channelNumber << " -> " << nch);
Ramon@5189
   345
  m_state->SwitchToChannelSwitching(m_channelSwitchDelay); 
Ramon@5189
   346
  m_interference.EraseEvents(); 
Ramon@5189
   347
  /*
Ramon@5189
   348
   * Needed here to be able to correctly sensed the medium for the first
Ramon@5189
   349
   * time after the switching. The actual switching is not performed until
Ramon@5189
   350
   * after m_channelSwitchDelay. Packets received during the switching
Ramon@5189
   351
   * state are added to the event list and are employed later to figure
Ramon@5189
   352
   * out the state of the medium after the switching.
Ramon@5189
   353
   */
Ramon@5189
   354
  m_channelNumber = nch;
boyko@4690
   355
}
boyko@4690
   356
boyko@4690
   357
uint16_t 
boyko@4690
   358
YansWifiPhy::GetChannelNumber() const
boyko@4690
   359
{
Ramon@5189
   360
  return m_channelNumber;
boyko@4690
   361
}
boyko@4690
   362
boyko@4690
   363
double
boyko@4690
   364
YansWifiPhy::GetChannelFrequencyMhz() const
boyko@4690
   365
{
boyko@4690
   366
  return m_channelStartingFrequency + 5 * (GetChannelNumber() - 1);
mathieu@1889
   367
}
mathieu@1889
   368
mathieu@1889
   369
void 
mathieu@3888
   370
YansWifiPhy::SetReceiveOkCallback (SyncOkCallback callback)
mathieu@1889
   371
{
mathieu@3900
   372
  m_state->SetReceiveOkCallback (callback);
mathieu@1889
   373
}
mathieu@1889
   374
void 
mathieu@3888
   375
YansWifiPhy::SetReceiveErrorCallback (SyncErrorCallback callback)
mathieu@1889
   376
{
mathieu@3900
   377
  m_state->SetReceiveErrorCallback (callback);
mathieu@1889
   378
}
mathieu@1889
   379
void 
mathieu@3888
   380
YansWifiPhy::StartReceivePacket (Ptr<Packet> packet, 
mathieu@3905
   381
                                 double rxPowerDbm,
mathieu@3905
   382
                                 WifiMode txMode,
mathieu@3905
   383
                                 enum WifiPreamble preamble)
mathieu@1889
   384
{
mathieu@2985
   385
  NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble);
mathieu@2071
   386
  rxPowerDbm += m_rxGainDb;
mathieu@1988
   387
  double rxPowerW = DbmToW (rxPowerDbm);
mathieu@2159
   388
  Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
mathieu@1889
   389
  Time endRx = Simulator::Now () + rxDuration;
mathieu@1889
   390
mathieu@3905
   391
  Ptr<InterferenceHelper::Event> event;
mathieu@3905
   392
  event = m_interference.Add (packet->GetSize (), 
mathieu@3905
   393
                              txMode,
mathieu@3905
   394
                              preamble,
mathieu@3905
   395
                              rxDuration,
mathieu@3905
   396
                              rxPowerW);
mathieu@1889
   397
mathieu@3900
   398
  switch (m_state->GetState ()) {
Ramon@5189
   399
  case YansWifiPhy::SWITCHING: 
Ramon@5189
   400
    NS_LOG_DEBUG ("drop packet because of channel switching");
Ramon@5189
   401
    NotifyRxDrop (packet);
Ramon@5189
   402
    /*
Ramon@5189
   403
     * Packets received on the upcoming channel are added to the event list
Ramon@5189
   404
     * during the switching state. This way the medium can be correctly sensed
Ramon@5189
   405
     * when the device listens to the channel for the first time after the
Ramon@5189
   406
     * switching e.g. after channel switching, the channel may be sensed as
Ramon@5189
   407
     * busy due to other devices' tramissions started before the end of
Ramon@5189
   408
     * the switching.
Ramon@5189
   409
     */
Ramon@5189
   410
    if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) 
Ramon@5189
   411
      {
Ramon@5189
   412
        // that packet will be noise _after_ the completion of the
Ramon@5189
   413
        // channel switching.
Ramon@5189
   414
        goto maybeCcaBusy;
Ramon@5189
   415
      }
Ramon@5189
   416
    break;
mathieu@3888
   417
  case YansWifiPhy::SYNC:
mathieu@1979
   418
    NS_LOG_DEBUG ("drop packet because already in Sync (power="<<
mathieu@1979
   419
                  rxPowerW<<"W)");
craigdo@4264
   420
    NotifyRxDrop (packet);
mathieu@3900
   421
    if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) 
mathieu@1889
   422
      {
mathieu@3897
   423
        // that packet will be noise _after_ the reception of the
mathieu@3897
   424
        // currently-received packet.
mathieu@1889
   425
        goto maybeCcaBusy;
mathieu@1889
   426
      }
mathieu@1889
   427
    break;
mathieu@3888
   428
  case YansWifiPhy::TX:
mathieu@1979
   429
    NS_LOG_DEBUG ("drop packet because already in Tx (power="<<
mathieu@1979
   430
                  rxPowerW<<"W)");
craigdo@4264
   431
    NotifyRxDrop (packet);
mathieu@3900
   432
    if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) 
mathieu@1889
   433
      {
mathieu@3897
   434
        // that packet will be noise _after_ the transmission of the
mathieu@3897
   435
        // currently-transmitted packet.
mathieu@1889
   436
        goto maybeCcaBusy;
mathieu@1889
   437
      }
mathieu@1889
   438
    break;
mathieu@3888
   439
  case YansWifiPhy::CCA_BUSY:
mathieu@3888
   440
  case YansWifiPhy::IDLE:
mathieu@1889
   441
    if (rxPowerW > m_edThresholdW) 
mathieu@1889
   442
      {
mathieu@2150
   443
        NS_LOG_DEBUG ("sync (power="<<rxPowerW<<"W)");
mathieu@1889
   444
        // sync to signal
mathieu@3900
   445
        m_state->SwitchToSync (rxDuration);
mathieu@1974
   446
        NS_ASSERT (m_endSyncEvent.IsExpired ());
craigdo@4264
   447
        NotifyRxBegin (packet);
mathieu@3888
   448
        m_endSyncEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndSync, this, 
mathieu@1889
   449
                                              packet,
mathieu@1919
   450
                                              event);
mathieu@2071
   451
      }
mathieu@1889
   452
    else 
mathieu@1889
   453
      {
mathieu@1979
   454
        NS_LOG_DEBUG ("drop packet because signal power too Small ("<<
mathieu@1979
   455
                      rxPowerW<<"<"<<m_edThresholdW<<")");
craigdo@4264
   456
        NotifyRxDrop (packet);
mathieu@1889
   457
        goto maybeCcaBusy;
mathieu@1889
   458
      }
mathieu@1889
   459
    break;
mathieu@1889
   460
  }
mathieu@1889
   461
mathieu@1889
   462
  return;
mathieu@1889
   463
mathieu@1889
   464
 maybeCcaBusy:
mathieu@3905
   465
  // We are here because we have received the first bit of a packet and we are
mathieu@3905
   466
  // not going to be able to synchronize on it
mathieu@3905
   467
  // In this model, CCA becomes busy when the aggregation of all signals as
mathieu@3905
   468
  // tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
mathieu@1889
   469
mathieu@3905
   470
  Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaMode1ThresholdW);
mathieu@3905
   471
  if (!delayUntilCcaEnd.IsZero ())
mathieu@1889
   472
    {
mathieu@3905
   473
      m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
mathieu@1889
   474
    }
mathieu@1889
   475
}
craigdo@4263
   476
mathieu@1889
   477
void 
mathieu@3888
   478
YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
mathieu@1889
   479
{
mathieu@3882
   480
  NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txPower);
mathieu@1889
   481
  /* Transmission can happen if:
mathieu@1889
   482
   *  - we are syncing on a packet. It is the responsability of the
mathieu@1889
   483
   *    MAC layer to avoid doing this but the PHY does nothing to 
mathieu@1889
   484
   *    prevent it.
mathieu@1889
   485
   *  - we are idle
mathieu@1889
   486
   */
Ramon@5189
   487
  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
mathieu@1889
   488
mathieu@2159
   489
  Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
mathieu@3900
   490
  if (m_state->IsStateSync ())
mathieu@3897
   491
    {
mathieu@3897
   492
      m_endSyncEvent.Cancel ();
mathieu@3897
   493
    }
craigdo@4264
   494
  NotifyTxBegin (packet);
nbaldo@4492
   495
  uint32_t dataRate500KbpsUnits = txMode.GetDataRate () / 500000;   
nbaldo@4492
   496
  bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble);
nbaldo@4715
   497
  NotifyPromiscSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble);
mathieu@3900
   498
  m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower);
mathieu@2524
   499
  m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
mathieu@1889
   500
}
mathieu@1889
   501
mathieu@1889
   502
uint32_t 
mathieu@3888
   503
YansWifiPhy::GetNModes (void) const
mathieu@1889
   504
{
mathieu@1889
   505
  return m_modes.size ();
mathieu@1889
   506
}
mathieu@1891
   507
WifiMode 
mathieu@3888
   508
YansWifiPhy::GetMode (uint32_t mode) const
mathieu@1889
   509
{
mathieu@1891
   510
  return m_modes[mode];
mathieu@1889
   511
}
mathieu@1889
   512
uint32_t 
mathieu@3888
   513
YansWifiPhy::GetNTxPower (void) const
mathieu@1889
   514
{
mathieu@1889
   515
  return m_nTxPower;
mathieu@1889
   516
}
mathieu@1889
   517
mathieu@2083
   518
void
mathieu@3888
   519
YansWifiPhy::Configure80211a (void)
mathieu@2083
   520
{
mathieu@2985
   521
  NS_LOG_FUNCTION (this);
boyko@4690
   522
  m_channelStartingFrequency = 5e3; // 5.000 GHz 
mathieu@4039
   523
  m_modes.push_back (WifiPhy::Get6mba ());
mathieu@4039
   524
  m_modes.push_back (WifiPhy::Get9mba ());
mathieu@4039
   525
  m_modes.push_back (WifiPhy::Get12mba ());
mathieu@4039
   526
  m_modes.push_back (WifiPhy::Get18mba ());
mathieu@4039
   527
  m_modes.push_back (WifiPhy::Get24mba ());
mathieu@4039
   528
  m_modes.push_back (WifiPhy::Get36mba ());
mathieu@4039
   529
  m_modes.push_back (WifiPhy::Get48mba ());
mathieu@4039
   530
  m_modes.push_back (WifiPhy::Get54mba ());
mathieu@2083
   531
}
mathieu@2083
   532
guangyu@4470
   533
guangyu@4470
   534
void
guangyu@4470
   535
YansWifiPhy::Configure80211b (void)
guangyu@4470
   536
{
guangyu@4470
   537
  NS_LOG_FUNCTION (this);
boyko@4690
   538
  m_channelStartingFrequency = 2412; // 2.412 GHz 
guangyu@4470
   539
  m_modes.push_back (WifiPhy::Get1mbb ());
guangyu@4470
   540
  m_modes.push_back (WifiPhy::Get2mbb ());
guangyu@4470
   541
  m_modes.push_back (WifiPhy::Get5_5mbb ());
guangyu@4470
   542
  m_modes.push_back (WifiPhy::Get11mbb ());
guangyu@4470
   543
}
guangyu@4470
   544
mathieu@2083
   545
void
monbauza@4680
   546
YansWifiPhy::Configure80211_10Mhz (void)
monbauza@4680
   547
{
monbauza@4680
   548
  NS_LOG_FUNCTION (this);
boyko@4690
   549
  m_channelStartingFrequency = 5e3; // 5.000 GHz, suppose 802.11a 
monbauza@4680
   550
  m_modes.push_back (WifiPhy::Get3mb10Mhz ());
monbauza@4680
   551
  m_modes.push_back (WifiPhy::Get4_5mb10Mhz ());
monbauza@4680
   552
  m_modes.push_back (WifiPhy::Get6mb10Mhz ());
monbauza@4680
   553
  m_modes.push_back (WifiPhy::Get9mb10Mhz ());
monbauza@4680
   554
  m_modes.push_back (WifiPhy::Get12mb10Mhz ());
monbauza@4680
   555
  m_modes.push_back (WifiPhy::Get18mb10Mhz ());
monbauza@4680
   556
  m_modes.push_back (WifiPhy::Get24mb10Mhz ());
monbauza@4680
   557
  m_modes.push_back (WifiPhy::Get27mb10Mhz  ());
monbauza@4680
   558
}
monbauza@4680
   559
monbauza@4680
   560
void
monbauza@4680
   561
YansWifiPhy::Configure80211_5Mhz (void)
monbauza@4680
   562
{
nbaldo@4681
   563
  NS_LOG_FUNCTION (this); 
boyko@4690
   564
  m_channelStartingFrequency = 5e3; // 5.000 GHz, suppose 802.11a
monbauza@4680
   565
  m_modes.push_back (WifiPhy::Get1_5mb5Mhz ());
monbauza@4680
   566
  m_modes.push_back (WifiPhy::Get2_25mb5Mhz ());
monbauza@4680
   567
  m_modes.push_back (WifiPhy::Get3mb5Mhz ());
monbauza@4680
   568
  m_modes.push_back (WifiPhy::Get4_5mb5Mhz ());
monbauza@4680
   569
  m_modes.push_back (WifiPhy::Get6mb5Mhz ());
monbauza@4680
   570
  m_modes.push_back (WifiPhy::Get9mb5Mhz ());
monbauza@4680
   571
  m_modes.push_back (WifiPhy::Get12mb5Mhz ());
monbauza@4680
   572
  m_modes.push_back (WifiPhy::Get13_5mb5Mhz  ());
monbauza@4680
   573
}
monbauza@4680
   574
monbauza@4680
   575
void
mathieu@3888
   576
YansWifiPhy::ConfigureHolland (void)
mathieu@2083
   577
{
mathieu@2985
   578
  NS_LOG_FUNCTION (this);
boyko@4690
   579
  m_channelStartingFrequency = 5e3; // 5.000 GHz 
mathieu@4039
   580
  m_modes.push_back (WifiPhy::Get6mba ());
mathieu@4039
   581
  m_modes.push_back (WifiPhy::Get12mba ());
mathieu@4039
   582
  m_modes.push_back (WifiPhy::Get18mba ());
mathieu@4039
   583
  m_modes.push_back (WifiPhy::Get36mba ());
mathieu@4039
   584
  m_modes.push_back (WifiPhy::Get54mba ());
mathieu@2083
   585
}
mathieu@2083
   586
mathieu@1889
   587
void 
mathieu@3888
   588
YansWifiPhy::RegisterListener (WifiPhyListener *listener)
mathieu@1889
   589
{
mathieu@3900
   590
  m_state->RegisterListener (listener);
mathieu@1889
   591
}
mathieu@1889
   592
mathieu@1889
   593
bool 
mathieu@3888
   594
YansWifiPhy::IsStateCcaBusy (void)
mathieu@1889
   595
{
mathieu@3900
   596
  return m_state->IsStateCcaBusy ();
mathieu@1889
   597
}
mathieu@1889
   598
mathieu@1889
   599
bool 
mathieu@3888
   600
YansWifiPhy::IsStateIdle (void)
mathieu@1889
   601
{
mathieu@3900
   602
  return m_state->IsStateIdle ();
mathieu@1889
   603
}
mathieu@1889
   604
bool 
mathieu@3888
   605
YansWifiPhy::IsStateBusy (void)
mathieu@1889
   606
{
mathieu@3900
   607
  return m_state->IsStateBusy ();
mathieu@1889
   608
}
mathieu@1889
   609
bool 
mathieu@3888
   610
YansWifiPhy::IsStateSync (void)
mathieu@1889
   611
{
mathieu@3900
   612
  return m_state->IsStateSync ();
mathieu@1889
   613
}
mathieu@1889
   614
bool 
mathieu@3888
   615
YansWifiPhy::IsStateTx (void)
mathieu@1889
   616
{
mathieu@3900
   617
  return m_state->IsStateTx ();
mathieu@1889
   618
}
Ramon@5189
   619
bool 
Ramon@5189
   620
YansWifiPhy::IsStateSwitching (void)
Ramon@5189
   621
{
Ramon@5189
   622
  return m_state->IsStateSwitching ();
Ramon@5189
   623
}
mathieu@1889
   624
mathieu@1889
   625
Time
mathieu@3888
   626
YansWifiPhy::GetStateDuration (void)
mathieu@1889
   627
{
mathieu@3900
   628
  return m_state->GetStateDuration ();
mathieu@1889
   629
}
mathieu@1889
   630
Time
mathieu@3888
   631
YansWifiPhy::GetDelayUntilIdle (void)
mathieu@1889
   632
{
mathieu@3900
   633
  return m_state->GetDelayUntilIdle ();
mathieu@1889
   634
}
mathieu@1889
   635
mathieu@2139
   636
Time 
mathieu@3888
   637
YansWifiPhy::GetLastRxStartTime (void) const
mathieu@2139
   638
{
mathieu@3900
   639
  return m_state->GetLastRxStartTime ();
mathieu@2139
   640
}
mathieu@2139
   641
mathieu@3905
   642
Time 
mathieu@3905
   643
YansWifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const
mathieu@1889
   644
{
mathieu@3905
   645
  return m_interference.CalculateTxDuration (size, payloadMode, preamble);
mathieu@1889
   646
}
mathieu@1889
   647
mathieu@1889
   648
double 
mathieu@3888
   649
YansWifiPhy::DbToRatio (double dB) const
mathieu@1889
   650
{
mathieu@1889
   651
  double ratio = pow(10.0,dB/10.0);
mathieu@1889
   652
  return ratio;
mathieu@1889
   653
}
mathieu@1889
   654
mathieu@1889
   655
double 
mathieu@3888
   656
YansWifiPhy::DbmToW (double dBm) const
mathieu@1889
   657
{
mathieu@1889
   658
  double mW = pow(10.0,dBm/10.0);
mathieu@1889
   659
  return mW / 1000.0;
mathieu@1889
   660
}
mathieu@1889
   661
mathieu@1889
   662
double
mathieu@3888
   663
YansWifiPhy::WToDbm (double w) const
mathieu@2524
   664
{
mathieu@2524
   665
  return 10.0 * log10(w * 1000.0);
mathieu@2524
   666
}
mathieu@2524
   667
mathieu@2524
   668
double
mathieu@3888
   669
YansWifiPhy::RatioToDb (double ratio) const
mathieu@2524
   670
{
mathieu@2524
   671
  return 10.0 * log10(ratio);
mathieu@2524
   672
}
mathieu@2524
   673
mathieu@2524
   674
double
mathieu@3888
   675
YansWifiPhy::GetEdThresholdW (void) const
mathieu@1889
   676
{
mathieu@1889
   677
  return m_edThresholdW;
mathieu@1889
   678
}
mathieu@1889
   679
mathieu@1889
   680
double 
mathieu@3888
   681
YansWifiPhy::GetPowerDbm (uint8_t power) const
mathieu@1889
   682
{
mathieu@1974
   683
  NS_ASSERT (m_txPowerBaseDbm <= m_txPowerEndDbm);
mathieu@1974
   684
  NS_ASSERT (m_nTxPower > 0);
Providence@2782
   685
  double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower;
mathieu@1889
   686
  return dbm;
mathieu@1889
   687
}
mathieu@1889
   688
mathieu@1889
   689
void
mathieu@3905
   690
YansWifiPhy::EndSync (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event)
mathieu@1889
   691
{
mathieu@2985
   692
  NS_LOG_FUNCTION (this << packet << event);
mathieu@1974
   693
  NS_ASSERT (IsStateSync ());
mathieu@1974
   694
  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
mathieu@1889
   695
mathieu@3905
   696
  struct InterferenceHelper::SnrPer snrPer;
mathieu@3905
   697
  snrPer = m_interference.CalculateSnrPer (event);
mathieu@3905
   698
mathieu@3905
   699
  NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
mathieu@3905
   700
                ", snr="<<snrPer.snr<<", per="<<snrPer.per<<", size="<<packet->GetSize ());
mathieu@3905
   701
  if (m_random.GetValue () > snrPer.per) 
mathieu@1889
   702
    {
nbaldo@4492
   703
      NotifyRxEnd (packet); 
nbaldo@4492
   704
      uint32_t dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () / 500000;   
nbaldo@4492
   705
      bool isShortPreamble = (WIFI_PREAMBLE_SHORT == event->GetPreambleType ());  
nbaldo@4492
   706
      double signalDbm = RatioToDb (event->GetRxPowerW ()) + 30;
nbaldo@4492
   707
      double noiseDbm = RatioToDb(event->GetRxPowerW() / snrPer.snr) - GetRxNoiseFigure() + 30 ;
nbaldo@4715
   708
      NotifyPromiscSniffRx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, signalDbm, noiseDbm);
mathieu@3905
   709
      m_state->SwitchFromSyncEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ());
mathieu@1889
   710
    } 
mathieu@1889
   711
  else 
mathieu@1889
   712
    {
mathieu@1889
   713
      /* failure. */
craigdo@4264
   714
      NotifyRxDrop (packet);
mathieu@3905
   715
      m_state->SwitchFromSyncEndError (packet, snrPer.snr);
mathieu@1889
   716
    }
mathieu@1889
   717
}
mathieu@1977
   718
} // namespace ns3