void Mpl::InitOption(OptionMpl &aOption, uint16_t aSeed) { aOption.Init(); aOption.SetSeedLength(OptionMpl::kSeedLength2); aOption.SetSequence(mSequence++); aOption.SetSeed(aSeed); }
otError Mpl::ProcessOption(Message &aMessage, const Address &aAddress, bool aIsOutbound) { otError error; OptionMpl option; VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(option), &option) >= OptionMpl::kMinLength && (option.GetSeedIdLength() == OptionMpl::kSeedIdLength0 || option.GetSeedIdLength() == OptionMpl::kSeedIdLength2), error = OT_ERROR_DROP); if (option.GetSeedIdLength() == OptionMpl::kSeedIdLength0) { // Retrieve MPL Seed Id from the IPv6 Source Address. option.SetSeedId(HostSwap16(aAddress.mFields.m16[7])); } // Check MPL Data Messages in the MPL Buffered Set against sequence number. UpdateBufferedSet(option.GetSeedId(), option.GetSequence()); // Check if the MPL Data Message is new. error = UpdateSeedSet(option.GetSeedId(), option.GetSequence()); if (error == OT_ERROR_NONE) { AddBufferedMessage(aMessage, option.GetSeedId(), option.GetSequence(), aIsOutbound); } else if (aIsOutbound) { // In case MPL Data Message is generated locally, ignore potential error of the MPL Seed Set // to allow subsequent retransmissions with the same sequence number. ExitNow(error = OT_ERROR_NONE); } exit: return error; }
void Mpl::InitOption(OptionMpl &aOption, const Address &aAddress) { aOption.Init(); aOption.SetSequence(mSequence++); // Check if Seed Id can be elided. if (mMatchingAddress && aAddress == *mMatchingAddress) { aOption.SetSeedIdLength(OptionMpl::kSeedIdLength0); // Decrease default option length. aOption.SetLength(aOption.GetLength() - sizeof(mSeedId)); } else { aOption.SetSeedIdLength(OptionMpl::kSeedIdLength2); aOption.SetSeedId(mSeedId); } }
ThreadError Mpl::ProcessOption(const Message &aMessage) { ThreadError error = kThreadError_None; OptionMpl option; MplEntry *entry = NULL; int8_t diff; VerifyOrExit(aMessage.Read(aMessage.GetOffset(), sizeof(option), &option) == sizeof(option) && option.GetLength() == sizeof(OptionMpl) - sizeof(OptionHeader), error = kThreadError_Drop); for (int i = 0; i < kNumEntries; i++) { if (mEntries[i].mLifetime == 0) { entry = &mEntries[i]; } else if (mEntries[i].mSeed == option.GetSeed()) { entry = &mEntries[i]; diff = option.GetSequence() - entry->mSequence; if (diff <= 0) { error = kThreadError_Drop; } break; } } VerifyOrExit(entry != NULL, error = kThreadError_Drop); entry->mSeed = option.GetSeed(); entry->mSequence = option.GetSequence(); entry->mLifetime = kLifetime; mTimer.Start(1000); exit: return error; }