src/devices/point-to-point/point-to-point-net-device.cc
author vincent@clarinet.u-strasbg.fr
Fri Nov 07 11:36:15 2008 -0800 (2008-11-07)
changeset 3852 9cf7ad0cac85
parent 3841 1e7abf5fca79
child 3936 e525995ce5dc
permissions -rw-r--r--
Initial IPv6 capability
tomh@368
     1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
tomh@368
     2
/*
craigdo@3086
     3
 * Copyright (c) 2007, 2008 University of Washington
tomh@368
     4
 *
tomh@368
     5
 * This program is free software; you can redistribute it and/or modify
tomh@368
     6
 * it under the terms of the GNU General Public License version 2 as
tomh@368
     7
 * published by the Free Software Foundation;
tomh@368
     8
 *
tomh@368
     9
 * This program is distributed in the hope that it will be useful,
tomh@368
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
tomh@368
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
tomh@368
    12
 * GNU General Public License for more details.
tomh@368
    13
 *
tomh@368
    14
 * You should have received a copy of the GNU General Public License
tomh@368
    15
 * along with this program; if not, write to the Free Software
tomh@368
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
tomh@368
    17
 */
mathieu@245
    18
craigdo@1504
    19
#include "ns3/log.h"
tomh@368
    20
#include "ns3/queue.h"
Craig@378
    21
#include "ns3/simulator.h"
mathieu@1494
    22
#include "ns3/mac48-address.h"
mathieu@1167
    23
#include "ns3/llc-snap-header.h"
tomh@1820
    24
#include "ns3/error-model.h"
mathieu@2502
    25
#include "ns3/trace-source-accessor.h"
craigdo@3632
    26
#include "ns3/uinteger.h"
mathieu@2927
    27
#include "ns3/pointer.h"
emmanuelle@973
    28
#include "point-to-point-net-device.h"
emmanuelle@973
    29
#include "point-to-point-channel.h"
craigdo@3012
    30
#include "ppp-header.h"
tomh@368
    31
craigdo@1504
    32
NS_LOG_COMPONENT_DEFINE ("PointToPointNetDevice");
mathieu@245
    33
mathieu@245
    34
namespace ns3 {
mathieu@245
    35
mathieu@2502
    36
NS_OBJECT_ENSURE_REGISTERED (PointToPointNetDevice);
riley@926
    37
mathieu@2502
    38
TypeId 
mathieu@2502
    39
PointToPointNetDevice::GetTypeId (void)
craigdo@1504
    40
{
mathieu@2602
    41
  static TypeId tid = TypeId ("ns3::PointToPointNetDevice")
mathieu@2502
    42
    .SetParent<NetDevice> ()
mathieu@2502
    43
    .AddConstructor<PointToPointNetDevice> ()
craigdo@3321
    44
    .AddAttribute ("Address", 
craigdo@3321
    45
                   "The MAC address of this device.",
mathieu@2965
    46
                   Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
mathieu@2502
    47
                   MakeMac48AddressAccessor (&PointToPointNetDevice::m_address),
mathieu@2502
    48
                   MakeMac48AddressChecker ())
craigdo@3632
    49
    .AddAttribute ("FrameSize", 
craigdo@3632
    50
                   "The maximum size of a packet sent over this device.",
craigdo@3632
    51
                   UintegerValue (DEFAULT_FRAME_SIZE),
craigdo@3632
    52
                   MakeUintegerAccessor (&PointToPointNetDevice::SetFrameSize,
craigdo@3632
    53
                                         &PointToPointNetDevice::GetFrameSize),
craigdo@3632
    54
                   MakeUintegerChecker<uint16_t> ())
craigdo@3321
    55
    .AddAttribute ("DataRate", 
craigdo@3321
    56
                   "The default data rate for point to point links",
craigdo@3181
    57
                   DataRateValue (DataRate ("32768b/s")),
mathieu@2502
    58
                   MakeDataRateAccessor (&PointToPointNetDevice::m_bps),
mathieu@2502
    59
                   MakeDataRateChecker ())
craigdo@3321
    60
    .AddAttribute ("ReceiveErrorModel", 
craigdo@3321
    61
                   "The receiver error model used to simulate packet loss",
mathieu@2965
    62
                   PointerValue (),
mathieu@2927
    63
                   MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel),
mathieu@2927
    64
                   MakePointerChecker<ErrorModel> ())
craigdo@3321
    65
    .AddAttribute ("TxQueue",
craigdo@3321
    66
                   "A queue to use as the transmit queue in the device.",
mathieu@2965
    67
                   PointerValue (),
mathieu@2927
    68
                   MakePointerAccessor (&PointToPointNetDevice::m_queue),
mathieu@2927
    69
                   MakePointerChecker<Queue> ())
craigdo@3321
    70
    .AddAttribute ("InterframeGap", 
craigdo@3321
    71
                   "The time to wait between packet (frame) transmissions",
mathieu@2965
    72
                   TimeValue (Seconds (0.0)),
mathieu@2502
    73
                   MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap),
mathieu@2502
    74
                   MakeTimeChecker ())
