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")),
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.",
65 MakeEnumAccessor<EncapsulationMode>(&CsmaNetDevice::SetEncapsulationMode),
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 Ptr<Packet> pktCopy = packet->Copy();
728
729 if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt(pktCopy))
730 {
731 NS_LOG_LOGIC("Dropping pkt due to error model ");
732 m_phyRxDropTrace(packet);
733 return;
734 }
735
736 //
737 // Trace sinks will expect complete packets, not packets without some of the
738 // headers.
739 //
740
741 EthernetTrailer trailer;
742 pktCopy->RemoveTrailer(trailer);
744 {
745 trailer.EnableFcs(true);
746 }
747
748 bool crcGood = trailer.CheckFcs(pktCopy);
749 if (!crcGood)
750 {
751 NS_LOG_INFO("CRC error on Packet " << packet);
752 m_phyRxDropTrace(packet);
753 return;
754 }
755
756 EthernetHeader header(false);
757 pktCopy->RemoveHeader(header);
758
759 NS_LOG_LOGIC("Pkt source is " << header.GetSource());
760 NS_LOG_LOGIC("Pkt destination is " << header.GetDestination());
761
762 uint16_t protocol;
763 //
764 // If the length/type is less than 1500, it corresponds to a length
765 // interpretation packet. In this case, it is an 802.3 packet and
766 // will also have an 802.2 LLC header. If greater than 1500, we
767 // find the protocol number (Ethernet type) directly.
768 //
769 if (header.GetLengthType() <= 1500)
770 {
771 NS_ASSERT(pktCopy->GetSize() >= header.GetLengthType());
772 uint32_t padlen = pktCopy->GetSize() - header.GetLengthType();
773 NS_ASSERT(padlen <= 46);
774 if (padlen > 0)
775 {
776 pktCopy->RemoveAtEnd(padlen);
777 }
778
779 LlcSnapHeader llc;
780 pktCopy->RemoveHeader(llc);
781 protocol = llc.GetType();
782 }
783 else
784 {
785 protocol = header.GetLengthType();
786 }
787
788 //
789 // Classify the packet based on its destination.
790 //
791 PacketType packetType;
792
793 if (header.GetDestination().IsBroadcast())
794 {
795 packetType = PACKET_BROADCAST;
796 }
797 else if (header.GetDestination().IsGroup())
798 {
799 packetType = PACKET_MULTICAST;
800 }
801 else if (header.GetDestination() == m_address)
802 {
803 packetType = PACKET_HOST;
804 }
805 else
806 {
807 packetType = PACKET_OTHERHOST;
808 }
809
810 //
811 // For all kinds of packetType we receive, we hit the promiscuous sniffer
812 // hook and pass a copy up to the promiscuous callback. Pass a copy to
813 // make sure that nobody messes with our packet.
814 //
815 m_promiscSnifferTrace(packet);
817 {
818 m_macPromiscRxTrace(packet);
820 pktCopy,
821 protocol,
822 header.GetSource(),
823 header.GetDestination(),
824 packetType);
825 }
826
827 //
828 // If this packet is not destined for some other host, it must be for us
829 // as either a broadcast, multicast or unicast. We need to hit the mac
830 // packet received trace hook and forward the packet up the stack.
831 //
832 if (packetType != PACKET_OTHERHOST)
833 {
834 m_snifferTrace(packet);
835 m_macRxTrace(packet);
836 m_rxCallback(this, pktCopy, protocol, header.GetSource());
837 }
838}
839
842{
844 return m_queue;
845}
846
847void
849{
851 m_linkUp = true;
853}
854
855void
857{
858 NS_LOG_FUNCTION(index);
859 m_ifIndex = index;
860}
861
864{
866 return m_ifIndex;
867}
868
871{
873 return m_channel;
874}
875
876void
878{
881}
882
885{
887 return m_address;
888}
889
890bool
892{
894 return m_linkUp;
895}
896
897void
899{
900 NS_LOG_FUNCTION(&callback);
902}
903
904bool
906{
908 return true;
909}
910
913{
916}
917
918bool
920{
922 return true;
923}
924
927{
928 NS_LOG_FUNCTION(multicastGroup);
929
930 Mac48Address ad = Mac48Address::GetMulticast(multicastGroup);
931
932 //
933 // Implicit conversion (operator Address ()) is defined for Mac48Address, so
934 // use it by just returning the EUI-48 address which is automagically converted
935 // to an Address.
936 //
937 NS_LOG_LOGIC("multicast address is " << ad);
938
939 return ad;
940}
941
942bool
944{
946 return false;
947}
948
949bool
951{
953 return false;
954}
955
956bool
957CsmaNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
958{
959 NS_LOG_FUNCTION(packet << dest << protocolNumber);
960 return SendFrom(packet, m_address, dest, protocolNumber);
961}
962
963bool
965 const Address& src,
966 const Address& dest,
967 uint16_t protocolNumber)
968{
969 NS_LOG_FUNCTION(packet << src << dest << protocolNumber);
970 NS_LOG_LOGIC("packet =" << packet);
971 NS_LOG_LOGIC("UID is " << packet->GetUid() << ")");
972
974
975 //
976 // Only transmit if send side of net device is enabled
977 //
978 if (!IsSendEnabled())
979 {
980 m_macTxDropTrace(packet);
981 return false;
982 }
983
984 Mac48Address destination = Mac48Address::ConvertFrom(dest);
986 AddHeader(packet, source, destination, protocolNumber);
987
988 m_macTxTrace(packet);
989
990 //
991 // Place the packet to be sent on the send queue. Note that the
992 // queue may fire a drop trace, but we will too.
993 //
994 if (!m_queue->Enqueue(packet))
995 {
996 m_macTxDropTrace(packet);
997 return false;
998 }
999
1000 //
1001 // If the device is idle, we need to start a transmission. Otherwise,
1002 // the transmission will be started when the current packet finished
1003 // transmission (see TransmitCompleteEvent)
1004 //
1005 if (m_txMachineState == READY)
1006 {
1007 if (!m_queue->IsEmpty())
1008 {
1009 Ptr<Packet> packet = m_queue->Dequeue();
1010 NS_ASSERT_MSG(packet,
1011 "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
1012 m_currentPkt = packet;
1015 TransmitStart();
1016 }
1017 }
1018 return true;
1019}
1020
1023{
1025 return m_node;
1026}
1027
1028void
1030{
1031 NS_LOG_FUNCTION(node);
1032
1033 m_node = node;
1034}
1035
1036bool
1038{
1040 return true;
1041}
1042
1043void
1045{
1046 NS_LOG_FUNCTION(&cb);
1047 m_rxCallback = cb;
1048}
1049
1050Address
1052{
1054
1055 NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
1056 return ad;
1057}
1058
1059void
1061{
1062 NS_LOG_FUNCTION(&cb);
1064}
1065
1066bool
1068{
1070 return true;
1071}
1072
1073int64_t
1075{
1076 return m_backoff.AssignStreams(stream);
1077}
1078
1079} // namespace ns3
a polymophic address class
Definition: address.h:101
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:571
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< const 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:62
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)
static Mac48Address GetBroadcast()
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:278
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
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
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Template class for packet Queues.
Definition: queue.h:268
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
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:415
@ 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:932
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:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeMac48AddressAccessor(T1 a1)
Ptr< const AttributeChecker > MakeMac48AddressChecker()
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
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:1319
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(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:189
@ 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