From bc9934ee5a9cc511a10c9e383dd86229c58d0de0 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 18 May 2018 05:52:09 -0700 Subject: [PATCH 01/55] Implement function uip_sr_link_snprint --- os/net/ipv6/uip-sr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ os/net/ipv6/uip-sr.h | 11 +++++++++++ 2 files changed, 57 insertions(+) diff --git a/os/net/ipv6/uip-sr.c b/os/net/ipv6/uip-sr.c index 15b123552..a82491827 100644 --- a/os/net/ipv6/uip-sr.c +++ b/os/net/ipv6/uip-sr.c @@ -41,6 +41,7 @@ #include "contiki.h" #include "net/ipv6/uip-sr.h" +#include "net/ipv6/uiplib.h" #include "net/routing/routing.h" #include "lib/list.h" #include "lib/memb.h" @@ -246,4 +247,49 @@ uip_sr_free_all(void) num_nodes--; } } +/*---------------------------------------------------------------------------*/ +int +uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link) +{ + int index = 0; + uip_ipaddr_t child_ipaddr; + uip_ipaddr_t parent_ipaddr; + + NETSTACK_ROUTING.get_sr_node_ipaddr(&child_ipaddr, link); + NETSTACK_ROUTING.get_sr_node_ipaddr(&parent_ipaddr, link->parent); + + index += uiplib_ipaddr_snprint(buf+index, buflen-index, &child_ipaddr); + if(index >= buflen) { + return index; + } + + if(link->parent == NULL) { + index += snprintf(buf+index, buflen-index, " (DODAG root)"); + if(index >= buflen) { + return index; + } + } else { + index += snprintf(buf+index, buflen-index, " to "); + if(index >= buflen) { + return index; + } + index += uiplib_ipaddr_snprint(buf+index, buflen-index, &parent_ipaddr); + if(index >= buflen) { + return index; + } + } + if(link->lifetime != UIP_SR_INFINITE_LIFETIME) { + index += snprintf(buf+index, buflen-index, + " (lifetime: %lu seconds)", (unsigned long)link->lifetime); + if(index >= buflen) { + return index; + } + } else { + index += snprintf(buf+index, buflen-index, " (lifetime: infinite)"); + if(index >= buflen) { + return index; + } + } + return index; +} /** @} */ diff --git a/os/net/ipv6/uip-sr.h b/os/net/ipv6/uip-sr.h index 7224cea14..01ed57c1c 100644 --- a/os/net/ipv6/uip-sr.h +++ b/os/net/ipv6/uip-sr.h @@ -180,6 +180,17 @@ void uip_sr_init(void); */ void uip_sr_free_all(void); +/** +* Print a textual description of a source routing link +* +* \param buf The buffer where to write content +* \param buflen The buffer len +* \param link A pointer to the source routing link +* \return Identical to snprintf: number of bytes written excluding ending null +* byte. A value >= buflen if the buffer was too small. +*/ +int uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link); + /** @} */ #endif /* UIP_SR_H */ From 59e8d059c265c5487f23a2520a6d6ed44c6cd5fd Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 18 May 2018 05:52:33 -0700 Subject: [PATCH 02/55] RPL: print links at root periodically --- os/net/routing/rpl-lite/rpl-dag-root.c | 23 +++++++++++++++++++++++ os/net/routing/rpl-lite/rpl-dag-root.h | 6 ++++++ os/net/routing/rpl-lite/rpl-timers.c | 1 + 3 files changed, 30 insertions(+) diff --git a/os/net/routing/rpl-lite/rpl-dag-root.c b/os/net/routing/rpl-lite/rpl-dag-root.c index 0d5cebe92..c96fd6656 100644 --- a/os/net/routing/rpl-lite/rpl-dag-root.c +++ b/os/net/routing/rpl-lite/rpl-dag-root.c @@ -42,12 +42,35 @@ #include "net/routing/rpl-lite/rpl.h" #include "net/ipv6/uip-ds6-route.h" +#include "net/ipv6/uip-sr.h" /* Log configuration */ #include "sys/log.h" #define LOG_MODULE "RPL" #define LOG_LEVEL LOG_LEVEL_RPL +/*---------------------------------------------------------------------------*/ +void +rpl_dag_root_print_links(const char *str) +{ + if(rpl_dag_root_is_root()) { + if(uip_sr_num_nodes() > 0) { + uip_sr_node_t *link; + /* Our routing links */ + LOG_INFO("links: %u routing links in total (%s)\n", uip_sr_num_nodes(), str); + link = uip_sr_node_head(); + while(link != NULL) { + char buf[100]; + uip_sr_link_snprint(buf, sizeof(buf), link); + LOG_INFO("links: %s\n", buf); + link = uip_sr_node_next(link); + } + LOG_INFO("links: end of list\n"); + } else { + LOG_INFO("No routing links\n"); + } + } +} /*---------------------------------------------------------------------------*/ static void set_global_address(uip_ipaddr_t *prefix, uip_ipaddr_t *iid) diff --git a/os/net/routing/rpl-lite/rpl-dag-root.h b/os/net/routing/rpl-lite/rpl-dag-root.h index af0048c4d..71b999765 100644 --- a/os/net/routing/rpl-lite/rpl-dag-root.h +++ b/os/net/routing/rpl-lite/rpl-dag-root.h @@ -63,6 +63,12 @@ int rpl_dag_root_start(void); * \return 1 if we are dag root, 0 otherwise */ int rpl_dag_root_is_root(void); +/** + * Prints a summary of all routing links + * + * \param str A descriptive text on the caller +*/ +void rpl_dag_root_print_links(const char *str); /** @} */ diff --git a/os/net/routing/rpl-lite/rpl-timers.c b/os/net/routing/rpl-lite/rpl-timers.c index 6fb00ca17..c41b92948 100644 --- a/os/net/routing/rpl-lite/rpl-timers.c +++ b/os/net/routing/rpl-lite/rpl-timers.c @@ -521,6 +521,7 @@ handle_periodic_timer(void *ptr) if(LOG_INFO_ENABLED) { rpl_neighbor_print_list("Periodic"); + rpl_dag_root_print_links("Periodic"); } ctimer_reset(&periodic_timer); From 96c3bff6a9086b071298994302513dc7a5a793ea Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 18 May 2018 05:52:55 -0700 Subject: [PATCH 03/55] Shell rpl-routes command: use uip_sr_link_snprint --- os/services/shell/shell-commands.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/os/services/shell/shell-commands.c b/os/services/shell/shell-commands.c index fedbc06c6..f2f036eda 100644 --- a/os/services/shell/shell-commands.c +++ b/os/services/shell/shell-commands.c @@ -615,24 +615,9 @@ PT_THREAD(cmd_routes(struct pt *pt, shell_output_func output, char *args)) SHELL_OUTPUT(output, "Routing links (%u in total):\n", uip_sr_num_nodes()); link = uip_sr_node_head(); while(link != NULL) { - uip_ipaddr_t child_ipaddr; - uip_ipaddr_t parent_ipaddr; - NETSTACK_ROUTING.get_sr_node_ipaddr(&child_ipaddr, link); - NETSTACK_ROUTING.get_sr_node_ipaddr(&parent_ipaddr, link->parent); - SHELL_OUTPUT(output, "-- "); - shell_output_6addr(output, &child_ipaddr); - if(link->parent == NULL) { - memset(&parent_ipaddr, 0, sizeof(parent_ipaddr)); - SHELL_OUTPUT(output, " (DODAG root)"); - } else { - SHELL_OUTPUT(output, " to "); - shell_output_6addr(output, &parent_ipaddr); - } - if(link->lifetime != UIP_SR_INFINITE_LIFETIME) { - SHELL_OUTPUT(output, " (lifetime: %lu seconds)\n", (unsigned long)link->lifetime); - } else { - SHELL_OUTPUT(output, " (lifetime: infinite)\n"); - } + char buf[100]; + uip_sr_link_snprint(buf, sizeof(buf), link); + SHELL_OUTPUT(output, "-- %s\n", buf); link = uip_sr_node_next(link); } } else { From d1940450873ea44232c00bb53cd5120171c9c17d Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 18 May 2018 05:53:22 -0700 Subject: [PATCH 04/55] rpl_neighbor_snprint: do not add prefix --- os/net/routing/rpl-lite/rpl-neighbor.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/os/net/routing/rpl-lite/rpl-neighbor.c b/os/net/routing/rpl-lite/rpl-neighbor.c index b33e4dad7..5f2f7f69a 100644 --- a/os/net/routing/rpl-lite/rpl-neighbor.c +++ b/os/net/routing/rpl-lite/rpl-neighbor.c @@ -94,10 +94,6 @@ rpl_neighbor_snprint(char *buf, int buflen, rpl_nbr_t *nbr) const struct link_stats *stats = rpl_neighbor_get_link_stats(nbr); clock_time_t clock_now = clock_time(); - index += snprintf(buf+index, buflen-index, "nbr: "); - if(index >= buflen) { - return index; - } index += uiplib_ipaddr_snprint(buf+index, buflen-index, rpl_neighbor_get_ipaddr(nbr)); if(index >= buflen) { return index; @@ -157,7 +153,7 @@ rpl_neighbor_print_list(const char *str) while(nbr != NULL) { char buf[120]; rpl_neighbor_snprint(buf, sizeof(buf), nbr); - LOG_INFO("%s\n", buf); + LOG_INFO("nbr: %s\n", buf); nbr = nbr_table_next(rpl_neighbors, nbr); } LOG_INFO("nbr: end of list\n"); From d744e8306af916b22d389f82a9f972df77e2f56b Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Tue, 13 Mar 2018 09:34:11 +0100 Subject: [PATCH 05/55] Added Queue Mode implementation in LwM2M --- examples/ipso-objects/zoul/module-macros.h | 34 +++ examples/lwm2m-ipso-objects/Makefile | 3 + examples/lwm2m-ipso-objects/project-conf.h | 10 +- os/net/app-layer/coap/coap-observe.c | 14 + os/net/app-layer/coap/coap-observe.h | 2 + os/services/lwm2m/lwm2m-engine.c | 146 ++++++++- os/services/lwm2m/lwm2m-engine.h | 10 + os/services/lwm2m/lwm2m-notification-queue.c | 239 +++++++++++++++ os/services/lwm2m/lwm2m-notification-queue.h | 67 +++++ os/services/lwm2m/lwm2m-qmode-conf.h | 85 ++++++ os/services/lwm2m/lwm2m-qmode-object.c | 301 +++++++++++++++++++ os/services/lwm2m/lwm2m-qmode-object.h | 65 ++++ os/services/lwm2m/lwm2m-rd-client.c | 131 +++++++- os/services/lwm2m/lwm2m-rd-client.h | 9 + tests/01-compile-base/Makefile | 2 + tests/02-compile-arm-ports-01/Makefile | 2 + tests/03-compile-arm-ports-02/Makefile | 2 + 17 files changed, 1115 insertions(+), 7 deletions(-) create mode 100644 examples/ipso-objects/zoul/module-macros.h create mode 100644 os/services/lwm2m/lwm2m-notification-queue.c create mode 100644 os/services/lwm2m/lwm2m-notification-queue.h create mode 100644 os/services/lwm2m/lwm2m-qmode-conf.h create mode 100644 os/services/lwm2m/lwm2m-qmode-object.c create mode 100644 os/services/lwm2m/lwm2m-qmode-object.h diff --git a/examples/ipso-objects/zoul/module-macros.h b/examples/ipso-objects/zoul/module-macros.h new file mode 100644 index 000000000..5091ff08b --- /dev/null +++ b/examples/ipso-objects/zoul/module-macros.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018, 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. + */ + +/*---------------------------------------------------------------------------*/ +/* Only sleep mode 1 on Zoul to enable full 32 KiB RAM */ +#define LPM_CONF_MAX_PM 1 +/*---------------------------------------------------------------------------*/ diff --git a/examples/lwm2m-ipso-objects/Makefile b/examples/lwm2m-ipso-objects/Makefile index 7fa79d1ee..c2cef2cfd 100644 --- a/examples/lwm2m-ipso-objects/Makefile +++ b/examples/lwm2m-ipso-objects/Makefile @@ -11,4 +11,7 @@ MODULES += os/services/lwm2m MODULES += os/services/ipso-objects CONTIKI=../.. +include $(CONTIKI)/Makefile.identify-target +MODULES_REL += $(TARGET) + include $(CONTIKI)/Makefile.include diff --git a/examples/lwm2m-ipso-objects/project-conf.h b/examples/lwm2m-ipso-objects/project-conf.h index a7ad8b3ea..affe626b0 100644 --- a/examples/lwm2m-ipso-objects/project-conf.h +++ b/examples/lwm2m-ipso-objects/project-conf.h @@ -30,9 +30,6 @@ #ifndef PROJECT_CONF_H_ #define PROJECT_CONF_H_ -/* No sleep on CC2538 to enable full 32 KiB RAM */ -#define LPM_CONF_ENABLE 0 - #ifdef BOARD_STRING #define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING #elif defined(CONTIKI_TARGET_WISMOTE) @@ -62,4 +59,11 @@ /* Enable client-side support for COAP observe */ #define COAP_OBSERVE_CLIENT 1 +/* Definitions to enable Queue Mode, include the dynamic adaptation and change the default parameters */ +/* #define LWM2M_Q_MODE_CONF_ENABLED 1 + #define LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION 1 + #define LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME 2000 + #define LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME 10000 + #define LWM2M_Q_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG 1 */ + #endif /* PROJECT_CONF_H_ */ diff --git a/os/net/app-layer/coap/coap-observe.c b/os/net/app-layer/coap/coap-observe.c index 83f5edf4a..d6ef3887e 100644 --- a/os/net/app-layer/coap/coap-observe.c +++ b/os/net/app-layer/coap/coap-observe.c @@ -353,4 +353,18 @@ coap_observe_handler(coap_resource_t *resource, coap_message_t *coap_req, } } /*---------------------------------------------------------------------------*/ +uint8_t +coap_has_observers(char *path) +{ + coap_observer_t *obs = NULL; + + for(obs = (coap_observer_t *)list_head(observers_list); obs; + obs = obs->next) { + if((strncmp(obs->url, path, strlen(path))) == 0) { + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/net/app-layer/coap/coap-observe.h b/os/net/app-layer/coap/coap-observe.h index c276522c5..93898f954 100644 --- a/os/net/app-layer/coap/coap-observe.h +++ b/os/net/app-layer/coap/coap-observe.h @@ -80,5 +80,7 @@ void coap_notify_observers_sub(coap_resource_t *resource, const char *subpath); void coap_observe_handler(coap_resource_t *resource, coap_message_t *request, coap_message_t *response); +uint8_t coap_has_observers(char *path); + #endif /* COAP_OBSERVE_H_ */ /** @} */ diff --git a/os/services/lwm2m/lwm2m-engine.c b/os/services/lwm2m/lwm2m-engine.c index 6f2aeefd8..3c038deec 100644 --- a/os/services/lwm2m/lwm2m-engine.c +++ b/os/services/lwm2m/lwm2m-engine.c @@ -39,6 +39,7 @@ * \author * Joakim Eriksson * Niclas Finne + * Carlos Gonzalo Peces */ #include "lwm2m-engine.h" @@ -56,7 +57,6 @@ #include #include #include - #ifndef LWM2M_ENGINE_CLIENT_ENDPOINT_NAME #include "net/ipv6/uip-ds6.h" #endif /* LWM2M_ENGINE_CLIENT_ENDPOINT_NAME */ @@ -80,10 +80,24 @@ #define USE_RD_CLIENT 1 #endif /* LWM2M_ENGINE_CONF_USE_RD_CLIENT */ + +#if LWM2M_Q_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 */ +#define FIRST_REQUEST_MASK 0x01 +#define HANDLER_FROM_NOTIFICATION_MASK 0x02 +#endif + #if USE_RD_CLIENT #include "lwm2m-rd-client.h" #endif +#if LWM2M_Q_MODE_ENABLED +#include "lwm2m-qmode-object.h" +#include "lwm2m-notification-queue.h" +#endif + /* MACRO for getting out resource ID from resource array ID + flags */ #define RSC_ID(x) ((uint16_t)(x & 0xffff)) #define RSC_READABLE(x) ((x & LWM2M_RESOURCE_READ) > 0) @@ -129,6 +143,18 @@ static struct { /* in the future also a timeout */ } created; +#if LWM2M_Q_MODE_ENABLED +static uint8_t waked_up_by_notification; +/* For the dynamic adaptation of the awake time */ +#if LWM2M_Q_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 */ COAP_HANDLER(lwm2m_handler, lwm2m_handler_callback); LIST(object_list); @@ -554,6 +580,10 @@ lwm2m_engine_init(void) #if USE_RD_CLIENT lwm2m_rd_client_init(endpoint); #endif + +#if LWM2M_Q_MODE_ENABLED + lwm2m_q_object_init(); +#endif } /*---------------------------------------------------------------------------*/ /* @@ -1373,6 +1403,31 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response, context.inbuf->size = coap_get_payload(request, (const uint8_t **)&context.inbuf->buffer); context.inbuf->pos = 0; + /*If Queue Mode, restart the client awake timer */ +#if LWM2M_Q_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(is_first_request()) { + previous_request_time = coap_timer_uptime(); + clear_first_request(); + }else{ + if(coap_timer_uptime()-previous_request_time >= 0) { + lwm2m_q_object_add_time_object(coap_timer_uptime()-previous_request_time); + + } + previous_request_time = coap_timer_uptime(); + } + } + if(get_handler_from_notification()) { + clear_handler_from_notification(); + } +#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +#endif /* LWM2M_Q_MODE_ENABLED */ + /* Maybe this should be part of CoAP itself - this seems not to be working with the leshan server */ #define LWM2M_CONF_ENTITY_TOO_LARGE_BLOCK1 0 @@ -1632,14 +1687,99 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response, return COAP_HANDLER_STATUS_PROCESSED; } /*---------------------------------------------------------------------------*/ -void lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, +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()){ + lwm2m_engine_set_handler_from_notification(); + } +#endif + coap_notify_observers_sub(NULL, path); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, uint16_t resource) { char path[20]; /* 60000/60000/60000 */ if(obj != NULL) { snprintf(path, 20, "%d/%d/%d", obj->object_id, obj->instance_id, resource); - coap_notify_observers_sub(NULL, path); } + +#if LWM2M_Q_MODE_ENABLED + + if(coap_has_observers(path)) { + /* Client is sleeping -> add the notification to the list */ + if(!lwm2m_rd_client_is_client_awake()) { + lwm2m_notification_queue_add_notification_path(path); + + /* 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(); + } + /* Client is awake -> send the notification */ + } else { + lwm2m_send_notification(path); + } + } +#else + lwm2m_send_notification(path); +#endif } /*---------------------------------------------------------------------------*/ +/* Queue Mode Support and dynamic adaptation of the client awake time */ +#if LWM2M_Q_MODE_ENABLED +uint8_t +lwm2m_engine_is_waked_up_by_notification() +{ + return waked_up_by_notification; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_clear_waked_up_by_notification() +{ + waked_up_by_notification = 0; +} +/*---------------------------------------------------------------------------*/ +#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION +void +lwm2m_engine_set_first_request() +{ + dynamic_adaptation_params |= FIRST_REQUEST_MASK; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_set_handler_from_notification() +{ + dynamic_adaptation_params |= HANDLER_FROM_NOTIFICATION_MASK; +} +/*---------------------------------------------------------------------------*/ +static inline uint8_t +is_first_request() +{ + return dynamic_adaptation_params & FIRST_REQUEST_MASK; +} +/*---------------------------------------------------------------------------*/ +static inline uint8_t +get_handler_from_notification() +{ + return (dynamic_adaptation_params & HANDLER_FROM_NOTIFICATION_MASK) != 0; +} +/*---------------------------------------------------------------------------*/ +static inline void +clear_first_request() +{ + dynamic_adaptation_params &= ~FIRST_REQUEST_MASK; +} +/*---------------------------------------------------------------------------*/ +static inline void +clear_handler_from_notification() +{ + dynamic_adaptation_params &= ~HANDLER_FROM_NOTIFICATION_MASK; +} +#endif /* LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +#endif /* LWM2M_Q_MODE_ENABLED */ +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/services/lwm2m/lwm2m-engine.h b/os/services/lwm2m/lwm2m-engine.h index 62a667e99..61d0353af 100644 --- a/os/services/lwm2m/lwm2m-engine.h +++ b/os/services/lwm2m/lwm2m-engine.h @@ -39,12 +39,14 @@ * \author * Joakim Eriksson * Niclas Finne + * Carlos Gonzalo Peces */ #ifndef LWM2M_ENGINE_H #define LWM2M_ENGINE_H #include "lwm2m-object.h" +#include "lwm2m-qmode-conf.h" #define LWM2M_FLOAT32_BITS 10 #define LWM2M_FLOAT32_FRAC (1L << LWM2M_FLOAT32_BITS) @@ -114,6 +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 +uint8_t lwm2m_engine_is_waked_up_by_notification(); +void lwm2m_engine_clear_waked_up_by_notification(); +#if LWM2M_Q_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_ENGINE_H */ /** @} */ diff --git a/os/services/lwm2m/lwm2m-notification-queue.c b/os/services/lwm2m/lwm2m-notification-queue.c new file mode 100644 index 000000000..c3150a879 --- /dev/null +++ b/os/services/lwm2m/lwm2m-notification-queue.c @@ -0,0 +1,239 @@ +/* + * 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 functions to manage the queue of notifications + * \author + * Carlos Gonzalo Peces + */ +/*---------------------------------------------------------------------------*/ +#include "lwm2m-notification-queue.h" + +#if LWM2M_Q_MODE_ENABLED + +#include "lwm2m-qmode-object.h" +#include "lwm2m-engine.h" +#include "coap-engine.h" +#include "lib/memb.h" +#include "lib/list.h" +#include +#include +#include +#include + +/* Log configuration */ +#include "coap-log.h" +#define LOG_MODULE "lwm2m-notification-queue" +#define LOG_LEVEL LOG_LEVEL_LWM2M + +#ifdef LWM2M_NOTIFICATION_QUEUE_CONF_LENGTH +#define LWM2M_NOTIFICATION_QUEUE_LENGTH LWM2M_NOTIFICATION_QUEUE_CONF_LENGTH +#else +#define LWM2M_NOTIFICATION_QUEUE_LENGTH 3 +#endif + +/*---------------------------------------------------------------------------*/ +/* Queue to store the notifications in the period when the client has woken up, sent the update and it's waiting for the server response*/ +MEMB(notification_memb, notification_path_t, LWM2M_NOTIFICATION_QUEUE_LENGTH + 1); /* Length + 1 to allocate the new path to add */ +LIST(notification_paths_queue); +/*---------------------------------------------------------------------------*/ +void +lwm2m_notification_queue_init(void) +{ + list_init(notification_paths_queue); +} +/*---------------------------------------------------------------------------*/ +static void +reduce_path(notification_path_t *path_object, char *path) +{ + char *cut = strtok(path, "/"); + int i; + for(i = 0; i < 3; i++) { + if(cut != NULL) { + path_object->reduced_path[i] = (uint16_t)atoi(cut); + cut = strtok(NULL, "/"); + } else { + break; + } + } + path_object->level = i; +} +/*---------------------------------------------------------------------------*/ +static void +extend_path(notification_path_t *path_object, char *path) +{ + switch(path_object->level) { + case 1: + snprintf(path, sizeof(path) - 1, "%u", path_object->reduced_path[0]); + break; + case 2: + snprintf(path, sizeof(path) - 1, "%u/%u", path_object->reduced_path[0], path_object->reduced_path[1]); + break; + case 3: + snprintf(path, sizeof(path) - 1, "%u/%u/%u", path_object->reduced_path[0], path_object->reduced_path[1], path_object->reduced_path[2]); + break; + } +} +/*---------------------------------------------------------------------------*/ +static void +add_notification_path_object_ordered(notification_path_t *path) +{ + notification_path_t *iteration_path = (notification_path_t *)list_head(notification_paths_queue); + if(list_length(notification_paths_queue) == 0) { + list_add(notification_paths_queue, path); + } else if(path->level < iteration_path->level) { + list_push(notification_paths_queue, path); + } else if(memcmp((path->reduced_path), (iteration_path->reduced_path), (path->level) * sizeof(uint16_t)) <= 0) { + list_push(notification_paths_queue, path); + } else { + notification_path_t *previous_path = iteration_path; + while(iteration_path != NULL) { + if(path->level < iteration_path->level) { + path->next = iteration_path; + previous_path->next = path; + return; + } + if(memcmp((path->reduced_path), (iteration_path->reduced_path), (path->level) * sizeof(uint16_t)) <= 0) { + path->next = iteration_path; + previous_path->next = path; + return; + } + previous_path = iteration_path; + iteration_path = iteration_path->next; + } + list_add(notification_paths_queue, path); + } +} +/*---------------------------------------------------------------------------*/ +static void +remove_notification_path(notification_path_t *path) +{ + list_remove(notification_paths_queue, path); + memb_free(¬ification_memb, path); +} +/*---------------------------------------------------------------------------*/ +static void +notification_queue_remove_policy(uint16_t *reduced_path, uint8_t level) +{ + uint8_t path_removed_flag = 0; + + notification_path_t *path_object = NULL; + notification_path_t *iteration_path = NULL; + notification_path_t *previous = NULL; + notification_path_t *next_next = NULL; + notification_path_t *path_to_remove = NULL; + + for(iteration_path = (notification_path_t *)list_head(notification_paths_queue); iteration_path != NULL; + iteration_path = iteration_path->next) { + /* 1. check if there is one event of the same path -> remove it and add the new one */ + if((level == iteration_path->level) && memcmp(iteration_path->reduced_path, reduced_path, level * sizeof(uint16_t)) == 0) { + remove_notification_path(iteration_path); + path_object = memb_alloc(¬ification_memb); + memcpy(path_object->reduced_path, reduced_path, level * sizeof(uint16_t)); + path_object->level = level; + add_notification_path_object_ordered(path_object); + return; + } + /* 2. If there is no event of the same type, look for repeated events of the same resource and remove the oldest one */ + if(iteration_path->next != NULL && (iteration_path->level == iteration_path->next->level) + && (memcmp(iteration_path->reduced_path, (iteration_path->next)->reduced_path, iteration_path->level * sizeof(uint16_t)) == 0)) { + path_removed_flag = 1; + next_next = iteration_path->next->next; + path_to_remove = iteration_path->next; + previous = iteration_path; + } + } + /* 3. If there are no events for the same path, we remove a the oldest repeated event of another resource */ + if(path_removed_flag) { + memb_free(¬ification_memb, path_to_remove); + previous->next = next_next; + path_object = memb_alloc(¬ification_memb); + memcpy(path_object->reduced_path, reduced_path, level * sizeof(uint16_t)); + path_object->level = level; + add_notification_path_object_ordered(path_object); + } else { + /* 4. If all the events are from different resources, remove the last one */ + list_chop(notification_paths_queue); + path_object = memb_alloc(¬ification_memb); + memcpy(path_object->reduced_path, reduced_path, level * sizeof(uint16_t)); + path_object->level = level; + add_notification_path_object_ordered(path_object); + } + return; +} +/*---------------------------------------------------------------------------*/ +/* For adding objects to the list in an ordered way, depending on the path*/ +void +lwm2m_notification_queue_add_notification_path(char *path) +{ + notification_path_t *path_object = memb_alloc(¬ification_memb); + if(path_object == NULL) { + LOG_DBG("Could not allocate new notification in the queue\n"); + return; + } + reduce_path(path_object, path); + if(list_length(notification_paths_queue) >= LWM2M_NOTIFICATION_QUEUE_LENGTH) { + /* The queue is full, apply policy to remove */ + notification_queue_remove_policy(path_object->reduced_path, path_object->level); + } else { + add_notification_path_object_ordered(path_object); + } + LOG_DBG("Notification path added to the list: %s\n", path); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_notification_queue_send_notifications() +{ + char path[20]; + notification_path_t *iteration_path = (notification_path_t *)list_head(notification_paths_queue); + notification_path_t *aux = iteration_path; + + while(iteration_path != NULL) { + extend_path(iteration_path, path); +#if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION + if(lwm2m_q_object_get_dynamic_adaptation_flag()) { + lwm2m_engine_set_handler_from_notification(); + } +#endif + LOG_DBG("Sending stored notification with path: %s\n", path); + coap_notify_observers_sub(NULL, path); + aux = iteration_path; + iteration_path = iteration_path->next; + remove_notification_path(aux); + } +} +#endif /* LWM2M_Q_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 new file mode 100644 index 000000000..3364d3a77 --- /dev/null +++ b/os/services/lwm2m/lwm2m-notification-queue.h @@ -0,0 +1,67 @@ +/* + * 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 + * Header file for functions to manage the queue of notifications + * \author + * Carlos Gonzalo Peces + */ + +#ifndef LWM2M_NOTIFICATION_QUEUE_H +#define LWM2M_NOTIFICATION_QUEUE_H + +#include "contiki.h" +#include "lwm2m-qmode-conf.h" + +#if LWM2M_Q_MODE_ENABLED +#include + +typedef struct notification_path { + struct notification_path *next; + uint16_t reduced_path[3]; + uint8_t level; /* The depth level of the path: 1. object, 2. object/instance, 3. object/instance/resource */ +} notification_path_t; + +void lwm2m_notification_queue_init(void); + +/* For adding objects to the list in an ordered way, depending on the path*/ +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-conf.h b/os/services/lwm2m/lwm2m-qmode-conf.h new file mode 100644 index 000000000..1220d0584 --- /dev/null +++ b/os/services/lwm2m/lwm2m-qmode-conf.h @@ -0,0 +1,85 @@ +/* + * 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 + * Queue Mode Configuration Parameters + * \author + * Carlos Gonzalo Peces + */ + +#ifndef LWM2M_QMODE_CONF_H +#define LWM2M_QMODE_CONF_H + +/* Enable the Queue Mode */ +#ifdef LWM2M_Q_MODE_CONF_ENABLED +#define LWM2M_Q_MODE_ENABLED LWM2M_Q_MODE_CONF_ENABLED +#else +#define LWM2M_Q_MODE_ENABLED 0 +#endif /* LWM2M_Q_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 +#else +#define LWM2M_Q_MODE_DEFAULT_CLIENT_SLEEP_TIME 10000 /* msec */ +#endif /* LWM2M_Q_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 +#else +#define LWM2M_Q_MODE_DEFAULT_CLIENT_AWAKE_TIME 5000 /* msec */ +#endif /* LWM2M_Q_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 +#else +#define LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION 0 /* not included */ +#endif /* LWM2M_Q_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 +#else +#define LWM2M_Q_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG 0 /* disabled */ +#endif /* LWM2M_Q_MODE_DEFAULT_DYNAMIC_ADAPTATION_FLAG */ + +/* Length of the list of times for the dynamic adaptation */ +#define LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH 10 + +#endif /* LWM2M_QMODE_CONF_H */ +/** @} */ diff --git a/os/services/lwm2m/lwm2m-qmode-object.c b/os/services/lwm2m/lwm2m-qmode-object.c new file mode 100644 index 000000000..77a12e460 --- /dev/null +++ b/os/services/lwm2m/lwm2m-qmode-object.c @@ -0,0 +1,301 @@ +/* + * 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; + +typedef struct time_object { + struct times_object *next; + uint64_t time; +} time_object_t; + +/* Window to save the times and do the dynamic adaptation of the awake time*/ +MEMB(times_memb, time_object_t, LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH); +LIST(time_object_list); + +#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 uint64_t +get_maximum_time() +{ + uint64_t max_time = 0; + time_object_t *iteration_time = NULL; + for(iteration_time = (time_object_t *)list_head(time_object_list); iteration_time; + iteration_time = (time_object_t *)iteration_time->next) { + + if(iteration_time->time > max_time) { + max_time = iteration_time->time; + } + } + return max_time; +} +#endif +/*---------------------------------------------------------------------------*/ +#if UPDATE_WITH_MEAN +static uint64_t +get_mean_time() +{ + uint64_t mean_time = 0; + time_object_t *iteration_time = NULL; + for(iteration_time = (time_object_t *)list_head(time_object_list); iteration_time; + (time_object_t *)iteration_time = iteration_time->next) { + + if(mean_time == 0) { + mean_time = iteration_time->time; + } else { + mean_time = (mean_time + iteration_time->time) / 2; + } + } + return mean_time; +} +#endif +/*---------------------------------------------------------------------------*/ +static void +update_awake_time() +{ +#if UPDATE_WITH_MEAN + uint64_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 + uint64_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 +} +/*---------------------------------------------------------------------------*/ +static void +remove_time_object(time_object_t *time_object) +{ + memb_free(×_memb, time_object); + list_remove(time_object_list, time_object); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_q_object_add_time_object(uint64_t time) +{ + time_object_t *time_object; + time_object = memb_alloc(×_memb); + if(time_object != NULL) { + time_object->time = time; + list_add(time_object_list, time_object); + } else { + remove_time_object((time_object_t *)list_head(time_object_list)); + time_object = memb_alloc(×_memb); + time_object->time = time; + list_add(time_object_list, time_object); + } + 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-object.h b/os/services/lwm2m/lwm2m-qmode-object.h new file mode 100644 index 000000000..68427a59c --- /dev/null +++ b/os/services/lwm2m/lwm2m-qmode-object.h @@ -0,0 +1,65 @@ +/* + * 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 Object for managing the queue mode + * \author + * Carlos Gonzalo Peces + */ + +#ifndef LWM2M_Q_OBJECT_H_ +#define LWM2M_Q_OBJECT_H_ + +#include "contiki.h" +#include "lwm2m-qmode-conf.h" + +#if LWM2M_Q_MODE_ENABLED +#include + +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_object(uint64_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_ */ +/** @} */ diff --git a/os/services/lwm2m/lwm2m-rd-client.c b/os/services/lwm2m/lwm2m-rd-client.c index 03d21e33e..61273797a 100644 --- a/os/services/lwm2m/lwm2m-rd-client.c +++ b/os/services/lwm2m/lwm2m-rd-client.c @@ -41,6 +41,7 @@ * Joakim Eriksson * Niclas Finne * Joel Hoglund + * Carlos Gonzalo Peces */ #include "lwm2m-engine.h" @@ -57,6 +58,10 @@ #include #include #include +#if LWM2M_Q_MODE_ENABLED +#include "lwm2m-qmode-object.h" +#include "lwm2m-notification-queue.h" +#endif #if UIP_CONF_IPV6_RPL #include "rpl.h" @@ -100,6 +105,10 @@ 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 +#endif #define FLAG_RD_DATA_DIRTY 0x01 #define FLAG_RD_DATA_UPDATE_TRIGGERED 0x02 @@ -121,6 +130,13 @@ 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 awake time */ +static uint8_t q_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 void q_mode_awake_timer_callback(coap_timer_t *timer); /* Callback for the client awake timer */ +#endif + static void check_periodic_observations(); static void update_callback(coap_request_state_t *state); @@ -147,7 +163,8 @@ set_rd_data(coap_message_t *request) } /*---------------------------------------------------------------------------*/ static void -prepare_update(coap_message_t *request, int triggered) { +prepare_update(coap_message_t *request, int triggered) +{ coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); coap_set_header_uri_path(request, session_info.assigned_ep); @@ -423,7 +440,16 @@ 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()) { + lwm2m_engine_set_first_request(); + } +#endif + lwm2m_rd_client_fsm_execute_q_mode_awake(); /* Avoid 500 ms delay and move directly to the state*/ +#else rd_state = REGISTRATION_DONE; +#endif /* remember the last reg time */ last_update = coap_timer_uptime(); LOG_DBG_("Done (assigned EP='%s')!\n", session_info.assigned_ep); @@ -468,8 +494,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 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()) { + 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*/ +#else rd_state = REGISTRATION_DONE; rd_flags &= ~FLAG_RD_DATA_UPDATE_TRIGGERED; +#endif /* LWM2M_Q_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", @@ -516,7 +557,15 @@ periodic_process(coap_timer_t *timer) uint64_t now; /* reschedule the CoAP timer */ +#if LWM2M_Q_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); + } +#else coap_timer_reset(&rd_timer, STATE_MACHINE_UPDATE_INTERVAL); +#endif + now = coap_timer_uptime(); LOG_DBG("RD Client - state: %d, ms: %lu\n", rd_state, @@ -685,6 +734,24 @@ periodic_process(coap_timer_t *timer) rd_state = UPDATE_SENT; } break; +#if LWM2M_Q_MODE_ENABLED + case Q_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); + break; + case Q_MODE_SEND_UPDATE: +#if !STANDALONE + NETSTACK_MAC.on(); +#endif + 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 case UPDATE_SENT: /* just wait until the callback kicks us to the next state... */ @@ -718,15 +785,26 @@ lwm2m_rd_client_init(const char *ep) { session_info.ep = ep; /* default binding U = UDP, UQ = UDP Q-mode*/ +#if LWM2M_Q_MODE_ENABLED + session_info.binding = "UQ"; + session_info.lifetime = (LWM2M_Q_MODE_DEFAULT_CLIENT_SLEEP_TIME / 1000) * 2; /* Enough margin to ensure that the client is not unregistered (we + * do not know the time it can stay awake) + */ +#else session_info.binding = "U"; if(session_info.lifetime == 0) { session_info.lifetime = LWM2M_DEFAULT_CLIENT_LIFETIME; } +#endif + rd_state = INIT; /* 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); +#endif } /*---------------------------------------------------------------------------*/ static void @@ -735,4 +813,55 @@ check_periodic_observations(void) /* TODO */ } /*---------------------------------------------------------------------------*/ +/* + *Queue Mode Support + */ +#if LWM2M_Q_MODE_ENABLED +/*---------------------------------------------------------------------------*/ +void +lwm2m_rd_client_restart_client_awake_timer(void) +{ + coap_timer_set(&q_mode_client_awake_timer, q_mode_client_awake_time); +} +/*---------------------------------------------------------------------------*/ +uint8_t +lwm2m_rd_client_is_client_awake(void) +{ + return q_mode_client_awake; +} +/*---------------------------------------------------------------------------*/ +static void +q_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; +#if !STANDALONE + /* Turn off the radio and start sleeping timer. LPM will be entered since the radio + and the peripherals are off, and there is a sleep timer started for waking up */ + NETSTACK_MAC.off(); + rtimer_arch_schedule(RTIMER_NOW() + ((lwm2m_q_object_get_sleep_time() / 1000) * RTIMER_SECOND)); +#endif + rd_state = Q_MODE_SEND_UPDATE; + coap_timer_set(&rd_timer, lwm2m_q_object_get_sleep_time()); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_rd_client_fsm_execute_q_mode_awake() +{ + coap_timer_stop(&rd_timer); + rd_state = Q_MODE_AWAKE; + periodic_process(&rd_timer); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_rd_client_fsm_execute_q_mode_update() +{ + coap_timer_stop(&rd_timer); + rd_state = Q_MODE_SEND_UPDATE; + periodic_process(&rd_timer); +} +/*---------------------------------------------------------------------------*/ +#endif +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/services/lwm2m/lwm2m-rd-client.h b/os/services/lwm2m/lwm2m-rd-client.h index 7fba7e0ae..85946235d 100644 --- a/os/services/lwm2m/lwm2m-rd-client.h +++ b/os/services/lwm2m/lwm2m-rd-client.h @@ -40,6 +40,7 @@ * \author * Joakim Eriksson * Niclas Finne + * Carlos Gonzalo Peces */ #ifndef LWM2M_RD_CLIENT_H_ @@ -52,6 +53,7 @@ #define LWM2M_RD_CLIENT_DISCONNECTED 5 #include "lwm2m-object.h" +#include "lwm2m-qmode-conf.h" struct lwm2m_session_info; typedef void (*session_callback_t)(struct lwm2m_session_info *session, int status); @@ -75,6 +77,13 @@ void lwm2m_rd_client_init(const char *ep); void lwm2m_rd_client_set_session_callback(session_callback_t cb); +#if LWM2M_Q_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(); +#endif + #ifndef LWM2M_RD_CLIENT_ASSIGNED_ENDPOINT_MAX_LEN #define LWM2M_RD_CLIENT_ASSIGNED_ENDPOINT_MAX_LEN 15 #endif /* LWM2M_RD_CLIENT_ASSIGNED_ENDPOINT_MAX_LEN */ diff --git a/tests/01-compile-base/Makefile b/tests/01-compile-base/Makefile index eae930138..d9ef0ba58 100644 --- a/tests/01-compile-base/Makefile +++ b/tests/01-compile-base/Makefile @@ -15,6 +15,8 @@ libs/data-structures/sky \ libs/stack-check/sky \ lwm2m-ipso-objects/native \ lwm2m-ipso-objects/native:MAKE_WITH_DTLS=1 \ +lwm2m-ipso-objects/native:DEFINES=LWM2M_Q_MODE_CONF_ENABLED=1 \ +lwm2m-ipso-objects/native:DEFINES=LWM2M_Q_MODE_CONF_ENABLED=1,LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION=1\ rpl-udp/sky \ rpl-border-router/native \ rpl-border-router/native:MAKE_ROUTING=MAKE_ROUTING_RPL_CLASSIC \ diff --git a/tests/02-compile-arm-ports-01/Makefile b/tests/02-compile-arm-ports-01/Makefile index 5e73c4ecb..4bb1e9269 100644 --- a/tests/02-compile-arm-ports-01/Makefile +++ b/tests/02-compile-arm-ports-01/Makefile @@ -43,6 +43,8 @@ coap/coap-example-client/cc2538dk \ coap/coap-example-server/cc2538dk \ slip-radio/cc2538dk \ lwm2m-ipso-objects/cc2538dk \ +lwm2m-ipso-objects/cc2538dk:DEFINES=LWM2M_Q_MODE_CONF_ENABLED=1 \ +lwm2m-ipso-objects/native:DEFINES=LWM2M_Q_MODE_CONF_ENABLED=1,LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION=1\ multicast/cc2538dk \ dev/gpio-hal/cc2538dk \ dev/leds/cc2538dk \ diff --git a/tests/03-compile-arm-ports-02/Makefile b/tests/03-compile-arm-ports-02/Makefile index defd10a96..62120eba3 100644 --- a/tests/03-compile-arm-ports-02/Makefile +++ b/tests/03-compile-arm-ports-02/Makefile @@ -17,6 +17,8 @@ coap/coap-example-server/zoul \ multicast/zoul \ lwm2m-ipso-objects/zoul \ lwm2m-ipso-objects/zoul:MAKE_WITH_DTLS=1 \ +lwm2m-ipso-objects/zoul:DEFINES=LWM2M_Q_MODE_CONF_ENABLED=1 \ +lwm2m-ipso-objects/zoul:DEFINES=LWM2M_Q_MODE_CONF_ENABLED=1,LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION=1\ hello-world/zoul \ sensniff/zoul \ sensniff/zoul:ZOUL_CONF_SUB_GHZ_SNIFFER=1 \ From 1f8754766a751c3f9c548340ca361577acd43269 Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Fri, 6 Apr 2018 15:16:42 +0200 Subject: [PATCH 06/55] Added macros for defining wake up/sleep behaviour depending on the platform --- examples/ipso-objects/zoul/module-macros.h | 16 ++++++- os/services/lwm2m/lwm2m-rd-client.c | 52 +++++++++++++--------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/examples/ipso-objects/zoul/module-macros.h b/examples/ipso-objects/zoul/module-macros.h index 5091ff08b..4db4e82fe 100644 --- a/examples/ipso-objects/zoul/module-macros.h +++ b/examples/ipso-objects/zoul/module-macros.h @@ -27,8 +27,22 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ - /*---------------------------------------------------------------------------*/ /* Only sleep mode 1 on Zoul to enable full 32 KiB RAM */ #define LPM_CONF_MAX_PM 1 /*---------------------------------------------------------------------------*/ +/* Macros to enter sleep mode and wake up in the Zoul module. Sleep consists + * on turn off the radio and start a RTIMER to wake up, and wake up consists on + * turn on the radio again + */ +#define LWM2M_Q_MODE_WAKE_UP() do { \ + NETSTACK_MAC.on(); \ +} while(0) + +#define LWM2M_Q_MODE_SLEEP_MS(TIME_MS) do { \ + uint64_t aux = TIME_MS * RTIMER_SECOND; \ + NETSTACK_MAC.off(); \ + rtimer_arch_schedule(RTIMER_NOW() + (rtimer_clock_t)(aux / 1000)); \ +} while(0) + + diff --git a/os/services/lwm2m/lwm2m-rd-client.c b/os/services/lwm2m/lwm2m-rd-client.c index 61273797a..cf7c5deb3 100644 --- a/os/services/lwm2m/lwm2m-rd-client.c +++ b/os/services/lwm2m/lwm2m-rd-client.c @@ -43,7 +43,6 @@ * Joel Hoglund * Carlos Gonzalo Peces */ - #include "lwm2m-engine.h" #include "lwm2m-object.h" #include "lwm2m-device.h" @@ -58,15 +57,16 @@ #include #include #include -#if LWM2M_Q_MODE_ENABLED -#include "lwm2m-qmode-object.h" -#include "lwm2m-notification-queue.h" -#endif #if UIP_CONF_IPV6_RPL #include "rpl.h" #endif /* UIP_CONF_IPV6_RPL */ +#if LWM2M_Q_MODE_ENABLED +#include "lwm2m-qmode-object.h" +#include "lwm2m-notification-queue.h" +#endif /* LWM2M_Q_MODE_ENABLED */ + /* Log configuration */ #include "coap-log.h" #define LOG_MODULE "lwm2m-rd" @@ -131,10 +131,15 @@ 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 awake time */ -static uint8_t q_mode_client_awake; /* 1 - client is awake, 0 - client is sleeping */ +static coap_timer_t q_mode_client_awake_timer; /* Timer to control the client's + * awake time + */ +static uint8_t q_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 void q_mode_awake_timer_callback(coap_timer_t *timer); /* Callback for the client awake timer */ +/* Callback for the client awake timer */ +static void q_mode_awake_timer_callback(coap_timer_t *timer); #endif static void check_periodic_observations(); @@ -742,16 +747,19 @@ periodic_process(coap_timer_t *timer) coap_timer_set(&q_mode_client_awake_timer, q_mode_client_awake_time); break; case Q_MODE_SEND_UPDATE: -#if !STANDALONE - NETSTACK_MAC.on(); -#endif +/* 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 */ 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 +#endif /* LWM2M_Q_MODE_ENABLED */ case UPDATE_SENT: /* just wait until the callback kicks us to the next state... */ @@ -787,9 +795,10 @@ lwm2m_rd_client_init(const char *ep) /* default binding U = UDP, UQ = UDP Q-mode*/ #if LWM2M_Q_MODE_ENABLED session_info.binding = "UQ"; - session_info.lifetime = (LWM2M_Q_MODE_DEFAULT_CLIENT_SLEEP_TIME / 1000) * 2; /* Enough margin to ensure that the client is not unregistered (we - * do not know the time it can stay awake) - */ + /* 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; #else session_info.binding = "U"; if(session_info.lifetime == 0) { @@ -836,12 +845,11 @@ q_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; -#if !STANDALONE - /* Turn off the radio and start sleeping timer. LPM will be entered since the radio - and the peripherals are off, and there is a sleep timer started for waking up */ - NETSTACK_MAC.off(); - rtimer_arch_schedule(RTIMER_NOW() + ((lwm2m_q_object_get_sleep_time() / 1000) * RTIMER_SECOND)); -#endif + +/* 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()); } @@ -862,6 +870,6 @@ lwm2m_rd_client_fsm_execute_q_mode_update() periodic_process(&rd_timer); } /*---------------------------------------------------------------------------*/ -#endif +#endif /* LWM2M_Q_MODE_ENABLED */ /*---------------------------------------------------------------------------*/ /** @} */ From 1dfa62fc88d58ef136b897e6bfe56cdf54cbf093 Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Mon, 9 Apr 2018 14:16:26 +0200 Subject: [PATCH 07/55] Added Q-Mode regression tests working with Leshan Server --- .../zoul/module-macros.h | 0 .../18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh | 69 +++++++++++++++++++ .../09-lwm2m-qmode-standalone-test.sh | 68 ++++++++++++++++++ .../18-coap-lwm2m/pytests/test-qmode-awake.py | 20 ++++++ .../18-coap-lwm2m/pytests/test-qmode-sleep.py | 19 +++++ 5 files changed, 176 insertions(+) rename examples/{ipso-objects => lwm2m-ipso-objects}/zoul/module-macros.h (100%) create mode 100755 tests/18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh create mode 100755 tests/18-coap-lwm2m/09-lwm2m-qmode-standalone-test.sh create mode 100644 tests/18-coap-lwm2m/pytests/test-qmode-awake.py create mode 100644 tests/18-coap-lwm2m/pytests/test-qmode-sleep.py diff --git a/examples/ipso-objects/zoul/module-macros.h b/examples/lwm2m-ipso-objects/zoul/module-macros.h similarity index 100% rename from examples/ipso-objects/zoul/module-macros.h rename to examples/lwm2m-ipso-objects/zoul/module-macros.h diff --git a/tests/18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh b/tests/18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh new file mode 100755 index 000000000..142fb253d --- /dev/null +++ b/tests/18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# Contiki directory +CONTIKI=$1 +# Test basename +BASENAME=08-lwm2m-qmode-ipso-test + +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 +sudo $CONTIKI/examples/lwm2m-ipso-objects/example-ipso-objects.native > node.log 2> node.err & +CPID=$! +sleep 10 + +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 +echo "Starting leshan server with Q-Mode enabled" +java -jar leshan-server-demo-qmode-support1.0.0-SNAPSHOT-jar-with-dependencies.jar >leshan.log 2>leshan.err & +LESHID=$! + +COUNTER=10 +while [ $COUNTER -gt 0 ]; do + sleep 5 + aux=$(grep -c 'OK' leshan.err) + if [ $aux -eq 2 ] ; then + break + fi + let COUNTER-=1 +done + +echo "Closing native node" +sleep 1 +pgrep ipso | sudo xargs kill -9 + +echo "Closing leshan" +sleep 1 +pgrep java | sudo xargs kill -9 + +#Two OKs needed: awake and sleeping +aux=$(grep -c 'OK' leshan.err) +if [ $aux -eq 2 ] +then + cp leshan.err $BASENAME.testlog; + printf "%-32s TEST OK\n" "$BASENAME" | tee $BASENAME.testlog; +else + echo "==== make.log ====" ; cat make.log; + echo "==== make.err ====" ; cat make.err; + echo "==== node.log ====" ; cat node.log; + echo "==== node.err ====" ; cat node.err; + echo "==== leshan.log ====" ; cat leshan.log; + echo "==== leshan.err ====" ; cat leshan.err; + echo "==== $BASENAME.log ====" ; cat $BASENAME.log; + + printf "%-32s TEST FAIL\n" "$BASENAME" | tee $BASENAME.testlog; +fi + +rm make.log +rm make.err +rm node.log +rm node.err +rm leshan.log +rm leshan.err + +# We do not want Make to stop -> Return 0 +# The Makefile will check if a log contains FAIL at the end +exit 0 diff --git a/tests/18-coap-lwm2m/09-lwm2m-qmode-standalone-test.sh b/tests/18-coap-lwm2m/09-lwm2m-qmode-standalone-test.sh new file mode 100755 index 000000000..f22b20bef --- /dev/null +++ b/tests/18-coap-lwm2m/09-lwm2m-qmode-standalone-test.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# Contiki directory +CONTIKI=$1 +# Test basename +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 + +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 +echo "Starting leshan server with Q-Mode enabled" +java -jar leshan-server-demo-1.0.0-SNAPSHOT-jar-with-dependencies.jar -lp 5686 -slp 5687 >leshan.log 2>leshan.err & +LESHID=$! + +echo "Starting lwm2m standalone example" +example-lwm2m-standalone/lwm2m/lwm2m-example coap://127.0.0.1:5686 > node.log 2> node.err & + +CPID=$! + +COUNTER=10 +while [ $COUNTER -gt 0 ]; do + sleep 5 + aux=$(grep -c 'OK' leshan.err) + if [ $aux -eq 2 ] ; then + break + fi + let COUNTER-=1 +done + +echo "Closing standalone example" +sleep 1 +pgrep lwm2m-example | sudo xargs kill -9 + +echo "Closing leshan" +sleep 1 +pgrep java | sudo xargs kill -9 + +aux=$(grep -c 'OK' leshan.err) +if [ $aux -eq 2 ] +then + cp leshan.err $BASENAME.testlog; + printf "%-32s TEST OK\n" "$BASENAME" | tee $BASENAME.testlog; +else + echo "==== make.log ====" ; cat make.log; + echo "==== make.err ====" ; cat make.err; + echo "==== node.log ====" ; cat node.log; + echo "==== node.err ====" ; cat node.err; + echo "==== leshan.log ====" ; cat leshan.log; + echo "==== leshan.err ====" ; cat leshan.err; + echo "==== $BASENAME.log ====" ; cat $BASENAME.log; + + printf "%-32s TEST FAIL\n" "$BASENAME" | tee $BASENAME.testlog; +fi + +rm make.log +rm make.err +rm node.log +rm node.err +rm leshan.log +rm leshan.err + +# We do not want Make to stop -> Return 0 +# The Makefile will check if a log contains FAIL at the end +exit 0 diff --git a/tests/18-coap-lwm2m/pytests/test-qmode-awake.py b/tests/18-coap-lwm2m/pytests/test-qmode-awake.py new file mode 100644 index 000000000..775e1cff0 --- /dev/null +++ b/tests/18-coap-lwm2m/pytests/test-qmode-awake.py @@ -0,0 +1,20 @@ +import unittest, array, time + +class TestQueueModeAwake(unittest.TestCase): + global respAwakeTime + global respSleepTime + + def test_read_awake_time(self): + self.assertEqual(respAwakeTime.getCode().getName(), "CONTENT") + + def test_read_sleep_time(self): + self.assertEqual(respSleepTime.getCode().getName(), "CONTENT") + + +print "----------------------------------------" +print "LWM2M Queue Mode Awake State Tester" +print "----------------------------------------" + + +suite = unittest.TestLoader().loadTestsFromTestCase(TestQueueModeAwake) +unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/18-coap-lwm2m/pytests/test-qmode-sleep.py b/tests/18-coap-lwm2m/pytests/test-qmode-sleep.py new file mode 100644 index 000000000..da9a2ffe8 --- /dev/null +++ b/tests/18-coap-lwm2m/pytests/test-qmode-sleep.py @@ -0,0 +1,19 @@ +from __future__ import with_statement +import unittest, array, time + +class TestQueueModeSleep(unittest.TestCase): + global client + + def test_read_awake_time(self): + self.assertIsNone(client.read("6000/0/3000")) + + def test_read_sleep_time(self): + self.assertIsNone(client.read("6000/0/3001")) + + +print "----------------------------------------" +print "LWM2M Queue Mode Sleep State Tester - name of client: ", client.endpoint +print "----------------------------------------" + +suite = unittest.TestLoader().loadTestsFromTestCase(TestQueueModeSleep) +unittest.TextTestRunner(verbosity=2).run(suite) From 18714f2cad672fb73fee92e59843343cfa36d6b4 Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Fri, 27 Apr 2018 16:31:22 +0200 Subject: [PATCH 08/55] Simplified awake time adaptation with array and other small fixes --- examples/lwm2m-ipso-objects/project-conf.h | 2 +- os/services/lwm2m/lwm2m-engine.c | 10 +-- os/services/lwm2m/lwm2m-notification-queue.c | 10 +-- os/services/lwm2m/lwm2m-qmode-object.c | 66 +++++++------------- os/services/lwm2m/lwm2m-qmode-object.h | 2 +- 5 files changed, 36 insertions(+), 54 deletions(-) diff --git a/examples/lwm2m-ipso-objects/project-conf.h b/examples/lwm2m-ipso-objects/project-conf.h index affe626b0..53d149617 100644 --- a/examples/lwm2m-ipso-objects/project-conf.h +++ b/examples/lwm2m-ipso-objects/project-conf.h @@ -64,6 +64,6 @@ #define LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION 1 #define LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME 2000 #define LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME 10000 - #define LWM2M_Q_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG 1 */ + #define LWM2M_Q_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG 0 */ #endif /* PROJECT_CONF_H_ */ diff --git a/os/services/lwm2m/lwm2m-engine.c b/os/services/lwm2m/lwm2m-engine.c index 3c038deec..b80e6f5a4 100644 --- a/os/services/lwm2m/lwm2m-engine.c +++ b/os/services/lwm2m/lwm2m-engine.c @@ -1414,10 +1414,12 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response, if(is_first_request()) { previous_request_time = coap_timer_uptime(); clear_first_request(); - }else{ + } else { if(coap_timer_uptime()-previous_request_time >= 0) { - lwm2m_q_object_add_time_object(coap_timer_uptime()-previous_request_time); - + if(coap_timer_uptime()-previous_request_time > 0xffff) { + lwm2m_q_object_add_time_to_window(0xffff); + } + lwm2m_q_object_add_time_to_window(coap_timer_uptime()-previous_request_time); } previous_request_time = coap_timer_uptime(); } @@ -1691,7 +1693,7 @@ 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_q_object_get_dynamic_adaptation_flag()) { lwm2m_engine_set_handler_from_notification(); } #endif diff --git a/os/services/lwm2m/lwm2m-notification-queue.c b/os/services/lwm2m/lwm2m-notification-queue.c index c3150a879..dab243ec1 100644 --- a/os/services/lwm2m/lwm2m-notification-queue.c +++ b/os/services/lwm2m/lwm2m-notification-queue.c @@ -93,17 +93,17 @@ reduce_path(notification_path_t *path_object, char *path) } /*---------------------------------------------------------------------------*/ static void -extend_path(notification_path_t *path_object, char *path) +extend_path(notification_path_t *path_object, char *path, int path_size) { switch(path_object->level) { case 1: - snprintf(path, sizeof(path) - 1, "%u", path_object->reduced_path[0]); + snprintf(path, path_size, "%u", path_object->reduced_path[0]); break; case 2: - snprintf(path, sizeof(path) - 1, "%u/%u", path_object->reduced_path[0], path_object->reduced_path[1]); + snprintf(path, path_size, "%u/%u", path_object->reduced_path[0], path_object->reduced_path[1]); break; case 3: - snprintf(path, sizeof(path) - 1, "%u/%u/%u", path_object->reduced_path[0], path_object->reduced_path[1], path_object->reduced_path[2]); + snprintf(path, path_size, "%u/%u/%u", path_object->reduced_path[0], path_object->reduced_path[1], path_object->reduced_path[2]); break; } } @@ -222,7 +222,7 @@ lwm2m_notification_queue_send_notifications() notification_path_t *aux = iteration_path; while(iteration_path != NULL) { - extend_path(iteration_path, path); + extend_path(iteration_path, path, sizeof(path)); #if LWM2M_Q_MODE_INCLUDE_DYNAMIC_ADAPTATION if(lwm2m_q_object_get_dynamic_adaptation_flag()) { lwm2m_engine_set_handler_from_notification(); diff --git a/os/services/lwm2m/lwm2m-qmode-object.c b/os/services/lwm2m/lwm2m-qmode-object.c index 77a12e460..be5bc7674 100644 --- a/os/services/lwm2m/lwm2m-qmode-object.c +++ b/os/services/lwm2m/lwm2m-qmode-object.c @@ -78,14 +78,9 @@ 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; -typedef struct time_object { - struct times_object *next; - uint64_t time; -} time_object_t; - /* Window to save the times and do the dynamic adaptation of the awake time*/ -MEMB(times_memb, time_object_t, LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH); -LIST(time_object_list); +uint16_t times_window[LWM2M_Q_MODE_DYNAMIC_ADAPTATION_WINDOW_LENGTH] = { 0 }; +uint8_t times_window_index = 0; #endif /*---------------------------------------------------------------------------*/ @@ -130,16 +125,14 @@ lwm2m_q_object_set_dynamic_adaptation_flag(uint8_t flag) } /*---------------------------------------------------------------------------*/ #if !UPDATE_WITH_MEAN -static uint64_t +static uint16_t get_maximum_time() { - uint64_t max_time = 0; - time_object_t *iteration_time = NULL; - for(iteration_time = (time_object_t *)list_head(time_object_list); iteration_time; - iteration_time = (time_object_t *)iteration_time->next) { - - if(iteration_time->time > max_time) { - max_time = iteration_time->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; @@ -147,18 +140,18 @@ get_maximum_time() #endif /*---------------------------------------------------------------------------*/ #if UPDATE_WITH_MEAN -static uint64_t +static uint16_t get_mean_time() { - uint64_t mean_time = 0; - time_object_t *iteration_time = NULL; - for(iteration_time = (time_object_t *)list_head(time_object_list); iteration_time; - (time_object_t *)iteration_time = iteration_time->next) { - + 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 = iteration_time->time; + mean_time = times_window[i]; } else { - mean_time = (mean_time + iteration_time->time) / 2; + if(times_window[i] != 0) { + mean_time = (mean_time + times_window[i]) / 2; + } } } return mean_time; @@ -169,39 +162,26 @@ static void update_awake_time() { #if UPDATE_WITH_MEAN - uint64_t mean_time = get_mean_time(); + 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 - uint64_t max_time = get_maximum_time(); + 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 } /*---------------------------------------------------------------------------*/ -static void -remove_time_object(time_object_t *time_object) -{ - memb_free(×_memb, time_object); - list_remove(time_object_list, time_object); -} -/*---------------------------------------------------------------------------*/ void -lwm2m_q_object_add_time_object(uint64_t time) +lwm2m_q_object_add_time_to_window(uint16_t time) { - time_object_t *time_object; - time_object = memb_alloc(×_memb); - if(time_object != NULL) { - time_object->time = time; - list_add(time_object_list, time_object); - } else { - remove_time_object((time_object_t *)list_head(time_object_list)); - time_object = memb_alloc(×_memb); - time_object->time = time; - list_add(time_object_list, time_object); + 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 */ diff --git a/os/services/lwm2m/lwm2m-qmode-object.h b/os/services/lwm2m/lwm2m-qmode-object.h index 68427a59c..61ac35ff3 100644 --- a/os/services/lwm2m/lwm2m-qmode-object.h +++ b/os/services/lwm2m/lwm2m-qmode-object.h @@ -53,7 +53,7 @@ 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_object(uint64_t time); +void lwm2m_q_object_add_time_to_window(uint16_t time); #endif void lwm2m_q_object_send_notifications(); From 3889ffe7502b33f131b9ef66dcb0052d0bb432e9 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 16 May 2018 11:25:14 -0700 Subject: [PATCH 09/55] Simplify and homogenize node-id across all platforms --- arch/platform/cooja/platform.c | 14 ++-- arch/platform/jn516x/Makefile.jn516x | 2 +- arch/platform/jn516x/dev/node-id.c | 61 -------------- arch/platform/jn516x/platform.c | 34 +------- arch/platform/native/platform.c | 14 +--- arch/platform/sky/Makefile.common | 2 +- arch/platform/sky/apps/burn-nodeid.c | 80 ------------------- arch/platform/sky/node-id.c | 71 ---------------- arch/platform/sky/platform.c | 35 +------- arch/platform/srf06-cc26xx/platform.c | 7 -- examples/6tisch/etsi-plugtest-2017/node.c | 2 +- examples/6tisch/simple-node/node.c | 2 +- examples/6tisch/sixtop/node-sixtop.c | 2 +- .../tsch/simple-sensor-network/node/node.c | 2 +- os/contiki-main.c | 11 ++- .../cooja/sys/node-id.h => os/sys/node-id.c | 26 ++++-- os/sys/node-id.h | 23 ++++-- 17 files changed, 64 insertions(+), 324 deletions(-) delete mode 100644 arch/platform/jn516x/dev/node-id.c delete mode 100644 arch/platform/sky/apps/burn-nodeid.c delete mode 100644 arch/platform/sky/node-id.c rename arch/platform/cooja/sys/node-id.h => os/sys/node-id.c (75%) diff --git a/arch/platform/cooja/platform.c b/arch/platform/cooja/platform.c index 9ef310bce..591abe67e 100644 --- a/arch/platform/cooja/platform.c +++ b/arch/platform/cooja/platform.c @@ -64,6 +64,7 @@ #include "dev/button-sensor.h" #include "dev/pir-sensor.h" #include "dev/vib-sensor.h" +#include "dev/moteid.h" #include "sys/node-id.h" #include "services/rpl-border-router/rpl-border-router.h" @@ -151,13 +152,13 @@ set_lladdr(void) { int i; for(i = 0; i < sizeof(uip_lladdr.addr); i += 2) { - addr.u8[i + 1] = node_id & 0xff; - addr.u8[i + 0] = node_id >> 8; + addr.u8[i + 1] = simMoteID & 0xff; + addr.u8[i + 0] = simMoteID >> 8; } } #else /* NETSTACK_CONF_WITH_IPV6 */ - addr.u8[0] = node_id & 0xff; - addr.u8[1] = node_id >> 8; + addr.u8[0] = simMoteID & 0xff; + addr.u8[1] = simMoteID >> 8; #endif /* NETSTACK_CONF_WITH_IPV6 */ linkaddr_set_node_addr(&addr); } @@ -177,11 +178,6 @@ platform_init_stage_two() void platform_init_stage_three() { - if(node_id > 0) { - LOG_INFO("Node id is set to %u.\n", node_id); - } else { - LOG_INFO("Node id is not set.\n"); - } /* Initialize eeprom */ eeprom_init(); /* Start serial process */ diff --git a/arch/platform/jn516x/Makefile.jn516x b/arch/platform/jn516x/Makefile.jn516x index bb40b5638..93ba5f296 100644 --- a/arch/platform/jn516x/Makefile.jn516x +++ b/arch/platform/jn516x/Makefile.jn516x @@ -82,7 +82,7 @@ OBJDUMP:=$(CROSS_COMPILE)-objdump ARCH = jn516x-ccm-star.c exceptions.c rtimer-arch.c rtimer-arch-slow.c \ slip_uart0.c clock.c micromac-radio.c int-master.c \ - node-id.c watchdog.c slip.c dbg.c + watchdog.c slip.c dbg.c # Default uart0 for printf and slip TARGET_WITH_UART0 ?= 1 TARGET_WITH_UART1 ?= 0 diff --git a/arch/platform/jn516x/dev/node-id.c b/arch/platform/jn516x/dev/node-id.c deleted file mode 100644 index c29aa8282..000000000 --- a/arch/platform/jn516x/dev/node-id.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2014, SICS Swedish ICT. - * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * For compatibility with Contiki node-id interface - * - * \author - * Beshr Al Nahas - */ - -#include "contiki.h" -#include "sys/node-id.h" -#include "contiki.h" - -/*---------------------------------------------------------------------------*/ -extern unsigned char node_mac[8]; -unsigned short node_id = 0; -/*---------------------------------------------------------------------------*/ -void -node_id_restore(void) -{ - /* base node-id on MAC address */ - node_id = (node_mac[6] << 8) | node_mac[7]; -} -/*---------------------------------------------------------------------------*/ -void -node_id_burn(unsigned short id) -{ - /* does not burn anything */ - node_id = id; -} diff --git a/arch/platform/jn516x/platform.c b/arch/platform/jn516x/platform.c index 20dabfb61..9d44444e8 100644 --- a/arch/platform/jn516x/platform.c +++ b/arch/platform/jn516x/platform.c @@ -113,8 +113,7 @@ static uint32_t sleep_start_ticks; #define LOG_LEVEL LOG_LEVEL_MAIN /*---------------------------------------------------------------------------*/ /* Reads MAC from SoC - * Must be called before node_id_restore() - * and network addresses initialization */ + * Must be called before network addresses initialization */ static void init_node_mac(void) { @@ -139,14 +138,9 @@ set_linkaddr(void) #if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, node_mac, sizeof(addr.u8)); #else - if(node_id == 0) { - int i; - for(i = 0; i < LINKADDR_SIZE; ++i) { - addr.u8[i] = node_mac[LINKADDR_SIZE - 1 - i]; - } - } else { - addr.u8[0] = node_id & 0xff; - addr.u8[1] = node_id >> 8; + int i; + for(i = 0; i < LINKADDR_SIZE; ++i) { + addr.u8[i] = node_mac[LINKADDR_SIZE - 1 - i]; } #endif linkaddr_set_node_addr(&addr); @@ -194,20 +188,6 @@ platform_init_stage_one(void) leds_init(); leds_on(LEDS_ALL); init_node_mac(); - - node_id_restore(); - -#if WITH_TINYOS_AUTO_IDS - node_id = TOS_NODE_ID; -#endif /* WITH_TINYOS_AUTO_IDS */ - /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */ -#ifdef IEEE_802154_MAC_ADDRESS - { - uint8_t ieee[] = IEEE_802154_MAC_ADDRESS; - memcpy(node_mac, ieee, sizeof(uip_lladdr.addr)); - node_mac[7] = node_id & 0xff; - } -#endif } /*---------------------------------------------------------------------------*/ void @@ -225,12 +205,6 @@ platform_init_stage_two(void) void platform_init_stage_three(void) { - if(node_id > 0) { - LOG_INFO("Node id is set to %u.\n", node_id); - } else { - LOG_INFO("Node id is not set.\n"); - } - #ifndef UIP_FALLBACK_INTERFACE uart0_set_input(serial_line_input_byte); serial_line_init(); diff --git a/arch/platform/native/platform.c b/arch/platform/native/platform.c index c5c4f23e7..d00efaac1 100644 --- a/arch/platform/native/platform.c +++ b/arch/platform/native/platform.c @@ -120,9 +120,6 @@ static uint8_t mac_addr[] = PLATFORM_CONF_MAC_ADDR; static uint8_t mac_addr[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; #endif /* PLATFORM_CONF_MAC_ADDR */ -#if !NETSTACK_CONF_WITH_IPV6 -static uint16_t node_id = 0x0102; -#endif /* !NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ int select_set_callback(int fd, const struct select_callback *callback) @@ -187,14 +184,9 @@ set_lladdr(void) #if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, mac_addr, sizeof(addr.u8)); #else - if(node_id == 0) { - int i; - for(i = 0; i < sizeof(linkaddr_t); ++i) { - addr.u8[i] = mac_addr[7 - i]; - } - } else { - addr.u8[0] = node_id & 0xff; - addr.u8[1] = node_id >> 8; + int i; + for(i = 0; i < sizeof(linkaddr_t); ++i) { + addr.u8[i] = mac_addr[7 - i]; } #endif linkaddr_set_node_addr(&addr); diff --git a/arch/platform/sky/Makefile.common b/arch/platform/sky/Makefile.common index 3d688b573..c8de6d6ad 100644 --- a/arch/platform/sky/Makefile.common +++ b/arch/platform/sky/Makefile.common @@ -1,6 +1,6 @@ # $Id: Makefile.common,v 1.3 2010/08/24 16:24:11 joxe Exp $ -ARCH=spi-legacy.c ds2411.c xmem.c i2c.c node-id.c sensors.c cfs-coffee.c \ +ARCH=spi-legacy.c ds2411.c xmem.c i2c.c sensors.c cfs-coffee.c \ cc2420.c cc2420-arch.c cc2420-arch-sfd.c \ sky-sensors.c uip-ipchksum.c \ uart1.c slip_uart1.c uart1-putchar.c platform.c diff --git a/arch/platform/sky/apps/burn-nodeid.c b/arch/platform/sky/apps/burn-nodeid.c deleted file mode 100644 index 128ba2ba9..000000000 --- a/arch/platform/sky/apps/burn-nodeid.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A program for burning a node ID into the flash ROM of a Tmote Sky node. - * \author - * Adam Dunkels - */ - -#include "dev/leds.h" -#include "dev/watchdog.h" -#include "sys/node-id.h" -#include "contiki.h" -#include "sys/etimer.h" - -#include - -static struct etimer etimer; - -PROCESS(burn_process, "Burn node id"); -AUTOSTART_PROCESSES(&burn_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(burn_process, ev, data) -{ - PROCESS_BEGIN(); - - etimer_set(&etimer, 5*CLOCK_SECOND); - PROCESS_WAIT_UNTIL(etimer_expired(&etimer)); - - watchdog_stop(); - leds_on(LEDS_RED); -#if NODEID - printf("Burning node id %d\n", NODEID); - node_id_burn(NODEID); - leds_on(LEDS_BLUE); - node_id_restore(); - printf("Restored node id %d\n", node_id); -#else -#error "burn-nodeid must be compiled with nodeid=" - node_id_restore(); - printf("Restored node id %d\n", node_id); -#endif - leds_off(LEDS_RED + LEDS_BLUE); - watchdog_start(); - while(1) { - PROCESS_WAIT_EVENT(); - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/sky/node-id.c b/arch/platform/sky/node-id.c deleted file mode 100644 index ce6f68f85..000000000 --- a/arch/platform/sky/node-id.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Utility to store a node id in the external flash - * \author - * Adam Dunkels - */ - -#include "sys/node-id.h" -#include "contiki.h" -#include "dev/xmem.h" - -unsigned short node_id = 0; - -/*---------------------------------------------------------------------------*/ -void -node_id_restore(void) -{ - unsigned char buf[4]; - xmem_pread(buf, 4, NODE_ID_XMEM_OFFSET); - if(buf[0] == 0xad && - buf[1] == 0xde) { - node_id = (buf[2] << 8) | buf[3]; - } else { - node_id = 0; - } -} -/*---------------------------------------------------------------------------*/ -void -node_id_burn(unsigned short id) -{ - unsigned char buf[4]; - buf[0] = 0xad; - buf[1] = 0xde; - buf[2] = id >> 8; - buf[3] = id & 0xff; - xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET); - xmem_pwrite(buf, 4, NODE_ID_XMEM_OFFSET); -} -/*---------------------------------------------------------------------------*/ diff --git a/arch/platform/sky/platform.c b/arch/platform/sky/platform.c index deaa53b5a..670e5443d 100644 --- a/arch/platform/sky/platform.c +++ b/arch/platform/sky/platform.c @@ -103,14 +103,9 @@ set_lladdr(void) #if NETSTACK_CONF_WITH_IPV6 memcpy(addr.u8, ds2411_id, sizeof(addr.u8)); #else - if(node_id == 0) { - int i; - for(i = 0; i < sizeof(linkaddr_t); ++i) { - addr.u8[i] = ds2411_id[7 - i]; - } - } else { - addr.u8[0] = node_id & 0xff; - addr.u8[1] = node_id >> 8; + int i; + for(i = 0; i < sizeof(linkaddr_t); ++i) { + addr.u8[i] = ds2411_id[7 - i]; } #endif linkaddr_set_node_addr(&addr); @@ -153,23 +148,7 @@ platform_init_stage_two(void) * Hardware initialization done! */ -#if WITH_TINYOS_AUTO_IDS - node_id = TOS_NODE_ID; -#else /* WITH_TINYOS_AUTO_IDS */ - /* Restore node id if such has been stored in external mem */ - node_id_restore(); -#endif /* WITH_TINYOS_AUTO_IDS */ - - /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */ -#ifdef IEEE_802154_MAC_ADDRESS - { - uint8_t ieee[] = IEEE_802154_MAC_ADDRESS; - memcpy(ds2411_id, ieee, sizeof(uip_lladdr.addr)); - ds2411_id[7] = node_id & 0xff; - } -#endif - - random_init(ds2411_id[0] + node_id); + random_init(ds2411_id[0]); leds_off(LEDS_BLUE); @@ -198,12 +177,6 @@ platform_init_stage_three(void) cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr); - if(node_id > 0) { - LOG_INFO("Node id: %u\n", node_id); - } else { - LOG_INFO("Node id: N/A\n"); - } - LOG_INFO("CC2420 CCA threshold %i\n", CC2420_CONF_CCA_THRESH); #if !NETSTACK_CONF_WITH_IPV6 diff --git a/arch/platform/srf06-cc26xx/platform.c b/arch/platform/srf06-cc26xx/platform.c index 362b9614e..d71e597f1 100644 --- a/arch/platform/srf06-cc26xx/platform.c +++ b/arch/platform/srf06-cc26xx/platform.c @@ -81,8 +81,6 @@ #define LOG_MODULE "CC26xx/CC13xx" #define LOG_LEVEL LOG_LEVEL_MAIN /*---------------------------------------------------------------------------*/ -unsigned short node_id = 0; -/*---------------------------------------------------------------------------*/ /** \brief Board specific iniatialisation */ void board_init(void); /*---------------------------------------------------------------------------*/ @@ -130,9 +128,6 @@ set_rf_params(void) NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr); NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, IEEE802154_DEFAULT_CHANNEL); NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); - - /* also set the global node id */ - node_id = short_addr; #endif } /*---------------------------------------------------------------------------*/ @@ -227,8 +222,6 @@ platform_init_stage_three() } LOG_INFO_("\n"); - LOG_INFO(" Node ID: %d\n", node_id); - #if BOARD_HAS_SENSORS process_start(&sensors_process, NULL); #endif diff --git a/examples/6tisch/etsi-plugtest-2017/node.c b/examples/6tisch/etsi-plugtest-2017/node.c index 3046bb291..32d0429c0 100644 --- a/examples/6tisch/etsi-plugtest-2017/node.c +++ b/examples/6tisch/etsi-plugtest-2017/node.c @@ -37,7 +37,7 @@ */ #include "contiki.h" -#include "node-id.h" +#include "sys/node-id.h" #include "sys/log.h" #include "net/ipv6/uip-ds6-route.h" #include "net/mac/tsch/tsch.h" diff --git a/examples/6tisch/simple-node/node.c b/examples/6tisch/simple-node/node.c index d2f75ae33..381d81f8e 100644 --- a/examples/6tisch/simple-node/node.c +++ b/examples/6tisch/simple-node/node.c @@ -37,7 +37,7 @@ */ #include "contiki.h" -#include "node-id.h" +#include "sys/node-id.h" #include "sys/log.h" #include "net/ipv6/uip-ds6-route.h" #include "net/ipv6/uip-sr.h" diff --git a/examples/6tisch/sixtop/node-sixtop.c b/examples/6tisch/sixtop/node-sixtop.c index 67bee378a..e2dfe08c2 100755 --- a/examples/6tisch/sixtop/node-sixtop.c +++ b/examples/6tisch/sixtop/node-sixtop.c @@ -38,7 +38,7 @@ */ #include "contiki.h" -#include "node-id.h" +#include "sys/node-id.h" #include "sys/log.h" #include "net/ipv6/uip-ds6-route.h" #include "net/mac/tsch/tsch.h" diff --git a/examples/platform-specific/jn516x/tsch/simple-sensor-network/node/node.c b/examples/platform-specific/jn516x/tsch/simple-sensor-network/node/node.c index 42fa11fb7..df72b69b3 100644 --- a/examples/platform-specific/jn516x/tsch/simple-sensor-network/node/node.c +++ b/examples/platform-specific/jn516x/tsch/simple-sensor-network/node/node.c @@ -38,7 +38,7 @@ #include "net/routing/routing.h" #include "net/ipv6/uip-debug.h" #include "lib/random.h" -#include "node-id.h" +#include "sys/node-id.h" #include "waveform.h" #include "leds.h" #include "net/ipv6/uiplib.h" diff --git a/os/contiki-main.c b/os/contiki-main.c index b9aea5cd6..6252df828 100644 --- a/os/contiki-main.c +++ b/os/contiki-main.c @@ -42,6 +42,7 @@ /*---------------------------------------------------------------------------*/ #include "contiki.h" #include "contiki-net.h" +#include "sys/node-id.h" #include "sys/platform.h" #include "sys/energest.h" #include "sys/stack-check.h" @@ -86,6 +87,9 @@ main(void) platform_init_stage_two(); + netstack_init(); + node_id_init(); + LOG_INFO("Starting " CONTIKI_VERSION_STRING "\n"); LOG_INFO("- Routing: %s\n", NETSTACK_ROUTING.name); LOG_INFO("- Net: %s\n", NETSTACK_NETWORK.name); @@ -97,9 +101,8 @@ main(void) LOG_INFO("- 802.15.4 Default channel: %u\n", IEEE802154_DEFAULT_CHANNEL); #endif /* MAC_CONF_WITH_TSCH */ - netstack_init(); - - LOG_INFO("Link-layer address "); + LOG_INFO("Node ID: %u\n", node_id); + LOG_INFO("Link-layer address: "); LOG_INFO_LLADDR(&linkaddr_node_addr); LOG_INFO_("\n"); @@ -110,7 +113,7 @@ main(void) process_start(&tcpip_process, NULL); lladdr = uip_ds6_get_link_local(-1); - LOG_INFO("Tentative link-local IPv6 address "); + LOG_INFO("Tentative link-local IPv6 address: "); LOG_INFO_6ADDR(lladdr != NULL ? &lladdr->ipaddr : NULL); LOG_INFO_("\n"); } diff --git a/arch/platform/cooja/sys/node-id.h b/os/sys/node-id.c similarity index 75% rename from arch/platform/cooja/sys/node-id.h rename to os/sys/node-id.c index a6876bd1f..7914256e9 100644 --- a/arch/platform/cooja/sys/node-id.h +++ b/os/sys/node-id.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Swedish Institute of Computer Science. + * Copyright (c) 2018, RISE SICS. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,14 +26,26 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * + * This file is part of the Contiki operating system. + * */ -#ifndef NODE_ID_H_ -#define NODE_ID_H_ +/** + * \file + * Node-id management + * \author + * Simon Duquennoy + */ -#include "dev/moteid.h" +#include "contiki.h" +#include "sys/node-id.h" +#include "net/linkaddr.h" -#define node_id simMoteID +uint16_t node_id = 0; -#endif /* NODE_ID_H_ */ +void +node_id_init(void) { + /* Initialize with a default value derived from linkaddr */ + node_id = linkaddr_node_addr.u8[LINKADDR_SIZE - 1] + + (linkaddr_node_addr.u8[LINKADDR_SIZE - 2] << 8); +} diff --git a/os/sys/node-id.h b/os/sys/node-id.h index 0b6ebe6b1..5718269eb 100644 --- a/os/sys/node-id.h +++ b/os/sys/node-id.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Swedish Institute of Computer Science. + * Copyright (c) 2018, RISE SICS. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,16 +28,25 @@ * * This file is part of the Contiki operating system. * - * Author: Adam Dunkels - * */ + /** + * \addtogroup node-id + * @{ + * + * \file Node-id (simple 16-bit identifiers) handling + * \author Simon Duquennoy + * + */ + #ifndef NODE_ID_H_ #define NODE_ID_H_ -void node_id_restore(void); -void node_id_burn(unsigned short node_id); - -extern unsigned short node_id; +/* A global variable that hosts the node ID */ +extern uint16_t node_id; +/** + * Initialize the node ID. Must be called after initialized of linkaddr + */ +void node_id_init(void); #endif /* NODE_ID_H_ */ From 9531b02a3ad59af633a664cbce8401040ba3d4ac Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 18 May 2018 07:27:25 -0700 Subject: [PATCH 10/55] Doxygen fix --- os/sys/node-id.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/os/sys/node-id.h b/os/sys/node-id.h index 5718269eb..58909ddaa 100644 --- a/os/sys/node-id.h +++ b/os/sys/node-id.h @@ -34,7 +34,8 @@ * \addtogroup node-id * @{ * - * \file Node-id (simple 16-bit identifiers) handling + * \file + * Node-id (simple 16-bit identifiers) handling * \author Simon Duquennoy * */ @@ -50,3 +51,5 @@ extern uint16_t node_id; void node_id_init(void); #endif /* NODE_ID_H_ */ + /** @} */ + From 21657d1b37997c7d3532e62ed3dc2065a1040e05 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 18 May 2018 14:07:53 -0700 Subject: [PATCH 11/55] Fix ipv6 test: use new node-id log string --- tests/09-ipv6/js/ping-test-lla.js | 2 +- tests/09-ipv6/js/ping-test-ula.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/09-ipv6/js/ping-test-lla.js b/tests/09-ipv6/js/ping-test-lla.js index 1823d87b2..d9beedf8b 100644 --- a/tests/09-ipv6/js/ping-test-lla.js +++ b/tests/09-ipv6/js/ping-test-lla.js @@ -8,7 +8,7 @@ while(1) { YIELD(); log.log(time + " " + id + " "+ msg + "\n"); - if(msg.contains("Node id is set to")) { + if(msg.contains("Node ID: ")) { if(id == 1) { write(sim.getMoteWithID(1), "rpl-set-root 1"); } diff --git a/tests/09-ipv6/js/ping-test-ula.js b/tests/09-ipv6/js/ping-test-ula.js index b78f0342a..adbd22ccf 100644 --- a/tests/09-ipv6/js/ping-test-ula.js +++ b/tests/09-ipv6/js/ping-test-ula.js @@ -9,7 +9,7 @@ while(1) { YIELD(); log.log(time + " " + id + " "+ msg + "\n"); - if(msg.contains("Node id is set to")) { + if(msg.contains("Node ID: ")) { if(id == 1) { write(sim.getMoteWithID(1), "rpl-set-root 1"); } From 2e84d2abbec1742e217182f8664c3cefed8240a2 Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Fri, 18 May 2018 18:22:14 +0200 Subject: [PATCH 12/55] Separated Queue Mode implementation and Queue Mode object. Changes in the naming --- os/services/lwm2m/lwm2m-engine.c | 54 ++-- os/services/lwm2m/lwm2m-engine.h | 10 +- os/services/lwm2m/lwm2m-notification-queue.c | 10 +- os/services/lwm2m/lwm2m-notification-queue.h | 4 +- os/services/lwm2m/lwm2m-qmode-object.c | 281 ------------------ ...m-qmode-conf.h => lwm2m-queue-mode-conf.h} | 59 ++-- os/services/lwm2m/lwm2m-queue-mode-object.c | 152 ++++++++++ ...ode-object.h => lwm2m-queue-mode-object.h} | 27 +- os/services/lwm2m/lwm2m-queue-mode.c | 173 +++++++++++ os/services/lwm2m/lwm2m-queue-mode.h | 61 ++++ os/services/lwm2m/lwm2m-rd-client.c | 102 +++---- os/services/lwm2m/lwm2m-rd-client.h | 8 +- .../18-coap-lwm2m/08-lwm2m-qmode-ipso-test.sh | 2 +- .../09-lwm2m-qmode-standalone-test.sh | 2 +- .../18-coap-lwm2m/pytests/test-qmode-sleep.py | 4 +- 15 files changed, 527 insertions(+), 422 deletions(-) delete mode 100644 os/services/lwm2m/lwm2m-qmode-object.c rename os/services/lwm2m/{lwm2m-qmode-conf.h => lwm2m-queue-mode-conf.h} (53%) create mode 100644 os/services/lwm2m/lwm2m-queue-mode-object.c rename os/services/lwm2m/{lwm2m-qmode-object.h => lwm2m-queue-mode-object.h} (74%) create mode 100644 os/services/lwm2m/lwm2m-queue-mode.c create mode 100644 os/services/lwm2m/lwm2m-queue-mode.h 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 "----------------------------------------" From eba756e340e4f64fd12e98d428dc06b5e0c8acac Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Mon, 21 May 2018 16:13:29 +0200 Subject: [PATCH 13/55] Code of notification queue simplified --- os/services/lwm2m/lwm2m-engine.c | 2 +- os/services/lwm2m/lwm2m-notification-queue.c | 130 ++++--------------- os/services/lwm2m/lwm2m-notification-queue.h | 6 +- 3 files changed, 29 insertions(+), 109 deletions(-) diff --git a/os/services/lwm2m/lwm2m-engine.c b/os/services/lwm2m/lwm2m-engine.c index 36f6fae44..015e1cea9 100644 --- a/os/services/lwm2m/lwm2m-engine.c +++ b/os/services/lwm2m/lwm2m-engine.c @@ -1718,7 +1718,7 @@ lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, if(coap_has_observers(path)) { /* Client is sleeping -> add the notification to the list */ if(!lwm2m_rd_client_is_client_awake()) { - lwm2m_notification_queue_add_notification_path(path); + lwm2m_notification_queue_add_notification_path(obj->object_id, obj->instance_id, resource); /* if it is the first notification -> wake up and send update */ if(!waked_up_by_notification) { diff --git a/os/services/lwm2m/lwm2m-notification-queue.c b/os/services/lwm2m/lwm2m-notification-queue.c index e7c57a03c..4bbb860c1 100644 --- a/os/services/lwm2m/lwm2m-notification-queue.c +++ b/os/services/lwm2m/lwm2m-notification-queue.c @@ -35,7 +35,8 @@ /** * \file - * Implementation of functions to manage the queue of notifications + * Implementation of functions to manage the queue to store notifications + when waiting for the response to the update message in Queue Mode. * \author * Carlos Gonzalo Peces */ @@ -62,12 +63,12 @@ #ifdef LWM2M_NOTIFICATION_QUEUE_CONF_LENGTH #define LWM2M_NOTIFICATION_QUEUE_LENGTH LWM2M_NOTIFICATION_QUEUE_CONF_LENGTH #else -#define LWM2M_NOTIFICATION_QUEUE_LENGTH 3 +#define LWM2M_NOTIFICATION_QUEUE_LENGTH COAP_MAX_OBSERVERS #endif /*---------------------------------------------------------------------------*/ /* Queue to store the notifications in the period when the client has woken up, sent the update and it's waiting for the server response*/ -MEMB(notification_memb, notification_path_t, LWM2M_NOTIFICATION_QUEUE_LENGTH + 1); /* Length + 1 to allocate the new path to add */ +MEMB(notification_memb, notification_path_t, LWM2M_NOTIFICATION_QUEUE_LENGTH); /* Length + 1 to allocate the new path to add */ LIST(notification_paths_queue); /*---------------------------------------------------------------------------*/ void @@ -77,22 +78,6 @@ lwm2m_notification_queue_init(void) } /*---------------------------------------------------------------------------*/ static void -reduce_path(notification_path_t *path_object, char *path) -{ - char *cut = strtok(path, "/"); - int i; - for(i = 0; i < 3; i++) { - if(cut != NULL) { - path_object->reduced_path[i] = (uint16_t)atoi(cut); - cut = strtok(NULL, "/"); - } else { - break; - } - } - path_object->level = i; -} -/*---------------------------------------------------------------------------*/ -static void extend_path(notification_path_t *path_object, char *path, int path_size) { switch(path_object->level) { @@ -108,34 +93,18 @@ extend_path(notification_path_t *path_object, char *path, int path_size) } } /*---------------------------------------------------------------------------*/ -static void -add_notification_path_object_ordered(notification_path_t *path) +static int +is_notification_path_present(uint16_t object_id, uint16_t instance_id, uint16_t resource_id) { notification_path_t *iteration_path = (notification_path_t *)list_head(notification_paths_queue); - if(list_length(notification_paths_queue) == 0) { - list_add(notification_paths_queue, path); - } else if(path->level < iteration_path->level) { - list_push(notification_paths_queue, path); - } else if(memcmp((path->reduced_path), (iteration_path->reduced_path), (path->level) * sizeof(uint16_t)) <= 0) { - list_push(notification_paths_queue, path); - } else { - notification_path_t *previous_path = iteration_path; - while(iteration_path != NULL) { - if(path->level < iteration_path->level) { - path->next = iteration_path; - previous_path->next = path; - return; - } - if(memcmp((path->reduced_path), (iteration_path->reduced_path), (path->level) * sizeof(uint16_t)) <= 0) { - path->next = iteration_path; - previous_path->next = path; - return; - } - previous_path = iteration_path; - iteration_path = iteration_path->next; + while(iteration_path != NULL) { + if(iteration_path->reduced_path[0] == object_id && iteration_path->reduced_path[1] == instance_id + && iteration_path->reduced_path[2] == resource_id) { + return 1; } - list_add(notification_paths_queue, path); + iteration_path = iteration_path->next; } + return 0; } /*---------------------------------------------------------------------------*/ static void @@ -145,73 +114,24 @@ remove_notification_path(notification_path_t *path) memb_free(¬ification_memb, path); } /*---------------------------------------------------------------------------*/ -static void -notification_queue_remove_policy(uint16_t *reduced_path, uint8_t level) -{ - uint8_t path_removed_flag = 0; - - notification_path_t *path_object = NULL; - notification_path_t *iteration_path = NULL; - notification_path_t *previous = NULL; - notification_path_t *next_next = NULL; - notification_path_t *path_to_remove = NULL; - - for(iteration_path = (notification_path_t *)list_head(notification_paths_queue); iteration_path != NULL; - iteration_path = iteration_path->next) { - /* 1. check if there is one event of the same path -> remove it and add the new one */ - if((level == iteration_path->level) && memcmp(iteration_path->reduced_path, reduced_path, level * sizeof(uint16_t)) == 0) { - remove_notification_path(iteration_path); - path_object = memb_alloc(¬ification_memb); - memcpy(path_object->reduced_path, reduced_path, level * sizeof(uint16_t)); - path_object->level = level; - add_notification_path_object_ordered(path_object); - return; - } - /* 2. If there is no event of the same type, look for repeated events of the same resource and remove the oldest one */ - if(iteration_path->next != NULL && (iteration_path->level == iteration_path->next->level) - && (memcmp(iteration_path->reduced_path, (iteration_path->next)->reduced_path, iteration_path->level * sizeof(uint16_t)) == 0)) { - path_removed_flag = 1; - next_next = iteration_path->next->next; - path_to_remove = iteration_path->next; - previous = iteration_path; - } - } - /* 3. If there are no events for the same path, we remove a the oldest repeated event of another resource */ - if(path_removed_flag) { - memb_free(¬ification_memb, path_to_remove); - previous->next = next_next; - path_object = memb_alloc(¬ification_memb); - memcpy(path_object->reduced_path, reduced_path, level * sizeof(uint16_t)); - path_object->level = level; - add_notification_path_object_ordered(path_object); - } else { - /* 4. If all the events are from different resources, remove the last one */ - list_chop(notification_paths_queue); - path_object = memb_alloc(¬ification_memb); - memcpy(path_object->reduced_path, reduced_path, level * sizeof(uint16_t)); - path_object->level = level; - add_notification_path_object_ordered(path_object); - } - return; -} -/*---------------------------------------------------------------------------*/ -/* For adding objects to the list in an ordered way, depending on the path*/ void -lwm2m_notification_queue_add_notification_path(char *path) +lwm2m_notification_queue_add_notification_path(uint16_t object_id, uint16_t instance_id, uint16_t resource_id) { - notification_path_t *path_object = memb_alloc(¬ification_memb); - if(path_object == NULL) { - LOG_DBG("Could not allocate new notification in the queue\n"); + if(is_notification_path_present(object_id, instance_id, resource_id)) { + LOG_DBG("Notification path already present, not queueing it\n"); return; } - reduce_path(path_object, path); - if(list_length(notification_paths_queue) >= LWM2M_NOTIFICATION_QUEUE_LENGTH) { - /* The queue is full, apply policy to remove */ - notification_queue_remove_policy(path_object->reduced_path, path_object->level); - } else { - add_notification_path_object_ordered(path_object); + notification_path_t *path_object = memb_alloc(¬ification_memb); + if(path_object == NULL) { + LOG_DBG("Queue is full, could not allocate new notification\n"); + return; } - LOG_DBG("Notification path added to the list: %s\n", path); + path_object->reduced_path[0] = object_id; + path_object->reduced_path[1] = instance_id; + path_object->reduced_path[2] = resource_id; + path_object->level = 3; + list_add(notification_paths_queue, path_object); + LOG_DBG("Notification path added to the list: %u/%u/%u\n", object_id, instance_id, resource_id); } /*---------------------------------------------------------------------------*/ void diff --git a/os/services/lwm2m/lwm2m-notification-queue.h b/os/services/lwm2m/lwm2m-notification-queue.h index 805002cc2..e3f4719ac 100644 --- a/os/services/lwm2m/lwm2m-notification-queue.h +++ b/os/services/lwm2m/lwm2m-notification-queue.h @@ -35,7 +35,8 @@ /** * \file - * Header file for functions to manage the queue of notifications + * Header file for functions to manage the queue to store notifications + when waiting for the response to the update message in Queue Mode. * \author * Carlos Gonzalo Peces */ @@ -56,8 +57,7 @@ typedef struct notification_path { void lwm2m_notification_queue_init(void); -/* For adding objects to the list in an ordered way, depending on the path*/ -void lwm2m_notification_queue_add_notification_path(char *path); +void lwm2m_notification_queue_add_notification_path(uint16_t object_id, uint16_t instance_id, uint16_t resource_id); void lwm2m_notification_queue_send_notifications(); From ec8fe6eb22a5e48a4358a2d30c5dc8b765689ca6 Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Tue, 22 May 2018 15:34:30 +0200 Subject: [PATCH 14/55] Code moved frome lwm2m-engine to lwm2m-queue-mode to have a clearer separation --- examples/lwm2m-ipso-objects/project-conf.h | 11 +- os/services/lwm2m/lwm2m-engine.c | 101 +------------------ os/services/lwm2m/lwm2m-engine.h | 9 -- os/services/lwm2m/lwm2m-notification-queue.c | 2 +- os/services/lwm2m/lwm2m-queue-mode.c | 101 ++++++++++++++++++- os/services/lwm2m/lwm2m-queue-mode.h | 12 ++- os/services/lwm2m/lwm2m-rd-client.c | 8 +- 7 files changed, 125 insertions(+), 119 deletions(-) diff --git a/examples/lwm2m-ipso-objects/project-conf.h b/examples/lwm2m-ipso-objects/project-conf.h index 53d149617..01f919866 100644 --- a/examples/lwm2m-ipso-objects/project-conf.h +++ b/examples/lwm2m-ipso-objects/project-conf.h @@ -60,10 +60,11 @@ #define COAP_OBSERVE_CLIENT 1 /* Definitions to enable Queue Mode, include the dynamic adaptation and change the default parameters */ -/* #define LWM2M_Q_MODE_CONF_ENABLED 1 - #define LWM2M_Q_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION 1 - #define LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME 2000 - #define LWM2M_Q_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME 10000 - #define LWM2M_Q_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG 0 */ +/* #define LWM2M_QUEUE_MODE_CONF_ENABLED 1 + #define LWM2M_QUEUE_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION 1 + #define LWM2M_QUEUE_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME 2000 + #define LWM2M_QUEUE_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME 10000 + #define LWM2M_QUEUE_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG 1 + #define LWM2M_QUEUE_MODE_OBJECT_CONF_ENABLED 0 */ #endif /* PROJECT_CONF_H_ */ diff --git a/os/services/lwm2m/lwm2m-engine.c b/os/services/lwm2m/lwm2m-engine.c index 015e1cea9..0c4d9f5fd 100644 --- a/os/services/lwm2m/lwm2m-engine.c +++ b/os/services/lwm2m/lwm2m-engine.c @@ -84,9 +84,6 @@ #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 */ -#define FIRST_REQUEST_MASK 0x01 -#define HANDLER_FROM_NOTIFICATION_MASK 0x02 #endif #if USE_RD_CLIENT @@ -146,19 +143,6 @@ static struct { /* in the future also a timeout */ } created; -#if LWM2M_QUEUE_MODE_ENABLED -static uint8_t waked_up_by_notification; -/* For the dynamic adaptation of the awake time */ -#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_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ -#endif /* LWM2M_QUEUE_MODE_ENABLED */ - COAP_HANDLER(lwm2m_handler, lwm2m_handler_callback); LIST(object_list); LIST(generic_object_list); @@ -1406,32 +1390,8 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response, context.inbuf->size = coap_get_payload(request, (const uint8_t **)&context.inbuf->buffer); context.inbuf->pos = 0; - /*If Queue Mode, restart the client awake timer */ #if LWM2M_QUEUE_MODE_ENABLED - if(lwm2m_rd_client_is_client_awake()) { - lwm2m_rd_client_restart_client_awake_timer(); - } - -#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_queue_mode_add_time_to_window(0xffff); - } else { - lwm2m_queue_mode_add_time_to_window(coap_timer_uptime()-previous_request_time); - } - } - previous_request_time = coap_timer_uptime(); - } - } - if(get_handler_from_notification()) { - clear_handler_from_notification(); - } -#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +lwm2m_queue_mode_request_received(); #endif /* LWM2M_QUEUE_MODE_ENABLED */ /* Maybe this should be part of CoAP itself - this seems not to be working @@ -1698,7 +1658,7 @@ lwm2m_send_notification(char* path) { #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(); + lwm2m_queue_mode_set_handler_from_notification(); } #endif coap_notify_observers_sub(NULL, path); @@ -1721,8 +1681,8 @@ lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, lwm2m_notification_queue_add_notification_path(obj->object_id, obj->instance_id, resource); /* if it is the first notification -> wake up and send update */ - if(!waked_up_by_notification) { - waked_up_by_notification = 1; + if(!lwm2m_queue_mode_is_waked_up_by_notification()) { + lwm2m_queue_mode_set_waked_up_by_notification(); lwm2m_rd_client_fsm_execute_queue_mode_update(); } /* Client is awake -> send the notification */ @@ -1735,57 +1695,4 @@ lwm2m_notify_object_observers(lwm2m_object_instance_t *obj, #endif } /*---------------------------------------------------------------------------*/ -/* Queue Mode Support and dynamic adaptation of the client awake time */ -#if LWM2M_QUEUE_MODE_ENABLED -uint8_t -lwm2m_engine_is_waked_up_by_notification() -{ - return waked_up_by_notification; -} -/*---------------------------------------------------------------------------*/ -void -lwm2m_engine_clear_waked_up_by_notification() -{ - waked_up_by_notification = 0; -} -/*---------------------------------------------------------------------------*/ -#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION -void -lwm2m_engine_set_first_request() -{ - dynamic_adaptation_params |= FIRST_REQUEST_MASK; -} -/*---------------------------------------------------------------------------*/ -void -lwm2m_engine_set_handler_from_notification() -{ - dynamic_adaptation_params |= HANDLER_FROM_NOTIFICATION_MASK; -} -/*---------------------------------------------------------------------------*/ -static inline uint8_t -is_first_request() -{ - return dynamic_adaptation_params & FIRST_REQUEST_MASK; -} -/*---------------------------------------------------------------------------*/ -static inline uint8_t -get_handler_from_notification() -{ - return (dynamic_adaptation_params & HANDLER_FROM_NOTIFICATION_MASK) != 0; -} -/*---------------------------------------------------------------------------*/ -static inline void -clear_first_request() -{ - dynamic_adaptation_params &= ~FIRST_REQUEST_MASK; -} -/*---------------------------------------------------------------------------*/ -static inline void -clear_handler_from_notification() -{ - dynamic_adaptation_params &= ~HANDLER_FROM_NOTIFICATION_MASK; -} -#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 0f6d35734..0ca24fb90 100644 --- a/os/services/lwm2m/lwm2m-engine.h +++ b/os/services/lwm2m/lwm2m-engine.h @@ -116,14 +116,5 @@ 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_QUEUE_MODE_ENABLED -uint8_t lwm2m_engine_is_waked_up_by_notification(); -void lwm2m_engine_clear_waked_up_by_notification(); -#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION -void lwm2m_engine_set_first_request(); -void lwm2m_engine_set_handler_from_notification(); -#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 4bbb860c1..c901bef82 100644 --- a/os/services/lwm2m/lwm2m-notification-queue.c +++ b/os/services/lwm2m/lwm2m-notification-queue.c @@ -145,7 +145,7 @@ lwm2m_notification_queue_send_notifications() extend_path(iteration_path, path, sizeof(path)); #if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION if(lwm2m_queue_mode_get_dynamic_adaptation_flag()) { - lwm2m_engine_set_handler_from_notification(); + lwm2m_queue_mode_set_handler_from_notification(); } #endif LOG_DBG("Sending stored notification with path: %s\n", path); diff --git a/os/services/lwm2m/lwm2m-queue-mode.c b/os/services/lwm2m/lwm2m-queue-mode.c index 30c8dd6cc..aad80ce3e 100644 --- a/os/services/lwm2m/lwm2m-queue-mode.c +++ b/os/services/lwm2m/lwm2m-queue-mode.c @@ -55,17 +55,30 @@ #define LOG_MODULE "lwm2m-queue-mode" #define LOG_LEVEL LOG_LEVEL_LWM2M +/* Queue Mode dynamic adaptation masks */ +#define FIRST_REQUEST_MASK 0x01 +#define HANDLER_FROM_NOTIFICATION_MASK 0x02 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; + +/* Flag for notifications */ +static uint8_t waked_up_by_notification; + +/* For the dynamic adaptation of the awake 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 +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_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ /*---------------------------------------------------------------------------*/ uint16_t lwm2m_queue_mode_get_awake_time() @@ -106,6 +119,7 @@ lwm2m_queue_mode_set_dynamic_adaptation_flag(uint8_t flag) { queue_mode_dynamic_adaptation_flag = flag; } +#endif /*---------------------------------------------------------------------------*/ #if !UPDATE_WITH_MEAN static uint16_t @@ -167,6 +181,89 @@ lwm2m_queue_mode_add_time_to_window(uint16_t time) times_window_index++; update_awake_time(); } +/*---------------------------------------------------------------------------*/ +uint8_t +lwm2m_queue_mode_is_waked_up_by_notification() +{ + return waked_up_by_notification; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_clear_waked_up_by_notification() +{ + waked_up_by_notification = 0; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_set_waked_up_by_notification() +{ + waked_up_by_notification = 1; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_request_received() +{ + if(lwm2m_rd_client_is_client_awake()) { + lwm2m_rd_client_restart_client_awake_timer(); + } +#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_queue_mode_add_time_to_window(0xffff); + } else { + lwm2m_queue_mode_add_time_to_window(coap_timer_uptime() - previous_request_time); + } + } + previous_request_time = coap_timer_uptime(); + } + } + if(get_handler_from_notification()) { + clear_handler_from_notification(); + } +#endif /* LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION */ +} +/*---------------------------------------------------------------------------*/ +#if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION +void +lwm2m_queue_mode_set_first_request() +{ + dynamic_adaptation_params |= FIRST_REQUEST_MASK; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_queue_mode_set_handler_from_notification() +{ + dynamic_adaptation_params |= HANDLER_FROM_NOTIFICATION_MASK; +} +/*---------------------------------------------------------------------------*/ +static inline uint8_t +is_first_request() +{ + return dynamic_adaptation_params & FIRST_REQUEST_MASK; +} +/*---------------------------------------------------------------------------*/ +static inline uint8_t +get_handler_from_notification() +{ + return (dynamic_adaptation_params & HANDLER_FROM_NOTIFICATION_MASK) != 0; +} +/*---------------------------------------------------------------------------*/ +static inline void +clear_first_request() +{ + dynamic_adaptation_params &= ~FIRST_REQUEST_MASK; +} +/*---------------------------------------------------------------------------*/ +static inline void +clear_handler_from_notification() +{ + dynamic_adaptation_params &= ~HANDLER_FROM_NOTIFICATION_MASK; +} #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 index cc3bd3290..5c65face5 100644 --- a/os/services/lwm2m/lwm2m-queue-mode.h +++ b/os/services/lwm2m/lwm2m-queue-mode.h @@ -36,7 +36,7 @@ /** * \file * Header file for the Contiki OMA LWM2M Queue Mode implementation - to manage the parameters + to manage the parameters * \author * Carlos Gonzalo Peces */ @@ -51,11 +51,21 @@ 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 +uint8_t lwm2m_queue_mode_is_waked_up_by_notification(); +void lwm2m_queue_mode_clear_waked_up_by_notification(); +void lwm2m_queue_mode_set_waked_up_by_notification(); + +void lwm2m_queue_mode_set_first_request(); +void lwm2m_queue_mode_set_handler_from_notification(); + +void lwm2m_queue_mode_request_received(); + #endif /* LWM2M_QUEUE_MODE_H_ */ /** @} */ diff --git a/os/services/lwm2m/lwm2m-rd-client.c b/os/services/lwm2m/lwm2m-rd-client.c index da8d276d0..63c9443e1 100644 --- a/os/services/lwm2m/lwm2m-rd-client.c +++ b/os/services/lwm2m/lwm2m-rd-client.c @@ -448,7 +448,7 @@ registration_callback(coap_request_state_t *state) #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(); + lwm2m_queue_mode_set_first_request(); } #endif lwm2m_rd_client_fsm_execute_queue_mode_awake(); /* Avoid 500 ms delay and move directly to the state*/ @@ -501,14 +501,14 @@ update_callback(coap_request_state_t *state) last_update = coap_timer_uptime(); #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()) { + if(lwm2m_queue_mode_is_waked_up_by_notification()) { - lwm2m_engine_clear_waked_up_by_notification(); + lwm2m_queue_mode_clear_waked_up_by_notification(); lwm2m_notification_queue_send_notifications(); } #if LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION if(lwm2m_queue_mode_get_dynamic_adaptation_flag()) { - lwm2m_engine_set_first_request(); + lwm2m_queue_mode_set_first_request(); } #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*/ From f7ab2750a0184e9f9600005f43f4f882cb8df6ce Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Thu, 17 May 2018 02:56:34 -0700 Subject: [PATCH 15/55] Added simple-energest --- os/contiki-main.c | 5 + os/services/simple-energest/module-macros.h | 2 + os/services/simple-energest/simple-energest.c | 132 ++++++++++++++++++ os/services/simple-energest/simple-energest.h | 60 ++++++++ 4 files changed, 199 insertions(+) create mode 100644 os/services/simple-energest/module-macros.h create mode 100644 os/services/simple-energest/simple-energest.c create mode 100644 os/services/simple-energest/simple-energest.h diff --git a/os/contiki-main.c b/os/contiki-main.c index b9aea5cd6..a6c063d1d 100644 --- a/os/contiki-main.c +++ b/os/contiki-main.c @@ -51,6 +51,7 @@ #include "services/rpl-border-router/rpl-border-router.h" #include "services/orchestra/orchestra.h" #include "services/shell/serial-shell.h" +#include "services/simple-energest/simple-energest.h" #include #include @@ -138,6 +139,10 @@ main(void) LOG_DBG("With CoAP\n"); #endif /* BUILD_WITH_SHELL */ +#if BUILD_WITH_SIMPLE_ENERGEST + simple_energest_init(); +#endif /* BUILD_WITH_SIMPLE_ENERGEST */ + autostart_start(autostart_processes); watchdog_start(); diff --git a/os/services/simple-energest/module-macros.h b/os/services/simple-energest/module-macros.h new file mode 100644 index 000000000..f5ae1e890 --- /dev/null +++ b/os/services/simple-energest/module-macros.h @@ -0,0 +1,2 @@ +#define BUILD_WITH_SIMPLE_ENERGEST 1 +#define ENERGEST_CONF_ON 1 diff --git a/os/services/simple-energest/simple-energest.c b/os/services/simple-energest/simple-energest.c new file mode 100644 index 000000000..fc7393bc6 --- /dev/null +++ b/os/services/simple-energest/simple-energest.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2018, RISE SICS. + * 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 Institute 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 INSTITUTE 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 INSTITUTE 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 simple-energest +* @{ +*/ + +/** + * \file + * A process that periodically prints out the time spent in + * radio tx, radio rx, total time and duty cycle. + * + * \author Simon Duquennoy + */ + +#include "contiki.h" +#include "sys/energest.h" +#include "simple-energest.h" +#include +#include + +/* Log configuration */ +#include "sys/log.h" +#define LOG_MODULE "Energest" +#define LOG_LEVEL LOG_LEVEL_INFO + +static unsigned long last_tx, last_rx, last_time, last_cpu, last_lpm, last_deep_lpm; +static unsigned long delta_tx, delta_rx, delta_time, delta_cpu, delta_lpm, delta_deep_lpm; +static unsigned long curr_tx, curr_rx, curr_time, curr_cpu, curr_lpm, curr_deep_lpm; + +PROCESS(simple_energest_process, "Simple Energest"); +/*---------------------------------------------------------------------------*/ +static unsigned long +to_permil(unsigned long delta_metric, unsigned long delta_time) +{ + return (1000ul * (delta_metric)) / delta_time; +} +/*---------------------------------------------------------------------------*/ +static void +simple_energest_step(void) +{ + static unsigned count = 0; + + energest_flush(); + + curr_time = ENERGEST_GET_TOTAL_TIME(); + curr_cpu = energest_type_time(ENERGEST_TYPE_CPU); + curr_lpm = energest_type_time(ENERGEST_TYPE_LPM); + curr_deep_lpm = energest_type_time(ENERGEST_TYPE_DEEP_LPM); + curr_tx = energest_type_time(ENERGEST_TYPE_TRANSMIT); + curr_rx = energest_type_time(ENERGEST_TYPE_LISTEN); + + delta_time = curr_time - last_time; + delta_cpu = curr_cpu - last_cpu; + delta_lpm = curr_lpm - last_lpm; + delta_deep_lpm = curr_deep_lpm - last_deep_lpm; + delta_tx = curr_tx - last_tx; + delta_rx = curr_rx - last_rx; + + last_time = curr_time; + last_cpu = curr_cpu; + last_lpm = curr_lpm; + last_deep_lpm = curr_deep_lpm; + last_tx = curr_tx; + last_rx = curr_rx; + + LOG_INFO("--- Period summary #%u (%lu seconds)\n", count++, delta_time/ENERGEST_SECOND); + LOG_INFO("Total time : %10lu\n", delta_time); + LOG_INFO("CPU : %10lu/%10lu (%lu permil)\n", delta_cpu, delta_time, to_permil(delta_cpu, delta_time)); + LOG_INFO("LPM : %10lu/%10lu (%lu permil)\n", delta_lpm, delta_time, to_permil(delta_lpm, delta_time)); + LOG_INFO("Deep LPM : %10lu/%10lu (%lu permil)\n", delta_deep_lpm, delta_time, to_permil(delta_deep_lpm, delta_time)); + LOG_INFO("Radio Tx : %10lu/%10lu (%lu permil)\n", delta_tx, delta_time, to_permil(delta_tx, delta_time)); + LOG_INFO("Radio Rx : %10lu/%10lu (%lu permil)\n", delta_rx, delta_time, to_permil(delta_rx, delta_time)); + LOG_INFO("Radio total : %10lu/%10lu (%lu permil)\n", delta_tx+delta_rx, delta_time, to_permil(delta_tx+delta_rx, delta_time)); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(simple_energest_process, ev, data) +{ + static struct etimer periodic_timer; + PROCESS_BEGIN(); + + etimer_set(&periodic_timer, SIMPLE_ENERGEST_PERIOD); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer)); + etimer_reset(&periodic_timer); + simple_energest_step(); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +simple_energest_init(void) +{ + energest_flush(); + last_time = ENERGEST_GET_TOTAL_TIME(); + last_cpu = energest_type_time(ENERGEST_TYPE_CPU); + last_lpm = energest_type_time(ENERGEST_TYPE_LPM); + curr_tx = energest_type_time(ENERGEST_TYPE_TRANSMIT); + last_deep_lpm = energest_type_time(ENERGEST_TYPE_DEEP_LPM); + last_rx = energest_type_time(ENERGEST_TYPE_LISTEN); + process_start(&simple_energest_process, NULL); +} + +/** @} */ diff --git a/os/services/simple-energest/simple-energest.h b/os/services/simple-energest/simple-energest.h new file mode 100644 index 000000000..4f7281e9c --- /dev/null +++ b/os/services/simple-energest/simple-energest.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, RISE SICS. + * 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 Institute 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 INSTITUTE 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 INSTITUTE 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 simple-energest + * @{ + */ + + /** + * \file + * A process that periodically prints out the time spent in + * radio tx, radio rx, total time and duty cycle. + * + * \author Simon Duquennoy + */ + +#ifndef SIMPLE_ENERGEST_H_ +#define SIMPLE_ENERGEST_H_ + +/** \brief The period at which Energest statistics will be logged */ +#ifdef SIMPLE_ENERGEST_CONF_PERIOD +#define SIMPLE_ENERGEST_PERIOD SIMPLE_ENERGEST_CONF_PERIOD +#else /* SIMPLE_ENERGEST_CONF_PERIOD */ +#define SIMPLE_ENERGEST_PERIOD (CLOCK_SECOND * 60) +#endif /* SIMPLE_ENERGEST_CONF_PERIOD */ + +/** + * Initialize the deployment module + */ +void simple_energest_init(void); + +#endif /* SIMPLE_ENERGEST_H_ */ +/** @} */ From e0e58f6eec5d14b5076af8a6a4dd30455d844375 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 23 May 2018 12:46:32 -0700 Subject: [PATCH 16/55] Added example for simple-energest --- examples/libs/simple-energest/Makefile | 6 +++ examples/libs/simple-energest/README.md | 1 + examples/libs/simple-energest/example.c | 56 +++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 examples/libs/simple-energest/Makefile create mode 100644 examples/libs/simple-energest/README.md create mode 100644 examples/libs/simple-energest/example.c diff --git a/examples/libs/simple-energest/Makefile b/examples/libs/simple-energest/Makefile new file mode 100644 index 000000000..056aa5c43 --- /dev/null +++ b/examples/libs/simple-energest/Makefile @@ -0,0 +1,6 @@ +CONTIKI_PROJECT = example +all: $(CONTIKI_PROJECT) + +MODULES += os/services/simple-energest +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/libs/simple-energest/README.md b/examples/libs/simple-energest/README.md new file mode 100644 index 000000000..42e382b5f --- /dev/null +++ b/examples/libs/simple-energest/README.md @@ -0,0 +1 @@ +This is a minimal example for the module simple-energest. diff --git a/examples/libs/simple-energest/example.c b/examples/libs/simple-energest/example.c new file mode 100644 index 000000000..e9d6d585c --- /dev/null +++ b/examples/libs/simple-energest/example.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, Swedish Institute of Computer Science. + * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * A very simple example of simple-energest + * \author + * Simon Duquennoy + */ + +#include "contiki.h" + +#include /* For printf() */ +/*---------------------------------------------------------------------------*/ +PROCESS(example_process, "Example process: simple-energest"); +AUTOSTART_PROCESSES(&example_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(example_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Do nothing, just let simple-energest write its summary + * at a period of SIMPLE_ENERGEST_CONF_PERIOD */ + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ From 77939f421cf6beba20ee27ae858048a3ac73d344 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 23 May 2018 12:49:25 -0700 Subject: [PATCH 17/55] Added example for the shell --- examples/libs/shell/Makefile | 6 ++++ examples/libs/shell/README.md | 1 + examples/libs/shell/example.c | 56 +++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 examples/libs/shell/Makefile create mode 100644 examples/libs/shell/README.md create mode 100644 examples/libs/shell/example.c diff --git a/examples/libs/shell/Makefile b/examples/libs/shell/Makefile new file mode 100644 index 000000000..b44069cf8 --- /dev/null +++ b/examples/libs/shell/Makefile @@ -0,0 +1,6 @@ +CONTIKI_PROJECT = example +all: $(CONTIKI_PROJECT) + +MODULES += os/services/shell +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/libs/shell/README.md b/examples/libs/shell/README.md new file mode 100644 index 000000000..a76aa8c05 --- /dev/null +++ b/examples/libs/shell/README.md @@ -0,0 +1 @@ +This is a minimal example for the shell. diff --git a/examples/libs/shell/example.c b/examples/libs/shell/example.c new file mode 100644 index 000000000..9d2320c58 --- /dev/null +++ b/examples/libs/shell/example.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, Swedish Institute of Computer Science. + * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * A very simple example using the shell + * \author + * Simon Duquennoy + */ + +#include "contiki.h" + +#include /* For printf() */ +/*---------------------------------------------------------------------------*/ +PROCESS(example_process, "Example process: shell"); +AUTOSTART_PROCESSES(&example_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(example_process, ev, data) +{ + PROCESS_BEGIN(); + + /* This process does nothing. Connect to the node with `make login` + * to use the shell. */ + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ From d972dc607e29a9cfe611e95c88e4a328adbf4571 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 23 May 2018 12:50:20 -0700 Subject: [PATCH 18/55] Added compile test for the shell and simple-energest examples --- tests/03-compile-arm-ports-02/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/03-compile-arm-ports-02/Makefile b/tests/03-compile-arm-ports-02/Makefile index defd10a96..f0c7155ae 100644 --- a/tests/03-compile-arm-ports-02/Makefile +++ b/tests/03-compile-arm-ports-02/Makefile @@ -62,6 +62,8 @@ dev/gpio-hal/openmote-cc2538 \ dev/leds/openmote-cc2538 \ rpl-border-router/openmote-cc2538 \ libs/ipv6-hooks/openmote-cc2538 \ +libs/shell/openmote-cc2538 \ +libs/simple-energest/openmote-cc2538 \ TOOLS= From 1f5d109f336e5f48d5e4db40f79d215278747472 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 25 May 2018 12:29:26 -0700 Subject: [PATCH 19/55] Remove left-over instances of WITH_TINYOS_AUTO_IDS --- arch/platform/jn516x/platform.c | 4 ---- arch/platform/sky/platform.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/arch/platform/jn516x/platform.c b/arch/platform/jn516x/platform.c index 9d44444e8..bc9d7b955 100644 --- a/arch/platform/jn516x/platform.c +++ b/arch/platform/jn516x/platform.c @@ -158,10 +158,6 @@ xosc_init(void) return bAHI_Set32KhzClockMode(E_AHI_XTAL); } /*---------------------------------------------------------------------------*/ -#if WITH_TINYOS_AUTO_IDS -uint16_t TOS_NODE_ID = 0x1234; /* non-zero */ -uint16_t TOS_LOCAL_ADDRESS = 0x1234; /* non-zero */ -#endif /* WITH_TINYOS_AUTO_IDS */ void platform_init_stage_one(void) { diff --git a/arch/platform/sky/platform.c b/arch/platform/sky/platform.c index 670e5443d..89d18d3e8 100644 --- a/arch/platform/sky/platform.c +++ b/arch/platform/sky/platform.c @@ -111,10 +111,6 @@ set_lladdr(void) linkaddr_set_node_addr(&addr); } /*---------------------------------------------------------------------------*/ -#if WITH_TINYOS_AUTO_IDS -uint16_t TOS_NODE_ID = 0x1234; /* non-zero */ -uint16_t TOS_LOCAL_ADDRESS = 0x1234; /* non-zero */ -#endif /* WITH_TINYOS_AUTO_IDS */ void platform_init_stage_one(void) { From 9aa08fd3024a37ec739c01be13c693f3d6686614 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 26 May 2018 02:04:22 +0100 Subject: [PATCH 20/55] Reposition the generic flash driver in the doxygen tree --- arch/dev/ext-flash/ext-flash.c | 4 ++-- arch/dev/ext-flash/ext-flash.h | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/arch/dev/ext-flash/ext-flash.c b/arch/dev/ext-flash/ext-flash.c index 10e953ffa..c9378d2aa 100644 --- a/arch/dev/ext-flash/ext-flash.c +++ b/arch/dev/ext-flash/ext-flash.c @@ -29,11 +29,11 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup sensortag-cc26xx-ext-flash + * \addtogroup ext-flash * @{ * * \file - * Sensortag/LaunchPad External Flash Driver + * Implementation of a generic external SPI flash driver */ /*---------------------------------------------------------------------------*/ #include "contiki.h" diff --git a/arch/dev/ext-flash/ext-flash.h b/arch/dev/ext-flash/ext-flash.h index 20748a2f0..73b7320f8 100644 --- a/arch/dev/ext-flash/ext-flash.h +++ b/arch/dev/ext-flash/ext-flash.h @@ -29,14 +29,23 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup common-cc26xx-peripherals + * \addtogroup dev * @{ * - * \defgroup sensortag-cc26xx-ext-flash SensorTag/LaunchPad External Flash + * \defgroup ext-flash Generic external SPI flash driver + * + * This is a generic driver for external SPI flash memories. The driver has + * been tested and works with multiple external SPI flash parts. The list of + * parts the driver has been tested against is shown in the README in this + * directory. + * + * If you successfully use this driver with a part that is not listed in the + * README, please let us know so we can update it. + * * @{ * * \file - * Header file for the Sensortag/LaunchPad External Flash Driver + * Header file for the external SPI flash API */ /*---------------------------------------------------------------------------*/ #ifndef EXT_FLASH_H_ From 92e4ff3ef457ef1cc790324ada49b5e1a2cbc73b Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 26 May 2018 02:04:42 +0100 Subject: [PATCH 21/55] Tidy-up doxygen for uiplib --- os/net/ipv6/uiplib.c | 8 +++++++- os/net/ipv6/uiplib.h | 31 +++++++++++++++---------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/os/net/ipv6/uiplib.c b/os/net/ipv6/uiplib.c index cd6d15c8b..a6d8b4f0c 100644 --- a/os/net/ipv6/uiplib.c +++ b/os/net/ipv6/uiplib.c @@ -33,8 +33,11 @@ */ /** + * \addtogroup uip-addr-lib + * @{ + * * \file - * Various uIP library functions. + * Implementation of the IP address manipulation library * \author * Nicolas Tsiftes * Niclas Finne @@ -223,3 +226,6 @@ uiplib_ipaddr_snprint(char *buf, size_t size, const uip_ipaddr_t *addr) return n; } /*---------------------------------------------------------------------------*/ +/** + * @} + */ diff --git a/os/net/ipv6/uiplib.h b/os/net/ipv6/uiplib.h index 3a935f51b..b30a1bcb5 100644 --- a/os/net/ipv6/uiplib.h +++ b/os/net/ipv6/uiplib.h @@ -31,23 +31,24 @@ * * */ - -/** - * \file - * Various uIP library functions. - * \author - * Adam Dunkels - * - */ - #ifndef UIPLIB_H_ #define UIPLIB_H_ #include "net/ipv6/uip.h" /** - * \addtogroup uipconvfunc + * \addtogroup uip * @{ + * + * \defgroup uip-addr-lib uIP address manipulation library + * + * A library with various IP address manipulation functions + * @{ + * + * \file + * Header file for the IP address manipulation library + * \author + * Adam Dunkels */ /** @@ -77,10 +78,6 @@ int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr); int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr); /** @} */ -/** - * \addtogroup uiplib - * @{ - */ /* The maxium length of an IPv6 string, including terminating null bytes * fd01:0002:0003:0004:0005:0006:0007:0008 => 39 + 1 bytes */ @@ -103,6 +100,8 @@ void uiplib_ipaddr_print(const uip_ipaddr_t *addr); */ int uiplib_ipaddr_snprint(char *buffer, size_t size, const uip_ipaddr_t *addr); -/** @} */ - #endif /* UIPLIB_H_ */ +/** + * @} + * @} + */ From 9610adb5e17e4cde044ce54917df59b48b853e34 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 25 May 2018 12:38:09 -0700 Subject: [PATCH 22/55] RPL Lite urgent probing logs: from WARN to INFO --- os/net/routing/rpl-lite/rpl-neighbor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/os/net/routing/rpl-lite/rpl-neighbor.c b/os/net/routing/rpl-lite/rpl-neighbor.c index 5f2f7f69a..a066af313 100644 --- a/os/net/routing/rpl-lite/rpl-neighbor.c +++ b/os/net/routing/rpl-lite/rpl-neighbor.c @@ -405,9 +405,9 @@ rpl_neighbor_select_best(void) /* The best is not fresh. Probe it (unless there is already an urgent probing target). We will be called back after the probing anyway. */ if(curr_instance.dag.urgent_probing_target == NULL) { - LOG_WARN("best parent is not fresh, schedule urgent probing to "); - LOG_WARN_6ADDR(rpl_neighbor_get_ipaddr(best)); - LOG_WARN_("\n"); + LOG_INFO("best parent is not fresh, schedule urgent probing to "); + LOG_INFO_6ADDR(rpl_neighbor_get_ipaddr(best)); + LOG_INFO_("\n"); curr_instance.dag.urgent_probing_target = best; rpl_schedule_probing_now(); } From 471a7093b9a2a015c0a89d7fea1947b321c691ce Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 25 May 2018 12:40:00 -0700 Subject: [PATCH 23/55] nbr-policy: fix typo in logs --- os/net/routing/rpl-lite/rpl-nbr-policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/os/net/routing/rpl-lite/rpl-nbr-policy.c b/os/net/routing/rpl-lite/rpl-nbr-policy.c index 3db84f3a8..9adbc3b90 100644 --- a/os/net/routing/rpl-lite/rpl-nbr-policy.c +++ b/os/net/routing/rpl-lite/rpl-nbr-policy.c @@ -127,12 +127,12 @@ find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio) /* Add the new neighbor only if it is better than the current worst. */ if(dio->rank + curr_instance.min_hoprankinc < worst_rank - curr_instance.min_hoprankinc / 2) { /* Found *great* neighbor - add! */ - LOG_INFO("nbr-policy: DIO rank %u, worse_rank %u -- add to cache\n", + LOG_INFO("nbr-policy: DIO rank %u, worst_rank %u -- add to cache\n", dio->rank, worst_rank); return worst_rank_nbr_lladdr; } - LOG_INFO("nbr-policy: DIO rank %u, worse_rank %u -- do not add to cache\n", + LOG_INFO("nbr-policy: DIO rank %u, worst_rank %u -- do not add to cache\n", dio->rank, worst_rank); return NULL; } From 361725038390648907530feb74e25d1ad230daa9 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 25 May 2018 12:41:31 -0700 Subject: [PATCH 24/55] nbr-policy: change log level from INFO to DBG for most logs --- os/net/routing/rpl-lite/rpl-nbr-policy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/os/net/routing/rpl-lite/rpl-nbr-policy.c b/os/net/routing/rpl-lite/rpl-nbr-policy.c index 9adbc3b90..9752b1446 100644 --- a/os/net/routing/rpl-lite/rpl-nbr-policy.c +++ b/os/net/routing/rpl-lite/rpl-nbr-policy.c @@ -104,7 +104,7 @@ update_state(void) /* how many more IP neighbors can be have? */ num_free = NBR_TABLE_MAX_NEIGHBORS - num_used; - LOG_INFO("nbr-policy: free: %d, parents: %d\n", num_free, num_parents); + LOG_DBG("nbr-policy: free: %d, parents: %d\n", num_free, num_parents); } /*---------------------------------------------------------------------------*/ static const linkaddr_t * @@ -127,12 +127,12 @@ find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio) /* Add the new neighbor only if it is better than the current worst. */ if(dio->rank + curr_instance.min_hoprankinc < worst_rank - curr_instance.min_hoprankinc / 2) { /* Found *great* neighbor - add! */ - LOG_INFO("nbr-policy: DIO rank %u, worst_rank %u -- add to cache\n", + LOG_DBG("nbr-policy: DIO rank %u, worst_rank %u -- add to cache\n", dio->rank, worst_rank); return worst_rank_nbr_lladdr; } - LOG_INFO("nbr-policy: DIO rank %u, worst_rank %u -- do not add to cache\n", + LOG_DBG("nbr-policy: DIO rank %u, worst_rank %u -- do not add to cache\n", dio->rank, worst_rank); return NULL; } From 857c7f51b2fcabd641b075757903cda9dc923762 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Fri, 25 May 2018 12:51:46 -0700 Subject: [PATCH 25/55] rpl-dag-root: more readable logging of DAG root node IPv6 addresses --- os/net/routing/rpl-lite/rpl-dag-root.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/os/net/routing/rpl-lite/rpl-dag-root.c b/os/net/routing/rpl-lite/rpl-dag-root.c index c96fd6656..c3e356828 100644 --- a/os/net/routing/rpl-lite/rpl-dag-root.c +++ b/os/net/routing/rpl-lite/rpl-dag-root.c @@ -94,11 +94,12 @@ set_global_address(uip_ipaddr_t *prefix, uip_ipaddr_t *iid) uip_ds6_addr_add(&root_ipaddr, 0, ADDR_AUTOCONF); - LOG_INFO("IPv6 addresses: "); + LOG_INFO("IPv6 addresses:\n"); for(i = 0; i < UIP_DS6_ADDR_NB; i++) { state = uip_ds6_if.addr_list[i].state; if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + LOG_INFO("-- "); LOG_INFO_6ADDR(&uip_ds6_if.addr_list[i].ipaddr); LOG_INFO_("\n"); } From cf8d2b6f135811479aebb6f7071b494ce3bd17c3 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:13:44 +0100 Subject: [PATCH 26/55] Remove jn516x serialdump source, makefile and binaries --- tools/jn516x/Makefile | 30 --- tools/jn516x/serialdump-linux | Bin 12663 -> 0 bytes tools/jn516x/serialdump.c | 396 ---------------------------------- 3 files changed, 426 deletions(-) delete mode 100644 tools/jn516x/Makefile delete mode 100644 tools/jn516x/serialdump-linux delete mode 100644 tools/jn516x/serialdump.c diff --git a/tools/jn516x/Makefile b/tools/jn516x/Makefile deleted file mode 100644 index 2c4254a71..000000000 --- a/tools/jn516x/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -ifndef HOST_OS - ifeq ($(OS),Windows_NT) - HOST_OS := Windows - else - HOST_OS := $(shell uname) - endif -endif - -ifeq ($(HOST_OS),Windows) - SERIALDUMP = serialdump-windows -endif - -ifeq ($(HOST_OS),Darwin) - SERIALDUMP = serialdump-macos -endif - -ifndef SERIALDUMP - # Assume Linux - SERIALDUMP = serialdump-linux -endif - -all: $(SERIALDUMP) - -CFLAGS += -Wall -Werror - -$(SERIALDUMP): serialdump.c - $(CC) -O2 -o $@ $< - -clean: - rm -f $(SERIALDUMP) diff --git a/tools/jn516x/serialdump-linux b/tools/jn516x/serialdump-linux deleted file mode 100644 index 69fd8cfdbb5347bfc6e91999ffc9685af6722e94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12663 zcmeHNe|%KcmA^BYz=$CeHMLQwJnKY*g)xCZ0kIMi&{RN50^%Y*Ci8=tWim6Jc>}>l zjXMcsHb&DHt+uQm{H(RzUE6g(b=go^8yX6>-EOgNt-ENYR=YC=yA~8t(An?z-uIH1 zQ9t|H{cHc|%jf3a?>Xn5d+xpGo_FWId-t*x%N-7fupXx<6GXAEy4;P(U%Fgz8igj# z6LsP;F-=SYiM+-h$RKH`z*G*J3#kmL9k~4-mz(J#U?%cFmI;{Obk-3U&D#U-!-vl$2GCw>{v9O>GGu$zB!7=y5!%m zYAyb&eo$u(66;nYaqP(dhZmiHc=r1be7WPFe{kW+MW+(?pZ8x~Uv%un4reZk3r=}+AB+mX#{{cLW+<7P$kxe)oI7C=snAsKs!Gh;~c&y`^NAW{CN z68@qRJhueDP=bG6g1=URmzUtnZT-=}^Of*lF2P?c!LOEJk4+!@^Q#j69VPg53BIia z?0sA`T$mW5eeIcRy(HJz@*+V>Z5kp9bik z^M&4evz|7B(YT&Thk_y;j%Csjq3g+1G;W0TKxB&ubwv%445dWXkQ7K$fCCLIffk|Mk<6*WR4kqpHJb;e|i zMqsn4G#rQhP03gF4C%N#+rnmK|_4Rbiz zbmj;=8gsPlWj{lFYfxPW;DVk~o5xP&?EXkqRV;zs7^&mdzAmAbYM@EcT5U<@rBgl(Gli8%E`L@n3PC3$=>1Zv2q~bF?Ej60eq+qaImJyhLJ-eq=pyy~Lb_$R=VFs1iFbsS>&A-h2*b^^N3Oymg-bQ&?V70V`t3u{Bxou*-V@dLUJiKl6UE zH~?|Vm=?MCPN4GLQkkb8n>Rt3!QI{@8ip+{vfnV-gQz&r?VW}8bKPE7el6%M(4JPR z@AY=6YSMJJl6}nE4bp41KgaT!`Xm%!%qYZWz%)?&fNg9?{k{=Te-lKW)=;xyB=_%w z-QLD?r~Yoh@YekRf+E-G%~wG%_s86O&%c^$_j=E3?`?eaF^(N{l+zyCi?(uy23mR> z(eqhj?BAg#dQas7lXDq|sfOU;cg_y>dikQvJ@@>7p3felUatG8#=)nqqyRg;PeWnQ z@HU?MrYVf-m{B>}2oo}wBa6x|j68R1)RX@l%wg9ifiPywt?UMDZ31)Psa`fd#=8!@ zhY$RIn&U|J*o>J+Jb!)2^A`?O9>AEf&Q#Vx=lgcadY<0f;2bdOMvM^~ryQrb4oWG1 z=UHXIdGHfY?>%rm&)yZ@8H4*}je*;|+F;}4LE}o%^RC;o^A%|E>^)HQ_5~kyxjoOc zIR=+LvDoX`dB0?gfYA>I-P;8hz7{UrR||`u-T+rC%tfhTB!4wVVqlkC9ih3O;1clk zwZb(ALvL-kUEesG9p%z+T}bbQ_x$udX<=_UUL2%XnDpD>3cETsHaLFsslBWu`w5ws`C57`-qL z?bchk9o=AeIbWbxz>%tvy9ax{jr1*4xf~)E1c%bs!5iT3vZb$p?b$n-lDDAPbNv+0 z0|&B)9Sh&_^gROC=!f4StY`yRhj^Ku-_wnLdU~7TlaG#=%lOx4ip4?>K0XAg8myeY zC+I(WCodlH^uDX?K&aI6Z^Qfn6plY)_6suEQAdCF6==$yz38qTx&IjcGN*#l+>F3X zY&k^3(fmHMZb8S|QT5oDrt!Y85<8!N2BO)s7qBJIeSAG0A0BT{N};z=OP@#Sqpd4p z>*AxHzSq$tCiJqSg_E3vts;LDRW5LO`bODt#(p&JW-y`=97$N}hAo_h{B<0VF3jdw zgqVin}-X)N-(<5w^$;lZlSZ-*FQ5<8>( z8z?XQz%#fTO<-;rMjUTaFAaeOGQh8g5q%?f??}kVMs^(99TVGe1eU&q{66!eG;MZV$MB!=FrT)I7#%+jE znMA`;jwcn!0ABby1-1$VMNLk4{!*-#!ry{A#CnTg^7QV2qQx%{?nNdtsY8>G4j;u# zNi~I=QKB5`*EEdu{Q|2D-L5G#o9$-1VTkdU*|XK(m!WLc^TRjLVAu#(`YuKoqe92Z zcbKM6H18~&S+(>!*Y@O*;gPYnpC^Uu9-XOfg|imEg@v<^kr9+x*!haW1Eeq}l7c<4 zC@|3F%h6bN!Ns25O_&AcMam4$S^ksY!mRzMmOuWsEThq4{`%AAL_k^TG<*fZ(&c`F z3MzJN!VDA|&>W3)7pBk@hGClGU?e*OUqm~X(gQVBfEX0 zqEmH#u`1WmTBwqiZtHA8G}zH(WZSGXIKxQ{On+E`8-U&V5< z_Htn`3L80ad|yz6KV%9&fXF_+SxA{g%6C9%c;oimZ?M%|-M%KW3BSuDZ$991e_>q& z(bt_Hg;8&XhX$s5N5ezof5QV z38nmjGtS%(5Bz?H?VDcDz~t_RFxwv&sXK$EMJXs_Fzr!#SNo~6YFv>;OCuuwPEaC z??M9IlwSKB1p7{V?t2m4Y&d%SGcta7_FB=5;_r`(V}RWGM^I(qDdW=9qh*<2LXU>3 z`CCCee%O3Zu$Ge(Z8j34H6L7b_qDlG$7jGEi;r+=iL_GWY_(BMt*=;G%c%9ap}y01 z&4Y0lf$T$LsFp9Bltx@;nmV}p)t>h@ZTmG|#N_@|ax<@H4_0ruebj2sYU^ci3tyB| zp?qrXEe*wWZTSZf{_Ytq$B*RfiRl9|>=V9M0jd0N-bA>}x>1~Y=)ecgzSG84%CGRg zUXYvR<*1;@-M6c_>uCzgEkNd#?7``B`*(cmko`F|YX087Lbmu-{5;R{2Q~t$JmXlK z_HPa?($b++)E^6GI+NOl*XdkrHnsgBsy`@6wumMw64}V6Ty&OCLx6+ zD-n-vmwc_xAB$;0zv0)SX;m$W)2@(_o;g8(Tr(0{BpM8j%b<5@yG;8A*oo#hQq&&| zYCN5iO@{n|h-QSk3=QYTG|94C)9TWpkk;vsYe}e+!q!Pz-AoCUPAwQp2U5`_PtjnSREqW0F=wVktTgIev4i)vRcs%;b31VdY|F^uhP^&%5bXOhW8$_NEDdFHlA zt4&V#e{u+^rux>^jq zJmS+f+-zN(;BAjZmkCqr=z~ z>i~0HzdV#wXN8`JxAQ+_6SDx}mDVJQ8CjK7R=Oa2FM5m*o?EE;qkLYDoNHO#|_ZB(WQGY`zk-6MMGAdSDd) z*AKs+Tb1VTbh(!!twRbUZAIFF^dQpXNPCeEA-#a~JEYS{lloomi;=EGnvb*`X&q7+ zX)DqWqz926N7{>Y2MAQ#rm$N)BG{X@0D<10B3nC`NfzNX87|i^lQY)W?mT@Pz@u zN^mPFe4&UQPWd}SdL)RN7E(2Ie=6nQu4-82KMz0*%Ke?u02)p}A^!PfD@tQWIxT#G zL?^dR*2w){&U(|}~j^~3-9-uFt5 z`e(_t0OBWhg6(qM@PkV|%3MEuD95x4iED>)Tu(2tT>!2x6r~K;)jA}uDavvEode*y zvmUE>I|y7ml;gTtj|ORr)h_8wTadWcSmt`;QSxe(?d<}JJCN{sMb_bZJpnll*wV*7 z(9yFE8AiGc?$)Oz4cIz&rT#uPQzN%FzCmuPJ+iVq3l;| zay)CG5giO_=0iC?4k#FXQ>bV05Qa*uJ~&Bu~^9GLnjC-2(e z=jLKlhM6Vz6v~#|dfdlZ54mbvKP{u@HrQhlXs3F$9W@-4{hN5zJ_G!ztDu}0nK_S z!*mkK($@pI9!<3avV17R=L{0tr+s@M*RKh&gaq@^%=~@i)K_m}%B?iZ%*bQndxyHL z=a(A#N{0DZMdqAa>$&$z=*FPn6T57K_R+WCZWHwF$7cL#%XsiCeJFnDVLT#H-AYq; zx)fF|GrlOSEM^>0ST(?Sp|Dzwj0*~@*|Xl8Win!^b*}hQOul~=W-ruxSz*4_)%sMJ z5lRTILxs7b@o>H2DHCeJaa}1)Pgd(kVS21uCkm@o$@QQxXGQtF!rT=o|5jKi;@&u76~}7s>lk+~*Nf{%6P;M~EG`0at3z3D6_ou=p2<_kiv8v7YtNey$O# zJ>Ho6B(OF94vfDBY_&)JTwrVb9T@*sV4e%pvoC~ww~}u@ob4?o_)9jdf&Vq&A&d__ z|3c?f@f~1mJ~iAj9Ja|*-%o(|U_L0%`(u2s^7t4K>$XPxwnY9^37%qG{M0uc*z)fS z5vf02!v9dD=ak@^OYo)=ybYM20Q}I!`Q8cqm~B2DDv|%261*Sy*swKUxc^te ze;Jtfc%feEf31Xn8kp~IHUA#*KJbXGeGeGp{&0zyMnS|go}bWOjo5rR9*auwO*X87 zuLE29INn=qeAeG#!<64+!{q-XF!w_!qJ6~M@l#`80N4L;I4a~-K^^D7xXc$1VJ{p{ z8_856>8ls1u8vGt1X4!Y$b`eFq3fS-UZbyQZEM$cft!S(%~2furF5fH55y929Nc~c zN!No3eRC|);g9J-Bauq${!AAR6+4r$5DpK0^XDyWfaZ@7(z*LrdwCuE^VD{scKdAm^L~zLK>*x~vfue3wnzu{s>eNL}J4Fx4Uo<=&x0B_?QFU$8 zPFA-}?G)9K(rc;X5{)o(><;TV8P_@071wc6y?LY5PEl7)?Ub=gt9ByXV7%A7Cp(cj z;c_Xj*G^;y(+NG|j|VZNJn5dmoOoT=`Wj#t8N2#wCw}OPtDPy&wCx1jEnPd=<}LIu zb+^|pAWz@z1oJYmorD$e;j6zB1eC+7yS)<_;iMkf##Zr#X97dV&tKEU% -#include -#include -#include -#include -#include -#include -#include -#include - -#define BAUDRATE B115200 -#define BAUDRATE_S "115200" -#ifdef linux -#define MODEMDEVICE "/dev/ttyS0" -#else -#define MODEMDEVICE "/dev/com1" -#endif /* linux */ - -#define SLIP_END 0300 -#define SLIP_ESC 0333 -#define SLIP_ESC_END 0334 -#define SLIP_ESC_ESC 0335 - -#define CSNA_INIT 0x01 - -#define BUFSIZE 40 -#define HCOLS 20 -#define ICOLS 18 - -#define MODE_START_DATE 0 -#define MODE_DATE 1 -#define MODE_START_TEXT 2 -#define MODE_TEXT 3 -#define MODE_INT 4 -#define MODE_HEX 5 -#define MODE_SLIP_AUTO 6 -#define MODE_SLIP 7 -#define MODE_SLIP_HIDE 8 - -static unsigned char rxbuf[2048]; - -static int -usage(int result) -{ - printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] [SERIALDEVICE]\n"); - printf(" -x for hexadecimal output\n"); - printf(" -i for decimal output\n"); - printf(" -s for automatic SLIP mode\n"); - printf(" -so for SLIP only mode (all data is SLIP packets)\n"); - printf(" -sn to hide SLIP packages\n"); - printf(" -T[format] to add time for each text line\n"); - printf(" (see man page for strftime() for format description)\n"); - return result; -} - -static void -print_hex_line(unsigned char *prefix, unsigned char *outbuf, int index) -{ - int i; - - printf("\r%s", prefix); - for(i = 0; i < index; i++) { - if((i % 4) == 0) { - printf(" "); - } - printf("%02X", outbuf[i] & 0xFF); - } - printf(" "); - for(i = index; i < HCOLS; i++) { - if((i % 4) == 0) { - printf(" "); - } - printf(" "); - } - for(i = 0; i < index; i++) { - if(outbuf[i] < 30 || outbuf[i] > 126) { - printf("."); - } else { - printf("%c", outbuf[i]); - } - } -} - -int -main(int argc, char **argv) -{ - struct termios options; - fd_set mask, smask; - int fd; - speed_t speed = BAUDRATE; - char *speedname = BAUDRATE_S; - char *device = MODEMDEVICE; - char *timeformat = NULL; - unsigned char buf[BUFSIZE], outbuf[HCOLS]; - unsigned char mode = MODE_START_TEXT; - int nfound, flags = 0; - unsigned char lastc = '\0'; - - int index = 1; - while(index < argc) { - if(argv[index][0] == '-') { - switch(argv[index][1]) { - case 'b': - /* set speed */ - if(strcmp(&argv[index][2], "38400") == 0) { - speed = B38400; - speedname = "38400"; - } else if(strcmp(&argv[index][2], "19200") == 0) { - speed = B19200; - speedname = "19200"; - } else if(strcmp(&argv[index][2], "57600") == 0) { - speed = B57600; - speedname = "57600"; - } else if(strcmp(&argv[index][2], "115200") == 0) { - speed = B115200; - speedname = "115200"; - } else if(strcmp(&argv[index][2], "230400") == 0) { - speed = B230400; - speedname = "230400"; - } else if(strcmp(&argv[index][2], "460800") == 0) { - speed = B460800; - speedname = "460800"; - } else if(strcmp(&argv[index][2], "500000") == 0) { - speed = B500000; - speedname = "500000"; - } else if(strcmp(&argv[index][2], "576000") == 0) { - speed = B576000; - speedname = "576000"; - } else if(strcmp(&argv[index][2], "921600") == 0) { - speed = B921600; - speedname = "921600"; - } else if(strcmp(&argv[index][2], "1000000") == 0) { - speed = B1000000; - speedname = "1000000"; - } else { - fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); - return usage(1); - } - break; - case 'x': - mode = MODE_HEX; - break; - case 'i': - mode = MODE_INT; - break; - case 's': - switch(argv[index][2]) { - case 'n': - mode = MODE_SLIP_HIDE; - break; - case 'o': - mode = MODE_SLIP; - break; - default: - mode = MODE_SLIP_AUTO; - break; - } - break; - case 'T': - if(strlen(&argv[index][2]) == 0) { - timeformat = "%Y-%m-%d %H:%M:%S"; - } else { - timeformat = &argv[index][2]; - } - mode = MODE_START_DATE; - break; - case 'h': - return usage(0); - default: - fprintf(stderr, "unknown option '%c'\n", argv[index][1]); - return usage(1); - } - index++; - } else { - device = argv[index++]; - if(index < argc) { - fprintf(stderr, "too many arguments\n"); - return usage(1); - } - } - } - fprintf(stderr, "connecting to %s (%s)", device, speedname); - -#ifdef O_SYNC - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY /*| O_DIRECT*/ | O_SYNC); - if(fd < 0 && errno == EINVAL){ // O_SYNC not supported (e.g. raspberian) - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT); - } -#else - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC ); -#endif - if(fd < 0) { - fprintf(stderr, "\n"); - perror("open"); - exit(-1); - } - fprintf(stderr, " [OK]\n"); - - if(fcntl(fd, F_SETFL, 0) < 0) { - perror("could not set fcntl"); - exit(-1); - } - - if(tcgetattr(fd, &options) < 0) { - perror("could not get options"); - exit(-1); - } - /* fprintf(stderr, "serial options set\n"); */ - cfsetispeed(&options, speed); - cfsetospeed(&options, speed); - /* Enable the receiver and set local mode */ - options.c_cflag |= (CLOCAL | CREAD); - /* Mask the character size bits and turn off (odd) parity */ - options.c_cflag &= ~(CSIZE | PARENB | PARODD); - /* Select 8 data bits */ - options.c_cflag |= CS8; - - /* Raw input */ - options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); - /* Raw output */ - options.c_oflag &= ~OPOST; - - if(tcsetattr(fd, TCSANOW, &options) < 0) { - perror("could not set options"); - exit(-1); - } - - /* Make read() return immediately */ - /* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */ - /* perror("\ncould not set fcntl"); */ - /* exit(-1); */ - /* } */ - - FD_ZERO(&mask); - FD_SET(fd, &mask); - FD_SET(fileno(stdin), &mask); - - index = 0; - for(;;) { - smask = mask; - nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); - if(nfound < 0) { - if(errno == EINTR) { - fprintf(stderr, "interrupted system call\n"); - continue; - } - /* something is very wrong! */ - perror("select"); - exit(1); - } - - if(FD_ISSET(fileno(stdin), &smask)) { - /* data from standard in */ - int n = read(fileno(stdin), buf, sizeof(buf)); - if(n < 0) { - perror("could not read"); - exit(-1); - } else if(n > 0) { - /* because commands might need parameters, lines needs to be - separated which means the terminating LF must be sent */ - /* while(n > 0 && buf[n - 1] < 32) { */ - /* n--; */ - /* } */ - if(n > 0) { - int i; - /* fprintf(stderr, "SEND %d bytes\n", n);*/ - /* write slowly */ - for(i = 0; i < n; i++) { - if(write(fd, &buf[i], 1) <= 0) { - perror("write"); - exit(1); - } else { - fflush(NULL); - usleep(6000); - } - } - } - } else { - /* End of input, exit. */ - exit(0); - } - } - - if(FD_ISSET(fd, &smask)) { - int i, j, n = read(fd, buf, sizeof(buf)); - if(n < 0) { - perror("could not read"); - exit(-1); - } - - for(i = 0; i < n; i++) { - switch(mode) { - case MODE_START_TEXT: - case MODE_TEXT: - printf("%c", buf[i]); - break; - case MODE_START_DATE: { - time_t t; - t = time(&t); - strftime(outbuf, HCOLS, timeformat, localtime(&t)); - printf("%s|", outbuf); - mode = MODE_DATE; - } - /* continue into the MODE_DATE */ - case MODE_DATE: - printf("%c", buf[i]); - if(buf[i] == '\n') { - mode = MODE_START_DATE; - } - break; - case MODE_INT: - printf("%03d ", buf[i]); - if(++index >= ICOLS) { - index = 0; - printf("\n"); - } - break; - case MODE_HEX: - rxbuf[index++] = buf[i]; - if(index >= HCOLS) { - print_hex_line("", rxbuf, index); - index = 0; - printf("\n"); - } - break; - - case MODE_SLIP_AUTO: - case MODE_SLIP_HIDE: - if(!flags && (buf[i] != SLIP_END)) { - /* Not a SLIP packet? */ - printf("%c", buf[i]); - break; - } - /* continue to slip only mode */ - case MODE_SLIP: - switch(buf[i]) { - case SLIP_ESC: - lastc = SLIP_ESC; - break; - - case SLIP_END: - if(index > 0) { - if(flags != 2 && mode != MODE_SLIP_HIDE) { - /* not overflowed: show packet */ - print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index); - printf("\n"); - } - lastc = '\0'; - index = 0; - flags = 0; - } else { - flags = !flags; - } - break; - - default: - if(lastc == SLIP_ESC) { - lastc = '\0'; - - /* Previous read byte was an escape byte, so this byte will be - interpreted differently from others. */ - switch(buf[i]) { - case SLIP_ESC_END: - buf[i] = SLIP_END; - break; - case SLIP_ESC_ESC: - buf[i] = SLIP_ESC; - break; - } - } - - rxbuf[index++] = buf[i]; - if(index >= sizeof(rxbuf)) { - fprintf(stderr, "**** slip overflow\n"); - index = 0; - flags = 2; - } - break; - } - break; - } - } - - /* after processing for some output modes */ - if(index > 0) { - switch(mode) { - case MODE_HEX: - print_hex_line("", rxbuf, index); - break; - } - } - fflush(stdout); - } - } -} From 31ceb23f3adb470e29c1d56a83573c150e5e2102 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:15:29 +0100 Subject: [PATCH 27/55] Remove sky serialdump makefile and binaries --- tools/sky/Makefile | 30 ------------------------------ tools/sky/serialdump-linux | Bin 12728 -> 0 bytes tools/sky/serialdump-macos | Bin 14008 -> 0 bytes tools/sky/serialdump-windows.exe | Bin 24342 -> 0 bytes 4 files changed, 30 deletions(-) delete mode 100644 tools/sky/Makefile delete mode 100755 tools/sky/serialdump-linux delete mode 100755 tools/sky/serialdump-macos delete mode 100755 tools/sky/serialdump-windows.exe diff --git a/tools/sky/Makefile b/tools/sky/Makefile deleted file mode 100644 index 2c4254a71..000000000 --- a/tools/sky/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -ifndef HOST_OS - ifeq ($(OS),Windows_NT) - HOST_OS := Windows - else - HOST_OS := $(shell uname) - endif -endif - -ifeq ($(HOST_OS),Windows) - SERIALDUMP = serialdump-windows -endif - -ifeq ($(HOST_OS),Darwin) - SERIALDUMP = serialdump-macos -endif - -ifndef SERIALDUMP - # Assume Linux - SERIALDUMP = serialdump-linux -endif - -all: $(SERIALDUMP) - -CFLAGS += -Wall -Werror - -$(SERIALDUMP): serialdump.c - $(CC) -O2 -o $@ $< - -clean: - rm -f $(SERIALDUMP) diff --git a/tools/sky/serialdump-linux b/tools/sky/serialdump-linux deleted file mode 100755 index 4d3e616a9554d698c9b826be0e4ce45cf5a8940c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12728 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 diff --git a/tools/sky/serialdump-macos b/tools/sky/serialdump-macos deleted file mode 100755 index 775f88707f25032d7f8835e8d4dc7a09bb07647b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14008 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 diff --git a/tools/sky/serialdump-windows.exe b/tools/sky/serialdump-windows.exe deleted file mode 100755 index 11ac7cae668a1c98aa16e2016c8cd4bf8f8fa487..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24342 zcmeHv4|H6`dGAPCn>EO+01@=wQQ^Xof@naIY{{0v32RB~$j`DZYzZsa;%cp3SqrP( z?f$`XYlEEKO|)+j)oblnn&8HcIgMIq>n5%de~e|!vFwJlK0sQ)B*)=Tx*NMEZtx+( zalQS0Gjn(MYGkr-lD_tx+;e7U=DXkgzHh$y=Fh!%W>?)e#!47t7KBWOu?fU<+4=9s z{|w{y)i*tNH9Iix`!`P%wSWKS&H+zI3k3a}gU&&%&*}5|!`ddd7L52bk56k|vrZfI zyWF+&=U-VRp*tLmwHH~~%D*08$!ZweT+G;Mc16imMa5050!*a{S0a?jP=}bbqda&? z?;-?>`PGYGWFA{n#OuYFCU~g;mBA$=k?COUY__l<{b&5vhTTJ92pYQqKco=Vb%q`q z>*%d@Im1re>ZE&h2y+oC5%MlO>z%CK6bcckW*&a*lv1x@W}mF}2tZzE)SctqV&=88 zx=AzTx4HjcEzp&CKYF$z`rf&{%x-7#$#BstZ*IS2d&Y68zk2dqf5IWs^Y1R9^qYg1 zrYu!~YwRrb$LN$Nj*g-Hy69O;;wb1^9q8W!9qC?59~S8yl>V+r@1gX!Mfzn*e?z2M zJ<@+D(p8j>igY)nw;+9A;*AYGT;BS`Ki>^Mu z%cUFc*L#kRKE%2vsIw>DUw`kq9cRxX3Dc);K;cvnKgZ%<%49Od6W@YLhl{|Oh_{1K zKl$R*q-4B}XA*Hc;t3k|67eP^lMd?=o;Vi28(Fsfk>n_+_mn2flf!r3VT=FE6^z+l zY%YqXI-}E7Tdv4d#ZNAP%??0nKC|t`wMB`}D(iFKA%UH+ue}s?NbLk4mzcWpQYJI% zKF=#8^qrFtTJ%_#>?X0>cBFd1o(NZ!K0gJR}ydJx3!S0l?%xB;{JGN`(!mkz1{d)lY(EouHADdj^Lg z<^KjZ39bonqdgO(Npcs-NR(Hl{A0S~;Zk+x zVkR?xKQTBaColssz*)JxQ4Wbp+$14ONZz4d2%12OB`)-j9V=$dZCgJ|a^4rI36nz2 z528Q5>9u!{q~^@4{95Wp03_`e(*1j+*3lzp<{WvqI5js%|1Qywpb%=!&Hvg@<~7_k zmW-3Q`b_9KDX{N0PD6kqAnF89Ho+y3Mw z+aFCfy>!@y?2B~Q7Mq8Hhkr_LsBm3PTy)D8dl$Zv_|akNyfd+=ck^CtiyZ>jv#=#Q ze2xP`V*GV@@!?|PAzJ$D#PSQeJ4$1~@b4G1@Vw|t#fe>%6*Xn)Fu0Q38PJT6eH+af zJw!uAv2E96{j0-=XmGLGcD)pTDO@Y~qSNIM&zUHPZ1~!9R!jjC^JrMubs>|1TVM=i zsegkia$qrhjbZ}sA6t&rd2};|1Tl!jPdr?fZK650*fnUPR0oli>)*Y>&=CRcw#lfZzI4OFpoTJ^=)y?^{PLH}US5 z?a@QL+`}{pK!4Vf(m_BbfVEa?CDH`(<&TAELa8#c$9920{Wax5I#q?AXp_Yj zUki6n`H;g9^*k-&o+TzeCSYKLVx_?N3}Nhr`st0-M0}JK*8V*1(1=s@Q6`gqm4?>c zoiHqs{uKO)xRLt<$^k98n_8UkpXbenv21krfGl!9F@XY+btLj9$P4EvvK?$~g`Pmm3{HB&$O17*_87SBwQ z>%Iy@oEbOFd*)}NtDIV%eg{o0`^}CEZ$oytamR%pBDTeklHt)Fr}m#pKZA7rr0A&3 zwsSJQ7v-SaYUq}ZLIq-++&`Iq42+<6fu8zT2t^vIWm0d7G}SKkeQFgk8+Vl^S6SuE zZ28I(-Y#M}VH@2zjdJ9uXr05<7Hk{T)f@q17E&)5F4S{ebhQy9yd(-EUEe=iTTPHD+ZSO5FIgoDsjXX zdjjU)TL#wniK!OLIBrh0Sbv7wQ!S;q#S$%LNe7#X4kJz1R5XU)wKx-yRVi_mOtn<(;rYsO9%=h|)H;F47CQp?^ zWwC=u?kz(Z%wX}qpbW!P0y43mljatg`2l6DGDD-t-cp(Q24%`*=3!)#jpda4&=%{Z z-24j4ov_84iLp{L-bxvglqlvh63rG4pJ=vnt!3+dE+F$H)ZF|Gc`O+LU2tD$MDM=#x5GhE*i$p8zwpYByJ~uuV!kQXr5)f zc@o9cy30fxEfa0DOtewa)H2aV%S0P36K%9iv{8H`MxS&AdT_G2avzy3{R${!$>xfE zWQg?NB8Oo%*<8Ml43z$3BVV?US|c4X@}>KzsnXp>-nx(4F@2Yjx9p=vPTwf=#rw#T z>0)H5!;0tCy-nm*m_YW{h=gTt1trke?}EeQ;qb)KQF0|Fo=?k@4jK)UU1ibfB3tZh zxDl*~P8Wy!qthkNqwQIEdE$*^&&3ljm5OH!WAwm!G>w)5B32?t!*A_vlX8xNIyHxK zuu1035&1lr=t9@KIOQlsmtu)k))VQ!1Y?$pX+}_Yf=cVz`bl{G&PhDW&Zino&7lgB zLW%3Cj{B%9&``GjMmwX$aVaS?ow4mYx{qsOC_N_SqrNB7S3n~<%w?+U__zQ>e&IfU z^n3xDz+=yYbM)^9Fw3O=7a`+GehT8OR@|nkz;NnDezP=+3HPWihIeb!B_H!6mRwZb z)IVaqOv(-;lQ=f&C`A*MVl1YX8jS}a3+oxkqIP5Ydp9N_vH60-*C9)-}K=ziWn4N}QtHGJ- zfm^5c3!GUQmVzOE%JzrPf}8v$XH=3h4C-vgT@6HGS~6+@=IlWMRDEV`t_42Hxl3Ao z5!jNvp?;;Et`dmpQ>Z|`k33}&kX-d&;UixIui+!~&|vt;=g4b&&Pm_k4G%3%J^}-S zDU*r;Li))vB&i73M!J_|lW|hXWCxQ%LILhG8T1aRL<5rP zDQXn){)mrfZSfO{p7V+CB_h*_V~On-6I~}G^OHU2lac8pa%b`8$niSWkY4-}BDwu{ zI4FiCTWlZ5Nk=L=Z4djS)0Xf9Nyq8Y?dRwjpGw(fsifm|>Uld*FzGmnMFRBYF8~N` zA*XVTIAIJY9UOp612~c@%P-@C%hDTQ-!TAjlm^i|{uR~|n%H7@;XaU{NaVZeT4Z2& zzAU3!z>;I=A}KFDdGnEa^f1UYUPsT??4@awOag;!zlgVzW@|i0)9H?%(r@&_6;pGF zn>yaZZ$>X%H9_QuZ%uxI;&{duPvB0n(L%WoBabA1haMy1ry|!*lp>L|#!o~ZNOoA_ zuSWWk9oFatyu$chfQ@#S?)W7^gks5%#ddI=b@Z$BWx!iTylhd!=C5` z%@#WjLD36VTkKDem~x!MFMoxGx=vGFhw)I&wZa%0C-QuER7$@uG6-I#j(k)_W3k%<&`D_QfYd1a%K{Ew|#_ci8Zn69M>>) z58e2-EOF*BBXN}85~7MPQx$jPF;>nzB0_uOt!?i5r1?yBw_M-0%Q!6KN*)6b%iZ#1 z5BIEY%$Aty$;&^$)RyS6ipiMhcmOz&?m{JV${>}gzMbQM&aW=?xa_4wZ^H4rd=LXaP;(LhI>2hgd z&!C%&bUXV7H2R{ac|AUNUKvfR3Ax?cpwp)X0LPg_;b1?NthtS61*Yb5hx&q^K-lB= z-Nxouhgfypf^MkCKJRir^!YyjU_EPGyr`~@MSKtX{9AmQpYv+BR`=a{CF}G1eD1!m z$G4eus}5;3)u^AgVa>{(E7`)P29&E`vVeZ;8!4*(@*UNKcT~Hy>b5(pSKV2?j*(^V z)Yz7wC+ub(U)UWCMgn2COABoch28Wu*XzBKvFgw^_Pe;Wkk=E?{13T<{a!!5&s5hf zbZIQ)_CgD26Y;t<`uH1kJ6$a7_mc&-YR=&1$e`O74w1qJOUND8`ulugZys$kXrg|h zJSuS-)QB$>2?YE>u3^CKcHN0uL%*l4$AbKtPadwlOt})!e^Fi--qb97U%b}N{?83~ zfI(>cA0m8MVQ1e&(2y^aF-#Bb$sh0a1j7-h_nwG5xK-N{wxOret2EbANKe8y&767M1*QrEeX=J%a_^Y32PzG z@4E$W%ht_X@bMns@P)fWqeu`#0$XZ$BEIQIyzVc8^xNydn+2A3Wb7jHr}JoU zgSO|M98Z4g1<;Qpyn*l@!g&O?7TXyRDiNv>>JaP*9S8#m+YrVO_8^QS96*>vcm?5g zgtrk=2Mi9mjoLo5eKv`};s*?-cj-V;uH`Xv{_a zU6J=2`SOxJK3+hY+ZhI`Gdw`$t~cl|cNmi;Da39tXneZyIlbV!y@XUnAZ?M~SmGY? zphnwE`un|+5XXv_^kY=y)n>a(`U63f?+5QUk&cA>*pnswumgOmq+d*Dxc9h)hD0w7 zVeAThhPVsbR$CP5Z3u~_|(P{6icx0 z&yn*V_`2pA(>(l?(omRiN9Kn6&`!=Uter#}w&dxZbGd5lxw(;$*X<4v@2hhk3i+fO zpSeO*rK9Le?(ix;;4X&|RyzmX>lwQzM{RTZTweDw#$rTU7j_8(V>gz_nWY0$0?pFw zW`n}#8piG_Sx>V+;iAJrf&aomcv*cd`B6FaoGq+$tX=JBU$}rXkwJfZ&1wO9{-mpj zX{?wY182F)C5`hiWA_>nsX$55-SkV@>}Bj+BLY2{mdt`|>{=rpDqT`!=t2~6)lz3i z@|Osg@Qk#%DEBZ@%f}?f^awqs(6h6s#cZ;0i`|N_-{4`!02zR0qF#D%Xj243i4{Ct zpKML-ycB78FP2Y3$mOn2QqwGQ5f_pJL8>+=_U36w3yTdv3EEziyRe?yMArCoXh8;@ z%Upi(#BnG~Fp>;iUN4F0(fc);HfKsr>OuQdjULc1@Lqfz|&m-Pj3M{ z0|oE|3g8(kfM>V>o{<80#tPthya1j(1@Md)z_Y&qo{0i@CJW#>{xLk%^IH*4a-Lr? zZe(%Z#-MR070q7ixS`=5jk3ARm}RWlam;+5IE^u3KXz}?Xi>t%PU)(}w_{48St(0t zECYjy(m)F(6J-$%Z-RnbYy*No)@GdtiHBCOO@@X6)N`;9s3d(7&Gi-=7 zWBU-=Ogw)L%1P{9Gtb@Gnik!L`dmXrvzK924HQD1Z9X-uT4u;9YRi^45{6YzbLoVm zj>g3M4+!U^hO@~co*yCH0+Vumh`^>1?lMuXMoosV6E&q73#(pG#;|x1btlRaP&%@u z3=M^J(y$LIE+xk7^+~MJowY``cs60o?;}u6SoK);UVdUlzJ{}`h={ibJiVWh^+I~) zWzIs^*PNAUdS^?3yP3>Tn};Q7t#GX{Oe3eZRJ{ATqrd}9yS zhh(X}(%=~{fM`iejoJQ{9kE3zs>MPSqA@pj zeL4@PCj|3lScBa_J#Kc3QHcY%S;l#0uZ4jlcnF7%H<_r_f3>V$6#bh zk>|F$Kb7=X0AfOJ99N{L6zOj%(tAIZ^p_Rsdlc!X73upG=>wli`WuRL>MbT~G@MtY zm*z@I%LhJ{blOjElGV6hk$z5*eo?9W(5I4qQjz|&BAs^HnlxPW)0}kq4rCrmiFY9V z&Ijo=K;AXr!@EG_Pa_DN{_p@k(coQsPL{Ocuu%)#nR)%%#vgvtuxbIlIpX>hQ3_Sc zyW|?X;WTKbx;N(OEbD&wW9n{6!JR=N=Pf(R(v_7S|{^w4c{hs-a!MIX{zUah-xwK9i@R zQ^6_2Eaz6db#P z)2iUqC^!QOPKScirr_MJ;Lvw3u;tbyiv|>&b_J(S!3iih+Y}sn@-@k7Y*28*3eK2< zL+8=WI86!;y(KsCEZU>sbSpSZ6`XAf&bWfJQNgh*IKv9g0R^X5!D&@+VhYZrg5y$f z+7z4-1?Lq7XF$PeS8yIxa9&q%yb4Z-f-|Pz(EBzN%z5VGfP&Mh;OtazQVLF3!Rc0T z9#?SAD>y?6&PE022?d9iA?A8*Q*e3}oIMH-?eaI{3@bP;1?Ncxr$WJrDL4ZP&bWe8 zrQnPxI9>(kX$7ZF!Fg1{2`D)9+zhsyw=8N>aK;pzu!3_y!LchiI~ANE1!qFRX;*L_ zS8%o|I4>wT-3rbV3eK>CGpXRX6r4Q@PE5ghS-}Y?I8Q1#BMQ!O1!tRrGp^t~s^Gk$ z;LsaR6wG{oDhDmbqzI8P`z2Nayg6`VH|obj1B4R6onX?$WP z&f2kA4MV3OPUPCFmpa4qIMd#s+J}4-cKryT# zC^kff{|JgEqC6ZrA4?ZSBDoCFhL3k{E$lFqFvM?X(dycC>l|Koa0%d z@VGfe%j0KhU#r{P~Il*6DH-`|BkClsDHK{39bz!SvABBq(zosMRTw_#)- zU2ZTEUqTIw(OU}fR>YvphiV5*_PH4p@y5*Hp(F0%ODIPcTc?=SB;8I`#6_x$TC4`e zSjh;=28HKgLN-aK*~92xqST*Kscc*5Zr?+mpx5^RbKm^6GAJmOuY zfpY>BdJ3RgikkitD8`!;*ide?Yct`z2OeWZBuf1p6#BQRoNrtLCD(IxV*{cI=W2Xv zFh+ioCAPPTugRpLuJhe=PIKR>L@CW=u{!!>VHzcxLCLFy+_EUXI~aAp2R!2IHkT!~ z+_9#thPvKQe^ACst@-upK`CSQ6m|E3Qf_Lm?VuP}aS;F+ZqK;BE_re-_!=n2>>!YT z0*bMM6_oR`6gjb=T!F)wbmedsfTEf7aez{ntru~x0mWkC=^-3I=5PX_81uW3wT*ai z2_9W;b`)QH467alPqzvAWh!NAuYU%GYLJt4Rw5I6aS?rgRxNe`JPjt~`DhvADyIKX znWa=Ec*3Sqp995eqI?mQQWIr0A!jMrS?hD@7$rk1n@{iT_46&KOlX0t5n-7ZkOO?96_DSK9DU2Ml@d$K&b+@X9tOCcFQ zFv-FOl^L>#=ik6nlSL-VRluMtS1*U8N`{e<0|IgVa?W{dxyX?Y{L0_`frkI)#9+>I?gWZdV7kjLYO&w=?9=-jF-Ivp}?i z9>)NJTkZ7=#MXb0&*dJlZXEVtUu=m8;jRU#+iN)7sVU;8Z$+AbO9EHI6^H75RYMv#@EAF3%1Dou5l0 z=q=8W?(uoTD7vt*QGCKR4B^9pCG5yIvVowRPBOq!QfW!3pGiPv%^VA}1njXlP95m2 z!mQjl<}LB|dQ?r<*LJP$T(QcbcdT=CwXV_EI@;H?=9_>h2|Y!obDQ)f zA-BUHV0lfgZ-RH|w8t0C2xsANdTZyJwORE1qP{^C&pVtU(PvYc>m+aR&HTJ_`HJab zZzxYHFJSmU?nH(ZA;$LFEpF$7wa|ekeO z_2?X#?(ZkjeGhW)_E5cNV!ON@4_zMI41$wy?%+di4nOF8z#r5@kxk;1qApLl3CrRL zi9Y1bt2G^g(T6-H%D{u6@PpLq@}8LXk#}vy2UQO(Be&{aKaQ=U!Ks!A{A`M@*ju

