Add 6LoWPAN uncompressed IPv6 header support
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Sat, 15 Mar 2014 19:18:53 +0100
changeset 10665 57dd71d4886e
parent 10664 2bb07b08e681
child 10666 dd496c654c73
Add 6LoWPAN uncompressed IPv6 header support
RELEASE_NOTES
src/sixlowpan/bindings/modulegen__gcc_ILP32.py
src/sixlowpan/bindings/modulegen__gcc_LP64.py
src/sixlowpan/doc/sixlowpan.rst
src/sixlowpan/model/sixlowpan-header.cc
src/sixlowpan/model/sixlowpan-header.h
src/sixlowpan/model/sixlowpan-net-device.cc
src/sixlowpan/model/sixlowpan-net-device.h
--- a/RELEASE_NOTES	Sat Mar 15 17:04:02 2014 +0100
+++ b/RELEASE_NOTES	Sat Mar 15 19:18:53 2014 +0100
@@ -27,7 +27,8 @@
 - A new LTE MAC downlink scheduling algorithm named Channel and QoS
   Aware (CQA) Scheduler is provided by the new
   ``ns3::CqaFfMacScheduler`` object.
-  
+- SixLowPan model can now use uncompressed IPv6 headers. An option to
+  define the minimum compressed packet size has been added. 
 
 Bugs fixed
 ----------
--- a/src/sixlowpan/bindings/modulegen__gcc_ILP32.py	Sat Mar 15 17:04:02 2014 +0100
+++ b/src/sixlowpan/bindings/modulegen__gcc_ILP32.py	Sat Mar 15 19:18:53 2014 +0100
@@ -91,7 +91,7 @@
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanDispatch [class]
     module.add_class('SixLowPanDispatch')
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanDispatch::Dispatch_e [enumeration]
-    module.add_enum('Dispatch_e', ['LOWPAN_NALP', 'LOWPAN_NALP_N', 'LOWPAN_NOTCOMPRESSED', 'LOWPAN_HC1', 'LOWPAN_BC0', 'LOWPAN_IPHC', 'LOWPAN_IPHC_N', 'LOWPAN_MESH', 'LOWPAN_MESH_N', 'LOWPAN_FRAG1', 'LOWPAN_FRAG1_N', 'LOWPAN_FRAGN', 'LOWPAN_FRAGN_N', 'LOWPAN_UNSUPPORTED'], outer_class=root_module['ns3::SixLowPanDispatch'])
+    module.add_enum('Dispatch_e', ['LOWPAN_NALP', 'LOWPAN_NALP_N', 'LOWPAN_IPv6', 'LOWPAN_HC1', 'LOWPAN_BC0', 'LOWPAN_IPHC', 'LOWPAN_IPHC_N', 'LOWPAN_MESH', 'LOWPAN_MESH_N', 'LOWPAN_FRAG1', 'LOWPAN_FRAG1_N', 'LOWPAN_FRAGN', 'LOWPAN_FRAGN_N', 'LOWPAN_UNSUPPORTED'], outer_class=root_module['ns3::SixLowPanDispatch'])
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanDispatch::NhcDispatch_e [enumeration]
     module.add_enum('NhcDispatch_e', ['LOWPAN_NHC', 'LOWPAN_NHC_N', 'LOWPAN_UDPNHC', 'LOWPAN_UDPNHC_N', 'LOWPAN_NHCUNSUPPORTED'], outer_class=root_module['ns3::SixLowPanDispatch'])
     ## sixlowpan-helper.h (module 'sixlowpan'): ns3::SixLowPanHelper [class]
@@ -166,6 +166,8 @@
     module.add_enum('Hlim_e', ['HLIM_INLINE', 'HLIM_COMPR_1', 'HLIM_COMPR_64', 'HLIM_COMPR_255'], outer_class=root_module['ns3::SixLowPanIphc'])
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanIphc::HeaderCompression_e [enumeration]
     module.add_enum('HeaderCompression_e', ['HC_INLINE', 'HC_COMPR_64', 'HC_COMPR_16', 'HC_COMPR_0'], outer_class=root_module['ns3::SixLowPanIphc'])
