Prechádzať zdrojové kódy

move method to receive a chunk with a timeout into ua_connection.c

Julius Pfrommer 7 rokov pred
rodič
commit
4de389564c
2 zmenil súbory, kde vykonal 65 pridanie a 20 odobranie
  1. 30 2
      src/ua_connection.c
  2. 35 18
      src/ua_connection_internal.h

+ 30 - 2
src/ua_connection.c

@@ -10,8 +10,8 @@ void UA_Connection_deleteMembers(UA_Connection *connection) {
 }
 
 UA_StatusCode
-UA_Connection_completeMessages(UA_Connection *connection, UA_ByteString * UA_RESTRICT message,
-                               UA_Boolean * UA_RESTRICT realloced) {
+UA_Connection_completeMessages(UA_Connection *connection, UA_ByteString *message,
+                               UA_Boolean *realloced) {
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
 
     /* We have a stored an incomplete chunk. Concat the received message to the end.
@@ -113,6 +113,34 @@ UA_Connection_completeMessages(UA_Connection *connection, UA_ByteString * UA_RES
     return retval;
 }
 
+UA_StatusCode
+UA_Connection_receiveChunksBlocking(UA_Connection *connection, UA_ByteString *chunks,
+                                    UA_Boolean *realloced, UA_UInt32 timeout) {
+    UA_DateTime now = UA_DateTime_nowMonotonic();
+    UA_DateTime maxDate = now + (timeout * UA_MSEC_TO_DATETIME);
+    *realloced = false;
+
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
+    while(true) {
+        /* Listen for messages to arrive */
+        retval = connection->recv(connection, chunks, timeout);
+
+        /* Get complete chunks and return */
+        retval |= UA_Connection_completeMessages(connection, chunks, realloced);
+        if(retval != UA_STATUSCODE_GOOD || chunks->length > 0)
+            break;
+
+        /* We received a message. But the chunk is incomplete. Compute the
+         * remaining timeout. */
+        now = UA_DateTime_nowMonotonic();
+        if(now > maxDate)
+            return UA_STATUSCODE_GOODNONCRITICALTIMEOUT;
+        timeout = (UA_UInt32)((maxDate - now) / UA_MSEC_TO_DATETIME);
+    }
+    return retval;
+}
+
+
 void UA_Connection_detachSecureChannel(UA_Connection *connection) {
     UA_SecureChannel *channel = connection->channel;
     if(channel)

+ 35 - 18
src/ua_connection_internal.h

@@ -3,8 +3,7 @@
 
 #include "ua_connection.h"
 
-/**
- * The network layer may receive chopped up messages since TCP is a streaming
+/* The network layer may receive chopped up messages since TCP is a streaming
  * protocol. Furthermore, the networklayer may operate on ringbuffers or
  * statically assigned memory.
  *
@@ -19,27 +18,45 @@
  * @param realloced The Boolean value is set to true if the outgoing message has
  *        been reallocated from the network layer.
  * @return Returns UA_STATUSCODE_GOOD or an error code. When an error occurs, the ingoing message
- *         and the current buffer in the connection are freed.
- */
+ *         and the current buffer in the connection are freed. */
 UA_StatusCode
-UA_Connection_completeMessages(UA_Connection *connection, UA_ByteString * UA_RESTRICT message,
-                               UA_Boolean * UA_RESTRICT realloced);
-
-void UA_EXPORT UA_Connection_detachSecureChannel(UA_Connection *connection);
-void UA_EXPORT UA_Connection_attachSecureChannel(UA_Connection *connection, UA_SecureChannel *channel);
+UA_Connection_completeMessages(UA_Connection *connection, UA_ByteString *message,
+                               UA_Boolean *realloced);
 
-/**
- * EndpointURL helper
+/* Try to receive at least one complete chunk on the connection. This blocks the
+ * current thread up to the given timeout.
+ *
+ * @param connection The connection
+ * @param chunk The received chunk. The memory is allocated either by the
+ *        networklayer or internally.
+ * @param realloced The Boolean value is set to true if the chunk has been
+ *        reallocated from the network layer.
+ * @param timeout The timeout (in milliseconds) the method will block at most.
+ * @return Returns UA_STATUSCODE_GOOD or an error code. When an error occurs,
+ *         the chunk buffer is returned empty. Upon a timeout,
+ *         UA_STATUSCODE_GOODNONCRITICALTIMEOUT is returned.
  */
+UA_StatusCode
+UA_Connection_receiveChunksBlocking(UA_Connection *connection, UA_ByteString *chunks,
+                                    UA_Boolean *realloced, UA_UInt32 timeout);
+
+void UA_Connection_detachSecureChannel(UA_Connection *connection);
+void UA_Connection_attachSecureChannel(UA_Connection *connection, UA_SecureChannel *channel);
 
-/**
- * Split the given endpoint url into hostname and port. Some of the chunks are returned as pointer.
+/* Split the given endpoint url into hostname and port. Some of the chunks are
+ * returned as pointer.
  * @param endpointUrl The endpoint URL to split up
  * @param hostname the target array for hostname. Has to be at least 256 size.
- * @param port if url contains port, it will point to the beginning of port. NULL otherwise. It may also include the path part, thus stop at position of path pointer, if it is not NULL.
- * @param path points to the first occurance of '/' after the port or NULL if no path in url
- * @return UA_STATUSCODE_BADOUTOFRANGE if url too long, UA_STATUSCODE_BADATTRIBUTEIDINVALID if url not starting with 'opc.tcp://', UA_STATUSCODE_GOOD on success
- */
-UA_StatusCode UA_EXPORT UA_EndpointUrl_split_ptr(const char *endpointUrl, char *hostname, const char ** port, const char ** path);
+ * @param port if url contains port, it will point to the beginning of port.
+ *        NULL otherwise. It may also include the path part, thus stop at
+ *        position of path pointer, if it is not NULL.
+ * @param path points to the first occurance of '/' after the port or NULL if no
+ *        path in url
+ * @return UA_STATUSCODE_BADOUTOFRANGE if url too long,
+ *         UA_STATUSCODE_BADATTRIBUTEIDINVALID if url not starting with
+ *         'opc.tcp://', UA_STATUSCODE_GOOD on success */
+UA_StatusCode
+UA_EndpointUrl_split_ptr(const char *endpointUrl, char *hostname,
+                         const char ** port, const char ** path);
 
 #endif /* UA_CONNECTION_INTERNAL_H_ */