craigdo@3321
    75
    .AddTraceSource ("Rx", 
craigdo@3321
    76
                     "Trace source to fire on reception of a MAC packet.",
mathieu@2502
    77
                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_rxTrace))
craigdo@3321
    78
    .AddTraceSource ("Drop",
craigdo@3321
    79
                     "Trace source to fire on when a MAC packet is dropped.",
craigdo@3321
    80
mathieu@2502
    81
                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_dropTrace))
mathieu@2502
    82
mathieu@2502
    83
    ;
mathieu@2502
    84
  return tid;
tomh@1820
    85
}
tomh@1820
    86
craigdo@1504
    87
mathieu@2502
    88
PointToPointNetDevice::PointToPointNetDevice () 
Craig@378
    89
: 
Craig@379
    90
  m_txMachineState (READY),
Craig@379
    91
  m_channel (0), 
mathieu@2470
    92
  m_name (""),
craigdo@3632
    93
  m_linkUp (false)
mathieu@257
    94
{
mathieu@2983
    95
  NS_LOG_FUNCTION (this);
craigdo@3632
    96
craigdo@3632
    97
  //
craigdo@3632
    98
  // A quick sanity check to ensure consistent constants.
craigdo@3632
    99
  //
craigdo@3632
   100
  PppHeader ppp;
craigdo@3632
   101
  NS_ASSERT_MSG (PPP_OVERHEAD == ppp.GetSerializedSize (), 
craigdo@3632
   102
                 "PointToPointNetDevice::PointToPointNetDevice(): PPP_OVERHEAD inconsistent");
craigdo@3632
   103
craigdo@3632
   104
  m_frameSize = DEFAULT_FRAME_SIZE;
craigdo@3632
   105
  m_mtu = MtuFromFrameSize (m_frameSize);
mathieu@257
   106
}
mathieu@245
   107
mathieu@2470
   108
PointToPointNetDevice::~PointToPointNetDevice ()
mathieu@2655
   109
{
mathieu@2655
   110
}
mathieu@2655
   111
craigdo@3181
   112
  void 
mathieu@1866
   113
PointToPointNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
emmanuelle@975
   114
{
mathieu@2983
   115
  NS_LOG_FUNCTION_NOARGS ();
craigdo@3012
   116
  NS_ASSERT_MSG (protocolNumber == 0x800,
craigdo@3012
   117
    "PointToPointNetDevice::AddHeader(): protocolNumber must be 0x800");
craigdo@3012
   118
  PppHeader ppp;
craigdo@3012
   119
  p->AddHeader (ppp);
emmanuelle@975
   120
}
emmanuelle@975
   121
craigdo@3181
   122
  bool 
mathieu@1866
   123
PointToPointNetDevice::ProcessHeader(Ptr<Packet> p, uint16_t& param)
emmanuelle@975
   124
{
mathieu@2983
   125
  NS_LOG_FUNCTION_NOARGS ();
craigdo@3012
   126
  PppHeader ppp;
craigdo@3012
   127
  p->RemoveHeader (ppp);
craigdo@3012
   128
  param = 0x800;
emmanuelle@975
   129
  return true;
emmanuelle@975
   130
}
emmanuelle@975
   131
craigdo@3181
   132
  void 
craigdo@3181
   133
PointToPointNetDevice::DoDispose()
mathieu@465
   134
{
mathieu@2983
   135
  NS_LOG_FUNCTION_NOARGS ();
mathieu@2470
   136
  m_node = 0;
mathieu@568
   137
  m_channel = 0;
mathieu@2470
   138
  m_receiveErrorModel = 0;
mathieu@568
   139
  NetDevice::DoDispose ();
mathieu@465
   140
}
mathieu@465
   141
craigdo@3181
   142
  void 
