Prechádzať zdrojové kódy

Sample sever's start time in UA_Server_run_startup() (#1290)

* Sample sever's start time in UA_Server_run_startup()

To allow a device who gets its time knowledge from the network to
initialize the OPC UA server and its address space during startup
but sample a proper Start time to the Server object the start time
is sampled in UA_Server_run_startup().
The device can now initialize the server during startup, go online
on the network and synchronize time and then start the OPC UA server
by calling UA_Server_run_startup() and get a proper sampled start
time in the Server object.

* Removed an unintentional erase of a white space
Jonas Green 7 rokov pred
rodič
commit
a6a9a36ee1

+ 4 - 1
src/server/ua_server.c

@@ -170,7 +170,10 @@ UA_Server_new(const UA_ServerConfig *config) {
     }
 
     server->config = *config;
-    server->startTime = UA_DateTime_now();
+
+    /* Init start time to zero, the actual start time will be sampled in
+     * UA_Server_run_startup() */
+    server->startTime = 0;
 
     /* Set a seed for non-cyptographic randomness */
 #ifndef UA_ENABLE_DETERMINISTIC_RNG

+ 1 - 3
src/server/ua_server_ns0.c

@@ -616,9 +616,7 @@ UA_Server_initNS0(UA_Server *server) {
     retVal |= UA_Server_setVariableNode_dataSource(server,
                         UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS), serverStatus);
 
-    /* StartTime */
-    retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME,
-                               &server->startTime, &UA_TYPES[UA_TYPES_DATETIME]);
+    /* StartTime will be sampled in UA_Server_run_startup()*/
 
     /* CurrentTime */
     UA_DataSource currentTime = {readCurrentTime, NULL};

+ 13 - 2
src/server/ua_server_worker.c

@@ -258,7 +258,8 @@ processDelayedCallback(UA_Server *server, WorkerCallback *dc) {
 /**
  * Main Server Loop
  * ----------------
- * Start: Spin up the workers and the network layer
+ * Start: Spin up the workers and the network layer and sample the server's
+ *        start time.
  * Iterate: Process repeated callbacks and events in the network layer.
  *          This part can be driven from an external main-loop in an
  *          event-driven single-threaded architecture.
@@ -267,8 +268,18 @@ processDelayedCallback(UA_Server *server, WorkerCallback *dc) {
 
 UA_StatusCode
 UA_Server_run_startup(UA_Server *server) {
-    /* Start the networklayers */
+    UA_Variant var;
     UA_StatusCode result = UA_STATUSCODE_GOOD;
+
+    /* Sample the start time and set it to the Server object */
+    server->startTime = UA_DateTime_now();
+    UA_Variant_init(&var);
+    UA_Variant_setScalar(&var, &server->startTime, &UA_TYPES[UA_TYPES_DATETIME]);
+    UA_Server_writeValue(server,
+                         UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME),
+                         var);
+
+    /* Start the networklayers */
     for(size_t i = 0; i < server->config.networkLayersSize; ++i) {
         UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
         result |= nl->start(nl);