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