L5>wJ$7t>6!t%#TC9o89^*XGpXZ zSCvm5(2b6&`h8gHdp7&%KxnQqCWn{4mOUP%c#ZSpyyo)eLpRPp8$)d(x~0+hE%|*? zG^<=mi54^XgwynyjUwOZyHbGl^hINNN(E(})7kn^J%I{s4ofao|qgkdNdtr`$FUGaB6D9AUQe!`*2P%XK|@ z&TweRc*Zh!2-PdM6xs!Zsj~K+F;sHn^H-pTpNOF@Z|*VA0b=?H>iu5lW-%*rh?#CL z*U`CJV8VsHd2jQ2Ha+ML`rO`y3v?%lV#LigMV@SVPthssoyt&PIHG)kWKzJ~qYTdM zA|N-kDcuo$z+Cw9L&D`pYGa}^)gKE-+UjKZ37tok=TD(JpT@C* Date: Sat, 12 May 2018 16:17:22 +0100 Subject: [PATCH 28/55] Move serialdump source to the top-level tools dir --- tools/{sky => }/serialdump.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/{sky => }/serialdump.c (100%) diff --git a/tools/sky/serialdump.c b/tools/serialdump.c similarity index 100% rename from tools/sky/serialdump.c rename to tools/serialdump.c From 5c65a07c56376318945e405874aab24f96ce5e01 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:18:03 +0100 Subject: [PATCH 29/55] Fix serialdump code style --- tools/serialdump.c | 286 +++++++++++++++++++++++---------------------- 1 file changed, 144 insertions(+), 142 deletions(-) diff --git a/tools/serialdump.c b/tools/serialdump.c index 1fc93ef49..b2822d6bf 100644 --- a/tools/serialdump.c +++ b/tools/serialdump.c @@ -1,4 +1,5 @@ #define _GNU_SOURCE +/*---------------------------------------------------------------------------*/ #include #include #include @@ -9,15 +10,16 @@ #include #include #include - +/*---------------------------------------------------------------------------*/ #define BAUDRATE B115200 #define BAUDRATE_S "115200" +/*---------------------------------------------------------------------------*/ #ifdef linux #define MODEMDEVICE "/dev/ttyS0" #else #define MODEMDEVICE "/dev/com1" #endif /* linux */ - +/*---------------------------------------------------------------------------*/ #define SLIP_END 0300 #define SLIP_ESC 0333 #define SLIP_ESC_END 0334 @@ -38,9 +40,11 @@ #define MODE_SLIP_AUTO 6 #define MODE_SLIP 7 #define MODE_SLIP_HIDE 8 +/*---------------------------------------------------------------------------*/ + static unsigned char rxbuf[2048]; - +/*---------------------------------------------------------------------------*/ static int usage(int result) { @@ -54,7 +58,7 @@ usage(int result) printf(" (see man page for strftime() for format description)\n"); return result; } - +/*---------------------------------------------------------------------------*/ static void print_hex_line(char *prefix, unsigned char *outbuf, int index) { @@ -82,13 +86,13 @@ print_hex_line(char *prefix, unsigned char *outbuf, int index) } } } - +/*---------------------------------------------------------------------------*/ static void intHandler(int sig) { exit(0); } - +/*---------------------------------------------------------------------------*/ int main(int argc, char **argv) { @@ -111,57 +115,57 @@ main(int argc, char **argv) while(index < argc) { if(argv[index][0] == '-') { switch(argv[index][1]) { - case 'b': - /* set speed */ - if(strcmp(&argv[index][2], "38400") == 0) { - speed = B38400; - speedname = "38400"; - } else if(strcmp(&argv[index][2], "19200") == 0) { - speed = B19200; - speedname = "19200"; - } else if(strcmp(&argv[index][2], "57600") == 0) { - speed = B57600; - speedname = "57600"; - } else if(strcmp(&argv[index][2], "115200") == 0) { - speed = B115200; - speedname = "115200"; - } else { - fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); - return usage(1); - } - break; - case 'x': - mode = MODE_HEX; - break; - case 'i': - mode = MODE_INT; - break; - case 's': - switch(argv[index][2]) { - case 'n': - mode = MODE_SLIP_HIDE; - break; - case 'o': - mode = MODE_SLIP; - break; - default: - mode = MODE_SLIP_AUTO; - break; - } - break; - case 'T': - if(strlen(&argv[index][2]) == 0) { - timeformat = "%Y-%m-%d %H:%M:%S"; - } else { - timeformat = &argv[index][2]; - } - mode = MODE_START_DATE; - break; - case 'h': - return usage(0); - default: - fprintf(stderr, "unknown option '%c'\n", argv[index][1]); + case 'b': + /* set speed */ + if(strcmp(&argv[index][2], "38400") == 0) { + speed = B38400; + speedname = "38400"; + } else if(strcmp(&argv[index][2], "19200") == 0) { + speed = B19200; + speedname = "19200"; + } else if(strcmp(&argv[index][2], "57600") == 0) { + speed = B57600; + speedname = "57600"; + } else if(strcmp(&argv[index][2], "115200") == 0) { + speed = B115200; + speedname = "115200"; + } else { + fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); return usage(1); + } + break; + case 'x': + mode = MODE_HEX; + break; + case 'i': + mode = MODE_INT; + break; + case 's': + switch(argv[index][2]) { + case 'n': + mode = MODE_SLIP_HIDE; + break; + case 'o': + mode = MODE_SLIP; + break; + default: + mode = MODE_SLIP_AUTO; + break; + } + break; + case 'T': + if(strlen(&argv[index][2]) == 0) { + timeformat = "%Y-%m-%d %H:%M:%S"; + } else { + timeformat = &argv[index][2]; + } + mode = MODE_START_DATE; + break; + case 'h': + return usage(0); + default: + fprintf(stderr, "unknown option '%c'\n", argv[index][1]); + return usage(1); } index++; } else { @@ -174,8 +178,6 @@ main(int argc, char **argv) } fprintf(stderr, "connecting to %s (%s)", device, speedname); - - #ifndef O_SYNC #define O_SYNC 0 #endif @@ -184,7 +186,7 @@ main(int argc, char **argv) /* Some systems do not support certain parameters (e.g. raspbian) * Just do some random testing. Not sure whether there is a better way * of doing this. */ - if(fd < 0 && errno == EINVAL){ + if(fd < 0 && errno == EINVAL) { fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); } #else @@ -241,7 +243,7 @@ main(int argc, char **argv) index = 0; for(;;) { smask = mask; - nfound = select(FD_SETSIZE, &smask, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); + nfound = select(FD_SETSIZE, &smask, (fd_set *)0, (fd_set *)0, (struct timeval *)0); if(nfound < 0) { if(errno == EINTR) { fprintf(stderr, "interrupted system call\n"); @@ -260,7 +262,7 @@ main(int argc, char **argv) exit(-1); } else if(n > 0) { /* because commands might need parameters, lines needs to be - separated which means the terminating LF must be sent */ + separated which means the terminating LF must be sent */ /* while(n > 0 && buf[n - 1] < 32) { */ /* n--; */ /* } */ @@ -298,103 +300,103 @@ main(int argc, char **argv) for(i = 0; i < n; i++) { switch(mode) { - case MODE_START_TEXT: - case MODE_TEXT: - printf("%c", buf[i]); - break; - case MODE_START_DATE: { - time_t t; - t = time(&t); - strftime(outbuf, HCOLS, timeformat, localtime(&t)); - printf("%s|", outbuf); - mode = MODE_DATE; + case MODE_START_TEXT: + case MODE_TEXT: + printf("%c", buf[i]); + break; + case MODE_START_DATE: { + time_t t; + t = time(&t); + strftime(outbuf, HCOLS, timeformat, localtime(&t)); + printf("%s|", outbuf); + mode = MODE_DATE; + } + /* continue into the MODE_DATE */ + case MODE_DATE: + printf("%c", buf[i]); + if(buf[i] == '\n') { + mode = MODE_START_DATE; } - /* continue into the MODE_DATE */ - case MODE_DATE: + break; + case MODE_INT: + printf("%03d ", buf[i]); + if(++index >= ICOLS) { + index = 0; + printf("\n"); + } + break; + case MODE_HEX: + rxbuf[index++] = buf[i]; + if(index >= HCOLS) { + print_hex_line("", rxbuf, index); + index = 0; + printf("\n"); + } + break; + + case MODE_SLIP_AUTO: + case MODE_SLIP_HIDE: + if(!flags && (buf[i] != SLIP_END)) { + /* Not a SLIP packet? */ printf("%c", buf[i]); - if(buf[i] == '\n') { - mode = MODE_START_DATE; - } break; - case MODE_INT: - printf("%03d ", buf[i]); - if(++index >= ICOLS) { + } + /* continue to slip only mode */ + case MODE_SLIP: + switch(buf[i]) { + case SLIP_ESC: + lastc = SLIP_ESC; + break; + + case SLIP_END: + if(index > 0) { + if(flags != 2 && mode != MODE_SLIP_HIDE) { + /* not overflowed: show packet */ + print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index); + printf("\n"); + } + lastc = '\0'; index = 0; - printf("\n"); + flags = 0; + } else { + flags = !flags; } break; - case MODE_HEX: + + default: + if(lastc == SLIP_ESC) { + lastc = '\0'; + + /* Previous read byte was an escape byte, so this byte will be + interpreted differently from others. */ + switch(buf[i]) { + case SLIP_ESC_END: + buf[i] = SLIP_END; + break; + case SLIP_ESC_ESC: + buf[i] = SLIP_ESC; + break; + } + } + rxbuf[index++] = buf[i]; - if(index >= HCOLS) { - print_hex_line("", rxbuf, index); + if(index >= sizeof(rxbuf)) { + fprintf(stderr, "**** slip overflow\n"); index = 0; - printf("\n"); - } - break; - - case MODE_SLIP_AUTO: - case MODE_SLIP_HIDE: - if(!flags && (buf[i] != SLIP_END)) { - /* Not a SLIP packet? */ - printf("%c", buf[i]); - break; - } - /* continue to slip only mode */ - case MODE_SLIP: - switch(buf[i]) { - case SLIP_ESC: - lastc = SLIP_ESC; - break; - - case SLIP_END: - if(index > 0) { - if(flags != 2 && mode != MODE_SLIP_HIDE) { - /* not overflowed: show packet */ - print_hex_line("SLIP: ", rxbuf, index > HCOLS ? HCOLS : index); - printf("\n"); - } - lastc = '\0'; - index = 0; - flags = 0; - } else { - flags = !flags; - } - break; - - default: - if(lastc == SLIP_ESC) { - lastc = '\0'; - - /* Previous read byte was an escape byte, so this byte will be - interpreted differently from others. */ - switch(buf[i]) { - case SLIP_ESC_END: - buf[i] = SLIP_END; - break; - case SLIP_ESC_ESC: - buf[i] = SLIP_ESC; - break; - } - } - - rxbuf[index++] = buf[i]; - if(index >= sizeof(rxbuf)) { - fprintf(stderr, "**** slip overflow\n"); - index = 0; - flags = 2; - } - break; + flags = 2; } break; + } + break; } } /* after processing for some output modes */ if(index > 0) { switch(mode) { - case MODE_HEX: - print_hex_line("", rxbuf, index); - break; + case MODE_HEX: + print_hex_line("", rxbuf, index); + break; } } fflush(stdout); From a81ff510f58b6e8fee21cddabaca0b74090555f5 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:20:49 +0100 Subject: [PATCH 30/55] Provide a macro for the unknown baudrate --- tools/tools-utils.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/tools-utils.h b/tools/tools-utils.h index 4b996cc75..c3e655305 100644 --- a/tools/tools-utils.h +++ b/tools/tools-utils.h @@ -35,6 +35,9 @@ #include +/* The unspecified baudrate */ +#define BUNKNOWN -2 + #if __APPLE__ #ifndef B460800 #define B460800 460800 From aa926ee288c907761664c71a1d530701e7d81ace Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:21:08 +0100 Subject: [PATCH 31/55] Remove dead code block --- tools/serialdump.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/serialdump.c b/tools/serialdump.c index b2822d6bf..d9bb986f2 100644 --- a/tools/serialdump.c +++ b/tools/serialdump.c @@ -230,12 +230,6 @@ main(int argc, char **argv) exit(-1); } - /* Make read() return immediately */ - /* if (fcntl(fd, F_SETFL, FNDELAY) < 0) { */ - /* perror("\ncould not set fcntl"); */ - /* exit(-1); */ - /* } */ - FD_ZERO(&mask); FD_SET(fd, &mask); FD_SET(fileno(stdin), &mask); From 64ad54d692ef2d5047de9c4e997efb06fc45b99b Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:24:05 +0100 Subject: [PATCH 32/55] Fix usage string --- tools/serialdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/serialdump.c b/tools/serialdump.c index d9bb986f2..316cc517e 100644 --- a/tools/serialdump.c +++ b/tools/serialdump.c @@ -48,7 +48,7 @@ static unsigned char rxbuf[2048]; static int usage(int result) { - printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] [SERIALDEVICE]\n"); + printf("Usage: serialdump [-x] [-s[on]] [-i] [-bSPEED] T[format] [SERIALDEVICE]\n"); printf(" -x for hexadecimal output\n"); printf(" -i for decimal output\n"); printf(" -s for automatic SLIP mode\n"); From b2bd5ed662f90f4391a25f9a115b70fa1d8a75f6 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:25:33 +0100 Subject: [PATCH 33/55] Tidy-up handling of O_SYNC and O_DIRECT --- tools/serialdump.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/tools/serialdump.c b/tools/serialdump.c index 316cc517e..02e3df15e 100644 --- a/tools/serialdump.c +++ b/tools/serialdump.c @@ -41,8 +41,12 @@ #define MODE_SLIP 7 #define MODE_SLIP_HIDE 8 /*---------------------------------------------------------------------------*/ +#ifndef O_SYNC +#define O_SYNC 0 +#endif - +#define OPEN_FLAGS (O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC) +/*---------------------------------------------------------------------------*/ static unsigned char rxbuf[2048]; /*---------------------------------------------------------------------------*/ static int @@ -176,22 +180,13 @@ main(int argc, char **argv) } } } - fprintf(stderr, "connecting to %s (%s)", device, speedname); -#ifndef O_SYNC -#define O_SYNC 0 -#endif -#ifdef O_DIRECT - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC); - /* Some systems do not support certain parameters (e.g. raspbian) - * Just do some random testing. Not sure whether there is a better way - * of doing this. */ - if(fd < 0 && errno == EINVAL) { - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); } -#else - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); -#endif + + fprintf(stderr, "connecting to %s", device); + + fd = open(device, OPEN_FLAGS); + if(fd < 0) { fprintf(stderr, "\n"); perror("open"); From 93608baed40a898c38ccd0ac3e30ed79d6ebed93 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:28:56 +0100 Subject: [PATCH 34/55] Improve baudrate handling --- tools/serialdump.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/tools/serialdump.c b/tools/serialdump.c index 02e3df15e..ed4f6d85d 100644 --- a/tools/serialdump.c +++ b/tools/serialdump.c @@ -1,5 +1,7 @@ #define _GNU_SOURCE /*---------------------------------------------------------------------------*/ +#include "tools-utils.h" + #include #include #include @@ -13,6 +15,8 @@ /*---------------------------------------------------------------------------*/ #define BAUDRATE B115200 #define BAUDRATE_S "115200" + +speed_t b_rate = BAUDRATE; /*---------------------------------------------------------------------------*/ #ifdef linux #define MODEMDEVICE "/dev/ttyS0" @@ -105,8 +109,7 @@ main(int argc, char **argv) struct termios options; fd_set mask, smask; int fd; - speed_t speed = BAUDRATE; - char *speedname = BAUDRATE_S; + int baudrate = BUNKNOWN; char *device = MODEMDEVICE; char *timeformat = NULL; unsigned char buf[BUFSIZE]; @@ -120,23 +123,7 @@ main(int argc, char **argv) if(argv[index][0] == '-') { switch(argv[index][1]) { case 'b': - /* set speed */ - if(strcmp(&argv[index][2], "38400") == 0) { - speed = B38400; - speedname = "38400"; - } else if(strcmp(&argv[index][2], "19200") == 0) { - speed = B19200; - speedname = "19200"; - } else if(strcmp(&argv[index][2], "57600") == 0) { - speed = B57600; - speedname = "57600"; - } else if(strcmp(&argv[index][2], "115200") == 0) { - speed = B115200; - speedname = "115200"; - } else { - fprintf(stderr, "unsupported speed: %s\n", &argv[index][2]); - return usage(1); - } + baudrate = atoi(&argv[index][2]); break; case 'x': mode = MODE_HEX; @@ -181,6 +168,12 @@ main(int argc, char **argv) } } + if(baudrate != BUNKNOWN) { + b_rate = select_baudrate(baudrate); + if(b_rate == 0) { + fprintf(stderr, "unknown baudrate %d\n", baudrate); + exit(-1); + } } fprintf(stderr, "connecting to %s", device); @@ -203,9 +196,10 @@ main(int argc, char **argv) perror("could not get options"); exit(-1); } - /* fprintf(stderr, "serial options set\n"); */ - cfsetispeed(&options, speed); - cfsetospeed(&options, speed); + + cfsetispeed(&options, b_rate); + cfsetospeed(&options, b_rate); + /* Enable the receiver and set local mode */ options.c_cflag |= (CLOCAL | CREAD); /* Mask the character size bits and turn off (odd) parity */ From 4d97186df237030adafa05ed6db0876bbbb93f5e Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:29:24 +0100 Subject: [PATCH 35/55] Support tunslip6 and serialdump with a single makefile --- tools/Makefile | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index ef1711d7c..a17086730 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,8 +1,13 @@ -all: tunslip6 +APPS = tunslip6 serialdump +LIB_SRCS = tools-utils.c +DEPEND = tools-utils.h -CFLAGS += -Wall -Werror +all: $(APPS) -tunslip6: tools-utils.c tunslip6.c +CFLAGS += -Wall -Werror -O2 + +$(APPS) : % : %.c $(LIB_SRCS) $(DEPEND) + $(CC) $(CFLAGS) $< $(LIB_SRCS) -o $@ clean: - rm -f *.o tunslip6 + rm -f $(APPS) From 1d551724568be4ecaae0571379dcb485f0f84a2a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:29:38 +0100 Subject: [PATCH 36/55] Remove obsolete line in gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index f59be6e16..444d6ee24 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,6 @@ Makefile.target Makefile.*.defines tools/doxygen/html patches-* -tools/tunslip tools/tunslip6 build tools/coffee-manager/build/ From 1c48307690a4b8c723fd15b50cd9f3125ed5702c Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 16:29:55 +0100 Subject: [PATCH 37/55] gitignore the serialdump binary --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 444d6ee24..a40863398 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ Makefile.*.defines tools/doxygen/html patches-* tools/tunslip6 +tools/serialdump build tools/coffee-manager/build/ tools/coffee-manager/coffee.jar From 8c347f96d73adb32f2cc78592646ff819828d0ca Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 19:36:30 +0100 Subject: [PATCH 38/55] gitignore files created by make serialdump --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a40863398..8bcfac060 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ tools/doxygen/html patches-* tools/tunslip6 tools/serialdump +serialdump-* build tools/coffee-manager/build/ tools/coffee-manager/coffee.jar From 37f14efad503de8563ef25167cc24ff0c7a0da1c Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 17:34:29 +0100 Subject: [PATCH 39/55] Harmonize building of tools from within an example dir --- Makefile.include | 3 +++ Makefile.tools | 11 +++++++++++ arch/platform/jn516x/Makefile.jn516x | 3 --- .../rpl-border-router/embedded/Makefile.embedded | 12 +++++------- 4 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 Makefile.tools diff --git a/Makefile.include b/Makefile.include index de0606ad4..105459d4d 100644 --- a/Makefile.include +++ b/Makefile.include @@ -10,6 +10,9 @@ WERROR ?= 1 include $(CONTIKI)/Makefile.identify-target +### Include Makefile.tools to pull in targets that allow us to build tools dir +include $(CONTIKI)/Makefile.tools + CONTIKI_NG_TARGET_LIB = contiki-ng-$(TARGET).a ifeq ($(DEFINES),) diff --git a/Makefile.tools b/Makefile.tools new file mode 100644 index 000000000..6dd978ee1 --- /dev/null +++ b/Makefile.tools @@ -0,0 +1,11 @@ +TOOLS_DIR = $(CONTIKI)/tools +TOOL_DEPS = $(TOOLS_DIR)/tools-utils.c $(TOOLS_DIR)/tools-utils.h + +TUNSLIP6 = $(TOOLS_DIR)/tunslip6 +SERIAL_DUMP_BIN = $(TOOLS_DIR)/serialdump + +$(SERIAL_DUMP_BIN): $(TOOLS_DIR)/serialdump.c $(TOOL_DEPS) + make -C $(TOOLS_DIR) serialdump + +$(TUNSLIP6): $(TOOLS_DIR)/tunslip6.c $(TOOL_DEPS) + make -C $(TOOLS_DIR) tunslip6 diff --git a/arch/platform/jn516x/Makefile.jn516x b/arch/platform/jn516x/Makefile.jn516x index 93ba5f296..2dbe0cdef 100644 --- a/arch/platform/jn516x/Makefile.jn516x +++ b/arch/platform/jn516x/Makefile.jn516x @@ -299,9 +299,6 @@ serialdumpall: UART_BAUDRATE ?= 1000000 -$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c - ($(MAKE) -C $(CONTIKI)/tools tunslip6 CFLAGS= LDFLAGS= LDLIBS= INCFLAGS=) - $(SERIALDUMP): $(CONTIKI)/tools/jn516x/serialdump.c (cd $(CONTIKI)/tools/jn516x; ${MAKE} $(notdir $(SERIALDUMP))) diff --git a/os/services/rpl-border-router/embedded/Makefile.embedded b/os/services/rpl-border-router/embedded/Makefile.embedded index c62f7df54..8324722fc 100644 --- a/os/services/rpl-border-router/embedded/Makefile.embedded +++ b/os/services/rpl-border-router/embedded/Makefile.embedded @@ -1,9 +1,7 @@ -$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c - (cd $(CONTIKI)/tools && $(MAKE) tunslip6) - PREFIX ?= fd00::1/64 -connect-router: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 $(PREFIX) -connect-router-cooja: $(CONTIKI)/tools/tunslip6 - sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 $(PREFIX) +connect-router: $(TUNSLIP6) + sudo $(TUNSLIP6) $(PREFIX) + +connect-router-cooja: $(TUNSLIP6) + sudo $(TUNSLIP6) -a 127.0.0.1 $(PREFIX) From 11f563dc98b9f622a8247c0a4d2c36723cc3262b Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 17:35:51 +0100 Subject: [PATCH 40/55] Harmonize login, serialdump and serialvew across all platforms --- Makefile.embedded | 18 ++++++++++++ Makefile.include | 11 ++++++- arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx | 18 ++---------- arch/platform/jn516x/Makefile.jn516x | 29 +++++-------------- arch/platform/sky/Makefile.common | 20 ++----------- arch/platform/zoul/Makefile.zoul | 10 ++----- 6 files changed, 43 insertions(+), 63 deletions(-) create mode 100644 Makefile.embedded diff --git a/Makefile.embedded b/Makefile.embedded new file mode 100644 index 000000000..a0967b628 --- /dev/null +++ b/Makefile.embedded @@ -0,0 +1,18 @@ +.PHONY: login serialdump serialview + +BAUDRATE ?= 115200 +TIMESTAMP = $(CONTIKI)/tools/timestamp +ifeq ($(HOST_OS),Windows) + SERIALDUMP = $(SERIAL_DUMP_BIN) +else + SERIALDUMP = rlwrap $(SERIAL_DUMP_BIN) +endif + +serialdump: $(SERIAL_DUMP_BIN) + $(SERIALDUMP) -b$(BAUDRATE) $(PORT) | $(TIMESTAMP) | tee serialdump-`date +%Y%m%d-%H%M` + +serialview: $(SERIAL_DUMP_BIN) + $(SERIALDUMP) -b$(BAUDRATE) $(PORT) | $(TIMESTAMP) + +login: $(SERIAL_DUMP_BIN) + $(SERIALDUMP) -b$(BAUDRATE) $(PORT) diff --git a/Makefile.include b/Makefile.include index 105459d4d..f24124e83 100644 --- a/Makefile.include +++ b/Makefile.include @@ -396,7 +396,7 @@ endif usage: @echo "Usage:" - @echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [DEFINES=(DEFINES)] [target]" + @echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [DEFINES=(DEFINES)] [PORT=(PORT)] [target]" @echo "" @echo "Typical usage:" @echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [all]" @@ -417,6 +417,9 @@ usage: @echo " %.o Produces an object file from a given source file (e.g. hello-world.o)" @echo " %.e Produces the pre-processed version of a given source file (e.g. hello-world.e)" @echo " %.s Produces an assembly file from a given source file (e.g. hello-world.s)" + @echo " login View the serial output of the device connected to PORT" + @echo " serialview Same as login, but prepend serial output with a unix timestamp" + @echo " serialdump same as serialview, but also save the output to a file" help: usage @@ -462,6 +465,12 @@ endif @echo "To view more Make variables, edit $(CONTIKI)/Makefile.include, rule 'viewconf'" @echo "To view more C variables, edit $(CONTIKI)/tools/viewconf.c" +### Include Makefile.embedded for relevant platforms, in order to pull in +### rules for login, serialview etc +ifeq ($(findstring $(TARGET),native cooja),) + include $(CONTIKI)/Makefile.embedded +endif + # Don't treat %.$(TARGET) as an intermediate file because it is # in fact the primary target. .PRECIOUS: %.$(TARGET) diff --git a/arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx b/arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx index ef7c47443..4845b36ba 100644 --- a/arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx +++ b/arch/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -88,21 +88,7 @@ else @echo "This board cannot be programmed through the ROM bootloader and therefore does not support the .upload target." endif -# Check if we are running under Windows -ifeq ($(HOST_OS),Windows) - SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-windows -else -ifeq ($(HOST_OS),Darwin) - SERIALDUMP ?= rlwrap $(CONTIKI)/tools/sky/serialdump-macos -else - # Else assume Linux - SERIALDUMP ?= rlwrap $(CONTIKI)/tools/sky/serialdump-linux -endif -endif - -UART_BAUDRATE = 115200 - -login: - $(SERIALDUMP) -b$(UART_BAUDRATE) $(PORT) +### For the login etc targets +BAUDRATE = 115200 include $(CONTIKI)/arch/cpu/arm/cortex-m/cm3/Makefile.cm3 diff --git a/arch/platform/jn516x/Makefile.jn516x b/arch/platform/jn516x/Makefile.jn516x index 2dbe0cdef..6cff59c65 100644 --- a/arch/platform/jn516x/Makefile.jn516x +++ b/arch/platform/jn516x/Makefile.jn516x @@ -175,17 +175,14 @@ MOTELIST = python $(CONTIKI)/tools/jn516x/mote-list.py ifeq ($(HOST_OS),Windows) USBDEVPREFIX=/dev/com USBDEVBASENAME=COM - SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-windows else ifeq ($(HOST_OS),Darwin) USBDEVPREFIX= USBDEVBASENAME=/dev/tty.usbserial- - SERIALDUMP ?= rlwrap $(CONTIKI)/tools/jn516x/serialdump-macos else # Else we assume Linux USBDEVPREFIX= USBDEVBASENAME=/dev/ttyUSB - SERIALDUMP ?= rlwrap $(CONTIKI)/tools/jn516x/serialdump-linux endif endif @@ -195,7 +192,7 @@ ifndef MOTE $(error MOTE not defined! You must specify which MOTE (serial port) to use) endif endif -PORT = $(USBDEVBASENAME)$(MOTE) +DEV_PORT = $(USBDEVBASENAME)$(MOTE) #### make targets @@ -255,19 +252,19 @@ endif ### Upload target to one jn516x mote specified by MOTE=portNumber ifeq ($(HOST_OS),Windows) %.upload: %.$(TARGET).bin - ${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $< + ${FLASH_PROGRAMMER} -a -c $(DEV_PORT) -B 1000000 -s -w -f $< else %.upload: %.$(TARGET).bin - ${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -f $< + ${FLASH_PROGRAMMER} -V 10 -v -s $(DEV_PORT) -I 38400 -P 1000000 -f $< endif ### Flash the given file ifeq ($(HOST_OS),Windows) %.flash: ${FLASH_PROGRAMMER} - ${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $*.$(TARGET).bin + ${FLASH_PROGRAMMER} -a -c $(DEV_PORT) -B 1000000 -s -w -f $*.$(TARGET).bin else %.flash: ${FLASH_PROGRAMMER} - ${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -s -f $*.$(TARGET).bin + ${FLASH_PROGRAMMER} -V 10 -v -s $(DEV_PORT) -I 38400 -P 1000000 -s -f $*.$(TARGET).bin endif ### List the ports with connected jn516x motes @@ -297,16 +294,6 @@ serialdumpall: ### UART_BAUDRATE: i.e., 115200. default is 1000000 ### example: make TARGET=jn516x UART_BAUDRATE=115200 login MOTE=1 -UART_BAUDRATE ?= 1000000 - -$(SERIALDUMP): $(CONTIKI)/tools/jn516x/serialdump.c - (cd $(CONTIKI)/tools/jn516x; ${MAKE} $(notdir $(SERIALDUMP))) - -login: $(SERIALDUMP) - $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) - -serialview: $(SERIALDUMP) - $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp - -serialdump: $(SERIALDUMP) - $(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp | tee serialdump-$(notdir $(PORT))-`date +%Y%m%d-%H%M` +### For the login etc targets +BAUDRATE = 1000000 +PORT = $(USBDEVPREFIX)$(DEV_PORT) diff --git a/arch/platform/sky/Makefile.common b/arch/platform/sky/Makefile.common index c8de6d6ad..5018da3da 100644 --- a/arch/platform/sky/Makefile.common +++ b/arch/platform/sky/Makefile.common @@ -54,7 +54,6 @@ else ifeq ($(HOST_OS),Darwin) ifndef MOTELIST USBDEVPREFIX= - SERIALDUMP = rlwrap $(CONTIKI)/tools/sky/serialdump-macos MOTELIST = $(CONTIKI)/tools/sky/motelist-macos TMOTE_BSL_FILE = tmote-bsl-linux TMOTE_BSL=$(if $(wildcard $(CONTIKI)/tools/sky/$(TMOTE_BSL_FILE)),1,0) @@ -75,7 +74,6 @@ else # Else we assume Linux ifndef MOTELIST USBDEVPREFIX= - SERIALDUMP = rlwrap $(CONTIKI)/tools/sky/serialdump-linux MOTELIST = $(CONTIKI)/tools/sky/motelist-linux TMOTE_BSL_FILE = tmote-bsl-linux TMOTE_BSL=$(if $(wildcard $(CONTIKI)/tools/sky/$(TMOTE_BSL_FILE)),1,0) @@ -171,21 +169,7 @@ $(CONTIKI)/tools/tunslip: (cd $(CONTIKI)/tools; $(MAKE) tunslip) ifdef MOTE -serialdump: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) | $(CONTIKI)/tools/timestamp | tee serialdump-`date +%Y%m%d-%H%M` - -serialview: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) | $(CONTIKI)/tools/timestamp - -login: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) + PORT = $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) else -serialdump: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES)) | $(CONTIKI)/tools/timestamp | tee serialdump-`date +%Y%m%d-%H%M` - -serialview: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES)) | $(CONTIKI)/tools/timestamp - -login: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES)) + PORT = $(USBDEVPREFIX)$(firstword $(CMOTES)) endif diff --git a/arch/platform/zoul/Makefile.zoul b/arch/platform/zoul/Makefile.zoul index e7e4af709..38b86fd13 100644 --- a/arch/platform/zoul/Makefile.zoul +++ b/arch/platform/zoul/Makefile.zoul @@ -56,11 +56,9 @@ ifeq ($(HOST_OS),Darwin) USBDEVPREFIX= MOTELIST := $(CONTIKI)/tools/zolertia/motelist-zolertia-macos MOTES := $(shell $(MOTELIST) -c 2>&- | cut -f 2 -d ,) - SERIALDUMP := rlwrap $(CONTIKI)/tools/sky/serialdump-macos else ### If we are not running under Mac, we assume Linux USBDEVPREFIX= - SERIALDUMP := rlwrap $(CONTIKI)/tools/sky/serialdump-linux MOTELIST := $(CONTIKI)/tools/zolertia/motelist-zolertia MOTES := $(shell $(MOTELIST) -b $(MOTELIST_ZOLERTIA) -c 2>&- | cut -f 2 -d , | \ perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);') @@ -103,8 +101,6 @@ zoul-motelist: zoul-motes: @echo $(MOTES) -serialview: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES)) | $(CONTIKI)/tools/timestamp - -login: - $(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES)) +### For the login etc targets +BAUDRATE = 115200 +PORT = $(USBDEVPREFIX)$(firstword $(MOTES)) From a73f126c1d553cecc3ab6e3803952ef60a6c2332 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 18:02:15 +0100 Subject: [PATCH 41/55] Adjust travis tests for tools/ --- tests/05-compile-tools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/05-compile-tools/Makefile b/tests/05-compile-tools/Makefile index 43f84405a..a89a585e4 100644 --- a/tests/05-compile-tools/Makefile +++ b/tests/05-compile-tools/Makefile @@ -25,7 +25,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -TOOLS=tools tools/sky tools/jn516x +TOOLS=tools BASEDIR=../../ TESTLOGS=$(subst /,__,$(patsubst %,%.testlog, $(TOOLS))) From 4e7ab7ff2608caf92ed54fa9df4e3cb63de5cbc5 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Mon, 14 May 2018 16:58:40 +0100 Subject: [PATCH 42/55] Run serialdump without rlwrap if it is missing and warn the user --- Makefile.embedded | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Makefile.embedded b/Makefile.embedded index a0967b628..1c1a7b8ec 100644 --- a/Makefile.embedded +++ b/Makefile.embedded @@ -1,11 +1,20 @@ -.PHONY: login serialdump serialview +RLWRAPGOALS = login serialdump serialview + +.PHONY: $(RLWRAPGOALS) BAUDRATE ?= 115200 TIMESTAMP = $(CONTIKI)/tools/timestamp ifeq ($(HOST_OS),Windows) SERIALDUMP = $(SERIAL_DUMP_BIN) else - SERIALDUMP = rlwrap $(SERIAL_DUMP_BIN) + RLWRAP = $(notdir $(shell which rlwrap)) + ifeq ($(RLWRAP),) + ifneq ($(filter $(RLWRAPGOALS),$(MAKECMDGOALS)),) + $(info Running serialdump without rlwrap support.) + $(info Consider installing rlwarp in order to be able to use command history) + endif + endif + SERIALDUMP = $(RLWRAP) $(SERIAL_DUMP_BIN) endif serialdump: $(SERIAL_DUMP_BIN) From da9b35e8158e7f88c5edac3b31377f0fe15b672a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 15 May 2018 17:48:50 +0100 Subject: [PATCH 43/55] Change time format output --- tools/serialdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/serialdump.c b/tools/serialdump.c index ed4f6d85d..ab82024a3 100644 --- a/tools/serialdump.c +++ b/tools/serialdump.c @@ -291,7 +291,7 @@ main(int argc, char **argv) time_t t; t = time(&t); strftime(outbuf, HCOLS, timeformat, localtime(&t)); - printf("%s|", outbuf); + printf("[%s] ", outbuf); mode = MODE_DATE; } /* continue into the MODE_DATE */ From 0dd46af8e6d21b92f74d63553449c09343bfc73e Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 15 May 2018 17:49:32 +0100 Subject: [PATCH 44/55] Timestamp lines using serialdump -T instead of tools/timestamp --- Makefile.embedded | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.embedded b/Makefile.embedded index 1c1a7b8ec..67d12ef34 100644 --- a/Makefile.embedded +++ b/Makefile.embedded @@ -3,7 +3,7 @@ RLWRAPGOALS = login serialdump serialview .PHONY: $(RLWRAPGOALS) BAUDRATE ?= 115200 -TIMESTAMP = $(CONTIKI)/tools/timestamp + ifeq ($(HOST_OS),Windows) SERIALDUMP = $(SERIAL_DUMP_BIN) else @@ -18,10 +18,10 @@ else endif serialdump: $(SERIAL_DUMP_BIN) - $(SERIALDUMP) -b$(BAUDRATE) $(PORT) | $(TIMESTAMP) | tee serialdump-`date +%Y%m%d-%H%M` + $(SERIALDUMP) -b$(BAUDRATE) -T $(PORT) | tee serialdump-`date +%Y%m%d-%H%M` serialview: $(SERIAL_DUMP_BIN) - $(SERIALDUMP) -b$(BAUDRATE) $(PORT) | $(TIMESTAMP) + $(SERIALDUMP) -b$(BAUDRATE) -T $(PORT) login: $(SERIAL_DUMP_BIN) $(SERIALDUMP) -b$(BAUDRATE) $(PORT) From e1a81808df09e7f2e36a2b7ed21dec86b63bbba4 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 15 May 2018 17:50:56 +0100 Subject: [PATCH 45/55] Remove tools/timestamp, which is no longer in use --- tools/timestamp | 3 --- 1 file changed, 3 deletions(-) delete mode 100755 tools/timestamp diff --git a/tools/timestamp b/tools/timestamp deleted file mode 100755 index 16db8c988..000000000 --- a/tools/timestamp +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# We run perl through a shell to avoid having to hard-code the path to perl -perl -e '$|=1; while(<>) {print time . " $_";}' From cdfcf9003f8a4b6e7b2b8f12995eba7973e4c455 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 15 May 2018 22:24:22 +0100 Subject: [PATCH 46/55] Make serialdump timestamp format configurable from the command line --- Makefile.embedded | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.embedded b/Makefile.embedded index 67d12ef34..8253b39af 100644 --- a/Makefile.embedded +++ b/Makefile.embedded @@ -3,6 +3,7 @@ RLWRAPGOALS = login serialdump serialview .PHONY: $(RLWRAPGOALS) BAUDRATE ?= 115200 +SERIALDUMP_TIME_FMT ?= ifeq ($(HOST_OS),Windows) SERIALDUMP = $(SERIAL_DUMP_BIN) @@ -18,10 +19,10 @@ else endif serialdump: $(SERIAL_DUMP_BIN) - $(SERIALDUMP) -b$(BAUDRATE) -T $(PORT) | tee serialdump-`date +%Y%m%d-%H%M` + $(SERIALDUMP) -b$(BAUDRATE) -T$(SERIALDUMP_TIME_FMT) $(PORT) | tee serialdump-`date +%Y%m%d-%H%M` serialview: $(SERIAL_DUMP_BIN) - $(SERIALDUMP) -b$(BAUDRATE) -T $(PORT) + $(SERIALDUMP) -b$(BAUDRATE) -T$(SERIALDUMP_TIME_FMT) $(PORT) login: $(SERIAL_DUMP_BIN) $(SERIALDUMP) -b$(BAUDRATE) $(PORT) From c29534f0132e7151cf31d50a310975f758758a8f Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 26 May 2018 13:59:12 +0100 Subject: [PATCH 47/55] Document the various top-level Makefiles --- Makefile.embedded | 5 +++++ Makefile.identify-target | 5 +++++ Makefile.tools | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/Makefile.embedded b/Makefile.embedded index 8253b39af..4654626c4 100644 --- a/Makefile.embedded +++ b/Makefile.embedded @@ -1,3 +1,8 @@ +# This Makefile contains make variables and rules that are only applicable +# to builds for embedded devices (i.e. excluding platforms native and cooja). +# Future extensions to the build system that are of a similar nature (for +# embedded devices only), can be achieved by extending this Makefile here. + RLWRAPGOALS = login serialdump serialview .PHONY: $(RLWRAPGOALS) diff --git a/Makefile.identify-target b/Makefile.identify-target index 7843fdf6a..86e06c093 100644 --- a/Makefile.identify-target +++ b/Makefile.identify-target @@ -1,3 +1,8 @@ +# This Makefile can be used to identify the selected TARGET used for a +# specific build. It can be included by example Makefiles that need to take +# decisions based on TARGET. It is also automatically included by the +# top-level Makefile.include. + ifeq ($(TARGET),) -include Makefile.target ifeq ($(TARGET),) diff --git a/Makefile.tools b/Makefile.tools index 6dd978ee1..041f383b6 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -1,3 +1,7 @@ +# Some make rules in the main build system depend on the presence of utilities +# under the tools/ dir. For those dependencies, we use this makefile here to +# recursively invoke the respective build under tools/. + TOOLS_DIR = $(CONTIKI)/tools TOOL_DEPS = $(TOOLS_DIR)/tools-utils.c $(TOOLS_DIR)/tools-utils.h From 3e3cb08c7f37114975f30ed1db9d3dbdf1f2dbbc Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 26 May 2018 15:26:20 +0100 Subject: [PATCH 48/55] Move serialdump and tunslip6 to their own subdir --- .gitignore | 4 ++-- Makefile.tools | 16 +++++++++------- tools/{ => serial-io}/Makefile | 0 tools/{ => serial-io}/serialdump.c | 0 tools/{ => serial-io}/tools-utils.c | 3 +-- tools/{ => serial-io}/tools-utils.h | 0 tools/{ => serial-io}/tunslip6.c | 0 7 files changed, 12 insertions(+), 11 deletions(-) rename tools/{ => serial-io}/Makefile (100%) rename tools/{ => serial-io}/serialdump.c (100%) rename tools/{ => serial-io}/tools-utils.c (99%) rename tools/{ => serial-io}/tools-utils.h (100%) rename tools/{ => serial-io}/tunslip6.c (100%) diff --git a/.gitignore b/.gitignore index 8bcfac060..6bab22c32 100644 --- a/.gitignore +++ b/.gitignore @@ -17,8 +17,8 @@ Makefile.target Makefile.*.defines tools/doxygen/html patches-* -tools/tunslip6 -tools/serialdump +tools/serial-io/tunslip6 +tools/serial-io/serialdump serialdump-* build tools/coffee-manager/build/ diff --git a/Makefile.tools b/Makefile.tools index 041f383b6..6151ba83a 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -3,13 +3,15 @@ # recursively invoke the respective build under tools/. TOOLS_DIR = $(CONTIKI)/tools -TOOL_DEPS = $(TOOLS_DIR)/tools-utils.c $(TOOLS_DIR)/tools-utils.h +SERIAL_IO_TOOL_DIR = $(TOOLS_DIR)/serial-io -TUNSLIP6 = $(TOOLS_DIR)/tunslip6 -SERIAL_DUMP_BIN = $(TOOLS_DIR)/serialdump +SERIAL_IO_TOOL_DEPS = $(addprefix $(SERIAL_IO_TOOL_DIR)/, tools-utils.c tools-utils.h) -$(SERIAL_DUMP_BIN): $(TOOLS_DIR)/serialdump.c $(TOOL_DEPS) - make -C $(TOOLS_DIR) serialdump +TUNSLIP6 = $(SERIAL_IO_TOOL_DIR)/tunslip6 +SERIAL_DUMP_BIN = $(SERIAL_IO_TOOL_DIR)/serialdump -$(TUNSLIP6): $(TOOLS_DIR)/tunslip6.c $(TOOL_DEPS) - make -C $(TOOLS_DIR) tunslip6 +$(SERIAL_DUMP_BIN): $(SERIAL_IO_TOOL_DIR)/serialdump.c $(SERIAL_IO_TOOL_DEPS) + make -C $(SERIAL_IO_TOOL_DIR) serialdump + +$(TUNSLIP6): $(SERIAL_IO_TOOL_DIR)/tunslip6.c $(SERIAL_IO_TOOL_DEPS) + make -C $(SERIAL_IO_TOOL_DIR) tunslip6 diff --git a/tools/Makefile b/tools/serial-io/Makefile similarity index 100% rename from tools/Makefile rename to tools/serial-io/Makefile diff --git a/tools/serialdump.c b/tools/serial-io/serialdump.c similarity index 100% rename from tools/serialdump.c rename to tools/serial-io/serialdump.c diff --git a/tools/tools-utils.c b/tools/serial-io/tools-utils.c similarity index 99% rename from tools/tools-utils.c rename to tools/serial-io/tools-utils.c index 50a50c025..8e292e9b3 100644 --- a/tools/tools-utils.c +++ b/tools/serial-io/tools-utils.c @@ -30,7 +30,7 @@ * */ -#include "tools-utils.h" +#include "tools-utils.h" speed_t select_baudrate(int baudrate) { @@ -159,4 +159,3 @@ select_baudrate(int baudrate) { return 0; } } - diff --git a/tools/tools-utils.h b/tools/serial-io/tools-utils.h similarity index 100% rename from tools/tools-utils.h rename to tools/serial-io/tools-utils.h diff --git a/tools/tunslip6.c b/tools/serial-io/tunslip6.c similarity index 100% rename from tools/tunslip6.c rename to tools/serial-io/tunslip6.c From 285578bbf48b562652e762126ffdd4cd2803ec18 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 27 May 2018 13:35:50 +0100 Subject: [PATCH 49/55] Update travis test for tools/serial-io --- tests/05-compile-tools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/05-compile-tools/Makefile b/tests/05-compile-tools/Makefile index a89a585e4..6377d6674 100644 --- a/tests/05-compile-tools/Makefile +++ b/tests/05-compile-tools/Makefile @@ -25,7 +25,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -TOOLS=tools +TOOLS=tools/serial-io BASEDIR=../../ TESTLOGS=$(subst /,__,$(patsubst %,%.testlog, $(TOOLS))) From 5f7984354774e2e5ef2ea0cc1e97cdffa2427943 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 27 May 2018 14:48:38 +0100 Subject: [PATCH 50/55] Create the (failed) summary log even when sub-make fails --- tests/00-doxygen/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/00-doxygen/Makefile b/tests/00-doxygen/Makefile index 3d99c5d00..067090b73 100644 --- a/tests/00-doxygen/Makefile +++ b/tests/00-doxygen/Makefile @@ -30,7 +30,7 @@ DOCDIR=../../tools/doxygen all: clean summary doxygen: - @make -C $(DOCDIR) 2> doxygen.err > /dev/null + -@$(MAKE) -C $(DOCDIR) 2> doxygen.err > /dev/null summary: doxygen @( \ @@ -55,4 +55,4 @@ summary: doxygen clean: @rm -f summary doxygen.err - @make -C $(DOCDIR) clean + @$(MAKE) -C $(DOCDIR) clean From 8daaa357f57445c93587e65dfeed91a15b8b1ad2 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 27 May 2018 15:34:33 +0100 Subject: [PATCH 51/55] Remove makefsdata --- tools/makefsdata | 375 ----------------------------------------------- 1 file changed, 375 deletions(-) delete mode 100755 tools/makefsdata diff --git a/tools/makefsdata b/tools/makefsdata deleted file mode 100755 index 5ea48a611..000000000 --- a/tools/makefsdata +++ /dev/null @@ -1,375 +0,0 @@ -#!/usr/bin/perl -#Generate a .c source that preinitializes a file system -#David Kopf July 2009 -#Extended from the existing non-coffee tool - -#The simplest format is used with httpd-fs.c. It contains a linked -#list pointing to file names and file contents. - -#An extension uses the same linked list that points to a the file names -#and contents within a coffee file system having fixed file sizes. -#This allows the content to be rewritten by coffee while still being -#readable by httpd-fs.c New files or sector extension of existing files -#is not possible, but a larger initial sector allocation could be given -#to some files to allow a limited size increase. Since this would leave the -#wrong file size in the linked list, httpd-fs would have to terminate on -#a reverse zero scan like coffee does. Rewriting the linked list would -#probably be OK if in eeprom, but not if in program flash. Suggestions -#for a workaround would be welcome! - -#Lastly a full coffee file system can be preinitialized. File reads must -#then be done using coffee. - -#Assumes the coffee file_header structure is -#struct file_header { -# coffee_page_t log_page; -# uint16_t log_records; -# uint16_t log_record_size; -# coffee_page_t max_pages; -# uint8_t deprecated_eof_hint; -# uint8_t flags=3 for the initial value; -# char name[COFFEE_NAME_LENGTH]; -# } __attribute__((packed)); - -goto DEFAULTS; -START:$version="1.1"; - -#Process options -for($n=0;$n<=$#ARGV;$n++) { - $arg=$ARGV[$n]; - if ($arg eq "-v") { - print "makefsdata Version $version\n"; - } elsif ($arg eq "-A") { - $n++;$attribute=$ARGV[$n]; - } elsif ($arg eq "-C") { - $coffee=1; - } elsif ($arg eq "-c") { - $complement=1; - } elsif ($arg eq "-i") { - $n++;$includefile=$ARGV[$n]; -# } elsif ($arg eq "-p") { -# $n++;$coffee_page_length=$ARGV[$n]; - } elsif ($arg eq "-s") { - $n++;$coffee_sector_size=$ARGV[$n]; - } elsif ($arg eq "-t") { - $n++;$coffee_page_t =$ARGV[$n]; - } elsif ($arg eq "-f") { - $n++;$coffee_name_length=$ARGV[$n]; - } elsif ($arg eq "-S") { - $n++;$sectionname=$ARGV[$n]; - } elsif ($arg eq "-l") { - $linkedlist=1; - } elsif ($arg eq "-d") { - $n++;$directory=$ARGV[$n]; - } elsif ($arg eq "-o") { - $n++;$outputfile=$ARGV[$n]; - $coffeefile=$outputfile; - } else { -DEFAULTS: -#Set up defaults -$coffee=0; -#$coffee_page_length=256; -$coffee_sector_size=256; -$coffee_page_t=1; -$coffee_name_length=16; -$complement=0; -$directory=""; -$outputfile="httpd-fsdata.c"; -$coffeefile="httpd-coffeedata.c"; -$includefile="makefsdata.h"; -$linkedlist=0; -$attribute=""; -$sectionname=".coffeefiles"; -if (!$version) {goto START;} - print "\n"; - print "Usage: makefsdata <-d input_directory> <-o output_file>\n\n"; - print " Generates c source file to pre-initialize a contiki file system.\n"; - print " The default output is a simple linked list readable by httpd-fs.c\n"; - print " and written to $outputfile.\n\n"; - print " The -C option makes a coffee file system to default output $coffeefile.\n"; - print " A linked list can be still be generated for use with httpd-fs.c so long\n"; - print " as coffee does not extend, delete, or add any files.\n\n"; - print " The input directory structure is copied. If input_directory is specified\n"; - print " it becomes the root \"/\". If no input_directory is specified the first\n"; - print " subdirectory found in the current directory is used as the root.\n\n"; - print " WARNING : If the output file exists it will be overwritten without confirmation!\n\n"; - print " Options are:\n"; - print " -v Display the version number\n"; - print " -A attribute Append \"attribute\" to the declaration, e.g. PROGMEM to put data in AVR program flash memory\n"; - print " -C Use coffee file system format\n"; - print " -c Complement the data, useful for obscurity or fast page erases for coffee\n"; - print " -i filename Treat any input files with name \"filename\" as include files.\n"; - print " Useful for giving a server a name and ip address associated with the web content.\n"; - print " The default is $includefile.\n\n"; - print " The following apply only to coffee file system\n"; -# print " -p pagesize Page size in bytes (default $coffee_page_length)\n"; - print " -s sectorsize Sector size in bytes (default $coffee_sector_size)\n"; - print " -t page_t Number of bytes in coffee_page_t (1,2,or 4, default $coffee_page_t)\n"; - print " -f namesize File name field size in bytes (default $coffee_name_length)\n"; - print " -S section Section name for data (default $sectionname)\n"; - print " -l Append a linked list for use with httpd-fs\n"; - exit; - } -} - -#--------------------Configure parameters----------------------- -if ($coffee) { - $outputfile=$coffeefile; - $coffee_header_length=2*$coffee_page_t+$coffee_name_length+6; - if ($coffee_page_t==1) { - $coffeemax=0xff; - } elsif ($coffee_page_t==2) { - $coffeemax=0xffff; - } elsif ($coffee_page_t==4) { - $coffeemax=0xffffffff; - } else { - die "Unsupported coffee_page_t $coffee_page_t\n"; - } -} else { -# $coffee_page_length=1; - $coffee_sector_size=1; - $linkedlist=1; - $coffee_name_length=256; - $coffee_max=0xffffffff; - $coffee_header_length=0; -} -$null="0x00";if ($complement) {$null="0xff";} -$tab=" "; #optional tabs or spaces at beginning of line, e.g. "\t\t" - -#--------------------Create output file------------------------- -#awkward but could not figure out how to compare paths later unless the file exists -- dak -if (!open(OUTPUT, "> $outputfile")) {die "Aborted: Could not create output file $outputfile";} -print(OUTPUT "\n"); -close($outputfile); -use Cwd qw(abs_path); -if (!open(OUTPUT, "> $outputfile")) {die "Aborted: Could not create output file $outputfile";} -$outputfile=abs_path($outputfile); - -#--------------------Get a list of input files------------------ -if ($directory eq "") { - opendir(DIR, "."); - @files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); - closedir(DIR); - foreach $file (@files) { - if(-d $file && $file !~ /^\./) { - $directory=$file; - break; - } - } -} -if ($directory eq "") {die "Aborted: No subdirectory in current directory";} -if (!chdir("$directory")) {die "Aborted: Directory \"$directory\" does not exist!";} - -if ($coffee) { - print "Processing directory $directory as root of coffee file system\n"; -} else { - print "Processing directory $directory as root of packed httpd-fs file system\n"; -} -opendir(DIR, "."); -@files = grep { !/^\./ && !/(CVS|~)/ && !/(makefsdata.ignore)/ } readdir(DIR); -closedir(DIR); - -foreach $file (@files) { - if(-d $file && $file !~ /^\./) { - print "Adding subdirectory $file\n"; - opendir(DIR, $file); - @newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); - closedir(DIR); -# printf "Adding files @newfiles\n"; - @files = (@files, map { $_ = "$file/$_" } @newfiles); - next; - } -} -#--------------------Write the output file------------------- -print "Writing to $outputfile\n"; -($DAY, $MONTH, $YEAR) = (localtime)[3,4,5]; -printf(OUTPUT "/*********Generated by contiki/tools/makefsdata on %04d-%02d-%02d*********/\n", $YEAR+1900, $MONTH+1, $DAY); -if ($coffee) { - print(OUTPUT "/*For coffee filesystem of sector size $coffee_sector_size and header length $coffee_header_length bytes*/\n"); -} -print(OUTPUT "\n"); -#--------------------Process include file------------------- -foreach $file (@files) {if ($file eq $includefile) { - open(FILE, $file) || die "Aborted: Could not open include file $file\n"; - print "Including text from $file\n"; - $file_length= -s FILE; - read(FILE, $data, $file_length); - print OUTPUT ($data); - close(FILE); - next; #include all include file matches -# break; #include only first include file match -}} - -#--------------------Process data files------------------- -$n=0;$coffeesize=0;$coffeesectors=0; -foreach $file (@files) {if(-f $file) { - if (length($file)>=($coffee_name_length-1)) {die "Aborted: File name $file is too long";} - if (abs_path("$file") eq abs_path("$outputfile")) { - print "Skipping output file $outputfile - recursive input NOT allowed\n"; - next; - } - if ($file eq $includefile) {next;} - open(FILE, $file) || die "Aborted: Could not open file $file\n"; - print "Adding /$file\n"; - if (grep /.png/||/.jpg/||/jpeg/||/.pdf/||/.gif/||/.bin/||/.zip/,$file) {binmode FILE;} - - $file_length= -s FILE; - $file =~ s-^-/-; - $fvar = $file; - $fvar =~ s-/-_-g; - $fvar =~ s-\.-_-g; - - if ($coffee) { - $coffee_sectors=int(($coffee_header_length+$file_length+$coffee_sector_size-1)/$coffee_sector_size); -# $coffee_sectors=sprintf("%.0f",($coffee_header_length+$file_length+$coffee_sector_size-1)/$coffee_sector_size)-1; - $coffee_length=$coffee_sectors*$coffee_sector_size; - } else { - $coffee_length=$file_length+length($file)+1; - } - $flen[$n]=$file_length; - $clen[$n]=$coffee_length; - $n++;$coffeesectors+=$coffee_sectors;$coffeesize+=$coffee_length; - if ($coffee) { - if ($coffeesectors>$coffeemax) { - print "Warning: sector number $coffeesectors overflows allocated sector size in coffee header\n"; - } - print(OUTPUT "\n__attribute__ ((section (\"$sectionname\")))\n"); - print(OUTPUT "volatile const char data".$fvar."[$coffee_length] = {\n"); - } else { - print(OUTPUT "\nconst char data".$fvar."[$coffee_length] $attribute = {\n"); - } - print(OUTPUT "$tab/* $file */\n$tab"); -#--------------------Header----------------------------- -#log_page - if ($coffee) { - print (OUTPUT " "); - for($j=0;$j<$coffee_page_t;$j++) {print (OUTPUT "$ null ,");} -#log_records, log_record_size - for($j=0;$j<4;$j++) {print (OUTPUT "$null, ");} -#max_pages - if ($complement) {$coffee_sectors=$coffee_sectors^0xffffffff;} - if ($coffee_page_t==1) { - printf(OUTPUT "0x%2.2x, ",($coffee_sectors )&0xff); - } elsif ($coffee_page_t==2) { - printf(OUTPUT "0x%2.2x, ",($coffee_sectors>> 8)&0xff); - printf(OUTPUT "0x%2.2x, ",($coffee_sectors )&0xff); - } elsif ($coffee_page_t==4) { - printf(OUTPUT "0x%2.2x, ",($coffee_sectors>>24)&0xff); - printf(OUTPUT "0x%2.2x, ",($coffee_sectors>>16)&0xff); - printf(OUTPUT "0x%2.2x, ",($coffee_sectors>> 8)&0xff); - printf(OUTPUT "0x%2.2x, ",($coffee_sectors )&0xff); - } - if ($complement) {$coffee_sectors=$coffee_sectors^0xffffffff;} -#eof hint and flags - if ($complement) { - print(OUTPUT "0xff, 0xfc,\n$tab"); - } else { - print(OUTPUT "0x00, 0x03,\n$tab"); - } - } - -#-------------------File name-------------------------- - for($j = 0; $j < length($file); $j++) { - $temp=unpack("C", substr($file, $j, 1)); - if ($complement) {$temp=$temp^0xff;} - printf(OUTPUT " %#02.2x,", $temp); - } - if ($coffee) { - for(; $j < $coffee_name_length-1; $j++) {printf(OUTPUT " $null,");} - {print(OUTPUT " $null");} - } else { - {printf(OUTPUT " $null");} - } -#------------------File Data--------------------------- - $coffee_length-=$coffee_header_length; - $i = 10; - while(read(FILE, $data, 1)) { - $temp=unpack("C", $data); - if ($complement) {$temp=$temp^0xff;} - if($i == 10) { - printf(OUTPUT ",\n$tab 0x%2.2x", $temp); - $i = 0; - } else { - printf(OUTPUT ", 0x%2.2x", $temp) - } - $i++;$coffee_length--; - } - - if ($coffee) { - print (OUTPUT ","); - while (--$coffee_length) { - if($i==9) { - print(OUTPUT " $null,\n$tab"); - $i = 0; - } else { - print (OUTPUT " $null,"); - $i++; - } - } - print (OUTPUT " $null"); - } - print (OUTPUT "};\n"); - close(FILE); - push(@fvars, $fvar); - push(@pfiles, $file); -}} - -if ($linkedlist) { -#-------------------httpd_fsdata_file links------------------- -#The non-coffee PROGMEM flash file system for the Raven webserver uses a linked flash list as follows: -print(OUTPUT "\n\n/* Structure of linked list (all offsets relative to start of section):\n"); -print(OUTPUT "struct httpd_fsdata_file {\n"); -print(OUTPUT "$tab const struct httpd_fsdata_file *next; //actual flash address of next link\n"); -print(OUTPUT "$tab const char *name; //offset to coffee file name\n"); -print(OUTPUT "$tab const char *data; //offset to coffee file data\n"); -print(OUTPUT "$tab const int len; //length of file data\n"); -print(OUTPUT "#if HTTPD_FS_STATISTICS == 1 //not enabled since list is in PROGMEM\n"); -print(OUTPUT "$tab uint16_t count; //storage for file statistics\n"); -print(OUTPUT "#endif\n"); -print(OUTPUT "}\n*/\n"); - -# For the static httpd-fs.c file system the file name and data addresses in the linked list -# point to the actual memory locations. -# For the coffee file system the addresses start from zero. The starting address must be added -# in the coffee read routine. - -for($i = 0; $i < @fvars; $i++) { - $file = $pfiles[$i]; - $fvar = $fvars[$i]; - if($i == 0) { - $prevfile = "NULL"; - $data_offset=0; - } else { - $data_offset=$data_offset+$clen[$i-1]; - $prevfile = "file" . $fvars[$i - 1]; - } - $filename_offset=$data_offset+6+2*$coffee_page_t; - $coffee_offset=$data_offset+$coffee_header_length; - if ($coffee_offset>0xffff) {print "Warning : Linked list offset field overflow\n";} - print(OUTPUT "const struct httpd_fsdata_file"); - for ($t=length($file);$t<16;$t++) {print(OUTPUT " ")}; - print(OUTPUT " file".$fvar."[] "); - if ($attribute) {print(OUTPUT "$attribute ");} - print(OUTPUT "={{"); - for ($t=length($prevfile);$t<20;$t++) {print(OUTPUT " ")}; - print(OUTPUT "$prevfile, "); - if ($coffee) { - printf(OUTPUT "(const char *)0x%4.4x, ",$filename_offset); - printf(OUTPUT "(const char *)0x%4.4x, ",$coffee_offset); - printf(OUTPUT "%5u}};\n",$flen[$i]); - } else { - print(OUTPUT "data$fvar"); - for ($t=length($file);$t<15;$t++) {print(OUTPUT " ")}; - print(OUTPUT ", data$fvar"); - for ($t=length($file);$t<15;$t++) {print(OUTPUT " ")}; - print(OUTPUT " +".(length($file)+1).", sizeof(data$fvar)"); - for ($t=length($file);$t<16;$t++) {print(OUTPUT " ")}; - print(OUTPUT " -".(length($file)+1)."}};\n"); - } -} -print(OUTPUT "\n#define HTTPD_FS_ROOT file$fvars[$n-1]\n"); -print(OUTPUT "#define HTTPD_FS_NUMFILES $n\n"); -print(OUTPUT "#define HTTPD_FS_SIZE $coffeesize\n"); -} -print "All done, files occupy $coffeesize bytes\n"; - From 5d234e1138b365147560d8cc600e7a8452402ab2 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 12 May 2018 18:14:03 +0100 Subject: [PATCH 52/55] Move viewconf to its own dir --- Makefile.include | 5 +++-- tools/{ => viewconf}/viewconf.c | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename tools/{ => viewconf}/viewconf.c (100%) diff --git a/Makefile.include b/Makefile.include index f24124e83..61e028c72 100644 --- a/Makefile.include +++ b/Makefile.include @@ -446,6 +446,7 @@ savedefines: @echo "saving Makefile.$(TARGET).defines" @echo >Makefile.$(TARGET).defines "DEFINES = $(DEFINES)" +VIEWCONF = $(CONTIKI)/tools/viewconf/viewconf.c viewconf: @echo "----------------- Make variables: --------------" @echo "##### \"TARGET\": ________________________________ $(TARGET)" @@ -457,13 +458,13 @@ ifdef MAKE_COAP_DTLS_KEYSTORE @echo "##### \"MAKE_COAP_DTLS_KEYSTORE\": _______________ $(MAKE_COAP_DTLS_KEYSTORE)" endif @echo "----------------- C variables: -----------------" - $(Q)$(CC) $(CFLAGS) -E $(CONTIKI)/tools/viewconf.c | grep \#\#\#\#\# + $(Q)$(CC) $(CFLAGS) -E $(VIEWCONF) | grep \#\#\#\#\# @echo "------------------------------------------------" @echo "'==' Means the flag is set to a given a value" @echo "'->' Means the flag is unset, but will default to a given value" @echo "'><' Means the flag is unset and has no default value" @echo "To view more Make variables, edit $(CONTIKI)/Makefile.include, rule 'viewconf'" - @echo "To view more C variables, edit $(CONTIKI)/tools/viewconf.c" + @echo "To view more C variables, edit $(VIEWCONF)" ### Include Makefile.embedded for relevant platforms, in order to pull in ### rules for login, serialview etc diff --git a/tools/viewconf.c b/tools/viewconf/viewconf.c similarity index 100% rename from tools/viewconf.c rename to tools/viewconf/viewconf.c From 6177cac919e680b662e3d40096da0cc345901693 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 27 May 2018 19:21:08 +0100 Subject: [PATCH 53/55] Use $(MAKE) instead of make to invoke recursively --- Makefile.include | 4 ++-- Makefile.tools | 4 ++-- tests/Makefile | 2 +- tests/Makefile.compile-test | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile.include b/Makefile.include index f24124e83..51ce92cfa 100644 --- a/Makefile.include +++ b/Makefile.include @@ -315,8 +315,8 @@ clean: distclean: @for TARG in `ls $(CONTIKI)/arch/platform $(TARGETDIRS)`; do \ - echo Running: make TARGET=$$TARG clean; \ - make TARGET=$$TARG clean; \ + echo Running: $(MAKE) TARGET=$$TARG clean; \ + $(MAKE) TARGET=$$TARG clean; \ done -include $(CONTIKI)/arch/platform/$(TARGET)/Makefile.customrules-$(TARGET) diff --git a/Makefile.tools b/Makefile.tools index 6151ba83a..81653cde6 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -11,7 +11,7 @@ TUNSLIP6 = $(SERIAL_IO_TOOL_DIR)/tunslip6 SERIAL_DUMP_BIN = $(SERIAL_IO_TOOL_DIR)/serialdump $(SERIAL_DUMP_BIN): $(SERIAL_IO_TOOL_DIR)/serialdump.c $(SERIAL_IO_TOOL_DEPS) - make -C $(SERIAL_IO_TOOL_DIR) serialdump + $(MAKE) -C $(SERIAL_IO_TOOL_DIR) serialdump $(TUNSLIP6): $(SERIAL_IO_TOOL_DIR)/tunslip6.c $(SERIAL_IO_TOOL_DEPS) - make -C $(SERIAL_IO_TOOL_DIR) tunslip6 + $(MAKE) -C $(SERIAL_IO_TOOL_DIR) tunslip6 diff --git a/tests/Makefile b/tests/Makefile index a879c805f..ddee606f2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -36,7 +36,7 @@ summary: $(SUMMARIES) @cat $(SUMMARIES) > $@ %/summary: - @make -C $* summary || true + @$(MAKE) -C $* summary || true clean: rm -f $(SUMMARIES) summary diff --git a/tests/Makefile.compile-test b/tests/Makefile.compile-test index 1a5952033..e30f9da36 100644 --- a/tests/Makefile.compile-test +++ b/tests/Makefile.compile-test @@ -40,7 +40,7 @@ get_target_vars = $(wordlist 2,15,$(subst :, ,$1)) define dooneexample @echo -n Building example $(3): $(1) $(4) for target $(2) @((cd $(EXAMPLESDIR)/$(1); \ - make $(4) TARGET=$(2) clean && make -j $(4) TARGET=$(2) WERROR=1) > \ + $(MAKE) $(4) TARGET=$(2) clean && make -j $(4) TARGET=$(2) WERROR=1) > \ /dev/null 2>make.err && \ (echo " -> OK" && printf "%-75s %-40s %-20s TEST OK\n" "$(1)" "$(4)" "$(2)" > $(3)-$(subst /,-,$(1))$(2).testlog) || \ (echo " -> FAIL" && printf "%-75s %-40s %-20s TEST FAIL\n" "$(1)" "$(4)" "$(2)" > $(3)-$(subst /,-,$(1))$(2).testlog ; cat make.err)) @@ -65,4 +65,4 @@ clean: @rm -f *.testlog summary @$(foreach example, $(EXAMPLES), \ $(foreach target, $(EXAMPLESTARGETS), \ - (cd $(EXAMPLESDIR)/$(example); make TARGET=$(target) clean);)) + (cd $(EXAMPLESDIR)/$(example); $(MAKE) TARGET=$(target) clean);)) From 535e2dbbdccca7fca077c30f58a20edbe6d5842a Mon Sep 17 00:00:00 2001 From: Rehan MALAK Date: Mon, 28 May 2018 13:19:54 +0200 Subject: [PATCH 54/55] exclude sky platform for examples/libs/shell --- examples/libs/shell/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/libs/shell/Makefile b/examples/libs/shell/Makefile index b44069cf8..7be7dd18e 100644 --- a/examples/libs/shell/Makefile +++ b/examples/libs/shell/Makefile @@ -3,4 +3,7 @@ all: $(CONTIKI_PROJECT) MODULES += os/services/shell CONTIKI = ../../.. + +PLATFORMS_EXCLUDE = sky + include $(CONTIKI)/Makefile.include From 12f15a4f27712cac06c95e153a3bd33aa571018a Mon Sep 17 00:00:00 2001 From: Rehan MALAK Date: Mon, 28 May 2018 20:56:12 +0200 Subject: [PATCH 55/55] minor modifications related to tools/serial-io/tunslip6 --- tests/17-tun-rpl-br/04-border-router-traceroute.sh | 7 +++---- tests/17-tun-rpl-br/test-border-router.sh | 7 +++---- tests/17-tun-rpl-br/test-native-border-router.sh | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/17-tun-rpl-br/04-border-router-traceroute.sh b/tests/17-tun-rpl-br/04-border-router-traceroute.sh index fe1333aab..4effb9bd3 100755 --- a/tests/17-tun-rpl-br/04-border-router-traceroute.sh +++ b/tests/17-tun-rpl-br/04-border-router-traceroute.sh @@ -22,10 +22,9 @@ java -Xshare:on -jar $CONTIKI/tools/cooja/dist/cooja.jar -nogui=$BASENAME.csc -c JPID=$! sleep 20 -# Connect to the simlation +# Connect to the simulation echo "Starting tunslip6" -make -C $CONTIKI/tools tunslip6 -make -C $CONTIKI/examples/rpl-border-router/ connect-router-cooja TARGET=zoul >> $BASENAME.tunslip.log 2>&1 & +make -C $CONTIKI/examples/rpl-border-router/ connect-router-cooja TARGET=zoul >> $BASENAME.tunslip6.log 2>&1 & MPID=$! printf "Waiting for network formation (%d seconds)\n" "$WAIT_TIME" sleep $WAIT_TIME @@ -49,7 +48,7 @@ if [ $STATUS -eq 0 ] && [ $HOPS -eq $TARGETHOPS ] ; then printf "%-32s TEST OK\n" "$BASENAME" | tee $BASENAME.testlog; else echo "==== $BASENAME.coojalog ====" ; cat $BASENAME.coojalog; - echo "==== $BASENAME.tunslip.log ====" ; cat $BASENAME.tunslip.log; + echo "==== $BASENAME.tunslip6.log ====" ; cat $BASENAME.tunslip6.log; echo "==== $BASENAME.scriptlog ====" ; cat $BASENAME.scriptlog; printf "%-32s TEST FAIL\n" "$BASENAME" | tee $BASENAME.testlog; diff --git a/tests/17-tun-rpl-br/test-border-router.sh b/tests/17-tun-rpl-br/test-border-router.sh index c5653d480..a69446254 100755 --- a/tests/17-tun-rpl-br/test-border-router.sh +++ b/tests/17-tun-rpl-br/test-border-router.sh @@ -28,10 +28,9 @@ java -Xshare:on -jar $CONTIKI/tools/cooja/dist/cooja.jar -nogui=$BASENAME.csc -c JPID=$! sleep 20 -# Connect to the simlation +# Connect to the simulation echo "Starting tunslip6" -make -C $CONTIKI/tools tunslip6 -make -C $CONTIKI/examples/rpl-border-router/ connect-router-cooja TARGET=zoul >> $BASENAME.tunslip.log 2>&1 & +make -C $CONTIKI/examples/rpl-border-router/ connect-router-cooja TARGET=zoul >> $BASENAME.tunslip6.log 2>&1 & MPID=$! printf "Waiting for network formation (%d seconds)\n" "$WAIT_TIME" sleep $WAIT_TIME @@ -55,7 +54,7 @@ if [ $STATUS -eq 0 ] && [ $REPLIES -eq $COUNT ] ; then printf "%-32s TEST OK\n" "$BASENAME" | tee $BASENAME.testlog; else echo "==== $BASENAME.coojalog ====" ; cat $BASENAME.coojalog; - echo "==== $BASENAME.tunslip.log ====" ; cat $BASENAME.tunslip.log; + echo "==== $BASENAME.tunslip6.log ====" ; cat $BASENAME.tunslip6.log; echo "==== $BASENAME.scriptlog ====" ; cat $BASENAME.scriptlog; printf "%-32s TEST FAIL\n" "$BASENAME" | tee $BASENAME.testlog; diff --git a/tests/17-tun-rpl-br/test-native-border-router.sh b/tests/17-tun-rpl-br/test-native-border-router.sh index 50ea18179..e2e205f20 100644 --- a/tests/17-tun-rpl-br/test-native-border-router.sh +++ b/tests/17-tun-rpl-br/test-native-border-router.sh @@ -28,7 +28,7 @@ java -Xshare:on -jar $CONTIKI/tools/cooja/dist/cooja.jar -nogui=$BASENAME.csc -c JPID=$! sleep 20 -# Connect to the simlation +# Connect to the simulation echo "Starting native border-router" nohup make -C $CONTIKI/examples/rpl-border-router/ connect-router-cooja TARGET=native >> $BASENAME.nbr.log 2>&1 & MPID=$!