1 /* 2 * Copyright (c) 2023, 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 a signed preference value and its 2-bit unsigned representation used by 32 * Route Preference in RFC-4191. 33 */ 34 35 #ifndef PREFERENCE_HPP_ 36 #define PREFERENCE_HPP_ 37 38 #include "openthread-core-config.h" 39 40 #include "common/error.hpp" 41 42 namespace ot { 43 44 /** 45 * Provides constants and static methods to convert between `int8_t` preference and its 2-bit unsigned 46 * representation. 47 */ 48 class Preference 49 { 50 public: 51 static constexpr int8_t kHigh = 1; ///< High preference. 52 static constexpr int8_t kMedium = 0; ///< Medium preference. 53 static constexpr int8_t kLow = -1; ///< Low preference. 54 55 /** 56 * Converts a signed preference value to its corresponding 2-bit `uint8_t` value. 57 * 58 * A positive @p aPrf is mapped to "High Preference", a negative @p aPrf is mapped to "Low Preference", and 59 * zero @p aPrf is mapped to "Medium Preference". 60 * 61 * @param[in] aPrf The preference to convert to `uint8_t`. 62 * 63 * @returns The 2-bit unsigned value representing @p aPrf. 64 */ 65 static uint8_t To2BitUint(int8_t aPrf); 66 67 /** 68 * Converts a 2-bit `uint8_t` value to a signed preference value `kHigh`, `kMedium`, and `kLow`. 69 * 70 * Only the first two bits (LSB) of @p a2BitUint are used and the rest of the bits are ignored. 71 * 72 * - `0b01` (or 1) is mapped to `kHigh`. 73 * - `0b00` (or 0) is mapped to `kMedium`. 74 * - `0b11` (or 3) is mapped to `kLow`. 75 * - `0b10` (or 2) is reserved for future and is also mapped to `kMedium` (this complies with RFC-4191 where 76 * the reserved value `0b10` MUST be treated as `0b00` for Route Preference). 77 * 78 * @param[in] a2BitUint The 2-bit unsigned value to convert from. Only two LSB bits are used and the reset are 79 * ignored. 80 * 81 * @returns The signed preference `kHigh`, `kMedium`, or `kLow` corresponding to @p a2BitUint. 82 */ 83 static int8_t From2BitUint(uint8_t a2BitUint); 84 85 /** 86 * Indicates whether a given `int8_t` preference value is valid, i.e., whether it has of the 87 * three values `kHigh`, `kMedium`, or `kLow`. 88 * 89 * @param[in] aPrf The signed preference value to check. 90 * 91 * @retval TRUE if @p aPrf is valid. 92 * @retval FALSE if @p aPrf is not valid 93 */ 94 static bool IsValid(int8_t aPrf); 95 96 /** 97 * Indicates whether a given 2-bit `uint8_t` preference value is valid. 98 * 99 * @param[in] a2BitUint The 2-bit unsigned value to convert from. Only two LSB bits are used and the reset are 100 * ignored. 101 * 102 * @retval TRUE if the first 2 bits of @p a2BitUint are `0b00`, `0b01`, or `0b11`. 103 * @retval FALSE if the first 2 bits of @p a2BitUint are `0b01`. 104 */ Is2BitUintValid(uint8_t a2BitUint)105 static bool Is2BitUintValid(uint8_t a2BitUint) { return ((a2BitUint & k2BitMask) != k2BitReserved); } 106 107 /** 108 * Converts a given preference to a human-readable string. 109 * 110 * @param[in] aPrf The preference to convert. 111 * 112 * @returns The string representation of @p aPrf. 113 */ 114 static const char *ToString(int8_t aPrf); 115 116 Preference(void) = delete; 117 118 private: 119 static constexpr uint8_t k2BitMask = 3; 120 121 static constexpr uint8_t k2BitHigh = 1; // 0b01 122 static constexpr uint8_t k2BitMedium = 0; // 0b00 123 static constexpr uint8_t k2BitLow = 3; // 0b11 124 static constexpr uint8_t k2BitReserved = 2; // 0b10 125 }; 126 127 } // namespace ot 128 129 #endif // PREFERENCE_HPP_ 130