+    ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanIpv6 [class]
+    module.add_class('SixLowPanIpv6', parent=root_module['ns3::Header'])
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanNhcExtension [class]
     module.add_class('SixLowPanNhcExtension', parent=root_module['ns3::Header'])
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanNhcExtension::Eid_e [enumeration]
@@ -376,6 +378,7 @@
     register_Ns3SixLowPanFragN_methods(root_module, root_module['ns3::SixLowPanFragN'])
     register_Ns3SixLowPanHc1_methods(root_module, root_module['ns3::SixLowPanHc1'])
     register_Ns3SixLowPanIphc_methods(root_module, root_module['ns3::SixLowPanIphc'])
+    register_Ns3SixLowPanIpv6_methods(root_module, root_module['ns3::SixLowPanIpv6'])
     register_Ns3SixLowPanNhcExtension_methods(root_module, root_module['ns3::SixLowPanNhcExtension'])
     register_Ns3SixLowPanUdpNhcExtension_methods(root_module, root_module['ns3::SixLowPanUdpNhcExtension'])
     register_Ns3Time_methods(root_module, root_module['ns3::Time'])
@@ -3049,6 +3052,44 @@
                    [param('ns3::SixLowPanIphc::TrafficClassFlowLabel_e', 'tfField')])
     return
 
+def register_Ns3SixLowPanIpv6_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanIpv6::SixLowPanIpv6(ns3::SixLowPanIpv6 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::SixLowPanIpv6 const &', 'arg0')])
+    ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanIpv6::SixLowPanIpv6() [constructor]
+    cls.add_constructor([])
+    ## sixlowpan-header.h (module 'sixlowpan'): uint32_t ns3::SixLowPanIpv6::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): ns3::TypeId ns3::SixLowPanIpv6::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): uint32_t ns3::SixLowPanIpv6::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): static ns3::TypeId ns3::SixLowPanIpv6::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): void ns3::SixLowPanIpv6::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): void ns3::SixLowPanIpv6::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    return
+
 def register_Ns3SixLowPanNhcExtension_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanNhcExtension::SixLowPanNhcExtension(ns3::SixLowPanNhcExtension const & arg0) [copy constructor]
@@ -4691,10 +4732,10 @@
                    'uint32_t', 
                    [param('uint8_t *', 'buffer'), param('uint32_t', 'maxSize')], 
                    is_const=True)
-    ## packet.h (module 'network'): void ns3::Packet::SetNixVector(ns3::Ptr<ns3::NixVector> arg0) [member function]
+    ## packet.h (module 'network'): void ns3::Packet::SetNixVector(ns3::Ptr<ns3::NixVector> nixVector) [member function]
     cls.add_method('SetNixVector', 
                    'void', 
-                   [param('ns3::Ptr< ns3::NixVector >', 'arg0')])
+                   [param('ns3::Ptr< ns3::NixVector >', 'nixVector')])
     return
 
 def register_Ns3ParetoRandomVariable_methods(root_module, cls):
--- a/src/sixlowpan/bindings/modulegen__gcc_LP64.py	Sat Mar 15 17:04:02 2014 +0100
+++ b/src/sixlowpan/bindings/modulegen__gcc_LP64.py	Sat Mar 15 19:18:53 2014 +0100
@@ -91,7 +91,7 @@
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanDispatch [class]
     module.add_class('SixLowPanDispatch')
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanDispatch::Dispatch_e [enumeration]
-    module.add_enum('Dispatch_e', ['LOWPAN_NALP', 'LOWPAN_NALP_N', 'LOWPAN_NOTCOMPRESSED', 'LOWPAN_HC1', 'LOWPAN_BC0', 'LOWPAN_IPHC', 'LOWPAN_IPHC_N', 'LOWPAN_MESH', 'LOWPAN_MESH_N', 'LOWPAN_FRAG1', 'LOWPAN_FRAG1_N', 'LOWPAN_FRAGN', 'LOWPAN_FRAGN_N', 'LOWPAN_UNSUPPORTED'], outer_class=root_module['ns3::SixLowPanDispatch'])
+    module.add_enum('Dispatch_e', ['LOWPAN_NALP', 'LOWPAN_NALP_N', 'LOWPAN_IPv6', 'LOWPAN_HC1', 'LOWPAN_BC0', 'LOWPAN_IPHC', 'LOWPAN_IPHC_N', 'LOWPAN_MESH', 'LOWPAN_MESH_N', 'LOWPAN_FRAG1', 'LOWPAN_FRAG1_N', 'LOWPAN_FRAGN', 'LOWPAN_FRAGN_N', 'LOWPAN_UNSUPPORTED'], outer_class=root_module['ns3::SixLowPanDispatch'])
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanDispatch::NhcDispatch_e [enumeration]
     module.add_enum('NhcDispatch_e', ['LOWPAN_NHC', 'LOWPAN_NHC_N', 'LOWPAN_UDPNHC', 'LOWPAN_UDPNHC_N', 'LOWPAN_NHCUNSUPPORTED'], outer_class=root_module['ns3::SixLowPanDispatch'])
     ## sixlowpan-helper.h (module 'sixlowpan'): ns3::SixLowPanHelper [class]
