/*
 *  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.
 */

/**
 * @file
 *   This file includes definitions for 6LoWPAN header compression.
 */

#ifndef LOWPAN_HPP_
#define LOWPAN_HPP_

#include "openthread-core-config.h"

#include "common/debug.hpp"
#include "common/locator.hpp"
#include "common/message.hpp"
#include "common/non_copyable.hpp"
#include "mac/mac_types.hpp"
#include "net/ip6.hpp"
#include "net/ip6_address.hpp"
#include "net/ip6_types.hpp"

namespace ot {

/**
 * @addtogroup core-6lowpan
 *
 * @brief
 *   This module includes definitions for 6LoWPAN header compression.
 *
 * @{
 */

/**
 * @namespace ot::Lowpan
 *
 * @brief
 *   This namespace includes definitions for 6LoWPAN message processing.
 *
 */
namespace Lowpan {

using ot::Encoding::BigEndian::HostSwap16;

/**
 * This structure represents a LOWPAN_IPHC Context.
 *
 */
struct Context
{
    Ip6::Prefix mPrefix;       ///< The Prefix
    uint8_t     mContextId;    ///< The Context ID.
    bool        mCompressFlag; ///< The Context compression flag.
};

/**
 * This class defines a buffer writer used by the 6LoWPAN compressor.
 *
 */
class BufferWriter
{
public:
    /**
     * This constructor initializes the buffer writer.
     *
     * @param[in]  aBuf     A pointer to the write buffer.
     * @param[in]  aLength  The size of the write buffer.
     *
     */
    BufferWriter(uint8_t *aBuf, uint16_t aLength)
        : mWritePointer(aBuf)
        , mEndPointer(aBuf + aLength)
    {
    }

    /**
     * This method indicates whether there is buffer space available to write @p aLength bytes.
     *
     * @param[in]  aLength  Number of bytes to write.
     *
     * @retval  TRUE   Enough buffer space is available to write the requested number of bytes.
     * @retval  FALSE  Insufficient buffer space to write the requested number of bytes.
     *
     */
    bool CanWrite(uint8_t aLength) const { return (mWritePointer + aLength) <= mEndPointer; }

    /**
     * This method returns the current write pointer value.
     *
     * @returns the current write pointer value.
     *
     */
    uint8_t *GetWritePointer(void) { return mWritePointer; }

    /**
     * This method advances the write pointer.
     *
     * @param[in]  aLength  Number of bytes to advance.
     *
     * @retval kErrorNone    Enough buffer space is available to advance the requested number of bytes.
     * @retval kErrorNoBufs  Insufficient buffer space to advance the requested number of bytes.
     *
     */
    Error Advance(uint8_t aLength)
    {
        Error error = kErrorNone;

        VerifyOrExit(CanWrite(aLength), error = kErrorNoBufs);
        mWritePointer += aLength;

    exit:
        return error;
    }

    /**
     * This method writes a byte into the buffer and updates the write pointer, if space is available.
     *
     * @param[in]  aByte  Byte to write.
     *
     * @retval  kErrorNone     Successfully wrote the byte and updated the pointer.
     * @retval  kErrorNoBufs  Insufficient buffer space to write the byte.
     *
     */
    Error Write(uint8_t aByte)
    {
        Error error = kErrorNone;

        VerifyOrExit(CanWrite(sizeof(aByte)), error = kErrorNoBufs);

        *mWritePointer++ = aByte;

    exit:
        return error;
    }

    /**
     * This method writes a byte sequence into the buffer and updates the write pointer, if space is available.
     *
     * @param[in]  aBuf     A pointer to the byte sequence.
     * @param[in]  aLength  Number of bytes to write.
     *
     * @retval kErrorNone    Successfully wrote the byte sequence and updated the pointer.
     * @retval kErrorNoBufs  Insufficient buffer space to write the byte sequence.
     *
     */
    Error Write(const void *aBuf, uint8_t aLength)
    {
        Error error = kErrorNone;

        VerifyOrExit(CanWrite(aLength), error = kErrorNoBufs);

        memcpy(mWritePointer, aBuf, aLength);
        mWritePointer += aLength;

    exit:
        return error;
    }

