123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- /* 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/. */
- #ifndef UA_PLUGIN_NETWORK_H_
- #define UA_PLUGIN_NETWORK_H_
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include "ua_server.h"
- /* Forward declarations */
- struct UA_Connection;
- typedef struct UA_Connection UA_Connection;
- struct UA_SecureChannel;
- typedef struct UA_SecureChannel UA_SecureChannel;
- struct UA_ServerNetworkLayer;
- typedef struct UA_ServerNetworkLayer UA_ServerNetworkLayer;
- /**
- * .. _networking:
- *
- * Networking Plugin API
- * =====================
- *
- * Connection
- * ----------
- * Client-server connections are represented by a `UA_Connection`. The
- * connection is stateful and stores partially received messages, and so on. In
- * addition, the connection contains function pointers to the underlying
- * networking implementation. An example for this is the `send` function. So the
- * connection encapsulates all the required networking functionality. This lets
- * users on embedded (or otherwise exotic) systems implement their own
- * networking plugins with a clear interface to the main open62541 library. */
- typedef struct {
- UA_UInt32 protocolVersion;
- UA_UInt32 sendBufferSize;
- UA_UInt32 recvBufferSize;
- UA_UInt32 maxMessageSize;
- UA_UInt32 maxChunkCount;
- } UA_ConnectionConfig;
- typedef enum {
- UA_CONNECTION_OPENING, /* The socket is open, but the HEL/ACK handshake
- * is not done */
- UA_CONNECTION_ESTABLISHED, /* The socket is open and the connection
- * configured */
- UA_CONNECTION_CLOSED /* The socket has been closed and the connection
- * will be deleted */
- } UA_ConnectionState;
- struct UA_Connection {
- UA_ConnectionState state;
- UA_ConnectionConfig localConf;
- UA_ConnectionConfig remoteConf;
- UA_SecureChannel *channel; /* The securechannel that is attached to
- * this connection */
- UA_Int32 sockfd; /* Most connectivity solutions run on
- * sockets. Having the socket id here
- * simplifies the design. */
- UA_DateTime openingDate; /* The date the connection was created */
- void *handle; /* A pointer to internal data */
- UA_ByteString incompleteMessage; /* A half-received message (TCP is a
- * streaming protocol) is stored here */
- /* Get a buffer for sending */
- UA_StatusCode (*getSendBuffer)(UA_Connection *connection, size_t length,
- UA_ByteString *buf);
- /* Release the send buffer manually */
- void (*releaseSendBuffer)(UA_Connection *connection, UA_ByteString *buf);
- /* Sends a message over the connection. The message buffer is always freed,
- * even if sending fails.
- *
- * @param connection The connection
- * @param buf The message buffer
- * @return Returns an error code or UA_STATUSCODE_GOOD. */
- UA_StatusCode (*send)(UA_Connection *connection, UA_ByteString *buf);
- /* Receive a message from the remote connection
- *
- * @param connection The connection
- * @param response The response string. It is allocated by the connection
- * and needs to be freed with connection->releaseBuffer
- * @param timeout Timeout of the recv operation in milliseconds
- * @return Returns UA_STATUSCODE_BADCOMMUNICATIONERROR if the recv operation
- * can be repeated, UA_STATUSCODE_GOOD if it succeeded and
- * UA_STATUSCODE_BADCONNECTIONCLOSED if the connection was
- * closed. */
- UA_StatusCode (*recv)(UA_Connection *connection, UA_ByteString *response,
- UA_UInt32 timeout);
- /* Release the buffer of a received message */
- void (*releaseRecvBuffer)(UA_Connection *connection, UA_ByteString *buf);
- /* Close the connection. The network layer closes the socket. This is picked
- * up during the next 'listen' and the connection is freed in the network
- * layer. */
- void (*close)(UA_Connection *connection);
- /* To be called only from within the server (and not the network layer).
- * Frees up the connection's memory. */
- void (*free)(UA_Connection *connection);
- };
- /* Cleans up half-received messages, and so on. Called from connection->free. */
- void UA_EXPORT
- UA_Connection_deleteMembers(UA_Connection *connection);
- /**
- * Server Network Layer
- * --------------------
- * The server exposes two functions to interact with remote clients:
- * `processBinaryMessage` and `removeConnection`. These functions are called by
- * the server network layer.
- *
- * It is the job of the server network layer to listen on a TCP socket, to
- * accept new connections, to call the server with received messages and to
- * signal closed connections to the server.
- *
- * The network layer is part of the server config. So users can provide a custom
- * implementation if the provided example does not fit their architecture. The
- * network layer is invoked only from the server's main loop. So the network
- * layer does not need to be thread-safe. If the networklayer receives a
- * positive duration for blocking listening, the server's main loop will block
- * until a message is received or the duration times out. */
- /* Process a binary message (TCP packet). The message can contain partial
- * chunks. (TCP is a streaming protocol and packets may be split/merge during
- * transport.) After processing, the message is freed with
- * connection->releaseRecvBuffer. */
- void UA_EXPORT
- UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection,
- UA_ByteString *message);
- /* The server internally cleans up the connection and then calls
- * connection->free. */
- void UA_EXPORT
- UA_Server_removeConnection(UA_Server *server, UA_Connection *connection);
- struct UA_ServerNetworkLayer {
- void *handle; /* Internal data */
- UA_String discoveryUrl;
- /* Start listening on the networklayer.
- *
- * @param nl The network layer
- * @return Returns UA_STATUSCODE_GOOD or an error code. */
- UA_StatusCode (*start)(UA_ServerNetworkLayer *nl, const UA_String *customHostname);
- /* Listen for new and closed connections and arriving packets. Calls
- * UA_Server_processBinaryMessage for the arriving packets. Closed
- * connections are picked up here and forwarded to
- * UA_Server_removeConnection where they are cleaned up and freed.
- *
- * @param nl The network layer
- * @param server The server for processing the incoming packets and for
- * closing connections.
- * @param timeout The timeout during which an event must arrive in
- * milliseconds
- * @return A statuscode for the status of the network layer. */
- UA_StatusCode (*listen)(UA_ServerNetworkLayer *nl, UA_Server *server,
- UA_UInt16 timeout);
- /* Close the network socket and all open connections. Afterwards, the
- * network layer can be safely deleted.
- *
- * @param nl The network layer
- * @param server The server that processes the incoming packets and for
- * closing connections before deleting them.
- * @return A statuscode for the status of the closing operation. */
- void (*stop)(UA_ServerNetworkLayer *nl, UA_Server *server);
- /* Deletes the network layer context. Call only after stopping. */
- void (*deleteMembers)(UA_ServerNetworkLayer *nl);
- };
- /**
- * Client Network Layer
- * --------------------
- * The client has only a single connection used for sending and receiving binary
- * messages. */
- /* @param localConf the connection config for this client
- * @param endpointUrl to where to connect
- * @param timeout in ms until the connection try times out if remote not reachable */
- typedef UA_Connection
- (*UA_ConnectClientConnection)(UA_ConnectionConfig localConf, const char *endpointUrl,
- const UA_UInt32 timeout);
- /**
- * Endpoint URL Parser
- * -------------------
- * The endpoint URL parser is generally useful for the implementation of network
- * layer plugins. */
- /* Split the given endpoint url into hostname, port and path. All arguments must
- * be non-NULL. EndpointUrls have the form "opc.tcp://hostname:port/path", port
- * and path may be omitted (together with the prefix colon and slash).
- *
- * @param endpointUrl The endpoint URL.
- * @param outHostname Set to the parsed hostname. The string points into the
- * original endpointUrl, so no memory is allocated. If an IPv6 address is
- * given, hostname contains e.g. '[2001:0db8:85a3::8a2e:0370:7334]'
- * @param outPort Set to the port of the url or left unchanged.
- * @param outPath Set to the path if one is present in the endpointUrl.
- * Starting or trailing '/' are NOT included in the path. The string
- * points into the original endpointUrl, so no memory is allocated.
- * @return Returns UA_STATUSCODE_BADTCPENDPOINTURLINVALID if parsing failed. */
- UA_StatusCode UA_EXPORT
- UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname,
- UA_UInt16 *outPort, UA_String *outPath);
- #ifdef __cplusplus
- } // extern "C"
- #endif
- #endif /* UA_PLUGIN_NETWORK_H_ */
|