Explorar el Código

Made client state visible to userspace; client recovers from potential decoding errors after successfull service calls or channel renewals (closes #570).

ichrispa hace 9 años
padre
commit
8c22a486bd
Se han modificado 3 ficheros con 38 adiciones y 8 borrados
  1. 25 0
      include/ua_client.h
  2. 13 2
      src/client/ua_client.c
  3. 0 6
      src/client/ua_client_internal.h

+ 25 - 0
include/ua_client.h

@@ -14,6 +14,13 @@ extern "C" {
 struct UA_Client;
 typedef struct UA_Client UA_Client;
 
+typedef enum {
+  UA_CLIENTSTATE_READY,
+  UA_CLIENTSTATE_CONNECTED,
+  UA_CLIENTSTATE_FAULTED,
+  UA_CLIENTSTATE_ERRORED
+} UA_Client_State;
+
 typedef struct UA_ClientConfig {
     UA_UInt32 timeout; //sync response timeout
     UA_UInt32 secureChannelLifeTime; // lifetime in ms (then the channel needs to be renewed)
@@ -107,6 +114,24 @@ UA_StatusCode UA_EXPORT UA_Client_disconnect(UA_Client *client);
  */
 UA_StatusCode UA_EXPORT UA_Client_manuallyRenewSecureChannel(UA_Client *client);
 
+
+/**
+ * @brief Get the client connection status
+ * 
+ * Returns the client connection status, being one of the following:
+ * - UA_CLIENTSTATE_READY:     The client is not connected but initialized and ready to use.
+ * - UA_CLIENTSTATE_CONNECTED: The client is connected to a server.
+ * - UA_CLIENTSTATE_FAULTED:   An error has occured that might have influenced the connection state.
+ *                             A successfull service call or renewal of the secure channel will 
+ *                             reset the state to CONNECTED.
+ * - UA_CLIENTSTATE_ERRORED:   A non-recoverable error has occured and the connection is no longer
+ *                             reliable. The client needs to be disconnected and reinitialized to 
+ *                             recover into a CONNECTED state.
+ * @param client to use.
+ * @return Current state of the client.
+ */
+UA_Client_State UA_EXPORT UA_Client_getState(UA_Client *client);
+
 /****************/
 /* Raw Services */
 /****************/

+ 13 - 2
src/client/ua_client.c

@@ -629,9 +629,17 @@ UA_StatusCode UA_Client_disconnect(UA_Client *client) {
 }
 
 UA_StatusCode UA_Client_manuallyRenewSecureChannel(UA_Client *client) {
-    return SecureChannelHandshake(client, true);
+    UA_StatusCode retval = SecureChannelHandshake(client, true);
+    if(retval == UA_STATUSCODE_GOOD)
+      client->state = UA_CLIENTSTATE_CONNECTED;
+    return retval;
 }
 
+UA_Client_State UA_EXPORT UA_Client_getState(UA_Client *client) {
+  if (client == NULL)
+    return UA_CLIENTSTATE_ERRORED;
+  return client->state;
+}
 /****************/
 /* Raw Services */
 /****************/
@@ -726,8 +734,11 @@ void __UA_Client_Service(UA_Client *client, const void *r, const UA_DataType *re
         UA_ByteString_deleteMembers(&reply);
     if(retval != UA_STATUSCODE_GOOD){
         UA_LOG_INFO(client->logger, UA_LOGCATEGORY_CLIENT, "Error receiving the response");
-        client->state = UA_CLIENTSTATE_ERRORED;
+        client->state = UA_CLIENTSTATE_FAULTED;
         respHeader->serviceResult = retval;
     }
+    else {
+      client->state = UA_CLIENTSTATE_CONNECTED;
+    }
     UA_LOG_DEBUG(client->logger, UA_LOGCATEGORY_CLIENT, "Received a response of type %i", responseId.identifier.numeric);
 }

+ 0 - 6
src/client/ua_client_internal.h

@@ -46,12 +46,6 @@ typedef struct UA_Client_Subscription_s {
 /* Client */
 /**********/
 
-typedef enum {
-    UA_CLIENTSTATE_READY,
-    UA_CLIENTSTATE_CONNECTED,
-    UA_CLIENTSTATE_ERRORED
-} UA_Client_State;
-
 typedef enum {
     UA_CLIENTAUTHENTICATION_NONE,
     UA_CLIENTAUTHENTICATION_USERNAME