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 using ot::Encoding::BigEndian::HostSwap16; 53 using ot::Encoding::BigEndian::HostSwap32; 54 55 /** 56 * This class implements Timestamp generation and parsing. 57 * 58 */ 59 OT_TOOL_PACKED_BEGIN 60 class Timestamp : public Clearable<Timestamp> 61 { 62 public: 63 /** 64 * This method converts the timestamp to `otTimestamp`. 65 * 66 */ 67 void ConvertTo(otTimestamp &aTimestamp) const; 68 69 /** 70 * This method sets the timestamp from `otTimestamp`. 71 * 72 */ 73 void SetFromTimestamp(const otTimestamp &aTimestamp); 74 75 /** 76 * This method returns the Seconds value. 77 * 78 * @returns The Seconds value. 79 * 80 */ GetSeconds(void) const81 uint64_t GetSeconds(void) const 82 { 83 return (static_cast<uint64_t>(HostSwap16(mSeconds16)) << 32) + HostSwap32(mSeconds32); 84 } 85 86 /** 87 * This method sets the Seconds value. 88 * 89 * @param[in] aSeconds The Seconds value. 90 * 91 */ SetSeconds(uint64_t aSeconds)92 void SetSeconds(uint64_t aSeconds) 93 { 94 mSeconds16 = HostSwap16(static_cast<uint16_t>(aSeconds >> 32)); 95 mSeconds32 = HostSwap32(static_cast<uint32_t>(aSeconds & 0xffffffff)); 96 } 97 98 /** 99 * This method returns the Ticks value. 100 * 101 * @returns The Ticks value. 102 * 103 */ GetTicks(void) const104 uint16_t GetTicks(void) const { return HostSwap16(mTicks) >> kTicksOffset; } 105 106 /** 107 * This method sets the Ticks value. 108 * 109 * @param[in] aTicks The Ticks value. 110 * 111 */ SetTicks(uint16_t aTicks)112 void SetTicks(uint16_t aTicks) 113 { 114 mTicks = HostSwap16((HostSwap16(mTicks) & ~kTicksMask) | ((aTicks << kTicksOffset) & kTicksMask)); 115 } 116 117 /** 118 * This method returns the Authoritative value. 119 * 120 * @returns The Authoritative value. 121 * 122 */ GetAuthoritative(void) const123 bool GetAuthoritative(void) const { return (HostSwap16(mTicks) & kAuthoritativeMask) != 0; } 124 125 /** 126 * This method sets the Authoritative value. 127 * 128 * @param[in] aAuthoritative The Authoritative value. 129 * 130 */ SetAuthoritative(bool aAuthoritative)131 void SetAuthoritative(bool aAuthoritative) 132 { 133 mTicks = HostSwap16((HostSwap16(mTicks) & kTicksMask) | 134 ((aAuthoritative << kAuthoritativeOffset) & kAuthoritativeMask)); 135 } 136 137 /** 138 * This method increments the timestamp by a random number of ticks [0, 32767]. 139 * 140 */ 141 void AdvanceRandomTicks(void); 142 143 /** 144 * This method indicates whether the timestamp indicates an MLE Orphan Announce message. 145 * 146 * @retval TRUE The timestamp indicates an Orphan Announce message. 147 * @retval FALSE If the timestamp does not indicate an Orphan Announce message. 148 * 149 */ IsOrphanTimestamp(void) const150 bool IsOrphanTimestamp(void) const { return GetSeconds() == 0 && GetTicks() == 0 && GetAuthoritative(); } 151 152 /** 153 * This static method compares two timestamps. 154 * 155 * Either one or both @p aFirst or @p aSecond can be `nullptr`. A non-null timestamp is considered greater than 156 * a null one. If both are null, they are considered as equal. 157 * 158 * @param[in] aFirst A pointer to the first timestamp to compare (can be nullptr). 159 * @param[in] aSecond A pointer to the second timestamp to compare (can be nullptr). 160 * 161 * @retval -1 if @p aFirst is less than @p aSecond (`aFirst < aSecond`). 162 * @retval 0 if @p aFirst is equal to @p aSecond (`aFirst == aSecond`). 163 * @retval 1 if @p aFirst is greater than @p aSecond (`aFirst > aSecond`). 164 * 165 */ 166 static int Compare(const Timestamp *aFirst, const Timestamp *aSecond); 167 168 /** 169 * This static method compares two timestamps. 170 * 171 * @param[in] aFirst A reference to the first timestamp to compare. 172 * @param[in] aSecond A reference to the second timestamp to compare. 173 * 174 * @retval -1 if @p aFirst is less than @p aSecond (`aFirst < aSecond`). 175 * @retval 0 if @p aFirst is equal to @p aSecond (`aFirst == aSecond`). 176 * @retval 1 if @p aFirst is greater than @p aSecond (`aFirst > aSecond`). 177 * 178 */ 179 static int Compare(const Timestamp &aFirst, const Timestamp &aSecond); 180 181 private: 182 static constexpr uint8_t kTicksOffset = 1; 183 static constexpr uint16_t kTicksMask = 0x7fff << kTicksOffset; 184 static constexpr uint16_t kMaxRandomTicks = 0x7fff; 185 static constexpr uint8_t kAuthoritativeOffset = 0; 186 static constexpr uint16_t kAuthoritativeMask = 1 << kAuthoritativeOffset; 187 188 uint16_t mSeconds16; // bits 32-47 189 uint32_t mSeconds32; // bits 0-31 190 uint16_t mTicks; 191 } OT_TOOL_PACKED_END; 192 193 } // namespace MeshCoP 194 } // namespace ot 195 196 #endif // MESHCOP_TIMESTAMP_HPP_ 197