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 "mdns/mdns.hpp" 47 #include "ncp/rcp_host.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 : 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::Ncp::RcpHost &aHost, Mdns::Publisher &aPublisher); 91 92 ~BorderAgent(void) = default; 93 94 /** 95 * Overrides MeshCoP service (i.e. _meshcop._udp) instance name, product name, vendor name and vendor OUI. 96 * 97 * This method must be called before this BorderAgent is enabled by SetEnabled. 98 * 99 * @param[in] aServiceInstanceName The service instance name; suffix may be appended to this value to avoid 100 * name conflicts. 101 * @param[in] aProductName The product name; must not exceed length of kMaxProductNameLength 102 * and an empty string will be ignored. 103 * @param[in] aVendorName The vendor name; must not exceed length of kMaxVendorNameLength 104 * and an empty string will be ignored. 105 * @param[in] aVendorOui The vendor OUI; must have length of 3 bytes or be empty and ignored. 106 * @param[in] aNonStandardTxtEntries Non-standard (vendor-specific) TXT entries whose key MUST start with "v" 107 * 108 * @returns OTBR_ERROR_INVALID_ARGS If aVendorName, aProductName or aVendorOui exceeds the 109 * allowed ranges or invalid keys are found in aNonStandardTxtEntries 110 * @returns OTBR_ERROR_NONE If successfully set the meshcop service values. 111 */ 112 otbrError SetMeshCopServiceValues(const std::string &aServiceInstanceName, 113 const std::string &aProductName, 114 const std::string &aVendorName, 115 const std::vector<uint8_t> &aVendorOui = {}, 116 const Mdns::Publisher::TxtList &aNonStandardTxtEntries = {}); 117 118 /** 119 * This method enables/disables the Border Agent. 120 * 121 * @param[in] aIsEnabled Whether to enable the Border Agent. 122 */ 123 void SetEnabled(bool aIsEnabled); 124 125 /** 126 * This method enables/disables the Border Agent Ephemeral Key feature. 127 * 128 * @param[in] aIsEnabled Whether to enable the BA Ephemeral Key feature. 129 */ 130 void SetEphemeralKeyEnabled(bool aIsEnabled); 131 132 /** 133 * This method returns the Border Agent Ephemeral Key feature state. 134 */ GetEphemeralKeyEnabled(void) const135 bool GetEphemeralKeyEnabled(void) const { return mIsEphemeralKeyEnabled; } 136 137 /** 138 * This method handles mDNS publisher's state changes. 139 * 140 * @param[in] aState The state of mDNS publisher. 141 */ 142 void HandleMdnsState(Mdns::Publisher::State aState); 143 144 /** 145 * This method creates ephemeral key in the Border Agent. 146 * 147 * @param[out] aEphemeralKey The ephemeral key digit string of length 9 with first 8 digits randomly 148 * generated, and the last 9th digit as verhoeff checksum. 149 * 150 * @returns OTBR_ERROR_INVALID_ARGS If Verhoeff checksum calculate returns error. 151 * @returns OTBR_ERROR_NONE If successfully generate the ePSKc. 152 */ 153 static otbrError CreateEphemeralKey(std::string &aEphemeralKey); 154 155 /** 156 * This method adds a callback for ephemeral key changes. 157 * 158 * @param[in] aCallback The callback to receive ephemeral key changed events. 159 */ 160 void AddEphemeralKeyChangedCallback(EphemeralKeyChangedCallback aCallback); 161 162 private: 163 void Start(void); 164 void Stop(void); IsEnabled(void) const165 bool IsEnabled(void) const { return mIsEnabled; } 166 void PublishMeshCopService(void); 167 void UpdateMeshCopService(void); 168 void UnpublishMeshCopService(void); 169 #if OTBR_ENABLE_DBUS_SERVER 170 void HandleUpdateVendorMeshCoPTxtEntries(std::map<std::string, std::vector<uint8_t>> aUpdate); 171 #endif 172 173 void HandleThreadStateChanged(otChangedFlags aFlags); 174 175 bool IsThreadStarted(void) const; 176 std::string GetServiceInstanceNameWithExtAddr(const std::string &aServiceInstanceName) const; 177 std::string GetAlternativeServiceInstanceName() const; 178 179 static void HandleEpskcStateChanged(void *aContext); 180 void PublishEpskcService(void); 181 void UnpublishEpskcService(void); 182 183 otbr::Ncp::RcpHost &mHost; 184 Mdns::Publisher &mPublisher; 185 bool mIsEnabled; 186 bool mIsEphemeralKeyEnabled; 187 188 std::map<std::string, std::vector<uint8_t>> mMeshCopTxtUpdate; 189 190 std::vector<uint8_t> mVendorOui; 191 192 std::string mVendorName; 193 std::string mProductName; 194 195 // The base service instance name typically consists of the vendor and product name. But it can 196 // also be overridden by `OTBR_MESHCOP_SERVICE_INSTANCE_NAME` or method `SetMeshCopServiceValues()`. 197 // For example, this value can be "OpenThread Border Router". 198 std::string mBaseServiceInstanceName; 199 200 // The actual instance name advertised in the mDNS service. This is usually the value of 201 // `mBaseServiceInstanceName` plus the Extended Address and optional random number for avoiding 202 // conflicts. For example, this value can be "OpenThread Border Router #7AC3" or 203 // "OpenThread Border Router #7AC3 (14379)". 204 std::string mServiceInstanceName; 205 206 std::vector<EphemeralKeyChangedCallback> mEphemeralKeyChangedCallbacks; 207 }; 208 209 /** 210 * @} 211 */ 212 213 } // namespace otbr 214 215 #endif // OTBR_AGENT_BORDER_AGENT_HPP_ 216