Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 1 | /* |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 2 | * Copyright (c) 2019-2021, The OpenThread Authors. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 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 | |
Abtin Keshavarzian | 743e913 | 2021-04-05 14:13:24 -0700 | [diff] [blame] | 39 | #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| 40 | |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 41 | #include <openthread/trel.h> |
| 42 | #include <openthread/platform/trel.h> |
| 43 | |
| 44 | #include "common/array.hpp" |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 45 | #include "common/locator.hpp" |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 46 | #include "common/tasklet.hpp" |
| 47 | #include "common/time.hpp" |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 48 | #include "mac/mac_types.hpp" |
| 49 | #include "net/ip6_address.hpp" |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 50 | #include "net/socket.hpp" |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 51 | #include "radio/trel_packet.hpp" |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 52 | #include "thread/mle_types.hpp" |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 53 | |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 54 | namespace ot { |
| 55 | namespace Trel { |
| 56 | |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 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 | |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 62 | /** |
| 63 | * This class represents a TREL link interface. |
| 64 | * |
| 65 | */ |
| 66 | class Interface : public InstanceLocator |
| 67 | { |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 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 | |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 72 | public: |
| 73 | /** |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 74 | * This class represents information about a discovered TREL peer. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 75 | * |
| 76 | */ |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 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 | */ |
| 89 | 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 | */ |
Jonathan Hui | 515c3d3 | 2022-04-20 12:20:50 -0700 | [diff] [blame] | 97 | const MeshCoP::ExtendedPanId &GetExtPanId(void) const |
| 98 | { |
| 99 | return static_cast<const MeshCoP::ExtendedPanId &>(mExtPanId); |
| 100 | } |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 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 | */ |
| 108 | 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 | */ |
| 119 | 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 | */ |
| 130 | bool Matches(const Ip6::SockAddr &aSockAddr) const { return GetSockAddr() == aSockAddr; } |
| 131 | |
| 132 | private: |
| 133 | class Info : public otPlatTrelPeerInfo |
| 134 | { |
| 135 | public: |
| 136 | bool IsRemoved(void) const { return mRemoved; } |
Jonathan Hui | 9c467a2 | 2022-12-06 14:39:30 -0800 | [diff] [blame] | 137 | const uint8_t *GetTxtData(void) const { return mTxtData; } |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 138 | uint16_t GetTxtLength(void) const { return mTxtLength; } |
| 139 | const Ip6::SockAddr &GetSockAddr(void) const { return static_cast<const Ip6::SockAddr &>(mSockAddr); } |
| 140 | }; |
| 141 | |
| 142 | void SetExtAddress(const Mac::ExtAddress &aExtAddress) { mExtAddress = aExtAddress; } |
Jonathan Hui | 515c3d3 | 2022-04-20 12:20:50 -0700 | [diff] [blame] | 143 | void SetExtPanId(const MeshCoP::ExtendedPanId &aExtPanId) { mExtPanId = aExtPanId; } |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 144 | void SetSockAddr(const Ip6::SockAddr &aSockAddr) { mSockAddr = aSockAddr; } |
| 145 | void Log(const char *aAction) const; |
| 146 | }; |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 147 | |
| 148 | /** |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 149 | * This type represents an iterator for iterating over TREL peer table entries. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 150 | * |
| 151 | */ |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 152 | typedef otTrelPeerIterator PeerIterator; |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 153 | |
| 154 | /** |
Yang Sun | 27e56b3 | 2023-02-14 13:30:39 +0800 | [diff] [blame] | 155 | * This method 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 | /** |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 162 | * This method enables the TREL interface. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 163 | * |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 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. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 168 | * |
| 169 | */ |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 170 | void Enable(void); |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 171 | |
| 172 | /** |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 173 | * This method 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. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 177 | * |
| 178 | */ |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 179 | void Disable(void); |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 180 | |
| 181 | /** |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 182 | * This method indicates whether the TREL interface is enabled. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 183 | * |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 184 | * @retval TRUE if the TREL interface is enabled. |
| 185 | * @retval FALSE if the TREL interface is disabled. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 186 | * |
| 187 | */ |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 188 | bool IsEnabled(void) const { return mEnabled; } |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 189 | |
| 190 | /** |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 191 | * This method initializes a peer table iterator. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 192 | * |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 193 | * @param[in] aIterator The iterator to initialize. |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 194 | * |
| 195 | */ |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 196 | void InitIterator(PeerIterator &aIterator) const { aIterator = 0; } |
| 197 | |
| 198 | /** |
| 199 | * This method 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 | * This method 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 | */ |
| 220 | void SetFilterEnabled(bool aEnable) { mFiltered = aEnable; } |
| 221 | |
| 222 | /** |
| 223 | * This method 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 | */ |
| 229 | bool IsFilterEnabled(void) const { return mFiltered; } |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 230 | |
| 231 | private: |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 232 | static constexpr uint16_t kPeerTableExtraEntries = 32; |
| 233 | static constexpr uint16_t kPeerTableSize = Mle::kMaxRouters + Mle::kMaxChildren + kPeerTableExtraEntries; |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 234 | |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 235 | static const char kTxtRecordExtAddressKey[]; |
| 236 | static const char kTxtRecordExtPanIdKey[]; |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 237 | |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 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 | |
Abtin Keshavarzian | 9699d31 | 2022-08-24 10:44:48 -0700 | [diff] [blame] | 252 | void RegisterService(void); |
Jonathan Hui | 9c467a2 | 2022-12-06 14:39:30 -0800 | [diff] [blame] | 253 | Error ParsePeerInfoTxtData(const Peer::Info &aInfo, |
| 254 | Mac::ExtAddress &aExtAddress, |
Abtin Keshavarzian | 9699d31 | 2022-08-24 10:44:48 -0700 | [diff] [blame] | 255 | MeshCoP::ExtendedPanId &aExtPanId) const; |
| 256 | Peer *GetNewPeerEntry(void); |
| 257 | void RemovePeerEntry(Peer &aEntry); |
Abtin Keshavarzian | 69ad966 | 2021-10-20 17:54:25 -0700 | [diff] [blame] | 258 | |
Jonathan Hui | 3d39d24 | 2023-04-11 22:39:35 -0700 | [diff] [blame] | 259 | using RegisterServiceTask = TaskletIn<Interface, &Interface::RegisterService>; |
Abtin Keshavarzian | 9699d31 | 2022-08-24 10:44:48 -0700 | [diff] [blame] | 260 | |
| 261 | bool mInitialized : 1; |
| 262 | bool mEnabled : 1; |
| 263 | bool mFiltered : 1; |
Jonathan Hui | 3d39d24 | 2023-04-11 22:39:35 -0700 | [diff] [blame] | 264 | RegisterServiceTask mRegisterServiceTask; |
Abtin Keshavarzian | 9699d31 | 2022-08-24 10:44:48 -0700 | [diff] [blame] | 265 | uint16_t mUdpPort; |
| 266 | Packet mRxPacket; |
| 267 | PeerTable mPeerTable; |
Abtin Keshavarzian | 2d36853 | 2019-12-18 15:50:50 -0800 | [diff] [blame] | 268 | }; |
| 269 | |
| 270 | } // namespace Trel |
| 271 | } // namespace ot |
| 272 | |
| 273 | #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
| 274 | |
| 275 | #endif // TREL_INTERFACE_HPP_ |