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

(-)src/csma/doc/csma.rst (-19 / +43 lines)
 Lines 14-19    Link Here 
14
Although it does not model any real physical network you could ever build or
14
Although it does not model any real physical network you could ever build or
15
buy, it does provide some very useful functionality.
15
buy, it does provide some very useful functionality.
16
16
17
When Ethernet was standardised, all communication was half-duplex. Half-duplex
18
communication restricts a node to either transmit or receive at a time but not
19
perform both actions concurrently. By default, the |ns3| CSMA device models a
20
half-duplex bus network, with no fixed limit on the number of devices connected
21
to the shared transmission medium. 
22
17
Typically when one thinks of a bus network Ethernet or IEEE 802.3 comes to mind.
23
Typically when one thinks of a bus network Ethernet or IEEE 802.3 comes to mind.
18
Ethernet uses CSMA/CD (Carrier Sense Multiple Access with Collision Detection
24
Ethernet uses CSMA/CD (Carrier Sense Multiple Access with Collision Detection
19
with exponentially increasing backoff to contend for the shared transmission
25
with exponentially increasing backoff to contend for the shared transmission
 Lines 23-28    Link Here 
23
sense of Ethernet never happen and so the |ns3| CSMA device does not model
29
sense of Ethernet never happen and so the |ns3| CSMA device does not model
24
collision detection, nor will any transmission in progress be "jammed."
30
collision detection, nor will any transmission in progress be "jammed."
25
31
32
This model also offers support for full-duplex communication, where the
33
transmission medium can operate in both directions simultaneously but is
34
restricted to a maximum of two devices connected on the single full-duplex
35
link.  When in full-duplex operation, the original CSMA/CD protocol is shut off
36
and the two devices on the link can send data independently.
37
26
CSMA Layer Model
38
CSMA Layer Model
27
++++++++++++++++
39
++++++++++++++++
28
40
 Lines 83-90    Link Here 
83
CSMA Channel Model
95
CSMA Channel Model
84
******************
96
******************
85
97
86
The class CsmaChannel models the actual transmission medium. There is no fixed
98
The class CsmaChannel models the actual transmission medium. The CsmaChannel models
87
limit for the number of devices connected to the channel. The CsmaChannel models
88
a data rate and a speed-of-light delay which can be accessed via the attributes
99
a data rate and a speed-of-light delay which can be accessed via the attributes
89
"DataRate" and "Delay" respectively. The data rate provided to the channel is
100
"DataRate" and "Delay" respectively. The data rate provided to the channel is
90
used to set the data rates used by the transmitter sections of the CSMA devices
101
used to set the data rates used by the transmitter sections of the CSMA devices
 Lines 94-99    Link Here 
94
CSMA channels and devices can operate; and no restriction based on any kind of
105
CSMA channels and devices can operate; and no restriction based on any kind of
95
PHY characteristics.
106
PHY characteristics.
96
107
108
The CsmaChannel can operate in half-duplex or in full-duplex mode, which can be
109
defined via the attribute "FullDuplex". The CsmaChannel holds two internal
110
subchannels. When operating in half-duplex mode, only the first subchannel is
111
used by all devices for both transmission and reception procedures. In this
112
case, the CsmaChannel models a broadcast medium so the packet is delivered to
113
all of the devices on the channel (including the source) at the end of the
114
propagation time. It is the responsibility of the sending device to determine
115
whether or not it receives a packet broadcast over the channel. When the
116
CsmaChannel is operating in full-duplex mode (with a maximum of two devices
117
attached to the channel), each device uses its exclusive subchannel for
118
unidirectional packet transmission, getting rid of the CSMA/CD mechanism.
119
97
The CsmaChannel has three states, ``IDLE``, ``TRANSMITTING`` and
120
The CsmaChannel has three states, ``IDLE``, ``TRANSMITTING`` and
98
``PROPAGATING``. These three states are "seen" instantaneously by all devices on
121
``PROPAGATING``. These three states are "seen" instantaneously by all devices on
99
the channel. By this we mean that if one device begins or ends a simulated
122
the channel. By this we mean that if one device begins or ends a simulated
 Lines 133-147    Link Here 
133
the packet out a port; plus 3) the time it takes for the signal in question to
156
the packet out a port; plus 3) the time it takes for the signal in question to
134
propagate to the destination net device.
157
propagate to the destination net device.
135
158
136
The CsmaChannel models a broadcast medium so the packet is delivered to all of
137
the devices on the channel (including the source) at the end of the propagation
138
time. It is the responsibility of the sending device to determine whether or not
139
it receives a packet broadcast over the channel.
140
141
The CsmaChannel provides following Attributes:
159
The CsmaChannel provides following Attributes:
142
160
143
* DataRate:  The bitrate for packet transmission on connected devices;
161
* DataRate:  The bitrate for packet transmission on connected devices;
144
* Delay: The speed of light transmission delay for the channel.
162
* Delay: The speed of light transmission delay for the channel;
163
* FullDuplex: Whether the channel is operating in full-duplex mode or not.
145
164
146
CSMA Net Device Model
165
CSMA Net Device Model
147
*********************
166
*********************
 Lines 195-201    Link Here 
