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/platform/toolchain.h>
43 
44 #include "common/encoding.hpp"
45 #include "common/random.hpp"
46 
47 namespace ot {
48 namespace MeshCoP {
49 
50 using ot::Encoding::BigEndian::HostSwap16;
51 using ot::Encoding::BigEndian::HostSwap32;
52 
53 /**
54  * This class implements Timestamp generation and parsing.
55  *
56  */
57 OT_TOOL_PACKED_BEGIN
58 class Timestamp
59 {
60 public:
61     /**
62      * This method initializes the Timestamp
63      *
64      */
Init(void)65     void Init(void) { memset(this, 0, sizeof(*this)); }
66 
67     /**
68      * This method compares this timestamp to another.
69      *
70      * @param[in]  aCompare  A reference to the timestamp to compare.
71      *
72      * @retval -1  if @p aCompare is less than this timestamp.
73      * @retval  0  if @p aCompare is equal to this timestamp.
74      * @retval  1  if @p aCompare is greater than this timestamp.
75      *
76      */
77     int Compare(const Timestamp &aCompare) const;
78 
79     /**
80      * This method returns the Seconds value.
81      *
82      * @returns The Seconds value.
83      *
84      */
GetSeconds(void) const85     uint64_t GetSeconds(void) const
86     {
87         return (static_cast<uint64_t>(HostSwap16(mSeconds16)) << 32) + HostSwap32(mSeconds32);
88     }
89 
90     /**
91      * This method sets the Seconds value.
92      *
93      * @param[in]  aSeconds  The Seconds value.
94      *
95      */
SetSeconds(uint64_t aSeconds)96     void SetSeconds(uint64_t aSeconds)
97     {
98         mSeconds16 = HostSwap16(static_cast<uint16_t>(aSeconds >> 32));
99         mSeconds32 = HostSwap32(static_cast<uint32_t>(aSeconds & 0xffffffff));
100     }
101 
102     /**
103      * This method returns the Ticks value.
104      *
105      * @returns The Ticks value.
106      *
107      */
GetTicks(void) const108     uint16_t GetTicks(void) const { return HostSwap16(mTicks) >> kTicksOffset; }
109 
110     /**
111      * This method sets the Ticks value.
112      *
113      * @param[in]  aTicks  The Ticks value.
114      *
115      */
SetTicks(uint16_t aTicks)116     void SetTicks(uint16_t aTicks)
117     {
118         mTicks = HostSwap16((HostSwap16(mTicks) & ~kTicksMask) | ((aTicks << kTicksOffset) & kTicksMask));
119     }
120 
121     /**
122      * This method returns the Authoritative value.
123      *
124      * @returns The Authoritative value.
125      *
126      */
GetAuthoritative(void) const127     bool GetAuthoritative(void) const { return (HostSwap16(mTicks) & kAuthoritativeMask) != 0; }
128 
129     /**
130      * This method sets the Authoritative value.
131      *
132      * @param[in]  aAuthoritative  The Authoritative value.
133      *
134      */
SetAuthoritative(bool aAuthoritative)135     void SetAuthoritative(bool aAuthoritative)
136     {
137         mTicks = HostSwap16((HostSwap16(mTicks) & kTicksMask) |
138                             ((aAuthoritative << kAuthoritativeOffset) & kAuthoritativeMask));
139     }
140 
141     /**
142      * This method increments the timestamp by a random number of ticks [0, 32767].
143      *
144      */
145     void AdvanceRandomTicks(void);
146 
147 private:
148     static constexpr uint8_t  kTicksOffset         = 1;
149     static constexpr uint16_t kTicksMask           = 0x7fff << kTicksOffset;
150     static constexpr uint16_t kMaxRandomTicks      = 0x7fff;
151     static constexpr uint8_t  kAuthoritativeOffset = 0;
152     static constexpr uint16_t kAuthoritativeMask   = 1 << kAuthoritativeOffset;
153 
154     uint16_t mSeconds16; // bits 32-47
155     uint32_t mSeconds32; // bits 0-31
156     uint16_t mTicks;
157 } OT_TOOL_PACKED_END;
158 
159 } // namespace MeshCoP
160 } // namespace ot
161 
162 #endif // MESHCOP_TIMESTAMP_HPP_
163