    /**
     * This method writes a byte sequence into the buffer and updates the write pointer, if space is available.
     *
     * The byte sequence is taken from a message buffer at the current message buffer's offset.
     *
     * @param[in]  aMessage  A message buffer.
     * @param[in]  aLength   Number of bytes to write.
     *
     * @retval kErrorNone    Successfully wrote the byte sequence and updated the pointer.
     * @retval kErrorNoBufs  Insufficient buffer space to write the byte sequence.
     *
     */
    Error Write(const Message &aMessage, uint8_t aLength)
    {
        Error error = kErrorNone;
        int   rval;

        OT_UNUSED_VARIABLE(rval);

        VerifyOrExit(CanWrite(aLength), error = kErrorNoBufs);

        rval = aMessage.ReadBytes(aMessage.GetOffset(), mWritePointer, aLength);
        OT_ASSERT(rval == aLength);

        mWritePointer += aLength;

    exit:
        return error;
    }

private:
    uint8_t *mWritePointer;
    uint8_t *mEndPointer;
};

/**
 * This class implements LOWPAN_IPHC header compression.
 *
 */
class Lowpan : public InstanceLocator, private NonCopyable
{
public:
    /**
     * This constructor initializes the object.
     *
     * @param[in]  aInstance     A reference to the OpenThread instance.
     *
     */
    explicit Lowpan(Instance &aInstance);

    /**
     * This method indicates whether or not the header is a LOWPAN_IPHC header.
     *
     * @param[in]  aHeader  A pointer to the header.
     *
     * @retval TRUE   If the header matches the LOWPAN_IPHC dispatch value.
     * @retval FALSE  If the header does not match the LOWPAN_IPHC dispatch value.
     */
    static bool IsLowpanHc(const uint8_t *aHeader)
    {
        return (aHeader[0] & (Lowpan::kHcDispatchMask >> 8)) == (Lowpan::kHcDispatch >> 8);
    }

    /**
     * This method compresses an IPv6 header.
     *
     * @param[in]   aMessage     A reference to the IPv6 message.
     * @param[in]   aMacSource   The MAC source address.
     * @param[in]   aMacDest     The MAC destination address.
     * @param[out]  aBuf         A pointer where the compressed IPv6 header will be placed.
     *
     * @returns The size of the compressed header in bytes.
     *
     */
    Error Compress(Message &aMessage, const Mac::Address &aMacSource, const Mac::Address &aMacDest, BufferWriter &aBuf);

    /**
     * This method decompresses a LOWPAN_IPHC header.
     *
     * @param[out]  aMessage         A reference where the IPv6 header will be placed.
     * @param[in]   aMacSource       The MAC source address.
     * @param[in]   aMacDest         The MAC destination address.
     * @param[in]   aBuf             A pointer to the LOWPAN_IPHC header.
     * @param[in]   aBufLength       The number of bytes in @p aBuf.
     * @param[in]   aDatagramLength  The IPv6 datagram length.
     *
     * @returns The size of the compressed header in bytes.
     *
     */
    int Decompress(Message &           aMessage,
                   const Mac::Address &aMacSource,
                   const Mac::Address &aMacDest,
                   const uint8_t *     aBuf,
                   uint16_t            aBufLength,
                   uint16_t            aDatagramLength);

    /**
     * This method decompresses a LOWPAN_IPHC header.
     *
     * @param[out]  aIp6Header             A reference where the IPv6 header will be placed.
     * @param[out]  aCompressedNextHeader  A boolean reference to output whether next header is compressed or not.
     * @param[in]   aMacSource             The MAC source address.
     * @param[in]   aMacDest               The MAC destination address.
     * @param[in]   aBuf                   A pointer to the LOWPAN_IPHC header.
     * @param[in]   aBufLength             The number of bytes in @p aBuf.
     *
     * @returns The size of the compressed header in bytes or -1 if decompression fails.
     *
     */
    int DecompressBaseHeader(Ip6::Header &       aIp6Header,
                             bool &              aCompressedNextHeader,
                             const Mac::Address &aMacSource,
                             const Mac::Address &aMacDest,
                             const uint8_t *     aBuf,
                             uint16_t            aBufLength);

