3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
47 #include "olsr_time.h"
50 *Function that converts a double to a mantissa/exponent
51 *product as described in RFC3626:
53 * value = C*(1+a/16)*2^b [in seconds]
55 * where a is the integer represented by the four highest bits of the
56 * field and b the integer represented by the four lowest bits of the
59 *@param interval the time interval to process
61 *@return a 8-bit mantissa/exponent product
64 reltime_to_me(const olsr_reltime interval)
66 uint8_t a = 0, b = 0; /* Underflow defaults */
68 /* It is sufficent to compare the integer part since we test on >=.
69 * So we have now only a floating point division and the rest of the loop
70 * are only integer operations.
72 * const unsigned int unscaled_interval = interval / VTIME_SCALE_FACTOR;
74 * VTIME_SCALE_FACTOR = 1/16
76 * => unscaled_interval = interval(ms) / 1000 * 16
77 * = interval(ms) / 125 * 2
80 unsigned unscaled_interval = interval;
81 while (unscaled_interval >= 62) {
82 unscaled_interval >>= 1;
88 a = 15; /* Overflow defaults */
91 a = (interval >> (b + 2)) - 15;
99 * Function for converting a mantissa/exponent 8bit value back
100 * to double as described in RFC3626:
102 * value = C*(1+a/16)*2^b [in seconds]
104 * where a is the integer represented by the four highest bits of the
105 * field and b the integer represented by the four lowest bits of the
108 * me is the 8 bit mantissa/exponent value
110 * To avoid expensive floating maths, we transform the equation:
111 * value = C * (1 + a / 16) * 2^b
112 * first, we make an int addition from the floating point addition:
113 * value = C * ((16 + a) / 16) * 2^b
114 * then we get rid of a pair of parentheses
115 * value = C * (16 + a) / 16 * 2^b
116 * and now we make an int multiplication from the floating point one
117 * value = C * (16 + a) * 2^b / 16
118 * so that we can make a shift from the multiplication
119 * value = C * ((16 + a) << b) / 16
120 * and sionce C and 16 are constants
121 * value = ((16 + a) << b) * C / 16
123 * VTIME_SCALE_FACTOR = 1/16
125 * => value(ms) = ((16 + a) << b) / 256 * 1000
128 * = ((16 + a) << (b-8)) * 1000
131 * = ((16 + a) * 1000) >> (8-b)
134 me_to_reltime(const uint8_t me)
136 const uint8_t a = me >> 4;
137 const uint8_t b = me & 0x0F;
140 return ((16 + a) << (b - 8)) * 1000;
142 assert(me == reltime_to_me(((16 + a) * 1000) >> (8 - b)));
143 return ((16 + a) * 1000) >> (8 - b);
147 reltime_to_txt(struct time_txt *buffer, olsr_reltime t) {
148 sprintf(buffer->buf, "%u.%03u", t/1000, t%1000);
153 txt_to_reltime(char *txt) {
154 uint32_t t1 = 0,t2 = 0;
157 fraction = strchr(txt, '.');
158 if (fraction != NULL) {
161 if (strlen(fraction) > 3) {
165 t2 = strtoul(fraction, NULL, 10);
167 t1 = strtoul(txt, NULL, 10);
168 if (t1 > UINT32_MAX / MSEC_PER_SEC) {
169 t1 = UINT32_MAX / MSEC_PER_SEC;
171 return t1*MSEC_PER_SEC + t2;
177 * indent-tabs-mode: nil