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