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