@@ -166,6 +166,8 @@
     module.add_enum('Hlim_e', ['HLIM_INLINE', 'HLIM_COMPR_1', 'HLIM_COMPR_64', 'HLIM_COMPR_255'], outer_class=root_module['ns3::SixLowPanIphc'])
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanIphc::HeaderCompression_e [enumeration]
     module.add_enum('HeaderCompression_e', ['HC_INLINE', 'HC_COMPR_64', 'HC_COMPR_16', 'HC_COMPR_0'], outer_class=root_module['ns3::SixLowPanIphc'])
+    ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanIpv6 [class]
+    module.add_class('SixLowPanIpv6', parent=root_module['ns3::Header'])
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanNhcExtension [class]
     module.add_class('SixLowPanNhcExtension', parent=root_module['ns3::Header'])
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanNhcExtension::Eid_e [enumeration]
@@ -376,6 +378,7 @@
     register_Ns3SixLowPanFragN_methods(root_module, root_module['ns3::SixLowPanFragN'])
     register_Ns3SixLowPanHc1_methods(root_module, root_module['ns3::SixLowPanHc1'])
     register_Ns3SixLowPanIphc_methods(root_module, root_module['ns3::SixLowPanIphc'])
+    register_Ns3SixLowPanIpv6_methods(root_module, root_module['ns3::SixLowPanIpv6'])
     register_Ns3SixLowPanNhcExtension_methods(root_module, root_module['ns3::SixLowPanNhcExtension'])
     register_Ns3SixLowPanUdpNhcExtension_methods(root_module, root_module['ns3::SixLowPanUdpNhcExtension'])
     register_Ns3Time_methods(root_module, root_module['ns3::Time'])
@@ -3049,6 +3052,44 @@
                    [param('ns3::SixLowPanIphc::TrafficClassFlowLabel_e', 'tfField')])
     return
 
+def register_Ns3SixLowPanIpv6_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanIpv6::SixLowPanIpv6(ns3::SixLowPanIpv6 const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::SixLowPanIpv6 const &', 'arg0')])
+    ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanIpv6::SixLowPanIpv6() [constructor]
+    cls.add_constructor([])
+    ## sixlowpan-header.h (module 'sixlowpan'): uint32_t ns3::SixLowPanIpv6::Deserialize(ns3::Buffer::Iterator start) [member function]
+    cls.add_method('Deserialize', 
+                   'uint32_t', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_virtual=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): ns3::TypeId ns3::SixLowPanIpv6::GetInstanceTypeId() const [member function]
+    cls.add_method('GetInstanceTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): uint32_t ns3::SixLowPanIpv6::GetSerializedSize() const [member function]
+    cls.add_method('GetSerializedSize', 
+                   'uint32_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): static ns3::TypeId ns3::SixLowPanIpv6::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 
+                   'ns3::TypeId', 
+                   [], 
+                   is_static=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): void ns3::SixLowPanIpv6::Print(std::ostream & os) const [member function]
+    cls.add_method('Print', 
+                   'void', 
+                   [param('std::ostream &', 'os')], 
+                   is_const=True, is_virtual=True)
+    ## sixlowpan-header.h (module 'sixlowpan'): void ns3::SixLowPanIpv6::Serialize(ns3::Buffer::Iterator start) const [member function]
+    cls.add_method('Serialize', 
+                   'void', 
+                   [param('ns3::Buffer::Iterator', 'start')], 
+                   is_const=True, is_virtual=True)
+    return
+
 def register_Ns3SixLowPanNhcExtension_methods(root_module, cls):
     cls.add_output_stream_operator()
     ## sixlowpan-header.h (module 'sixlowpan'): ns3::SixLowPanNhcExtension::SixLowPanNhcExtension(ns3::SixLowPanNhcExtension const & arg0) [copy constructor]
@@ -4691,10 +4732,10 @@
                    'uint32_t', 
                    [param('uint8_t *', 'buffer'), param('uint32_t', 'maxSize')], 
                    is_const=True)
-    ## packet.h (module 'network'): void ns3::Packet::SetNixVector(ns3::Ptr<ns3::NixVector> arg0) [member function]
+    ## packet.h (module 'network'): void ns3::Packet::SetNixVector(ns3::Ptr<ns3::NixVector> nixVector) [member function]
     cls.add_method('SetNixVector', 
                    'void', 
-                   [param('ns3::Ptr< ns3::NixVector >', 'arg0')])
+                   [param('ns3::Ptr< ns3::NixVector >', 'nixVector')])
     return
 
 def register_Ns3ParetoRandomVariable_methods(root_module, cls):
