int main(int argc, char** argv) { signal(SIGINT, stopHandler); /* catches ctrl-c */ UA_ServerConfig config = UA_ServerConfig_standard; UA_ServerNetworkLayer nl = UA_ServerNetworkLayerTCP(UA_ConnectionConfig_standard, 16664); config.networkLayers = &nl; config.networkLayersSize = 1; UA_Server *server = UA_Server_new(config); /* add a variable node to the address space */ UA_Int32 myInteger = 42; UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer"); UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer"); UA_DataSource dateDataSource = (UA_DataSource) { .handle = &myInteger, .read = readInteger, .write = writeInteger}; UA_VariableAttributes attr; UA_VariableAttributes_init(&attr); attr.description = UA_LOCALIZEDTEXT("en_US","the answer"); attr.displayName = UA_LOCALIZEDTEXT("en_US","the answer"); UA_Server_addDataSourceVariableNode(server, myIntegerNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), myIntegerName, UA_NODEID_NULL, attr, dateDataSource, NULL); UA_StatusCode retval = UA_Server_run(server, &running); UA_Server_delete(server); nl.deleteMembers(&nl); return (int)retval; }
int main(int argc, char** argv) { signal(SIGINT, stopHandler); /* catches ctrl-c */ #ifdef UA_ENABLE_MULTITHREADING pthread_rwlock_init(&writeLock, 0); #endif UA_ServerNetworkLayer nl = UA_ServerNetworkLayerTCP(UA_ConnectionConfig_standard, 16664); UA_ServerConfig config = UA_ServerConfig_standard; config.serverCertificate = loadCertificate(); config.networkLayers = &nl; config.networkLayersSize = 1; UA_Server *server = UA_Server_new(config); // add node with the datetime data source UA_DataSource dateDataSource = (UA_DataSource) {.handle = NULL, .read = readTimeData, .write = NULL}; UA_VariableAttributes v_attr; UA_VariableAttributes_init(&v_attr); v_attr.description = UA_LOCALIZEDTEXT("en_US","current time"); v_attr.displayName = UA_LOCALIZEDTEXT("en_US","current time"); v_attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; const UA_QualifiedName dateName = UA_QUALIFIEDNAME(1, "current time"); UA_NodeId dataSourceId; UA_Server_addDataSourceVariableNode(server, UA_NODEID_NULL, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), dateName, UA_NODEID_NULL, v_attr, dateDataSource, &dataSourceId); #ifndef _WIN32 /* cpu temperature monitoring for linux machines */ const char *temperatureFileName = "/sys/class/thermal/thermal_zone0/temp"; // RaspberryPi // const char *temperatureFileName = "/sys/class/hwmon/hwmon0/device/temp1_input"; // Beaglebone // const char *temperatureFileName = "/sys/class/thermal/thermal_zone3/temp"; // Intel Edison Alternative 1 // const char *temperatureFileName = "/sys/class/thermal/thermal_zone4/temp"; // Intel Edison Alternative 2 if((temperatureFile = fopen(temperatureFileName, "r"))) { // add node with the data source UA_DataSource temperatureDataSource = (UA_DataSource) { .handle = NULL, .read = readTemperature, .write = NULL}; const UA_QualifiedName tempName = UA_QUALIFIEDNAME(1, "cpu temperature"); UA_VariableAttributes_init(&v_attr); v_attr.description = UA_LOCALIZEDTEXT("en_US","temperature"); v_attr.displayName = UA_LOCALIZEDTEXT("en_US","temperature"); v_attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; UA_Server_addDataSourceVariableNode(server, UA_NODEID_NULL, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), tempName, UA_NODEID_NULL, v_attr, temperatureDataSource, NULL); }
//#######################################MAIN####################################### int main(int argc, char** argv) { signal(SIGINT, stopHandler); /* catches ctrl-c */ if (gpioInitialise() < 0) { fprintf(stderr, "pigpio initialisation failed\n"); return 1; } gpioSetMode(17, PI_OUTPUT); gpioSetMode(22, PI_INPUT); gpioSetMode(24, PI_OUTPUT); UA_ServerConfig config = UA_ServerConfig_standard; UA_ServerNetworkLayer nl = UA_ServerNetworkLayerTCP(UA_ConnectionConfig_standard, 16664); config.networkLayers = &nl; config.networkLayersSize = 1; UA_Server *server = UA_Server_new(config); /* add a variable node to the address space */ UA_Int32 myIntegerB = 32; UA_NodeId myIntegerBNodeId = UA_NODEID_STRING(1, "button"); UA_QualifiedName myIntegerBName = UA_QUALIFIEDNAME(1, "button"); UA_DataSource dateDataSource = (UA_DataSource) { .handle = &myIntegerB, .read = readIntegerB, .write = writeIntegerB}; UA_VariableAttributes attr; UA_VariableAttributes_init(&attr); attr.description = UA_LOCALIZEDTEXT("en_US","button_on_off"); attr.displayName = UA_LOCALIZEDTEXT("en_US","button"); UA_Server_addDataSourceVariableNode(server, myIntegerBNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), myIntegerBName, UA_NODEID_NULL, attr, dateDataSource, NULL); /* add a repeated job to the server */ UA_Job job = {.type = UA_JOBTYPE_METHODCALL, .job.methodCall = {.method = testCallback, .data = NULL} }; UA_Server_addRepeatedJob(server, job, 2000, NULL); // call every 2 sec UA_StatusCode retval = UA_Server_run(server, &running); UA_Server_delete(server); nl.deleteMembers(&nl); return (int)retval; }
int main(int argc, char** argv) { signal(SIGINT, stopHandler); /* catches ctrl-c */ #ifdef UA_MULTITHREADING pthread_rwlock_init(&writeLock, 0); #endif UA_Server *server = UA_Server_new(UA_ServerConfig_standard); logger = Logger_Stdout_new(); UA_Server_setLogger(server, logger); UA_ByteString certificate = loadCertificate(); UA_Server_setServerCertificate(server, certificate); UA_ByteString_deleteMembers(&certificate); UA_Server_addNetworkLayer(server, ServerNetworkLayerTCP_new(UA_ConnectionConfig_standard, 16664)); // add node with the datetime data source UA_DataSource dateDataSource = (UA_DataSource) {.handle = NULL, .read = readTimeData, .release = releaseTimeData, .write = NULL}; const UA_QualifiedName dateName = UA_QUALIFIEDNAME(1, "current time"); UA_Server_addDataSourceVariableNode(server, dateDataSource, dateName, UA_NODEID_NULL, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES)); //cpu temperature monitoring for linux machines if((temperatureFile = fopen("/sys/class/thermal/thermal_zone0/temp", "r"))){ // add node with the data source UA_DataSource temperatureDataSource = (UA_DataSource) {.handle = NULL, .read = readTemperature, .release = releaseTemperature, .write = NULL}; const UA_QualifiedName tempName = UA_QUALIFIEDNAME(1, "cpu temperature"); UA_Server_addDataSourceVariableNode(server, temperatureDataSource, tempName, UA_NODEID_NULL, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES)); }
int main(int argc, char** argv) { signal(SIGINT, signalHandler); /* catch ctrl-c */ /* Create a server with one network layer listening on port 4840 */ UA_ServerConfig config = UA_ServerConfig_standard; UA_ServerNetworkLayer nl = UA_ServerNetworkLayerTCP(UA_ConnectionConfig_standard, 4840); config.networkLayers = &nl; config.networkLayersSize = 1; UA_Server *server = UA_Server_new(config); /* Add a variable node */ UA_VariableAttributes attr; UA_VariableAttributes_init(&attr); attr.displayName = UA_LOCALIZEDTEXT("en_US", "Test Var"); UA_Int32 myInteger = 2572; UA_Variant_setScalar(&attr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]); UA_NodeId newNodeId = UA_NODEID_STRING(1, "Test.Var"); UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES); UA_NodeId variableType = UA_NODEID_NULL; /* take the default variable type */ UA_QualifiedName browseName = UA_QUALIFIEDNAME(1, "Test Node"); UA_DataSource dateDataSource = (UA_DataSource) {.handle = &myInteger, .read = onRead, .write = NULL}; UA_Server_addDataSourceVariableNode(server, newNodeId, parentNodeId, parentReferenceNodeId, browseName, UA_NODEID_NULL, attr, dateDataSource, NULL); UA_Job job = {.type = UA_JOBTYPE_METHODCALL, .job.methodCall = {.method = testCallback, .data = NULL} }; UA_Server_addRepeatedJob(server, job, 2000, NULL); // call every 2 sec /* Run the server loop */ UA_StatusCode status = UA_Server_run(server, &running); UA_Server_delete(server); nl.deleteMembers(&nl); return status; }
int main(int argc, char **argv) { signal(SIGINT, stopHandler); /* catches ctrl-c */ signal(SIGTERM, stopHandler); #ifdef UA_ENABLE_ENCRYPTION if(argc < 3) { UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Missing arguments for encryption support. " "Arguments are <server-certificate.der> " "<private-key.der> [<trustlist1.crl>, ...]"); return 1; } /* Load certificate and private key */ UA_ByteString certificate = loadFile(argv[1]); UA_ByteString privateKey = loadFile(argv[2]); /* Load the trustlist */ size_t trustListSize = 0; if(argc > 3) trustListSize = (size_t)argc-3; UA_STACKARRAY(UA_ByteString, trustList, trustListSize); for(size_t i = 0; i < trustListSize; i++) trustList[i] = loadFile(argv[i+3]); /* Loading of a revocation list currently unsupported */ UA_ByteString *revocationList = NULL; size_t revocationListSize = 0; UA_ServerConfig *config = UA_ServerConfig_new_allSecurityPolicies(4840, &certificate, &privateKey, trustList, trustListSize, revocationList, revocationListSize); UA_ByteString_deleteMembers(&certificate); UA_ByteString_deleteMembers(&privateKey); for(size_t i = 0; i < trustListSize; i++) UA_ByteString_deleteMembers(&trustList[i]); if(!config) { UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Could not create the server config"); return 1; } #else if(argc < 2) { UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Missing argument for the server certificate"); return 1; } UA_ByteString certificate = loadFile(argv[1]); UA_ServerConfig *config = UA_ServerConfig_new_minimal(4840, &certificate); UA_ByteString_deleteMembers(&certificate); #endif /* uncomment next line to add a custom hostname */ // UA_ServerConfig_set_customHostname(config, UA_STRING("custom")); UA_Server *server = UA_Server_new(config); if(server == NULL) return 1; /* add a static variable node to the server */ UA_VariableAttributes myVar = UA_VariableAttributes_default; myVar.description = UA_LOCALIZEDTEXT("en-US", "the answer"); myVar.displayName = UA_LOCALIZEDTEXT("en-US", "the answer"); myVar.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; myVar.dataType = UA_TYPES[UA_TYPES_INT32].typeId; myVar.valueRank = -1; UA_Int32 myInteger = 42; UA_Variant_setScalarCopy(&myVar.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]); const UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer"); const UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer"); UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES); UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId, parentReferenceNodeId, myIntegerName, baseDataVariableType, myVar, NULL, NULL); UA_Variant_deleteMembers(&myVar.value); /* add a static variable that is readable but not writable*/ myVar = UA_VariableAttributes_default; myVar.description = UA_LOCALIZEDTEXT("en-US", "the answer - not readable"); myVar.displayName = UA_LOCALIZEDTEXT("en-US", "the answer - not readable"); myVar.accessLevel = UA_ACCESSLEVELMASK_WRITE; myVar.dataType = UA_TYPES[UA_TYPES_INT32].typeId; myVar.valueRank = -1; UA_Variant_setScalarCopy(&myVar.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]); const UA_QualifiedName myInteger2Name = UA_QUALIFIEDNAME(1, "the answer - not readable"); const UA_NodeId myInteger2NodeId = UA_NODEID_STRING(1, "the.answer.no.read"); UA_Server_addVariableNode(server, myInteger2NodeId, parentNodeId, parentReferenceNodeId, myInteger2Name, baseDataVariableType, myVar, NULL, NULL); UA_Variant_deleteMembers(&myVar.value); /* add a variable with the datetime data source */ UA_DataSource dateDataSource; dateDataSource.read = readTimeData; dateDataSource.write = NULL; UA_VariableAttributes v_attr = UA_VariableAttributes_default; v_attr.description = UA_LOCALIZEDTEXT("en-US", "current time"); v_attr.displayName = UA_LOCALIZEDTEXT("en-US", "current time"); v_attr.accessLevel = UA_ACCESSLEVELMASK_READ; v_attr.dataType = UA_TYPES[UA_TYPES_DATETIME].typeId; v_attr.valueRank = -1; const UA_QualifiedName dateName = UA_QUALIFIEDNAME(1, "current time"); UA_Server_addDataSourceVariableNode(server, UA_NODEID_NULL, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), dateName, baseDataVariableType, v_attr, dateDataSource, NULL, NULL); /* Add HelloWorld method to the server */ #ifdef UA_ENABLE_METHODCALLS /* Method with IO Arguments */ UA_Argument inputArguments; UA_Argument_init(&inputArguments); inputArguments.dataType = UA_TYPES[UA_TYPES_STRING].typeId; inputArguments.description = UA_LOCALIZEDTEXT("en-US", "Say your name"); inputArguments.name = UA_STRING("Name"); inputArguments.valueRank = -1; /* scalar argument */ UA_Argument outputArguments; UA_Argument_init(&outputArguments); outputArguments.arrayDimensionsSize = 0; outputArguments.arrayDimensions = NULL; outputArguments.dataType = UA_TYPES[UA_TYPES_STRING].typeId; outputArguments.description = UA_LOCALIZEDTEXT("en-US", "Receive a greeting"); outputArguments.name = UA_STRING("greeting"); outputArguments.valueRank = -1; UA_MethodAttributes addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "Hello World"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, 62541), UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "hello_world"), addmethodattributes, &helloWorld, /* callback of the method node */ 1, &inputArguments, 1, &outputArguments, NULL, NULL); #endif /* Add folders for demo information model */ #define DEMOID 50000 #define SCALARID 50001 #define ARRAYID 50002 #define MATRIXID 50003 #define DEPTHID 50004 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default; object_attr.description = UA_LOCALIZEDTEXT("en-US", "Demo"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Demo"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "Demo"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); object_attr.description = UA_LOCALIZEDTEXT("en-US", "Scalar"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Scalar"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "Scalar"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); object_attr.description = UA_LOCALIZEDTEXT("en-US", "Array"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Array"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, ARRAYID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "Array"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); object_attr.description = UA_LOCALIZEDTEXT("en-US", "Matrix"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Matrix"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, MATRIXID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "Matrix"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); /* Fill demo nodes for each type*/ UA_UInt32 id = 51000; // running id in namespace 0 for(UA_UInt32 type = 0; type < UA_TYPES_DIAGNOSTICINFO; type++) { if(type == UA_TYPES_VARIANT || type == UA_TYPES_DIAGNOSTICINFO) continue; UA_VariableAttributes attr = UA_VariableAttributes_default; attr.valueRank = -2; attr.dataType = UA_TYPES[type].typeId; #ifndef UA_ENABLE_TYPENAMES char name[15]; #if defined(_WIN32) && !defined(__MINGW32__) sprintf_s(name, 15, "%02d", type); #else sprintf(name, "%02d", type); #endif attr.displayName = UA_LOCALIZEDTEXT("en-US", name); UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME(1, name); #else attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", UA_TYPES[type].typeName); UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, UA_TYPES[type].typeName); #endif attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; attr.writeMask = UA_WRITEMASK_DISPLAYNAME | UA_WRITEMASK_DESCRIPTION; attr.userWriteMask = UA_WRITEMASK_DISPLAYNAME | UA_WRITEMASK_DESCRIPTION; /* add a scalar node for every built-in type */ void *value = UA_new(&UA_TYPES[type]); UA_Variant_setScalar(&attr.value, value, &UA_TYPES[type]); UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(1, ++id), UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), qualifiedName, baseDataVariableType, attr, NULL, NULL); UA_Variant_deleteMembers(&attr.value); /* add an array node for every built-in type */ UA_Variant_setArray(&attr.value, UA_Array_new(10, &UA_TYPES[type]), 10, &UA_TYPES[type]); UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(1, ++id), UA_NODEID_NUMERIC(1, ARRAYID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), qualifiedName, baseDataVariableType, attr, NULL, NULL); UA_Variant_deleteMembers(&attr.value); /* add an matrix node for every built-in type */ void *myMultiArray = UA_Array_new(9, &UA_TYPES[type]); attr.value.arrayDimensions = (UA_UInt32 *)UA_Array_new(2, &UA_TYPES[UA_TYPES_INT32]); attr.value.arrayDimensions[0] = 3; attr.value.arrayDimensions[1] = 3; attr.value.arrayDimensionsSize = 2; attr.value.arrayLength = 9; attr.value.data = myMultiArray; attr.value.type = &UA_TYPES[type]; UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(1, ++id), UA_NODEID_NUMERIC(1, MATRIXID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), qualifiedName, baseDataVariableType, attr, NULL, NULL); UA_Variant_deleteMembers(&attr.value); #ifdef UA_ENABLE_TYPENAMES UA_LocalizedText_deleteMembers(&attr.displayName); UA_QualifiedName_deleteMembers(&qualifiedName); #endif } /* Hierarchy of depth 10 for CTT testing with forward and inverse references */ /* Enter node "depth 9" in CTT configuration - Project->Settings->Server Test->NodeIds->Paths->Starting Node 1 */ object_attr.description = UA_LOCALIZEDTEXT("en-US", "DepthDemo"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "DepthDemo"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, DEPTHID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "DepthDemo"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); id = DEPTHID; // running id in namespace 0 - Start with Matrix NODE for(UA_UInt32 i = 1; i <= 20; i++) { char name[15]; #if defined(_WIN32) && !defined(__MINGW32__) sprintf_s(name, 15, "depth%i", i); #else sprintf(name, "depth%i", i); #endif object_attr.description = UA_LOCALIZEDTEXT("en-US", name); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", name); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, id + i), UA_NODEID_NUMERIC(1, i == 1 ? DEPTHID : id + i - 1), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, name), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); } /* Add the variable to some more places to get a node with three inverse references for the CTT */ UA_ExpandedNodeId answer_nodeid = UA_EXPANDEDNODEID_STRING(1, "the.answer"); UA_Server_addReference(server, UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), answer_nodeid, true); UA_Server_addReference(server, UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), answer_nodeid, true); /* Example for manually setting an attribute within the server */ UA_LocalizedText objectsName = UA_LOCALIZEDTEXT("en-US", "Objects"); UA_Server_writeDisplayName(server, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), objectsName); #define NOARGID 60000 #define INARGID 60001 #define OUTARGID 60002 #define INOUTARGID 60003 #ifdef UA_ENABLE_METHODCALLS /* adding some more method nodes to pass CTT */ /* Method without arguments */ addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "noarg"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, NOARGID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "noarg"), addmethodattributes, &noargMethod, /* callback of the method node */ 0, NULL, 0, NULL, NULL, NULL); /* Method with in arguments */ addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "inarg"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Argument_init(&inputArguments); inputArguments.dataType = UA_TYPES[UA_TYPES_INT32].typeId; inputArguments.description = UA_LOCALIZEDTEXT("en-US", "Input"); inputArguments.name = UA_STRING("Input"); inputArguments.valueRank = -1; //uaexpert will crash if set to 0 ;) UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, INARGID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "noarg"), addmethodattributes, &noargMethod, /* callback of the method node */ 1, &inputArguments, 0, NULL, NULL, NULL); /* Method with out arguments */ addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "outarg"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Argument_init(&outputArguments); outputArguments.dataType = UA_TYPES[UA_TYPES_INT32].typeId; outputArguments.description = UA_LOCALIZEDTEXT("en-US", "Output"); outputArguments.name = UA_STRING("Output"); outputArguments.valueRank = -1; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, OUTARGID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "outarg"), addmethodattributes, &outargMethod, /* callback of the method node */ 0, NULL, 1, &outputArguments, NULL, NULL); /* Method with inout arguments */ addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "inoutarg"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, INOUTARGID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "inoutarg"), addmethodattributes, &outargMethod, /* callback of the method node */ 1, &inputArguments, 1, &outputArguments, NULL, NULL); #endif /* run server */ UA_StatusCode retval = UA_Server_run(server, &running); UA_Server_delete(server); UA_ServerConfig_delete(config); return (int)retval; }
static void setInformationModel(UA_Server *server) { /* add a static variable node to the server */ UA_VariableAttributes myVar = UA_VariableAttributes_default; myVar.description = UA_LOCALIZEDTEXT("en-US", "the answer"); myVar.displayName = UA_LOCALIZEDTEXT("en-US", "the answer"); myVar.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; myVar.dataType = UA_TYPES[UA_TYPES_INT32].typeId; myVar.valueRank = UA_VALUERANK_SCALAR; UA_Int32 myInteger = 42; UA_Variant_setScalar(&myVar.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]); const UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer"); const UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer"); UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES); UA_Server_addVariableNode(server, myIntegerNodeId, parentNodeId, parentReferenceNodeId, myIntegerName, baseDataVariableType, myVar, NULL, NULL); /* add a static variable that is readable but not writable*/ myVar = UA_VariableAttributes_default; myVar.description = UA_LOCALIZEDTEXT("en-US", "the answer - not readable"); myVar.displayName = UA_LOCALIZEDTEXT("en-US", "the answer - not readable"); myVar.accessLevel = UA_ACCESSLEVELMASK_WRITE; myVar.dataType = UA_TYPES[UA_TYPES_INT32].typeId; myVar.valueRank = UA_VALUERANK_SCALAR; UA_Variant_setScalar(&myVar.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]); const UA_QualifiedName myInteger2Name = UA_QUALIFIEDNAME(1, "the answer - not readable"); const UA_NodeId myInteger2NodeId = UA_NODEID_STRING(1, "the.answer.no.read"); UA_Server_addVariableNode(server, myInteger2NodeId, parentNodeId, parentReferenceNodeId, myInteger2Name, baseDataVariableType, myVar, NULL, NULL); /* add a variable that is not readable or writable for the current user */ myVar = UA_VariableAttributes_default; myVar.description = UA_LOCALIZEDTEXT("en-US", "the answer - not current user"); myVar.displayName = UA_LOCALIZEDTEXT("en-US", "the answer - not current user"); myVar.accessLevel = UA_ACCESSLEVELMASK_WRITE; myVar.dataType = UA_TYPES[UA_TYPES_INT32].typeId; myVar.valueRank = UA_VALUERANK_SCALAR; myVar.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; UA_Variant_setScalar(&myVar.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]); const UA_QualifiedName accessDeniedName = UA_QUALIFIEDNAME(1, "the answer - not current user"); UA_Server_addVariableNode(server, accessDenied, parentNodeId, parentReferenceNodeId, accessDeniedName, baseDataVariableType, myVar, NULL, NULL); /* add a variable with the datetime data source */ UA_DataSource dateDataSource; dateDataSource.read = readTimeData; dateDataSource.write = NULL; UA_VariableAttributes v_attr = UA_VariableAttributes_default; v_attr.description = UA_LOCALIZEDTEXT("en-US", "current time"); v_attr.displayName = UA_LOCALIZEDTEXT("en-US", "current time"); v_attr.accessLevel = UA_ACCESSLEVELMASK_READ; v_attr.dataType = UA_TYPES[UA_TYPES_DATETIME].typeId; v_attr.valueRank = UA_VALUERANK_SCALAR; const UA_QualifiedName dateName = UA_QUALIFIEDNAME(1, "current time"); UA_Server_addDataSourceVariableNode(server, UA_NODEID_NUMERIC(1, 2345), UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), dateName, baseDataVariableType, v_attr, dateDataSource, NULL, NULL); /* add a bytestring variable with some content */ myVar = UA_VariableAttributes_default; myVar.description = UA_LOCALIZEDTEXT("", ""); myVar.displayName = UA_LOCALIZEDTEXT("", "example bytestring"); myVar.dataType = UA_TYPES[UA_TYPES_BYTESTRING].typeId; myVar.valueRank = UA_VALUERANK_SCALAR; myVar.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; UA_ByteString myByteString = UA_BYTESTRING("test123\0test123"); UA_Variant_setScalar(&myVar.value, &myByteString, &UA_TYPES[UA_TYPES_BYTESTRING]); const UA_QualifiedName byteStringName = UA_QUALIFIEDNAME(1, "example bytestring"); UA_Server_addVariableNode(server, UA_NODEID_STRING(1, "myByteString"), UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), byteStringName, baseDataVariableType, myVar, NULL, NULL); /* Add HelloWorld method to the server */ #ifdef UA_ENABLE_METHODCALLS /* Method with IO Arguments */ UA_Argument inputArguments; UA_Argument_init(&inputArguments); inputArguments.dataType = UA_TYPES[UA_TYPES_STRING].typeId; inputArguments.description = UA_LOCALIZEDTEXT("en-US", "Say your name"); inputArguments.name = UA_STRING("Name"); inputArguments.valueRank = UA_VALUERANK_SCALAR; /* scalar argument */ UA_Argument outputArguments; UA_Argument_init(&outputArguments); outputArguments.arrayDimensionsSize = 0; outputArguments.arrayDimensions = NULL; outputArguments.dataType = UA_TYPES[UA_TYPES_STRING].typeId; outputArguments.description = UA_LOCALIZEDTEXT("en-US", "Receive a greeting"); outputArguments.name = UA_STRING("greeting"); outputArguments.valueRank = UA_VALUERANK_SCALAR; UA_MethodAttributes addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "Hello World"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, 62541), UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "hello_world"), addmethodattributes, &helloWorld, /* callback of the method node */ 1, &inputArguments, 1, &outputArguments, NULL, NULL); #endif /* Add folders for demo information model */ #define DEMOID 50000 #define SCALARID 50001 #define ARRAYID 50002 #define MATRIXID 50003 #define DEPTHID 50004 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default; object_attr.description = UA_LOCALIZEDTEXT("en-US", "Demo"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Demo"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "Demo"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); object_attr.description = UA_LOCALIZEDTEXT("en-US", "Scalar"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Scalar"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "Scalar"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); object_attr.description = UA_LOCALIZEDTEXT("en-US", "Array"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Array"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, ARRAYID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "Array"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); object_attr.description = UA_LOCALIZEDTEXT("en-US", "Matrix"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Matrix"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, MATRIXID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "Matrix"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); /* Fill demo nodes for each type*/ UA_UInt32 matrixDims[2] = {3, 3}; UA_UInt32 id = 51000; // running id in namespace 0 for(UA_UInt32 type = 0; type < UA_TYPES_DIAGNOSTICINFO; type++) { if(type == UA_TYPES_VARIANT || type == UA_TYPES_DIAGNOSTICINFO) continue; UA_VariableAttributes attr = UA_VariableAttributes_default; attr.dataType = UA_TYPES[type].typeId; #ifndef UA_ENABLE_TYPENAMES char name[15]; UA_snprintf(name, 15, "%02d", type); attr.displayName = UA_LOCALIZEDTEXT("en-US", name); UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME(1, name); #else attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", UA_TYPES[type].typeName); UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, UA_TYPES[type].typeName); #endif attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; attr.writeMask = UA_WRITEMASK_DISPLAYNAME | UA_WRITEMASK_DESCRIPTION; attr.userWriteMask = UA_WRITEMASK_DISPLAYNAME | UA_WRITEMASK_DESCRIPTION; /* add a scalar node for every built-in type */ attr.valueRank = UA_VALUERANK_SCALAR; void *value = UA_new(&UA_TYPES[type]); UA_Variant_setScalar(&attr.value, value, &UA_TYPES[type]); UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(1, ++id), UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), qualifiedName, baseDataVariableType, attr, NULL, NULL); UA_Variant_clear(&attr.value); /* add an array node for every built-in type */ UA_UInt32 arrayDims = 0; attr.valueRank = UA_VALUERANK_ONE_DIMENSION; attr.arrayDimensions = &arrayDims; attr.arrayDimensionsSize = 1; UA_Variant_setArray(&attr.value, UA_Array_new(10, &UA_TYPES[type]), 10, &UA_TYPES[type]); UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(1, ++id), UA_NODEID_NUMERIC(1, ARRAYID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), qualifiedName, baseDataVariableType, attr, NULL, NULL); UA_Variant_clear(&attr.value); /* add an matrix node for every built-in type */ attr.valueRank = UA_VALUERANK_TWO_DIMENSIONS; attr.arrayDimensions = matrixDims; attr.arrayDimensionsSize = 2; void *myMultiArray = UA_Array_new(9, &UA_TYPES[type]); attr.value.arrayDimensions = (UA_UInt32 *)UA_Array_new(2, &UA_TYPES[UA_TYPES_INT32]); attr.value.arrayDimensions[0] = 3; attr.value.arrayDimensions[1] = 3; attr.value.arrayDimensionsSize = 2; attr.value.arrayLength = 9; attr.value.data = myMultiArray; attr.value.type = &UA_TYPES[type]; UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(1, ++id), UA_NODEID_NUMERIC(1, MATRIXID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), qualifiedName, baseDataVariableType, attr, NULL, NULL); UA_Variant_clear(&attr.value); #ifdef UA_ENABLE_TYPENAMES UA_LocalizedText_clear(&attr.displayName); UA_QualifiedName_clear(&qualifiedName); #endif } /* Add Integer and UInteger variables */ UA_VariableAttributes iattr = UA_VariableAttributes_default; iattr.dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_INTEGER); iattr.displayName = UA_LOCALIZEDTEXT("en-US", "Integer"); iattr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE; iattr.writeMask = UA_WRITEMASK_DISPLAYNAME | UA_WRITEMASK_DESCRIPTION; iattr.userWriteMask = UA_WRITEMASK_DISPLAYNAME | UA_WRITEMASK_DESCRIPTION; iattr.valueRank = UA_VALUERANK_SCALAR; UA_QualifiedName iQualifiedName = UA_QUALIFIEDNAME(1, "integer"); UA_Server_addVariableNode(server, UA_NODEID_STRING(1, "integer"), UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), iQualifiedName, baseDataVariableType, iattr, NULL, NULL); iattr.dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_UINTEGER); iattr.displayName = UA_LOCALIZEDTEXT("en-US", "UInteger"); UA_QualifiedName uQualifiedName = UA_QUALIFIEDNAME(1, "uinteger"); UA_Server_addVariableNode(server, UA_NODEID_STRING(1, "uinteger"), UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), uQualifiedName, baseDataVariableType, iattr, NULL, NULL); UA_Variant_clear(&iattr.value); /* Hierarchy of depth 10 for CTT testing with forward and inverse references */ /* Enter node "depth 9" in CTT configuration - Project->Settings->Server Test->NodeIds->Paths->Starting Node 1 */ object_attr.description = UA_LOCALIZEDTEXT("en-US", "DepthDemo"); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "DepthDemo"); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, DEPTHID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "DepthDemo"), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); id = DEPTHID; // running id in namespace 0 - Start with Matrix NODE for(UA_UInt32 i = 1; i <= 20; i++) { char name[15]; UA_snprintf(name, 15, "depth%i", i); object_attr.description = UA_LOCALIZEDTEXT("en-US", name); object_attr.displayName = UA_LOCALIZEDTEXT("en-US", name); UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(1, id + i), UA_NODEID_NUMERIC(1, i == 1 ? DEPTHID : id + i - 1), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, name), UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), object_attr, NULL, NULL); } /* Add the variable to some more places to get a node with three inverse references for the CTT */ UA_ExpandedNodeId answer_nodeid = UA_EXPANDEDNODEID_STRING(1, "the.answer"); UA_Server_addReference(server, UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), answer_nodeid, true); UA_Server_addReference(server, UA_NODEID_NUMERIC(1, SCALARID), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), answer_nodeid, true); /* Example for manually setting an attribute within the server */ UA_LocalizedText objectsName = UA_LOCALIZEDTEXT("en-US", "Objects"); UA_Server_writeDisplayName(server, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), objectsName); #define NOARGID 60000 #define INARGID 60001 #define OUTARGID 60002 #define INOUTARGID 60003 #ifdef UA_ENABLE_METHODCALLS /* adding some more method nodes to pass CTT */ /* Method without arguments */ addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "noarg"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, NOARGID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "noarg"), addmethodattributes, &noargMethod, /* callback of the method node */ 0, NULL, 0, NULL, NULL, NULL); /* Method with in arguments */ addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "inarg"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Argument_init(&inputArguments); inputArguments.dataType = UA_TYPES[UA_TYPES_INT32].typeId; inputArguments.description = UA_LOCALIZEDTEXT("en-US", "Input"); inputArguments.name = UA_STRING("Input"); inputArguments.valueRank = UA_VALUERANK_SCALAR; //uaexpert will crash if set to 0 ;) UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, INARGID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "noarg"), addmethodattributes, &noargMethod, /* callback of the method node */ 1, &inputArguments, 0, NULL, NULL, NULL); /* Method with out arguments */ addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "outarg"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Argument_init(&outputArguments); outputArguments.dataType = UA_TYPES[UA_TYPES_INT32].typeId; outputArguments.description = UA_LOCALIZEDTEXT("en-US", "Output"); outputArguments.name = UA_STRING("Output"); outputArguments.valueRank = UA_VALUERANK_SCALAR; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, OUTARGID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "outarg"), addmethodattributes, &outargMethod, /* callback of the method node */ 0, NULL, 1, &outputArguments, NULL, NULL); /* Method with inout arguments */ addmethodattributes = UA_MethodAttributes_default; addmethodattributes.displayName = UA_LOCALIZEDTEXT("en-US", "inoutarg"); addmethodattributes.executable = true; addmethodattributes.userExecutable = true; UA_Server_addMethodNode(server, UA_NODEID_NUMERIC(1, INOUTARGID), UA_NODEID_NUMERIC(1, DEMOID), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "inoutarg"), addmethodattributes, &outargMethod, /* callback of the method node */ 1, &inputArguments, 1, &outputArguments, NULL, NULL); #endif }
int main(int argc, char **argv) { signal(SIGINT, stopHandler); /* catches ctrl-c */ signal(SIGTERM, stopHandler); UA_ServerConfig *config = UA_ServerConfig_new_default(); UA_String_deleteMembers(&config->applicationDescription.applicationUri); config->applicationDescription.applicationUri = UA_String_fromChars("urn:open62541.example.server_register"); config->mdnsServerName = UA_String_fromChars("Sample Server"); // See http://www.opcfoundation.org/UA/schemas/1.03/ServerCapabilities.csv //config.serverCapabilitiesSize = 1; //UA_String caps = UA_String_fromChars("LDS"); //config.serverCapabilities = ∩︀ UA_Server *server = UA_Server_new(config); /* add a variable node to the address space */ UA_Int32 myInteger = 42; UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer"); UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer"); UA_DataSource dateDataSource; dateDataSource.read = readInteger; dateDataSource.write = writeInteger; UA_VariableAttributes attr = UA_VariableAttributes_default; attr.description = UA_LOCALIZEDTEXT("en-US", "the answer"); attr.displayName = UA_LOCALIZEDTEXT("en-US", "the answer"); UA_Server_addDataSourceVariableNode(server, myIntegerNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), myIntegerName, UA_NODEID_NULL, attr, dateDataSource, &myInteger, NULL); // periodic server register after 10 Minutes, delay first register for 500ms UA_StatusCode retval = UA_Server_addPeriodicServerRegisterCallback(server, DISCOVERY_SERVER_ENDPOINT, 10 * 60 * 1000, 500, NULL); // UA_StatusCode retval = UA_Server_addPeriodicServerRegisterJob(server, // "opc.tcp://localhost:4840", 10*60*1000, 500, NULL); if (retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Could not create periodic job for server register. StatusCode %s", UA_StatusCode_name(retval)); UA_Server_delete(server); UA_ServerConfig_delete(config); return (int)retval; } retval = UA_Server_run(server, &running); if (retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Could not start the server. StatusCode %s", UA_StatusCode_name(retval)); UA_Server_delete(server); UA_ServerConfig_delete(config); return (int)retval; } // UNregister the server from the discovery server. retval = UA_Server_unregister_discovery(server, DISCOVERY_SERVER_ENDPOINT); //retval = UA_Server_unregister_discovery(server, "opc.tcp://localhost:4840" ); if(retval != UA_STATUSCODE_GOOD) UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Could not unregister server from discovery server. StatusCode %s", UA_StatusCode_name(retval)); UA_Server_delete(server); UA_ServerConfig_delete(config); return (int)retval; }
int main(int argc, char **argv) { signal(SIGINT, stopHandler); /* catches ctrl-c */ signal(SIGTERM, stopHandler); UA_ServerConfig *config = UA_ServerConfig_new_minimal(16600, NULL); // To enable mDNS discovery, set application type to discovery server. config->applicationDescription.applicationType = UA_APPLICATIONTYPE_DISCOVERYSERVER; UA_String_deleteMembers(&config->applicationDescription.applicationUri); config->applicationDescription.applicationUri = UA_String_fromChars("urn:open62541.example.server_multicast"); config->mdnsServerName = UA_String_fromChars("Sample Multicast Server"); // See http://www.opcfoundation.org/UA/schemas/1.03/ServerCapabilities.csv //config.serverCapabilitiesSize = 1; //UA_String caps = UA_String_fromChars("LDS"); //config.serverCapabilities = ∩︀ UA_Server *server = UA_Server_new(config); self_discovery_url = &config->networkLayers[0].discoveryUrl; /* add a variable node to the address space */ UA_Int32 myInteger = 42; UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer"); UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer"); UA_DataSource dateDataSource; dateDataSource.read = readInteger; dateDataSource.write = writeInteger; UA_VariableAttributes attr = UA_VariableAttributes_default; attr.description = UA_LOCALIZEDTEXT("en-US", "the answer"); attr.displayName = UA_LOCALIZEDTEXT("en-US", "the answer"); UA_Server_addDataSourceVariableNode(server, myIntegerNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), myIntegerName, UA_NODEID_NULL, attr, dateDataSource, &myInteger, NULL); // callback which is called when a new server is detected through mDNS UA_Server_setServerOnNetworkCallback(server, serverOnNetworkCallback, NULL); // Start the server and call iterate to wait for the multicast discovery of the LDS UA_StatusCode retval = UA_Server_run_startup(server); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Could not start the server. StatusCode %s", UA_StatusCode_name(retval)); UA_Server_delete(server); UA_ServerConfig_delete(config); UA_free(discovery_url); return 1; } UA_LOG_INFO(logger, UA_LOGCATEGORY_SERVER, "Server started. Waiting for announce of LDS Server."); while (running && discovery_url == NULL) UA_Server_run_iterate(server, true); if(!running) { UA_Server_delete(server); UA_ServerConfig_delete(config); UA_free(discovery_url); return 1; } UA_LOG_INFO(logger, UA_LOGCATEGORY_SERVER, "LDS-ME server found on %s", discovery_url); /* Check if the server supports sign and encrypt. OPC Foundation LDS requires an encrypted session for * RegisterServer call, our server currently uses encrpytion optionally */ UA_EndpointDescription *endpointRegister = getRegisterEndpointFromServer(discovery_url); UA_free(discovery_url); if (endpointRegister == NULL || endpointRegister->securityMode == UA_MESSAGESECURITYMODE_INVALID) { UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Could not find any suitable endpoints on discovery server"); UA_Server_delete(server); UA_ServerConfig_delete(config); return 1; } UA_Client *clientRegister = getRegisterClient(endpointRegister, argc, argv); if (!clientRegister) { UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Could not create the client for remote registering"); UA_Server_delete(server); UA_ServerConfig_delete(config); return 1; } /* Connect the client */ char *endpointUrl = (char*)UA_malloc(endpointRegister->endpointUrl.length + 1); memcpy(endpointUrl, endpointRegister->endpointUrl.data, endpointRegister->endpointUrl.length); endpointUrl[endpointRegister->endpointUrl.length] = 0; retval = UA_Server_addPeriodicServerRegisterCallback(server, clientRegister, endpointUrl, 10 * 60 * 1000, 500, NULL); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Could not create periodic job for server register. StatusCode %s", UA_StatusCode_name(retval)); UA_free(endpointUrl); UA_Client_disconnect(clientRegister); UA_Client_delete(clientRegister); UA_Server_delete(server); UA_ServerConfig_delete(config); return 1; } while (running) UA_Server_run_iterate(server, true); UA_Server_run_shutdown(server); // UNregister the server from the discovery server. retval = UA_Server_unregister_discovery(server, clientRegister); if (retval != UA_STATUSCODE_GOOD) UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Could not unregister server from discovery server. " "StatusCode %s", UA_StatusCode_name(retval)); UA_free(endpointUrl); UA_Client_disconnect(clientRegister); UA_Client_delete(clientRegister); UA_Server_delete(server); UA_ServerConfig_delete(config); return (int)retval; }