aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-zbee-zcl-misc.c
diff options
context:
space:
mode:
authorChris Brandson <chris.brandson@gmail.com>2014-11-07 14:11:02 -0800
committerAnders Broman <a.broman58@gmail.com>2014-12-17 11:53:26 +0000
commitdf639f509e812fff3c5eb4bdf4f77988c6ec122b (patch)
tree2d6733280c8596f2dfacc878c878b469d301428f /epan/dissectors/packet-zbee-zcl-misc.c
parentc5b720708e75562d1b8676fd5ab75f9d7b338652 (diff)
Fixed bug in ZigBee (zbee) decryption, added Key Establishment cluster and moved IAS, Thermostat and Poll clusters out of the ZCL foundation dissector.
Removed attrID and cmdID ZCL cluster functions. Bug in ZCL HVAC attribute registration. Fixed bug in ZCL command ID field registration. Update Manufacturer Codes and Profile Ids to ZigBee-053874r26 Oct 2014 Fixed broken fragmented ZigBee packet collection and reassembly Use protocol fields for Thermostat schedule transitions. Added support for Key Establishment Cluster (CBKE) at SE 1.2a Updated Message cluster to SE 1.2a spec Added attribute reporting status which is common to all SE 1.2a clusters Added SE 1.2a tunnel cluster support ZigBee Smart Energy (SE) decryption appears to have been broken for some time. For SE you do not know the Link Key until after successful completion of Key Establishment and then manually enter it into preferences. Entry in preferences was broken such that when the new Link Key was entered all existing link keys would be lost. This lead to the loss of the Network Key as well when the Transport Key message was re-processed without the Pre-Configured Link Key. The Link Key 'key ring' has been moved to the UAT post-update callback so that it will always be updated correctly after changes to the link keys in preferences The attribute reporting status attribute which is common to all SE clusters was accidentally shared, now each cluster has it's own instance ZigBee security added key display for decrypted packets ZigBee Security Preferences fixed UAT type for Label so key label is editable again Added definition for Retail Service profile Added dissection for profile-wide (General Command Frame) commands when the profile is unknown Added zbee-zcl-misc.c to precommit check whitelist as it contains ias and hvac clusters avoiding proliferation of too many small files Change-Id: I53d85ba9d782db6a0e7e78c51b0bc7cdcdbca3ad Reviewed-on: https://code.wireshark.org/review/5565 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-zbee-zcl-misc.c')
-rw-r--r--epan/dissectors/packet-zbee-zcl-misc.c1115
1 files changed, 1115 insertions, 0 deletions
diff --git a/epan/dissectors/packet-zbee-zcl-misc.c b/epan/dissectors/packet-zbee-zcl-misc.c
new file mode 100644
index 0000000000..4a9862d4b6
--- /dev/null
+++ b/epan/dissectors/packet-zbee-zcl-misc.c
@@ -0,0 +1,1115 @@
+/* packet-zbee-zcl-misc.c
+ * Dissector routines for the ZigBee ZCL SE clusters like
+ * Messaging
+ * By Fabio Tarabelloni <fabio.tarabelloni@reloc.it>
+ * Copyright 2013 RELOC s.r.l.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* Include Files */
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/to_str.h>
+
+#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
+/* Air Conditioning Atrributes. */
+#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" },
+ { 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_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 = -1;
+
+static int hf_zbee_zcl_thermostat_attr_id = -1;
+static int hf_zbee_zcl_thermostat_srv_rx_cmd_id = -1;
+static int hf_zbee_zcl_thermostat_srv_tx_cmd_id = -1;
+static int hf_zbee_zcl_thermostat_setpoint_mode = -1;
+static int hf_zbee_zcl_thermostat_setpoint_amount = -1;
+
+static int hf_zbee_zcl_thermostat_schedule_num_trans = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_sequence = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_sunday = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_monday = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_tuesday = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_wednesday = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_thursday = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_friday = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_saturday = -1;
+static int hf_zbee_zcl_thermostat_schedule_day_vacation = -1;
+static int hf_zbee_zcl_thermostat_schedule_mode_sequence = -1;
+static int hf_zbee_zcl_thermostat_schedule_mode_heat = -1;
+static int hf_zbee_zcl_thermostat_schedule_mode_cool = -1;
+static int hf_zbee_zcl_thermostat_schedule_time = -1;
+static int hf_zbee_zcl_thermostat_schedule_heat = -1;
+static int hf_zbee_zcl_thermostat_schedule_cool = -1;
+
+static gint ett_zbee_zcl_thermostat = -1;
+static gint ett_zbee_zcl_thermostat_schedule_days = -1;
+static gint ett_zbee_zcl_thermostat_schedule_mode = -1;
+
+/*************************/
+/* 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, guint *offset, guint16 attr_id, guint data_type);
+
+static int dissect_zcl_thermostat_schedule(proto_tree *tree, tvbuff_t *tvb, guint offset);
+static void dissect_zcl_thermostat_schedule_days(proto_tree *tree, tvbuff_t *tvb, guint offset);
+static void dissect_zcl_thermostat_schedule_mode(proto_tree *tree, tvbuff_t *tvb, guint offset);
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zcl_thermostat_schedule_days
+ * DESCRIPTION
+ * Helper function to dissect a Thermostat scheduling days bitmask.
+ * PARAMETERS
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * guint offset - payload offset of the ZoneStatus value.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+static void
+dissect_zcl_thermostat_schedule_days(proto_tree *tree, tvbuff_t *tvb, guint offset)
+{
+
+ static const int * 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 */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zcl_thermostat_schedule_mode
+ * DESCRIPTION
+ * Helper function to dissect a Thermostat scheduling mode bitmask.
+ * PARAMETERS
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * guint offset - payload offset of the ZoneStatus value.
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+static void
+dissect_zcl_thermostat_schedule_mode(proto_tree *tree, tvbuff_t *tvb, guint offset)
+{
+
+ static const int * 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);
+}
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zcl_thermostat_cmd_schedule
+ * DESCRIPTION
+ * Helper function to dissect a Thermostat schedule, which has
+ * a common format in both the Set Weekly Schedule, and Get
+ * Weekly Schedule Response commands.
+ * PARAMETERS
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * guint offset - payload offset of the ZoneStatus value.
+ * RETURNS
+ * int - length of parsed data.
+ *---------------------------------------------------------------
+ */
+static int
+dissect_zcl_thermostat_schedule(proto_tree *tree, tvbuff_t *tvb, guint offset)
+{
+ guint start = offset;
+ guint8 num_transitions;
+ guint8 mode_sequence;
+ int i;
+
+ num_transitions = tvb_get_guint8(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_guint8(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 = (gint16)tvb_get_letohs(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 = (gint16)tvb_get_letohs(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 */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zcl_thermostat
+ * DESCRIPTION
+ * ZigBee ZCL Thermostat cluster dissector for wireshark.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_info *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * void *data - pointer to ZCL packet structure.
+ * RETURNS
+ * int - 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;
+ guint offset = 0;
+ guint8 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, cmd_id);
+ 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 = (gint8)tvb_get_guint8(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_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, cmd_id);
+ 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 */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zcl_thermostat_attr_data
+ * DESCRIPTION
+ * this function is called by ZCL foundation dissector in order to decode
+ * specific cluster attributes data.
+ * PARAMETERS
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * guint *offset - pointer to buffer offset
+ * guint16 attr_id - attribute identifier
+ * guint data_type - attribute data type
+ * RETURNS
+ * none
+ *---------------------------------------------------------------
+ */
+static void
+dissect_zcl_thermostat_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type)
+{
+ /* Dissect attribute data type and data */
+ switch (attr_id) {
+ default:
+ dissect_zcl_attr_data(tvb, tree, offset, data_type);
+ break;
+ }
+} /*dissect_zcl_thermostat_attr_data*/
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_register_zbee_zcl_ias_zone
+ * DESCRIPTION
+ * ZigBee ZCL IAS Zone cluste protocol registration.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+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, TFS(&tfs_true_false), 0x01, NULL,
+ HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_day_monday,
+ { "Monday", "zbee_zcl_hvac.thermostat.day.monday", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x02, NULL,
+ HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_day_tuesday,
+ { "Tuesday", "zbee_zcl_hvac.thermostat.day.tuesday", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x04, NULL,
+ HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_day_wednesday,
+ { "Wednesday", "zbee_zcl_hvac.thermostat.day.wednesday", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x08, NULL,
+ HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_day_thursday,
+ { "Thursday", "zbee_zcl_hvac.thermostat.day.thursday", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x10, NULL,
+ HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_day_friday,
+ { "Friday", "zbee_zcl_hvac.thermostat.day.friday", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x20, NULL,
+ HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_day_saturday,
+ { "Saturday", "zbee_zcl_hvac.thermostat.day.saturday", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x40, NULL,
+ HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_day_vacation,
+ { "Away/Vacation", "zbee_zcl_hvac.thermostat.day.vacation", FT_BOOLEAN, 8, TFS(&tfs_true_false), 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, TFS(&tfs_true_false), 0x01, NULL, HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_mode_cool,
+ { "Cooling", "zbee_zcl_hvac.thermostat.mode.cool", FT_BOOLEAN, 8, TFS(&tfs_true_false), 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 Celcius", HFILL }},
+
+ { &hf_zbee_zcl_thermostat_schedule_cool,
+ { "Cooling Setpoint", "zbee_zcl_hvac.thermostat.cool", FT_FLOAT, BASE_NONE, NULL, 0x0,
+ "Cooling setpoint in degrees Celcius", HFILL }}
+ };
+
+ /* ZCL IAS Zone subtrees */
+ static gint *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. */
+ new_register_dissector(ZBEE_PROTOABBREV_ZCL_THERMOSTAT, dissect_zbee_zcl_thermostat, proto_zbee_zcl_thermostat);
+} /*proto_register_zbee_zcl_thermostat*/
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_reg_handoff_zbee_zcl_thermostat
+ * DESCRIPTION
+ * Hands off the ZCL Thermostat dissector.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * none
+ *---------------------------------------------------------------
+ */
+void
+proto_reg_handoff_zbee_zcl_thermostat(void)
+{
+ dissector_handle_t thermostat_handle;
+
+ /* Register our dissector with the ZigBee application dissectors. */
+ thermostat_handle = find_dissector(ZBEE_PROTOABBREV_ZCL_THERMOSTAT);
+ dissector_add_uint("zbee.zcl.cluster", ZBEE_ZCL_CID_THERMOSTAT, thermostat_handle);
+
+ zbee_zcl_init_cluster( proto_zbee_zcl_thermostat,
+ ett_zbee_zcl_thermostat,
+ ZBEE_ZCL_CID_THERMOSTAT,
+ 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 = -1;
+
+static int hf_zbee_zcl_ias_zone_attr_id = -1;
+static int hf_zbee_zcl_ias_zone_srv_rx_cmd_id = -1;
+static int hf_zbee_zcl_ias_zone_srv_tx_cmd_id = -1;
+static int hf_zbee_zcl_ias_zone_enroll_code = -1;
+static int hf_zbee_zcl_ias_zone_zone_id = -1;
+static int hf_zbee_zcl_ias_zone_state = -1;
+static int hf_zbee_zcl_ias_zone_type = -1;
+static int hf_zbee_zcl_ias_zone_status = -1;
+static int hf_zbee_zcl_ias_zone_delay = -1;
+static int hf_zbee_zcl_ias_zone_ext_status = -1;
+static int hf_zbee_zcl_ias_zone_status_ac_mains = -1;
+static int hf_zbee_zcl_ias_zone_status_alarm1 = -1;
+static int hf_zbee_zcl_ias_zone_status_alarm2 = -1;
+static int hf_zbee_zcl_ias_zone_status_battery = -1;
+static int hf_zbee_zcl_ias_zone_status_restore_reports = -1;
+static int hf_zbee_zcl_ias_zone_status_supervision_reports = -1;
+static int hf_zbee_zcl_ias_zone_status_tamper = -1;
+static int hf_zbee_zcl_ias_zone_status_trouble = -1;
+
+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 gint ett_zbee_zcl_ias_zone = -1;
+static gint ett_zbee_zcl_ias_zone_status = -1;
+
+/*************************/
+/* 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, guint *offset, guint16 attr_id, guint data_type);
+
+/* ZoneStatus bitmask helper */
+static void dissect_zcl_ias_zone_status (proto_tree *tree, tvbuff_t *tvb, guint offset);
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zcl_ias_zone_status
+ * DESCRIPTION
+ * Helper function to dissect the IAS ZoneStatus bitmask.
+ * PARAMETERS
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * guint offset - payload offset of the ZoneStatus value.
+ * RETURNS
+ * int - length of parsed data.
+ *---------------------------------------------------------------
+ */
+static void
+dissect_zcl_ias_zone_status(proto_tree *tree, tvbuff_t *tvb, guint offset)
+{
+ static const int * 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_NA);
+
+} /* dissect_zcl_ias_zone_status */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zcl_ias_zone
+ * DESCRIPTION
+ * ZigBee ZCL IAS Zone cluster dissector for wireshark.
+ * PARAMETERS
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * packet_info *pinfo - pointer to packet information fields
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * void *data - pointer to ZCL packet structure.
+ * RETURNS
+ * int - 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;
+ guint offset = 0;
+ guint8 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, cmd_id);
+ 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, cmd_id);
+ 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);
+
+ case ZBEE_ZCL_CMD_ID_IAS_ZONE_ENROLL_REQUEST:
+ default:
+ break;
+ } /* switch */
+ }
+
+ return tvb_captured_length(tvb);
+} /* dissect_zbee_zcl_ias_zone */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zcl_ias_zone_attr_data
+ * DESCRIPTION
+ * this function is called by ZCL foundation dissector in order to decode
+ * specific cluster attributes data.
+ * PARAMETERS
+ * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
+ * tvbuff_t *tvb - pointer to buffer containing raw packet.
+ * guint *offset - pointer to buffer offset
+ * guint16 attr_id - attribute identifier
+ * guint data_type - attribute data type
+ * RETURNS
+ * none
+ *---------------------------------------------------------------
+ */
+static void
+dissect_zcl_ias_zone_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type)
+{
+ /* 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);
+ break;
+ }
+} /*dissect_zcl_ias_zone_attr_data*/
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_reg_handoff_zbee_zcl_ias_zone
+ * DESCRIPTION
+ * Hands off the ZCL IAS Zone dissector.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * none
+ *---------------------------------------------------------------
+ */
+void
+proto_reg_handoff_zbee_zcl_ias_zone(void)
+{
+ dissector_handle_t zone_handle;
+
+ /* Register our dissector with the ZigBee application dissectors. */
+ zone_handle = find_dissector(ZBEE_PROTOABBREV_ZCL_IAS_ZONE);
+ dissector_add_uint("zbee.zcl.cluster", ZBEE_ZCL_CID_IAS_ZONE, zone_handle);
+
+ zbee_zcl_init_cluster( proto_zbee_zcl_ias_zone,
+ ett_zbee_zcl_ias_zone,
+ ZBEE_ZCL_CID_IAS_ZONE,
+ 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*/
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_register_zbee_zcl_ias_zone
+ * DESCRIPTION
+ * ZigBee ZCL IAS Zone cluste protocol registration.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+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_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 gint *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. */
+ new_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 - http://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:
+ */