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
This commit is contained in:
parent
035f3fc27a
commit
cf7ec9f1e9
1
AUTHORS
1
AUTHORS
|
@ -3736,6 +3736,7 @@ Hauke Mehrtens <hauke[AT]hauke-m.de>
|
|||
Peter Van Eynde <pevaneyn[AT]cisco.com>
|
||||
Marko Hrastovec <marko.hrastovec[AT]sloveniacontrol.si>
|
||||
Mike Garratt <mg.wireshark[AT]evn.co.nz>
|
||||
Fabio Tarabelloni <fabio.tarabelloni[AT]reloc.it>
|
||||
|
||||
Dan Lasley <dlasley[AT]promus.com> gave permission for his
|
||||
dumpit() hex-dump routine to be used.
|
||||
|
|
|
@ -1291,6 +1291,7 @@ set(DISSECTOR_SRC
|
|||
dissectors/packet-zbee-nwk.c
|
||||
dissectors/packet-zbee-security.c
|
||||
dissectors/packet-zbee-zcl.c
|
||||
dissectors/packet-zbee-zcl-on-off.c
|
||||
dissectors/packet-zbee-zdp-binding.c
|
||||
dissectors/packet-zbee-zdp-discovery.c
|
||||
dissectors/packet-zbee-zdp-management.c
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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*/
|
|
@ -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);
|
||||
|
||||
/* Don't decode cluster-specific commands */
|
||||
zcl_dump_data(tvb, offset, pinfo, zcl_tree);
|
||||
}
|
||||
|
||||
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);
|
||||
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,36 +1387,6 @@ 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
|
||||
* 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.
|
||||
* RETURNS
|
||||
* guint - attribute data type
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
static guint dissect_zcl_attr_data_type(tvbuff_t *tvb, proto_tree *tree, guint *offset)
|
||||
{
|
||||
guint attr_data_type;
|
||||
|
||||
/* Dissect attribute data type */
|
||||
attr_data_type = tvb_get_guint8(tvb, *offset);
|
||||
|
||||
if ( tree ) {
|
||||
proto_tree_add_uint(tree, hf_zbee_zcl_attr_data_type, tvb, *offset, (int)sizeof(guint8),
|
||||
attr_data_type);
|
||||
}
|
||||
*offset += (int)sizeof(guint8);
|
||||
|
||||
return attr_data_type;
|
||||
} /* dissect_zcl_attr_data_type */
|
||||
#endif
|
||||
|
||||
/*FUNCTION:------------------------------------------------------
|
||||
* NAME
|
||||
|
@ -1399,13 +1405,24 @@ static guint dissect_zcl_attr_data_type(tvbuff_t *tvb, proto_tree *tree, guint *
|
|||
*/
|
||||
static void dissect_zcl_attr_id(tvbuff_t *tvb, proto_tree *tree, guint *offset)
|
||||
{
|
||||
guint16 attr_id;
|
||||
guint16 attr_id;
|
||||
zbee_zcl_cluster_desc *desc;
|
||||
|
||||
attr_id = tvb_get_letohs(tvb, *offset);
|
||||
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);
|
||||
}
|
||||
else {
|
||||
/* Add the identifier */
|
||||
proto_tree_add_uint(tree,
|
||||
hf_zbee_zcl_attr_id,
|
||||
tvb,
|
||||
*offset,
|
||||
(int)sizeof(guint16),
|
||||
attr_id);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
@ -1424,14 +1441,54 @@ static void dissect_zcl_attr_id(tvbuff_t *tvb, proto_tree *tree, guint *offset)
|
|||
* void
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
static void dissect_zcl_attr_data_type_val(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)
|
||||
{
|
||||
dissect_zcl_attr_data(tvb, tree, offset,
|
||||
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,
|
||||
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_data_type_val */
|
||||
|
||||
|
||||
/*FUNCTION:------------------------------------------------------
|
||||
* NAME
|
||||
* 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_general(tvbuff_t *tvb, proto_tree *tree, guint *offset, guint16 attr_id, guint 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_general*/
|
||||
|
||||
/*FUNCTION:------------------------------------------------------
|
||||
* NAME
|
||||
* dissect_zcl_attr_data
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue