From e618cf09465de9404d04dc90727f08795c7e709f Mon Sep 17 00:00:00 2001 From: Mandeep Shetty Date: Tue, 22 Sep 2015 15:24:53 -0700 Subject: [PATCH] Fix logic in zigbee wrapper to correctly evaluate boolean values. 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: I9a8918d9824dcb452b64fdbe9f344cfa020f9e7c Signed-off-by: Mandeep Shetty Reviewed-on: https://gerrit.iotivity.org/gerrit/3157 Reviewed-by: Joseph Morrow Tested-by: jenkins-iotivity Reviewed-by: Patrick Lankswert --- plugins/zigbee_wrapper/src/zigbee_wrapper.c | 80 ++++++++++++--------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/plugins/zigbee_wrapper/src/zigbee_wrapper.c b/plugins/zigbee_wrapper/src/zigbee_wrapper.c index a21e561c3..7af6390a0 100644 --- a/plugins/zigbee_wrapper/src/zigbee_wrapper.c +++ b/plugins/zigbee_wrapper/src/zigbee_wrapper.c @@ -35,6 +35,7 @@ #include #include // To convert "int64_t" to string. #include +#include #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) -- 2.34.1