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