From b8220135a37464d385616d8eb07cfe08aa5fbd66 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Wed, 9 Jun 2021 13:14:54 +0300 Subject: [PATCH 1/2] System time read/write callbacks (#2637) - Add new API for setting system time read and write callbacks. - Update ws_pae to use the new time service. --- .../nanostack/ns_time_api.h | 32 +++++++++-- .../source/6LoWPAN/ws/ws_empty_functions.c | 5 -- .../source/6LoWPAN/ws/ws_pae_time.c | 22 +++----- .../source/Service_Libs/utils/ns_time.c | 55 ++++++++++++++++++ .../source/Service_Libs/utils/ns_time.h | 56 +++++++++++++++++++ .../nanostack/sal-stack-nanostack/sources.mk | 1 + 6 files changed, 147 insertions(+), 24 deletions(-) create mode 100644 features/nanostack/sal-stack-nanostack/source/Service_Libs/utils/ns_time.c create mode 100644 features/nanostack/sal-stack-nanostack/source/Service_Libs/utils/ns_time.h diff --git a/features/nanostack/sal-stack-nanostack/nanostack/ns_time_api.h b/features/nanostack/sal-stack-nanostack/nanostack/ns_time_api.h index a306bad718..4b1907cfc9 100644 --- a/features/nanostack/sal-stack-nanostack/nanostack/ns_time_api.h +++ b/features/nanostack/sal-stack-nanostack/nanostack/ns_time_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Arm Limited and affiliates. + * Copyright (c) 2020-2021, Pelion and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,7 +29,7 @@ #include "ns_types.h" /** - * System time callback. + * System time read callback. * * Callback shall return the system time in seconds after 1970. * @@ -39,13 +39,33 @@ typedef uint64_t ns_time_api_system_time_callback(void); /** - * System time callback set. + * System time write callback. * - * Sets callback for the system time. + * Callback will write the time in seconds after 1970. * - * \param callback system time callback + * \param seconds system time in seconds * */ -void ns_time_api_system_time_callback_set(ns_time_api_system_time_callback callback); +typedef void ns_time_api_system_time_write_callback(uint64_t write_time); + +/** + * System time read callback set. + * + * Sets callback for the system time read. + * + * \param callback_rd system time read callback + * + */ +void ns_time_api_system_time_callback_set(ns_time_api_system_time_callback callback_rd); + +/** + * Set system time write callback. + * + * Sets system time write callback. + * + * \param callback_wr system time write callback. + * + */ +void ns_time_api_system_time_write_callback_set(ns_time_api_system_time_write_callback callback_wr); #endif /* NS_TIME_API_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_empty_functions.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_empty_functions.c index 3f6279685d..9416533d73 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_empty_functions.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_empty_functions.c @@ -440,11 +440,6 @@ int ws_statistics_stop(int8_t interface_id) return -1; } -void ns_time_api_system_time_callback_set(ns_time_api_system_time_callback callback) -{ - (void) callback; -} - int ws_stack_info_get(int8_t interface_id, ws_stack_info_t *info_ptr) { (void) interface_id; diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_time.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_time.c index a962b9415d..55a3e8b5c6 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_time.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_time.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Arm Limited and affiliates. + * Copyright (c) 2020-2021, Pelion and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,6 +25,7 @@ #include "6LoWPAN/ws/ws_pae_time.h" #include "Security/protocols/sec_prot_certs.h" #include "Security/protocols/sec_prot_keys.h" +#include "Service_Libs/utils/ns_time.h" #ifdef HAVE_WS @@ -34,7 +35,6 @@ #define CURRENT_TIME_INIT_VALUE 1577836800 static uint64_t current_time = CURRENT_TIME_INIT_VALUE; -static ns_time_api_system_time_callback *system_time_callback = NULL; uint16_t ws_pae_time_to_short_convert(uint32_t time) { @@ -148,8 +148,9 @@ int8_t ws_pae_time_diff_calc(uint64_t curr_time, uint64_t comp_time, uint32_t *t uint64_t ws_pae_current_time_get(void) { - if (system_time_callback) { - return system_time_callback(); + uint64_t new_time; + if (ns_time_system_time_read(&new_time) == 0) { + return new_time; } return current_time; @@ -162,15 +163,15 @@ void ws_pae_current_time_update(uint16_t seconds) int8_t ws_pae_current_time_set(uint64_t time) { + uint64_t new_system_time; current_time = time; tr_debug("Current time set: %"PRIi64, time); - if (system_time_callback) { - uint64_t system_time = system_time_callback(); + if (ns_time_system_time_read(&new_system_time) == 0) { // System time has gone backwards - if (system_time < current_time || system_time > current_time + SYSTEM_TIME_MAXIMUM_DIFF) { - tr_error("FATAL: system time less than reference time or more than 12 months in future: %"PRIi64" reference time: %"PRIi64, system_time, current_time); + if (new_system_time < current_time || new_system_time > current_time + SYSTEM_TIME_MAXIMUM_DIFF) { + tr_error("FATAL: system time less than reference time or more than 12 months in future: %"PRIi64" reference time: %"PRIi64, new_system_time, current_time); return -1; } } @@ -178,10 +179,5 @@ int8_t ws_pae_current_time_set(uint64_t time) return 0; } -void ns_time_api_system_time_callback_set(ns_time_api_system_time_callback callback) -{ - system_time_callback = callback; -} - #endif /* HAVE_WS */ diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/utils/ns_time.c b/features/nanostack/sal-stack-nanostack/source/Service_Libs/utils/ns_time.c new file mode 100644 index 0000000000..9e8bf761b3 --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/utils/ns_time.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021, Pelion and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "ns_types.h" +#include "ns_time_api.h" //ns_time_api_system_time_callback + +static ns_time_api_system_time_callback *system_time_read_callback = NULL; +static ns_time_api_system_time_write_callback *system_time_write_callback = NULL; + +void ns_time_api_system_time_callback_set(ns_time_api_system_time_callback callback_rd) +{ + system_time_read_callback = callback_rd; +} + +void ns_time_api_system_time_write_callback_set(ns_time_api_system_time_write_callback callback_wr) +{ + system_time_write_callback = callback_wr; +} + +int ns_time_system_time_write(uint64_t time_write) +{ + if (system_time_write_callback) { + system_time_write_callback(time_write); + return 0; + } + + return -1; +} + +int ns_time_system_time_read(uint64_t *time_read) +{ + if (system_time_read_callback && time_read) { + uint64_t new_time = system_time_read_callback(); + *time_read = new_time; + return 0; + } + + return -1; +} diff --git a/features/nanostack/sal-stack-nanostack/source/Service_Libs/utils/ns_time.h b/features/nanostack/sal-stack-nanostack/source/Service_Libs/utils/ns_time.h new file mode 100644 index 0000000000..27299ce0bb --- /dev/null +++ b/features/nanostack/sal-stack-nanostack/source/Service_Libs/utils/ns_time.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Pelion and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _NS_TIME_H_ +#define _NS_TIME_H_ + +/** + * \file ns_time.h + * \brief Nanostack internal time handling API. + */ + +/** + * Write new time as a platform time + * + * Write a new time to platform provided time system. + * Platform time callbacks must be set by using method ns_time_api_system_time_callbacks_set. + * + * \param time_write time to be written as a new system time. + * + * \return 0 in success. + * \return <0 in case of errors. + * + */ +int ns_time_system_time_write(uint64_t time_write); + +/** + * Read platform time from a time callback + * + * Read a new time from time system provided by the platform. + * Platform time callbacks must be set by using the method ns_time_api_system_time_callbacks_set. + * + * \param time_read Address to variable where new time will be written. + * + * \return 0 in success. + * \return <0 in case of errors. + * + */ +int ns_time_system_time_read(uint64_t *time_read); + + + +#endif /* _NS_TIME_H_ */ diff --git a/features/nanostack/sal-stack-nanostack/sources.mk b/features/nanostack/sal-stack-nanostack/sources.mk index ef0ec51253..f8812e75e3 100644 --- a/features/nanostack/sal-stack-nanostack/sources.mk +++ b/features/nanostack/sal-stack-nanostack/sources.mk @@ -211,6 +211,7 @@ SRCS += \ source/Service_Libs/utils/ns_crc.c \ source/Service_Libs/utils/isqrt.c \ source/Service_Libs/utils/ns_file_system.c \ + source/Service_Libs/utils/ns_time.c \ source/Service_Libs/utils/ns_conf.c \ source/Service_Libs/mdns/ns_mdns_api.c \ source/Service_Libs/mdns/ns_fnet_port.c \ From c20ee2aa85469a86e943d46db96e3a2cdb2ac885 Mon Sep 17 00:00:00 2001 From: Arto Kinnunen Date: Wed, 9 Jun 2021 09:00:26 +0300 Subject: [PATCH 2/2] Enable nanostack system time read/write Allow Nanostack to read and write system time to synchronise time in the mesh network. By default feature is enabled in the mesh json- configuration. --- .../nanostack/mbed-mesh-api/mbed_lib.json | 4 ++++ .../source/MeshInterfaceNanostack.cpp | 19 +++++++++++++++++++ .../source/include/mesh_system.h | 7 +++++++ .../mbed-mesh-api/source/mesh_system.c | 7 +++++++ 4 files changed, 37 insertions(+) diff --git a/features/nanostack/mbed-mesh-api/mbed_lib.json b/features/nanostack/mbed-mesh-api/mbed_lib.json index 4278e60141..f0c855733c 100644 --- a/features/nanostack/mbed-mesh-api/mbed_lib.json +++ b/features/nanostack/mbed-mesh-api/mbed_lib.json @@ -24,6 +24,10 @@ "help": "Definition of heap statistics `mem_stat_t` storage.", "value": null }, + "system-time-update-from-nanostack": { + "help": "Allow nanostack to read and write device system time to synchronise time in the network. Feature enabled when set to true, false otherwise.", + "value": true + }, "6lowpan-nd-channel-mask": { "help": "Channel mask, bit-mask of channels to use. [0-0x07fff800]", "value": "0x7fff800" diff --git a/features/nanostack/mbed-mesh-api/source/MeshInterfaceNanostack.cpp b/features/nanostack/mbed-mesh-api/source/MeshInterfaceNanostack.cpp index f09f2175ef..2ac8146296 100644 --- a/features/nanostack/mbed-mesh-api/source/MeshInterfaceNanostack.cpp +++ b/features/nanostack/mbed-mesh-api/source/MeshInterfaceNanostack.cpp @@ -22,6 +22,21 @@ #include "thread_management_if.h" #include "ip6string.h" #include "mbed_error.h" +#include "mbed_rtc_time.h" + +#if (MBED_CONF_MBED_MESH_API_SYSTEM_TIME_UPDATE_FROM_NANOSTACK == true) +static uint64_t time_read_callback(void) +{ + time_t seconds = time(NULL); + + return (uint64_t)seconds; +} + +static void time_write_callback(uint64_t time_write) +{ + set_time((time_t)time_write); +} +#endif /* MBED_CONF_MBED_MESH_API_SYSTEM_TIME_UPDATE_FROM_NANOSTACK */ nsapi_error_t Nanostack::Interface::get_ip_address(SocketAddress *address) { @@ -142,6 +157,10 @@ int InterfaceNanostack::connect() return error; } +#if (MBED_CONF_MBED_MESH_API_SYSTEM_TIME_UPDATE_FROM_NANOSTACK == true) + mesh_system_time_callback_set(time_read_callback, time_write_callback); +#endif /* MBED_CONF_MBED_MESH_API_SYSTEM_TIME_UPDATE_FROM_NANOSTACK */ + return _interface->bringup(false, NULL, NULL, NULL, IPV6_STACK, _blocking); } diff --git a/features/nanostack/mbed-mesh-api/source/include/mesh_system.h b/features/nanostack/mbed-mesh-api/source/include/mesh_system.h index b075ec6004..a6525c508c 100644 --- a/features/nanostack/mbed-mesh-api/source/include/mesh_system.h +++ b/features/nanostack/mbed-mesh-api/source/include/mesh_system.h @@ -32,6 +32,11 @@ enum { APPL_BACKHAUL_LINK_UP }; + +typedef uint64_t ns_time_read_cb(void); +typedef void ns_time_write_cb(uint64_t); + + /* * \brief Send application connect event to receiver tasklet to * ensure that connection is made in right tasklet. @@ -40,6 +45,8 @@ void mesh_system_send_connect_event(uint8_t receiver); int mesh_system_set_file_system_root_path(const char *root_path); +void mesh_system_time_callback_set(ns_time_read_cb, ns_time_write_cb); + /* * \brief Initialize mesh system. * Memory pool, timers, traces and support are initialized. diff --git a/features/nanostack/mbed-mesh-api/source/mesh_system.c b/features/nanostack/mbed-mesh-api/source/mesh_system.c index 59fa78582f..28bdabef08 100644 --- a/features/nanostack/mbed-mesh-api/source/mesh_system.c +++ b/features/nanostack/mbed-mesh-api/source/mesh_system.c @@ -26,6 +26,7 @@ #include "mbed_assert.h" #include "mbed_error.h" #include "ns_file_system.h" +#include "ns_time_api.h" // For tracing we need to define flag, have include and define group #define HAVE_DEBUG 1 #include "ns_trace.h" @@ -83,3 +84,9 @@ int mesh_system_set_file_system_root_path(const char *root_path) { return ns_file_system_set_root_path(root_path); } + +void mesh_system_time_callback_set(ns_time_read_cb read_cb, ns_time_write_cb write_cb) +{ + ns_time_api_system_time_callback_set(read_cb); + ns_time_api_system_time_write_callback_set(write_cb); +}