/* packet-zbee-zcl-misc.c * Dissector routines for the ZigBee ZCL SE clusters like * Messaging * 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 "packet-zbee.h" #include "packet-zbee-aps.h" #include "packet-zbee-zcl.h" /* ########################################################################## */ /* #### (0x0201) THERMOSTAT CLUSTER ######################################### */ /* ########################################################################## */ /* Cluster-specific commands and parameters */ #define ZBEE_ZCL_CSC_POLL_CONTROL_C_CIR 0x00 #define ZBEE_ZCL_CSC_POLL_CONTROL_C_FPS 0x01 #define ZBEE_ZCL_CSC_POLL_CONTROL_C_SLPI 0x02 #define ZBEE_ZCL_CSC_POLL_CONTROL_C_SSPI 0x03 #define ZBEE_ZCL_CSC_POLL_CONTROL_S_CI 0x00 #define ZBEE_ZCL_CSC_THERMOSTAT_C_CWS 0x03 #define ZBEE_ZCL_CSC_THERMOSTAT_C_GWS 0x02 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SRL 0x00 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS 0x01 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_DOW_AV 0x80 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_DOW_FR 0x20 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_DOW_MO 0x02 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_DOW_SA 0x40 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_DOW_SU 0x01 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_DOW_TH 0x10 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_DOW_TU 0x04 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_DOW_WE 0x08 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_SP_B 0x03 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_SP_C 0x02 #define ZBEE_ZCL_CSC_THERMOSTAT_C_SWS_SP_H 0x01 #define ZBEE_ZCL_CSC_THERMOSTAT_S_GWSR 0x00 #define ZBEE_ZCL_THERMOSTAT_NUM_ETT 3 /* Thermostat Information Attributes */ #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_LOCAL_TEMP 0x0000 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_OUTDOOR_TEMP 0x0001 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPANCY 0x0002 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_ABS_MIN_HEAT_SETPOINT 0x0003 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_ABS_MAX_HEAT_SETPOINT 0x0004 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_ABS_MIN_COOL_SETPOINT 0x0005 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_ABS_MAX_COOL_SETPOINT 0x0006 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_PI_COOL_DEMAND 0x0007 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_PI_HEAT_DEMAND 0x0008 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_HVAC_TYPE_CONFIG 0x0009 /* Thermostat Settings Attributes */ #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_LOCAL_TEMP_CALIBRATION 0x0010 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_COOL_SETPOINT 0x0011 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_HEAT_SETPOINT 0x0012 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_COOL_SETPOINT 0x0013 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_HEAT_SETPOINT 0x0014 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_MIN_HEAT_SETPOINT 0x0015 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_MAX_HEAT_SETPOINT 0x0016 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_MIN_COOL_SETPOINT 0x0017 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_MAX_COOL_SETPOINT 0x0018 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_MIN_SETPOINT_DEADBAND 0x0019 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_REMOTE_SENSING 0x001A #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_CONTROL_SEQUENCE 0x001B #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_SYSTEM_MODE 0x001C #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_ALARM_MASK 0x001D #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_RUNNING_MODE 0x001E /* Schedule & HVAC Relay Attributes. */ #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_START_OF_WEEK 0x0020 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_NUM_WEEKLY_TRANSITIONS 0x0021 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_NUM_DAILY_TRANSITIONS 0x0022 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_HOLD 0x0023 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_HOLD_DURATION 0x0024 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_PROGRAMMING_MODE 0x0025 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_RUNNING_STATE 0x0029 /* Setpoint Change Tracking Attributes. */ #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_CHANGE_SOURCE 0x0030 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_CHANGE_AMOUNT 0x0031 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_CHANGE_TIME 0x0032 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_SETBACK 0x0034 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_SETBACK_MIN 0x0035 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_SETBACK_MAX 0x0036 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_SETBACK 0x0037 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_SETBACK_MIN 0x0038 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_SETBACK_MAX 0x0039 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_EMERGENCY_HEAT_DELTA 0x003a /* Air Conditioning Attributes. */ #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_TYPE 0x0040 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_CAPACITY 0x0041 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_REFRIGERANT_TYPE 0x0042 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_COMPRESSOR_TYPE 0x0043 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_ERROR_CODE 0x0044 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_LOUVER_POSITION 0x0045 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_COIL_TEMPERATURE 0x0046 #define ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_CAPACITY_FORMAT 0x0047 static const value_string zbee_zcl_thermostat_attr_names[] = { { ZBEE_ZCL_ATTR_ID_THERMOSTAT_LOCAL_TEMP, "LocalTemperature" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_OUTDOOR_TEMP, "OutdoorTemperature" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPANCY, "Occupancy" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_ABS_MIN_HEAT_SETPOINT, "AbsMinHeatSetpointLimit" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_ABS_MAX_HEAT_SETPOINT, "AbsMaxHeatSetpointLimit" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_ABS_MIN_COOL_SETPOINT, "AbsMinCoolSetpointLimit" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_ABS_MAX_COOL_SETPOINT, "AbsMaxCoolSetpointLimit" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_PI_COOL_DEMAND, "PICoolingDemand" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_PI_HEAT_DEMAND, "PIHeatingDemand" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_HVAC_TYPE_CONFIG, "HVACSystemTypeConfiguration" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_LOCAL_TEMP_CALIBRATION, "LocalTemperatureCalibration" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_COOL_SETPOINT, "OccupiedCoolingSetpoint" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_HEAT_SETPOINT, "OccupiedHeatingSetpoint" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_COOL_SETPOINT, "UnoccupiedCoolingSetpoint" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_HEAT_SETPOINT, "UnoccupiedHeatingSetpoint" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_MIN_HEAT_SETPOINT, "MinHeatSetpointLimit" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_MAX_HEAT_SETPOINT, "MaxHeatSetpointLimit" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_MIN_COOL_SETPOINT, "MinCoolSetpointLimit" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_MAX_COOL_SETPOINT, "MaxCoolSetpointLimit" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_MIN_SETPOINT_DEADBAND, "MinSetpointDeadBand" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_REMOTE_SENSING, "RemoteSensing" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_CONTROL_SEQUENCE, "ControlSequenceOfOperation" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_SYSTEM_MODE, "SystemMode" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_ALARM_MASK, "AlarmMask" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_RUNNING_MODE, "ThermostatRunningMode" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_START_OF_WEEK, "StartOfWeek" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_NUM_WEEKLY_TRANSITIONS, "NumberOfWeeklyTransitions" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_NUM_DAILY_TRANSITIONS, "NumberOfDailyTransitions" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_HOLD, "TemperatureSetpointHold" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_HOLD_DURATION, "TemperatureSetpointHoldDuration" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_PROGRAMMING_MODE, "ThermostatProgrammingOperationMode" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_RUNNING_STATE, "ThermostatRunningState" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_CHANGE_SOURCE, "SetpointChangeSource" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_CHANGE_AMOUNT, "SetpointChangeAmount" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_SETPOINT_CHANGE_TIME, "SetpointChangeTime" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_SETBACK, "OccupiedSetback" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_SETBACK_MIN, "OccupiedSetbackMin" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_OCCUPIED_SETBACK_MAX, "OccupiedSetbackMax" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_SETBACK, "UnoccupiedSetback" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_SETBACK_MIN, "UnoccupiedSetbackMin" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_UNOCCUPIED_SETBACK_MAX, "UnoccupiedSetbackMax" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_EMERGENCY_HEAT_DELTA, "EmergencyHeatDelta" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_TYPE, "AcType" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_CAPACITY, "AcCapacity" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_REFRIGERANT_TYPE, "AcRefrigerantType" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_COMPRESSOR_TYPE, "AcCompressorType" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_ERROR_CODE, "AcErrorCode" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_LOUVER_POSITION, "AcLouverPosition" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_COIL_TEMPERATURE, "AcCoilTemperature" }, { ZBEE_ZCL_ATTR_ID_THERMOSTAT_AC_CAPACITY_FORMAT, "AcCapacityFormat" }, { 0, NULL } }; /* RemoteSensing bitmask. */ #define ZBEE_ZCL_THERMOSTAT_REMOTE_SENSE_LOCAL 0x01 #define ZBEE_ZCL_THERMOSTAT_REMOTE_SENSE_OUTDOOR 0x02 #define ZBEE_ZCL_THERMOSTAT_REMOTE_SENSE_OCCUPANCY 0x04 #define ZBEE_ZCL_THERMOSTAT_ALARM_INIT_FAILURE 0x01 #define ZBEE_ZCL_THERMOSTAT_ALARM_HARDWARE_FAILURE 0x02 #define ZBEE_ZCL_THERMOSTAT_ALARM_CALIBRATION_FAILURE 0x04 /* Programming operation mode bits. */ #define ZBEE_ZCL_THERMOSTAT_PROGRAM_MODE_SCHEDULE 0x01 #define ZBEE_ZCL_THERMOSTAT_PROGRAM_MODE_AUTO 0x02 #define ZBEE_ZCL_THERMOSTAT_PROGRAM_MODE_ENERGY_STAR 0x04 /* HVAC Running State bits. */ #define ZBEE_ZCL_THERMOSTAT_RUNNING_STATE_HEAT 0x0001 #define ZBEE_ZCL_THERMOSTAT_RUNNING_STATE_COOL 0x0002 #define ZBEE_ZCL_THERMOSTAT_RUNNING_STATE_FAN 0x0004 #define ZBEE_ZCL_THERMOSTAT_RUNNING_STATE_HEAT2 0x0008 #define ZBEE_ZCL_THERMOSTAT_RUNNING_STATE_COOL2 0x0010 #define ZBEE_ZCL_THERMOSTAT_RUNNING_STATE_FAN2 0x0020 #define ZBEE_ZCL_THERMOSTAT_RUNNING_STATE_FAN3 0x0040 /* Client-to-server commands. */ #define ZBEE_ZCL_CMD_ID_THERMOSTAT_SETPOINT 0x00 #define ZBEE_ZCL_CMD_ID_THERMOSTAT_SET_SCHEDULE 0x01 #define ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_SCHEDULE 0x02 #define ZBEE_ZCL_CMD_ID_THERMOSTAT_CLEAR_SCHEDULE 0x03 #define ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_RELAY_LOG 0x04 static const value_string zbee_zcl_thermostat_srv_rx_cmd_names[] = { { ZBEE_ZCL_CMD_ID_THERMOSTAT_SETPOINT, "Setpoint Raise/Lower" }, { ZBEE_ZCL_CMD_ID_THERMOSTAT_SET_SCHEDULE, "Set Weekly Schedule" }, { ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_SCHEDULE, "Get Weekly Schedule" }, { ZBEE_ZCL_CMD_ID_THERMOSTAT_CLEAR_SCHEDULE, "Clear Weekly Schedule" }, { ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_RELAY_LOG, "Get Relay Status Log" }, { 0, NULL } }; #define ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_SCHEDULE_RESPONSE 0x00 #define ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_RELAY_LOG_RESPONSE 0x01 static const value_string zbee_zcl_thermostat_srv_tx_cmd_names[] = { { ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_SCHEDULE_RESPONSE, "Get Weekly Schedule Response" }, { ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_RELAY_LOG_RESPONSE,"Get Relay Status Log Response" }, { 0, NULL } }; #define ZBEE_ZCL_CMD_THERMOSTAT_SCHEDULE_MODE_SEQUENCE_HEAT 0x01 #define ZBEE_ZCL_CMD_THERMOSTAT_SCHEDULE_MODE_SEQUENCE_COOL 0x02 /* Setpoint mode names. */ static const value_string zbee_zcl_thermostat_setpoint_mode_names[] = { { 0, "Heat" }, { 1, "Cool" }, { 2, "Both" }, { 0, NULL } }; /*************************/ /* Global Variables */ /*************************/ static int proto_zbee_zcl_thermostat; static int hf_zbee_zcl_thermostat_attr_id; static int hf_zbee_zcl_thermostat_srv_rx_cmd_id; static int hf_zbee_zcl_thermostat_srv_tx_cmd_id; static int hf_zbee_zcl_thermostat_setpoint_mode; static int hf_zbee_zcl_thermostat_setpoint_amount; static int hf_zbee_zcl_thermostat_schedule_num_trans; static int hf_zbee_zcl_thermostat_schedule_day_sequence; static int hf_zbee_zcl_thermostat_schedule_day_sunday; static int hf_zbee_zcl_thermostat_schedule_day_monday; static int hf_zbee_zcl_thermostat_schedule_day_tuesday; static int hf_zbee_zcl_thermostat_schedule_day_wednesday; static int hf_zbee_zcl_thermostat_schedule_day_thursday; static int hf_zbee_zcl_thermostat_schedule_day_friday; static int hf_zbee_zcl_thermostat_schedule_day_saturday; static int hf_zbee_zcl_thermostat_schedule_day_vacation; static int hf_zbee_zcl_thermostat_schedule_mode_sequence; static int hf_zbee_zcl_thermostat_schedule_mode_heat; static int hf_zbee_zcl_thermostat_schedule_mode_cool; static int hf_zbee_zcl_thermostat_schedule_time; static int hf_zbee_zcl_thermostat_schedule_heat; static int hf_zbee_zcl_thermostat_schedule_cool; static int ett_zbee_zcl_thermostat; static int ett_zbee_zcl_thermostat_schedule_days; static int ett_zbee_zcl_thermostat_schedule_mode; /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_thermostat(void); void proto_reg_handoff_zbee_zcl_thermostat(void); /* Attribute Dissector Helpers */ static void dissect_zcl_thermostat_attr_data(proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); static int dissect_zcl_thermostat_schedule(proto_tree *tree, tvbuff_t *tvb, unsigned offset); static void dissect_zcl_thermostat_schedule_days(proto_tree *tree, tvbuff_t *tvb, unsigned offset); static void dissect_zcl_thermostat_schedule_mode(proto_tree *tree, tvbuff_t *tvb, unsigned offset); /** *Helper function to dissect a Thermostat scheduling days bitmask. * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset payload offset of the ZoneStatus value. */ static void dissect_zcl_thermostat_schedule_days(proto_tree *tree, tvbuff_t *tvb, unsigned offset) { static int * const thermostat_schedule_days[] = { &hf_zbee_zcl_thermostat_schedule_day_sunday, &hf_zbee_zcl_thermostat_schedule_day_monday, &hf_zbee_zcl_thermostat_schedule_day_tuesday, &hf_zbee_zcl_thermostat_schedule_day_wednesday, &hf_zbee_zcl_thermostat_schedule_day_thursday, &hf_zbee_zcl_thermostat_schedule_day_friday, &hf_zbee_zcl_thermostat_schedule_day_saturday, &hf_zbee_zcl_thermostat_schedule_day_vacation, NULL }; proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_thermostat_schedule_day_sequence, ett_zbee_zcl_thermostat_schedule_days, thermostat_schedule_days, ENC_NA); } /* dissect_zcl_thermostat_schedule_days */ /** *Helper function to dissect a Thermostat scheduling mode bitmask. * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset payload offset of the ZoneStatus value. */ static void dissect_zcl_thermostat_schedule_mode(proto_tree *tree, tvbuff_t *tvb, unsigned offset) { static int * const thermostat_schedule_modes[] = { &hf_zbee_zcl_thermostat_schedule_mode_heat, &hf_zbee_zcl_thermostat_schedule_mode_cool, NULL }; proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_thermostat_schedule_mode_sequence, ett_zbee_zcl_thermostat_schedule_mode, thermostat_schedule_modes, ENC_NA); } /** *Helper function to dissect a Thermostat schedule, which has * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset payload offset of the ZoneStatus value. *@return length of parsed data. */ static int dissect_zcl_thermostat_schedule(proto_tree *tree, tvbuff_t *tvb, unsigned offset) { unsigned start = offset; uint8_t num_transitions; uint8_t mode_sequence; int i; num_transitions = tvb_get_uint8(tvb, offset); proto_tree_add_uint(tree, hf_zbee_zcl_thermostat_schedule_num_trans, tvb, offset, 1, num_transitions); offset++; dissect_zcl_thermostat_schedule_days(tree, tvb, offset); offset++; mode_sequence = tvb_get_uint8(tvb, offset); dissect_zcl_thermostat_schedule_mode(tree, tvb, offset); offset++; /* Parse the list of setpoint transitions. */ for (i = 0; i < num_transitions; i++) { nstime_t tv; tv.secs = tvb_get_letohs(tvb, offset) * 60; tv.nsecs = 0; proto_tree_add_time(tree, hf_zbee_zcl_thermostat_schedule_time, tvb, offset, 2, &tv); offset += 2; if (mode_sequence & ZBEE_ZCL_CMD_THERMOSTAT_SCHEDULE_MODE_SEQUENCE_HEAT) { float setpoint = tvb_get_letohis(tvb, offset); proto_tree_add_float(tree, hf_zbee_zcl_thermostat_schedule_heat, tvb, offset, 2, (setpoint / 100.0f)); offset += 2; } if (mode_sequence & ZBEE_ZCL_CMD_THERMOSTAT_SCHEDULE_MODE_SEQUENCE_COOL) { float setpoint = tvb_get_letohis(tvb, offset); proto_tree_add_float(tree, hf_zbee_zcl_thermostat_schedule_cool, tvb, offset, 2, (setpoint / 100.0f)); offset += 2; } } /* for */ /* Return the number of bytes parsed. */ return (offset - start); } /* dissect_zcl_thermostat_cmd_schedule */ /** *ZigBee ZCL Thermostat 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. *@param data pointer to ZCL packet structure. *@return length of parsed data. */ static int dissect_zbee_zcl_thermostat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { zbee_zcl_packet *zcl; unsigned offset = 0; uint8_t cmd_id; float amount; /* Reject the packet if data is NULL */ if (data == NULL) return 0; zcl = (zbee_zcl_packet *)data; cmd_id = zcl->cmd_id; 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_thermostat_srv_rx_cmd_names, "Unknown Command"), zcl->tran_seqno); /* Add the command ID. */ proto_tree_add_item(tree, hf_zbee_zcl_thermostat_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; /* Handle the command dissection. */ switch (cmd_id) { case ZBEE_ZCL_CMD_ID_THERMOSTAT_SETPOINT: /* Setpoint Raise/Lower. */ proto_tree_add_item(tree, hf_zbee_zcl_thermostat_setpoint_mode, tvb, offset, 1, ENC_NA); offset++; amount = tvb_get_int8(tvb, offset); proto_tree_add_float(tree, hf_zbee_zcl_thermostat_setpoint_amount, tvb, offset, 1, (amount / 100.0f)); offset++; break; case ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_SCHEDULE: /* Get Weekly Schedule. */ dissect_zcl_thermostat_schedule_days(tree, tvb, offset); offset++; dissect_zcl_thermostat_schedule_mode(tree, tvb, offset); offset++; break; case ZBEE_ZCL_CMD_ID_THERMOSTAT_SET_SCHEDULE: /* Set Weekly Schedule. */ dissect_zcl_thermostat_schedule(tree, tvb, offset); break; case ZBEE_ZCL_CMD_ID_THERMOSTAT_CLEAR_SCHEDULE: case ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_RELAY_LOG: /* No Payload - fall-through. */ default: break; } /* switch */ } else { /* 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_thermostat_srv_tx_cmd_names, "Unknown Command"), zcl->tran_seqno); /* Add the command ID. */ proto_tree_add_item(tree, hf_zbee_zcl_thermostat_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; /* Handle the command dissection. */ switch (cmd_id) { case ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_SCHEDULE_RESPONSE: /* Get Weekly Schedule Response. */ dissect_zcl_thermostat_schedule(tree, tvb, offset); break; case ZBEE_ZCL_CMD_ID_THERMOSTAT_GET_RELAY_LOG_RESPONSE: /* TODO: Implement Me! */ default: break; } /* switch */ } return tvb_captured_length(tvb); } /* dissect_zbee_zcl_thermostat */ /** *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_thermostat_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_thermostat_attr_data*/ /** *ZigBee ZCL IAS Zone cluste protocol registration. * */ void proto_register_zbee_zcl_thermostat(void) { /* Setup list of header fields */ static hf_register_info hf[] = { { &hf_zbee_zcl_thermostat_attr_id, { "Attribute", "zbee_zcl_hvac.thermostat.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_thermostat_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_thermostat_srv_rx_cmd_id, { "Command", "zbee_zcl_hvac.thermostat.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_thermostat_srv_rx_cmd_names), 0x0, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_srv_tx_cmd_id, { "Command", "zbee_zcl_hvac.thermostat.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_thermostat_srv_tx_cmd_names), 0x0, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_setpoint_mode, { "Mode", "zbee_zcl_hvac.thermostat.mode", FT_UINT8, BASE_HEX, VALS(zbee_zcl_thermostat_setpoint_mode_names), 0x0, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_setpoint_amount, { "Amount", "zbee_zcl_hvac.thermostat.amount", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_num_trans, { "Number of Transitions for Sequence", "zbee_zcl_hvac.thermostat.num_trans", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_sequence, { "Days of Week for Sequence", "zbee_zcl_hvac.thermostat.day_sequence", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_sunday, { "Sunday", "zbee_zcl_hvac.thermostat.day.sunday", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_monday, { "Monday", "zbee_zcl_hvac.thermostat.day.monday", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_tuesday, { "Tuesday", "zbee_zcl_hvac.thermostat.day.tuesday", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_wednesday, { "Wednesday", "zbee_zcl_hvac.thermostat.day.wednesday", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_thursday, { "Thursday", "zbee_zcl_hvac.thermostat.day.thursday", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_friday, { "Friday", "zbee_zcl_hvac.thermostat.day.friday", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_saturday, { "Saturday", "zbee_zcl_hvac.thermostat.day.saturday", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_day_vacation, { "Away/Vacation", "zbee_zcl_hvac.thermostat.day.vacation", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_mode_sequence, { "Mode for Sequence", "zbee_zcl_hvac.thermostat.mode_sequence", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_mode_heat, { "Heating", "zbee_zcl_hvac.thermostat.mode.heat", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_mode_cool, { "Cooling", "zbee_zcl_hvac.thermostat.mode.cool", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }}, { &hf_zbee_zcl_thermostat_schedule_time, { "Transition Time", "zbee_zcl_hvac.thermostat.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, "Setpoint transition time relative to midnight of the scheduled day", HFILL }}, { &hf_zbee_zcl_thermostat_schedule_heat, { "Heating Setpoint", "zbee_zcl_hvac.thermostat.heat", FT_FLOAT, BASE_NONE, NULL, 0x0, "Heating setpoint in degrees Celsius", HFILL }}, { &hf_zbee_zcl_thermostat_schedule_cool, { "Cooling Setpoint", "zbee_zcl_hvac.thermostat.cool", FT_FLOAT, BASE_NONE, NULL, 0x0, "Cooling setpoint in degrees Celsius", HFILL }} }; /* ZCL IAS Zone subtrees */ static int *ett[ZBEE_ZCL_THERMOSTAT_NUM_ETT]; ett[0] = &ett_zbee_zcl_thermostat; ett[1] = &ett_zbee_zcl_thermostat_schedule_days; ett[2] = &ett_zbee_zcl_thermostat_schedule_mode; /* Register the ZigBee ZCL IAS Zoben cluster protocol name and description */ proto_zbee_zcl_thermostat = proto_register_protocol("ZigBee ZCL Thermostat", "ZCL Thermostat", ZBEE_PROTOABBREV_ZCL_THERMOSTAT); proto_register_field_array(proto_zbee_zcl_thermostat, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL IAS Zone dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_THERMOSTAT, dissect_zbee_zcl_thermostat, proto_zbee_zcl_thermostat); } /*proto_register_zbee_zcl_thermostat*/ /** *Hands off the ZCL Thermostat dissector. * */ void proto_reg_handoff_zbee_zcl_thermostat(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_THERMOSTAT, proto_zbee_zcl_thermostat, ett_zbee_zcl_thermostat, ZBEE_ZCL_CID_THERMOSTAT, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_thermostat_attr_id, hf_zbee_zcl_thermostat_attr_id, hf_zbee_zcl_thermostat_srv_rx_cmd_id, hf_zbee_zcl_thermostat_srv_tx_cmd_id, (zbee_zcl_fn_attr_data)dissect_zcl_thermostat_attr_data ); } /*proto_reg_handoff_zbee_zcl_thermostat*/ /* ########################################################################## */ /* #### (0x0500) IAS ZONE CLUSTER ########################################### */ /* ########################################################################## */ #define ZBEE_ZCL_IAS_ZONE_NUM_ETT 2 /* IAS Zone Server Attributes */ #define ZBEE_ZCL_ATTR_ID_IAS_ZONE_STATE 0x0000 #define ZBEE_ZCL_ATTR_ID_IAS_ZONE_TYPE 0x0001 #define ZBEE_ZCL_ATTR_ID_IAS_ZONE_STATUS 0x0002 #define ZBEE_ZCL_ATTR_ID_IAS_CIE_ADDRESS 0x0010 static const value_string zbee_zcl_ias_zone_attr_names[] = { { ZBEE_ZCL_ATTR_ID_IAS_ZONE_STATE, "ZoneState" }, { ZBEE_ZCL_ATTR_ID_IAS_ZONE_TYPE, "ZoneType" }, { ZBEE_ZCL_ATTR_ID_IAS_ZONE_STATUS, "ZoneStatus" }, { ZBEE_ZCL_ATTR_ID_IAS_CIE_ADDRESS, "IAS_CIE_Address" }, { 0, NULL } }; /* IAS Zone States */ #define ZBEE_IAS_ZONE_STATE_NOT_ENROLLED 0x00 #define ZBEE_IAS_ZONE_STATE_ENROLLED 0x01 static const value_string zbee_ias_state_names[] = { { ZBEE_IAS_ZONE_STATE_NOT_ENROLLED, "Not Enrolled" }, { ZBEE_IAS_ZONE_STATE_ENROLLED, "Enrolled" }, { 0, NULL } }; /* IAS Zone Type values. */ #define ZBEE_IAS_ZONE_TYPE_STANDARD_CIE 0x0000 #define ZBEE_IAS_ZONE_TYPE_MOTION_SENSOR 0x000D #define ZBEE_IAS_ZONE_TYPE_CONTACT_SWITCH 0x0015 #define ZBEE_IAS_ZONE_TYPE_FIRE_SENSOR 0x0028 #define ZBEE_IAS_ZONE_TYPE_WATER_SENSOR 0x002A #define ZBEE_IAS_ZONE_TYPE_GAS_SENSOR 0x002B #define ZBEE_IAS_ZONE_TYPE_PERSONAL_EMERGENCY 0x002C #define ZBEE_IAS_ZONE_TYPE_VIBRATION_SENSOR 0x002D #define ZBEE_IAS_ZONE_TYPE_REMOTE_CONTROL 0x010F #define ZBEE_IAS_ZONE_TYPE_KEY_FOB 0x0115 #define ZBEE_IAS_ZONE_TYPE_KEYPAD 0x021D #define ZBEE_IAS_ZONE_TYPE_STANDARD_WARNING 0x0225 #define ZBEE_IAS_ZONE_TYPE_INVALID_ZONE_TYPE 0xFFFF #define ZBEE_IAS_ZONE_STATUS_ALARM1 0x0001 #define ZBEE_IAS_ZONE_STATUS_ALARM2 0x0002 #define ZBEE_IAS_ZONE_STATUS_TAMPER 0x0004 #define ZBEE_IAS_ZONE_STATUS_BATTERY 0x0008 #define ZBEE_IAS_ZONE_STATUS_SUPERVISION 0x0010 #define ZBEE_IAS_ZONE_STATUS_RESTORE 0x0020 #define ZBEE_IAS_ZONE_STATUS_TROUBLE 0x0040 #define ZBEE_IAS_ZONE_STATUS_AC_MAINS 0x0080 static const value_string zbee_ias_type_names[] = { { ZBEE_IAS_ZONE_TYPE_STANDARD_CIE, "Standard CIE" }, { ZBEE_IAS_ZONE_TYPE_MOTION_SENSOR, "Motion sensor" }, { ZBEE_IAS_ZONE_TYPE_CONTACT_SWITCH, "Contact switch" }, { ZBEE_IAS_ZONE_TYPE_FIRE_SENSOR, "Fire sensor" }, { ZBEE_IAS_ZONE_TYPE_WATER_SENSOR, "Water sensor" }, { ZBEE_IAS_ZONE_TYPE_GAS_SENSOR, "Gas sensor" }, { ZBEE_IAS_ZONE_TYPE_PERSONAL_EMERGENCY, "Personal emergency device" }, { ZBEE_IAS_ZONE_TYPE_VIBRATION_SENSOR, "Vibration/movement sensor" }, { ZBEE_IAS_ZONE_TYPE_REMOTE_CONTROL, "Remote control" }, { ZBEE_IAS_ZONE_TYPE_KEY_FOB, "Key fob" }, { ZBEE_IAS_ZONE_TYPE_KEYPAD, "Keypad" }, { ZBEE_IAS_ZONE_TYPE_STANDARD_WARNING, "Standard warning device" }, { ZBEE_IAS_ZONE_TYPE_INVALID_ZONE_TYPE, "Invalid zone type" }, { 0, NULL } }; /* Server-to-client command IDs. */ #define ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_NOTIFY 0x00 #define ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_REQUEST 0x01 static const value_string zbee_zcl_ias_zone_srv_tx_cmd_names[] = { { ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_REQUEST, "Zone Enroll Request" }, { ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_NOTIFY, "Zone Status Change Notification" }, { 0, NULL } }; /* Client-to-server command IDs. */ #define ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_RESPONSE 0x00 static const value_string zbee_zcl_ias_zone_srv_rx_cmd_names[] = { { ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_RESPONSE, "Zone Enroll Response" }, { 0, NULL } }; static const value_string zbee_zcl_ias_zone_enroll_code_names[] = { { 0, "Success" }, { 1, "Not Supported" }, { 2, "No enroll permit" }, { 3, "Too many zones" }, { 0, NULL } }; /*************************/ /* Global Variables */ /*************************/ /* Initialize the protocol and registered fields */ static int proto_zbee_zcl_ias_zone; static int hf_zbee_zcl_ias_zone_attr_id; static int hf_zbee_zcl_ias_zone_srv_rx_cmd_id; static int hf_zbee_zcl_ias_zone_srv_tx_cmd_id; static int hf_zbee_zcl_ias_zone_enroll_code; static int hf_zbee_zcl_ias_zone_zone_id; static int hf_zbee_zcl_ias_zone_state; static int hf_zbee_zcl_ias_zone_type; static int hf_zbee_zcl_ias_zone_status; static int hf_zbee_zcl_ias_zone_delay; static int hf_zbee_zcl_ias_zone_ext_status; static int hf_zbee_zcl_ias_zone_manufacturer_code; static int hf_zbee_zcl_ias_zone_status_ac_mains; static int hf_zbee_zcl_ias_zone_status_alarm1; static int hf_zbee_zcl_ias_zone_status_alarm2; static int hf_zbee_zcl_ias_zone_status_battery; static int hf_zbee_zcl_ias_zone_status_restore_reports; static int hf_zbee_zcl_ias_zone_status_supervision_reports; static int hf_zbee_zcl_ias_zone_status_tamper; static int hf_zbee_zcl_ias_zone_status_trouble; static const true_false_string tfs_ac_mains = { "AC/Mains fault", "AC/Mains OK" }; static const true_false_string tfs_alarmed_or_not = { "Opened or alarmed", "Closed or not alarmed" }; static const true_false_string tfs_battery = { "Low battery", "Battery OK" }; static const true_false_string tfs_reports_or_not = { "Reports", "Does not report" }; static const true_false_string tfs_reports_restore = { "Reports restore", "Does not report restore" }; static const true_false_string tfs_tampered_or_not = { "Tampered", "Not tampered" }; static const true_false_string tfs_trouble_failure = { "Trouble/Failure", "OK" }; static int ett_zbee_zcl_ias_zone; static int ett_zbee_zcl_ias_zone_status; /*************************/ /* Function Declarations */ /*************************/ void proto_register_zbee_zcl_ias_zone(void); void proto_reg_handoff_zbee_zcl_ias_zone(void); /* Command Dissector Helpers. */ static int dissect_zbee_zcl_ias_zone (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data); /* Attribute Dissector Helpers */ static void dissect_zcl_ias_zone_attr_data (proto_tree *tree, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr); /* ZoneStatus bitmask helper */ static void dissect_zcl_ias_zone_status (proto_tree *tree, tvbuff_t *tvb, unsigned offset); /** *Helper function to dissect the IAS ZoneStatus bitmask. * *@param tree pointer to data tree Wireshark uses to display packet. *@param tvb pointer to buffer containing raw packet. *@param offset payload offset of the ZoneStatus value. */ static void dissect_zcl_ias_zone_status(proto_tree *tree, tvbuff_t *tvb, unsigned offset) { static int * const ias_zone_statuses[] = { &hf_zbee_zcl_ias_zone_status_alarm1, &hf_zbee_zcl_ias_zone_status_alarm2, &hf_zbee_zcl_ias_zone_status_tamper, &hf_zbee_zcl_ias_zone_status_battery, &hf_zbee_zcl_ias_zone_status_supervision_reports, &hf_zbee_zcl_ias_zone_status_restore_reports, &hf_zbee_zcl_ias_zone_status_trouble, &hf_zbee_zcl_ias_zone_status_ac_mains, NULL }; proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_ias_zone_status, ett_zbee_zcl_ias_zone_status, ias_zone_statuses, ENC_LITTLE_ENDIAN); } /* dissect_zcl_ias_zone_status */ /** *ZigBee ZCL IAS Zone 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. *@param data pointer to ZCL packet structure. *@return length of parsed data. */ static int dissect_zbee_zcl_ias_zone(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { zbee_zcl_packet *zcl; unsigned offset = 0; uint8_t cmd_id; /* Reject the packet if data is NULL */ if (data == NULL) return 0; zcl = (zbee_zcl_packet *)data; cmd_id = zcl->cmd_id; 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_ias_zone_srv_rx_cmd_names, "Unknown Command"), zcl->tran_seqno); /* Add the command ID. */ proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; /* Handle the command dissection. */ switch (cmd_id) { case ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_RESPONSE: proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_enroll_code, tvb, offset, 1, ENC_NA); offset++; proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_zone_id, tvb, offset, 1, ENC_NA); offset++; break; default: break; } /* switch */ } else { /* 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_ias_zone_srv_tx_cmd_names, "Unknown Command"), zcl->tran_seqno); /* Add the command ID. */ proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; /* Handle the command dissection. */ switch (cmd_id) { case ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_NOTIFY: dissect_zcl_ias_zone_status(tree, tvb, offset); offset += 2; proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_ext_status, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_zone_id, tvb, offset, 1, ENC_NA); offset += 1; proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_delay, tvb, offset, 2, ENC_LITTLE_ENDIAN); break; case ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_REQUEST: proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_type, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_manufacturer_code, tvb, offset, 2, ENC_LITTLE_ENDIAN); break; default: break; } /* switch */ } return tvb_reported_length(tvb); } /* dissect_zbee_zcl_ias_zone */ /** *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_ias_zone_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_IAS_ZONE_STATE: proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_state, tvb, *offset, 1, ENC_NA); *offset += 1; break; case ZBEE_ZCL_ATTR_ID_IAS_ZONE_TYPE: proto_tree_add_item(tree, hf_zbee_zcl_ias_zone_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_IAS_ZONE_STATUS: dissect_zcl_ias_zone_status(tree, tvb, *offset); *offset += 2; break; case ZBEE_ZCL_ATTR_ID_IAS_CIE_ADDRESS: default: dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr); break; } } /*dissect_zcl_ias_zone_attr_data*/ /** *Hands off the ZCL IAS Zone dissector. * */ void proto_reg_handoff_zbee_zcl_ias_zone(void) { zbee_zcl_init_cluster( ZBEE_PROTOABBREV_ZCL_IAS_ZONE, proto_zbee_zcl_ias_zone, ett_zbee_zcl_ias_zone, ZBEE_ZCL_CID_IAS_ZONE, ZBEE_MFG_CODE_NONE, hf_zbee_zcl_ias_zone_attr_id, hf_zbee_zcl_ias_zone_attr_id, hf_zbee_zcl_ias_zone_srv_rx_cmd_id, hf_zbee_zcl_ias_zone_srv_tx_cmd_id, (zbee_zcl_fn_attr_data)dissect_zcl_ias_zone_attr_data ); } /*proto_reg_handoff_zbee_zcl_ias_zone*/ /** *ZigBee ZCL IAS Zone cluste protocol registration. * */ void proto_register_zbee_zcl_ias_zone(void) { /* Setup list of header fields */ static hf_register_info hf[] = { { &hf_zbee_zcl_ias_zone_attr_id, { "Attribute", "zbee_zcl_ias.zone.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_ias_zone_attr_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_ias_zone_srv_rx_cmd_id, { "Command", "zbee_zcl_ias.zone.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_ias_zone_srv_rx_cmd_names), 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_srv_tx_cmd_id, { "Command", "zbee_zcl_ias.zone.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_ias_zone_srv_tx_cmd_names), 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_enroll_code, { "Enroll response code", "zbee_zcl_ias.zone.enroll_code", FT_UINT8, BASE_HEX, VALS(zbee_zcl_ias_zone_enroll_code_names), 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_zone_id, { "Zone ID", "zbee_zcl_ias.zone.zone_id", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_state, { "ZoneState", "zbee_zcl_ias.zone.state", FT_UINT16, BASE_HEX, VALS(zbee_ias_state_names), 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_type, { "ZoneType", "zbee_zcl_ias.zone.type", FT_UINT16, BASE_HEX, VALS(zbee_ias_type_names), 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_manufacturer_code, { "ManufacturerCode", "zbee_zcl_ias.zone.manufacturer_code", FT_UINT16, BASE_HEX, VALS(zbee_mfr_code_names), 0x0, NULL, HFILL } }, { &hf_zbee_zcl_ias_zone_status, { "ZoneStatus", "zbee_zcl_ias.zone.status", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_delay, { "Delay (in quarterseconds)", "zbee_zcl_ias.zone.delay", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_ext_status, { "Extended Status", "zbee_zcl_ias.zone.ext_status", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_status_alarm1, { "Alarm 1", "zbee_zcl_ias.zone.status.alarm_1", FT_BOOLEAN, 16, TFS(&tfs_alarmed_or_not), ZBEE_IAS_ZONE_STATUS_ALARM1, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_status_alarm2, { "Alarm 2", "zbee_zcl_ias.zone.status.alarm_2", FT_BOOLEAN, 16, TFS(&tfs_alarmed_or_not), ZBEE_IAS_ZONE_STATUS_ALARM2, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_status_battery, { "Battery", "zbee_zcl_ias.zone.status.battery", FT_BOOLEAN, 16, TFS(&tfs_battery), ZBEE_IAS_ZONE_STATUS_BATTERY, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_status_tamper, { "Tamper", "zbee_zcl_ias.zone.status.tamper", FT_BOOLEAN, 16, TFS(&tfs_tampered_or_not), ZBEE_IAS_ZONE_STATUS_TAMPER, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_status_supervision_reports, { "Supervision Reports", "zbee_zcl_ias.zone.status.supervision_reports", FT_BOOLEAN, 16, TFS(&tfs_reports_or_not), ZBEE_IAS_ZONE_STATUS_SUPERVISION, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_status_restore_reports, { "Restore Reports", "zbee_zcl_ias.zone.status.restore_reports", FT_BOOLEAN, 16, TFS(&tfs_reports_restore), ZBEE_IAS_ZONE_STATUS_RESTORE, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_status_trouble, { "Trouble", "zbee_zcl_ias.zone.status.trouble", FT_BOOLEAN, 16, TFS(&tfs_trouble_failure), ZBEE_IAS_ZONE_STATUS_TROUBLE, NULL, HFILL }}, { &hf_zbee_zcl_ias_zone_status_ac_mains, { "AC (mains)", "zbee_zcl_ias.zone.status.ac_mains", FT_BOOLEAN, 16, TFS(&tfs_ac_mains), ZBEE_IAS_ZONE_STATUS_AC_MAINS, NULL, HFILL }} }; /* ZCL IAS Zone subtrees */ static int *ett[ZBEE_ZCL_IAS_ZONE_NUM_ETT]; ett[0] = &ett_zbee_zcl_ias_zone; ett[1] = &ett_zbee_zcl_ias_zone_status; /* Register the ZigBee ZCL IAS Zoben cluster protocol name and description */ proto_zbee_zcl_ias_zone = proto_register_protocol("ZigBee ZCL IAS Zone", "ZCL IAS Zone", ZBEE_PROTOABBREV_ZCL_IAS_ZONE); proto_register_field_array(proto_zbee_zcl_ias_zone, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); /* Register the ZigBee ZCL IAS Zone dissector. */ register_dissector(ZBEE_PROTOABBREV_ZCL_IAS_ZONE, dissect_zbee_zcl_ias_zone, proto_zbee_zcl_ias_zone); } /*proto_register_zbee_zcl_ias_zone*/ /* * 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: */