/* packet-zbee-zcl-meas-sensing.c * Dissector routines for the ZigBee ZCL Measurement & Sensing clusters like * Illuminance Measurement, Temperature Measurement ... * By Fabio Tarabelloni * Copyright 2013 RELOC s.r.l. * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ /* Include Files */ #include "config.h" #include #include #include #include "packet-zbee.h" #include "packet-zbee-aps.h" #include "packet-zbee-zcl.h" /* ########################################################################## */ /* #### (0x0400) ILLUMINANCE MEASUREMENT CLUSTER ############################ */ /* ########################################################################## */ /*************************/ /* Defines */ /*************************/ #define ZBEE_ZCL_ILLUM_MEAS_NUM_GENERIC_ETT 1 #define ZBEE_ZCL_ILLUM_MEAS_NUM_ETT ZBEE_ZCL_ILLUM_MEAS_NUM_GENERIC_ETT /* Attributes */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MEASURED_VALUE 0x0000 /* Measured Value */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MIN_MEASURED_VALUE 0x0001 /* Min Measured Value */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MAX_MEASURED_VALUE 0x0002 /* Max Measured Value */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_TOLERANCE 0x0003 /* Tolerance */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_LIGHT_SENSOR_TYPE 0x0004 /* Light Sensor Type */ /* Server Commands Received - None */ /* Server Commands Generated - None */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_TOO_LOW_VALUE 0x0000 /* Too Low Value */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_INVALID_VALUE 0x8000 /* Invalid Value */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MIN_LO_VALUE 0x0002 /* Minimum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MIN_HI_VALUE 0xfffd /* Minimum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MAX_LO_VALUE 0x0001 /* Maximum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MAX_HI_VALUE 0xfffe /* Maximum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_TOL_LO_VALUE 0x0000 /* Tolerance (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_TOL_HI_VALUE 0x0800 /* Tolerance (Low Bound) */ #define ZBEE_ZCL_ILLUM_MEAS_SENSOR_TYPE_PHOTODIODE 0x00 /* Photodiode */ #define ZBEE_ZCL_ILLUM_MEAS_SENSOR_TYPE_CMOS 0x01 /* CMOS */ /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_illum_meas(void); void proto_reg_handoff_zbee_zcl_illum_meas(void); /* Command Dissector Helpers */ static void dissect_zcl_illum_meas_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); /* Private functions prototype */ static void decode_illum_meas_value (char *s, uint16_t value); static void decode_illum_meas_min_value (char *s, uint16_t value); static void decode_illum_meas_max_value (char *s, uint16_t value); static void decode_illum_meas_tolerance (char *s, uint16_t value); /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_illum_meas; static int hf_zbee_zcl_illum_meas_attr_id; static int hf_zbee_zcl_illum_meas_measured_value; static int hf_zbee_zcl_illum_meas_min_measured_value; static int hf_zbee_zcl_illum_meas_max_measured_value; static int hf_zbee_zcl_illum_meas_tolerance; static int hf_zbee_zcl_illum_meas_sensor_type; /* Initialize the subtree pointers */ static int ett_zbee_zcl_illum_meas; /* Attributes */ static const value_string zbee_zcl_illum_meas_attr_names[] = { { ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MEASURED_VALUE, "Measured Value" }, { ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MIN_MEASURED_VALUE, "Min Measured Value" }, { ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MAX_MEASURED_VALUE, "Max Measured Value" }, { ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_TOLERANCE, "Tolerance" }, { ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_LIGHT_SENSOR_TYPE, "Light Sensor Type" }, { 0, NULL } }; static const value_string zbee_zcl_illum_meas_sensor_type_names[] = { { ZBEE_ZCL_ILLUM_MEAS_SENSOR_TYPE_PHOTODIODE, "Photodiode" }, { ZBEE_ZCL_ILLUM_MEAS_SENSOR_TYPE_CMOS, "CMOS" }, { 0, NULL } }; /*************************/ /* Function Bodies */ /*************************/ /** *ZigBee ZCL Illuminance Measurement cluster dissector for wireshark. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ static int dissect_zbee_zcl_illum_meas(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_) { return tvb_captured_length(tvb); } /*dissect_zbee_zcl_illum_meas*/ /** *This function is called by ZCL foundation dissector in order to decode * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset pointer to buffer offset *@param attr_id attribute identifier *@param data_type attribute data type *@param client_attr ZCL client */ static void dissect_zcl_illum_meas_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr) { /* Dissect attribute data type and data */ switch ( attr_id ) { case ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_illum_meas_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MIN_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_illum_meas_min_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MAX_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_illum_meas_max_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_TOLERANCE: proto_tree_add_item(tree, hf_zbee_zcl_illum_meas_tolerance, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_LIGHT_SENSOR_TYPE: proto_tree_add_item(tree, hf_zbee_zcl_illum_meas_sensor_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN); *offset += 1; break; default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_illum_meas_attr_data*/ /** *This function decodes illuminance value * *@param s string to display *@param value value to decode */ static void decode_illum_meas_value(char *s, uint16_t value) { if (value == ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_TOO_LOW_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Value too low to be measured"); else if (value == ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_INVALID_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Invalid value"); else /* calculate lux value from measured value according to doc 07-5123-04 */ snprintf(s, ITEM_LABEL_LENGTH, "%d (=%f [lx])", value, pow(10,value/10000.0)-1); return; } /*decode_illum_meas_value*/ /** *This function decodes minimum illuminance value * *@param s string to display *@param value value to decode */ static void decode_illum_meas_min_value(char *s, uint16_t value) { if ( (value < ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MIN_LO_VALUE) || (value > ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MIN_HI_VALUE) ) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d (=%f [lx])", value, pow(10,value/10000.0)-1); return; } /*decode_illum_meas_min_value*/ /** *This function decodes maximum illuminance value * *@param s string to display *@param value value to decode */ static void decode_illum_meas_max_value(char *s, uint16_t value) { if ( (value < ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MAX_LO_VALUE) || (value > ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_MAX_HI_VALUE) ) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d (=%f [lx])", value, pow(10,value/10000.0)-1); return; } /*decode_illum_meas_max_value*/ /** *This function decodes tolerance value * *@param s string to display *@param value value to decode */ static void decode_illum_meas_tolerance(char *s, uint16_t value) { if (value > ZBEE_ZCL_ATTR_ID_ILLUM_MEAS_TOL_HI_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d", value); return; } /*decode_illum_meas_tolerance*/ /** *This function registers the ZCL Illuminance Measurement dissector * */ void proto_register_zbee_zcl_illum_meas(void) { static hf_register_info hf[] = { { &hf_zbee_zcl_illum_meas_attr_id, { "Attribute", "zbee_zcl_meas_sensing.illummeas.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_illum_meas_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_illum_meas_measured_value, { "Measured Value", "zbee_zcl_meas_sensing.illummeas.attr.value", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_illum_meas_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_illum_meas_min_measured_value, { "Min Measured Value", "zbee_zcl_meas_sensing.illummeas.attr.value.min", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_illum_meas_min_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_illum_meas_max_measured_value, { "Max Measured Value", "zbee_zcl_meas_sensing.illummeas.attr.value.max", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_illum_meas_max_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_illum_meas_tolerance, { "Tolerance", "zbee_zcl_meas_sensing.illummeas.attr.tolerance", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_illum_meas_tolerance), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_illum_meas_sensor_type, { "Sensor Type", "zbee_zcl_meas_sensing.illummeas.attr.sensor_type", FT_UINT8, BASE_HEX, VALS(zbee_zcl_illum_meas_sensor_type_names), 0x0, NULL, HFILL } } }; /* ZCL Illuminance Measurement subtrees */ int *ett[] = { &ett_zbee_zcl_illum_meas }; /* Register the ZigBee ZCL Illuminance Measurement cluster protocol name and description */ proto_zbee_zcl_illum_meas = proto_register_protocol("ZigBee ZCL Illuminance Meas.", "ZCL Illuminance Meas.", ZBEE_PROTOABBREV_ZCL_ILLUMMEAS); proto_register_field_array(proto_zbee_zcl_illum_meas, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL Illuminance Measurement dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_ILLUMMEAS, dissect_zbee_zcl_illum_meas, proto_zbee_zcl_illum_meas); } /*proto_register_zbee_zcl_illum_meas*/ /** *Hands off the ZCL Illuminance Measurement dissector. * */ void proto_reg_handoff_zbee_zcl_illum_meas(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_ILLUMMEAS, proto_zbee_zcl_illum_meas, ett_zbee_zcl_illum_meas, ZBEE_ZCL_CID_ILLUMINANCE_MEASUREMENT, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_illum_meas_attr_id, hf_zbee_zcl_illum_meas_attr_id, -1, -1, (zbee_zcl_fn_attr_data)dissect_zcl_illum_meas_attr_data ); } /*proto_reg_handoff_zbee_zcl_illum_meas*/ /* ########################################################################## */ /* #### (0x0401) ILLUMINANCE LEVEL SENSING CLUSTER ########################## */ /* ########################################################################## */ /*************************/ /* Defines */ /*************************/ #define ZBEE_ZCL_ILLUM_LEVEL_SEN_NUM_GENERIC_ETT 1 #define ZBEE_ZCL_ILLUM_LEVEL_SEN_NUM_ETT ZBEE_ZCL_ILLUM_LEVEL_SEN_NUM_GENERIC_ETT /* Attributes */ #define ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_LEVEL_STATUS 0x0000 /* Level Status */ #define ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_LIGHT_SENSOR_TYPE 0x0001 /* Light Sensor Type */ #define ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_ILLUM_TARGET_LEVEL 0x0010 /* Illuminance Target Level */ /* Server Commands Received - None */ /* Server Commands Generated - None */ #define ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_TOO_LOW_VALUE 0x0000 /* Too Low Value */ #define ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_INVALID_VALUE 0x8000 /* Invalid Value */ #define ZBEE_ZCL_ILLUM_LEVEL_SEN_SENSOR_TYPE_PHOTODIODE 0x00 /* Photodiode */ #define ZBEE_ZCL_ILLUM_LEVEL_SEN_SENSOR_TYPE_CMOS 0x01 /* CMOS */ #define ZBEE_ZCL_ILLUM_LEVEL_SEN_ILLUM_ON_TARGET 0x00 /* Illuminance on Target */ #define ZBEE_ZCL_ILLUM_LEVEL_SEN_ILLUM_BELOW_TARGET 0x01 /* Illuminance below Target */ #define ZBEE_ZCL_ILLUM_LEVEL_SEN_ILLUM_ABOVE_TARGET 0x02 /* Illuminance above Target */ /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_illum_level_sen(void); void proto_reg_handoff_zbee_zcl_illum_level_sen(void); /* Command Dissector Helpers */ static void dissect_zcl_illum_level_sen_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); /* Private functions prototype */ static void decode_illum_level_sen_target_level (char *s, uint16_t value); /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_illum_level_sen; static int hf_zbee_zcl_illum_level_sen_attr_id; static int hf_zbee_zcl_illum_level_sen_level_status; static int hf_zbee_zcl_illum_level_sen_light_sensor_type; static int hf_zbee_zcl_illum_level_sen_illum_target_level; /* Initialize the subtree pointers */ static int ett_zbee_zcl_illum_level_sen; /* Attributes */ static const value_string zbee_zcl_illum_level_sen_attr_names[] = { { ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_LEVEL_STATUS, "Level Status" }, { ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_LIGHT_SENSOR_TYPE, "Light Sensor Type" }, { ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_ILLUM_TARGET_LEVEL, "Illuminance Target Level" }, { 0, NULL } }; static const value_string zbee_zcl_illum_level_sen_sensor_type_names[] = { { ZBEE_ZCL_ILLUM_LEVEL_SEN_SENSOR_TYPE_PHOTODIODE, "Photodiode" }, { ZBEE_ZCL_ILLUM_LEVEL_SEN_SENSOR_TYPE_CMOS, "CMOS" }, { 0, NULL } }; static const value_string zbee_zcl_illum_level_sen_level_status_names[] = { { ZBEE_ZCL_ILLUM_LEVEL_SEN_ILLUM_ON_TARGET, "Illuminance on Target" }, { ZBEE_ZCL_ILLUM_LEVEL_SEN_ILLUM_BELOW_TARGET, "Illuminance below Target" }, { ZBEE_ZCL_ILLUM_LEVEL_SEN_ILLUM_ABOVE_TARGET, "Illuminance above Target" }, { 0, NULL } }; /*************************/ /* Function Bodies */ /*************************/ /** *ZigBee ZCL Illuminance Level Sensing cluster dissector for wireshark. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ static int dissect_zbee_zcl_illum_level_sen(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_) { return tvb_captured_length(tvb); } /*dissect_zbee_zcl_illum_level_sen*/ /** *This function is called by ZCL foundation dissector in order to decode * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset pointer to buffer offset *@param attr_id attribute identifier *@param data_type attribute data type *@param client_attr ZCL client */ static void dissect_zcl_illum_level_sen_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr) { /* Dissect attribute data type and data */ switch ( attr_id ) { case ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_LEVEL_STATUS: proto_tree_add_item(tree, hf_zbee_zcl_illum_level_sen_level_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN); *offset += 1; break; case ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_LIGHT_SENSOR_TYPE: proto_tree_add_item(tree, hf_zbee_zcl_illum_level_sen_light_sensor_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN); *offset += 1; break; case ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_ILLUM_TARGET_LEVEL: proto_tree_add_item(tree, hf_zbee_zcl_illum_level_sen_illum_target_level, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_illum_level_sen_attr_data*/ /** *This function decodes illuminance value * *@param s string to display *@param value value to decode */ static void decode_illum_level_sen_target_level(char *s, uint16_t value) { if (value == ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_TOO_LOW_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Value too low to be measured"); else if (value == ZBEE_ZCL_ATTR_ID_ILLUM_LEVEL_SEN_INVALID_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Invalid value"); else /* calculate lux value from measured value according to doc 07-5123-04 */ snprintf(s, ITEM_LABEL_LENGTH, "%d (=%f [lx])", value, pow(10,value/10000.0)-1); return; } /*decode_illum_level_sen_value*/ /** *This function registers the ZCL Illuminance Level Sensing dissector * */ void proto_register_zbee_zcl_illum_level_sen(void) { static hf_register_info hf[] = { { &hf_zbee_zcl_illum_level_sen_attr_id, { "Attribute", "zbee_zcl_meas_sensing.illumlevelsen.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_illum_level_sen_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_illum_level_sen_level_status, { "Level Status", "zbee_zcl_meas_sensing.illumlevelsen.attr.level_status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_illum_level_sen_level_status_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_illum_level_sen_light_sensor_type, { "Light Sensor Type", "zbee_zcl_meas_sensing.illumlevelsen.attr.light_sensor_type", FT_UINT8, BASE_HEX, VALS(zbee_zcl_illum_level_sen_sensor_type_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_illum_level_sen_illum_target_level, { "Target Level", "zbee_zcl_meas_sensing.illumlevelsen.attr.target_level", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_illum_level_sen_target_level), 0x0, NULL, HFILL } } }; /* ZCL Illuminance Level Sensing subtrees */ int *ett[] = { &ett_zbee_zcl_illum_level_sen }; /* Register the ZigBee ZCL Illuminance Level Sensing cluster protocol name and description */ proto_zbee_zcl_illum_level_sen = proto_register_protocol("ZigBee ZCL Illuminance Level Sensing", "ZCL Illuminance Level Sensing", ZBEE_PROTOABBREV_ZCL_ILLUMLEVELSEN); proto_register_field_array(proto_zbee_zcl_illum_level_sen, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL Illuminance Level Sensing dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_ILLUMLEVELSEN, dissect_zbee_zcl_illum_level_sen, proto_zbee_zcl_illum_level_sen); } /*proto_register_zbee_zcl_illum_level_sen*/ /** *Hands off the ZCL Illuminance Level Sensing dissector. * */ void proto_reg_handoff_zbee_zcl_illum_level_sen(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_ILLUMLEVELSEN, proto_zbee_zcl_illum_level_sen, ett_zbee_zcl_illum_level_sen, ZBEE_ZCL_CID_ILLUMINANCE_LEVEL_SENSING, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_illum_level_sen_attr_id, hf_zbee_zcl_illum_level_sen_attr_id, -1, -1, (zbee_zcl_fn_attr_data)dissect_zcl_illum_level_sen_attr_data ); } /*proto_reg_handoff_zbee_zcl_illum_level_sen*/ /* ########################################################################## */ /* #### (0x0402) TEMPERATURE MEASUREMENT CLUSTER ############################ */ /* ########################################################################## */ /*************************/ /* Defines */ /*************************/ #define ZBEE_ZCL_TEMP_MEAS_NUM_GENERIC_ETT 1 #define ZBEE_ZCL_TEMP_MEAS_NUM_ETT ZBEE_ZCL_TEMP_MEAS_NUM_GENERIC_ETT /* Attributes */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MEASURED_VALUE 0x0000 /* Measured Value */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MIN_MEASURED_VALUE 0x0001 /* Min Measured Value */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MAX_MEASURED_VALUE 0x0002 /* Max Measured Value */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_TOLERANCE 0x0003 /* Tolerance */ /* Server Commands Received - None */ /* Server Commands Generated - None */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_INVALID_VALUE 0x8000 /* Invalid Value */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MIN_LO_VALUE 0x954d /* Minimum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MIN_HI_VALUE 0x7ffe /* Minimum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MAX_LO_VALUE 0x954e /* Maximum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MAX_HI_VALUE 0x7fff /* Maximum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_TOL_LO_VALUE 0x0000 /* Tolerance (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_TEMP_MEAS_TOL_HI_VALUE 0x0800 /* Tolerance (Low Bound) */ /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_temp_meas(void); void proto_reg_handoff_zbee_zcl_temp_meas(void); /* Command Dissector Helpers */ static void dissect_zcl_temp_meas_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); /* Private functions prototype */ static void decode_temp_meas_value (char *s, int16_t value); static void decode_temp_meas_min_value (char *s, int16_t value); static void decode_temp_meas_max_value (char *s, int16_t value); static void decode_temp_meas_tolerance (char *s, uint16_t value); /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_temp_meas; static int hf_zbee_zcl_temp_meas_attr_id; static int hf_zbee_zcl_temp_meas_measured_value; static int hf_zbee_zcl_temp_meas_min_measured_value; static int hf_zbee_zcl_temp_meas_max_measured_value; static int hf_zbee_zcl_temp_meas_tolerance; /* Initialize the subtree pointers */ static int ett_zbee_zcl_temp_meas; /* Attributes */ static const value_string zbee_zcl_temp_meas_attr_names[] = { { ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MEASURED_VALUE, "Measured Value" }, { ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MIN_MEASURED_VALUE, "Min Measured Value" }, { ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MAX_MEASURED_VALUE, "Max Measured Value" }, { ZBEE_ZCL_ATTR_ID_TEMP_MEAS_TOLERANCE, "Tolerance" }, { 0, NULL } }; /*************************/ /* Function Bodies */ /*************************/ /** *ZigBee ZCL Temperature Measurement cluster dissector for wireshark. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ static int dissect_zbee_zcl_temp_meas(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_) { return tvb_captured_length(tvb); } /*dissect_zbee_zcl_temp_meas*/ /** *This function is called by ZCL foundation dissector in order to decode * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset pointer to buffer offset *@param attr_id attribute identifier *@param data_type attribute data type *@param client_attr ZCL client */ static void dissect_zcl_temp_meas_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr) { /* Dissect attribute data type and data */ switch ( attr_id ) { case ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_temp_meas_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MIN_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_temp_meas_min_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MAX_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_temp_meas_max_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_TEMP_MEAS_TOLERANCE: proto_tree_add_item(tree, hf_zbee_zcl_temp_meas_tolerance, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_temp_meas_attr_data*/ /** *This function decodes temperature value * *@param s string to display *@param value value to decode */ static void decode_temp_meas_value(char *s, int16_t value) { if (value == (int16_t)ZBEE_ZCL_ATTR_ID_TEMP_MEAS_INVALID_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Invalid value"); else snprintf(s, ITEM_LABEL_LENGTH, "%.2f [" UTF8_DEGREE_SIGN "C]", value/100.0); return; } /*decode_temp_meas_value*/ /** *This function decodes minimum temperature value * *@param s string to display *@param value value to decode */ static void decode_temp_meas_min_value(char *s, int16_t value) { if ( (value < (int16_t)ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MIN_LO_VALUE) || (value > (int16_t)ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MIN_HI_VALUE) ) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%.2f [" UTF8_DEGREE_SIGN "C]", value/100.0); return; } /*decode_temp_meas_min_value*/ /** *This function decodes maximum temperature value * *@param s string to display *@param value value to decode */ static void decode_temp_meas_max_value(char *s, int16_t value) { if (value < (int16_t)ZBEE_ZCL_ATTR_ID_TEMP_MEAS_MAX_LO_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%.2f [" UTF8_DEGREE_SIGN "C]", value/100.0); return; } /*decode_temp_meas_max_value*/ /** *This function decodes tolerance value * *@param s string to display *@param value value to decode */ static void decode_temp_meas_tolerance(char *s, uint16_t value) { if (value > ZBEE_ZCL_ATTR_ID_TEMP_MEAS_TOL_HI_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%d [" UTF8_DEGREE_SIGN "C]", value/100, value%100); return; } /*decode_temp_meas_tolerance*/ /** *This function registers the ZCL Temperature Measurement dissector * */ void proto_register_zbee_zcl_temp_meas(void) { static hf_register_info hf[] = { { &hf_zbee_zcl_temp_meas_attr_id, { "Attribute", "zbee_zcl_meas_sensing.tempmeas.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_temp_meas_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_temp_meas_measured_value, { "Measured Value", "zbee_zcl_meas_sensing.tempmeas.attr.value", FT_INT16, BASE_CUSTOM, CF_FUNC(decode_temp_meas_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_temp_meas_min_measured_value, { "Min Measured Value", "zbee_zcl_meas_sensing.tempmeas.attr.value.min", FT_INT16, BASE_CUSTOM, CF_FUNC(decode_temp_meas_min_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_temp_meas_max_measured_value, { "Max Measured Value", "zbee_zcl_meas_sensing.tempmeas.attr.value.max", FT_INT16, BASE_CUSTOM, CF_FUNC(decode_temp_meas_max_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_temp_meas_tolerance, { "Tolerance", "zbee_zcl_meas_sensing.tempmeas.attr.tolerance", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_temp_meas_tolerance), 0x0, NULL, HFILL } } }; /* ZCL Temperature Measurement subtrees */ int *ett[] = { &ett_zbee_zcl_temp_meas }; /* Register the ZigBee ZCL Temperature Measurement cluster protocol name and description */ proto_zbee_zcl_temp_meas = proto_register_protocol("ZigBee ZCL Temperature Meas.", "ZCL Temperature Meas.", ZBEE_PROTOABBREV_ZCL_TEMPMEAS); proto_register_field_array(proto_zbee_zcl_temp_meas, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL Temperature Measurement dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_TEMPMEAS, dissect_zbee_zcl_temp_meas, proto_zbee_zcl_temp_meas); } /*proto_register_zbee_zcl_temp_meas*/ /** *Hands off the ZCL Temperature Measurement dissector. * */ void proto_reg_handoff_zbee_zcl_temp_meas(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_TEMPMEAS, proto_zbee_zcl_temp_meas, ett_zbee_zcl_temp_meas, ZBEE_ZCL_CID_TEMPERATURE_MEASUREMENT, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_temp_meas_attr_id, hf_zbee_zcl_temp_meas_attr_id, -1, -1, (zbee_zcl_fn_attr_data)dissect_zcl_temp_meas_attr_data ); } /*proto_reg_handoff_zbee_zcl_temp_meas*/ /* ########################################################################## */ /* #### (0x0403) PRESSURE MEASUREMENT CLUSTER ############################### */ /* ########################################################################## */ /*************************/ /* Defines */ /*************************/ #define ZBEE_ZCL_PRESS_MEAS_NUM_GENERIC_ETT 1 #define ZBEE_ZCL_PRESS_MEAS_NUM_ETT ZBEE_ZCL_PRESS_MEAS_NUM_GENERIC_ETT /* Attributes */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MEASURED_VALUE 0x0000 /* Measured Value */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_MEASURED_VALUE 0x0001 /* Min Measured Value */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_MEASURED_VALUE 0x0002 /* Max Measured Value */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_TOLERANCE 0x0003 /* Tolerance */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALED_VALUE 0x0010 /* Scaled Value */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_SCALED_VALUE 0x0011 /* Min Scaled Value */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_SCALED_VALUE 0x0012 /* Max Scaled Value */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALED_TOLERANCE 0x0013 /* Scaled Tolerance */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALE 0x0014 /* Scale */ /* Server Commands Received - None */ /* Server Commands Generated - None */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_INVALID_VALUE 0x8000 /* Invalid Value */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_LO_VALUE 0x8001 /* Minimum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_HI_VALUE 0x7ffe /* Minimum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_LO_VALUE 0x8002 /* Maximum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_HI_VALUE 0x7fff /* Maximum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_TOL_LO_VALUE 0x0000 /* Tolerance (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_TOL_HI_VALUE 0x0800 /* Tolerance (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALE_LO_VALUE 0x81 /* Scale (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALE_HI_VALUE 0x7f /* Scale (Low Bound) */ /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_press_meas(void); void proto_reg_handoff_zbee_zcl_press_meas(void); /* Command Dissector Helpers */ static void dissect_zcl_press_meas_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); /* Private functions prototype */ static void decode_press_meas_value (char *s, int16_t value); static void decode_press_meas_min_value (char *s, int16_t value); static void decode_press_meas_max_value (char *s, int16_t value); static void decode_press_meas_tolerance (char *s, uint16_t value); /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_press_meas; static int hf_zbee_zcl_press_meas_attr_id; static int hf_zbee_zcl_press_meas_measured_value; static int hf_zbee_zcl_press_meas_min_measured_value; static int hf_zbee_zcl_press_meas_max_measured_value; static int hf_zbee_zcl_press_meas_tolerance; static int hf_zbee_zcl_press_meas_scaled_value; static int hf_zbee_zcl_press_meas_min_scaled_value; static int hf_zbee_zcl_press_meas_max_scaled_value; static int hf_zbee_zcl_press_meas_scaled_tolerance; static int hf_zbee_zcl_press_meas_scale; /* Initialize the subtree pointers */ static int ett_zbee_zcl_press_meas; /* Attributes */ static const value_string zbee_zcl_press_meas_attr_names[] = { { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MEASURED_VALUE, "Measured Value" }, { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_MEASURED_VALUE, "Min Measured Value" }, { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_MEASURED_VALUE, "Max Measured Value" }, { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_TOLERANCE, "Tolerance" }, { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALED_VALUE, "Scaled Value" }, { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_SCALED_VALUE, "Min Scaled Value" }, { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_SCALED_VALUE, "Max Scaled Value" }, { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALED_TOLERANCE, "Scaled Tolerance" }, { ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALE, "Scale" }, { 0, NULL } }; /*************************/ /* Function Bodies */ /*************************/ /** *ZigBee ZCL Pressure Measurement cluster dissector for wireshark. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ static int dissect_zbee_zcl_press_meas(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_) { return tvb_captured_length(tvb); } /*dissect_zbee_zcl_press_meas*/ /** *This function is called by ZCL foundation dissector in order to decode * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset pointer to buffer offset *@param attr_id attribute identifier *@param data_type attribute data type *@param client_attr ZCL client */ static void dissect_zcl_press_meas_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr) { /* Dissect attribute data type and data */ switch ( attr_id ) { case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_min_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_max_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_TOLERANCE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_tolerance, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_scaled_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_SCALED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_min_scaled_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_SCALED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_max_scaled_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALED_TOLERANCE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_scaled_tolerance, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_PRESS_MEAS_SCALE: proto_tree_add_item(tree, hf_zbee_zcl_press_meas_scale, tvb, *offset, 1, ENC_LITTLE_ENDIAN); *offset += 1; break; default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_press_meas_attr_data*/ /** *This function decodes pressure value * *@param s string to display *@param value value to decode */ static void decode_press_meas_value(char *s, int16_t value) { if (value == (int16_t)ZBEE_ZCL_ATTR_ID_PRESS_MEAS_INVALID_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Invalid value"); if (value < (int16_t)ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_LO_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%d [kPa]", value/10, value%10); return; } /*decode_press_meas_value*/ /** *This function decodes minimum pressure value * *@param s string to display *@param value value to decode */ static void decode_press_meas_min_value(char *s, int16_t value) { if (value > (int16_t)ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MIN_HI_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%d [kPa]", value/10, value%10); return; } /*decode_press_meas_min_value*/ /** *This function decodes maximum pressure value * *@param s string to display *@param value value to decode */ static void decode_press_meas_max_value(char *s, int16_t value) { if (value < (int16_t)ZBEE_ZCL_ATTR_ID_PRESS_MEAS_MAX_LO_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%d [kPa]", value/10, value%10); return; } /*decode_press_meas_max_value*/ /** *This function decodes tolerance value * *@param s string to display *@param value value to decode */ static void decode_press_meas_tolerance(char *s, uint16_t value) { if (value > (uint16_t)ZBEE_ZCL_ATTR_ID_PRESS_MEAS_TOL_HI_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%d [kPa]", value/10, value%10); return; } /*decode_press_meas_tolerance*/ /** *This function registers the ZCL Pressure Measurement dissector * */ void proto_register_zbee_zcl_press_meas(void) { static hf_register_info hf[] = { { &hf_zbee_zcl_press_meas_attr_id, { "Attribute", "zbee_zcl_meas_sensing.pressmeas.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_press_meas_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_measured_value, { "Measured Value", "zbee_zcl_meas_sensing.pressmeas.attr.value", FT_INT16, BASE_CUSTOM, CF_FUNC(decode_press_meas_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_min_measured_value, { "Min Measured Value", "zbee_zcl_meas_sensing.pressmeas.attr.value.min", FT_INT16, BASE_CUSTOM, CF_FUNC(decode_press_meas_min_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_max_measured_value, { "Max Measured Value", "zbee_zcl_meas_sensing.pressmeas.attr.value.max", FT_INT16, BASE_CUSTOM, CF_FUNC(decode_press_meas_max_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_tolerance, { "Tolerance", "zbee_zcl_meas_sensing.pressmeas.attr.tolerance", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_press_meas_tolerance), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_scaled_value, { "Scaled Value", "zbee_zcl_meas_sensing.pressmeas.attr.scaled_value", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_min_scaled_value, { "Min Scaled Value", "zbee_zcl_meas_sensing.pressmeas.attr.scaled_value.min", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_max_scaled_value, { "Max Scaled Value", "zbee_zcl_meas_sensing.pressmeas.attr.scaled_value.max", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_scaled_tolerance, { "Scaled Tolerance", "zbee_zcl_meas_sensing.pressmeas.attr.scaled_tolerance", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_press_meas_scale, { "Scale", "zbee_zcl_meas_sensing.pressmeas.attr.scale", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } } }; /* ZCL Pressure Measurement subtrees */ int *ett[] = { &ett_zbee_zcl_press_meas }; /* Register the ZigBee ZCL Pressure Measurement cluster protocol name and description */ proto_zbee_zcl_press_meas = proto_register_protocol("ZigBee ZCL Pressure Meas.", "ZCL Pressure Meas.", ZBEE_PROTOABBREV_ZCL_PRESSMEAS); proto_register_field_array(proto_zbee_zcl_press_meas, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL Pressure Measurement dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_PRESSMEAS, dissect_zbee_zcl_press_meas, proto_zbee_zcl_press_meas); } /*proto_register_zbee_zcl_press_meas*/ /** *Hands off the ZCL Pressure Measurement dissector. * */ void proto_reg_handoff_zbee_zcl_press_meas(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_PRESSMEAS, proto_zbee_zcl_press_meas, ett_zbee_zcl_press_meas, ZBEE_ZCL_CID_PRESSURE_MEASUREMENT, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_press_meas_attr_id, hf_zbee_zcl_press_meas_attr_id, -1, -1, (zbee_zcl_fn_attr_data)dissect_zcl_press_meas_attr_data ); } /*proto_reg_handoff_zbee_zcl_press_meas*/ /* ########################################################################## */ /* #### (0x0404) FLOW MEASUREMENT CLUSTER ################################### */ /* ########################################################################## */ /*************************/ /* Defines */ /*************************/ #define ZBEE_ZCL_FLOW_MEAS_NUM_GENERIC_ETT 1 #define ZBEE_ZCL_FLOW_MEAS_NUM_ETT ZBEE_ZCL_FLOW_MEAS_NUM_GENERIC_ETT /* Attributes */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MEASURED_VALUE 0x0000 /* Measured Value */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MIN_MEASURED_VALUE 0x0001 /* Min Measured Value */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MAX_MEASURED_VALUE 0x0002 /* Max Measured Value */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_TOLERANCE 0x0003 /* Tolerance */ /* Server Commands Received - None */ /* Server Commands Generated - None */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_TOO_LOW_VALUE 0x0000 /* Too Low Value */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_INVALID_VALUE 0xffff /* Invalid Value */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MIN_LO_VALUE 0x0000 /* Minimum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MIN_HI_VALUE 0xfffd /* Minimum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MAX_LO_VALUE 0x0001 /* Maximum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MAX_HI_VALUE 0xfffe /* Maximum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_TOL_LO_VALUE 0x0000 /* Tolerance (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_FLOW_MEAS_TOL_HI_VALUE 0x0800 /* Tolerance (Low Bound) */ /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_flow_meas(void); void proto_reg_handoff_zbee_zcl_flow_meas(void); /* Command Dissector Helpers */ static void dissect_zcl_flow_meas_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); /* Private functions prototype */ static void decode_flow_meas_value (char *s, uint16_t value); static void decode_flow_meas_min_value (char *s, uint16_t value); static void decode_flow_meas_max_value (char *s, uint16_t value); static void decode_flow_meas_tolerance (char *s, uint16_t value); /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_flow_meas; static int hf_zbee_zcl_flow_meas_attr_id; static int hf_zbee_zcl_flow_meas_measured_value; static int hf_zbee_zcl_flow_meas_min_measured_value; static int hf_zbee_zcl_flow_meas_max_measured_value; static int hf_zbee_zcl_flow_meas_tolerance; /* Initialize the subtree pointers */ static int ett_zbee_zcl_flow_meas; /* Attributes */ static const value_string zbee_zcl_flow_meas_attr_names[] = { { ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MEASURED_VALUE, "Measured Value" }, { ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MIN_MEASURED_VALUE, "Min Measured Value" }, { ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MAX_MEASURED_VALUE, "Max Measured Value" }, { ZBEE_ZCL_ATTR_ID_FLOW_MEAS_TOLERANCE, "Tolerance" }, { 0, NULL } }; /*************************/ /* Function Bodies */ /*************************/ /** *ZigBee ZCL Flow Measurement cluster dissector for wireshark. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ static int dissect_zbee_zcl_flow_meas(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_) { return tvb_captured_length(tvb); } /*dissect_zbee_zcl_flow_meas*/ /** *This function is called by ZCL foundation dissector in order to decode * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset pointer to buffer offset *@param attr_id attribute identifier *@param data_type attribute data type *@param client_attr ZCL client */ static void dissect_zcl_flow_meas_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr) { /* Dissect attribute data type and data */ switch ( attr_id ) { case ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_flow_meas_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MIN_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_flow_meas_min_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MAX_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_flow_meas_max_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_FLOW_MEAS_TOLERANCE: proto_tree_add_item(tree, hf_zbee_zcl_flow_meas_tolerance, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_flow_meas_attr_data*/ /** *This function decodes flow value * *@param s string to display *@param value value to decode */ static void decode_flow_meas_value(char *s, uint16_t value) { if (value == ZBEE_ZCL_ATTR_ID_FLOW_MEAS_TOO_LOW_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Value too low to be measured"); else if (value == ZBEE_ZCL_ATTR_ID_FLOW_MEAS_INVALID_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Invalid value"); else /* calculate flow value from measured value according to doc 07-5123-04 */ snprintf(s, ITEM_LABEL_LENGTH, "%d (=%f [m^3/h])", value, value/10.0); return; } /*decode_flow_meas_value*/ /** *This function decodes minimum flow value * *@param s string to display *@param value value to decode */ static void decode_flow_meas_min_value(char *s, uint16_t value) { if ( /*(value < ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MIN_LO_VALUE) ||*/ (value > ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MIN_HI_VALUE) ) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d (=%f [m^3/h])", value, value/10.0); return; } /*decode_flow_meas_min_value*/ /** *This function decodes maximum flow value * *@param s string to display *@param value value to decode */ static void decode_flow_meas_max_value(char *s, uint16_t value) { if ( (value < ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MAX_LO_VALUE) || (value > ZBEE_ZCL_ATTR_ID_FLOW_MEAS_MAX_HI_VALUE) ) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d (=%f [m^3/h])", value, value/10.0); return; } /*decode_flow_meas_max_value*/ /** *This function decodes tolerance value * *@param s string to display *@param value value to decode */ static void decode_flow_meas_tolerance(char *s, uint16_t value) { if (value > ZBEE_ZCL_ATTR_ID_FLOW_MEAS_TOL_HI_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d", value); return; } /*decode_flow_meas_tolerance*/ /** *This function registers the ZCL Flow Measurement dissector * */ void proto_register_zbee_zcl_flow_meas(void) { static hf_register_info hf[] = { { &hf_zbee_zcl_flow_meas_attr_id, { "Attribute", "zbee_zcl_meas_sensing.flowmeas.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_flow_meas_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_flow_meas_measured_value, { "Measured Value", "zbee_zcl_meas_sensing.flowmeas.attr.value", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_flow_meas_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_flow_meas_min_measured_value, { "Min Measured Value", "zbee_zcl_meas_sensing.flowmeas.attr.value.min", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_flow_meas_min_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_flow_meas_max_measured_value, { "Max Measured Value", "zbee_zcl_meas_sensing.flowmeas.attr.value.max", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_flow_meas_max_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_flow_meas_tolerance, { "Tolerance", "zbee_zcl_meas_sensing.flowmeas.attr.tolerance", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_flow_meas_tolerance), 0x0, NULL, HFILL } } }; /* ZCL Flow Measurement subtrees */ int *ett[] = { &ett_zbee_zcl_flow_meas }; /* Register the ZigBee ZCL Flow Measurement cluster protocol name and description */ proto_zbee_zcl_flow_meas = proto_register_protocol("ZigBee ZCL Flow Meas.", "ZCL Flow Meas.", ZBEE_PROTOABBREV_ZCL_FLOWMEAS); proto_register_field_array(proto_zbee_zcl_flow_meas, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL Flow Measurement dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_FLOWMEAS, dissect_zbee_zcl_flow_meas, proto_zbee_zcl_flow_meas); } /*proto_register_zbee_zcl_flow_meas*/ /** *Hands off the ZCL Flow Measurement dissector. * */ void proto_reg_handoff_zbee_zcl_flow_meas(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_FLOWMEAS, proto_zbee_zcl_flow_meas, ett_zbee_zcl_flow_meas, ZBEE_ZCL_CID_FLOW_MEASUREMENT, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_flow_meas_attr_id, hf_zbee_zcl_flow_meas_attr_id, -1, -1, (zbee_zcl_fn_attr_data)dissect_zcl_flow_meas_attr_data ); } /*proto_reg_handoff_zbee_zcl_flow_meas*/ /* ########################################################################## */ /* #### (0x0405) RELATIVE HUMIDITY MEASUREMENT CLUSTER ###################### */ /* ########################################################################## */ /*************************/ /* Defines */ /*************************/ #define ZBEE_ZCL_RELHUM_MEAS_NUM_GENERIC_ETT 1 #define ZBEE_ZCL_RELHUM_MEAS_NUM_ETT ZBEE_ZCL_RELHUM_MEAS_NUM_GENERIC_ETT /* Attributes */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MEASURED_VALUE 0x0000 /* Measured Value */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MIN_MEASURED_VALUE 0x0001 /* Min Measured Value */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MAX_MEASURED_VALUE 0x0002 /* Max Measured Value */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_TOLERANCE 0x0003 /* Tolerance */ /* Server Commands Received - None */ /* Server Commands Generated - None */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_INVALID_VALUE 0xffff /* Invalid Value */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MIN_LO_VALUE 0x0000 /* Minimum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MIN_HI_VALUE 0x270f /* Minimum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MAX_LO_VALUE 0x0000 /* Maximum Value (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MAX_HI_VALUE 0x2710 /* Maximum Value (High Bound) */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_TOL_LO_VALUE 0x0000 /* Tolerance (Low Bound) */ #define ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_TOL_HI_VALUE 0x0800 /* Tolerance (Low Bound) */ /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_relhum_meas(void); void proto_reg_handoff_zbee_zcl_relhum_meas(void); /* Command Dissector Helpers */ static void dissect_zcl_relhum_meas_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); /* Private functions prototype */ static void decode_relhum_meas_value (char *s, uint16_t value); static void decode_relhum_meas_min_value (char *s, uint16_t value); static void decode_relhum_meas_max_value (char *s, uint16_t value); static void decode_relhum_meas_tolerance (char *s, uint16_t value); /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_relhum_meas; static int hf_zbee_zcl_relhum_meas_attr_id; static int hf_zbee_zcl_relhum_meas_measured_value; static int hf_zbee_zcl_relhum_meas_min_measured_value; static int hf_zbee_zcl_relhum_meas_max_measured_value; static int hf_zbee_zcl_relhum_meas_tolerance; /* Initialize the subtree pointers */ static int ett_zbee_zcl_relhum_meas; /* Attributes */ static const value_string zbee_zcl_relhum_meas_attr_names[] = { { ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MEASURED_VALUE, "Measured Value" }, { ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MIN_MEASURED_VALUE, "Min Measured Value" }, { ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MAX_MEASURED_VALUE, "Max Measured Value" }, { ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_TOLERANCE, "Tolerance" }, { 0, NULL } }; /*************************/ /* Function Bodies */ /*************************/ /** *ZigBee ZCL Relative Humidity Measurement cluster dissector for wireshark. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ static int dissect_zbee_zcl_relhum_meas(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_) { return tvb_captured_length(tvb); } /*dissect_zbee_zcl_relhum_meas*/ /** *This function is called by ZCL foundation dissector in order to decode * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset pointer to buffer offset *@param attr_id attribute identifier *@param data_type attribute data type *@param client_attr ZCL client */ static void dissect_zcl_relhum_meas_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr) { /* Dissect attribute data type and data */ switch ( attr_id ) { case ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_relhum_meas_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MIN_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_relhum_meas_min_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MAX_MEASURED_VALUE: proto_tree_add_item(tree, hf_zbee_zcl_relhum_meas_max_measured_value, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_TOLERANCE: proto_tree_add_item(tree, hf_zbee_zcl_relhum_meas_tolerance, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_relhum_meas_attr_data*/ /** *This function decodes relative humidity value * *@param s string to display *@param value value to decode */ static void decode_relhum_meas_value(char *s, uint16_t value) { if (value == ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_INVALID_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Invalid value"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%02d [%%]", value/100, value%100); return; } /*decode_relhum_meas_value*/ /** *This function decodes minimum relative humidity value * *@param s string to display *@param value value to decode */ static void decode_relhum_meas_min_value(char *s, uint16_t value) { if (value > ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MIN_HI_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%02d [%%]", value/100, value%100); return; } /*decode_relhum_meas_min_value*/ /** *This function decodes maximum relative humidity value * *@param s string to display *@param value value to decode */ static void decode_relhum_meas_max_value(char *s, uint16_t value) { if (value > ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_MAX_HI_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%02d [%%]", value/100, value%100); return; } /*decode_relhum_meas_max_value*/ /** *This function decodes tolerance value * *@param s string to display *@param value value to decode */ static void decode_relhum_meas_tolerance(char *s, uint16_t value) { if (value > ZBEE_ZCL_ATTR_ID_RELHUM_MEAS_TOL_HI_VALUE) snprintf(s, ITEM_LABEL_LENGTH, "Out of range"); else snprintf(s, ITEM_LABEL_LENGTH, "%d.%02d [%%]", value/100, value%100); return; } /*decode_relhum_meas_tolerance*/ /** *This function registers the ZCL Relative Humidity Measurement dissector * */ void proto_register_zbee_zcl_relhum_meas(void) { static hf_register_info hf[] = { { &hf_zbee_zcl_relhum_meas_attr_id, { "Attribute", "zbee_zcl_meas_sensing.relhummeas.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_relhum_meas_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_relhum_meas_measured_value, { "Measured Value", "zbee_zcl_meas_sensing.relhummeas.attr.value", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_relhum_meas_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_relhum_meas_min_measured_value, { "Min Measured Value", "zbee_zcl_meas_sensing.relhummeas.attr.value.min", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_relhum_meas_min_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_relhum_meas_max_measured_value, { "Max Measured Value", "zbee_zcl_meas_sensing.relhummeas.attr.value.max", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_relhum_meas_max_value), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_relhum_meas_tolerance, { "Tolerance", "zbee_zcl_meas_sensing.relhummeas.attr.tolerance", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_relhum_meas_tolerance), 0x0, NULL, HFILL } } }; /* ZCL Relative Humidity Measurement subtrees */ int *ett[] = { &ett_zbee_zcl_relhum_meas }; /* Register the ZigBee ZCL Relative Humidity Measurement cluster protocol name and description */ proto_zbee_zcl_relhum_meas = proto_register_protocol("ZigBee ZCL Rel. Humidity Meas.", "ZCL Relative Humidity Meas.", ZBEE_PROTOABBREV_ZCL_RELHUMMEAS); proto_register_field_array(proto_zbee_zcl_relhum_meas, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL Relative Humidity Measurement dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_RELHUMMEAS, dissect_zbee_zcl_relhum_meas, proto_zbee_zcl_relhum_meas); } /*proto_register_zbee_zcl_relhum_meas*/ /** *Hands off the ZCL Relative Humidity Measurement dissector. * */ void proto_reg_handoff_zbee_zcl_relhum_meas(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_RELHUMMEAS, proto_zbee_zcl_relhum_meas, ett_zbee_zcl_relhum_meas, ZBEE_ZCL_CID_REL_HUMIDITY_MEASUREMENT, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_relhum_meas_attr_id, hf_zbee_zcl_relhum_meas_attr_id, -1, -1, (zbee_zcl_fn_attr_data)dissect_zcl_relhum_meas_attr_data ); } /*proto_reg_handoff_zbee_zcl_relhum_meas*/ /* ########################################################################## */ /* #### (0x0406) OCCUPANCY SENSING CLUSTER ################################## */ /* ########################################################################## */ /*************************/ /* Defines */ /*************************/ #define ZBEE_ZCL_OCC_SEN_NUM_ETT 2 /* Attributes */ #define ZBEE_ZCL_ATTR_ID_OCC_SEN_OCCUPANCY 0x0000 /* Occupancy */ #define ZBEE_ZCL_ATTR_ID_OCC_SEN_OCC_SENSOR_TYPE 0x0001 /* Occupancy Sensor Type */ #define ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_OCC_TO_UNOCC_DELAY 0x0010 /* PIR Occupied to Unoccupied Delay */ #define ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_UNOCC_TO_OCC_DELAY 0x0011 /* PIR Unoccupied to Occupied Delay */ #define ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_UNOCC_TO_OCC_THOLD 0x0012 /* PIR Unoccupied to Occupied Threshold */ #define ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_OCC_TO_UNOCC_DELAY 0x0020 /* Ultrasonic Occupied to Unoccupied Threshold */ #define ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_UNOCC_TO_OCC_DELAY 0x0021 /* Ultrasonic Unoccupied to Occupied Delay */ #define ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_UNOCC_TO_OCC_THOLD 0x0022 /* Ultrasonic Unoccupied to Occupied Threshold */ /* Server Commands Received - None */ /* Server Commands Generated - None */ /* Occupancy Mask fields */ #define ZBEE_ZCL_OCCUPANCY_SENSED_OCC 0x01 /* Sensed Occupancy */ /* Occupancy Sensor Type */ #define ZBEE_ZCL_OCC_SENSOR_TYPE_PIR 0x00 /* PIR */ #define ZBEE_ZCL_OCC_SENSOR_TYPE_USONIC 0x01 /* Ultrasonic */ #define ZBEE_ZCL_OCC_SENSOR_TYPE_PIR_AND_USONIC 0x02 /* PIR and Ultrasonic */ /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_occ_sen(void); void proto_reg_handoff_zbee_zcl_occ_sen(void); /* Command Dissector Helpers */ static void dissect_zcl_occ_sen_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_occ_sen; static int hf_zbee_zcl_occ_sen_attr_id; static int hf_zbee_zcl_occ_sen_occupancy; static int hf_zbee_zcl_occ_sen_occupancy_occupied; static int hf_zbee_zcl_occ_sen_occ_sensor_type; /* Initialize the subtree pointers */ static int ett_zbee_zcl_occ_sen; static int ett_zbee_zcl_occ_sen_occupancy; /* Attributes */ static const value_string zbee_zcl_occ_sen_attr_names[] = { { ZBEE_ZCL_ATTR_ID_OCC_SEN_OCCUPANCY, "Occupancy" }, { ZBEE_ZCL_ATTR_ID_OCC_SEN_OCC_SENSOR_TYPE, "Occupancy Sensor Type" }, { ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_OCC_TO_UNOCC_DELAY, "PIR Occupied to Unoccupied Delay" }, { ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_UNOCC_TO_OCC_DELAY, "PIR Unoccupied to Occupied Delay" }, { ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_UNOCC_TO_OCC_THOLD, "PIR Unoccupied to Occupied Threshold" }, { ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_OCC_TO_UNOCC_DELAY, "Ultrasonic Occupied to Unoccupied Threshold" }, { ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_UNOCC_TO_OCC_DELAY, "Ultrasonic Unoccupied to Occupied Delay" }, { ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_UNOCC_TO_OCC_THOLD, "Ultrasonic Unoccupied to Occupied Threshold" }, { 0, NULL } }; /* Occupancy Sensor types */ static const value_string zbee_zcl_occ_sen_sensor_type_names[] = { { ZBEE_ZCL_OCC_SENSOR_TYPE_PIR, "PIR" }, { ZBEE_ZCL_OCC_SENSOR_TYPE_USONIC, "Ultrasonic" }, { ZBEE_ZCL_OCC_SENSOR_TYPE_PIR_AND_USONIC, "PIR and Ultrasonic" }, { 0, NULL } }; /*************************/ /* Function Bodies */ /*************************/ /** *ZigBee ZCL Occupancy Sensing cluster dissector for wireshark. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ static int dissect_zbee_zcl_occ_sen(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_) { return tvb_captured_length(tvb); } /*dissect_zbee_zcl_occ_sen*/ /** *This function is called by ZCL foundation dissector in order to decode * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset pointer to buffer offset *@param attr_id attribute identifier *@param data_type attribute data type *@param client_attr ZCL client */ static void dissect_zcl_occ_sen_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr) { static int * const occupancy[] = { &hf_zbee_zcl_occ_sen_occupancy_occupied, NULL }; /* Dissect attribute data type and data */ switch ( attr_id ) { case ZBEE_ZCL_ATTR_ID_OCC_SEN_OCCUPANCY: proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_occ_sen_occupancy, ett_zbee_zcl_occ_sen_occupancy, occupancy, ENC_LITTLE_ENDIAN); *offset += 1; break; case ZBEE_ZCL_ATTR_ID_OCC_SEN_OCC_SENSOR_TYPE: proto_tree_add_item(tree, hf_zbee_zcl_occ_sen_occ_sensor_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN); *offset += 1; break; case ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_OCC_TO_UNOCC_DELAY: case ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_UNOCC_TO_OCC_DELAY: case ZBEE_ZCL_ATTR_ID_OCC_SEN_PIR_UNOCC_TO_OCC_THOLD: case ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_OCC_TO_UNOCC_DELAY: case ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_UNOCC_TO_OCC_DELAY: case ZBEE_ZCL_ATTR_ID_OCC_SEN_USONIC_UNOCC_TO_OCC_THOLD: default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_occ_sen_attr_data*/ /** *This function registers the ZCL Occupancy Sensing dissector * */ void proto_register_zbee_zcl_occ_sen(void) { static hf_register_info hf[] = { { &hf_zbee_zcl_occ_sen_attr_id, { "Attribute", "zbee_zcl_meas_sensing.occsen.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_occ_sen_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_occ_sen_occupancy, { "Occupancy", "zbee_zcl_meas_sensing.occsen.attr.occupancy", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_occ_sen_occupancy_occupied, { "Occupied", "zbee_zcl_meas_sensing.occsen.attr.occupancy_occupied", FT_BOOLEAN, 8, NULL, ZBEE_ZCL_OCCUPANCY_SENSED_OCC, NULL, HFILL } }, { &hf_zbee_zcl_occ_sen_occ_sensor_type, { "Occupancy Sensor Type", "zbee_zcl_meas_sensing.occsen.attr.occ_sensor_type", FT_UINT8, BASE_HEX, VALS(zbee_zcl_occ_sen_sensor_type_names), 0x0, NULL, HFILL } } }; /* ZCL Occupancy Sensing subtrees */ static int *ett[ZBEE_ZCL_OCC_SEN_NUM_ETT]; ett[0] = &ett_zbee_zcl_occ_sen; ett[1] = &ett_zbee_zcl_occ_sen_occupancy; /* Register the ZigBee ZCL Occupancy Sensing cluster protocol name and description */ proto_zbee_zcl_occ_sen = proto_register_protocol("ZigBee ZCL Occupancy Sensing", "ZCL Occupancy Sensing", ZBEE_PROTOABBREV_ZCL_OCCSEN); proto_register_field_array(proto_zbee_zcl_occ_sen, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL Occupancy Sensing dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_OCCSEN, dissect_zbee_zcl_occ_sen, proto_zbee_zcl_occ_sen); } /*proto_register_zbee_zcl_occ_sen*/ /** *Hands off the ZCL Occupancy Sensing dissector. * */ void proto_reg_handoff_zbee_zcl_occ_sen(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_OCCSEN, proto_zbee_zcl_occ_sen, ett_zbee_zcl_occ_sen, ZBEE_ZCL_CID_OCCUPANCY_SENSING, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_occ_sen_attr_id, hf_zbee_zcl_occ_sen_attr_id, -1, -1, (zbee_zcl_fn_attr_data)dissect_zcl_occ_sen_attr_data ); } /*proto_reg_handoff_zbee_zcl_occ_sen*/ /* ########################################################################## */ /* #### (0x0b04) ELECTRICAL MEASUREMENT CLUSTER ############################# */ /* ########################################################################## */ /*************************/ /* Defines */ /*************************/ #define ZBEE_ZCL_ELEC_MES_NUM_ETT 1 /* Attributes */ #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASUREMENT_TYPE 0x0000 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE 0x0100 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_MIN 0x0101 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_MAX 0x0102 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT 0x0103 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_MIN 0x0104 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_MAX 0x0105 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER 0x0106 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER_MIN 0x0107 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER_MAX 0x0108 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_MULTIPLIER 0x0200 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_DIVISOR 0x0201 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_MULTIPLIER 0x0202 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_DIVISOR 0x0203 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER_MULTIPLIER 0x0204 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER_DIVISOR 0x0205 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY 0x0300 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY_MIN 0x0301 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY_MAX 0x0302 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_NEUTRAL_CURRENT 0x0303 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_TOTAL_ACTIVE_POWER 0x0304 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_TOTAL_REACTIVE_POWER 0x0305 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_TOTAL_APPARENT_POWER 0x0306 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_1ST_HARMONIC_CURRENT 0x0307 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_3RD_HARMONIC_CURRENT 0x0308 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_5TH_HARMONIC_CURRENT 0x0309 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_7TH_HARMONIC_CURRENT 0x030A #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_9TH_HARMONIC_CURRENT 0x030B #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_11TH_HARMONIC_CURRENT 0x030C #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_1ST_HARMONIC_CURRENT 0x030D #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_3RD_HARMONIC_CURRENT 0x030E #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_5TH_HARMONIC_CURRENT 0x030F #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_7TH_HARMONIC_CURRENT 0x0310 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_9TH_HARMONIC_CURRENT 0x0311 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_11TH_HARMONIC_CURRENT 0x0312 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY_MULTIPLIER 0x0400 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY_DIVISOR 0x0401 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_MULTIPLIER 0x0402 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_DIVISOR 0x0403 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_HARMONIC_CURRENT_MULTIPLIER 0x0404 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_PHASE_HARMONIC_CURRENT_MULTIPLIER 0x0405 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_LINE_CURRENT 0x0501 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_CURRENT 0x0502 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_CURRENT 0x0503 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE 0x0505 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MIN 0x0506 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MAX 0x0507 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT 0x0508 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MIN 0x0509 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MAX 0x050A #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER 0x050B #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MIN 0x050C #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MAX 0x050D #define ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_POWER 0x050E #define ZBEE_ZCL_ATTR_ID_ELEC_MES_APPARENT_POWER 0x050F #define ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_FACTOR 0x0510 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_VOLTAGE_MEASUREMENT_PERIOD 0x0511 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_OVER_VOLTAGE_COUNTER 0x0512 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_UNDER_VOLTAGE_COUNTER 0x0513 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_OVER_VOLTAGE_PERIOD 0x0514 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_UNDER_VOLTAGE_PERIOD 0x0515 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SAG_PERIOD 0x0516 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SWELL_PERIOD 0x0517 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_VOLTAGE_MULTIPLIER 0x0600 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_VOLTAGE_DIVISOR 0x0601 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_CURRENT_MULTIPLIER 0x0602 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_CURRENT_DIVISOR 0x0603 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_POWER_MULTIPLIER 0x0604 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_POWER_DIVISOR 0x0605 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_OVERLOAD_ALARMS_MASK 0x0700 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_OVERLOAD 0x0701 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_OVERLOAD 0x0702 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_ALARMS_MASK 0x0800 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_VOLTAGE_OVERLOAD 0x0801 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_CURRENT_OVERLOAD 0x0802 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_ACTIVE_POWER_OVERLOAD 0x0803 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_REACTIVE_POWER_OVERLOAD 0x0804 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_OVER_VOLTAGE 0x0805 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_UNDER_VOLTAGE 0x0806 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_OVER_VOLTAGE 0x0807 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_UNDER_VOLTAGE 0x0808 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SAG 0x0809 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SWELL 0x080A #define ZBEE_ZCL_ATTR_ID_ELEC_MES_LINE_CURRENT_PH_B 0x0901 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_CURRENT_PH_B 0x0902 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_CURRENT_PH_B 0x0903 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_PH_B 0x0905 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MIN_PH_B 0x0906 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MAX_PH_B 0x0907 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_PH_B 0x0908 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MIN_PH_B 0x0909 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MAX_PH_B 0x090A #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_PH_B 0x090B #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MIN_PH_B 0x090C #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MAX_PH_B 0x090D #define ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_POWER_PH_B 0x090E #define ZBEE_ZCL_ATTR_ID_ELEC_MES_APPARENT_POWER_PH_B 0x090F #define ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_FACTOR_PH_B 0x0910 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_VOLTAGE_MEASUREMENT_PERIOD_PH_B 0x0911 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_OVER_VOLTAGE_COUNTER_PH_B 0x0912 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_UNDER_VOLTAGE_COUNTER_PH_B 0x0913 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_OVER_VOLTAGE_PERIOD_PH_B 0x0914 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_UNDER_VOLTAGE_PERIOD_PH_B 0x0915 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SAG_PERIOD_PH_B 0x0916 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SWELL_PERIOD_PH_B 0x0917 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_LINE_CURRENT_PH_C 0x0A01 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_CURRENT_PH_C 0x0A03 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_PH_C 0x0A05 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MIN_PH_C 0x0A06 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MAX_PH_C 0x0A07 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_PH_C 0x0A08 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MIN_PH_C 0x0A09 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MAX_PH_C 0x0A0A #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_PH_C 0x0A0B #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MIN_PH_C 0x0A0C #define ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MAX_PH_C 0x0A0D #define ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_POWER_PH_C 0x0A0E #define ZBEE_ZCL_ATTR_ID_ELEC_MES_APPARENT_POWER_PH_C 0x0A0F #define ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_FACTOR_PH_C 0x0A10 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_VOLTAGE_MEASUREMENT_PERIOD_PH_C 0x0A11 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_OVER_VOLTAGE_COUNTER_PH_C 0x0A12 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_UNDER_VOLTAGE_COUNTER_PH_C 0x0A13 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_OVER_VOLTAGE_PERIOD_PH_C 0x0A14 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_UNDER_VOLTAGE_PERIOD_PH_C 0x0A15 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SAG_PERIOD_PH_C 0x0A16 #define ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SWELL_PERIOD_PH_C 0x0A17 /* Server Commands Received */ #define ZBEE_ZCL_CMD_GET_PROFILE_INFO 0x00 #define ZBEE_ZCL_CMD_GET_MEASUREMENT_PROFILE_INFO 0x01 /* Server Commands Generated */ #define ZBEE_ZCL_CMD_GET_PROFILE_INFO_RESPONSE 0x00 #define ZBEE_ZCL_CMD_GET_MEASUREMENT_PROFILE_INFO_RESPONSE 0x01 /* Profile Interval Period */ #define ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_DAILY 0 #define ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_60_MINUTES 1 #define ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_30_MINUTES 2 #define ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_15_MINUTES 3 #define ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_10_MINUTES 4 #define ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_7_5_MINUTES 5 #define ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_5_MINUTES 6 #define ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_2_5_MINUTES 7 /* List of Status Valid Values */ #define ZBEE_ZCL_ELEC_MES_STATUS_SUCCESS 0x00 #define ZBEE_ZCL_ELEC_MES_STATUS_ATTRIBUTE_PROFILE_NOT_SUPPORTED 0x01 #define ZBEE_ZCL_ELEC_MES_STATUS_INVALID_START_TIME 0x02 #define ZBEE_ZCL_ELEC_MES_STATUS_MORE_INTERVALS_REQUESTED_THAN_CAN_BE_RET 0x03 #define ZBEE_ZCL_ELEC_MES_STATUS_NO_INTERVALS_AVAILABLE_FOR_THE_REQ_TIME 0x04 /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_elec_mes(void); void proto_reg_handoff_zbee_zcl_elec_mes(void); /* Command Dissector Helpers */ static void dissect_zcl_elec_mes_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); static void dissect_zcl_elec_mes_get_measurement_profile_info (tvbuff_t *tvb, proto_tree *tree, unsigned *offset); static void dissect_zcl_elec_mes_get_profile_info_response (tvbuff_t *tvb, proto_tree *tree, unsigned *offset); static void dissect_zcl_elec_mes_get_measurement_profile_info_response (tvbuff_t *tvb, proto_tree *tree, unsigned *offset); /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_elec_mes; static int hf_zbee_zcl_elec_mes_srv_tx_cmd_id; static int hf_zbee_zcl_elec_mes_srv_rx_cmd_id; static int hf_zbee_zcl_elec_mes_attr_id; static int hf_zbee_zcl_elec_mes_start_time; static int hf_zbee_zcl_elec_mes_number_of_intervals; static int hf_zbee_zcl_elec_mes_profile_count; static int hf_zbee_zcl_elec_mes_profile_interval_period; static int hf_zbee_zcl_elec_mes_max_number_of_intervals; static int hf_zbee_zcl_elec_mes_status; static int hf_zbee_zcl_elec_mes_number_of_intervals_delivered; static int hf_zbee_zcl_elec_mes_intervals; /* Initialize the subtree pointers */ static int ett_zbee_zcl_elec_mes; /* Attributes */ static const value_string zbee_zcl_elec_mes_attr_names[] = { { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASUREMENT_TYPE, "Measurement Type" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE, "DC Voltage" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_MIN, "DC Voltage Min" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_MAX, "DC Voltage Max" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT, "DC Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_MIN, "DC Current Min" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_MAX, "DC Current Max" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER, "DC Power" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER_MIN, "DC Power Min" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER_MAX, "DC Power Max" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_MULTIPLIER, "DC Voltage Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_DIVISOR, "DC Voltage Divisor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_MULTIPLIER, "DC Current Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_DIVISOR, "DC Current Divisor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER_MULTIPLIER, "DC Power Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_POWER_DIVISOR, "DC Power Divisor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY, "AC Frequency" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY_MIN, "AC Frequency Min" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY_MAX, "AC Frequency Max" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_NEUTRAL_CURRENT, "Neutral Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_TOTAL_ACTIVE_POWER, "Total Active Power" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_TOTAL_REACTIVE_POWER, "Total Reactive Power" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_TOTAL_APPARENT_POWER, "Total Apparent Power" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_1ST_HARMONIC_CURRENT, "Measured 1st Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_3RD_HARMONIC_CURRENT, "Measured 3rd Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_5TH_HARMONIC_CURRENT, "Measured 5th Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_7TH_HARMONIC_CURRENT, "Measured 7th Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_9TH_HARMONIC_CURRENT, "Measured 9th Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_11TH_HARMONIC_CURRENT, "Measured 11th Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_1ST_HARMONIC_CURRENT, "Measured Phase 1st Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_3RD_HARMONIC_CURRENT, "Measured Phase 3rd Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_5TH_HARMONIC_CURRENT, "Measured Phase 5th Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_7TH_HARMONIC_CURRENT, "Measured Phase 7th Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_9TH_HARMONIC_CURRENT, "Measured Phase 9th Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_MEASURED_PHASE_11TH_HARMONIC_CURRENT, "Measured Phase 11th Harmonic Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY_MULTIPLIER, "AC Frequency Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_FREQUENCY_DIVISOR, "AC Frequency Divisor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_MULTIPLIER, "Power Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_DIVISOR, "Power Divisor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_HARMONIC_CURRENT_MULTIPLIER, "Harmonic Current Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_PHASE_HARMONIC_CURRENT_MULTIPLIER, "Phase Harmonic Current Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_LINE_CURRENT, "Line Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_CURRENT, "Active Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_CURRENT, "Reactive Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE, "RMS Voltage" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MIN, "RMS Voltage Min" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MAX, "RMS Voltage Max" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT, "RMS Current" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MIN, "RMS Current Min" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MAX, "RMS Current Max" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER, "Active Power" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MIN, "Active Power Min" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MAX, "Active Power Max" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_POWER, "Reactive Power" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_APPARENT_POWER, "Apparent Power" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_FACTOR, "Power Factor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_VOLTAGE_MEASUREMENT_PERIOD, "Average RMS Voltage Measurement Period" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_OVER_VOLTAGE_COUNTER, "Average RMS Over Voltage Counter" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_UNDER_VOLTAGE_COUNTER, "Average RMS Under Voltage Counter" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_OVER_VOLTAGE_PERIOD, "RMS Extreme Over Voltage Period" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_UNDER_VOLTAGE_PERIOD, "RMS Extreme Under Voltage Period" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SAG_PERIOD, "RMS Voltage Sag Period" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SWELL_PERIOD, "RMS Voltage Swell Period" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_VOLTAGE_MULTIPLIER, "AC Voltage Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_VOLTAGE_DIVISOR, "AC Voltage Divisor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_CURRENT_MULTIPLIER, "AC Current Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_CURRENT_DIVISOR, "AC Current Divisor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_POWER_MULTIPLIER, "AC Power Multiplier" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_POWER_DIVISOR, "AC Power Divisor" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_OVERLOAD_ALARMS_MASK, "DC Overload Alarms Mask" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_VOLTAGE_OVERLOAD, "DC Voltage Overload" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_DC_CURRENT_OVERLOAD, "DC Current Overload" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_ALARMS_MASK, "AC Alarms Mask" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_VOLTAGE_OVERLOAD, "AC Voltage Overload" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_CURRENT_OVERLOAD, "AC Current Overload" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_ACTIVE_POWER_OVERLOAD, "AC Active Power Overload" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AC_REACTIVE_POWER_OVERLOAD, "AC Reactive Power Overload" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_OVER_VOLTAGE, "Average RMS Over Voltage" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_UNDER_VOLTAGE, "Average RMS Under Voltage" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_OVER_VOLTAGE, "RMS Extreme Over Voltage" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_UNDER_VOLTAGE, "RMS Extreme Under Voltage" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SAG, "RMS Voltage Sag" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SWELL, "RMS Voltage Swell" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_LINE_CURRENT_PH_B, "Line Current Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_CURRENT_PH_B, "Active Current Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_CURRENT_PH_B, "Reactive Current Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_PH_B, "RMS Voltage Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MIN_PH_B, "RMS Voltage Min Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MAX_PH_B, "RMS Voltage Max Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_PH_B, "RMS Current Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MIN_PH_B, "RMS Current Min Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MAX_PH_B, "RMS Current Max Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_PH_B, "Active Power Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MIN_PH_B, "Active Power Min Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MAX_PH_B, "Active Power Max Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_POWER_PH_B, "Reactive Power Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_APPARENT_POWER_PH_B, "Apparent Power Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_FACTOR_PH_B, "Power Factor Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_VOLTAGE_MEASUREMENT_PERIOD_PH_B, "Average RMS Voltage Measurement Period Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_OVER_VOLTAGE_COUNTER_PH_B, "Average RMS Over Voltage Counter Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_UNDER_VOLTAGE_COUNTER_PH_B, "Average RMS Under Voltage Counter Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_OVER_VOLTAGE_PERIOD_PH_B, "RMS Extreme Over Voltage Period Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_UNDER_VOLTAGE_PERIOD_PH_B, "RMS Extreme Under Voltage Period Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SAG_PERIOD_PH_B, "RMS Voltage Sag Period Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SWELL_PERIOD_PH_B, "RMS Voltage Swell Period Ph B" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_LINE_CURRENT_PH_C, "Line Current Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_CURRENT_PH_C, "Reactive Current Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_PH_C, "RMS Voltage Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MIN_PH_C, "RMS Voltage Min Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_MAX_PH_C, "RMS Voltage Max Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_PH_C, "RMS Current Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MIN_PH_C, "RMS Current Min Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_CURRENT_MAX_PH_C, "RMS Current Max Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_PH_C, "Active Power Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MIN_PH_C, "Active Power Min Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_ACTIVE_POWER_MAX_PH_C, "Active Power Max Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_REACTIVE_POWER_PH_C, "Reactive Power Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_APPARENT_POWER_PH_C, "Apparent Power Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_POWER_FACTOR_PH_C, "Power Factor Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_VOLTAGE_MEASUREMENT_PERIOD_PH_C, "Average RMS Voltage Measurement Period Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_OVER_VOLTAGE_COUNTER_PH_C, "Average RMS Over Voltage Counter Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_AVERAGE_RMS_UNDER_VOLTAGE_COUNTER_PH_C, "Average RMS Under Voltage Counter Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_OVER_VOLTAGE_PERIOD_PH_C, "RMS Extreme Over Voltage Period Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_EXTREME_UNDER_VOLTAGE_PERIOD_PH_C, "RMS Extreme Under Voltage Period Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SAG_PERIOD_PH_C, "RMS Voltage Sag Period Ph C" }, { ZBEE_ZCL_ATTR_ID_ELEC_MES_RMS_VOLTAGE_SWELL_PERIOD_PH_C, "RMS Voltage Swell Period Ph C" }, { 0, NULL } }; static value_string_ext zbee_zcl_elec_mes_attr_names_ext = VALUE_STRING_EXT_INIT(zbee_zcl_elec_mes_attr_names); /* Server Commands Received */ static const value_string zbee_zcl_elec_mes_srv_rx_cmd_names[] = { { ZBEE_ZCL_CMD_GET_PROFILE_INFO, "Get Profile Info", }, { ZBEE_ZCL_CMD_GET_MEASUREMENT_PROFILE_INFO, "Get Measurement Profile", }, { 0, NULL } }; /* Server Commands Generated */ static const value_string zbee_zcl_elec_mes_srv_tx_cmd_names[] = { { ZBEE_ZCL_CMD_GET_PROFILE_INFO_RESPONSE, "Get Profile Info Response", }, { ZBEE_ZCL_CMD_GET_MEASUREMENT_PROFILE_INFO_RESPONSE, "Get Measurement Profile Response", }, { 0, NULL } }; /* Profile Interval Period */ static const value_string zbee_zcl_elec_mes_profile_interval_period_names[] = { { ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_DAILY, "Daily", }, { ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_60_MINUTES, "60 Minutes", }, { ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_30_MINUTES, "30 Minutes", }, { ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_15_MINUTES, "15 Minutes", }, { ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_10_MINUTES, "10 Minutes", }, { ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_7_5_MINUTES, "7.5 Minutes", }, { ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_5_MINUTES, "5 Minutes", }, { ZBEE_ZCL_ELEC_MES_PROFILE_INTERVAL_PERIOD_2_5_MINUTES, "2.5 Minutes", }, { 0, NULL } }; /* List of Status Valid Values */ static const value_string zbee_zcl_elec_mes_status_names[] = { { ZBEE_ZCL_ELEC_MES_STATUS_SUCCESS, "Success", }, { ZBEE_ZCL_ELEC_MES_STATUS_ATTRIBUTE_PROFILE_NOT_SUPPORTED, "Attribute Profile not supported", }, { ZBEE_ZCL_ELEC_MES_STATUS_INVALID_START_TIME, "Invalid Start Time", }, { ZBEE_ZCL_ELEC_MES_STATUS_MORE_INTERVALS_REQUESTED_THAN_CAN_BE_RET, "More intervals requested than can be returned", }, { ZBEE_ZCL_ELEC_MES_STATUS_NO_INTERVALS_AVAILABLE_FOR_THE_REQ_TIME, "No intervals available for the requested time", }, { 0, NULL } }; /*************************/ /* Function Bodies */ /*************************/ /** *ZigBee ZCL Electrical Measurement cluster dissector for wireshark. * *@param tvb pointer to buffer containing raw packet. *@param pinfo pointer to packet information fields *@param tree pointer to data tree Wireshark uses to display packet. */ static int dissect_zbee_zcl_elec_mes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { proto_tree *payload_tree; zbee_zcl_packet *zcl; unsigned offset = 0; uint8_t cmd_id; int rem_len; /* Reject the packet if data is NULL */ if (data == NULL) return 0; zcl = (zbee_zcl_packet *)data; cmd_id = zcl->cmd_id; /* Create a subtree for the ZCL Command frame, and add the command ID to it. */ if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) { /* Append the command name to the info column. */ col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u", val_to_str_const(cmd_id, zbee_zcl_elec_mes_srv_rx_cmd_names, "Unknown Command"), zcl->tran_seqno); /* Add the command ID. */ proto_tree_add_uint(tree, hf_zbee_zcl_elec_mes_srv_rx_cmd_id, tvb, offset, 1, cmd_id); /* Check is this command has a payload, than add the payload tree */ rem_len = tvb_reported_length_remaining(tvb, ++offset); if (rem_len > 0) { payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_elec_mes, NULL, "Payload"); /* Call the appropriate command dissector */ switch (cmd_id) { case ZBEE_ZCL_CMD_GET_PROFILE_INFO: /* No Payload */ break; case ZBEE_ZCL_CMD_GET_MEASUREMENT_PROFILE_INFO: dissect_zcl_elec_mes_get_measurement_profile_info(tvb, payload_tree, &offset); break; default: break; } } } else { /* ZBEE_ZCL_FCF_TO_CLIENT */ /* Append the command name to the info column. */ col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u", val_to_str_const(cmd_id, zbee_zcl_elec_mes_srv_tx_cmd_names, "Unknown Command"), zcl->tran_seqno); /* Add the command ID. */ proto_tree_add_uint(tree, hf_zbee_zcl_elec_mes_srv_tx_cmd_id, tvb, offset, 1, cmd_id); /* Check is this command has a payload, than add the payload tree */ rem_len = tvb_reported_length_remaining(tvb, ++offset); if (rem_len > 0) { payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_elec_mes, NULL, "Payload"); /* Call the appropriate command dissector */ switch (cmd_id) { case ZBEE_ZCL_CMD_GET_PROFILE_INFO_RESPONSE: dissect_zcl_elec_mes_get_profile_info_response(tvb, payload_tree, &offset); break; case ZBEE_ZCL_CMD_GET_MEASUREMENT_PROFILE_INFO_RESPONSE: dissect_zcl_elec_mes_get_measurement_profile_info_response(tvb, payload_tree, &offset); break; default: break; } } } return tvb_captured_length(tvb); } /*dissect_zbee_zcl_elec_mes*/ /** *This function is called by ZCL foundation dissector in order to decode * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset pointer to buffer offset *@param attr_id attribute identifier *@param data_type attribute data type *@param client_attr ZCL client */ static void dissect_zcl_elec_mes_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr) { /* Dissect attribute data type and data */ switch ( attr_id ) { default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_elec_mes_attr_data*/ /** *This function manages the Get Measurement Profile Info payload * *@param tvb pointer to buffer containing raw packet. *@param tree pointer to data tree Wireshark uses to display packet. *@param offset pointer to offset from caller */ static void dissect_zcl_elec_mes_get_measurement_profile_info(tvbuff_t *tvb, proto_tree *tree, unsigned *offset) { proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_attr_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_start_time, tvb, *offset, 4, ENC_TIME_ZBEE_ZCL|ENC_LITTLE_ENDIAN); *offset += 4; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_number_of_intervals, tvb, *offset, 1, ENC_NA); *offset += 1; } /** *This function manages the Get Profile Info Response payload * *@param tvb pointer to buffer containing raw packet. *@param tree pointer to data tree Wireshark uses to display packet. *@param offset pointer to offset from caller */ static void dissect_zcl_elec_mes_get_profile_info_response(tvbuff_t *tvb, proto_tree *tree, unsigned *offset) { proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_profile_count, tvb, *offset, 1, ENC_NA); *offset += 1; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_profile_interval_period, tvb, *offset, 1, ENC_NA); *offset += 1; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_max_number_of_intervals, tvb, *offset, 1, ENC_NA); *offset += 1; while (tvb_reported_length_remaining(tvb, *offset) > 0) { proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_attr_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; } } /** *This function manages the Get Measurement Profile Info Response payload * *@param tvb pointer to buffer containing raw packet. *@param tree pointer to data tree Wireshark uses to display packet. *@param offset pointer to offset from caller */ static void dissect_zcl_elec_mes_get_measurement_profile_info_response(tvbuff_t *tvb, proto_tree *tree, unsigned *offset) { unsigned rem_len; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_start_time, tvb, *offset, 4, ENC_TIME_ZBEE_ZCL|ENC_LITTLE_ENDIAN); *offset += 4; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_status, tvb, *offset, 1, ENC_NA); *offset += 1; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_profile_interval_period, tvb, *offset, 1, ENC_NA); *offset += 1; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_number_of_intervals_delivered, tvb, *offset, 1, ENC_NA); *offset += 1; proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_attr_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; rem_len = tvb_reported_length_remaining(tvb, *offset); proto_tree_add_item(tree, hf_zbee_zcl_elec_mes_intervals, tvb, *offset, rem_len, ENC_NA); *offset += rem_len; } /** *This function registers the ZCL Occupancy Sensing dissector * */ void proto_register_zbee_zcl_elec_mes(void) { static hf_register_info hf[] = { { &hf_zbee_zcl_elec_mes_srv_tx_cmd_id, { "Command", "zbee_zcl_meas_sensing.elecmes.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_elec_mes_srv_tx_cmd_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_srv_rx_cmd_id, { "Command", "zbee_zcl_meas_sensing.elecmes.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_elec_mes_srv_rx_cmd_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_attr_id, { "Attribute", "zbee_zcl_meas_sensing.elecmes.attr_id", FT_UINT16, BASE_HEX | BASE_EXT_STRING, &zbee_zcl_elec_mes_attr_names_ext, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_start_time, { "Start Time", "zbee_zcl_meas_sensing.elecmes.start_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_number_of_intervals, { "Number of Intervals", "zbee_zcl_meas_sensing.elecmes.number_of_intervals", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_profile_count, { "Profile Count", "zbee_zcl_meas_sensing.elecmes.profile_count", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_profile_interval_period, { "Profile Interval Period", "zbee_zcl_meas_sensing.elecmes.profile_interval_period", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_max_number_of_intervals, { "Max Number of Intervals", "zbee_zcl_meas_sensing.elecmes.max_number_of_intervals", FT_UINT8, BASE_DEC, VALS(zbee_zcl_elec_mes_profile_interval_period_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_status, { "Status", "zbee_zcl_meas_sensing.elecmes.status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_elec_mes_status_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_number_of_intervals_delivered, { "Number of Intervals Delivered", "zbee_zcl_meas_sensing.elecmes.number_of_intervals_delivered", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, { &hf_zbee_zcl_elec_mes_intervals, { "Intervals", "zbee_zcl_meas_sensing.elecmes.intervals", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } } }; /* ZCL Electrical Measurement subtrees */ static int *ett[ZBEE_ZCL_ELEC_MES_NUM_ETT]; ett[0] = &ett_zbee_zcl_elec_mes; /* Register the ZigBee ZCL Electrical Measurement cluster protocol name and description */ proto_zbee_zcl_elec_mes = proto_register_protocol("ZigBee ZCL Electrical Measurement", "ZCL Electrical Measurement", ZBEE_PROTOABBREV_ZCL_ELECMES); proto_register_field_array(proto_zbee_zcl_elec_mes, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL Electrical Measurement dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_ELECMES, dissect_zbee_zcl_elec_mes, proto_zbee_zcl_elec_mes); } /*proto_register_zbee_zcl_elec_mes*/ /** *Hands off the ZCL Electrical Measurement dissector. * */ void proto_reg_handoff_zbee_zcl_elec_mes(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_ELECMES, proto_zbee_zcl_elec_mes, ett_zbee_zcl_elec_mes, ZBEE_ZCL_CID_ELECTRICAL_MEASUREMENT, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_elec_mes_attr_id, -1, hf_zbee_zcl_elec_mes_srv_rx_cmd_id, hf_zbee_zcl_elec_mes_srv_tx_cmd_id, (zbee_zcl_fn_attr_data)dissect_zcl_elec_mes_attr_data ); } /*proto_reg_handoff_zbee_zcl_elec_mes*/ /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * * vi: set shiftwidth=4 tabstop=8 expandtab: * :indentSize=4:tabSize=8:noTabs=true: */