195
executed if the channel is determined to be busy (``TRANSMITTING`` or
214
executed if the channel is determined to be busy (``TRANSMITTING`` or
196
``PPROPAGATING``) when the device wants to start propagating. This results in a
215
``PPROPAGATING``) when the device wants to start propagating. This results in a
197
random delay of up to pow (2, retries) - 1 microseconds before a retry is
216
random delay of up to pow (2, retries) - 1 microseconds before a retry is
198
attempted. The default maximum number of retries is 1000.
217
attempted. The default maximum number of retries is 1000. Note that the random
218
exponential backoff algorithm is not used when the device is attached to a
219
channel in full-duplex operation.
199
220
200
Using the CsmaNetDevice
221
Using the CsmaNetDevice
201
***********************
222
***********************
 Lines 349-364    Link Here 
349
Summary
370
Summary
350
*******
371
*******
351
372
352
The ns3 CSMA model is a simplistic model of an Ethernet-like network.  It
373
The ns3 CSMA model is a simplistic model of an Ethernet-like network that can
353
supports a Carrier-Sense function and allows for Multiple Access to a
374
operate in half-duplex or in full-duplex modes. In half-duplex mode, it
354
shared medium.  It is not physical in the sense that the state of the
375
supports a Carrier-Sense function and allows for Multiple Access to a shared
355
medium is instantaneously shared among all devices.  This means that there
376
medium. It is not physical in the sense that the state of the medium is
356
is no collision detection required in this model and none is implemented.
377
instantaneously shared among all devices. This means that there is no collision
357
There will never be a "jam" of a packet already on the medium.  Access to
378
detection required in this model and none is implemented. There will never be a
358
the shared channel is on a first-come first-served basis as determined by
379
"jam" of a packet already on the medium. Access to the shared channel is on a
359
the simulator scheduler.  If the channel is determined to be busy by looking
380
first-come first-served basis as determined by the simulator scheduler. If the
360
at the global state, a random exponential backoff is performed and a retry
381
channel is determined to be busy by looking at the global state, a random
361
is attempted.
382
exponential backoff is performed and a retry is attempted. When operating in
383
full-duplex mode, restricted to a maximum of two devices on the channel, the
384
transmission medium can operate in both directions simultaneously and there is
385
no need of the original CSMA/CD protocol.
362
386
363
Ns-3 Attributes provide a mechanism for setting various parameters in the
387
Ns-3 Attributes provide a mechanism for setting various parameters in the
364
device and channel such as addresses, encapsulation modes and error model
388
device and channel such as addresses, encapsulation modes and error model
(-)src/csma/examples/csma-duplex.cc (+104 lines)
Line 0    Link Here 
1
/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2017 Luciano Jerez Chaves
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
7
 * published by the Free Software Foundation;
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 * Author: Luciano Jerez Chaves <luciano@lrc.ic.unicamp.br>
19
 */
20
21
#include "ns3/core-module.h"
22
#include "ns3/network-module.h"
23
#include "ns3/csma-module.h"
24
#include "ns3/internet-module.h"
25
#include "ns3/applications-module.h"
26
27
using namespace ns3;
28
29
int
30
main (int argc, char *argv[])
31
{
32
  bool verbose = false;
33
  bool trace = false;
34
35
  CommandLine cmd;
36
  cmd.AddValue ("verbose",  "Tell application to log if true", verbose);
37
  cmd.AddValue ("trace",    "Tracing traffic to files", trace);
38
  cmd.AddValue ("duplex",   "ns3::CsmaChannel::FullDuplex");
39
  cmd.Parse (argc, argv);
40
41
  if (verbose)
42
    {
43
      LogComponentEnable ("CsmaNetDevice", LOG_LEVEL_ALL);
44
      LogComponentEnable ("CsmaChannel", LOG_LEVEL_ALL);
45
      LogComponentEnable ("Backoff", LOG_LEVEL_ALL);
46
    }
47
48
  // Create the host nodes
49
  NodeContainer hosts;
50
  hosts.Create (2);
51
52
  // Connecting the hosts
53
  CsmaHelper csmaHelper;
54
  csmaHelper.SetChannelAttribute ("DataRate", DataRateValue (DataRate ("100Mbps")));
55
  csmaHelper.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (1)));
56
  NetDeviceContainer hostDevices = csmaHelper.Install (hosts);
57
58
  // Enable pcap traces
59
  if (trace)
60
    {
61
      csmaHelper.EnablePcap ("csma-duplex", hostDevices);
62
    }
63
64
  // Installing the tcp/ip stack into hosts
65
  InternetStackHelper internet;
66
  internet.Install (hosts);
67
68
  // Set IPv4 host address
69
  Ipv4AddressHelper ipv4switches;
70
  Ipv4InterfaceContainer internetIpIfaces;
71
  ipv4switches.SetBase ("10.1.1.0", "255.255.255.0");
72
  internetIpIfaces = ipv4switches.Assign (hostDevices);
73
  Ipv4Address h0Addr = internetIpIfaces.GetAddress (0);
74
  Ipv4Address h1Addr = internetIpIfaces.GetAddress (1);
75
76
  ApplicationContainer senderApps, sinkApps;
77
78
  // TCP traffic from host 0 to 1
79
  BulkSendHelper sender0 ("ns3::TcpSocketFactory", InetSocketAddress (h1Addr, 10000));
80
  PacketSinkHelper sink1 ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), 10000));
81
  senderApps.Add (sender0.Install (hosts.Get (0)));
82
  sinkApps.Add (sink1.Install (hosts.Get (1)));
83
84
  // TCP traffic from host 1 to 0
85
  BulkSendHelper sender1 ("ns3::TcpSocketFactory", InetSocketAddress (h0Addr, 10001));
86
  PacketSinkHelper sink0 ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), 10001));
87
  senderApps.Add (sender1.Install (hosts.Get (1)));
88
  sinkApps.Add (sink0.Install (hosts.Get (0)));