craigdo@3181
   143
PointToPointNetDevice::SetDataRate(DataRate bps)
Craig@378
   144
{
mathieu@2983
   145
  NS_LOG_FUNCTION_NOARGS ();
craigdo@3181
   146
  m_bps = bps;
Craig@378
   147
}
tomh@368
   148
craigdo@3181
   149
  void 
craigdo@3181
   150
PointToPointNetDevice::SetInterframeGap(Time t)
Craig@378
   151
{
mathieu@2983
   152
  NS_LOG_FUNCTION_NOARGS ();
Craig@378
   153
  m_tInterframeGap = t;
Craig@378
   154
}
Craig@378
   155
craigdo@3181
   156
  bool
mathieu@1866
   157
PointToPointNetDevice::TransmitStart (Ptr<Packet> p)
Craig@378
   158
{
mathieu@2983
   159
  NS_LOG_FUNCTION (this << p);
mathieu@1866
   160
  NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
Craig@378
   161
//
Craig@378
   162
// This function is called to start the process of transmitting a packet.
Craig@378
   163
// We need to tell the channel that we've started wiggling the wire and
riley@926
   164
// schedule an event that will be executed when the transmission is complete.
Craig@378
   165
//
Craig@414
   166
  NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
Craig@378
   167
  m_txMachineState = BUSY;
mathieu@1866
   168
  Time txTime = Seconds (m_bps.CalculateTxTime(p->GetSize()));
riley@926
   169
  Time txCompleteTime = txTime + m_tInterframeGap;
Craig@378
   170
craigdo@1504
   171
  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << 
riley@926
   172
    txCompleteTime.GetSeconds () << "sec");
craigdo@3181
   173
riley@926
   174
  Simulator::Schedule (txCompleteTime, 
craigdo@3181
   175
    &PointToPointNetDevice::TransmitComplete, this);
craigdo@3181
   176
riley@926
   177
  return m_channel->TransmitStart(p, this, txTime); 
Craig@378
   178
}
Craig@378
   179
craigdo@3181
   180
  void 
craigdo@3181
   181
PointToPointNetDevice::TransmitComplete (void)
Craig@378
   182
{
mathieu@2983
   183
  NS_LOG_FUNCTION_NOARGS ();
Craig@378
   184
//
craigdo@3181
   185
// This function is called to when we're all done transmitting a packet.
craigdo@3181
   186
// We try and pull another packet off of the transmit queue.  If the queue
craigdo@3181
   187
// is empty, we are done, otherwise we need to start transmitting the
craigdo@3181
   188
// next packet.
Craig@378
   189
//
Craig@414
   190
  NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
riley@926
   191
  m_txMachineState = READY;
mathieu@1866
   192
  Ptr<Packet> p = m_queue->Dequeue ();
mathieu@1866
   193
  if (p == 0)
mathieu@1866
   194
    {
craigdo@3181
   195
//
craigdo@3181
   196
// No packet was on the queue, so we just exit.
craigdo@3181
   197
//
craigdo@3181
   198
      return;
mathieu@1866
   199
    }
craigdo@3181
   200
//
craigdo@3181
   201
// Got another packet off of the queue, so start the transmit process agin.
craigdo@3181
   202
//
riley@926
   203
  TransmitStart(p);
tomh@773
   204
}
tomh@773
   205
craigdo@3181
   206
  bool 
craigdo@1504
   207
PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
mathieu@245
   208
{
mathieu@2983
   209
  NS_LOG_FUNCTION (this << &ch);
tomh@368
   210
tomh@368
   211
  m_channel = ch;
Craig@378
   212
Craig@378
   213
  m_channel->Attach(this);
Craig@378
   214
craigdo@3181
   215
//
craigdo@3181
   216
// This device is up whenever it is attached to a channel.  A better plan
craigdo@3181
   217
// would be to have the link come up when both devices are attached, but this
craigdo@3181
   218
// is not done for now.
craigdo@3181
   219
//
tomh@368
   220
  NotifyLinkUp ();
mathieu@245
   221
  return true;
mathieu@245
   222
}
mathieu@245
   223
craigdo@3181
   224
  void
craigdo@3181
   225
PointToPointNetDevice::SetQueue (Ptr<Queue> q)
tomh@345
   226
{
mathieu@2983
   227
  NS_LOG_FUNCTION (this << q);
tomh@368
   228
  m_queue = q;
tomh@345
   229
}
tomh@345
   230