--- a/src/sixlowpan/doc/sixlowpan.rst	Sat Mar 15 17:04:02 2014 +0100
+++ b/src/sixlowpan/doc/sixlowpan.rst	Sat Mar 15 19:18:53 2014 +0100
@@ -55,9 +55,16 @@
 * OmitUdpChecksum (boolean, default true), used to activate UDP checksum compression in IPHC.
 * FragmentReassemblyListSize (integer, default 0), indicating the number of packets that can be reassembled at the same time. If the limit is reached, the oldest packet is discarded. Zero means infinite.
 * FragmentExpirationTimeout (Time, default 60 seconds), being the timeout to wait for further fragments before discarding a partial packet.
+* CompressionThreshold (unsigned 32 bits integer, default 0), minimum compressed payload size. 
 * ForceEtherType (boolean, default false), and
 * EtherType (unsigned 16 bits integer, default 0xFFFF), to force a particular L2 EtherType.
 
+The CompressionThreshold attribute is similar to Contiki's SICSLOWPAN_CONF_MIN_MAC_PAYLOAD
+option. If a compressed packet size is less than the threshold, the uncompressed version is
+used (plus one byte for the correct dispatch header).
+This option is useful only when a MAC with specific requirement for minimum frame size is 
+used (e.g., ContikiMAC).
+
 The last two attributes are needed to use the module with a NetDevice other than 802.15.4, as
 neither IANA or IEEE did reserve an EtherType for 6LoWPAN. As a consequence there might be a
 conflict with the L2 multiplexer/demultiplexer which is based on EtherType. The default 
--- a/src/sixlowpan/model/sixlowpan-header.cc	Sat Mar 15 17:04:02 2014 +0100
+++ b/src/sixlowpan/model/sixlowpan-header.cc	Sat Mar 15 19:18:53 2014 +0100
@@ -45,9 +45,9 @@
     {
       return LOWPAN_NALP;
     }
-  else if (dispatch == LOWPAN_NOTCOMPRESSED)
+  else if (dispatch == LOWPAN_IPv6)
     {
-      return LOWPAN_NOTCOMPRESSED;
+      return LOWPAN_IPv6;
     }
   else if (dispatch == LOWPAN_HC1)
     {
@@ -718,6 +718,58 @@
 }
 
 /*
+ * SixLowPanIpv6
+ */
+
+NS_OBJECT_ENSURE_REGISTERED (SixLowPanIpv6);
+
+SixLowPanIpv6::SixLowPanIpv6 ()
+{
+}
+
+TypeId SixLowPanIpv6::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::SixLowPanIpv6").SetParent<Header> ().AddConstructor<SixLowPanIpv6> ();
+  return tid;
+}
+
+TypeId SixLowPanIpv6::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void SixLowPanIpv6::Print (std::ostream & os) const
+{
+  os << "Uncompressed IPv6";
+}
+
+uint32_t SixLowPanIpv6::GetSerializedSize () const
+{
+  return 1;
+}
+
+void SixLowPanIpv6::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+
+  i.WriteU8 (uint8_t (SixLowPanDispatch::LOWPAN_IPv6));
+}
+
+uint32_t SixLowPanIpv6::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  i.ReadU8 ();
+
+  return GetSerializedSize ();
+}
+
+std::ostream & operator << (std::ostream & os, const SixLowPanIpv6 & h)
+{
+  h.Print (os);
+  return os;
+}
+
+/*
  * SixLowPanIphcHeader
  */
 NS_OBJECT_ENSURE_REGISTERED (SixLowPanIphc);