89
90
  sinkApps.Start (Seconds (0));
91
  senderApps.Start (Seconds (0.01));
92
  senderApps.Stop (Seconds (5));
93
94
  // Run the simulation
95
  Simulator::Run ();
96
  Simulator::Destroy ();
97
98
  // Transmitted bytes
99
  Ptr<PacketSink> pktSink0 = DynamicCast<PacketSink> (sinkApps.Get (1));
100
  Ptr<PacketSink> pktSink1 = DynamicCast<PacketSink> (sinkApps.Get (0));
101
  std::cout << "Total bytes sent from H0 to H1: " << pktSink1->GetTotalRx () << std::endl;
102
  std::cout << "Total bytes sent from H1 to H0: " << pktSink0->GetTotalRx () << std::endl;
103
}
104
(-)src/csma/examples/wscript (+3 lines)
 Lines 18-20    Link Here 
18
18
19
    obj = bld.create_ns3_program('csma-ping', ['csma', 'internet', 'applications', 'internet-apps'])
19
    obj = bld.create_ns3_program('csma-ping', ['csma', 'internet', 'applications', 'internet-apps'])
20
    obj.source = 'csma-ping.cc'
20
    obj.source = 'csma-ping.cc'
21
22
    obj = bld.create_ns3_program('csma-duplex', ['csma', 'internet', 'applications'])
23
    obj.source = 'csma-duplex.cc'
(-)src/csma/model/csma-channel.cc (-32 / +112 lines)
 Lines 1-6    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
2
/*
3
 * Copyright (c) 2007 Emmanuelle Laprise
3
 * Copyright (c) 2007 Emmanuelle Laprise
4
 * Copyright (c) 2012 Jeff Young
5
 * Copyright (c) 2014 Murphy McCauley
6
 * Copyright (c) 2017 Luciano Jerez Chaves
4
 *
7
 *
5
 * This program is free software; you can redistribute it and/or modify
8
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
9
 * it under the terms of the GNU General Public License version 2 as
 Lines 16-21    Link Here 
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
20
 *
18
 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
21
 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
22
 * Author: Jeff Young <jyoung9@gatech.edu>
23
 * Author: Murphy McCauley <murphy.mccauley@gmail.com>
24
 * Author: Luciano Jerez Chaves <luciano@lrc.ic.unicamp.br>
19
 */
25
 */
20
26
21
#include "csma-channel.h"
27
#include "csma-channel.h"
 Lines 46-51    Link Here 
46
                   TimeValue (Seconds (0)),
52
                   TimeValue (Seconds (0)),
47
                   MakeTimeAccessor (&CsmaChannel::m_delay),
53
                   MakeTimeAccessor (&CsmaChannel::m_delay),
48
                   MakeTimeChecker ())
54
                   MakeTimeChecker ())
55
    .AddAttribute ("FullDuplex", "Whether the channel is full-duplex mode.",
56
                   TypeId::ATTR_CONSTRUCT,
57
                   BooleanValue (false),
58
                   MakeBooleanAccessor (&CsmaChannel::m_fullDuplex),
59
                   MakeBooleanChecker ())
49
  ;
60
  ;
50
  return tid;
61
  return tid;
51
}
62
}
 Lines 55-61    Link Here 
55
    Channel ()
66
    Channel ()
56
{
67
{
57
  NS_LOG_FUNCTION_NOARGS ();
68
  NS_LOG_FUNCTION_NOARGS ();
58
  m_state = IDLE;
59
  m_deviceList.clear ();
69
  m_deviceList.clear ();
60
}
70
}
61
71
 Lines 71-79    Link Here 
71
  NS_LOG_FUNCTION (this << device);
81
  NS_LOG_FUNCTION (this << device);
72
  NS_ASSERT (device != 0);
82
  NS_ASSERT (device != 0);
73
83
84
  //
85
  // For full-duplex links we can only attach two devices to the same channel
86
  // since there is no backoff mechanism for concurrent transmissions.
87
  //
88
  if (m_fullDuplex && m_deviceList.size () >= 2)
89
    {
90
      NS_LOG_DEBUG ("Falling back to half-duplex");
91
      m_fullDuplex = false;
92
    }
93
74
  CsmaDeviceRec rec (device);
94
  CsmaDeviceRec rec (device);
75
95
76
  m_deviceList.push_back (rec);
96
  m_deviceList.push_back (rec);
97
  SetState (m_deviceList.size () - 1, IDLE);
98
  SetCurrentSrc (m_deviceList.size () - 1, m_deviceList.size () - 1);
77
  return (m_deviceList.size () - 1);
99
  return (m_deviceList.size () - 1);
78
}
100
}
79
101
 Lines 107-113    Link Here 
