A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
csma-channel.cc
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
34 CsmaChannel::GetTypeId (void)
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 
354 CsmaDeviceRec::CsmaDeviceRec (CsmaDeviceRec const &deviceRec)
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
Definition: csma-channel.h:316
keep track of time unit.
Definition: nstime.h:149
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
WireState m_state
Definition: csma-channel.h:321
void Receive(Ptr< Packet > p, Ptr< CsmaNetDevice > sender)
uint64_t GetUid(void) const
Definition: packet.cc:412
#define NS_ASSERT(condition)
Definition: assert.h:64
uint32_t GetNumActDevices(void)
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
Abstract Channel Base Class.
Definition: channel.h:43
#define NS_LOG_INFO(msg)
Definition: log.h:264
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
std::vector< CsmaDeviceRec > m_deviceList
Definition: csma-channel.h:302
WireState GetState()
Ptr< Packet > m_currentPkt
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
double GetSeconds(void) const
Definition: nstime.h:262
bool Detach(Ptr< CsmaNetDevice > device)
Detach a given netdevice from this channel.
virtual uint32_t GetNDevices(void) const
virtual Ptr< NetDevice > GetDevice(uint32_t i) const
Time GetDelay(void)
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)
Definition: simulator.h:900
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
WireState
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. The channel is released and b...
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
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
bool TransmitEnd()
Indicates that the net device has finished transmitting the packet over the channel.
bool IsBusy()
Indicates if the channel is busy. The channel will only accept new packets for transmission if it is ...
#define NS_LOG_WARN(msg)
Definition: log.h:246
bool active
Pointer to the net device.
Definition: csma-channel.h:44
DataRate GetDataRate(void)
Ptr< CsmaNetDevice > GetCsmaDevice(uint32_t i) const
#define NS_LOG_ERROR(msg)
Definition: log.h:237
bool Reattach(uint32_t deviceId)
Reattach a previously detached net device to the channel.
bool TransmitStart(Ptr< Packet > p, uint32_t srcId)
Start transmitting a packet over the channel.