src/devices/csma/csma-net-device.h
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
emmanuelle@977
     1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
emmanuelle@977
     2
/*
emmanuelle@977
     3
 * Copyright (c) 2007 Emmanuelle Laprise
emmanuelle@977
     4
 *
emmanuelle@977
     5
 * This program is free software; you can redistribute it and/or modify
emmanuelle@977
     6
 * it under the terms of the GNU General Public License version 2 as
emmanuelle@977
     7
 * published by the Free Software Foundation;
emmanuelle@977
     8
 *
emmanuelle@977
     9
 * This program is distributed in the hope that it will be useful,
emmanuelle@977
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
emmanuelle@977
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
emmanuelle@977
    12
 * GNU General Public License for more details.
emmanuelle@977
    13
 *
emmanuelle@977
    14
 * You should have received a copy of the GNU General Public License
emmanuelle@977
    15
 * along with this program; if not, write to the Free Software
emmanuelle@977
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
emmanuelle@977
    17
 *
emmanuelle@977
    18
 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
emmanuelle@977
    19
 */
emmanuelle@977
    20
craigdo@1276
    21
#ifndef CSMA_NET_DEVICE_H
craigdo@1276
    22
#define CSMA_NET_DEVICE_H
emmanuelle@977
    23
emmanuelle@977
    24
#include <string.h>
emmanuelle@977
    25
#include "ns3/node.h"
emmanuelle@977
    26
#include "ns3/backoff.h"
mathieu@1167
    27
#include "ns3/address.h"
emmanuelle@977
    28
#include "ns3/net-device.h"
emmanuelle@977
    29
#include "ns3/callback.h"
emmanuelle@977
    30
#include "ns3/packet.h"
mathieu@2500
    31
#include "ns3/traced-callback.h"
emmanuelle@977
    32
#include "ns3/nstime.h"
emmanuelle@977
    33
#include "ns3/data-rate.h"
emmanuelle@977
    34
#include "ns3/ptr.h"
emmanuelle@977
    35
#include "ns3/random-variable.h"
mathieu@1494
    36
#include "ns3/mac48-address.h"
emmanuelle@977
    37
emmanuelle@977
    38
