| /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. |
| * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */ |
| /** |
| * This client requests all the available servers from the discovery server (see server_lds.c) |
| * and then calls GetEndpoints on the returned list of servers. |
| */ |
| |
| #include <open62541/client_config_default.h> |
| #include <open62541/client_highlevel.h> |
| #include <open62541/plugin/log_stdout.h> |
| |
| #include <stdlib.h> |
| |
| #define DISCOVERY_SERVER_ENDPOINT "opc.tcp://localhost:4840" |
| |
| 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; |
| } |