Exemplo n.º 1
0
otError Netif::GetNextExternalMulticast(uint8_t &aIterator, Address &aAddress)
{
    otError                error = OT_ERROR_NOT_FOUND;
    size_t                 num   = sizeof(mExtMulticastAddresses) / sizeof(mExtMulticastAddresses[0]);
    NetifMulticastAddress *entry;

    VerifyOrExit(aIterator < num);

    // Find an available entry in the `mExtMulticastAddresses` array.
    for (uint8_t i = aIterator; i < num; i++)
    {
        entry = &mExtMulticastAddresses[i];

        // In an unused/available entry, `mNext` points back to the entry itself.
        if (entry->mNext != entry)
        {
            aAddress  = entry->GetAddress();
            aIterator = i + 1;
            ExitNow(error = OT_ERROR_NONE);
        }
    }

exit:
    return error;
}
Exemplo n.º 2
0
ThreadError Netif::UnsubscribeMulticast(const NetifMulticastAddress &aAddress)
{
    ThreadError error = kThreadError_None;

    if (mMulticastAddresses == &aAddress)
    {
        mMulticastAddresses = mMulticastAddresses->GetNext();
        ExitNow();
    }
    else if (mMulticastAddresses != NULL)
    {
        for (NetifMulticastAddress *cur = mMulticastAddresses; cur->GetNext(); cur = cur->GetNext())
        {
            if (cur->mNext == &aAddress)
            {
                cur->mNext = aAddress.mNext;
                ExitNow();
            }
        }
    }

    ExitNow(error = kThreadError_Error);

exit:
    return error;
}
Exemplo n.º 3
0
bool Netif::IsMulticastSubscribed(const Address &aAddress) const
{
    bool rval = false;

    if (aAddress.IsLinkLocalAllNodesMulticast() || aAddress.IsRealmLocalAllNodesMulticast() ||
        aAddress.IsRealmLocalAllMplForwarders())
    {
        ExitNow(rval = true);
    }
    else if (aAddress.IsLinkLocalAllRoutersMulticast() || aAddress.IsRealmLocalAllRoutersMulticast())
    {
        ExitNow(rval = mAllRoutersSubscribed);
    }

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (memcmp(&cur->mAddress, &aAddress, sizeof(cur->mAddress)) == 0)
        {
            ExitNow(rval = true);
        }
    }

exit:
    return rval;
}
Exemplo n.º 4
0
otError Netif::UnsubscribeMulticast(const NetifMulticastAddress &aAddress)
{
    otError error = OT_ERROR_NONE;

    if (mMulticastAddresses == &aAddress)
    {
        mMulticastAddresses = mMulticastAddresses->GetNext();
        ExitNow();
    }
    else if (mMulticastAddresses != NULL)
    {
        for (NetifMulticastAddress *cur = mMulticastAddresses; cur->GetNext(); cur = cur->GetNext())
        {
            if (cur->mNext == &aAddress)
            {
                cur->mNext = aAddress.mNext;
                ExitNow();
            }
        }
    }

    ExitNow(error = OT_ERROR_NOT_FOUND);

exit:

    if (error != OT_ERROR_NOT_FOUND)
    {
        GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED);
    }

    return error;
}
Exemplo n.º 5
0
otError Netif::UnsubscribeAllRoutersMulticast(void)
{
    otError error = OT_ERROR_NONE;

    if (mMulticastAddresses == &kLinkLocalAllRoutersMulticastAddress)
    {
        mMulticastAddresses = static_cast<NetifMulticastAddress *>(
            const_cast<otNetifMulticastAddress *>(&kLinkLocalAllNodesMulticastAddress));
        ExitNow();
    }

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (cur->mNext == &kLinkLocalAllRoutersMulticastAddress)
        {
            cur->mNext = &kLinkLocalAllNodesMulticastAddress;
            ExitNow();
        }
    }

    error = OT_ERROR_NOT_FOUND;

exit:

    if (error != OT_ERROR_NOT_FOUND)
    {
        GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED);
    }

    return error;
}
Exemplo n.º 6
0
otError Netif::SubscribeAllRoutersMulticast(void)
{
    otError error = OT_ERROR_NONE;

    if (mMulticastAddresses == &kLinkLocalAllNodesMulticastAddress)
    {
        mMulticastAddresses = static_cast<NetifMulticastAddress *>(
            const_cast<otNetifMulticastAddress *>(&kLinkLocalAllRoutersMulticastAddress));
    }
    else
    {
        for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
        {
            if (cur == &kLinkLocalAllRoutersMulticastAddress)
            {
                ExitNow(error = OT_ERROR_ALREADY);
            }

            if (cur->mNext == &kLinkLocalAllNodesMulticastAddress)
            {
                cur->mNext = &kLinkLocalAllRoutersMulticastAddress;
                break;
            }
        }
    }

    GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED);

