00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "ns3/log.h"
00020 #include "ns3/queue.h"
00021 #include "ns3/simulator.h"
00022 #include "ns3/mac48-address.h"
00023 #include "ns3/llc-snap-header.h"
00024 #include "ns3/error-model.h"
00025 #include "ns3/trace-source-accessor.h"
00026 #include "ns3/uinteger.h"
00027 #include "ns3/pointer.h"
00028 #include "point-to-point-net-device.h"
00029 #include "point-to-point-channel.h"
00030 #include "ppp-header.h"
00031
00032 NS_LOG_COMPONENT_DEFINE ("PointToPointNetDevice");
00033
00034 namespace ns3 {
00035
00036 NS_OBJECT_ENSURE_REGISTERED (PointToPointNetDevice);
00037
00038 TypeId
00039 PointToPointNetDevice::GetTypeId (void)
00040 {
00041 static TypeId tid = TypeId ("ns3::PointToPointNetDevice")
00042 .SetParent<NetDevice> ()
00043 .AddConstructor<PointToPointNetDevice> ()
00044 .AddAttribute ("Address",
00045 "The MAC address of this device.",
00046 Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
00047 MakeMac48AddressAccessor (&PointToPointNetDevice::m_address),
00048 MakeMac48AddressChecker ())
00049 .AddAttribute ("FrameSize",
00050 "The maximum size of a packet sent over this device.",
00051 UintegerValue (DEFAULT_FRAME_SIZE),
00052 MakeUintegerAccessor (&PointToPointNetDevice::SetFrameSize,
00053 &PointToPointNetDevice::GetFrameSize),
00054 MakeUintegerChecker<uint16_t> ())
00055 .AddAttribute ("DataRate",
00056 "The default data rate for point to point links",
00057 DataRateValue (DataRate ("32768b/s")),
00058 MakeDataRateAccessor (&PointToPointNetDevice::m_bps),
00059 MakeDataRateChecker ())
00060 .AddAttribute ("ReceiveErrorModel",
00061 "The receiver error model used to simulate packet loss",
00062 PointerValue (),
00063 MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel),
00064 MakePointerChecker<ErrorModel> ())
00065 .AddAttribute ("TxQueue",
00066 "A queue to use as the transmit queue in the device.",
00067 PointerValue (),
00068 MakePointerAccessor (&PointToPointNetDevice::m_queue),
00069 MakePointerChecker<Queue> ())
00070 .AddAttribute ("InterframeGap",
00071 "The time to wait between packet (frame) transmissions",
00072 TimeValue (Seconds (0.0)),
00073 MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap),
00074 MakeTimeChecker ())
00075 .AddTraceSource ("Rx",
00076 "Trace source indicating reception of packet from the PointToPointChannel.",
00077 MakeTraceSourceAccessor (&PointToPointNetDevice::m_rxTrace))
00078 .AddTraceSource ("Drop",
00079 "Trace source indicating a packet was discarded due to a ReceiveErrorModel decision.",
00080 MakeTraceSourceAccessor (&PointToPointNetDevice::m_dropTrace))
00081
00082 ;
00083 return tid;
00084 }
00085
00086
00087 PointToPointNetDevice::PointToPointNetDevice ()
00088 :
00089 m_txMachineState (READY),
00090 m_channel (0),
00091 m_name (""),
00092 m_linkUp (false)
00093 {
00094 NS_LOG_FUNCTION (this);
00095
00096
00097
00098
00099 PppHeader ppp;
00100 NS_ASSERT_MSG (PPP_OVERHEAD == ppp.GetSerializedSize (),
00101 "PointToPointNetDevice::PointToPointNetDevice(): PPP_OVERHEAD inconsistent");
00102
00103 m_frameSize = DEFAULT_FRAME_SIZE;
00104 m_mtu = MtuFromFrameSize (m_frameSize);
00105 }
00106
00107 PointToPointNetDevice::~PointToPointNetDevice ()
00108 {
00109 }
00110
00111 void
00112 PointToPointNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
00113 {
00114 NS_LOG_FUNCTION_NOARGS ();
00115 NS_ASSERT_MSG (protocolNumber == 0x800,
00116 "PointToPointNetDevice::AddHeader(): protocolNumber must be 0x800");
00117 PppHeader ppp;
00118 p->AddHeader (ppp);
00119 }
00120
00121 bool
00122 PointToPointNetDevice::ProcessHeader(Ptr<Packet> p, uint16_t& param)
00123 {
00124 NS_LOG_FUNCTION_NOARGS ();
00125 PppHeader ppp;
00126 p->RemoveHeader (ppp);
00127 param = 0x800;
00128 return true;
00129 }
00130
00131 void
00132 PointToPointNetDevice::DoDispose()
00133 {
00134 NS_LOG_FUNCTION_NOARGS ();
00135 m_node = 0;
00136 m_channel = 0;
00137 m_receiveErrorModel = 0;
00138 NetDevice::DoDispose ();
00139 }
00140
00141 void
00142 PointToPointNetDevice::SetDataRate(DataRate bps)
00143 {
00144 NS_LOG_FUNCTION_NOARGS ();
00145 m_bps = bps;
00146 }
00147
00148 void
00149 PointToPointNetDevice::SetInterframeGap(Time t)
00150 {
00151 NS_LOG_FUNCTION_NOARGS ();
00152 m_tInterframeGap = t;
00153 }
00154
00155 bool
00156 PointToPointNetDevice::TransmitStart (Ptr<Packet> p)
00157 {
00158 NS_LOG_FUNCTION (this << p);
00159 NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
00160
00161
00162
00163
00164
00165 NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
00166 m_txMachineState = BUSY;
00167 Time txTime = Seconds (m_bps.CalculateTxTime(p->GetSize()));
00168 Time txCompleteTime = txTime + m_tInterframeGap;
00169
00170 NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " <<
00171 txCompleteTime.GetSeconds () << "sec");
00172
00173 Simulator::Schedule (txCompleteTime,
00174 &PointToPointNetDevice::TransmitComplete, this);
00175
00176 return m_channel->TransmitStart(p, this, txTime);
00177 }
00178
00179 void
00180 PointToPointNetDevice::TransmitComplete (void)
00181 {
00182 NS_LOG_FUNCTION_NOARGS ();
00183
00184
00185
00186
00187
00188
00189 NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
00190 m_txMachineState = READY;
00191 Ptr<Packet> p = m_queue->Dequeue ();
00192 if (p == 0)
00193 {
00194
00195
00196
00197 return;
00198 }
00199
00200
00201
00202 TransmitStart(p);
00203 }
00204
00205 bool
00206 PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
00207 {
00208 NS_LOG_FUNCTION (this << &ch);
00209
00210 m_channel = ch;
00211
00212 m_channel->Attach(this);
00213
00214
00215
00216
00217
00218
00219 NotifyLinkUp ();
00220 return true;
00221 }
00222
00223 void
00224 PointToPointNetDevice::SetQueue (Ptr<Queue> q)
00225 {
00226 NS_LOG_FUNCTION (this << q);
00227 m_queue = q;
00228 }
00229
00230 void
00231 PointToPointNetDevice::SetReceiveErrorModel (Ptr<ErrorModel> em)
00232 {
00233 NS_LOG_FUNCTION (this << em);
00234 m_receiveErrorModel = em;
00235 }
00236
00237 void
00238 PointToPointNetDevice::Receive (Ptr<Packet> packet)
00239 {
00240 NS_LOG_FUNCTION (this << packet);
00241 uint16_t protocol = 0;
00242
00243 if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
00244 {
00245
00246
00247
00248
00249 m_dropTrace (packet);
00250 }
00251 else
00252 {
00253
00254
00255
00256
00257 m_rxTrace (packet);
00258 ProcessHeader(packet, protocol);
00259 m_rxCallback (this, packet, protocol, GetRemote ());
00260 if (!m_promiscCallback.IsNull ())
00261 {
00262 m_promiscCallback (this, packet, protocol, GetRemote (), GetAddress (), NetDevice::PACKET_HOST);
00263 }
00264 }
00265 }
00266
00267 Ptr<Queue>
00268 PointToPointNetDevice::GetQueue(void) const
00269 {
00270 NS_LOG_FUNCTION_NOARGS ();
00271 return m_queue;
00272 }
00273
00274 void
00275 PointToPointNetDevice::NotifyLinkUp (void)
00276 {
00277 m_linkUp = true;
00278 if (!m_linkChangeCallback.IsNull ())
00279 {
00280 m_linkChangeCallback ();
00281 }
00282 }
00283
00284 void
00285 PointToPointNetDevice::SetName(const std::string name)
00286 {
00287 m_name = name;
00288 }
00289
00290 std::string
00291 PointToPointNetDevice::GetName(void) const
00292 {
00293 return m_name;
00294 }
00295
00296 void
00297 PointToPointNetDevice::SetIfIndex(const uint32_t index)
00298 {
00299 m_ifIndex = index;
00300 }
00301
00302 uint32_t
00303 PointToPointNetDevice::GetIfIndex(void) const
00304 {
00305 return m_ifIndex;
00306 }
00307
00308 Ptr<Channel>
00309 PointToPointNetDevice::GetChannel (void) const
00310 {
00311 return m_channel;
00312 }
00313
00314
00315
00316
00317
00318
00319 void
00320 PointToPointNetDevice::SetAddress (Mac48Address addr)
00321 {
00322 m_address = addr;
00323 }
00324
00325 Address
00326 PointToPointNetDevice::GetAddress (void) const
00327 {
00328 return m_address;
00329 }
00330
00331 bool
00332 PointToPointNetDevice::IsLinkUp (void) const
00333 {
00334 return m_linkUp;
00335 }
00336
00337 void
00338 PointToPointNetDevice::SetLinkChangeCallback (Callback<void> callback)
00339 {
00340 m_linkChangeCallback = callback;
00341 }
00342
00343
00344
00345
00346
00347 bool
00348 PointToPointNetDevice::IsBroadcast (void) const
00349 {
00350 return true;
00351 }
00352
00353
00354
00355
00356
00357
00358 Address
00359 PointToPointNetDevice::GetBroadcast (void) const
00360 {
00361 return Mac48Address ("ff:ff:ff:ff:ff:ff");
00362 }
00363
00364
00365
00366
00367
00368 bool
00369 PointToPointNetDevice::IsMulticast (void) const
00370 {
00371 return false;
00372 }
00373
00374 Address
00375 PointToPointNetDevice::GetMulticast (Ipv4Address multicastGroup) const
00376 {
00377 return Mac48Address ("01:00:5e:00:00:00");
00378 }
00379
00380 Address
00381 PointToPointNetDevice::GetMulticast (Ipv6Address addr) const
00382 {
00383 NS_LOG_FUNCTION(this << addr);
00384 return Mac48Address ("33:33:00:00:00:00");
00385 }
00386
00387 bool
00388 PointToPointNetDevice::IsPointToPoint (void) const
00389 {
00390 return true;
00391 }
00392
00393 bool
00394 PointToPointNetDevice::IsBridge (void) const
00395 {
00396 return false;
00397 }
00398
00399 bool
00400 PointToPointNetDevice::Send(
00401 Ptr<Packet> packet,
00402 const Address &dest,
00403 uint16_t protocolNumber)
00404 {
00405 NS_LOG_FUNCTION_NOARGS ();
00406 NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest);
00407 NS_LOG_LOGIC ("UID is " << packet->GetUid ());
00408
00409
00410
00411
00412
00413 if (IsLinkUp () == false)
00414 {
00415 return false;
00416 }
00417
00418
00419
00420
00421
00422 AddHeader(packet, protocolNumber);
00423
00424
00425
00426
00427
00428 if (m_txMachineState == READY)
00429 {
00430
00431
00432
00433
00434 m_queue->Enqueue (packet);
00435 packet = m_queue->Dequeue ();
00436 return TransmitStart (packet);
00437 }
00438 else
00439 {
00440 return m_queue->Enqueue(packet);
00441 }
00442 }
00443
00444 bool
00445 PointToPointNetDevice::SendFrom (Ptr<Packet> packet,
00446 const Address &source,
00447 const Address &dest,
00448 uint16_t protocolNumber)
00449 {
00450 return false;
00451 }
00452
00453 Ptr<Node>
00454 PointToPointNetDevice::GetNode (void) const
00455 {
00456 return m_node;
00457 }
00458
00459 void
00460 PointToPointNetDevice::SetNode (Ptr<Node> node)
00461 {
00462 m_node = node;
00463 }
00464
00465 bool
00466 PointToPointNetDevice::NeedsArp (void) const
00467 {
00468 return false;
00469 }
00470
00471 void
00472 PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
00473 {
00474 m_rxCallback = cb;
00475 }
00476
00477 void
00478 PointToPointNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
00479 {
00480 NS_FATAL_ERROR ("not implemented");
00481 m_promiscCallback = cb;
00482 }
00483
00484 bool
00485 PointToPointNetDevice::SupportsSendFrom (void) const
00486 {
00487 return false;
00488 }
00489
00490 Address
00491 PointToPointNetDevice::GetRemote (void) const
00492 {
00493 NS_ASSERT (m_channel->GetNDevices () == 2);
00494 for (uint32_t i = 0; i < m_channel->GetNDevices (); ++i)
00495 {
00496 Ptr<NetDevice> tmp = m_channel->GetDevice (i);
00497 if (tmp != this)
00498 {
00499 return tmp->GetAddress ();
00500 }
00501 }
00502 NS_ASSERT (false);
00503
00504 return Address ();
00505 }
00506
00507 uint32_t
00508 PointToPointNetDevice::MtuFromFrameSize (uint32_t frameSize)
00509 {
00510 NS_LOG_FUNCTION (frameSize);
00511 NS_ASSERT_MSG (frameSize <= std::numeric_limits<uint16_t>::max (),
00512 "PointToPointNetDevice::MtuFromFrameSize(): Frame size should be derived from 16-bit quantity: " <<
00513 frameSize);
00514 PppHeader ppp;
00515 NS_ASSERT_MSG ((uint32_t)frameSize >= ppp.GetSerializedSize (),
00516 "PointToPointNetDevice::MtuFromFrameSize(): Given frame size too small to support PPP");
00517 return frameSize - ppp.GetSerializedSize ();
00518 }
00519
00520 uint32_t
00521 PointToPointNetDevice::FrameSizeFromMtu (uint32_t mtu)
00522 {
00523 NS_LOG_FUNCTION (mtu);
00524
00525 PppHeader ppp;
00526 return mtu + ppp.GetSerializedSize ();
00527 }
00528
00529 void
00530 PointToPointNetDevice::SetFrameSize (uint16_t frameSize)
00531 {
00532 NS_LOG_FUNCTION (frameSize);
00533
00534 m_frameSize = frameSize;
00535 m_mtu = MtuFromFrameSize (frameSize);
00536
00537 NS_LOG_LOGIC ("m_frameSize = " << m_frameSize);
00538 NS_LOG_LOGIC ("m_mtu = " << m_mtu);
00539 }
00540
00541 uint16_t
00542 PointToPointNetDevice::GetFrameSize (void) const
00543 {
00544 return m_frameSize;
00545 }
00546
00547 bool
00548 PointToPointNetDevice::SetMtu (uint16_t mtu)
00549 {
00550 NS_LOG_FUNCTION (mtu);
00551
00552 uint32_t newFrameSize = FrameSizeFromMtu (mtu);
00553
00554 if (newFrameSize > std::numeric_limits<uint16_t>::max ())
00555 {
00556 NS_LOG_WARN ("PointToPointNetDevice::SetMtu(): Frame size overflow, MTU not set.");
00557 return false;
00558 }
00559
00560 m_frameSize = newFrameSize;
00561 m_mtu = mtu;
00562
00563 NS_LOG_LOGIC ("m_frameSize = " << m_frameSize);
00564 NS_LOG_LOGIC ("m_mtu = " << m_mtu);
00565
00566 return true;
00567 }
00568
00569 uint16_t
00570 PointToPointNetDevice::GetMtu (void) const
00571 {
00572 NS_LOG_FUNCTION_NOARGS ();
00573 return m_mtu;
00574 }
00575
00576
00577 }