[time-sync] network-wide time synchronization service (#2618)

OpenThread network-wide time synchronization service is an experimental feature, not part of the standard Thread protocol.

Feature Overview:
 * All the nodes in the same Thread partition sync to the same Thread network-wide time;
 * Microsecond level time synchronization precision;
 * Flexible time accuracy and time sync period configuration;
 * APIs for application layer use case, support both CLI and NCP version.

The feature is wrapped by OPENTHREAD_CONFIG_ENABLE_TIME_SYNC, there's no change to current Thread 1.1
implementation if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC is not enabled.

If OPENTHREAD_CONFIG_ENABLE_TIME_SYNC is enabled, the node could:
 * Attach to a time sync enabled network, otherwise
 * Attach to a standard Thread 1.1 network, otherwise
 * Form a new time sync enabled network

In addition, if OPENTHREAD_CONFIG_TIME_SYNC_REQUIRED is also enable, the node could only:
 * Attach to a time sync enabled network, otherwise
 * Form a new time sync enabled network

Note:
Currently, the feature is only supported on nRF52840 and posix platforms. And the network time
is only synced among Routers and REEDs, the SEDs will be supported later as an optional feature.
This commit is contained in:
Shu Chen
2018-06-27 02:46:32 +08:00
committed by Jonathan Hui
parent 292349c4d3
commit e69019f962
44 changed files with 2283 additions and 97 deletions
+60
View File
@@ -45,6 +45,9 @@
#include <openthread/icmp6.h>
#include <openthread/joiner.h>
#include <openthread/link.h>
#if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC
#include <openthread/network_time.h>
#endif
#include <openthread/openthread.h>
#if OPENTHREAD_FTD
@@ -177,6 +180,9 @@ const struct Command Interpreter::sCommands[] = {
{"networkidtimeout", &Interpreter::ProcessNetworkIdTimeout},
#endif
{"networkname", &Interpreter::ProcessNetworkName},
#if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC
{"networktime", &Interpreter::ProcessNetworkTime},
#endif
{"panid", &Interpreter::ProcessPanId},
{"parent", &Interpreter::ProcessParent},
#if OPENTHREAD_FTD
@@ -1579,6 +1585,60 @@ exit:
AppendResult(error);
}
#if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC
void Interpreter::ProcessNetworkTime(int argc, char *argv[])
{
otError error = OT_ERROR_NONE;
long value;
if (argc == 0)
{
uint64_t time;
otNetworkTimeStatus networkTimeStatus;
networkTimeStatus = otNetworkTimeGet(mInstance, time);
mServer->OutputFormat("Network Time: %dus", time);
switch (networkTimeStatus)
{
case OT_NETWORK_TIME_UNSYNCHRONIZED:
mServer->OutputFormat(" (unsynchronized)\r\n");
break;
case OT_NETWORK_TIME_RESYNC_NEEDED:
mServer->OutputFormat(" (resync needed)\r\n");
break;
case OT_NETWORK_TIME_SYNCHRONIZED:
mServer->OutputFormat(" (synchronized)\r\n");
break;
default:
break;
}
mServer->OutputFormat("Time Sync Period: %ds\r\n", otNetworkTimeGetSyncPeriod(mInstance));
mServer->OutputFormat("XTAL Threshold: %dppm\r\n", otNetworkTimeGetXtalThreshold(mInstance));
}
else if (argc == 2)
{
SuccessOrExit(error = ParseLong(argv[0], value));
SuccessOrExit(error = otNetworkTimeSetSyncPeriod(mInstance, static_cast<uint16_t>(value)));
SuccessOrExit(error = ParseLong(argv[1], value));
SuccessOrExit(error = otNetworkTimeSetXtalThreshold(mInstance, static_cast<uint16_t>(value)));
}
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
exit:
AppendResult(error);
}
#endif // OPENTHREAD_CONFIG_ENABLE_TIME_SYNC
void Interpreter::ProcessPanId(int argc, char *argv[])
{
otError error = OT_ERROR_NONE;