--- a/src/sixlowpan/model/sixlowpan-header.h	Sat Mar 15 17:04:02 2014 +0100
+++ b/src/sixlowpan/model/sixlowpan-header.h	Sat Mar 15 19:18:53 2014 +0100
@@ -79,7 +79,7 @@
   {
     LOWPAN_NALP = 0x0,
     LOWPAN_NALP_N = 0x3F,
-    LOWPAN_NOTCOMPRESSED = 0x41,
+    LOWPAN_IPv6 = 0x41,
     LOWPAN_HC1 = 0x42,
     LOWPAN_BC0 = 0x50,
     LOWPAN_IPHC = 0x60,
@@ -199,12 +199,6 @@
   virtual uint32_t Deserialize (Buffer::Iterator start);
 
   /**
-   * \brief Get the Dispatch type.
-   * \return the Dispatch type
-   */
-  // virtual Dispatch_e GetDispatchType (void) const;
-
-  /**
    * \brief Set the "Hop limit" field (TTL).
    * \param limit the hop limit value
    */
@@ -416,12 +410,6 @@
   virtual uint32_t Deserialize (Buffer::Iterator start);
 
   /**
-   * \brief Get the Dispatch type.
-   * \return the Dispatch type
-   */
-  // virtual Dispatch_e GetDispatchType (void) const;
-
-  /**
    * \brief Set the datagram size
    * \param datagramSize the datagram size
    */
@@ -503,12 +491,6 @@
   virtual uint32_t Deserialize (Buffer::Iterator start);
 
   /**
-   * \brief Get the Dispatch type.
-   * \return the Dispatch type
-   */
-  // virtual Dispatch_e GetDispatchType (void) const;
-
-  /**
    * \brief Set the datagram size
    * \param datagramSize the datagram size
    */
@@ -561,6 +543,59 @@
 std::ostream & operator<< (std::ostream & os, SixLowPanFragN const &header);
 
 /**
+ * \ingroup sixlowpan
+ * \brief 6LoWPAN IPv6 uncomprssed header - see RFC 4944
+ */
+class SixLowPanIpv6 : public Header
+{
+public:
+  SixLowPanIpv6 (void);
+
+  /**
+   * \brief Get the type ID.
+   * \return the object TypeId
+   */
+  static TypeId GetTypeId (void);
+
+  /**
+   * \brief Return the instance type identifier.
+   * \return instance type ID
+   */
+  virtual TypeId GetInstanceTypeId (void) const;
+
+  virtual void Print (std::ostream& os) const;
+
+  /**
+   * \brief Get the serialized size of the packet.
+   * \return size
+   */
+  virtual uint32_t GetSerializedSize (void) const;
+
+  /**
+   * \brief Serialize the packet.
+   * \param start Buffer iterator
+   */
+  virtual void Serialize (Buffer::Iterator start) const;
+
+  /**
+   * \brief Deserialize the packet.
+   * \param start Buffer iterator
+   * \return size of the packet
+   */
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+};
+
+/**
+ * \brief Stream insertion operator.
+ *
+ * \param os the reference to the output stream
+ * \param header the Frag1 Header
+ * \returns the reference to the output stream
+ */
+std::ostream & operator<< (std::ostream & os, SixLowPanIpv6 const & header);
+
+/**
 * \ingroup sixlowpan
 * \brief   LOWPAN_IPHC base Encoding - see RFC 6282
   \verbatim
@@ -664,12 +699,6 @@
   virtual uint32_t Deserialize (Buffer::Iterator start);
 
   /**
-   * \brief Get the Dispatch type.
-   * \return the Dispatch type
-   */
-  // virtual Dispatch_e GetDispatchType (void) const;
-
-  /**
    * \brief Set the TF (Traffic Class, Flow Label) compression.
    * \param tfField ECN, DSCP, Flow Label compression type
    */
--- a/src/sixlowpan/model/sixlowpan-net-device.cc	Sat Mar 15 17:04:02 2014 +0100
+++ b/src/sixlowpan/model/sixlowpan-net-device.cc	Sat Mar 15 19:18:53 2014 +0100
@@ -70,6 +70,11 @@
                    TimeValue (Seconds (60)),
                    MakeTimeAccessor (&SixLowPanNetDevice::m_fragmentExpirationTimeout),
                    MakeTimeChecker ())
