OLD | NEW |
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 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 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 | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 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 | 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 | 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 * | 17 * |
18 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca> | 18 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca> |
| 19 * Vedran Miletić <rivanvx@gmail.com> |
19 */ | 20 */ |
20 | 21 |
21 #include "csma-channel.h" | 22 #include "csma-channel.h" |
22 #include "csma-net-device.h" | 23 #include "csma-net-device.h" |
23 #include "ns3/packet.h" | 24 #include "ns3/packet.h" |
24 #include "ns3/simulator.h" | 25 #include "ns3/simulator.h" |
25 #include "ns3/log.h" | 26 #include "ns3/log.h" |
| 27 #include "ns3/double.h" |
26 | 28 |
27 NS_LOG_COMPONENT_DEFINE ("CsmaChannel"); | 29 NS_LOG_COMPONENT_DEFINE ("CsmaChannel"); |
28 | 30 |
29 namespace ns3 { | 31 namespace ns3 { |
30 | 32 |
31 NS_OBJECT_ENSURE_REGISTERED (CsmaChannel); | 33 NS_OBJECT_ENSURE_REGISTERED (CsmaChannel); |
32 | 34 |
33 TypeId | 35 TypeId |
34 CsmaChannel::GetTypeId (void) | 36 CsmaChannel::GetTypeId (void) |
35 { | 37 { |
36 static TypeId tid = TypeId ("ns3::CsmaChannel") | 38 static TypeId tid = TypeId ("ns3::CsmaChannel") |
37 .SetParent<Channel> () | 39 .SetParent<Channel> () |
38 .AddConstructor<CsmaChannel> () | 40 .AddConstructor<CsmaChannel> () |
39 .AddAttribute ("DataRate",· | 41 .AddAttribute ("DataRate",· |
40 "The transmission data rate to be provided to devices connect
ed to the channel", | 42 "The transmission data rate to be provided to devices connect
ed to the channel", |
41 DataRateValue (DataRate (0xffffffff)), | 43 DataRateValue (DataRate (0xffffffff)), |
42 MakeDataRateAccessor (&CsmaChannel::m_bps), | 44 MakeDataRateAccessor (&CsmaChannel::m_bps), |
43 MakeDataRateChecker ()) | 45 MakeDataRateChecker ()) |
44 .AddAttribute ("Delay", "Transmission delay through the channel", | 46 .AddAttribute ("Delay", "Transmission delay through the channel", |
45 TimeValue (Seconds (0)), | 47 TimeValue (Seconds (0)), |
46 MakeTimeAccessor (&CsmaChannel::m_delay), | 48 MakeTimeAccessor (&CsmaChannel::m_delay), |
47 MakeTimeChecker ()) | 49 MakeTimeChecker ()) |
| 50 .AddAttribute ("Length", "Physical length of the wire", |
| 51 DoubleValue (0.0), |
| 52 MakeDoubleAccessor (&CsmaChannel::m_length), |
| 53 MakeDoubleChecker<double> ()) |
48 ; | 54 ; |
49 return tid; | 55 return tid; |
50 } | 56 } |
51 | 57 |
52 CsmaChannel::CsmaChannel () | 58 CsmaChannel::CsmaChannel () |
53 : | 59 : |
54 Channel () | 60 Channel () |
55 { | 61 { |
56 NS_LOG_FUNCTION_NOARGS (); | 62 NS_LOG_FUNCTION_NOARGS (); |
57 m_state = IDLE; | 63 m_state = IDLE; |
58 m_deviceList.clear (); | 64 m_deviceList.clear (); |
59 } | 65 } |
60 | 66 |
61 CsmaChannel::~CsmaChannel () | 67 CsmaChannel::~CsmaChannel () |
62 { | 68 { |
63 NS_LOG_FUNCTION (this); | 69 NS_LOG_FUNCTION (this); |
64 m_deviceList.clear (); | 70 m_deviceList.clear (); |
65 } | 71 } |
66 | 72 |
67 int32_t | 73 int32_t |
68 CsmaChannel::Attach (Ptr<CsmaNetDevice> device) | 74 CsmaChannel::Attach (Ptr<CsmaNetDevice> device, double distance) |
69 { | 75 { |
70 NS_LOG_FUNCTION (this << device); | 76 NS_LOG_FUNCTION (this << device); |
71 NS_ASSERT (device != 0); | 77 NS_ASSERT (device != 0); |
72 | 78 |
73 CsmaDeviceRec rec (device); | 79 CsmaDeviceRec rec (device, distance); |
74 | 80 |
75 m_deviceList.push_back (rec); | 81 m_deviceList.push_back (rec); |
76 return (m_deviceList.size () - 1); | 82 return (m_deviceList.size () - 1); |
77 } | 83 } |
78 | 84 |
79 bool | 85 bool |
80 CsmaChannel::Reattach (Ptr<CsmaNetDevice> device) | 86 CsmaChannel::Reattach (Ptr<CsmaNetDevice> device) |
81 { | 87 { |
82 NS_LOG_FUNCTION (this << device); | 88 NS_LOG_FUNCTION (this << device); |
83 NS_ASSERT (device != 0); | 89 NS_ASSERT (device != 0); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 if (deviceId < m_deviceList.size ()) | 136 if (deviceId < m_deviceList.size ()) |
131 { | 137 { |
132 if (!m_deviceList[deviceId].active) | 138 if (!m_deviceList[deviceId].active) |
133 { | 139 { |
134 NS_LOG_WARN ("CsmaChannel::Detach(): Device is already detached (" <<
deviceId << ")"); | 140 NS_LOG_WARN ("CsmaChannel::Detach(): Device is already detached (" <<
deviceId << ")"); |
135 return false; | 141 return false; |
136 } | 142 } |
137 | 143 |
138 m_deviceList[deviceId].active = false; | 144 m_deviceList[deviceId].active = false; |
139 | 145 |
140 if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId)) | 146 if ((m_state == OCCUPIED) && (m_currentSrc == deviceId)) |
141 { | 147 { |
142 NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmit
ting (" << deviceId << ")"); | 148 NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmit
ting (" << deviceId << ")"); |
143 } | 149 } |
144 | 150 |
145 return true; | 151 return true; |
146 }· | 152 }· |
147 else· | 153 else· |
148 { | 154 { |
149 return false; | 155 return false; |
150 } | 156 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 | 188 |
183 if (!IsActive (srcId)) | 189 if (!IsActive (srcId)) |
184 { | 190 { |
185 NS_LOG_ERROR ("CsmaChannel::TransmitStart(): Seclected source is not curre
ntly attached to network"); | 191 NS_LOG_ERROR ("CsmaChannel::TransmitStart(): Seclected source is not curre
ntly attached to network"); |
186 return false; | 192 return false; |
187 } | 193 } |
188 | 194 |
189 NS_LOG_LOGIC ("switch to TRANSMITTING"); | 195 NS_LOG_LOGIC ("switch to TRANSMITTING"); |
190 m_currentPkt = p; | 196 m_currentPkt = p; |
191 m_currentSrc = srcId; | 197 m_currentSrc = srcId; |
192 m_state = TRANSMITTING; | 198 m_state = OCCUPIED; |
193 return true; | 199 return true; |
194 } | 200 } |
195 | 201 |
196 bool | 202 bool |
197 CsmaChannel::IsActive (uint32_t deviceId) | 203 CsmaChannel::IsActive (uint32_t deviceId) |
198 { | 204 { |
199 return (m_deviceList[deviceId].active); | 205 return (m_deviceList[deviceId].active); |
200 } | 206 } |
201 | 207 |
202 bool | 208 bool |
203 CsmaChannel::TransmitEnd () | 209 CsmaChannel::TransmitEnd () |
204 { | 210 { |
205 NS_LOG_FUNCTION (this << m_currentPkt << m_currentSrc); | 211 NS_LOG_FUNCTION (this << m_currentPkt << m_currentSrc); |
206 NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")"); | 212 NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")"); |
207 | 213 |
208 NS_ASSERT (m_state == TRANSMITTING); | 214 NS_ASSERT (m_state == OCCUPIED); |
209 m_state = PROPAGATING; | |
210 | 215 |
211 bool retVal = true; | 216 bool retVal = true; |
212 | 217 |
213 if (!IsActive (m_currentSrc)) | 218 if (!IsActive (m_currentSrc)) |
214 { | 219 { |
215 NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): Seclected source was detached b
efore the end of the transmission"); | 220 NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): Seclected source was detached b
efore the end of the transmission"); |
216 retVal = false; | 221 retVal = false; |
217 } | 222 } |
218 | 223 |
219 NS_LOG_LOGIC ("Schedule event in " << m_delay.GetSeconds () << " sec"); | 224 NS_LOG_LOGIC ("From one to other end of the wire delay is " << m_delay.GetSeco
nds () << " s"); |
220 | 225 |
221 | 226 |
222 NS_LOG_LOGIC ("Receive"); | 227 NS_LOG_LOGIC ("Receive"); |
223 | 228 |
224 std::vector<CsmaDeviceRec>::iterator it; | 229 // Make all attached devices start receiving after signal has |
225 uint32_t devId = 0; | 230 // propagated far enough so that device can see it |
226 for (it = m_deviceList.begin (); it < m_deviceList.end (); it++) | 231 Time tEventTx = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ())); |
| 232 NS_LOG_DEBUG ("CSMA channel packet transmission time is " << tEventTx.GetSecon
ds () << "s"); |
| 233 for (std::vector<CsmaDeviceRec>::iterator it = m_deviceList.begin (); it < m_d
eviceList.end (); it++) |
227 { | 234 { |
228 if (it->IsActive ()) | 235 // Device doesn't send to itself |
| 236 if (GetDeviceNum (it->devicePtr) != m_currentSrc && it->IsActive ()) |
229 { | 237 { |
230 // schedule reception events | 238 » // Compute propagation time based on device distance from wire end |
| 239 » Time tEventProp = std::abs ((m_deviceList[m_currentSrc].position - it-
>position) / m_length) * m_delay; |
| 240 » NS_LOG_DEBUG ("CSMA channel propagation time for device " << it->devic
ePtr << " is " << tEventProp.GetSeconds () << "s"); |
231 Simulator::ScheduleWithContext (it->devicePtr->GetNode ()->GetId (), | 241 Simulator::ScheduleWithContext (it->devicePtr->GetNode ()->GetId (), |
232 m_delay, | 242 tEventProp + tEventTx, |
233 &CsmaNetDevice::Receive, it->devicePtr
, | 243 &CsmaNetDevice::Receive, it->devicePtr
, |
234 m_currentPkt->Copy (), m_deviceList[m_
currentSrc].devicePtr); | 244 m_currentPkt->Copy (), m_deviceList[m_
currentSrc].devicePtr); |
235 } | 245 } |
236 devId++; | |
237 } | 246 } |
238 | 247 |
239 // also schedule for the tx side to go back to IDLE | 248 // also schedule for the tx side to go back to IDLE |
240 Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent, | 249 Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent, |
241 this); | 250 this); |
242 return retVal; | 251 return retVal; |
243 } | 252 } |
244 | 253 |
245 void | 254 void |
246 CsmaChannel::PropagationCompleteEvent () | 255 CsmaChannel::PropagationCompleteEvent () |
247 { | 256 { |
248 NS_LOG_FUNCTION (this << m_currentPkt); | 257 NS_LOG_FUNCTION (this << m_currentPkt); |
249 NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")"); | 258 NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")"); |
250 | 259 |
251 NS_ASSERT (m_state == PROPAGATING); | 260 NS_ASSERT (m_state == OCCUPIED); |
252 m_state = IDLE; | 261 m_state = IDLE; |
253 } | 262 } |
254 | 263 |
255 uint32_t | 264 uint32_t |
256 CsmaChannel::GetNumActDevices (void) | 265 CsmaChannel::GetNumActDevices (void) |
257 { | 266 { |
258 int numActDevices = 0; | 267 int numActDevices = 0; |
259 std::vector<CsmaDeviceRec>::iterator it; | 268 std::vector<CsmaDeviceRec>::iterator it; |
260 for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)· | 269 for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)· |
261 { | 270 { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 CsmaChannel::GetDevice (uint32_t i) const | 347 CsmaChannel::GetDevice (uint32_t i) const |
339 { | 348 { |
340 return GetCsmaDevice (i); | 349 return GetCsmaDevice (i); |
341 } | 350 } |
342 | 351 |
343 CsmaDeviceRec::CsmaDeviceRec () | 352 CsmaDeviceRec::CsmaDeviceRec () |
344 { | 353 { |
345 active = false; | 354 active = false; |
346 } | 355 } |
347 | 356 |
348 CsmaDeviceRec::CsmaDeviceRec (Ptr<CsmaNetDevice> device) | 357 CsmaDeviceRec::CsmaDeviceRec (Ptr<CsmaNetDevice> device, double distance) |
349 { | 358 { |
350 devicePtr = device;· | 359 devicePtr = device;· |
351 active = true; | 360 active = true; |
| 361 position = distance; |
352 } | 362 } |
353 | 363 |
354 CsmaDeviceRec::CsmaDeviceRec (CsmaDeviceRec const &deviceRec) | 364 CsmaDeviceRec::CsmaDeviceRec (CsmaDeviceRec const &deviceRec) |
355 { | 365 { |
356 devicePtr = deviceRec.devicePtr; | 366 devicePtr = deviceRec.devicePtr; |
357 active = deviceRec.active; | 367 active = deviceRec.active; |
| 368 position = deviceRec.position; |
358 } | 369 } |
359 | 370 |
360 bool | 371 bool |
361 CsmaDeviceRec::IsActive ()· | 372 CsmaDeviceRec::IsActive ()· |
362 { | 373 { |
363 return active; | 374 return active; |
364 } | 375 } |
365 | 376 |
366 } // namespace ns3 | 377 } // namespace ns3 |
OLD | NEW |