namespace ns3 {
emmanuelle@977
    39
emmanuelle@977
    40
class Queue;
craigdo@1276
    41
class CsmaChannel;
tomh@1820
    42
class ErrorModel;
emmanuelle@977
    43
mathieu@1403
    44
/**
craigdo@1276
    45
 * \class CsmaNetDevice
craigdo@1276
    46
 * \brief A Device for a Csma Network Link.
emmanuelle@977
    47
 *
craigdo@1276
    48
 * The Csma net device class is analogous to layer 1 and 2 of the
emmanuelle@977
    49
 * TCP stack. The NetDevice takes a raw packet of bytes and creates a
craigdo@3257
    50
 * protocol specific packet from them. 
craigdo@3257
    51
 *
craigdo@3257
    52
 * Each Csma net device will receive all packets written to the Csma link. 
craigdo@3257
    53
 * The ProcessHeader function can be used to filter out the packets such that
craigdo@3257
    54
 * higher level layers only receive packets that are addressed to their
craigdo@3257
    55
 * associated net devices
emmanuelle@977
    56
 */
mathieu@2500
    57
class CsmaNetDevice : public NetDevice 
mathieu@2500
    58
{
emmanuelle@977
    59
public:
mathieu@2500
    60
  static TypeId GetTypeId (void);
craigdo@3506
    61
emmanuelle@977
    62
  /**
emmanuelle@977
    63
   * Enumeration of the types of packets supported in the class.
emmanuelle@977
    64
   *
emmanuelle@977
    65
   */
craigdo@3506
    66
  enum EncapsulationMode {
craigdo@3630
    67
    ILLEGAL,     /**< Encapsulation mode not set */
craigdo@3629
    68
    DIX,         /**< DIX II / Ethernet II packet */
craigdo@3630
    69
    LLC,         /**< 802.2 LLC/SNAP Packet*/  
craigdo@3257
    70
  };
emmanuelle@977
    71
emmanuelle@977
    72
  /**
craigdo@1276
    73
   * Construct a CsmaNetDevice
emmanuelle@977
    74
   *
craigdo@3257
    75
   * This is the default constructor for a CsmaNetDevice.
emmanuelle@977
    76
   */
mathieu@2500
    77
  CsmaNetDevice ();
tomh@1280
    78
tomh@1280
    79
  /**
craigdo@1276
    80
   * Destroy a CsmaNetDevice
emmanuelle@977
    81
   *
craigdo@3257
    82
   * This is the destructor for a CsmaNetDevice.
emmanuelle@977
    83
   */
craigdo@3257
    84
  virtual ~CsmaNetDevice ();
craigdo@3257
    85
emmanuelle@977
    86
  /**
emmanuelle@977
    87
   * Set the inteframe gap used to separate packets.  The interframe gap
emmanuelle@977
    88
   * defines the minimum space required between packets sent by this device.
craigdo@3257
    89
   * As in Ethernet, it defaults to 96 bit times.
emmanuelle@977
    90
   *
emmanuelle@977
    91
   * \param t the interframe gap time
emmanuelle@977
    92
   */
emmanuelle@977
    93
  void SetInterframeGap (Time t);
craigdo@3257
    94
emmanuelle@977
    95
  /**
emmanuelle@977
    96
   * Set the backoff parameters used to determine the wait to retry
emmanuelle@977
    97
   * transmitting a packet when the channel is busy.
emmanuelle@977
    98
   *
craigdo@3504
    99
   * \see Attach ()
emmanuelle@977
   100
   * \param slotTime Length of a packet slot (or average packet time)
emmanuelle@977
   101
   * \param minSlots Minimum number of slots to wait
emmanuelle@977
   102
   * \param maxSlots Maximum number of slots to wait
emmanuelle@977
   103
   * \param maxRetries Maximum number of retries before packet is discard
emmanuelle@977
   104
   * \param ceiling Cap on the exponential function when calculating max slots
emmanuelle@977
   105
   */
emmanuelle@977
   106
  void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, 
craigdo@3257
   107
    uint32_t maxRetries, uint32_t ceiling);
craigdo@3257
   108
emmanuelle@977
   109
  /**
emmanuelle@977
   110
   * Attach the device to a channel.
emmanuelle@977
   111
   *
craigdo@3257
   112
   * The function Attach is used to add a CsmaNetDevice to a CsmaChannel.
emmanuelle@977
   113
   *
craigdo@3504
   114
   * \see SetDataRate ()
craigdo@3504
   115
   * \see SetInterframeGap ()
emmanuelle@977
   116
   * \param ch a pointer to the channel to which this object is being attached.
emmanuelle@977
   117
   */
craigdo@1276
   118
  bool Attach (Ptr<CsmaChannel> ch);
craigdo@3257
   119
emmanuelle@977
   120
  /**
craigdo@1276
   121
   * Attach a queue to the CsmaNetDevice.
emmanuelle@977
   122
   *
craigdo@3257
   123
   * The CsmaNetDevice "owns" a queue.  This queue may be set by higher
craigdo@3257
   124
   * level topology objects to implement a particular queueing method such as
craigdo@3257
   125
   * DropTail or RED.  
emmanuelle@977
   126
   *
craigdo@3504
   127
   * \see Queue
craigdo@3504
   128
   * \see DropTailQueue
craigdo@3257
   129
   * \param queue a Ptr to the queue for being assigned to the device.
emmanuelle@977
   130
   */
craigdo@3011
   131
  void SetQueue (Ptr<Queue> queue);
craigdo@3257
   132
emmanuelle@977
   133
  /**
tomh@1820
   134
   * Attach a receive ErrorModel to the CsmaNetDevice.
tomh@1820
   135
   *
tomh@1820
   136
   * The CsmaNetDevice may optionally include an ErrorModel in
craigdo@3257
   137
   * the packet receive chain to simulate data errors in during transmission.
tomh@1820
   138
   *
craigdo@3504
   139
   * \see ErrorModel
craigdo@3504
   140
   * \param em a pointer to the ErrorModel 
tomh@1820
   141
   */
craigdo@3257
   142
  void SetReceiveErrorModel (Ptr<ErrorModel> em);
craigdo@3257
   143
tomh@1820
   144
  /**
craigdo@1276
   145
   * Receive a packet from a connected CsmaChannel.
emmanuelle@977
   146
   *
craigdo@1276
   147
   * The CsmaNetDevice receives packets from its connected channel
emmanuelle@977
   148
   * and forwards them up the protocol stack.  This is the public method
emmanuelle@977
   149
   * used by the channel to indicate that the last bit of a packet has 
emmanuelle@977
   150
   * arrived at the device.
emmanuelle@977
   151
   *
craigdo@3504
   152
   * \see CsmaChannel
emmanuelle@977
   153
   * \param p a reference to the received packet
gjc@3447
   154
   * \param sender the CsmaNetDevice that transmitted the packet in the first place
emmanuelle@977
   155
   */
gjc@3447
   156
  void Receive (Ptr<Packet> p, Ptr<CsmaNetDevice> sender);
emmanuelle@977
   157
craigdo@3257
   158
  /**
craigdo@3257
   159
   * Is the send side of the network device enabled?
craigdo@3257
   160
   *
craigdo@3257
   161
   * \returns True if the send side is enabled, otherwise false.
craigdo@3257
   162
   */
mathieu@2470
   163
  bool IsSendEnabled (void);
craigdo@3257
   164
craigdo@3257
   165
  /**
craigdo@3257
   166
   * Enable or disable the send side of the network device.
craigdo@3257
   167
   *
craigdo@3257
   168
   * \param enable Enable the send side if true, otherwise disable.
craigdo@3257
   169
   */
craigdo@3257
   170
  void SetSendEnable (bool enable);
craigdo@3257
   171
craigdo@3257
   172
  /**
craigdo@3257
   173
   * Is the receive side of the network device enabled?
craigdo@3257
   174
   *
craigdo@3257
   175
   * \returns True if the receiver side is enabled, otherwise false.
craigdo@3257
   176
   */
mathieu@2470
   177
  bool IsReceiveEnabled (void);
mathieu@2470
   178
craigdo@3257
   179
  /**
craigdo@3257
   180
   * Enable or disable the receive side of the network device.
craigdo@3257
   181
   *
craigdo@3257
   182
   * \param enable Enable the receive side if true, otherwise disable.
craigdo@3257
   183
   */
craigdo@3257
   184
  void SetReceiveEnable (bool enable);
mathieu@2470
   185
craigdo@3257
   186
  /**
craigdo@3257
   187
   * Set the MAC address of the the network device.
craigdo@3257
   188
   *
craigdo@3257
   189
   * \param addr The Mac48Address to use as the address of the device.
craigdo@3257
   190
   */
craigdo@3257
   191
  void SetAddress (Mac48Address addr);
mathieu@2655
   192
craigdo@3506
   193
  /**
craigdo@3629
   194
   * Set The max frame size of packets sent over this device.
craigdo@3506
   195
   *
craigdo@3510
   196
   * Okay, that was easy to say, but the details are a bit thorny.  We have a MAC-level MTU that is the payload that higher 
craigdo@3506
   197
   * level protocols see.  We have a PHY-level MTU which is the maximum number of bytes we can send over the link 
craigdo@3629
   198
   * (cf. 1500 bytes for Ethernet).  We also have a frame size which is some total number of bytes in a packet which could
craigdo@3629
   199
   * or could not include any framing and overhead.  There can be a lot of inconsistency in definitions of these terms.  For
craigdo@3629
   200
   * example, RFC 1042 asserts that the terms maximum transmission unit and maximum packet size are equivalent.  RFC 791, 
craigdo@3629
   201
   * however, defines MTU as the maximum sized IP datagram that can be sent.  Packet size and frame size are sometimes
craigdo@3629
   202
   * used interchangeably.
craigdo@3629
   203
   *
craigdo@3629
   204
   * So, some careful definitions are in order to avoid confusion:
craigdo@3629
   205
   *
craigdo@3629
   206
   * In real Ethernet, a packet on the wire starts with a preamble of seven bytes of alternating ones and zeroes followed by
craigdo@3629
   207
   * a Start-of-Frame-Delimeter (10101011).  This is followed by what is usually called the packet: a MAC destination and 
craigdo@3629
   208
   * source, a type field, payload, a possible padding field and a CRC.  To be strictly and pedantically correct the frame 
craigdo@3629
   209
   * size is necessarily larger than the packet size on a real Ethernet.  But, this isn't a real Ethernet, it's a simulation
craigdo@3629
   210
   * of a device similar to Ethernet, and we have no good reason to add framing bits.  So, in the case of the CSMA device, 
craigdo@3629
   211
   * the frame size is equal to the packet size.  Since these two values are equal, there is no danger in assuming they are 
craigdo@3629
   212
   * identical.  We do not implement any padding out to a minimum frame size, so padding is a non-issue.  We define packet 
craigdo@3629
   213
   * size to be equal to frame size and this excludes the preamble and SFD bytes of a real Ethernet frame.  We define a 
craigdo@3629
   214
   * single (MAC-level) MTU that coresponds to the payload size of the packet, which is the IP-centric view of the term as
craigdo@3629
   215
   * seen in RFC 791.
craigdo@3629
   216
   *
craigdo@3629
   217
   * To make this concrete, consider DIX II (Digital Equipment, Intel, Xerox type II) framing, which is used in most TCP/IP 
craigdo@3630
   218
   * stacks.  NetWare and Wireshark call this framing Ethernet II, by the way.  In this framing scheme, a real packet on the 
craigdo@3630
   219
   * wire starts with the preamble and Start-of-Frame-Delimeter (10101011).  We ignore these bits on this device since it they 
craigdo@3630
   220
   * are not  needed.  In DIX II, the SFD is followed by the MAC (48) destination address (6 bytes), source address (6 bytes), 
craigdo@3630
   221
   * the EtherType field (2 bytes), payload (0-1500 bytes) and a CRC (4 bytes) -- this corresponds to our entire frame.  The
craigdo@3629
   222
   * payload of the packet/frame in DIX can be from 0 to 1500 bytes.  It is the maxmimum value of this payload that we call
craigdo@3629
   223
   * the MTU.  Typically, one sees the MTU set to 1500 bytes and the maximum frame size set to 1518 bytes in Ethernet-based
craigdo@3629
   224
   * networks.
craigdo@3629
   225
   *
craigdo@3629
   226
   * Different framing schemes can make for different MTU and frame size relationships.  For example, we support LLC/SNAP
craigdo@3629
   227
   * encapsulation which adds eight bytes of header overhead to the usual DIX framing.  In this case, if the maximum frame
craigdo@3629
   228
   * size is left at 1518 bytes, we need to export an MTU that reflects the loss of eight bytes for a total of 1492.
craigdo@3629
   229
   * 
craigdo@3629
   230
   * Another complication is that IEEE 802.1Q adds four bytes to the maximum frame size for VLAN tagging.  In order to 
craigdo@3629
   231
   * provide an MTU of 1500 bytes, the frame size would need to increased to 1522 bytes to absorb the additional overhead.
craigdo@3629
   232
   *
craigdo@3629
   233
   * So, there are really three variables that are not entirely free at work here.  There is the maximum frame size, the
craigdo@3629
   234
   * MTU and the framing scheme which we call the encapsulation mode.
craigdo@3506
   235
   *
craigdo@3510
   236
   * So, what do we do since there are be three values which must always be consistent in the driver?  Which values to we
craigdo@3629
   237
   * allow to be changed and how do we ensure the other two are consistent?  We want to actually allow a user to change 
craigdo@3510
   238
   * these three variables in flexible ways, but we want the results (even at intermediate stages of her ultimate change) to 
craigdo@3510
   239
   * be consistent.  We certainly don't want to require that users must understand the various requirements of an enapsulation
craigdo@3510
   240
   * mode in order to set these variables.
craigdo@3506
   241
   *
craigdo@3629
   242
   * Consider the following situation:  A user wants to set the maximum frame size to 1418 bytes instead of 1518.  This
craigdo@3629
   243
   * user shouldn't have to concern herself that the current encapuslation mode is LLC/SNAP and this will consume eight bytes.
craigdo@3629
   244
   * She should not have to also figure out that the MTU needs to be set to 1392 bytes, and she should certainly not have to 
craigdo@3629
   245
   * do this in some special order to keep intermediate steps consistent.
craigdo@3506
   246
   *
craigdo@3629
   247
   * Similarly, a user who is interested in setting the MTU to 1400 bytes should not be forced to understand that 
craigdo@3629
   248
   * (based on encapsulation mode) the frame size may need to be set to eighteen + eight bytes more than what he wants 
craigdo@3629
   249
   * in certain cases (802,3 + LLC/SNAP), twenty-two + zero bytes in others (802.1Q) and other inscrutable combinations
craigdo@3506
   250
   *
craigdo@3629
   251
   * Now, consider a user who is only interested in changing the encapsulation mode from LLC/SNAP to DIX.  This 
craigdo@3629
   252
   * is going to change the relationship between the MTU and the frame size.  We've may have to come up with a new value 
craigdo@3629
   253
   * for at least one of the these?  Which one?  There are too many free variables.
craigdo@3506
   254
   *
craigdo@3510
   255
   * We could play games trying to figure out what the user wants to do, but that is typically a bad plan and programmers
craigdo@3510
   256
   * have a long and distinguished history of guessing wrong.  We'll avoid all of that and just define a flexible behavior
craigdo@3510
   257
   * that can be worked to get what you want.  Here it is:
craigdo@3506
   258
   *
craigdo@3506
   259
   * - If the user is changing the encapsulation mode, the PHY MTU will remain fixed and the MAC MTU will change, if required,
craigdo@3506
   260
   * to make the three values consistent;
craigdo@3506
   261
   *
craigdo@3629
   262
   * - If the user is changing the MTU, she is interested in getting that part of the system set, so the frame size
craigdo@3506
   263
   * will be changed to make the three values consistent;
craigdo@3506
   264
   *
craigdo@3629
   265
   * - If the user is changing the frame size, he is interested in getting that part of the system set, so the MTU
craigdo@3510
   266
   * will be changed to make the three values consistent;
craigdo@3510
   267
   *
craigdo@3629
   268
   * - You cannot define the MTU and frame size separately -- they are always tied together by the emulation mode.  This
craigdo@3629
   269
   * is not a restriction.  Consider what this means.  Perhaps you want to set the frame size to some large number and the
craigdo@3629
   270
   * MTU to some small number.  The largest packet you can send is going to be limited by the MTU, so it is not possible to
craigdo@3629
   271
   * send a frame larger than the MTU plus overhead.  The larger frame size is not useful.
craigdo@3506
   272
   * 
craigdo@3629
   273
   * So, if a user calls SetFrameSize, we assume that the maximum frame size is the interesting thing for that user and
craigdo@3629
   274
   * we just adjust the MTU to a new "correct value" based on the current encapsulation mode.  If a user calls SetMtu, we 
craigdo@3629
   275
   * assume that the MTU is the interesting property for that user, and we adjust the frame size to a new "correct value" 
craigdo@3629
   276
   * for the current encapsulation mode.  If a user calls SetEncapsulationMode, then we take the MTU as the free variable 
craigdo@3629
   277
   * and set its value to match the current frame size.
craigdo@3506
   278
   *
craigdo@3629
   279
   * \param frameSize The max frame size of packets sent over this device.
craigdo@3506
   280
   */
craigdo@3629
   281
  void SetFrameSize (uint16_t frameSize);
craigdo@3506
   282
craigdo@3506
   283
  /**
craigdo@3629
   284
   * Get The max frame size of packets sent over this device.
craigdo@3506
   285
   *
craigdo@3629
   286
   * \returns The max frame size of packets sent over this device.
craigdo@3506
   287
   */
craigdo@3629
   288
  uint16_t GetFrameSize (void) const;
craigdo@3506
   289
craigdo@3506
   290
  /**
craigdo@3506
   291
   * Set the encapsulation mode of this device.
craigdo@3506
   292
   *
craigdo@3506
   293
   * \param mode The encapsulation mode of this device.
craigdo@3506
   294
   *
craigdo@3629
   295
   * \see SetFrameSize
craigdo@3506
   296
   */
craigdo@3506
   297
  void SetEncapsulationMode (CsmaNetDevice::EncapsulationMode mode);
craigdo@3506
   298
craigdo@3506
   299
  /**
craigdo@3506
   300
   * Get the encapsulation mode of this device.
craigdo@3506
   301
   *
craigdo@3506
   302
   * \returns The encapsulation mode of this device.
craigdo@3506
   303
   */
craigdo@3506
   304
  CsmaNetDevice::EncapsulationMode  GetEncapsulationMode (void);
craigdo@3506
   305
craigdo@3506
   306
  //
craigdo@3506
   307
  // The following methods are inherited from NetDevice base class.
craigdo@3506
   308
  //
craigdo@3257
   309
  virtual void SetName (const std::string name);
craigdo@3257
   310
  virtual std::string GetName (void) const;
craigdo@3257
   311
  virtual void SetIfIndex (const uint32_t index);
craigdo@3257
   312
  virtual uint32_t GetIfIndex (void) const;
mathieu@2470
   313
  virtual Ptr<Channel> GetChannel (void) const;
mathieu@2470
   314
  virtual bool SetMtu (const uint16_t mtu);
mathieu@2470
   315
  virtual uint16_t GetMtu (void) const;
craigdo@3506
   316
  virtual Address GetAddress (void) const;
mathieu@2470
   317
  virtual bool IsLinkUp (void) const;
mathieu@2470
   318
  virtual void SetLinkChangeCallback (Callback<void> callback);
mathieu@2470
   319
  virtual bool IsBroadcast (void) const;
mathieu@2470
   320
  virtual Address GetBroadcast (void) const;
mathieu@2470
   321
  virtual bool IsMulticast (void) const;
craigdo@3257
   322
craigdo@1443
   323
  /**
craigdo@3504
   324
   * \brief Make and return a MAC multicast address using the provided
craigdo@1443
   325
   *        multicast group
craigdo@1443
   326
   *
craigdo@1443
   327
   * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet 
craigdo@1443
   328
   * multicast address by placing the low-order 23-bits of the IP address into 
craigdo@1443
   329
   * the low-order 23 bits of the Ethernet multicast address 
craigdo@1443
   330
   * 01-00-5E-00-00-00 (hex).
craigdo@1443
   331
   *
craigdo@1443
   332
   * This method performs the multicast address creation function appropriate
craigdo@1443
   333
   * to an EUI-48-based CSMA device.  This MAC address is encapsulated in an
craigdo@1443
   334
   *  abstract Address to avoid dependencies on the exact address format.
craigdo@1443
   335
   *
craigdo@3504
   336
   * \param multicastGroup The IP address for the multicast group destination
craigdo@1443
   337
   * of the packet.
craigdo@3504
   338
   * \return The MAC multicast Address used to send packets to the provided
craigdo@1443
   339
   * multicast group.
craigdo@1443
   340
   *
craigdo@3504
   341
   * \see Ipv4Address
craigdo@3504
   342
   * \see Mac48Address
craigdo@3504
   343
   * \see Address
craigdo@1443
   344
   */
craigdo@3841
   345
  virtual Address GetMulticast (Ipv4Address multicastGroup) const;
craigdo@3257
   346
craigdo@3257
   347
  /**
craigdo@3257
   348
   * Is this a point to point link?
craigdo@3257
   349
   * \returns false.
craigdo@3257
   350
   */
mathieu@2470
   351
  virtual bool IsPointToPoint (void) const;
craigdo@3257
   352
craigdo@3257
   353
  /**
craigdo@3257
   354
   * Start sending a packet down the channel.
craigdo@3257
   355
   */
craigdo@3257
   356
  virtual bool Send (Ptr<Packet> packet, const Address& dest, 
craigdo@3257
   357
    uint16_t protocolNumber);
craigdo@3257
   358
craigdo@3257
   359
  /**
gjc@3442
   360
   * Start sending a packet down the channel, with MAC spoofing
gjc@3442
   361
   */
gjc@3442
   362
  virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, 
gjc@3442
   363
                         uint16_t protocolNumber);