craigdo@3181
   231
  void
craigdo@3181
   232
PointToPointNetDevice::SetReceiveErrorModel (Ptr<ErrorModel> em)
tomh@1820
   233
{
craigdo@3321
   234
  NS_LOG_FUNCTION (this << em);
tomh@1820
   235
  m_receiveErrorModel = em;
tomh@1820
   236
}
tomh@1820
   237
craigdo@3181
   238
 void
craigdo@3181
   239
PointToPointNetDevice::Receive (Ptr<Packet> packet)
mathieu@245
   240
{
mathieu@2983
   241
  NS_LOG_FUNCTION (this << packet);
mathieu@1186
   242
  uint16_t protocol = 0;
mathieu@1308
   243
mathieu@1870
   244
  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) ) 
tomh@1820
   245
    {
craigdo@3181
   246
// 
craigdo@3181
   247
// If we have an error model and it indicates that it is time to lose a
craigdo@3181
   248
// corrupted packet, don't forward this packet up, let it go.
craigdo@3181
   249
//
tomh@1820
   250
      m_dropTrace (packet);
tomh@1820
   251
    }
tomh@1820
   252
  else 
tomh@1820
   253
    {
craigdo@3181
   254
// 
craigdo@3181
   255
// Hit the receive trace hook, strip off the point-to-point protocol header
craigdo@3181
   256
// and forward this packet up the protocol stack.
craigdo@3181
   257
//
tomh@1820
   258
      m_rxTrace (packet);
tomh@1820
   259
      ProcessHeader(packet, protocol);
mathieu@3584
   260
      m_rxCallback (this, packet, protocol, GetRemote ());
mathieu@3584
   261
      if (!m_promiscCallback.IsNull ())
mathieu@3584
   262
        {
mathieu@3584
   263
          m_promiscCallback (this, packet, protocol, GetRemote (), GetAddress (), NetDevice::PACKET_HOST);
mathieu@3584
   264
        }
tomh@1820
   265
    }
mathieu@245
   266
}
mathieu@245
   267
craigdo@3181
   268
  Ptr<Queue> 
craigdo@3181
   269
PointToPointNetDevice::GetQueue(void) const 
tomh@368
   270
{ 
mathieu@2983
   271
  NS_LOG_FUNCTION_NOARGS ();
craigdo@1504
   272
  return m_queue;
tomh@368
   273
}
tomh@368
   274
craigdo@3181
   275
  void
mathieu@2470
   276
PointToPointNetDevice::NotifyLinkUp (void)
mathieu@2470
   277
{
mathieu@2470
   278
  m_linkUp = true;
mathieu@2470
   279
  if (!m_linkChangeCallback.IsNull ())
mathieu@2470
   280
    {
mathieu@2470
   281
      m_linkChangeCallback ();
mathieu@2470
   282
    }
mathieu@2470
   283
}
mathieu@2470
   284
craigdo@3181
   285
  void 
mathieu@2470
   286
PointToPointNetDevice::SetName(const std::string name)
mathieu@2470
   287
{
mathieu@2470
   288
  m_name = name;
mathieu@2470
   289
}
craigdo@3181
   290
craigdo@3181
   291
  std::string 
mathieu@2470
   292
PointToPointNetDevice::GetName(void) const
mathieu@2470
   293
{
mathieu@2470
   294
  return m_name;
mathieu@2470
   295
}
craigdo@3181
   296
craigdo@3181
   297
  void 
mathieu@2470
   298
PointToPointNetDevice::SetIfIndex(const uint32_t index)
mathieu@2470
   299
{
mathieu@2470
   300
  m_ifIndex = index;
mathieu@2470
   301
}
craigdo@3181
   302
craigdo@3181
   303
  uint32_t 
mathieu@2470
   304
PointToPointNetDevice::GetIfIndex(void) const
mathieu@2470
   305
{
mathieu@2470
   306
  return m_ifIndex;
mathieu@2470
   307
}
craigdo@3181
   308
craigdo@3181
   309
  Ptr<Channel> 
mathieu@2470
   310
PointToPointNetDevice::GetChannel (void) const
mathieu@2470
   311
{
craigdo@1504
   312
  return m_channel;
tomh@368
   313
}
craigdo@3181
   314
craigdo@3181
   315
//
craigdo@3181
   316
// This is a point-to-point device, so we really don't need any kind of address
craigdo@3181
   317
