Selaa lähdekoodia

Client: Refactor async read response handling

Julius Pfrommer 6 vuotta sitten
vanhempi
commit
844d709f40
1 muutettua tiedostoa jossa 33 lisäystä ja 37 poistoa
  1. 33 37
      src/client/ua_client_highlevel.c

+ 33 - 37
src/client/ua_client_highlevel.c

@@ -456,54 +456,50 @@ UA_Client_readArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId
     UA_ReadResponse_deleteMembers(&response);
     return retval;
 }
-/*Async Functions*/
 
-/*highlevel callbacks
- * used to hide response handling details*/
-static
-void ValueAttributeRead(UA_Client *client, void *userdata, UA_UInt32 requestId,
-        void *response) {
+/* Async Functions */
 
-    if (response == NULL) {
+static
+void ValueAttributeRead(UA_Client *client, void *userdata,
+                        UA_UInt32 requestId, void *response) {
+    if(!response)
         return;
-    }
 
+    /* Find the callback for the response */
     CustomCallback *cc;
-    LIST_FOREACH(cc, &client->customCallbacks, pointers)
-    {
-        if (cc->callbackId == requestId)
+    LIST_FOREACH(cc, &client->customCallbacks, pointers) {
+        if(cc->callbackId == requestId)
             break;
     }
-    if (!cc)
+    if(!cc)
         return;
 
-    UA_ReadResponse rr = *(UA_ReadResponse *) response;
-    UA_DataValue *res = rr.results;
-    if ((rr.resultsSize > 0) && (res != NULL) && (res->hasValue)) {
-        UA_Variant out;
-        UA_Variant_init(&out);
-        /*__UA_Client_readAttribute*/
-        memcpy(&out, &res->value, sizeof(UA_Variant));
-        /* Copy value into out */
-        if (cc->attributeId == UA_ATTRIBUTEID_VALUE) {
-            memcpy(&out, &res->value, sizeof(UA_Variant));
-            UA_Variant_init(&res->value);
-        } else if (cc->attributeId == UA_ATTRIBUTEID_NODECLASS) {
-            memcpy(&out, (UA_NodeClass*) res->value.data, sizeof(UA_NodeClass));
-        } else if (UA_Variant_isScalar(&res->value)
-                && res->value.type == cc->outDataType) {
-            memcpy(&out, res->value.data, res->value.type->memSize);
-            UA_free(res->value.data);
-            res->value.data = NULL;
+    UA_ReadResponse *rr = (UA_ReadResponse *) response;
+    UA_DataValue *res = rr->results;
+    UA_Boolean done = false;
+    if(rr->resultsSize == 1 && res != NULL && res->hasValue) {
+        if(cc->attributeId == UA_ATTRIBUTEID_VALUE) {
+            /* Call directly with the variant */
+            cc->callback(client, userdata, requestId, &res->value);
+            done = true;
+        } else if(UA_Variant_isScalar(&res->value) &&
+                  res->value.type == cc->outDataType) {
+            /* Unpack the value */
+            UA_STACKARRAY(UA_Byte, value, cc->outDataType->memSize);
+            memcpy(&value, res->value.data, cc->outDataType->memSize);
+            cc->callback(client, userdata, requestId, &value);
+            done = true;
         }
-
-        //use callbackId to find the right custom callback
-        cc->callback(client, userdata, requestId, &out);
-        UA_Variant_deleteMembers(&out);
     }
+
+    /* Could not process, delete the callback anyway */
+    if(!done)
+        UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT,
+                    "Cannot process the response to the async read "
+                    "request %u", requestId);
+
     LIST_REMOVE(cc, pointers);
     UA_free(cc);
-    UA_ReadResponse_deleteMembers((UA_ReadResponse*) response);
 }
 
 /*Read Attributes*/
@@ -521,8 +517,8 @@ UA_StatusCode __UA_Client_readAttribute_async(UA_Client *client,
     request.nodesToReadSize = 1;
 
     __UA_Client_AsyncService(client, &request, &UA_TYPES[UA_TYPES_READREQUEST],
-            ValueAttributeRead, &UA_TYPES[UA_TYPES_READRESPONSE], userdata,
-            reqId);
+                             ValueAttributeRead, &UA_TYPES[UA_TYPES_READRESPONSE],
+                             userdata, reqId);
 
     CustomCallback *cc = (CustomCallback*) UA_malloc(sizeof(CustomCallback));
     if (!cc)