gjc@3442
   364
gjc@3442
   365
  /**
craigdo@3257
   366
   * Get the node to which this device is attached.
craigdo@3257
   367
   *
craigdo@3257
   368
   * \returns Ptr to the Node to which the device is attached.
craigdo@3257
   369
   */
mathieu@2470
   370
  virtual Ptr<Node> GetNode (void) const;
craigdo@3257
   371
craigdo@3257
   372
  /**
craigdo@3257
   373
   * Set the node to which this device is being attached.
craigdo@3257
   374
   *
craigdo@3257
   375
   * \param node Ptr to the Node to which the device is being attached.
craigdo@3257
   376
   */
mathieu@2600
   377
  virtual void SetNode (Ptr<Node> node);
craigdo@3257
   378
craigdo@3257
   379
  /**
craigdo@3257
   380
   * Does this device need to use the address resolution protocol?
craigdo@3257
   381
   *
craigdo@3257
   382
   * \returns True if the encapsulation mode is set to a value that requires
craigdo@3257
   383
   * ARP (IP_ARP or LLC).
craigdo@3257
   384
   */
mathieu@2470
   385
  virtual bool NeedsArp (void) const;
craigdo@3257
   386
craigdo@3257
   387
  /**
craigdo@3257
   388
   * Set the callback to be used to notify higher layers when a packet has been
craigdo@3257
   389
   * received.
craigdo@3257
   390
   *
craigdo@3257
   391
   * \param cb The callback.
craigdo@3257
   392
   */