// information.  However, the base class NetDevice wants us to define the
craigdo@3181
   318
// methods to get and set the address.  Rather than be rude and assert, we let
craigdo@3181
   319
// clients get and set the address, but simply ignore them.
craigdo@3181
   320
  void 
craigdo@3181
   321
PointToPointNetDevice::SetAddress (Mac48Address addr)
craigdo@3181
   322
{
craigdo@3181
   323
  m_address = addr;
craigdo@3181
   324
}
craigdo@3181
   325
craigdo@3181
   326
  Address 
mathieu@2470
   327
PointToPointNetDevice::GetAddress (void) const
mathieu@445
   328
{
mathieu@2470
   329
  return m_address;
mathieu@2470
   330
}
craigdo@3181
   331
craigdo@3181
   332
  bool 
mathieu@2470
   333
PointToPointNetDevice::IsLinkUp (void) const
mathieu@2470
   334
{
mathieu@2470
   335
  return m_linkUp;
mathieu@2470
   336
}
craigdo@3181
   337
craigdo@3181
   338
  void 
mathieu@2470
   339
PointToPointNetDevice::SetLinkChangeCallback (Callback<void> callback)
mathieu@2470
   340
{
mathieu@2470
   341
  m_linkChangeCallback = callback;
mathieu@2470
   342
}
craigdo@3181
   343
craigdo@3181
   344
//
craigdo@3181
   345
// This is a point-to-point device, so every transmission is a broadcast to
craigdo@3181
   346
// all of the devices on the network.
craigdo@3181
   347
//
craigdo@3181
   348
  bool 
mathieu@2470
   349
PointToPointNetDevice::IsBroadcast (void) const
mathieu@2470
   350
{
mathieu@2470
   351
  return true;
mathieu@2470
   352
}
craigdo@3181
   353
craigdo@3181
   354
//
craigdo@3181
   355
// We don't really need any addressing information since this is a 
craigdo@3181
   356
// point-to-point device.  The base class NetDevice wants us to return a
craigdo@3181
   357
// broadcast address, so we make up something reasonable.
craigdo@3181
   358
//
craigdo@3181
   359
  Address
mathieu@2470
   360
PointToPointNetDevice::GetBroadcast (void) const
mathieu@2470
   361
{
mathieu@2470
   362
  return Mac48Address ("ff:ff:ff:ff:ff:ff");
mathieu@2470
   363
}
craigdo@3181
   364
craigdo@3181
   365
//
craigdo@3181
   366
// We don't deal with multicast here.  It doesn't make sense to include some
craigdo@3181
   367
// of the one destinations on the network but exclude some of the others.
craigdo@3321
   368
//
craigdo@3181
   369
  bool 
mathieu@2470
   370
PointToPointNetDevice::IsMulticast (void) const
mathieu@2470
   371
{
mathieu@445
   372
  return false;
mathieu@445
   373
}
craigdo@3181
   374
craigdo@3181
   375
  Address 
craigdo@3841
   376
PointToPointNetDevice::GetMulticast (Ipv4Address multicastGroup) const
mathieu@2470
   377
{
mathieu@2470
   378
  return Mac48Address ("01:00:5e:00:00:00");
mathieu@2470
   379
}
craigdo@3181
   380
vincent@3852
   381
Address
vincent@3852
   382
PointToPointNetDevice::GetMulticast (Ipv6Address addr) const
vincent@3852
   383
{
vincent@3852
   384
  NS_LOG_FUNCTION(this << addr);
vincent@3852
   385
  return Mac48Address ("33:33:00:00:00:00");
vincent@3852
   386
}
vincent@3852
   387
craigdo@3181
   388
  bool 
mathieu@2470
   389
PointToPointNetDevice::IsPointToPoint (void) const
mathieu@2470
   390
{
mathieu@2470
   391
  return true;
mathieu@2470
   392
}
craigdo@3181
   393
craigdo@3181
   394
  bool 
craigdo@3181
   395
PointToPointNetDevice::Send(
craigdo@3181
   396
  Ptr<Packet> packet, 
craigdo@3181
   397
  const Address &dest, 
craigdo@3181
   398
  uint16_t protocolNumber)
mathieu@2470
   399
{
mathieu@2983
   400
  NS_LOG_FUNCTION_NOARGS ();
mathieu@2470
   401
  NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest);
mathieu@2470
   402
  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
mathieu@2470
   403
craigdo@3181
   404