    /**
     * This method decompresses a LOWPAN_NHC UDP header.
     *
     * @param[out]  aUdpHeader    A reference where the UDP header will be placed.
     * @param[in]   aBuf          A pointer to the LOWPAN_NHC header.
     * @param[in]   aBufLength    The number of bytes in @p aBuf.
     *
     * @returns The size of the compressed header in bytes or -1 if decompression fails.
     *
     */
    int DecompressUdpHeader(Ip6::Udp::Header &aUdpHeader, const uint8_t *aBuf, uint16_t aBufLength);

    /**
     * This method decompresses the IPv6 ECN field in a LOWPAN_IPHC header.
     *
     * @param[in] aMessage  The message to read the IPHC header from.
     * @param[in] aOffset   The offset in @p aMessage to start of IPHC header.
     *
     * @returns The decompressed ECN field. If the IPHC header is not valid `kEcnNotCapable` is returned.
     *
     */
    Ip6::Ecn DecompressEcn(const Message &aMessage, uint16_t aOffset) const;

    /**
     * This method updates the compressed ECN field in a LOWPAN_IPHC header to `kEcnMarked`.
     *
     * This method MUST be used when the ECN field is not elided in the IPHC header. Note that the ECN is not elided
     * when it is not zero (`kEcnNotCapable`).
     *
     * @param[in,out] aMessage  The message containing the IPHC header and to update.
     * @param[in]     aOffset   The offset in @p aMessage to start of IPHC header.
     *
     */
    void MarkCompressedEcn(Message &aMessage, uint16_t aOffset);

private:
    static constexpr uint16_t kHcDispatch     = 3 << 13;
    static constexpr uint16_t kHcDispatchMask = 7 << 13;

    static constexpr uint16_t kHcTrafficClass    = 1 << 11;
    static constexpr uint16_t kHcFlowLabel       = 2 << 11;
    static constexpr uint16_t kHcTrafficFlow     = 3 << 11;
    static constexpr uint16_t kHcTrafficFlowMask = 3 << 11;
    static constexpr uint16_t kHcNextHeader      = 1 << 10;
    static constexpr uint16_t kHcHopLimit1       = 1 << 8;
    static constexpr uint16_t kHcHopLimit64      = 2 << 8;
    static constexpr uint16_t kHcHopLimit255     = 3 << 8;
    static constexpr uint16_t kHcHopLimitMask    = 3 << 8;
    static constexpr uint16_t kHcContextId       = 1 << 7;
    static constexpr uint16_t kHcSrcAddrContext  = 1 << 6;
    static constexpr uint16_t kHcSrcAddrMode0    = 0 << 4;
    static constexpr uint16_t kHcSrcAddrMode1    = 1 << 4;
    static constexpr uint16_t kHcSrcAddrMode2    = 2 << 4;
    static constexpr uint16_t kHcSrcAddrMode3    = 3 << 4;
    static constexpr uint16_t kHcSrcAddrModeMask = 3 << 4;
    static constexpr uint16_t kHcMulticast       = 1 << 3;
    static constexpr uint16_t kHcDstAddrContext  = 1 << 2;
    static constexpr uint16_t kHcDstAddrMode0    = 0 << 0;
    static constexpr uint16_t kHcDstAddrMode1    = 1 << 0;
    static constexpr uint16_t kHcDstAddrMode2    = 2 << 0;
    static constexpr uint16_t kHcDstAddrMode3    = 3 << 0;
    static constexpr uint16_t kHcDstAddrModeMask = 3 << 0;

    static constexpr uint8_t kEcnOffset = 6;
    static constexpr uint8_t kEcnMask   = 3 << kEcnOffset;

    static constexpr uint8_t kExtHdrDispatch     = 0xe0;
    static constexpr uint8_t kExtHdrDispatchMask = 0xf0;

    static constexpr uint8_t kExtHdrEidHbh      = 0x00;
    static constexpr uint8_t kExtHdrEidRouting  = 0x02;
    static constexpr uint8_t kExtHdrEidFragment = 0x04;
    static constexpr uint8_t kExtHdrEidDst      = 0x06;
    static constexpr uint8_t kExtHdrEidMobility = 0x08;
    static constexpr uint8_t kExtHdrEidIp6      = 0x0e;
    static constexpr uint8_t kExtHdrEidMask     = 0x0e;

