aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-05-25 01:45:16 +0000
committerEvan Huus <eapache@gmail.com>2013-05-25 01:45:16 +0000
commitcf7ec9f1e9a654345be4f89f312e92ea696bb3dd (patch)
treea03b8502bed98fc06600e907d4fef208b6af8ad5 /epan/dissectors
parent035f3fc27abd0eea0a132e43d25398751950774d (diff)
From Fabio Tarabelloni via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8387
ZigBee ZCL OnOff cluster dissection. Also, fix decryption of APS commands. svn path=/trunk/; revision=49571
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/Makefile.common1
-rw-r--r--epan/dissectors/packet-zbee-aps.c1
-rw-r--r--epan/dissectors/packet-zbee-aps.h2
-rw-r--r--epan/dissectors/packet-zbee-zcl-on-off.c241
-rw-r--r--epan/dissectors/packet-zbee-zcl.c279
-rw-r--r--epan/dissectors/packet-zbee-zcl.h18
-rw-r--r--epan/dissectors/packet-zbee.h17
7 files changed, 474 insertions, 85 deletions
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
index 8e0022961c..7929a7d4a6 100644
--- a/epan/dissectors/Makefile.common
+++ b/epan/dissectors/Makefile.common
@@ -1213,6 +1213,7 @@ DISSECTOR_SRC = \
packet-zbee-nwk.c \
packet-zbee-security.c \
packet-zbee-zcl.c \
+ packet-zbee-zcl-on-off.c \
packet-zbee-zdp-binding.c \
packet-zbee-zdp-discovery.c \
packet-zbee-zdp-management.c \
diff --git a/epan/dissectors/packet-zbee-aps.c b/epan/dissectors/packet-zbee-aps.c
index 79a1512251..c54bace73b 100644
--- a/epan/dissectors/packet-zbee-aps.c
+++ b/epan/dissectors/packet-zbee-aps.c
@@ -619,6 +619,7 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_item_append_text(proto_root, " %s", val_to_str_const(packet.type, zbee_aps_frame_types, "Unknown Type"));
}
col_clear(pinfo->cinfo, COL_INFO);
+ col_append_str(pinfo->cinfo, COL_INFO, "APS: ");
col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet.type, zbee_aps_frame_types, "Unknown Frame Type"));
/* Display the FCF */
diff --git a/epan/dissectors/packet-zbee-aps.h b/epan/dissectors/packet-zbee-aps.h
index ebd85408a5..889cc33412 100644
--- a/epan/dissectors/packet-zbee-aps.h
+++ b/epan/dissectors/packet-zbee-aps.h
@@ -211,7 +211,7 @@ typedef struct{
gboolean indirect_mode; /* ZigBee 2004 and Earlier */
guint8 type;
guint8 delivery;
- gboolean ack_format; /* ZigBee 2007 and Later */
+ gboolean ack_format; /* ZigBee 2007 and Later */
gboolean security;
gboolean ack_req;
gboolean ext_header; /* ZigBee 2007 and Later */
diff --git a/epan/dissectors/packet-zbee-zcl-on-off.c b/epan/dissectors/packet-zbee-zcl-on-off.c
new file mode 100644
index 0000000000..caa498b405
--- /dev/null
+++ b/epan/dissectors/packet-zbee-zcl-on-off.c
@@ -0,0 +1,241 @@
+/* packet-zbee-zcl-on-off.c
+ * Dissector routines for the ZigBee ZCL On Off cluster
+ * By Fabio Tarabelloni <fabio.tarabelloni@reloc.it>
+ * Copyright 2012 RELOC s.r.l.
+ *
+ * $Id$
+ *
+ * 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 "packet-zbee.h"
+#include "packet-zbee-aps.h"
+#include "packet-zbee-zcl.h"
+
+/*************************/
+/* Defines */
+/*************************/
+
+/* Attributes */
+#define ZBEE_ZCL_ON_OFF_ATTR_ID_ONOFF 0x0000
+
+/* Server Commands Received */
+#define ZBEE_ZCL_ON_OFF_CMD_OFF 0x00 /* Off */
+#define ZBEE_ZCL_ON_OFF_CMD_ON 0x01 /* On */
+#define ZBEE_ZCL_ON_OFF_CMD_TOGGLE 0x02 /* Toggle */
+
+/*************************/
+/* Function Declarations */
+/*************************/
+
+void proto_reg_handoff_zbee_zcl_on_off(void);
+
+/* Command Dissector Helpers */
+
+/* Private functions prototype */
+static void dissect_zcl_on_off_attr_id (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id);
+static void dissect_zcl_on_off_attr_data (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type);
+
+/********************
+ * Global Variables *
+ ********************/
+
+/* Initialize the protocol and registered fields */
+static int proto_zbee_zcl_on_off = -1;
+
+static int hf_zbee_zcl_on_off_attr_id = -1;
+static int hf_zbee_zcl_on_off_attr_onoff = -1;
+static int hf_zbee_zcl_on_off_srv_rx_cmd_id = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_zbee_zcl_on_off = -1;
+
+/* Attributes */
+static const value_string zbee_zcl_on_off_attr_names[] = {
+ { ZBEE_ZCL_ON_OFF_ATTR_ID_ONOFF, "OnOff" },
+ { 0, NULL }
+};
+
+/* Server Commands Generated */
+static const value_string zbee_zcl_on_off_srv_rx_cmd_names[] = {
+ { ZBEE_ZCL_ON_OFF_CMD_OFF, "Off" },
+ { ZBEE_ZCL_ON_OFF_CMD_ON, "On" },
+ { ZBEE_ZCL_ON_OFF_CMD_TOGGLE, "Toggle" },
+ { 0, NULL }
+};
+
+/* OnOff Names */
+static const value_string zbee_zcl_on_off_onoff_names[] = {
+ { 0, "Off" },
+ { 1, "On" },
+ { 0, NULL }
+};
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zbee_zcl_onoff
+ * DESCRIPTION
+ * ZigBee ZCL OnOff 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.
+ * RETURNS
+ * none
+ *---------------------------------------------------------------
+ */
+static void
+dissect_zbee_zcl_on_off(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ zbee_zcl_packet *zcl = (zbee_zcl_packet *)pinfo->private_data;
+ guint offset = 0;
+ guint8 cmd_id = zcl->cmd_id;
+
+ /* Create a subtree for the ZCL Command frame, and add the command ID to it. */
+ if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
+ if (tree) {
+ /* Add the command ID. */
+ proto_tree_add_item(tree, hf_zbee_zcl_on_off_srv_rx_cmd_id, tvb, offset, sizeof(guint8), cmd_id);
+ }
+ offset += (int)sizeof(guint8);
+
+ /* 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_on_off_srv_rx_cmd_names, "Unknown Command"),
+ zcl->tran_seqno);
+ }
+}
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zcl_on_off_attr_id
+ * DESCRIPTION
+ * PARAMETERS
+ * RETURNS
+ * none
+ *---------------------------------------------------------------
+ */
+void
+dissect_zcl_on_off_attr_id(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id)
+{
+ proto_tree_add_item(tree, hf_zbee_zcl_on_off_attr_id, tvb, *offset, sizeof(guint16), attr_id);
+} /*dissect_zcl_on_off_attr_id*/
+
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * dissect_zcl_on_off_attr_data
+ * DESCRIPTION
+ * PARAMETERS
+ * RETURNS
+ * none
+ *---------------------------------------------------------------
+ */
+void
+dissect_zcl_on_off_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_ON_OFF_ATTR_ID_ONOFF:
+ proto_tree_add_item(tree, hf_zbee_zcl_on_off_attr_onoff, tvb, *offset, sizeof(guint8), ENC_NA);
+ *offset += (int)sizeof(guint8);
+ break;
+
+ default:
+ dissect_zcl_attr_data(tvb, tree, offset, data_type);
+ break;
+ }
+
+} /*dissect_zcl_on_off_attr_data*/
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_register_zbee_zcl_on_off
+ * DESCRIPTION
+ * ZigBee ZCL OnOff cluster protocol registration routine.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+proto_register_zbee_zcl_on_off(void)
+{
+ /* Setup list of header fields */
+ static hf_register_info hf[] = {
+
+ { &hf_zbee_zcl_on_off_attr_id,
+ { "Attribute", "zbee.zcl.on_off.attr.id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_on_off_attr_names),
+ 0x00, NULL, HFILL }},
+
+ { &hf_zbee_zcl_on_off_attr_onoff,
+ { "Data Value", "zbee.zcl.on_off.attr.onoff", FT_UINT8, BASE_HEX, VALS(zbee_zcl_on_off_onoff_names),
+ 0x00, NULL, HFILL }},
+
+ { &hf_zbee_zcl_on_off_srv_rx_cmd_id,
+ { "Command", "zbee.zcl.on_off.srv_rx.cmd.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_on_off_srv_rx_cmd_names),
+ 0x00, NULL, HFILL }}
+
+ };
+
+ /* Register the ZigBee ZCL OnOff cluster protocol name and description */
+ proto_zbee_zcl_on_off = proto_register_protocol("ZigBee ZCL OnOff", "ZCL OnOff", ZBEE_PROTOABBREV_ZCL_ONOFF);
+ proto_register_field_array(proto_zbee_zcl_on_off, hf, array_length(hf));
+
+ /* Register the ZigBee ZCL Power Profile dissector. */
+ register_dissector(ZBEE_PROTOABBREV_ZCL_ONOFF, dissect_zbee_zcl_on_off, proto_zbee_zcl_on_off);
+} /* proto_register_zbee_zcl_on_off */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * proto_reg_handoff_zbee_zcl_on_off
+ * DESCRIPTION
+ * Hands off the Zcl Power Profile cluster dissector.
+ * PARAMETERS
+ * none
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+proto_reg_handoff_zbee_zcl_on_off(void)
+{
+ dissector_handle_t on_off_handle;
+
+ /* Register our dissector with the ZigBee application dissectors. */
+ on_off_handle = find_dissector(ZBEE_PROTOABBREV_ZCL_ONOFF);
+
+ dissector_add_uint("zbee.zcl.cluster", ZBEE_ZCL_CID_ON_OFF, on_off_handle);
+ zbee_zcl_init_cluster( proto_zbee_zcl_on_off,
+ ett_zbee_zcl_on_off,
+ ZBEE_ZCL_CID_ON_OFF,
+ (zbee_zcl_fn_attr_id)dissect_zcl_on_off_attr_id,
+ (zbee_zcl_fn_attr_data)dissect_zcl_on_off_attr_data
+ );
+} /*proto_reg_handoff_zbee_zcl_on_off*/
diff --git a/epan/dissectors/packet-zbee-zcl.c b/epan/dissectors/packet-zbee-zcl.c
index 7b532f0786..ab02a62fdd 100644
--- a/epan/dissectors/packet-zbee-zcl.c
+++ b/epan/dissectors/packet-zbee-zcl.c
@@ -34,6 +34,7 @@
#include <epan/packet.h>
#include "packet-zbee.h"
+#include "packet-zbee-aps.h"
#include "packet-zbee-zcl.h"
/*************************
@@ -64,11 +65,8 @@ static void dissect_zcl_discover_attr_resp (tvbuff_t *tvb, packet_info *pinfo, p
/* Helper routines */
guint zbee_apf_transaction_len (tvbuff_t *tvb, guint offset, guint8 type);
-static void dissect_zcl_attr_data_type_val (tvbuff_t *tvb, proto_tree *tree, guint *offset);
-#if 0
-static guint dissect_zcl_attr_data_type (tvbuff_t *tvb, proto_tree *tree, guint *offset);
-#endif
-static void dissect_zcl_attr_data (tvbuff_t *tvb, proto_tree *tree, guint *offset, guint data_type);
+static void dissect_zcl_attr_data_general(tvbuff_t *tvb, proto_tree *tree, guint *offset, guint16 attr_id, guint data_type);
+static void dissect_zcl_attr_data_type_val (tvbuff_t *tvb, proto_tree *tree, guint *offset, guint16 cmd_id);
static void dissect_zcl_attr_bytes (tvbuff_t *tvb, proto_tree *tree, guint *offset, guint length);
static guint dissect_zcl_attr_uint8 (tvbuff_t *tvb, proto_tree *tree, guint *offset, int *length);
static guint dissect_zcl_attr_uint16 (tvbuff_t *tvb, proto_tree *tree, guint *offset, int *length);
@@ -146,6 +144,14 @@ static gint ett_zbee_zcl_array_elements[ZBEE_ZCL_NUM_ARRAY_ELEM_ETT];
/* Dissector Handles. */
static dissector_handle_t data_handle;
+/* Dissector List. */
+static dissector_table_t zbee_zcl_dissector_table;
+
+/* Global variables */
+static guint16 zcl_cluster_id = -1;
+
+static GList *acluster_desc = NULL;
+
/********************/
/* Field Names */
/********************/
@@ -407,7 +413,7 @@ static const value_string zbee_mfr_code_names[] = {
{ 0x10ca, "Unknown" }, /**/
{ 0x10cb, "Unknown" }, /**/
{ ZBEE_MFG_CODE_MAINSTREAM, ZBEE_MFG_MAINSTREAM },
- { 0x10cd, "Unknown" }, /**/
+ { ZBEE_MFG_CODE_INDESIT_C, ZBEE_MFG_INDESIT_C },
{ 0x10ce, "Unknown" }, /**/
{ 0x10cf, "Unknown" }, /**/
{ 0x10d0, "Unknown" }, /**/
@@ -458,7 +464,7 @@ static const value_string zbee_mfr_code_names[] = {
{ 0x10fd, "Unknown" }, /**/
{ 0x10fe, "Unknown" }, /**/
{ 0x10ff, "Unknown" }, /**/
-
+ { ZBEE_MFG_CODE_RELOC, ZBEE_MFG_RELOC },
{ 0, NULL }
};
static value_string_ext zbee_mfr_code_names_ext = VALUE_STRING_EXT_INIT(zbee_mfr_code_names);
@@ -693,6 +699,9 @@ static const value_string zbee_zcl_dis_names[] = {
*/
static void dissect_zbee_zcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
+ tvbuff_t *payload_tvb = NULL;
+ dissector_handle_t cluster_handle = NULL;
+
proto_tree *zcl_tree = NULL;
proto_tree *sub_tree = NULL;
@@ -700,13 +709,18 @@ static void dissect_zbee_zcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
proto_item *ti;
zbee_zcl_packet packet;
-
+ zbee_zcl_cluster_desc *desc;
+
guint8 fcf;
guint offset = 0;
/* Init. */
memset(&packet, 0, sizeof(zbee_zcl_packet));
-
+
+ /* Fill the zcl cluster id */
+ zcl_cluster_id = pinfo->zbee_cluster_id;
+ cluster_handle = dissector_get_uint_handle(zbee_zcl_dissector_table, zcl_cluster_id);
+
/* Create the protocol tree */
if ( tree ) {
proto_root = proto_tree_add_protocol_format(tree, proto_zbee_zcl, tvb, offset,
@@ -769,13 +783,18 @@ static void dissect_zbee_zcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
if ( zcl_tree ) {
proto_tree_add_uint(zcl_tree, hf_zbee_zcl_tran_seqno, tvb, offset, (int)sizeof(guint8),
- packet.tran_seqno);
+ packet.tran_seqno);
}
offset += (int)sizeof(guint8);
/* Display the command and sequence number on the proto root and info column. */
packet.cmd_id = tvb_get_guint8(tvb, offset);
+ desc = zbee_zcl_get_cluster_desc(zcl_cluster_id);
+ if (desc != NULL) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s: ", desc->name);
+ }
+
/* Add command ID to the tree. */
if ( packet.frame_type == ZBEE_ZCL_FCF_PROFILE_WIDE ) {
if ( tree ) {
@@ -783,37 +802,46 @@ static void dissect_zbee_zcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
val_to_str_ext_const(packet.cmd_id, &zbee_zcl_cmd_names_ext, "Unknown Command"),
packet.tran_seqno);
}
-
- if ( check_col(pinfo->cinfo, COL_INFO) ) {
- col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
- val_to_str_ext_const(packet.cmd_id, &zbee_zcl_cmd_names_ext, "Unknown Command"),
- packet.tran_seqno);
- }
-
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
+ val_to_str_ext_const(packet.cmd_id, &zbee_zcl_cmd_names_ext, "Unknown Command"),
+ packet.tran_seqno);
+
if ( zcl_tree ) {
proto_tree_add_uint(zcl_tree, hf_zbee_zcl_cmd_id, tvb, offset, (int)sizeof(guint8),
packet.cmd_id);
}
offset += (int)sizeof(guint8);
- } else {
- if ( tree ) {
- proto_item_append_text(proto_root, ", Cluster-specific Command: 0x%02x, Seq: %u",
- packet.cmd_id, packet.tran_seqno);
+ }
+ else {
+ /* Cluster Specific */
+ payload_tvb = tvb_new_subset_remaining(tvb, offset);
+
+ if (cluster_handle != NULL) {
+ /* Call the specific cluster dissector registered */
+ pinfo->private_data = (void *)&packet;
+ call_dissector(cluster_handle, payload_tvb, pinfo, zcl_tree);
}
+ else {
+ if ( tree ) {
+ proto_item_append_text(proto_root, ", Cluster-specific Command: 0x%02x, Seq: %u",
+ packet.cmd_id, packet.tran_seqno);
+ }
- if ( check_col(pinfo->cinfo, COL_INFO) ) {
- col_append_fstr(pinfo->cinfo, COL_INFO, "Command: 0x%02x, Seq: %u",
- packet.cmd_id, packet.tran_seqno);
- }
+ if ( check_col(pinfo->cinfo, COL_INFO) ) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Command: 0x%02x, Seq: %u",
+ packet.cmd_id, packet.tran_seqno);
+ }
- if ( zcl_tree ) {
- proto_tree_add_uint(zcl_tree, hf_zbee_zcl_cs_cmd_id, tvb, offset, (int)sizeof(guint8),
- packet.cmd_id);
- }
- offset += (int)sizeof(guint8);
+ if ( zcl_tree ) {
+ proto_tree_add_uint(zcl_tree, hf_zbee_zcl_cs_cmd_id, tvb, offset, (int)sizeof(guint8),
+ packet.cmd_id);
+ }
+ offset += (int)sizeof(guint8);
- /* Don't decode cluster-specific commands */
- zcl_dump_data(tvb, offset, pinfo, zcl_tree);
+ /* Don't decode cluster-specific commands */
+ zcl_dump_data(tvb, offset, pinfo, zcl_tree);
+ }
return;
}
@@ -929,7 +957,8 @@ static void dissect_zcl_read_attr_resp(tvbuff_t *tvb, packet_info *pinfo _U_, pr
guint tvb_len;
guint i = 0;
-
+ guint16 attr_id;
+
tvb_len = tvb_length(tvb);
while ( *offset < tvb_len && i < ZBEE_ZCL_NUM_ATTR_ETT ) {
@@ -939,6 +968,7 @@ static void dissect_zcl_read_attr_resp(tvbuff_t *tvb, packet_info *pinfo _U_, pr
i++;
/* Dissect the attribute identifier */
+ attr_id = tvb_get_letohs(tvb, *offset);
dissect_zcl_attr_id(tvb, sub_tree, offset);
/* Dissect the status and optionally the data type and value */
@@ -946,7 +976,7 @@ static void dissect_zcl_read_attr_resp(tvbuff_t *tvb, packet_info *pinfo _U_, pr
== ZBEE_ZCL_STAT_SUCCESS ) {
/* Dissect the attribute data type and data */
- dissect_zcl_attr_data_type_val(tvb, sub_tree, offset);
+ dissect_zcl_attr_data_type_val(tvb, sub_tree, offset, attr_id);
}
}
@@ -974,7 +1004,8 @@ static void dissect_zcl_write_attr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
guint tvb_len;
guint i = 0;
-
+ guint16 attr_id;
+
tvb_len = tvb_length(tvb);
while ( *offset < tvb_len && i < ZBEE_ZCL_NUM_ATTR_ETT ) {
@@ -984,10 +1015,11 @@ static void dissect_zcl_write_attr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
i++;
/* Dissect the attribute identifier */
+ attr_id = tvb_get_letohs(tvb, *offset);
dissect_zcl_attr_id(tvb, sub_tree, offset);
/* Dissect the attribute data type and data */
- dissect_zcl_attr_data_type_val(tvb, sub_tree, offset);
+ dissect_zcl_attr_data_type_val(tvb, sub_tree, offset, attr_id);
}
return;
@@ -1058,6 +1090,7 @@ static void dissect_zcl_read_report_config_resp(tvbuff_t *tvb, packet_info *pinf
guint data_type;
guint attr_status;
guint attr_dir;
+ guint16 attr_id;
tvb_len = tvb_length(tvb);
while ( *offset < tvb_len && i < ZBEE_ZCL_NUM_ATTR_ETT ) {
@@ -1074,6 +1107,7 @@ static void dissect_zcl_read_report_config_resp(tvbuff_t *tvb, packet_info *pinf
attr_dir = dissect_zcl_attr_uint8(tvb, sub_tree, offset, &hf_zbee_zcl_attr_dir);
/* Dissect the attribute id */
+ attr_id = tvb_get_letohs(tvb, *offset);
dissect_zcl_attr_id(tvb, sub_tree, offset);
if ( attr_status == ZBEE_ZCL_STAT_SUCCESS ) {
@@ -1091,7 +1125,7 @@ static void dissect_zcl_read_report_config_resp(tvbuff_t *tvb, packet_info *pinf
if ( IS_ANALOG_SUBTYPE(data_type) ) {
/* Dissect reportable change */
- dissect_zcl_attr_data(tvb, sub_tree, offset, data_type);
+ dissect_zcl_attr_data_general(tvb, sub_tree, offset, attr_id, data_type);
}
} else {
@@ -1124,6 +1158,7 @@ static void dissect_zcl_config_report(tvbuff_t *tvb, packet_info *pinfo _U_, pro
guint tvb_len;
guint i = 0;
guint data_type;
+ guint16 attr_id;
tvb_len = tvb_length(tvb);
while ( *offset < tvb_len && i < ZBEE_ZCL_NUM_ATTR_ETT ) {
@@ -1138,6 +1173,7 @@ static void dissect_zcl_config_report(tvbuff_t *tvb, packet_info *pinfo _U_, pro
== ZBEE_ZCL_DIR_REPORTED ) {
/* Dissect the attribute id */
+ attr_id = tvb_get_letohs(tvb, *offset);
dissect_zcl_attr_id(tvb, sub_tree, offset);
/* Dissect the attribute data type */
@@ -1151,7 +1187,7 @@ static void dissect_zcl_config_report(tvbuff_t *tvb, packet_info *pinfo _U_, pro
if ( IS_ANALOG_SUBTYPE(data_type) ) {
/* Dissect reportable change */
- dissect_zcl_attr_data(tvb, sub_tree, offset, data_type);
+ dissect_zcl_attr_data_general(tvb, sub_tree, offset, attr_id, data_type);
}
} else {
@@ -1351,44 +1387,52 @@ static void dissect_zcl_discover_attr_resp(tvbuff_t *tvb, packet_info *pinfo _U_
return;
} /* dissect_zcl_discover_attr_resp */
-#if 0
+
/*FUNCTION:------------------------------------------------------
* NAME
- * dissect_zcl_attr_data_type
+ * dissect_zcl_attr_id
* DESCRIPTION
- * Helper dissector for ZCL Attribute commands.
+ * Dissects Attribute ID field. This could be done with the
+ * dissect_zcl_attr_uint16 function, but we leave it separate
+ * so we can dissect the attr_id with a hash in the future.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* proto_tree *tree - pointer to data tree wireshark uses to display packet.
* offset - offset into the tvb to begin dissection.
* RETURNS
- * guint - attribute data type
+ * void
*---------------------------------------------------------------
*/
-static guint dissect_zcl_attr_data_type(tvbuff_t *tvb, proto_tree *tree, guint *offset)
+static void dissect_zcl_attr_id(tvbuff_t *tvb, proto_tree *tree, guint *offset)
{
- guint attr_data_type;
-
- /* Dissect attribute data type */
- attr_data_type = tvb_get_guint8(tvb, *offset);
+ guint16 attr_id;
+ zbee_zcl_cluster_desc *desc;
- if ( tree ) {
- proto_tree_add_uint(tree, hf_zbee_zcl_attr_data_type, tvb, *offset, (int)sizeof(guint8),
- attr_data_type);
+ attr_id = tvb_get_letohs(tvb, *offset);
+ desc = zbee_zcl_get_cluster_desc(zcl_cluster_id);
+ if ((desc != NULL) && (desc->fn_attr_id != NULL)) {
+ desc->fn_attr_id(tree, tvb, offset, attr_id);
}
- *offset += (int)sizeof(guint8);
+ else {
+ /* Add the identifier */
+ proto_tree_add_uint(tree,
+ hf_zbee_zcl_attr_id,
+ tvb,
+ *offset,
+ (int)sizeof(guint16),
+ attr_id);
+ }
+
+ *offset += (int)sizeof(guint16);
- return attr_data_type;
-} /* dissect_zcl_attr_data_type */
-#endif
+ return;
+} /* dissect_zcl_attr_id */
/*FUNCTION:------------------------------------------------------
* NAME
- * dissect_zcl_attr_id
+ * dissect_zcl_attr_data_type_val
* DESCRIPTION
- * Dissects Attribute ID field. This could be done with the
- * dissect_zcl_attr_uint16 function, but we leave it separate
- * so we can dissect the attr_id with a hash in the future.
+ * Helper dissector for ZCL Attribute commands.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* proto_tree *tree - pointer to data tree wireshark uses to display packet.
@@ -1397,40 +1441,53 @@ static guint dissect_zcl_attr_data_type(tvbuff_t *tvb, proto_tree *tree, guint *
* void
*---------------------------------------------------------------
*/
-static void dissect_zcl_attr_id(tvbuff_t *tvb, proto_tree *tree, guint *offset)
+static void dissect_zcl_attr_data_type_val(tvbuff_t *tvb, proto_tree *tree, guint *offset, guint16 attr_id)
{
- guint16 attr_id;
-
- attr_id = tvb_get_letohs(tvb, *offset);
+ zbee_zcl_cluster_desc *desc;
- /* Add the identifier */
- proto_tree_add_uint(tree, hf_zbee_zcl_attr_id, tvb, *offset, (int)sizeof(guint16),
- attr_id);
- *offset += (int)sizeof(guint16);
+ desc = zbee_zcl_get_cluster_desc(zcl_cluster_id);
+ if ((desc != NULL) && (desc->fn_attr_data != NULL)) {
+ desc->fn_attr_data(tree, tvb, offset, attr_id,
+ dissect_zcl_attr_uint8(tvb, tree, offset, &hf_zbee_zcl_attr_data_type));
+ }
+ else {
+ dissect_zcl_attr_data(tvb, tree, offset,
+ dissect_zcl_attr_uint8(tvb, tree, offset, &hf_zbee_zcl_attr_data_type) );
+ }
return;
-} /* dissect_zcl_attr_id */
+} /* dissect_zcl_attr_data_type_val */
+
/*FUNCTION:------------------------------------------------------
* NAME
- * dissect_zcl_attr_data_type_val
+ * dissect_zcl_attr_data_general
* DESCRIPTION
* Helper dissector for ZCL Attribute commands.
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* proto_tree *tree - pointer to data tree wireshark uses to display packet.
* offset - offset into the tvb to begin dissection.
+ * attr_id - attribute identification
+ * data_type - type of data
* RETURNS
* void
*---------------------------------------------------------------
*/
-static void dissect_zcl_attr_data_type_val(tvbuff_t *tvb, proto_tree *tree, guint *offset)
+static void dissect_zcl_attr_data_general(tvbuff_t *tvb, proto_tree *tree, guint *offset, guint16 attr_id, guint data_type)
{
- dissect_zcl_attr_data(tvb, tree, offset,
- dissect_zcl_attr_uint8(tvb, tree, offset, &hf_zbee_zcl_attr_data_type) );
+ zbee_zcl_cluster_desc *desc;
+
+ desc = zbee_zcl_get_cluster_desc(zcl_cluster_id);
+ if ((desc != NULL) && (desc->fn_attr_data != NULL)) {
+ desc->fn_attr_data(tree, tvb, offset, attr_id, data_type);
+ }
+ else {
+ dissect_zcl_attr_data(tvb, tree, offset, data_type);
+ }
return;
-} /* dissect_zcl_attr_data_type_val */
+} /*dissect_zcl_attr_data_general*/
/*FUNCTION:------------------------------------------------------
* NAME
@@ -1447,7 +1504,7 @@ static void dissect_zcl_attr_data_type_val(tvbuff_t *tvb, proto_tree *tree, guin
* void
*---------------------------------------------------------------
*/
-static void dissect_zcl_attr_data(tvbuff_t *tvb, proto_tree *tree, guint *offset, guint data_type)
+void dissect_zcl_attr_data(tvbuff_t *tvb, proto_tree *tree, guint *offset, guint data_type)
{
guint attr_uint;
gint attr_int;
@@ -2023,6 +2080,8 @@ static void zcl_dump_data(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto
remainder = tvb_new_subset(tvb, offset, length, length);
call_dissector(data_handle, remainder, pinfo, root);
}
+
+ return;
} /* zcl_dump_data */
/*FUNCTION:------------------------------------------------------
@@ -2171,12 +2230,6 @@ void proto_register_zbee_zcl(void)
{ "Int64", "zbee_zcl.attr.int64", FT_INT64, BASE_DEC, NULL, 0x0,
NULL, HFILL }},
-#if 0
- { &hf_zbee_zcl_attr_semi,
- { "Semi Float", "zbee_zcl.attr.float", FT_FLOAT, BASE_NONE, NULL, 0x0,
- NULL, HFILL }},
-#endif
-
{ &hf_zbee_zcl_attr_float,
{ "Float", "zbee_zcl.attr.float", FT_FLOAT, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
@@ -2303,7 +2356,8 @@ void proto_register_zbee_zcl(void)
proto_register_subtree_array(ett, array_length(ett));
/* Register the ZCL dissector and subdissector list. */
- register_dissector("zbee_zcl", dissect_zbee_zcl, proto_zbee_zcl);
+ zbee_zcl_dissector_table = register_dissector_table("zbee.zcl.cluster", "ZigBee ZCL Cluster ID", FT_UINT16, BASE_HEX);
+ register_dissector(ZBEE_PROTOABBREV_ZCL, dissect_zbee_zcl, proto_zbee_zcl);
} /* proto_register_zbee_zcl */
@@ -2326,7 +2380,7 @@ void proto_reg_handoff_zbee_zcl(void)
data_handle = find_dissector("data");
/* Register our dissector for the appropriate profiles. */
- zbee_zcl_handle = find_dissector("zbee_zcl");
+ zbee_zcl_handle = find_dissector(ZBEE_PROTOABBREV_ZCL);
dissector_add_uint("zbee.profile", ZBEE_PROFILE_IPM, zbee_zcl_handle);
dissector_add_uint("zbee.profile", ZBEE_PROFILE_T1, zbee_zcl_handle);
dissector_add_uint("zbee.profile", ZBEE_PROFILE_HA, zbee_zcl_handle);
@@ -2338,3 +2392,66 @@ void proto_reg_handoff_zbee_zcl(void)
dissector_add_uint("zbee.profile", ZBEE_PROFILE_C4_CL, zbee_zcl_handle);
} /* proto_reg_handoff_zbee_zcl */
+
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * zbee_zcl_init_cluster
+ * DESCRIPTION
+ * Register the specific cluster.
+ * PARAMETERS
+ * proto - dissector proto
+ * ett - ett proto (not used at the moment)
+ * cluster_id - cluster id
+ * fn_attr_id - specific cluster attribute id decode function
+ * fn_attr_data - specific cluster attribute data decode function
+ * RETURNS
+ * void
+ *---------------------------------------------------------------
+ */
+void
+zbee_zcl_init_cluster(int proto, gint ett, guint16 cluster_id, zbee_zcl_fn_attr_id fn_attr_id, zbee_zcl_fn_attr_data fn_attr_data)
+{
+ zbee_zcl_cluster_desc *cluster_desc;
+ cluster_desc = g_new(zbee_zcl_cluster_desc, 1);
+
+ cluster_desc->proto = find_protocol_by_id(proto);
+ cluster_desc->name = proto_get_protocol_short_name(cluster_desc->proto);
+ cluster_desc->cluster_id = cluster_id;
+ cluster_desc->fn_attr_id = fn_attr_id;
+ cluster_desc->fn_attr_data = fn_attr_data;
+ acluster_desc = g_list_append(acluster_desc, cluster_desc);
+
+ cluster_desc->proto_id = proto;
+ cluster_desc->ett = ett;
+
+ return;
+}
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
+ * zbee_zcl_get_cluster_desc
+ * DESCRIPTION
+ * Retrieves the registered specific cluster descriptor.
+ * PARAMETERS
+ * cluster_id - cluster id
+ * RETURNS
+ * zbee_zcl_cluster_desc - cluster descriptor pointer
+ *---------------------------------------------------------------
+ */
+zbee_zcl_cluster_desc
+*zbee_zcl_get_cluster_desc(guint16 cluster_id)
+{
+ GList *gl;
+ gl = acluster_desc;
+
+ while (gl) {
+ zbee_zcl_cluster_desc *cluster_desc = (zbee_zcl_cluster_desc *)gl->data;
+ if(cluster_desc->cluster_id == cluster_id) {
+ return cluster_desc;
+ }
+ gl = gl->next;
+ }
+
+ return NULL;
+}
diff --git a/epan/dissectors/packet-zbee-zcl.h b/epan/dissectors/packet-zbee-zcl.h
index d8e9a181f5..6665710da5 100644
--- a/epan/dissectors/packet-zbee-zcl.h
+++ b/epan/dissectors/packet-zbee-zcl.h
@@ -176,4 +176,22 @@ typedef struct{
#define MONTHS_PER_YEAR 12
#define YEAR_OFFSET 1900
+typedef void (*zbee_zcl_fn_attr_id) (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id);
+typedef void (*zbee_zcl_fn_attr_data) (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type);
+
+typedef struct _zbee_zcl_cluster_desc {
+ int proto_id;
+ protocol_t *proto;
+ const char *name;
+ int ett;
+ guint16 cluster_id;
+ zbee_zcl_fn_attr_id fn_attr_id;
+ zbee_zcl_fn_attr_data fn_attr_data;
+} zbee_zcl_cluster_desc;
+
+
+void dissect_zcl_attr_data (tvbuff_t *tvb, proto_tree *tree, guint *offset, guint data_type);
+void zbee_zcl_init_cluster(int proto, gint ett, guint16 cluster_id, zbee_zcl_fn_attr_id fn_attr_id, zbee_zcl_fn_attr_data fn_attr_data);
+zbee_zcl_cluster_desc *zbee_zcl_get_cluster_desc(guint16 cluster_id);
+
#endif /* PACKET_ZBEE_ZCL_H*/
diff --git a/epan/dissectors/packet-zbee.h b/epan/dissectors/packet-zbee.h
index 84ac504094..e8e7c15c72 100644
--- a/epan/dissectors/packet-zbee.h
+++ b/epan/dissectors/packet-zbee.h
@@ -398,6 +398,9 @@
#define ZBEE_ZCL_FCF_PROFILE_WIDE 0x00
#define ZBEE_ZCL_FCF_CLUSTER_SPEC 0x01
+#define ZBEE_ZCL_FCF_TO_SERVER 0x00
+#define ZBEE_ZCL_FCF_TO_CLIENT 0x01
+
/* Manufacturer Codes */
/* Codes less than 0x1000 were issued for RF4CE */
#define ZBEE_MFG_CODE_SAMSUNG 0x0003
@@ -574,6 +577,7 @@
/**/
/**/
#define ZBEE_MFG_CODE_MAINSTREAM 0x10cc
+#define ZBEE_MFG_CODE_INDESIT_C 0x10cd
/**/
#define ZBEE_MFG_CODE_RADIOCRAFTS 0x10dd
/**/
@@ -585,6 +589,8 @@
#define ZBEE_MFG_CODE_ABB 0x10eb
/**/
#define ZBEE_MFG_CODE_GENUS 0x10ed
+/**/
+#define ZBEE_MFG_CODE_RELOC 0x1114
/* Manufacturer Names */
#define ZBEE_MFG_CIRRONET "Cirronet"
@@ -762,6 +768,7 @@
#define ZBEE_MFG_SAMSUNG "Samsung Electronics Co., Ltd."
/**/
#define ZBEE_MFG_MAINSTREAM "Mainstream Engineering"
+#define ZBEE_MFG_INDESIT_C "Indesit Company"
/**/
#define ZBEE_MFG_RADIOCRAFTS "Radiocrafts AS"
/**/
@@ -772,11 +779,15 @@
#define ZBEE_MFG_ABB "ABB"
/**/
#define ZBEE_MFG_GENUS "Genus Power Infrastructures Limited"
+/**/
+#define ZBEE_MFG_RELOC "RELOC"
/* Protocol Abbreviations */
-#define ZBEE_PROTOABBREV_NWK "zbee_nwk"
-#define ZBEE_PROTOABBREV_APS "zbee_aps"
-#define ZBEE_PROTOABBREV_APF "zbee_apf"
+#define ZBEE_PROTOABBREV_NWK "zbee_nwk"
+#define ZBEE_PROTOABBREV_APS "zbee_aps"
+#define ZBEE_PROTOABBREV_APF "zbee_apf"
+#define ZBEE_PROTOABBREV_ZCL "zbee_zcl"
+#define ZBEE_PROTOABBREV_ZCL_ONOFF "zbee_zcl_onoff"
/* Helper Functions */
extern guint zbee_get_bit_field(guint input, guint mask);