#ifndef IP6_HPP_
#define IP6_HPP_
#include "openthread-core-config.h"
#include <stddef.h>
#include <openthread/ip6.h>
#include <openthread/udp.h>
#include "common/encoding.hpp"
#include "common/locator.hpp"
#include "common/message.hpp"
#include "common/non_copyable.hpp"
#include "common/timer.hpp"
#include "net/icmp6.hpp"
#include "net/ip6_address.hpp"
#include "net/ip6_headers.hpp"
#include "net/ip6_mpl.hpp"
#include "net/netif.hpp"
#include "net/socket.hpp"
#include "net/udp6.hpp"
namespace ot {
namespace Ip6 {
using ot::Encoding::BigEndian::HostSwap16;
using ot::Encoding::BigEndian::HostSwap32;
class Ip6 : public InstanceLocator, private NonCopyable
{
friend class ot::Instance;
public:
enum
{
kDefaultHopLimit = OPENTHREAD_CONFIG_IP6_HOP_LIMIT_DEFAULT,
kMaxDatagramLength = OPENTHREAD_CONFIG_IP6_MAX_DATAGRAM_LENGTH,
kMaxAssembledDatagramLength = OPENTHREAD_CONFIG_IP6_MAX_ASSEMBLED_DATAGRAM,
kIp6ReassemblyTimeout = OPENTHREAD_CONFIG_IP6_REASSEMBLY_TIMEOUT,
kMinimalMtu = 1280,
kStateUpdatePeriod = 1000,
};
Message *NewMessage(uint16_t aReserved, const Message::Settings &aSettings = Message::Settings::GetDefault());
Message *NewMessage(const uint8_t *aData, uint16_t aDataLength, const Message::Settings &aSettings);
Message *NewMessage(const uint8_t *aData, uint16_t aDataLength);
static uint8_t PriorityToDscp(Message::Priority aPriority);
static Message::Priority DscpToPriority(uint8_t aDscp);
explicit Ip6(Instance &aInstance);
otError SendDatagram(Message &aMessage, MessageInfo &aMessageInfo, uint8_t aIpProto);
otError SendRaw(Message &aMessage);
otError HandleDatagram(Message &aMessage, Netif *aNetif, const void *aLinkMessageInfo, bool aFromNcpHost);
void EnqueueDatagram(Message &aMessage);
static uint16_t UpdateChecksum(uint16_t aChecksum, const Address &aAddress);
static uint16_t ComputePseudoheaderChecksum(const Address &aSource,
const Address &aDestination,
uint16_t aLength,
uint8_t aProto);
void SetReceiveDatagramCallback(otIp6ReceiveCallback aCallback, void *aCallbackContext);
bool IsReceiveIp6FilterEnabled(void) const { return mIsReceiveIp6FilterEnabled; }
void SetReceiveIp6FilterEnabled(bool aEnabled) { mIsReceiveIp6FilterEnabled = aEnabled; }
bool IsForwardingEnabled(void) const { return mForwardingEnabled; }
void SetForwardingEnabled(bool aEnable) { mForwardingEnabled = aEnable; }
const NetifUnicastAddress *SelectSourceAddress(MessageInfo &aMessageInfo);
const PriorityQueue &GetSendQueue(void) const { return mSendQueue; }
static const char *IpProtoToString(uint8_t aIpProto);
private:
enum
{
kDefaultIp6MessagePriority = Message::kPriorityNormal,
};
static void HandleSendQueue(Tasklet &aTasklet);
void HandleSendQueue(void);
static otError GetDatagramPriority(const uint8_t *aData, uint16_t aDataLen, Message::Priority &aPriority);
otError ProcessReceiveCallback(const Message & aMessage,
const MessageInfo &aMessageInfo,
uint8_t aIpProto,
bool aFromNcpHost);
otError HandleExtensionHeaders(Message & aMessage,
Netif * aNetif,
MessageInfo &aMessageInfo,
Header & aHeader,
uint8_t & aNextHeader,
bool aForward,
bool aFromNcpHost,
bool aReceive);
otError FragmentDatagram(Message &aMessage, uint8_t aIpProto);
otError HandleFragment(Message &aMessage, Netif *aNetif, MessageInfo &aMessageInfo, bool aFromNcpHost);
#if OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE
void CleanupFragmentationBuffer(void);
void HandleUpdateTimer(void);
void UpdateReassemblyList(void);
void SendIcmpError(Message &aMessage, IcmpHeader::Type aIcmpType, IcmpHeader::Code aIcmpCode);
static void HandleTimer(Timer &aTimer);
#endif
otError AddMplOption(Message &aMessage, Header &aHeader);
otError AddTunneledMplOption(Message &aMessage, Header &aHeader, MessageInfo &aMessageInfo);
otError InsertMplOption(Message &aMessage, Header &aHeader, MessageInfo &aMessageInfo);
otError RemoveMplOption(Message &aMessage);
otError HandleOptions(Message &aMessage, Header &aHeader, bool &aForward);
otError HandlePayload(Message &aMessage, MessageInfo &aMessageInfo, uint8_t aIpProto);
bool ShouldForwardToThread(const MessageInfo &aMessageInfo) const;
bool IsOnLink(const Address &aAddress) const;
bool mForwardingEnabled;
bool mIsReceiveIp6FilterEnabled;
otIp6ReceiveCallback mReceiveIp6DatagramCallback;
void * mReceiveIp6DatagramCallbackContext;
PriorityQueue mSendQueue;
Tasklet mSendQueueTask;
Icmp mIcmp;
Udp mUdp;
Mpl mMpl;
#if OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE
TimerMilli mTimer;
MessageQueue mReassemblyList;
#endif
};
} }
#endif