1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 * This file contains defined interface for the Zigbee Radio.
36 #include <inttypes.h> // To convert "int64_t" to string.
40 #include "zigbee_wrapper.h"
41 #include "telegesis_wrapper.h"
42 #include "pluginlist.h"
44 #include "ocpayload.h"
45 #include "oic_malloc.h"
46 #include "oic_string.h"
49 #define HexPrepend "0x"
51 #define TAG "zigbeeWrapper"
53 // TODO: These should eventually go into an XML/JSON/Mapping thing
54 #define MAX_ATTRIBUTES 10
55 #define ZB_TEMPERATURE_CLUSTER "0402"
56 #define ZB_TEMPERATURE_ATTRIBUTE_ID "0000"
57 #define ZB_CURRENT_LEVEL_ATTRIBUTE_READONLY "0000"
58 #define ZB_ON_LEVEL_ATTRIBUTE "0011"
59 #define ZB_LEVEL_CONTROL_CLUSTER "0008"
60 #define ZB_CONTACT_CLUSTER "0500"
61 #define ZB_CONTACT_ATTRIBUTE_ID "0002"
62 #define ZB_INDICATOR_CLUSTER "0003"
63 #define ZB_INDICATOR_ATTRIBUTE_ID "0000"
64 #define ZB_ON_OFF_CLUSTER "0006"
65 #define ZB_ON_OFF_ATTRIBUTE_ID "0000"
67 #define ZB_DATA_TYPE_NULL "00"
68 #define ZB_DATA_TYPE_1_BYTE "08"
69 #define ZB_DATA_TYPE_2_BYTE "09"
70 #define ZB_DATA_TYPE_3_BYTE "0a"
71 #define ZB_DATA_TYPE_4_BYTE "0b"
72 #define ZB_DATA_TYPE_5_BYTE "0c"
73 #define ZB_DATA_TYPE_6_BYTE "0d"
74 #define ZB_DATA_TYPE_7_BYTE "0e"
75 #define ZB_DATA_TYPE_8_BYTE "0f"
76 #define ZB_DATA_TYPE_BOOL "10"
77 #define ZB_DATA_TYPE_SIGNED_INT_16 "29"
78 #define ZB_DATA_TYPE_UNSIGNED_INT_8 "20"
79 #define ZB_DATA_TYPE_UNSIGNED_INT_16 "21"
81 #define MAX_STRLEN_INT (10)
82 // DBL_MANT_DIG = Max # of digits after decimal after the leading zeros.
83 // DBL_MIN_EXP = Max # of leading zeros of the mantissa.
84 // Magic number '3' represents a '-' (negative sign), '0' (a possible zero), and '.' (a period).
85 // "-0." from a number like "-0.999999991245", the "-0." adds 3 unaccounted characters.
86 #define MAX_STRLEN_DOUBLE (3 + DBL_MANT_DIG - DBL_MIN_EXP)
87 #define MAX_STRLEN_BOOL (1)
89 #define DEFAULT_TRANS_TIME "0000"
90 #define DEFAULT_MOVETOLEVEL_MODE "0"
92 static const char* OIC_TEMPERATURE_SENSOR = "oic.r.temperature";
93 static const char* OIC_DIMMABLE_LIGHT = "oic.r.light.dimming";
94 static const char* OIC_CONTACT_SENSOR = "oic.r.sensor.contact";
95 static const char* OIC_BINARY_SWITCH = "oic.r.switch.binary";
97 static const char* OIC_TEMPERATURE_ATTRIBUTE = "temperature";
98 static const char* OIC_DIMMING_ATTRIBUTE = "dimmingSetting";
99 static const char* OIC_CONTACT_ATTRIBUTE = "value";
100 static const char* OIC_ON_OFF_ATTRIBUTE = "value";
102 PIPlugin_Zigbee ** gPlugin = NULL;
108 ZB_16_BIT, // 2 bytes
109 ZB_24_BIT, // 3 bytes
110 ZB_32_BIT, // 4 bytes
111 ZB_40_BIT, // 5 bytes
112 ZB_48_BIT, // 6 bytes
113 ZB_56_BIT, // 7 bytes
114 ZB_64_BIT, // 8 bytes
127 } ZigBeeAttributeDataType;
129 char * getZBDataTypeString(ZigBeeAttributeDataType attrType);
130 OCEntityHandlerResult ProcessEHRequest (PIPluginBase * plugin, OCEntityHandlerRequest *ehRequest,
131 OCRepPayload **payload);
145 char *zigBeeAttribute;
146 OICAttributeType oicType;
147 ZigBeeAttributeDataType zigbeeType;
156 } OICZigBeeAttributePair;
160 CIE_RON_OFF = 1 << 1,
161 CIE_MOVE_TO_LEVEL = 1 << 2
168 CIECommandMask CIEMask;
169 OICZigBeeAttributePair list[MAX_ATTRIBUTES];
172 const char* ZigBeeClusterIDToOICResourceType (const char * clusterID);
174 OCStackResult getZigBeeAttributesForOICResource (char * OICResourceType,
175 AttributeList *attributeList);
177 bool getZigBeeAttributesIfValid (char * OICResourceType,
178 AttributeList *attributeList,
179 OCRepPayload *payload);
181 void foundZigbeeCallback(TWDevice *device)
183 int count = device->endpointOfInterest->clusterList->count;
184 size_t lenSeparator = strlen ("/");
186 for(int i=0; i < count; i++)
188 PIResource_Zigbee *piResource = (PIResource_Zigbee *) OICMalloc(sizeof(*piResource));
191 OC_LOG (ERROR, TAG, "Out of memory");
194 piResource->header.plugin = (PIPluginBase *)gPlugin;
195 size_t newUriSize = strlen(PI_ZIGBEE_PREFIX) + lenSeparator +
196 sizeof(device->nodeId) + lenSeparator +
197 sizeof(device->endpointOfInterest->endpointId) + lenSeparator +
198 sizeof(device->endpointOfInterest->clusterList->clusterIds[i].clusterId)
199 + 1; // NULL Terminator
200 char * newUri = (char *) OICCalloc(newUriSize, 1);
204 OC_LOG (ERROR, TAG, "Out of memory");
208 ret = snprintf(newUri, newUriSize, "%s/%s/%s/%s",
211 device->endpointOfInterest->endpointId,
212 device->endpointOfInterest->clusterList->clusterIds[i].clusterId);
215 OC_LOG (ERROR, TAG, "Encoding error occurred trying to build Zigbee URI.");
217 else if(ret > newUriSize)
219 OC_LOG_V (ERROR, TAG, "Did not allocate enough memory to build URI. Required Size: %d",
223 piResource->header.piResource.uri = newUri;
224 piResource->header.piResource.resourceTypeName =
226 (char *) ZigBeeClusterIDToOICResourceType(
227 device->endpointOfInterest->clusterList->clusterIds[i].clusterId);
229 if(piResource->header.piResource.resourceTypeName == NULL)
231 OC_LOG_V (ERROR, TAG, "unsupported clusterId : %d",
232 device->endpointOfInterest->clusterList->clusterIds[i].clusterId);
233 OICFree(piResource->header.piResource.uri);
237 piResource->header.piResource.resourceInterfaceName =
238 OC_RSRVD_INTERFACE_DEFAULT;
240 piResource->header.piResource.callbackParam = NULL;
241 piResource->header.piResource.resourceProperties = 0;
242 piResource->eui = OICStrdup(device->eui);
243 piResource->nodeId = OICStrdup(device->nodeId);
244 piResource->endpointId = OICStrdup(device->endpointOfInterest->endpointId);
245 piResource->clusterId =
246 OICStrdup(device->endpointOfInterest->clusterList->clusterIds[i].clusterId);
247 (*gPlugin)->header.NewResourceFoundCB(&(*gPlugin)->header, &piResource->header);
251 OCStackResult ZigbeeInit(const char * comPort, PIPlugin_Zigbee ** plugin,
252 PINewResourceFound newResourceCB)
256 return OC_STACK_INVALID_PARAM;
258 *plugin = (PIPlugin_Zigbee *) OICMalloc(sizeof(PIPlugin_Zigbee) + sizeof(PIPluginBase));
261 return OC_STACK_NO_MEMORY;
263 ((*plugin)->header).type = PLUGIN_ZIGBEE;
264 ((*plugin)->header).comPort = OICStrdup(comPort);
265 ((*plugin)->header).NewResourceFoundCB = newResourceCB;
266 ((*plugin)->header).next = NULL;
267 ((*plugin)->header).resourceList = NULL;
268 ((*plugin)->header).processEHRequest = ProcessEHRequest;
271 return TWInitialize(comPort);
274 OCStackResult ZigbeeDiscover(PIPlugin_Zigbee * plugin)
276 OCStackResult result = OC_STACK_ERROR;
278 TWSetDiscoveryCallback(foundZigbeeCallback);
279 result = TWDiscover(NULL);
280 OC_LOG_V (DEBUG, TAG, "ZigbeeDiscover : Status = %d\n", result);
285 OCStackResult ZigbeeStop(PIPlugin_Zigbee * plugin)
287 free((plugin->header).comPort);
289 return TWUninitialize();
292 OCStackResult ZigbeeProcess(PIPlugin_Zigbee * plugin)
298 // Function returns an OIC Smart Home resource Type
299 // from the cluster ID. If the cluster is not supported, null is
301 // NOTE: The returned string is NOT malloc'ed.
302 const char* ZigBeeClusterIDToOICResourceType (const char * clusterID) //Discovery/CreateResource
304 if (strcmp(clusterID, ZB_TEMPERATURE_CLUSTER) == 0)
306 return OIC_TEMPERATURE_SENSOR;
308 else if (strcmp(clusterID, ZB_LEVEL_CONTROL_CLUSTER) == 0)
310 return OIC_DIMMABLE_LIGHT;
312 else if (strcmp(clusterID, ZB_CONTACT_CLUSTER) == 0)
314 return OIC_CONTACT_SENSOR;
316 else if (strcmp(clusterID, ZB_ON_OFF_CLUSTER) == 0)
318 return OIC_BINARY_SWITCH;
326 const char* OICResourceToZigBeeClusterID (char *oicResourceType)
328 if (strcmp(oicResourceType, OIC_TEMPERATURE_SENSOR) == 0)
330 return ZB_TEMPERATURE_CLUSTER;
332 else if (strcmp(oicResourceType, OIC_DIMMABLE_LIGHT) == 0)
334 return ZB_LEVEL_CONTROL_CLUSTER;
336 else if (strcmp(oicResourceType, OIC_CONTACT_SENSOR) == 0)
338 return ZB_CONTACT_CLUSTER;
340 else if (strcmp(oicResourceType, OIC_BINARY_SWITCH) == 0)
342 return ZB_ON_OFF_CLUSTER;
344 else if (strcmp(oicResourceType, OIC_BINARY_SWITCH) == 0)
346 return ZB_INDICATOR_CLUSTER;
354 OCStackResult getZigBeeAttributesForOICResource (char * OICResourceType,
355 AttributeList *attributeList) // GET
357 if (strcmp (OICResourceType, OIC_TEMPERATURE_SENSOR) == 0)
359 attributeList->count = 1;
360 attributeList->list[0].oicAttribute = OICStrdup(OIC_TEMPERATURE_ATTRIBUTE);
361 attributeList->list[0].zigBeeAttribute = ZB_TEMPERATURE_ATTRIBUTE_ID;
362 attributeList->list[0].oicType = OIC_ATTR_DOUBLE;
363 attributeList->list[0].zigbeeType = ZB_16_SINT;
366 else if (strcmp (OICResourceType, OIC_DIMMABLE_LIGHT) == 0)
368 attributeList->count = 1;
369 attributeList->list[0].oicAttribute = OICStrdup(OIC_DIMMING_ATTRIBUTE);
370 attributeList->list[0].zigBeeAttribute = ZB_CURRENT_LEVEL_ATTRIBUTE_READONLY;
371 attributeList->list[0].oicType = OIC_ATTR_INT;
372 attributeList->list[0].zigbeeType = ZB_8_UINT;
375 else if (strcmp (OICResourceType, OIC_CONTACT_SENSOR) == 0)
377 attributeList->count = 1;
378 attributeList->list[0].oicAttribute = OICStrdup(OIC_CONTACT_ATTRIBUTE);
379 attributeList->list[0].zigBeeAttribute = ZB_CONTACT_ATTRIBUTE_ID;
380 attributeList->list[0].oicType = OIC_ATTR_BOOL;
381 attributeList->list[0].zigbeeType = ZB_BOOL;
384 else if (strcmp (OICResourceType, OIC_BINARY_SWITCH) == 0)
386 attributeList->count = 1;
387 attributeList->list[0].oicAttribute = OICStrdup(OIC_ON_OFF_ATTRIBUTE);
388 attributeList->list[0].zigBeeAttribute = ZB_ON_OFF_ATTRIBUTE_ID;
389 attributeList->list[0].oicType = OIC_ATTR_BOOL;
390 attributeList->list[0].zigbeeType = ZB_BOOL;
394 return OC_STACK_ERROR;
397 bool getZigBeeAttributesIfValid (char * OICResourceType,
398 AttributeList *attributeList,
399 OCRepPayload *payload) // Put
405 if(strcmp(OICResourceType, OIC_TEMPERATURE_SENSOR) == 0)
407 // Cant really PUT on the temp sensor, but the code is still there.
408 int64_t temperature = 0;
410 // TODO: This if should only look for attributes it supports and ignore the rest
411 // or examine every attribute in the payload and complain about unsupported attributes?
412 if(OCRepPayloadGetPropInt(payload, OIC_TEMPERATURE_ATTRIBUTE, &temperature))
414 attributeList->count = 1;
415 attributeList->list[0].oicAttribute = OICStrdup(OIC_TEMPERATURE_ATTRIBUTE);
416 attributeList->list[0].zigBeeAttribute = ZB_TEMPERATURE_ATTRIBUTE_ID;
417 attributeList->list[0].oicType = OIC_ATTR_DOUBLE;
418 attributeList->list[0].val.d = temperature;
419 attributeList->list[0].zigbeeType = ZB_16_SINT;
420 attributeList->CIEMask = (CIECommandMask) 0;
425 else if (strcmp (OICResourceType, OIC_DIMMABLE_LIGHT) == 0)
429 if(OCRepPayloadGetPropInt(payload, OIC_DIMMING_ATTRIBUTE, &onLevel))
431 attributeList->count = 1;
432 attributeList->list[0].oicAttribute = OICStrdup(OIC_DIMMING_ATTRIBUTE);
433 attributeList->list[0].zigBeeAttribute = ZB_ON_LEVEL_ATTRIBUTE;
434 attributeList->list[0].oicType = OIC_ATTR_INT;
435 attributeList->list[0].val.i = onLevel;
436 attributeList->list[0].zigbeeType = ZB_8_UINT;
438 // Level control cluster is dealing with level in the PUT payload.
439 attributeList->CIEMask = attributeList->CIEMask | CIE_MOVE_TO_LEVEL;
443 else if (strcmp (OICResourceType, OIC_CONTACT_SENSOR) == 0)
447 if(OCRepPayloadGetPropInt(payload, OIC_CONTACT_ATTRIBUTE, &value))
449 attributeList->count = 1;
450 attributeList->list[0].oicAttribute = OICStrdup(OIC_CONTACT_ATTRIBUTE);
451 attributeList->list[0].zigBeeAttribute = ZB_CONTACT_ATTRIBUTE_ID;
452 attributeList->list[0].oicType = OIC_ATTR_BOOL;
453 attributeList->list[0].val.i = value;
454 attributeList->list[0].zigbeeType = ZB_BOOL;
455 attributeList->CIEMask = (CIECommandMask) 0;
460 else if (strcmp (OICResourceType, OIC_BINARY_SWITCH) == 0)
464 if(OCRepPayloadGetPropBool(payload, OIC_ON_OFF_ATTRIBUTE, &value))
466 attributeList->count = 1;
467 attributeList->list[0].oicAttribute = OICStrdup(OIC_ON_OFF_ATTRIBUTE);
468 attributeList->list[0].zigBeeAttribute = ZB_ON_OFF_ATTRIBUTE_ID;
469 attributeList->list[0].oicType = OIC_ATTR_BOOL;
470 attributeList->list[0].val.b = value;
471 attributeList->list[0].zigbeeType = ZB_BOOL;
473 attributeList->CIEMask = attributeList->CIEMask | CIE_RON_OFF;
480 OCEntityHandlerResult getDoubleValueFromString (const char *str, double *outDouble)
482 size_t hexOutValSize = strlen(HexPrepend) + strlen(str) + 1;
483 char * hexOutVal = (char *) OICCalloc(1, hexOutValSize);
488 OICStrcpy(hexOutVal, hexOutValSize, HexPrepend);
489 OICStrcat(hexOutVal, hexOutValSize, str);
493 double value = strtod(hexOutVal, &endPtr);
495 if(errno != 0 || *endPtr != 0 || value == HUGE_VALF || value == HUGE_VALL)
507 OCEntityHandlerResult processGetRequest (PIPluginBase * plugin,
508 OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
510 if (!plugin || !ehRequest || !payload)
514 uint32_t attributeListIndex = 0;
515 OCStackResult stackResult = OC_STACK_OK;
516 PIResource_Zigbee * piResource = NULL;
518 AttributeList attributeList = { 0, (CIECommandMask) 0,
519 .list[0] = { NULL, NULL, OIC_ATTR_NULL, ZB_NULL, { .i = 0 } } };
520 stackResult = GetResourceFromHandle(plugin, (PIResource**) (&piResource),
521 ehRequest->resource);
522 if (stackResult != OC_STACK_OK)
524 OC_LOG (ERROR, TAG, "Failed to get resource from handle");
527 stackResult = getZigBeeAttributesForOICResource (
528 piResource->header.piResource.resourceTypeName, &attributeList);
529 if(stackResult != OC_STACK_OK)
531 OC_LOG_V (ERROR, TAG, "Failed to fetch attributes for %s",
532 piResource->header.piResource.resourceTypeName);
536 *payload = OCRepPayloadCreate();
539 OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
542 bool boolRes = OCRepPayloadSetUri(*payload, piResource->header.piResource.uri);
543 if (boolRes == false)
545 OCRepPayloadDestroy (*payload);
548 for(uint32_t i = 0; i<attributeList.count; i++)
550 char * outVal = NULL;
551 uint8_t outValLength = 0;
553 stackResult = TWGetAttribute(piResource->eui,
555 piResource->endpointId,
556 piResource->clusterId,
557 attributeList.list[i].zigBeeAttribute,
561 if (stackResult != OC_STACK_OK || !outVal)
563 stackResult = OC_EH_ERROR;
564 OCRepPayloadDestroy (*payload);
567 if (attributeList.list[i].oicType == OIC_ATTR_INT)
570 // Third arg is 16 as outVal is a hex Number
571 uint64_t value = strtol (outVal, &endPtr, 16);
577 if (strcmp(attributeList.list[i].oicAttribute, OIC_DIMMING_ATTRIBUTE) == 0)
579 // OIC Dimming operates between 0-100, while Zigbee operates
580 // between 0-254 (ie. 0xFE).
587 value = value / 2.54;
590 boolRes = OCRepPayloadSetPropInt(*payload,
591 attributeList.list[i].oicAttribute,
594 else if (attributeList.list[i].oicType == OIC_ATTR_DOUBLE)
598 if (getDoubleValueFromString (outVal, &value) != OC_EH_OK)
602 if (strcmp(piResource->clusterId, ZB_TEMPERATURE_CLUSTER) == 0)
604 // Divide by 100 as temperature readings have a resolution of
605 // 0.01 or one hundreth of a degree celsius.
608 boolRes = OCRepPayloadSetPropDouble(*payload,
609 attributeList.list[i].oicAttribute,
612 else if (attributeList.list[i].oicType == OIC_ATTR_STRING)
614 boolRes = OCRepPayloadSetPropString(*payload,
615 attributeList.list[i].oicAttribute,
618 else if (attributeList.list[i].oicType == OIC_ATTR_BOOL)
622 // Third arg is 16 as outVal is a hex Number
623 uint64_t value = strtol (outVal, &endPtr, 16);
625 if (errno != 0 || *endPtr != 0)
629 // value COULD be a bit mask and the LSB indicates boolean true/false.
630 // If not a bit mask, it'll be plain 0 or 1.
632 boolRes = OCRepPayloadSetPropBool(*payload,
633 attributeList.list[i].oicAttribute,
640 if (boolRes == false)
642 stackResult = OC_EH_ERROR;
647 for(; attributeListIndex < attributeList.count; attributeListIndex++)
649 OICFree(attributeList.list[attributeListIndex].oicAttribute);
654 OCEntityHandlerResult processPutRequest (PIPluginBase * plugin,
655 OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
657 if (!plugin || !ehRequest || !payload)
661 OCStackResult stackResult = OC_STACK_OK;
662 PIResource_Zigbee *piResource = NULL;
663 AttributeList attributeList = {
666 .list[0] = { NULL, NULL, OIC_ATTR_NULL, ZB_NULL, { .i = 0 } }
669 stackResult = GetResourceFromHandle(plugin,
670 ((PIResource **) (&piResource)),
671 ehRequest->resource);
672 if (stackResult != OC_STACK_OK)
674 OC_LOG (ERROR, TAG, "Failed to get resource from handle");
678 bool boolRes = getZigBeeAttributesIfValid (
679 piResource->header.piResource.resourceTypeName,
680 &attributeList, *payload);
683 OC_LOG_V (ERROR, TAG, "Failed to fetch attributes for %s",
684 piResource->header.piResource.resourceTypeName);
689 for(; i<attributeList.count; i++)
691 if (attributeList.list[i].oicType == OIC_ATTR_INT)
693 char value[MAX_STRLEN_INT] = {};
694 if (attributeList.CIEMask || CIE_MOVE_TO_LEVEL)
696 int64_t rangeDiff = 0;
697 // OIC Dimming operates between 0-100, while Zigbee
698 // operates between 0-254 (ie. 0xFE).
699 rangeDiff = attributeList.list[i].val.i * 0xFE/100;
700 if (rangeDiff > 0xFE)
708 if (rangeDiff <= 0xFE)
710 snprintf(value, sizeof(value), "%02x", (unsigned int) rangeDiff);
712 stackResult = TWMoveToLevel(piResource->nodeId, piResource->endpointId,
713 DEFAULT_MOVETOLEVEL_MODE, value, DEFAULT_TRANS_TIME);
717 snprintf(value, sizeof(value), "%"PRId64, attributeList.list[i].val.i);
718 stackResult = TWSetAttribute(piResource->eui,
719 piResource->nodeId, piResource->endpointId,
720 piResource->clusterId, attributeList.list[i].zigBeeAttribute,
721 getZBDataTypeString(attributeList.list[i].zigbeeType), value);
723 if (stackResult != OC_STACK_OK)
728 else if (attributeList.list[i].oicType == OIC_ATTR_DOUBLE)
730 char value[MAX_STRLEN_DOUBLE] = {};
731 snprintf(value, sizeof(value), "%f", attributeList.list[i].val.d);
732 stackResult = TWSetAttribute(piResource->eui,
733 piResource->nodeId, piResource->endpointId,
734 piResource->clusterId, attributeList.list[i].zigBeeAttribute,
735 getZBDataTypeString(attributeList.list[i].zigbeeType), value);
737 else if (attributeList.list[i].oicType == OIC_ATTR_STRING)
739 stackResult = TWSetAttribute(piResource->eui,
740 piResource->nodeId, piResource->endpointId,
741 piResource->clusterId, attributeList.list[i].zigBeeAttribute,
742 getZBDataTypeString(attributeList.list[i].zigbeeType),
743 attributeList.list[i].val.str);
744 if (stackResult != OC_STACK_OK)
749 else if (attributeList.list[i].oicType == OIC_ATTR_BOOL)
751 char * value = attributeList.list[i].val.b ? "1" : "0";
752 if (attributeList.CIEMask || CIE_RON_OFF)
754 stackResult = TWSwitchOnOff(piResource->nodeId, piResource->endpointId, value);
758 stackResult = TWSetAttribute(piResource->eui,
759 piResource->nodeId, piResource->endpointId,
760 piResource->clusterId, attributeList.list[i].zigBeeAttribute,
761 getZBDataTypeString(attributeList.list[i].zigbeeType),
764 if (stackResult != OC_STACK_OK)
775 return processGetRequest(plugin, ehRequest, payload);
778 OCEntityHandlerResult ProcessEHRequest (PIPluginBase * plugin,
779 OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
781 if(!ehRequest || !payload)
785 if(ehRequest->method == OC_REST_GET)
787 return processGetRequest(plugin, ehRequest, payload);
789 else if(ehRequest->method == OC_REST_PUT)
791 return processPutRequest(plugin, ehRequest, payload);
795 return OC_EH_FORBIDDEN;
799 char * getZBDataTypeString(ZigBeeAttributeDataType attrType)
804 return ZB_DATA_TYPE_NULL;
806 return ZB_DATA_TYPE_1_BYTE;
808 return ZB_DATA_TYPE_2_BYTE;
810 return ZB_DATA_TYPE_3_BYTE;
812 return ZB_DATA_TYPE_4_BYTE;
814 return ZB_DATA_TYPE_5_BYTE;
816 return ZB_DATA_TYPE_6_BYTE;
818 return ZB_DATA_TYPE_7_BYTE;
820 return ZB_DATA_TYPE_8_BYTE;
822 return ZB_DATA_TYPE_BOOL;
824 return ZB_DATA_TYPE_1_BYTE;
826 return ZB_DATA_TYPE_2_BYTE;
828 return ZB_DATA_TYPE_3_BYTE;
830 return ZB_DATA_TYPE_4_BYTE;
832 return ZB_DATA_TYPE_5_BYTE;
834 return ZB_DATA_TYPE_6_BYTE;
836 return ZB_DATA_TYPE_7_BYTE;
838 return ZB_DATA_TYPE_8_BYTE;
840 return ZB_DATA_TYPE_SIGNED_INT_16;
842 return ZB_DATA_TYPE_UNSIGNED_INT_8;
844 return ZB_DATA_TYPE_UNSIGNED_INT_16;
846 return ZB_DATA_TYPE_NULL;