ua_plugin_network.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #ifndef UA_PLUGIN_NETWORK_H_
  5. #define UA_PLUGIN_NETWORK_H_
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. #include "ua_server.h"
  10. /* Forward declarations */
  11. struct UA_Connection;
  12. typedef struct UA_Connection UA_Connection;
  13. struct UA_SecureChannel;
  14. typedef struct UA_SecureChannel UA_SecureChannel;
  15. struct UA_ServerNetworkLayer;
  16. typedef struct UA_ServerNetworkLayer UA_ServerNetworkLayer;
  17. /**
  18. * .. _networking:
  19. *
  20. * Networking Plugin API
  21. * =====================
  22. *
  23. * Connection
  24. * ----------
  25. * Client-server connections are represented by a `UA_Connection`. The
  26. * connection is stateful and stores partially received messages, and so on. In
  27. * addition, the connection contains function pointers to the underlying
  28. * networking implementation. An example for this is the `send` function. So the
  29. * connection encapsulates all the required networking functionality. This lets
  30. * users on embedded (or otherwise exotic) systems implement their own
  31. * networking plugins with a clear interface to the main open62541 library. */
  32. typedef struct {
  33. UA_UInt32 protocolVersion;
  34. UA_UInt32 sendBufferSize;
  35. UA_UInt32 recvBufferSize;
  36. UA_UInt32 maxMessageSize;
  37. UA_UInt32 maxChunkCount;
  38. } UA_ConnectionConfig;
  39. typedef enum {
  40. UA_CONNECTION_OPENING, /* The socket is open, but the HEL/ACK handshake
  41. * is not done */
  42. UA_CONNECTION_ESTABLISHED, /* The socket is open and the connection
  43. * configured */
  44. UA_CONNECTION_CLOSED /* The socket has been closed and the connection
  45. * will be deleted */
  46. } UA_ConnectionState;
  47. struct UA_Connection {
  48. UA_ConnectionState state;
  49. UA_ConnectionConfig localConf;
  50. UA_ConnectionConfig remoteConf;
  51. UA_SecureChannel *channel; /* The securechannel that is attached to
  52. * this connection */
  53. UA_Int32 sockfd; /* Most connectivity solutions run on
  54. * sockets. Having the socket id here
  55. * simplifies the design. */
  56. UA_DateTime openingDate; /* The date the connection was created */
  57. void *handle; /* A pointer to internal data */
  58. UA_ByteString incompleteMessage; /* A half-received message (TCP is a
  59. * streaming protocol) is stored here */
  60. /* Get a buffer for sending */
  61. UA_StatusCode (*getSendBuffer)(UA_Connection *connection, size_t length,
  62. UA_ByteString *buf);
  63. /* Release the send buffer manually */
  64. void (*releaseSendBuffer)(UA_Connection *connection, UA_ByteString *buf);
  65. /* Sends a message over the connection. The message buffer is always freed,
  66. * even if sending fails.
  67. *
  68. * @param connection The connection
  69. * @param buf The message buffer
  70. * @return Returns an error code or UA_STATUSCODE_GOOD. */
  71. UA_StatusCode (*send)(UA_Connection *connection, UA_ByteString *buf);
  72. /* Receive a message from the remote connection
  73. *
  74. * @param connection The connection
  75. * @param response The response string. It is allocated by the connection
  76. * and needs to be freed with connection->releaseBuffer
  77. * @param timeout Timeout of the recv operation in milliseconds
  78. * @return Returns UA_STATUSCODE_BADCOMMUNICATIONERROR if the recv operation
  79. * can be repeated, UA_STATUSCODE_GOOD if it succeeded and
  80. * UA_STATUSCODE_BADCONNECTIONCLOSED if the connection was
  81. * closed. */
  82. UA_StatusCode (*recv)(UA_Connection *connection, UA_ByteString *response,
  83. UA_UInt32 timeout);
  84. /* Release the buffer of a received message */
  85. void (*releaseRecvBuffer)(UA_Connection *connection, UA_ByteString *buf);
  86. /* Close the connection. The network layer closes the socket. This is picked
  87. * up during the next 'listen' and the connection is freed in the network
  88. * layer. */
  89. void (*close)(UA_Connection *connection);
  90. /* To be called only from within the server (and not the network layer).
  91. * Frees up the connection's memory. */
  92. void (*free)(UA_Connection *connection);
  93. };
  94. /* Cleans up half-received messages, and so on. Called from connection->free. */
  95. void UA_EXPORT
  96. UA_Connection_deleteMembers(UA_Connection *connection);
  97. /**
  98. * Server Network Layer
  99. * --------------------
  100. * The server exposes two functions to interact with remote clients:
  101. * `processBinaryMessage` and `removeConnection`. These functions are called by
  102. * the server network layer.
  103. *
  104. * It is the job of the server network layer to listen on a TCP socket, to
  105. * accept new connections, to call the server with received messages and to
  106. * signal closed connections to the server.
  107. *
  108. * The network layer is part of the server config. So users can provide a custom
  109. * implementation if the provided example does not fit their architecture. The
  110. * network layer is invoked only from the server's main loop. So the network
  111. * layer does not need to be thread-safe. If the networklayer receives a
  112. * positive duration for blocking listening, the server's main loop will block
  113. * until a message is received or the duration times out. */
  114. /* Process a binary message (TCP packet). The message can contain partial
  115. * chunks. (TCP is a streaming protocol and packets may be split/merge during
  116. * transport.) After processing, the message is freed with
  117. * connection->releaseRecvBuffer. */
  118. void UA_EXPORT
  119. UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection,
  120. UA_ByteString *message);
  121. /* The server internally cleans up the connection and then calls
  122. * connection->free. */
  123. void UA_EXPORT
  124. UA_Server_removeConnection(UA_Server *server, UA_Connection *connection);
  125. struct UA_ServerNetworkLayer {
  126. void *handle; /* Internal data */
  127. UA_String discoveryUrl;
  128. /* Start listening on the networklayer.
  129. *
  130. * @param nl The network layer
  131. * @return Returns UA_STATUSCODE_GOOD or an error code. */
  132. UA_StatusCode (*start)(UA_ServerNetworkLayer *nl, const UA_String *customHostname);
  133. /* Listen for new and closed connections and arriving packets. Calls
  134. * UA_Server_processBinaryMessage for the arriving packets. Closed
  135. * connections are picked up here and forwarded to
  136. * UA_Server_removeConnection where they are cleaned up and freed.
  137. *
  138. * @param nl The network layer
  139. * @param server The server for processing the incoming packets and for
  140. * closing connections.
  141. * @param timeout The timeout during which an event must arrive in
  142. * milliseconds
  143. * @return A statuscode for the status of the network layer. */
  144. UA_StatusCode (*listen)(UA_ServerNetworkLayer *nl, UA_Server *server,
  145. UA_UInt16 timeout);
  146. /* Close the network socket and all open connections. Afterwards, the
  147. * network layer can be safely deleted.
  148. *
  149. * @param nl The network layer
  150. * @param server The server that processes the incoming packets and for
  151. * closing connections before deleting them.
  152. * @return A statuscode for the status of the closing operation. */
  153. void (*stop)(UA_ServerNetworkLayer *nl, UA_Server *server);
  154. /* Deletes the network layer context. Call only after stopping. */
  155. void (*deleteMembers)(UA_ServerNetworkLayer *nl);
  156. };
  157. /**
  158. * Client Network Layer
  159. * --------------------
  160. * The client has only a single connection used for sending and receiving binary
  161. * messages. */
  162. /* @param localConf the connection config for this client
  163. * @param endpointUrl to where to connect
  164. * @param timeout in ms until the connection try times out if remote not reachable */
  165. typedef UA_Connection
  166. (*UA_ConnectClientConnection)(UA_ConnectionConfig localConf, const char *endpointUrl,
  167. const UA_UInt32 timeout);
  168. /**
  169. * Endpoint URL Parser
  170. * -------------------
  171. * The endpoint URL parser is generally useful for the implementation of network
  172. * layer plugins. */
  173. /* Split the given endpoint url into hostname, port and path. All arguments must
  174. * be non-NULL. EndpointUrls have the form "opc.tcp://hostname:port/path", port
  175. * and path may be omitted (together with the prefix colon and slash).
  176. *
  177. * @param endpointUrl The endpoint URL.
  178. * @param outHostname Set to the parsed hostname. The string points into the
  179. * original endpointUrl, so no memory is allocated. If an IPv6 address is
  180. * given, hostname contains e.g. '[2001:0db8:85a3::8a2e:0370:7334]'
  181. * @param outPort Set to the port of the url or left unchanged.
  182. * @param outPath Set to the path if one is present in the endpointUrl.
  183. * Starting or trailing '/' are NOT included in the path. The string
  184. * points into the original endpointUrl, so no memory is allocated.
  185. * @return Returns UA_STATUSCODE_BADTCPENDPOINTURLINVALID if parsing failed. */
  186. UA_StatusCode UA_EXPORT
  187. UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname,
  188. UA_UInt16 *outPort, UA_String *outPath);
  189. #ifdef __cplusplus
  190. } // extern "C"
  191. #endif
  192. #endif /* UA_PLUGIN_NETWORK_H_ */