mathieu@2470
   393
  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
emmanuelle@977
   394
vincent@3852
   395
  /**
vincent@3852
   396
   * \brief Get the MAC multicast address corresponding
vincent@3852
   397
   * to the IPv6 address provided.
vincent@3852
   398
   * \param addr IPv6 address
vincent@3852
   399
   * \return the MAC multicast address
vincent@3852
   400
   * \warning Calling this method is invalid if IsMulticast returns not true.
vincent@3852
   401
   */
vincent@3852
   402
  virtual Address GetMulticast (Ipv6Address addr) const;
vincent@3852
   403
gjc@3460
   404
gjc@3460
   405
  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
mathieu@3584
   406
  virtual bool SupportsSendFrom (void) const;
gjc@3460
   407
emmanuelle@977
   408
protected:
craigdo@3257
   409
  /**
craigdo@3257
   410
   * Perform any object release functionality required to break reference 
craigdo@3257
   411
   * cycles in reference counted objects held by the device.
craigdo@3257
   412
   */
emmanuelle@977
   413
  virtual void DoDispose (void);
mathieu@1341
   414
mathieu@1341
   415
  /**
emmanuelle@977
   416
   * Get a copy of the attached Queue.
emmanuelle@977
   417
   *
emmanuelle@977
   418
   * This method is provided for any derived class that may need to get
emmanuelle@977
   419
   * direct access to the underlying queue.
emmanuelle@977
   420
   *
emmanuelle@977
   421
   * \return a pointer to the queue.
emmanuelle@977
   422
   */
