A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
csma-net-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 Emmanuelle Laprise
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
18 */
19
20#include "csma-net-device.h"
21
22#include "csma-channel.h"
23
24#include "ns3/boolean.h"
25#include "ns3/enum.h"
26#include "ns3/error-model.h"
27#include "ns3/ethernet-header.h"
28#include "ns3/ethernet-trailer.h"
29#include "ns3/llc-snap-header.h"
30#include "ns3/log.h"
31#include "ns3/pointer.h"
32#include "ns3/queue.h"
33#include "ns3/simulator.h"
34#include "ns3/trace-source-accessor.h"
35#include "ns3/uinteger.h"
36
37namespace ns3
38{
39
40NS_LOG_COMPONENT_DEFINE("CsmaNetDevice");
41
42NS_OBJECT_ENSURE_REGISTERED(CsmaNetDevice);
43
44TypeId
46{
47 static TypeId tid =
48 TypeId("ns3::CsmaNetDevice")
50 .SetGroupName("Csma")
51 .AddConstructor<CsmaNetDevice>()
52 .AddAttribute("Address",
53 "The MAC address of this device.",
54 Mac48AddressValue(Mac48Address("ff:ff:ff:ff:ff:ff")),
55 MakeMac48AddressAccessor(&CsmaNetDevice::m_address),
56 MakeMac48AddressChecker())
57 .AddAttribute("Mtu",
58 "The MAC-level Maximum Transmission Unit",
61 MakeUintegerChecker<uint16_t>())
62 .AddAttribute("EncapsulationMode",
63 "The link-layer encapsulation type to use.",
66 MakeEnumChecker(DIX, "Dix", LLC, "Llc"))
67 .AddAttribute("SendEnable",
68 "Enable or disable the transmitter section of the device.",
69 BooleanValue(true),
72 .AddAttribute("ReceiveEnable",
73 "Enable or disable the receiver section of the device.",
74 BooleanValue(true),
77 .AddAttribute("ReceiveErrorModel",
78 "The receiver error model used to simulate packet loss",
81 MakePointerChecker<ErrorModel>())
82
83 //
84 // Transmit queueing discipline for the device which includes its own set
85 // of trace hooks.
86 //
87 .AddAttribute("TxQueue",
88 "A queue to use as the transmit queue in the device.",
91 MakePointerChecker<Queue<Packet>>())
92
93 //
94 // Trace sources at the "top" of the net device, where packets transition
95 // to/from higher layers.
96 //
97 .AddTraceSource("MacTx",
98 "Trace source indicating a packet has "
99 "arrived for transmission by this device",
101 "ns3::Packet::TracedCallback")
102 .AddTraceSource("MacTxDrop",
103 "Trace source indicating a packet has been "
104 "dropped by the device before transmission",
106 "ns3::Packet::TracedCallback")
107 .AddTraceSource("MacPromiscRx",
108 "A packet has been received by this device, "
109 "has been passed up from the physical layer "
110 "and is being forwarded up the local protocol stack. "
111 "This is a promiscuous trace,",
113 "ns3::Packet::TracedCallback")
114 .AddTraceSource("MacRx",
115 "A packet has been received by this device, "
116 "has been passed up from the physical layer "
117 "and is being forwarded up the local protocol stack. "
118 "This is a non-promiscuous trace,",
120 "ns3::Packet::TracedCallback")
121#if 0
122 // Not currently implemented in this device
123 .AddTraceSource ("MacRxDrop",
124 "Trace source indicating a packet was received, "
125 "but dropped before being forwarded up the stack",
127 "ns3::Packet::TracedCallback")
128#endif
129 .AddTraceSource("MacTxBackoff",
130 "Trace source indicating a packet has been "
131 "delayed by the CSMA backoff process",
133 "ns3::Packet::TracedCallback")
134 //
135 // Trace sources at the "bottom" of the net device, where packets transition
136 // to/from the channel.
137 //
138 .AddTraceSource("PhyTxBegin",
139 "Trace source indicating a packet has "
140 "begun transmitting over the channel",
142 "ns3::Packet::TracedCallback")
143 .AddTraceSource("PhyTxEnd",
144 "Trace source indicating a packet has been "
145 "completely transmitted over the channel",
147 "ns3::Packet::TracedCallback")
148 .AddTraceSource("PhyTxDrop",
149 "Trace source indicating a packet has been "
150 "dropped by the device during transmission",
152 "ns3::Packet::TracedCallback")
153#if 0
154 // Not currently implemented in this device
155 .AddTraceSource ("PhyRxBegin",
156 "Trace source indicating a packet has "
157 "begun being received by the device",
159 "ns3::Packet::TracedCallback")
160#endif
161 .AddTraceSource("PhyRxEnd",
162 "Trace source indicating a packet has been "
163 "completely received by the device",
165 "ns3::Packet::TracedCallback")
166 .AddTraceSource("PhyRxDrop",
167 "Trace source indicating a packet has been "
168 "dropped by the device during reception",
170 "ns3::Packet::TracedCallback")
171 //
172 // Trace sources designed to simulate a packet sniffer facility (tcpdump).
173 //
174 .AddTraceSource("Sniffer",
175 "Trace source simulating a non-promiscuous "
176 "packet sniffer attached to the device",
178 "ns3::Packet::TracedCallback")
179 .AddTraceSource("PromiscSniffer",
180 "Trace source simulating a promiscuous "
181 "packet sniffer attached to the device",
183 "ns3::Packet::TracedCallback");
184 return tid;
185}
186
188 : m_linkUp(false)
189{
190 NS_LOG_FUNCTION(this);
193 m_channel = nullptr;
194
195 //
196 // We would like to let the attribute system take care of initializing the
197 // packet encapsulation stuff, but we also don't want to get caught up in
198 // initialization order changes. So we'll get the three problem variables
199 // into a consistent state here before the attribute calls, and then depend
200 // on the semantics of the setters to preserve a consistent state. This
201 // really doesn't have to be the same set of values as the initial values
202 // set by the attributes, but it does have to be a consistent set. That is,
203 // you can just change the default encapsulation mode above without having
204 // to change it here.
205 //
207}
208
210{
212 m_queue = nullptr;
213}
214
215void
217{
219 m_channel = nullptr;
220 m_node = nullptr;
221 m_queue = nullptr;
223}
224
225void
227{
228 NS_LOG_FUNCTION(mode);
229
230 m_encapMode = mode;
231
232 NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
233 NS_LOG_LOGIC("m_mtu = " << m_mtu);
234}
235
238{
240 return m_encapMode;
241}
242
243bool
245{
246 NS_LOG_FUNCTION(this << mtu);
247 m_mtu = mtu;
248
249 NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
250 NS_LOG_LOGIC("m_mtu = " << m_mtu);
251
252 return true;
253}
254
255uint16_t
257{
259 return m_mtu;
260}
261
262void
264{
265 NS_LOG_FUNCTION(sendEnable);
266 m_sendEnable = sendEnable;
267}
268
269void
271{
272 NS_LOG_FUNCTION(receiveEnable);
273 m_receiveEnable = receiveEnable;
274}
275
276bool
278{
280 return m_sendEnable;
281}
282
283bool
285{
287 return m_receiveEnable;
288}
289
290void
292{
295}
296
297void
299 uint32_t minSlots,
300 uint32_t maxSlots,
301 uint32_t ceiling,
302 uint32_t maxRetries)
303{
304 NS_LOG_FUNCTION(slotTime << minSlots << maxSlots << ceiling << maxRetries);
305 m_backoff.m_slotTime = slotTime;
306 m_backoff.m_minSlots = minSlots;
307 m_backoff.m_maxSlots = maxSlots;
308 m_backoff.m_ceiling = ceiling;
309 m_backoff.m_maxRetries = maxRetries;
310}
311
312void
314 Mac48Address source,
315 Mac48Address dest,
316 uint16_t protocolNumber)
317{
318 NS_LOG_FUNCTION(p << source << dest << protocolNumber);
319
320 EthernetHeader header(false);
321 header.SetSource(source);
322 header.SetDestination(dest);
323
324 EthernetTrailer trailer;
325
326 NS_LOG_LOGIC("p->GetSize () = " << p->GetSize());
327 NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
328 NS_LOG_LOGIC("m_mtu = " << m_mtu);
329
330 uint16_t lengthType = 0;
331 switch (m_encapMode)
332 {
333 case DIX:
334 NS_LOG_LOGIC("Encapsulating packet as DIX (type interpretation)");
335 //
336 // This corresponds to the type interpretation of the lengthType field as
337 // in the old Ethernet Blue Book.
338 //
339 lengthType = protocolNumber;
340
341 //
342 // All Ethernet frames must carry a minimum payload of 46 bytes. We need
343 // to pad out if we don't have enough bytes. These must be real bytes
344 // since they will be written to pcap files and compared in regression
345 // trace files.
346 //
347 if (p->GetSize() < 46)
348 {
349 uint8_t buffer[46];
350 memset(buffer, 0, 46);
351 Ptr<Packet> padd = Create<Packet>(buffer, 46 - p->GetSize());
352 p->AddAtEnd(padd);
353 }
354 break;
355 case LLC: {
356 NS_LOG_LOGIC("Encapsulating packet as LLC (length interpretation)");
357
358 LlcSnapHeader llc;
359 llc.SetType(protocolNumber);
360 p->AddHeader(llc);
361
362 //
363 // This corresponds to the length interpretation of the lengthType
364 // field but with an LLC/SNAP header added to the payload as in
365 // IEEE 802.2
366 //
367 lengthType = p->GetSize();
368
369 //
370 // All Ethernet frames must carry a minimum payload of 46 bytes. The
371 // LLC SNAP header counts as part of this payload. We need to pad out
372 // if we don't have enough bytes. These must be real bytes since they
373 // will be written to pcap files and compared in regression trace files.
374 //
375 if (p->GetSize() < 46)
376 {
377 uint8_t buffer[46];
378 memset(buffer, 0, 46);
379 Ptr<Packet> padd = Create<Packet>(buffer, 46 - p->GetSize());
380 p->AddAtEnd(padd);
381 }
382
383 NS_ASSERT_MSG(p->GetSize() <= GetMtu(),
384 "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
385 "length interpretation must not exceed device frame size minus overhead");
386 }
387 break;
388 case ILLEGAL:
389 default:
390 NS_FATAL_ERROR("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
391 break;
392 }
393
394 NS_LOG_LOGIC("header.SetLengthType (" << lengthType << ")");
395 header.SetLengthType(lengthType);
396 p->AddHeader(header);
397
399 {
400 trailer.EnableFcs(true);
401 }
402 trailer.CalcFcs(p);
403 p->AddTrailer(trailer);
404}
405
406#if 0
407bool
408CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
409{
410 NS_LOG_FUNCTION (p << param);
411
412 EthernetTrailer trailer;
413 p->RemoveTrailer (trailer);
414
415 EthernetHeader header (false);
416 p->RemoveHeader (header);
417
418 if ((header.GetDestination () != GetBroadcast ()) &&
419 (header.GetDestination () != GetAddress ()))
420 {
421 return false;
422 }
423
424 switch (m_encapMode)
425 {
426 case DIX:
427 param = header.GetLengthType ();
428 break;
429 case LLC:
430 {
431 LlcSnapHeader llc;
432 p->RemoveHeader (llc);
433 param = llc.GetType ();
434 }
435 break;
436 case ILLEGAL:
437 default:
438 NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
439 break;
440 }
441 return true;
442}
443#endif
444
445void
447{
449
450 //
451 // This function is called to start the process of transmitting a packet. We
452 // expect that the packet to transmit will be found in m_currentPkt.
453 //
454 NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
455
456 NS_LOG_LOGIC("m_currentPkt = " << m_currentPkt);
457 NS_LOG_LOGIC("UID = " << m_currentPkt->GetUid());
458
459 //
460 // Only transmit if the send side of net device is enabled
461 //
462 if (!IsSendEnabled())
463 {
465 m_currentPkt = nullptr;
466 return;
467 }
468
469 //
470 // Somebody has called here telling us to start transmitting a packet. They
471 // can only do this if the state machine is in the READY or BACKOFF state.
472 // Specifically, if we are ready to start transmitting, we cannot already
473 // be transmitting (i.e., BUSY)
474 //
476 "Must be READY to transmit. Tx state is: " << m_txMachineState);
477
478 //
479 // Now we have to sense the state of the medium and either start transmitting
480 // if it is idle, or backoff our transmission if someone else is on the wire.
481 //
482 if (m_channel->GetState() != IDLE)
483 {
484 //
485 // The channel is busy -- backoff and rechedule TransmitStart() unless
486 // we have exhausted all of our retries.
487 //
489
491 {
492 //
493 // Too many retries, abort transmission of packet
494 //
496 }
497 else
498 {
500
502 Time backoffTime = m_backoff.GetBackoffTime();
503
504 NS_LOG_LOGIC("Channel busy, backing off for " << backoffTime.As(Time::S));
505
507 }
508 }
509 else
510 {
511 //
512 // The channel is free, transmit the packet
513 //
515 if (!m_channel->TransmitStart(m_currentPkt, m_deviceId))
516 {
517 NS_LOG_WARN("Channel TransmitStart returns an error");
519 m_currentPkt = nullptr;
521 }
522 else
523 {
524 //
525 // Transmission succeeded, reset the backoff time parameters and
526 // schedule a transmit complete event.
527 //
530
532 NS_LOG_LOGIC("Schedule TransmitCompleteEvent in " << tEvent.As(Time::S));
534 }
535 }
536}
537
538void
540{
542
543 //
544 // When we started the process of transmitting the current packet, it was
545 // placed in m_currentPkt. So we had better find one there.
546 //
547 NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
548 NS_LOG_LOGIC("m_currentPkt=" << m_currentPkt);
549 NS_LOG_LOGIC("Pkt UID is " << m_currentPkt->GetUid() << ")");
550
552 m_currentPkt = nullptr;
553
555 "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
556
557 //
558 // We're done with that one, so reset the backoff algorithm and ready the
559 // transmit state machine.
560 //
563
564 //
565 // If there is another packet on the input queue, we need to start trying to
566 // get that out. If the queue is empty we just wait until someone puts one
567 // in.
568 //
569 if (m_queue->IsEmpty())
570 {
571 return;
572 }
573 else
574 {
575 Ptr<Packet> packet = m_queue->Dequeue();
576 NS_ASSERT_MSG(packet,
577 "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
578 m_currentPkt = packet;
582 }
583}
584
585void
587{
589
590 //
591 // This function is called to finish the process of transmitting a packet.
592 // We need to tell the channel that we've stopped wiggling the wire and
593 // schedule an event that will be executed when it's time to re-enable
594 // the transmitter after the interframe gap.
595 //
597 "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
598 NS_ASSERT(m_channel->GetState() == TRANSMITTING);
600
601 //
602 // When we started transmitting the current packet, it was placed in
603 // m_currentPkt. So we had better find one there.
604 //
605 NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
606 NS_LOG_LOGIC("m_currentPkt=" << m_currentPkt);
607 NS_LOG_LOGIC("Pkt UID is " << m_currentPkt->GetUid() << ")");
608
609 m_channel->TransmitEnd();
611 m_currentPkt = nullptr;
612
613 NS_LOG_LOGIC("Schedule TransmitReadyEvent in " << m_tInterframeGap.As(Time::S));
614
616}
617
618void
620{
622
623 //
624 // This function is called to enable the transmitter after the interframe
625 // gap has passed. If there are pending transmissions, we use this opportunity
626 // to start the next transmit.
627 //
629 "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
631
632 //
633 // We expect that the packet we had been transmitting was cleared when the
634 // TransmitCompleteEvent() was executed.
635 //
636 NS_ASSERT_MSG(!m_currentPkt, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
637
638 //
639 // Get the next packet from the queue for transmitting
640 //
641 if (m_queue->IsEmpty())
642 {
643 return;
644 }
645 else
646 {
647 Ptr<Packet> packet = m_queue->Dequeue();
648 NS_ASSERT_MSG(packet,
649 "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
650 m_currentPkt = packet;
654 }
655}
656
657bool
659{
660 NS_LOG_FUNCTION(this << &ch);
661
662 m_channel = ch;
663
664 m_deviceId = m_channel->Attach(this);
665
666 //
667 // The channel provides us with the transmitter data rate.
668 //
669 m_bps = m_channel->GetDataRate();
670
671 //
672 // We use the Ethernet interframe gap of 96 bit times.
673 //
675
676 //
677 // This device is up whenever a channel is attached to it.
678 //
679 NotifyLinkUp();
680 return true;
681}
682
683void
685{
687 m_queue = q;
688}
689
690void
692{
693 NS_LOG_FUNCTION(em);
695}
696
697void
699{
700 NS_LOG_FUNCTION(packet << senderDevice);
701 NS_LOG_LOGIC("UID is " << packet->GetUid());
702
703 //
704 // We never forward up packets that we sent. Real devices don't do this since
705 // their receivers are disabled during send, so we don't.
706 //
707 if (senderDevice == this)
708 {
709 return;
710 }
711
712 //
713 // Hit the trace hook. This trace will fire on all packets received from the
714 // channel except those originated by this device.
715 //
716 m_phyRxEndTrace(packet);
717
718 //
719 // Only receive if the send side of net device is enabled
720 //
721 if (!IsReceiveEnabled())
722 {
723 m_phyRxDropTrace(packet);
724 return;
725 }
726
727 if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt(packet))
728 {
729 NS_LOG_LOGIC("Dropping pkt due to error model ");
730 m_phyRxDropTrace(packet);
731 return;
732 }
733
734 //
735 // Trace sinks will expect complete packets, not packets without some of the
736 // headers.
737 //
738 Ptr<Packet> originalPacket = packet->Copy();
739
740 EthernetTrailer trailer;
741 packet->RemoveTrailer(trailer);
743 {
744 trailer.EnableFcs(true);
745 }
746
747 bool crcGood = trailer.CheckFcs(packet);
748 if (!crcGood)
749 {
750 NS_LOG_INFO("CRC error on Packet " << packet);
751 m_phyRxDropTrace(packet);
752 return;
753 }
754
755 EthernetHeader header(false);
756 packet->RemoveHeader(header);
757
758 NS_LOG_LOGIC("Pkt source is " << header.GetSource());
759 NS_LOG_LOGIC("Pkt destination is " << header.GetDestination());
760
761 uint16_t protocol;
762 //
763 // If the length/type is less than 1500, it corresponds to a length
764 // interpretation packet. In this case, it is an 802.3 packet and
765 // will also have an 802.2 LLC header. If greater than 1500, we
766 // find the protocol number (Ethernet type) directly.
767 //
768 if (header.GetLengthType() <= 1500)
769 {
770 NS_ASSERT(packet->GetSize() >= header.GetLengthType());
771 uint32_t padlen = packet->GetSize() - header.GetLengthType();
772 NS_ASSERT(padlen <= 46);
773 if (padlen > 0)
774 {
775 packet->RemoveAtEnd(padlen);
776 }
777
778 LlcSnapHeader llc;
779 packet->RemoveHeader(llc);
780 protocol = llc.GetType();
781 }
782 else
783 {
784 protocol = header.GetLengthType();
785 }
786
787 //
788 // Classify the packet based on its destination.
789 //
790 PacketType packetType;
791
792 if (header.GetDestination().IsBroadcast())
793 {
794 packetType = PACKET_BROADCAST;
795 }
796 else if (header.GetDestination().IsGroup())
797 {
798 packetType = PACKET_MULTICAST;
799 }
800 else if (header.GetDestination() == m_address)
801 {
802 packetType = PACKET_HOST;
803 }
804 else
805 {
806 packetType = PACKET_OTHERHOST;
807 }
808
809 //
810 // For all kinds of packetType we receive, we hit the promiscuous sniffer
811 // hook and pass a copy up to the promiscuous callback. Pass a copy to
812 // make sure that nobody messes with our packet.
813 //
814 m_promiscSnifferTrace(originalPacket);
816 {
817 m_macPromiscRxTrace(originalPacket);
819 packet,
820 protocol,
821 header.GetSource(),
822 header.GetDestination(),
823 packetType);
824 }
825
826 //
827 // If this packet is not destined for some other host, it must be for us
828 // as either a broadcast, multicast or unicast. We need to hit the mac
829 // packet received trace hook and forward the packet up the stack.
830 //
831 if (packetType != PACKET_OTHERHOST)
832 {
833 m_snifferTrace(originalPacket);
834 m_macRxTrace(originalPacket);
835 m_rxCallback(this, packet, protocol, header.GetSource());
836 }
837}
838
841{
843 return m_queue;
844}
845
846void
848{
850 m_linkUp = true;
852}
853
854void
856{
857 NS_LOG_FUNCTION(index);
858 m_ifIndex = index;
859}
860
863{
865 return m_ifIndex;
866}
867
870{
872 return m_channel;
873}
874
875void
877{
880}
881
884{
886 return m_address;
887}
888
889bool
891{
893 return m_linkUp;
894}
895
896void
898{
899 NS_LOG_FUNCTION(&callback);
901}
902
903bool
905{
907 return true;
908}
909
912{
914 return Mac48Address("ff:ff:ff:ff:ff:ff");
915}
916
917bool
919{
921 return true;
922}
923
926{
927 NS_LOG_FUNCTION(multicastGroup);
928
929 Mac48Address ad = Mac48Address::GetMulticast(multicastGroup);
930
931 //
932 // Implicit conversion (operator Address ()) is defined for Mac48Address, so
933 // use it by just returning the EUI-48 address which is automagically converted
934 // to an Address.
935 //
936 NS_LOG_LOGIC("multicast address is " << ad);
937
938 return ad;
939}
940
941bool
943{
945 return false;
946}
947
948bool
950{
952 return false;
953}
954
955bool
956CsmaNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
957{
958 NS_LOG_FUNCTION(packet << dest << protocolNumber);
959 return SendFrom(packet, m_address, dest, protocolNumber);
960}
961
962bool
964 const Address& src,
965 const Address& dest,
966 uint16_t protocolNumber)
967{
968 NS_LOG_FUNCTION(packet << src << dest << protocolNumber);
969 NS_LOG_LOGIC("packet =" << packet);
970 NS_LOG_LOGIC("UID is " << packet->GetUid() << ")");
971
973
974 //
975 // Only transmit if send side of net device is enabled
976 //
977 if (!IsSendEnabled())
978 {
979 m_macTxDropTrace(packet);
980 return false;
981 }
982
983 Mac48Address destination = Mac48Address::ConvertFrom(dest);
985 AddHeader(packet, source, destination, protocolNumber);
986
987 m_macTxTrace(packet);
988
989 //
990 // Place the packet to be sent on the send queue. Note that the
991 // queue may fire a drop trace, but we will too.
992 //
993 if (!m_queue->Enqueue(packet))
994 {
995 m_macTxDropTrace(packet);
996 return false;
997 }
998
999 //
1000 // If the device is idle, we need to start a transmission. Otherwise,
1001 // the transmission will be started when the current packet finished
1002 // transmission (see TransmitCompleteEvent)
1003 //
1004 if (m_txMachineState == READY)
1005 {
1006 if (!m_queue->IsEmpty())
1007 {
1008 Ptr<Packet> packet = m_queue->Dequeue();
1009 NS_ASSERT_MSG(packet,
1010 "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
1011 m_currentPkt = packet;
1014 TransmitStart();
1015 }
1016 }
1017 return true;
1018}
1019
1022{
1024 return m_node;
1025}
1026
1027void
1029{
1030 NS_LOG_FUNCTION(node);
1031
1032 m_node = node;
1033}
1034
1035bool
1037{
1039 return true;
1040}
1041
1042void
1044{
1045 NS_LOG_FUNCTION(&cb);
1046 m_rxCallback = cb;
1047}
1048
1049Address
1051{
1053
1054 NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
1055 return ad;
1056}
1057
1058void
1060{
1061 NS_LOG_FUNCTION(&cb);
1063}
1064
1065bool
1067{
1069 return true;
1070}
1071
1072int64_t
1074{
1075 return m_backoff.AssignStreams(stream);
1076}
1077
1078} // namespace ns3
a polymophic address class
Definition: address.h:100
void ResetBackoffTime()
Indicates to the backoff object that the last packet was successfully transmitted and that the number...
Definition: backoff.cc:85
uint32_t m_maxRetries
Maximum number of transmission retries before the packet is dropped.
Definition: backoff.h:61
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: backoff.cc:103
uint32_t m_maxSlots
Maximum number of backoff slots (when multiplied by m_slotTime, determines maximum backoff time)
Definition: backoff.h:51
bool MaxRetriesReached() const
Definition: backoff.cc:91
void IncrNumRetries()
Increments the number of retries by 1.
Definition: backoff.cc:97
uint32_t m_minSlots
Minimum number of backoff slots (when multiplied by m_slotTime, determines minimum backoff time)
Definition: backoff.h:45
Time GetBackoffTime()
Definition: backoff.cc:58
uint32_t m_ceiling
Caps the exponential function when the number of retries reaches m_ceiling.
Definition: backoff.h:56
Time m_slotTime
Length of one slot.
Definition: backoff.h:67
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:438
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
A Device for a Csma Network Link.
void SetInterframeGap(Time t)
Set the interframe gap used to separate packets.
Ptr< Queue< Packet > > GetQueue() const
Get a copy of the attached Queue.
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but dropped before being forwa...
Ptr< Node > GetNode() const override
Get the node to which this device is attached.
EncapsulationMode
Enumeration of the types of packets supported in the class.
@ ILLEGAL
Encapsulation mode not set.
@ DIX
DIX II / Ethernet II packet.
@ LLC
802.2 LLC/SNAP Packet
NetDevice::ReceiveCallback m_rxCallback
The callback used to notify higher layers that a packet has been received.
TracedCallback< Ptr< const Packet > > m_macTxBackoffTrace
The trace source fired when the mac layer is forced to begin the backoff process for a packet.
void SetReceiveEnable(bool enable)
Enable or disable the receive side of the network device.
Backoff m_backoff
Holds the backoff parameters and is used to calculate the next backoff time to use when the channel i...
DataRate m_bps
The data rate that the Net Device uses to simulate packet transmission timing.
void DoDispose() override
Perform any object release functionality required to break reference cycles in reference counted obje...
~CsmaNetDevice() override
Destroy a CsmaNetDevice.
bool SetMtu(const uint16_t mtu) override
void TransmitAbort()
Aborts the transmission of the current packet.
EncapsulationMode m_encapMode
The type of packet that should be created by the AddHeader function and that should be processed by t...
bool NeedsArp() const override
Does this device need to use the address resolution protocol?
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
void TransmitStart()
Start Sending a Packet Down the Wire.
void SetIfIndex(const uint32_t index) override
@ BACKOFF
The transmitter is waiting for the channel to be free.
@ READY
The transmitter is ready to begin transmission of a packet.
@ BUSY
The transmitter is busy transmitting a packet.
@ GAP
The transmitter is in the interframe gap time.
Ptr< Queue< Packet > > m_queue
The Queue which this CsmaNetDevice uses as a packet source.
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
uint32_t m_mtu
The Maximum Transmission Unit.
bool SupportsSendFrom() const override
NetDevice::PromiscReceiveCallback m_promiscRxCallback
The callback used to notify higher layers that a packet has been received in promiscuous mode.
CsmaNetDevice()
Construct a CsmaNetDevice.
void SetPromiscReceiveCallback(PromiscReceiveCallback cb) override
Address GetBroadcast() const override
static TypeId GetTypeId()
Get the type ID.
bool IsPointToPoint() const override
Is this a point to point link?
Ptr< CsmaChannel > m_channel
The CsmaChannel to which this CsmaNetDevice has been attached.
bool Attach(Ptr< CsmaChannel > ch)
Attach the device to a channel.
bool IsBridge() const override
Is this a bridge?
void TransmitCompleteEvent()
Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
Start sending a packet down the channel, with MAC spoofing.
void Receive(Ptr< Packet > p, Ptr< CsmaNetDevice > sender)
Receive a packet from a connected CsmaChannel.
bool IsMulticast() const override
TracedCallback m_linkChangeCallbacks
List of callbacks to fire if the link changes state (up or down).
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
CsmaNetDevice::EncapsulationMode GetEncapsulationMode()
Get the encapsulation mode of this device.
void AddHeader(Ptr< Packet > p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
Adds the necessary headers and trailers to a packet of data in order to respect the packet type.
uint16_t GetMtu() const override
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< Channel > GetChannel() const override
void NotifyLinkUp()
Notify any interested parties that the link has come up.
void SetBackoffParams(Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t maxRetries, uint32_t ceiling)
Set the backoff parameters used to determine the wait to retry transmitting a packet when the channel...
Ptr< Packet > m_currentPkt
Next packet that will be transmitted (if transmitter is not currently transmitting) or packet that is...
TracedCallback< Ptr< const Packet > > m_snifferTrace
A trace source that emulates a non-promiscuous protocol sniffer connected to the device.
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
uint32_t m_deviceId
Device ID returned by the attached functions.
bool m_receiveEnable
Enable net device to receive packets.
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
Ptr< Node > m_node
The Node to which this device is attached.
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the CsmaNetDevice.
void SetSendEnable(bool enable)
Enable or disable the send side of the network device.
bool IsLinkUp() const override
void TransmitReadyEvent()
Cause the Transmitter to Become Ready to Send Another Packet.
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device.
uint32_t GetIfIndex() const override
bool IsBroadcast() const override
static const uint16_t DEFAULT_MTU
Default Maximum Transmission Unit (MTU) for the CsmaNetDevice.
void SetEncapsulationMode(CsmaNetDevice::EncapsulationMode mode)
Set the encapsulation mode of this device.
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
bool m_sendEnable
Enable net device to send packets.
TracedCallback< Ptr< const Packet > > m_macTxDropTrace
The trace source fired when packets coming into the "top" of the device at the L3/L2 transition are d...
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
Start sending a packet down the channel.
bool IsSendEnabled() const
Is the send side of the network device enabled?
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition,...
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
Set the callback to be used to notify higher layers when a packet has been received.
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet as it tries to transmit it.
Address GetAddress() const override
void AddLinkChangeCallback(Callback< void > callback) override
void SetNode(Ptr< Node > node) override
Set the node to which this device is being attached.
void SetAddress(Address address) override
Set the address of this interface.
Mac48Address m_address
The MAC address which has been assigned to this device.
Time m_tInterframeGap
The interframe gap that the Net Device uses insert time between packet transmission.
void SetQueue(Ptr< Queue< Packet > > queue)
Attach a queue to the CsmaNetDevice.
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
TxMachineState m_txMachineState
The state of the Net Device transmit state machine.
uint32_t m_ifIndex
The interface index (really net evice index) that has been assigned to this network device.
bool IsReceiveEnabled() const
Is the receive side of the network device enabled?
bool m_linkUp
Flag indicating whether or not the link is up.
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:291
Hold variables of type enum.
Definition: enum.h:56
Packet header for Ethernet.
uint16_t GetLengthType() const
void SetDestination(Mac48Address destination)
Mac48Address GetDestination() const
void SetLengthType(uint16_t size)
void SetSource(Mac48Address source)
Mac48Address GetSource() const
Packet trailer for Ethernet.
bool CheckFcs(Ptr< const Packet > p) const
Calculate an FCS on the provided packet and check this value against the FCS found when the trailer w...
void EnableFcs(bool enable)
Enable or disable FCS checking and calculations.
void CalcFcs(Ptr< const Packet > p)
Updates the Fcs Field to the correct FCS.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Describes an IPv6 address.
Definition: ipv6-address.h:49
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
void SetType(uint16_t type)
Set the Ethertype.
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
static Mac48Address ConvertFrom(const Address &address)
bool IsBroadcast() const
AttributeValue implementation for Mac48Address.
Network layer to device interface.
Definition: net-device.h:98
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition: net-device.h:307
@ PACKET_BROADCAST
Packet addressed to all.
Definition: net-device.h:303
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition: net-device.h:305
static bool ChecksumEnabled()
Definition: node.cc:290
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Template class for packet Queues.
Definition: queue.h:267
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
@ S
second
Definition: nstime.h:116
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:205
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:163
@ TRANSMITTING
Channel is BUSY, a packet is being written by a net device.
Definition: csma-channel.h:77
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:76