107
{
129
{
108
  NS_LOG_FUNCTION (this << deviceId);
130
  NS_LOG_FUNCTION (this << deviceId);
109
131
110
  if (deviceId < m_deviceList.size ())
132
  if (deviceId >= m_deviceList.size ())
111
    {
133
    {
112
      return false;
134
      return false;
113
    }
135
    }
 Lines 138-144    Link Here 
138
160
139
      m_deviceList[deviceId].active = false;
161
      m_deviceList[deviceId].active = false;
140
162
141
      if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
163
      if ((GetState (deviceId) == TRANSMITTING) && (GetCurrentSrc (deviceId) == deviceId))
142
        {
164
        {
143
          NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmitting (" << deviceId << ")");
165
          NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmitting (" << deviceId << ")");
144
        }
166
        }
 Lines 175-181    Link Here 
175
  NS_LOG_FUNCTION (this << p << srcId);
197
  NS_LOG_FUNCTION (this << p << srcId);
176
  NS_LOG_INFO ("UID is " << p->GetUid () << ")");
198
  NS_LOG_INFO ("UID is " << p->GetUid () << ")");
177
199
178
  if (m_state != IDLE)
200
  if (GetState (srcId) != IDLE)
179
    {
201
    {
180
      NS_LOG_WARN ("CsmaChannel::TransmitStart(): State is not IDLE");
202
      NS_LOG_WARN ("CsmaChannel::TransmitStart(): State is not IDLE");
181
      return false;
203
      return false;
 Lines 183-196    Link Here 
183
205
184
  if (!IsActive (srcId))
206
  if (!IsActive (srcId))
185
    {
207
    {
186
      NS_LOG_ERROR ("CsmaChannel::TransmitStart(): Seclected source is not currently attached to network");
208
      NS_LOG_ERROR ("CsmaChannel::TransmitStart(): Selected source is not currently attached to network");
187
      return false;
209
      return false;
188
    }
210
    }
189
211
190
  NS_LOG_LOGIC ("switch to TRANSMITTING");
212
  NS_LOG_LOGIC ("switch to TRANSMITTING");
191
  m_currentPkt = p;
213
  SetCurrentPkt (srcId, p);
192
  m_currentSrc = srcId;
214
  SetCurrentSrc (srcId, srcId);
193
  m_state = TRANSMITTING;
215
  SetState (srcId, TRANSMITTING);
194
  return true;
216
  return true;
195
}
217
}
196
218
 Lines 201-217    Link Here 
201
}
223
}
202
224
203
bool
225
bool
204
CsmaChannel::TransmitEnd ()
226
CsmaChannel::IsFullDuplex (void) const
205
{
227
{
206
  NS_LOG_FUNCTION (this << m_currentPkt << m_currentSrc);
228
  return m_fullDuplex;
207
  NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
229
}
208
230
209
  NS_ASSERT (m_state == TRANSMITTING);
231
bool
210
  m_state = PROPAGATING;
232
CsmaChannel::TransmitEnd (uint32_t srcId)
233
{
234
  NS_LOG_FUNCTION (this << GetCurrentPkt (srcId) << GetCurrentSrc (srcId));
235
  NS_LOG_INFO ("UID is " << GetCurrentPkt (srcId)->GetUid () << ")");
236
237
  NS_ASSERT (GetState (srcId) == TRANSMITTING);
238
  SetState (srcId, PROPAGATING);
211
239
212
  bool retVal = true;
240
  bool retVal = true;
213
241
214
  if (!IsActive (m_currentSrc))
242
  if (!IsActive (GetCurrentSrc (srcId)))
215
    {
243
    {
216
      NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): Seclected source was detached before the end of the transmission");
244
      NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): Seclected source was detached before the end of the transmission");
217
      retVal = false;
245
      retVal = false;
 Lines 226-256    Link Here 
226
  uint32_t devId = 0;
254
  uint32_t devId = 0;
227
  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
255
  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
228
    {
256
    {
229
      if (it->IsActive ())
257
      //
258
      // In full-duplex mode, don't deliver the packet back to the sender.
259
      //
260
      if (!m_fullDuplex || (devId != GetCurrentSrc (srcId)))
230
        {
261
        {
231
          // schedule reception events
262
          if (it->IsActive ())
232
          Simulator::ScheduleWithContext (it->devicePtr->GetNode ()->GetId (),
263
            {
233
                                          m_delay,
264
              // schedule reception events
234
                                          &CsmaNetDevice::Receive, it->devicePtr,
265
              Simulator::ScheduleWithContext (it->devicePtr->GetNode ()->GetId (),
235
                                          m_currentPkt->Copy (), m_deviceList[m_currentSrc].devicePtr);
266
                                              m_delay,
267
                                              &CsmaNetDevice::Receive, it->devicePtr,
268
                                              GetCurrentPkt (srcId)->Copy (), m_deviceList[GetCurrentSrc (srcId)].devicePtr);
269
            }
236
        }
270
        }
237
      devId++;
271
      devId++;
238
    }
272
    }
239
273
240
  // also schedule for the tx side to go back to IDLE
274
  // Schedule for the TX side to go back to IDLE.
241
  Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent,
275
  if (IsFullDuplex ())
242
                       this);
276
    {
277
      //
278
      // In full-duplex mode, the channel should be IDLE during propagation
279
      // since it's ok to start transmitting again. In this case, we don't need
280
      // to wait for the channel delay.
281
      //
282
      PropagationCompleteEvent (srcId);
283
    }
284
  else
285
    {
286
      //
287
      // In half-duplex mode, the channel can only go back to IDLE after
288
      // propagation delay.
289
      //
290
      Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent,
291
                           this, srcId);
292
    }
243
  return retVal;
293
  return retVal;
244
}
294
}
245
295
246
void
296
void
247
CsmaChannel::PropagationCompleteEvent ()
297
CsmaChannel::PropagationCompleteEvent (uint32_t deviceId)
248
{
298
{
249
  NS_LOG_FUNCTION (this << m_currentPkt);
299
  NS_LOG_FUNCTION (this << GetCurrentPkt (deviceId));
250
  NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
300
  NS_LOG_INFO ("UID is " << GetCurrentPkt (deviceId)->GetUid () << ")");
251
301
252
  NS_ASSERT (m_state == PROPAGATING);
302
  NS_ASSERT (GetState (deviceId) == PROPAGATING);
253
  m_state = IDLE;
303
  SetState (deviceId, IDLE);
254
}
304
}
255
305
256
uint32_t
306
uint32_t
 Lines 305-313    Link Here 