emmanuelle@977
   423
  Ptr<Queue> GetQueue (void) const; 
craigdo@3257
   424
emmanuelle@977
   425
  /**
emmanuelle@977
   426
   * Adds the necessary headers and trailers to a packet of data in order to
emmanuelle@977
   427
   * respect the packet type
emmanuelle@977
   428
   *
emmanuelle@977
   429
   * \param p Packet to which header should be added
tomh@3698
   430
   * \param source MAC source address from which packet should be sent
emmanuelle@977
   431
   * \param dest MAC destination address to which packet should be sent
emmanuelle@977
   432
   * \param protocolNumber In some protocols, identifies the type of
emmanuelle@977
   433
   * payload contained in this packet.
emmanuelle@977
   434
   */
gjc@3442
   435
  void AddHeader (Ptr<Packet> p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber);
craigdo@3257
   436
emmanuelle@977
   437
  /**
emmanuelle@977
   438
   * Removes, from a packet of data, all headers and trailers that
emmanuelle@977
   439
   * relate to the packet type
emmanuelle@977
   440
   *
emmanuelle@977
   441
   * \param p Packet whose headers need to be processed
emmanuelle@977
   442
   * \param param An integer parameter that can be set by the function
emmanuelle@977
   443
   * to return information gathered in the header
emmanuelle@977
   444
   * \return Returns true if the packet should be forwarded up the
emmanuelle@977
   445
   * protocol stack.
emmanuelle@977
   446
   */
