Contiki-Inga 3.x
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
core
lib
trickle-timer.h
Go to the documentation of this file.
1
/** \addtogroup lib
2
* @{ */
3
4
/**
5
* \defgroup trickle-timer Trickle timers
6
*
7
* This library implements timers which behave in accordance with RFC 6206
8
* "The Trickle Algorithm" (http://tools.ietf.org/html/rfc6206)
9
*
10
* Protocols wishing to use trickle timers, may use this library instead of
11
* implementing the trickle algorithm internally.
12
*
13
* The protocol implementation will declare one (or more) variable(s) of type
14
* struct ::trickle_timer and will then populate its fields by calling
15
* trickle_timer_config(). trickle_timer_set() will start the timer.
16
*
17
* When the timer reaches time t within the current trickle interval, the
18
* library will call a protocol-provided callback, which will signal to the
19
* protocol that it is time to TX (see algorithm step 4 in the RFC).
20
*
21
* The proto does not need to check the suppression conditions. This is done by
22
* the library and if TX must be suppressed, the callback won't be called at
23
* all.
24
*
25
* The library also provides functions to be called when the protocol hears a
26
* 'consistent' or 'inconsistent' message and when an 'external event' occurs
27
* (in this context, those terms have the exact same meaning as in the RFC).
28
*
29
* @{
30
*/
31
32
33
/**
34
* \file
35
* Trickle timer library header file.
36
*
37
* \author
38
* George Oikonomou - <oikonomou@users.sourceforge.net>
39
*/
40
41
/*
42
* Copyright (c) 2012, George Oikonomou - <oikonomou@users.sourceforge.net>
43
* All rights reserved.
44
*
45
* Redistribution and use in source and binary forms, with or without
46
* modification, are permitted provided that the following conditions
47
* are met:
48
*
49
* 1. Redistributions of source code must retain the above copyright
50
* notice, this list of conditions and the following disclaimer.
51
* 2. Redistributions in binary form must reproduce the above copyright
52
* notice, this list of conditions and the following disclaimer in the
53
* documentation and/or other materials provided with the distribution.
54
* 3. Neither the name of the copyright holder nor the names of its
55
* contributors may be used to endorse or promote products derived
56
* from this software without specific prior written permission.
57
*
58
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
59
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
60
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
61
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
62
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
63
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
65
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
67
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
68
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
69
* OF THE POSSIBILITY OF SUCH DAMAGE.
70
*/
71
#ifndef TRICKLE_TIMER_H_
72
#define TRICKLE_TIMER_H_
73
74
#include "contiki-conf.h"
75
#include "
sys/ctimer.h
"
76
/*---------------------------------------------------------------------------*/
77
/* Trickle Timer Library Constants */
78
/*---------------------------------------------------------------------------*/
79
/**
80
* \name Trickle Timer Library: Constants
81
* @{
82
*/
83
/*---------------------------------------------------------------------------*/
84
/**
85
* \brief Set as value of k to disable suppression
86
*/
87
#define TRICKLE_TIMER_INFINITE_REDUNDANCY 0x00
88
89
#define TRICKLE_TIMER_ERROR 0
90
#define TRICKLE_TIMER_SUCCESS 1
91
92
/**
93
* \brief Use as the value of TRICKLE_TIMER_MAX_IMAX_WIDTH to enable the
94
* generic 'Find max Imax' routine
95
*/
96
#define TRICKLE_TIMER_MAX_IMAX_GENERIC 0
97
/**
98
* \brief Use as the value of TRICKLE_TIMER_MAX_IMAX_WIDTH to enable the 16-bit
99
* 'Find max Imax' routine
100
*/
101
#define TRICKLE_TIMER_MAX_IMAX_16_BIT 1
102
/**
103
* \brief Use as the value of TRICKLE_TIMER_MAX_IMAX_WIDTH to enable the 32-bit
104
* 'Find max Imax' routine
105
*/
106
#define TRICKLE_TIMER_MAX_IMAX_32_BIT 2
107
108
/**
109
* \brief Constants used as values for the \e suppress param of
110
* trickle_timer_cb_t
111
*/
112
#define TRICKLE_TIMER_TX_SUPPRESS 0
113
#define TRICKLE_TIMER_TX_OK 1
114
115
/**
116
* \brief A trickle timer is considered 'stopped' when
117
* i_cur == TRICKLE_TIMER_IS_STOPPED.
118
*
119
* trickle_timer_stop() must be used to correctly disable a trickle timer.
120
* Do NOT set the value of i_cur to 0 directly, as this will fail to stop the
121
* timer.
122
*/
123
#define TRICKLE_TIMER_IS_STOPPED 0
124
/** @} */
125
/*---------------------------------------------------------------------------*/
126
/**
127
* \brief Controls whether the library will try to compensate for time drifts
128
* caused by getting called later than scheduled.
129
*
130
* 1: Enabled (default). 0: Disabled
131
*
132
* To override the default, define TRICKLE_TIMER_CONF_COMPENSATE_DRIFT in
133
* contiki-conf.h
134
*
135
* Bear in mind that this controls the behaviour of the entire library (i.e.
136
* all trickle timers) and not of an individual timer
137
*/
138
#ifdef TRICKLE_TIMER_CONF_COMPENSATE_DRIFT
139
#define TRICKLE_TIMER_COMPENSATE_DRIFT TRICKLE_TIMER_CONF_COMPENSATE_DRIFT
140
#else
141
#define TRICKLE_TIMER_COMPENSATE_DRIFT 1
142
#endif
143
/*---------------------------------------------------------------------------*/
144
/**
145
* \brief Turns on support for 4-byte wide, unsigned random numbers
146
*
147
* We need this for platforms which have a 4-byte wide clock_time_t. For those
148
* platforms and if Imin << Imax is GT 0xFFFF, random_rand alone is not always
149
* enough to generate a correct t in [I/2, I). Specifically, we need wide
150
* randoms when I > 0x1FFFF.
151
*
152
* For platforms with a 2-byte wide clock_time_t, this can be defined as 0
153
* to reduce code footprint and increase speed.
154
*/
155
#ifdef TRICKLE_TIMER_CONF_WIDE_RAND
156
#define TRICKLE_TIMER_WIDE_RAND TRICKLE_TIMER_CONF_WIDE_RAND
157
#else
158
#define TRICKLE_TIMER_WIDE_RAND 1
159
#endif
160
/*---------------------------------------------------------------------------*/
161
/**
162
* \brief Selects a flavor for the 'Find maximum Imax' (max_imax) function.
163
*
164
* When configuring a new trickle timer, the library verifies that the (Imin ,
165
* Imax) pair will fit in the platform's clock_time_t boundaries. If this is
166
* not the case, Imax will be adjusted down. In order to achieve this, we use
167
* an internal function which is a slight variant of a standard 'Count Leading
168
* Zeros'.
169
*
170
* This functionality is disabled when ::TRICKLE_TIMER_ERROR_CHECKING is 0
171
*
172
* This define helps us generate, at the pre-processing stage, the desired
173
* version of this function. We start with a generic version by default. The
174
* platform's contiki-conf.h can change this to use the 16- or 32-bit specific
175
* flavor by defining TRICKLE_TIMER_CONF_MAX_IMAX_WIDTH.
176
*
177
* Depending on the toolchain, the generic variant may actually result in a
178
* smaller code size. Do your own experiments.
179
*
180
* TRICKLE_TIMER_MAX_IMAX_GENERIC (0): Generic function which will work
181
* regardless whether the platform uses a 16 or 32 bit wide clock type
182
*
183
* TRICKLE_TIMER_MAX_IMAX_16_BIT (1): You can select this in your
184
* contiki-conf.h if your platform's clock_time_t is 16 bits wide
185
*
186
* TRICKLE_TIMER_MAX_IMAX_32_BIT (2): You can select this in your
187
* contiki-conf.h if your platform's clock_time_t is 32 bits wide
188
*/
189
#ifdef TRICKLE_TIMER_CONF_MAX_IMAX_WIDTH
190
#define TRICKLE_TIMER_MAX_IMAX_WIDTH TRICKLE_TIMER_CONF_MAX_IMAX_WIDTH
191
#else
192
#define TRICKLE_TIMER_MAX_IMAX_WIDTH TRICKLE_TIMER_MAX_IMAX_GENERIC
193
#endif
194
195
/**
196
* \brief Enables/Disables error checking
197
*
198
* 1: Enabled (default). The library checks the validity of Imin and Imax
199
* 0: Disabled. All error checking is turned off. This reduces code size.
200
*/
201
#ifdef TRICKLE_TIMER_CONF_ERROR_CHECKING
202
#define TRICKLE_TIMER_ERROR_CHECKING TRICKLE_TIMER_CONF_ERROR_CHECKING
203
#else
204
#define TRICKLE_TIMER_ERROR_CHECKING 1
205
#endif
206
/*---------------------------------------------------------------------------*/
207
/* Trickle Timer Library Macros */
208
/*---------------------------------------------------------------------------*/
209
/**
210
* \name Trickle Timer Library: Macros
211
* @{
212
*/
213
/**
214
* \brief cross-platform method to get the maximum clock_time_t value
215
*/
216
#define TRICKLE_TIMER_CLOCK_MAX ((clock_time_t)~0)
217
218
219
/**
220
* \brief Checks if the trickle timer's suppression feature is enabled
221
*
222
* \param tt A pointer to a ::trickle_timer structure
223
*
224
* \retval non-zero Suppression is enabled
225
* \retval 0 Suppression is disabled
226
*/
227
#define TRICKLE_TIMER_SUPPRESSION_ENABLED(tt) \
228
((tt)->k != TRICKLE_TIMER_INFINITE_REDUNDANCY)
229
230
/**
231
* \brief Checks if the trickle timer's suppression feature is disabled
232
*
233
* \param tt A pointer to a ::trickle_timer structure
234
*
235
* \retval non-zero Suppression is disabled
236
* \retval 0 Suppression is enabled
237
*/
238
#define TRICKLE_TIMER_SUPPRESSION_DISABLED(tt) \
239
((tt)->k == TRICKLE_TIMER_INFINITE_REDUNDANCY)
240
241
/**
242
* \brief Determines whether the protocol must go ahead with a transmission
243
*
244
* \param tt A pointer to a ::trickle_timer structure
245
*
246
* \retval non-zero Go ahead with TX
247
* \retval 0 Suppress
248
*/
249
#define TRICKLE_TIMER_PROTO_TX_ALLOW(tt) \
250
(TRICKLE_TIMER_SUPPRESSION_DISABLED(tt) || ((tt)->c < (tt)->k))
251
252
/**
253
* \brief Determines whether the protocol must suppress a transmission
254
*
255
* \param tt A pointer to a ::trickle_timer structure
256
*
257
* \retval non-zero Suppress
258
* \retval 0 Go ahead with TX
259
*/
260
#define TRICKLE_TIMER_PROTO_TX_SUPPRESS(tt) \
261
(TRICKLE_TIMER_SUPPRESSION_ENABLED(tt) && ((tt)->c >= (tt)->k))
262
263
/**
264
* \brief Returns a timer's maximum interval size (Imin << Imax) as a number of
265
* clock ticks
266
*
267
* \param tt A pointer to a ::trickle_timer structure
268
*
269
* \return Maximum trickle interval length in clock ticks
270
*/
271
#define TRICKLE_TIMER_INTERVAL_MAX(tt) ((tt)->i_max_abs)
272
273
/**
274
* \brief Returns the current trickle interval's end (absolute time in ticks)
275
*
276
* \param tt A pointer to a ::trickle_timer structure
277
*
278
* \return The absolute number of clock ticks when the current trickle interval
279
* will expire
280
*/
281
#define TRICKLE_TIMER_INTERVAL_END(tt) ((tt)->i_start + (tt)->i_cur)
282
283
/**
284
* \brief Checks whether an Imin value is suitable considering the various
285
* restrictions imposed by our platform's clock as well as by the library itself
286
*
287
* \param imin An Imin value in clock ticks
288
*
289
* \retval 1 The Imin value is valid
290
* \retval 0 The Imin value is invalid
291
*/
292
#define TRICKLE_TIMER_IMIN_IS_OK(imin) \
293
((imin > 1) && (i_min <= (TRICKLE_TIMER_CLOCK_MAX >> 1)))
294
295
/**
296
* \brief Checks whether an Imin value is invalid considering the various
297
* restrictions imposed by our platform's clock as well as by the library itself
298
*
299
* \param imin An Imin value in clock ticks
300
*
301
* \retval 1 The Imin value is invalid
302
* \retval 0 The Imin value is valid
303
*/
304
#define TRICKLE_TIMER_IMIN_IS_BAD(imin) \
305
((imin < 2) || (i_min > (TRICKLE_TIMER_CLOCK_MAX >> 1)))
306
307
/**
308
* \brief Checks whether Imin << Imax is unsuitable considering the boundaries
309
* of our platform's clock_time_t
310
*
311
* \param i_min Imin value
312
* \param i_max Maximum number of doublings
313
*
314
* \retval non-zero The pair would exceed clock boundaries
315
* \retval 0 The pair is suitable for the platform
316
*
317
* Timers scheduled far in the future can be perceived as being scheduled in
318
* the past.
319
* Thus, we limit Imin << Imax to be LEQ(TRICKLE_TIMER_CLOCK_MAX >> 1) + 1
320
*/
321
#define TRICKLE_TIMER_IPAIR_IS_BAD(i_min, i_max) \
322
((TRICKLE_TIMER_CLOCK_MAX >> (i_max + 1)) < i_min - 1)
323
/** @} */
324
/*---------------------------------------------------------------------------*/
325
/* Trickle Timer Library Data Representation */
326
/*---------------------------------------------------------------------------*/
327
/**
328
* \name Trickle Timer Library: Data Representation
329
* @{
330
*/
331
332
/**
333
* \brief typedef for a callback function to be defined in the protocol's
334
* implementation.
335
*
336
* Those callbaks are stored as a function pointer inside a ::trickle_timer
337
* structure and are called by the library at time t within the current trickle
338
* interval.
339
*
340
* Some protocols may rely on multiple trickle timers. For this reason, this
341
* function's argument will be an opaque pointer, aiming to help the protocol
342
* determine which timer triggered the call.
343
*
344
* The \e suppress argument is used so that the library can signal the protocol
345
* whether it should TX or suppress
346
*/
347
typedef
void (*
trickle_timer_cb_t
)(
void
*ptr, uint8_t suppress);
348
349
/**
350
* \struct trickle_timer
351
*
352
* A trickle timer.
353
*
354
* This structure is used for declaring a trickle timer. In order for the timer
355
* to start running, the protocol must first populate the structure's fields
356
* by calling trickle_timer_set(). Protocol implementations must NOT modify the
357
* contents of this structure directly.
358
*
359
* Protocol developers must also be careful to specify the values of Imin and
360
* Imax in such a way that the maximum interval size does not exceed the
361
* boundaries of clock_time_t
362
*/
363
struct
trickle_timer
{
364
clock_time_t
i_min
;
/**< Imin: Clock ticks */
365
clock_time_t
i_cur
;
/**< I: Current interval in clock_ticks */
366
clock_time_t
i_start
;
/**< Start of this interval (absolute clock_time) */
367
clock_time_t
i_max_abs
;
/**< Maximum interval size in clock ticks (and not in
368
number of doublings). This is a cached value of
369
Imin << Imax used internally, so that we can
370
have direct access to the maximum interval size
371
without having to calculate it all the time */
372
struct
ctimer
ct
;
/**< A \ref ctimer used internally */
373
trickle_timer_cb_t
cb
;
/**< Protocol's own callback, invoked at time t
374
within the current interval */
375
void
*
cb_arg
;
/**< Opaque pointer to be used as the argument of the
376
protocol's callback */
377
uint8_t
i_max
;
/**< Imax: Max number of doublings */
378
uint8_t
k
;
/**< k: Redundancy Constant */
379
uint8_t
c
;
/**< c: Consistency Counter */
380
};
381
/** @} */
382
/*---------------------------------------------------------------------------*/
383
/* Trickle Timer Library Functions */
384
/*---------------------------------------------------------------------------*/
385
/**
386
* \name Trickle Timer Library: Functions called by protocol implementations
387
* @{
388
*/
389
390
/**
391
* \brief Configure a trickle timer
392
* \param tt A pointer to a ::trickle_timer structure
393
* \param i_min The timer's Imin configuration parameter, in units of
394
* clock_time_t
395
* \param i_max The timer's Imax configuration parameter (maximum number of
396
* doublings), specified as number of doublings
397
* \param k The timer's K (redundancy constant). If the value of K
398
* equals #TRICKLE_TIMER_INFINITE_REDUNDANCY, message
399
* suppression will be disabled
400
* \retval 0 Error (Bad argument)
401
* \retval non-zero Success.
402
*
403
* This function is used to set the initial configuration for a trickle timer.
404
* A trickle timer MUST be configured before the protocol calls
405
* trickle_timer_set().
406
*
407
* If Imin<<Imax would exceed the platform's clock_time_t boundaries, this
408
* function adjusts Imax to the maximum permitted value for the provided Imin.
409
* This means that in a network with heterogenous hardware, 'we' are likely to
410
* have a different Imax than 'some of them'. See RFC 6206, sec 6.3 for the
411
* consequences of this situation
412
*/
413
uint8_t
trickle_timer_config
(
struct
trickle_timer
*tt, clock_time_t i_min,
414
uint8_t i_max, uint8_t k);
415
416
/**
417
* \brief Start a previously configured trickle timer
418
* \param tt A pointer to a ::trickle_timer structure
419
* \param proto_cb A pointer to a callback function, which will be invoked at
420
* at time t within the current trickle interval
421
* \param ptr An opaque pointer which will be passed as the argument to
422
* proto_cb when the timer fires.
423
* \retval 0 Error (tt was null or the timer was not configured properly)
424
* \retval non-zero Success.
425
*
426
* This function is used to set a trickle timer. The protocol implementation
427
* must use this function ONLY to initialise a new trickle timer and NOT to
428
* reset it as a result of external events or inconsistencies.
429
*
430
* The protocol implementation must configure the trickle timer by calling
431
* trickle_timer_config() before calling this function.
432
*/
433
uint8_t
trickle_timer_set
(
struct
trickle_timer
*tt,
434
trickle_timer_cb_t
proto_cb,
void
*ptr);
435
436
/**
437
* \brief Stop a running trickle timer.
438
* \param tt A pointer to a ::trickle_timer structure
439
*
440
* This function stops a running trickle timer that was previously started with
441
* trickle_timer_start(). After this function has been called, the trickle
442
* timer will no longer call the protocol's callback and its interval will not
443
* double any more. In order to resume the trickle timer, the user application
444
* must call trickle_timer_set().
445
*
446
* The protocol implementation must NOT use trickle_timer_stop(), _set() cycles
447
* to reset a timer manually. Instead, in response to events or inconsistencies,
448
* the corresponding functions must be used
449
*/
450
#define trickle_timer_stop(tt) do { \
451
ctimer_stop(&((tt)->ct)); \
452
(tt)->i_cur = TRICKLE_TIMER_IS_STOPPED; \
453
} while(0)
454
455
/**
456
* \brief To be called by the protocol when it hears a consistent
457
* transmission
458
* \param tt A pointer to a ::trickle_timer structure
459
*
460
* When the trickle-based protocol hears a consistent transmission it must call
461
* this function to increment trickle's consistency counter, which is later
462
* used to determine whether the protocol must suppress or go ahead with its
463
* own transmissions.
464
*
465
* As the trickle timer library implementation may change in the future to
466
* perform further tasks upon reception of a consistent transmission, the
467
* protocol's implementation MUST use this call to increment the consistency
468
* counter instead of directly writing to the structure's field.
469
*/
470
void
trickle_timer_consistency
(
struct
trickle_timer
*tt);
471
472
/**
473
* \brief To be called by the protocol when it hears an inconsistent
474
* transmission
475
* \param tt A pointer to a ::trickle_timer structure
476
*
477
* When the protocol hears an inconsistent transmission, it must call this
478
* function to notify the library that the timer must be reset.
479
*
480
* Before resetting the timer, the library will perform a set of checks.
481
* Therefore, it is important that the protocol calls this function instead of
482
* trying to reset the timer by itself.
483
*/
484
void
trickle_timer_inconsistency
(
struct
trickle_timer
*tt);
485
486
/**
487
* \brief To be called by the protocol when an external event occurs that
488
* should trigger a timer reset
489
* \param tt A pointer to a ::trickle_timer structure
490
*
491
* When an external event occurs that should result in a timer reset, the
492
* protocol implementation must call this function to notify the library.
493
*
494
* Before resetting the timer, the library will perform a set of checks.
495
* Therefore, it is important that the protocol calls this function instead of
496
* trying to reset the timer by itself.
497
*/
498
#define trickle_timer_reset_event(tt) trickle_timer_inconsistency(tt)
499
500
/**
501
* \brief To be called in order to determine whether a trickle timer is
502
* running
503
* \param tt A pointer to a ::trickle_timer structure
504
* \retval 0 The timer is stopped
505
* \retval non-zero The timer is running
506
*
507
*/
508
#define trickle_timer_is_running(tt) ((tt)->i_cur != TRICKLE_TIMER_IS_STOPPED)
509
510
/** @} */
511
512
#endif
/* TRICKLE_TIMER_H_ */
513
/** @} */
514
/** @} */
Generated on Thu Apr 24 2014 16:26:11 for Contiki-Inga 3.x by
1.8.3.1