A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
csma-channel.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 Emmanuelle Laprise
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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
19  */
20 
21 #include "csma-channel.h"
22 #include "csma-net-device.h"
23 #include "ns3/packet.h"
24 #include "ns3/simulator.h"
25 #include "ns3/log.h"
26 
27 NS_LOG_COMPONENT_DEFINE ("CsmaChannel");
28 
29 namespace ns3 {
30 
31 NS_OBJECT_ENSURE_REGISTERED (CsmaChannel);
32 
33 TypeId
35 {
36  static TypeId tid = TypeId ("ns3::CsmaChannel")
37  .SetParent<Channel> ()
38  .AddConstructor<CsmaChannel> ()
39  .AddAttribute ("DataRate",
40  "The transmission data rate to be provided to devices connected to the channel",
41  DataRateValue (DataRate (0xffffffff)),
42  MakeDataRateAccessor (&CsmaChannel::m_bps),
43  MakeDataRateChecker ())
44  .AddAttribute ("Delay", "Transmission delay through the channel",
45  TimeValue (Seconds (0)),
46  MakeTimeAccessor (&CsmaChannel::m_delay),
47  MakeTimeChecker ())
48  ;
49  return tid;
50 }
51 
53  :
54  Channel ()
55 {
57  m_state = IDLE;
58  m_deviceList.clear ();
59 }
60 
62 {
63  NS_LOG_FUNCTION (this);
64  m_deviceList.clear ();
65 }
66 
67 int32_t
69 {
70  NS_LOG_FUNCTION (this << device);
71  NS_ASSERT (device != 0);
72 
73  CsmaDeviceRec rec (device);
74 
75  m_deviceList.push_back (rec);
76  return (m_deviceList.size () - 1);
77 }
78 
79 bool
81 {
82  NS_LOG_FUNCTION (this << device);
83  NS_ASSERT (device != 0);
84 
85  std::vector<CsmaDeviceRec>::iterator it;
86  for (it = m_deviceList.begin (); it < m_deviceList.end ( ); it++)
87  {
88  if (it->devicePtr == device)
89  {
90  if (!it->active)
91  {
92  it->active = true;
93  return true;
94  }
95  else
96  {
97  return false;
98  }
99  }
100  }
101  return false;
102 }
103 
104 bool
105 CsmaChannel::Reattach (uint32_t deviceId)
106 {
107  NS_LOG_FUNCTION (this << deviceId);
108 
109  if (deviceId < m_deviceList.size ())
110  {
111  return false;
112  }
113 
114  if (m_deviceList[deviceId].active)
115  {
116  return false;
117  }
118  else
119  {
120  m_deviceList[deviceId].active = true;
121  return true;
122  }
123 }
124 
125 bool
126 CsmaChannel::Detach (uint32_t deviceId)
127 {
128  NS_LOG_FUNCTION (this << deviceId);
129 
130  if (deviceId < m_deviceList.size ())
131  {
132  if (!m_deviceList[deviceId].active)
133  {
134  NS_LOG_WARN ("CsmaChannel::Detach(): Device is already detached (" << deviceId << ")");
135  return false;
136  }
137 
138  m_deviceList[deviceId].active = false;
139 
140  if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
141  {
142  NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmitting (" << deviceId << ")");
143  }
144 
145  return true;
146  }
147  else
148  {
149  return false;
150  }
151 }
152 
153 bool
155 {
156  NS_LOG_FUNCTION (this << device);
157  NS_ASSERT (device != 0);
158 
159  std::vector<CsmaDeviceRec>::iterator it;
160  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
161  {
162  if ((it->devicePtr == device) && (it->active))
163  {
164  it->active = false;
165  return true;
166  }
167  }
168  return false;
169 }
170 
171 bool
173 {
174  NS_LOG_FUNCTION (this << p << srcId);
175  NS_LOG_INFO ("UID is " << p->GetUid () << ")");
176 
177  if (m_state != IDLE)
178  {
179  NS_LOG_WARN ("CsmaChannel::TransmitStart(): State is not IDLE");
180  return false;
181  }
182 
183  if (!IsActive (srcId))
184  {
185  NS_LOG_ERROR ("CsmaChannel::TransmitStart(): Seclected source is not currently attached to network");
186  return false;
187  }
188 
189  NS_LOG_LOGIC ("switch to TRANSMITTING");
190  m_currentPkt = p;
191  m_currentSrc = srcId;
193  return true;
194 }
195 
196 bool
197 CsmaChannel::IsActive (uint32_t deviceId)
198 {
199  return (m_deviceList[deviceId].active);
200 }
201 
202 bool
204 {
206  NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
207 
210 
211  bool retVal = true;
212 
213  if (!IsActive (m_currentSrc))
214  {
215  NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): Seclected source was detached before the end of the transmission");
216  retVal = false;
217  }
218 
219  NS_LOG_LOGIC ("Schedule event in " << m_delay.GetSeconds () << " sec");
220 
221 
222  NS_LOG_LOGIC ("Receive");
223 
224  std::vector<CsmaDeviceRec>::iterator it;
225  uint32_t devId = 0;
226  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
227  {
228  if (it->IsActive ())
229  {
230  // schedule reception events
231  Simulator::ScheduleWithContext (it->devicePtr->GetNode ()->GetId (),
232  m_delay,
233  &CsmaNetDevice::Receive, it->devicePtr,
234  m_currentPkt->Copy (), m_deviceList[m_currentSrc].devicePtr);
235  }
236  devId++;
237  }
238 
239  // also schedule for the tx side to go back to IDLE
241  this);
242  return retVal;
243 }
244 
245 void
247 {
248  NS_LOG_FUNCTION (this << m_currentPkt);
249  NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
250 
252  m_state = IDLE;
253 }
254 
255 uint32_t
257 {
258  int numActDevices = 0;
259  std::vector<CsmaDeviceRec>::iterator it;
260  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
261  {
262  if (it->active)
263  {
264  numActDevices++;
265  }
266  }
267  return numActDevices;
268 }
269 
270 uint32_t
272 {
273  return (m_deviceList.size ());
274 }
275 
277 CsmaChannel::GetCsmaDevice (uint32_t i) const
278 {
279  Ptr<CsmaNetDevice> netDevice = m_deviceList[i].devicePtr;
280  return netDevice;
281 }
282 
283 int32_t
285 {
286  std::vector<CsmaDeviceRec>::iterator it;
287  int i = 0;
288  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
289  {
290  if (it->devicePtr == device)
291  {
292  if (it->active)
293  {
294  return i;
295  }
296  else
297  {
298  return -2;
299  }
300  }
301  i++;
302  }
303  return -1;
304 }
305 
306 bool
308 {
309  if (m_state == IDLE)
310  {
311  return false;
312  }
313  else
314  {
315  return true;
316  }
317 }
318 
319 DataRate
321 {
322  return m_bps;
323 }
324 
325 Time
327 {
328  return m_delay;
329 }
330 
331 WireState
333 {
334  return m_state;
335 }
336 
338 CsmaChannel::GetDevice (uint32_t i) const
339 {
340  return GetCsmaDevice (i);
341 }
342 
344 {
345  active = false;
346 }
347 
349 {
350  devicePtr = device;
351  active = true;
352 }
353 
355 {
356  devicePtr = deviceRec.devicePtr;
357  active = deviceRec.active;
358 }
359 
360 bool
362 {
363  return active;
364 }
365 
366 } // namespace ns3
uint32_t m_currentSrc
Device Id of the source that is currently transmitting on the channel.
Definition: csma-channel.h:316
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
WireState m_state
Current state of the channel.
Definition: csma-channel.h:321
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
void Receive(Ptr< Packet > p, Ptr< CsmaNetDevice > sender)
Receive a packet from a connected CsmaChannel.
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:393
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
uint32_t GetNumActDevices(void)
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:62
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
Abstract Channel Base Class.
Definition: channel.h:43
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:223
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
std::vector< CsmaDeviceRec > m_deviceList
List of the net devices that have been or are currently connected to the channel. ...
Definition: csma-channel.h:302
WireState GetState()
Ptr< Packet > m_currentPkt
The Packet that is currently being transmitted on the channel (or last packet to have been transmitte...
Definition: csma-channel.h:309
Class for representing data rates.
Definition: data-rate.h:71
virtual ~CsmaChannel()
Destroy a CsmaChannel.
Definition: csma-channel.cc:61
Channel is BUSY, a packet is being written by a net device.
Definition: csma-channel.h:63
double GetSeconds(void) const
Definition: nstime.h:272
bool Detach(Ptr< CsmaNetDevice > device)
Detach a given netdevice from this channel.
virtual uint32_t GetNDevices(void) const
hold objects of type ns3::Time
Definition: nstime.h:1008
DataRate m_bps
The assigned data rate of the channel.
Definition: csma-channel.h:284
virtual Ptr< NetDevice > GetDevice(uint32_t i) const
Time m_delay
The assigned speed-of-light delay of the channel.
Definition: csma-channel.h:289
Time GetDelay(void)
Get the assigned speed-of-light delay of the channel.
int32_t Attach(Ptr< CsmaNetDevice > device)
Attach a given netdevice to this channel.
Definition: csma-channel.cc:68
static void ScheduleWithContext(uint32_t context, Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event with the given context.
Definition: simulator.h:905
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
Channel is BUSY, packet is propagating to all attached net devices.
Definition: csma-channel.h:64
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
WireState
Current state of the channel.
Definition: csma-channel.h:60
bool IsActive(uint32_t deviceId)
Indicates if a net device is currently attached or detached from the channel.
void PropagationCompleteEvent()
Indicates that the channel has finished propagating the current packet.
CsmaNetDevice Record.
Definition: csma-channel.h:41
CsmaDeviceRec()
Is net device enabled to TX/RX.
int32_t GetDeviceNum(Ptr< CsmaNetDevice > device)
CsmaChannel()
Create a CsmaChannel.
Definition: csma-channel.cc:52
bool TransmitEnd()
Indicates that the net device has finished transmitting the packet over the channel.
bool IsBusy()
Indicates if the channel is busy.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:203
hold objects of type ns3::DataRate
bool active
Pointer to the net device.
Definition: csma-channel.h:44
DataRate GetDataRate(void)
Get the assigned data rate of the channel.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
Ptr< CsmaNetDevice > GetCsmaDevice(uint32_t i) const
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:193
Ptr< CsmaNetDevice > devicePtr
Definition: csma-channel.h:43
bool Reattach(uint32_t deviceId)
Reattach a previously detached net device to the channel.
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
bool TransmitStart(Ptr< Packet > p, uint32_t srcId)
Start transmitting a packet over the channel.
static TypeId GetTypeId(void)
Definition: csma-channel.cc:34