    static constexpr uint8_t  kExtHdrNextHeader = 0x01;
    static constexpr uint16_t kExtHdrMaxLength  = 255;

    static constexpr uint8_t kUdpDispatch     = 0xf0;
    static constexpr uint8_t kUdpDispatchMask = 0xf8;

    static constexpr uint8_t kUdpChecksum = 1 << 2;
    static constexpr uint8_t kUdpPortMask = 3 << 0;

    Error Compress(Message &           aMessage,
                   const Mac::Address &aMacSource,
                   const Mac::Address &aMacDest,
                   BufferWriter &      aBuf,
                   uint8_t &           aHeaderDepth);

    Error CompressExtensionHeader(Message &aMessage, BufferWriter &aBuf, uint8_t &aNextHeader);
    Error CompressSourceIid(const Mac::Address &aMacAddr,
                            const Ip6::Address &aIpAddr,
                            const Context &     aContext,
                            uint16_t &          aHcCtl,
                            BufferWriter &      aBuf);
    Error CompressDestinationIid(const Mac::Address &aMacAddr,
                                 const Ip6::Address &aIpAddr,
                                 const Context &     aContext,
                                 uint16_t &          aHcCtl,
                                 BufferWriter &      aBuf);
    Error CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl, BufferWriter &aBuf);
    Error CompressUdp(Message &aMessage, BufferWriter &aBuf);

    int   DecompressExtensionHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength);
    int   DecompressUdpHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength, uint16_t aDatagramLength);
    Error DispatchToNextHeader(uint8_t aDispatch, uint8_t &aNextHeader);

    static void  CopyContext(const Context &aContext, Ip6::Address &aAddress);
    static Error ComputeIid(const Mac::Address &aMacAddr, const Context &aContext, Ip6::Address &aIpAddress);
};

/**
 * This class implements Mesh Header generation and processing.
 *
 */
class MeshHeader
{
public:
    /**
     * The additional value that is added to predicted value of the route cost.
     *
     */
    static constexpr uint8_t kAdditionalHopsLeft = 1;

    /**
     * This method initializes the Mesh Header with a given Mesh Source, Mesh Destination and Hops Left value.
     *
     * @param[in]  aSource       The Mesh Source address.
     * @param[in]  aDestination  The Mesh Destination address.
     * @param[in]  aHopsLeft     The Hops Left value.
     *
     */
    void Init(uint16_t aSource, uint16_t aDestination, uint8_t aHopsLeft);

    /**
     * This static method indicates whether or not the header (in a given frame) is a Mesh Header.
     *
     * @note This method checks whether the first byte in header/frame (dispatch byte) matches the Mesh Header dispatch
     * It does not fully parse and validate the Mesh Header. `ParseFrom()` method can be used to fully parse and
     * validate the header.
     *
     * @retval TRUE   If the header matches the Mesh Header dispatch value.
     * @retval FALSE  If the header does not match the Mesh Header dispatch value.
     *
     */
    static bool IsMeshHeader(const uint8_t *aFrame, uint16_t aFrameLength);

    /**
     * This method parses the Mesh Header from a frame @p aFrame.
     *
     * @param[in]  aFrame        The pointer to the frame.
     * @param[in]  aFrameLength  The length of the frame.
     * @param[out] aHeaderLength A reference to a variable to output the parsed header length (on success).
     *
     * @retval kErrorNone     Mesh Header parsed successfully.
     * @retval kErrorParse    Mesh Header could not be parsed.
     *
     */
    Error ParseFrom(const uint8_t *aFrame, uint16_t aFrameLength, uint16_t &aHeaderLength);

    /**
     * This method parses the Mesh Header from a given message.
     *
     * @note The Mesh Header is read from offset zero within the @p aMessage.
     *
     * @param[in]  aMessage    The message to read from.
     *
     * @retval kErrorNone   Mesh Header parsed successfully.
     * @retval kErrorParse  Mesh Header could not be parsed.
     *
     */
    Error ParseFrom(const Message &aMessage);

