1 /* 2 * Copyright (c) 2016, 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 manipulating MeshCoP timestamps. 32 * 33 */ 34 35 #ifndef MESHCOP_TIMESTAMP_HPP_ 36 #define MESHCOP_TIMESTAMP_HPP_ 37 38 #include "openthread-core-config.h" 39 40 #include <string.h> 41 42 #include <openthread/dataset.h> 43 #include <openthread/platform/toolchain.h> 44 45 #include "common/clearable.hpp" 46 #include "common/encoding.hpp" 47 #include "common/random.hpp" 48 49 namespace ot { 50 namespace MeshCoP { 51 52 /** 53 * Implements Timestamp generation and parsing. 54 * 55 */ 56 OT_TOOL_PACKED_BEGIN 57 class Timestamp : public Clearable<Timestamp> 58 { 59 public: 60 /** 61 * Converts the timestamp to `otTimestamp`. 62 * 63 */ 64 void ConvertTo(otTimestamp &aTimestamp) const; 65 66 /** 67 * Sets the timestamp from `otTimestamp`. 68 * 69 */ 70 void SetFromTimestamp(const otTimestamp &aTimestamp); 71 72 /** 73 * Returns the Seconds value. 74 * 75 * @returns The Seconds value. 76 * 77 */ GetSeconds(void) const78 uint64_t GetSeconds(void) const 79 { 80 return (static_cast<uint64_t>(BigEndian::HostSwap16(mSeconds16)) << 32) + BigEndian::HostSwap32(mSeconds32); 81 } 82 83 /** 84 * Sets the Seconds value. 85 * 86 * @param[in] aSeconds The Seconds value. 87 * 88 */ SetSeconds(uint64_t aSeconds)89 void SetSeconds(uint64_t aSeconds) 90 { 91 mSeconds16 = BigEndian::HostSwap16(static_cast<uint16_t>(aSeconds >> 32)); 92 mSeconds32 = BigEndian::HostSwap32(static_cast<uint32_t>(aSeconds & 0xffffffff)); 93 } 94 95 /** 96 * Returns the Ticks value. 97 * 98 * @returns The Ticks value. 99 * 100 */ GetTicks(void) const101 uint16_t GetTicks(void) const { return BigEndian::HostSwap16(mTicks) >> kTicksOffset; } 102 103 /** 104 * Sets the Ticks value. 105 * 106 * @param[in] aTicks The Ticks value. 107 * 108 */ SetTicks(uint16_t aTicks)109 void SetTicks(uint16_t aTicks) 110 { 111 mTicks = BigEndian::HostSwap16((BigEndian::HostSwap16(mTicks) & ~kTicksMask) | 112 ((aTicks << kTicksOffset) & kTicksMask)); 113 } 114 115 /** 116 * Returns the Authoritative value. 117 * 118 * @returns The Authoritative value. 119 * 120 */ GetAuthoritative(void) const121 bool GetAuthoritative(void) const { return (BigEndian::HostSwap16(mTicks) & kAuthoritativeMask) != 0; } 122 123 /** 124 * Sets the Authoritative value. 125 * 126 * @param[in] aAuthoritative The Authoritative value. 127 * 128 */ SetAuthoritative(bool aAuthoritative)129 void SetAuthoritative(bool aAuthoritative) 130 { 131 mTicks = BigEndian::HostSwap16((BigEndian::HostSwap16(mTicks) & kTicksMask) | 132 ((aAuthoritative << kAuthoritativeOffset) & kAuthoritativeMask)); 133 } 134 135 /** 136 * Increments the timestamp by a random number of ticks [0, 32767]. 137 * 138 */ 139 void AdvanceRandomTicks(void); 140 141 /** 142 * Indicates whether the timestamp indicates an MLE Orphan Announce message. 143 * 144 * @retval TRUE The timestamp indicates an Orphan Announce message. 145 * @retval FALSE If the timestamp does not indicate an Orphan Announce message. 146 * 147 */ IsOrphanTimestamp(void) const148 bool IsOrphanTimestamp(void) const { return GetSeconds() == 0 && GetTicks() == 0 && GetAuthoritative(); } 149 150 /** 151 * Compares two timestamps. 152 * 153 * Either one or both @p aFirst or @p aSecond can be `nullptr`. A non-null timestamp is considered greater than 154 * a null one. If both are null, they are considered as equal. 155 * 156 * @param[in] aFirst A pointer to the first timestamp to compare (can be nullptr). 157 * @param[in] aSecond A pointer to the second timestamp to compare (can be nullptr). 158 * 159 * @retval -1 if @p aFirst is less than @p aSecond (`aFirst < aSecond`). 160 * @retval 0 if @p aFirst is equal to @p aSecond (`aFirst == aSecond`). 161 * @retval 1 if @p aFirst is greater than @p aSecond (`aFirst > aSecond`). 162 * 163 */ 164 static int Compare(const Timestamp *aFirst, const Timestamp *aSecond); 165 166 /** 167 * Compares two timestamps. 168 * 169 * @param[in] aFirst A reference to the first timestamp to compare. 170 * @param[in] aSecond A reference to the second timestamp to compare. 171 * 172 * @retval -1 if @p aFirst is less than @p aSecond (`aFirst < aSecond`). 173 * @retval 0 if @p aFirst is equal to @p aSecond (`aFirst == aSecond`). 174 * @retval 1 if @p aFirst is greater than @p aSecond (`aFirst > aSecond`). 175 * 176 */ 177 static int Compare(const Timestamp &aFirst, const Timestamp &aSecond); 178 179 private: 180 static constexpr uint8_t kTicksOffset = 1; 181 static constexpr uint16_t kTicksMask = 0x7fff << kTicksOffset; 182 static constexpr uint16_t kMaxRandomTicks = 0x7fff; 183 static constexpr uint8_t kAuthoritativeOffset = 0; 184 static constexpr uint16_t kAuthoritativeMask = 1 << kAuthoritativeOffset; 185 186 uint16_t mSeconds16; // bits 32-47 187 uint32_t mSeconds32; // bits 0-31 188 uint16_t mTicks; 189 } OT_TOOL_PACKED_END; 190 191 } // namespace MeshCoP 192 } // namespace ot 193 194 #endif // MESHCOP_TIMESTAMP_HPP_ 195