From 18c3b9637f02e2df9c1e926d2e7cc508a276eafa Mon Sep 17 00:00:00 2001 From: Joseph Morrow Date: Mon, 5 Oct 2015 16:13:13 -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: I9ab20ba5b4f2e9eb335a9dd51503fe19ceca7158 Signed-off-by: Mandeep Shetty Signed-off-by: Joseph Morrow Reviewed-on: https://gerrit.iotivity.org/gerrit/3157 Reviewed-by: Joseph Morrow Tested-by: jenkins-iotivity Reviewed-by: Patrick Lankswert Reviewed-on: https://gerrit.iotivity.org/gerrit/3525 --- 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 a21e561..7af6390 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.7.4