mathieu@1866
   447
  bool ProcessHeader (Ptr<Packet> p, uint16_t & param);
emmanuelle@977
   448
emmanuelle@977
   449
private:
craigdo@3476
   450
craigdo@3257
   451
  /**
craigdo@3257
   452
   * Operator = is declared but not implemented.  This disables the assigment
craigdo@3257
   453
   * operator for CsmaNetDevice objects.
craigdo@3257
   454
craigdo@3257
   455
   */
craigdo@1276
   456
  CsmaNetDevice &operator = (const CsmaNetDevice &o);
craigdo@3257
   457
craigdo@3257
   458
  /**
craigdo@3257
   459
   * Copy constructor is declared but not implemented.  This disables the
craigdo@3257
   460
   * copy constructor for CsmaNetDevice objects.
craigdo@3257
   461
   */
craigdo@1276
   462
  CsmaNetDevice (const CsmaNetDevice &o);
craigdo@3257
   463
emmanuelle@977
   464
  /**
craigdo@3257
   465
   * Initialization function used during object construction.
emmanuelle@977
   466
   */
emmanuelle@977
   467
  void Init (bool sendEnable, bool receiveEnable);
emmanuelle@977
   468
emmanuelle@977
   469
  /**
craigdo@3629
   470
   * Calculate the value for the MTU that would result from 
craigdo@3629
   471
   * setting the frame size to the given value.
craigdo@3506
   472
   */
craigdo@3682
   473
  uint32_t MtuFromFrameSize (uint32_t frameSize);
craigdo@3506
   474
craigdo@3506
   475
  /**
craigdo@3629
   476
   * Calculate the value for the frame size that would be required
craigdo@3629
   477
   * to be able to set the MTU to the given value.
craigdo@3506
   478
   */
craigdo@3682
   479
  uint32_t FrameSizeFromMtu (uint32_t mtu);
craigdo@3506
   480
craigdo@3506
   481
  /**
emmanuelle@977
   482
   * Start Sending a Packet Down the Wire.
emmanuelle@977
   483
   *
emmanuelle@977
   484
   * The TransmitStart method is the method that is used internally in
craigdo@1276
   485
   * the CsmaNetDevice to begin the process of sending a packet
craigdo@3257
   486
   * out on the channel.  A corresponding method is called on the
emmanuelle@977
   487
   * channel to let it know that the physical device this class
craigdo@3257
   488
   * represents has actually started sending signals, this causes the
craigdo@3257
   489
   * channel to enter the BUSY state.  An event is scheduled for the time at
craigdo@3257
   490
   * which the bits have been completely transmitted. 
craigdo@3257
   491
   *
craigdo@3257
   492
   * If the channel is found to be BUSY, this method reschedules itself for
craigdo@3257
   493
   * execution at a later time (within the backoff period).
emmanuelle@977
   494
   *
craigdo@3504
   495
   * \see CsmaChannel::TransmitStart ()
craigdo@3504
   496
   * \see TransmitCompleteEvent ()
emmanuelle@977
   497
   */
emmanuelle@977
   498
  void TransmitStart ();
craigdo@3257
   499
emmanuelle@977
   500
  /**
emmanuelle@977
   501
   * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
emmanuelle@977
   502
   *
emmanuelle@977
   503
   * The TransmitCompleteEvent method is used internally to finish the process
emmanuelle@977
   504
   * of sending a packet out on the channel.  During execution of this method
emmanuelle@977
   505
   * the TransmitEnd method is called on the channel to let it know that the
craigdo@3257
   506
   * physical device this class represents has finished sending simulated
emmanuelle@977
   507
   * signals.  The channel uses this event to begin its speed of light delay
craigdo@3257
   508
   * timer after which it notifies the Net Device(s) at the other end of the 
craigdo@3257
   509
   * link that new bits have arrived (it delivers the Packet).  During this 
craigdo@3257
   510
   * method, the net device also schedules the TransmitReadyEvent at which
craigdo@3257
   511
   * time the transmitter becomes ready to send the next packet.
emmanuelle@977
   512
   *
craigdo@3504
   513
   * \see CsmaChannel::TransmitEnd ()
craigdo@3504
   514
   * \see TransmitReadyEvent ()
emmanuelle@977
   515
   */
