diff --git a/os/services/lwm2m/lwm2m-engine.c b/os/services/lwm2m/lwm2m-engine.c index b80e6f5a4..36f6fae44 100644 --- a/os/services/lwm2m/lwm2m-engine.c +++ b/os/services/lwm2m/lwm2m-engine.c @@ -81,7 +81,7 @@ #endif /* LWM2M_ENGINE_CONF_USE_RD_CLIENT */ -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED /* Queue Mode is handled using the RD Client and the Q-Mode object */ #define USE_RD_CLIENT 1 /* Queue Mode dynamic adaptation masks */ @@ -93,10 +93,13 @@ #include "lwm2m-rd-client.h" #endif -#if LWM2M_Q_MODE_ENABLED -#include "lwm2m-qmode-object.h" +#if LWM2M_QUEUE_MODE_ENABLED +#include "lwm2m-queue-mode.h" #include "lwm2m-notification-queue.h" -#endif +#if LWM2M_QUEUE_MODE_OBJECT_ENABLED +#include "lwm2m-queue-mode-object.h" +#endif /* LWM2M_QUEUE_MODE_OBJECT_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ /* MACRO for getting out resource ID from resource array ID + flags */ #define RSC_ID(x) ((uint16_t)(x & 0xffff)) @@ -143,18 +146,18 @@ static struct { /* in the future also a timeout */ } created; -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED static uint8_t waked_up_by_notification; /* For the dynamic adaptation of the awake time */ -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION static uint8_t dynamic_adaptation_params = 0x00; /* bit0: first_request, bit1: handler from notification */ static uint64_t previous_request_time; static inline void clear_first_request(); static inline uint8_t is_first_request(); static inline void clear_handler_from_notification(); static inline uint8_t get_handler_from_notification(); -#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ COAP_HANDLER(lwm2m_handler, lwm2m_handler_callback); LIST(object_list); @@ -581,8 +584,8 @@ lwm2m_engine_init(void) lwm2m_rd_client_init(endpoint); #endif -#if LWM2M_Q_MODE_ENABLED - lwm2m_q_object_init(); +#if LWM2M_QUEUE_MODE_ENABLED && LWM2M_QUEUE_MODE_OBJECT_ENABLED + lwm2m_queue_mode_object_init(); #endif } /*---------------------------------------------------------------------------*/ @@ -1404,22 +1407,23 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response, context.inbuf->pos = 0; /*If Queue Mode, restart the client awake timer */ -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED if(lwm2m_rd_client_is_client_awake()) { lwm2m_rd_client_restart_client_awake_timer(); } -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - if(lwm2m_q_object_get_dynamic_adaptation_flag() && !get_handler_from_notification()) { +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION + if(lwm2m_queue_mode_get_dynamic_adaptation_flag() && !get_handler_from_notification()) { if(is_first_request()) { previous_request_time = coap_timer_uptime(); clear_first_request(); } else { if(coap_timer_uptime()-previous_request_time >= 0) { if(coap_timer_uptime()-previous_request_time > 0xffff) { - lwm2m_q_object_add_time_to_window(0xffff); + lwm2m_queue_mode_add_time_to_window(0xffff); + } else { + lwm2m_queue_mode_add_time_to_window(coap_timer_uptime()-previous_request_time); } - lwm2m_q_object_add_time_to_window(coap_timer_uptime()-previous_request_time); } previous_request_time = coap_timer_uptime(); } @@ -1427,8 +1431,8 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response, if(get_handler_from_notification()) { clear_handler_from_notification(); } -#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ /* Maybe this should be part of CoAP itself - this seems not to be working with the leshan server */ @@ -1692,8 +1696,8 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response, static void lwm2m_send_notification(char* path) { -#if LWM2M_Q_MODE_ENABLED && LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - if(lwm2m_q_object_get_dynamic_adaptation_flag()) { +#if LWM2M_QUEUE_MODE_ENABLED && LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION + if(lwm2m_queue_mode_get_dynamic_adaptation_flag()) { lwm2m_engine_set_handler_from_notification(); } #endif @@ -1709,7 +1713,7 @@ lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, snprintf(path, 20, "%d/%d/%d", obj->object_id, obj->instance_id, resource); } -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED if(coap_has_observers(path)) { /* Client is sleeping -> add the notification to the list */ @@ -1719,7 +1723,7 @@ lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, /* if it is the first notification -> wake up and send update */ if(!waked_up_by_notification) { waked_up_by_notification = 1; - lwm2m_rd_client_fsm_execute_q_mode_update(); + lwm2m_rd_client_fsm_execute_queue_mode_update(); } /* Client is awake -> send the notification */ } else { @@ -1732,7 +1736,7 @@ lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, } /*---------------------------------------------------------------------------*/ /* Queue Mode Support and dynamic adaptation of the client awake time */ -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED uint8_t lwm2m_engine_is_waked_up_by_notification() { @@ -1745,7 +1749,7 @@ lwm2m_engine_clear_waked_up_by_notification() waked_up_by_notification = 0; } /*---------------------------------------------------------------------------*/ -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION void lwm2m_engine_set_first_request() { @@ -1781,7 +1785,7 @@ clear_handler_from_notification() { dynamic_adaptation_params &= ~HANDLER_FROM_NOTIFICATION_MASK; } -#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/services/lwm2m/lwm2m-engine.h b/os/services/lwm2m/lwm2m-engine.h index 61d0353af..0f6d35734 100644 --- a/os/services/lwm2m/lwm2m-engine.h +++ b/os/services/lwm2m/lwm2m-engine.h @@ -46,7 +46,7 @@ #define LWM2M_ENGINE_H #include "lwm2m-object.h" -#include "lwm2m-qmode-conf.h" +#include "lwm2m-queue-mode-conf.h" #define LWM2M_FLOAT32_BITS 10 #define LWM2M_FLOAT32_FRAC (1L << LWM2M_FLOAT32_BITS) @@ -116,14 +116,14 @@ void lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, void lwm2m_engine_set_opaque_callback(lwm2m_context_t *ctx, lwm2m_write_opaque_callback cb); -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED uint8_t lwm2m_engine_is_waked_up_by_notification(); void lwm2m_engine_clear_waked_up_by_notification(); -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION void lwm2m_engine_set_first_request(); void lwm2m_engine_set_handler_from_notification(); -#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ #endif /* LWM2M_ENGINE_H */ /** @} */ diff --git a/os/services/lwm2m/lwm2m-notification-queue.c b/os/services/lwm2m/lwm2m-notification-queue.c index dab243ec1..e7c57a03c 100644 --- a/os/services/lwm2m/lwm2m-notification-queue.c +++ b/os/services/lwm2m/lwm2m-notification-queue.c @@ -42,9 +42,9 @@ /*---------------------------------------------------------------------------*/ #include "lwm2m-notification-queue.h" -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED -#include "lwm2m-qmode-object.h" +#include "lwm2m-queue-mode.h" #include "lwm2m-engine.h" #include "coap-engine.h" #include "lib/memb.h" @@ -223,8 +223,8 @@ lwm2m_notification_queue_send_notifications() while(iteration_path != NULL) { extend_path(iteration_path, path, sizeof(path)); -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - if(lwm2m_q_object_get_dynamic_adaptation_flag()) { +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION + if(lwm2m_queue_mode_get_dynamic_adaptation_flag()) { lwm2m_engine_set_handler_from_notification(); } #endif @@ -235,5 +235,5 @@ lwm2m_notification_queue_send_notifications() remove_notification_path(aux); } } -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ /** @} */ \ No newline at end of file diff --git a/os/services/lwm2m/lwm2m-notification-queue.h b/os/services/lwm2m/lwm2m-notification-queue.h index 3364d3a77..805002cc2 100644 --- a/os/services/lwm2m/lwm2m-notification-queue.h +++ b/os/services/lwm2m/lwm2m-notification-queue.h @@ -44,9 +44,8 @@ #define LWM2M_NOTIFICATION_QUEUE_H #include "contiki.h" -#include "lwm2m-qmode-conf.h" +#include "lwm2m-queue-mode-conf.h" -#if LWM2M_Q_MODE_ENABLED #include typedef struct notification_path { @@ -62,6 +61,5 @@ void lwm2m_notification_queue_add_notification_path(char *path); void lwm2m_notification_queue_send_notifications(); -#endif /* LWM2M_Q_MODE_ENABLED */ #endif /* LWM2M_NOTIFICATION_QUEUE_H */ /** @} */ \ No newline at end of file diff --git a/os/services/lwm2m/lwm2m-qmode-object.c b/os/services/lwm2m/lwm2m-qmode-object.c deleted file mode 100644 index be5bc7674..000000000 --- a/os/services/lwm2m/lwm2m-qmode-object.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2017, RISE SICS AB. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \addtogroup lwm2m - * @{ - */ - -/** - * \file - * Implementation of the Contiki OMA LWM2M Queue Object for managing the queue mode - * \author - * Carlos Gonzalo Peces - */ - -#include "lwm2m-qmode-object.h" - -#if LWM2M_Q_MODE_ENABLED - -#include "lwm2m-object.h" -#include "lwm2m-engine.h" -#include "lwm2m-rd-client.h" -#include "lib/memb.h" -#include "lib/list.h" -#include - -/* Log configuration */ -#include "coap-log.h" -#define LOG_MODULE "lwm2m-qmode-object" -#define LOG_LEVEL LOG_LEVEL_LWM2M - -#define LWM2M_Q_OBJECT_ID 6000 -#define LWM2M_AWAKE_TIME_ID 3000 -#define LWM2M_SLEEP_TIME_ID 3001 - -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION -#define LWM2M_DYNAMIC_ADAPTATION_FLAG_ID 3002 -#define UPDATE_WITH_MEAN 0 /* 1-mean time 0-maximum time */ -#endif - -static const lwm2m_resource_id_t resources[] = -{ RW(LWM2M_AWAKE_TIME_ID), - RW(LWM2M_SLEEP_TIME_ID), -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - RW(LWM2M_DYNAMIC_ADAPTATION_FLAG_ID), -#endif -}; - -static uint16_t q_mode_awake_time = LWM2M_Q_MODE_DEFAULT_CLIENT_AWAKE_TIME; -static uint32_t q_mode_sleep_time = LWM2M_Q_MODE_DEFAULT_CLIENT_SLEEP_TIME; -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION -static uint8_t q_mode_dynamic_adaptation_flag = LWM2M_Q_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG; - -/* Window to save the times and do the dynamic adaptation of the awake time*/ -uint16_t times_window[LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH] = { 0 }; -uint8_t times_window_index = 0; - -#endif -/*---------------------------------------------------------------------------*/ -uint16_t -lwm2m_q_object_get_awake_time() -{ - LOG_DBG("Client Awake Time: %d ms\n", (int)q_mode_awake_time); - return q_mode_awake_time; -} -/*---------------------------------------------------------------------------*/ -static void -lwm2m_q_object_set_awake_time(uint16_t time) -{ - q_mode_awake_time = time; -} -/*---------------------------------------------------------------------------*/ -uint32_t -lwm2m_q_object_get_sleep_time() -{ - LOG_DBG("Client Sleep Time: %d ms\n", (int)q_mode_sleep_time); - return q_mode_sleep_time; -} -/*---------------------------------------------------------------------------*/ -static void -lwm2m_q_object_set_sleep_time(uint32_t time) -{ - q_mode_sleep_time = time; -} -/*---------------------------------------------------------------------------*/ -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION -uint8_t -lwm2m_q_object_get_dynamic_adaptation_flag() -{ - LOG_DBG("Dynamic Adaptation Flag: %d ms\n", (int)q_mode_dynamic_adaptation_flag); - return q_mode_dynamic_adaptation_flag; -} -/*---------------------------------------------------------------------------*/ -static void -lwm2m_q_object_set_dynamic_adaptation_flag(uint8_t flag) -{ - q_mode_dynamic_adaptation_flag = flag; -} -/*---------------------------------------------------------------------------*/ -#if !UPDATE_WITH_MEAN -static uint16_t -get_maximum_time() -{ - uint16_t max_time = 0; - uint8_t i; - for(i = 0; i < LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH; i++) { - if(times_window[i] > max_time) { - max_time = times_window[i]; - } - } - return max_time; -} -#endif -/*---------------------------------------------------------------------------*/ -#if UPDATE_WITH_MEAN -static uint16_t -get_mean_time() -{ - uint16_t mean_time = 0; - uint8_t i; - for(i = 0; i < LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH; i++) { - if(mean_time == 0) { - mean_time = times_window[i]; - } else { - if(times_window[i] != 0) { - mean_time = (mean_time + times_window[i]) / 2; - } - } - } - return mean_time; -} -#endif -/*---------------------------------------------------------------------------*/ -static void -update_awake_time() -{ -#if UPDATE_WITH_MEAN - uint16_t mean_time = get_mean_time(); - LOG_DBG("Dynamic Adaptation: updated awake time: %d ms\n", (int)mean_time); - lwm2m_q_object_set_awake_time(mean_time + (mean_time >> 1)); /* 50% margin */ - return; -#else - uint16_t max_time = get_maximum_time(); - LOG_DBG("Dynamic Adaptation: updated awake time: %d ms\n", (int)max_time); - lwm2m_q_object_set_awake_time(max_time + (max_time >> 1)); /* 50% margin */ - return; -#endif -} -/*---------------------------------------------------------------------------*/ -void -lwm2m_q_object_add_time_to_window(uint16_t time) -{ - if(times_window_index == LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH) { - times_window_index = 0; - } - times_window[times_window_index] = time; - times_window_index++; - update_awake_time(); -} -#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ -/*---------------------------------------------------------------------------*/ -static lwm2m_status_t -lwm2m_callback(lwm2m_object_instance_t *object, lwm2m_context_t *ctx) -{ - if(ctx->operation == LWM2M_OP_READ) { - switch(ctx->resource_id) { - case LWM2M_AWAKE_TIME_ID: - lwm2m_object_write_int(ctx, (int32_t)q_mode_awake_time); - return LWM2M_STATUS_OK; - case LWM2M_SLEEP_TIME_ID: - lwm2m_object_write_int(ctx, (int32_t)q_mode_sleep_time); - return LWM2M_STATUS_OK; -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - case LWM2M_DYNAMIC_ADAPTATION_FLAG_ID: - lwm2m_object_write_int(ctx, (int32_t)q_mode_dynamic_adaptation_flag); - return LWM2M_STATUS_OK; -#endif - } - } else if(ctx->operation == LWM2M_OP_WRITE) { - switch(ctx->resource_id) { - int32_t value_read; - size_t len; - - case LWM2M_AWAKE_TIME_ID: - - len = lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, - &value_read); - LOG_DBG("Client Awake Time write request value: %d\n", (int)value_read); - if(len == 0) { - LOG_WARN("FAIL: could not write awake time\n"); - return LWM2M_STATUS_WRITE_ERROR; - } else { - lwm2m_q_object_set_awake_time(value_read); - return LWM2M_STATUS_OK; - } - - case LWM2M_SLEEP_TIME_ID: - len = lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, - &value_read); - LOG_DBG("Client Sleep Time write request value: %d\n", (int)value_read); - if(len == 0) { - LOG_WARN("FAIL: could not write sleep time\n"); - return LWM2M_STATUS_WRITE_ERROR; - } else { - lwm2m_q_object_set_sleep_time(value_read); - return LWM2M_STATUS_OK; - } -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - case LWM2M_DYNAMIC_ADAPTATION_FLAG_ID: - len = lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, - &value_read); - LOG_DBG("Dynamic Adaptation Flag request value: %d\n", (int)value_read); - if(len == 0) { - LOG_WARN("FAIL: could not write dynamic flag\n"); - return LWM2M_STATUS_WRITE_ERROR; - } else { - lwm2m_q_object_set_dynamic_adaptation_flag(value_read); - return LWM2M_STATUS_OK; - } -#endif - } - } - - return LWM2M_STATUS_OPERATION_NOT_ALLOWED; -} -/*---------------------------------------------------------------------------*/ -static lwm2m_object_instance_t queue_object = { - .object_id = LWM2M_Q_OBJECT_ID, - .instance_id = 0, - .resource_ids = resources, - .resource_count = sizeof(resources) / sizeof(lwm2m_resource_id_t), - .resource_dim_callback = NULL, - .callback = lwm2m_callback, -}; -/*---------------------------------------------------------------------------*/ -void -lwm2m_q_object_init(void) -{ - lwm2m_engine_add_object(&queue_object); -} -/*---------------------------------------------------------------------------*/ -void -lwm2m_q_object_send_notifications() -{ - lwm2m_notify_object_observers(&queue_object, LWM2M_AWAKE_TIME_ID); - lwm2m_notify_object_observers(&queue_object, LWM2M_SLEEP_TIME_ID); -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - lwm2m_notify_object_observers(&queue_object, LWM2M_DYNAMIC_ADAPTATION_FLAG_ID); -#endif -} -/*---------------------------------------------------------------------------*/ -#endif /* LWM2M_Q_MODE_ENABLED */ -/** @} */ - diff --git a/os/services/lwm2m/lwm2m-qmode-conf.h b/os/services/lwm2m/lwm2m-queue-mode-conf.h similarity index 53% rename from os/services/lwm2m/lwm2m-qmode-conf.h rename to os/services/lwm2m/lwm2m-queue-mode-conf.h index 1220d0584..3432c112a 100644 --- a/os/services/lwm2m/lwm2m-qmode-conf.h +++ b/os/services/lwm2m/lwm2m-queue-mode-conf.h @@ -40,46 +40,57 @@ * Carlos Gonzalo Peces */ -#ifndef LWM2M_QMODE_CONF_H -#define LWM2M_QMODE_CONF_H +#ifndef LWM2M_QUEUE_MODE_CONF_H +#define LWM2M_QUEUE_MODE_CONF_H + +#include "contiki.h" /* Enable the Queue Mode */ -#ifdef LWM2M_Q_MODE_CONF_ENABLED -#define LWM2M_Q_MODE_ENABLED LWM2M_Q_MODE_CONF_ENABLED +#ifdef LWM2M_QUEUE_MODE_CONF_ENABLED +#define LWM2M_QUEUE_MODE_ENABLED LWM2M_QUEUE_MODE_CONF_ENABLED #else -#define LWM2M_Q_MODE_ENABLED 0 -#endif /* LWM2M_Q_MODE_CONF_ENABLED */ +#define LWM2M_QUEUE_MODE_ENABLED 0 +#endif /* LWM2M_QUEUE_MODE_CONF_ENABLED */ /* Default Sleeping Time */ -#ifdef LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME -#define LWM2M_Q_MODE_DEFAULT_CLIENT_SLEEP_TIME LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME +#ifdef LWM2M_QUEUE_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME +#define LWM2M_QUEUE_MODE_DEFAULT_CLIENT_SLEEP_TIME LWM2M_QUEUE_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME #else -#define LWM2M_Q_MODE_DEFAULT_CLIENT_SLEEP_TIME 10000 /* msec */ -#endif /* LWM2M_Q_MODE_DEFAULT_CLIENT_SLEEPING_TIME */ +#define LWM2M_QUEUE_MODE_DEFAULT_CLIENT_SLEEP_TIME 10000 /* msec */ +#endif /* LWM2M_QUEUE_MODE_DEFAULT_CLIENT_SLEEPING_TIME */ /* Default Awake Time */ -#ifdef LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME -#define LWM2M_Q_MODE_DEFAULT_CLIENT_AWAKE_TIME LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME +#ifdef LWM2M_QUEUE_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME +#define LWM2M_QUEUE_MODE_DEFAULT_CLIENT_AWAKE_TIME LWM2M_QUEUE_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME #else -#define LWM2M_Q_MODE_DEFAULT_CLIENT_AWAKE_TIME 5000 /* msec */ -#endif /* LWM2M_Q_MODE_DEFAULT_CLIENT_AWAKE_TIME */ +#define LWM2M_QUEUE_MODE_DEFAULT_CLIENT_AWAKE_TIME 5000 /* msec */ +#endif /* LWM2M_QUEUE_MODE_DEFAULT_CLIENT_AWAKE_TIME */ /* Include the possibility to do the dynamic adaptation of the client awake time */ -#ifdef LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION -#define LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION +#ifdef LWM2M_QUEUE_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION +#define LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION LWM2M_QUEUE_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION #else -#define LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION 0 /* not included */ -#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +#define LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION 0 /* not included */ +#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ /* Default value for the dynamic adaptation flag */ -#ifdef LWM2M_Q_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG -#define LWM2M_Q_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG LWM2M_Q_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG +#ifdef LWM2M_QUEUE_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG +#define LWM2M_QUEUE_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG LWM2M_QUEUE_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG #else -#define LWM2M_Q_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG 0 /* disabled */ -#endif /* LWM2M_Q_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG */ +#define LWM2M_QUEUE_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG 0 /* disabled */ +#endif /* LWM2M_QUEUE_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG */ /* Length of the list of times for the dynamic adaptation */ -#define LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH 10 +#define LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH 10 -#endif /* LWM2M_QMODE_CONF_H */ +/* Enable and disable the Queue Mode Object */ +#ifdef LWM2M_QUEUE_MODE_OBJECT_CONF_ENABLED +#define LWM2M_QUEUE_MODE_OBJECT_ENABLED LWM2M_QUEUE_MODE_OBJECT_CONF_ENABLED +#else +#define LWM2M_QUEUE_MODE_OBJECT_ENABLED 0 /* not included */ +#endif /* LWM2M_QUEUE_MODE_OBJECT_ENABLED */ + + + +#endif /* LWM2M_QUEUE_MODE_CONF_H */ /** @} */ diff --git a/os/services/lwm2m/lwm2m-queue-mode-object.c b/os/services/lwm2m/lwm2m-queue-mode-object.c new file mode 100644 index 000000000..a3c000d69 --- /dev/null +++ b/os/services/lwm2m/lwm2m-queue-mode-object.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017, RISE SICS AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \addtogroup lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M Queue Mode object + to manage the parameters from the server side + * \author + * Carlos Gonzalo Peces + */ + +#include "lwm2m-object.h" +#include "lwm2m-queue-mode.h" + +/* Log configuration */ +#include "coap-log.h" +#define LOG_MODULE "lwm2m-qmode-object" +#define LOG_LEVEL LOG_LEVEL_LWM2M + +#if LWM2M_QUEUE_MODE_ENABLED && LWM2M_QUEUE_MODE_OBJECT_ENABLED + +#define LWM2M_QUEUE_MODE_OBJECT_ID 30000 +#define LWM2M_AWAKE_TIME_ID 30000 +#define LWM2M_SLEEP_TIME_ID 30001 + +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION +#define LWM2M_DYNAMIC_ADAPTATION_FLAG_ID 30002 +#define UPDATE_WITH_MEAN 0 /* 1-mean time 0-maximum time */ +#endif + +static const lwm2m_resource_id_t resources[] = +{ RW(LWM2M_AWAKE_TIME_ID), + RW(LWM2M_SLEEP_TIME_ID), +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION + RW(LWM2M_DYNAMIC_ADAPTATION_FLAG_ID), +#endif +}; + +/*---------------------------------------------------------------------------*/ +static lwm2m_status_t +lwm2m_callback(lwm2m_object_instance_t *object, lwm2m_context_t *ctx) +{ + if(ctx->operation == LWM2M_OP_READ) { + switch(ctx->resource_id) { + case LWM2M_AWAKE_TIME_ID: + lwm2m_object_write_int(ctx, (int32_t)lwm2m_queue_mode_get_awake_time()); + return LWM2M_STATUS_OK; + case LWM2M_SLEEP_TIME_ID: + lwm2m_object_write_int(ctx, (int32_t)lwm2m_queue_mode_get_sleep_time()); + return LWM2M_STATUS_OK; +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION + case LWM2M_DYNAMIC_ADAPTATION_FLAG_ID: + lwm2m_object_write_int(ctx, (int32_t)lwm2m_queue_mode_get_dynamic_adaptation_flag()); + return LWM2M_STATUS_OK; +#endif + } + } else if(ctx->operation == LWM2M_OP_WRITE) { + switch(ctx->resource_id) { + int32_t value_read; + size_t len; + + case LWM2M_AWAKE_TIME_ID: + + len = lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, + &value_read); + LOG_DBG("Client Awake Time write request value: %d\n", (int)value_read); + if(len == 0) { + LOG_WARN("FAIL: could not write awake time\n"); + return LWM2M_STATUS_WRITE_ERROR; + } else { + lwm2m_queue_mode_set_awake_time(value_read); + return LWM2M_STATUS_OK; + } + + case LWM2M_SLEEP_TIME_ID: + len = lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, + &value_read); + LOG_DBG("Client Sleep Time write request value: %d\n", (int)value_read); + if(len == 0) { + LOG_WARN("FAIL: could not write sleep time\n"); + return LWM2M_STATUS_WRITE_ERROR; + } else { + lwm2m_queue_mode_set_sleep_time(value_read); + return LWM2M_STATUS_OK; + } +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION + case LWM2M_DYNAMIC_ADAPTATION_FLAG_ID: + len = lwm2m_object_read_int(ctx, ctx->inbuf->buffer, ctx->inbuf->size, + &value_read); + LOG_DBG("Dynamic Adaptation Flag request value: %d\n", (int)value_read); + if(len == 0) { + LOG_WARN("FAIL: could not write dynamic flag\n"); + return LWM2M_STATUS_WRITE_ERROR; + } else { + lwm2m_queue_mode_set_dynamic_adaptation_flag(value_read); + return LWM2M_STATUS_OK; + } +#endif + } + } + + return LWM2M_STATUS_OPERATION_NOT_ALLOWED; +} +/*---------------------------------------------------------------------------*/ +static lwm2m_object_instance_t queue_object = { + .object_id = LWM2M_QUEUE_MODE_OBJECT_ID, + .instance_id = 0, + .resource_ids = resources, + .resource_count = sizeof(resources) / sizeof(lwm2m_resource_id_t), + .resource_dim_callback = NULL, + .callback = lwm2m_callback, +}; +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_object_init(void) +{ + lwm2m_engine_add_object(&queue_object); +} +#endif /* LWM2M_QUEUE_MODE_ENABLED && LWM2M_QUEUE_MODE_OBJECT_ENABLED */ +/** @} */ \ No newline at end of file diff --git a/os/services/lwm2m/lwm2m-qmode-object.h b/os/services/lwm2m/lwm2m-queue-mode-object.h similarity index 74% rename from os/services/lwm2m/lwm2m-qmode-object.h rename to os/services/lwm2m/lwm2m-queue-mode-object.h index 61ac35ff3..017b797fc 100644 --- a/os/services/lwm2m/lwm2m-qmode-object.h +++ b/os/services/lwm2m/lwm2m-queue-mode-object.h @@ -35,31 +35,18 @@ /** * \file - * Header file for the Contiki OMA LWM2M Queue Object for managing the queue mode + * Header file for the Contiki OMA LWM2M Queue Mode object + to manage the parameters from the server side * \author * Carlos Gonzalo Peces */ -#ifndef LWM2M_Q_OBJECT_H_ -#define LWM2M_Q_OBJECT_H_ +#ifndef LWM2M_QUEUE_MODE_OBJECT_H_ +#define LWM2M_QUEUE_MODE_OBJECT_H_ -#include "contiki.h" -#include "lwm2m-qmode-conf.h" +#include "lwm2m-queue-mode-conf.h" -#if LWM2M_Q_MODE_ENABLED -#include +void lwm2m_queue_mode_object_init(void); -uint16_t lwm2m_q_object_get_awake_time(); -uint32_t lwm2m_q_object_get_sleep_time(); -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION -uint8_t lwm2m_q_object_get_dynamic_adaptation_flag(); -void lwm2m_q_object_add_time_to_window(uint16_t time); -#endif - -void lwm2m_q_object_send_notifications(); - -void lwm2m_q_object_init(void); - -#endif /* LWM2M_Q_MODE_ENABLED */ #endif /* LWM2M_Q_OBJECT_H_ */ -/** @} */ +/** @} */ \ No newline at end of file diff --git a/os/services/lwm2m/lwm2m-queue-mode.c b/os/services/lwm2m/lwm2m-queue-mode.c new file mode 100644 index 000000000..30c8dd6cc --- /dev/null +++ b/os/services/lwm2m/lwm2m-queue-mode.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2017, RISE SICS AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \addtogroup lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M Queue Mode for managing the parameters + * \author + * Carlos Gonzalo Peces + */ + +#include "lwm2m-queue-mode.h" + +#if LWM2M_QUEUE_MODE_ENABLED + +#include "lwm2m-engine.h" +#include "lwm2m-rd-client.h" +#include "lib/memb.h" +#include "lib/list.h" +#include + +/* Log configuration */ +#include "coap-log.h" +#define LOG_MODULE "lwm2m-queue-mode" +#define LOG_LEVEL LOG_LEVEL_LWM2M + + +static uint16_t queue_mode_awake_time = LWM2M_QUEUE_MODE_DEFAULT_CLIENT_AWAKE_TIME; +static uint32_t queue_mode_sleep_time = LWM2M_QUEUE_MODE_DEFAULT_CLIENT_SLEEP_TIME; +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION +static uint8_t queue_mode_dynamic_adaptation_flag = LWM2M_QUEUE_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG; + +/* Window to save the times and do the dynamic adaptation of the awake time*/ +uint16_t times_window[LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH] = { 0 }; +uint8_t times_window_index = 0; + +#endif +/*---------------------------------------------------------------------------*/ +uint16_t +lwm2m_queue_mode_get_awake_time() +{ + LOG_DBG("Client Awake Time: %d ms\n", (int)queue_mode_awake_time); + return queue_mode_awake_time; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_set_awake_time(uint16_t time) +{ + queue_mode_awake_time = time; +} +/*---------------------------------------------------------------------------*/ +uint32_t +lwm2m_queue_mode_get_sleep_time() +{ + LOG_DBG("Client Sleep Time: %d ms\n", (int)queue_mode_sleep_time); + return queue_mode_sleep_time; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_set_sleep_time(uint32_t time) +{ + queue_mode_sleep_time = time; +} +/*---------------------------------------------------------------------------*/ +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION +uint8_t +lwm2m_queue_mode_get_dynamic_adaptation_flag() +{ + LOG_DBG("Dynamic Adaptation Flag: %d ms\n", (int)queue_mode_dynamic_adaptation_flag); + return queue_mode_dynamic_adaptation_flag; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_set_dynamic_adaptation_flag(uint8_t flag) +{ + queue_mode_dynamic_adaptation_flag = flag; +} +/*---------------------------------------------------------------------------*/ +#if !UPDATE_WITH_MEAN +static uint16_t +get_maximum_time() +{ + uint16_t max_time = 0; + uint8_t i; + for(i = 0; i < LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH; i++) { + if(times_window[i] > max_time) { + max_time = times_window[i]; + } + } + return max_time; +} +#endif +/*---------------------------------------------------------------------------*/ +#if UPDATE_WITH_MEAN +static uint16_t +get_mean_time() +{ + uint16_t mean_time = 0; + uint8_t i; + for(i = 0; i < LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH; i++) { + if(mean_time == 0) { + mean_time = times_window[i]; + } else { + if(times_window[i] != 0) { + mean_time = (mean_time + times_window[i]) / 2; + } + } + } + return mean_time; +} +#endif +/*---------------------------------------------------------------------------*/ +static void +update_awake_time() +{ +#if UPDATE_WITH_MEAN + uint16_t mean_time = get_mean_time(); + LOG_DBG("Dynamic Adaptation: updated awake time: %d ms\n", (int)mean_time); + lwm2m_queue_mode_set_awake_time(mean_time + (mean_time >> 1)); /* 50% margin */ + return; +#else + uint16_t max_time = get_maximum_time(); + LOG_DBG("Dynamic Adaptation: updated awake time: %d ms\n", (int)max_time); + lwm2m_queue_mode_set_awake_time(max_time + (max_time >> 1)); /* 50% margin */ + return; +#endif +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_add_time_to_window(uint16_t time) +{ + if(times_window_index == LWM2M_QUEUE_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH) { + times_window_index = 0; + } + times_window[times_window_index] = time; + times_window_index++; + update_awake_time(); +} +#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ +/** @} */ + diff --git a/os/services/lwm2m/lwm2m-queue-mode.h b/os/services/lwm2m/lwm2m-queue-mode.h new file mode 100644 index 000000000..cc3bd3290 --- /dev/null +++ b/os/services/lwm2m/lwm2m-queue-mode.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017, RISE SICS AB. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \addtogroup oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M Queue Mode implementation + to manage the parameters + * \author + * Carlos Gonzalo Peces + */ + +#ifndef LWM2M_QUEUE_MODE_H_ +#define LWM2M_QUEUE_MODE_H_ + +#include "lwm2m-queue-mode-conf.h" +#include + +uint16_t lwm2m_queue_mode_get_awake_time(); +void lwm2m_queue_mode_set_awake_time(uint16_t time); +uint32_t lwm2m_queue_mode_get_sleep_time(); +void lwm2m_queue_mode_set_sleep_time(uint32_t time); +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION +uint8_t lwm2m_queue_mode_get_dynamic_adaptation_flag(); +void lwm2m_queue_mode_set_dynamic_adaptation_flag(uint8_t flag); +void lwm2m_queue_mode_add_time_to_window(uint16_t time); +#endif + +#endif /* LWM2M_QUEUE_MODE_H_ */ +/** @} */ diff --git a/os/services/lwm2m/lwm2m-rd-client.c b/os/services/lwm2m/lwm2m-rd-client.c index cf7c5deb3..da8d276d0 100644 --- a/os/services/lwm2m/lwm2m-rd-client.c +++ b/os/services/lwm2m/lwm2m-rd-client.c @@ -62,10 +62,10 @@ #include "rpl.h" #endif /* UIP_CONF_IPV6_RPL */ -#if LWM2M_Q_MODE_ENABLED -#include "lwm2m-qmode-object.h" +#if LWM2M_QUEUE_MODE_ENABLED +#include "lwm2m-queue-mode.h" #include "lwm2m-notification-queue.h" -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ /* Log configuration */ #include "coap-log.h" @@ -105,9 +105,9 @@ static coap_message_t request[1]; /* This way the message can be treated as #define DEREGISTER_SENT 11 #define DEREGISTER_FAILED 12 #define DEREGISTERED 13 -#if LWM2M_Q_MODE_ENABLED -#define Q_MODE_AWAKE 14 -#define Q_MODE_SEND_UPDATE 15 +#if LWM2M_QUEUE_MODE_ENABLED +#define QUEUE_MODE_AWAKE 14 +#define QUEUE_MODE_SEND_UPDATE 15 #endif #define FLAG_RD_DATA_DIRTY 0x01 @@ -130,16 +130,16 @@ static void (*rd_callback)(coap_request_state_t *state); static coap_timer_t block1_timer; -#if LWM2M_Q_MODE_ENABLED -static coap_timer_t q_mode_client_awake_timer; /* Timer to control the client's +#if LWM2M_QUEUE_MODE_ENABLED +static coap_timer_t queue_mode_client_awake_timer; /* Timer to control the client's * awake time */ -static uint8_t q_mode_client_awake; /* 1 - client is awake, +static uint8_t queue_mode_client_awake; /* 1 - client is awake, * 0 - client is sleeping */ -static uint16_t q_mode_client_awake_time; /* The time to be awake */ +static uint16_t queue_mode_client_awake_time; /* The time to be awake */ /* Callback for the client awake timer */ -static void q_mode_awake_timer_callback(coap_timer_t *timer); +static void queue_mode_awake_timer_callback(coap_timer_t *timer); #endif static void check_periodic_observations(); @@ -445,13 +445,13 @@ registration_callback(coap_request_state_t *state) state->response->location_path_len); session_info.assigned_ep[state->response->location_path_len] = 0; /* if we decide to not pass the lt-argument on registration, we should force an initial "update" to register lifetime with server */ -#if LWM2M_Q_MODE_ENABLED -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - if(lwm2m_q_object_get_dynamic_adaptation_flag()) { +#if LWM2M_QUEUE_MODE_ENABLED +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION + if(lwm2m_queue_mode_get_dynamic_adaptation_flag()) { lwm2m_engine_set_first_request(); } #endif - lwm2m_rd_client_fsm_execute_q_mode_awake(); /* Avoid 500 ms delay and move directly to the state*/ + lwm2m_rd_client_fsm_execute_queue_mode_awake(); /* Avoid 500 ms delay and move directly to the state*/ #else rd_state = REGISTRATION_DONE; #endif @@ -499,23 +499,23 @@ update_callback(coap_request_state_t *state) LOG_DBG_("Done!\n"); /* remember the last reg time */ last_update = coap_timer_uptime(); -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED /* If it has been waked up by a notification, send the stored notifications in queue */ if(lwm2m_engine_is_waked_up_by_notification()) { lwm2m_engine_clear_waked_up_by_notification(); lwm2m_notification_queue_send_notifications(); } -#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION - if(lwm2m_q_object_get_dynamic_adaptation_flag()) { +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION + if(lwm2m_queue_mode_get_dynamic_adaptation_flag()) { lwm2m_engine_set_first_request(); } -#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ - lwm2m_rd_client_fsm_execute_q_mode_awake(); /* Avoid 500 ms delay and move directly to the state*/ +#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ + lwm2m_rd_client_fsm_execute_queue_mode_awake(); /* Avoid 500 ms delay and move directly to the state*/ #else rd_state = REGISTRATION_DONE; rd_flags &= ~FLAG_RD_DATA_UPDATE_TRIGGERED; -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ } else { /* Possible error response codes are 4.00 Bad request & 4.04 Not Found */ LOG_DBG_("Failed with code %d. Retrying registration\n", @@ -562,7 +562,7 @@ periodic_process(coap_timer_t *timer) uint64_t now; /* reschedule the CoAP timer */ -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED /* In Queue Mode, the machine is not executed periodically, but with the awake/sleeping times */ if(!((rd_state & 0xF) == 0xE)) { coap_timer_reset(&rd_timer, STATE_MACHINE_UPDATE_INTERVAL); @@ -739,27 +739,27 @@ periodic_process(coap_timer_t *timer) rd_state = UPDATE_SENT; } break; -#if LWM2M_Q_MODE_ENABLED - case Q_MODE_AWAKE: +#if LWM2M_QUEUE_MODE_ENABLED + case QUEUE_MODE_AWAKE: LOG_DBG("Queue Mode: Client is AWAKE at %lu\n", (unsigned long)coap_timer_uptime()); - q_mode_client_awake = 1; - q_mode_client_awake_time = lwm2m_q_object_get_awake_time(); - coap_timer_set(&q_mode_client_awake_timer, q_mode_client_awake_time); + queue_mode_client_awake = 1; + queue_mode_client_awake_time = lwm2m_queue_mode_get_awake_time(); + coap_timer_set(&queue_mode_client_awake_timer, queue_mode_client_awake_time); break; - case Q_MODE_SEND_UPDATE: + case QUEUE_MODE_SEND_UPDATE: /* Define this macro to make the necessary actions for waking up, * depending on the platform */ -#ifdef LWM2M_Q_MODE_WAKE_UP - LWM2M_Q_MODE_WAKE_UP(); -#endif /* LWM2M_Q_MODE_WAKE_UP */ +#ifdef LWM2M_QUEUE_MODE_WAKE_UP + LWM2M_QUEUE_MODE_WAKE_UP(); +#endif /* LWM2M_QUEUE_MODE_WAKE_UP */ prepare_update(request, rd_flags & FLAG_RD_DATA_UPDATE_TRIGGERED); coap_send_request(&rd_request_state, &session_info.server_ep, request, update_callback); last_rd_progress = coap_timer_uptime(); rd_state = UPDATE_SENT; break; -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ case UPDATE_SENT: /* just wait until the callback kicks us to the next state... */ @@ -793,12 +793,12 @@ lwm2m_rd_client_init(const char *ep) { session_info.ep = ep; /* default binding U = UDP, UQ = UDP Q-mode*/ -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED session_info.binding = "UQ"; /* Enough margin to ensure that the client is not unregistered (we * do not know the time it can stay awake) */ - session_info.lifetime = (LWM2M_Q_MODE_DEFAULT_CLIENT_SLEEP_TIME / 1000) * 2; + session_info.lifetime = (LWM2M_QUEUE_MODE_DEFAULT_CLIENT_SLEEP_TIME / 1000) * 2; #else session_info.binding = "U"; if(session_info.lifetime == 0) { @@ -811,8 +811,8 @@ lwm2m_rd_client_init(const char *ep) /* call the RD client periodically */ coap_timer_set_callback(&rd_timer, periodic_process); coap_timer_set(&rd_timer, STATE_MACHINE_UPDATE_INTERVAL); -#if LWM2M_Q_MODE_ENABLED - coap_timer_set_callback(&q_mode_client_awake_timer, q_mode_awake_timer_callback); +#if LWM2M_QUEUE_MODE_ENABLED + coap_timer_set_callback(&queue_mode_client_awake_timer, queue_mode_awake_timer_callback); #endif } /*---------------------------------------------------------------------------*/ @@ -825,51 +825,51 @@ check_periodic_observations(void) /* *Queue Mode Support */ -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED /*---------------------------------------------------------------------------*/ void lwm2m_rd_client_restart_client_awake_timer(void) { - coap_timer_set(&q_mode_client_awake_timer, q_mode_client_awake_time); + coap_timer_set(&queue_mode_client_awake_timer, queue_mode_client_awake_time); } /*---------------------------------------------------------------------------*/ uint8_t lwm2m_rd_client_is_client_awake(void) { - return q_mode_client_awake; + return queue_mode_client_awake; } /*---------------------------------------------------------------------------*/ static void -q_mode_awake_timer_callback(coap_timer_t *timer) +queue_mode_awake_timer_callback(coap_timer_t *timer) { /* Timer has expired, no requests has been received, client can go to sleep */ LOG_DBG("Queue Mode: Client is SLEEPING at %lu\n", (unsigned long)coap_timer_uptime()); - q_mode_client_awake = 0; + queue_mode_client_awake = 0; /* Define this macro to enter sleep mode depending on the platform */ -#ifdef LWM2M_Q_MODE_SLEEP_MS - LWM2M_Q_MODE_SLEEP_MS(lwm2m_q_object_get_sleep_time()); -#endif /* LWM2M_Q_MODE_SLEEP_MS */ - rd_state = Q_MODE_SEND_UPDATE; - coap_timer_set(&rd_timer, lwm2m_q_object_get_sleep_time()); +#ifdef LWM2M_QUEUE_MODE_SLEEP_MS + LWM2M_QUEUE_MODE_SLEEP_MS(lwm2m_queue_mode_get_sleep_time()); +#endif /* LWM2M_QUEUE_MODE_SLEEP_MS */ + rd_state = QUEUE_MODE_SEND_UPDATE; + coap_timer_set(&rd_timer, lwm2m_queue_mode_get_sleep_time()); } /*---------------------------------------------------------------------------*/ void -lwm2m_rd_client_fsm_execute_q_mode_awake() +lwm2m_rd_client_fsm_execute_queue_mode_awake() { coap_timer_stop(&rd_timer); - rd_state = Q_MODE_AWAKE; + rd_state = QUEUE_MODE_AWAKE; periodic_process(&rd_timer); } /*---------------------------------------------------------------------------*/ void -lwm2m_rd_client_fsm_execute_q_mode_update() +lwm2m_rd_client_fsm_execute_queue_mode_update() { coap_timer_stop(&rd_timer); - rd_state = Q_MODE_SEND_UPDATE; + rd_state = QUEUE_MODE_SEND_UPDATE; periodic_process(&rd_timer); } /*---------------------------------------------------------------------------*/ -#endif /* LWM2M_Q_MODE_ENABLED */ +#endif /* LWM2M_QUEUE_MODE_ENABLED */ /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/services/lwm2m/lwm2m-rd-client.h b/os/services/lwm2m/lwm2m-rd-client.h index 85946235d..cfc5c549d 100644 --- a/os/services/lwm2m/lwm2m-rd-client.h +++ b/os/services/lwm2m/lwm2m-rd-client.h @@ -53,7 +53,7 @@ #define LWM2M_RD_CLIENT_DISCONNECTED 5 #include "lwm2m-object.h" -#include "lwm2m-qmode-conf.h" +#include "lwm2m-queue-mode-conf.h" struct lwm2m_session_info; typedef void (*session_callback_t)(struct lwm2m_session_info *session, int status); @@ -77,11 +77,11 @@ void lwm2m_rd_client_init(const char *ep); void lwm2m_rd_client_set_session_callback(session_callback_t cb); -#if LWM2M_Q_MODE_ENABLED +#if LWM2M_QUEUE_MODE_ENABLED uint8_t lwm2m_rd_client_is_client_awake(void); void lwm2m_rd_client_restart_client_awake_timer(void); -void lwm2m_rd_client_fsm_execute_q_mode_awake(); -void lwm2m_rd_client_fsm_execute_q_mode_update(); +void lwm2m_rd_client_fsm_execute_queue_mode_awake(); +void lwm2m_rd_client_fsm_execute_queue_mode_update(); #endif #ifndef LWM2M_RD_CLIENT_ASSIGNED_ENDPOINT_MAX_LEN diff --git a/tests/18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh b/tests/18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh index 142fb253d..2b3d52c3e 100755 --- a/tests/18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh +++ b/tests/18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh @@ -10,7 +10,7 @@ IPADDR=fd00::302:304:506:708 # Starting Contiki-NG native node echo "Starting native node - lwm2m/ipso objects with Q-Mode" make -C $CONTIKI/examples/lwm2m-ipso-objects clean >/dev/null -make -C $CONTIKI/examples/lwm2m-ipso-objects DEFINES=LWM2M_Q_MODE_CONF_ENABLED=1,LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION=1 > make.log 2> make.err +make -C $CONTIKI/examples/lwm2m-ipso-objects DEFINES=LWM2M_QUEUE_MODE_CONF_ENABLED=1,LWM2M_QUEUE_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION=1,LWM2M_QUEUE_MODE_OBJECT_CONF_ENABLED=1 > make.log 2> make.err sudo $CONTIKI/examples/lwm2m-ipso-objects/example-ipso-objects.native > node.log 2> node.err & CPID=$! sleep 10 diff --git a/tests/18-coap-lwm2m/09-lwm2m-qmode-standalone-test.sh b/tests/18-coap-lwm2m/09-lwm2m-qmode-standalone-test.sh index f22b20bef..57f0e3f71 100755 --- a/tests/18-coap-lwm2m/09-lwm2m-qmode-standalone-test.sh +++ b/tests/18-coap-lwm2m/09-lwm2m-qmode-standalone-test.sh @@ -8,7 +8,7 @@ BASENAME=09-lwm2m-qmode-standalone-test # Building standalone posix example echo "Compiling standalone posix example" make CONTIKI_NG=../../$CONTIKI -C example-lwm2m-standalone/lwm2m clean >/dev/null -make CONTIKI_NG=../../$CONTIKI -C example-lwm2m-standalone/lwm2m DEFINES=LWM2M_Q_MODE_CONF_ENABLED=1,LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION=1 >make.log 2>make.err +make CONTIKI_NG=../../$CONTIKI -C example-lwm2m-standalone/lwm2m DEFINES=LWM2M_QUEUE_MODE_CONF_ENABLED=1,LWM2M_QUEUE_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION=1,LWM2M_QUEUE_MODE_OBJECT_CONF_ENABLED=1 >make.log 2>make.err echo "Downloading leshan with Q-Mode support" wget -nc https://carlosgp143.github.io/resources/leshan-server-demo-qmode-support1.0.0-SNAPSHOT-jar-with-dependencies.jar diff --git a/tests/18-coap-lwm2m/pytests/test-qmode-sleep.py b/tests/18-coap-lwm2m/pytests/test-qmode-sleep.py index da9a2ffe8..66dc061ff 100644 --- a/tests/18-coap-lwm2m/pytests/test-qmode-sleep.py +++ b/tests/18-coap-lwm2m/pytests/test-qmode-sleep.py @@ -5,10 +5,10 @@ class TestQueueModeSleep(unittest.TestCase): global client def test_read_awake_time(self): - self.assertIsNone(client.read("6000/0/3000")) + self.assertIsNone(client.read("30000/0/30000")) def test_read_sleep_time(self): - self.assertIsNone(client.read("6000/0/3001")) + self.assertIsNone(client.read("30000/0/30001")) print "----------------------------------------"