/* * Copyright (c) 2019-2021, 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) interface. */ #ifndef TREL_INTERFACE_HPP_ #define TREL_INTERFACE_HPP_ #include "openthread-core-config.h" #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE #include #include #include "common/array.hpp" #include "common/locator.hpp" #include "common/tasklet.hpp" #include "common/time.hpp" #include "mac/mac_types.hpp" #include "net/ip6_address.hpp" #include "net/socket.hpp" #include "radio/trel_packet.hpp" #include "thread/mle_types.hpp" namespace ot { namespace Trel { class Link; extern "C" void otPlatTrelHandleReceived(otInstance *aInstance, uint8_t *aBuffer, uint16_t aLength); extern "C" void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); /** * This class represents a TREL link interface. * */ class Interface : public InstanceLocator { friend class Link; friend void otPlatTrelHandleReceived(otInstance *aInstance, uint8_t *aBuffer, uint16_t aLength); friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); public: /** * This class represents information about a discovered TREL peer. * */ class Peer : public otTrelPeer { friend class Interface; friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); public: /** * This method returns the Extended MAC Address of the discovered TREL peer. * * @returns The Extended MAC Address of the TREL peer. * */ const Mac::ExtAddress &GetExtAddress(void) const { return static_cast(mExtAddress); } /** * This method returns the Extended PAN Identifier of the discovered TREL peer. * * @returns The Extended PAN Identifier of the TREL peer. * */ const MeshCoP::ExtendedPanId &GetExtPanId(void) const { return static_cast(mExtPanId); } /** * This method returns the IPv6 socket address of the discovered TREL peer. * * @returns The IPv6 socket address of the TREP peer. * */ const Ip6::SockAddr &GetSockAddr(void) const { return static_cast(mSockAddr); } /** * This method indicates whether the peer matches a given Extended Address. * * @param[in] aExtAddress A Extended Address to match with. * * @retval TRUE if the peer matches @p aExtAddress. * @retval FALSE if the peer does not match @p aExtAddress. * */ bool Matches(const Mac::ExtAddress &aExtAddress) const { return GetExtAddress() == aExtAddress; } /** * This method indicates whether the peer matches a given Socket Address. * * @param[in] aSockAddr A Socket Address to match with. * * @retval TRUE if the peer matches @p aSockAddr. * @retval FALSE if the peer does not match @p aSockAddr. * */ bool Matches(const Ip6::SockAddr &aSockAddr) const { return GetSockAddr() == aSockAddr; } private: class Info : public otPlatTrelPeerInfo { public: bool IsRemoved(void) const { return mRemoved; } const uint8_t * GetTxtData(void) const { return mTxtData; } uint16_t GetTxtLength(void) const { return mTxtLength; } const Ip6::SockAddr &GetSockAddr(void) const { return static_cast(mSockAddr); } }; void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; } void SetExtPanId(const MeshCoP::ExtendedPanId &aExtPanId) { mExtPanId = aExtPanId; } void SetSockAddr(const Ip6::SockAddr &aSockAddr) { mSockAddr = aSockAddr; } void Log(const char *aAction) const; }; /** * This type represents an iterator for iterating over TREL peer table entries. * */ typedef otTrelPeerIterator PeerIterator; /** * This method enables the TREL interface. * * This call initiates an ongoing DNS-SD browse on the service name "_trel._udp" within the local browsing domain * to discover other devices supporting TREL. Device also registers a new service to be advertised using DNS-SD, * with the service name is "_trel._udp" indicating its support for TREL. Device is ready to receive TREL messages * from peers. * */ void Enable(void); /** * This method disables the TREL interface. * * This call stops the DNS-SD browse on the service name "_trel._udp", stops advertising TREL DNS-SD service, and * clears the TREL peer table. * */ void Disable(void); /** * This method indicates whether the TREL interface is enabled. * * @retval TRUE if the TREL interface is enabled. * @retval FALSE if the TREL interface is disabled. * */ bool IsEnabled(void) const { return mEnabled; } /** * This method initializes a peer table iterator. * * @param[in] aIterator The iterator to initialize. * */ void InitIterator(PeerIterator &aIterator) const { aIterator = 0; } /** * This method iterates over the peer table entries. * * @param[in] aIterator The iterator. MUST be initialized. * * @returns A pointer to the next `Peer` entry or `nullptr` if no more entries in the table. * */ const Peer *GetNextPeer(PeerIterator &aIterator) const; /** * This method sets the filter mode (enables/disables filtering). * * When filtering is enabled, any rx and tx traffic through TREL interface is silently dropped. This is mainly * intended for use during testing. * * Unlike `Enable()/Disable()` which fully start/stop the TREL interface operation, when filter mode is enabled the * TREL interface continues to be enabled. * * @param[in] aFiltered TRUE to enable filter mode, FALSE to disable filter mode. * */ void SetFilterEnabled(bool aEnable) { mFiltered = aEnable; } /** * This method indicates whether or not the filter mode is enabled. * * @retval TRUE if the TREL filter mode is enabled. * @retval FALSE if the TREL filter mode is disabled. * */ bool IsFilterEnabled(void) const { return mFiltered; } private: static constexpr uint16_t kPeerTableExtraEntries = 32; static constexpr uint16_t kPeerTableSize = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries; static const char kTxtRecordExtAddressKey[]; static const char kTxtRecordExtPanIdKey[]; typedef Array PeerTable; explicit Interface(Instance &aInstance); // Methods used by `Trel::Link`. void Init(void); void HandleExtAddressChange(void); void HandleExtPanIdChange(void); Error Send(const Packet &aPacket, bool aIsDiscovery = false); // Callbacks from `otPlatTrel`. void HandleReceived(uint8_t *aBuffer, uint16_t aLength); void HandleDiscoveredPeerInfo(const Peer::Info &aInfo); static void HandleRegisterServiceTask(Tasklet &aTasklet); void RegisterService(void); Error ParsePeerInfoTxtData(const Peer::Info & aInfo, Mac::ExtAddress & aExtAddress, MeshCoP::ExtendedPanId &aExtPanId) const; Peer * GetNewPeerEntry(void); void RemovePeerEntry(Peer &aEntry); bool mInitialized : 1; bool mEnabled : 1; bool mFiltered : 1; Tasklet mRegisterServiceTask; uint16_t mUdpPort; Packet mRxPacket; PeerTable mPeerTable; }; } // namespace Trel } // namespace ot #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE #endif // TREL_INTERFACE_HPP_