emmanuelle@977
   516
  void TransmitCompleteEvent (void);
craigdo@3257
   517
emmanuelle@977
   518
  /**
emmanuelle@977
   519
   * Cause the Transmitter to Become Ready to Send Another Packet.
emmanuelle@977
   520
   *
emmanuelle@977
   521
   * The TransmitReadyEvent method is used internally to re-enable the 
emmanuelle@977
   522
   * transmit machine of the net device.  It is scheduled after a suitable
emmanuelle@977
   523
   * interframe gap after the completion of the previous transmission.
emmanuelle@977
   524
   * The queue is checked at this time, and if there is a packet waiting on
emmanuelle@977
   525
   * the queue, the transmission process is begun.
emmanuelle@977
   526
   *
emmanuelle@977
   527
   * If a packet is in the queue, it is extracted for the queue as the
emmanuelle@977
   528
   * next packet to be transmitted by the net device.
emmanuelle@977
   529
   *
craigdo@3504
   530
   * \see TransmitStart ()
emmanuelle@977
   531
   */
emmanuelle@977
   532
  void TransmitReadyEvent (void);
emmanuelle@977
   533
emmanuelle@977
   534
  /**
emmanuelle@977
   535
   * Aborts the transmission of the current packet
emmanuelle@977
   536
   *
emmanuelle@977
   537
   * If the net device has tried to transmit a packet for more times
emmanuelle@977
   538
   * than the maximum allowed number of retries (channel always busy)
emmanuelle@977
   539
   * then the packet is dropped.
emmanuelle@977
   540
   */
emmanuelle@977
   541
  void TransmitAbort (void);
craigdo@3257
   542
craigdo@3257
   543
  /**
craigdo@3257
   544
   * Notify any interested parties that the link has come up.
craigdo@3257
   545
   */
mathieu@2470
   546
  void NotifyLinkUp (void);
emmanuelle@977
   547
emmanuelle@977
   548
  /** 
emmanuelle@977
   549
   * Device ID returned by the attached functions. It is used by the
emmanuelle@977
   550
   * mp-channel to identify each net device to make sure that only
emmanuelle@977
   551
   * active net devices are writing to the channel
emmanuelle@977
   552
   */
emmanuelle@977
   553
  uint32_t m_deviceId; 
emmanuelle@977
   554
emmanuelle@977
   555
  /**
emmanuelle@977
   556
   * Enable net device to send packets. True by default
emmanuelle@977
   557
   */
emmanuelle@977
   558
  bool m_sendEnable;
craigdo@3257
   559
emmanuelle@977
   560
  /**
emmanuelle@977
   561
   * Enable net device to receive packets. True by default
emmanuelle@977
   562
   */
emmanuelle@977
   563
  bool m_receiveEnable;
craigdo@3257
   564
emmanuelle@977
   565
  /**
emmanuelle@977
   566
   * Enumeration of the states of the transmit machine of the net device.
emmanuelle@977
   567
   */
emmanuelle@977
   568
  enum TxMachineState
emmanuelle@977
   569
    {
emmanuelle@977
   570
      READY, /**< The transmitter is ready to begin transmission of a packet */
emmanuelle@977
   571
      BUSY,  /**< The transmitter is busy transmitting a packet */
emmanuelle@977
   572
      GAP,    /**< The transmitter is in the interframe gap time */
emmanuelle@977
   573
      BACKOFF    /**< The transmitter is waiting for the channel to be free */
emmanuelle@977
   574
    };
craigdo@3257
   575
emmanuelle@977
   576
  /**
emmanuelle@977
   577
   * The state of the Net Device transmit state machine.
craigdo@3504
   578
   * \see TxMachineState
emmanuelle@977
   579
   */
emmanuelle@977
   580
  TxMachineState m_txMachineState;
emmanuelle@977
   581
  
emmanuelle@977
   582
  /**
emmanuelle@977
   583
   * The type of packet that should be created by the AddHeader
emmanuelle@977
   584
   * function and that should be processed by the ProcessHeader
emmanuelle@977
   585
   * function.
emmanuelle@977
   586
   */
craigdo@3506
   587
  EncapsulationMode m_encapMode;
craigdo@3257
   588
emmanuelle@977
   589
  /**
emmanuelle@977
   590
   * The data rate that the Net Device uses to simulate packet transmission
emmanuelle@977
   591
   * timing.
craigdo@3504
   592
   * \see class DataRate
emmanuelle@977
   593
   */
emmanuelle@977
   594
  DataRate m_bps;
craigdo@3257
   595
emmanuelle@977
   596
  /**
craigdo@3257
   597
   * The interframe gap that the Net Device uses insert time between packet
emmanuelle@977
   598
   * transmission
craigdo@3504
   599
   * \see class Time
emmanuelle@977
   600
   */
emmanuelle@977
   601
  Time m_tInterframeGap;
craigdo@3257
   602
emmanuelle@977
   603
  /**
emmanuelle@977
   604
   * Holds the backoff parameters and is used to calculate the next
emmanuelle@977
   605
   * backoff time to use when the channel is busy and the net device
emmanuelle@977
   606
   * is ready to transmit
emmanuelle@977
   607
   */
emmanuelle@977
   608
  Backoff m_backoff;
craigdo@3257
   609
emmanuelle@977
   610
  /**
emmanuelle@977
   611
   * Next packet that will be transmitted (if transmitter is not
emmanuelle@977
   612
   * currently transmitting) or packet that is currently being
emmanuelle@977
   613
   * transmitted.
emmanuelle@977
   614
   */
