Add FCS capability to CSMA
authorFlorian Schmidt <Florian.Schmidt@cs.rwth-aachen.de>
Wed, 02 Dec 2009 14:29:43 -0800
changeset 5831 3fda006341e6
parent 5830 e03be90a225c
child 5832 2812b92d4888
Add FCS capability to CSMA
src/devices/csma/csma-net-device.cc
src/node/ethernet-trailer.cc
src/node/ethernet-trailer.h
--- a/src/devices/csma/csma-net-device.cc	Wed Dec 02 11:25:49 2009 -0800
+++ b/src/devices/csma/csma-net-device.cc	Wed Dec 02 14:29:43 2009 -0800
@@ -421,6 +421,10 @@
   header.SetLengthType (lengthType);
   p->AddHeader (header);
 
+  if (Node::ChecksumEnabled ())
+    {
+      trailer.EnableFcs (true);
+    }
   trailer.CalcFcs (p);
   p->AddTrailer (trailer);
 }
@@ -747,6 +751,10 @@
 
   EthernetTrailer trailer;
   packet->RemoveTrailer (trailer);
+  if (Node::ChecksumEnabled ())
+    {
+      trailer.EnableFcs (true);
+    }
   trailer.CheckFcs (packet);
 
   EthernetHeader header (false);
--- a/src/node/ethernet-trailer.cc	Wed Dec 02 11:25:49 2009 -0800
+++ b/src/node/ethernet-trailer.cc	Wed Dec 02 14:29:43 2009 -0800
@@ -29,17 +29,10 @@
 
 NS_OBJECT_ENSURE_REGISTERED (EthernetTrailer);
 
-bool EthernetTrailer::m_calcFcs = false;
-
 EthernetTrailer::EthernetTrailer ()
-{
-  Init();
-}
-
-void EthernetTrailer::Init()
-{
-  m_fcs = 0;
-}
+  : m_calcFcs (false),
+    m_fcs (0)
+{}
 
 void 
 EthernetTrailer::EnableFcs (bool enable)
@@ -50,21 +43,37 @@
 bool
 EthernetTrailer::CheckFcs (Ptr<Packet> p) const
 {
+  int len = p->GetSize ();
+  uint8_t *buffer;
+  uint32_t crc;
+
   if (!m_calcFcs)
     {
       return true;
-    } 
-  else 
-    {
-      NS_LOG_WARN ("FCS calculation is not yet enabled");
-      return false;
     }
+
+  buffer = new uint8_t[len];
+  p->CopyData (buffer, len);
+  crc = DoCalcFcs (buffer, len);
+  delete[] buffer;
+  return (m_fcs == crc);
 }
 
 void
 EthernetTrailer::CalcFcs (Ptr<Packet> p)
 {
-  NS_LOG_WARN ("FCS calculation is not yet enabled");
+  int len = p->GetSize ();
+  uint8_t *buffer;
+
+  if (!m_calcFcs)
+    {
+      return;
+    }
+
+  buffer = new uint8_t[len];
+  p->CopyData (buffer, len);
+  m_fcs = DoCalcFcs (buffer, len);
+  delete[] buffer;
 }
 
 void
@@ -130,4 +139,23 @@
   return size;
 }
 
+// This code is copied from /lib/crc32.c in the linux kernel.
+// It assumes little endian ordering.
+uint32_t
+EthernetTrailer::DoCalcFcs (uint8_t *buffer, size_t len) const
+{
+  uint32_t crc = 0xffffffff;
+  int i;
+
+  while (len--)
+    {
+      crc ^= *buffer++;
+      for (i = 0; i < 8; i++)
+        {
+	  crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+	}
+    }
+  return ~crc;
+}
+
 }; // namespace ns3
--- a/src/node/ethernet-trailer.h	Wed Dec 02 11:25:49 2009 -0800
+++ b/src/node/ethernet-trailer.h	Wed Dec 02 14:29:43 2009 -0800
@@ -22,11 +22,11 @@
 #define ETHERNET_TRAILER_H
 
 #include "ns3/trailer.h"
+#include "ns3/packet.h"
 #include <string>
 
 namespace ns3 {
 
-class Packet;
 
 /**
  * \ingroup node
@@ -46,10 +46,10 @@
   EthernetTrailer ();
 
   /**
-   * \brief Enable or disabled FCS checking and calculations
+   * \brief Enable or disable FCS checking and calculations
    * \param enable If true, enables FCS calculations.
    */
-  static void EnableFcs (bool enable);
+  void EnableFcs (bool enable);
   /**
    * \brief Updates the Fcs Field to the correct FCS
    * \param p Reference to a packet on which the FCS should be
@@ -89,19 +89,15 @@
   virtual void Serialize (Buffer::Iterator end) const;
   virtual uint32_t Deserialize (Buffer::Iterator end);
 private:
-
-  /**
-   * Initializes the trailer parameters during construction.
-   */
-  void Init (void);
-
   /**
    * Enabled FCS calculations. If false, fcs is set to 0 and checkFCS
    * returns true.
    */
-  static bool m_calcFcs;
+  bool m_calcFcs;
   uint32_t m_fcs; /// Value of the fcs contained in the trailer
 
+  uint32_t DoCalcFcs (uint8_t *buffer, size_t len) const;
+
 };
 
 } // namespace ns3