305
}
355
}
306
356
307
bool
357
bool
308
CsmaChannel::IsBusy (void)
358
CsmaChannel::IsBusy (uint32_t deviceId)
309
{
359
{
310
  if (m_state == IDLE) 
360
  if (GetState (deviceId) == IDLE)
311
    {
361
    {
312
      return false;
362
      return false;
313
    } 
363
    } 
 Lines 330-338    Link Here 
330
}
380
}
331
381
332
WireState
382
WireState
333
CsmaChannel::GetState (void)
383
CsmaChannel::GetState (uint32_t deviceId)
334
{
384
{
335
  return m_state;
385
  return m_state[m_fullDuplex ? deviceId : 0];
336
}
386
}
337
387
338
Ptr<NetDevice>
388
Ptr<NetDevice>
 Lines 341-346    Link Here 
341
  return GetCsmaDevice (i);
391
  return GetCsmaDevice (i);
342
}
392
}
343
393
394
Ptr<Packet>
395
CsmaChannel::GetCurrentPkt (uint32_t deviceId)
396
{
397
  return m_currentPkt[m_fullDuplex ? deviceId : 0];
398
}
399
400
void
401
CsmaChannel::SetCurrentPkt (uint32_t deviceId, Ptr<Packet> pkt)
402
{
403
  m_currentPkt[m_fullDuplex ? deviceId : 0] = pkt;
404
}
405
406
uint32_t
407
CsmaChannel::GetCurrentSrc (uint32_t deviceId)
408
{
409
  return m_currentSrc[m_fullDuplex ? deviceId : 0];
410
}
411
412
void
413
CsmaChannel::SetCurrentSrc (uint32_t deviceId, uint32_t transmitterId)
414
{
415
  m_currentSrc[m_fullDuplex ? deviceId : 0] = transmitterId;
416
}
417
418
void
419
CsmaChannel::SetState (uint32_t deviceId, WireState state)
420
{
421
  m_state[m_fullDuplex ? deviceId : 0] = state;
422
}
423
344
CsmaDeviceRec::CsmaDeviceRec ()
424
CsmaDeviceRec::CsmaDeviceRec ()
345
{
425
{
346
  active = false;
426
  active = false;
(-)src/csma/model/csma-channel.h (-24 / +113 lines)
 Lines 1-6    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
2
/*
3
 * Copyright (c) 2007 Emmanuelle Laprise
3
 * Copyright (c) 2007 Emmanuelle Laprise
4
 * Copyright (c) 2012 Jeffrey Young
5
 * Copyright (c) 2014 Murphy McCauley
6
 * Copyright (c) 2017 Luciano Jerez Chaves
4
 *
7
 *
5
 * This program is free software; you can redistribute it and/or modify
8
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
9
 * it under the terms of the GNU General Public License version 2 as
 Lines 16-21    Link Here 
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
20
 *
18
 * Author: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
21
 * Author: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
22
 * Author: Jeff Young <jyoung9@gatech.edu>
23
 * Author: Murphy McCauley <murphy.mccauley@gmail.com>
24
 * Author: Luciano Jerez Chaves <luciano@lrc.ic.unicamp.br>
19
 */
25
 */
20
26
21
#ifndef CSMA_CHANNEL_H
27
#ifndef CSMA_CHANNEL_H
 Lines 25-30    Link Here 
25
#include "ns3/ptr.h"
31
#include "ns3/ptr.h"
26
#include "ns3/nstime.h"
32
#include "ns3/nstime.h"
27
#include "ns3/data-rate.h"
33
#include "ns3/data-rate.h"
34
#include "ns3/boolean.h"
28
35
29
namespace ns3 {
36
namespace ns3 {
30
37
 Lines 34-50    Link Here 
34
41
35
/**
42
/**
36
 * \ingroup csma
43
 * \ingroup csma
37
 * \brief CsmaNetDevice Record 
44
 * \brief CsmaNetDevice Record
38
 *
45
 *
39
 * Stores the information related to each net device that is
46
 * Stores the information related to each net device that is
40
 * connected to the channel. 
47
 * connected to the channel.
41
 */
48
 */
42
class CsmaDeviceRec {
49
class CsmaDeviceRec
50
{
43
public:
51
public:
44
  Ptr< CsmaNetDevice > devicePtr; //!< Pointer to the net device
52
  Ptr< CsmaNetDevice > devicePtr; //!< Pointer to the net device
45
  bool                 active;    //!< Is net device enabled to TX/RX
53
  bool                 active;    //!< Is net device enabled to TX/RX
46
54
47
  CsmaDeviceRec();
55
  CsmaDeviceRec ();
48
56
49
  /**
57
  /**
50
   * \brief Constructor
58
   * \brief Constructor
 Lines 52-58    Link Here 
52
   *
60
   *
53
   * \param device the device to record
61
   * \param device the device to record
54
   */
62
   */
55
  CsmaDeviceRec(Ptr< CsmaNetDevice > device);
63
  CsmaDeviceRec (Ptr< CsmaNetDevice > device);
56
64
57
  /**
65
  /**
58
   * Copy constructor
66
   * Copy constructor
 Lines 69-75    Link Here 
69
77
70
/**
78
/**
71
 * Current state of the channel
79
 * Current state of the channel
72
 */ 
80
 */
73
enum WireState
81
enum WireState
74
{
82
{
75
  IDLE,            /**< Channel is IDLE, no packet is being transmitted */
83
  IDLE,            /**< Channel is IDLE, no packet is being transmitted */
 Lines 85-96    Link Here 
85
 * when many nodes are connected to one wire. It uses a single busy
93
 * when many nodes are connected to one wire. It uses a single busy
86
 * flag to indicate if the channel is currently in use. It does not
94
 * flag to indicate if the channel is currently in use. It does not
87
 * take into account the distances between stations or the speed of
95
 * take into account the distances between stations or the speed of
88
 * light to determine collisions.
96
 * light to determine collisions. Optionally, it allows for full-
97
 * duplex operation when there are only two attached nodes. To
98
 * implement full-duplex, we internally keep two TX "subchannels"
99
 * (one for each attached node). When in half-duplex mode, only
100
 * the first subchannel is used.
89
 */
101
 */
90
class CsmaChannel : public Channel 
102
class CsmaChannel : public Channel
91
{
103
{
92
public:
104
public:
93
94
  /**
105
  /**
95
   * \brief Get the type ID.
106
   * \brief Get the type ID.
96
   * \return the object TypeId
107
   * \return the object TypeId
 Lines 148-154    Link Here 
148
   * or transmit packets. The net device must have been previously
159
   * or transmit packets. The net device must have been previously
149
   * attached to the channel using the attach function.
160
   * attached to the channel using the attach function.
150
   *
161
   *
151
   * \param deviceId The device ID assigned to the net device when it
162
   * \param deviceId The deviceID assigned to the net device when it
152
   * was connected to the channel
163
   * was connected to the channel
153
   * \return True if the device is found and is not attached to the
164
   * \return True if the device is found and is not attached to the
154
   * channel, false if the device is currently connected to the
165
   * channel, false if the device is currently connected to the
 Lines 197-215    Link Here 
197
   * packet p as the m_currentPkt, the packet being currently
208
   * packet p as the m_currentPkt, the packet being currently
198
   * transmitting.
209
   * transmitting.
199
   *
210
   *
211
   * \param deviceId The deviceID assigned to the net device when it
212
   * was connected to the channel
213
   *
200
   * \return Returns true unless the source was detached before it
214
   * \return Returns true unless the source was detached before it
201
   * completed its transmission.
215
   * completed its transmission.
202
   */
216
   */
203
  bool TransmitEnd ();
217
  bool TransmitEnd (uint32_t deviceId);
204
218
205
  /**
219
  /**
206
   * \brief Indicates that the channel has finished propagating the
220
   * \brief Indicates that the channel has finished propagating the
207
   * current packet. The channel is released and becomes free.
221
   * current packet. The channel is released and becomes free.
208
   *
222
   *
209
   * Calls the receive function of every active net device that is
223
   * \param deviceId The deviceID assigned to the net device when it
224
   * was connected to the channel
225
   *
226
   * Calls the receive function of the other net device that is
210
   * attached to the channel.
227
   * attached to the channel.
211
   */
228
   */
212
  void PropagationCompleteEvent ();
229
  void PropagationCompleteEvent (uint32_t deviceId);
213
230
214
  /**
231
  /**
215
   * \return Returns the device number assigned to a net device by the
232
   * \return Returns the device number assigned to a net device by the
 Lines 221-252    Link Here 
221
  int32_t GetDeviceNum (Ptr<CsmaNetDevice> device);
238
  int32_t GetDeviceNum (Ptr<CsmaNetDevice> device);
222
239
223
  /**
240
  /**
241
   * \brief Checks the state of the channel.
242
   *
243
   * \param deviceId The deviceID assigned to the net device when it
244
   * was connected to the channel
224
   * \return Returns the state of the channel (IDLE -- free,
245
   * \return Returns the state of the channel (IDLE -- free,
225
   * TRANSMITTING -- busy, PROPAGATING - busy )
246
   * TRANSMITTING -- busy, PROPAGATING - busy )
226
   */
247
   */
227
  WireState GetState ();
248
  WireState GetState (uint32_t deviceId);
228
249
229
  /**
250
  /**
230
   * \brief Indicates if the channel is busy. The channel will only
251
   * \brief Indicates if the channel is busy. The channel will only
231
   * accept new packets for transmission if it is not busy.
252
   * accept new packets for transmission if it is not busy.
232
   *
253
   *
254
   * \param deviceId The deviceID assigned to the net device when it
255
   * was connected to the channel
233
   * \return Returns true if the channel is busy and false if it is
256
   * \return Returns true if the channel is busy and false if it is
234
   * free.
257
   * free.
235
   */
258
   */
236
  bool IsBusy ();
259
  bool IsBusy (uint32_t deviceId);
237
260
238
  /**
261
  /**
239
   * \brief Indicates if a net device is currently attached or
262
   * \brief Indicates if a net device is currently attached or
240
   * detached from the channel.
263
   * detached from the channel.
241
   *
264
   *
242
   * \param deviceId The ID that was assigned to the net device when
265
   * \param deviceId The deviceID assigned to the net device when it
243
   * it was attached to the channel.
266
   * was connected to the channel
244
   * \return Returns true if the net device is attached to the
267
   * \return Returns true if the net device is attached to the
245
   * channel, false otherwise.
268
   * channel, false otherwise.
246
   */
269
   */
247
  bool IsActive (uint32_t deviceId);
270
  bool IsActive (uint32_t deviceId);
248
271
249
  /**
272
  /**
273
   * \brief Indicates if channel is operating in full-duplex mode.
274
   *
275
   * \return Returns true if channel is in full-duplex mode, false if in
276
   * half-duplex mode.
277
   */
278
  bool IsFullDuplex (void) const;
279
280
  /**
250
   * \return Returns the number of net devices that are currently
281
   * \return Returns the number of net devices that are currently
251
   * attached to the channel.
282
   * attached to the channel.
252
   */
283
   */
 Lines 319-324    Link Here 
319
  Time          m_delay;
350
  Time          m_delay;
320
351
321
  /**
352
  /**
353
   * Whether the channel is in full-duplex mode.
354
   */
355
  bool          m_fullDuplex;
356
357
  /**
322
   * List of the net devices that have been or are currently connected
358
   * List of the net devices that have been or are currently connected
323
   * to the channel.
359
   * to the channel.
324
   *
360
   *
 Lines 332-354    Link Here 
332
  std::vector<CsmaDeviceRec> m_deviceList;
368
  std::vector<CsmaDeviceRec> m_deviceList;
333
369
334
  /**
370
  /**
335
   * The Packet that is currently being transmitted on the channel (or last
371
   * The Packet that is currently being transmitted on the subchannel (or the
336
   * packet to have been transmitted on the channel if the channel is
372
   * last packet to have been transmitted if the subchannel is free).
337
   * free.)
373
   * In half-duplex mode, only the first subchannel is used.
338
   */
374
   */
339
  Ptr<Packet> m_currentPkt;
375
  Ptr<Packet>   m_currentPkt[2];
340
376
341
  /**
377
  /**
342
   * Device Id of the source that is currently transmitting on the
378
   * Device Id of the source that is currently transmitting on the
379
   * subchannel, or the last source to have transmitted a packet on the
380
   * subchannel, if it is not currently busy.
381
   * In half-duplex mode, only the first subchannel is used.
382
   */
383
  uint32_t      m_currentSrc[2];
384
385
  /**
386
   * Current state of each subchannel.
387
   * In half-duplex mode, only the first subchannel is used.
388
   */
389
  WireState     m_state[2];
390
391
  /**
392
   * \brief Gets current packet
393
   *
394
   * \param deviceId The deviceID assigned to the net device when it
395
   * was connected to the channel
396
   * \return Device Id of the source that is currently transmitting on the
397
   * subchannel or the last source to have transmitted a packet on the
398
   * subchannel, if it is not currently busy.
399
   */
400
  Ptr<Packet> GetCurrentPkt (uint32_t deviceId);
401
402
  /**
403
   * \brief Sets the current packet
404
   *
405
   * \param deviceId The deviceID assigned to the net device when it
406
   * was connected to the channel
407
   * \param The Packet that is current being transmitted by deviceId (or last
408
   * packet to have been transmitted on the channel if the channel is free.)
409
   */
410
  void SetCurrentPkt (uint32_t deviceId, Ptr<Packet> pkt);
411
412
  /**
413
   * \brief Gets current transmitter
414
   *
415
   * \param deviceId The deviceID assigned to the net device when it
416
   * was connected to the channel
417
   * \return Device Id of the source that is currently transmitting on the
343
   * channel. Or last source to have transmitted a packet on the
418
   * channel. Or last source to have transmitted a packet on the
344
   * channel, if the channel is currently not busy.
419
   * channel, if the channel is currently not busy.
345
   */
420
   */
346
  uint32_t                            m_currentSrc;
421
  uint32_t GetCurrentSrc (uint32_t deviceId);
347
422
348
  /**
423
  /**
349
   * Current state of the channel
424
   * \brief Sets the current transmitter
425
   *
426
   * \param deviceId The deviceID assigned to the net device when it
427
   * was connected to the channel
428
   * \param transmitterId The ID of the transmitting device.
350
   */
429
   */
351
  WireState          m_state;
430
  void SetCurrentSrc (uint32_t deviceId, uint32_t transmitterId);
431
432
  /**
433
   * \brief Sets the state of the channel
434
   *
435
   * \param deviceId The deviceID assigned to the net device when it
436
   * was connected to the channel
437
   * \param state The new channel state.
438
   */
439
  void SetState (uint32_t deviceId, WireState state);
440
352
};
441
};
353
442
354
} // namespace ns3
443
} // namespace ns3
(-)src/csma/model/csma-net-device.cc (-25 / +40 lines)
 Lines 1-6    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
2
/*
3
 * Copyright (c) 2007 Emmanuelle Laprise
3
 * Copyright (c) 2007 Emmanuelle Laprise
4
 * Copyright (c) 2012 Jeffrey Young
5
 * Copyright (c) 2014 Murphy McCauley
6
 * Copyright (c) 2017 Luciano Jerez Chaves
4
 *
7
 *
5
 * This program is free software; you can redistribute it and/or modify
8
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
9
 * it under the terms of the GNU General Public License version 2 as
 Lines 16-21    Link Here 
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
20
 *
18
 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
21
 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
22
 * Author: Jeff Young <jyoung9@gatech.edu>
23
 * Author: Murphy McCauley <murphy.mccauley@gmail.com>
24
 * Author: Luciano Jerez Chaves <luciano@lrc.ic.unicamp.br>
19
 */
25
 */
20
26
21
#include "ns3/log.h"
27
#include "ns3/log.h"
 Lines 448-453    Link Here 
448
454
449
  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
455
  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
450
  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
456
  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
457
  NS_LOG_LOGIC ("Device ID = " << m_deviceId);
451
458
452
  //
459
  //
453
  // Only transmit if the send side of net device is enabled
460
  // Only transmit if the send side of net device is enabled
 Lines 469-502    Link Here 
469
                 "Must be READY to transmit. Tx state is: " << m_txMachineState);
476
                 "Must be READY to transmit. Tx state is: " << m_txMachineState);
470
477
471
  //
478
  //
472
  // Now we have to sense the state of the medium and either start transmitting
479
  // Now we sense the state of the medium. If idle, we start transmitting.
473
  // if it is idle, or backoff our transmission if someone else is on the wire.
480
  // Otherwise, we have to wait.
474
  //
481
  //
475
  if (m_channel->GetState () != IDLE)
482
  if (m_channel->GetState (m_deviceId) != IDLE)
476
    {
483
    {
477
      //
484
      //
478
      // The channel is busy -- backoff and rechedule TransmitStart() unless
485
      // The (sub)channel is busy. If in half-duplex mode, backoff and
479
      // we have exhausted all of our retries.
486
      // reschedule TransmitStart() unless we have exhausted all of our
487
      // retries. This is not supposed to happen in full-duplex mode.
480
      //
488
      //
481
      m_txMachineState = BACKOFF;
489
      if (m_channel->IsFullDuplex () == false)
482
483
      if (m_backoff.MaxRetriesReached ())
484
        { 
485
          //
486
          // Too many retries, abort transmission of packet
487
          //
488
          TransmitAbort ();
489
        } 
490
      else 
491
        {
490
        {
492
          m_macTxBackoffTrace (m_currentPkt);
491
          m_txMachineState = BACKOFF;
493
492
          if (m_backoff.MaxRetriesReached ())
494
          m_backoff.IncrNumRetries ();
493
            {
495
          Time backoffTime = m_backoff.GetBackoffTime ();
494
              //
496
495
              // Too many retries, abort transmission of packet
497
          NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec");
496
              //
498
497
              TransmitAbort ();
499
          Simulator::Schedule (backoffTime, &CsmaNetDevice::TransmitStart, this);
498
            }
499
          else
500
            {
501
              //
502
              // Backoff and reschedule transmission.
503
              //
504
              m_macTxBackoffTrace (m_currentPkt);
505
              m_backoff.IncrNumRetries ();
506
              Time backoffTime = m_backoff.GetBackoffTime ();
507
              NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec");
508
              Simulator::Schedule (backoffTime, &CsmaNetDevice::TransmitStart, this);
509
            }
500
        }
510
        }
501
    } 
511
    } 
502
  else 
512
  else 
 Lines 585-591    Link Here 
585
  // the transmitter after the interframe gap.
595
  // the transmitter after the interframe gap.
586
  //
596
  //
587
  NS_ASSERT_MSG (m_txMachineState == BUSY, "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
597
  NS_ASSERT_MSG (m_txMachineState == BUSY, "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
588
  NS_ASSERT (m_channel->GetState () == TRANSMITTING);
598
  NS_ASSERT (m_channel->GetState (m_deviceId) == TRANSMITTING);
589
  m_txMachineState = GAP;
599
  m_txMachineState = GAP;
590
600
591
  //
601
  //
 Lines 595-602    Link Here 
595
  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
605
  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
596
  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
606
  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
597
  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
607
  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
608
  NS_LOG_LOGIC ("Device ID is " << m_deviceId);
598
609
599
  m_channel->TransmitEnd (); 
610
  m_channel->TransmitEnd (m_deviceId);
600
  m_phyTxEndTrace (m_currentPkt);
611
  m_phyTxEndTrace (m_currentPkt);
601
  m_currentPkt = 0;
612
  m_currentPkt = 0;
602
613
 Lines 651-656    Link Here 
651
662
652
  m_deviceId = m_channel->Attach (this);
663
  m_deviceId = m_channel->Attach (this);
653
664
665
  NS_LOG_FUNCTION ("Device ID is " << m_deviceId);
666
654
  //
667
  //
655
  // The channel provides us with the transmitter data rate.
668
  // The channel provides us with the transmitter data rate.
656
  //
669
  //
 Lines 687-692    Link Here 
687
{
700
{
688
  NS_LOG_FUNCTION (packet << senderDevice);
701
  NS_LOG_FUNCTION (packet << senderDevice);
689
  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
702
  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
703
  NS_LOG_LOGIC ("Device ID is " << m_deviceId);
690
704
691
  //
705
  //
692
  // We never forward up packets that we sent.  Real devices don't do this since
706
  // We never forward up packets that we sent.  Real devices don't do this since
 Lines 948-953    Link Here 
948
  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
962
  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
949
  NS_LOG_LOGIC ("packet =" << packet);
963
  NS_LOG_LOGIC ("packet =" << packet);
950
  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
964
  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
965
  NS_LOG_LOGIC ("Device ID is " << m_deviceId);
951
966
952
  NS_ASSERT (IsLinkUp ());
967
  NS_ASSERT (IsLinkUp ());
953
968
(-)src/csma/test/examples-to-run.py (+1 lines)
 Lines 14-19    Link Here 
14
    ("csma-packet-socket", "True", "True"),
14
    ("csma-packet-socket", "True", "True"),
15
    ("csma-ping", "True", "True"),
15
    ("csma-ping", "True", "True"),
16
    ("csma-raw-ip-socket", "True", "True"),
16
    ("csma-raw-ip-socket", "True", "True"),
17
    ("csma-duplex", "True", "True"),
17
]
18
]
18
19
19
# A list of Python examples to run in order to ensure that they remain
20
# A list of Python examples to run in order to ensure that they remain

Return to bug 2354