void SixLowPanNetDevice::ReceiveFromDevice()

in simulation/src/sixlowpan/model/sixlowpan-net-device.cc [191:382]


void SixLowPanNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort,
                                            Ptr<const Packet> packet,
                                            uint16_t protocol,
                                            Address const &src,
                                            Address const &dst,
                                            PacketType packetType)
{
  NS_LOG_FUNCTION (this << incomingPort << packet << protocol << src << dst);

  uint8_t dispatchRawVal = 0;
  SixLowPanDispatch::Dispatch_e dispatchVal;
  Ptr<Packet> copyPkt = packet->Copy ();

  m_rxTrace (copyPkt, this, GetIfIndex ());

  copyPkt->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
  dispatchVal = SixLowPanDispatch::GetDispatchType (dispatchRawVal);
  bool isPktDecompressed = false;
  bool fragmented = false;

  NS_LOG_DEBUG ( "Packet received: " << *copyPkt );
  NS_LOG_DEBUG ( "Packet length: " << copyPkt->GetSize () );
  NS_LOG_DEBUG ( "Dispatches: " << int(dispatchRawVal) << " - " << int(dispatchVal) );

  SixLowPanMesh meshHdr;
  SixLowPanBc0 bc0Hdr;
  bool hasMesh = false;
  bool hasBc0 = false;

  if ( dispatchVal == SixLowPanDispatch::LOWPAN_MESH )
    {
      hasMesh = true;
      copyPkt->RemoveHeader (meshHdr);
      copyPkt->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
      dispatchVal = SixLowPanDispatch::GetDispatchType (dispatchRawVal);
    }
  if ( dispatchVal == SixLowPanDispatch::LOWPAN_BC0 )
    {
      hasBc0 = true;
      copyPkt->RemoveHeader (bc0Hdr);
      copyPkt->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
      dispatchVal = SixLowPanDispatch::GetDispatchType (dispatchRawVal);
    }

  if (hasMesh)
    {
      if (!hasBc0)
        {
          NS_LOG_LOGIC ("Dropped packet - we only support mesh if it is paired with a BC0");
          m_dropTrace (DROP_UNKNOWN_EXTENSION, copyPkt, this, GetIfIndex ());
          return;
        }

      if (find (m_seenPkts[meshHdr.GetOriginator ()].begin (),
                m_seenPkts[meshHdr.GetOriginator ()].end (),
                bc0Hdr.GetSequenceNumber ()) != m_seenPkts[meshHdr.GetOriginator ()].end ())
        {
          NS_LOG_LOGIC ("We have already seen this, no further processing.");
          return;
        }

      m_seenPkts[meshHdr.GetOriginator ()].push_back (bc0Hdr.GetSequenceNumber ());
      if (m_seenPkts[meshHdr.GetOriginator ()].size () > m_meshCacheLength)
        {
          m_seenPkts[meshHdr.GetOriginator ()].pop_front ();
        }

      NS_ABORT_MSG_IF (!Mac16Address::IsMatchingType (meshHdr.GetFinalDst ()), "SixLowPan mesh-under flooding can not currently handle extended address final destinations: " << meshHdr.GetFinalDst ());
      NS_ABORT_MSG_IF (!Mac48Address::IsMatchingType (m_netDevice->GetAddress ()), "SixLowPan mesh-under flooding can not currently handle devices using extended addresses: " << m_netDevice->GetAddress ());

      Mac16Address finalDst = Mac16Address::ConvertFrom (meshHdr.GetFinalDst ());

      // See if the packet is for others than me. In case forward it.
      if (meshHdr.GetFinalDst () != Get16MacFrom48Mac (m_netDevice->GetAddress ())
          || finalDst.IsBroadcast ()
          || finalDst.IsMulticast ()
          )
        {
          uint8_t hopsLeft = meshHdr.GetHopsLeft ();

          if (hopsLeft == 0)
            {
              NS_LOG_LOGIC ("Not forwarding packet -- hop limit reached");
            }
          else if (meshHdr.GetOriginator () == Get16MacFrom48Mac (m_netDevice->GetAddress ()))
            {
              NS_LOG_LOGIC ("Not forwarding packet -- I am the originator");
            }
          else
            {
              meshHdr.SetHopsLeft (hopsLeft - 1);
              Ptr<Packet> sendPkt = copyPkt->Copy ();
              sendPkt->AddHeader (bc0Hdr);
              sendPkt->AddHeader (meshHdr);
              Simulator::Schedule (Time (MilliSeconds (m_meshUnderJitter->GetValue ())), &NetDevice::Send, m_netDevice, sendPkt, m_netDevice->GetBroadcast (), protocol);
            }

          if (!finalDst.IsBroadcast () && !finalDst.IsMulticast ())
            {
              return;
            }
        }
    }

  Address realDst = dst;
  Address realSrc = src;
  if (hasMesh)
    {
      realSrc = meshHdr.GetOriginator ();
      realDst = meshHdr.GetFinalDst ();
    }

  if ( dispatchVal == SixLowPanDispatch::LOWPAN_FRAG1 )
    {
      isPktDecompressed = ProcessFragment (copyPkt, realSrc, realDst, true);
      fragmented = true;
    }
  else if ( dispatchVal == SixLowPanDispatch::LOWPAN_FRAGN )
    {
      isPktDecompressed = ProcessFragment (copyPkt, realSrc, realDst, false);
      fragmented = true;
    }
  if ( fragmented )
    {
      if ( !isPktDecompressed )
        {
          return;
        }
      else
        {
          copyPkt->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
          dispatchVal = SixLowPanDispatch::GetDispatchType (dispatchRawVal);
        }
    }

  switch ( dispatchVal )
    {
    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:
      if (m_useIphc)
        {
          m_dropTrace (DROP_DISALLOWED_COMPRESSION, copyPkt, this, GetIfIndex ());
          return;
        }
      DecompressLowPanHc1 (copyPkt, realSrc, realDst);
      isPktDecompressed = true;
      break;
    case SixLowPanDispatch::LOWPAN_IPHC:
      if (!m_useIphc)
        {
          m_dropTrace (DROP_DISALLOWED_COMPRESSION, copyPkt, this, GetIfIndex ());
          return;
        }
      if (DecompressLowPanIphc (copyPkt, realSrc, realDst))
        {
          m_dropTrace (DROP_SATETFUL_DECOMPRESSION_PROBLEM, copyPkt, this, GetIfIndex ());
        }
      else
        {
          isPktDecompressed = true;
        }
      break;
    default:
      NS_LOG_DEBUG ("Unsupported 6LoWPAN encoding: dropping.");
      m_dropTrace (DROP_UNKNOWN_EXTENSION, copyPkt, this, GetIfIndex ());
      break;
    }

  if ( !isPktDecompressed )
    {
      return;
    }

  NS_LOG_DEBUG ( "Packet decompressed length: " << copyPkt->GetSize () );
  NS_LOG_DEBUG ( "Packet decompressed received: " << *copyPkt );

  if (!m_promiscRxCallback.IsNull ())
    {
      m_promiscRxCallback (this, copyPkt, Ipv6L3Protocol::PROT_NUMBER, realSrc, realDst, packetType);
    }

  m_rxCallback (this, copyPkt, Ipv6L3Protocol::PROT_NUMBER, realSrc);

  return;
}