forked from osmocom/wireshark
![Martin Mathieson](/assets/img/avatar_default.png)
Fifth batch (packet-rtp.c -> end). Will look at cleaning up and committing script afterwards. Change-Id: I8ed61dc941d98d3f7259a9d1f74e214eb7b4bfa2 Reviewed-on: https://code.wireshark.org/review/6052 Reviewed-by: Martin Mathieson <martin.r.mathieson@googlemail.com>
1114 lines
47 KiB
C
1114 lines
47 KiB
C
/* 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 <epan/packet.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:
|
|
*/
|