1 /* 2 * Copyright (c) 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 the SRP client buffers and service pool. 32 */ 33 34 #ifndef SRP_CLIENT_BUFFERS_HPP_ 35 #define SRP_CLIENT_BUFFERS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE 40 41 #include <openthread/srp_client_buffers.h> 42 43 #include "common/array.hpp" 44 #include "common/as_core_type.hpp" 45 #include "common/clearable.hpp" 46 #include "common/locator.hpp" 47 #include "common/non_copyable.hpp" 48 #include "common/pool.hpp" 49 #include "net/srp_client.hpp" 50 51 namespace ot { 52 namespace Utils { 53 54 #if !OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE 55 #error "OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE requires OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE feature." 56 #endif 57 58 /** 59 * Represents the SRP client buffers and service pool. 60 */ 61 class SrpClientBuffers : public InstanceLocator, private NonCopyable 62 { 63 public: 64 /** 65 * Maximum number of service entries in the pool. 66 */ 67 static constexpr uint16_t kMaxServices = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_MAX_SERVICES; 68 69 /** 70 * Max number of host address entries. 71 */ 72 static constexpr uint16_t kMaxHostAddresses = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_MAX_HOST_ADDRESSES; 73 74 /** 75 * Size (number of char) of host name string (includes null `\0` termination char). 76 */ 77 static constexpr uint16_t kHostNameSize = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_HOST_NAME_SIZE; 78 79 /** 80 * Size (number of char) of service name string (includes null `\0` termination char). 81 */ 82 static constexpr uint16_t kServiceNameSize = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_SERVICE_NAME_SIZE; 83 84 /** 85 * Array length for service subtype label. 86 */ 87 static constexpr uint16_t kServiceMaxSubTypes = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_SERVICE_MAX_SUB_TYPES; 88 89 /** 90 * Size (number of char) of service instance name string (includes null `\0` termination char). 91 */ 92 static constexpr uint16_t kInstanceNameSize = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_SERVICE_INSTANCE_NAME_SIZE; 93 94 /** 95 * Size (number of bytes) of TXT record buffer. 96 */ 97 static constexpr uint16_t kTxtBufferSize = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_TXT_BUFFER_SIZE; 98 99 /** 100 * Represents a SRP client service entry from the pool. 101 */ 102 class ServiceEntry : public otSrpClientBuffersServiceEntry, public Clearable<ServiceEntry> 103 { 104 friend class SrpClientBuffers; 105 friend class LinkedList<ServiceEntry>; 106 107 public: 108 /** 109 * Gets the string buffer for the service name from the service entry. 110 * 111 * @param[out] aSize Reference to a variable to return the size (number of bytes) of the string buffer. 112 * 113 * @returns A pointer to the string buffer. 114 */ GetServiceNameString(uint16_t & aSize)115 char *GetServiceNameString(uint16_t &aSize) 116 { 117 aSize = sizeof(mServiceName); 118 return mServiceName; 119 } 120 121 /** 122 * Gets the string buffer for the instance name from the service entry. 123 * 124 * @param[out] aSize Reference to a variable to return the size (number of bytes) of the string buffer. 125 * 126 * @returns A pointer to the string buffer. 127 */ GetInstanceNameString(uint16_t & aSize)128 char *GetInstanceNameString(uint16_t &aSize) 129 { 130 aSize = sizeof(mInstanceName); 131 return mInstanceName; 132 } 133 134 /** 135 * Gets the buffer for the TXT value from the service entry. 136 * 137 * @param[out] aSize Reference to a variable to return the size (number of bytes) of the buffer. 138 * 139 * @returns A pointer to the buffer. 140 */ GetTxtBuffer(uint16_t & aSize)141 uint8_t *GetTxtBuffer(uint16_t &aSize) 142 { 143 aSize = sizeof(mTxtBuffer); 144 return mTxtBuffer; 145 } 146 147 /** 148 * Gets the array for service subtype labels from the service entry. 149 * 150 * @param[out] aArrayLength Reference to a variable to return the array length. 151 * 152 * @returns A pointer to the array. 153 */ GetSubTypeLabelsArray(uint16_t & aArrayLength)154 const char **GetSubTypeLabelsArray(uint16_t &aArrayLength) 155 { 156 aArrayLength = GetArrayLength(mSubTypeLabels); 157 return mSubTypeLabels; 158 } 159 160 private: GetNext(void)161 ServiceEntry *GetNext(void) { return reinterpret_cast<ServiceEntry *>(mService.mNext); } GetNext(void) const162 const ServiceEntry *GetNext(void) const { return reinterpret_cast<const ServiceEntry *>(mService.mNext); } SetNext(ServiceEntry * aEntry)163 void SetNext(ServiceEntry *aEntry) { mService.mNext = reinterpret_cast<Srp::Client::Service *>(aEntry); } 164 165 char mServiceName[kServiceNameSize]; 166 char mInstanceName[kInstanceNameSize]; 167 uint8_t mTxtBuffer[kTxtBufferSize]; 168 const char *mSubTypeLabels[kServiceMaxSubTypes + 1]; 169 }; 170 171 /** 172 * Initializes the `SrpClientBuffers` object. 173 * 174 * @param[in] aInstance A reference to the OpenThread instance. 175 */ 176 explicit SrpClientBuffers(Instance &aInstance); 177 178 /** 179 * Gets the string buffer to use for SRP client host name. 180 * 181 * @param[out] aSize Reference to a variable to return the size (number of bytes) of the string buffer. 182 * 183 * @returns A pointer to char buffer to use for SRP client host name. 184 */ GetHostNameString(uint16_t & aSize)185 char *GetHostNameString(uint16_t &aSize) 186 { 187 aSize = sizeof(mHostName); 188 return mHostName; 189 } 190 191 /** 192 * Gets the array of IPv6 address entries to use as SRP client host address list. 193 * 194 * @param[out] aArrayLength Reference to a variable to return the array length (number of IPv6 address entries in 195 * * the array). 196 * 197 * @returns A pointer to an array of `Ip6::Address` entries (number of entries is returned in @p aArrayLength). 198 */ GetHostAddressesArray(uint8_t & aArrayLength)199 Ip6::Address *GetHostAddressesArray(uint8_t &aArrayLength) 200 { 201 aArrayLength = static_cast<uint8_t>(GetArrayLength(mHostAddresses)); 202 return &mHostAddresses[0]; 203 } 204 205 /** 206 * Allocates a new service entry from the pool. 207 * 208 * The returned service entry instance will be initialized as follows: 209 * 210 * - `mService.mName` points to a string buffer which can be retrieved using `GetServiceNameString()`. 211 * - `mService.mInstanceName` points to a string buffer which can be retrieved using `GetInstanceNameString()`. 212 * - `mService.mSubTypeLabels` points to array which can be retrieved using `GetSubTypeLabelsArray()`. 213 * - `mService.mTxtEntries` points to `mTxtEntry`. 214 * - `mService.mNumTxtEntries` is set to one (one entry in the list). 215 * - Other `mService` fields (port, priority, weight) are set to zero. 216 * - `mTxtEntry.mKey` is set to `nullptr` (value is treated as already encoded data). 217 * - `mTxtEntry.mValue` points to a buffer which can be retrieved using `GetTxtBuffer()` 218 * - `mTxtEntry.mValueLength` is set to zero. 219 * - All related data/string buffers and arrays are cleared to all zero. 220 * 221 * @returns A pointer to the newly allocated service entry or `nullptr` if not more entry available in the pool. 222 */ 223 ServiceEntry *AllocateService(void); 224 225 /** 226 * Frees a previously allocated service entry. 227 * 228 * The @p aService MUST be previously allocated using `AllocateService()` and not yet freed. Otherwise the behavior 229 * of this method is undefined. 230 * 231 * @param[in] aServiceEntry A service entry to free. 232 */ FreeService(ServiceEntry & aServiceEntry)233 void FreeService(ServiceEntry &aServiceEntry) { mServicePool.Free(aServiceEntry); } 234 235 /** 236 * Frees all previously allocated service entries. 237 */ FreeAllServices(void)238 void FreeAllServices(void) { mServicePool.FreeAll(); } 239 240 private: 241 char mHostName[kHostNameSize]; 242 Ip6::Address mHostAddresses[kMaxHostAddresses]; 243 Pool<ServiceEntry, kMaxServices> mServicePool; 244 }; 245 246 } // namespace Utils 247 248 DefineCoreType(otSrpClientBuffersServiceEntry, Utils::SrpClientBuffers::ServiceEntry); 249 250 } // namespace ot 251 252 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE 253 254 #endif // SRP_CLIENT_BUFFERS_HPP_ 255