00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "csma-channel.h"
00022 #include "csma-net-device.h"
00023 #include "ns3/packet.h"
00024 #include "ns3/simulator.h"
00025 #include "ns3/log.h"
00026
00027 NS_LOG_COMPONENT_DEFINE ("CsmaChannel");
00028
00029 namespace ns3 {
00030
00031 NS_OBJECT_ENSURE_REGISTERED (CsmaChannel);
00032
00033 TypeId
00034 CsmaChannel::GetTypeId (void)
00035 {
00036 static TypeId tid = TypeId ("ns3::CsmaChannel")
00037 .SetParent<Channel> ()
00038 .AddConstructor<CsmaChannel> ()
00039 .AddAttribute ("DataRate",
00040 "The transmission data rate to be provided to devices connected to the channel",
00041 DataRateValue (DataRate (0xffffffff)),
00042 MakeDataRateAccessor (&CsmaChannel::m_bps),
00043 MakeDataRateChecker ())
00044 .AddAttribute ("Delay", "Transmission delay through the channel",
00045 TimeValue (Seconds (0)),
00046 MakeTimeAccessor (&CsmaChannel::m_delay),
00047 MakeTimeChecker ())
00048 ;
00049 return tid;
00050 }
00051
00052 CsmaChannel::CsmaChannel ()
00053 :
00054 Channel ("Csma Channel")
00055 {
00056 NS_LOG_FUNCTION_NOARGS ();
00057 m_state = IDLE;
00058 m_deviceList.clear();
00059 }
00060
00061 int32_t
00062 CsmaChannel::Attach (Ptr<CsmaNetDevice> device)
00063 {
00064 NS_LOG_FUNCTION (this << device);
00065 NS_ASSERT (device != 0);
00066
00067 CsmaDeviceRec rec (device);
00068
00069 m_deviceList.push_back (rec);
00070 return (m_deviceList.size () - 1);
00071 }
00072
00073 bool
00074 CsmaChannel::Reattach (Ptr<CsmaNetDevice> device)
00075 {
00076 NS_LOG_FUNCTION (this << device);
00077 NS_ASSERT (device != 0);
00078
00079 std::vector<CsmaDeviceRec>::iterator it;
00080 for (it = m_deviceList.begin (); it < m_deviceList.end( ); it++)
00081 {
00082 if (it->devicePtr == device)
00083 {
00084 if (!it->active)
00085 {
00086 it->active = true;
00087 return true;
00088 }
00089 else
00090 {
00091 return false;
00092 }
00093 }
00094 }
00095 return false;
00096 }
00097
00098 bool
00099 CsmaChannel::Reattach (uint32_t deviceId)
00100 {
00101 NS_LOG_FUNCTION (this << deviceId);
00102
00103 if (deviceId < m_deviceList.size ())
00104 {
00105 return false;
00106 }
00107
00108 if (m_deviceList[deviceId].active)
00109 {
00110 return false;
00111 }
00112 else
00113 {
00114 m_deviceList[deviceId].active = true;
00115 return true;
00116 }
00117 }
00118
00119 bool
00120 CsmaChannel::Detach (uint32_t deviceId)
00121 {
00122 NS_LOG_FUNCTION (this << deviceId);
00123
00124 if (deviceId < m_deviceList.size ())
00125 {
00126 if (!m_deviceList[deviceId].active)
00127 {
00128 NS_LOG_WARN ("CsmaChannel::Detach(): Device is already detached (" << deviceId << ")");
00129 return false;
00130 }
00131
00132 m_deviceList[deviceId].active = false;
00133
00134 if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
00135 {
00136 NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << "transmitting (" << deviceId << ")");
00137 }
00138
00139 return true;
00140 }
00141 else
00142 {
00143 return false;
00144 }
00145 }
00146
00147 bool
00148 CsmaChannel::Detach (Ptr<CsmaNetDevice> device)
00149 {
00150 NS_LOG_FUNCTION (this << device);
00151 NS_ASSERT (device != 0);
00152
00153 std::vector<CsmaDeviceRec>::iterator it;
00154 for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
00155 {
00156 if ((it->devicePtr == device) && (it->active))
00157 {
00158 it->active = false;
00159 return true;
00160 }
00161 }
00162 return false;
00163 }
00164
00165 bool
00166 CsmaChannel::TransmitStart (Ptr<Packet> p, uint32_t srcId)
00167 {
00168 NS_LOG_FUNCTION (this << p << srcId);
00169 NS_LOG_INFO ("UID is " << p->GetUid () << ")");
00170
00171 if (m_state != IDLE)
00172 {
00173 NS_LOG_WARN ("CsmaChannel::TransmitStart(): State is not IDLE");
00174 return false;
00175 }
00176
00177 if (!IsActive(srcId))
00178 {
00179 NS_LOG_ERROR ("CsmaChannel::TransmitStart(): Seclected source is not currently attached to network");
00180 return false;
00181 }
00182
00183 NS_LOG_LOGIC ("switch to TRANSMITTING");
00184 m_currentPkt = p;
00185 m_currentSrc = srcId;
00186 m_state = TRANSMITTING;
00187 return true;
00188 }
00189
00190 bool
00191 CsmaChannel::IsActive(uint32_t deviceId)
00192 {
00193 return (m_deviceList[deviceId].active);
00194 }
00195
00196 bool
00197 CsmaChannel::TransmitEnd()
00198 {
00199 NS_LOG_FUNCTION (this << m_currentPkt << m_currentSrc);
00200 NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
00201
00202 NS_ASSERT (m_state == TRANSMITTING);
00203 m_state = PROPAGATING;
00204
00205 bool retVal = true;
00206
00207 if (!IsActive (m_currentSrc))
00208 {
00209 NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): Seclected source was detached before the end of the transmission");
00210 retVal = false;
00211 }
00212
00213 NS_LOG_LOGIC ("Schedule event in " << m_delay.GetSeconds () << " sec");
00214
00215 Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent,
00216 this);
00217 return retVal;
00218 }
00219
00220 void
00221 CsmaChannel::PropagationCompleteEvent()
00222 {
00223 NS_LOG_FUNCTION (this << m_currentPkt);
00224 NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
00225
00226 NS_ASSERT (m_state == PROPAGATING);
00227
00228 NS_LOG_LOGIC ("Receive");
00229
00230 std::vector<CsmaDeviceRec>::iterator it;
00231 uint32_t devId = 0;
00232 for (it = m_deviceList.begin (); it < m_deviceList.end(); it++)
00233 {
00234 if (it->IsActive ())
00235 {
00236 it->devicePtr->Receive (m_currentPkt->Copy (), m_deviceList[m_currentSrc].devicePtr);
00237 }
00238 devId++;
00239 }
00240 m_state = IDLE;
00241 }
00242
00243 uint32_t
00244 CsmaChannel::GetNumActDevices (void)
00245 {
00246 int numActDevices = 0;
00247 std::vector<CsmaDeviceRec>::iterator it;
00248 for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
00249 {
00250 if (it->active)
00251 {
00252 numActDevices++;
00253 }
00254 }
00255 return numActDevices;
00256 }
00257
00258 uint32_t
00259 CsmaChannel::GetNDevices (void) const
00260 {
00261 return (m_deviceList.size ());
00262 }
00263
00264 Ptr<CsmaNetDevice>
00265 CsmaChannel::GetCsmaDevice (uint32_t i) const
00266 {
00267 Ptr<CsmaNetDevice> netDevice = m_deviceList[i].devicePtr;
00268 return netDevice;
00269 }
00270
00271 int32_t
00272 CsmaChannel::GetDeviceNum (Ptr<CsmaNetDevice> device)
00273 {
00274 std::vector<CsmaDeviceRec>::iterator it;
00275 int i = 0;
00276 for (it = m_deviceList.begin (); it < m_deviceList.end (); it++)
00277 {
00278 if (it->devicePtr == device)
00279 {
00280 if (it->active)
00281 {
00282 return i;
00283 }
00284 else
00285 {
00286 return -2;
00287 }
00288 }
00289 i++;
00290 }
00291 return -1;
00292 }
00293
00294 bool
00295 CsmaChannel::IsBusy (void)
00296 {
00297 if (m_state == IDLE)
00298 {
00299 return false;
00300 }
00301 else
00302 {
00303 return true;
00304 }
00305 }
00306
00307 DataRate
00308 CsmaChannel::GetDataRate (void)
00309 {
00310 return m_bps;
00311 }
00312
00313 Time
00314 CsmaChannel::GetDelay (void)
00315 {
00316 return m_delay;
00317 }
00318
00319 WireState
00320 CsmaChannel::GetState (void)
00321 {
00322 return m_state;
00323 }
00324
00325 Ptr<NetDevice>
00326 CsmaChannel::GetDevice (uint32_t i) const
00327 {
00328 return GetCsmaDevice (i);
00329 }
00330
00331 CsmaDeviceRec::CsmaDeviceRec ()
00332 {
00333 active = false;
00334 }
00335
00336 CsmaDeviceRec::CsmaDeviceRec (Ptr<CsmaNetDevice> device)
00337 {
00338 devicePtr = device;
00339 active = true;
00340 }
00341
00342 bool
00343 CsmaDeviceRec::IsActive ()
00344 {
00345 return active;
00346 }
00347
00348 }