From Fabio Tarabelloni via

https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8718

Zigbee partition cluster dissector.

svn path=/trunk/; revision=50089
This commit is contained in:
Evan Huus 2013-06-20 21:52:22 +00:00
parent 2b3b994b01
commit 176be6b481
6 changed files with 635 additions and 6 deletions

View File

@ -504,9 +504,14 @@ const value_string zbee_aps_cid_names[] = {
{ ZBEE_ZCL_CID_MULTISTATE_OUTPUT_BASIC, "Multistate Output (Basic)"},
{ ZBEE_ZCL_CID_MULTISTATE_VALUE_BASIC, "Multistate Value (Basic)"},
{ ZBEE_ZCL_CID_COMMISSIONING, "Commissioning"},
{ ZBEE_ZCL_CID_PARTITION, "Partition"},
/* */
{ ZBEE_ZCL_CID_POWER_PROFILE, "Power Profile"},
{ ZBEE_ZCL_CID_APPLIANCE_CONTROL, "Appliance Control"},
/* Closures */
{ ZBEE_ZCL_CID_SHADE_CONFIG, "Shade Configuration"},
{ ZBEE_ZCL_CID_DOOR_LOCK, "Door Lock"},
/* HVAC */
{ ZBEE_ZCL_CID_PUMP_CONFIG_CONTROL, "Pump Configuration Control"},
@ -563,6 +568,12 @@ const value_string zbee_aps_cid_names[] = {
{ ZBEE_ZCL_CID_SMART_ENERGY_TUNNELING, "Smart Energy Tunneling"},
{ ZBEE_ZCL_CID_PRE_PAYMENT, "Pre-Payment"},
/* ZCL Cluster IDs - Home Automation */
{ZBEE_ZCL_CID_APPLIANCE_IDENTIFICATION, "Appliance Identification"},
{ZBEE_ZCL_CID_METER_IDENTIFICATION, "Meter Identification"},
{ZBEE_ZCL_CID_APPLIANCE_EVENTS_AND_ALERT, "Appliance Events And Alerts"},
{ZBEE_ZCL_CID_APPLIANCE_STATISTICS, "Appliance Statistics"},
{ 0, NULL }
};

View File

@ -147,9 +147,14 @@
#define ZBEE_ZCL_CID_MULTISTATE_OUTPUT_BASIC 0x0013
#define ZBEE_ZCL_CID_MULTISTATE_VALUE_BASIC 0x0014
#define ZBEE_ZCL_CID_COMMISSIONING 0x0015
#define ZBEE_ZCL_CID_PARTITION 0x0016
/* */
#define ZBEE_ZCL_CID_POWER_PROFILE 0x001a
#define ZBEE_ZCL_CID_APPLIANCE_CONTROL 0x001b
/* ZCL Cluster IDs - Closures */
#define ZBEE_ZCL_CID_SHADE_CONFIG 0x0100
#define ZBEE_ZCL_CID_DOOR_LOCK 0X0101
/* ZCL Cluster IDs - HVAC */
#define ZBEE_ZCL_CID_PUMP_CONFIG_CONTROL 0x0200
@ -206,6 +211,12 @@
#define ZBEE_ZCL_CID_SMART_ENERGY_TUNNELING 0x0704
#define ZBEE_ZCL_CID_PRE_PAYMENT 0x0705
/* ZCL Cluster IDs - Home Automation */
#define ZBEE_ZCL_CID_APPLIANCE_IDENTIFICATION 0x0b00
#define ZBEE_ZCL_CID_METER_IDENTIFICATION 0x0b01
#define ZBEE_ZCL_CID_APPLIANCE_EVENTS_AND_ALERT 0x0b02
#define ZBEE_ZCL_CID_APPLIANCE_STATISTICS 0x0b03
/* Structure to contain the APS frame information */
typedef struct{
gboolean indirect_mode; /* ZigBee 2004 and Earlier */

View File

@ -987,3 +987,607 @@ proto_reg_handoff_zbee_zcl_on_off(void)
(zbee_zcl_fn_attr_data)dissect_zcl_on_off_attr_data
);
} /*proto_reg_handoff_zbee_zcl_on_off*/
/* ########################################################################## */
/* #### (0x0016) PARTITION ################################################## */
/* ########################################################################## */
/*************************/
/* Defines */
/*************************/
#define ZBEE_ZCL_PART_NUM_GENERIC_ETT 3
#define ZBEE_ZCL_PART_NUM_NACK_ID_ETT 16
#define ZBEE_ZCL_PART_NUM_ATTRS_ID_ETT 16
#define ZBEE_ZCL_PART_NUM_ETT (ZBEE_ZCL_PART_NUM_GENERIC_ETT + \
ZBEE_ZCL_PART_NUM_NACK_ID_ETT + \
ZBEE_ZCL_PART_NUM_ATTRS_ID_ETT)
#define ZBEE_ZCL_PART_OPT_1_BLOCK 0x01
#define ZBEE_ZCL_PART_OPT_INDIC_LEN 0x02
#define ZBEE_ZCL_PART_OPT_RESERVED 0xc0
#define ZBEE_ZCL_PART_ACK_OPT_NACK_LEN 0x01
#define ZBEE_ZCL_PART_ACK_OPT_RESERVED 0xFE
/* Attributes */
#define ZBEE_ZCL_ATTR_ID_PART_MAX_IN_TRANSF_SIZE 0x0000 /* Maximum Incoming Transfer Size */
#define ZBEE_ZCL_ATTR_ID_PART_MAX_OUT_TRANSF_SIZE 0x0001 /* Maximum Outgoing Transfer Size */
#define ZBEE_ZCL_ATTR_ID_PART_PARTIONED_FRAME_SIZE 0x0002 /* Partioned Frame Size */
#define ZBEE_ZCL_ATTR_ID_PART_LARGE_FRAME_SIZE 0x0003 /* Large Frame Size */
#define ZBEE_ZCL_ATTR_ID_PART_ACK_FRAME_NUM 0x0004 /* Number of Ack Frame*/
#define ZBEE_ZCL_ATTR_ID_PART_NACK_TIMEOUT 0x0005 /* Nack Timeout */
#define ZBEE_ZCL_ATTR_ID_PART_INTERFRAME_DELEAY 0x0006 /* Interframe Delay */
#define ZBEE_ZCL_ATTR_ID_PART_SEND_RETRIES_NUM 0x0007 /* Number of Send Retries */
#define ZBEE_ZCL_ATTR_ID_PART_SENDER_TIMEOUT 0x0008 /* Sender Timeout */
#define ZBEE_ZCL_ATTR_ID_PART_RECEIVER_TIMEOUT 0x0009 /* Receiver Timeout */
/* Server Commands Received */
#define ZBEE_ZCL_CMD_ID_PART_TRANSF_PART_FRAME 0x00 /* Transfer Partitioned Frame */
#define ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM 0x01 /* Read Handshake Param */
#define ZBEE_ZCL_CMD_ID_PART_WR_HANDSHAKE_PARAM 0x02 /* Write Handshake Param */
/* Server Commands Generated */
#define ZBEE_ZCL_CMD_ID_PART_MULTI_ACK 0x00 /* Multiple Ack */
#define ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM_RSP 0x01 /* Read Handshake Param Response */
/*************************/
/* Function Declarations */
/*************************/
/* Command Dissector Helpers */
static void dissect_zcl_part_trasfpartframe (tvbuff_t *tvb, proto_tree *tree, guint *offset);
static void dissect_zcl_part_rdhandshakeparam (tvbuff_t *tvb, proto_tree *tree, guint *offset);
static void dissect_zcl_part_wrhandshakeparam (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset);
static void dissect_zcl_part_multiack (tvbuff_t *tvb, proto_tree *tree, guint *offset);
static void dissect_zcl_part_rdhandshakeparamrsp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset);
/* Private functions prototype */
static void dissect_zcl_part_attr_id (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id);
/*************************/
/* Global Variables */
/*************************/
extern const value_string zbee_aps_cid_names[];
/* Initialize the protocol and registered fields */
static int proto_zbee_zcl_part = -1;
static int hf_zbee_zcl_part_attr_id = -1;
static int hf_zbee_zcl_part_srv_tx_cmd_id = -1;
static int hf_zbee_zcl_part_srv_rx_cmd_id = -1;
static int hf_zbee_zcl_part_opt_first_block = -1;
static int hf_zbee_zcl_part_opt_indic_len = -1;
static int hf_zbee_zcl_part_opt_res = -1;
static int hf_zbee_zcl_part_first_frame_id = -1;
static int hf_zbee_zcl_part_part_indicator = -1;
static int hf_zbee_zcl_part_part_frame = -1;
static int hf_zbee_zcl_part_part_frame_len = -1;
static int hf_zbee_zcl_part_partitioned_cluster_id = -1;
static int hf_zbee_zcl_part_ack_opt_nack_id_len = -1;
static int hf_zbee_zcl_part_ack_opt_res = -1;
static int hf_zbee_zcl_part_nack_id = -1;
/* Initialize the subtree pointers */
static gint ett_zbee_zcl_part = -1;
static gint ett_zbee_zcl_part_fragm_options = -1;
static gint ett_zbee_zcl_part_ack_opts = -1;
static gint ett_zbee_zcl_part_nack_id_list[ZBEE_ZCL_PART_NUM_NACK_ID_ETT];
static gint ett_zbee_zcl_part_attrs_id_list[ZBEE_ZCL_PART_NUM_ATTRS_ID_ETT];
/* Attributes */
static const value_string zbee_zcl_part_attr_names[] = {
{ ZBEE_ZCL_ATTR_ID_PART_MAX_IN_TRANSF_SIZE, "Maximum Incoming Transfer Size" },
{ ZBEE_ZCL_ATTR_ID_PART_MAX_OUT_TRANSF_SIZE, "Maximum Outgoing Transfer Size" },
{ ZBEE_ZCL_ATTR_ID_PART_PARTIONED_FRAME_SIZE, "Partioned Frame Size" },
{ ZBEE_ZCL_ATTR_ID_PART_LARGE_FRAME_SIZE, "Large Frame Size" },
{ ZBEE_ZCL_ATTR_ID_PART_ACK_FRAME_NUM, "Number of Ack Frame" },
{ ZBEE_ZCL_ATTR_ID_PART_NACK_TIMEOUT, "Nack Timeout" },
{ ZBEE_ZCL_ATTR_ID_PART_INTERFRAME_DELEAY, "Interframe Delay" },
{ ZBEE_ZCL_ATTR_ID_PART_SEND_RETRIES_NUM, "Number of Send Retries" },
{ ZBEE_ZCL_ATTR_ID_PART_SENDER_TIMEOUT, "Sender Timeout" },
{ ZBEE_ZCL_ATTR_ID_PART_RECEIVER_TIMEOUT, "Receiver Timeout" },
{ 0, NULL }
};
/* Server Commands Received */
static const value_string zbee_zcl_part_srv_rx_cmd_names[] = {
{ ZBEE_ZCL_CMD_ID_PART_TRANSF_PART_FRAME, "Transfer Partitioned Frame" },
{ ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM, "Read Handshake Param" },
{ ZBEE_ZCL_CMD_ID_PART_WR_HANDSHAKE_PARAM, "Write Handshake Param" },
{ 0, NULL }
};
/* Server Commands Generated */
static const value_string zbee_zcl_part_srv_tx_cmd_names[] = {
{ ZBEE_ZCL_CMD_ID_PART_MULTI_ACK, "Multiple Ack" },
{ ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM_RSP, "Read Handshake Param Response" },
{ 0, NULL }
};
/* ID Lenght */
static const value_string zbee_zcl_part_id_length_names[] = {
{ 0, "1-Byte length" },
{ 1, "2-Bytes length" },
{ 0, NULL }
};
/*************************/
/* Function Bodies */
/*************************/
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zbee_zcl_part
* DESCRIPTION
* ZigBee ZCL Partition 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_part(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *payload_root = NULL;
proto_tree *payload_tree = NULL;
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_part_srv_rx_cmd_id, tvb, offset, 1, cmd_id);
/* Check is this command has a payload, than add the payload tree */
if (offset != (tvb_length(tvb) - 1)) {
payload_root = proto_tree_add_text(tree, tvb, offset, tvb_length(tvb), "Payload");
payload_tree = proto_item_add_subtree(payload_root, ett_zbee_zcl_part);
}
}
offset += (int)1;
/* 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_part_srv_rx_cmd_names, "Unknown Command"),
zcl->tran_seqno);
/* Call the appropriate command dissector */
switch (cmd_id) {
case ZBEE_ZCL_CMD_ID_PART_TRANSF_PART_FRAME:
dissect_zcl_part_trasfpartframe(tvb, payload_tree, &offset);
break;
case ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM:
dissect_zcl_part_rdhandshakeparam(tvb, payload_tree, &offset);
break;
case ZBEE_ZCL_CMD_ID_PART_WR_HANDSHAKE_PARAM:
dissect_zcl_part_wrhandshakeparam(tvb, pinfo, payload_tree, &offset);
break;
default:
break;
}
}
else { /* ZBEE_ZCL_FCF_TO_CLIENT */
if (tree) {
/* Add the command ID. */
proto_tree_add_item(tree, hf_zbee_zcl_part_srv_tx_cmd_id, tvb, offset, 1, cmd_id);
/* Check is this command has a payload, than add the payload tree */
if (offset != (tvb_length(tvb) - 1)) {
payload_root = proto_tree_add_text(tree, tvb, offset, tvb_length(tvb), "Payload");
payload_tree = proto_item_add_subtree(payload_root, ett_zbee_zcl_part);
}
}
offset += (int)1;
/* 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_part_srv_tx_cmd_names, "Unknown Command"),
zcl->tran_seqno);
/* Call the appropriate command dissector */
switch (cmd_id) {
case ZBEE_ZCL_CMD_ID_PART_MULTI_ACK:
dissect_zcl_part_multiack(tvb, payload_tree, &offset);
break;
case ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM_RSP:
dissect_zcl_part_rdhandshakeparamrsp(tvb, pinfo, payload_tree, &offset);
break;
default:
break;
}
}
} /*dissect_zbee_zcl_part*/
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zcl_part_trasfpartframe
* DESCRIPTION
* This function manages the Trasfer Partition Frame payload
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* offset - pointer of buffer offset
* RETURNS
* none
*---------------------------------------------------------------
*/
static void dissect_zcl_part_trasfpartframe(tvbuff_t *tvb, proto_tree *tree, guint *offset)
{
proto_tree *sub_tree = NULL;
proto_item *ti;
guint8 options;
guint16 u16len;
guint8 frame_len;
guint8 *data_frame;
/* Retrieve "Fragmentation Options" field */
options = tvb_get_guint8(tvb, *offset);
ti = proto_tree_add_text(tree, tvb, *offset, 1, "Fragmentation Options: 0x%02x", options);
sub_tree = proto_item_add_subtree(ti, ett_zbee_zcl_part_fragm_options);
proto_tree_add_item(sub_tree, hf_zbee_zcl_part_opt_first_block, tvb, *offset, 1, ENC_NA);
proto_tree_add_item(sub_tree, hf_zbee_zcl_part_opt_indic_len, tvb, *offset, 1, ENC_NA);
proto_tree_add_item(sub_tree, hf_zbee_zcl_part_opt_res, tvb, *offset, 1, ENC_NA);
*offset += (int)1;
/* Retrieve "PartitionIndicator" field */
if ((options & ZBEE_ZCL_PART_OPT_INDIC_LEN) == 0)
{
/* 1-byte length */
u16len = (guint16)tvb_get_guint8(tvb, *offset);
proto_tree_add_item(tree, hf_zbee_zcl_part_part_indicator, tvb, *offset, 1, (u16len & 0xFF));
*offset += (int)1;
}
else {
/* 2-bytes length */
u16len = tvb_get_letohs(tvb, *offset);
proto_tree_add_item(tree, hf_zbee_zcl_part_part_indicator, tvb, *offset, 2, u16len);
*offset += (int)2;
}
/* Retrieve PartitionedFrame length field */
frame_len = tvb_get_guint8(tvb, *offset); /* string length */
if (frame_len == ZBEE_ZCL_INVALID_STR_LENGTH) frame_len = 0;
proto_tree_add_item(tree, hf_zbee_zcl_part_part_frame_len, tvb, *offset, 1, ENC_NA);
*offset += (int)1;
/* Retrieve "PartitionedFrame" field */
data_frame = tvb_bytes_to_str_punct(tvb, *offset, frame_len, ':');
proto_tree_add_string(tree, hf_zbee_zcl_part_part_frame, tvb, *offset, frame_len, data_frame);
*offset += frame_len;
} /*dissect_zcl_part_trasfpartframe*/
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zcl_part_rdhandshakeparam
* DESCRIPTION
* This function manages the ReadHandshakeParam payload
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* offset - offset
* RETURNS
* none
*---------------------------------------------------------------
*/
static void
dissect_zcl_part_rdhandshakeparam(tvbuff_t *tvb, proto_tree *tree, guint *offset)
{
guint tvb_len;
guint16 attr_id;
/* Retrieve "Partitioned Cluster ID" field */
proto_tree_add_item(tree, hf_zbee_zcl_part_partitioned_cluster_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
*offset += (int)2;
/* Dissect the attribute id list */
tvb_len = tvb_length(tvb);
while ( *offset < tvb_len ) {
/* Dissect the attribute identifier */
attr_id = tvb_get_letohs(tvb, *offset);
dissect_zcl_part_attr_id(tree, tvb, offset, attr_id);
*offset += (int)2;
}
return;
} /*dissect_zcl_part_rdhandshakeparam*/
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zcl_part_wrhandshakeparam
* DESCRIPTION
* This function manages the WriteAndShakeParam payload
* 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.
* offset - offset
* RETURNS
* none
*---------------------------------------------------------------
*/
static void
dissect_zcl_part_wrhandshakeparam(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset)
{
/* Retrieve "Partitioned Cluster ID" field */
proto_tree_add_item(tree, hf_zbee_zcl_part_partitioned_cluster_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
*offset += (int)2;
/* Dissect the attributes list */
dissect_zcl_write_attr(tvb, pinfo, tree, offset);
} /*dissect_zcl_part_wrhandshakeparam*/
/* Management of Cluster specific commands sent by the server */
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zcl_part_multiack
* DESCRIPTION
* This function manages the MultipleACK payload
* PARAMETERS
* tvbuff_t *tvb - pointer to buffer containing raw packet.
* packet_info *pinfo, -
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
* offset - offset
* RETURNS
* none
*---------------------------------------------------------------
*/
static void
dissect_zcl_part_multiack(tvbuff_t *tvb, proto_tree *tree, guint *offset)
{
proto_tree *sub_tree = NULL;
proto_item *ti;
guint tvb_len = tvb_length(tvb);
guint i = 0;
guint8 options;
guint16 first_frame_id;
guint16 nack_id;
/* Retrieve "Ack Options" field */
options = tvb_get_guint8(tvb, *offset);
ti = proto_tree_add_text(tree, tvb, *offset, 1, "Ack Options: 0x%02x", options);
sub_tree = proto_item_add_subtree(ti, ett_zbee_zcl_part_ack_opts);
proto_tree_add_item(sub_tree, hf_zbee_zcl_part_ack_opt_nack_id_len, tvb, *offset, 1, ENC_NA);
proto_tree_add_item(sub_tree, hf_zbee_zcl_part_ack_opt_res, tvb, *offset, 1, ENC_NA);
*offset += (int)1;
/* Retrieve "First Frame ID" field */
if ((options & ZBEE_ZCL_PART_ACK_OPT_NACK_LEN) == 0)
{
/* 1-byte length */
first_frame_id = (guint16)tvb_get_guint8(tvb, *offset);
proto_tree_add_item(tree, hf_zbee_zcl_part_first_frame_id, tvb, *offset, 1, (first_frame_id & 0xFF));
*offset += (int)1;
}
else {
/* 2-bytes length */
first_frame_id = tvb_get_letohs(tvb, *offset);
proto_tree_add_item(tree, hf_zbee_zcl_part_first_frame_id, tvb, *offset, 2, first_frame_id);
*offset += (int)2;
}
/* Dissect the nack id list */
while ( *offset < tvb_len && i < ZBEE_ZCL_PART_NUM_NACK_ID_ETT )
{
if ((options & ZBEE_ZCL_PART_ACK_OPT_NACK_LEN) == 0)
{
/* 1-byte length */
nack_id = (guint16)tvb_get_guint8(tvb, *offset);
proto_tree_add_item(tree, hf_zbee_zcl_part_nack_id, tvb, *offset, 1, (nack_id & 0xFF));
*offset += (int)1;
}
else {
/* 2-bytes length */
nack_id = tvb_get_letohs(tvb, *offset);
proto_tree_add_item(tree, hf_zbee_zcl_part_nack_id, tvb, *offset, 2, nack_id);
*offset += (int)2;
}
i++;
}
} /*dissect_zcl_part_multiack*/
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zcl_part_multiack
* DESCRIPTION
* This function manages the ReadHandshakeParamResponse payload
* 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.
* offset - offset
* RETURNS
* none
*---------------------------------------------------------------
*/
static void
dissect_zcl_part_rdhandshakeparamrsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset)
{
/* Retrieve "Partitioned Cluster ID" field */
proto_tree_add_item(tree, hf_zbee_zcl_part_partitioned_cluster_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
*offset += (int)2;
/* Dissect the attributes list */
dissect_zcl_read_attr_resp(tvb, pinfo, tree, offset);
} /*dissect_zcl_part_rdhandshakeparamrsp*/
/*FUNCTION:------------------------------------------------------
* NAME
* dissect_zcl_part_attr_id
* DESCRIPTION
* this function is called by ZCL foundation dissector in order to decode
* specific cluster attributes identifier.
* 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
*
* RETURNS
* none
*---------------------------------------------------------------
*/
static void
dissect_zcl_part_attr_id(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id)
{
proto_tree_add_item(tree, hf_zbee_zcl_part_attr_id, tvb, *offset, 2, attr_id);
} /*dissect_zcl_part_attr_id*/
/*FUNCTION:------------------------------------------------------
* NAME
* proto_register_zbee_zcl_part
* 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
*---------------------------------------------------------------
*/
void proto_register_zbee_zcl_part(void)
{
guint8 i, j;
static hf_register_info hf[] = {
{ &hf_zbee_zcl_part_attr_id,
{ "Attribute", "zbee_zcl_general.part.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_part_attr_names),
0x0, NULL, HFILL } },
{ &hf_zbee_zcl_part_srv_tx_cmd_id,
{ "Command", "zbee_zcl_general.part.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_part_srv_tx_cmd_names),
0x0, NULL, HFILL } },
{ &hf_zbee_zcl_part_srv_rx_cmd_id,
{ "Command", "zbee_zcl_general.part.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_part_srv_rx_cmd_names),
0x0, NULL, HFILL } },
{ &hf_zbee_zcl_part_opt_first_block,
{ "First Block", "zbee_zcl_general.part.opt.first_block", FT_UINT8, BASE_HEX, NULL,
ZBEE_ZCL_PART_OPT_1_BLOCK, NULL, HFILL } },
{ &hf_zbee_zcl_part_opt_indic_len,
{ "Indicator length", "zbee_zcl_general.part.opt.indic_len", FT_UINT8, BASE_DEC, VALS(zbee_zcl_part_id_length_names),
ZBEE_ZCL_PART_OPT_INDIC_LEN, NULL, HFILL } },
{ &hf_zbee_zcl_part_opt_res,
{ "Reserved", "zbee_zcl_general.part.opt.res", FT_UINT8, BASE_HEX, NULL,
ZBEE_ZCL_PART_OPT_RESERVED, NULL, HFILL } },
{ &hf_zbee_zcl_part_first_frame_id,
{ "First Frame ID", "zbee_zcl_general.part.first_frame_id", FT_UINT16, BASE_DEC, NULL,
0x00, NULL, HFILL } },
{ &hf_zbee_zcl_part_part_indicator,
{ "Partition Indicator", "zbee_zcl_general.part.part_indicator", FT_UINT16, BASE_DEC, NULL,
0x00, NULL, HFILL } },
{ &hf_zbee_zcl_part_part_frame_len,
{ "Partition Frame Length", "zbee_zcl_general.part.part_frame_length", FT_UINT8, BASE_DEC, NULL,
0x00, NULL, HFILL } },
{ &hf_zbee_zcl_part_part_frame,
{ "Partition Frame", "zbee_zcl_general.part.part_frame", FT_STRING, BASE_NONE, NULL,
0x00, NULL, HFILL } },
{ &hf_zbee_zcl_part_partitioned_cluster_id,
{ "Partitioned Cluster ID", "zbee_zcl_general.part.part_cluster_id", FT_UINT16, BASE_HEX, VALS(zbee_aps_cid_names),
0x00, NULL, HFILL } },
{ &hf_zbee_zcl_part_ack_opt_nack_id_len,
{ "Nack Id Length", "zbee_zcl_general.ack_opt.part.nack_id.len", FT_UINT8, BASE_HEX, VALS(zbee_zcl_part_id_length_names),
ZBEE_ZCL_PART_ACK_OPT_NACK_LEN, NULL, HFILL } },
{ &hf_zbee_zcl_part_ack_opt_res,
{ "Reserved", "zbee_zcl_general.part.ack_opt.reserved", FT_UINT8, BASE_HEX, NULL,
ZBEE_ZCL_PART_ACK_OPT_RESERVED, NULL, HFILL } },
{ &hf_zbee_zcl_part_nack_id,
{ "Nack Id", "zbee_zcl_general.part.nack_id", FT_UINT16, BASE_DEC, NULL,
0x00, NULL, HFILL } }
};
/* ZCL Partition subtrees */
gint *ett[ZBEE_ZCL_PART_NUM_ETT];
ett[0] = &ett_zbee_zcl_part;
ett[1] = &ett_zbee_zcl_part_fragm_options;
ett[2] = &ett_zbee_zcl_part_ack_opts;
/* initialize attribute subtree types */
for ( i = 0, j = ZBEE_ZCL_PART_NUM_GENERIC_ETT; i < ZBEE_ZCL_PART_NUM_NACK_ID_ETT; i++, j++) {
ett_zbee_zcl_part_nack_id_list[i] = -1;
ett[j] = &ett_zbee_zcl_part_nack_id_list[i];
}
for ( i = 0; i < ZBEE_ZCL_PART_NUM_ATTRS_ID_ETT; i++, j++) {
ett_zbee_zcl_part_attrs_id_list[i] = -1;
ett[j] = &ett_zbee_zcl_part_attrs_id_list[i];
}
/* Register ZigBee ZCL Partition protocol with Wireshark. */
proto_zbee_zcl_part = proto_register_protocol("ZigBee ZCL Partition", "ZCL Partition", ZBEE_PROTOABBREV_ZCL_PART);
proto_register_field_array(proto_zbee_zcl_part, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
/* Register the ZigBee ZCL Partition dissector. */
register_dissector(ZBEE_PROTOABBREV_ZCL_PART, dissect_zbee_zcl_part, proto_zbee_zcl_part);
} /* proto_register_zbee_zcl_pwr_prof */
/*FUNCTION:------------------------------------------------------
* NAME
* proto_reg_handoff_zbee_zcl_part
* DESCRIPTION
* Registers the zigbee ZCL Partition cluster dissector with Wireshark.
* PARAMETERS
* none
* RETURNS
* void
*---------------------------------------------------------------
*/
void proto_reg_handoff_zbee_zcl_part(void)
{
dissector_handle_t part_handle;
/* Register our dissector with the ZigBee application dissectors. */
part_handle = find_dissector(ZBEE_PROTOABBREV_ZCL_PART);
dissector_add_uint("zbee.zcl.cluster", ZBEE_ZCL_CID_PARTITION, part_handle);
zbee_zcl_init_cluster( proto_zbee_zcl_part,
ett_zbee_zcl_part,
ZBEE_ZCL_CID_PARTITION,
(zbee_zcl_fn_attr_id)dissect_zcl_part_attr_id,
NULL
);
} /*proto_reg_handoff_zbee_zcl_part*/

View File

@ -46,9 +46,6 @@ static void dissect_zbee_zcl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
/* Command Dissector Helpers */
static void dissect_zcl_read_attr (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset);
static void dissect_zcl_read_attr_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint *offset);
static void dissect_zcl_write_attr (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset);
static void dissect_zcl_write_attr_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint *offset);
static void dissect_zcl_config_report (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset);
@ -579,7 +576,7 @@ static const value_string zbee_zcl_data_type_names[] = {
static value_string_ext zbee_zcl_data_type_names_ext = VALUE_STRING_EXT_INIT(zbee_zcl_data_type_names);
/* ZCL Attribute Short Data Names */
static const value_string zbee_zcl_short_data_type_names[] = {
const value_string zbee_zcl_short_data_type_names[] = {
{ ZBEE_ZCL_NO_DATA, "No Data" },
{ ZBEE_ZCL_8_BIT_DATA, "Data8" },
{ ZBEE_ZCL_16_BIT_DATA, "Data16" },
@ -944,7 +941,7 @@ static void dissect_zcl_read_attr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t
* guint - offset after command dissection.
*---------------------------------------------------------------
*/
static void dissect_zcl_read_attr_resp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset)
void dissect_zcl_read_attr_resp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset)
{
proto_item *ti = NULL;
proto_tree *sub_tree = NULL;
@ -991,7 +988,7 @@ static void dissect_zcl_read_attr_resp(tvbuff_t *tvb, packet_info *pinfo _U_, pr
* guint - offset after command dissection.
*---------------------------------------------------------------
*/
static void dissect_zcl_write_attr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset)
void dissect_zcl_write_attr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint *offset)
{
proto_item *ti = NULL;
proto_tree *sub_tree = NULL;

View File

@ -189,6 +189,11 @@ typedef struct _zbee_zcl_cluster_desc {
zbee_zcl_fn_attr_data fn_attr_data;
} zbee_zcl_cluster_desc;
extern const value_string zbee_zcl_short_data_type_names[];
/* Dissector functions */
extern void dissect_zcl_write_attr (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset);
extern void dissect_zcl_read_attr_resp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset);
/* Helper functions */
void decode_zcl_time_in_seconds (gchar *s, guint16 value);

View File

@ -790,6 +790,7 @@
#define ZBEE_PROTOABBREV_ZCL_BASIC "zbee_zcl_general.basic"
#define ZBEE_PROTOABBREV_ZCL_IDENTIFY "zbee_zcl_general.identify"
#define ZBEE_PROTOABBREV_ZCL_ONOFF "zbee_zcl_general.onoff"
#define ZBEE_PROTOABBREV_ZCL_PART "zbee_zcl_general.part"
/* Helper Functions */
extern guint zbee_get_bit_field(guint input, guint mask);