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;
}