//
craigdo@3181
   405
// If IsLinkUp() is false it means there is no channel to send any packet 
craigdo@3181
   406
// over so we just return an error.
craigdo@3181
   407
//
craigdo@3181
   408
  if (IsLinkUp () == false)
craigdo@3181
   409
    {
craigdo@3181
   410
      return false;
craigdo@3181
   411
    }
craigdo@3181
   412
craigdo@3181
   413
//
craigdo@3181
   414
// Stick a point to point protocol header on the packet in preparation for
craigdo@3181
   415
// shoving it out the door.
craigdo@3181
   416
//
mathieu@2470
   417
  AddHeader(packet, protocolNumber);
mathieu@2470
   418
mathieu@2470
   419
//
mathieu@2470
   420
// If there's a transmission in progress, we enque the packet for later
mathieu@2470
   421
// transmission; otherwise we send it now.
craigdo@3181
   422
//
mathieu@2470
   423
  if (m_txMachineState == READY) 
mathieu@2470
   424
    {
craigdo@3181
   425
// 
craigdo@3181
   426
// Even if the transmitter is immediately available, we still enqueue and 
craigdo@3181
   427
// dequeue the packet to hit the tracing hooks.
craigdo@3181
   428
//
mathieu@2470
   429
      m_queue->Enqueue (packet);
mathieu@2470
   430
      packet = m_queue->Dequeue ();
mathieu@2470
   431
      return TransmitStart (packet);
mathieu@2470
   432
    }
mathieu@2470
   433
  else
mathieu@2470
   434
    {
mathieu@2470
   435
      return m_queue->Enqueue(packet);
mathieu@2470
   436
    }
mathieu@2470
   437
}
craigdo@3181
   438
gjc@3442
   439
bool
gjc@3442
   440
PointToPointNetDevice::SendFrom (Ptr<Packet> packet, 
gjc@3442
   441
                                 const Address &source, 
gjc@3442
   442
                                 const Address &dest, 
gjc@3442
   443
                                 uint16_t protocolNumber)
gjc@3442
   444
{
mathieu@3584
   445
  return false;
gjc@3442
   446
}
gjc@3442
   447
craigdo@3181
   448
  Ptr<Node> 
mathieu@2470
   449
PointToPointNetDevice::GetNode (void) const
mathieu@2470
   450
{
mathieu@2470
   451
  return m_node;
mathieu@2470
   452
}
craigdo@3181
   453
craigdo@3181
   454
  void 
mathieu@2600
   455
PointToPointNetDevice::SetNode (Ptr<Node> node)
mathieu@2600
   456
{
mathieu@2600
   457
  m_node = node;
mathieu@2600
   458
}
craigdo@3181
   459
craigdo@3181
   460
  bool 
mathieu@2470
   461
PointToPointNetDevice::NeedsArp (void) const
mathieu@2470
   462
{
mathieu@2470
   463
  return false;
mathieu@2470
   464
}
craigdo@3181
   465
craigdo@3181
   466
  void 
mathieu@2470
   467
PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
mathieu@2470
   468
{
mathieu@2470
   469
  m_rxCallback = cb;
mathieu@2470
   470
}
mathieu@2470
   471
mathieu@3584
   472
void
mathieu@3584
   473
PointToPointNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
gjc@3480
   474
{
gjc@3480
   475
  NS_FATAL_ERROR ("not implemented");
mathieu@3584
   476
  m_promiscCallback = cb;
gjc@3480
   477
}
gjc@3480
   478
gjc@3480
   479
  bool
mathieu@3584
   480
PointToPointNetDevice::SupportsSendFrom (void) const
gjc@3480
   481
{
gjc@3480
   482
  return false;
gjc@3480
   483
}
gjc@3480
   484
mathieu@3584
   485
Address 
mathieu@3584
   486
PointToPointNetDevice::GetRemote (void) const
mathieu@3584
   487
{
mathieu@3584
   488
  NS_ASSERT (m_channel->GetNDevices () == 2);
mathieu@3584
   489
  for (uint32_t i = 0; i < m_channel->GetNDevices (); ++i)
mathieu@3584
   490
    {
mathieu@3584
   491
      Ptr<NetDevice> tmp = m_channel->GetDevice (i);
mathieu@3584
   492
      if (tmp != this)
mathieu@3584
   493
        {
mathieu@3584
   494
          return tmp->GetAddress ();
mathieu@3584
   495
        }
mathieu@3584
   496
    }
mathieu@3584
   497
  NS_ASSERT (false);
mathieu@3584
   498
  // quiet compiler.
mathieu@3584
   499
  return Address ();
mathieu@3584
   500
}
mathieu@3584
   501
