--- a/src/devices/csma-cd/csma-cd-net-device.cc Mon Jul 30 14:48:56 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,488 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
- */
-
-#include <iostream>
-#include <cassert>
-#include "ns3/debug.h"
-#include "ns3/queue.h"
-#include "ns3/simulator.h"
-#include "ns3/composite-trace-resolver.h"
-#include "csma-cd-net-device.h"
-#include "csma-cd-channel.h"
-#include "ns3/ethernet-header.h"
-#include "ns3/ethernet-trailer.h"
-#include "ns3/llc-snap-header.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice");
-
-namespace ns3 {
-
-CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
- CsmaCdEncapsulationMode encapMode)
- : NetDevice(node, addr), m_bps (DataRate (0xffffffff))
-{
- NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
- m_encapMode = encapMode;
-
- Init(true, true);
-}
-
-CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
- CsmaCdEncapsulationMode encapMode,
- bool sendEnable, bool receiveEnable)
- : NetDevice(node, addr), m_bps (DataRate (0xffffffff))
-{
- NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
- m_encapMode = encapMode;
-
- Init(sendEnable, receiveEnable);
-}
-
-CsmaCdNetDevice::~CsmaCdNetDevice()
-{
- NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()");
- m_queue = 0;
-}
-
-void
-CsmaCdNetDevice::DoDispose ()
-{
- m_channel = 0;
- NetDevice::DoDispose ();
-}
-
-//
-// Assignment operator for CsmaCdNetDevice.
-//
-// This uses the non-obvious trick of taking the source net device passed by
-// value instead of by reference. This causes the copy constructor to be
-// invoked (where the real work is done -- see above). All we have to do
-// here is to return the newly constructed net device.
-//
-/*
-CsmaCdNetDevice&
-CsmaCdNetDevice::operator= (const CsmaCdNetDevice nd)
-{
- NS_DEBUG ("CsmaCdNetDevice::operator= (" << &nd << ")");
- return *this;
-}
-*/
-
-void
-CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
-{
- m_txMachineState = READY;
- m_tInterframeGap = Seconds(0);
- m_channel = 0;
- m_queue = 0;
-
- EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
- EnableMulticast();
- EnablePointToPoint();
-
- SetSendEnable (sendEnable);
- SetReceiveEnable (receiveEnable);
-}
-
-void
-CsmaCdNetDevice::SetSendEnable (bool sendEnable)
-{
- m_sendEnable = sendEnable;
-}
-
-void
-CsmaCdNetDevice::SetReceiveEnable (bool receiveEnable)
-{
- m_receiveEnable = receiveEnable;
-}
-bool
-CsmaCdNetDevice::IsSendEnabled (void)
-{
- return (m_sendEnable);
-}
-
-bool
-CsmaCdNetDevice::IsReceiveEnabled (void)
-{
- return (m_receiveEnable);
-}
-
-void
-CsmaCdNetDevice::SetDataRate (DataRate bps)
-{
- m_bps = bps;
-}
-
-void
-CsmaCdNetDevice::SetInterframeGap (Time t)
-{
- m_tInterframeGap = t;
-}
-
-void
-CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
- uint32_t maxSlots, uint32_t ceiling,
- uint32_t maxRetries)
-{
- m_backoff.m_slotTime = slotTime;
- m_backoff.m_minSlots = minSlots;
- m_backoff.m_maxSlots = maxSlots;
- m_backoff.m_ceiling = ceiling;
- m_backoff.m_maxRetries = maxRetries;
-}
-void
-CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest,
- uint16_t protocolNumber)
-{
- if (m_encapMode == RAW)
- {
- return;
- }
- EthernetHeader header (false);
- EthernetTrailer trailer;
- header.SetSource(this->GetAddress());
- header.SetDestination(dest);
-
- uint16_t lengthType = 0;
- switch (m_encapMode)
- {
- case ETHERNET_V1:
- lengthType = p.GetSize() + header.GetSize() + trailer.GetSize();
- break;
- case IP_ARP:
- lengthType = protocolNumber;
- break;
- case LLC: {
- LlcSnapHeader llc;
- llc.SetType (protocolNumber);
- p.AddHeader (llc);
- } break;
- case RAW:
- NS_ASSERT (false);
- break;
- }
- header.SetLengthType (lengthType);
- p.AddHeader(header);
- trailer.CalcFcs(p);
- p.AddTrailer(trailer);
-}
-bool
-CsmaCdNetDevice::ProcessHeader (Packet& p, uint16_t & param)
-{
- if (m_encapMode == RAW)
- {
- return true;
- }
- EthernetHeader header (false);
- EthernetTrailer trailer;
-
- p.RemoveTrailer(trailer);
- trailer.CheckFcs(p);
- p.RemoveHeader(header);
-
- if ((header.GetDestination() != this->GetBroadcast()) &&
- (header.GetDestination() != this->GetAddress()))
- {
- return false;
- }
-
- switch (m_encapMode)
- {
- case ETHERNET_V1:
- case IP_ARP:
- param = header.GetLengthType();
- break;
- case LLC: {
- LlcSnapHeader llc;
- p.RemoveHeader (llc);
- param = llc.GetType ();
- } break;
- case RAW:
- NS_ASSERT (false);
- break;
- }
- return true;
-}
-
-bool
-CsmaCdNetDevice::DoNeedsArp (void) const
-{
- if ((m_encapMode == IP_ARP) || (m_encapMode == LLC))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool
-CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber)
-{
- NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")");
- NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")");
-
- NS_ASSERT (IsLinkUp ());
-
- // Only transmit if send side of net device is enabled
- if (!IsSendEnabled())
- return false;
-
- AddHeader(p, dest, protocolNumber);
-
- // Place the packet to be sent on the send queue
- if (m_queue->Enqueue(p) == false )
- {
- return false;
- }
- // If the device is idle, we need to start a transmission. Otherwise,
- // the transmission will be started when the current packet finished
- // transmission (see TransmitCompleteEvent)
- if (m_txMachineState == READY)
- {
- // Store the next packet to be transmitted
- if (m_queue->Dequeue (m_currentPkt))
- {
- TransmitStart();
- }
- }
- return true;
-}
-
-void
-CsmaCdNetDevice::TransmitStart ()
-{
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (" << &m_currentPkt << ")");
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): UID is "
- << m_currentPkt.GetUid () << ")");
-//
-// This function is called to start the process of transmitting a packet.
-// We need to tell the channel that we've started wiggling the wire and
-// schedule an event that will be executed when it's time to tell the
-// channel that we're done wiggling the wire.
-//
- NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF),
- "Must be READY to transmit. Tx state is: "
- << m_txMachineState);
-
- // Only transmit if send side of net device is enabled
- if (!IsSendEnabled())
- return;
-
- if (m_channel->GetState() != IDLE)
- { // Channel busy, backoff and rechedule TransmitStart()
- m_txMachineState = BACKOFF;
- if (m_backoff.MaxRetriesReached())
- { // Too many retries reached, abort transmission of packet
- TransmitAbort();
- }
- else
- {
- m_backoff.IncrNumRetries();
- Time backoffTime = m_backoff.GetBackoffTime();
-
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): "
- << "Channel busy, backing off for "
- << backoffTime.GetSeconds () << "sec");
-
- Simulator::Schedule (backoffTime,
- &CsmaCdNetDevice::TransmitStart,
- this);
- }
- }
- else
- {
- // Channel is free, transmit packet
- m_txMachineState = BUSY;
- Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
-
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
- "Schedule TransmitCompleteEvent in " <<
- tEvent.GetSeconds () << "sec");
-
- Simulator::Schedule (tEvent,
- &CsmaCdNetDevice::TransmitCompleteEvent,
- this);
- if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
- {
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
- "Channel transmit start did not work at " <<
- tEvent.GetSeconds () << "sec");
- m_txMachineState = READY;
- }
- else
- {
- // Transmission success, reset backoff time parameters.
- m_backoff.ResetBackoffTime();
- }
- }
-}
-
-
-void
-CsmaCdNetDevice::TransmitAbort (void)
-{
- NS_DEBUG ("CsmaCdNetDevice::TransmitAbort ()");
-
- NS_DEBUG ("CsmaCdNetDevice::TransmitAbort (): Pkt UID is " <<
- m_currentPkt.GetUid () << ")");
-
- // Try to transmit a new packet
- bool found;
- found = m_queue->Dequeue (m_currentPkt);
- NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
- m_backoff.ResetBackoffTime();
- m_txMachineState = READY;
- TransmitStart ();
-}
-
-void
-CsmaCdNetDevice::TransmitCompleteEvent (void)
-{
- NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent ()");
-//
-// This function is called to finish the process of transmitting a packet.
-// We need to tell the channel that we've stopped wiggling the wire and
-// schedule an event that will be executed when it's time to re-enable
-// the transmitter after the interframe gap.
-//
- NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
- // Channel should be transmitting
- NS_ASSERT(m_channel->GetState() == TRANSMITTING);
- m_txMachineState = GAP;
-
- NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
- m_currentPkt.GetUid () << ")");
- m_channel->TransmitEnd ();
-
- NS_DEBUG (
- "CsmaCdNetDevice::TransmitCompleteEvent (): " <<
- "Schedule TransmitReadyEvent in "
- << m_tInterframeGap.GetSeconds () << "sec");
-
- Simulator::Schedule (m_tInterframeGap,
- &CsmaCdNetDevice::TransmitReadyEvent,
- this);
-}
-
-void
-CsmaCdNetDevice::TransmitReadyEvent (void)
-{
- NS_DEBUG ("CsmaCdNetDevice::TransmitReadyEvent ()");
-//
-// This function is called to enable the transmitter after the interframe
-// gap has passed. If there are pending transmissions, we use this opportunity
-// to start the next transmit.
-//
- NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
- m_txMachineState = READY;
-
- // Get the next packet from the queue for transmitting
- if (m_queue->IsEmpty())
- {
- return;
- }
- else
- {
- bool found;
- found = m_queue->Dequeue (m_currentPkt);
- NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
- TransmitStart ();
- }
-}
-
-TraceResolver *
-CsmaCdNetDevice::DoCreateTraceResolver (TraceContext const &context)
-{
- CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- resolver->Add ("queue",
- MakeCallback (&Queue::CreateTraceResolver,
- PeekPointer (m_queue)),
- CsmaCdNetDevice::QUEUE);
- resolver->Add ("rx",
- m_rxTrace,
- CsmaCdNetDevice::RX);
- return resolver;
-}
-
-bool
-CsmaCdNetDevice::Attach (Ptr<CsmaCdChannel> ch)
-{
- NS_DEBUG ("CsmaCdNetDevice::Attach (" << &ch << ")");
-
- m_channel = ch;
-
- m_deviceId = m_channel->Attach(this);
- m_bps = m_channel->GetDataRate ();
- m_tInterframeGap = m_channel->GetDelay ();
-
- /*
- * For now, this device is up whenever a channel is attached to it.
- */
- NotifyLinkUp ();
- return true;
-}
-
-void
-CsmaCdNetDevice::AddQueue (Ptr<Queue> q)
-{
- NS_DEBUG ("CsmaCdNetDevice::AddQueue (" << q << ")");
-
- m_queue = q;
-}
-
-void
-CsmaCdNetDevice::Receive (Packet& p)
-{
- NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
-
- // Only receive if send side of net device is enabled
- if (!IsReceiveEnabled())
- return;
-
- uint16_t param = 0;
- Packet packet = p;
-
- if (ProcessHeader(packet, param))
- {
- m_rxTrace (packet);
- ForwardUp (packet, param);
- }
- else
- {
- m_dropTrace (packet);
- }
-}
-
-Ptr<Queue>
-CsmaCdNetDevice::GetQueue(void) const
-{
- return m_queue;
-}
-
-Ptr<Channel>
-CsmaCdNetDevice::DoGetChannel(void) const
-{
- return m_channel;
-}
-
-} // namespace ns3