blob: 5b28cb784a258365c0e4720bb781b23b49e7928a [file] [log] [blame]
/*
* Copyright (c) 2019, 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 Thread Radio Encapsulation Link (TREL) Packet
*/
#ifndef TREL_PACKET_HPP_
#define TREL_PACKET_HPP_
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
#include "common/data.hpp"
#include "common/encoding.hpp"
#include "common/locator.hpp"
#include "common/string.hpp"
#include "mac/mac_types.hpp"
namespace ot {
namespace Trel {
/**
* This class represents a TREL radio link packet encapsulation header.
*
*/
OT_TOOL_PACKED_BEGIN
class Header
{
public:
/**
* This enumeration defines packet types.
*
*/
enum Type : uint8_t
{
kTypeBroadcast = 0, ///< A TREL broadcast packet.
kTypeUnicast = 1, ///< A TREL unicast packet.
kTypeAck = 2, ///< A TREL Ack packet.
};
/**
* This enumeration represents Ack Mode field in TREL header.
*
*/
enum AckMode : uint8_t
{
kNoAck, ///< No TREL Ack is requested.
kAckRequested, ///< A TREL Ack is requested.
};
static constexpr uint16_t kInfoStringSize = 128; ///< Max chars for the info string (@sa ToInfoString()).
/**
* This type defines the fixed-length `String` object returned from `ToString()` method.
*
*/
typedef String<kInfoStringSize> InfoString;
/**
* This method initializes the header.
*
* @param[in] aType The header type.
*
*/
void Init(Type aType) { mControl = aType + kVersion; }
/**
* This method checks whether the version field in header is valid or not
*
* @returns TRUE if the version field is valid, FALSE otherwise.
*
*/
bool IsVersionValid(void) const { return (mControl & kVersionMask) == kVersion; }
/**
* This method gets the packet type.
*
* @returns The packet type.
*
*/
Type GetType(void) const { return static_cast<Type>(mControl & kTypeMask); }
/**
* This method gets the header length based on its type.
*
* @returns the header length (number of bytes).
*
*/
uint16_t GetLength(void) const { return GetSize(GetType()); }
/**
* This method gets the Ack Mode field from the header.
*
* @returns The Ack Mode field.
*
*/
AckMode GetAckMode(void) const { return (mControl & kAckModeFlag) ? kAckRequested : kNoAck; }
/**
* This method sets the Ack Mode field in the header.
*
* @param[in] aAckMode The Ack Mode field
*
*/
void SetAckMode(AckMode aAckMode);
/**
* This method gets the channel field from the header.
*
* @returns The channel field.
*
*/
uint8_t GetChannel(void) const { return mChannel; }
/**
* This method sets the channel field in the header.
*
* @param[in] aChannel A channel.
*
*/
void SetChannel(uint8_t aChannel) { mChannel = aChannel; }
/**
* This method gets the PAN Identifier field from the header.
*
* @returns The PAN Identifier field.
*
*/
Mac::PanId GetPanId(void) const { return Encoding::BigEndian::HostSwap16(mPanId); }
/**
* This method sets the PAN Identifier field in the header.
*
* @param[in] aPanId A PAN Identifier.
*
*/
void SetPanId(Mac::PanId aPanId) { mPanId = Encoding::BigEndian::HostSwap16(aPanId); }
/**
* This method gets the packet number field from the header.
*
* @returns The packet number field.
*
*/
uint32_t GetPacketNumber(void) const { return Encoding::BigEndian::HostSwap32(mPacketNumber); }
/**
* This method sets the packet number field in the header.
*
* @param[in] aPacketNumber The packet number.
*
*/
void SetPacketNumber(uint32_t aPacketNumber) { mPacketNumber = Encoding::BigEndian::HostSwap32(aPacketNumber); }
/**
* This method gets the source MAC address field from the header.
*
* @returns The source MAC address field.
*
*/
const Mac::ExtAddress &GetSource(void) const { return mSource; }
/**
* This method sets the source MAC address filed in the header.
*
* @param[in] aSource A MAC extended address to set as source.
*
*/
void SetSource(const Mac::ExtAddress &aSource) { mSource = aSource; }
/**
* This method gets the destination MAC address field from the header.
*
* This method MUST be used with a unicast of ack type packet, otherwise its behavior is undefined.
*
* @returns The destination MAC address field.
*
*/
const Mac::ExtAddress &GetDestination(void) const { return mDestination; }
/**
* This method sets the destination MAC address field in the header.
*
* This method MUST be used with a unicast of ack type packet, otherwise its behavior is undefined.
*
* @param[in] aDest A MAC extended address to set as destination.
*
*/
void SetDestination(const Mac::ExtAddress &aDest) { mDestination = aDest; }
/**
* This static method gets the size (number of bytes) in header of given packet type.
*
* @param[in] aType The packet type.
*
* @returns The fixed header size (number of bytes) for @p aType packet.
*
*/
static uint16_t GetSize(Type aType);
/**
* This method returns a string representation of header.
*
* @returns An `InfoString` representation of header.
*
*/
InfoString ToString(void) const;
private:
static constexpr uint8_t kTypeMask = (3 << 0); // Bits 0-1 specify packet `Type`
static constexpr uint8_t kAckModeFlag = (1 << 2); // Bit 2 indicate "ack mode" (TREL ack requested or not).
static constexpr uint8_t kVersionMask = (7 << 5); // Bits 5-7 specify the version.
static constexpr uint8_t kVersion = (0 << 5); // Current TREL header version.
// All header fields are big-endian.
uint8_t mControl;
uint8_t mChannel;
uint16_t mPanId;
uint32_t mPacketNumber;
Mac::ExtAddress mSource;
Mac::ExtAddress mDestination; // Present in `kTypeAck` or `kTypeUnicast` packet types.
} OT_TOOL_PACKED_END;
/**
* This class represents a TREL radio link packet.
*
*/
class Packet : private MutableData<kWithUint16Length>
{
using Base = MutableData<kWithUint16Length>;
public:
/**
* This method initializes the `Packet` with a given buffer and length.
*
* @param[in] aBuffer A pointer to a buffer containing the entire packet (header and payload).
* @param[in] aLength Length (number of bytes) of the packet (including header and payload).
*
*/
void Init(uint8_t *aBuffer, uint16_t aLength) { Base::Init(aBuffer, aLength); }
/**
* This method initializes the `Packet` with a specified header type and given a payload.
*
* The payload buffer @p aPayload should have space reserved before the start of payload for the packet header.
* This method will initialize the header with the given type @p aType. Rest of header fields can be updated after
* initializing the packet.
*
* @param[in] aType The packet type.
* @param[in] aPayload A pointer to a buffer containing the packet payload. Buffer should have space reserved
* for header before the payload.
* @param[in] aPayloadLength The length (number of bytes) in the payload only (not including the header).
*
*/
void Init(Header::Type aType, uint8_t *aPayload, uint16_t aPayloadLength);
/**
* This method gets a pointer to buffer containing the packet.
*
* @returns A pointer to buffer containing the packet.
*
*/
uint8_t *GetBuffer(void) { return Base::GetBytes(); }
/**
* This method gets a pointer to buffer containing the packet.
*
* @returns A pointer to buffer containing the packet.
*
*/
const uint8_t *GetBuffer(void) const { return Base::GetBytes(); }
/**
* This method gets the length of packet.
*
* @returns The length (number of bytes) of packet (header and payload).
*
*/
uint16_t GetLength(void) const { return Base::GetLength(); }
/**
* This method checks whether or not the packet header is valid.
*
* @retval TRUE The packet header is valid and well-formed.
* @retval FALSE The packet header is not valid.
*
*/
bool IsHeaderValid(void) const;
/**
* This method gets the packet header.
*
* @returns A reference to the packet header as `Header`.
*
*/
Header &GetHeader(void) { return *reinterpret_cast<Header *>(Base::GetBytes()); }
/**
* This method gets the packet header.
*
* @returns A reference to the packet header as `Header`.
*
*/
const Header &GetHeader(void) const { return *reinterpret_cast<const Header *>(Base::GetBytes()); }
/**
* This method gets a pointer to start of packet payload.
*
* @returns A pointer to start of packet payload (after header).
*
*/
uint8_t *GetPayload(void) { return Base::GetBytes() + GetHeader().GetLength(); }
/**
* This method gets a pointer to start of packet payload.
*
* @returns A pointer to start of packet payload (after header).
*
*/
const uint8_t *GetPayload(void) const { return Base::GetBytes() + GetHeader().GetLength(); }
/**
* This method gets the payload length.
*
* @returns The packet payload length (number of bytes).
*
*/
uint16_t GetPayloadLength(void) const { return GetLength() - GetHeader().GetLength(); }
};
} // namespace Trel
} // namespace ot
#endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
#endif // TREL_PACKET_HPP_