static void setup_lds(void) { // start LDS server running_lds = UA_Boolean_new(); *running_lds = true; config_lds = UA_ServerConfig_new_default(); config_lds->applicationDescription.applicationType = UA_APPLICATIONTYPE_DISCOVERYSERVER; UA_String_deleteMembers(&config_lds->applicationDescription.applicationUri); config_lds->applicationDescription.applicationUri = UA_STRING_ALLOC("urn:open62541.test.local_discovery_server"); UA_LocalizedText_deleteMembers(&config_lds->applicationDescription.applicationName); config_lds->applicationDescription.applicationName = UA_LOCALIZEDTEXT_ALLOC("en", "LDS Server"); config_lds->mdnsServerName = UA_String_fromChars("LDS_test"); config_lds->serverCapabilitiesSize = 1; UA_String *caps = UA_String_new(); *caps = UA_String_fromChars("LDS"); config_lds->serverCapabilities = caps; config_lds->discoveryCleanupTimeout = registerTimeout; server_lds = UA_Server_new(config_lds); UA_Server_run_startup(server_lds); pthread_create(&server_thread_lds, NULL, serverloop_lds, NULL); // wait until LDS started UA_sleep(1000); sleep(1); }
static void configure_lds_server(UA_Server *pServer) { UA_ServerConfig *config_lds = UA_Server_getConfig(pServer); UA_ServerConfig_setDefault(config_lds); config_lds->applicationDescription.applicationType = UA_APPLICATIONTYPE_DISCOVERYSERVER; UA_String_deleteMembers(&config_lds->applicationDescription.applicationUri); config_lds->applicationDescription.applicationUri = UA_STRING_ALLOC("urn:open62541.test.local_discovery_server"); UA_LocalizedText_deleteMembers(&config_lds->applicationDescription.applicationName); config_lds->applicationDescription.applicationName = UA_LOCALIZEDTEXT_ALLOC("en", "LDS Server"); config_lds->discovery.mdnsEnable = true; #ifdef UA_ENABLE_DISCOVERY_MULTICAST config_lds->discovery.mdns.mdnsServerName = UA_String_fromChars("LDS_test"); config_lds->discovery.mdns.serverCapabilitiesSize = 1; UA_String *caps = UA_String_new(); *caps = UA_String_fromChars("LDS"); config_lds->discovery.mdns.serverCapabilities = caps; #endif config_lds->discovery.cleanupTimeout = registerTimeout; }
END_TEST static void FindAndCheck(const UA_String expectedUris[], size_t expectedUrisSize, const UA_String expectedLocales[], const UA_String expectedNames[], const char *filterUri, const char *filterLocale) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_ApplicationDescription* applicationDescriptionArray = NULL; size_t applicationDescriptionArraySize = 0; size_t serverUrisSize = 0; UA_String *serverUris = NULL; if(filterUri) { serverUrisSize = 1; serverUris = UA_String_new(); serverUris[0] = UA_String_fromChars(filterUri); } size_t localeIdsSize = 0; UA_String *localeIds = NULL; if(filterLocale) { localeIdsSize = 1; localeIds = UA_String_new(); localeIds[0] = UA_String_fromChars(filterLocale); } UA_StatusCode retval = UA_Client_findServers(client, "opc.tcp://localhost:4840", serverUrisSize, serverUris, localeIdsSize, localeIds, &applicationDescriptionArraySize, &applicationDescriptionArray); if(filterUri) UA_Array_delete(serverUris, serverUrisSize, &UA_TYPES[UA_TYPES_STRING]); if(filterLocale) UA_Array_delete(localeIds, localeIdsSize, &UA_TYPES[UA_TYPES_STRING]); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); // only the discovery server is expected ck_assert_uint_eq(applicationDescriptionArraySize, expectedUrisSize); ck_assert(applicationDescriptionArray != NULL); for(size_t i = 0; i < expectedUrisSize; ++i) { ck_assert(UA_String_equal(&applicationDescriptionArray[i].applicationUri, &expectedUris[i])); if(expectedNames) ck_assert(UA_String_equal(&applicationDescriptionArray[i].applicationName.text, &expectedNames[i])); if (expectedLocales) ck_assert(UA_String_equal(&applicationDescriptionArray[i].applicationName.locale, &expectedLocales[i])); } UA_Array_delete(applicationDescriptionArray, applicationDescriptionArraySize, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); UA_Client_disconnect(client); UA_Client_delete(client); }
OV_DLLFNCEXPORT OV_RESULT opcuafb_Write_Execute_set( OV_INSTPTR_opcuafb_Write pinst, const OV_BOOL value ) { OV_INSTPTR_opcuafb_Connect pConnect = NULL; OV_INSTPTR_opcuafb_NodeGetHandle pNodeGetHandle = NULL; UA_WriteRequest WriteRequest; UA_WriteResponse WriteResponse; UA_String tempString; UA_DateTime *tempTime; char *endPtr = NULL; unsigned long int tempulong = 0; if(value == FALSE || pinst->v_Execute == TRUE){ //only react on the rising edge pinst->v_Execute = value; return OV_ERR_OK; } pConnect = Ov_DynamicPtrCast(opcuafb_Connect, fb_connection_getFirstConnectedObject(Ov_PtrUpCast(fb_object, pinst), FALSE, TRUE, "ConnectionHdl")); if(pConnect == NULL){ pinst->v_Error = TRUE; pinst->v_ErrorID = 1; //todo return OV_ERR_BADVALUE; } if(pConnect->v_ConnectionHdl == 0){ pinst->v_Error = TRUE; pinst->v_ErrorID = 1; //todo return OV_ERR_BADVALUE; } if(pConnect->v_Client == NULL){ //internal error pinst->v_Error = TRUE; pinst->v_ErrorID = 1; //todo return OV_ERR_BADVALUE; } pNodeGetHandle = Ov_DynamicPtrCast(opcuafb_NodeGetHandle, fb_connection_getFirstConnectedObject(Ov_PtrUpCast(fb_object, pinst), FALSE, TRUE, "NodeHdl")); if(pNodeGetHandle == NULL){ pinst->v_Error = TRUE; pinst->v_ErrorID = 1; //todo return OV_ERR_BADVALUE; } if(pNodeGetHandle->v_NodeHdl == 0){ pinst->v_Error = TRUE; pinst->v_ErrorID = 1; //todo return OV_ERR_BADVALUE; } UA_WriteRequest_init(&WriteRequest); WriteRequest.nodesToWrite = UA_WriteValue_new(); WriteRequest.nodesToWriteSize = 1; WriteRequest.nodesToWrite[0].attributeId = UA_ATTRIBUTEID_VALUE; WriteRequest.nodesToWrite[0].value.hasValue = UA_TRUE; if(pNodeGetHandle->v_NodeID.IdentifierType == UA_IDTYPE_STRING){ WriteRequest.nodesToWrite[0].nodeId = UA_NODEID_STRING_ALLOC(pNodeGetHandle->v_NodeID.NamespaceIndex, pNodeGetHandle->v_NodeID.Identifier); }else if(pNodeGetHandle->v_NodeID.IdentifierType == UA_IDTYPE_NUMERIC){ tempulong = strtoul(pNodeGetHandle->v_NodeID.Identifier, &endPtr, 10); if (ERANGE != errno && tempulong < UINT16_MAX && endPtr != pNodeGetHandle->v_NodeID.Identifier) { WriteRequest.nodesToWrite[0].nodeId = UA_NODEID_NUMERIC(pNodeGetHandle->v_NodeID.NamespaceIndex, (UA_UInt16)tempulong); } WriteRequest.nodesToWrite[0].nodeId = UA_NODEID_NUMERIC(pNodeGetHandle->v_NodeID.NamespaceIndex, atoi(pNodeGetHandle->v_NodeID.Identifier)); // }else if(pNodeGetHandle->v_NodeID.IdentifierType == UA_IDTYPE_GUID){ //todo //WriteRequest.nodesToWrite[0].nodeId = UA_NODEID_GUID(pNodeGetHandle->v_NodeID.NamespaceIndex, pNodeGetHandle->v_NodeID.Identifier); }else{ UA_WriteRequest_deleteMembers(&WriteRequest); return OV_ERR_BADVALUE; } switch (pinst->v_Variable.value.vartype & OV_VT_KSMASK){ case OV_VT_INT: WriteRequest.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_INT32]; WriteRequest.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA_NODELETE; //do not free the data on deletion WriteRequest.nodesToWrite[0].value.value.data = &pinst->v_Variable.value.valueunion.val_int; break; case OV_VT_UINT: WriteRequest.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_UINT32]; WriteRequest.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA_NODELETE; //do not free the data on deletion WriteRequest.nodesToWrite[0].value.value.data = &pinst->v_Variable.value.valueunion.val_uint; break; case OV_VT_SINGLE: WriteRequest.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_FLOAT]; WriteRequest.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA_NODELETE; //do not free the data on deletion WriteRequest.nodesToWrite[0].value.value.data = &pinst->v_Variable.value.valueunion.val_single; break; case OV_VT_DOUBLE: WriteRequest.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_DOUBLE]; WriteRequest.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA_NODELETE; //do not free the data on deletion WriteRequest.nodesToWrite[0].value.value.data = &pinst->v_Variable.value.valueunion.val_double; break; case OV_VT_STRING: WriteRequest.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_STRING]; WriteRequest.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA; //free the data on deletion WriteRequest.nodesToWrite[0].value.value.data = UA_String_new(); tempString = UA_String_fromChars(pinst->v_Variable.value.valueunion.val_string); WriteRequest.nodesToWrite[0].value.value.data = &tempString; break; case OV_VT_TIME: WriteRequest.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_DATETIME]; WriteRequest.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA; //free the data on deletion tempTime = UA_DateTime_new(); if(tempTime){ *tempTime = ov_ovTimeTo1601nsTime(pinst->v_Variable.value.valueunion.val_time); WriteRequest.nodesToWrite[0].value.value.data = tempTime; }else{ pinst->v_Error = TRUE; pinst->v_ErrorID = 1; // todo } break; default: break; } WriteResponse = UA_Client_Service_write(pConnect->v_Client, WriteRequest); if(WriteResponse.responseHeader.serviceResult != UA_STATUSCODE_GOOD){ pinst->v_Error = FALSE; pinst->v_ErrorID = 0; }else{ pinst->v_Error = TRUE; pinst->v_ErrorID = 1; // todo } UA_WriteResponse_deleteMembers(&WriteResponse); UA_WriteRequest_deleteMembers(&WriteRequest); pinst->v_Done = TRUE; pinst->v_Execute = value; return OV_ERR_OK; }