blob: e627de08eae183b50bcb35e652d064a77e239d42 [file] [log] [blame]
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2015-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
* Copyright 2015-2016 (c) Sten GrĂ¼ner
* Copyright 2015-2016 (c) Chris Iatrou
* Copyright 2015-2017 (c) Florian Palm
* Copyright 2015 (c) Holger Jeromin
* Copyright 2015 (c) Oleksiy Vasylyev
* Copyright 2017 (c) Stefan Profanter, fortiss GmbH
* Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
* Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA
* Copyright 2018 (c) Kalycito Infotech Private Limited
*/
#ifndef UA_CLIENT_H_
#define UA_CLIENT_H_
#include <open62541/client_config.h>
#include <open62541/nodeids.h>
#include <open62541/types.h>
#include <open62541/types_generated.h>
#include <open62541/types_generated_handling.h>
_UA_BEGIN_DECLS
/**
* .. _client:
*
* Client
* ======
*
* The client implementation allows remote access to all OPC UA services. For
* convenience, some functionality has been wrapped in :ref:`high-level
* abstractions <client-highlevel>`.
*
* **However**: At this time, the client does not yet contain its own thread or
* event-driven main-loop. So the client will not perform any actions
* automatically in the background. This is especially relevant for
* subscriptions. The user will have to periodically call
* `UA_Client_Subscriptions_manuallySendPublishRequest`. See also :ref:`here
* <client-subscriptions>`.
*
*
* .. include:: client_config.rst
*
* Client Lifecycle
* ---------------- */
/* Create a new client */
UA_Client UA_EXPORT *
UA_Client_new(void);
/* Get the client connection status */
UA_ClientState UA_EXPORT
UA_Client_getState(UA_Client *client);
/* Get the client configuration */
UA_EXPORT UA_ClientConfig *
UA_Client_getConfig(UA_Client *client);
/* Get the client context */
static UA_INLINE void *
UA_Client_getContext(UA_Client *client) {
UA_ClientConfig *config = UA_Client_getConfig(client); /* Cannot fail */
return config->clientContext;
}
/* Reset a client */
void UA_EXPORT
UA_Client_reset(UA_Client *client);
/* Delete a client */
void UA_EXPORT
UA_Client_delete(UA_Client *client);
/**
* Connect to a Server
* ------------------- */
typedef void (*UA_ClientAsyncServiceCallback)(UA_Client *client, void *userdata,
UA_UInt32 requestId, void *response);
/* Connect to the server
*
* @param client to use
* @param endpointURL to connect (for example "opc.tcp://localhost:4840")
* @return Indicates whether the operation succeeded or returns an error code */
UA_StatusCode UA_EXPORT
UA_Client_connect(UA_Client *client, const char *endpointUrl);
UA_StatusCode UA_EXPORT
UA_Client_connect_async(UA_Client *client, const char *endpointUrl,
UA_ClientAsyncServiceCallback callback,
void *userdata);
/* Connect to the server without creating a session
*
* @param client to use
* @param endpointURL to connect (for example "opc.tcp://localhost:4840")
* @return Indicates whether the operation succeeded or returns an error code */
UA_StatusCode UA_EXPORT
UA_Client_connect_noSession(UA_Client *client, const char *endpointUrl);
/* Connect to the selected server with the given username and password
*
* @param client to use
* @param endpointURL to connect (for example "opc.tcp://localhost:4840")
* @param username
* @param password
* @return Indicates whether the operation succeeded or returns an error code */
UA_StatusCode UA_EXPORT
UA_Client_connect_username(UA_Client *client, const char *endpointUrl,
const char *username, const char *password);
/* Disconnect and close a connection to the selected server */
UA_StatusCode UA_EXPORT
UA_Client_disconnect(UA_Client *client);
UA_StatusCode UA_EXPORT
UA_Client_disconnect_async(UA_Client *client, UA_UInt32 *requestId);
/* Close a connection to the selected server */
UA_DEPRECATED static UA_INLINE UA_StatusCode
UA_Client_close(UA_Client *client) {
return UA_Client_disconnect(client);
}
/**
* Discovery
* --------- */
/* Gets a list of endpoints of a server
*
* @param client to use. Must be connected to the same endpoint given in
* serverUrl or otherwise in disconnected state.
* @param serverUrl url to connect (for example "opc.tcp://localhost:4840")
* @param endpointDescriptionsSize size of the array of endpoint descriptions
* @param endpointDescriptions array of endpoint descriptions that is allocated
* by the function (you need to free manually)
* @return Indicates whether the operation succeeded or returns an error code */
UA_StatusCode UA_EXPORT
UA_Client_getEndpoints(UA_Client *client, const char *serverUrl,
size_t* endpointDescriptionsSize,
UA_EndpointDescription** endpointDescriptions);
/* Gets a list of all registered servers at the given server.
*
* You can pass an optional filter for serverUris. If the given server is not registered,
* an empty array will be returned. If the server is registered, only that application
* description will be returned.
*
* Additionally you can optionally indicate which locale you want for the server name
* in the returned application description. The array indicates the order of preference.
* A server may have localized names.
*
* @param client to use. Must be connected to the same endpoint given in
* serverUrl or otherwise in disconnected state.
* @param serverUrl url to connect (for example "opc.tcp://localhost:4840")
* @param serverUrisSize Optional filter for specific server uris
* @param serverUris Optional filter for specific server uris
* @param localeIdsSize Optional indication which locale you prefer
* @param localeIds Optional indication which locale you prefer
* @param registeredServersSize size of returned array, i.e., number of found/registered servers
* @param registeredServers array containing found/registered servers
* @return Indicates whether the operation succeeded or returns an error code */
UA_StatusCode UA_EXPORT
UA_Client_findServers(UA_Client *client, const char *serverUrl,
size_t serverUrisSize, UA_String *serverUris,
size_t localeIdsSize, UA_String *localeIds,
size_t *registeredServersSize,
UA_ApplicationDescription **registeredServers);
#ifdef UA_ENABLE_DISCOVERY
/* Get a list of all known server in the network. Only supported by LDS servers.
*
* @param client to use. Must be connected to the same endpoint given in
* serverUrl or otherwise in disconnected state.
* @param serverUrl url to connect (for example "opc.tcp://localhost:4840")
* @param startingRecordId optional. Only return the records with an ID higher
* or equal the given. Can be used for pagination to only get a subset of
* the full list
* @param maxRecordsToReturn optional. Only return this number of records
* @param serverCapabilityFilterSize optional. Filter the returned list to only
* get servers with given capabilities, e.g. "LDS"
* @param serverCapabilityFilter optional. Filter the returned list to only get
* servers with given capabilities, e.g. "LDS"
* @param serverOnNetworkSize size of returned array, i.e., number of
* known/registered servers
* @param serverOnNetwork array containing known/registered servers
* @return Indicates whether the operation succeeded or returns an error code */
UA_StatusCode UA_EXPORT
UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl,
UA_UInt32 startingRecordId, UA_UInt32 maxRecordsToReturn,
size_t serverCapabilityFilterSize, UA_String *serverCapabilityFilter,
size_t *serverOnNetworkSize, UA_ServerOnNetwork **serverOnNetwork);
#endif
/**
* .. _client-services:
*
* Services
* --------
*
* The raw OPC UA services are exposed to the client. But most of them time, it
* is better to use the convenience functions from ``ua_client_highlevel.h``
* that wrap the raw services. */
/* Don't use this function. Use the type versions below instead. */
void UA_EXPORT
__UA_Client_Service(UA_Client *client, const void *request,
const UA_DataType *requestType, void *response,
const UA_DataType *responseType);
/*
* Attribute Service Set
* ^^^^^^^^^^^^^^^^^^^^^ */
static UA_INLINE UA_ReadResponse
UA_Client_Service_read(UA_Client *client, const UA_ReadRequest request) {
UA_ReadResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_READREQUEST],
&response, &UA_TYPES[UA_TYPES_READRESPONSE]);
return response;
}
static UA_INLINE UA_WriteResponse
UA_Client_Service_write(UA_Client *client, const UA_WriteRequest request) {
UA_WriteResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_WRITEREQUEST],
&response, &UA_TYPES[UA_TYPES_WRITERESPONSE]);
return response;
}
/*
* Historical Access Service Set
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
#ifdef UA_ENABLE_HISTORIZING
static UA_INLINE UA_HistoryReadResponse
UA_Client_Service_historyRead(UA_Client *client, const UA_HistoryReadRequest request) {
UA_HistoryReadResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_HISTORYREADREQUEST],
&response, &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]);
return response;
}
static UA_INLINE UA_HistoryUpdateResponse
UA_Client_Service_historyUpdate(UA_Client *client, const UA_HistoryUpdateRequest request) {
UA_HistoryUpdateResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST],
&response, &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]);
return response;
}
#endif
/*
* Method Service Set
* ^^^^^^^^^^^^^^^^^^ */
#ifdef UA_ENABLE_METHODCALLS
static UA_INLINE UA_CallResponse
UA_Client_Service_call(UA_Client *client, const UA_CallRequest request) {
UA_CallResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_CALLREQUEST],
&response, &UA_TYPES[UA_TYPES_CALLRESPONSE]);
return response;
}
#endif
/*
* NodeManagement Service Set
* ^^^^^^^^^^^^^^^^^^^^^^^^^^ */
static UA_INLINE UA_AddNodesResponse
UA_Client_Service_addNodes(UA_Client *client, const UA_AddNodesRequest request) {
UA_AddNodesResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_ADDNODESREQUEST],
&response, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE]);
return response;
}
static UA_INLINE UA_AddReferencesResponse
UA_Client_Service_addReferences(UA_Client *client,
const UA_AddReferencesRequest request) {
UA_AddReferencesResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST],
&response, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]);
return response;
}
static UA_INLINE UA_DeleteNodesResponse
UA_Client_Service_deleteNodes(UA_Client *client,
const UA_DeleteNodesRequest request) {
UA_DeleteNodesResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_DELETENODESREQUEST],
&response, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE]);
return response;
}
static UA_INLINE UA_DeleteReferencesResponse
UA_Client_Service_deleteReferences(UA_Client *client,
const UA_DeleteReferencesRequest request) {
UA_DeleteReferencesResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST],
&response, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]);
return response;
}
/*
* View Service Set
* ^^^^^^^^^^^^^^^^ */
static UA_INLINE UA_BrowseResponse
UA_Client_Service_browse(UA_Client *client, const UA_BrowseRequest request) {
UA_BrowseResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_BROWSEREQUEST],
&response, &UA_TYPES[UA_TYPES_BROWSERESPONSE]);
return response;
}
static UA_INLINE UA_BrowseNextResponse
UA_Client_Service_browseNext(UA_Client *client,
const UA_BrowseNextRequest request) {
UA_BrowseNextResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST],
&response, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]);
return response;
}
static UA_INLINE UA_TranslateBrowsePathsToNodeIdsResponse
UA_Client_Service_translateBrowsePathsToNodeIds(UA_Client *client,
const UA_TranslateBrowsePathsToNodeIdsRequest request) {
UA_TranslateBrowsePathsToNodeIdsResponse response;
__UA_Client_Service(client, &request,
&UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST],
&response,
&UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]);
return response;
}
static UA_INLINE UA_RegisterNodesResponse
UA_Client_Service_registerNodes(UA_Client *client,
const UA_RegisterNodesRequest request) {
UA_RegisterNodesResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST],
&response, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]);
return response;
}
static UA_INLINE UA_UnregisterNodesResponse
UA_Client_Service_unregisterNodes(UA_Client *client,
const UA_UnregisterNodesRequest request) {
UA_UnregisterNodesResponse response;
__UA_Client_Service(client, &request,
&UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST],
&response, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]);
return response;
}
/*
* Query Service Set
* ^^^^^^^^^^^^^^^^^ */
#ifdef UA_ENABLE_QUERY
static UA_INLINE UA_QueryFirstResponse
UA_Client_Service_queryFirst(UA_Client *client,
const UA_QueryFirstRequest request) {
UA_QueryFirstResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST],
&response, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]);
return response;
}
static UA_INLINE UA_QueryNextResponse
UA_Client_Service_queryNext(UA_Client *client,
const UA_QueryNextRequest request) {
UA_QueryNextResponse response;
__UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST],
&response, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]);
return response;
}
#endif
/**
* .. _client-async-services:
*
* Asynchronous Services
* ---------------------
* All OPC UA services are asynchronous in nature. So several service calls can
* be made without waiting for a response first. Responess may come in a
* different ordering. */
/* Use the type versions of this method. See below. However, the general
* mechanism of async service calls is explained here.
*
* We say that an async service call has been dispatched once this method
* returns UA_STATUSCODE_GOOD. If there is an error after an async service has
* been dispatched, the callback is called with an "empty" response where the
* statusCode has been set accordingly. This is also done if the client is
* shutting down and the list of dispatched async services is emptied.
*
* The statusCode received when the client is shutting down is
* UA_STATUSCODE_BADSHUTDOWN.
*
* The statusCode received when the client don't receive response
* after specified config->timeout (in ms) is
* UA_STATUSCODE_BADTIMEOUT.
*
* Instead, you can use __UA_Client_AsyncServiceEx to specify
* a custom timeout
*
* The userdata and requestId arguments can be NULL. */
UA_StatusCode UA_EXPORT
__UA_Client_AsyncService(UA_Client *client, const void *request,
const UA_DataType *requestType,
UA_ClientAsyncServiceCallback callback,
const UA_DataType *responseType,
void *userdata, UA_UInt32 *requestId);
UA_StatusCode UA_EXPORT
UA_Client_sendAsyncRequest(UA_Client *client, const void *request,
const UA_DataType *requestType, UA_ClientAsyncServiceCallback callback,
const UA_DataType *responseType, void *userdata, UA_UInt32 *requestId);
/* Listen on the network and process arriving asynchronous responses in the
* background. Internal housekeeping, renewal of SecureChannels and subscription
* management is done as well. */
UA_StatusCode UA_EXPORT
UA_Client_run_iterate(UA_Client *client, UA_UInt16 timeout);
UA_DEPRECATED static UA_INLINE UA_StatusCode
UA_Client_runAsync(UA_Client *client, UA_UInt16 timeout) {
return UA_Client_run_iterate(client, timeout);
}
UA_DEPRECATED static UA_INLINE UA_StatusCode
UA_Client_manuallyRenewSecureChannel(UA_Client *client) {
return UA_Client_run_iterate(client, 0);
}
/* Use the type versions of this method. See below. However, the general
* mechanism of async service calls is explained here.
*
* We say that an async service call has been dispatched once this method
* returns UA_STATUSCODE_GOOD. If there is an error after an async service has
* been dispatched, the callback is called with an "empty" response where the
* statusCode has been set accordingly. This is also done if the client is
* shutting down and the list of dispatched async services is emptied.
*
* The statusCode received when the client is shutting down is
* UA_STATUSCODE_BADSHUTDOWN.
*
* The statusCode received when the client don't receive response
* after specified timeout (in ms) is
* UA_STATUSCODE_BADTIMEOUT.
*
* The timeout can be disabled by setting timeout to 0
*
* The userdata and requestId arguments can be NULL. */
UA_StatusCode UA_EXPORT
__UA_Client_AsyncServiceEx(UA_Client *client, const void *request,
const UA_DataType *requestType,
UA_ClientAsyncServiceCallback callback,
const UA_DataType *responseType,
void *userdata, UA_UInt32 *requestId,
UA_UInt32 timeout);
/**
* Timed Callbacks
* ---------------
* Repeated callbacks can be attached to a client and will be executed in the
* defined interval. */
typedef void (*UA_ClientCallback)(UA_Client *client, void *data);
/* Add a callback for execution at a specified time. If the indicated time lies
* in the past, then the callback is executed at the next iteration of the
* server's main loop.
*
* @param client The client object.
* @param callback The callback that shall be added.
* @param data Data that is forwarded to the callback.
* @param date The timestamp for the execution time.
* @param callbackId Set to the identifier of the repeated callback . This can
* be used to cancel the callback later on. If the pointer is null, the
* identifier is not set.
* @return Upon success, UA_STATUSCODE_GOOD is returned. An error code
* otherwise. */
UA_StatusCode UA_EXPORT
UA_Client_addTimedCallback(UA_Client *client, UA_ClientCallback callback,
void *data, UA_DateTime date, UA_UInt64 *callbackId);
/* Add a callback for cyclic repetition to the client.
*
* @param client The client object.
* @param callback The callback that shall be added.
* @param data Data that is forwarded to the callback.
* @param interval_ms The callback shall be repeatedly executed with the given
* interval (in ms). The interval must be positive. The first execution
* occurs at now() + interval at the latest.
* @param callbackId Set to the identifier of the repeated callback . This can
* be used to cancel the callback later on. If the pointer is null, the
* identifier is not set.
* @return Upon success, UA_STATUSCODE_GOOD is returned. An error code
* otherwise. */
UA_StatusCode UA_EXPORT
UA_Client_addRepeatedCallback(UA_Client *client, UA_ClientCallback callback,
void *data, UA_Double interval_ms,
UA_UInt64 *callbackId);
UA_StatusCode UA_EXPORT
UA_Client_changeRepeatedCallbackInterval(UA_Client *client,
UA_UInt64 callbackId,
UA_Double interval_ms);
void UA_EXPORT
UA_Client_removeCallback(UA_Client *client, UA_UInt64 callbackId);
#define UA_Client_removeRepeatedCallback(client, callbackId) \
UA_Client_removeCallback(client, callbackId)
/**
* .. toctree::
*
* client_highlevel
* client_subscriptions */
_UA_END_DECLS
#endif /* UA_CLIENT_H_ */