1 /* 2 * Copyright (c) 2020, 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 generating and processing Link Metrics TLVs. 32 * 33 */ 34 35 #ifndef LINK_METRICS_TLVS_HPP_ 36 #define LINK_METRICS_TLVS_HPP_ 37 38 #include "openthread-core-config.h" 39 40 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 41 42 #include <openthread/link_metrics.h> 43 44 #include "common/clearable.hpp" 45 #include "common/encoding.hpp" 46 #include "common/message.hpp" 47 #include "common/tlvs.hpp" 48 #include "thread/link_metrics_types.hpp" 49 50 namespace ot { 51 namespace LinkMetrics { 52 53 /** 54 * Defines constants related to Link Metrics Sub-TLVs. 55 * 56 */ 57 class SubTlv 58 { 59 public: 60 /** 61 * Link Metrics Sub-TLV types. 62 * 63 */ 64 enum Type : uint8_t 65 { 66 kReport = 0, ///< Report Sub-TLV 67 kQueryId = 1, ///< Query ID Sub-TLV 68 kQueryOptions = 2, ///< Query Options Sub-TLV 69 kFwdProbingReg = 3, ///< Forward Probing Registration Sub-TLV 70 kStatus = 5, ///< Status Sub-TLV 71 kEnhAckConfig = 7, ///< Enhanced ACK Configuration Sub-TLV 72 }; 73 }; 74 75 /** 76 * Defines Link Metrics Query ID Sub-TLV constants and types. 77 * 78 */ 79 typedef UintTlvInfo<SubTlv::kQueryId, uint8_t> QueryIdSubTlv; 80 81 /** 82 * Defines a Link Metrics Status Sub-Tlv. 83 * 84 */ 85 typedef UintTlvInfo<SubTlv::kStatus, uint8_t> StatusSubTlv; 86 87 /** 88 * Implements Link Metrics Report Sub-TLV generation and parsing. 89 * 90 */ 91 OT_TOOL_PACKED_BEGIN 92 class ReportSubTlv : public Tlv, public TlvInfo<SubTlv::kReport> 93 { 94 public: 95 static constexpr uint8_t kMinLength = 2; ///< Minimum expected TLV length (type ID and u8 value). 96 97 /** 98 * Initializes the TLV. 99 * 100 */ Init(void)101 void Init(void) { SetType(SubTlv::kReport); } 102 103 /** 104 * Indicates whether or not the TLV appears to be well-formed. 105 * 106 * @retval true The TLV appears to be well-formed. 107 * @retval false The TLV does not appear to be well-formed. 108 * 109 */ IsValid(void) const110 bool IsValid(void) const { return GetLength() >= kMinLength; } 111 112 /** 113 * Returns the Link Metrics Type ID. 114 * 115 * @returns The Link Metrics Type ID. 116 * 117 */ GetMetricsTypeId(void) const118 uint8_t GetMetricsTypeId(void) const { return mMetricsTypeId; } 119 120 /** 121 * Sets the Link Metrics Type ID. 122 * 123 * @param[in] aMetricsTypeId The Link Metrics Type ID to set. 124 * 125 */ SetMetricsTypeId(uint8_t aMetricsTypeId)126 void SetMetricsTypeId(uint8_t aMetricsTypeId) { mMetricsTypeId = aMetricsTypeId; } 127 128 /** 129 * Returns the metric value in 8 bits. 130 * 131 * @returns The metric value. 132 * 133 */ GetMetricsValue8(void) const134 uint8_t GetMetricsValue8(void) const { return mMetricsValue.m8; } 135 136 /** 137 * Returns the metric value in 32 bits. 138 * 139 * @returns The metric value. 140 * 141 */ GetMetricsValue32(void) const142 uint32_t GetMetricsValue32(void) const { return BigEndian::HostSwap32(mMetricsValue.m32); } 143 144 /** 145 * Sets the metric value (8 bits). 146 * 147 * @param[in] aMetricsValue Metrics value. 148 * 149 */ SetMetricsValue8(uint8_t aMetricsValue)150 void SetMetricsValue8(uint8_t aMetricsValue) 151 { 152 mMetricsValue.m8 = aMetricsValue; 153 SetLength(kMinLength); 154 } 155 156 /** 157 * Sets the metric value (32 bits). 158 * 159 * @param[in] aMetricsValue Metrics value. 160 * 161 */ SetMetricsValue32(uint32_t aMetricsValue)162 void SetMetricsValue32(uint32_t aMetricsValue) 163 { 164 mMetricsValue.m32 = BigEndian::HostSwap32(aMetricsValue); 165 SetLength(sizeof(*this) - sizeof(Tlv)); 166 } 167 168 private: 169 uint8_t mMetricsTypeId; 170 union 171 { 172 uint8_t m8; 173 uint32_t m32; 174 } mMetricsValue; 175 } OT_TOOL_PACKED_END; 176 177 /** 178 * Implements Link Metrics Query Options Sub-TLV generation and parsing. 179 * 180 */ 181 OT_TOOL_PACKED_BEGIN 182 class QueryOptionsSubTlv : public Tlv, public TlvInfo<SubTlv::kQueryOptions> 183 { 184 public: 185 /** 186 * Initializes the TLV. 187 * 188 */ Init(void)189 void Init(void) 190 { 191 SetType(SubTlv::kQueryOptions); 192 SetLength(0); 193 } 194 195 /** 196 * Indicates whether or not the TLV appears to be well-formed. 197 * 198 * @retval TRUE If the TLV appears to be well-formed. 199 * @retval FALSE If the TLV does not appear to be well-formed. 200 * 201 */ IsValid(void) const202 bool IsValid(void) const { return GetLength() >= sizeof(uint8_t); } 203 204 } OT_TOOL_PACKED_END; 205 206 /** 207 * Defines Link Metrics Forward Probing Registration Sub-TLV. 208 * 209 */ 210 OT_TOOL_PACKED_BEGIN 211 class FwdProbingRegSubTlv : public Tlv, public TlvInfo<SubTlv::kFwdProbingReg> 212 { 213 public: 214 static constexpr uint8_t kMinLength = sizeof(uint8_t) + sizeof(uint8_t); ///< Minimum expected TLV length 215 216 /** 217 * Initializes the TLV. 218 * 219 */ Init(void)220 void Init(void) 221 { 222 SetType(SubTlv::kFwdProbingReg); 223 SetLength(kMinLength); 224 } 225 226 /** 227 * Indicates whether or not the TLV appears to be well-formed. 228 * 229 * @retval true The TLV appears to be well-formed. 230 * @retval false The TLV does not appear to be well-formed. 231 * 232 */ IsValid(void) const233 bool IsValid(void) const { return GetLength() >= kMinLength; } 234 235 /** 236 * Gets the Forward Series ID value. 237 * 238 * @returns The Forward Series ID. 239 * 240 */ GetSeriesId(void) const241 uint8_t GetSeriesId(void) const { return mSeriesId; } 242 243 /** 244 * Sets the Forward Series ID value. 245 * 246 * @param[in] aSeriesId The Forward Series ID. 247 * 248 */ SetSeriesId(uint8_t aSeriesId)249 void SetSeriesId(uint8_t aSeriesId) { mSeriesId = aSeriesId; } 250 251 /** 252 * Gets the Forward Series Flags bit-mask. 253 * 254 * @returns The Forward Series Flags mask. 255 * 256 */ GetSeriesFlagsMask(void) const257 uint8_t GetSeriesFlagsMask(void) const { return mSeriesFlagsMask; } 258 259 /** 260 * Sets the Forward Series Flags bit-mask 261 * 262 * @param[in] aSeriesFlagsMask The Forward Series Flags. 263 * 264 */ SetSeriesFlagsMask(uint8_t aSeriesFlagsMask)265 void SetSeriesFlagsMask(uint8_t aSeriesFlagsMask) { mSeriesFlagsMask = aSeriesFlagsMask; } 266 267 /** 268 * Gets the start of Type ID array. 269 * 270 * @returns The start of Type ID array. Array has `kMaxTypeIds` max length. 271 * 272 */ GetTypeIds(void)273 uint8_t *GetTypeIds(void) { return mTypeIds; } 274 275 private: 276 uint8_t mSeriesId; 277 uint8_t mSeriesFlagsMask; 278 uint8_t mTypeIds[kMaxTypeIds]; 279 } OT_TOOL_PACKED_END; 280 281 OT_TOOL_PACKED_BEGIN 282 class EnhAckConfigSubTlv : public Tlv, public TlvInfo<SubTlv::kEnhAckConfig> 283 { 284 public: 285 static constexpr uint8_t kMinLength = sizeof(uint8_t); ///< Minimum TLV length (only `EnhAckFlags`). 286 287 /** 288 * Initializes the TLV. 289 * 290 */ Init(void)291 void Init(void) 292 { 293 SetType(SubTlv::kEnhAckConfig); 294 SetLength(kMinLength); 295 } 296 297 /** 298 * Indicates whether or not the TLV appears to be well-formed. 299 * 300 * @retval true The TLV appears to be well-formed. 301 * @retval false The TLV does not appear to be well-formed. 302 * 303 */ IsValid(void) const304 bool IsValid(void) const { return GetLength() >= kMinLength; } 305 306 /** 307 * Gets the Enhanced ACK Flags. 308 * 309 * @returns The Enhanced ACK Flags. 310 * 311 */ GetEnhAckFlags(void) const312 uint8_t GetEnhAckFlags(void) const { return mEnhAckFlags; } 313 314 /** 315 * Sets Enhanced ACK Flags. 316 * 317 * @param[in] aEnhAckFlags The value of Enhanced ACK Flags. 318 * 319 */ SetEnhAckFlags(EnhAckFlags aEnhAckFlags)320 void SetEnhAckFlags(EnhAckFlags aEnhAckFlags) { mEnhAckFlags = aEnhAckFlags; } 321 322 /** 323 * Gets the start of Type ID array. 324 * 325 * @returns The start of Type ID array. Array has `kMaxTypeIds` max length. 326 * 327 */ GetTypeIds(void)328 uint8_t *GetTypeIds(void) { return mTypeIds; } 329 330 private: 331 uint8_t mEnhAckFlags; 332 uint8_t mTypeIds[kMaxTypeIds]; 333 } OT_TOOL_PACKED_END; 334 335 } // namespace LinkMetrics 336 } // namespace ot 337 338 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 339 340 #endif // LINK_METRICS_TLVS_HPP_ 341