    /**
     * This method parses the Mesh Header from a given message.
     *
     * @note The Mesh Header is read from offset zero within the @p aMessage.
     *
     * @param[in]  aMessage       The message to read from.
     * @param[out] aHeaderLength  A reference to a variable to output the parsed header length (on success).
     *
     * @retval kErrorNone   Mesh Header parsed successfully.
     * @retval kErrorParse  Mesh Header could not be parsed.
     *
     */
    Error ParseFrom(const Message &aMessage, uint16_t &aHeaderLength);

    /**
     * This method returns the the Mesh Header length when written to a frame.
     *
     * @note The returned value from this method gives the header length (number of bytes) when the header is written
     * to a frame or message. This should not be used to determine the parsed length (number of bytes read) when the
     * Mesh Header is parsed from a frame/message (using `ParseFrom()` methods).
     *
     * @returns The length of the Mesh Header (in bytes) when written to a frame.
     *
     */
    uint16_t GetHeaderLength(void) const;

    /**
     * This method returns the Hops Left value.
     *
     * @returns The Hops Left value.
     *
     */
    uint8_t GetHopsLeft(void) const { return mHopsLeft; }

    /**
     * This method decrements the Hops Left value (if it is not zero).
     *
     */
    void DecrementHopsLeft(void);

    /**
     * This method returns the Mesh Source address.
     *
     * @returns The Mesh Source address.
     *
     */
    uint16_t GetSource(void) const { return mSource; }

    /**
     * This method returns the Mesh Destination address.
     *
     * @returns The Mesh Destination address.
     *
     */
    uint16_t GetDestination(void) const { return mDestination; }

    /**
     * This method writes the Mesh Header into a given frame.
     *
     * @note This method expects the frame buffer to have enough space for the entire Mesh Header.
     *
     * @param[out]  aFrame  The pointer to the frame buffer to write to.
     *
     * @returns The header length (number of bytes written).
     *
     */
    uint16_t WriteTo(uint8_t *aFrame) const;

    /**
     * This method writes the Mesh Header to a message at a given offset.
     *
     * @note This method expects the @p aMessage length to be already set such that there is enough space for the
     * entire Mesh Header to be written.
     *
     * @param[out] aMessage  A message to write the Mesh Header into.
     * @param[in]  aOffset   The offset at which to write the header.
     *
     * @returns The header length (number of bytes written).
     *
     */
    uint16_t WriteTo(Message &aMessage, uint16_t aOffset) const;

private:
    static constexpr uint8_t kDispatch     = 2 << 6;
    static constexpr uint8_t kDispatchMask = 3 << 6;
    static constexpr uint8_t kHopsLeftMask = 0x0f;
    static constexpr uint8_t kSourceShort  = 1 << 5;
    static constexpr uint8_t kDestShort    = 1 << 4;
    static constexpr uint8_t kDeepHopsLeft = 0x0f;

    // Dispatch byte + src + dest
    static constexpr uint16_t kMinHeaderLength      = sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint16_t);
    static constexpr uint16_t kDeepHopsHeaderLength = kMinHeaderLength + sizeof(uint8_t); // min header + deep hops

    uint16_t mSource;
    uint16_t mDestination;
    uint8_t  mHopsLeft;
};

/**
 * This class implements Fragment Header generation and parsing.
 *
 */
class FragmentHeader
{
public:
    static constexpr uint16_t kFirstFragmentHeaderSize      = 4; ///< First fragment header size in octets.
    static constexpr uint16_t kSubsequentFragmentHeaderSize = 5; ///< Subsequent fragment header size in octets.

    /**
     * This method initializes the Fragment Header as a first fragment.
     *
     * A first fragment header starts at offset zero.
     *
     * @param[in] aSize   The Datagram Size value.
     * @param[in] aTag    The Datagram Tag value.
     *
     */
    void InitFirstFragment(uint16_t aSize, uint16_t aTag) { Init(aSize, aTag, 0); }

