void ChildSupervisor::SendMessage(Child &aChild)
{
    Message *message = NULL;
    uint8_t  childIndex;

    VerifyOrExit(aChild.GetIndirectMessageCount() == 0);

    message = Get<MessagePool>().New(Message::kTypeSupervision, sizeof(uint8_t));
    VerifyOrExit(message != NULL);

    // Supervision message is an empty payload 15.4 data frame.
    // The child index is stored here in the message content to allow
    // the destination of the message to be later retrieved using
    // `ChildSupervisor::GetDestination(message)`.

    childIndex = Get<ChildTable>().GetChildIndex(aChild);
    SuccessOrExit(message->Append(&childIndex, sizeof(childIndex)));

    SuccessOrExit(Get<ThreadNetif>().SendMessage(*message));
    message = NULL;

    otLogInfoUtil("Sending supervision message to child 0x%04x", aChild.GetRloc16());

exit:

    if (message != NULL)
    {
        message->Free();
    }
}
void ChildSupervisor::SendMessage(Child &aChild)
{
    ThreadNetif &netif = GetNetif();
    Message *message = NULL;
    otError error = OT_ERROR_NONE;
    uint8_t childIndex;

    VerifyOrExit(aChild.GetIndirectMessageCount() == 0);

    message = netif.GetInstance().mMessagePool.New(Message::kTypeSupervision, sizeof(uint8_t));
    VerifyOrExit(message != NULL);

    // Supervision message is an empty payload 15.4 data frame.
    // The child index is stored here in the message content to allow
    // the destination of the message to be later retrieved using
    // `ChildSupervisor::GetDestination(message)`.

    childIndex = netif.GetMle().GetChildIndex(aChild);
    SuccessOrExit(error = message->Append(&childIndex, sizeof(childIndex)));

    SuccessOrExit(error = netif.SendMessage(*message));
    message = NULL;

    otLogInfoMle(GetInstance(), "Sending supervision message to child 0x%04x", aChild.GetRloc16());

exit:

    if (message != NULL)
    {
        message->Free();
    }
}
otError SourceMatchController::AddAddress(const Child &aChild)
{
    otError error = OT_ERROR_NONE;

    if (aChild.IsIndirectSourceMatchShort())
    {
        error = otPlatRadioAddSrcMatchShortEntry(&GetInstance(), aChild.GetRloc16());

        otLogDebgMac(GetInstance(), "SrcAddrMatch - Adding short addr: 0x%04x -- %s (%d)", aChild.GetRloc16(),
                     otThreadErrorToString(error), error);
    }
    else
    {
        otExtAddress addr;

        for (uint8_t i = 0; i < sizeof(addr); i++)
        {
            addr.m8[i] = aChild.GetExtAddress().m8[sizeof(addr) - 1 - i];
        }

        error = otPlatRadioAddSrcMatchExtEntry(&GetInstance(), &addr);

        otLogDebgMac(GetInstance(), "SrcAddrMatch - Adding addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x -- %s (%d)",
                     addr.m8[7], addr.m8[6], addr.m8[5], addr.m8[4], addr.m8[3], addr.m8[2], addr.m8[1], addr.m8[0],
                     otThreadErrorToString(error), error);
    }

    return error;
}
void SourceMatchController::ClearEntry(Child &aChild)
{
    otError error = OT_ERROR_NONE;

    if (aChild.IsIndirectSourceMatchPending())
    {
        otLogDebgMac(GetInstance(), "SrcAddrMatch - Clearing pending flag for 0x%04x", aChild.GetRloc16());
        aChild.SetIndirectSourceMatchPending(false);
        ExitNow();
    }

    if (aChild.IsIndirectSourceMatchShort())
    {
        error = otPlatRadioClearSrcMatchShortEntry(&GetInstance(), aChild.GetRloc16());

        otLogDebgMac(GetInstance(), "SrcAddrMatch - Clearing short address: 0x%04x -- %s (%d)", aChild.GetRloc16(),
                     otThreadErrorToString(error), error);
    }
    else
    {
        otExtAddress addr;

        for (uint8_t i = 0; i < sizeof(addr); i++)
        {
            addr.m8[i] = aChild.GetExtAddress().m8[sizeof(aChild.GetExtAddress()) - 1 - i];
        }

        error = otPlatRadioClearSrcMatchExtEntry(&GetInstance(), &addr);

        otLogDebgMac(GetInstance(), "SrcAddrMatch - Clearing addr: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x -- %s (%d)",
                     addr.m8[7], addr.m8[6], addr.m8[5], addr.m8[4], addr.m8[3], addr.m8[2], addr.m8[1], addr.m8[0],
                     otThreadErrorToString(error), error);
    }

    SuccessOrExit(error);

    if (!IsEnabled())
    {
        SuccessOrExit(AddPendingEntries());
        Enable(true);
    }

exit:
    return;
}
void SourceMatchController::DecrementMessageCount(Child &aChild)
{
    if (aChild.GetIndirectMessageCount() == 0)
    {
        otLogWarnMac(GetInstance(), "DecrementMessageCount(child 0x%04x) called when already at zero count.",
                     aChild.GetRloc16());
        ExitNow();
    }

    aChild.DecrementIndirectMessageCount();

    if (aChild.GetIndirectMessageCount() == 0)
    {
        ClearEntry(aChild);
    }

exit:
    return;
}
Beispiel #6
0
// Checks whether a `Child` matches the `TestChild` struct.
static bool ChildMatches(const Child &aChild, const TestChild &aTestChild)
{
    return (aChild.GetState() == aTestChild.mState) && (aChild.GetRloc16() == aTestChild.mRloc16) &&
           (aChild.GetExtAddress() == static_cast<const Mac::ExtAddress &>(aTestChild.mExtAddress));
}