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