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 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 * 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 * 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 * 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 * 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 * 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 * 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 * Represents an iterator for iterating over TREL peer table entries. 150 * 151 */ 152 typedef otTrelPeerIterator PeerIterator; 153 154 /** 155 * Enables or disables the TREL interface. 156 * 157 * @param[in] aEnable A boolean to enable/disable the TREL interface. 158 */ 159 void SetEnabled(bool aEnable); 160 161 /** 162 * Enables the TREL interface. 163 * 164 * This call initiates an ongoing DNS-SD browse on the service name "_trel._udp" within the local browsing domain 165 * to discover other devices supporting TREL. Device also registers a new service to be advertised using DNS-SD, 166 * with the service name is "_trel._udp" indicating its support for TREL. Device is ready to receive TREL messages 167 * from peers. 168 * 169 */ 170 void Enable(void); 171 172 /** 173 * Disables the TREL interface. 174 * 175 * This call stops the DNS-SD browse on the service name "_trel._udp", stops advertising TREL DNS-SD service, and 176 * clears the TREL peer table. 177 * 178 */ 179 void Disable(void); 180 181 /** 182 * Indicates whether the TREL interface is enabled. 183 * 184 * @retval TRUE if the TREL interface is enabled. 185 * @retval FALSE if the TREL interface is disabled. 186 * 187 */ IsEnabled(void) const188 bool IsEnabled(void) const { return mEnabled; } 189 190 /** 191 * Initializes a peer table iterator. 192 * 193 * @param[in] aIterator The iterator to initialize. 194 * 195 */ InitIterator(PeerIterator & aIterator) const196 void InitIterator(PeerIterator &aIterator) const { aIterator = 0; } 197 198 /** 199 * Iterates over the peer table entries. 200 * 201 * @param[in] aIterator The iterator. MUST be initialized. 202 * 203 * @returns A pointer to the next `Peer` entry or `nullptr` if no more entries in the table. 204 * 205 */ 206 const Peer *GetNextPeer(PeerIterator &aIterator) const; 207 208 /** 209 * Sets the filter mode (enables/disables filtering). 210 * 211 * When filtering is enabled, any rx and tx traffic through TREL interface is silently dropped. This is mainly 212 * intended for use during testing. 213 * 214 * Unlike `Enable()/Disable()` which fully start/stop the TREL interface operation, when filter mode is enabled the 215 * TREL interface continues to be enabled. 216 * 217 * @param[in] aFiltered TRUE to enable filter mode, FALSE to disable filter mode. 218 * 219 */ SetFilterEnabled(bool aEnable)220 void SetFilterEnabled(bool aEnable) { mFiltered = aEnable; } 221 222 /** 223 * Indicates whether or not the filter mode is enabled. 224 * 225 * @retval TRUE if the TREL filter mode is enabled. 226 * @retval FALSE if the TREL filter mode is disabled. 227 * 228 */ IsFilterEnabled(void) const229 bool IsFilterEnabled(void) const { return mFiltered; } 230 231 private: 232 static constexpr uint16_t kPeerTableExtraEntries = 32; 233 static constexpr uint16_t kPeerTableSize = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries; 234 235 static const char kTxtRecordExtAddressKey[]; 236 static const char kTxtRecordExtPanIdKey[]; 237 238 typedef Array<Peer, kPeerTableSize, uint16_t> PeerTable; 239 240 explicit Interface(Instance &aInstance); 241 242 // Methods used by `Trel::Link`. 243 void Init(void); 244 void HandleExtAddressChange(void); 245 void HandleExtPanIdChange(void); 246 Error Send(const Packet &aPacket, bool aIsDiscovery = false); 247 248 // Callbacks from `otPlatTrel`. 249 void HandleReceived(uint8_t *aBuffer, uint16_t aLength); 250 void HandleDiscoveredPeerInfo(const Peer::Info &aInfo); 251 252 void RegisterService(void); 253 Error ParsePeerInfoTxtData(const Peer::Info &aInfo, 254 Mac::ExtAddress &aExtAddress, 255 MeshCoP::ExtendedPanId &aExtPanId) const; 256 Peer *GetNewPeerEntry(void); 257 void RemovePeerEntry(Peer &aEntry); 258 259 using RegisterServiceTask = TaskletIn<Interface, &Interface::RegisterService>; 260 261 bool mInitialized : 1; 262 bool mEnabled : 1; 263 bool mFiltered : 1; 264 RegisterServiceTask mRegisterServiceTask; 265 uint16_t mUdpPort; 266 Packet mRxPacket; 267 PeerTable mPeerTable; 268 }; 269 270 } // namespace Trel 271 } // namespace ot 272 273 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 274 275 #endif // TREL_INTERFACE_HPP_ 276