    /**
     * This method initializes the Fragment Header.
     *
     * The @p aOffset value will be truncated to become a multiple of 8.
     *
     * @param[in] aSize   The Datagram Size value.
     * @param[in] aTag    The Datagram Tag value.
     * @param[in] aOffset The Datagram Offset value.
     *
     */
    void Init(uint16_t aSize, uint16_t aTag, uint16_t aOffset);

    /**
     * This static method indicates whether or not the header (in a given frame) is a Fragment Header.
     *
     * @note This method checks whether the frame has the minimum required length and that the first byte in
     * header (dispatch byte) matches the Fragment Header dispatch value. It does not fully parse and validate the
     * Fragment Header. `ParseFrom()` method can be used to fully parse and validate the header.
     *
     * @retval TRUE   If the header matches the Fragment Header dispatch value.
     * @retval FALSE  If the header does not match the Fragment Header dispatch value.
     *
     */
    static bool IsFragmentHeader(const uint8_t *aFrame, uint16_t aFrameLength);

    /**
     * This method parses the Fragment Header from a frame @p aFrame.
     *
     * @param[in]  aFrame          The pointer to the frame.
     * @param[in]  aFrameLength    The length of the frame.
     * @param[out] aHeaderLength   A reference to a variable to output the parsed header length (on success).
     *
     * @retval kErrorNone     Fragment Header parsed successfully.
     * @retval kErrorParse    Fragment header could not be parsed from @p aFrame.
     *
     */
    Error ParseFrom(const uint8_t *aFrame, uint16_t aFrameLength, uint16_t &aHeaderLength);

    /**
     * This method parses the Fragment Header from a message.
     *
     * @param[in]  aMessage      The message to read from.
     * @param[in]  aOffset       The offset within the message to start reading from.
     * @param[out] aHeaderLength A reference to a variable to output the parsed header length (on success).
     *
     * @retval kErrorNone     Fragment Header parsed successfully.
     * @retval kErrorParse    Fragment header could not be parsed from @p aFrame.
     *
     */
    Error ParseFrom(const Message &aMessage, uint16_t aOffset, uint16_t &aHeaderLength);

    /**
     * This method returns the Datagram Size value.
     *
     * @returns The Datagram Size value.
     *
     */
    uint16_t GetDatagramSize(void) const { return mSize; }

    /**
     * This method returns the Datagram Tag value.
     *
     * @returns The Datagram Tag value.
     *
     */
    uint16_t GetDatagramTag(void) const { return mTag; }

    /**
     * This method returns the Datagram Offset value.
     *
     * The returned offset value is always multiple of 8.
     *
     * @returns The Datagram Offset value (multiple of 8).
     *
     */
    uint16_t GetDatagramOffset(void) const { return mOffset; }

    /**
     * This method writes the Fragment Header into a given frame.
     *
     * @note This method expects the frame buffer to have enough space for the entire Fragment Header
     *
     * @param[out]  aFrame  The pointer to the frame buffer to write to.
     *
     * @returns The header length (number of bytes written).
     *
     */
    uint16_t WriteTo(uint8_t *aFrame) const;

private:
    static constexpr uint8_t kDispatch     = 0xc0;   // 0b1100_0000
    static constexpr uint8_t kDispatchMask = 0xd8;   // 0b1101_1000 accepts first (0b1100_0xxx) and next (0b1110_0xxx).
    static constexpr uint8_t kOffsetFlag   = 1 << 5; // Indicate first (no offset) vs. next (offset present) fragment.

    static constexpr uint16_t kSizeMask   = 0x7ff;  // 0b0111_1111_1111 (first 11 bits).
    static constexpr uint16_t kOffsetMask = 0xfff8; // Clears the last 3 bits to ensure offset is a multiple of 8.

    static constexpr uint8_t kSizeIndex   = 0; // Start index of Size field in the Fragment Header byte sequence.
    static constexpr uint8_t kTagIndex    = 2; // Start index of Tag field in the Fragment Header byte sequence.
    static constexpr uint8_t kOffsetIndex = 4; // Start index of Offset field in the Fragment Header byte sequence.

    uint16_t mSize;
    uint16_t mTag;
    uint16_t mOffset;
};

/**
 * @}
 */

} // namespace Lowpan
} // namespace ot

#endif // LOWPAN_HPP_
