blob: b688b2c3becf196fb5d1a064c561792d480181a1 [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.
*/
/**
* @file
* This file includes definitions for forwarding IPv6 datagrams across the Thread mesh.
*/
#ifndef MESH_FORWARDER_HPP_
#define MESH_FORWARDER_HPP_
#include <openthread/types.h>
#include "openthread-core-config.h"
#include "common/locator.hpp"
#include "common/tasklet.hpp"
#include "mac/mac.hpp"
#include "net/ip6.hpp"
#include "thread/address_resolver.hpp"
#include "thread/data_poll_manager.hpp"
#include "thread/lowpan.hpp"
#include "thread/network_data_leader.hpp"
#include "thread/src_match_controller.hpp"
#include "thread/topology.hpp"
namespace ot {
enum
{
kReassemblyTimeout = OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT,
};
class MleRouter;
struct ThreadMessageInfo;
/**
* @addtogroup core-mesh-forwarding
*
* @brief
* This module includes definitions for mesh forwarding within Thread.
*
* @{
*/
/**
* This class implements mesh forwarding within Thread.
*
*/
class MeshForwarder: public ThreadNetifLocator
{
public:
/**
* This constructor initializes the object.
*
* @param[in] aThreadNetif A reference to the Thread network interface.
*
*/
explicit MeshForwarder(ThreadNetif &aThreadNetif);
/**
* This method enables mesh forwarding and the IEEE 802.15.4 MAC layer.
*
* @retval OT_ERROR_NONE Successfully enabled the mesh forwarder.
*
*/
otError Start(void);
/**
* This method disables mesh forwarding and the IEEE 802.15.4 MAC layer.
*
* @retval OT_ERROR_NONE Successfully disabled the mesh forwarder.
*
*/
otError Stop(void);
/**
* This method submits a message to the mesh forwarder for forwarding.
*
* @param[in] aMessage A reference to the message.
*
* @retval OT_ERROR_NONE Successfully enqueued the message.
* @retval OT_ERROR_ALREADY The message was already enqueued.
* @retval OT_ERROR_DROP The message could not be sent and should be dropped.
*
*/
otError SendMessage(Message &aMessage);
/**
* This method is called by the address resolver when an EID-to-RLOC mapping has been resolved.
*
* @param[in] aEid A reference to the EID that has been resolved.
* @param[in] aError OT_ERROR_NONE on success and OT_ERROR_DROP otherwise.
*
*/
void HandleResolved(const Ip6::Address &aEid, otError aError);
/**
* This method sets the radio receiver and polling timer off.
*
*/
void SetRxOff(void);
/**
* This method indicates whether or not rx-on-when-idle mode is enabled.
*
* @retval TRUE The rx-on-when-idle mode is enabled.
* @retval FALSE The rx-on-when-idle-mode is disabled.
*
*/
bool GetRxOnWhenIdle(void);
/**
* This method sets the rx-on-when-idle mode
*
* @param[in] aRxOnWhenIdle TRUE to enable, FALSE otherwise.
*
*/
void SetRxOnWhenIdle(bool aRxOnWhenIdle);
/**
* This method sets the scan parameters for MLE Discovery Request messages.
*
* @param[in] aScanChannels A bit vector indicating which channels to scan.
*
*/
void SetDiscoverParameters(uint32_t aScanChannels);
/**
* This method frees any indirect messages queued for a specific child.
*
* @param[in] aChild A reference to a child whom messages shall be removed.
*
*/
void ClearChildIndirectMessages(Child &aChild);
/**
* This method frees any indirect messages queued for children that are no longer attached.
*
*/
void UpdateIndirectMessages(void);
/**
* This method returns a reference to the send queue.
*
* @returns A reference to the send queue.
*
*/
const PriorityQueue &GetSendQueue(void) const { return mSendQueue; }
/**
* This method returns a reference to the reassembly queue.
*
* @returns A reference to the reassembly queue.
*
*/
const MessageQueue &GetReassemblyQueue(void) const { return mReassemblyList; }
/**
* This method returns a reference to the resolving queue.
*
* @returns A reference to the resolving queue.
*
*/
const MessageQueue &GetResolvingQueue(void) const { return mResolvingQueue; }
/**
* This method returns a reference to the data poll manager.
*
* @returns A reference to the data poll manager.
*
*/
DataPollManager &GetDataPollManager(void) { return mDataPollManager; }
/**
* This method returns a reference to the source match controller.
*
* @returns A reference to the source match controller.
*
*/
SourceMatchController &GetSourceMatchController(void) { return mSourceMatchController; }
/**
* This method returns a reference to the IP level counters.
*
* @returns A reference to the IP level counters.
*
*/
const otIpCounters &GetCounters(void) const { return mIpCounters; }
private:
enum
{
kStateUpdatePeriod = 1000, ///< State update period in milliseconds.
};
enum
{
/**
* Maximum number of tx attempts by `MeshForwarder` for an outbound indirect frame (for a sleepy child). The
* `MeshForwader` attempts occur following the reception of a new data request command (a new data poll) from
* the sleepy child.
*
*/
kMaxPollTriggeredTxAttempts = OPENTHREAD_CONFIG_MAX_TX_ATTEMPTS_INDIRECT_POLLS,
/**
* Indicates whether to set/enable 15.4 ack request in the MAC header of a supervision message.
*
*/
kSupervisionMsgAckRequest = (OPENTHREAD_CONFIG_SUPERVISION_MSG_NO_ACK_REQUEST == 0) ? true : false,
};
enum MessageAction ///< Defines the action parameter in `LogMessageInfo()` method.
{
kMessageReceive, ///< Indicates that the message was received.
kMessageTransmit, ///< Indicates that the message was sent.
kMessagePrepareIndirect, ///< Indicates that the message is being prepared for indirect tx.
kMessageDrop, ///< Indicates that the message is being dropped from reassembly list.
};
otError CheckReachability(uint8_t *aFrame, uint8_t aFrameLength,
const Mac::Address &aMeshSource, const Mac::Address &aMeshDest);
otError GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
otError GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
Message *GetDirectTransmission(void);
Message *GetIndirectTransmission(Child &aChild);
otError PrepareDiscoverRequest(void);
void PrepareIndirectTransmission(Message &aMessage, const Child &aChild);
void HandleMesh(uint8_t *aFrame, uint8_t aPayloadLength, const Mac::Address &aMacSource,
const ThreadMessageInfo &aMessageInfo);
void HandleFragment(uint8_t *aFrame, uint8_t aPayloadLength,
const Mac::Address &aMacSource, const Mac::Address &aMacDest,
const ThreadMessageInfo &aMessageInfo);
void HandleLowpanHC(uint8_t *aFrame, uint8_t aPayloadLength,
const Mac::Address &aMacSource, const Mac::Address &aMacDest,
const ThreadMessageInfo &aMessageInfo);
void HandleDataRequest(const Mac::Address &aMacSource, const ThreadMessageInfo &aMessageInfo);
otError SendPoll(Message &aMessage, Mac::Frame &aFrame);
otError SendMesh(Message &aMessage, Mac::Frame &aFrame);
otError SendFragment(Message &aMessage, Mac::Frame &aFrame);
otError SendEmptyFrame(Mac::Frame &aFrame, bool aAckRequest);
otError UpdateIp6Route(Message &aMessage);
otError UpdateMeshRoute(Message &aMessage);
otError HandleDatagram(Message &aMessage, const ThreadMessageInfo &aMessageInfo,
const Mac::Address &aMacSource);
void ClearReassemblyList(void);
static void HandleReceivedFrame(Mac::Receiver &aReceiver, Mac::Frame &aFrame);
void HandleReceivedFrame(Mac::Frame &aFrame);
static otError HandleFrameRequest(Mac::Sender &aSender, Mac::Frame &aFrame);
otError HandleFrameRequest(Mac::Frame &aFrame);
static void HandleSentFrame(Mac::Sender &aSender, Mac::Frame &aFrame, otError aError);
void HandleSentFrame(Mac::Frame &aFrame, otError aError);
static void HandleDiscoverTimer(Timer &aTimer);
void HandleDiscoverTimer(void);
static void HandleReassemblyTimer(Timer &aTimer);
void HandleReassemblyTimer(void);
static void ScheduleTransmissionTask(Tasklet &aTasklet);
void ScheduleTransmissionTask(void);
static void HandleDataPollTimeout(Mac::Receiver &aReceiver);
otError AddPendingSrcMatchEntries(void);
otError AddSrcMatchEntry(Child &aChild);
void ClearSrcMatchEntry(Child &aChild);
static MeshForwarder &GetOwner(const Context &aContext);
void LogIp6Message(MessageAction aAction, const Message &aMessage, const Mac::Address *aMacAddress,
otError aError);
Mac::Receiver mMacReceiver;
Mac::Sender mMacSender;
Timer mDiscoverTimer;
Timer mReassemblyTimer;
PriorityQueue mSendQueue;
MessageQueue mReassemblyList;
MessageQueue mResolvingQueue;
uint16_t mFragTag;
uint16_t mMessageNextOffset;
uint32_t mSendMessageFrameCounter;
Message *mSendMessage;
bool mSendMessageIsARetransmission;
uint8_t mSendMessageMaxMacTxAttempts;
uint8_t mSendMessageKeyId;
uint8_t mSendMessageDataSequenceNumber;
uint8_t mStartChildIndex;
Mac::Address mMacSource;
Mac::Address mMacDest;
uint16_t mMeshSource;
uint16_t mMeshDest;
bool mAddMeshHeader;
bool mSendBusy;
Tasklet mScheduleTransmissionTask;
bool mEnabled;
uint32_t mScanChannels;
uint8_t mScanChannel;
uint8_t mRestoreChannel;
uint16_t mRestorePanId;
bool mScanning;
DataPollManager mDataPollManager;
SourceMatchController mSourceMatchController;
otIpCounters mIpCounters;
};
/**
* @}
*
*/
} // namespace ot
#endif // MESH_FORWARDER_HPP_