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, 60 uint8_t *aBuffer, 61 uint16_t aLength, 62 const otSockAddr *aSenderAddr); 63 extern "C" void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); 64 65 /** 66 * Represents a group of TREL counters. 67 */ 68 typedef otTrelCounters Counters; 69 70 /** 71 * Represents a TREL link interface. 72 */ 73 class Interface : public InstanceLocator 74 { 75 friend class Link; 76 friend void otPlatTrelHandleReceived(otInstance *aInstance, 77 uint8_t *aBuffer, 78 uint16_t aLength, 79 const otSockAddr *aSenderAddr); 80 friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); 81 82 public: 83 /** 84 * Represents information about a discovered TREL peer. 85 */ 86 class Peer : public otTrelPeer 87 { 88 friend class Interface; 89 friend void otPlatTrelHandleDiscoveredPeerInfo(otInstance *aInstance, const otPlatTrelPeerInfo *aInfo); 90 91 public: 92 /** 93 * Returns the Extended MAC Address of the discovered TREL peer. 94 * 95 * @returns The Extended MAC Address of the TREL peer. 96 */ GetExtAddress(void) const97 const Mac::ExtAddress &GetExtAddress(void) const { return static_cast<const Mac::ExtAddress &>(mExtAddress); } 98 99 /** 100 * Returns the Extended PAN Identifier of the discovered TREL peer. 101 * 102 * @returns The Extended PAN Identifier of the TREL peer. 103 */ GetExtPanId(void) const104 const MeshCoP::ExtendedPanId &GetExtPanId(void) const 105 { 106 return static_cast<const MeshCoP::ExtendedPanId &>(mExtPanId); 107 } 108 109 /** 110 * Returns the IPv6 socket address of the discovered TREL peer. 111 * 112 * @returns The IPv6 socket address of the TREL peer. 113 */ GetSockAddr(void) const114 const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); } 115 116 /** 117 * Set the IPv6 socket address of the discovered TREL peer. 118 * 119 * @param[in] aSockAddr The IPv6 socket address. 120 */ SetSockAddr(const Ip6::SockAddr & aSockAddr)121 void SetSockAddr(const Ip6::SockAddr &aSockAddr) { mSockAddr = aSockAddr; } 122 123 /** 124 * Indicates whether the peer matches a given Extended Address. 125 * 126 * @param[in] aExtAddress A Extended Address to match with. 127 * 128 * @retval TRUE if the peer matches @p aExtAddress. 129 * @retval FALSE if the peer does not match @p aExtAddress. 130 */ Matches(const Mac::ExtAddress & aExtAddress) const131 bool Matches(const Mac::ExtAddress &aExtAddress) const { return GetExtAddress() == aExtAddress; } 132 133 /** 134 * Indicates whether the peer matches a given Socket Address. 135 * 136 * @param[in] aSockAddr A Socket Address to match with. 137 * 138 * @retval TRUE if the peer matches @p aSockAddr. 139 * @retval FALSE if the peer does not match @p aSockAddr. 140 */ Matches(const Ip6::SockAddr & aSockAddr) const141 bool Matches(const Ip6::SockAddr &aSockAddr) const { return GetSockAddr() == aSockAddr; } 142 143 private: 144 class Info : public otPlatTrelPeerInfo 145 { 146 public: IsRemoved(void) const147 bool IsRemoved(void) const { return mRemoved; } GetTxtData(void) const148 const uint8_t *GetTxtData(void) const { return mTxtData; } GetTxtLength(void) const149 uint16_t GetTxtLength(void) const { return mTxtLength; } GetSockAddr(void) const150 const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); } 151 }; 152 SetExtAddress(const Mac::ExtAddress & aExtAddress)153 void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; } SetExtPanId(const MeshCoP::ExtendedPanId & aExtPanId)154 void SetExtPanId(const MeshCoP::ExtendedPanId &aExtPanId) { mExtPanId = aExtPanId; } 155 void Log(const char *aAction) const; 156 }; 157 158 /** 159 * Represents an iterator for iterating over TREL peer table entries. 160 */ 161 typedef otTrelPeerIterator PeerIterator; 162 163 /** 164 * Enables or disables the TREL interface. 165 * 166 * @param[in] aEnable A boolean to enable/disable the TREL interface. 167 */ 168 void SetEnabled(bool aEnable); 169 170 /** 171 * Enables the TREL interface. 172 * 173 * This call initiates an ongoing DNS-SD browse on the service name "_trel._udp" within the local browsing domain 174 * to discover other devices supporting TREL. Device also registers a new service to be advertised using DNS-SD, 175 * with the service name is "_trel._udp" indicating its support for TREL. Device is ready to receive TREL messages 176 * from peers. 177 */ 178 void Enable(void); 179 180 /** 181 * Disables the TREL interface. 182 * 183 * This call stops the DNS-SD browse on the service name "_trel._udp", stops advertising TREL DNS-SD service, and 184 * clears the TREL peer table. 185 */ 186 void Disable(void); 187 188 /** 189 * Indicates whether the TREL interface is enabled. 190 * 191 * @retval TRUE if the TREL interface is enabled. 192 * @retval FALSE if the TREL interface is disabled. 193 */ IsEnabled(void) const194 bool IsEnabled(void) const { return mEnabled; } 195 196 /** 197 * Initializes a peer table iterator. 198 * 199 * @param[in] aIterator The iterator to initialize. 200 */ InitIterator(PeerIterator & aIterator) const201 void InitIterator(PeerIterator &aIterator) const { aIterator = 0; } 202 203 /** 204 * Iterates over the peer table entries. 205 * 206 * @param[in] aIterator The iterator. MUST be initialized. 207 * 208 * @returns A pointer to the next `Peer` entry or `nullptr` if no more entries in the table. 209 */ 210 const Peer *GetNextPeer(PeerIterator &aIterator) const; 211 212 /** 213 * Returns the number of TREL peers. 214 * 215 * @returns The number of TREL peers. 216 */ GetNumberOfPeers(void) const217 uint16_t GetNumberOfPeers(void) const { return mPeerTable.GetLength(); } 218 219 /** 220 * Sets the filter mode (enables/disables filtering). 221 * 222 * When filtering is enabled, any rx and tx traffic through TREL interface is silently dropped. This is mainly 223 * intended for use during testing. 224 * 225 * Unlike `Enable()/Disable()` which fully start/stop the TREL interface operation, when filter mode is enabled the 226 * TREL interface continues to be enabled. 227 * 228 * @param[in] aFiltered TRUE to enable filter mode, FALSE to disable filter mode. 229 */ SetFilterEnabled(bool aEnable)230 void SetFilterEnabled(bool aEnable) { mFiltered = aEnable; } 231 232 /** 233 * Indicates whether or not the filter mode is enabled. 234 * 235 * @retval TRUE if the TREL filter mode is enabled. 236 * @retval FALSE if the TREL filter mode is disabled. 237 */ IsFilterEnabled(void) const238 bool IsFilterEnabled(void) const { return mFiltered; } 239 240 /** 241 * Gets the TREL counters. 242 * 243 * The counters are initialized to zero when the TREL platform is initialized. 244 */ 245 const Counters *GetCounters(void) const; 246 247 /** 248 * Resets the TREL counters. 249 */ 250 void ResetCounters(void); 251 252 /** 253 * Returns the TREL UDP port. 254 * 255 * @returns The TREL UDP port. 256 */ GetUdpPort(void) const257 uint16_t GetUdpPort(void) const { return mUdpPort; } 258 259 /** 260 * Finds the TREL peer associated with a given Extended Address. 261 * 262 * @param[in] aExtAddress The extended address. 263 * 264 * @returns The peer associated with @ aExtAddress, or `nullptr` if not found. 265 */ 266 Peer *FindPeer(const Mac::ExtAddress &aExtAddress); 267 268 /** 269 * Notifies platform that a TREL packet is received from a peer using a different socket address than the one 270 * reported earlier. 271 * 272 * @param[in] aPeerSockAddr The previously reported peer sock addr. 273 * @param[in] aRxSockAddr The address of received packet from the same peer. 274 */ 275 void NotifyPeerSocketAddressDifference(const Ip6::SockAddr &aPeerSockAddr, const Ip6::SockAddr &aRxSockAddr); 276 277 private: 278 #if OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE != 0 279 static constexpr uint16_t kPeerTableSize = OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE; 280 #else 281 static constexpr uint16_t kPeerTableExtraEntries = 32; 282 static constexpr uint16_t kPeerTableSize = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries; 283 #endif 284 static const char kTxtRecordExtAddressKey[]; 285 static const char kTxtRecordExtPanIdKey[]; 286 287 typedef Array<Peer, kPeerTableSize, uint16_t> PeerTable; 288 289 explicit Interface(Instance &aInstance); 290 291 // Methods used by `Trel::Link`. 292 void Init(void); 293 void HandleExtAddressChange(void); 294 void HandleExtPanIdChange(void); 295 Error Send(const Packet &aPacket, bool aIsDiscovery = false); 296 297 // Callbacks from `otPlatTrel`. 298 void HandleReceived(uint8_t *aBuffer, uint16_t aLength, const Ip6::SockAddr &aSenderAddr); 299 void HandleDiscoveredPeerInfo(const Peer::Info &aInfo); 300 301 void RegisterService(void); 302 Error ParsePeerInfoTxtData(const Peer::Info &aInfo, 303 Mac::ExtAddress &aExtAddress, 304 MeshCoP::ExtendedPanId &aExtPanId) const; 305 Peer *GetNewPeerEntry(void); 306 void RemovePeerEntry(Peer &aEntry); 307 308 using RegisterServiceTask = TaskletIn<Interface, &Interface::RegisterService>; 309 310 bool mInitialized : 1; 311 bool mEnabled : 1; 312 bool mFiltered : 1; 313 RegisterServiceTask mRegisterServiceTask; 314 uint16_t mUdpPort; 315 Packet mRxPacket; 316 PeerTable mPeerTable; 317 }; 318 319 } // namespace Trel 320 } // namespace ot 321 322 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 323 324 #endif // TREL_INTERFACE_HPP_ 325