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