END_TEST START_TEST(SecureChannel_cableunplugged) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_Variant val; UA_Variant_init(&val); UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE); retval = UA_Client_readValueAttribute(client, nodeId, &val); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_Variant_deleteMembers(&val); UA_Client_recv = client->connection.recv; client->connection.recv = UA_Client_recvTesting; /* Simulate network cable unplugged (no response from server) */ UA_Client_recvTesting_result = UA_STATUSCODE_GOODNONCRITICALTIMEOUT; UA_Variant_init(&val); retval = UA_Client_readValueAttribute(client, nodeId, &val); ck_assert_uint_eq(retval, UA_STATUSCODE_BADCONNECTIONCLOSED); ck_assert_msg(UA_Client_getState(client) == UA_CLIENTSTATE_DISCONNECTED); UA_Client_recvTesting_result = UA_STATUSCODE_GOOD; UA_Client_delete(client); }
END_TEST /* Send an async message and receive the response when the securechannel timed out */ START_TEST(SecureChannel_networkfail) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_ReadRequest rq; UA_ReadRequest_init(&rq); UA_ReadValueId rvi; UA_ReadValueId_init(&rvi); rvi.attributeId = UA_ATTRIBUTEID_VALUE; rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE); rq.nodesToRead = &rvi; rq.nodesToReadSize = 1; /* Forward the clock after recv in the client */ UA_ClientConfig *cconfig = UA_Client_getConfig(client); UA_Client_recv = client->connection.recv; client->connection.recv = UA_Client_recvTesting; UA_Client_recvSleepDuration = cconfig->secureChannelLifeTime + 1; UA_Variant val; UA_Variant_init(&val); UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE); retval = UA_Client_readValueAttribute(client, nodeId, &val); ck_assert_msg(retval == UA_STATUSCODE_BADSECURECHANNELCLOSED); UA_Client_disconnect(client); UA_Client_delete(client); }
static void GetEndpointsAndCheck(const char* discoveryUrl, const char* filterTransportProfileUri, const UA_String expectedEndpointUrls[], size_t expectedEndpointUrlsSize) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); ck_assert_uint_eq(UA_Client_connect(client, discoveryUrl), UA_STATUSCODE_GOOD); UA_EndpointDescription* endpointArray = NULL; size_t endpointArraySize = 0; UA_String discoveryUrlUA = UA_String_fromChars(discoveryUrl); UA_StatusCode retval = GetEndpoints(client, &discoveryUrlUA, &endpointArraySize, &endpointArray, filterTransportProfileUri); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_String_deleteMembers(&discoveryUrlUA); ck_assert_uint_eq(endpointArraySize , expectedEndpointUrlsSize); for(size_t j = 0; j < endpointArraySize && j < expectedEndpointUrlsSize; j++) { UA_EndpointDescription* endpoint = &endpointArray[j]; ck_assert(UA_String_equal(&endpoint->endpointUrl, &expectedEndpointUrls[j])); } UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); UA_Client_delete(client); }
END_TEST /* Send the next message after the securechannel timed out */ START_TEST(SecureChannel_timeout_fail) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_ClientConfig *cconfig = UA_Client_getConfig(client); UA_fakeSleep(cconfig->secureChannelLifeTime + 1); UA_realSleep(50 + 1); // UA_MAXTIMEOUT+1 wait to be sure UA_Server_run_iterate can be completely executed UA_Variant val; UA_Variant_init(&val); UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE); retval = UA_Client_readValueAttribute(client, nodeId, &val); ck_assert(retval != UA_STATUSCODE_GOOD); UA_Variant_deleteMembers(&val); UA_Client_disconnect(client); UA_Client_delete(client); }
END_TEST #ifdef UA_ENABLE_DISCOVERY_SEMAPHORE #ifndef WIN32 #define SEMAPHORE_PATH "/tmp/open62541-unit-test-semaphore" #else #define SEMAPHORE_PATH ".\\open62541-unit-test-semaphore" #endif START_TEST(Server_register_semaphore) { // create the semaphore #ifndef WIN32 int fd = open(SEMAPHORE_PATH, O_RDWR|O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); ck_assert_int_ne(fd, -1); close(fd); #else FILE *fp; fopen_s(&fp, SEMAPHORE_PATH, "ab+"); ck_assert_ptr_ne(fp, NULL); fclose(fp); #endif UA_Client *clientRegister = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(clientRegister)); UA_StatusCode retval = UA_Client_connect_noSession(clientRegister, "opc.tcp://localhost:4840"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); retval = UA_Server_register_discovery(server_register, clientRegister, SEMAPHORE_PATH); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_Client_disconnect(clientRegister); UA_Client_delete(clientRegister); }
} END_TEST START_TEST(AddAndRemovePublishedDataSetItems){ UA_StatusCode retVal; UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); retVal = UA_Client_connect(client, "opc.tcp://localhost:4840"); if(retVal != UA_STATUSCODE_GOOD) { UA_Client_delete(client); } ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_Variant *inputArguments = (UA_Variant *) UA_calloc(4, (sizeof(UA_Variant))); UA_String pdsName = UA_STRING("Test PDS"); UA_Variant_setScalar(&inputArguments[0], &pdsName, &UA_TYPES[UA_TYPES_STRING]); UA_String *fieldNameAliases = (UA_String *) UA_calloc(2, sizeof(UA_String)); fieldNameAliases[0] = UA_STRING("field1"); fieldNameAliases[1] = UA_STRING("field2"); UA_Variant_setArray(&inputArguments[1], fieldNameAliases, 2, &UA_TYPES[UA_TYPES_STRING]); UA_DataSetFieldFlags *dataSetFieldFlags = (UA_DataSetFieldFlags *) UA_calloc(2, sizeof(UA_DataSetFieldFlags)); dataSetFieldFlags[0] = UA_DATASETFIELDFLAGS_PROMOTEDFIELD; dataSetFieldFlags[1] = UA_DATASETFIELDFLAGS_PROMOTEDFIELD; UA_Variant_setArray(&inputArguments[2], dataSetFieldFlags, 2, &UA_TYPES[UA_TYPES_DATASETFIELDFLAGS]); UA_PublishedVariableDataType *variablesToAdd = (UA_PublishedVariableDataType *) UA_calloc(2, sizeof(UA_PublishedVariableDataType)); variablesToAdd[0].publishedVariable = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_LOCALTIME); variablesToAdd[0].attributeId = UA_ATTRIBUTEID_VALUE; variablesToAdd[1].publishedVariable = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERREDUNDANCY_CURRENTSERVERID); variablesToAdd[1].attributeId = UA_ATTRIBUTEID_VALUE; UA_Variant_setArray(&inputArguments[3], variablesToAdd, 2, &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]); UA_CallMethodRequest callMethodRequest; UA_CallMethodRequest_init(&callMethodRequest); callMethodRequest.inputArgumentsSize = 4; callMethodRequest.inputArguments = inputArguments; callMethodRequest.objectId = UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS); callMethodRequest.methodId = UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS); UA_CallMethodResult result; UA_CallMethodResult_init(&result); result = UA_Server_call(server, &callMethodRequest); ck_assert_int_eq(3, result.outputArgumentsSize); ck_assert_int_eq(result.statusCode, UA_STATUSCODE_GOOD); //TODO checked correctness of created items UA_CallMethodResult_deleteMembers(&result); UA_free(inputArguments); UA_free(fieldNameAliases); UA_free(dataSetFieldFlags); UA_free(variablesToAdd); UA_Client_disconnect(client); UA_Client_delete(client); } END_TEST
int main(void) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_connect_username(client, "opc.tcp://localhost:4840", "paula", "paula123"); if(retval != UA_STATUSCODE_GOOD) { UA_Client_delete(client); return EXIT_FAILURE; } UA_NodeId newVariableIdRequest = UA_NODEID_NUMERIC(1, 1001); UA_NodeId newVariableId = UA_NODEID_NULL; UA_VariableAttributes newVariableAttributes = UA_VariableAttributes_default; newVariableAttributes.accessLevel = UA_ACCESSLEVELMASK_READ; newVariableAttributes.description = UA_LOCALIZEDTEXT_ALLOC("en-US", "NewVariable desc"); newVariableAttributes.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", "NewVariable"); newVariableAttributes.dataType = UA_TYPES[UA_TYPES_UINT32].typeId; UA_UInt32 value = 50; UA_Variant_setScalarCopy(&newVariableAttributes.value, &value, &UA_TYPES[UA_TYPES_UINT32]); UA_StatusCode retCode; retCode = UA_Client_addVariableNode(client, newVariableIdRequest, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_QUALIFIEDNAME(1, "newVariable"), UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), newVariableAttributes, &newVariableId); printf("addVariable returned: %s\n", UA_StatusCode_name(retCode)); UA_ExpandedNodeId extNodeId = UA_EXPANDEDNODEID_NUMERIC(0, 0); extNodeId.nodeId = newVariableId; retCode = UA_Client_addReference(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_TRUE, UA_STRING_NULL, extNodeId, UA_NODECLASS_VARIABLE); printf("addReference returned: %s\n", UA_StatusCode_name(retCode)); retCode = UA_Client_deleteReference(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), UA_TRUE, extNodeId, UA_TRUE); printf("deleteReference returned: %s\n", UA_StatusCode_name(retCode)); retCode = UA_Client_deleteNode(client, newVariableId, UA_TRUE); printf("deleteNode returned: %s\n", UA_StatusCode_name(retCode)); /* Clean up */ UA_VariableAttributes_clear(&newVariableAttributes); UA_Client_delete(client); /* Disconnects the client internally */ return EXIT_SUCCESS; }
static void FindOnNetworkAndCheck(UA_String expectedServerNames[], size_t expectedServerNamesSize, const char *filterUri, const char *filterLocale, const char** filterCapabilities, size_t filterCapabilitiesSize) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_ServerOnNetwork* serverOnNetwork = NULL; size_t serverOnNetworkSize = 0; size_t serverCapabilityFilterSize = 0; UA_String *serverCapabilityFilter = NULL; if(filterCapabilitiesSize) { serverCapabilityFilterSize = filterCapabilitiesSize; serverCapabilityFilter = (UA_String*)UA_malloc(sizeof(UA_String) * filterCapabilitiesSize); for(size_t i = 0; i < filterCapabilitiesSize; i++) serverCapabilityFilter[i] = UA_String_fromChars(filterCapabilities[i]); } UA_StatusCode retval = UA_Client_findServersOnNetwork(client, "opc.tcp://localhost:4840", 0, 0, serverCapabilityFilterSize, serverCapabilityFilter, &serverOnNetworkSize, &serverOnNetwork); if(serverCapabilityFilterSize) UA_Array_delete(serverCapabilityFilter, serverCapabilityFilterSize, &UA_TYPES[UA_TYPES_STRING]); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); // only the discovery server is expected ck_assert_uint_eq(serverOnNetworkSize , expectedServerNamesSize); if(expectedServerNamesSize > 0) ck_assert_ptr_ne(serverOnNetwork, NULL); if(serverOnNetwork != NULL) { for(size_t i = 0; i < expectedServerNamesSize; i++) { UA_Boolean expectedServerNameInServerOnNetwork = false; for(size_t j = 0; j < expectedServerNamesSize && !expectedServerNameInServerOnNetwork; j++) { expectedServerNameInServerOnNetwork = UA_String_equal(&serverOnNetwork[j].serverName, &expectedServerNames[i]); } ck_assert_msg(expectedServerNameInServerOnNetwork, "Expected %.*s in serverOnNetwork list, but not found", expectedServerNames[i].length, expectedServerNames[i].data); } } UA_Array_delete(serverOnNetwork, serverOnNetworkSize, &UA_TYPES[UA_TYPES_SERVERONNETWORK]); UA_Client_disconnect(client); UA_Client_delete(client); }
END_TEST START_TEST(Server_unregister) { UA_Client *clientRegister = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(clientRegister)); UA_StatusCode retval = UA_Client_connect_noSession(clientRegister, "opc.tcp://localhost:4840"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); retval = UA_Server_unregister_discovery(server_register, clientRegister); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_Client_disconnect(clientRegister); UA_Client_delete(clientRegister); }
} END_TEST START_TEST(Client_pass_fail) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_connect_username(client, "opc.tcp://localhost:4840", "user1", "secret"); ck_assert_uint_eq(retval, UA_STATUSCODE_BADUSERACCESSDENIED); UA_Client_disconnect(client); UA_Client_delete(client); } END_TEST
} END_TEST START_TEST(Client_user_pass_ok) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_connect_username(client, "opc.tcp://localhost:4840", "user1", "password"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_Client_disconnect(client); UA_Client_delete(client); } END_TEST
} END_TEST START_TEST(AddAndRemoveWriterGroups){ UA_StatusCode retVal; UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); retVal = UA_Client_connect(client, "opc.tcp://localhost:4840"); if(retVal != UA_STATUSCODE_GOOD) { UA_Client_delete(client); } ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_NodeId createdConnection = addPubSubConnection(); UA_Variant *inputArgument = (UA_Variant *) UA_calloc(1, (sizeof(UA_Variant))); UA_WriterGroupDataType writerGroupDataType; UA_WriterGroupDataType_init(&writerGroupDataType); writerGroupDataType.name = UA_STRING("TestWriterGroup"); writerGroupDataType.enabled = UA_TRUE; writerGroupDataType.publishingInterval = 500; writerGroupDataType.writerGroupId = 1234; UA_Variant_setScalar(inputArgument, &writerGroupDataType, &UA_TYPES[UA_TYPES_WRITERGROUPDATATYPE]); UA_CallMethodRequest callMethodRequest; UA_CallMethodRequest_init(&callMethodRequest); callMethodRequest.inputArgumentsSize = 1; callMethodRequest.inputArguments = inputArgument; callMethodRequest.objectId = createdConnection; callMethodRequest.methodId = UA_NODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP); UA_CallMethodResult result; UA_CallMethodResult_init(&result); result = UA_Server_call(server, &callMethodRequest); ck_assert_int_eq(result.statusCode, UA_STATUSCODE_GOOD); ck_assert_int_eq(1, result.outputArgumentsSize); UA_NodeId createdWriterGroup = UA_NODEID_NULL; if(result.outputArguments->type == &UA_TYPES[UA_TYPES_NODEID]) createdWriterGroup = *((UA_NodeId *) result.outputArguments->data); UA_LocalizedText writerGroupDisplayName; UA_LocalizedText_init(&writerGroupDisplayName); retVal = UA_Server_readDisplayName(server, createdWriterGroup, &writerGroupDisplayName); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_String compareText = UA_STRING("TestWriterGroup"); ck_assert(UA_String_equal(&writerGroupDisplayName.text, &compareText) == UA_TRUE); UA_free(inputArgument); UA_CallMethodResult_deleteMembers(&result); UA_Client_disconnect(client); UA_Client_delete(client); UA_LocalizedText_deleteMembers(&writerGroupDisplayName); } END_TEST
END_TEST #endif /* UA_ENABLE_DISCOVERY_SEMAPHORE */ START_TEST(Server_register_periodic) { ck_assert(clientRegisterRepeated == NULL); clientRegisterRepeated = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(clientRegisterRepeated)); ck_assert(clientRegisterRepeated != NULL); // periodic register every minute, first register immediately UA_StatusCode retval = UA_Server_addPeriodicServerRegisterCallback(server_register, clientRegisterRepeated, "opc.tcp://localhost:4840", 60*1000, 100, &periodicRegisterCallbackId); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); }
END_TEST START_TEST(SecureChannel_reconnect) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); client->state = UA_CLIENTSTATE_CONNECTED; retval = UA_Client_disconnect(client); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_ClientConfig *cconfig = UA_Client_getConfig(client); UA_fakeSleep(cconfig->secureChannelLifeTime + 1); UA_realSleep(50 + 1); retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_Client_delete(client); }
static void setup(void) { if (!(MUTEX_INIT(serverMutex))) { fprintf(stderr, "Server mutex was not created correctly.\n"); exit(1); } running = true; server = UA_Server_new(); UA_ServerConfig *config = UA_Server_getConfig(server); UA_ServerConfig_setDefault(config); #ifdef UA_ENABLE_HISTORIZING gathering = (UA_HistoryDataGathering*)UA_calloc(1, sizeof(UA_HistoryDataGathering)); *gathering = UA_HistoryDataGathering_Default(1); config->historyDatabase = UA_HistoryDatabase_default(*gathering); #endif UA_StatusCode retval = UA_Server_run_startup(server); if(retval != UA_STATUSCODE_GOOD) { fprintf(stderr, "Error while calling Server_run_startup. %s\n", UA_StatusCode_name(retval)); UA_Server_delete(server); exit(1); } THREAD_CREATE(server_thread, serverloop); /* Define the attribute of the uint32 variable node */ UA_VariableAttributes attr = UA_VariableAttributes_default; UA_UInt32 myUint32 = 40; UA_Variant_setScalar(&attr.value, &myUint32, &UA_TYPES[UA_TYPES_UINT32]); attr.description = UA_LOCALIZEDTEXT("en-US","the answer"); attr.displayName = UA_LOCALIZEDTEXT("en-US","the answer"); attr.dataType = UA_TYPES[UA_TYPES_UINT32].typeId; attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE | UA_ACCESSLEVELMASK_HISTORYREAD | UA_ACCESSLEVELMASK_HISTORYWRITE; attr.historizing = true; /* Add the variable node to the information model */ UA_NodeId uint32NodeId = UA_NODEID_STRING(1, "the.answer"); UA_QualifiedName uint32Name = UA_QUALIFIEDNAME(1, "the answer"); parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES); UA_NodeId_init(&outNodeId); retval = UA_Server_addVariableNode(server, uint32NodeId, parentNodeId, parentReferenceNodeId, uint32Name, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), attr, NULL, &outNodeId); if (retval != UA_STATUSCODE_GOOD) { fprintf(stderr, "Error adding variable node. %s\n", UA_StatusCode_name(retval)); UA_Server_delete(server); exit(1); } client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); if (retval != UA_STATUSCODE_GOOD) { fprintf(stderr, "Client can not connect to opc.tcp://localhost:4840. %s\n", UA_StatusCode_name(retval)); UA_Client_delete(client); UA_Server_delete(server); exit(1); } UA_Client_recv = client->connection.recv; client->connection.recv = UA_Client_recvTesting; }
int main(void) { /* * Example for calling FindServersOnNetwork */ { UA_ServerOnNetwork *serverOnNetwork = NULL; size_t serverOnNetworkSize = 0; UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_findServersOnNetwork(client, DISCOVERY_SERVER_ENDPOINT, 0, 0, 0, NULL, &serverOnNetworkSize, &serverOnNetwork); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Could not call FindServersOnNetwork service. " "Is the discovery server started? StatusCode %s", UA_StatusCode_name(retval)); UA_Client_delete(client); return EXIT_FAILURE; } // output all the returned/registered servers for(size_t i = 0; i < serverOnNetworkSize; i++) { UA_ServerOnNetwork *server = &serverOnNetwork[i]; printf("Server[%lu]: %.*s", (unsigned long) i, (int) server->serverName.length, server->serverName.data); printf("\n\tRecordID: %d", server->recordId); printf("\n\tDiscovery URL: %.*s", (int) server->discoveryUrl.length, server->discoveryUrl.data); printf("\n\tCapabilities: "); for(size_t j = 0; j < server->serverCapabilitiesSize; j++) { printf("%.*s,", (int) server->serverCapabilities[j].length, server->serverCapabilities[j].data); } printf("\n\n"); } UA_Array_delete(serverOnNetwork, serverOnNetworkSize, &UA_TYPES[UA_TYPES_SERVERONNETWORK]); } /* Example for calling FindServers */ UA_ApplicationDescription *applicationDescriptionArray = NULL; size_t applicationDescriptionArraySize = 0; UA_StatusCode retval; { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); retval = UA_Client_findServers(client, DISCOVERY_SERVER_ENDPOINT, 0, NULL, 0, NULL, &applicationDescriptionArraySize, &applicationDescriptionArray); UA_Client_delete(client); } if(retval != UA_STATUSCODE_GOOD) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Could not call FindServers service. " "Is the discovery server started? StatusCode %s", UA_StatusCode_name(retval)); return EXIT_FAILURE; } // output all the returned/registered servers for(size_t i = 0; i < applicationDescriptionArraySize; i++) { UA_ApplicationDescription *description = &applicationDescriptionArray[i]; printf("Server[%lu]: %.*s", (unsigned long) i, (int) description->applicationUri.length, description->applicationUri.data); printf("\n\tName: %.*s", (int) description->applicationName.text.length, description->applicationName.text.data); printf("\n\tApplication URI: %.*s", (int) description->applicationUri.length, description->applicationUri.data); printf("\n\tProduct URI: %.*s", (int) description->productUri.length, description->productUri.data); printf("\n\tType: "); switch(description->applicationType) { case UA_APPLICATIONTYPE_SERVER: printf("Server"); break; case UA_APPLICATIONTYPE_CLIENT: printf("Client"); break; case UA_APPLICATIONTYPE_CLIENTANDSERVER: printf("Client and Server"); break; case UA_APPLICATIONTYPE_DISCOVERYSERVER: printf("Discovery Server"); break; default: printf("Unknown"); } printf("\n\tDiscovery URLs:"); for(size_t j = 0; j < description->discoveryUrlsSize; j++) { printf("\n\t\t[%lu]: %.*s", (unsigned long) j, (int) description->discoveryUrls[j].length, description->discoveryUrls[j].data); } printf("\n\n"); } /* * Now that we have the list of available servers, call get endpoints on all of them */ printf("-------- Server Endpoints --------\n"); for(size_t i = 0; i < applicationDescriptionArraySize; i++) { UA_ApplicationDescription *description = &applicationDescriptionArray[i]; if(description->discoveryUrlsSize == 0) { UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "[GetEndpoints] Server %.*s did not provide any discovery urls. Skipping.", (int)description->applicationUri.length, description->applicationUri.data); continue; } printf("\nEndpoints for Server[%lu]: %.*s\n", (unsigned long) i, (int) description->applicationUri.length, description->applicationUri.data); UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); char *discoveryUrl = (char *) UA_malloc(sizeof(char) * description->discoveryUrls[0].length + 1); memcpy(discoveryUrl, description->discoveryUrls[0].data, description->discoveryUrls[0].length); discoveryUrl[description->discoveryUrls[0].length] = '\0'; UA_EndpointDescription *endpointArray = NULL; size_t endpointArraySize = 0; //TODO: adapt to the new async getEndpoint retval = UA_Client_getEndpoints(client, discoveryUrl, &endpointArraySize, &endpointArray); UA_free(discoveryUrl); if(retval != UA_STATUSCODE_GOOD) { UA_Client_disconnect(client); UA_Client_delete(client); break; } for(size_t j = 0; j < endpointArraySize; j++) { UA_EndpointDescription *endpoint = &endpointArray[j]; printf("\n\tEndpoint[%lu]:", (unsigned long) j); printf("\n\t\tEndpoint URL: %.*s", (int) endpoint->endpointUrl.length, endpoint->endpointUrl.data); printf("\n\t\tTransport profile URI: %.*s", (int) endpoint->transportProfileUri.length, endpoint->transportProfileUri.data); printf("\n\t\tSecurity Mode: "); switch(endpoint->securityMode) { case UA_MESSAGESECURITYMODE_INVALID: printf("Invalid"); break; case UA_MESSAGESECURITYMODE_NONE: printf("None"); break; case UA_MESSAGESECURITYMODE_SIGN: printf("Sign"); break; case UA_MESSAGESECURITYMODE_SIGNANDENCRYPT: printf("Sign and Encrypt"); break; default: printf("No valid security mode"); break; } printf("\n\t\tSecurity profile URI: %.*s", (int) endpoint->securityPolicyUri.length, endpoint->securityPolicyUri.data); printf("\n\t\tSecurity Level: %d", endpoint->securityLevel); } UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); UA_Client_delete(client); } printf("\n"); UA_Array_delete(applicationDescriptionArray, applicationDescriptionArraySize, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); return EXIT_SUCCESS; }
} END_TEST START_TEST(AddAndRemovePublishedDataSetFolders){ UA_StatusCode retVal; UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); retVal = UA_Client_connect(client, "opc.tcp://localhost:4840"); if(retVal != UA_STATUSCODE_GOOD) { UA_Client_delete(client); } ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_String folderName = UA_STRING("TestFolder"); UA_Variant inputArguments; UA_Variant_init(&inputArguments); UA_Variant_setScalar(&inputArguments, &folderName, &UA_TYPES[UA_TYPES_STRING]); UA_CallMethodRequest callMethodRequest; UA_CallMethodRequest_init(&callMethodRequest); callMethodRequest.inputArgumentsSize = 1; callMethodRequest.inputArguments = &inputArguments; callMethodRequest.objectId = UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS); callMethodRequest.methodId = UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER); UA_CallMethodResult result; UA_CallMethodResult_init(&result); result = UA_Server_call(server, &callMethodRequest); ck_assert_int_eq(1, result.outputArgumentsSize); ck_assert_int_eq(result.statusCode, UA_STATUSCODE_GOOD); UA_NodeId createdFolder = UA_NODEID_NULL; if(result.outputArguments->type == &UA_TYPES[UA_TYPES_NODEID]) createdFolder = *((UA_NodeId *) result.outputArguments->data); UA_LocalizedText connectionDisplayName; UA_LocalizedText_init(&connectionDisplayName); retVal = UA_Server_readDisplayName(server, createdFolder, &connectionDisplayName); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_String compareText = UA_STRING("TestFolder"); ck_assert(UA_String_equal(&connectionDisplayName.text, &compareText) == UA_TRUE); retVal = UA_Server_readNodeId(server, createdFolder, &createdFolder); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_CallMethodResult_deleteMembers(&result); UA_LocalizedText_deleteMembers(&connectionDisplayName); //create folder inside the new folder folderName = UA_STRING("TestFolder2"); UA_Variant_init(&inputArguments); UA_Variant_setScalar(&inputArguments, &folderName, &UA_TYPES[UA_TYPES_STRING]); UA_CallMethodRequest_init(&callMethodRequest); callMethodRequest.inputArgumentsSize = 1; callMethodRequest.inputArguments = &inputArguments; callMethodRequest.objectId = createdFolder; callMethodRequest.methodId = UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER); UA_CallMethodResult_init(&result); result = UA_Server_call(server, &callMethodRequest); ck_assert_int_eq(1, result.outputArgumentsSize); ck_assert_int_eq(result.statusCode, UA_STATUSCODE_GOOD); UA_NodeId createdFolder2 = UA_NODEID_NULL; if(result.outputArguments->type == &UA_TYPES[UA_TYPES_NODEID]) createdFolder2 = *((UA_NodeId *) result.outputArguments->data); UA_LocalizedText_init(&connectionDisplayName); retVal = UA_Server_readDisplayName(server, createdFolder2, &connectionDisplayName); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); compareText = UA_STRING("TestFolder2"); ck_assert(UA_String_equal(&connectionDisplayName.text, &compareText) == UA_TRUE); retVal = UA_Server_readNodeId(server, createdFolder2, &createdFolder2); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_CallMethodResult_deleteMembers(&result); //delete the folder UA_Variant_init(&inputArguments); UA_Variant_setScalar(&inputArguments, &createdFolder, &UA_TYPES[UA_TYPES_NODEID]); UA_CallMethodRequest_init(&callMethodRequest); callMethodRequest.inputArgumentsSize = 1; callMethodRequest.inputArguments = &inputArguments; callMethodRequest.objectId = UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS); callMethodRequest.methodId = UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER); result = UA_Server_call(server, &callMethodRequest); ck_assert_int_eq(0, result.outputArgumentsSize); ck_assert_int_eq(result.statusCode, UA_STATUSCODE_GOOD); //check if the node is deleted retVal = UA_Server_readNodeId(server, createdFolder, NULL); ck_assert_int_eq(retVal, UA_STATUSCODE_BADNODEIDUNKNOWN); UA_CallMethodResult_deleteMembers(&result); UA_Client_disconnect(client); UA_Client_delete(client); UA_LocalizedText_deleteMembers(&connectionDisplayName); } END_TEST
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); }