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 private: 260 #if OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE != 0 261 static constexpr uint16_t kPeerTableSize = OPENTHREAD_CONFIG_TREL_PEER_TABLE_SIZE; 262 #else 263 static constexpr uint16_t kPeerTableExtraEntries = 32; 264 static constexpr uint16_t kPeerTableSize = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries; 265 #endif 266 static const char kTxtRecordExtAddressKey[]; 267 static const char kTxtRecordExtPanIdKey[]; 268 269 typedef Array<Peer, kPeerTableSize, uint16_t> PeerTable; 270 271 explicit Interface(Instance &aInstance); 272 273 // Methods used by `Trel::Link`. 274 void Init(void); 275 void HandleExtAddressChange(void); 276 void HandleExtPanIdChange(void); 277 Error Send(const Packet &aPacket, bool aIsDiscovery = false); 278 279 // Callbacks from `otPlatTrel`. 280 void HandleReceived(uint8_t *aBuffer, uint16_t aLength); 281 void HandleDiscoveredPeerInfo(const Peer::Info &aInfo); 282 283 void RegisterService(void); 284 Error ParsePeerInfoTxtData(const Peer::Info &aInfo, 285 Mac::ExtAddress &aExtAddress, 286 MeshCoP::ExtendedPanId &aExtPanId) const; 287 Peer *GetNewPeerEntry(void); 288 void RemovePeerEntry(Peer &aEntry); 289 290 using RegisterServiceTask = TaskletIn<Interface, &Interface::RegisterService>; 291 292 bool mInitialized : 1; 293 bool mEnabled : 1; 294 bool mFiltered : 1; 295 RegisterServiceTask mRegisterServiceTask; 296 uint16_t mUdpPort; 297 Packet mRxPacket; 298 PeerTable mPeerTable; 299 }; 300 301 } // namespace Trel 302 } // namespace ot 303 304 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 305 306 #endif // TREL_INTERFACE_HPP_ 307