Contiki-NG
Loading...
Searching...
No Matches
lwm2m-queue-mode.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017, RISE SICS AB.
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
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * \addtogroup lwm2m
33 * @{
34 */
35
36/**
37 * \file
38 * Implementation of the Contiki OMA LWM2M Queue Mode for managing the parameters
39 * \author
40 * Carlos Gonzalo Peces <carlosgp143@gmail.com>
41 */
42
43#include "lwm2m-queue-mode.h"
44
45#if LWM2M_QUEUE_MODE_ENABLED
46
47#include "lwm2m-engine.h"
48#include "lwm2m-rd-client.h"
49#include "lib/memb.h"
50#include "lib/list.h"
51#include <string.h>
52
53/* Log configuration */
54#include "coap-log.h"
55#define LOG_MODULE "lwm2m-queue-mode"
56#define LOG_LEVEL LOG_LEVEL_LWM2M
57
58/* Queue Mode dynamic adaptation masks */
59#define FIRST_REQUEST_MASK 0x01
60#define HANDLER_FROM_NOTIFICATION_MASK 0x02
61
62static uint16_t queue_mode_awake_time = LWM2M_QUEUE_MODE_DEFAULT_CLIENT_AWAKE_TIME;
63static uint32_t queue_mode_sleep_time = LWM2M_QUEUE_MODE_DEFAULT_CLIENT_SLEEP_TIME;
64
65/* Flag for notifications */
66static uint8_t waked_up_by_notification;
67
68/* For the dynamic adaptation of the awake time */
69#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION
70static uint8_t queue_mode_dynamic_adaptation_flag = LWM2M_QUEUE_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG;
71
72/* Window to save the times and do the dynamic adaptation of the awake time*/
73uint16_t times_window[LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH] = { 0 };
74uint8_t times_window_index = 0;
75static uint8_t dynamic_adaptation_params = 0x00; /* bit0: first_request, bit1: handler from notification */
76static uint64_t previous_request_time;
77static inline void clear_first_request();
78static inline uint8_t is_first_request();
79static inline void clear_handler_from_notification();
80static inline uint8_t get_handler_from_notification();
81#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */
82/*---------------------------------------------------------------------------*/
83uint16_t
84lwm2m_queue_mode_get_awake_time()
85{
86 LOG_DBG("Client Awake Time: %d ms\n", (int)queue_mode_awake_time);
87 return queue_mode_awake_time;
88}
89/*---------------------------------------------------------------------------*/
90void
91lwm2m_queue_mode_set_awake_time(uint16_t time)
92{
93 queue_mode_awake_time = time;
94}
95/*---------------------------------------------------------------------------*/
96uint32_t
97lwm2m_queue_mode_get_sleep_time()
98{
99 LOG_DBG("Client Sleep Time: %d ms\n", (int)queue_mode_sleep_time);
100 return queue_mode_sleep_time;
101}
102/*---------------------------------------------------------------------------*/
103void
104lwm2m_queue_mode_set_sleep_time(uint32_t time)
105{
106 queue_mode_sleep_time = time;
107}
108/*---------------------------------------------------------------------------*/
109#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION
110uint8_t
111lwm2m_queue_mode_get_dynamic_adaptation_flag()
112{
113 LOG_DBG("Dynamic Adaptation Flag: %d ms\n", (int)queue_mode_dynamic_adaptation_flag);
114 return queue_mode_dynamic_adaptation_flag;
115}
116/*---------------------------------------------------------------------------*/
117void
118lwm2m_queue_mode_set_dynamic_adaptation_flag(uint8_t flag)
119{
120 queue_mode_dynamic_adaptation_flag = flag;
121}
122#endif
123/*---------------------------------------------------------------------------*/
124#if !UPDATE_WITH_MEAN
125static uint16_t
126get_maximum_time()
127{
128 uint16_t max_time = 0;
129 uint8_t i;
130 for(i = 0; i < LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH; i++) {
131 if(times_window[i] > max_time) {
132 max_time = times_window[i];
133 }
134 }
135 return max_time;
136}
137#endif
138/*---------------------------------------------------------------------------*/
139#if UPDATE_WITH_MEAN
140static uint16_t
141get_mean_time()
142{
143 uint16_t mean_time = 0;
144 uint8_t i;
145 for(i = 0; i < LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH; i++) {
146 if(mean_time == 0) {
147 mean_time = times_window[i];
148 } else {
149 if(times_window[i] != 0) {
150 mean_time = (mean_time + times_window[i]) / 2;
151 }
152 }
153 }
154 return mean_time;
155}
156#endif
157/*---------------------------------------------------------------------------*/
158static void
159update_awake_time()
160{
161#if UPDATE_WITH_MEAN
162 uint16_t mean_time = get_mean_time();
163 LOG_DBG("Dynamic Adaptation: updated awake time: %d ms\n", (int)mean_time);
164 lwm2m_queue_mode_set_awake_time(mean_time + (mean_time >> 1)); /* 50% margin */
165 return;
166#else
167 uint16_t max_time = get_maximum_time();
168 LOG_DBG("Dynamic Adaptation: updated awake time: %d ms\n", (int)max_time);
169 lwm2m_queue_mode_set_awake_time(max_time + (max_time >> 1)); /* 50% margin */
170 return;
171#endif
172}
173/*---------------------------------------------------------------------------*/
174void
175lwm2m_queue_mode_add_time_to_window(uint16_t time)
176{
177 if(times_window_index == LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH) {
178 times_window_index = 0;
179 }
180 times_window[times_window_index] = time;
181 times_window_index++;
182 update_awake_time();
183}
184/*---------------------------------------------------------------------------*/
185uint8_t
186lwm2m_queue_mode_is_waked_up_by_notification()
187{
188 return waked_up_by_notification;
189}
190/*---------------------------------------------------------------------------*/
191void
192lwm2m_queue_mode_clear_waked_up_by_notification()
193{
194 waked_up_by_notification = 0;
195}
196/*---------------------------------------------------------------------------*/
197void
198lwm2m_queue_mode_set_waked_up_by_notification()
199{
200 waked_up_by_notification = 1;
201}
202/*---------------------------------------------------------------------------*/
203void
204lwm2m_queue_mode_request_received()
205{
206 if(lwm2m_rd_client_is_client_awake()) {
207 lwm2m_rd_client_restart_client_awake_timer();
208 }
209#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION
210 if(lwm2m_queue_mode_get_dynamic_adaptation_flag() && !get_handler_from_notification()) {
211 if(is_first_request()) {
212 previous_request_time = coap_timer_uptime();
213 clear_first_request();
214 } else {
215 if(coap_timer_uptime() - previous_request_time >= 0) {
216 if(coap_timer_uptime() - previous_request_time > 0xffff) {
217 lwm2m_queue_mode_add_time_to_window(0xffff);
218 } else {
219 lwm2m_queue_mode_add_time_to_window(coap_timer_uptime() - previous_request_time);
220 }
221 }
222 previous_request_time = coap_timer_uptime();
223 }
224 }
225 if(get_handler_from_notification()) {
226 clear_handler_from_notification();
227 }
228#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */
229}
230/*---------------------------------------------------------------------------*/
231#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION
232void
233lwm2m_queue_mode_set_first_request()
234{
235 dynamic_adaptation_params |= FIRST_REQUEST_MASK;
236}
237/*---------------------------------------------------------------------------*/
238void
239lwm2m_queue_mode_set_handler_from_notification()
240{
241 dynamic_adaptation_params |= HANDLER_FROM_NOTIFICATION_MASK;
242}
243/*---------------------------------------------------------------------------*/
244static inline uint8_t
245is_first_request()
246{
247 return dynamic_adaptation_params & FIRST_REQUEST_MASK;
248}
249/*---------------------------------------------------------------------------*/
250static inline uint8_t
251get_handler_from_notification()
252{
253 return (dynamic_adaptation_params & HANDLER_FROM_NOTIFICATION_MASK) != 0;
254}
255/*---------------------------------------------------------------------------*/
256static inline void
257clear_first_request()
258{
259 dynamic_adaptation_params &= ~FIRST_REQUEST_MASK;
260}
261/*---------------------------------------------------------------------------*/
262static inline void
263clear_handler_from_notification()
264{
265 dynamic_adaptation_params &= ~HANDLER_FROM_NOTIFICATION_MASK;
266}
267#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */
268#endif /* LWM2M_QUEUE_MODE_ENABLED */
269/** @} */
270
Log support for CoAP.
static uint64_t coap_timer_uptime(void)
Get the time since boot in milliseconds.
Definition coap-timer.h:83
Linked list manipulation routines.
Header file for the Contiki OMA LWM2M engine.
Header file for the Contiki OMA LWM2M Queue Mode implementation to manage the parameters.
Header file for the Contiki OMA LWM2M Registration and Bootstrap Client.
Memory block allocation routines.