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 Management Framework(TMF) Tlv. 32 */ 33 34 #ifndef OTBR_COMMON_TLV_HPP_ 35 #define OTBR_COMMON_TLV_HPP_ 36 37 #include "openthread-br/config.h" 38 39 #include <stdint.h> 40 #include <string.h> 41 42 namespace otbr { 43 44 /** 45 * This class implements TMF Tlv functionality. 46 * 47 */ 48 class Tlv 49 { 50 enum 51 { 52 kLengthEscape = 0xff, ///< This length value indicates the actual length is of two-bytes length. 53 }; 54 55 public: 56 /** 57 * This method returns the Tlv type. 58 * 59 * @returns The Tlv type. 60 * 61 */ GetType(void) const62 uint8_t GetType(void) const { return mType; } 63 64 /** 65 * This method sets the Tlv type. 66 * 67 */ SetType(uint8_t aType)68 void SetType(uint8_t aType) { mType = aType; } 69 70 /** 71 * This method returns the Tlv length. 72 * 73 * @returns The Tlv length. 74 * 75 */ GetLength(void) const76 uint16_t GetLength(void) const 77 { 78 return (mLength != kLengthEscape ? mLength : static_cast<uint16_t>((&mLength)[1] << 8 | (&mLength)[2])); 79 } 80 81 /** 82 * This method sets the length. 83 */ SetLength(uint16_t aLength,bool aForceExtended=false)84 void SetLength(uint16_t aLength, bool aForceExtended = false) 85 { 86 if (aLength >= kLengthEscape || aForceExtended) 87 { 88 mLength = kLengthEscape; 89 (&mLength)[1] = (aLength >> 8); 90 (&mLength)[2] = (aLength & 0xff); 91 } 92 else 93 { 94 mLength = static_cast<uint8_t>(aLength); 95 } 96 } 97 98 /** 99 * This method returns a pointer to the value. 100 * 101 * @returns The Tlv value. 102 * 103 */ GetValue(void) const104 const void *GetValue(void) const 105 { 106 return reinterpret_cast<const uint8_t *>(this) + sizeof(mType) + 107 (mLength != kLengthEscape ? sizeof(mLength) : (sizeof(uint16_t) + sizeof(mLength))); 108 } 109 110 /** 111 * This method returns the value as a uint16_t. 112 * 113 * @returns The uint16_t value. 114 * 115 */ GetValueUInt16(void) const116 uint16_t GetValueUInt16(void) const 117 { 118 const uint8_t *p = static_cast<const uint8_t *>(GetValue()); 119 120 return static_cast<uint16_t>(p[0] << 8 | p[1]); 121 } 122 123 /** 124 * This method returns the value as a uint8_t. 125 * 126 * @returns The uint8_t value. 127 * 128 */ GetValueUInt8(void) const129 uint8_t GetValueUInt8(void) const { return *static_cast<const uint8_t *>(GetValue()); } 130 131 /** 132 * This method sets a uint64_t as the value. 133 * 134 * @param[in] aValue The uint64_t value. 135 * 136 */ SetValue(uint64_t aValue)137 void SetValue(uint64_t aValue) 138 { 139 uint8_t *value; 140 141 SetLength(sizeof(aValue), false); 142 value = static_cast<uint8_t *>(GetValue()); 143 for (int i = 0; i < int{sizeof(aValue)}; ++i) 144 { 145 value[i] = (aValue >> (8 * (sizeof(aValue) - i - 1))) & 0xff; 146 } 147 } 148 149 /** 150 * This method sets a uint32_t as the value. 151 * 152 * @param[in] aValue The uint32_t value. 153 * 154 */ SetValue(uint32_t aValue)155 void SetValue(uint32_t aValue) 156 { 157 uint8_t *value; 158 159 SetLength(sizeof(aValue), false); 160 value = static_cast<uint8_t *>(GetValue()); 161 for (int i = 0; i < int{sizeof(aValue)}; ++i) 162 { 163 value[i] = (aValue >> (8 * (sizeof(aValue) - i - 1))) & 0xff; 164 } 165 } 166 167 /** 168 * This method sets uint16_t as the value. 169 * 170 * @param[in] aValue The uint16_t value. 171 * 172 */ SetValue(uint16_t aValue)173 void SetValue(uint16_t aValue) 174 { 175 uint8_t *value; 176 177 SetLength(sizeof(aValue), false); 178 value = static_cast<uint8_t *>(GetValue()); 179 value[0] = (aValue >> 8); 180 value[1] = (aValue & 0xff); 181 } 182 183 /** 184 * This method sets uint8_t as the value. 185 * 186 * @param[in] aValue The uint8_t value. 187 * 188 */ SetValue(uint8_t aValue)189 void SetValue(uint8_t aValue) 190 { 191 SetLength(sizeof(aValue), false); 192 *static_cast<uint8_t *>(GetValue()) = aValue; 193 } 194 195 /** 196 * This method sets int8_t as the value. 197 * 198 * @param[in] aValue The int8_t value. 199 * 200 */ SetValue(int8_t aValue)201 void SetValue(int8_t aValue) 202 { 203 SetLength(sizeof(aValue), false); 204 *static_cast<int8_t *>(GetValue()) = aValue; 205 } 206 207 /** 208 * This method copies the value. 209 */ SetValue(const void * aValue,uint16_t aLength,bool aForceExtended=false)210 void SetValue(const void *aValue, uint16_t aLength, bool aForceExtended = false) 211 { 212 SetLength(aLength, aForceExtended); 213 memcpy(GetValue(), aValue, aLength); 214 } 215 216 /** 217 * This method returns the pointer to the next Tlv. 218 * 219 * @returns A pointer to the next Tlv. 220 * 221 */ GetNext(void) const222 const Tlv *GetNext(void) const 223 { 224 return reinterpret_cast<const Tlv *>(static_cast<const uint8_t *>(GetValue()) + GetLength()); 225 } 226 227 /** 228 * This method returns the pointer to the next Tlv. 229 * 230 * @returns A pointer to the next Tlv. 231 * 232 */ GetNext(void)233 Tlv *GetNext(void) { return reinterpret_cast<Tlv *>(static_cast<uint8_t *>(GetValue()) + GetLength()); } 234 235 private: GetValue(void)236 void *GetValue(void) 237 { 238 return reinterpret_cast<uint8_t *>(this) + sizeof(mType) + 239 (mLength != kLengthEscape ? sizeof(mLength) : (sizeof(uint16_t) + sizeof(mLength))); 240 } 241 uint8_t mType; 242 uint8_t mLength; 243 }; 244 245 namespace Meshcop { 246 247 enum 248 { 249 kState = 16, 250 kCommissionerId = 10, 251 kCommissionerSessionId = 11, 252 kJoinerDtlsEncapsulation = 17, 253 kSteeringData = 8, 254 kJoinerUdpPort = 18, 255 kJoinerIid = 19, 256 kJoinerRouterLocator = 20, 257 kJoinerRouterKek = 21, 258 kUdpEncapsulation = 48, 259 kIPv6Address = 49, 260 }; 261 262 enum 263 { 264 kStateAccepted = 1, 265 kStatePending = 0, 266 kStateRejected = -1, 267 }; 268 269 } // namespace Meshcop 270 271 } // namespace otbr 272 273 #endif // OTBR_COMMON_TLV_HPP_ 274