1 /* 2 * Copyright (c) 2017, 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 definition for Thread border agent. 32 */ 33 34 #ifndef OTBR_AGENT_BORDER_AGENT_HPP_ 35 #define OTBR_AGENT_BORDER_AGENT_HPP_ 36 37 #include "openthread-br/config.h" 38 39 #include <vector> 40 41 #include <stdint.h> 42 43 #include "backbone_router/backbone_agent.hpp" 44 #include "common/code_utils.hpp" 45 #include "common/mainloop.hpp" 46 #include "host/rcp_host.hpp" 47 #include "mdns/mdns.hpp" 48 #include "sdp_proxy/advertising_proxy.hpp" 49 #include "sdp_proxy/discovery_proxy.hpp" 50 #include "trel_dnssd/trel_dnssd.hpp" 51 52 #ifndef OTBR_VENDOR_NAME 53 #define OTBR_VENDOR_NAME "OpenThread" 54 #endif 55 56 #ifndef OTBR_PRODUCT_NAME 57 #define OTBR_PRODUCT_NAME "BorderRouter" 58 #endif 59 60 #ifndef OTBR_MESHCOP_SERVICE_INSTANCE_NAME 61 #define OTBR_MESHCOP_SERVICE_INSTANCE_NAME (OTBR_VENDOR_NAME " " OTBR_PRODUCT_NAME) 62 #endif 63 64 namespace otbr { 65 66 /** 67 * @addtogroup border-router-border-agent 68 * 69 * @brief 70 * This module includes definition for Thread border agent 71 * 72 * @{ 73 */ 74 75 /** 76 * This class implements Thread border agent functionality. 77 */ 78 class BorderAgent : public Mdns::StateObserver, private NonCopyable 79 { 80 public: 81 /** The callback for receiving ephemeral key changes. */ 82 using EphemeralKeyChangedCallback = std::function<void(void)>; 83 84 /** 85 * The constructor to initialize the Thread border agent. 86 * 87 * @param[in] aHost A reference to the Thread controller. 88 * @param[in] aPublisher A reference to the mDNS Publisher. 89 */ 90 BorderAgent(otbr::Host::RcpHost &aHost, Mdns::Publisher &aPublisher); 91 92 ~BorderAgent(void) = default; 93 94 /** 95 * Initializes the Thread Border Agent. 96 */ 97 void Init(void); 98 99 /** 100 * Deinitializes the Thread Border Agent. 101 */ 102 void Deinit(void); 103 104 /** 105 * Overrides MeshCoP service (i.e. _meshcop._udp) instance name, product name, vendor name and vendor OUI. 106 * 107 * This method must be called before this BorderAgent is enabled by SetEnabled. 108 * 109 * @param[in] aServiceInstanceName The service instance name; suffix may be appended to this value to avoid 110 * name conflicts. 111 * @param[in] aProductName The product name; must not exceed length of kMaxProductNameLength 112 * and an empty string will be ignored. 113 * @param[in] aVendorName The vendor name; must not exceed length of kMaxVendorNameLength 114 * and an empty string will be ignored. 115 * @param[in] aVendorOui The vendor OUI; must have length of 3 bytes or be empty and ignored. 116 * @param[in] aNonStandardTxtEntries Non-standard (vendor-specific) TXT entries whose key MUST start with "v" 117 * 118 * @returns OTBR_ERROR_INVALID_ARGS If aVendorName, aProductName or aVendorOui exceeds the 119 * allowed ranges or invalid keys are found in aNonStandardTxtEntries 120 * @returns OTBR_ERROR_NONE If successfully set the meshcop service values. 121 */ 122 otbrError SetMeshCopServiceValues(const std::string &aServiceInstanceName, 123 const std::string &aProductName, 124 const std::string &aVendorName, 125 const std::vector<uint8_t> &aVendorOui = {}, 126 const Mdns::Publisher::TxtList &aNonStandardTxtEntries = {}); 127 128 /** 129 * This method enables/disables the Border Agent. 130 * 131 * @param[in] aIsEnabled Whether to enable the Border Agent. 132 */ 133 void SetEnabled(bool aIsEnabled); 134 135 /** 136 * This method enables/disables the Border Agent Ephemeral Key feature. 137 * 138 * @param[in] aIsEnabled Whether to enable the BA Ephemeral Key feature. 139 */ 140 void SetEphemeralKeyEnabled(bool aIsEnabled); 141 142 /** 143 * This method returns the Border Agent Ephemeral Key feature state. 144 */ GetEphemeralKeyEnabled(void) const145 bool GetEphemeralKeyEnabled(void) const { return mIsEphemeralKeyEnabled; } 146 147 /** 148 * This method handles mDNS publisher's state changes. 149 * 150 * @param[in] aState The state of mDNS publisher. 151 */ 152 void HandleMdnsState(Mdns::Publisher::State aState) override; 153 154 /** 155 * This method creates ephemeral key in the Border Agent. 156 * 157 * @param[out] aEphemeralKey The ephemeral key digit string of length 9 with first 8 digits randomly 158 * generated, and the last 9th digit as verhoeff checksum. 159 * 160 * @returns OTBR_ERROR_INVALID_ARGS If Verhoeff checksum calculate returns error. 161 * @returns OTBR_ERROR_NONE If successfully generate the ePSKc. 162 */ 163 static otbrError CreateEphemeralKey(std::string &aEphemeralKey); 164 165 /** 166 * This method adds a callback for ephemeral key changes. 167 * 168 * @param[in] aCallback The callback to receive ephemeral key changed events. 169 */ 170 void AddEphemeralKeyChangedCallback(EphemeralKeyChangedCallback aCallback); 171 172 private: 173 void ClearState(void); 174 void Start(void); 175 void Stop(void); IsEnabled(void) const176 bool IsEnabled(void) const { return mIsEnabled; } 177 void PublishMeshCopService(void); 178 void UpdateMeshCopService(void); 179 void UnpublishMeshCopService(void); 180 #if OTBR_ENABLE_DBUS_SERVER 181 void HandleUpdateVendorMeshCoPTxtEntries(std::map<std::string, std::vector<uint8_t>> aUpdate); 182 #endif 183 184 void HandleThreadStateChanged(otChangedFlags aFlags); 185 186 bool IsThreadStarted(void) const; 187 std::string GetServiceInstanceNameWithExtAddr(const std::string &aServiceInstanceName) const; 188 std::string GetAlternativeServiceInstanceName() const; 189 190 static void HandleEpskcStateChanged(void *aContext); 191 void HandleEpskcStateChanged(void); 192 void PublishEpskcService(void); 193 void UnpublishEpskcService(void); 194 195 otbr::Host::RcpHost &mHost; 196 Mdns::Publisher &mPublisher; 197 bool mIsEnabled; 198 bool mIsEphemeralKeyEnabled; 199 200 std::map<std::string, std::vector<uint8_t>> mMeshCopTxtUpdate; 201 202 std::vector<uint8_t> mVendorOui; 203 204 std::string mVendorName; 205 std::string mProductName; 206 207 // The base service instance name typically consists of the vendor and product name. But it can 208 // also be overridden by `OTBR_MESHCOP_SERVICE_INSTANCE_NAME` or method `SetMeshCopServiceValues()`. 209 // For example, this value can be "OpenThread Border Router". 210 std::string mBaseServiceInstanceName; 211 212 // The actual instance name advertised in the mDNS service. This is usually the value of 213 // `mBaseServiceInstanceName` plus the Extended Address and optional random number for avoiding 214 // conflicts. For example, this value can be "OpenThread Border Router #7AC3" or 215 // "OpenThread Border Router #7AC3 (14379)". 216 std::string mServiceInstanceName; 217 218 std::vector<EphemeralKeyChangedCallback> mEphemeralKeyChangedCallbacks; 219 }; 220 221 /** 222 * @} 223 */ 224 225 } // namespace otbr 226 227 #endif // OTBR_AGENT_BORDER_AGENT_HPP_ 228