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 
34 TypeId
36 {
37  static TypeId tid = TypeId ("ns3::CsmaChannel")
38  .SetParent<Channel> ()
39  .AddConstructor<CsmaChannel> ()
40  .AddAttribute ("DataRate",
41  "The transmission data rate to be provided to devices connected to the channel",
42  DataRateValue (DataRate (0xffffffff)),
43  MakeDataRateAccessor (&CsmaChannel::m_bps),
44  MakeDataRateChecker ())
45  .AddAttribute ("Delay", "Transmission delay through the channel",
46  TimeValue (Seconds (0)),
47  MakeTimeAccessor (&CsmaChannel::m_delay),
48  MakeTimeChecker ())
49  ;
50  return tid;
51 }
52 
54  :
55  Channel ()
56 {
58  m_state = IDLE;
59  m_deviceList.clear ();
60 }
61 
63 {
64  NS_LOG_FUNCTION (this);
65  m_deviceList.clear ();
66 }
67 
68 int32_t
70 {
71  NS_LOG_FUNCTION (this << device);
72  NS_ASSERT (device != 0);
73 
74  CsmaDeviceRec rec (device);
75 
76  m_deviceList.push_back (rec);
77  return (m_deviceList.size () - 1);
78 }
79 
80 bool
82 {
83  NS_LOG_FUNCTION (this << device);
84  NS_ASSERT (device != 0);
85 
86  std::vector<CsmaDeviceRec>::iterator it;
87  for (it = m_deviceList.begin (); it < m_deviceList.end ( ); it++)
88  {
89  if (it->devicePtr == device)
90  {
91  if (!it->active)
92  {
93  it->active = true;
94  return true;
95  }
96  else
97  {
98  return false;
99  }
100  }
101  }
102  return false;
103 }
104 
105 bool
106 CsmaChannel::Reattach (uint32_t deviceId)
107 {
108  NS_LOG_FUNCTION (this << deviceId);
109 
110  if (deviceId < m_deviceList.size ())
111  {
112  return false;
113  }
114 
115  if (m_deviceList[deviceId].active)
116  {
117  return false;
118  }
119  else
120  {
121  m_deviceList[deviceId].active = true;
122  return true;
123  }
124 }
125 
126 bool
127 CsmaChannel::Detach (uint32_t deviceId)
128 {
129  NS_LOG_FUNCTION (this << deviceId);
130 
131  if (deviceId < m_deviceList.size ())
132  {
133  if (!m_deviceList[deviceId].active)
134  {
135  NS_LOG_WARN ("CsmaChannel::Detach(): Device is already detached (" << deviceId << ")");
136  return false;
137  }
138 
139  m_deviceList[deviceId].active = false;
140 
141  if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
142  {
143  NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmitting (" << deviceId << ")");
144  }
145 
146  return true;
147  }
148  else
149  {
150  return false;
151  }
152 }
153 
154 bool
156 {
157  NS_LOG_FUNCTION (this << device);
158  NS_ASSERT (device != 0);
159 
160  std::vector<CsmaDeviceRec>::iterator it;
161  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
162  {
163  if ((it->devicePtr == device) && (it->active))
164  {
165  it->active = false;
166  return true;
167  }
168  }
169  return false;
170 }
171 
172 bool
174 {
175  NS_LOG_FUNCTION (this << p << srcId);
176  NS_LOG_INFO ("UID is " << p->GetUid () << ")");
177 
178  if (m_state != IDLE)
179  {
180  NS_LOG_WARN ("CsmaChannel::TransmitStart(): State is not IDLE");
181  return false;
182  }
183 
184  if (!IsActive (srcId))
185  {
186  NS_LOG_ERROR ("CsmaChannel::TransmitStart(): Seclected source is not currently attached to network");
187  return false;
188  }
189 
190  NS_LOG_LOGIC ("switch to TRANSMITTING");
191  m_currentPkt = p;
192  m_currentSrc = srcId;
194  return true;
195 }
196 
197 bool
198 CsmaChannel::IsActive (uint32_t deviceId)
199 {
200  return (m_deviceList[deviceId].active);
201 }
202 
203 bool
205 {
207  NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
208 
211 
212  bool retVal = true;
213 
214  if (!IsActive (m_currentSrc))
215  {
216  NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): Seclected source was detached before the end of the transmission");
217  retVal = false;
218  }
219 
220  NS_LOG_LOGIC ("Schedule event in " << m_delay.GetSeconds () << " sec");
221 
222 
223  NS_LOG_LOGIC ("Receive");
224 
225  std::vector<CsmaDeviceRec>::iterator it;
226  uint32_t devId = 0;
227  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
228  {
229  if (it->IsActive ())
230  {
231  // schedule reception events
232  Simulator::ScheduleWithContext (it->devicePtr->GetNode ()->GetId (),
233  m_delay,
234  &CsmaNetDevice::Receive, it->devicePtr,
235  m_currentPkt->Copy (), m_deviceList[m_currentSrc].devicePtr);
236  }
237  devId++;
238  }
239 
240  // also schedule for the tx side to go back to IDLE
242  this);
243  return retVal;
244 }
245 
246 void
248 {
249  NS_LOG_FUNCTION (this << m_currentPkt);
250  NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
251 
253  m_state = IDLE;
254 }
255 
256 uint32_t
258 {
259  int numActDevices = 0;
260  std::vector<CsmaDeviceRec>::iterator it;
261  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
262  {
263  if (it->active)
264  {
265  numActDevices++;
266  }
267  }
268  return numActDevices;
269 }
270 
271 uint32_t
273 {
274  return (m_deviceList.size ());
275 }
276 
278 CsmaChannel::GetCsmaDevice (uint32_t i) const
279 {
280  Ptr<CsmaNetDevice> netDevice = m_deviceList[i].devicePtr;
281  return netDevice;
282 }
283 
284 int32_t
286 {
287  std::vector<CsmaDeviceRec>::iterator it;
288  int i = 0;
289  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
290  {
291  if (it->devicePtr == device)
292  {
293  if (it->active)
294  {
295  return i;
296  }
297  else
298  {
299  return -2;
300  }
301  }
302  i++;
303  }
304  return -1;
305 }
306 
307 bool
309 {
310  if (m_state == IDLE)
311  {
312  return false;
313  }
314  else
315  {
316  return true;
317  }
318 }
319 
320 DataRate
322 {
323  return m_bps;
324 }
325 
326 Time
328 {
329  return m_delay;
330 }
331 
332 WireState
334 {
335  return m_state;
336 }
337 
339 CsmaChannel::GetDevice (uint32_t i) const
340 {
341  return GetCsmaDevice (i);
342 }
343 
345 {
346  active = false;
347 }
348 
350 {
351  devicePtr = device;
352  active = true;
353 }
354 
356 {
357  devicePtr = deviceRec.devicePtr;
358  active = deviceRec.active;
359 }
360 
361 bool
363 {
364  return active;
365 }
366 
367 } // namespace ns3
uint32_t m_currentSrc
Device Id of the source that is currently transmitting on the channel.
Definition: csma-channel.h:316
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
WireState m_state
Current state of the channel.
Definition: csma-channel.h:321
void Receive(Ptr< Packet > p, Ptr< CsmaNetDevice > sender)
Receive a packet from a connected CsmaChannel.
uint64_t GetUid(void) const
A packet is allocated a new uid when it is created empty or with zero-filled payload.
Definition: packet.cc:393
#define NS_ASSERT(condition)
Definition: assert.h:64
uint32_t GetNumActDevices(void)
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:62
Abstract Channel Base Class.
Definition: channel.h:43
#define NS_LOG_INFO(msg)
Definition: log.h:298
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
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:824
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:62
Channel is BUSY, a packet is being written by a net device.
Definition: csma-channel.h:63
double GetSeconds(void) const
Definition: nstime.h:274
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:961
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:69
static void ScheduleWithContext(uint32_t context, Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event with the given context.
Definition: simulator.h:904
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
Channel is BUSY, packet is propagating to all attached net devices.
Definition: csma-channel.h:64
Ptr< Packet > Copy(void) const
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
NS_LOG_COMPONENT_DEFINE("CsmaChannel")
CsmaDeviceRec()
Is net device enabled to TX/RX.
int32_t GetDeviceNum(Ptr< CsmaNetDevice > device)
CsmaChannel()
Create a CsmaChannel.
Definition: csma-channel.cc:53
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)
Definition: log.h:280
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:452
Ptr< CsmaNetDevice > GetCsmaDevice(uint32_t i) const
#define NS_LOG_ERROR(msg)
Definition: log.h:271
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:611
bool TransmitStart(Ptr< Packet > p, uint32_t srcId)
Start transmitting a packet over the channel.
static TypeId GetTypeId(void)
Definition: csma-channel.cc:35