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