mirror of
https://github.com/espressif/openthread.git
synced 2026-08-21 09:59:52 +00:00
[mesh-forwarder] simplify multicast forward to sleepy children (#9505)
This commit simplifies the `MeshForwarder::SendMessage()` method and its logic for determining whether to send a multicast message to sleepy children. We first determine whether the destination address is link-local or realm-local all-nodes, meaning it is destined to all nodes. Otherwise, we need to check whether each sleepy child is subscribed to the address. We then iterate through the child table and mark the message for indirect transmission accordingly.
This commit is contained in:
@@ -48,8 +48,7 @@ RegisterLogModule("MeshForwarder");
|
||||
|
||||
Error MeshForwarder::SendMessage(Message &aMessage)
|
||||
{
|
||||
Mle::MleRouter &mle = Get<Mle::MleRouter>();
|
||||
Error error = kErrorNone;
|
||||
Error error = kErrorNone;
|
||||
|
||||
aMessage.SetOffset(0);
|
||||
aMessage.SetDatagramTag(0);
|
||||
@@ -60,57 +59,48 @@ Error MeshForwarder::SendMessage(Message &aMessage)
|
||||
{
|
||||
case Message::kTypeIp6:
|
||||
{
|
||||
Ip6::Header ip6Header;
|
||||
Ip6::Header ip6Header;
|
||||
const Ip6::Address &destination = ip6Header.GetDestination();
|
||||
|
||||
IgnoreError(aMessage.Read(0, ip6Header));
|
||||
|
||||
if (ip6Header.GetDestination().IsMulticast())
|
||||
if (destination.IsMulticast())
|
||||
{
|
||||
// For traffic destined to multicast address larger than realm local, generally it uses IP-in-IP
|
||||
// encapsulation (RFC2473), with outer destination as ALL_MPL_FORWARDERS. So here if the destination
|
||||
// is multicast address larger than realm local, it should be for indirection transmission for the
|
||||
// device's sleepy child, thus there should be no direct transmission.
|
||||
if (!ip6Header.GetDestination().IsMulticastLargerThanRealmLocal())
|
||||
if (!destination.IsMulticastLargerThanRealmLocal())
|
||||
{
|
||||
// schedule direct transmission
|
||||
aMessage.SetDirectTransmission();
|
||||
}
|
||||
|
||||
if (aMessage.GetSubType() != Message::kSubTypeMplRetransmission)
|
||||
{
|
||||
if (ip6Header.GetDestination() == mle.GetLinkLocalAllThreadNodesAddress() ||
|
||||
ip6Header.GetDestination() == mle.GetRealmLocalAllThreadNodesAddress())
|
||||
// Check if we need to forward the multicast message
|
||||
// to any sleepy child. This is skipped for MPL retx
|
||||
// (only the first MPL transmission is forwarded to
|
||||
// sleepy children).
|
||||
|
||||
bool destinedForAll = ((destination == Get<Mle::Mle>().GetLinkLocalAllThreadNodesAddress()) ||
|
||||
(destination == Get<Mle::Mle>().GetRealmLocalAllThreadNodesAddress()));
|
||||
|
||||
for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
|
||||
{
|
||||
// destined for all sleepy children
|
||||
for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
|
||||
if (!child.IsRxOnWhenIdle() && (destinedForAll || child.HasIp6Address(destination)))
|
||||
{
|
||||
if (!child.IsRxOnWhenIdle())
|
||||
{
|
||||
mIndirectSender.AddMessageForSleepyChild(aMessage, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// destined for some sleepy children which subscribed the multicast address.
|
||||
for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
|
||||
{
|
||||
if (!child.IsRxOnWhenIdle() && child.HasIp6Address(ip6Header.GetDestination()))
|
||||
{
|
||||
mIndirectSender.AddMessageForSleepyChild(aMessage, child);
|
||||
}
|
||||
mIndirectSender.AddMessageForSleepyChild(aMessage, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Destination is unicast
|
||||
{
|
||||
Neighbor *neighbor = Get<NeighborTable>().FindNeighbor(ip6Header.GetDestination());
|
||||
Neighbor *neighbor = Get<NeighborTable>().FindNeighbor(destination);
|
||||
|
||||
if ((neighbor != nullptr) && !neighbor->IsRxOnWhenIdle() && !aMessage.IsDirectTransmission() &&
|
||||
Get<ChildTable>().Contains(*neighbor))
|
||||
{
|
||||
// Destined for a sleepy child
|
||||
mIndirectSender.AddMessageForSleepyChild(aMessage, *static_cast<Child *>(neighbor));
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user