Fix logic in zigbee wrapper to correctly evaluate boolean values.
authorJoseph Morrow <joseph.l.morrow@intel.com>
Mon, 5 Oct 2015 23:13:13 +0000 (16:13 -0700)
committerPatrick Lankswert <patrick.lankswert@intel.com>
Tue, 6 Oct 2015 12:55:47 +0000 (12:55 +0000)
Boolean values could be read as either "0" or "00" and thus a simple
strcmp with "0" would not suffice.
Additionally, sometimes, bitmasks are read and so we need the entire
numeric value of the string.

Changed strcmp operations to convert to numeric operations.
Also extracted duplicate code into it's own function

Change-Id: I9ab20ba5b4f2e9eb335a9dd51503fe19ceca7158
Signed-off-by: Mandeep Shetty <mandeep.shetty@intel.com>
Signed-off-by: Joseph Morrow <joseph.l.morrow@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/3157
Reviewed-by: Joseph Morrow <joseph.l.morrow@intel.com>
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Patrick Lankswert <patrick.lankswert@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/3525

plugins/zigbee_wrapper/src/zigbee_wrapper.c

index a21e561..7af6390 100644 (file)
@@ -35,6 +35,7 @@
 #include <stdlib.h>
 #include <inttypes.h> // To convert "int64_t" to string.
 #include <math.h>
+#include <errno.h>
 
 #include "zigbee_wrapper.h"
 #include "telegesis_wrapper.h"
@@ -477,6 +478,33 @@ bool getZigBeeAttributesIfValid (char * OICResourceType,
     return false;
 }
 
+OCEntityHandlerResult getDoubleValueFromString (const char *str, double *outDouble)
+{
+    size_t hexOutValSize = strlen(HexPrepend) + strlen(str) + 1;
+    char * hexOutVal = (char *) OICCalloc(1, hexOutValSize);
+    if(!hexOutVal)
+    {
+        return OC_EH_ERROR;
+    }
+    OICStrcpy(hexOutVal, hexOutValSize, HexPrepend);
+    OICStrcat(hexOutVal, hexOutValSize, str);
+
+    char *endPtr;
+    errno = 0;
+    double value = strtod(hexOutVal, &endPtr);
+
+    if(errno != 0 || *endPtr != 0 || value == HUGE_VALF || value == HUGE_VALL)
+    {
+        OICFree(hexOutVal);
+        return OC_EH_ERROR;
+    }
+
+    OICFree(hexOutVal);
+    *outDouble = value;
+    return OC_EH_OK;
+
+}
+
 OCEntityHandlerResult processGetRequest (PIPluginBase * plugin,
         OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
 {
@@ -539,22 +567,15 @@ OCEntityHandlerResult processGetRequest (PIPluginBase * plugin,
         }
         if (attributeList.list[i].oicType == OIC_ATTR_INT)
         {
-            size_t hexOutValSize = strlen(HexPrepend) + strlen(outVal) + 1;
-            char * hexOutVal = (char *) OICCalloc(1, hexOutValSize);
-            if(!hexOutVal)
-            {
-                return OC_EH_ERROR;
-            }
-            OICStrcpy(hexOutVal, hexOutValSize, HexPrepend);
-            OICStrcat(hexOutVal, hexOutValSize, outVal);
-            double value = strtod(hexOutVal, NULL);
-            if(value == 0.0 || value == HUGE_VALF || value == HUGE_VALL)
+            char *endPtr = NULL;
+            // Third arg is 16 as outVal is a hex Number
+            uint64_t value = strtol (outVal, &endPtr, 16);
+
+            if (*endPtr != 0)
             {
-                OICFree(hexOutVal);
                 return OC_EH_ERROR;
             }
-            if (strcmp(attributeList.list[i].oicAttribute, OIC_DIMMING_ATTRIBUTE)
-                == 0)
+            if (strcmp(attributeList.list[i].oicAttribute, OIC_DIMMING_ATTRIBUTE) == 0)
             {
                 // OIC Dimming operates between 0-100, while Zigbee operates
                 // between 0-254 (ie. 0xFE).
@@ -570,22 +591,13 @@ OCEntityHandlerResult processGetRequest (PIPluginBase * plugin,
             boolRes = OCRepPayloadSetPropInt(*payload,
                                              attributeList.list[i].oicAttribute,
                                              (uint64_t) value);
-            OICFree (hexOutVal);
         }
         else if (attributeList.list[i].oicType == OIC_ATTR_DOUBLE)
         {
-            size_t hexOutValSize = strlen(HexPrepend) + strlen(outVal) + 1;
-            char * hexOutVal = (char *) OICCalloc(1, hexOutValSize);
-            if(!hexOutVal)
-            {
-                return OC_EH_ERROR;
-            }
-            OICStrcat(hexOutVal, hexOutValSize, HexPrepend);
-            OICStrcat(hexOutVal, hexOutValSize, outVal);
-            double value = strtod(hexOutVal, NULL);
-            if(value == 0.0 || value == HUGE_VAL || value == -HUGE_VAL)
+            double value = 0;
+
+            if (getDoubleValueFromString (outVal, &value) != OC_EH_OK)
             {
-                OICFree(hexOutVal);
                 return OC_EH_ERROR;
             }
             if (strcmp(piResource->clusterId, ZB_TEMPERATURE_CLUSTER) == 0)
@@ -597,7 +609,6 @@ OCEntityHandlerResult processGetRequest (PIPluginBase * plugin,
             boolRes = OCRepPayloadSetPropDouble(*payload,
                                                 attributeList.list[i].oicAttribute,
                                                 value);
-            OICFree(hexOutVal);
         }
         else if (attributeList.list[i].oicType == OIC_ATTR_STRING)
         {
@@ -607,19 +618,24 @@ OCEntityHandlerResult processGetRequest (PIPluginBase * plugin,
         }
         else if (attributeList.list[i].oicType == OIC_ATTR_BOOL)
         {
-            bool value = true;
-            if(strcmp(outVal, "0") == 0)
+            char *endPtr = NULL;
+            errno = 0;
+            // Third arg is 16 as outVal is a hex Number
+            uint64_t value = strtol (outVal, &endPtr, 16);
+
+            if (errno != 0 || *endPtr != 0)
             {
-                value = false;
+                return OC_EH_ERROR;
             }
-
-            // value is a bit mask and the LSB indicates boolean true/false.
+            // value COULD be a bit mask and the LSB indicates boolean true/false.
+            // If not a bit mask, it'll be plain 0 or 1.
             value = value & 1;
             boolRes = OCRepPayloadSetPropBool(*payload,
                                               attributeList.list[i].oicAttribute,
                                               value);
         }
-        OICFree(outVal);
+
+        OICFree (outVal);
     }
 
     if (boolRes == false)