blob: a035cfdaaefa1264c3dc521b519b1c3ff6deb0b3 [file] [log] [blame]
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef IP6_MPL_HPP_
#define IP6_MPL_HPP_
/**
* @file
* This file includes definitions for MPL.
*/
#include <openthread/types.h>
#include "common/locator.hpp"
#include "common/message.hpp"
#include "common/timer.hpp"
#include "net/ip6_headers.hpp"
namespace ot {
namespace Ip6 {
/**
* @addtogroup core-ip6-mpl
*
* @brief
* This module includes definitions for MPL.
*
* @{
*
*/
/**
* This class implements MPL header generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class OptionMpl: public OptionHeader
{
public:
enum
{
kType = 0x6d, /* 01 1 01101 */
kMinLength = 2
};
/**
* This method initializes the MPL header.
*
*/
void Init(void) {
OptionHeader::SetType(kType);
OptionHeader::SetLength(sizeof(*this) - sizeof(OptionHeader));
mControl = 0;
}
/**
* This method returns the total MPL Option length value including option
* header.
*
* @returns The total IPv6 Option Length.
*
*/
uint8_t GetTotalLength(void) const { return OptionHeader::GetLength() + sizeof(OptionHeader); }
/**
* MPL Seed Id lengths.
*/
enum SeedIdLength
{
kSeedIdLength0 = 0 << 6, ///< 0-byte MPL Seed Id Length.
kSeedIdLength2 = 1 << 6, ///< 2-byte MPL Seed Id Length.
kSeedIdLength8 = 2 << 6, ///< 8-byte MPL Seed Id Length.
kSeedIdLength16 = 3 << 6, ///< 16-byte MPL Seed Id Length.
};
/**
* This method returns the MPL Seed Id Length value.
*
* @returns The MPL Seed Id Length value.
*
*/
SeedIdLength GetSeedIdLength(void) { return static_cast<SeedIdLength>(mControl & kSeedIdLengthMask); }
/**
* This method sets the MPL Seed Id Length value.
*
* @param[in] aSeedIdLength The MPL Seed Length.
*
*/
void SetSeedIdLength(SeedIdLength aSeedIdLength) { mControl = static_cast<uint8_t>((mControl & ~kSeedIdLengthMask) | aSeedIdLength); }
/**
* This method indicates whether or not the MPL M flag is set.
*
* @retval TRUE If the MPL M flag is set.
* @retval FALSE If the MPL M flag is not set.
*
*/
bool IsMaxFlagSet(void) { return (mControl & kMaxFlag) != 0; }
/**
* This method clears the MPL M flag.
*
*/
void ClearMaxFlag(void) { mControl &= ~kMaxFlag; }
/**
* This method sets the MPL M flag.
*
*/
void SetMaxFlag(void) { mControl |= kMaxFlag; }
/**
* This method returns the MPL Sequence value.
*
* @returns The MPL Sequence value.
*
*/
uint8_t GetSequence(void) const { return mSequence; }
/**
* This method sets the MPL Sequence value.
*
* @param[in] aSequence The MPL Sequence value.
*
*/
void SetSequence(uint8_t aSequence) { mSequence = aSequence; }
/**
* This method returns the MPL Seed Id value.
*
* @returns The MPL Seed Id value.
*
*/
uint16_t GetSeedId(void) const { return HostSwap16(mSeedId); }
/**
* This method sets the MPL Seed Id value.
*
* @param[in] aSeedId The MPL Seed Id value.
*
*/
void SetSeedId(uint16_t aSeedId) { mSeedId = HostSwap16(aSeedId); }
private:
enum
{
kSeedIdLengthMask = 3 << 6,
kMaxFlag = 1 << 5
};
uint8_t mControl;
uint8_t mSequence;
uint16_t mSeedId;
} OT_TOOL_PACKED_END;
/**
* This class represents an MPL's Seed Set entry.
*
*/
class MplSeedEntry
{
public:
/**
* This method returns the MPL Seed Id value.
*
* @returns The MPL Seed Id value.
*
*/
uint16_t GetSeedId(void) const { return mSeedId; }
/**
* This method sets the MPL Seed Id value.
*
* @param[in] aSeedId The MPL Seed Id value.
*
*/
void SetSeedId(uint16_t aSeedId) { mSeedId = aSeedId; }
/**
* This method returns the MPL Sequence value.
*
* @returns The MPL Sequence value.
*
*/
uint8_t GetSequence(void) const { return mSequence; }
/**
* This method sets the MPL Sequence value.
*
* @param[in] aSequence The MPL Sequence value.
*
*/
void SetSequence(uint8_t aSequence) { mSequence = aSequence; }
/**
* This method returns the MPL Seed Set entry's remaining lifetime.
*
* @returns The MPL Seed Set entry's remaining lifetime.
*
*/
uint8_t GetLifetime(void) const { return mLifetime; }
/**
* This method sets the remaining lifetime of the Seed Set entry.
*
* @param[in] aLifetime The remaining lifetime of the Seed Set entry.
*
*/
void SetLifetime(uint8_t aLifetime) { mLifetime = aLifetime; }
private:
uint16_t mSeedId;
uint8_t mSequence;
uint8_t mLifetime;
};
/**
* This class represents metadata required for MPL retransmissions.
*
*/
OT_TOOL_PACKED_BEGIN
class MplBufferedMessageMetadata
{
public:
/**
* Default constructor for the object.
*
*/
MplBufferedMessageMetadata(void):
mSeedId(0),
mSequence(0),
mTransmissionCount(0),
mTransmissionTime(0),
mIntervalOffset(0) {
};
/**
* This method appends MPL Buffered Message metadata to the message.
*
* @param[in] aMessage A reference to the message.
*
* @retval OT_ERROR_NONE Successfully appended the bytes.
* @retval OT_ERROR_NO_BUFS Insufficient available buffers to grow the message.
*
*/
otError AppendTo(Message &aMessage) const {
return aMessage.Append(this, sizeof(*this));
};
/**
* This method reads request data from the message.
*
* @param[in] aMessage A reference to the message.
*
* @returns The number of bytes that have been read.
*
*/
uint16_t ReadFrom(const Message &aMessage) {
return aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
};
/**
* This method removes MPL Buffered Messsage metadata from the message.
*
* @param[in] aMessage A reference to the message.
*
* @retval OT_ERROR_NONE Successfully removed the header.
*
*/
otError RemoveFrom(Message &aMessage) {
return aMessage.SetLength(aMessage.GetLength() - sizeof(*this));
};
/**
* This method updates MPL Buffered Messsage metadata in the message.
*
* @param[in] aMessage A reference to the message.
*
* @returns The number of bytes that have been updated.
*
*/
int UpdateIn(Message &aMessage) const {
return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this);
}
/**
* This method checks if the message shall be sent before the given time.
*
* @param[in] aTime A time to compare.
*
* @retval TRUE If the message shall be sent before the given time.
* @retval FALSE Otherwise.
*/
bool IsEarlier(uint32_t aTime) const { return (static_cast<int32_t>(aTime - mTransmissionTime) > 0); };
/**
* This method checks if the message shall be sent after the given time.
*
* @param[in] aTime A time to compare.
*
* @retval TRUE If the message shall be sent after the given time.
* @retval FALSE Otherwise.
*/
bool IsLater(uint32_t aTime) const { return (static_cast<int32_t>(aTime - mTransmissionTime) < 0); };
/**
* This method returns the MPL Seed Id value.
*
* @returns The MPL Seed Id value.
*
*/
uint16_t GetSeedId(void) const { return mSeedId; }
/**
* This method sets the MPL Seed Id value.
*
* @param[in] aSeedId The MPL Seed Id value.
*
*/
void SetSeedId(uint16_t aSeedId) { mSeedId = aSeedId; }
/**
* This method returns the MPL Sequence value.
*
* @returns The MPL Sequence value.
*
*/
uint8_t GetSequence(void) const { return mSequence; }
/**
* This method sets the MPL Sequence value.
*
* @param[in] aSequence The MPL Sequence value.
*
*/
void SetSequence(uint8_t aSequence) { mSequence = aSequence; }
/**
* This method returns the number of already preformed transmissions.
*
* @returns The number of already preformed transmissions.
*
*/
uint8_t GetTransmissionCount(void) const { return mTransmissionCount; }
/**
* This method sets the number of already performed transmissions.
*
* @param[in] aTransmissionCount The number of already performed transmissions.
*
*/
void SetTransmissionCount(uint8_t aTransmissionCount) { mTransmissionCount = aTransmissionCount; }
/**
* This method returns the transmission timestamp of the message.
*
* @returns The transmission timestamp of the message.
*
*/
uint32_t GetTransmissionTime(void) const { return mTransmissionTime; }
/**
* This method sets the transmission timestamp of the message.
*
* @param[in] aTransmissionTime The transmission timestamp of the message.
*
*/
void SetTransmissionTime(uint32_t aTransmissionTime) { mTransmissionTime = aTransmissionTime; }
/**
* This method returns the offset from the transmission time to the end of trickle interval.
*
* @returns The offset from the the transmission time to the end of trickle interval.
*
*/
uint8_t GetIntervalOffset(void) const { return mIntervalOffset; }
/**
* This method sets the offset from the transmission time to the end of trickle interval.
*
* @param[in] aIntervalOffset The offset from the the transmission time to the end of trickle interval.
*
*/
void SetIntervalOffset(uint8_t aIntervalOffset) { mIntervalOffset = aIntervalOffset; }
/**
* This method generates the next transmission time for the MPL Data Message.
*
* @param[in] aCurrentTime Current time (in milliseconds).
* @param[in] aInterval The current interval size (in milliseconds).
*/
void GenerateNextTransmissionTime(uint32_t aCurrentTime, uint8_t aInterval);
private:
uint16_t mSeedId;
uint8_t mSequence;
uint8_t mTransmissionCount;
uint32_t mTransmissionTime;
uint8_t mIntervalOffset;
} OT_TOOL_PACKED_END;
/**
* This class implements MPL message processing.
*
*/
class Mpl: public Ip6Locator
{
public:
/**
* This constructor initializes the MPL object.
*
* @param[in] aIp6 A reference to the IPv6 network object.
*
*/
Mpl(Ip6 &aIp6);
/**
* This method initializes the MPL option.
*
* @param[in] aOption A reference to the MPL header to initialize.
* @param[in] aAddress A reference to the IPv6 Source Address.
*
*/
void InitOption(OptionMpl &aOption, const Address &aAddress);
/**
* This method processes an MPL option. When the MPL module acts as an MPL Forwarder
* it disseminates MPL Data Message using Trickle timer expirations. When acts as an
* MPL Seed it allows to send the first MPL Data Message directly, then sets up Trickle
* timer expirations for subsequent retransmissions.
*
* @param[in] aMessage A reference to the message.
* @param[in] aAddress A reference to the IPv6 Source Address.
* @param[in] aIsOutbound TRUE if this message was locally generated, FALSE otherwise.
*
* @retval OT_ERROR_NONE Successfully processed the MPL option.
* @retval OT_ERROR_DROP The MPL message is a duplicate and should be dropped.
*
*/
otError ProcessOption(Message &aMessage, const Address &aAddress, bool aIsOutbound);
/**
* This method returns the MPL Seed Id value.
*
* @returns The MPL Seed Id value.
*
*/
uint16_t GetSeedId(void) const { return mSeedId; }
/**
* This method sets the MPL Seed Id value.
*
* @param[in] aSeedId The MPL Seed Id value.
*
*/
void SetSeedId(uint16_t aSeedId) { mSeedId = aSeedId; }
/**
* This method gets the MPL number of Trickle timer expirations that occur before
* terminating the Trickle algorithm's retransmission of a given MPL Data Message.
*
* @returns The MPL number of Trickle timer expirations.
*
*/
uint8_t GetTimerExpirations(void) const { return mTimerExpirations; }
/**
* This method sets the MPL number of Trickle timer expirations that occur before
* terminating the Trickle algorithm's retransmission of a given MPL Data Message.
*
* @param[in] aTimerExpirations The number of Trickle timer expirations.
*
*/
void SetTimerExpirations(uint8_t aTimerExpirations) { mTimerExpirations = aTimerExpirations; }
/**
* This method sets the IPv6 matching address, that allows to elide MPL Seed Id.
*
* @param[in] aAddress The reference to the IPv6 matching address.
*
*/
void SetMatchingAddress(const Address &aAddress) { mMatchingAddress = &aAddress; }
/**
* This method returns a reference to the buffered message set.
*
* @returns A reference to the buffered message set.
*
*/
const MessageQueue &GetBufferedMessageSet(void) const { return mBufferedMessageSet; }
private:
enum
{
kNumSeedEntries = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRIES,
kSeedEntryLifetime = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRY_LIFETIME,
kSeedEntryLifetimeDt = 1000,
kDataMessageInterval = 64
};
otError UpdateSeedSet(uint16_t aSeedId, uint8_t aSequence);
void UpdateBufferedSet(uint16_t aSeedId, uint8_t aSequence);
void AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound);
static void HandleSeedSetTimer(Timer &aTimer);
void HandleSeedSetTimer(void);
static void HandleRetransmissionTimer(Timer &aTimer);
void HandleRetransmissionTimer(void);
static Mpl &GetOwner(const Context &aContext);
Timer mSeedSetTimer;
Timer mRetransmissionTimer;
uint8_t mTimerExpirations;
uint8_t mSequence;
uint16_t mSeedId;
const Address *mMatchingAddress;
MplSeedEntry mSeedSet[kNumSeedEntries];
MessageQueue mBufferedMessageSet;
};
/**
* @}
*
*/
} // namespace Ip6
} // namespace ot
#endif // NET_IP6_MPL_HPP_