bool SixLowPanNetDevice::DoSend()

in simulation/src/sixlowpan/model/sixlowpan-net-device.cc [538:674]


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;

  Address destination = dest;

  bool useMesh = m_meshUnder;

  if (m_forceEtherType)
    {
      protocolNumber = m_etherType;
    }

  if (m_useIphc)
    {
      NS_LOG_LOGIC ("Compressing packet using IPHC");
      origHdrSize += CompressLowPanIphc (packet, m_netDevice->GetAddress (), destination);
    }
  else
    {
      NS_LOG_LOGIC ("Compressing packet using HC1");
      origHdrSize += CompressLowPanHc1 (packet, m_netDevice->GetAddress (), destination);
    }

  uint16_t pktSize = packet->GetSize ();

  SixLowPanMesh meshHdr;
  SixLowPanBc0 bc0Hdr;
  uint32_t extraHdrSize = 0;

  if (useMesh)
    {
      Address source = src;
      if (!doSendFrom)
        {
          source = m_netDevice->GetAddress ();
        }

      if (Mac48Address::IsMatchingType (source))
        {
          // We got a Mac48 pseudo-MAC. We need its original Mac16 here.
          source = Get16MacFrom48Mac (source);
        }
      if (Mac48Address::IsMatchingType (destination))
        {
          // We got a Mac48 pseudo-MAC. We need its original Mac16 here.
          destination = Get16MacFrom48Mac (destination);
        }

      meshHdr.SetOriginator (source);
      meshHdr.SetFinalDst (destination);
      meshHdr.SetHopsLeft (m_meshUnderHopsLeft);
      destination = m_netDevice->GetBroadcast ();
      // We are storing sum of mesh and bc0 header sizes. We will need it if packet is fragmented.
      extraHdrSize = meshHdr.GetSerializedSize () + bc0Hdr.GetSerializedSize ();
      pktSize +=  extraHdrSize;
    }

  if (pktSize < m_compressionThreshold)
    {
      NS_LOG_LOGIC ("Compressed packet too short, using uncompressed one");
      packet = origPacket;
      SixLowPanIpv6 ipv6UncompressedHdr;
      packet->AddHeader (ipv6UncompressedHdr);
      pktSize = packet->GetSize ();
      if (useMesh)
        {
          pktSize += meshHdr.GetSerializedSize () + bc0Hdr.GetSerializedSize ();
        }
    }


  if (pktSize > m_netDevice->GetMtu ())
    {
      NS_LOG_LOGIC ("Fragmentation: Packet size " << packet->GetSize () << " - Mtu " << m_netDevice->GetMtu () );
      // fragment
      std::list<Ptr<Packet> > fragmentList;
      DoFragmentation (packet, origPacketSize, origHdrSize, extraHdrSize, fragmentList);
      std::list<Ptr<Packet> >::iterator it;
      bool success = true;
      for ( it = fragmentList.begin (); it != fragmentList.end (); it++ )
        {
          NS_LOG_DEBUG ( "SixLowPanNetDevice::Send (Fragment) " << **it );
          m_txTrace (*it, this, GetIfIndex ());

          if (useMesh)
            {
              bc0Hdr.SetSequenceNumber (m_bc0Serial++);
              (*it)->AddHeader (bc0Hdr);
              (*it)->AddHeader (meshHdr);
            }
          if (doSendFrom)
            {
              success &= m_netDevice->SendFrom (*it, src, destination, protocolNumber);
            }
          else
            {
              success &= m_netDevice->Send (*it, destination, protocolNumber);
            }
        }
      ret = success;
    }
  else
    {
      m_txTrace (packet, this, GetIfIndex ());

      if (useMesh)
        {
          bc0Hdr.SetSequenceNumber (m_bc0Serial++);
          packet->AddHeader (bc0Hdr);
          packet->AddHeader (meshHdr);
        }

      if (doSendFrom)
        {
          NS_LOG_DEBUG ( "SixLowPanNetDevice::SendFrom " << m_node->GetId () << " " << *packet );
          ret = m_netDevice->SendFrom (packet, src, destination, protocolNumber);
        }
      else
        {
          NS_LOG_DEBUG ( "SixLowPanNetDevice::Send " << m_node->GetId () << " " << *packet );
          ret = m_netDevice->Send (packet, destination, protocolNumber);
        }
    }

  return ret;
}