+    .AddAttribute ("CompressionThreshold",
+                   "The minimum MAC layer payload size.",
+                   UintegerValue (0x0),
+                   MakeUintegerAccessor (&SixLowPanNetDevice::m_compressionThreshold),
+                   MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("ForceEtherType",
                    "Force a specific EtherType in L2 frames.",
                    BooleanValue (false),
@@ -210,10 +215,13 @@
       NS_LOG_DEBUG ("Unsupported 6LoWPAN encoding: BC0, dropping.");
       m_dropTrace (DROP_UNKNOWN_EXTENSION, copyPkt, m_node->GetObject<SixLowPanNetDevice> (), GetIfIndex ());
       break;
-    case SixLowPanDispatch::LOWPAN_NOTCOMPRESSED:
-      NS_LOG_DEBUG ( "Packet without compression:" << *copyPkt );
-      NS_LOG_DEBUG ( "Packet length:" << copyPkt->GetSize () );
-      m_dropTrace (DROP_UNKNOWN_EXTENSION, copyPkt, m_node->GetObject<SixLowPanNetDevice> (), GetIfIndex ());
+    case SixLowPanDispatch::LOWPAN_IPv6:
+      NS_LOG_DEBUG ( "Packet without compression. Length: " << copyPkt->GetSize () );
+      {
+        SixLowPanIpv6 uncompressedHdr;
+        copyPkt->RemoveHeader(uncompressedHdr);
+        isPktDecompressed = true;
+      }
       break;
     case SixLowPanDispatch::LOWPAN_HC1:
       DecompressLowPanHc1 (copyPkt, src, dst);
@@ -382,8 +390,35 @@
                                uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION (this << *packet << dest << protocolNumber);
+  bool ret = false;
+  Address src;
+
+  ret = DoSend (packet, src, dest, protocolNumber, false);
+  return ret;
+}
+
+bool SixLowPanNetDevice::SendFrom (Ptr<Packet> packet,
+                                   const Address& src,
+                                   const Address& dest,
+                                   uint16_t protocolNumber)
+{
+  NS_LOG_FUNCTION (this << *packet << src << dest << protocolNumber);
+  bool ret = false;
+
+  ret = DoSend (packet, src, dest, protocolNumber, true);
+  return ret;
+}
+
+bool SixLowPanNetDevice::DoSend (Ptr<Packet> packet,
+                                 const Address& src,
+                                 const Address& dest,
+                                 uint16_t protocolNumber,
+                                 bool doSendFrom)
+{
+  NS_LOG_FUNCTION (this << *packet << src << dest << protocolNumber << doSendFrom);
   NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
 
+  Ptr<Packet> origPacket = packet->Copy ();
   uint32_t origHdrSize = 0;
   uint32_t origPacketSize = packet->GetSize ();
   bool ret = false;
@@ -414,66 +449,38 @@
         {
           NS_LOG_DEBUG ( "SixLowPanNetDevice::Send (Fragment) " << **it );
           m_txTrace (*it, m_node->GetObject<SixLowPanNetDevice> (), GetIfIndex ());
-          success &= m_netDevice->Send (*it, dest, protocolNumber);
+          if (doSendFrom)
+            {
+              success &= m_netDevice->SendFrom (*it, src, dest, protocolNumber);
+            }
+          else
+            {
+              success &= m_netDevice->Send (*it, dest, protocolNumber);
+            }
         }
       ret = success;
     }
   else
     {
-      NS_LOG_DEBUG ( "SixLowPanNetDevice::Send " << m_node->GetId () << " " << *packet );
-      m_txTrace (packet, m_node->GetObject<SixLowPanNetDevice> (), GetIfIndex ());
-      ret = m_netDevice->Send (packet, dest, protocolNumber);
-    }
-
-  return ret;
-}
-
-bool SixLowPanNetDevice::SendFrom (Ptr<Packet> packet,
-                                   const Address& src,
-                                   const Address& dest,
-                                   uint16_t protocolNumber)
-{
-  NS_LOG_FUNCTION (this << packet << src << dest << protocolNumber);
-  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
-
-  uint32_t origHdrSize = 0;
-  uint32_t origPacketSize = packet->GetSize ();
-  bool ret = false;
-
-  if (m_forceEtherType)
-    {
-      protocolNumber = m_etherType;
-    }
+      if (packet->GetSize () < m_compressionThreshold)
+        {
+          NS_LOG_LOGIC ("Compressed packet too short, using uncompressed one");
+          packet = origPacket;
+          SixLowPanIpv6 ipv6UncompressedHdr;
+          packet->AddHeader (ipv6UncompressedHdr);
+        }
 
-  if (m_useIphc)
-    {
-      origHdrSize += CompressLowPanIphc (packet, m_netDevice->GetAddress (), dest);
-    }
-  else
-    {
-      origHdrSize += CompressLowPanHc1 (packet, m_netDevice->GetAddress (), dest);
-    }
-
-  if ( packet->GetSize () > m_netDevice->GetMtu () )
-    {
-      // fragment
-      std::list<Ptr<Packet> > fragmentList;
-      DoFragmentation (packet, origPacketSize, origHdrSize, fragmentList);
-      std::list<Ptr<Packet> >::iterator it;
-      bool err = false;
-      for ( it = fragmentList.begin (); it != fragmentList.end (); it++ )
+      m_txTrace (packet, m_node->GetObject<SixLowPanNetDevice> (), GetIfIndex ());
+      if (doSendFrom)
         {
-          NS_LOG_DEBUG ( "SixLowPanNetDevice::SendFrom (Fragment) " << **it );
-          m_txTrace (*it, m_node->GetObject<SixLowPanNetDevice> (), GetIfIndex ());
-          err |= !(m_netDevice->SendFrom (*it, src, dest, protocolNumber));
+          NS_LOG_DEBUG ( "SixLowPanNetDevice::SendFrom " << m_node->GetId () << " " << *packet );
+          ret = m_netDevice->SendFrom (packet, src, dest, protocolNumber);
         }
-      ret = !err;
-    }
-  else
-    {
-      NS_LOG_DEBUG ( "SixLowPanNetDevice::SendFrom " << *packet );
-      m_txTrace (packet, m_node->GetObject<SixLowPanNetDevice> (), GetIfIndex ());
-      ret = m_netDevice->SendFrom (packet, src, dest, protocolNumber);
+      else
+        {
+          NS_LOG_DEBUG ( "SixLowPanNetDevice::Send " << m_node->GetId () << " " << *packet );
+          ret = m_netDevice->Send (packet, dest, protocolNumber);
+        }
     }
 
   return ret;
@@ -1814,10 +1821,12 @@
 
       switch ( dispatchValFrag1 )
         {
-        case SixLowPanDispatch::LOWPAN_NOTCOMPRESSED:
-          NS_LOG_DEBUG ( "Packet without compression:" << *p );
-          NS_LOG_DEBUG ( "Packet length:" << p->GetSize () );
-          break;
+        case SixLowPanDispatch::LOWPAN_IPv6:
+          {
+            SixLowPanIpv6 uncompressedHdr;
+            p->RemoveHeader(uncompressedHdr);
+          }
+         break;
         case SixLowPanDispatch::LOWPAN_HC1:
           DecompressLowPanHc1 (p, src, dst);
           break;
--- a/src/sixlowpan/model/sixlowpan-net-device.h	Sat Mar 15 17:04:02 2014 +0100
+++ b/src/sixlowpan/model/sixlowpan-net-device.h	Sat Mar 15 19:18:53 2014 +0100
@@ -175,6 +175,23 @@
   void ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
                           Address const &source, Address const &destination, PacketType packetType);
 
+
+  /**
+   * \param packet packet sent from above down to Network Device
+   * \param source source mac address (so called "MAC spoofing")
+   * \param dest mac address of the destination (already resolved)
+   * \param protocolNumber identifies the type of payload contained in
+   *        this packet. Used to call the right L3Protocol when the packet
+   *        is received.
+   * \param doSendFrom perform a SendFrom instead of a Send
+   *
+   *  Called from higher layer to send packet into Network Device
+   *  with the specified source and destination Addresses.
+   *
+   * \return whether the Send operation succeeded
+   */
+  bool DoSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber, bool doSendFrom);
+
   /**
    * The callback used to notify higher layers that a packet has been received.
    */
@@ -460,6 +477,8 @@
   uint16_t m_etherType; /**< EtherType number (used only if m_forceEtherType is true) */
   bool m_omitUdpChecksum; /**< Omit UDP checksum in NC1 encoding */
 
+  uint32_t m_compressionThreshold; /**< Minimum L2 payload size */
+
   Ptr<UniformRandomVariable> m_rng; //!< Rng for the fragments tag.
 };