Przeglądaj źródła

ServerStatus is now a DataSource and returns the current time,
improvements in the DataSource

Stasik0 10 lat temu
rodzic
commit
247e304fb5

+ 0 - 2
examples/server_datasource.c

@@ -101,7 +101,6 @@ int main(int argc, char** argv) {
          .release = releaseTimeData,
          .write = writeTimeData};
     dateVariant->type = &UA_TYPES[UA_TYPES_DATETIME];
-    dateVariant->typeId = UA_NODEID_STATIC(0, UA_TYPES_IDS[UA_TYPES_DATETIME]);
     UA_QualifiedName dateName;
     UA_QUALIFIEDNAME_ASSIGN(dateName, "the time");
     UA_Server_addVariableNode(server, dateVariant, &UA_NODEID_NULL, &dateName,
@@ -121,7 +120,6 @@ int main(int argc, char** argv) {
          .release = releaseDeviceStatus,
          .write = writeDeviceStatus};
     statusVariant->type = &UA_TYPES[UA_TYPES_INT32];
-    statusVariant->typeId = UA_NODEID_STATIC(0, UA_TYPES_IDS[UA_TYPES_INT32]);
     UA_QualifiedName statusName;
     UA_QUALIFIEDNAME_ASSIGN(statusName, "device status");
     UA_Server_addVariableNode(server, statusVariant, &UA_NODEID_NULL, &statusName,

+ 35 - 14
src/server/ua_server.c

@@ -69,6 +69,26 @@ void UA_Server_delete(UA_Server *server) {
     UA_free(server);
 }
 
+static UA_StatusCode readStatus(const void *handle, UA_VariantData *data) {
+    UA_ServerStatusDataType *status = UA_ServerStatusDataType_new();
+    status->startTime   = ((const UA_Server*)handle)->timeStarted;
+    status->currentTime = UA_DateTime_now();
+    status->state       = UA_SERVERSTATE_RUNNING;
+    UA_String_copycstring("http://www.open62541.org", &status->buildInfo.productUri);
+    UA_String_copycstring("open62541", &status->buildInfo.manufacturerName);
+    UA_String_copycstring("open62541 OPC UA Server", &status->buildInfo.productName);
+    UA_String_copycstring("0.0", &status->buildInfo.softwareVersion);
+    UA_String_copycstring("0.0", &status->buildInfo.buildNumber);
+    status->buildInfo.buildDate = UA_DateTime_now();
+    status->secondsTillShutdown = 0;
+
+	data->arrayLength = 1;
+    data->dataPtr = status;
+    data->arrayDimensionsSize = -1;
+    data->arrayDimensions = UA_NULL;
+    return UA_STATUSCODE_GOOD;
+}
+
 UA_Server * UA_Server_new(void) {
     UA_Server *server = UA_malloc(sizeof(UA_Server));
     if(!server)
@@ -612,25 +632,26 @@ UA_Server * UA_Server_new(void) {
                       &UA_EXPANDEDNODEID_STATIC(0, UA_NS0ID_SERVER),
                       &UA_NODEID_STATIC(0, UA_NS0ID_HASPROPERTY));
 
-    UA_ServerStatusDataType *status = UA_ServerStatusDataType_new();
-    status->startTime   = UA_DateTime_now();
-    status->currentTime = UA_DateTime_now();
-    status->state       = UA_SERVERSTATE_RUNNING;
-    UA_String_copycstring("http://www.open62541.org", &status->buildInfo.productUri);
-    UA_String_copycstring("open62541", &status->buildInfo.manufacturerName);
-    UA_String_copycstring("open62541 OPC UA Server", &status->buildInfo.productName);
-    UA_String_copycstring("0.0", &status->buildInfo.softwareVersion);
-    UA_String_copycstring("0.0", &status->buildInfo.buildNumber);
-    status->buildInfo.buildDate = UA_DateTime_now();
-    status->secondsTillShutdown = 0;
-
-    UA_Variant *serverstatus = UA_Variant_new();
+    /*UA_Variant *serverstatus = UA_Variant_new();
     UA_Variant_setValue(serverstatus, status, UA_TYPES_SERVERSTATUSDATATYPE);
     UA_QualifiedName serverstatusname;
     UA_QUALIFIEDNAME_ASSIGN(serverstatusname, "ServerStatus");
     UA_Server_addVariableNode(server, serverstatus, &UA_NODEID_STATIC(0, UA_NS0ID_SERVER_SERVERSTATUS), &serverstatusname,
                               &UA_NODEID_STATIC(0, UA_NS0ID_SERVER),
-                              &UA_NODEID_STATIC(0, UA_NS0ID_HASCOMPONENT));
+                              &UA_NODEID_STATIC(0, UA_NS0ID_HASCOMPONENT));*/
+    UA_Variant *serverstatus = UA_Variant_new();
+    serverstatus->storageType = UA_VARIANT_DATASOURCE;
+    serverstatus->storage.datasource = (UA_VariantDataSource)
+        {.handle = server,
+         .read = readStatus,
+         .release = UA_NULL,
+         .write = UA_NULL};
+    serverstatus->type = &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE];
+    UA_QualifiedName serverstatusname;
+    UA_QUALIFIEDNAME_ASSIGN(serverstatusname, "ServerStatus");
+    UA_Server_addVariableNode(server, serverstatus, &UA_NODEID_NULL, &serverstatusname,
+    							&UA_NODEID_STATIC(0, UA_NS0ID_SERVER),
+    							&UA_NODEID_STATIC(0, UA_NS0ID_HASCOMPONENT));
 
     UA_VariableNode *state = UA_VariableNode_new();
     UA_ServerState *stateEnum = UA_ServerState_new();

+ 2 - 0
src/server/ua_server_internal.h

@@ -62,6 +62,8 @@ struct UA_Server {
 #endif
 
     LIST_HEAD(UA_TimedWorkList, UA_TimedWork) timedWork;
+
+    UA_DateTime timeStarted;
 };
 
 void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg);

+ 1 - 0
src/server/ua_server_worker.c

@@ -431,6 +431,7 @@ UA_StatusCode UA_Server_run(UA_Server *server, UA_UInt16 nThreads, UA_Boolean *r
         server->nls[i].start(server->nls[i].nlHandle);
 
     // 3) The loop
+    server->timeStarted = UA_DateTime_now();
     while(1) {
         // 3.1) Process timed work
         UA_UInt16 timeout = processTimedWork(server);

+ 13 - 7
src/server/ua_services_attribute.c

@@ -134,16 +134,18 @@ static void readValue(UA_Server *server, const UA_ReadValueId *id, UA_DataValue
             if(vn->value.storageType == UA_VARIANT_DATA || vn->value.storageType == UA_VARIANT_DATA_NODELETE)
                 data = &vn->value.storage.data;
             else {
-                if((retval = vn->value.storage.datasource.read(vn->value.storage.datasource.handle,
-                                                               &datasourceData)) != UA_STATUSCODE_GOOD)
-                    break;
-                data = &datasourceData;
+            	if(vn->value.storage.datasource.read != UA_NULL){
+					if((retval = vn->value.storage.datasource.read(vn->value.storage.datasource.handle,
+																   &datasourceData)) != UA_STATUSCODE_GOOD)
+						break;
+					data = &datasourceData;
+            	}
             }
             retval = UA_Variant_copySetArray(&v->value, data->arrayDimensions, data->arrayDimensionsSize,
                                              UA_TYPES_INT32);
             if(retval == UA_STATUSCODE_GOOD)
                 v->hasVariant = UA_TRUE;
-            if(vn->value.storageType == UA_VARIANT_DATASOURCE)
+            if(vn->value.storageType == UA_VARIANT_DATASOURCE && vn->value.storage.datasource.release != UA_NULL)
                 vn->value.storage.datasource.release(vn->value.storage.datasource.handle, &datasourceData);
         }
         break;
@@ -372,8 +374,12 @@ static UA_StatusCode writeValue(UA_Server *server, UA_WriteValue *wvalue) {
             }
 
             if(vn->value.storageType == UA_VARIANT_DATASOURCE) {
-                retval = vn->value.storage.datasource.write(vn->value.storage.datasource.handle,
-                                                            &wvalue->value.value.storage.data);
+            	if(vn->value.storage.datasource.write != UA_NULL){
+            		retval = vn->value.storage.datasource.write(vn->value.storage.datasource.handle,
+                                                            	&wvalue->value.value.storage.data);
+            	}else{
+            		retval = UA_STATUSCODE_BADINTERNALERROR;
+            	}
                 done = UA_TRUE;
             } else {
                 // could be a variable or variabletype node. They fit for the value.. member

+ 2 - 2
src/ua_types_encoding_binary.c

@@ -712,7 +712,7 @@ size_t UA_Variant_calcSizeBinary(UA_Variant const *p) {
         length += UA_Array_calcSizeBinary(data->arrayDimensions, data->arrayDimensionsSize,
                                           &UA_TYPES[UA_TYPES_INT32]);
     
-    if(p->storageType == UA_VARIANT_DATASOURCE)
+    if(p->storageType == UA_VARIANT_DATASOURCE && p->storage.datasource.release != UA_NULL)
         p->storage.datasource.release(p->storage.datasource.handle, &datasourceData);
 
     return length;
@@ -776,7 +776,7 @@ UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst,
         retval |= UA_Array_encodeBinary(data->arrayDimensions, data->arrayDimensionsSize,
                                         &UA_TYPES[UA_TYPES_INT32], dst, offset);
 
-    if(src->storageType == UA_VARIANT_DATASOURCE)
+    if(src->storageType == UA_VARIANT_DATASOURCE && src->storage.datasource.release!=UA_NULL)
         src->storage.datasource.release(src->storage.datasource.handle, &datasourceData);
                      
     return retval;