forked from osmocom/wireshark
1828 lines
79 KiB
C
1828 lines
79 KiB
C
/* packet-zbee-nwk-gp.c
|
|
* Dissector routines for the ZigBee Green Power profile (GP)
|
|
* Copyright 2013 DSR Corporation, http://dsr-wireless.com/
|
|
*
|
|
* $Id$
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* Used Owen Kirby's packet-zbee-aps module as a template. Based
|
|
* on ZigBee Cluster Library Specification document 075123r02ZB
|
|
*
|
|
* 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 <glib.h>
|
|
#include <epan/packet.h>
|
|
#include <epan/exceptions.h>
|
|
#include <epan/prefs.h>
|
|
#include <epan/addr_resolv.h>
|
|
#include <epan/expert.h>
|
|
#include <epan/uat.h>
|
|
#include "packet-ieee802154.h"
|
|
#include "packet-zbee.h"
|
|
#include "packet-zbee-nwk.h"
|
|
#include "packet-zbee-security.h"
|
|
#include "packet-zbee-aps.h"
|
|
#include "packet-zbee-zcl.h"
|
|
#include <wsutil/wsgcrypt.h>
|
|
|
|
|
|
void proto_register_zbee_nwk_gp(void);
|
|
void proto_reg_handoff_zbee_nwk_gp(void);
|
|
|
|
/**************************/
|
|
/* Defines. */
|
|
/**************************/
|
|
|
|
/* ZigBee NWK GP FCF frame types. */
|
|
#define ZBEE_NWK_GP_FCF_DATA 0x00
|
|
#define ZBEE_NWK_GP_FCF_MAINTENANCE 0x01
|
|
|
|
/* ZigBee NWK GP FCF fields. */
|
|
#define ZBEE_NWK_GP_FCF_AUTO_COMMISSIONING 0x40
|
|
#define ZBEE_NWK_GP_FCF_CONTROL_EXTENSION 0x80
|
|
#define ZBEE_NWK_GP_FCF_FRAME_TYPE 0x03
|
|
#define ZBEE_NWK_GP_FCF_VERSION 0x3C
|
|
|
|
/* Extended NWK Frame Control field. */
|
|
#define ZBEE_NWK_GP_FCF_EXT_APP_ID 0x07 /* 0 - 2 b. */
|
|
#define ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL 0x18 /* 3 - 4 b. */
|
|
#define ZBEE_NWK_GP_FCF_EXT_SECURITY_KEY 0x20 /* 5 b. */
|
|
#define ZBEE_NWK_GP_FCF_EXT_RX_AFTER_TX 0x40 /* 6 b. */
|
|
#define ZBEE_NWK_GP_FCF_EXT_DIRECTION 0x80 /* 7 b. */
|
|
|
|
/* Definitions for application IDs. */
|
|
#define ZBEE_NWK_GP_APP_ID_DEFAULT 0x00
|
|
#define ZBEE_NWK_GP_APP_ID_LPED 0x01
|
|
#define ZBEE_NWK_GP_APP_ID_ZGP 0x02
|
|
|
|
/* Definitions for GP directions. */
|
|
#define ZBEE_NWK_GP_FC_EXT_DIRECTION_DEFAULT 0x00
|
|
#define ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD 0x00
|
|
#define ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPP 0x01
|
|
|
|
/* Definitions for ZGPD Source IDs. */
|
|
#define ZBEE_NWK_GP_ZGPD_SRCID_ALL 0xFFFFFFFF
|
|
#define ZBEE_NWK_GP_ZGPD_SRCID_UNKNOWN 0x00000000
|
|
|
|
/* Security level values. */
|
|
#define ZBEE_NWK_GP_SECURITY_LEVEL_NO 0x00
|
|
#define ZBEE_NWK_GP_SECURITY_LEVEL_1LSB 0x01
|
|
#define ZBEE_NWK_GP_SECURITY_LEVEL_FULL 0x02
|
|
#define ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR 0x03
|
|
|
|
/* GP Security key types. */
|
|
#define ZBEE_NWK_GP_SECURITY_KEY_TYPE_NO_KEY 0x00
|
|
#define ZBEE_NWK_GP_SECURITY_KEY_TYPE_ZB_NWK_KEY 0x01
|
|
#define ZBEE_NWK_GP_SECURITY_KEY_TYPE_GPD_GROUP_KEY 0x02
|
|
#define ZBEE_NWK_GP_SECURITY_KEY_TYPE_NWK_KEY_DERIVED_GPD_KEY_GROUP_KEY 0x03
|
|
#define ZBEE_NWK_GP_SECURITY_KEY_TYPE_PRECONFIGURED_INDIVIDUAL_GPD_KEY 0x04
|
|
#define ZBEE_NWK_GP_SECURITY_KEY_TYPE_DERIVED_INDIVIDUAL_GPD_KEY 0x07
|
|
|
|
typedef struct {
|
|
/* FCF Data. */
|
|
guint8 frame_type;
|
|
gboolean nwk_frame_control_extension;
|
|
|
|
/* Ext FCF Data. */
|
|
guint8 application_id;
|
|
guint8 security_level;
|
|
guint8 direction;
|
|
|
|
/* Src ID. */
|
|
guint32 source_id;
|
|
|
|
/* Security Frame Counter. */
|
|
guint32 security_frame_counter;
|
|
|
|
/* MIC. */
|
|
guint8 mic_size;
|
|
guint32 mic;
|
|
|
|
/* Application Payload. */
|
|
guint8 payload_len;
|
|
} zbee_nwk_green_power_packet;
|
|
|
|
/* Commissioning command payload. */
|
|
#define NWK_CMD_SECURITY_KEY_LEN 16
|
|
|
|
/* Definitions for GP Commissioning command opt field (bitmask). */
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MAC_SEQ 0x01
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_RX_ON_CAP 0x02
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MANUFACTURER_INFO 0x04
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_PAN_ID_REQ 0x10
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_GP_SEC_KEY_REQ 0x20
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_FIXED_LOCATION 0x40
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS 0x80
|
|
|
|
/* Definitions for GP Commissioning command ext_opt field (bitmask). */
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_SEC_LEVEL_CAP 0x03
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_KEY_TYPE 0x1C
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT 0x20
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR 0x40
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER 0x80
|
|
|
|
/* Definitions for GP Commissioning command MS Extensions field (bitmask). */
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_MIP 0x01
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_MMIP 0x02
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_GCLP 0x04
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_CRP 0x08
|
|
|
|
/* Definitions for GP Decommissioning command opt field (bitmask). */
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT 0x01
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT 0x02
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR 0x04
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL 0x18
|
|
#define ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_TYPE 0xE0
|
|
|
|
/* Definitions for GP Channel Request command. */
|
|
#define ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_1ST 0x0F
|
|
#define ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_2ND 0xF0
|
|
|
|
/* GP Channel Configuration command. */
|
|
#define ZBEE_NWK_GP_CMD_CHANNEL_CONFIGURATION_OPERATION_CH 0x0F
|
|
|
|
/* GP GENERIC IDS. */
|
|
#define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_1STATE_SWITCH 0x00
|
|
#define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_2STATE_SWITCH 0x01
|
|
#define GPD_DEVICE_ID_GENERIC_GP_ON_OFF_SWITCH 0x02
|
|
#define GPD_DEVICE_ID_GENERIC_GP_LEVEL_CONTROL_SWITCH 0x03
|
|
#define GPD_DEVICE_ID_GENERIC_GP_SIMPLE_SENSOR 0x04
|
|
#define GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_1STATE_SWITCH 0x05
|
|
#define GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_2STATE_SWITCH 0x06
|
|
|
|
/* GP LIGHTING IDS. */
|
|
#define GPD_DEVICE_ID_LIGHTING_GP_COLOR_DIMMER_SWITCH 0x10
|
|
#define GPD_DEVICE_ID_LIGHTING_GP_LIGHT_SENSOR 0x11
|
|
#define GPD_DEVICE_ID_LIGHTING_GP_OCCUPANCY_SENSOR 0x12
|
|
|
|
/* GP CLOSURES IDS. */
|
|
#define GPD_DEVICE_ID_CLOSURES_GP_DOOR_LOCK_CONTROLLER 0x20
|
|
|
|
/* HVAC IDS. */
|
|
#define GPD_DEVICE_ID_HVAC_GP_TEMPERATURE_SENSOR 0x30
|
|
#define GPD_DEVICE_ID_HVAC_GP_PRESSURE_SENSOR 0x31
|
|
#define GPD_DEVICE_ID_HVAC_GP_FLOW_SENSOR 0x32
|
|
#define GPD_DEVICE_ID_HVAC_GP_INDOOR_ENVIRONMENT_SENSOR 0x33
|
|
|
|
/* Manufacturer specific device. */
|
|
#define GPD_DEVICE_ID_MANUFACTURER_SPECIFIC 0xFE
|
|
|
|
/* Payloadless GPDF commands sent by GPD. */
|
|
#define ZB_GP_CMD_ID_IDENTIFY 0x00
|
|
#define ZB_GP_CMD_ID_SCENE0 0x10
|
|
#define ZB_GP_CMD_ID_SCENE1 0x11
|
|
#define ZB_GP_CMD_ID_SCENE2 0x12
|
|
#define ZB_GP_CMD_ID_SCENE3 0x13
|
|
#define ZB_GP_CMD_ID_SCENE4 0x14
|
|
#define ZB_GP_CMD_ID_SCENE5 0x15
|
|
#define ZB_GP_CMD_ID_SCENE6 0x16
|
|
#define ZB_GP_CMD_ID_SCENE7 0x17
|
|
#define ZB_GP_CMD_ID_SCENE8 0x18
|
|
#define ZB_GP_CMD_ID_SCENE9 0x19
|
|
#define ZB_GP_CMD_ID_SCENE10 0x1A
|
|
#define ZB_GP_CMD_ID_SCENE11 0x1B
|
|
#define ZB_GP_CMD_ID_SCENE12 0x1C
|
|
#define ZB_GP_CMD_ID_SCENE13 0x1D
|
|
#define ZB_GP_CMD_ID_SCENE14 0x1E
|
|
#define ZB_GP_CMD_ID_SCENE15 0x1F
|
|
#define ZB_GP_CMD_ID_OFF 0x20
|
|
#define ZB_GP_CMD_ID_ON 0x21
|
|
#define ZB_GP_CMD_ID_TOGGLE 0x22
|
|
#define ZB_GP_CMD_ID_RELEASE 0x23
|
|
#define ZB_GP_CMD_ID_LEVEL_CONTROL_STOP 0x34
|
|
#define ZB_GP_CMD_ID_MOVE_HUE_STOP 0x40
|
|
#define ZB_GP_CMD_ID_MOVE_SATURATION_STOP 0x45
|
|
#define ZB_GP_CMD_ID_LOCK_DOOR 0x50
|
|
#define ZB_GP_CMD_ID_UNLOCK_DOOR 0x51
|
|
#define ZB_GP_CMD_ID_PRESS11 0x60
|
|
#define ZB_GP_CMD_ID_RELEASE11 0x61
|
|
#define ZB_GP_CMD_ID_PRESS12 0x62
|
|
#define ZB_GP_CMD_ID_RELEASE12 0x63
|
|
#define ZB_GP_CMD_ID_PRESS22 0x64
|
|
#define ZB_GP_CMD_ID_RELEASE22 0x65
|
|
#define ZB_GP_CMD_ID_SHORT_PRESS11 0x66
|
|
#define ZB_GP_CMD_ID_SHORT_PRESS12 0x67
|
|
#define ZB_GP_CMD_ID_SHORT_PRESS22 0x68
|
|
#define ZB_GP_CMD_ID_DECOMMISSIONING 0xE1
|
|
#define ZB_GP_CMD_ID_SUCCESS 0xE2
|
|
|
|
/* GPDF commands with payload sent by GPD. */
|
|
#define ZB_GP_CMD_ID_MOVE_UP 0x30
|
|
#define ZB_GP_CMD_ID_MOVE_DOWN 0x31
|
|
#define ZB_GP_CMD_ID_STEP_UP 0x32
|
|
#define ZB_GP_CMD_ID_STEP_DOWN 0x33
|
|
#define ZB_GP_CMD_ID_MOVE_UP_WITH_ON_OFF 0x35
|
|
#define ZB_GP_CMD_ID_MOVE_DOWN_WITH_ON_OFF 0x36
|
|
#define ZB_GP_CMD_ID_STEP_UP_WITH_ON_OFF 0x37
|
|
#define ZB_GP_CMD_ID_STEP_DOWN_WITH_ON_OFF 0x38
|
|
#define ZB_GP_CMD_ID_MOVE_HUE_UP 0x41
|
|
#define ZB_GP_CMD_ID_MOVE_HUE_DOWN 0x42
|
|
#define ZB_GP_CMD_ID_STEP_HUE_UP 0x43
|
|
#define ZB_GP_CMD_ID_STEP_HUW_DOWN 0x44
|
|
#define ZB_GP_CMD_ID_MOVE_SATUREATION_UP 0x46
|
|
#define ZB_GP_CMD_ID_MOVE_SATUREATION_DOWN 0x47
|
|
#define ZB_GP_CMD_ID_STEP_SATURATION_UP 0x48
|
|
#define ZB_GP_CMD_ID_STEP_SATURATION_DOWN 0x49
|
|
#define ZB_GP_CMD_ID_MOVE_COLOR 0x4A
|
|
#define ZB_GP_CMD_ID_STEP_COLOR 0x4B
|
|
#define ZB_GP_CMD_ID_ATTRIBUTE_REPORTING 0xA0
|
|
#define ZB_GP_CMD_ID_MANUFACTURE_SPECIFIC_ATTR_REPORTING 0xA1
|
|
#define ZB_GP_CMD_ID_MULTI_CLUSTER_REPORTING 0xA2
|
|
#define ZB_GP_CMD_ID_MANUFACTURER_SPECIFIC_MCLUSTER_REPORTING 0xA3
|
|
#define ZB_GP_CMD_ID_REQUEST_ATTRIBUTES 0xA4
|
|
#define ZB_GP_CMD_ID_READ_ATTRIBUTES_RESPONSE 0xA5
|
|
#define ZB_GP_CMD_ID_ANY_SENSOR_COMMAND_A0_A3 0xAF
|
|
#define ZB_GP_CMD_ID_COMMISSIONING 0xE0
|
|
#define ZB_GP_CMD_ID_CHANNEL_REQUEST 0xE3
|
|
|
|
/* GPDF commands sent to GPD. */
|
|
#define ZB_GP_CMD_ID_COMMISSIONING_REPLY 0xF0
|
|
#define ZB_GP_CMD_ID_WRITE_ATTRIBUTES 0xF1
|
|
#define ZB_GP_CMD_ID_READ_ATTRIBUTES 0xF2
|
|
#define ZB_GP_CMD_ID_CHANNEL_CONFIGURATION 0xF3
|
|
|
|
/* GPD manufacturers. */
|
|
#define ZBEE_NWK_GP_MANUF_ID_GREENPEAK 0x10D0
|
|
|
|
/* GPD devices by GreenPeak. */
|
|
#define ZBEE_NWK_GP_MANUF_GREENPEAK_IZDS 0x0000
|
|
#define ZBEE_NWK_GP_MANUF_GREENPEAK_IZDWS 0x0001
|
|
#define ZBEE_NWK_GP_MANUF_GREENPEAK_IZLS 0x0002
|
|
#define ZBEE_NWK_GP_MANUF_GREENPEAK_IZRHS 0x0003
|
|
|
|
/*********************/
|
|
/* Extern Constants. */
|
|
/*********************/
|
|
|
|
extern const value_string zbee_aps_cid_names[];
|
|
|
|
/*********************/
|
|
/* Global variables. */
|
|
/*********************/
|
|
|
|
/* GP proto handle. */
|
|
static int proto_zbee_nwk_gp = -1;
|
|
|
|
/* GP NWK FC. */
|
|
static int hf_zbee_nwk_gp_auto_commissioning = -1;
|
|
static int hf_zbee_nwk_gp_fc_ext = -1;
|
|
static int hf_zbee_nwk_gp_frame_type = -1;
|
|
static int hf_zbee_nwk_gp_proto_version = -1;
|
|
|
|
/* GP NWK FC extension. */
|
|
static int hf_zbee_nwk_gp_fc_ext_app_id = -1;
|
|
static int hf_zbee_nwk_gp_fc_ext_direction = -1;
|
|
static int hf_zbee_nwk_gp_fc_ext_rx_after_tx = -1;
|
|
static int hf_zbee_nwk_gp_fc_ext_sec_key = -1;
|
|
static int hf_zbee_nwk_gp_fc_ext_sec_level = -1;
|
|
|
|
/* ZGPD Src ID. */
|
|
static int hf_zbee_nwk_gp_zgpd_src_id = -1;
|
|
|
|
/* Security frame counter. */
|
|
static int hf_zbee_nwk_gp_security_frame_counter = -1;
|
|
|
|
/* Security MIC. */
|
|
static int hf_zbee_nwk_gp_security_mic_2b = -1;
|
|
static int hf_zbee_nwk_gp_security_mic_4b = -1;
|
|
|
|
/* Payload subframe. */
|
|
static int hf_zbee_nwk_gp_command_id = -1;
|
|
|
|
/* Commissioning. */
|
|
static int hf_zbee_nwk_gp_cmd_comm_device_id = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_opt_ext_opt = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_opt_fixed_location = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_opt_ms_ext_present = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_opt_panid_req = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_outgoing_counter = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_manufacturer_id = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ms_ext_crp = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ms_ext_gclp = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ms_ext_mip = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_ms_ext_mmip = -1;
|
|
|
|
/* Commissioning reply. */
|
|
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type = -1;
|
|
static int hf_zbee_nwk_gp_cmd_comm_rep_pan_id = -1;
|
|
|
|
/* Attribute reporting. */
|
|
static int hf_zbee_nwk_gp_cmd_attr_report_cluster_id = -1;
|
|
|
|
/* Channel request. */
|
|
static int hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st = -1;
|
|
static int hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd = -1;
|
|
|
|
/* Channel Configuration command. */
|
|
static int hf_zbee_nwk_gp_cmd_channel_configuration = -1;
|
|
|
|
/* Move Color command. */
|
|
static int hf_zbee_nwk_gp_cmd_move_color_ratex = -1;
|
|
static int hf_zbee_nwk_gp_cmd_move_color_ratey = -1;
|
|
|
|
/* Move Up/Down command. */
|
|
static int hf_zbee_nwk_gp_cmd_move_up_down_rate = -1;
|
|
|
|
/* Step Color command. */
|
|
static int hf_zbee_nwk_gp_cmd_step_color_stepx = -1;
|
|
static int hf_zbee_nwk_gp_cmd_step_color_stepy = -1;
|
|
static int hf_zbee_nwk_gp_cmd_step_color_transition_time = -1;
|
|
|
|
/* Step Up/Down command. */
|
|
static int hf_zbee_nwk_gp_cmd_step_up_down_step_size = -1;
|
|
static int hf_zbee_nwk_gp_cmd_step_up_down_transition_time = -1;
|
|
|
|
/* Proto tree elements. */
|
|
static gint ett_zbee_nwk = -1;
|
|
static gint ett_zbee_nwk_cmd = -1;
|
|
static gint ett_zbee_nwk_cmd_cinfo = -1;
|
|
static gint ett_zbee_nwk_cmd_ms_ext = -1;
|
|
static gint ett_zbee_nwk_cmd_options = -1;
|
|
static gint ett_zbee_nwk_fcf = -1;
|
|
static gint ett_zbee_nwk_fcf_ext = -1;
|
|
|
|
/* Common. */
|
|
static dissector_handle_t data_handle;
|
|
static GSList *zbee_gp_keyring = NULL;
|
|
static guint num_uat_key_records = 0;
|
|
|
|
typedef struct {
|
|
gchar *string;
|
|
guint8 byte_order;
|
|
gchar *label;
|
|
guint8 key[ZBEE_SEC_CONST_KEYSIZE];
|
|
} uat_key_record_t;
|
|
|
|
static uat_key_record_t *gp_uat_key_records = NULL;
|
|
static uat_t *zbee_gp_sec_key_table_uat;
|
|
|
|
/* UAT. */
|
|
UAT_CSTRING_CB_DEF(gp_uat_key_records, string, uat_key_record_t)
|
|
UAT_VS_DEF(gp_uat_key_records, byte_order, uat_key_record_t, guint8, 0, "Normal")
|
|
UAT_CSTRING_CB_DEF(gp_uat_key_records, label, uat_key_record_t)
|
|
|
|
/****************/
|
|
/* Field names. */
|
|
/****************/
|
|
|
|
/* Byte order. */
|
|
static const value_string byte_order_vals[] = {
|
|
{ 0, "Normal"},
|
|
{ 1, "Reverse"},
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* Application ID names. */
|
|
static const value_string zbee_nwk_gp_app_id_names[] = {
|
|
{ ZBEE_NWK_GP_APP_ID_LPED, "LPED" },
|
|
{ ZBEE_NWK_GP_APP_ID_ZGP, "ZGP" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* Green Power commands. */
|
|
static const value_string zbee_nwk_gp_cmd_names[] = {
|
|
{ ZB_GP_CMD_ID_ANY_SENSOR_COMMAND_A0_A3, "Any GPD sensor command (0xA0 - 0xA3)" },
|
|
{ ZB_GP_CMD_ID_ATTRIBUTE_REPORTING, "Attribute reporting" },
|
|
{ ZB_GP_CMD_ID_CHANNEL_CONFIGURATION, "Channel Configuration" },
|
|
{ ZB_GP_CMD_ID_CHANNEL_REQUEST, "Channel Request" },
|
|
{ ZB_GP_CMD_ID_COMMISSIONING, "Commissioning" },
|
|
{ ZB_GP_CMD_ID_COMMISSIONING_REPLY, "Commissioning Reply" },
|
|
{ ZB_GP_CMD_ID_DECOMMISSIONING, "Decommissioning" },
|
|
{ ZB_GP_CMD_ID_IDENTIFY, "Identify" },
|
|
{ ZB_GP_CMD_ID_LEVEL_CONTROL_STOP, "Level Control/Stop" },
|
|
{ ZB_GP_CMD_ID_LOCK_DOOR, "Lock Door" },
|
|
{ ZB_GP_CMD_ID_MANUFACTURER_SPECIFIC_MCLUSTER_REPORTING, "Manufacturer-specific multi-cluster reporting" },
|
|
{ ZB_GP_CMD_ID_MANUFACTURE_SPECIFIC_ATTR_REPORTING, "Manufacturer-specific attribute reporting" },
|
|
{ ZB_GP_CMD_ID_MOVE_COLOR, "Move Color" },
|
|
{ ZB_GP_CMD_ID_MOVE_DOWN, "Move Down" },
|
|
{ ZB_GP_CMD_ID_MOVE_DOWN_WITH_ON_OFF, "Move Down (with On/Off)" },
|
|
{ ZB_GP_CMD_ID_MOVE_HUE_DOWN, "Move Hue Down" },
|
|
{ ZB_GP_CMD_ID_MOVE_HUE_STOP, "Move Hue Stop" },
|
|
{ ZB_GP_CMD_ID_MOVE_HUE_UP, "Move Hue Up" },
|
|
{ ZB_GP_CMD_ID_MOVE_SATURATION_STOP, "Move Saturation Stop" },
|
|
{ ZB_GP_CMD_ID_MOVE_SATUREATION_DOWN, "Move Saturation Down" },
|
|
{ ZB_GP_CMD_ID_MOVE_SATUREATION_UP, "Move Saturation Up" },
|
|
{ ZB_GP_CMD_ID_MOVE_UP, "Move Up" },
|
|
{ ZB_GP_CMD_ID_MOVE_UP_WITH_ON_OFF, "Move Up (with On/Off)" },
|
|
{ ZB_GP_CMD_ID_MULTI_CLUSTER_REPORTING, "Multi-cluster reporting" },
|
|
{ ZB_GP_CMD_ID_OFF, "Off" },
|
|
{ ZB_GP_CMD_ID_ON, "On" },
|
|
{ ZB_GP_CMD_ID_PRESS11, "Press 1 of 1" },
|
|
{ ZB_GP_CMD_ID_PRESS12, "Press 1 of 2" },
|
|
{ ZB_GP_CMD_ID_PRESS22, "Press 2 of 2" },
|
|
{ ZB_GP_CMD_ID_READ_ATTRIBUTES, "Read Attributes" },
|
|
{ ZB_GP_CMD_ID_READ_ATTRIBUTES_RESPONSE, "Read Attributes Response" },
|
|
{ ZB_GP_CMD_ID_RELEASE11, "Release 1 of 1" },
|
|
{ ZB_GP_CMD_ID_RELEASE12, "Release 1 of 2" },
|
|
{ ZB_GP_CMD_ID_RELEASE22, "Release 2 of 2" },
|
|
{ ZB_GP_CMD_ID_RELEASE, "Release" },
|
|
{ ZB_GP_CMD_ID_REQUEST_ATTRIBUTES, "Request Attributes" },
|
|
{ ZB_GP_CMD_ID_SCENE0, "Scene 0" },
|
|
{ ZB_GP_CMD_ID_SCENE10, "Scene 10" },
|
|
{ ZB_GP_CMD_ID_SCENE11, "Scene 11" },
|
|
{ ZB_GP_CMD_ID_SCENE12, "Scene 12" },
|
|
{ ZB_GP_CMD_ID_SCENE13, "Scene 13" },
|
|
{ ZB_GP_CMD_ID_SCENE14, "Scene 14" },
|
|
{ ZB_GP_CMD_ID_SCENE15, "Scene 15" },
|
|
{ ZB_GP_CMD_ID_SCENE1, "Scene 1" },
|
|
{ ZB_GP_CMD_ID_SCENE2, "Scene 2" },
|
|
{ ZB_GP_CMD_ID_SCENE3, "Scene 3" },
|
|
{ ZB_GP_CMD_ID_SCENE4, "Scene 4" },
|
|
{ ZB_GP_CMD_ID_SCENE5, "Scene 5" },
|
|
{ ZB_GP_CMD_ID_SCENE6, "Scene 6" },
|
|
{ ZB_GP_CMD_ID_SCENE7, "Scene 7" },
|
|
{ ZB_GP_CMD_ID_SCENE8, "Scene 8" },
|
|
{ ZB_GP_CMD_ID_SCENE9, "Scene 9" },
|
|
{ ZB_GP_CMD_ID_SHORT_PRESS11, "Short press 1 of 1" },
|
|
{ ZB_GP_CMD_ID_SHORT_PRESS12, "Short press 1 of 2" },
|
|
{ ZB_GP_CMD_ID_SHORT_PRESS22, "Short press 2 of 2" },
|
|
{ ZB_GP_CMD_ID_STEP_COLOR, "Step Color" },
|
|
{ ZB_GP_CMD_ID_STEP_DOWN, "Step Down" },
|
|
{ ZB_GP_CMD_ID_STEP_DOWN_WITH_ON_OFF, "Step Down (with On/Off)" },
|
|
{ ZB_GP_CMD_ID_STEP_HUE_UP, "Step Hue Up" },
|
|
{ ZB_GP_CMD_ID_STEP_HUW_DOWN, "Step Hue Down" },
|
|
{ ZB_GP_CMD_ID_STEP_SATURATION_DOWN, "Step Saturation Down" },
|
|
{ ZB_GP_CMD_ID_STEP_SATURATION_UP, "Step Saturation Up" },
|
|
{ ZB_GP_CMD_ID_STEP_UP, "Step Up" },
|
|
{ ZB_GP_CMD_ID_STEP_UP_WITH_ON_OFF, "Step Up (with On/Off)" },
|
|
{ ZB_GP_CMD_ID_SUCCESS, "Success" },
|
|
{ ZB_GP_CMD_ID_TOGGLE, "Toggle" },
|
|
{ ZB_GP_CMD_ID_UNLOCK_DOOR, "Unlock Door" },
|
|
{ ZB_GP_CMD_ID_WRITE_ATTRIBUTES, "Write Attributes" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* Green Power devices. */
|
|
static const value_string zbee_nwk_gp_device_ids_names[] = {
|
|
|
|
/* GP GENERIC */
|
|
{ GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_1STATE_SWITCH, "Generic: GP Advanced Generic 1-state Switch" },
|
|
{ GPD_DEVICE_ID_GENERIC_GP_ADVANCED_GENERIC_2STATE_SWITCH, "Generic: GP Advanced Generic 2-state Switch" },
|
|
{ GPD_DEVICE_ID_GENERIC_GP_LEVEL_CONTROL_SWITCH, "Generic: GP Level Control Switch" },
|
|
{ GPD_DEVICE_ID_GENERIC_GP_ON_OFF_SWITCH, "Generic: GP On/Off Switch" },
|
|
{ GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_1STATE_SWITCH, "Generic: GP Simple Generic 1-state Switch" },
|
|
{ GPD_DEVICE_ID_GENERIC_GP_SIMPLE_GENERIC_2STATE_SWITCH, "Generic: GP Simple Generic 2-state Switch" },
|
|
{ GPD_DEVICE_ID_GENERIC_GP_SIMPLE_SENSOR, "Generic: GP Simple Sensor" },
|
|
|
|
/* GP LIGHTING */
|
|
{ GPD_DEVICE_ID_LIGHTING_GP_COLOR_DIMMER_SWITCH, "Lighting: GP Color Dimmer Switch" },
|
|
{ GPD_DEVICE_ID_LIGHTING_GP_LIGHT_SENSOR, "Lighting: GP Light Sensor" },
|
|
{ GPD_DEVICE_ID_LIGHTING_GP_OCCUPANCY_SENSOR, "Lighting: GP Occupancy Sensor" },
|
|
|
|
/* GP CLOSURES */
|
|
{ GPD_DEVICE_ID_CLOSURES_GP_DOOR_LOCK_CONTROLLER, "Closures: GP Door Lock Controller" },
|
|
|
|
/* HVAC */
|
|
{ GPD_DEVICE_ID_HVAC_GP_FLOW_SENSOR, "HVAC: GP Flow Sensor" },
|
|
{ GPD_DEVICE_ID_HVAC_GP_INDOOR_ENVIRONMENT_SENSOR, "HVAC: GP Indoor Environment Sensor" },
|
|
{ GPD_DEVICE_ID_HVAC_GP_PRESSURE_SENSOR, "HVAC: GP Pressure Sensor" },
|
|
{ GPD_DEVICE_ID_HVAC_GP_TEMPERATURE_SENSOR, "HVAC: GP Temperature Sensor" },
|
|
|
|
/* CUSTOM */
|
|
{ GPD_DEVICE_ID_MANUFACTURER_SPECIFIC, "Manufacturer Specific" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* GP directions. */
|
|
static const value_string zbee_nwk_gp_directions[] = {
|
|
{ ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD, "From ZGPD" },
|
|
{ ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPP, "From ZGPP" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* Frame types for Green Power profile. */
|
|
static const value_string zbee_nwk_gp_frame_types[] = {
|
|
{ ZBEE_NWK_GP_FCF_DATA, "Data" },
|
|
{ ZBEE_NWK_GP_FCF_MAINTENANCE, "Maintenance" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* GreenPeak Green Power devices. */
|
|
static const value_string zbee_nwk_gp_manufacturer_greenpeak_dev_names[] = {
|
|
{ ZBEE_NWK_GP_MANUF_GREENPEAK_IZDS, "IAS Zone Door Sensor" },
|
|
{ ZBEE_NWK_GP_MANUF_GREENPEAK_IZDWS, "IAS Zone Door/Window Sensor" },
|
|
{ ZBEE_NWK_GP_MANUF_GREENPEAK_IZLS, "IAS Zone Leakage Sensor" },
|
|
{ ZBEE_NWK_GP_MANUF_GREENPEAK_IZRHS, "IAS Zone Relative Humidity Sensor" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* GP manufacturers. */
|
|
static const value_string zbee_nwk_gp_manufacturers_ids_names[] = {
|
|
{ ZBEE_NWK_GP_MANUF_ID_GREENPEAK, "GreenPeak" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* GP Src ID names. */
|
|
static const value_string zbee_nwk_gp_src_id_names[] = {
|
|
{ ZBEE_NWK_GP_ZGPD_SRCID_ALL, "All" },
|
|
{ ZBEE_NWK_GP_ZGPD_SRCID_UNKNOWN, "Unspecified" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* GP security key type names. */
|
|
static const value_string zbee_nwk_gp_src_sec_keys_type_names[] = {
|
|
{ ZBEE_NWK_GP_SECURITY_KEY_TYPE_DERIVED_INDIVIDUAL_GPD_KEY, "Derived individual GPD key" },
|
|
{ ZBEE_NWK_GP_SECURITY_KEY_TYPE_GPD_GROUP_KEY, "GPD group key" },
|
|
{ ZBEE_NWK_GP_SECURITY_KEY_TYPE_NO_KEY, "No key" },
|
|
{ ZBEE_NWK_GP_SECURITY_KEY_TYPE_NWK_KEY_DERIVED_GPD_KEY_GROUP_KEY, "NWK key derived GPD group key" },
|
|
{ ZBEE_NWK_GP_SECURITY_KEY_TYPE_PRECONFIGURED_INDIVIDUAL_GPD_KEY, "Individual, out of the box GPD key" },
|
|
{ ZBEE_NWK_GP_SECURITY_KEY_TYPE_ZB_NWK_KEY, "ZigBee NWK key" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* GP security levels. */
|
|
static const value_string zbee_nwk_gp_src_sec_levels_names[] = {
|
|
{ ZBEE_NWK_GP_SECURITY_LEVEL_1LSB, "1 LSB of frame counter and short MIC only" },
|
|
{ ZBEE_NWK_GP_SECURITY_LEVEL_FULL, "Full frame counter and full MIC only" },
|
|
{ ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR, "Encryption with full frame counter and full MIC" },
|
|
{ ZBEE_NWK_GP_SECURITY_LEVEL_NO, "No security" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/*************************/
|
|
/* Function definitions. */
|
|
/*************************/
|
|
|
|
/* UAT record copy callback. */
|
|
static void *
|
|
uat_key_record_copy_cb(void *n, const void *o, size_t siz _U_)
|
|
{
|
|
uat_key_record_t *new_key = (uat_key_record_t *)n;
|
|
const uat_key_record_t *old_key = (uat_key_record_t *)o;
|
|
|
|
if (old_key->string) {
|
|
new_key->string = g_strdup(old_key->string);
|
|
} else {
|
|
new_key->string = NULL;
|
|
}
|
|
if (old_key->label) {
|
|
new_key->label = g_strdup(old_key->label);
|
|
} else {
|
|
new_key->label = NULL;
|
|
}
|
|
return new_key;
|
|
}
|
|
|
|
/* UAT record free callback. */
|
|
static void
|
|
uat_key_record_free_cb(void *r)
|
|
{
|
|
uat_key_record_t *key = (uat_key_record_t *)r;
|
|
if (key->string) {
|
|
g_free(key->string);
|
|
}
|
|
if (key->label) {
|
|
g_free(key->label);
|
|
}
|
|
}
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* zbee_gp_security_parse_key
|
|
* DESCRIPTION
|
|
* Parses a key string from left to right into a buffer with increasing (normal byte order) or decreasing (reverse
|
|
* byte order) address.
|
|
* PARAMETERS
|
|
* const gchar *key_str - pointer to the string
|
|
* guint8 *key_buf - destination buffer in memory
|
|
* gboolean byte_order - byte order
|
|
* RETURNS
|
|
* gboolean
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static gboolean
|
|
zbee_gp_security_parse_key(const gchar *key_str, guint8 *key_buf, gboolean byte_order)
|
|
{
|
|
gboolean string_mode = FALSE;
|
|
gchar temp;
|
|
int i, j;
|
|
|
|
memset(key_buf, 0, ZBEE_SEC_CONST_KEYSIZE);
|
|
if (key_str == NULL) {
|
|
return FALSE;
|
|
}
|
|
if ((temp = *key_str++) == '"') {
|
|
string_mode = TRUE;
|
|
temp = *key_str++;
|
|
}
|
|
j = byte_order ? ZBEE_SEC_CONST_KEYSIZE - 1 : 0;
|
|
for (i = ZBEE_SEC_CONST_KEYSIZE - 1; i >= 0; i--) {
|
|
if (string_mode) {
|
|
if (g_ascii_isprint(temp)) {
|
|
key_buf[j] = temp;
|
|
temp = *key_str++;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
if ((temp == ':') || (temp == '-') || (temp == ' ')) {
|
|
temp = *(key_str++);
|
|
}
|
|
if (g_ascii_isxdigit(temp)) {
|
|
key_buf[j] = g_ascii_xdigit_value(temp) << 4;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
temp = *(key_str++);
|
|
if (g_ascii_isxdigit(temp)) {
|
|
key_buf[j] |= g_ascii_xdigit_value(temp);
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
temp = *(key_str++);
|
|
}
|
|
if (byte_order) {
|
|
j--;
|
|
} else {
|
|
j++;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* UAT record update callback. */
|
|
static void
|
|
uat_key_record_update_cb(void *r, const char **err)
|
|
{
|
|
uat_key_record_t *rec = (uat_key_record_t *)r;
|
|
|
|
if (rec->string == NULL) {
|
|
*err = g_strdup_printf("Key can't be blank.");
|
|
} else {
|
|
g_strstrip(rec->string);
|
|
if (rec->string[0] != 0) {
|
|
*err = NULL;
|
|
if (!zbee_gp_security_parse_key(rec->string, rec->key, rec->byte_order)) {
|
|
*err = g_strdup_printf("Expecting %d hexadecimal bytes or a %d character double-quoted string",
|
|
ZBEE_SEC_CONST_KEYSIZE, ZBEE_SEC_CONST_KEYSIZE);
|
|
}
|
|
} else {
|
|
*err = g_strdup_printf("Key can't be blank.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_commissioning
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power commissioning.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_commissioning(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
guint8 comm_options = 0;
|
|
guint8 comm_ext_options = 0;
|
|
guint8 ms_ext_options = 0;
|
|
guint16 manufacturer_id = 0;
|
|
proto_item *ti = NULL;
|
|
proto_tree *field_tree = NULL;
|
|
|
|
/* Get Device ID and display it. */
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_device_id, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
/* Get Options Field, build subtree and display the results. */
|
|
comm_options = tvb_get_guint8(tvb, offset);
|
|
if (tree) {
|
|
ti = proto_tree_add_text(tree, tvb, offset, 1, "Options Field: 0x%02x", comm_options);
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_options);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_opt_ms_ext_present, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_opt_panid_req, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_opt_fixed_location, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_opt_ext_opt, tvb, offset, 1, ENC_NA);
|
|
}
|
|
offset += 1;
|
|
if (comm_options & ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS) {
|
|
/* Get extended Options Field, build subtree and display the results. */
|
|
comm_ext_options = tvb_get_guint8(tvb, offset);
|
|
if (tree) {
|
|
ti = proto_tree_add_text(tree, tvb, offset, 1, "Extended Options Field: 0x%02x", comm_ext_options);
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_options);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter, tvb, offset, 1, ENC_NA);
|
|
}
|
|
offset += 1;
|
|
if (comm_ext_options & ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT) {
|
|
/* Get security key and display it. */
|
|
proto_tree_add_text(tree, tvb, offset, NWK_CMD_SECURITY_KEY_LEN, "Security Key: %s",
|
|
tvb_get_string(wmem_packet_scope(), tvb, offset, NWK_CMD_SECURITY_KEY_LEN));
|
|
offset += NWK_CMD_SECURITY_KEY_LEN;
|
|
}
|
|
if (comm_ext_options & ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR) {
|
|
/* Get Security MIC and display it. */
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic, tvb, offset, 4, ENC_LITTLE_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
if (comm_ext_options & ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER) {
|
|
/* Get GPD Outgoing Frame Counter and display it. */
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_outgoing_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
}
|
|
/* Display manufacturer specific data. */
|
|
if (comm_options & ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MANUFACTURER_INFO) {
|
|
/* Display MS extensions. */
|
|
ms_ext_options = tvb_get_guint8(tvb, offset);
|
|
if (tree) {
|
|
ti = proto_tree_add_text(tree, tvb, offset, 1, "MS Extensions Field: 0x%02x", ms_ext_options);
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_ms_ext);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ms_ext_mip, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ms_ext_mmip, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ms_ext_gclp, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_ms_ext_crp, tvb, offset, 1, ENC_NA);
|
|
}
|
|
offset += 1;
|
|
if (ms_ext_options & ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_MIP) {
|
|
/* Get Manufacturer ID. */
|
|
manufacturer_id = tvb_get_letohs(tvb, offset);
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_manufacturer_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
}
|
|
if (ms_ext_options & ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_MMIP) {
|
|
/* Get Manufacturer Device ID. */
|
|
switch (manufacturer_id) {
|
|
case ZBEE_NWK_GP_MANUF_ID_GREENPEAK:
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id, tvb, offset, 2,
|
|
ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_commissioning */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_channel_request
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power channel request.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_channel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
proto_item *ti;
|
|
proto_tree *field_tree;
|
|
|
|
/* Get Command Options Field, build subtree and display the results. */
|
|
if (tree) {
|
|
ti = proto_tree_add_text(tree, tvb, offset, 1, "Channel Toggling Behaviour: 0x%02x", tvb_get_guint8(tvb,
|
|
offset));
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_options);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st, tvb, offset, 1,
|
|
ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd, tvb, offset, 1,
|
|
ENC_NA);
|
|
}
|
|
offset += 1;
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_channel_request */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_channel_configuration
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power channel configuration.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_channel_configuration(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
proto_item *ti;
|
|
proto_tree *field_tree;
|
|
|
|
/* Get Command Options Field, build subtree and display the results. */
|
|
if (tree) {
|
|
ti = proto_tree_add_text(tree, tvb, offset, 1, "Operational Channel: 0x%02x", tvb_get_guint8(tvb, offset));
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_options);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_channel_configuration, tvb, offset, 1, ENC_NA);
|
|
}
|
|
offset += 1;
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_channel_configuration */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_attr_reporting
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power commands attrib reporting.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_attr_reporting(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
guint16 cluster_id;
|
|
proto_item *ti;
|
|
proto_tree *field_tree;
|
|
|
|
/* Get cluster ID and add it into the tree. */
|
|
cluster_id = tvb_get_letohs(tvb, offset);
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_attr_report_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
|
|
offset += 2;
|
|
/* Create subtree and parse ZCL Write Attribute Payload. */
|
|
ti = proto_tree_add_text(tree, tvb, offset, 2, "Attribute reporting command for cluster: 0x%02X", cluster_id);
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_options);
|
|
dissect_zcl_write_attr(tvb, pinfo, field_tree, &offset, cluster_id);
|
|
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_attr_reporting */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_commissioning_reply
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power comissioning reply.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_commissioning_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
guint8 cr_options = 0;
|
|
proto_item *ti = NULL;
|
|
proto_tree *field_tree = NULL;
|
|
|
|
/* Get Options Field, build subtree and display the results. */
|
|
cr_options = tvb_get_guint8(tvb, offset);
|
|
if (tree) {
|
|
ti = proto_tree_add_text(tree, tvb, offset, 1, "Options Field: 0x%02x", cr_options);
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_cmd_options);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type, tvb, offset, 1, ENC_NA);
|
|
}
|
|
offset += 1;
|
|
/* Parse and display security Pan ID value. */
|
|
if (cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT) {
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_rep_pan_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
}
|
|
/* Parse and display security key. */
|
|
if (cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT) {
|
|
proto_tree_add_text(tree, tvb, offset, NWK_CMD_SECURITY_KEY_LEN, "Security Key: %s",
|
|
tvb_get_string(wmem_packet_scope(), tvb, offset, NWK_CMD_SECURITY_KEY_LEN));
|
|
offset += NWK_CMD_SECURITY_KEY_LEN;
|
|
}
|
|
/* Parse and display security MIC. */
|
|
if ((cr_options & ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR) && (cr_options &
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT)) {
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic, tvb, offset, 4, ENC_LITTLE_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_commissioning_reply */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_move_color
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power Move Color.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_move_color(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_move_color_ratex, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_move_color_ratey, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_move_color */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_move_up_down
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power Move Up/Down.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_move_up_down(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_move_up_down_rate, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_move_up_down */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_step_color
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power Step Color.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_step_color(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_color_stepx, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_color_stepy, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
/* Optional time field. */
|
|
if (tvb_reported_length(tvb) - offset >= 2) {
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_color_transition_time, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
}
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_step_color */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd_step_up_down
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power Step Up/Down.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* zbee_nwk_green_power_packet *packet - packet data.
|
|
* guint offset - current payload offset.
|
|
* RETURNS
|
|
* guint - payload processed offset.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd_step_up_down(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
|
|
zbee_nwk_green_power_packet *packet _U_, guint offset)
|
|
{
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_up_down_step_size, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
proto_tree_add_item(tree, hf_zbee_nwk_gp_cmd_step_up_down_transition_time, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
|
offset += 2;
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd_step_up_down */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp_cmd
|
|
* DESCRIPTION
|
|
* Dissector for ZigBee Green Power commands.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* void *data - raw packet private data.
|
|
* RETURNS
|
|
* guint - payload processed offset
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static guint
|
|
dissect_zbee_nwk_gp_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
guint offset = 0;
|
|
guint8 cmd_id = tvb_get_guint8(tvb, offset);
|
|
proto_item *cmd_root = NULL;
|
|
proto_tree *cmd_tree = NULL;
|
|
zbee_nwk_green_power_packet *packet = (zbee_nwk_green_power_packet *)data;
|
|
|
|
/* Create a subtree for the command. */
|
|
if (tree) {
|
|
cmd_root = proto_tree_add_text(tree, tvb, offset, tvb_length(tvb), "Command Frame: %s", val_to_str(cmd_id,
|
|
zbee_nwk_gp_cmd_names, "Unknown Command Frame"));
|
|
cmd_tree = proto_item_add_subtree(cmd_root, ett_zbee_nwk_cmd);
|
|
/* Add the command ID. */
|
|
proto_tree_add_uint(cmd_tree, hf_zbee_nwk_gp_command_id, tvb, offset, 1, cmd_id);
|
|
}
|
|
offset += 1;
|
|
/* Add the command name to the info column. */
|
|
col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(cmd_id, zbee_nwk_gp_cmd_names, "Unknown command"));
|
|
/* Handle the command for one of the following devices:
|
|
* - Door Lock Controller (IDs: 0x50 - 0x51);
|
|
* - GP Flow Sensor (IDs: 0xE0, 0xA0 - 0xA3);
|
|
* - GP Temperature Sensor (IDs: 0xE0, 0xA0 - 0xA3); */
|
|
switch(cmd_id) {
|
|
/* Payloadless GPDF commands sent by GPD. */
|
|
case ZB_GP_CMD_ID_IDENTIFY:
|
|
case ZB_GP_CMD_ID_SCENE0:
|
|
case ZB_GP_CMD_ID_SCENE1:
|
|
case ZB_GP_CMD_ID_SCENE2:
|
|
case ZB_GP_CMD_ID_SCENE3:
|
|
case ZB_GP_CMD_ID_SCENE4:
|
|
case ZB_GP_CMD_ID_SCENE5:
|
|
case ZB_GP_CMD_ID_SCENE6:
|
|
case ZB_GP_CMD_ID_SCENE7:
|
|
case ZB_GP_CMD_ID_SCENE8:
|
|
case ZB_GP_CMD_ID_SCENE9:
|
|
case ZB_GP_CMD_ID_SCENE10:
|
|
case ZB_GP_CMD_ID_SCENE11:
|
|
case ZB_GP_CMD_ID_SCENE12:
|
|
case ZB_GP_CMD_ID_SCENE13:
|
|
case ZB_GP_CMD_ID_SCENE14:
|
|
case ZB_GP_CMD_ID_SCENE15:
|
|
case ZB_GP_CMD_ID_OFF:
|
|
case ZB_GP_CMD_ID_ON:
|
|
case ZB_GP_CMD_ID_TOGGLE:
|
|
case ZB_GP_CMD_ID_RELEASE:
|
|
case ZB_GP_CMD_ID_LEVEL_CONTROL_STOP:
|
|
case ZB_GP_CMD_ID_MOVE_HUE_STOP:
|
|
case ZB_GP_CMD_ID_MOVE_SATURATION_STOP:
|
|
case ZB_GP_CMD_ID_LOCK_DOOR:
|
|
case ZB_GP_CMD_ID_UNLOCK_DOOR:
|
|
case ZB_GP_CMD_ID_PRESS11:
|
|
case ZB_GP_CMD_ID_RELEASE11:
|
|
case ZB_GP_CMD_ID_PRESS12:
|
|
case ZB_GP_CMD_ID_RELEASE12:
|
|
case ZB_GP_CMD_ID_PRESS22:
|
|
case ZB_GP_CMD_ID_RELEASE22:
|
|
case ZB_GP_CMD_ID_SHORT_PRESS11:
|
|
case ZB_GP_CMD_ID_SHORT_PRESS12:
|
|
case ZB_GP_CMD_ID_SHORT_PRESS22:
|
|
case ZB_GP_CMD_ID_DECOMMISSIONING:
|
|
case ZB_GP_CMD_ID_SUCCESS:
|
|
break;
|
|
/* GPDF commands with payload sent by GPD. */
|
|
case ZB_GP_CMD_ID_MOVE_UP:
|
|
case ZB_GP_CMD_ID_MOVE_DOWN:
|
|
case ZB_GP_CMD_ID_MOVE_UP_WITH_ON_OFF:
|
|
case ZB_GP_CMD_ID_MOVE_DOWN_WITH_ON_OFF:
|
|
case ZB_GP_CMD_ID_MOVE_HUE_UP:
|
|
case ZB_GP_CMD_ID_MOVE_HUE_DOWN:
|
|
case ZB_GP_CMD_ID_MOVE_SATUREATION_UP:
|
|
case ZB_GP_CMD_ID_MOVE_SATUREATION_DOWN:
|
|
offset = dissect_zbee_nwk_gp_cmd_move_up_down(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
case ZB_GP_CMD_ID_STEP_UP:
|
|
case ZB_GP_CMD_ID_STEP_DOWN:
|
|
case ZB_GP_CMD_ID_STEP_UP_WITH_ON_OFF:
|
|
case ZB_GP_CMD_ID_STEP_DOWN_WITH_ON_OFF:
|
|
case ZB_GP_CMD_ID_STEP_HUE_UP:
|
|
case ZB_GP_CMD_ID_STEP_HUW_DOWN:
|
|
case ZB_GP_CMD_ID_STEP_SATURATION_UP:
|
|
case ZB_GP_CMD_ID_STEP_SATURATION_DOWN:
|
|
offset = dissect_zbee_nwk_gp_cmd_step_up_down(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
case ZB_GP_CMD_ID_MOVE_COLOR:
|
|
offset = dissect_zbee_nwk_gp_cmd_move_color(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
case ZB_GP_CMD_ID_STEP_COLOR:
|
|
offset = dissect_zbee_nwk_gp_cmd_step_color(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
case ZB_GP_CMD_ID_ATTRIBUTE_REPORTING:
|
|
offset = dissect_zbee_nwk_gp_cmd_attr_reporting(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
case ZB_GP_CMD_ID_MANUFACTURE_SPECIFIC_ATTR_REPORTING:
|
|
case ZB_GP_CMD_ID_MULTI_CLUSTER_REPORTING:
|
|
case ZB_GP_CMD_ID_MANUFACTURER_SPECIFIC_MCLUSTER_REPORTING:
|
|
case ZB_GP_CMD_ID_REQUEST_ATTRIBUTES:
|
|
case ZB_GP_CMD_ID_READ_ATTRIBUTES_RESPONSE:
|
|
case ZB_GP_CMD_ID_ANY_SENSOR_COMMAND_A0_A3:
|
|
/* TODO: implement it. */
|
|
break;
|
|
case ZB_GP_CMD_ID_COMMISSIONING:
|
|
offset = dissect_zbee_nwk_gp_cmd_commissioning(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
case ZB_GP_CMD_ID_CHANNEL_REQUEST:
|
|
offset = dissect_zbee_nwk_gp_cmd_channel_request(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
/* GPDF commands sent to GPD. */
|
|
case ZB_GP_CMD_ID_COMMISSIONING_REPLY:
|
|
offset = dissect_zbee_nwk_gp_cmd_commissioning_reply(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
case ZB_GP_CMD_ID_WRITE_ATTRIBUTES:
|
|
case ZB_GP_CMD_ID_READ_ATTRIBUTES:
|
|
/* TODO: implement it. */
|
|
break;
|
|
case ZB_GP_CMD_ID_CHANNEL_CONFIGURATION:
|
|
offset = dissect_zbee_nwk_gp_cmd_channel_configuration(tvb, pinfo, cmd_tree, packet, offset);
|
|
break;
|
|
}
|
|
if (offset < tvb_reported_length(tvb)) {
|
|
/* There are leftover bytes! */
|
|
proto_tree *root = NULL;
|
|
tvbuff_t *leftover_tvb = tvb_new_subset_remaining(tvb, offset);
|
|
|
|
/* Correct the length of the command tree. */
|
|
if (tree) {
|
|
root = proto_tree_get_root(tree);
|
|
proto_item_set_len(cmd_root, offset);
|
|
}
|
|
/* Dump the tail. */
|
|
call_dissector(data_handle, leftover_tvb, pinfo, root);
|
|
}
|
|
return offset;
|
|
} /* dissect_zbee_nwk_gp_cmd */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* zbee_sec_make_nonce
|
|
* DESCRIPTION
|
|
* Fills in ZigBee GP security nonce from the provided packet structure.
|
|
* PARAMETERS
|
|
* zbee_nwk_green_power_packet *packet - ZigBee NWK packet.
|
|
* gchar *nonce - nonce buffer.
|
|
* RETURNS
|
|
* void
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static void
|
|
zbee_gp_make_nonce(zbee_nwk_green_power_packet *packet, gchar *nonce)
|
|
{
|
|
memset(nonce, 0, ZBEE_SEC_CONST_NONCE_LEN);
|
|
if (packet->direction == ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD) {
|
|
nonce[0] = (guint8)((packet->source_id) & 0xff);
|
|
nonce[1] = (guint8)((packet->source_id) >> 8 & 0xff);
|
|
nonce[2] = (guint8)((packet->source_id) >> 16 & 0xff);
|
|
nonce[3] = (guint8)((packet->source_id) >> 24 & 0xff);
|
|
}
|
|
nonce[4] = (guint8)((packet->source_id) & 0xff);
|
|
nonce[5] = (guint8)((packet->source_id) >> 8 & 0xff);
|
|
nonce[6] = (guint8)((packet->source_id) >> 16 & 0xff);
|
|
nonce[7] = (guint8)((packet->source_id) >> 24 & 0xff);
|
|
nonce[8] = (guint8)((packet->security_frame_counter) & 0xff);
|
|
nonce[9] = (guint8)((packet->security_frame_counter) >> 8 & 0xff);
|
|
nonce[10] = (guint8)((packet->security_frame_counter) >> 16 & 0xff);
|
|
nonce[11] = (guint8)((packet->security_frame_counter) >> 24 & 0xff);
|
|
if ((packet->application_id == ZBEE_NWK_GP_APP_ID_ZGP) && (packet->direction !=
|
|
ZBEE_NWK_GP_FC_EXT_DIRECTION_FROM_ZGPD)) {
|
|
nonce[12] = 0xa3;
|
|
} else {
|
|
nonce[12] = 0x05;
|
|
}
|
|
/* TODO: implement if application_id == ZB_ZGP_APP_ID_0000. */
|
|
/* TODO: implement if application_id != ZB_ZGP_APP_ID_0000. */
|
|
}
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* zbee_sec_decrypt_payload
|
|
* DESCRIPTION
|
|
* Creates a nonce and decrypts secured ZigBee GP payload.
|
|
* PARAMETERS
|
|
* zbee_nwk_green_power_packet *packet - ZigBee NWK packet.
|
|
* const gchar *enc_buffer - encoded payload buffer.
|
|
* const gchar offset - payload offset.
|
|
* guint8 *dec_buffer - decoded payload buffer.
|
|
* guint payload_len - payload length.
|
|
* guint mic_len - MIC length.
|
|
* guint8 *key - key.
|
|
* RETURNS
|
|
* gboolean
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static gboolean
|
|
zbee_gp_decrypt_payload(zbee_nwk_green_power_packet *packet, const gchar *enc_buffer, const gchar offset, guint8
|
|
*dec_buffer, guint payload_len, guint mic_len, guint8 *key)
|
|
{
|
|
guint8 *key_buffer = key;
|
|
guint8 nonce[ZBEE_SEC_CONST_NONCE_LEN];
|
|
|
|
zbee_gp_make_nonce(packet, nonce);
|
|
if (zbee_sec_ccm_decrypt(key_buffer, nonce, enc_buffer, enc_buffer + offset, dec_buffer, offset, payload_len,
|
|
mic_len)) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_gp
|
|
* DESCRIPTION
|
|
* ZigBee NWK packet dissection routine for Green Power profile.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* void *data - raw packet private data.
|
|
* RETURNS
|
|
* int
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static int
|
|
dissect_zbee_nwk_gp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
gboolean gp_decrypted;
|
|
GSList *GSList_i;
|
|
guint offset = 0;
|
|
guint8 *dec_buffer;
|
|
guint8 *enc_buffer;
|
|
guint8 fcf;
|
|
proto_tree *field_tree = NULL;
|
|
proto_tree *nwk_tree = NULL;
|
|
proto_item *proto_root = NULL;
|
|
proto_item *ti = NULL;
|
|
tvbuff_t *payload_tvb = NULL;
|
|
zbee_nwk_green_power_packet packet;
|
|
|
|
memset(&packet, 0, sizeof(packet));
|
|
/* Add ourself to the protocol column, clear the info column and create the protocol tree. */
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZigBee Green Power");
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
if (tree) {
|
|
proto_root = proto_tree_add_protocol_format(tree, proto_zbee_nwk_gp, tvb, offset, tvb_length(tvb),
|
|
"ZGP stub NWK header");
|
|
nwk_tree = proto_item_add_subtree(proto_root, ett_zbee_nwk);
|
|
}
|
|
enc_buffer = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, 0, tvb_length(tvb));
|
|
/* Get and parse the FCF. */
|
|
fcf = tvb_get_guint8(tvb, offset);
|
|
packet.frame_type = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_FRAME_TYPE);
|
|
packet.nwk_frame_control_extension = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_CONTROL_EXTENSION);
|
|
/* Display the FCF. */
|
|
if (tree) {
|
|
/* Create a subtree for the FCF. */
|
|
ti = proto_tree_add_text(nwk_tree, tvb, offset, 1, "Frame Control Field: %s (0x%02x)",
|
|
val_to_str(packet.frame_type, zbee_nwk_gp_frame_types, "Unknown Frame Type"), fcf);
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_fcf);
|
|
proto_tree_add_uint(field_tree, hf_zbee_nwk_gp_frame_type, tvb, offset, 1, fcf & ZBEE_NWK_GP_FCF_FRAME_TYPE);
|
|
proto_tree_add_uint(field_tree, hf_zbee_nwk_gp_proto_version, tvb, offset, 1, fcf & ZBEE_NWK_GP_FCF_VERSION);
|
|
proto_tree_add_boolean(field_tree, hf_zbee_nwk_gp_auto_commissioning, tvb, offset, 1, fcf &
|
|
ZBEE_NWK_GP_FCF_AUTO_COMMISSIONING);
|
|
proto_tree_add_boolean(field_tree, hf_zbee_nwk_gp_fc_ext, tvb, offset, 1, fcf &
|
|
ZBEE_NWK_GP_FCF_CONTROL_EXTENSION);
|
|
}
|
|
offset += 1;
|
|
/* Add the frame type to the info column and protocol root. */
|
|
if (tree) {
|
|
proto_item_append_text(proto_root, " %s", val_to_str(packet.frame_type, zbee_nwk_gp_frame_types,
|
|
"Unknown type"));
|
|
}
|
|
col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(packet.frame_type, zbee_nwk_gp_frame_types,
|
|
"Reserved frame type"));
|
|
if (packet.nwk_frame_control_extension) {
|
|
/* Display ext FCF. */
|
|
fcf = tvb_get_guint8(tvb, offset);
|
|
packet.application_id = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_EXT_APP_ID);
|
|
packet.security_level = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL);
|
|
packet.direction = zbee_get_bit_field(fcf, ZBEE_NWK_GP_FCF_EXT_DIRECTION);
|
|
/* Create a subtree for the extended FCF. */
|
|
if (tree) {
|
|
ti = proto_tree_add_text(nwk_tree, tvb, offset, 1, "Extended NWK Frame Control Field");
|
|
field_tree = proto_item_add_subtree(ti, ett_zbee_nwk_fcf_ext);
|
|
/* Add the fields. */
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_fc_ext_app_id, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_fc_ext_sec_level, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_fc_ext_sec_key, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_fc_ext_rx_after_tx, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(field_tree, hf_zbee_nwk_gp_fc_ext_direction, tvb, offset, 1, ENC_NA);
|
|
}
|
|
offset += 1;
|
|
}
|
|
if ((packet.frame_type == ZBEE_NWK_GP_FCF_DATA && !packet.nwk_frame_control_extension) || (packet.frame_type ==
|
|
ZBEE_NWK_GP_FCF_DATA && packet.nwk_frame_control_extension && packet.application_id ==
|
|
ZBEE_NWK_GP_APP_ID_DEFAULT) || (packet.frame_type == ZBEE_NWK_GP_FCF_MAINTENANCE &&
|
|
packet.nwk_frame_control_extension && packet.application_id == ZBEE_NWK_GP_APP_ID_DEFAULT && tvb_get_guint8(tvb,
|
|
offset) != ZB_GP_CMD_ID_CHANNEL_CONFIGURATION)) {
|
|
/* Display GPD Src ID. */
|
|
packet.source_id = tvb_get_letohl(tvb, offset);
|
|
proto_tree_add_item(nwk_tree, hf_zbee_nwk_gp_zgpd_src_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
|
|
proto_item_append_text(proto_root, ", GPD Src ID: 0x%04x", packet.source_id);
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, ", GPD Src ID: 0x%04x", packet.source_id);
|
|
offset += 4;
|
|
}
|
|
/* Display Security Frame Counter. */
|
|
packet.mic_size = 0;
|
|
if (packet.nwk_frame_control_extension) {
|
|
if (packet.application_id == ZBEE_NWK_GP_APP_ID_DEFAULT || packet.application_id == ZBEE_NWK_GP_APP_ID_ZGP) {
|
|
if (packet.security_level == ZBEE_NWK_GP_SECURITY_LEVEL_1LSB) {
|
|
packet.mic_size = 2;
|
|
} else if (packet.security_level == ZBEE_NWK_GP_SECURITY_LEVEL_FULL || packet.security_level ==
|
|
ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR) {
|
|
/* Get Security Frame Counter and display it. */
|
|
packet.mic_size = 4;
|
|
packet.security_frame_counter = tvb_get_letohl(tvb, offset);
|
|
proto_tree_add_item(nwk_tree, hf_zbee_nwk_gp_security_frame_counter, tvb, offset, 4,
|
|
ENC_LITTLE_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
}
|
|
}
|
|
/* Parse application payload. */
|
|
packet.payload_len = tvb_reported_length(tvb) - offset - packet.mic_size;
|
|
/* Ensure that the payload exists. */
|
|
if (packet.payload_len <= 0) {
|
|
THROW(BoundsError);
|
|
}
|
|
/* OK, payload exists. Parse MIC field if needed. */
|
|
if (packet.mic_size == 2) {
|
|
packet.mic = tvb_get_letohs(tvb, offset + packet.payload_len);
|
|
} else if (packet.mic_size == 4) {
|
|
packet.mic = tvb_get_letohl(tvb, offset + packet.payload_len);
|
|
}
|
|
payload_tvb = tvb_new_subset(tvb, offset, packet.payload_len, packet.payload_len);
|
|
if (packet.security_level != ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR) {
|
|
dissect_zbee_nwk_gp_cmd(payload_tvb, pinfo, nwk_tree, data);
|
|
}
|
|
offset += packet.payload_len;
|
|
/* Display MIC field. */
|
|
if (packet.mic_size) {
|
|
proto_tree_add_uint(nwk_tree, packet.mic_size == 4 ? hf_zbee_nwk_gp_security_mic_4b :
|
|
hf_zbee_nwk_gp_security_mic_2b, tvb, offset, packet.mic_size, packet.mic);
|
|
offset += packet.mic_size;
|
|
}
|
|
/* Save packet private data. */
|
|
data = (void *)&packet;
|
|
if ((offset < tvb_length(tvb)) && (packet.security_level != ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR)) {
|
|
THROW(BoundsError);
|
|
}
|
|
if (packet.security_level == ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR) {
|
|
dec_buffer = (guint8 *)g_malloc(packet.payload_len);
|
|
gp_decrypted = FALSE;
|
|
if (packet.security_level == ZBEE_NWK_GP_SECURITY_LEVEL_FULLENCR) {
|
|
GSList_i = zbee_gp_keyring;
|
|
while (GSList_i && !gp_decrypted) {
|
|
gp_decrypted = zbee_gp_decrypt_payload(&packet, enc_buffer, offset - packet.payload_len -
|
|
packet.mic_size, dec_buffer, packet.payload_len, packet.mic_size,
|
|
((key_record_t *)(GSList_i->data))->key);
|
|
if (!gp_decrypted) {
|
|
GSList_i = g_slist_next(GSList_i);
|
|
}
|
|
}
|
|
}
|
|
if (gp_decrypted) {
|
|
payload_tvb = tvb_new_child_real_data(tvb, dec_buffer, packet.payload_len, packet.payload_len);
|
|
add_new_data_source(pinfo, payload_tvb, "Decrypted GP Payload");
|
|
dissect_zbee_nwk_gp_cmd(payload_tvb, pinfo, nwk_tree, data);
|
|
g_free(dec_buffer);
|
|
return packet.payload_len;
|
|
} else {
|
|
g_free(dec_buffer);
|
|
payload_tvb = tvb_new_subset(tvb, offset - packet.payload_len - packet.mic_size, packet.payload_len, -1);
|
|
call_dissector(data_handle, payload_tvb, pinfo, tree);
|
|
}
|
|
}
|
|
return 0;
|
|
} /* dissect_zbee_nwk_gp */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* dissect_zbee_nwk_heur_gp
|
|
* DESCRIPTION
|
|
* Heuristic interpreter for the ZigBee Green Power dissectors.
|
|
* PARAMETERS
|
|
* tvbuff_t *tvb - pointer to buffer containing raw packet.
|
|
* packet_into *pinfo - pointer to packet information fields.
|
|
* proto_tree *tree - pointer to data tree Wireshark uses to display packet.
|
|
* void *data - raw packet private data.
|
|
* RETURNS
|
|
* Boolean value, whether it handles the packet or not.
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static gboolean
|
|
dissect_zbee_nwk_heur_gp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
ieee802154_packet *packet = (ieee802154_packet *)data;
|
|
|
|
/* Skip ZigBee beacons. */
|
|
if ((packet->frame_type == IEEE802154_FCF_BEACON) && (tvb_get_guint8(tvb, 0) == ZBEE_NWK_BEACON_PROCOL_ID))
|
|
return FALSE;
|
|
|
|
if (packet->dst_pan == IEEE802154_BCAST_PAN && packet->dst_addr_mode == IEEE802154_FCF_ADDR_SHORT &&
|
|
packet->dst16 == IEEE802154_BCAST_ADDR && packet->frame_type != IEEE802154_FCF_BEACON &&
|
|
packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) {
|
|
dissect_zbee_nwk_gp(tvb, pinfo, tree, data);
|
|
return TRUE;
|
|
}
|
|
/* 64-bit destination addressing mode support. */
|
|
if (packet->dst_addr_mode == IEEE802154_FCF_ADDR_EXT && packet->frame_type != IEEE802154_FCF_BEACON &&
|
|
packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) {
|
|
dissect_zbee_nwk_gp(tvb, pinfo, tree, data);
|
|
return TRUE;
|
|
}
|
|
/* All ZigBee 2006, 2007 and PRO frames must always have a 16-bit source address. */
|
|
if (packet->src_addr_mode != IEEE802154_FCF_ADDR_SHORT) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
} /* dissect_zbee_nwk_heur_gp */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* gp_init_zbee_security
|
|
* DESCRIPTION
|
|
* Init routine for the ZigBee GP profile security.
|
|
* PARAMETERS
|
|
* none
|
|
* RETURNS
|
|
* void
|
|
*---------------------------------------------------------------
|
|
*/
|
|
static void
|
|
gp_init_zbee_security(void)
|
|
{
|
|
guint i;
|
|
key_record_t key_record;
|
|
|
|
if (zbee_gp_keyring) {
|
|
g_slist_free(zbee_gp_keyring);
|
|
zbee_gp_keyring = NULL;
|
|
}
|
|
for (i = 0; gp_uat_key_records && (i < num_uat_key_records); i++) {
|
|
key_record.frame_num = 0;
|
|
key_record.label = g_strdup(gp_uat_key_records[i].label);
|
|
memcpy(&key_record.key, &gp_uat_key_records[i].key, ZBEE_SEC_CONST_KEYSIZE);
|
|
zbee_gp_keyring = g_slist_prepend(zbee_gp_keyring, g_memdup(&key_record, sizeof(key_record_t)));
|
|
}
|
|
}
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* proto_register_zbee_nwk_gp
|
|
* DESCRIPTION
|
|
* ZigBee NWK GP protocol registration routine.
|
|
* PARAMETERS
|
|
* none
|
|
* RETURNS
|
|
* void
|
|
*---------------------------------------------------------------
|
|
*/
|
|
void
|
|
proto_register_zbee_nwk_gp(void)
|
|
{
|
|
module_t *gp_zbee_prefs = NULL;
|
|
|
|
static hf_register_info hf[] = {
|
|
{ &hf_zbee_nwk_gp_auto_commissioning,
|
|
{ "Auto Commissioning", "zbee_nwk_gp.auto_commissioning", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_FCF_AUTO_COMMISSIONING, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_fc_ext,
|
|
{ "NWK Frame Extension", "zbee_nwk_gp.fc_extension", FT_BOOLEAN, 8, NULL, ZBEE_NWK_GP_FCF_CONTROL_EXTENSION,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_frame_type,
|
|
{ "Frame Type", "zbee_nwk_gp.frame_type", FT_UINT8, BASE_HEX, VALS(zbee_nwk_gp_frame_types),
|
|
ZBEE_NWK_GP_FCF_FRAME_TYPE, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_proto_version,
|
|
{ "Protocol Version", "zbee_nwk_gp.proto_version", FT_UINT8, BASE_DEC, NULL, ZBEE_NWK_GP_FCF_VERSION, NULL,
|
|
HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_fc_ext_app_id,
|
|
{ "Application ID", "zbee_nwk_gp.fc_ext_app_id", FT_UINT8, BASE_HEX, VALS(zbee_nwk_gp_app_id_names),
|
|
ZBEE_NWK_GP_FCF_EXT_APP_ID, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_fc_ext_direction,
|
|
{ "Direction", "zbee_nwk_gp.fc_ext_direction", FT_UINT8, BASE_HEX, VALS(zbee_nwk_gp_directions),
|
|
ZBEE_NWK_GP_FCF_EXT_DIRECTION, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_fc_ext_rx_after_tx,
|
|
{ "Rx After Tx", "zbee_nwk_gp.fc_ext_rxaftertx", FT_BOOLEAN, 8, NULL, ZBEE_NWK_GP_FCF_EXT_RX_AFTER_TX, NULL,
|
|
HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_fc_ext_sec_key,
|
|
{ "Security Key", "zbee_nwk_gp.fc_ext_security_key", FT_BOOLEAN, 8, NULL, ZBEE_NWK_GP_FCF_EXT_SECURITY_KEY,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_fc_ext_sec_level,
|
|
{ "Security Level", "zbee_nwk_gp.fc_ext_security_level", FT_UINT8, BASE_HEX,
|
|
VALS(zbee_nwk_gp_src_sec_levels_names), ZBEE_NWK_GP_FCF_EXT_SECURITY_LEVEL, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_zgpd_src_id,
|
|
{ "Src ID", "zbee_nwk_gp.source_id", FT_UINT32, BASE_HEX, VALS(zbee_nwk_gp_src_id_names), 0x0, NULL,
|
|
HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_security_frame_counter,
|
|
{ "Security Frame Counter", "zbee_nwk_gp.security_frame_counter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL,
|
|
HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_security_mic_2b,
|
|
{ "Security MIC", "zbee_nwk_gp.security_mic2", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_security_mic_4b,
|
|
{ "Security MIC", "zbee_nwk_gp.security_mic4", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_command_id,
|
|
{ "ZGPD Command ID", "zbee_nwk_gp.command_id", FT_UINT8, BASE_HEX, VALS(zbee_nwk_gp_cmd_names), 0x0, NULL,
|
|
HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_device_id,
|
|
{ "ZGPD Device ID", "zbee_nwk_gp.cmd.comm.dev_id", FT_UINT8, BASE_HEX, VALS(zbee_nwk_gp_device_ids_names),
|
|
0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_encr,
|
|
{ "GPD Key Encryption", "zbee_nwk_gp.cmd.comm.ext_opt.gpd_key_encr", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_ENCR, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ext_opt_gpd_key_present,
|
|
{ "GPD Key Present", "zbee_nwk_gp.cmd.comm.ext_opt.gpd_key_present", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_GPD_KEY_PRESENT, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ext_opt_key_type,
|
|
{ "Key Type", "zbee_nwk_gp.cmd.comm.ext_opt.key_type", FT_UINT8, BASE_HEX,
|
|
VALS(zbee_nwk_gp_src_sec_keys_type_names), ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_KEY_TYPE, NULL,
|
|
HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_outgoing_counter,
|
|
{ "GPD Outgoing Counter", "zbee_nwk_gp.cmd.comm.out_counter", FT_UINT32, BASE_HEX, NULL, 0x0, NULL,
|
|
HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ext_opt_sec_level_cap,
|
|
{ "Security Level Capabilities", "zbee_nwk_gp.cmd.comm.ext_opt.seclevel_cap", FT_UINT8, BASE_HEX, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_SEC_LEVEL_CAP, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_gpd_sec_key_mic,
|
|
{ "GPD Key MIC", "zbee_nwk_gp.cmd.comm.gpd_key_mic", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_opt_ext_opt,
|
|
{ "Extended Option Field", "zbee_nwk_gp.cmd.comm.opt.ext_opt_field", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_EXT_OPTIONS, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_opt_fixed_location,
|
|
{ "Fixed Location", "zbee_nwk_gp.cmd.comm.opt.fixed_location", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_FIXED_LOCATION, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_opt_mac_sec_num_cap,
|
|
{ "MAC Sequence number capability", "zbee_nwk_gp.cmd.comm.opt.mac_seq_num_cap", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MAC_SEQ, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_opt_ms_ext_present,
|
|
{ "MS Extensions Present", "zbee_nwk_gp.cmd.comm.opt.ms_ext_present", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_MANUFACTURER_INFO, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_opt_panid_req,
|
|
{ "PANId request", "zbee_nwk_gp.cmd.comm.opt.panid_req", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_PAN_ID_REQ, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_opt_rx_on_cap,
|
|
{ "RxOnCapability", "zbee_nwk_gp.cmd.comm.opt.rxon_cap", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_RX_ON_CAP, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_opt_sec_key_req,
|
|
{ "GP Security Key Request", "zbee_nwk_gp.cmd.comm.opt.seq_key_req", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_OPT_GP_SEC_KEY_REQ, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ext_opt_outgoing_counter,
|
|
{ "GPD Outgoing present", "zbee_nwk_gp.cmd.comm.ext_opt.outgoing_counter", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_EXT_OPT_OUT_COUNTER, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_manufacturer_greenpeak_dev_id,
|
|
{ "Manufacturer Model ID", "zbee_nwk_gp.cmd.comm.manufacturer_model_id", FT_UINT16, BASE_HEX,
|
|
VALS(zbee_nwk_gp_manufacturer_greenpeak_dev_names), 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_manufacturer_id,
|
|
{ "Manufacturer ID", "zbee_nwk_gp.cmd.comm.manufacturer_id", FT_UINT16, BASE_HEX,
|
|
VALS(zbee_nwk_gp_manufacturers_ids_names), 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ms_ext_crp,
|
|
{ "Cluster reports present", "zbee_nwk_gp.cmd.comm.ms_ext.crp", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_CRP , NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ms_ext_gclp,
|
|
{ "GP commands list present", "zbee_nwk_gp.cmd.comm.ms_ext.gclp", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_GCLP , NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ms_ext_mip,
|
|
{ "Manufacturer ID present", "zbee_nwk_gp.cmd.comm.ms_ext.mip", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_MIP , NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_ms_ext_mmip,
|
|
{ "Manufacturer Model ID present", "zbee_nwk_gp.cmd.comm.ms_ext.mmip", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_MS_EXT_MMIP , NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_rep_opt_key_encr,
|
|
{ "GPD Key Encryption", "zbee_nwk_gp.cmd.comm_reply.opt.sec_key_encr", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_ENCR, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_rep_opt_panid_present,
|
|
{ "PANID Present", "zbee_nwk_gp.cmd.comm_reply.opt.pan_id_present", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_PAN_ID_PRESENT, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_key_present,
|
|
{ "GPD Security Key Present", "zbee_nwk_gp.cmd.comm_reply.opt.sec_key_present", FT_BOOLEAN, 8, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_KEY_PRESENT, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_level,
|
|
{ "Security Level", "zbee_nwk_gp.cmd.comm_reply.opt.sec_level", FT_UINT8, BASE_HEX, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_SEC_LEVEL, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_rep_opt_sec_type,
|
|
{ "Key Type", "zbee_nwk_gp.cmd.comm_reply.opt.key_type", FT_UINT8, BASE_HEX, NULL,
|
|
ZBEE_NWK_GP_CMD_COMMISSIONING_REP_OPT_KEY_TYPE, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_comm_rep_pan_id,
|
|
{ "Manufacturer ID", "zbee_nwk_gp.cmd.comm_reply.pan_id", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_attr_report_cluster_id,
|
|
{ "ZigBee Cluster ID", "zbee_nwk_gp.cmd.comm.attr_report", FT_UINT16, BASE_HEX, VALS(zbee_aps_cid_names),
|
|
0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_1st,
|
|
{ "Rx channel in the next attempt", "zbee_nwk_gp.cmd.ch_req.1st", FT_UINT8, BASE_HEX, NULL,
|
|
ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_1ST, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_channel_request_toggling_behaviour_2nd,
|
|
{ "Rx channel in the second next attempt", "zbee_nwk_gp.ch_req.2nd", FT_UINT8, BASE_HEX, NULL,
|
|
ZBEE_NWK_GP_CMD_CHANNEL_REQUEST_2ND, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_channel_configuration,
|
|
{ "Operation channel", "zbee_nwk_gp.cmd.configuration_ch.operation_ch", FT_UINT8, BASE_HEX, NULL,
|
|
ZBEE_NWK_GP_CMD_CHANNEL_CONFIGURATION_OPERATION_CH, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_move_color_ratex,
|
|
{ "RateX", "zbee_nwk_gp.cmd.move_color.ratex", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_move_color_ratey,
|
|
{ "RateY", "zbee_nwk_gp.cmd.move_color.ratey", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_move_up_down_rate,
|
|
{ "Rate", "zbee_nwk_gp.cmd.move_up_down.rate", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_step_color_stepx,
|
|
{ "StepX", "zbee_nwk_gp.cmd.step_color.stepx", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_step_color_stepy,
|
|
{ "StepY", "zbee_nwk_gp.cmd.step_color.stepy", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_step_color_transition_time,
|
|
{ "Transition Time", "zbee_nwk_gp.cmd.step_color.transition_time", FT_UINT16, BASE_DEC, NULL, 0x0, NULL,
|
|
HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_step_up_down_step_size,
|
|
{ "Step Size", "zbee_nwk_gp.cmd.step_up_down.step_size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_zbee_nwk_gp_cmd_step_up_down_transition_time,
|
|
{ "Transition Time", "zbee_nwk_gp.cmd.step_up_down.transition_time", FT_UINT16, BASE_DEC, NULL, 0x0, NULL,
|
|
HFILL }}
|
|
};
|
|
|
|
static gint *ett[] = {
|
|
&ett_zbee_nwk,
|
|
&ett_zbee_nwk_cmd,
|
|
&ett_zbee_nwk_cmd_cinfo,
|
|
&ett_zbee_nwk_cmd_ms_ext,
|
|
&ett_zbee_nwk_cmd_options,
|
|
&ett_zbee_nwk_fcf,
|
|
&ett_zbee_nwk_fcf_ext
|
|
};
|
|
|
|
static uat_field_t key_uat_fields[] = {
|
|
UAT_FLD_CSTRING(gp_uat_key_records, string, "Key", "A 16-byte key."),
|
|
UAT_FLD_VS(gp_uat_key_records, byte_order, "Byte Order", byte_order_vals, "Byte order of a key."),
|
|
UAT_FLD_LSTRING(gp_uat_key_records, label, "Label", "User label for a key."),
|
|
UAT_END_FIELDS
|
|
};
|
|
|
|
proto_zbee_nwk_gp = proto_register_protocol("ZigBee Green Power Profile", "ZigBee Green Power",
|
|
ZBEE_PROTOABBREV_NWK_GP);
|
|
|
|
if (gp_zbee_prefs == NULL) {
|
|
gp_zbee_prefs = prefs_register_protocol(proto_zbee_nwk_gp, NULL);
|
|
}
|
|
|
|
zbee_gp_sec_key_table_uat = uat_new("ZigBee GP Security Keys", sizeof(uat_key_record_t), "zigbee_gp_keys", TRUE,
|
|
(void **)&gp_uat_key_records, &num_uat_key_records, UAT_AFFECTS_DISSECTION, NULL, uat_key_record_copy_cb,
|
|
uat_key_record_update_cb, uat_key_record_free_cb, NULL, key_uat_fields);
|
|
|
|
prefs_register_uat_preference(gp_zbee_prefs, "gp_key_table", "Pre-configured GP Security Keys",
|
|
"Pre-configured GP Security Keys.", zbee_gp_sec_key_table_uat);
|
|
|
|
register_init_routine(gp_init_zbee_security);
|
|
|
|
/* Register the Wireshark protocol. */
|
|
proto_register_field_array(proto_zbee_nwk_gp, hf, array_length(hf));
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
|
|
/* Register the dissectors. */
|
|
new_register_dissector(ZBEE_PROTOABBREV_NWK_GP, dissect_zbee_nwk_gp, proto_zbee_nwk_gp);
|
|
} /* proto_register_zbee_nwk_gp */
|
|
|
|
/*FUNCTION:------------------------------------------------------
|
|
* NAME
|
|
* proto_reg_handoff_zbee_nwk_gp
|
|
* DESCRIPTION
|
|
* Registers the ZigBee dissector with Wireshark.
|
|
* PARAMETERS
|
|
* none
|
|
* RETURNS
|
|
* void
|
|
*---------------------------------------------------------------
|
|
*/
|
|
void
|
|
proto_reg_handoff_zbee_nwk_gp(void)
|
|
{
|
|
/* Find the other dissectors we need. */
|
|
data_handle = find_dissector("data");
|
|
/* Register our dissector with IEEE 802.15.4. */
|
|
heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_zbee_nwk_heur_gp, proto_zbee_nwk_gp);
|
|
} /* proto_reg_handoff_zbee */
|