exit:
    return error;
}
Exemplo n.º 7
0
void Netif::UnsubscribeAllExternalMulticastAddresses(void)
{
    size_t num = sizeof(mExtMulticastAddresses) / sizeof(mExtMulticastAddresses[0]);

    for (NetifMulticastAddress *entry = &mExtMulticastAddresses[0]; num > 0; num--, entry++)
    {
        // In unused entries, the `mNext` points back to the entry itself.
        if (entry->mNext != entry)
        {
            UnsubscribeExternalMulticast(entry->GetAddress());
        }
    }
}
Exemplo n.º 8
0
bool Netif::IsMulticastSubscribed(const Address &aAddress) const
{
    bool rval = false;

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (cur->GetAddress() == aAddress)
        {
            ExitNow(rval = true);
        }
    }

exit:
    return rval;
}
Exemplo n.º 9
0
ThreadError Netif::SubscribeMulticast(NetifMulticastAddress &aAddress)
{
    ThreadError error = kThreadError_None;

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (cur == &aAddress)
        {
            ExitNow(error = kThreadError_Already);
        }
    }

    aAddress.mNext = mMulticastAddresses;
    mMulticastAddresses = &aAddress;

exit:
    return error;
}
Exemplo n.º 10
0
otError Netif::SubscribeMulticast(NetifMulticastAddress &aAddress)
{
    otError error = OT_ERROR_NONE;

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (cur == &aAddress)
        {
            ExitNow(error = OT_ERROR_ALREADY);
        }
    }

    aAddress.mNext      = mMulticastAddresses;
    mMulticastAddresses = &aAddress;
    GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_SUBSRCRIBED);

exit:
    return error;
}
Exemplo n.º 11
0
ThreadError Netif::UnsubscribeExternalMulticast(const Address &aAddress)
{
    ThreadError error = kThreadError_None;
    NetifMulticastAddress *last = NULL;
    int8_t aAddressIndexToRemove = -1;

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (memcmp(&cur->mAddress, &aAddress, sizeof(otIp6Address)) == 0)
        {
            aAddressIndexToRemove = GetExtMulticastAddressIndex(cur);
            VerifyOrExit(aAddressIndexToRemove != -1, error = kThreadError_InvalidArgs);

            if (last)
            {
                last->mNext = cur->GetNext();
            }
            else
            {
                mMulticastAddresses = cur->GetNext();
            }

            break;
        }

        last = cur;
    }

    if (aAddressIndexToRemove != -1)
    {
        mMaskExtMulticastAddresses &= ~(1 << aAddressIndexToRemove);
    }
    else
    {
        error = kThreadError_NotFound;
    }

exit:

    return error;
}
Exemplo n.º 12
0
otError Netif::UnsubscribeExternalMulticast(const Address &aAddress)
{
    otError                error = OT_ERROR_NONE;
    NetifMulticastAddress *entry;
    NetifMulticastAddress *last = NULL;
    size_t                 num  = sizeof(mExtMulticastAddresses) / sizeof(mExtMulticastAddresses[0]);

    for (entry = mMulticastAddresses; entry; entry = entry->GetNext())
    {
        if (entry->GetAddress() == aAddress)
        {
            VerifyOrExit((entry >= &mExtMulticastAddresses[0]) && (entry < &mExtMulticastAddresses[num]),
                         error = OT_ERROR_INVALID_ARGS);

            if (last)
            {
                last->mNext = entry->GetNext();
            }
            else
            {
                mMulticastAddresses = entry->GetNext();
            }

            break;
        }

        last = entry;
    }

    VerifyOrExit(entry != NULL, error = OT_ERROR_NOT_FOUND);

    // To mark the address entry as unused/available, set the `mNext` pointer back to the entry itself.
    entry->mNext = entry;

    GetNotifier().SetFlags(OT_CHANGED_IP6_MULTICAST_UNSUBSRCRIBED);

exit:
    return error;
}
Exemplo n.º 13
0
ThreadError Netif::SubscribeExternalMulticast(const Address &aAddress)
{
    ThreadError error = kThreadError_None;
    int8_t index = 0;

    for (NetifMulticastAddress *cur = mMulticastAddresses; cur; cur = cur->GetNext())
    {
        if (memcmp(&cur->mAddress, &aAddress, sizeof(otIp6Address)) == 0)
        {
            VerifyOrExit(GetExtMulticastAddressIndex(cur) != -1, error = kThreadError_InvalidArgs);
            ExitNow(error = kThreadError_Already);
        }
    }

    // Make sure we haven't set all the bits in the mask already
    VerifyOrExit(mMaskExtMulticastAddresses != ((1 << OPENTHREAD_CONFIG_MAX_EXT_MULTICAST_IP_ADDRS) - 1),
                 error = kThreadError_NoBufs);

    // Get next available entry index
    while ((mMaskExtMulticastAddresses & (1 << index)) != 0)
    {
        index++;
    }

    assert(index < OPENTHREAD_CONFIG_MAX_EXT_MULTICAST_IP_ADDRS);

    // Increase the count and mask the index
    mMaskExtMulticastAddresses |= 1 << index;

    // Copy the address to the next available dynamic address
    mExtMulticastAddresses[index].mAddress = aAddress;
    mExtMulticastAddresses[index].mNext = mMulticastAddresses;

    mMulticastAddresses = &mExtMulticastAddresses[index];

exit:
    return error;
}