craigdo@3682
   502
  uint32_t
craigdo@3682
   503
PointToPointNetDevice::MtuFromFrameSize (uint32_t frameSize)
craigdo@3632
   504
{
craigdo@3632
   505
  NS_LOG_FUNCTION (frameSize);
craigdo@3682
   506
  NS_ASSERT_MSG (frameSize <= std::numeric_limits<uint16_t>::max (), 
craigdo@3682
   507
                 "PointToPointNetDevice::MtuFromFrameSize(): Frame size should be derived from 16-bit quantity: " << 
craigdo@3682
   508
                 frameSize);
craigdo@3632
   509
  PppHeader ppp;
craigdo@3632
   510
  NS_ASSERT_MSG ((uint32_t)frameSize >= ppp.GetSerializedSize (), 
craigdo@3632
   511
                 "PointToPointNetDevice::MtuFromFrameSize(): Given frame size too small to support PPP");
craigdo@3632
   512
  return frameSize - ppp.GetSerializedSize ();
craigdo@3632
   513
}
craigdo@3632
   514
  
craigdo@3682
   515
  uint32_t
craigdo@3682
   516
PointToPointNetDevice::FrameSizeFromMtu (uint32_t mtu)
craigdo@3632
   517
{
craigdo@3632
   518
  NS_LOG_FUNCTION (mtu);
craigdo@3632
   519
craigdo@3632
   520
  PppHeader ppp;
craigdo@3632
   521
  return mtu + ppp.GetSerializedSize ();
craigdo@3632
   522
}
craigdo@3632
   523
craigdo@3632
   524
  void 
craigdo@3632
   525
PointToPointNetDevice::SetFrameSize (uint16_t frameSize)
craigdo@3632
   526
{
craigdo@3632
   527
  NS_LOG_FUNCTION (frameSize);
craigdo@3632
   528
craigdo@3632
   529
  m_frameSize = frameSize;
craigdo@3632
   530
  m_mtu = MtuFromFrameSize (frameSize);
craigdo@3632
   531
craigdo@3632
   532
  NS_LOG_LOGIC ("m_frameSize = " << m_frameSize);
craigdo@3632
   533
  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
craigdo@3632
   534
}
craigdo@3632
   535
craigdo@3632
   536
  uint16_t
craigdo@3632
   537
PointToPointNetDevice::GetFrameSize (void) const
craigdo@3632
   538
{
craigdo@3632
   539
  return m_frameSize;
craigdo@3632
   540
}
craigdo@3632
   541
craigdo@3632
   542
  bool
craigdo@3632
   543
PointToPointNetDevice::SetMtu (uint16_t mtu)
craigdo@3632
   544
{
craigdo@3632
   545
  NS_LOG_FUNCTION (mtu);
craigdo@3632
   546
craigdo@3682
   547
  uint32_t newFrameSize = FrameSizeFromMtu (mtu);
craigdo@3682
   548
craigdo@3682
   549
  if (newFrameSize > std::numeric_limits<uint16_t>::max ())
craigdo@3682
   550
    {
craigdo@3682
   551
      NS_LOG_WARN ("PointToPointNetDevice::SetMtu(): Frame size overflow, MTU not set.");
craigdo@3682
   552
      return false;
craigdo@3682
   553
    }
craigdo@3682
   554
craigdo@3682
   555
  m_frameSize = newFrameSize;
craigdo@3632
   556
  m_mtu = mtu;
craigdo@3632
   557
craigdo@3632
   558
  NS_LOG_LOGIC ("m_frameSize = " << m_frameSize);
craigdo@3632
   559
  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
craigdo@3632
   560
craigdo@3632
   561
  return true;
craigdo@3632
   562
}
craigdo@3632
   563
craigdo@3632
   564
  uint16_t
craigdo@3632
   565
PointToPointNetDevice::GetMtu (void) const
craigdo@3632
   566
{
craigdo@3632
   567
  NS_LOG_FUNCTION_NOARGS ();
craigdo@3632
   568
  return m_mtu;
craigdo@3632
   569
}
craigdo@3632
   570
craigdo@3632
   571
tomh@368
   572
} // namespace ns3