mathieu@1866
   615
  Ptr<Packet> m_currentPkt;
craigdo@3257
   616
emmanuelle@977
   617
  /**
craigdo@1276
   618
   * The CsmaChannel to which this CsmaNetDevice has been
emmanuelle@977
   619
   * attached.
craigdo@3504
   620
   * \see class CsmaChannel
emmanuelle@977
   621
   */
craigdo@1276
   622
  Ptr<CsmaChannel> m_channel;
craigdo@3257
   623
emmanuelle@977
   624
  /**
craigdo@1276
   625
   * The Queue which this CsmaNetDevice uses as a packet source.
craigdo@1276
   626
   * Management of this Queue has been delegated to the CsmaNetDevice
emmanuelle@977
   627
   * and it has the responsibility for deletion.
craigdo@3504
   628
   * \see class Queue
craigdo@3504
   629
   * \see class DropTailQueue
emmanuelle@977
   630
   */
emmanuelle@977
   631
  Ptr<Queue> m_queue;
tomh@1820
   632
tomh@1820
   633
  /**
tomh@1820
   634
   * Error model for receive packet events
tomh@1820
   635
   */
tomh@1820
   636
  Ptr<ErrorModel> m_receiveErrorModel;
tomh@1820
   637
emmanuelle@977
   638
  /**
emmanuelle@977
   639
   * The trace source for the packet reception events that the device can
emmanuelle@977
   640
   * fire.
emmanuelle@977
   641
   *
craigdo@3504
   642
   * \see class CallBackTraceSource
emmanuelle@977
   643
   */
mathieu@2500
   644
  TracedCallback<Ptr<const Packet> > m_rxTrace;
craigdo@3257
   645
craigdo@3257
   646
  /**
craigdo@3257
   647
   * The trace source for the packet drop events that the device can
craigdo@3257
   648
   * fire.
craigdo@3257
   649
   *
craigdo@3504
   650
   * \see class CallBackTraceSource
craigdo@3257
   651
   */
mathieu@2500
   652
  TracedCallback<Ptr<const Packet> > m_dropTrace;
emmanuelle@977
   653
craigdo@3257
   654
  /**
craigdo@3257
   655
   * The Node to which this device is attached.
craigdo@3257
   656
   */
mathieu@2470
   657
  Ptr<Node> m_node;
craigdo@3257
   658
craigdo@3257
   659
  /**
craigdo@3257
   660
   * The MAC address which has been assigned to this device.
craigdo@3257
   661
   */
mathieu@2470
   662
  Mac48Address m_address;
craigdo@3257
   663
craigdo@3257
   664
  /**
craigdo@3257
   665
   * The callback used to notify higher layers that a packet has been received.
craigdo@3257
   666
   */
mathieu@2470
   667
  NetDevice::ReceiveCallback m_rxCallback;
gjc@3460
   668
  /**
gjc@3460
   669
   * The callback used to notify higher layers that a packet has been received in promiscuous mode.
gjc@3460
   670
   */
gjc@3460
   671
  NetDevice::PromiscReceiveCallback m_promiscRxCallback;
craigdo@3257
   672
craigdo@3257
   673
  /**
craigdo@3257
   674
   * The interface index (really net evice index) that has been assigned to 
craigdo@3257
   675
   * this network device.
craigdo@3257
   676
   */
mathieu@2470
   677
  uint32_t m_ifIndex;
craigdo@3257
   678
craigdo@3257
   679
  /**
craigdo@3257
   680
   * The human readable name of this device.
craigdo@3257
   681
   */
mathieu@2470
   682
  std::string m_name;
craigdo@3257
   683
craigdo@3257
   684
  /**
craigdo@3257
   685
   * Flag indicating whether or not the link is up.  In this case,
craigdo@3257
   686
   * whether or not the device is connected to a channel.
craigdo@3257
   687
   */
mathieu@2470
   688
  bool m_linkUp;
craigdo@3257
   689
craigdo@3257
   690
  /**
craigdo@3257
   691
   * Callback to fire if the link changes state (up or down).
craigdo@3257
   692
   */
mathieu@2470
   693
  Callback<void> m_linkChangeCallback;
craigdo@3257
   694
craigdo@3629
   695
  static const uint16_t DEFAULT_FRAME_SIZE = 1518;
craigdo@3630
   696
  static const uint16_t ETHERNET_OVERHEAD = 18;
craigdo@3506
   697
craigdo@3257
   698
  /**
craigdo@3629
   699
   * The frame size/packet size.  This corresponds to the maximum 
craigdo@3629
   700
   * number of bytes that can be transmitted as a packet without framing.
craigdo@3629
   701
   * This corresponds to the 1518 byte packet size often seen on Ethernet.
craigdo@3257
   702
   */
craigdo@3629
   703
  uint32_t m_frameSize;
craigdo@3476
   704
craigdo@3476
   705
  /**
craigdo@3629
   706
   * The Maxmimum Transmission Unit.  This corresponds to the maximum 
craigdo@3629
   707
   * number of bytes that can be transmitted as seen from higher layers.
craigdo@3629
   708
   * This corresponds to the 1500 byte MTU size often seen on IP over 
craigdo@3629
   709
   * Ethernet.
craigdo@3476
   710
   */
craigdo@3629
   711
  uint32_t m_mtu;
emmanuelle@977
   712
};
emmanuelle@977
   713
emmanuelle@977
   714
}; // namespace ns3
emmanuelle@977
   715
craigdo@1276
   716
#endif // CSMA_NET_DEVICE_H