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