A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
csma-net-device.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 "ns3/log.h"
22 #include "ns3/queue.h"
23 #include "ns3/simulator.h"
24 #include "ns3/ethernet-header.h"
25 #include "ns3/ethernet-trailer.h"
26 #include "ns3/llc-snap-header.h"
27 #include "ns3/error-model.h"
28 #include "ns3/enum.h"
29 #include "ns3/boolean.h"
30 #include "ns3/uinteger.h"
31 #include "ns3/pointer.h"
32 #include "ns3/trace-source-accessor.h"
33 #include "csma-net-device.h"
34 #include "csma-channel.h"
35 
36 NS_LOG_COMPONENT_DEFINE ("CsmaNetDevice");
37 
38 namespace ns3 {
39 
40 NS_OBJECT_ENSURE_REGISTERED (CsmaNetDevice);
41 
42 TypeId
43 CsmaNetDevice::GetTypeId (void)
44 {
45  static TypeId tid = TypeId ("ns3::CsmaNetDevice")
46  .SetParent<NetDevice> ()
47  .AddConstructor<CsmaNetDevice> ()
48  .AddAttribute ("Address",
49  "The MAC address of this device.",
50  Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
51  MakeMac48AddressAccessor (&CsmaNetDevice::m_address),
52  MakeMac48AddressChecker ())
53  .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
54  UintegerValue (DEFAULT_MTU),
55  MakeUintegerAccessor (&CsmaNetDevice::SetMtu,
57  MakeUintegerChecker<uint16_t> ())
58  .AddAttribute ("EncapsulationMode",
59  "The link-layer encapsulation type to use.",
60  EnumValue (DIX),
61  MakeEnumAccessor (&CsmaNetDevice::SetEncapsulationMode),
62  MakeEnumChecker (DIX, "Dix",
63  LLC, "Llc"))
64  .AddAttribute ("SendEnable",
65  "Enable or disable the transmitter section of the device.",
66  BooleanValue (true),
67  MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable),
68  MakeBooleanChecker ())
69  .AddAttribute ("ReceiveEnable",
70  "Enable or disable the receiver section of the device.",
71  BooleanValue (true),
72  MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable),
73  MakeBooleanChecker ())
74  .AddAttribute ("ReceiveErrorModel",
75  "The receiver error model used to simulate packet loss",
76  PointerValue (),
77  MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel),
78  MakePointerChecker<ErrorModel> ())
79 
80  //
81  // Transmit queueing discipline for the device which includes its own set
82  // of trace hooks.
83  //
84  .AddAttribute ("TxQueue",
85  "A queue to use as the transmit queue in the device.",
86  PointerValue (),
87  MakePointerAccessor (&CsmaNetDevice::m_queue),
88  MakePointerChecker<Queue> ())
89 
90  //
91  // Trace sources at the "top" of the net device, where packets transition
92  // to/from higher layers.
93  //
94  .AddTraceSource ("MacTx",
95  "Trace source indicating a packet has arrived for transmission by this device",
97  .AddTraceSource ("MacTxDrop",
98  "Trace source indicating a packet has been dropped by the device before transmission",
100  .AddTraceSource ("MacPromiscRx",
101  "A packet has been received by this device, has been passed up from the physical layer "
102  "and is being forwarded up the local protocol stack. This is a promiscuous trace,",
104  .AddTraceSource ("MacRx",
105  "A packet has been received by this device, has been passed up from the physical layer "
106  "and is being forwarded up the local protocol stack. This is a non-promiscuous trace,",
108 #if 0
109  // Not currently implemented in this device
110  .AddTraceSource ("MacRxDrop",
111  "Trace source indicating a packet was received, but dropped before being forwarded up the stack",
113 #endif
114  .AddTraceSource ("MacTxBackoff",
115  "Trace source indicating a packet has been delayed by the CSMA backoff process",
117  //
118  // Trace souces at the "bottom" of the net device, where packets transition
119  // to/from the channel.
120  //
121  .AddTraceSource ("PhyTxBegin",
122  "Trace source indicating a packet has begun transmitting over the channel",
124  .AddTraceSource ("PhyTxEnd",
125  "Trace source indicating a packet has been completely transmitted over the channel",
127  .AddTraceSource ("PhyTxDrop",
128  "Trace source indicating a packet has been dropped by the device during transmission",
130 #if 0
131  // Not currently implemented in this device
132  .AddTraceSource ("PhyRxBegin",
133  "Trace source indicating a packet has begun being received by the device",
135 #endif
136  .AddTraceSource ("PhyRxEnd",
137  "Trace source indicating a packet has been completely received by the device",
139  .AddTraceSource ("PhyRxDrop",
140  "Trace source indicating a packet has been dropped by the device during reception",
142  //
143  // Trace sources designed to simulate a packet sniffer facility (tcpdump).
144  //
145  .AddTraceSource ("Sniffer",
146  "Trace source simulating a non-promiscuous packet sniffer attached to the device",
148  .AddTraceSource ("PromiscSniffer",
149  "Trace source simulating a promiscuous packet sniffer attached to the device",
151  ;
152  return tid;
153 }
154 
156  : m_linkUp (false)
157 {
158  NS_LOG_FUNCTION (this);
161  m_channel = 0;
162 
163  //
164  // We would like to let the attribute system take care of initializing the
165  // packet encapsulation stuff, but we also don't want to get caught up in
166  // initialization order changes. So we'll get the three problem variables
167  // into a consistent state here before the attribute calls, and then depend
168  // on the semantics of the setters to preserve a consistent state. This
169  // really doesn't have to be the same set of values as the initial values
170  // set by the attributes, but it does have to be a consistent set. That is,
171  // you can just change the default encapsulation mode above without having
172  // to change it here.
173  //
174  m_encapMode = DIX;
175 }
176 
178 {
180  m_queue = 0;
181 }
182 
183 void
185 {
187  m_channel = 0;
188  m_node = 0;
190 }
191 
192 void
194 {
195  NS_LOG_FUNCTION (mode);
196 
197  m_encapMode = mode;
198 
199  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
200  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
201 }
202 
205 {
207  return m_encapMode;
208 }
209 
210 bool
211 CsmaNetDevice::SetMtu (uint16_t mtu)
212 {
213  NS_LOG_FUNCTION (this << mtu);
214  m_mtu = mtu;
215 
216  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
217  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
218 
219  return true;
220 }
221 
222 uint16_t
224 {
226  return m_mtu;
227 }
228 
229 
230 void
232 {
233  NS_LOG_FUNCTION (sendEnable);
234  m_sendEnable = sendEnable;
235 }
236 
237 void
239 {
240  NS_LOG_FUNCTION (receiveEnable);
241  m_receiveEnable = receiveEnable;
242 }
243 
244 bool
246 {
248  return m_sendEnable;
249 }
250 
251 bool
253 {
255  return m_receiveEnable;
256 }
257 
258 void
260 {
261  NS_LOG_FUNCTION (t);
262  m_tInterframeGap = t;
263 }
264 
265 void
266 CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries)
267 {
268  NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries);
269  m_backoff.m_slotTime = slotTime;
270  m_backoff.m_minSlots = minSlots;
271  m_backoff.m_maxSlots = maxSlots;
272  m_backoff.m_ceiling = ceiling;
273  m_backoff.m_maxRetries = maxRetries;
274 }
275 
276 void
277 CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
278 {
279  NS_LOG_FUNCTION (p << source << dest << protocolNumber);
280 
281  EthernetHeader header (false);
282  header.SetSource (source);
283  header.SetDestination (dest);
284 
285  EthernetTrailer trailer;
286 
287  NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ());
288  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
289  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
290 
291  uint16_t lengthType = 0;
292  switch (m_encapMode)
293  {
294  case DIX:
295  NS_LOG_LOGIC ("Encapsulating packet as DIX (type interpretation)");
296  //
297  // This corresponds to the type interpretation of the lengthType field as
298  // in the old Ethernet Blue Book.
299  //
300  lengthType = protocolNumber;
301 
302  //
303  // All Ethernet frames must carry a minimum payload of 46 bytes. We need
304  // to pad out if we don't have enough bytes. These must be real bytes
305  // since they will be written to pcap files and compared in regression
306  // trace files.
307  //
308  if (p->GetSize () < 46)
309  {
310  uint8_t buffer[46];
311  memset (buffer, 0, 46);
312  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
313  p->AddAtEnd (padd);
314  }
315  break;
316  case LLC:
317  {
318  NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)");
319 
320  LlcSnapHeader llc;
321  llc.SetType (protocolNumber);
322  p->AddHeader (llc);
323 
324  //
325  // This corresponds to the length interpretation of the lengthType
326  // field but with an LLC/SNAP header added to the payload as in
327  // IEEE 802.2
328  //
329  lengthType = p->GetSize ();
330 
331  //
332  // All Ethernet frames must carry a minimum payload of 46 bytes. The
333  // LLC SNAP header counts as part of this payload. We need to padd out
334  // if we don't have enough bytes. These must be real bytes since they
335  // will be written to pcap files and compared in regression trace files.
336  //
337  if (p->GetSize () < 46)
338  {
339  uint8_t buffer[46];
340  memset (buffer, 0, 46);
341  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
342  p->AddAtEnd (padd);
343  }
344 
345  NS_ASSERT_MSG (p->GetSize () <= GetMtu (),
346  "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
347  "length interpretation must not exceed device frame size minus overhead");
348  }
349  break;
350  case ILLEGAL:
351  default:
352  NS_FATAL_ERROR ("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
353  break;
354  }
355 
356  NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")");
357  header.SetLengthType (lengthType);
358  p->AddHeader (header);
359 
360  if (Node::ChecksumEnabled ())
361  {
362  trailer.EnableFcs (true);
363  }
364  trailer.CalcFcs (p);
365  p->AddTrailer (trailer);
366 }
367 
368 #if 0
369 bool
370 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
371 {
372  NS_LOG_FUNCTION (p << param);
373 
374  EthernetTrailer trailer;
375  p->RemoveTrailer (trailer);
376 
377  EthernetHeader header (false);
378  p->RemoveHeader (header);
379 
380  if ((header.GetDestination () != GetBroadcast ()) &&
381  (header.GetDestination () != GetAddress ()))
382  {
383  return false;
384  }
385 
386  switch (m_encapMode)
387  {
388  case DIX:
389  param = header.GetLengthType ();
390  break;
391  case LLC:
392  {
393  LlcSnapHeader llc;
394  p->RemoveHeader (llc);
395  param = llc.GetType ();
396  }
397  break;
398  case ILLEGAL:
399  default:
400  NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
401  break;
402  }
403  return true;
404 }
405 #endif
406 
407 void
409 {
411 
412  //
413  // This function is called to start the process of transmitting a packet. We
414  // expect that the packet to transmit will be found in m_currentPkt.
415  //
416  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
417 
418  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
419  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
420 
421  //
422  // Only transmit if the send side of net device is enabled
423  //
424  if (IsSendEnabled () == false)
425  {
427  m_currentPkt = 0;
428  return;
429  }
430 
431  //
432  // Somebody has called here telling us to start transmitting a packet. They
433  // can only do this if the state machine is in the READY or BACKOFF state.
434  // Specifically, if we are ready to start transmitting, we cannot already
435  // be transmitting (i.e., BUSY)
436  //
438  "Must be READY to transmit. Tx state is: " << m_txMachineState);
439 
440  //
441  // Now we have to sense the state of the medium and either start transmitting
442  // if it is idle, or backoff our transmission if someone else is on the wire.
443  //
444  if (m_channel->GetState () != IDLE)
445  {
446  //
447  // The channel is busy -- backoff and rechedule TransmitStart() unless
448  // we have exhausted all of our retries.
449  //
451 
453  {
454  //
455  // Too many retries, abort transmission of packet
456  //
457  TransmitAbort ();
458  }
459  else
460  {
462 
464  Time backoffTime = m_backoff.GetBackoffTime ();
465 
466  NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec");
467 
469  }
470  }
471  else
472  {
473  //
474  // The channel is free, transmit the packet
475  //
476  if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
477  {
478  NS_LOG_WARN ("Channel TransmitStart returns an error");
480  m_currentPkt = 0;
482  }
483  else
484  {
485  //
486  // Transmission succeeded, reset the backoff time parameters and
487  // schedule a transmit complete event.
488  //
492 
494  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
496  }
497  }
498 }
499 
500 void
502 {
504 
505  //
506  // When we started the process of transmitting the current packet, it was
507  // placed in m_currentPkt. So we had better find one there.
508  //
509  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
510  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
511  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
512 
514  m_currentPkt = 0;
515 
516  NS_ASSERT_MSG (m_txMachineState == BACKOFF, "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
517 
518  //
519  // We're done with that one, so reset the backoff algorithm and ready the
520  // transmit state machine.
521  //
524 
525  //
526  // If there is another packet on the input queue, we need to start trying to
527  // get that out. If the queue is empty we just wait until someone puts one
528  // in.
529  //
530  if (m_queue->IsEmpty ())
531  {
532  return;
533  }
534  else
535  {
536  m_currentPkt = m_queue->Dequeue ();
537  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
540  TransmitStart ();
541  }
542 }
543 
544 void
546 {
548 
549  //
550  // This function is called to finish the process of transmitting a packet.
551  // We need to tell the channel that we've stopped wiggling the wire and
552  // schedule an event that will be executed when it's time to re-enable
553  // the transmitter after the interframe gap.
554  //
555  NS_ASSERT_MSG (m_txMachineState == BUSY, "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
556  NS_ASSERT (m_channel->GetState () == TRANSMITTING);
558 
559  //
560  // When we started transmitting the current packet, it was placed in
561  // m_currentPkt. So we had better find one there.
562  //
563  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
564  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
565  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
566 
567  m_channel->TransmitEnd ();
569  m_currentPkt = 0;
570 
571  NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec");
572 
574 }
575 
576 void
578 {
580 
581  //
582  // This function is called to enable the transmitter after the interframe
583  // gap has passed. If there are pending transmissions, we use this opportunity
584  // to start the next transmit.
585  //
586  NS_ASSERT_MSG (m_txMachineState == GAP, "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
588 
589  //
590  // We expect that the packet we had been transmitting was cleared when the
591  // TransmitCompleteEvent() was executed.
592  //
593  NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
594 
595  //
596  // Get the next packet from the queue for transmitting
597  //
598  if (m_queue->IsEmpty ())
599  {
600  return;
601  }
602  else
603  {
604  m_currentPkt = m_queue->Dequeue ();
605  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
608  TransmitStart ();
609  }
610 }
611 
612 bool
614 {
615  NS_LOG_FUNCTION (this << &ch);
616 
617  m_channel = ch;
618 
619  m_deviceId = m_channel->Attach (this);
620 
621  //
622  // The channel provides us with the transmitter data rate.
623  //
624  m_bps = m_channel->GetDataRate ();
625 
626  //
627  // We use the Ethernet interframe gap of 96 bit times.
628  //
630 
631  //
632  // This device is up whenever a channel is attached to it.
633  //
634  NotifyLinkUp ();
635  return true;
636 }
637 
638 void
640 {
641  NS_LOG_FUNCTION (q);
642  m_queue = q;
643 }
644 
645 void
647 {
648  NS_LOG_FUNCTION (em);
649  m_receiveErrorModel = em;
650 }
651 
652 void
654 {
655  NS_LOG_FUNCTION (packet << senderDevice);
656  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
657 
658  //
659  // We never forward up packets that we sent. Real devices don't do this since
660  // their receivers are disabled during send, so we don't.
661  //
662  if (senderDevice == this)
663  {
664  return;
665  }
666 
667  //
668  // Hit the trace hook. This trace will fire on all packets received from the
669  // channel except those originated by this device.
670  //
671  m_phyRxEndTrace (packet);
672 
673  //
674  // Only receive if the send side of net device is enabled
675  //
676  if (IsReceiveEnabled () == false)
677  {
678  m_phyRxDropTrace (packet);
679  return;
680  }
681 
682  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
683  {
684  NS_LOG_LOGIC ("Dropping pkt due to error model ");
685  m_phyRxDropTrace (packet);
686  return;
687  }
688 
689  //
690  // Trace sinks will expect complete packets, not packets without some of the
691  // headers.
692  //
693  Ptr<Packet> originalPacket = packet->Copy ();
694 
695  EthernetTrailer trailer;
696  packet->RemoveTrailer (trailer);
697  if (Node::ChecksumEnabled ())
698  {
699  trailer.EnableFcs (true);
700  }
701 
702  trailer.CheckFcs (packet);
703  bool crcGood = trailer.CheckFcs (packet);
704  if (!crcGood)
705  {
706  NS_LOG_INFO ("CRC error on Packet " << packet);
707  m_phyRxDropTrace (packet);
708  return;
709  }
710 
711  EthernetHeader header (false);
712  packet->RemoveHeader (header);
713 
714  NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
715  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
716 
717  uint16_t protocol;
718  //
719  // If the length/type is less than 1500, it corresponds to a length
720  // interpretation packet. In this case, it is an 802.3 packet and
721  // will also have an 802.2 LLC header. If greater than 1500, we
722  // find the protocol number (Ethernet type) directly.
723  //
724  if (header.GetLengthType () <= 1500)
725  {
726  NS_ASSERT (packet->GetSize () >= header.GetLengthType ());
727  uint32_t padlen = packet->GetSize () - header.GetLengthType ();
728  NS_ASSERT (padlen <= 46);
729  if (padlen > 0)
730  {
731  packet->RemoveAtEnd (padlen);
732  }
733 
734  LlcSnapHeader llc;
735  packet->RemoveHeader (llc);
736  protocol = llc.GetType ();
737  }
738  else
739  {
740  protocol = header.GetLengthType ();
741  }
742 
743  //
744  // Classify the packet based on its destination.
745  //
746  PacketType packetType;
747 
748  if (header.GetDestination ().IsBroadcast ())
749  {
750  packetType = PACKET_BROADCAST;
751  }
752  else if (header.GetDestination ().IsGroup ())
753  {
754  packetType = PACKET_MULTICAST;
755  }
756  else if (header.GetDestination () == m_address)
757  {
758  packetType = PACKET_HOST;
759  }
760  else
761  {
762  packetType = PACKET_OTHERHOST;
763  }
764 
765  //
766  // For all kinds of packetType we receive, we hit the promiscuous sniffer
767  // hook and pass a copy up to the promiscuous callback. Pass a copy to
768  // make sure that nobody messes with our packet.
769  //
770  m_promiscSnifferTrace (originalPacket);
771  if (!m_promiscRxCallback.IsNull ())
772  {
773  m_macPromiscRxTrace (originalPacket);
774  m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
775  }
776 
777  //
778  // If this packet is not destined for some other host, it must be for us
779  // as either a broadcast, multicast or unicast. We need to hit the mac
780  // packet received trace hook and forward the packet up the stack.
781  //
782  if (packetType != PACKET_OTHERHOST)
783  {
784  m_snifferTrace (originalPacket);
785  m_macRxTrace (originalPacket);
786  m_rxCallback (this, packet, protocol, header.GetSource ());
787  }
788 }
789 
792 {
794  return m_queue;
795 }
796 
797 void
799 {
801  m_linkUp = true;
803 }
804 
805 void
806 CsmaNetDevice::SetIfIndex (const uint32_t index)
807 {
808  NS_LOG_FUNCTION (index);
809  m_ifIndex = index;
810 }
811 
812 uint32_t
814 {
816  return m_ifIndex;
817 }
818 
821 {
823  return m_channel;
824 }
825 
826 void
828 {
831 }
832 
833 Address
835 {
837  return m_address;
838 }
839 
840 bool
842 {
844  return m_linkUp;
845 }
846 
847 void
849 {
850  NS_LOG_FUNCTION (&callback);
852 }
853 
854 bool
856 {
858  return true;
859 }
860 
861 Address
863 {
865  return Mac48Address ("ff:ff:ff:ff:ff:ff");
866 }
867 
868 bool
870 {
872  return true;
873 }
874 
875 Address
877 {
878  NS_LOG_FUNCTION (multicastGroup);
879 
880  Mac48Address ad = Mac48Address::GetMulticast (multicastGroup);
881 
882  //
883  // Implicit conversion (operator Address ()) is defined for Mac48Address, so
884  // use it by just returning the EUI-48 address which is automagically converted
885  // to an Address.
886  //
887  NS_LOG_LOGIC ("multicast address is " << ad);
888 
889  return ad;
890 }
891 
892 bool
894 {
896  return false;
897 }
898 
899 bool
901 {
903  return false;
904 }
905 
906 bool
907 CsmaNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t protocolNumber)
908 {
909  NS_LOG_FUNCTION (packet << dest << protocolNumber);
910  return SendFrom (packet, m_address, dest, protocolNumber);
911 }
912 
913 bool
914 CsmaNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
915 {
916  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
917  NS_LOG_LOGIC ("packet =" << packet);
918  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
919 
920  NS_ASSERT (IsLinkUp ());
921 
922  //
923  // Only transmit if send side of net device is enabled
924  //
925  if (IsSendEnabled () == false)
926  {
927  m_macTxDropTrace (packet);
928  return false;
929  }
930 
931  Mac48Address destination = Mac48Address::ConvertFrom (dest);
933  AddHeader (packet, source, destination, protocolNumber);
934 
935  m_macTxTrace (packet);
936 
937  //
938  // Place the packet to be sent on the send queue. Note that the
939  // queue may fire a drop trace, but we will too.
940  //
941  if (m_queue->Enqueue (packet) == false)
942  {
943  m_macTxDropTrace (packet);
944  return false;
945  }
946 
947  //
948  // If the device is idle, we need to start a transmission. Otherwise,
949  // the transmission will be started when the current packet finished
950  // transmission (see TransmitCompleteEvent)
951  //
952  if (m_txMachineState == READY)
953  {
954  if (m_queue->IsEmpty () == false)
955  {
956  m_currentPkt = m_queue->Dequeue ();
957  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
960  TransmitStart ();
961  }
962  }
963  return true;
964 }
965 
966 Ptr<Node>
968 {
970  return m_node;
971 }
972 
973 void
975 {
976  NS_LOG_FUNCTION (node);
977 
978  m_node = node;
979 }
980 
981 bool
983 {
985  return true;
986 }
987 
988 void
990 {
991  NS_LOG_FUNCTION (&cb);
992  m_rxCallback = cb;
993 }
994 
996 {
998 
999  NS_LOG_LOGIC ("MAC IPv6 multicast address is " << ad);
1000  return ad;
1001 }
1002 
1003 void
1005 {
1006  NS_LOG_FUNCTION (&cb);
1007  m_promiscRxCallback = cb;
1008 }
1009 
1010 bool
1012 {
1014  return true;
1015 }
1016 
1017 int64_t
1019 {
1020  return m_backoff.AssignStreams (stream);
1021 }
1022 
1023 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
keep track of time unit.
Definition: nstime.h:149
Ptr< Queue > m_queue
void ResetBackoffTime(void)
Definition: backoff.cc:78
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
TxMachineState m_txMachineState
void SetReceiveEnable(bool enable)
void SetEncapsulationMode(CsmaNetDevice::EncapsulationMode mode)
CsmaNetDevice::EncapsulationMode GetEncapsulationMode(void)
void TransmitReadyEvent(void)
void AddHeader(Ptr< Packet > p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
uint32_t m_maxSlots
Definition: backoff.h:47
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
void CalcFcs(Ptr< const Packet > p)
Updates the Fcs Field to the correct FCS.
void Receive(Ptr< Packet > p, Ptr< CsmaNetDevice > sender)
static bool ChecksumEnabled(void)
Definition: node.cc:267
TracedCallback< Ptr< const Packet > > m_macRxTrace
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
uint64_t GetUid(void) const
Definition: packet.cc:412
Ptr< Packet > m_currentPkt
#define NS_ASSERT(condition)
Definition: assert.h:64
void SetReceiveErrorModel(Ptr< ErrorModel > em)
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
uint32_t m_maxRetries
Definition: backoff.h:57
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
uint16_t GetLengthType(void) const
uint32_t GetSize(void) const
Definition: packet.h:620
bool IsBroadcast(void) const
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Definition: log.h:264
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
virtual Address GetBroadcast(void) const
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
void SetSource(Mac48Address source)
virtual void SetIfIndex(const uint32_t index)
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
virtual bool NeedsArp(void) const
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
a polymophic address class
Definition: address.h:86
bool MaxRetriesReached(void)
Definition: backoff.cc:84
double GetSeconds(void) const
Definition: nstime.h:262
TracedCallback m_linkChangeCallbacks
void AddAtEnd(Ptr< const Packet > packet)
Definition: packet.cc:334
double CalculateTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:229
TracedCallback< Ptr< const Packet > > m_macTxBackoffTrace
virtual bool IsLinkUp(void) const
void SetQueue(Ptr< Queue > queue)
TracedCallback< Ptr< const Packet > > m_snifferTrace
bool CheckFcs(Ptr< const Packet > p) const
static Mac48Address GetMulticast(Ipv4Address address)
void TransmitCompleteEvent(void)
bool IsReceiveEnabled(void)
virtual Ptr< Node > GetNode(void) const
Ptr< Queue > GetQueue(void) const
void SetInterframeGap(Time t)
virtual Address GetAddress(void) const
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
virtual uint32_t GetIfIndex(void) const
static Mac48Address ConvertFrom(const Address &address)
virtual uint16_t GetMtu(void) const
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
Packet trailer for Ethernet.
void EnableFcs(bool enable)
Enable or disable FCS checking and calculations.
bool IsGroup(void) const
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Ptr< ErrorModel > m_receiveErrorModel
void AddTrailer(const Trailer &trailer)
Definition: packet.cc:301
Ptr< CsmaChannel > m_channel
void RemoveAtEnd(uint32_t size)
Definition: packet.cc:363
uint32_t RemoveTrailer(Trailer &trailer)
Definition: packet.cc:317
an EUI-48 address
Definition: mac48-address.h:41
Packet header for Ethernet.
virtual Ptr< Channel > GetChannel(void) const
virtual bool IsBridge(void) const
int64_t AssignStreams(int64_t stream)
Definition: backoff.cc:96
virtual bool SetMtu(const uint16_t mtu)
virtual bool SupportsSendFrom(void) const
Time GetBackoffTime()
Definition: backoff.cc:51
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Mac48Address GetSource(void) const
Mac48Address m_address
Describes an IPv6 address.
Definition: ipv6-address.h:44
Mac48Address GetDestination(void) const
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
EncapsulationMode m_encapMode
NetDevice::ReceiveCallback m_rxCallback
void SetBackoffParams(Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t maxRetries, uint32_t ceiling)
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
void ConnectWithoutContext(const CallbackBase &callback)
TracedCallback< Ptr< const Packet > > m_macTxDropTrace
#define NS_LOG_WARN(msg)
Definition: log.h:246
void SetSendEnable(bool enable)
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
int64_t AssignStreams(int64_t stream)
uint32_t m_minSlots
Definition: backoff.h:42
void SetLengthType(uint16_t size)
NetDevice::PromiscReceiveCallback m_promiscRxCallback
virtual void SetAddress(Address address)
virtual void AddLinkChangeCallback(Callback< void > callback)
bool Attach(Ptr< CsmaChannel > ch)
virtual void SetNode(Ptr< Node > node)
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
void SetDestination(Mac48Address destination)
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
virtual bool IsMulticast(void) const
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
virtual void DoDispose(void)
virtual bool IsBroadcast(void) const
Time m_slotTime
Definition: backoff.h:62
void AddHeader(const Header &header)
Definition: packet.cc:270
Header for the LLC/SNAP encapsulation.
virtual bool IsPointToPoint(void) const
TracedCallback< Ptr< const Packet > > m_macTxTrace
void IncrNumRetries(void)
Definition: backoff.cc:90
uint32_t m_ceiling
Definition: backoff.h:52