1 /* 2 * Copyright (c) 2019-2021, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for Thread Radio Encapsulation Link (TREL) interface. 32 */ 33 34 #ifndef TREL_INTERFACE_HPP_ 35 #define TREL_INTERFACE_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 40 41 #include <openthread/trel.h> 42 #include <openthread/platform/trel.h> 43 44 #include "common/array.hpp" 45 #include "common/locator.hpp" 46 #include "common/tasklet.hpp" 47 #include "common/time.hpp" 48 #include "mac/mac_types.hpp" 49 #include "net/ip6_address.hpp" 50 #include "net/socket.hpp" 51 #include "radio/trel_packet.hpp" 52 #include "thread/mle_types.hpp" 53 54 namespace ot { 55 namespace Trel { 56 57 class Link; 58 59 extern "C" void otPlatTrelHandleReceived(otInstance *aInstance, uint8_t *aBuffer, uint16_t aLength); 60 extern "C" void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); 61 62 /** 63 * This class represents a TREL link interface. 64 * 65 */ 66 class Interface : public InstanceLocator 67 { 68 friend class Link; 69 friend void otPlatTrelHandleReceived(otInstance *aInstance, uint8_t *aBuffer, uint16_t aLength); 70 friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); 71 72 public: 73 /** 74 * This class represents information about a discovered TREL peer. 75 * 76 */ 77 class Peer : public otTrelPeer 78 { 79 friend class Interface; 80 friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); 81 82 public: 83 /** 84 * This method returns the Extended MAC Address of the discovered TREL peer. 85 * 86 * @returns The Extended MAC Address of the TREL peer. 87 * 88 */ GetExtAddress(void) const89 const Mac::ExtAddress &GetExtAddress(void) const { return static_cast<const Mac::ExtAddress &>(mExtAddress); } 90 91 /** 92 * This method returns the Extended PAN Identifier of the discovered TREL peer. 93 * 94 * @returns The Extended PAN Identifier of the TREL peer. 95 * 96 */ GetExtPanId(void) const97 const MeshCoP::ExtendedPanId &GetExtPanId(void) const 98 { 99 return static_cast<const MeshCoP::ExtendedPanId &>(mExtPanId); 100 } 101 102 /** 103 * This method returns the IPv6 socket address of the discovered TREL peer. 104 * 105 * @returns The IPv6 socket address of the TREP peer. 106 * 107 */ GetSockAddr(void) const108 const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); } 109 110 /** 111 * This method indicates whether the peer matches a given Extended Address. 112 * 113 * @param[in] aExtAddress A Extended Address to match with. 114 * 115 * @retval TRUE if the peer matches @p aExtAddress. 116 * @retval FALSE if the peer does not match @p aExtAddress. 117 * 118 */ Matches(const Mac::ExtAddress & aExtAddress) const119 bool Matches(const Mac::ExtAddress &aExtAddress) const { return GetExtAddress() == aExtAddress; } 120 121 /** 122 * This method indicates whether the peer matches a given Socket Address. 123 * 124 * @param[in] aSockAddr A Socket Address to match with. 125 * 126 * @retval TRUE if the peer matches @p aSockAddr. 127 * @retval FALSE if the peer does not match @p aSockAddr. 128 * 129 */ Matches(const Ip6::SockAddr & aSockAddr) const130 bool Matches(const Ip6::SockAddr &aSockAddr) const { return GetSockAddr() == aSockAddr; } 131 132 private: 133 class Info : public otPlatTrelPeerInfo 134 { 135 public: IsRemoved(void) const136 bool IsRemoved(void) const { return mRemoved; } GetTxtData(void) const137 const uint8_t * GetTxtData(void) const { return mTxtData; } GetTxtLength(void) const138 uint16_t GetTxtLength(void) const { return mTxtLength; } GetSockAddr(void) const139 const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); } 140 }; 141 SetExtAddress(const Mac::ExtAddress & aExtAddress)142 void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; } SetExtPanId(const MeshCoP::ExtendedPanId & aExtPanId)143 void SetExtPanId(const MeshCoP::ExtendedPanId &aExtPanId) { mExtPanId = aExtPanId; } SetSockAddr(const Ip6::SockAddr & aSockAddr)144 void SetSockAddr(const Ip6::SockAddr &aSockAddr) { mSockAddr = aSockAddr; } 145 void Log(const char *aAction) const; 146 }; 147 148 /** 149 * This type represents an iterator for iterating over TREL peer table entries. 150 * 151 */ 152 typedef otTrelPeerIterator PeerIterator; 153 154 /** 155 * This method enables the TREL interface. 156 * 157 * This call initiates an ongoing DNS-SD browse on the service name "_trel._udp" within the local browsing domain 158 * to discover other devices supporting TREL. Device also registers a new service to be advertised using DNS-SD, 159 * with the service name is "_trel._udp" indicating its support for TREL. Device is ready to receive TREL messages 160 * from peers. 161 * 162 */ 163 void Enable(void); 164 165 /** 166 * This method disables the TREL interface. 167 * 168 * This call stops the DNS-SD browse on the service name "_trel._udp", stops advertising TREL DNS-SD service, and 169 * clears the TREL peer table. 170 * 171 */ 172 void Disable(void); 173 174 /** 175 * This method indicates whether the TREL interface is enabled. 176 * 177 * @retval TRUE if the TREL interface is enabled. 178 * @retval FALSE if the TREL interface is disabled. 179 * 180 */ IsEnabled(void) const181 bool IsEnabled(void) const { return mEnabled; } 182 183 /** 184 * This method initializes a peer table iterator. 185 * 186 * @param[in] aIterator The iterator to initialize. 187 * 188 */ InitIterator(PeerIterator & aIterator) const189 void InitIterator(PeerIterator &aIterator) const { aIterator = 0; } 190 191 /** 192 * This method iterates over the peer table entries. 193 * 194 * @param[in] aIterator The iterator. MUST be initialized. 195 * 196 * @returns A pointer to the next `Peer` entry or `nullptr` if no more entries in the table. 197 * 198 */ 199 const Peer *GetNextPeer(PeerIterator &aIterator) const; 200 201 /** 202 * This method sets the filter mode (enables/disables filtering). 203 * 204 * When filtering is enabled, any rx and tx traffic through TREL interface is silently dropped. This is mainly 205 * intended for use during testing. 206 * 207 * Unlike `Enable()/Disable()` which fully start/stop the TREL interface operation, when filter mode is enabled the 208 * TREL interface continues to be enabled. 209 * 210 * @param[in] aFiltered TRUE to enable filter mode, FALSE to disable filter mode. 211 * 212 */ SetFilterEnabled(bool aEnable)213 void SetFilterEnabled(bool aEnable) { mFiltered = aEnable; } 214 215 /** 216 * This method indicates whether or not the filter mode is enabled. 217 * 218 * @retval TRUE if the TREL filter mode is enabled. 219 * @retval FALSE if the TREL filter mode is disabled. 220 * 221 */ IsFilterEnabled(void) const222 bool IsFilterEnabled(void) const { return mFiltered; } 223 224 private: 225 static constexpr uint16_t kPeerTableExtraEntries = 32; 226 static constexpr uint16_t kPeerTableSize = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries; 227 228 static const char kTxtRecordExtAddressKey[]; 229 static const char kTxtRecordExtPanIdKey[]; 230 231 typedef Array<Peer, kPeerTableSize, uint16_t> PeerTable; 232 233 explicit Interface(Instance &aInstance); 234 235 // Methods used by `Trel::Link`. 236 void Init(void); 237 void HandleExtAddressChange(void); 238 void HandleExtPanIdChange(void); 239 Error Send(const Packet &aPacket, bool aIsDiscovery = false); 240 241 // Callbacks from `otPlatTrel`. 242 void HandleReceived(uint8_t *aBuffer, uint16_t aLength); 243 void HandleDiscoveredPeerInfo(const Peer::Info &aInfo); 244 245 static void HandleRegisterServiceTask(Tasklet &aTasklet); 246 void RegisterService(void); 247 Error ParsePeerInfoTxtData(const Peer::Info & aInfo, 248 Mac::ExtAddress & aExtAddress, 249 MeshCoP::ExtendedPanId &aExtPanId) const; 250 Peer * GetNewPeerEntry(void); 251 void RemovePeerEntry(Peer &aEntry); 252 253 bool mInitialized : 1; 254 bool mEnabled : 1; 255 bool mFiltered : 1; 256 Tasklet mRegisterServiceTask; 257 uint16_t mUdpPort; 258 Packet mRxPacket; 259 PeerTable mPeerTable; 260 }; 261 262 } // namespace Trel 263 } // namespace ot 264 265 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 266 267 #endif // TREL_INTERFACE_HPP_ 268