1 /** @file
2  * @brief Trickle timer library
3  *
4  * This implements Trickle timer as specified in RFC 6206
5  */
6 
7 /*
8  * Copyright (c) 2016 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_NET_TRICKLE_H_
14 #define ZEPHYR_INCLUDE_NET_TRICKLE_H_
15 
16 #include <stdbool.h>
17 #include <zephyr/types.h>
18 
19 #include <zephyr/kernel.h>
20 #include <zephyr/net/net_core.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /**
27  * @brief Trickle algorithm library
28  * @defgroup trickle Trickle Algorithm Library
29  * @since 1.7
30  * @version 0.8.0
31  * @ingroup networking
32  * @{
33  */
34 
35 struct net_trickle;
36 
37 /**
38  * @typedef net_trickle_cb_t
39  * @brief Trickle timer callback.
40  *
41  * @details The callback is called after Trickle timeout expires.
42  *
43  * @param trickle The trickle context to use.
44  * @param do_suppress Is TX allowed (true) or not (false).
45  * @param user_data The user data given in net_trickle_start() call.
46  */
47 typedef void (*net_trickle_cb_t)(struct net_trickle *trickle,
48 				 bool do_suppress, void *user_data);
49 
50 /**
51  * The variable names are taken directly from RFC 6206 when applicable.
52  * Note that the struct members should not be accessed directly but
53  * only via the Trickle API.
54  */
55 struct net_trickle {
56 	uint32_t I;		/**< Current interval size */
57 	uint32_t Imin;		/**< Min interval size in ms */
58 	uint32_t Istart;	/**< Start of the interval in ms */
59 	uint32_t Imax_abs;	/**< Max interval size in ms (not doublings) */
60 	uint8_t Imax;		/**< Max number of doublings */
61 
62 	uint8_t k;		/**< Redundancy constant */
63 	uint8_t c;		/**< Consistency counter */
64 
65 	bool double_to;         /**< Flag telling if the internval is doubled */
66 
67 	struct k_work_delayable timer; /**< Internal timer struct */
68 	net_trickle_cb_t cb;	/**< Callback to be called when timer expires */
69 	void *user_data;        /**< User specific opaque data */
70 };
71 
72 /** @cond INTERNAL_HIDDEN */
73 #define NET_TRICKLE_INFINITE_REDUNDANCY 0
74 /** @endcond */
75 
76 /**
77  * @brief Create a Trickle timer.
78  *
79  * @param trickle Pointer to Trickle struct.
80  * @param Imin Imin configuration parameter in ms.
81  * @param Imax Max number of doublings.
82  * @param k Redundancy constant parameter. See RFC 6206 for details.
83  *
84  * @return Return 0 if ok and <0 if error.
85  */
86 int net_trickle_create(struct net_trickle *trickle,
87 		       uint32_t Imin,
88 		       uint8_t Imax,
89 		       uint8_t k);
90 
91 /**
92  * @brief Start a Trickle timer.
93  *
94  * @param trickle Pointer to Trickle struct.
95  * @param cb User callback to call at time T within the current trickle
96  * interval
97  * @param user_data User pointer that is passed to callback.
98  *
99  * @return Return 0 if ok and <0 if error.
100  */
101 int net_trickle_start(struct net_trickle *trickle,
102 		      net_trickle_cb_t cb,
103 		      void *user_data);
104 
105 /**
106  * @brief Stop a Trickle timer.
107  *
108  * @param trickle Pointer to Trickle struct.
109  *
110  * @return Return 0 if ok and <0 if error.
111  */
112 int net_trickle_stop(struct net_trickle *trickle);
113 
114 /**
115  * @brief To be called by the protocol handler when it hears a consistent
116  * network transmission.
117  *
118  * @param trickle Pointer to Trickle struct.
119  */
120 void net_trickle_consistency(struct net_trickle *trickle);
121 
122 /**
123  * @brief To be called by the protocol handler when it hears an inconsistent
124  * network transmission.
125  *
126  * @param trickle Pointer to Trickle struct.
127  */
128 void net_trickle_inconsistency(struct net_trickle *trickle);
129 
130 /**
131  * @brief Check if the Trickle timer is running or not.
132  *
133  * @param trickle Pointer to Trickle struct.
134  *
135  * @return Return True if timer is running and False if not.
136  */
net_trickle_is_running(struct net_trickle * trickle)137 static inline bool net_trickle_is_running(struct net_trickle *trickle)
138 {
139 	NET_ASSERT(trickle);
140 
141 	return trickle->I != 0U;
142 }
143 
144 /**
145  * @}
146  */
147 
148 #ifdef __cplusplus
149 }
150 #endif
151 
152 #endif /* ZEPHYR_INCLUDE_NET_TRICKLE_H_ */
153