1 /* packet-zbee-zcl-general.c
2  * Dissector routines for the ZigBee ZCL General clusters like
3  * Basic, Identify, OnOff ...
4  * By Fabio Tarabelloni <fabio.tarabelloni@reloc.it>
5  * Copyright 2013 RELOC s.r.l.
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * SPDX-License-Identifier: GPL-2.0-or-later
12  */
13 
14 /*  Include Files */
15 #include "config.h"
16 
17 #include <epan/packet.h>
18 #include <epan/to_str.h>
19 #include <wsutil/bits_ctz.h>
20 #include <wsutil/utf8_entities.h>
21 
22 #include "packet-zbee.h"
23 #include "packet-zbee-aps.h"
24 #include "packet-zbee-zcl.h"
25 
26 
27 /* ########################################################################## */
28 /* #### (0x0000) BASIC CLUSTER ############################################## */
29 /* ########################################################################## */
30 
31 /*************************/
32 /* Defines               */
33 /*************************/
34 
35 /* Attributes */
36 #define ZBEE_ZCL_ATTR_ID_BASIC_ZCL_VERSION              0x0000  /* ZCL Version */
37 #define ZBEE_ZCL_ATTR_ID_BASIC_APPL_VERSION             0x0001  /* Application Version */
38 #define ZBEE_ZCL_ATTR_ID_BASIC_STACK_VERSION            0x0002  /* Stack Version */
39 #define ZBEE_ZCL_ATTR_ID_BASIC_HW_VERSION               0x0003  /* HW Version */
40 #define ZBEE_ZCL_ATTR_ID_BASIC_MANUFACTURER_NAME        0x0004  /* Manufacturer Name */
41 #define ZBEE_ZCL_ATTR_ID_BASIC_MODEL_ID                 0x0005  /* Model Identifier */
42 #define ZBEE_ZCL_ATTR_ID_BASIC_DATE_CODE                0x0006  /* Date Code */
43 #define ZBEE_ZCL_ATTR_ID_BASIC_POWER_SOURCE             0x0007  /* Power Source */
44 #define ZBEE_ZCL_ATTR_ID_BASIC_LOCATION_DESCR           0x0010  /* Location Description */
45 #define ZBEE_ZCL_ATTR_ID_BASIC_PHY_ENVIRONMENT          0x0011  /* Physical Environment */
46 #define ZBEE_ZCL_ATTR_ID_BASIC_DEVICE_ENABLED           0x0012  /* Device Enabled */
47 #define ZBEE_ZCL_ATTR_ID_BASIC_ALARM_MASK               0x0013  /* Alarm Mask */
48 #define ZBEE_ZCL_ATTR_ID_BASIC_DISABLE_LOCAL_CFG        0x0014  /* Disable Local Config */
49 #define ZBEE_ZCL_ATTR_ID_BASIC_SW_BUILD_ID              0x4000  /* SW Build Id */
50 
51 /* Server Commands Received */
52 #define ZBEE_ZCL_CMD_ID_BASIC_RESET_FACTORY_DEFAULTS    0x00  /* Reset to Factory Defaults */
53 
54 /* Server Commands Generated - None */
55 
56 /* Power Source Id */
57 #define ZBEE_ZCL_BASIC_PWR_SRC_UNKNOWN                  0x00    /* Unknown */
58 #define ZBEE_ZCL_BASIC_PWR_SRC_MAINS_1PH                0x01    /* Mains (single phase) */
59 #define ZBEE_ZCL_BASIC_PWR_SRC_MAINS_3PH                0x02    /* Mains (3 phase) */
60 #define ZBEE_ZCL_BASIC_PWR_SRC_BATTERY                  0x03    /* Battery */
61 #define ZBEE_ZCL_BASIC_PWR_SRC_DC_SRC                   0x04    /* DC source */
62 #define ZBEE_ZCL_BASIC_PWR_SRC_EMERGENCY_1              0x05    /* Emergency mains constantly powered */
63 #define ZBEE_ZCL_BASIC_PWR_SRC_EMERGENCY_2              0x06    /* Emergency mains and tranfer switch */
64 
65 /* Device Enable Values */
66 #define ZBEE_ZCL_BASIC_DISABLED                         0x00    /* Disabled */
67 #define ZBEE_ZCL_BASIC_ENABLED                          0x01    /* Enabled */
68 
69 /* Alarm Mask bit-mask */
70 #define ZBEE_ZCL_BASIC_ALARM_GEN_HW_FAULT               0x01    /* General hardware fault */
71 #define ZBEE_ZCL_BASIC_ALARM_GEN_SW_FAULT               0x02    /* General software fault */
72 #define ZBEE_ZCL_BASIC_ALARM_RESERVED                   0xfc    /* Reserved */
73 
74 /* Disable Local Config bit-mask */
75 #define ZBEE_ZCL_BASIC_DIS_LOC_CFG_RESET                0x01    /* Reset (to factory defaults) */
76 #define ZBEE_ZCL_BASIC_DIS_LOC_CFG_DEV_CFG              0x02    /* Device configuration */
77 #define ZBEE_ZCL_BASIC_DIS_LOC_CFG_RESERVED             0xfc    /* Reserved */
78 
79 /*************************/
80 /* Function Declarations */
81 /*************************/
82 
83 void proto_register_zbee_zcl_basic(void);
84 void proto_reg_handoff_zbee_zcl_basic(void);
85 
86 /* Command Dissector Helpers */
87 static void dissect_zcl_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
88 
89 /* Private functions prototype */
90 
91 /*************************/
92 /* Global Variables      */
93 /*************************/
94 /* Initialize the protocol and registered fields */
95 static int proto_zbee_zcl_basic = -1;
96 
97 static int hf_zbee_zcl_basic_attr_id = -1;
98 static int hf_zbee_zcl_basic_pwr_src = -1;
99 static int hf_zbee_zcl_basic_dev_en = -1;
100 static int hf_zbee_zcl_basic_alarm_mask = -1;
101 static int hf_zbee_zcl_basic_alarm_mask_gen_hw_fault = -1;
102 static int hf_zbee_zcl_basic_alarm_mask_gen_sw_fault = -1;
103 static int hf_zbee_zcl_basic_alarm_mask_reserved = -1;
104 static int hf_zbee_zcl_basic_disable_local_cfg = -1;
105 static int hf_zbee_zcl_basic_disable_local_cfg_reset = -1;
106 static int hf_zbee_zcl_basic_disable_local_cfg_device_cfg = -1;
107 static int hf_zbee_zcl_basic_disable_local_cfg_reserved = -1;
108 static int hf_zbee_zcl_basic_srv_rx_cmd_id = -1;
109 
110 /* Initialize the subtree pointers */
111 static gint ett_zbee_zcl_basic = -1;
112 static gint ett_zbee_zcl_basic_alarm_mask = -1;
113 static gint ett_zbee_zcl_basic_dis_local_cfg = -1;
114 
115 /* Attributes */
116 static const value_string zbee_zcl_basic_attr_names[] = {
117     { ZBEE_ZCL_ATTR_ID_BASIC_ZCL_VERSION,           "ZCL Version" },
118     { ZBEE_ZCL_ATTR_ID_BASIC_APPL_VERSION,          "Application Version" },
119     { ZBEE_ZCL_ATTR_ID_BASIC_STACK_VERSION,         "Stack Version" },
120     { ZBEE_ZCL_ATTR_ID_BASIC_HW_VERSION,            "HW Version" },
121     { ZBEE_ZCL_ATTR_ID_BASIC_MANUFACTURER_NAME,     "Manufacturer Name" },
122     { ZBEE_ZCL_ATTR_ID_BASIC_MODEL_ID,              "Model Identifier" },
123     { ZBEE_ZCL_ATTR_ID_BASIC_DATE_CODE,             "Date Code" },
124     { ZBEE_ZCL_ATTR_ID_BASIC_POWER_SOURCE,          "Power Source" },
125     { ZBEE_ZCL_ATTR_ID_BASIC_LOCATION_DESCR,        "Location Description" },
126     { ZBEE_ZCL_ATTR_ID_BASIC_PHY_ENVIRONMENT,       "Physical Environment" },
127     { ZBEE_ZCL_ATTR_ID_BASIC_DEVICE_ENABLED,        "Device Enabled" },
128     { ZBEE_ZCL_ATTR_ID_BASIC_ALARM_MASK,            "Alarm Mask" },
129     { ZBEE_ZCL_ATTR_ID_BASIC_DISABLE_LOCAL_CFG,     "Disable Local Config" },
130     { ZBEE_ZCL_ATTR_ID_BASIC_SW_BUILD_ID,           "Software Build Id" },
131     { 0, NULL }
132 };
133 
134 /* Server Commands Received */
135 static const value_string zbee_zcl_basic_srv_rx_cmd_names[] = {
136     { ZBEE_ZCL_CMD_ID_BASIC_RESET_FACTORY_DEFAULTS, "Reset to Factory Defaults" },
137     { 0, NULL }
138 };
139 
140 /* Power Source Names */
141 static const value_string zbee_zcl_basic_pwr_src_names[] = {
142     { ZBEE_ZCL_BASIC_PWR_SRC_UNKNOWN,       "Unknown" },
143     { ZBEE_ZCL_BASIC_PWR_SRC_MAINS_1PH,     "Mains (single phase)" },
144     { ZBEE_ZCL_BASIC_PWR_SRC_MAINS_3PH,     "Mains (3 phase)" },
145     { ZBEE_ZCL_BASIC_PWR_SRC_BATTERY,       "Battery" },
146     { ZBEE_ZCL_BASIC_PWR_SRC_DC_SRC,        "DC source" },
147     { ZBEE_ZCL_BASIC_PWR_SRC_EMERGENCY_1,   "Emergency mains constantly powered" },
148     { ZBEE_ZCL_BASIC_PWR_SRC_EMERGENCY_2,   "Emergency mains and transfer switch" },
149     { 0, NULL }
150 };
151 
152 /* Device Enable Names */
153 static const value_string zbee_zcl_basic_dev_en_names[] = {
154     { ZBEE_ZCL_BASIC_DISABLED,      "Disabled" },
155     { ZBEE_ZCL_BASIC_ENABLED,       "Enabled" },
156     { 0, NULL }
157 };
158 
159 /*************************/
160 /* Function Bodies       */
161 /*************************/
162 
163 /*FUNCTION:------------------------------------------------------
164  *  NAME
165  *      dissect_zbee_zcl_basic
166  *  DESCRIPTION
167  *      ZigBee ZCL Basic cluster dissector for wireshark.
168  *  PARAMETERS
169  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
170  *      packet_info *pinfo  - pointer to packet information fields
171  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
172  *      void *data          - pointer to ZCL packet structure.
173  *  RETURNS
174  *      int                 - length of parsed data.
175  *---------------------------------------------------------------
176  */
177 static int
dissect_zbee_zcl_basic(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)178 dissect_zbee_zcl_basic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
179 {
180     zbee_zcl_packet   *zcl;
181     guint             offset = 0;
182     guint8            cmd_id;
183 
184     /* Reject the packet if data is NULL */
185     if (data == NULL)
186         return 0;
187     zcl = (zbee_zcl_packet *)data;
188     cmd_id = zcl->cmd_id;
189 
190     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
191     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
192         /* Append the command name to the info column. */
193         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
194             val_to_str_const(cmd_id, zbee_zcl_basic_srv_rx_cmd_names, "Unknown Command"),
195             zcl->tran_seqno);
196 
197         if (tree) {
198             /* Add the command ID. */
199             proto_tree_add_item(tree, hf_zbee_zcl_basic_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
200         }
201         /*offset++;*/
202 
203         /* Call the appropriate command dissector */
204         switch (cmd_id) {
205 
206             case ZBEE_ZCL_CMD_ID_BASIC_RESET_FACTORY_DEFAULTS:
207                 /* No payload */
208                 break;
209 
210             default:
211                 break;
212         }
213     }
214 
215     return tvb_captured_length(tvb);
216 } /*dissect_zbee_zcl_basic*/
217 
218 
219 /*FUNCTION:------------------------------------------------------
220  *  NAME
221  *      dissect_zcl_basic_attr_data
222  *  DESCRIPTION
223  *      this function is called by ZCL foundation dissector in order to decode
224  *      specific cluster attributes data.
225  *  PARAMETERS
226  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
227  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
228  *      guint *offset       - pointer to buffer offset
229  *      guint16 attr_id     - attribute identifier
230  *      guint data_type     - attribute data type
231  *      gboolean client_attr- ZCL client
232  *  RETURNS
233  *      none
234  *---------------------------------------------------------------
235  */
236 void
dissect_zcl_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)237 dissect_zcl_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
238 {
239 
240     static int * const alarm_mask[] = {
241         &hf_zbee_zcl_basic_alarm_mask_gen_hw_fault,
242         &hf_zbee_zcl_basic_alarm_mask_gen_sw_fault,
243         &hf_zbee_zcl_basic_alarm_mask_reserved,
244         NULL
245     };
246 
247     static int * const local_cfg[] = {
248         &hf_zbee_zcl_basic_disable_local_cfg_reset,
249         &hf_zbee_zcl_basic_disable_local_cfg_device_cfg,
250         &hf_zbee_zcl_basic_disable_local_cfg_reserved,
251         NULL
252     };
253 
254     /* Dissect attribute data type and data */
255     switch (attr_id) {
256 
257         case ZBEE_ZCL_ATTR_ID_BASIC_POWER_SOURCE:
258             proto_tree_add_item(tree, hf_zbee_zcl_basic_pwr_src, tvb, *offset, 1, ENC_NA);
259             *offset += 1;
260             break;
261 
262         case ZBEE_ZCL_ATTR_ID_BASIC_DEVICE_ENABLED:
263             proto_tree_add_item(tree, hf_zbee_zcl_basic_dev_en, tvb, *offset, 1, ENC_NA);
264             *offset += 1;
265             break;
266 
267         case ZBEE_ZCL_ATTR_ID_BASIC_ALARM_MASK:
268             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_basic_alarm_mask , ett_zbee_zcl_basic_alarm_mask, alarm_mask, ENC_NA);
269             *offset += 1;
270             break;
271 
272         case ZBEE_ZCL_ATTR_ID_BASIC_DISABLE_LOCAL_CFG:
273             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_basic_disable_local_cfg , ett_zbee_zcl_basic_dis_local_cfg, local_cfg, ENC_NA);
274             *offset += 1;
275             break;
276 
277         case ZBEE_ZCL_ATTR_ID_BASIC_ZCL_VERSION:
278         case ZBEE_ZCL_ATTR_ID_BASIC_APPL_VERSION:
279         case ZBEE_ZCL_ATTR_ID_BASIC_STACK_VERSION:
280         case ZBEE_ZCL_ATTR_ID_BASIC_HW_VERSION:
281         case ZBEE_ZCL_ATTR_ID_BASIC_MANUFACTURER_NAME:
282         case ZBEE_ZCL_ATTR_ID_BASIC_MODEL_ID:
283         case ZBEE_ZCL_ATTR_ID_BASIC_DATE_CODE:
284         case ZBEE_ZCL_ATTR_ID_BASIC_PHY_ENVIRONMENT:
285         case ZBEE_ZCL_ATTR_ID_BASIC_LOCATION_DESCR:
286         case ZBEE_ZCL_ATTR_ID_BASIC_SW_BUILD_ID:
287         default:
288             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
289             break;
290     }
291 
292 } /*dissect_zcl_basic_attr_data*/
293 
294 
295 /*FUNCTION:------------------------------------------------------
296  *  NAME
297  *      proto_register_zbee_zcl_basic
298  *  DESCRIPTION
299  *      ZigBee ZCL Basic cluster protocol registration routine.
300  *  PARAMETERS
301  *      none
302  *  RETURNS
303  *      void
304  *---------------------------------------------------------------
305  */
306 void
proto_register_zbee_zcl_basic(void)307 proto_register_zbee_zcl_basic(void)
308 {
309     /* Setup list of header fields */
310     static hf_register_info hf[] = {
311 
312         { &hf_zbee_zcl_basic_attr_id,
313             { "Attribute", "zbee_zcl_general.basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_basic_attr_names),
314             0x00, NULL, HFILL } },
315 
316         { &hf_zbee_zcl_basic_pwr_src,
317             { "Power Source", "zbee_zcl_general.basic.attr.pwr_src", FT_UINT8, BASE_HEX, VALS(zbee_zcl_basic_pwr_src_names),
318             0x00, NULL, HFILL } },
319 
320         { &hf_zbee_zcl_basic_dev_en,
321             { "Device Enabled", "zbee_zcl_general.basic.attr.dev_en", FT_UINT8, BASE_HEX, VALS(zbee_zcl_basic_dev_en_names),
322             0x00, NULL, HFILL } },
323 
324         /* start Alarm Mask fields */
325         { &hf_zbee_zcl_basic_alarm_mask,
326             { "Alarm Mask",  "zbee_zcl_general.basic.attr.alarm_mask", FT_UINT8, BASE_HEX, NULL,
327                 0x0, NULL, HFILL } },
328 
329         { &hf_zbee_zcl_basic_alarm_mask_gen_hw_fault,
330             { "General hardware fault", "zbee_zcl_general.basic.attr.alarm_mask.gen_hw_fault", FT_UINT8, BASE_DEC, NULL,
331             ZBEE_ZCL_BASIC_ALARM_GEN_HW_FAULT, NULL, HFILL } },
332 
333         { &hf_zbee_zcl_basic_alarm_mask_gen_sw_fault,
334             { "General software fault", "zbee_zcl_general.basic.attr.alarm_mask.gen_sw_fault", FT_UINT8, BASE_DEC, NULL,
335             ZBEE_ZCL_BASIC_ALARM_GEN_SW_FAULT, NULL, HFILL } },
336 
337         { &hf_zbee_zcl_basic_alarm_mask_reserved,
338             { "Reserved", "zbee_zcl_general.basic.attr.alarm_mask.reserved", FT_UINT8, BASE_DEC, NULL,
339             ZBEE_ZCL_BASIC_ALARM_RESERVED, NULL, HFILL } },
340         /* end Alarm Mask fields */
341 
342         /* start Disable Local Config fields */
343         { &hf_zbee_zcl_basic_disable_local_cfg,
344             { "Disable Local Config",  "zbee_zcl_general.basic.attr.dis_loc_cfg", FT_UINT8, BASE_HEX, NULL,
345                 0x0, NULL, HFILL } },
346 
347         { &hf_zbee_zcl_basic_disable_local_cfg_reset,
348             { "Reset (to factory defaults)", "zbee_zcl_general.basic.attr.dis_loc_cfg.reset", FT_UINT8, BASE_DEC, NULL,
349             ZBEE_ZCL_BASIC_DIS_LOC_CFG_RESET , NULL, HFILL } },
350 
351         { &hf_zbee_zcl_basic_disable_local_cfg_device_cfg,
352             { "Device configuration", "zbee_zcl_general.basic.attr.dis_loc_cfg.dev_cfg", FT_UINT8, BASE_DEC, NULL,
353             ZBEE_ZCL_BASIC_DIS_LOC_CFG_DEV_CFG , NULL, HFILL } },
354 
355         { &hf_zbee_zcl_basic_disable_local_cfg_reserved,
356             { "Reserved", "zbee_zcl_general.basic.attr.dis_loc_cfg.reserved", FT_UINT8, BASE_DEC, NULL,
357             ZBEE_ZCL_BASIC_DIS_LOC_CFG_RESERVED , NULL, HFILL } },
358         /* end Disable Local Config fields */
359 
360         { &hf_zbee_zcl_basic_srv_rx_cmd_id,
361           { "Command", "zbee_zcl_general.basic.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_basic_srv_rx_cmd_names),
362             0x00, NULL, HFILL } }
363 
364     };
365 
366     /* ZCL Basic subtrees */
367     static gint *ett[] = {
368         &ett_zbee_zcl_basic,
369         &ett_zbee_zcl_basic_alarm_mask,
370         &ett_zbee_zcl_basic_dis_local_cfg
371     };
372 
373     /* Register the ZigBee ZCL Basic cluster protocol name and description */
374     proto_zbee_zcl_basic = proto_register_protocol("ZigBee ZCL Basic", "ZCL Basic", ZBEE_PROTOABBREV_ZCL_BASIC);
375     proto_register_field_array(proto_zbee_zcl_basic, hf, array_length(hf));
376     proto_register_subtree_array(ett, array_length(ett));
377 
378     /* Register the ZigBee ZCL Basic dissector. */
379     register_dissector(ZBEE_PROTOABBREV_ZCL_BASIC, dissect_zbee_zcl_basic, proto_zbee_zcl_basic);
380 } /*proto_register_zbee_zcl_basic*/
381 
382 /*FUNCTION:------------------------------------------------------
383  *  NAME
384  *      proto_reg_handoff_zbee_zcl_basic
385  *  DESCRIPTION
386  *      Hands off the ZCL Basic dissector.
387  *  PARAMETERS
388  *      none
389  *  RETURNS
390  *      none
391  *---------------------------------------------------------------
392  */
393 void
proto_reg_handoff_zbee_zcl_basic(void)394 proto_reg_handoff_zbee_zcl_basic(void)
395 {
396     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_BASIC,
397                             proto_zbee_zcl_basic,
398                             ett_zbee_zcl_basic,
399                             ZBEE_ZCL_CID_BASIC,
400                             ZBEE_MFG_CODE_NONE,
401                             hf_zbee_zcl_basic_attr_id,
402                             hf_zbee_zcl_basic_attr_id,
403                             hf_zbee_zcl_basic_srv_rx_cmd_id,
404                             -1,
405                             (zbee_zcl_fn_attr_data)dissect_zcl_basic_attr_data
406                          );
407 } /*proto_reg_handoff_zbee_zcl_basic*/
408 
409 
410 
411 /* ########################################################################## */
412 /* #### (0x0001) POWER CONFIGURATION CLUSTER ################################ */
413 /* ########################################################################## */
414 
415 /*************************/
416 /* Defines               */
417 /*************************/
418 
419 /* Attributes */
420 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE           0x0000  /* Mains voltage */
421 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_FREQUENCY         0x0001  /* Mains frerquency */
422 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_ALARM_MASK        0x0010  /* Mains Alarm Mask */
423 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_MIN_THR   0x0011  /* Mains Voltage Min Threshold */
424 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_MAX_THR   0x0012  /* Mains Voltage Max Threshold */
425 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_DWELL_TP  0x0013  /* Mains Voltage Dwell Trip Point */
426 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_VOLTAGE         0x0020  /* Battery Voltage */
427 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_PERCENTAGE      0x0021  /* Battery Percentage Remaining */
428 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_MANUFACTURER    0x0030  /* Battery Manufacturer */
429 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_SIZE            0x0031  /* Battery Size */
430 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_AH_RATING       0x0032  /* Battery AHr Rating */
431 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_QUANTITY        0x0033  /* Battery Quantity */
432 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_RATED_VOLTAGE   0x0034  /* Battery Rated Voltage */
433 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_ALARM_MASK      0x0035  /* Battery Alarm Mask */
434 #define ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_VOLTAGE_MIN_THR 0x0036  /* Battery Voltage Min Threshold */
435 
436 /* Server Commands Received - None */
437 
438 /* Server Commands Generated - None */
439 
440 /* Mains Alarm Mask bit-mask */
441 #define ZBEE_ZCL_POWER_CONF_MAINS_ALARM_LOW         0x01    /* Mains voltage too low */
442 #define ZBEE_ZCL_POWER_CONF_MAINS_ALARM_HIGH        0x02    /* Mains voltage too high */
443 #define ZBEE_ZCL_POWER_CONF_MAINS_ALARM_RESERVED    0xfc    /* Reserved */
444 
445 /* Battery Size values */
446 #define ZBEE_ZCL_POWER_CONF_BAT_TYPE_NO_BAT         0x00    /* No battery */
447 #define ZBEE_ZCL_POWER_CONF_BAT_TYPE_BUILT_IN       0x01    /* Built in */
448 #define ZBEE_ZCL_POWER_CONF_BAT_TYPE_OTHER          0x02    /* Other */
449 #define ZBEE_ZCL_POWER_CONF_BAT_TYPE_AA             0x03    /* AA */
450 #define ZBEE_ZCL_POWER_CONF_BAT_TYPE_AAA            0x04    /* AAA */
451 #define ZBEE_ZCL_POWER_CONF_BAT_TYPE_C              0x05    /* C */
452 #define ZBEE_ZCL_POWER_CONF_BAT_TYPE_D              0x06    /* D */
453 #define ZBEE_ZCL_POWER_CONF_BAT_TYPE_UNKNOWN        0xFF    /* Unknown */
454 
455 /* Battery alarm mask bit-mask */
456 #define ZBEE_ZCL_POWER_CONF_BATTERY_ALARM_LOW       0x01    /* Battery voltage too low */
457 #define ZBEE_ZCL_POWER_CONF_BATTERY_ALARM_RESERVED  0xfe    /* Reserved */
458 
459 /*************************/
460 /* Function Declarations */
461 /*************************/
462 
463 void proto_register_zbee_zcl_power_config(void);
464 void proto_reg_handoff_zbee_zcl_power_config(void);
465 
466 /* Command Dissector Helpers */
467 static void dissect_zcl_power_config_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
468 
469 /* Private functions prototype */
470 
471 /*************************/
472 /* Global Variables      */
473 /*************************/
474 /* Initialize the protocol and registered fields */
475 static int proto_zbee_zcl_power_config = -1;
476 static int hf_zbee_zcl_power_config_attr_id = -1;
477 static int hf_zbee_zcl_power_config_batt_type = -1;
478 static int hf_zbee_zcl_power_config_mains_alarm_mask = -1;
479 static int hf_zbee_zcl_power_config_mains_alarm_mask_low = -1;
480 static int hf_zbee_zcl_power_config_mains_alarm_mask_high = -1;
481 static int hf_zbee_zcl_power_config_mains_alarm_mask_reserved = -1;
482 static int hf_zbee_zcl_power_config_batt_alarm_mask = -1;
483 static int hf_zbee_zcl_power_config_batt_alarm_mask_low = -1;
484 static int hf_zbee_zcl_power_config_batt_alarm_mask_reserved = -1;
485 static int hf_zbee_zcl_power_config_mains_voltage = -1;
486 static int hf_zbee_zcl_power_config_mains_frequency = -1;
487 static int hf_zbee_zcl_power_config_mains_voltage_min_thr = -1;
488 static int hf_zbee_zcl_power_config_mains_voltage_max_thr = -1;
489 static int hf_zbee_zcl_power_config_mains_voltage_dwell_tp = -1;
490 static int hf_zbee_zcl_power_config_batt_voltage = -1;
491 static int hf_zbee_zcl_power_config_batt_percentage = -1;
492 static int hf_zbee_zcl_power_config_batt_ah_rating = -1;
493 static int hf_zbee_zcl_power_config_batt_rated_voltage = -1;
494 static int hf_zbee_zcl_power_config_batt_voltage_min_thr = -1;
495 /* Initialize the subtree pointers */
496 static gint ett_zbee_zcl_power_config = -1;
497 static gint ett_zbee_zcl_power_config_mains_alarm_mask = -1;
498 static gint ett_zbee_zcl_power_config_batt_alarm_mask = -1;
499 
500 /* Attributes */
501 static const value_string zbee_zcl_power_config_attr_names[] = {
502     { ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE,           "Mains Voltage" },
503     { ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_FREQUENCY,         "Mains Frequency" },
504     { ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_ALARM_MASK,        "Mains Alarm Mask" },
505     { ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_MIN_THR,   "Mains Voltage Min Threshold" },
506     { ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_MAX_THR,   "Mains Voltage Max Threshold" },
507     { ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_DWELL_TP,  "Mains Voltage Dwell Trip Point" },
508     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_VOLTAGE,         "Battery Voltage" },
509     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_PERCENTAGE,      "Battery Percentage Remaining" },
510     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_MANUFACTURER,    "Battery Manufacturer" },
511     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_SIZE,            "Battery Size" },
512     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_AH_RATING,       "Battery AHr Rating" },
513     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_QUANTITY,        "Battery Quantity" },
514     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_RATED_VOLTAGE,   "Battery Rated Voltage" },
515     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_ALARM_MASK,      "Battery Alarm Mask" },
516     { ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_VOLTAGE_MIN_THR, "Battery Voltage Minimum Threshold" },
517     { 0, NULL }
518 };
519 
520 
521 /* Battery size Names */
522 static const value_string zbee_zcl_power_config_batt_type_names[] = {
523     { ZBEE_ZCL_POWER_CONF_BAT_TYPE_NO_BAT,         "No battery" },
524     { ZBEE_ZCL_POWER_CONF_BAT_TYPE_BUILT_IN,       "Built in" },
525     { ZBEE_ZCL_POWER_CONF_BAT_TYPE_OTHER,          "Other" },
526     { ZBEE_ZCL_POWER_CONF_BAT_TYPE_AA,             "AA" },
527     { ZBEE_ZCL_POWER_CONF_BAT_TYPE_AAA,            "AAA" },
528     { ZBEE_ZCL_POWER_CONF_BAT_TYPE_C,              "C" },
529     { ZBEE_ZCL_POWER_CONF_BAT_TYPE_D,              "D" },
530     { ZBEE_ZCL_POWER_CONF_BAT_TYPE_UNKNOWN,        "Unknown" },
531     { 0, NULL }
532 };
533 
534 
535 /*************************/
536 /* Function Bodies       */
537 /*************************/
538 
539 /*FUNCTION:------------------------------------------------------
540  *  NAME
541  *      dissect_zbee_zcl_power_config
542  *  DESCRIPTION
543  *      ZigBee ZCL power configuration cluster dissector for wireshark.
544  *  PARAMETERS
545  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
546  *      packet_info *pinfo  - pointer to packet information fields
547  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
548  *  RETURNS
549  *      none
550  *---------------------------------------------------------------
551  */
552 static int
dissect_zbee_zcl_power_config(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)553 dissect_zbee_zcl_power_config(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
554 {
555     return tvb_captured_length(tvb);
556 } /*dissect_zbee_zcl_power_config*/
557 
558 /*FUNCTION:------------------------------------------------------
559  *  NAME
560  *    decode_power_conf_voltage
561  *  DESCRIPTION
562  *    this function decodes voltage values
563  *  PARAMETERS
564  *      guint *s        - string to display
565  *      guint32 value   - value to decode
566  *  RETURNS
567  *    none
568  *---------------------------------------------------------------
569  */
570 static void
decode_power_conf_voltage(gchar * s,guint32 value)571 decode_power_conf_voltage(gchar *s, guint32 value)
572 {
573     g_snprintf(s, ITEM_LABEL_LENGTH, "%d.%d [V]", value/10, value%10);
574     return;
575 } /*decode_power_conf_voltage*/
576 
577   /*FUNCTION:------------------------------------------------------
578   *  NAME
579   *    decode_power_conf_percentage
580   *  DESCRIPTION
581   *    this function decodes percentage values
582   *  PARAMETERS
583   *      guint *s        - string to display
584   *      guint32 value   - value to decode
585   *  RETURNS
586   *    none
587   *---------------------------------------------------------------
588   */
589 static void
decode_power_conf_percentage(gchar * s,guint32 value)590 decode_power_conf_percentage(gchar *s, guint32 value)
591 {
592     g_snprintf(s, ITEM_LABEL_LENGTH, "%.1f [%%]", value/2.0);
593     return;
594 } /*decode_power_conf_percentage*/
595 
596   /*FUNCTION:------------------------------------------------------
597  *  NAME
598  *    decode_power_conf_frequency
599  *  DESCRIPTION
600  *    this function decodes mains frequency values
601  *  PARAMETERS
602  *      guint *s        - string to display
603  *      guint32 value   - value to decode
604  *  RETURNS
605  *    none
606  *---------------------------------------------------------------
607  */
608 static void
decode_power_conf_frequency(gchar * s,guint32 value)609 decode_power_conf_frequency(gchar *s, guint32 value)
610 {
611     if(value == 0x00)
612         g_snprintf(s, ITEM_LABEL_LENGTH, "Frequency too low to be measured (or DC supply)");
613     else if(value == 0xfe)
614         g_snprintf(s, ITEM_LABEL_LENGTH, "Frequency too high to be measured");
615     else if (value == 0xff)
616         g_snprintf(s, ITEM_LABEL_LENGTH, "Frequency could not be measured");
617     else
618         g_snprintf(s, ITEM_LABEL_LENGTH, "%d [Hz]", value*2);
619     return;
620 } /*decode_power_conf_frequency*/
621 
622 /*FUNCTION:------------------------------------------------------
623  *  NAME
624  *    decode_power_conf_batt_AHr
625  *  DESCRIPTION
626  *    this function decodes battery capacity values
627  *  PARAMETERS
628  *      guint *s        - string to display
629  *      guint32 value   - value to decode
630  *  RETURNS
631  *    none
632  *---------------------------------------------------------------
633  */
634 static void
decode_power_conf_batt_AHr(gchar * s,guint32 value)635 decode_power_conf_batt_AHr(gchar *s, guint32 value)
636 {
637     g_snprintf(s, ITEM_LABEL_LENGTH, "%d [mAHr]", value*10);
638     return;
639 } /*decode_power_conf_batt_AHr*/
640 
641 /*FUNCTION:------------------------------------------------------
642  *  NAME
643  *      dissect_zcl_power_config_attr_data
644  *  DESCRIPTION
645  *      this function is called by ZCL foundation dissector in order to decode
646  *      specific cluster attributes data.
647  *  PARAMETERS
648  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
649  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
650  *      guint *offset       - pointer to buffer offset
651  *      guint16 attr_id     - attribute identifier
652  *      guint data_type     - attribute data type
653  *      gboolean client_attr- ZCL client
654  *  RETURNS
655  *      none
656  *---------------------------------------------------------------
657  */
658 void
dissect_zcl_power_config_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)659 dissect_zcl_power_config_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
660 {
661     proto_item *it;
662     static int * const mains_alarm_mask[] = {
663         &hf_zbee_zcl_power_config_mains_alarm_mask_low,
664         &hf_zbee_zcl_power_config_mains_alarm_mask_high,
665         &hf_zbee_zcl_power_config_mains_alarm_mask_reserved,
666         NULL
667     };
668 
669     static int * const batt_alarm_mask[] = {
670         &hf_zbee_zcl_power_config_batt_alarm_mask_low,
671         &hf_zbee_zcl_power_config_batt_alarm_mask_reserved,
672         NULL
673     };
674 
675     /* Dissect attribute data type and data */
676     switch (attr_id) {
677         case ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE:
678             proto_tree_add_item(tree, hf_zbee_zcl_power_config_mains_voltage, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
679             *offset += 2;
680             break;
681         case ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_FREQUENCY:
682             proto_tree_add_item(tree, hf_zbee_zcl_power_config_mains_frequency, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
683             *offset += 1;
684             break;
685         case ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_ALARM_MASK:
686             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_power_config_mains_alarm_mask, ett_zbee_zcl_power_config_mains_alarm_mask, mains_alarm_mask, ENC_LITTLE_ENDIAN);
687             *offset += 1;
688             break;
689         case ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_MIN_THR:
690             proto_tree_add_item(tree, hf_zbee_zcl_power_config_mains_voltage_min_thr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
691             *offset += 2;
692             break;
693         case ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_MAX_THR:
694             proto_tree_add_item(tree, hf_zbee_zcl_power_config_mains_voltage_max_thr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
695             *offset += 2;
696             break;
697         case ZBEE_ZCL_ATTR_ID_POWER_CONF_MAINS_VOLTAGE_DWELL_TP:
698             it = proto_tree_add_item(tree, hf_zbee_zcl_power_config_mains_voltage_dwell_tp, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
699             proto_item_append_text(it, " [s]");
700             *offset += 2;
701             break;
702         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_SIZE:
703             proto_tree_add_item(tree, hf_zbee_zcl_power_config_batt_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
704             *offset += 1;
705             break;
706         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_VOLTAGE:
707             proto_tree_add_item(tree, hf_zbee_zcl_power_config_batt_voltage, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
708             *offset += 1;
709             break;
710         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_PERCENTAGE:
711             proto_tree_add_item(tree, hf_zbee_zcl_power_config_batt_percentage, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
712             *offset += 1;
713             break;
714         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_AH_RATING:
715             proto_tree_add_item(tree, hf_zbee_zcl_power_config_batt_ah_rating, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
716             *offset += 2;
717             break;
718         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_RATED_VOLTAGE:
719             proto_tree_add_item(tree, hf_zbee_zcl_power_config_batt_rated_voltage, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
720             *offset += 1;
721             break;
722         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_ALARM_MASK:
723             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_power_config_batt_alarm_mask, ett_zbee_zcl_power_config_batt_alarm_mask, batt_alarm_mask, ENC_LITTLE_ENDIAN);
724             *offset += 1;
725             break;
726         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_VOLTAGE_MIN_THR:
727             proto_tree_add_item(tree, hf_zbee_zcl_power_config_batt_voltage_min_thr, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
728             *offset += 1;
729             break;
730 
731         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_MANUFACTURER:
732         case ZBEE_ZCL_ATTR_ID_POWER_CONF_BATTERY_QUANTITY:
733         default:
734             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
735             break;
736     }
737 
738 } /*dissect_zcl_power_config_attr_data*/
739 
740 
741 /*FUNCTION:------------------------------------------------------
742  *  NAME
743  *      proto_register_zbee_zcl_power_config
744  *  DESCRIPTION
745  *      ZigBee ZCL power configuration cluster protocol registration routine.
746  *  PARAMETERS
747  *      none
748  *  RETURNS
749  *      void
750  *---------------------------------------------------------------
751  */
752 void
proto_register_zbee_zcl_power_config(void)753 proto_register_zbee_zcl_power_config(void)
754 {
755     /* Setup list of header fields */
756     static hf_register_info hf[] = {
757 
758         { &hf_zbee_zcl_power_config_attr_id,
759             { "Attribute", "zbee_zcl_general.power_config.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_power_config_attr_names),
760             0x00, NULL, HFILL } },
761 
762         { &hf_zbee_zcl_power_config_batt_type,
763             { "Battery Type", "zbee_zcl_general.power_config.attr.batt_type", FT_UINT8, BASE_HEX, VALS(zbee_zcl_power_config_batt_type_names),
764             0x00, NULL, HFILL } },
765 
766         /* start mains Alarm Mask fields */
767         { &hf_zbee_zcl_power_config_mains_alarm_mask,
768             { "Mains Alarm Mask",  "zbee_zcl_general.power_config.attr.mains_alarm_mask", FT_UINT8, BASE_HEX, NULL,
769                 0x0, NULL, HFILL } },
770 
771         { &hf_zbee_zcl_power_config_mains_alarm_mask_low,
772             { "Mains Voltage too low", "zbee_zcl_general.power_config.attr.mains_alarm_mask.mains_too_low", FT_UINT8, BASE_DEC, NULL,
773             ZBEE_ZCL_POWER_CONF_MAINS_ALARM_LOW, NULL, HFILL } },
774 
775         { &hf_zbee_zcl_power_config_mains_alarm_mask_high,
776             { "Mains Voltage too high", "zbee_zcl_general.power_config.attr.mains_alarm_mask.mains_too_high", FT_UINT8, BASE_DEC, NULL,
777             ZBEE_ZCL_POWER_CONF_MAINS_ALARM_HIGH, NULL, HFILL } },
778 
779         { &hf_zbee_zcl_power_config_mains_alarm_mask_reserved,
780             { "Reserved", "zbee_zcl_general.power_config.attr.mains_alarm_mask.reserved", FT_UINT8, BASE_DEC, NULL,
781             ZBEE_ZCL_POWER_CONF_MAINS_ALARM_RESERVED, NULL, HFILL } },
782         /* end mains Alarm Mask fields */
783 
784         /* start battery Alarm Mask fields */
785         { &hf_zbee_zcl_power_config_batt_alarm_mask,
786             { "Battery Alarm Mask",  "zbee_zcl_general.power_config.attr.batt_alarm_mask", FT_UINT8, BASE_HEX, NULL,
787                 0x0, NULL, HFILL } },
788 
789         { &hf_zbee_zcl_power_config_batt_alarm_mask_low,
790             { "Battery Voltage too low", "zbee_zcl_general.power_config.batt_attr.alarm_mask.batt_too_low", FT_UINT8, BASE_DEC, NULL,
791             ZBEE_ZCL_POWER_CONF_BATTERY_ALARM_LOW, NULL, HFILL } },
792 
793         { &hf_zbee_zcl_power_config_batt_alarm_mask_reserved,
794             { "Reserved", "zbee_zcl_general.power_config.attr.batt_alarm_mask.reserved", FT_UINT8, BASE_DEC, NULL,
795             ZBEE_ZCL_POWER_CONF_BATTERY_ALARM_RESERVED, NULL, HFILL } },
796         /* end battery Alarm Mask fields */
797 
798         { &hf_zbee_zcl_power_config_mains_voltage,
799             { "Measured Mains Voltage", "zbee_zcl_general.power_config.attr.mains_voltage", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_power_conf_voltage),
800             0x00, NULL, HFILL } },
801 
802         { &hf_zbee_zcl_power_config_mains_frequency,
803             { "Measured Mains Frequency", "zbee_zcl_general.power_config.attr.mains_frequency", FT_UINT8, BASE_CUSTOM, CF_FUNC(decode_power_conf_frequency),
804             0x00, NULL, HFILL } },
805 
806         { &hf_zbee_zcl_power_config_mains_voltage_min_thr,
807             { "Mains Voltage Minimum Threshold", "zbee_zcl_general.power_config.attr.mains_volt_min", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_power_conf_voltage),
808             0x00, NULL, HFILL } },
809 
810         { &hf_zbee_zcl_power_config_mains_voltage_max_thr,
811             { "Mains Voltage Maximum Threshold", "zbee_zcl_general.power_config.attr.mains_volt_max", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_power_conf_voltage),
812             0x00, NULL, HFILL } },
813 
814         { &hf_zbee_zcl_power_config_batt_voltage,
815             { "Measured Battery Voltage", "zbee_zcl_general.power_config.attr.batt_voltage", FT_UINT8, BASE_CUSTOM, CF_FUNC(decode_power_conf_voltage),
816             0x00, NULL, HFILL } },
817 
818         { &hf_zbee_zcl_power_config_batt_percentage,
819             { "Remaining Battery Percentage", "zbee_zcl_general.power_config.attr.batt_percentage", FT_UINT8, BASE_CUSTOM, CF_FUNC(decode_power_conf_percentage),
820             0x00, NULL, HFILL } },
821 
822         { &hf_zbee_zcl_power_config_batt_ah_rating,
823             { "Battery Capacity", "zbee_zcl_general.power_config.attr.batt_AHr", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_power_conf_batt_AHr),
824             0x00, NULL, HFILL } },
825 
826         { &hf_zbee_zcl_power_config_batt_rated_voltage,
827             { "Battery Rated Voltage", "zbee_zcl_general.power_config.attr.batt_rated_voltage", FT_UINT8, BASE_CUSTOM, CF_FUNC(decode_power_conf_voltage),
828             0x00, NULL, HFILL } },
829 
830         { &hf_zbee_zcl_power_config_batt_voltage_min_thr,
831             { "Battery Voltage Minimum Threshold", "zbee_zcl_general.power_config.attr.batt_voltage_min_thr", FT_UINT8, BASE_CUSTOM, CF_FUNC(decode_power_conf_voltage),
832             0x00, NULL, HFILL } },
833 
834         { &hf_zbee_zcl_power_config_mains_voltage_dwell_tp,
835             { "Mains Voltage Dwell Trip Point", "zbee_zcl_general.power_config.attr.mains_dwell_tp", FT_UINT16, BASE_DEC, NULL,
836             0x00, NULL, HFILL } },
837     };
838 
839     /* ZCL power configuration subtrees */
840     static gint *ett[] = {
841         &ett_zbee_zcl_power_config,
842         &ett_zbee_zcl_power_config_mains_alarm_mask,
843         &ett_zbee_zcl_power_config_batt_alarm_mask
844     };
845 
846     /* Register the ZigBee ZCL power configuration cluster protocol name and description */
847     proto_zbee_zcl_power_config = proto_register_protocol("ZigBee ZCL Power Configuration", "ZCL Power Configuration", ZBEE_PROTOABBREV_ZCL_POWER_CONFIG);
848     proto_register_field_array(proto_zbee_zcl_power_config, hf, array_length(hf));
849     proto_register_subtree_array(ett, array_length(ett));
850 
851     /* Register the ZigBee ZCL power configuration dissector. */
852     register_dissector(ZBEE_PROTOABBREV_ZCL_POWER_CONFIG, dissect_zbee_zcl_power_config, proto_zbee_zcl_power_config);
853 } /*proto_register_zbee_zcl_power_config*/
854 
855 /*FUNCTION:------------------------------------------------------
856  *  NAME
857  *      proto_reg_handoff_zbee_zcl_power_config
858  *  DESCRIPTION
859  *      Hands off the ZCL power configuration dissector.
860  *  PARAMETERS
861  *      none
862  *  RETURNS
863  *      none
864  *---------------------------------------------------------------
865  */
866 void
proto_reg_handoff_zbee_zcl_power_config(void)867 proto_reg_handoff_zbee_zcl_power_config(void)
868 {
869     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_POWER_CONFIG,
870                             proto_zbee_zcl_power_config,
871                             ett_zbee_zcl_power_config,
872                             ZBEE_ZCL_CID_POWER_CONFIG,
873                             ZBEE_MFG_CODE_NONE,
874                             hf_zbee_zcl_power_config_attr_id,
875                             hf_zbee_zcl_power_config_attr_id,
876                             -1, -1,
877                             (zbee_zcl_fn_attr_data)dissect_zcl_power_config_attr_data
878                          );
879 } /*proto_reg_handoff_zbee_zcl_power_config*/
880 
881 
882 /* ########################################################################## */
883 /* #### (0x0002) DEVICE TEMPERATURE CONFIGURATION CLUSTER ################### */
884 /* ########################################################################## */
885 
886 /*************************/
887 /* Defines               */
888 /*************************/
889 
890 /*Attributes*/
891 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_CURRENT_TEMP                  0x0000  /*Current Temperature*/
892 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_MIN_TEMP_EXP                  0x0001  /*Min Temperature Experienced*/
893 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_MAX_TEMP_EXP                  0x0002  /*Max Temperature Experienced*/
894 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_OVER_TEMP_TOTAL_DWELL         0x0003  /*Over Temperature Total Dwell*/
895 
896 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK        0x0010  /*Device Temperature Alarm Mask*/
897 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_LOW_TEMP_THRESHOLD            0x0011  /*Low Temperature Threshold*/
898 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_HIGH_TEMP_THRESHOLD           0x0012  /*High Temperature Threshold*/
899 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_LOW_TEMP_DWELL_TRIP_POINT     0x0013  /*Low Temperature Dwell Trip Point*/
900 #define ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_HIGH_TEMP_DWELL_TRIP_POINT    0x0014  /*High Temperature Dwell Trip Point*/
901 
902 /*Server commands received - none*/
903 
904 /*Server commands generated - none*/
905 
906 /*Device Temperature Alarm Mask Value*/
907 #define ZBEE_ZCL_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK_TOO_LOW        0x01    /*Mains Voltage too low*/
908 #define ZBEE_ZCL_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK_TOO_HIGH       0x02    /*Mains Voltage too high*/
909 #define ZBEE_ZCL_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK_RESERVED       0xfc    /*Mains Voltage reserved*/
910 
911 /*************************/
912 /* Function Declarations */
913 /*************************/
914 
915 void proto_register_zbee_zcl_device_temperature_configuration(void);
916 void proto_reg_handoff_zbee_zcl_device_temperature_configuration(void);
917 
918 /* Command Dissector Helpers */
919 static void dissect_zcl_device_temperature_configuration_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
920 
921 /* Private functions prototype */
922 
923 /*************************/
924 /* Global Variables      */
925 /*************************/
926 /* Initialize the protocol and registered fields */
927 static int proto_zbee_zcl_device_temperature_configuration = -1;
928 
929 static int hf_zbee_zcl_device_temperature_configuration_attr_id = -1;
930 static int hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask = -1;
931 static int hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_too_low = -1;
932 static int hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_too_high = -1;
933 static int hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_reserved = -1;
934 
935 /* Initialize the subtree pointers */
936 static gint ett_zbee_zcl_device_temperature_configuration = -1;
937 static gint ett_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask = -1;
938 
939 /* Attributes */
940 static const value_string zbee_zcl_device_temperature_configuration_attr_names[] = {
941     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_CURRENT_TEMP,                   "Current Temperature" },
942     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_MIN_TEMP_EXP,                   "Min Temperature Experienced" },
943     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_MAX_TEMP_EXP,                   "Max Temperature Experienced" },
944     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_OVER_TEMP_TOTAL_DWELL,          "Over Temperature Total Dwell" },
945     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK,         "Device Temperature Alarm Mask" },
946     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_LOW_TEMP_THRESHOLD,             "Low Temperature Threshold" },
947     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_HIGH_TEMP_THRESHOLD,            "High Temperature Threshold" },
948     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_LOW_TEMP_DWELL_TRIP_POINT,      "Low Temperature Dwell Trip Point" },
949     { ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_HIGH_TEMP_DWELL_TRIP_POINT,     "High Temperature Dwell Trip Point" },
950     { 0, NULL }
951 };
952 
953 /*************************/
954 /* Function Bodies       */
955 /*************************/
956 
957 /*FUNCTION:------------------------------------------------------
958  *  NAME
959  *      dissect_zbee_zcl_device_temperature_configuration
960  *  DESCRIPTION
961  *      ZigBee ZCL Device Temperature Configuration cluster dissector for wireshark.
962  *  PARAMETERS
963  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
964  *      packet_info *pinfo  - pointer to packet information fields
965  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
966  *  RETURNS
967  *      int                 - length of parsed data.
968  *---------------------------------------------------------------
969  */
970 
971 static int
dissect_zbee_zcl_device_temperature_configuration(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)972 dissect_zbee_zcl_device_temperature_configuration(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
973 {
974 	return tvb_captured_length(tvb);;
975 } /*dissect_zbee_zcl_device_temperature_configuration*/
976 
977 
978 /*FUNCTION:------------------------------------------------------
979  *  NAME
980  *      dissect_zcl_device_temperature_configuration_attr_data
981  *  DESCRIPTION
982  *      this function is called by ZCL foundation dissector in order to decode
983  *      specific cluster attributes data.
984  *  PARAMETERS
985  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
986  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
987  *      guint *offset       - pointer to buffer offset
988  *      guint16 attr_id     - attribute identifier
989  *      guint data_type     - attribute data type
990  *      gboolean client_attr- ZCL client
991  *  RETURNS
992  *      none
993  *---------------------------------------------------------------
994  */
995 void
dissect_zcl_device_temperature_configuration_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)996 dissect_zcl_device_temperature_configuration_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
997 {
998     static int * const device_temp_alarm_mask[] = {
999         &hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_too_low,
1000         &hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_too_high,
1001         &hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_reserved,
1002         NULL
1003     };
1004 
1005     /* Dissect attribute data type and data */
1006     switch (attr_id) {
1007 
1008         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK:
1009             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask, ett_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask, device_temp_alarm_mask, ENC_LITTLE_ENDIAN);
1010             *offset += 1;
1011             break;
1012 
1013         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_CURRENT_TEMP:
1014         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_MIN_TEMP_EXP:
1015         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_MAX_TEMP_EXP:
1016         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_OVER_TEMP_TOTAL_DWELL:
1017         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_LOW_TEMP_THRESHOLD:
1018         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_HIGH_TEMP_THRESHOLD:
1019         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_LOW_TEMP_DWELL_TRIP_POINT:
1020         case ZBEE_ZCL_ATTR_ID_DEVICE_TEMPERATURE_CONFIGURATION_HIGH_TEMP_DWELL_TRIP_POINT:
1021         default:
1022             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
1023             break;
1024     }
1025 
1026 } /*dissect_zcl_device_temperature_configuration_attr_data*/
1027 
1028 
1029 /*FUNCTION:------------------------------------------------------
1030  *  NAME
1031  *      proto_register_zbee_zcl_device_temperature_configuration
1032  *  DESCRIPTION
1033  *      ZigBee ZCL Device Temperature Configuration cluster protocol registration routine.
1034  *  PARAMETERS
1035  *      none
1036  *  RETURNS
1037  *      none
1038  *---------------------------------------------------------------
1039  */
1040 void
proto_register_zbee_zcl_device_temperature_configuration(void)1041 proto_register_zbee_zcl_device_temperature_configuration(void)
1042 {
1043     /* Setup list of header fields */
1044     static hf_register_info hf[] = {
1045 
1046         { &hf_zbee_zcl_device_temperature_configuration_attr_id,
1047             { "Attribute", "zbee_zcl_general.device_temperature_configuration.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_device_temperature_configuration_attr_names),
1048             0x00, NULL, HFILL } },
1049 
1050         /* start Device Temperature Alarm Mask fields */
1051         { &hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask,
1052             { "Device Temperature Alarm Mask", "zbee_zcl_general.device_temperature_configuration.attr.device_temp_alarm_mask", FT_UINT8, BASE_HEX, NULL,
1053             0x00, NULL, HFILL } },
1054 
1055         { &hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_too_low,
1056             { "Device Temperature too low", "zbee_zcl_general.device_temperature_configuration.attr.device_temp_alarm_mask.too_low", FT_UINT8, BASE_DEC, NULL,
1057             ZBEE_ZCL_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK_TOO_LOW, NULL, HFILL } },
1058 
1059         { &hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_too_high,
1060             { "Device Temperature too high", "zbee_zcl_general.device_temperature_configuration.attr.device_temp_alarm_mask.too_high", FT_UINT8, BASE_DEC, NULL,
1061             ZBEE_ZCL_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK_TOO_HIGH, NULL, HFILL } },
1062 
1063         { &hf_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask_reserved,
1064             { "Reserved", "zbee_zcl_general.device_temperature_configuration.attr.device_temp_alarm_mask.reserved", FT_UINT8, BASE_DEC, NULL,
1065             ZBEE_ZCL_DEVICE_TEMPERATURE_CONFIGURATION_DEVICE_TEMP_ALARM_MASK_RESERVED, NULL, HFILL } }
1066         /* end Device Temperature Alarm Mask fields */
1067     };
1068 
1069     /* ZCL Device Temperature Configuration subtrees */
1070     static gint *ett[] = {
1071         &ett_zbee_zcl_device_temperature_configuration,
1072         &ett_zbee_zcl_device_temperature_configuration_device_temp_alarm_mask
1073     };
1074 
1075     /* Register the ZigBee ZCL Device Temperature Configuration cluster protocol name and description */
1076     proto_zbee_zcl_device_temperature_configuration = proto_register_protocol("ZigBee ZCL Device Temperature Configuration", "ZCL Device Temperature Configuration", ZBEE_PROTOABBREV_ZCL_DEVICE_TEMP_CONFIG);
1077     proto_register_field_array(proto_zbee_zcl_device_temperature_configuration, hf, array_length(hf));
1078     proto_register_subtree_array(ett, array_length(ett));
1079 
1080     /* Register the ZigBee ZCL Device Temperature Configuration dissector. */
1081     register_dissector(ZBEE_PROTOABBREV_ZCL_DEVICE_TEMP_CONFIG, dissect_zbee_zcl_device_temperature_configuration, proto_zbee_zcl_device_temperature_configuration);
1082 } /*proto_register_zbee_zcl_device_temperature_configuration*/
1083 
1084 /*FUNCTION:------------------------------------------------------
1085  *  NAME
1086  *      proto_reg_handoff_zbee_zcl_device_temperature_configuration
1087  *  DESCRIPTION
1088  *      Hands off the ZCL Device Temperature Configuration dissector.
1089  *  PARAMETERS
1090  *      none
1091  *  RETURNS
1092  *      none
1093  *---------------------------------------------------------------
1094  */
1095 void
proto_reg_handoff_zbee_zcl_device_temperature_configuration(void)1096 proto_reg_handoff_zbee_zcl_device_temperature_configuration(void)
1097 {
1098     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_DEVICE_TEMP_CONFIG,
1099                             proto_zbee_zcl_device_temperature_configuration,
1100                             ett_zbee_zcl_device_temperature_configuration,
1101                             ZBEE_ZCL_CID_DEVICE_TEMP_CONFIG,
1102                             ZBEE_MFG_CODE_NONE,
1103                             hf_zbee_zcl_device_temperature_configuration_attr_id,
1104                             hf_zbee_zcl_device_temperature_configuration_attr_id,
1105                             -1, -1,
1106                             (zbee_zcl_fn_attr_data)dissect_zcl_device_temperature_configuration_attr_data
1107                          );
1108 } /*proto_reg_handoff_zbee_zcl_device_temperature_configuration*/
1109 
1110 
1111 /* ########################################################################## */
1112 /* #### (0x0003) IDENTIFY CLUSTER ########################################### */
1113 /* ########################################################################## */
1114 
1115 /*************************/
1116 /* Defines               */
1117 /*************************/
1118 
1119 /* Attributes */
1120 #define ZBEE_ZCL_ATTR_ID_IDENTIFY_IDENTIFY_TIME         0x0000  /* Identify Time */
1121 
1122 /* Server Commands Received */
1123 #define ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY               0x00  /* Identify */
1124 #define ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY_QUERY         0x01  /* Identify Query */
1125 #define ZBEE_ZCL_CMD_ID_IDENTIFY_TRIGGER_EFFECT         0x40  /* Trigger Effect */
1126 
1127 /* Server Commands Generated */
1128 #define ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY_QUERY_RSP     0x00  /* Identify Query Response */
1129 
1130 
1131 /*************************/
1132 /* Function Declarations */
1133 /*************************/
1134 
1135 void proto_register_zbee_zcl_identify(void);
1136 void proto_reg_handoff_zbee_zcl_identify(void);
1137 
1138 /* Command Dissector Helpers */
1139 static void dissect_zcl_identify_identify               (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1140 static void dissect_zcl_identify_identifyqueryrsp       (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1141 static void dissect_zcl_identify_triggereffect          (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1142 static void dissect_zcl_identify_attr_data              (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
1143 
1144 /* Private functions prototype */
1145 
1146 /*************************/
1147 /* Global Variables      */
1148 /*************************/
1149 /* Initialize the protocol and registered fields */
1150 static int proto_zbee_zcl_identify = -1;
1151 
1152 static int hf_zbee_zcl_identify_attr_id = -1;
1153 static int hf_zbee_zcl_identify_identify_time = -1;
1154 static int hf_zbee_zcl_identify_identify_timeout = -1;
1155 static int hf_zbee_zcl_identify_effect_id = -1;
1156 static int hf_zbee_zcl_identify_effect_variant = -1;
1157 static int hf_zbee_zcl_identify_srv_rx_cmd_id = -1;
1158 static int hf_zbee_zcl_identify_srv_tx_cmd_id = -1;
1159 
1160 /* Initialize the subtree pointers */
1161 static gint ett_zbee_zcl_identify = -1;
1162 
1163 /* Attributes */
1164 static const value_string zbee_zcl_identify_attr_names[] = {
1165     { ZBEE_ZCL_ATTR_ID_IDENTIFY_IDENTIFY_TIME,      "Identify Time" },
1166     { 0, NULL }
1167 };
1168 
1169 /* Server Commands Received */
1170 static const value_string zbee_zcl_identify_srv_rx_cmd_names[] = {
1171     { ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY,            "Identify" },
1172     { ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY_QUERY,      "Identify Query" },
1173     { ZBEE_ZCL_CMD_ID_IDENTIFY_TRIGGER_EFFECT,      "Trigger Effect" },
1174     { 0, NULL }
1175 };
1176 
1177 /* Server Commands Generated */
1178 static const value_string zbee_zcl_identify_srv_tx_cmd_names[] = {
1179     { ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY_QUERY_RSP,  "Identify Query Response" },
1180     { 0, NULL }
1181 };
1182 
1183 /* Trigger Effects */
1184 static const value_string zbee_zcl_identify_effect_id_names[] = {
1185     { 0x00,     "Blink" },
1186     { 0x01,     "Breathe" },
1187     { 0x02,     "Okay" },
1188     { 0x0b,     "Channel change" },
1189     { 0xfe,     "Finish" },
1190     { 0xff,     "Stop" },
1191     { 0, NULL }
1192 };
1193 
1194 /*************************/
1195 /* Function Bodies       */
1196 /*************************/
1197 
1198 /*FUNCTION:------------------------------------------------------
1199  *  NAME
1200  *      dissect_zbee_zcl_identify
1201  *  DESCRIPTION
1202  *      ZigBee ZCL Identify cluster dissector for wireshark.
1203  *  PARAMETERS
1204  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
1205  *      packet_info *pinfo  - pointer to packet information fields
1206  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
1207  *      void *data          - pointer to ZCL packet structure.
1208  *  RETURNS
1209  *      int                 - length of parsed data.
1210  *---------------------------------------------------------------
1211  */
1212 static int
dissect_zbee_zcl_identify(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)1213 dissect_zbee_zcl_identify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1214 {
1215     proto_tree        *payload_tree;
1216     zbee_zcl_packet   *zcl;
1217     guint             offset = 0;
1218     guint8            cmd_id;
1219     gint              rem_len;
1220 
1221     /* Reject the packet if data is NULL */
1222     if (data == NULL)
1223         return 0;
1224     zcl = (zbee_zcl_packet *)data;
1225     cmd_id = zcl->cmd_id;
1226 
1227     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
1228     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
1229         /* Append the command name to the info column. */
1230         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
1231             val_to_str_const(cmd_id, zbee_zcl_identify_srv_rx_cmd_names, "Unknown Command"),
1232             zcl->tran_seqno);
1233 
1234         /* Add the command ID. */
1235         proto_tree_add_item(tree, hf_zbee_zcl_identify_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1236 
1237         /* Check is this command has a payload, than add the payload tree */
1238         rem_len = tvb_reported_length_remaining(tvb, ++offset);
1239         if (rem_len > 0) {
1240             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_identify, NULL, "Payload");
1241 
1242             /* Call the appropriate command dissector */
1243             switch (cmd_id) {
1244                 case ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY:
1245                     dissect_zcl_identify_identify(tvb, payload_tree, &offset);
1246                     break;
1247 
1248                 case ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY_QUERY:
1249                     /* without payload*/
1250                     break;
1251 
1252                 case ZBEE_ZCL_CMD_ID_IDENTIFY_TRIGGER_EFFECT:
1253                     dissect_zcl_identify_triggereffect(tvb, payload_tree, &offset);
1254                     break;
1255 
1256                 default:
1257                     break;
1258             }
1259         }
1260     }
1261     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
1262         /* Append the command name to the info column. */
1263         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
1264             val_to_str_const(cmd_id, zbee_zcl_identify_srv_tx_cmd_names, "Unknown Command"),
1265             zcl->tran_seqno);
1266 
1267         /* Add the command ID. */
1268         proto_tree_add_item(tree, hf_zbee_zcl_identify_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1269 
1270         /* Check is this command has a payload, than add the payload tree */
1271         rem_len = tvb_reported_length_remaining(tvb, ++offset);
1272         if (rem_len > 0) {
1273             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_identify, NULL, "Payload");
1274 
1275             /* Call the appropriate command dissector */
1276             switch (cmd_id) {
1277                 case ZBEE_ZCL_CMD_ID_IDENTIFY_IDENTITY_QUERY_RSP:
1278                     dissect_zcl_identify_identifyqueryrsp(tvb, payload_tree, &offset);
1279                     break;
1280 
1281                 default:
1282                     break;
1283             }
1284         }
1285     }
1286 
1287     return tvb_captured_length(tvb);
1288 } /*dissect_zbee_zcl_identify*/
1289 
1290 
1291  /*FUNCTION:------------------------------------------------------
1292  *  NAME
1293  *      dissect_zcl_identify_identify
1294  *  DESCRIPTION
1295  *      this function decodes the Identify payload.
1296  *  PARAMETERS
1297  *      tvb     - the tv buffer of the current data_type
1298  *      tree    - the tree to append this item to
1299  *      offset  - offset of data in tvb
1300  *  RETURNS
1301  *      none
1302  *---------------------------------------------------------------
1303  */
1304 static void
dissect_zcl_identify_identify(tvbuff_t * tvb,proto_tree * tree,guint * offset)1305 dissect_zcl_identify_identify(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1306 {
1307     /* Retrieve "Identify Time" field */
1308     proto_tree_add_item(tree, hf_zbee_zcl_identify_identify_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1309     *offset += 2;
1310 
1311 } /*dissect_zcl_identify_identify*/
1312 
1313 
1314  /*FUNCTION:------------------------------------------------------
1315  *  NAME
1316  *      dissect_zcl_identify_identifyqueryrsp
1317  *  DESCRIPTION
1318  *      this function decodes the IdentifyQueryResponse payload.
1319  *  PARAMETERS
1320  *      tvb     - the tv buffer of the current data_type
1321  *      tree    - the tree to append this item to
1322  *      offset  - offset of data in tvb
1323  *  RETURNS
1324  *      none
1325  *---------------------------------------------------------------
1326  */
1327 static void
dissect_zcl_identify_identifyqueryrsp(tvbuff_t * tvb,proto_tree * tree,guint * offset)1328 dissect_zcl_identify_identifyqueryrsp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1329 {
1330     /* Retrieve "Identify Timeout" field */
1331     proto_tree_add_item(tree, hf_zbee_zcl_identify_identify_timeout, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1332     *offset += 2;
1333 
1334 } /*dissect_zcl_identify_identifyqueryrsp*/
1335 
1336  /*FUNCTION:------------------------------------------------------
1337  *  NAME
1338  *      dissect_zcl_identify_triggereffect
1339  *  DESCRIPTION
1340  *      this function decodes the Trigger Effect payload.
1341  *  PARAMETERS
1342  *      tvb     - the tv buffer of the current data_type
1343  *      tree    - the tree to append this item to
1344  *      offset  - offset of data in tvb
1345  *  RETURNS
1346  *      none
1347  *---------------------------------------------------------------
1348  */
1349 static void
dissect_zcl_identify_triggereffect(tvbuff_t * tvb,proto_tree * tree,guint * offset)1350 dissect_zcl_identify_triggereffect(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1351 {
1352     /* Retrieve "Trigger Effect Id" field */
1353     proto_tree_add_item(tree, hf_zbee_zcl_identify_effect_id, tvb, *offset, 1, ENC_NA);
1354     *offset += 1;
1355 
1356     /* Retrieve "Trigger Effect Variant" field */
1357     proto_tree_add_item(tree, hf_zbee_zcl_identify_effect_variant, tvb, *offset, 1, ENC_NA);
1358     *offset += 1;
1359 
1360 } /*dissect_zcl_identify_triggereffect*/
1361 
1362 
1363 /*FUNCTION:------------------------------------------------------
1364  *  NAME
1365  *      dissect_zcl_identify_attr_data
1366  *  DESCRIPTION
1367  *      this function is called by ZCL foundation dissector in order to decode
1368  *      specific cluster attributes data.
1369  *  PARAMETERS
1370  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
1371  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
1372  *      guint *offset       - pointer to buffer offset
1373  *      guint16 attr_id     - attribute identifier
1374  *      guint data_type     - attribute data type
1375  *      gboolean client_attr- ZCL client
1376  *  RETURNS
1377  *      none
1378  *---------------------------------------------------------------
1379  */
1380 void
dissect_zcl_identify_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)1381 dissect_zcl_identify_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
1382 {
1383     /* Dissect attribute data type and data */
1384     switch ( attr_id ) {
1385 
1386         case ZBEE_ZCL_ATTR_ID_IDENTIFY_IDENTIFY_TIME:
1387             proto_tree_add_item(tree, hf_zbee_zcl_identify_identify_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1388             *offset += 2;
1389             break;
1390 
1391         default:
1392             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
1393             break;
1394     }
1395 
1396 } /*dissect_zcl_identify_attr_data*/
1397 
1398 
1399 /*FUNCTION:------------------------------------------------------
1400  *  NAME
1401  *      proto_register_zbee_zcl_identify
1402  *  DESCRIPTION
1403  *      ZigBee ZCL Identify cluster protocol registration routine.
1404  *  PARAMETERS
1405  *      none
1406  *  RETURNS
1407  *      void
1408  *---------------------------------------------------------------
1409  */
1410 void
proto_register_zbee_zcl_identify(void)1411 proto_register_zbee_zcl_identify(void)
1412 {
1413     /* Setup list of header fields */
1414     static hf_register_info hf[] = {
1415 
1416         { &hf_zbee_zcl_identify_attr_id,
1417             { "Attribute", "zbee_zcl_general.identify.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_identify_attr_names),
1418             0x00, NULL, HFILL } },
1419 
1420         { &hf_zbee_zcl_identify_identify_time,
1421             { "Identify Time", "zbee_zcl_general.identify.attr.identify_time", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_seconds),
1422             0x00, NULL, HFILL } },
1423 
1424         { &hf_zbee_zcl_identify_identify_timeout,
1425             { "Identify Timeout", "zbee_zcl_general.identify.identify_timeout", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_seconds),
1426             0x00, NULL, HFILL } },
1427 
1428         { &hf_zbee_zcl_identify_effect_id,
1429             { "Effect", "zbee_zcl_general.identify.effect_id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_identify_effect_id_names),
1430             0x00, NULL, HFILL } },
1431 
1432         { &hf_zbee_zcl_identify_effect_variant,
1433             { "Variant", "zbee_zcl_general.identify.effect_variant", FT_UINT8, BASE_DEC, NULL,
1434             0x00, NULL, HFILL } },
1435 
1436         { &hf_zbee_zcl_identify_srv_rx_cmd_id,
1437           { "Command", "zbee_zcl_general.identify.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_identify_srv_rx_cmd_names),
1438             0x00, NULL, HFILL } },
1439 
1440         { &hf_zbee_zcl_identify_srv_tx_cmd_id,
1441           { "Command", "zbee_zcl_general.identify.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_identify_srv_tx_cmd_names),
1442             0x00, NULL, HFILL } }
1443 
1444     };
1445 
1446     /* ZCL Identify subtrees */
1447     static gint *ett[] = {
1448         &ett_zbee_zcl_identify
1449     };
1450 
1451     /* Register the ZigBee ZCL Identify cluster protocol name and description */
1452     proto_zbee_zcl_identify = proto_register_protocol("ZigBee ZCL Identify", "ZCL Identify", ZBEE_PROTOABBREV_ZCL_IDENTIFY);
1453     proto_register_field_array(proto_zbee_zcl_identify, hf, array_length(hf));
1454     proto_register_subtree_array(ett, array_length(ett));
1455 
1456     /* Register the ZigBee ZCL Identify dissector. */
1457     register_dissector(ZBEE_PROTOABBREV_ZCL_IDENTIFY, dissect_zbee_zcl_identify, proto_zbee_zcl_identify);
1458 
1459 } /*proto_register_zbee_zcl_identify*/
1460 
1461 
1462 /*FUNCTION:------------------------------------------------------
1463  *  NAME
1464  *      proto_reg_handoff_zbee_zcl_identify
1465  *  DESCRIPTION
1466  *      Hands off the ZCL Identify dissector.
1467  *  PARAMETERS
1468  *      none
1469  *  RETURNS
1470  *      none
1471  *---------------------------------------------------------------
1472  */
1473 void
proto_reg_handoff_zbee_zcl_identify(void)1474 proto_reg_handoff_zbee_zcl_identify(void)
1475 {
1476     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_IDENTIFY,
1477                             proto_zbee_zcl_identify,
1478                             ett_zbee_zcl_identify,
1479                             ZBEE_ZCL_CID_IDENTIFY,
1480                             ZBEE_MFG_CODE_NONE,
1481                             hf_zbee_zcl_identify_attr_id,
1482                             hf_zbee_zcl_identify_attr_id,
1483                             hf_zbee_zcl_identify_srv_rx_cmd_id,
1484                             hf_zbee_zcl_identify_srv_tx_cmd_id,
1485                             (zbee_zcl_fn_attr_data)dissect_zcl_identify_attr_data
1486                          );
1487 } /*proto_reg_handoff_zbee_zcl_identify*/
1488 
1489 
1490 /* ########################################################################## */
1491 /* #### (0x0004) GROUPS CLUSTER ############################################# */
1492 /* ########################################################################## */
1493 
1494 /*************************/
1495 /* Defines               */
1496 /*************************/
1497 
1498 #define ZBEE_ZCL_CMD_ID_GROUPS_NAME_SUPPORT_MASK                0x80  /*Name support Mask*/
1499 /* Attributes */
1500 #define ZBEE_ZCL_ATTR_ID_GROUPS_NAME_SUPPORT                    0x0000  /* Groups Name Support*/
1501 
1502 /* Server Commands Received */
1503 #define ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP                        0x00  /* Add Group */
1504 #define ZBEE_ZCL_CMD_ID_GROUPS_VIEW_GROUP                       0x01  /* View Group */
1505 #define ZBEE_ZCL_CMD_ID_GROUPS_ADD_GET_GROUP_MEMBERSHIP         0x02  /* Get Group Membership */
1506 #define ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_GROUP                     0x03  /* Remove a Group */
1507 #define ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_ALL_GROUPS                0x04  /* Remove all Groups */
1508 #define ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP_IF_IDENTIFYING         0x05  /* Add Group if Identifying */
1509 
1510 
1511 /* Server Commands Generated */
1512 #define ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP_RESPONSE               0x00  /* Add Group Response */
1513 #define ZBEE_ZCL_CMD_ID_GROUPS_VIEW_GROUP_RESPONSE              0x01  /* View Group Response */
1514 #define ZBEE_ZCL_CMD_ID_GROUPS_GET_GROUP_MEMBERSHIP_RESPONSE    0x02  /* Get Group Membership Response */
1515 #define ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_GROUP_RESPONSE            0x03  /* Remove a Group Response */
1516 
1517 /*************************/
1518 /* Function Declarations */
1519 /*************************/
1520 
1521 void proto_register_zbee_zcl_groups(void);
1522 void proto_reg_handoff_zbee_zcl_groups(void);
1523 
1524 /* Command Dissector Helpers */
1525 static void dissect_zcl_groups_add_group_or_if_identifying      (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1526 static void dissect_zcl_groups_view_group                       (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1527 static void dissect_zcl_groups_get_group_membership             (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1528 static void dissect_zcl_groups_remove_group                     (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1529 static void dissect_zcl_groups_add_remove_group_response        (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1530 static void dissect_zcl_groups_view_group_response              (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1531 static void dissect_zcl_groups_get_group_membership_response    (tvbuff_t *tvb, proto_tree *tree, guint *offset);
1532 
1533 static void dissect_zcl_groups_attr_data                        (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
1534 
1535 /* Private functions prototype */
1536 
1537 /*************************/
1538 /* Global Variables      */
1539 /*************************/
1540 /* Initialize the protocol and registered fields */
1541 static int proto_zbee_zcl_groups = -1;
1542 
1543 static int hf_zbee_zcl_groups_attr_id = -1;
1544 static int hf_zbee_zcl_groups_group_name_support = -1;
1545 static int hf_zbee_zcl_groups_group_id = -1;
1546 static int hf_zbee_zcl_groups_group_count = -1;
1547 static int hf_zbee_zcl_groups_group_capacity = -1;
1548 static int hf_zbee_zcl_groups_status = -1;
1549 static int hf_zbee_zcl_groups_attr_str_len = -1;
1550 static int hf_zbee_zcl_groups_attr_str = -1;
1551 static int hf_zbee_zcl_groups_srv_rx_cmd_id = -1;
1552 static int hf_zbee_zcl_groups_srv_tx_cmd_id = -1;
1553 static int hf_zbee_zcl_groups_group_list = -1;
1554 
1555 /* Initialize the subtree pointers */
1556 static gint ett_zbee_zcl_groups = -1;
1557 static gint ett_zbee_zcl_groups_grp_ctrl = -1;
1558 
1559 /* Attributes */
1560 static const value_string zbee_zcl_groups_attr_names[] = {
1561     { ZBEE_ZCL_ATTR_ID_GROUPS_NAME_SUPPORT,      "Groups Name Support" },
1562     { 0, NULL }
1563 };
1564 
1565 /* Server Commands Received */
1566 static const value_string zbee_zcl_groups_srv_rx_cmd_names[] = {
1567     { ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP,                 "Add Group" },
1568     { ZBEE_ZCL_CMD_ID_GROUPS_VIEW_GROUP,                "View Group" },
1569     { ZBEE_ZCL_CMD_ID_GROUPS_ADD_GET_GROUP_MEMBERSHIP,  "Get Group Membership" },
1570     { ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_GROUP,              "Remove a Group" },
1571     { ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_ALL_GROUPS,         "Remove all Groups" },
1572     { ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP_IF_IDENTIFYING,  "Add Group if Identifying" },
1573     { 0, NULL }
1574 };
1575 
1576 /* Server Commands Generated */
1577 static const value_string zbee_zcl_groups_srv_tx_cmd_names[] = {
1578     { ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP_RESPONSE,            "Add Group Response" },
1579     { ZBEE_ZCL_CMD_ID_GROUPS_VIEW_GROUP_RESPONSE,           "View Group Response" },
1580     { ZBEE_ZCL_CMD_ID_GROUPS_GET_GROUP_MEMBERSHIP_RESPONSE, "Get Group Membership Response" },
1581     { ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_GROUP_RESPONSE,         "Remove a Group Response" },
1582     { 0, NULL }
1583 };
1584 
1585 
1586 /*************************/
1587 /* Function Bodies       */
1588 /*************************/
1589 
1590 /*FUNCTION:------------------------------------------------------
1591  *  NAME
1592  *      dissect_zbee_zcl_groups
1593  *  DESCRIPTION
1594  *      ZigBee ZCL Groups cluster dissector for wireshark.
1595  *  PARAMETERS
1596  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
1597  *      packet_info *pinfo  - pointer to packet information fields
1598  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
1599  *  RETURNS
1600  *      none
1601  *---------------------------------------------------------------
1602  */
1603 static int
dissect_zbee_zcl_groups(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)1604 dissect_zbee_zcl_groups(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1605 {
1606     proto_tree        *payload_tree;
1607     zbee_zcl_packet   *zcl;
1608     guint             offset = 0;
1609     guint8            cmd_id;
1610     gint              rem_len;
1611 
1612     /* Reject the packet if data is NULL */
1613     if (data == NULL)
1614         return 0;
1615     zcl = (zbee_zcl_packet *)data;
1616     cmd_id = zcl->cmd_id;
1617 
1618     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
1619     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
1620         /* Append the command name to the info column. */
1621         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
1622             val_to_str_const(cmd_id, zbee_zcl_groups_srv_rx_cmd_names, "Unknown Command"),
1623             zcl->tran_seqno);
1624 
1625         /* Add the command ID. */
1626         proto_tree_add_item(tree, hf_zbee_zcl_groups_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1627 
1628         /* Check if this command has a payload, then add the payload tree */
1629         rem_len = tvb_reported_length_remaining(tvb, ++offset);
1630         if (rem_len > 0) {
1631             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_groups, NULL, "Payload");
1632 
1633             /* Call the appropriate command dissector */
1634             switch (cmd_id) {
1635                 case ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP:
1636                     dissect_zcl_groups_add_group_or_if_identifying(tvb, payload_tree, &offset);
1637                     break;
1638 
1639                 case ZBEE_ZCL_CMD_ID_GROUPS_VIEW_GROUP:
1640                     dissect_zcl_groups_view_group(tvb, payload_tree, &offset);
1641                     break;
1642 
1643                 case ZBEE_ZCL_CMD_ID_GROUPS_ADD_GET_GROUP_MEMBERSHIP:
1644                     dissect_zcl_groups_get_group_membership(tvb, payload_tree, &offset);
1645                     break;
1646 
1647                 case ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_GROUP:
1648                     dissect_zcl_groups_remove_group(tvb, payload_tree, &offset);
1649                     break;
1650 
1651                 case ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_ALL_GROUPS:
1652                     /* without payload*/
1653                     break;
1654 
1655                 case ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP_IF_IDENTIFYING:
1656                     dissect_zcl_groups_add_group_or_if_identifying(tvb, payload_tree, &offset);
1657                     break;
1658 
1659                 default:
1660                     break;
1661             }
1662         }
1663     }
1664     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
1665         /* Append the command name to the info column. */
1666         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
1667             val_to_str_const(cmd_id, zbee_zcl_groups_srv_tx_cmd_names, "Unknown Command"),
1668             zcl->tran_seqno);
1669 
1670         /* Add the command ID. */
1671         proto_tree_add_item(tree, hf_zbee_zcl_groups_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1672 
1673         /* Check if this command has a payload, then add the payload tree */
1674         rem_len = tvb_reported_length_remaining(tvb, ++offset);
1675         if (rem_len > 0) {
1676             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_groups, NULL, "Payload");
1677 
1678             /* Call the appropriate command dissector */
1679             switch (cmd_id) {
1680                 case ZBEE_ZCL_CMD_ID_GROUPS_ADD_GROUP_RESPONSE:
1681                     dissect_zcl_groups_add_remove_group_response(tvb, payload_tree, &offset);
1682                     break;
1683 
1684                 case ZBEE_ZCL_CMD_ID_GROUPS_VIEW_GROUP_RESPONSE:
1685                     dissect_zcl_groups_view_group_response(tvb, payload_tree, &offset);
1686                     break;
1687 
1688                 case ZBEE_ZCL_CMD_ID_GROUPS_GET_GROUP_MEMBERSHIP_RESPONSE:
1689                     dissect_zcl_groups_get_group_membership_response(tvb, payload_tree, &offset);
1690                     break;
1691 
1692                 case ZBEE_ZCL_CMD_ID_GROUPS_REMOVE_GROUP_RESPONSE:
1693                     dissect_zcl_groups_add_remove_group_response(tvb, payload_tree, &offset);
1694                     break;
1695 
1696                 default:
1697                     break;
1698             }
1699         }
1700     }
1701 
1702     return tvb_captured_length(tvb);
1703 } /*dissect_zbee_zcl_groups*/
1704 
1705 
1706  /*FUNCTION:------------------------------------------------------
1707  *  NAME
1708  *      dissect_zcl_groups_add_group_or_if_identifying
1709  *  DESCRIPTION
1710  *      this function decodes the Add Group or Add Group If
1711  *      Identifying payload.
1712  *  PARAMETERS
1713  *      tvb     - the tv buffer of the current data_type
1714  *      tree    - the tree to append this item to
1715  *      offset  - offset of data in tvb
1716  *  RETURNS
1717  *      none
1718  *---------------------------------------------------------------
1719  */
1720 static void
dissect_zcl_groups_add_group_or_if_identifying(tvbuff_t * tvb,proto_tree * tree,guint * offset)1721 dissect_zcl_groups_add_group_or_if_identifying(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1722 {
1723     guint attr_uint;
1724     guint8 *attr_string;
1725 
1726     /* Retrieve "Group ID" field */
1727     proto_tree_add_item(tree, hf_zbee_zcl_groups_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1728     *offset += 2;
1729 
1730     /* Retrieve "Group Name" field */
1731     attr_uint = tvb_get_guint8(tvb, *offset); /* string length */
1732     if (attr_uint == 0xff) attr_uint = 0;
1733 
1734     proto_tree_add_uint(tree, hf_zbee_zcl_groups_attr_str_len, tvb, *offset, 1, attr_uint);
1735 
1736     *offset += 1;
1737 
1738     attr_string = tvb_get_string_enc(wmem_packet_scope(), tvb, *offset, attr_uint, ENC_ASCII);
1739 
1740     proto_item_append_text(tree, ", String: %s", attr_string);
1741     proto_tree_add_string(tree, hf_zbee_zcl_groups_attr_str, tvb, *offset, attr_uint, attr_string);
1742 
1743     *offset += attr_uint;
1744 
1745 } /*dissect_zcl_groups_add_group*/
1746 
1747 
1748  /*FUNCTION:------------------------------------------------------
1749  *  NAME
1750  *      dissect_zcl_groups_view_group
1751  *  DESCRIPTION
1752  *      this function decodes the View Group payload.
1753  *  PARAMETERS
1754  *      tvb     - the tv buffer of the current data_type
1755  *      tree    - the tree to append this item to
1756  *      offset  - offset of data in tvb
1757  *  RETURNS
1758  *      none
1759  *---------------------------------------------------------------
1760  */
1761 static void
dissect_zcl_groups_view_group(tvbuff_t * tvb,proto_tree * tree,guint * offset)1762 dissect_zcl_groups_view_group(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1763 {
1764     /* Retrieve "Groups Timeout" field */
1765     proto_tree_add_item(tree, hf_zbee_zcl_groups_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1766     *offset += 2;
1767 
1768 } /*dissect_zcl_groups_view_group*/
1769 
1770 
1771 /*FUNCTION:------------------------------------------------------
1772 *  NAME
1773 *      dissect_zcl_groups_get_group_membership
1774 *  DESCRIPTION
1775 *      this function decodes the Get Group Membership payload.
1776 *  PARAMETERS
1777 *      tvb     - the tv buffer of the current data_type
1778 *      tree    - the tree to append this item to
1779 *      offset  - offset of data in tvb
1780 *  RETURNS
1781 *      none
1782 *---------------------------------------------------------------
1783 */
1784 static void
dissect_zcl_groups_get_group_membership(tvbuff_t * tvb,proto_tree * tree,guint * offset)1785 dissect_zcl_groups_get_group_membership(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1786 {
1787    proto_item *grp_list;
1788    proto_tree *grp_list_tree;
1789    guint8 count, i;
1790    /* Retrieve "Group Count" field */
1791    count = tvb_get_guint8(tvb, *offset);
1792    proto_tree_add_uint(tree, hf_zbee_zcl_groups_group_count, tvb, *offset, 1, count);
1793    *offset += 1;
1794 
1795    if(count > 0)
1796       {
1797           grp_list = proto_tree_add_item(tree, hf_zbee_zcl_groups_group_list, tvb, *offset, 2*count, ENC_NA);
1798           grp_list_tree = proto_item_add_subtree(grp_list, ett_zbee_zcl_groups_grp_ctrl);
1799           /* Retrieve "Group List" members */
1800           for( i = 0; i < count; i++)
1801           {
1802                proto_tree_add_item(grp_list_tree, hf_zbee_zcl_groups_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1803                *offset += 2;
1804           }
1805       }
1806 
1807 } /*dissect_zcl_groups_get_group_membership*/
1808 
1809 
1810 /*FUNCTION:------------------------------------------------------
1811 *  NAME
1812 *      dissect_zcl_groups_remove_group
1813 *  DESCRIPTION
1814 *      this function decodes the Remove Group payload.
1815 *  PARAMETERS
1816 *      tvb     - the tv buffer of the current data_type
1817 *      tree    - the tree to append this item to
1818 *      offset  - offset of data in tvb
1819 *  RETURNS
1820 *      none
1821 *---------------------------------------------------------------
1822 */
1823 static void
dissect_zcl_groups_remove_group(tvbuff_t * tvb,proto_tree * tree,guint * offset)1824 dissect_zcl_groups_remove_group(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1825 {
1826    /* Retrieve "Groups ID" field */
1827    proto_tree_add_item(tree, hf_zbee_zcl_groups_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1828    *offset += 2;
1829 
1830 } /*dissect_zcl_groups_remove_group*/
1831 
1832 
1833 /*FUNCTION:------------------------------------------------------
1834 *  NAME
1835 *      dissect_zcl_groups_add_group_response
1836 *  DESCRIPTION
1837 *      this function decodes the Add Group Response payload.
1838 *  PARAMETERS
1839 *      tvb     - the tv buffer of the current data_type
1840 *      tree    - the tree to append this item to
1841 *      offset  - offset of data in tvb
1842 *  RETURNS
1843 *      none
1844 *---------------------------------------------------------------
1845 */
1846 static void
dissect_zcl_groups_add_remove_group_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)1847 dissect_zcl_groups_add_remove_group_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1848 {
1849    /* Retrieve "Status" field */
1850    proto_tree_add_item(tree, hf_zbee_zcl_groups_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1851    *offset += 1;
1852 
1853    /* Retrieve "Groups ID" field */
1854    proto_tree_add_item(tree, hf_zbee_zcl_groups_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1855    *offset += 2;
1856 
1857 } /*dissect_zcl_groups_remove_group*/
1858 
1859 
1860 /*FUNCTION:------------------------------------------------------
1861 *  NAME
1862 *      dissect_zcl_groups_view_group_response
1863 *  DESCRIPTION
1864 *      this function decodes the View Group Response payload
1865 *  PARAMETERS
1866 *      tvb     - the tv buffer of the current data_type
1867 *      tree    - the tree to append this item to
1868 *      offset  - offset of data in tvb
1869 *  RETURNS
1870 *      none
1871 *---------------------------------------------------------------
1872 */
1873 static void
dissect_zcl_groups_view_group_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)1874 dissect_zcl_groups_view_group_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1875 {
1876     guint attr_uint;
1877     guint8 *attr_string;
1878    /* Retrieve "Status" field */
1879    proto_tree_add_item(tree, hf_zbee_zcl_groups_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1880    *offset += 1;
1881 
1882    /* Retrieve "Group ID" field */
1883    proto_tree_add_item(tree, hf_zbee_zcl_groups_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1884    *offset += 2;
1885 
1886    /* Retrieve "Group Name" field */
1887    attr_uint = tvb_get_guint8(tvb, *offset); /* string length */
1888    if (attr_uint == 0xff) attr_uint = 0;
1889 
1890    proto_tree_add_uint(tree, hf_zbee_zcl_groups_attr_str_len, tvb, *offset, 1, attr_uint);
1891 
1892    *offset += 1;
1893 
1894    attr_string = tvb_get_string_enc(wmem_packet_scope(), tvb, *offset, attr_uint, ENC_ASCII);
1895 
1896    proto_item_append_text(tree, ", String: %s", attr_string);
1897    proto_tree_add_string(tree, hf_zbee_zcl_groups_attr_str, tvb, *offset, attr_uint, attr_string);
1898 
1899    *offset += attr_uint;
1900 } /*dissect_zcl_groups_add_group*/
1901 
1902 
1903 /*FUNCTION:------------------------------------------------------
1904 *  NAME
1905 *      dissect_zcl_groups_get_group_membership_response
1906 *  DESCRIPTION
1907 *      this function decodes the Get Group Membership Response payload.
1908 *  PARAMETERS
1909 *      tvb     - the tv buffer of the current data_type
1910 *      tree    - the tree to append this item to
1911 *      offset  - offset of data in tvb
1912 *  RETURNS
1913 *      none
1914 *---------------------------------------------------------------
1915 */
1916 static void
dissect_zcl_groups_get_group_membership_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)1917 dissect_zcl_groups_get_group_membership_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
1918 {
1919    proto_item *grp_list;
1920    proto_tree *grp_list_tree;
1921    guint8  count, i;
1922 
1923    /* Retrieve "Capacity" field */
1924    proto_tree_add_item(tree, hf_zbee_zcl_groups_group_capacity, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1925    *offset += 1;
1926 
1927    /* Retrieve "Group Count" field */
1928    count = tvb_get_guint8(tvb, *offset);
1929    proto_tree_add_uint(tree, hf_zbee_zcl_groups_group_count, tvb, *offset, 1, count);
1930    *offset += 1;
1931    if(count > 0)
1932    {
1933        grp_list = proto_tree_add_item(tree, hf_zbee_zcl_groups_group_list, tvb, *offset, 2*count, ENC_NA);
1934        grp_list_tree = proto_item_add_subtree(grp_list, ett_zbee_zcl_groups_grp_ctrl);
1935        /* Retrieve "Group List" members */
1936        for( i = 0; i < count; i++)
1937        {
1938             proto_tree_add_item(grp_list_tree, hf_zbee_zcl_groups_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
1939             *offset += 2;
1940        }
1941    }
1942 
1943 } /*dissect_zcl_groups_get_group_membership*/
1944 
1945 
1946 /*FUNCTION:------------------------------------------------------
1947  *  NAME
1948  *      dissect_zcl_groups_attr_data
1949  *  DESCRIPTION
1950  *      this function is called by ZCL foundation dissector in order to decode
1951  *      specific cluster attributes data.
1952  *  PARAMETERS
1953  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
1954  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
1955  *      guint *offset       - pointer to buffer offset
1956  *      guint16 attr_id     - attribute identifier
1957  *      guint data_type     - attribute data type
1958  *      gboolean client_attr- ZCL client
1959  *  RETURNS
1960  *      none
1961  *---------------------------------------------------------------
1962  */
1963 void
dissect_zcl_groups_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)1964 dissect_zcl_groups_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
1965 {
1966     /* Dissect attribute data type and data */
1967     switch ( attr_id ) {
1968 
1969         case ZBEE_ZCL_ATTR_ID_GROUPS_NAME_SUPPORT:
1970             proto_tree_add_item(tree, hf_zbee_zcl_groups_group_name_support, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
1971             *offset += 1;
1972             break;
1973 
1974         default:
1975             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
1976             break;
1977     }
1978 
1979 } /*dissect_zcl_groups_attr_data*/
1980 
1981 
1982 /*FUNCTION:------------------------------------------------------
1983  *  NAME
1984  *      proto_register_zbee_zcl_groups
1985  *  DESCRIPTION
1986  *      ZigBee ZCL Groups cluster protocol registration routine.
1987  *  PARAMETERS
1988  *      none
1989  *  RETURNS
1990  *      void
1991  *---------------------------------------------------------------
1992  */
1993 void
proto_register_zbee_zcl_groups(void)1994 proto_register_zbee_zcl_groups(void)
1995 {
1996     /* Setup list of header fields */
1997     static hf_register_info hf[] = {
1998 
1999         { &hf_zbee_zcl_groups_attr_id,
2000             { "Attribute", "zbee_zcl_general.groups.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_groups_attr_names),
2001             0x00, NULL, HFILL } },
2002 
2003         { &hf_zbee_zcl_groups_group_name_support,
2004             { "Group Name Support", "zbee_zcl_general.groups.attr.group_name_support", FT_BOOLEAN, 8, TFS(&tfs_true_false),
2005             ZBEE_ZCL_CMD_ID_GROUPS_NAME_SUPPORT_MASK, NULL, HFILL } },
2006 
2007         { &hf_zbee_zcl_groups_group_id,
2008             { "Group ID", "zbee_zcl_general.groups.group_id", FT_UINT16, BASE_HEX, NULL,
2009             0x00, NULL, HFILL } },
2010 
2011         { &hf_zbee_zcl_groups_group_list,
2012             {"Group List", "zbee_zcl_general.groups.group_list",FT_NONE,BASE_NONE, NULL,
2013             0x00, NULL, HFILL } },
2014 
2015         { &hf_zbee_zcl_groups_group_count,
2016             { "Group Count", "zbee_zcl_general.groups.group_count", FT_UINT8, BASE_DEC, NULL,
2017             0x00, NULL, HFILL } },
2018 
2019         { &hf_zbee_zcl_groups_group_capacity,
2020             { "Group Capacity", "zbee_zcl_general.groups.group_capacity", FT_UINT8, BASE_DEC, NULL,
2021             0x00, NULL, HFILL } },
2022 
2023         { &hf_zbee_zcl_groups_status,
2024             { "Group Status", "zbee_zcl_general.groups.group_status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_status_names),
2025             0x00, NULL, HFILL } },
2026 
2027         { &hf_zbee_zcl_groups_attr_str_len,
2028             { "Length", "zbee_zcl_general.groups.attr_str_len", FT_UINT8, BASE_DEC, NULL,
2029             0x00, NULL, HFILL }},
2030 
2031         { &hf_zbee_zcl_groups_attr_str,
2032             { "String", "zbee_zcl_general.groups_attr_str", FT_STRING, BASE_NONE, NULL,
2033             0x00, NULL, HFILL }},
2034 
2035         { &hf_zbee_zcl_groups_srv_rx_cmd_id,
2036           { "Command", "zbee_zcl_general.groups.cmd_srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_groups_srv_rx_cmd_names),
2037             0x00, NULL, HFILL } },
2038 
2039         { &hf_zbee_zcl_groups_srv_tx_cmd_id,
2040           { "Command", "zbee_zcl_general.groups.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_groups_srv_tx_cmd_names),
2041             0x00, NULL, HFILL } }
2042 
2043     };
2044 
2045     /* ZCL Groups subtrees */
2046     static gint *ett[] = {
2047         &ett_zbee_zcl_groups,
2048         &ett_zbee_zcl_groups_grp_ctrl
2049     };
2050 
2051     /* Register the ZigBee ZCL Groups cluster protocol name and description */
2052     proto_zbee_zcl_groups = proto_register_protocol("ZigBee ZCL Groups", "ZCL Groups", ZBEE_PROTOABBREV_ZCL_GROUPS);
2053     proto_register_field_array(proto_zbee_zcl_groups, hf, array_length(hf));
2054     proto_register_subtree_array(ett, array_length(ett));
2055 
2056     /* Register the ZigBee ZCL Groups dissector. */
2057     register_dissector(ZBEE_PROTOABBREV_ZCL_GROUPS, dissect_zbee_zcl_groups, proto_zbee_zcl_groups);
2058 
2059 } /*proto_register_zbee_zcl_groups*/
2060 
2061 
2062 /*FUNCTION:------------------------------------------------------
2063  *  NAME
2064  *      proto_reg_handoff_zbee_zcl_groups
2065  *  DESCRIPTION
2066  *      Hands off the ZCL Groups dissector.
2067  *  PARAMETERS
2068  *      none
2069  *  RETURNS
2070  *      none
2071  *---------------------------------------------------------------
2072  */
2073 void
proto_reg_handoff_zbee_zcl_groups(void)2074 proto_reg_handoff_zbee_zcl_groups(void)
2075 {
2076     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_GROUPS,
2077                             proto_zbee_zcl_groups,
2078                             ett_zbee_zcl_groups,
2079                             ZBEE_ZCL_CID_GROUPS,
2080                             ZBEE_MFG_CODE_NONE,
2081                             hf_zbee_zcl_groups_attr_id,
2082                             hf_zbee_zcl_groups_attr_id,
2083                             hf_zbee_zcl_groups_srv_rx_cmd_id,
2084                             hf_zbee_zcl_groups_srv_tx_cmd_id,
2085                             (zbee_zcl_fn_attr_data)dissect_zcl_groups_attr_data
2086                          );
2087 } /*proto_reg_handoff_zbee_zcl_groups*/
2088 
2089 
2090 /* ########################################################################## */
2091 /* #### (0x0005) SCENES CLUSTER ############################################# */
2092 /* ########################################################################## */
2093 
2094 /*************************/
2095 /* Defines               */
2096 /*************************/
2097 
2098 #define ZBEE_ZCL_ATTR_SCENES_SCENE_VALID_MASK                   0x01  /* bit     0 */
2099 
2100 /* Attributes */
2101 #define ZBEE_ZCL_ATTR_ID_SCENES_SCENE_COUNT                     0x0000  /* Scene Count */
2102 #define ZBEE_ZCL_ATTR_ID_SCENES_CURRENT_SCENE                   0x0001  /* Current Scene */
2103 #define ZBEE_ZCL_ATTR_ID_SCENES_CURRENT_GROUP                   0x0002  /* Current Group */
2104 #define ZBEE_ZCL_ATTR_ID_SCENES_SCENE_VALID                     0x0003  /* Scene Valid */
2105 #define ZBEE_ZCL_ATTR_ID_SCENES_NAME_SUPPORT                    0x0004  /* Name Support */
2106 #define ZBEE_ZCL_ATTR_ID_SCENES_LAST_CONFIGURED_BY              0x0005  /* Last Configured By */
2107 
2108 /* Scene Name Support */
2109 #define ZBEE_ZCL_SCENES_NAME_SUPPORTED                          0x80  /* Scene Names Supported */
2110 #define ZBEE_ZCL_SCENES_NAME_NOT_SUPPORTED                      0x00  /* Scene Names Not Supported */
2111 
2112 /* Copy Mode */
2113 #define ZBEE_ZCL_SCENES_COPY_SPECIFIED                          0x00  /* Copy Specified Scenes */
2114 #define ZBEE_ZCL_SCENES_COPY_ALL                                0x01  /* Copy All Scenes */
2115 
2116 /* Server Commands Received */
2117 #define ZBEE_ZCL_CMD_ID_SCENES_ADD_SCENE                        0x00  /* Add Scene */
2118 #define ZBEE_ZCL_CMD_ID_SCENES_VIEW_SCENE                       0x01  /* View Scene */
2119 #define ZBEE_ZCL_CMD_ID_SCENES_REMOVE_SCENE                     0x02  /* Remove a Scene */
2120 #define ZBEE_ZCL_CMD_ID_SCENES_REMOVE_ALL_SCENES                0x03  /* Remove all Scenes */
2121 #define ZBEE_ZCL_CMD_ID_SCENES_STORE_SCENE                      0x04  /* Store Scene */
2122 #define ZBEE_ZCL_CMD_ID_SCENES_RECALL_SCENE                     0x05  /* Recall Scene */
2123 #define ZBEE_ZCL_CMD_ID_SCENES_GET_SCENE_MEMBERSHIP             0x06  /* Get Scene Membership */
2124 #define ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_ADD_SCENE               0x40  /* Enhanced Add Scene */
2125 #define ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_VIEW_SCENE              0x41  /* Enhanced View Scene */
2126 #define ZBEE_ZCL_CMD_ID_SCENES_COPY_SCENE                       0x42  /* Copy Scene */
2127 #define ZBEE_ZCL_CMD_ID_SCENES_NAME_SUPPORT_MASK                0x80
2128 
2129 /* Server Commands Generated */
2130 #define ZBEE_ZCL_CMD_ID_SCENES_ADD_SCENE_RESPONSE               0x00  /* Add Scene Response */
2131 #define ZBEE_ZCL_CMD_ID_SCENES_VIEW_SCENE_RESPONSE              0x01  /* View Scene Response */
2132 #define ZBEE_ZCL_CMD_ID_SCENES_REMOVE_SCENE_RESPONSE            0x02  /* Remove a Scene Response */
2133 #define ZBEE_ZCL_CMD_ID_SCENES_REMOVE_ALL_SCENES_RESPONSE       0x03  /* Remove all Scenes Response */
2134 #define ZBEE_ZCL_CMD_ID_SCENES_STORE_SCENE_RESPONSE             0x04  /* Store Scene Response */
2135 #define ZBEE_ZCL_CMD_ID_SCENES_GET_SCENE_MEMBERSHIP_RESPONSE    0x06  /* Get Scene Membership Response */
2136 #define ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_ADD_SCENE_RESPONSE      0x40  /* Enhanced Add Scene Response */
2137 #define ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_VIEW_SCENE_RESPONSE     0x41  /* Enhanced View Scene Response */
2138 #define ZBEE_ZCL_CMD_ID_SCENES_COPY_SCENE_RESPONSE              0x42  /* Copy Scene Response */
2139 
2140 /* Enhanced */
2141 #define IS_ENHANCED                                             TRUE
2142 #define IS_NOT_ENHANCED                                         FALSE
2143 
2144 /*************************/
2145 /* Function Declarations */
2146 /*************************/
2147 
2148 void proto_register_zbee_zcl_scenes(void);
2149 void proto_reg_handoff_zbee_zcl_scenes(void);
2150 
2151 /* Command Dissector Helpers */
2152 static void dissect_zcl_scenes_add_scene                                    (tvbuff_t *tvb, proto_tree *tree, guint *offset, gboolean enhanced);
2153 static void dissect_zcl_scenes_view_remove_store_recall_scene               (tvbuff_t *tvb, proto_tree *tree, guint *offset);
2154 static void dissect_zcl_scenes_remove_all_get_scene_membership              (tvbuff_t *tvb, proto_tree *tree, guint *offset);
2155 static void dissect_zcl_scenes_copy_scene                                   (tvbuff_t *tvb, proto_tree *tree, guint *offset);
2156 static void dissect_zcl_scenes_add_remove_store_scene_response              (tvbuff_t *tvb, proto_tree *tree, guint *offset);
2157 static void dissect_zcl_scenes_view_scene_response                          (tvbuff_t *tvb, proto_tree *tree, guint *offset, gboolean enhanced);
2158 static void dissect_zcl_scenes_remove_all_scenes_response                   (tvbuff_t *tvb, proto_tree *tree, guint *offset);
2159 static void dissect_zcl_scenes_get_scene_membership_response                (tvbuff_t *tvb, proto_tree *tree, guint *offset);
2160 static void dissect_zcl_scenes_copy_scene_response                          (tvbuff_t *tvb, proto_tree *tree, guint *offset);
2161 
2162 static void dissect_zcl_scenes_extension_fields                             (tvbuff_t *tvb, proto_tree *tree, guint *offset);
2163 static void dissect_zcl_scenes_attr_data                                    (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
2164 
2165 /* Private functions prototype */
2166 
2167 /*************************/
2168 /* Global Variables      */
2169 /*************************/
2170 /* Initialize the protocol and registered fields */
2171 static int proto_zbee_zcl_scenes = -1;
2172 
2173 static int hf_zbee_zcl_scenes_attr_id = -1;
2174 static int hf_zbee_zcl_scenes_attr_id_scene_valid = -1;
2175 static int hf_zbee_zcl_scenes_attr_id_name_support = -1;
2176 static int hf_zbee_zcl_scenes_group_id = -1;
2177 static int hf_zbee_zcl_scenes_group_id_from = -1;
2178 static int hf_zbee_zcl_scenes_group_id_to = -1;
2179 static int hf_zbee_zcl_scenes_scene_id = -1;
2180 static int hf_zbee_zcl_scenes_scene_id_from = -1;
2181 static int hf_zbee_zcl_scenes_scene_id_to = -1;
2182 static int hf_zbee_zcl_scenes_transit_time = -1;
2183 static int hf_zbee_zcl_scenes_enh_transit_time = -1;
2184 static int hf_zbee_zcl_scenes_extension_set_cluster = -1;
2185 static int hf_zbee_zcl_scenes_extension_set_onoff = -1;
2186 static int hf_zbee_zcl_scenes_extension_set_level = -1;
2187 static int hf_zbee_zcl_scenes_extension_set_x = -1;
2188 static int hf_zbee_zcl_scenes_extension_set_y = -1;
2189 static int hf_zbee_zcl_scenes_extension_set_hue = -1;
2190 static int hf_zbee_zcl_scenes_extension_set_saturation = -1;
2191 static int hf_zbee_zcl_scenes_extension_set_color_loop_active = -1;
2192 static int hf_zbee_zcl_scenes_extension_set_color_loop_direction = -1;
2193 static int hf_zbee_zcl_scenes_extension_set_color_loop_time = -1;
2194 static int hf_zbee_zcl_scenes_extension_set_cooling_setpoint = -1;
2195 static int hf_zbee_zcl_scenes_extension_set_heating_setpoint = -1;
2196 static int hf_zbee_zcl_scenes_extension_set_system_mode = -1;
2197 static int hf_zbee_zcl_scenes_extension_set_lock_state = -1;
2198 static int hf_zbee_zcl_scenes_extension_set_lift_percentage = -1;
2199 static int hf_zbee_zcl_scenes_extension_set_tilt_percentage = -1;
2200 
2201 static int hf_zbee_zcl_scenes_status = -1;
2202 static int hf_zbee_zcl_scenes_capacity = -1;
2203 static int hf_zbee_zcl_scenes_scene_count = -1;
2204 static int hf_zbee_zcl_scenes_attr_str_len = -1;
2205 static int hf_zbee_zcl_scenes_attr_str = -1;
2206 static int hf_zbee_zcl_scenes_srv_rx_cmd_id = -1;
2207 static int hf_zbee_zcl_scenes_srv_tx_cmd_id = -1;
2208 static int hf_zbee_zcl_scenes_scene_list = -1;
2209 static int hf_zbee_zcl_scenes_copy_mode = -1;
2210 
2211 /* Initialize the subtree pointers */
2212 static gint ett_zbee_zcl_scenes = -1;
2213 static gint ett_zbee_zcl_scenes_scene_ctrl = -1;
2214 static gint ett_zbee_zcl_scenes_extension_field_set = -1;
2215 
2216 /* Attributes */
2217 static const value_string zbee_zcl_scenes_attr_names[] = {
2218     { ZBEE_ZCL_ATTR_ID_SCENES_SCENE_COUNT,          "Scene Count" },
2219     { ZBEE_ZCL_ATTR_ID_SCENES_CURRENT_SCENE,        "Current Scene" },
2220     { ZBEE_ZCL_ATTR_ID_SCENES_CURRENT_GROUP,        "Current Group" },
2221     { ZBEE_ZCL_ATTR_ID_SCENES_SCENE_VALID,          "Scene Valid" },
2222     { ZBEE_ZCL_ATTR_ID_SCENES_NAME_SUPPORT,         "Name Support" },
2223     { ZBEE_ZCL_ATTR_ID_SCENES_LAST_CONFIGURED_BY,   "Last Configured By" },
2224     { 0, NULL }
2225 };
2226 
2227 /* Server Commands Received */
2228 static const value_string zbee_zcl_scenes_srv_rx_cmd_names[] = {
2229     { ZBEE_ZCL_CMD_ID_SCENES_ADD_SCENE,             "Add Scene" },
2230     { ZBEE_ZCL_CMD_ID_SCENES_VIEW_SCENE,            "View Scene" },
2231     { ZBEE_ZCL_CMD_ID_SCENES_REMOVE_SCENE,          "Remove a Scene" },
2232     { ZBEE_ZCL_CMD_ID_SCENES_REMOVE_ALL_SCENES,     "Remove all Scenes" },
2233     { ZBEE_ZCL_CMD_ID_SCENES_STORE_SCENE,           "Store Scene" },
2234     { ZBEE_ZCL_CMD_ID_SCENES_RECALL_SCENE,          "Recall Scene" },
2235     { ZBEE_ZCL_CMD_ID_SCENES_GET_SCENE_MEMBERSHIP,  "Get Scene Membership" },
2236     { ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_ADD_SCENE,    "Enhanced Add Scene" },
2237     { ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_VIEW_SCENE,   "Enhanced View Scene" },
2238     { ZBEE_ZCL_CMD_ID_SCENES_COPY_SCENE,            "Copy Scene" },
2239     { 0, NULL }
2240 };
2241 
2242 /* Server Commands Generated */
2243 static const value_string zbee_zcl_scenes_srv_tx_cmd_names[] = {
2244     { ZBEE_ZCL_CMD_ID_SCENES_ADD_SCENE_RESPONSE,            "Add Scene Response" },
2245     { ZBEE_ZCL_CMD_ID_SCENES_VIEW_SCENE_RESPONSE,           "View Scene Response" },
2246     { ZBEE_ZCL_CMD_ID_SCENES_REMOVE_SCENE_RESPONSE,         "Remove a Scene Response" },
2247     { ZBEE_ZCL_CMD_ID_SCENES_REMOVE_ALL_SCENES_RESPONSE,    "Remove all Scene Response" },
2248     { ZBEE_ZCL_CMD_ID_SCENES_STORE_SCENE_RESPONSE,          "Store Scene Response" },
2249     { ZBEE_ZCL_CMD_ID_SCENES_GET_SCENE_MEMBERSHIP_RESPONSE, "Get Scene Membership Response" },
2250     { ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_ADD_SCENE_RESPONSE,   "Enhanced Add Scene Response" },
2251     { ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_VIEW_SCENE_RESPONSE,  "Enhanced View Scene Response" },
2252     { ZBEE_ZCL_CMD_ID_SCENES_COPY_SCENE_RESPONSE,           "Copy Scene Response" },
2253     { 0, NULL }
2254 };
2255 
2256 /* Scene Names Support Values */
2257 static const value_string zbee_zcl_scenes_group_names_support_values[] = {
2258     { ZBEE_ZCL_SCENES_NAME_NOT_SUPPORTED,   "Scene names not supported" },
2259     { ZBEE_ZCL_SCENES_NAME_SUPPORTED,       "Scene names supported" },
2260     { 0, NULL }
2261 };
2262 
2263 /* Scene Copy Mode Values */
2264 static const value_string zbee_zcl_scenes_copy_mode_values[] = {
2265     { ZBEE_ZCL_SCENES_COPY_SPECIFIED,   "Copy Specified Scenes" },
2266     { ZBEE_ZCL_SCENES_COPY_ALL,         "Copy All Scenes" },
2267     { 0, NULL }
2268 };
2269 
2270 /* Color Loop Directions */
2271 static const value_string zbee_zcl_scenes_color_loop_direction_values[] = {
2272     { 0x00,   "Hue is Decrementing" },
2273     { 0x01,   "Hue is Incrementing" },
2274     { 0, NULL }
2275 };
2276 
2277 
2278 /*************************/
2279 /* Function Bodies       */
2280 /*************************/
2281 
2282 /*FUNCTION:------------------------------------------------------
2283  *  NAME
2284  *    decode_color_xy
2285  *  DESCRIPTION
2286  *    this function decodes color xy values
2287  *  PARAMETERS
2288  *      guint *s        - string to display
2289  *      guint16 value   - value to decode
2290  *  RETURNS
2291  *    none
2292  *---------------------------------------------------------------
2293  */
2294 static void
decode_color_xy(gchar * s,guint16 value)2295 decode_color_xy(gchar *s, guint16 value)
2296 {
2297     g_snprintf(s, ITEM_LABEL_LENGTH, "%.4lf", value/65535.0);
2298 }
2299 
2300 /*FUNCTION:------------------------------------------------------
2301  *  NAME
2302  *    decode_setpoint
2303  *  DESCRIPTION
2304  *    this function decodes the setpoint
2305  *  PARAMETERS
2306  *      guint *s        - string to display
2307  *      guint16 value   - value to decode
2308  *  RETURNS
2309  *    none
2310  *---------------------------------------------------------------
2311  */
decode_setpoint(gchar * s,gint16 value)2312 static void decode_setpoint(gchar *s, gint16 value)
2313 {
2314     g_snprintf(s, ITEM_LABEL_LENGTH, "%.2lf [" UTF8_DEGREE_SIGN "C]", value/100.0);
2315 }
2316 
2317 /*FUNCTION:------------------------------------------------------
2318  *  NAME
2319  *      dissect_zbee_zcl_scenes
2320  *  DESCRIPTION
2321  *      ZigBee ZCL Scenes cluster dissector for wireshark.
2322  *  PARAMETERS
2323  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
2324  *      packet_info *pinfo  - pointer to packet information fields
2325  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
2326  *  RETURNS
2327  *      none
2328  *---------------------------------------------------------------
2329  */
2330 static int
dissect_zbee_zcl_scenes(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)2331 dissect_zbee_zcl_scenes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2332 {
2333     proto_tree        *payload_tree;
2334     zbee_zcl_packet   *zcl;
2335     guint             offset = 0;
2336     guint8            cmd_id;
2337     gint              rem_len;
2338 
2339     /* Reject the packet if data is NULL */
2340     if (data == NULL)
2341         return 0;
2342     zcl = (zbee_zcl_packet *)data;
2343     cmd_id = zcl->cmd_id;
2344 
2345     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
2346     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
2347         /* Append the command name to the info column. */
2348         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
2349             val_to_str_const(cmd_id, zbee_zcl_scenes_srv_rx_cmd_names, "Unknown Command"),
2350             zcl->tran_seqno);
2351 
2352         /* Add the command ID. */
2353         proto_tree_add_item(tree, hf_zbee_zcl_scenes_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2354 
2355         /* Check if this command has a payload, then add the payload tree */
2356         rem_len = tvb_reported_length_remaining(tvb, ++offset);
2357         if (rem_len > 0) {
2358             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_scenes, NULL, "Payload");
2359 
2360             /* Call the appropriate command dissector */
2361             switch (cmd_id) {
2362                 case ZBEE_ZCL_CMD_ID_SCENES_ADD_SCENE:
2363                     dissect_zcl_scenes_add_scene(tvb, payload_tree, &offset, IS_NOT_ENHANCED);
2364                     break;
2365 
2366                 case ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_ADD_SCENE:
2367                     dissect_zcl_scenes_add_scene(tvb, payload_tree, &offset, IS_ENHANCED);
2368                     break;
2369 
2370                 case ZBEE_ZCL_CMD_ID_SCENES_VIEW_SCENE:
2371                 case ZBEE_ZCL_CMD_ID_SCENES_REMOVE_SCENE:
2372                 case ZBEE_ZCL_CMD_ID_SCENES_STORE_SCENE:
2373                 case ZBEE_ZCL_CMD_ID_SCENES_RECALL_SCENE:
2374                 case ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_VIEW_SCENE:
2375                     dissect_zcl_scenes_view_remove_store_recall_scene(tvb, payload_tree, &offset);
2376                     break;
2377 
2378                 case ZBEE_ZCL_CMD_ID_SCENES_REMOVE_ALL_SCENES:
2379                 case ZBEE_ZCL_CMD_ID_SCENES_GET_SCENE_MEMBERSHIP:
2380                     dissect_zcl_scenes_remove_all_get_scene_membership(tvb, payload_tree, &offset);
2381                     break;
2382 
2383                 case ZBEE_ZCL_CMD_ID_SCENES_COPY_SCENE:
2384                     dissect_zcl_scenes_copy_scene(tvb, payload_tree, &offset);
2385                     break;
2386 
2387                 default:
2388                     break;
2389             }
2390         }
2391     }
2392     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
2393         /* Append the command name to the info column. */
2394         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
2395             val_to_str_const(cmd_id, zbee_zcl_scenes_srv_tx_cmd_names, "Unknown Command"),
2396             zcl->tran_seqno);
2397 
2398         /* Add the command ID. */
2399         proto_tree_add_item(tree, hf_zbee_zcl_scenes_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2400 
2401         /* Check if this command has a payload, then add the payload tree */
2402         rem_len = tvb_reported_length_remaining(tvb, ++offset);
2403         if (rem_len > 0) {
2404             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_scenes, NULL, "Payload");
2405 
2406             /* Call the appropriate command dissector */
2407             switch (cmd_id) {
2408                 case ZBEE_ZCL_CMD_ID_SCENES_ADD_SCENE_RESPONSE:
2409                 case ZBEE_ZCL_CMD_ID_SCENES_REMOVE_SCENE_RESPONSE:
2410                 case ZBEE_ZCL_CMD_ID_SCENES_STORE_SCENE_RESPONSE:
2411                 case ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_ADD_SCENE_RESPONSE:
2412                     dissect_zcl_scenes_add_remove_store_scene_response(tvb, payload_tree, &offset);
2413                     break;
2414 
2415                 case ZBEE_ZCL_CMD_ID_SCENES_VIEW_SCENE_RESPONSE:
2416                     dissect_zcl_scenes_view_scene_response(tvb, payload_tree, &offset, IS_NOT_ENHANCED);
2417                     break;
2418 
2419                 case ZBEE_ZCL_CMD_ID_SCENES_ENHANCED_VIEW_SCENE_RESPONSE:
2420                     dissect_zcl_scenes_view_scene_response(tvb, payload_tree, &offset, IS_ENHANCED);
2421                     break;
2422 
2423                 case ZBEE_ZCL_CMD_ID_SCENES_REMOVE_ALL_SCENES_RESPONSE:
2424                     dissect_zcl_scenes_remove_all_scenes_response(tvb, payload_tree, &offset);
2425                     break;
2426 
2427                 case ZBEE_ZCL_CMD_ID_SCENES_GET_SCENE_MEMBERSHIP_RESPONSE:
2428                     dissect_zcl_scenes_get_scene_membership_response(tvb, payload_tree, &offset);
2429                     break;
2430 
2431                 case ZBEE_ZCL_CMD_ID_SCENES_COPY_SCENE_RESPONSE:
2432                     dissect_zcl_scenes_copy_scene_response(tvb, payload_tree, &offset);
2433                     break;
2434 
2435                 default:
2436                     break;
2437             }
2438         }
2439     }
2440 
2441     return tvb_captured_length(tvb);
2442 } /*dissect_zbee_zcl_scenes*/
2443 
2444 
2445  /*FUNCTION:------------------------------------------------------
2446  *  NAME
2447  *      dissect_zcl_scenes_add_scene
2448  *  DESCRIPTION
2449  *      this function decodes the Add Scene payload.
2450  *  PARAMETERS
2451  *      tvb      - the tv buffer of the current data_type
2452  *      tree     - the tree to append this item to
2453  *      offset   - offset of data in tvb
2454  *      enhanced - use enhanced transition time
2455  *  RETURNS
2456  *      none
2457  *---------------------------------------------------------------
2458  */
2459 static void
dissect_zcl_scenes_add_scene(tvbuff_t * tvb,proto_tree * tree,guint * offset,gboolean enhanced)2460 dissect_zcl_scenes_add_scene(tvbuff_t *tvb, proto_tree *tree, guint *offset, gboolean enhanced)
2461 {
2462     guint attr_uint;
2463     guint8 *attr_string;
2464 
2465     /* Retrieve "Group ID" field */
2466     proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2467     *offset += 2;
2468 
2469     /* Retrieve "Scene ID" field */
2470     proto_tree_add_item(tree, hf_zbee_zcl_scenes_scene_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2471     *offset += 1;
2472 
2473     /* Retrieve "Transition Time" field */
2474     proto_tree_add_item(tree, enhanced ? hf_zbee_zcl_scenes_enh_transit_time : hf_zbee_zcl_scenes_transit_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2475     *offset += 2;
2476 
2477     /* Retrieve Scene Name */
2478     attr_uint = tvb_get_guint8(tvb, *offset); /* string length */
2479     if (attr_uint == 0xff) attr_uint = 0;
2480 
2481     proto_tree_add_uint(tree, hf_zbee_zcl_scenes_attr_str_len, tvb, *offset, 1, attr_uint);
2482 
2483     *offset += 1;
2484 
2485     attr_string = tvb_get_string_enc(wmem_packet_scope(), tvb, *offset, attr_uint, ENC_ASCII);
2486 
2487     proto_item_append_text(tree, ", String: %s", attr_string);
2488     proto_tree_add_string(tree, hf_zbee_zcl_scenes_attr_str, tvb, *offset, attr_uint, attr_string);
2489 
2490     *offset += attr_uint;
2491 
2492     /* Retrieve "Extension Set" field */
2493     dissect_zcl_scenes_extension_fields(tvb, tree, offset);
2494 
2495 } /*dissect_zcl_scenes_add_scene*/
2496 
2497 
2498  /*FUNCTION:--------------------------------------------------------------------
2499  *  NAME
2500  *      dissect_zcl_scenes_view_remove_store_recall_scene
2501  *  DESCRIPTION
2502  *      this function decodes the View, Remove, Store and Recall Scene payload.
2503  *  PARAMETERS
2504  *      tvb     - the tv buffer of the current data_type
2505  *      tree    - the tree to append this item to
2506  *      offset  - offset of data in tvb
2507  *  RETURNS
2508  *      none
2509  *------------------------------------------------------------------------------
2510  */
2511 static void
dissect_zcl_scenes_view_remove_store_recall_scene(tvbuff_t * tvb,proto_tree * tree,guint * offset)2512 dissect_zcl_scenes_view_remove_store_recall_scene(tvbuff_t *tvb, proto_tree *tree, guint *offset)
2513 {
2514     /* Retrieve "Group ID" field */
2515     proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2516     *offset += 2;
2517 
2518     /* Retrieve "Scene ID" field */
2519     proto_tree_add_item(tree, hf_zbee_zcl_scenes_scene_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2520     *offset += 1;
2521 
2522 } /*dissect_zcl_scenes_view_remove_store_recall_scene*/
2523 
2524 
2525 /*FUNCTION:-------------------------------------------------------------------
2526 *  NAME
2527 *      dissect_zcl_scenes_remove_all_get_scene_membership
2528 *  DESCRIPTION
2529 *      this function decodes the Remove all and Get Scene Membership payload.
2530 *  PARAMETERS
2531 *      tvb     - the tv buffer of the current data_type
2532 *      tree    - the tree to append this item to
2533 *      offset  - offset of data in tvb
2534 *  RETURNS
2535 *      none
2536 *-----------------------------------------------------------------------------
2537 */
2538 static void
dissect_zcl_scenes_remove_all_get_scene_membership(tvbuff_t * tvb,proto_tree * tree,guint * offset)2539 dissect_zcl_scenes_remove_all_get_scene_membership(tvbuff_t *tvb, proto_tree *tree, guint *offset)
2540 {
2541     /* Retrieve "Group ID" field */
2542     proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2543     *offset += 2;
2544 
2545 } /*dissect_zcl_scenes_remove_all_get_scene_membership*/
2546 
2547 
2548 /*FUNCTION:--------------------------------------------------------------------
2549  *  NAME
2550  *      dissect_zcl_scenes_copy_scene
2551  *  DESCRIPTION
2552  *      this function decodes the Copy Scene payload.
2553  *  PARAMETERS
2554  *      tvb     - the tv buffer of the current data_type
2555  *      tree    - the tree to append this item to
2556  *      offset  - offset of data in tvb
2557  *  RETURNS
2558  *      none
2559  *------------------------------------------------------------------------------
2560  */
2561 static void
dissect_zcl_scenes_copy_scene(tvbuff_t * tvb,proto_tree * tree,guint * offset)2562 dissect_zcl_scenes_copy_scene(tvbuff_t *tvb, proto_tree *tree, guint *offset)
2563 {
2564     /* Retrieve "Mode" field */
2565     proto_tree_add_item(tree, hf_zbee_zcl_scenes_copy_mode, tvb, *offset, 1, ENC_NA);
2566     *offset += 1;
2567 
2568     /* Retrieve "Group ID From" field */
2569     proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id_from, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2570     *offset += 2;
2571 
2572     /* Retrieve "Scene ID From" field */
2573     proto_tree_add_item(tree, hf_zbee_zcl_scenes_scene_id_from, tvb, *offset, 1, ENC_NA);
2574     *offset += 1;
2575 
2576     /* Retrieve "Group ID To" field */
2577     proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id_to, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2578     *offset += 2;
2579 
2580     /* Retrieve "Scene ID To" field */
2581     proto_tree_add_item(tree, hf_zbee_zcl_scenes_scene_id_to, tvb, *offset, 1, ENC_NA);
2582     *offset += 1;
2583 
2584 } /*dissect_zcl_scenes_copy_scene*/
2585 
2586 
2587 /*FUNCTION:------------------------------------------------------
2588 *  NAME
2589 *      dissect_zcl_scenes_add_remove_store_scene_response
2590 *  DESCRIPTION
2591 *      this function decodes the Add, Remove, Store Scene payload.
2592 *  PARAMETERS
2593 *      tvb     - the tv buffer of the current data_type
2594 *      tree    - the tree to append this item to
2595 *      offset  - offset of data in tvb
2596 *  RETURNS
2597 *      none
2598 *---------------------------------------------------------------
2599 */
2600 static void
dissect_zcl_scenes_add_remove_store_scene_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)2601 dissect_zcl_scenes_add_remove_store_scene_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
2602 {
2603    /* Retrieve "Status" field */
2604    proto_tree_add_item(tree, hf_zbee_zcl_scenes_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2605    *offset += 1;
2606 
2607    /* Retrieve "Group ID" field */
2608    proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2609    *offset += 2;
2610 
2611    /* Retrieve "Scene ID" field */
2612    proto_tree_add_item(tree, hf_zbee_zcl_scenes_scene_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2613    *offset += 1;
2614 
2615 } /*dissect_zcl_scenes_add_remove_store_scene_response*/
2616 
2617 
2618 /*FUNCTION:------------------------------------------------------
2619 *  NAME
2620 *      dissect_zcl_scenes_view_scene_response
2621 *  DESCRIPTION
2622 *      this function decodes the View Scene Response payload.
2623 *  PARAMETERS
2624 *      tvb      - the tv buffer of the current data_type
2625 *      tree     - the tree to append this item to
2626 *      offset   - offset of data in tvb
2627 *      enhanced - use enhanced transition time
2628 *  RETURNS
2629 *      none
2630 *---------------------------------------------------------------
2631 */
2632 static void
dissect_zcl_scenes_view_scene_response(tvbuff_t * tvb,proto_tree * tree,guint * offset,gboolean enhanced)2633 dissect_zcl_scenes_view_scene_response(tvbuff_t *tvb, proto_tree *tree, guint *offset, gboolean enhanced)
2634 {
2635     guint8 status, *attr_string;
2636     guint attr_uint;
2637 
2638     /* Retrieve "Status" field */
2639     status = tvb_get_guint8(tvb, *offset);
2640     proto_tree_add_item(tree, hf_zbee_zcl_scenes_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2641     *offset += 1;
2642 
2643     /* Retrieve "Group ID" field */
2644     proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2645     *offset += 2;
2646 
2647     /* Retrieve "Scene ID" field */
2648     proto_tree_add_item(tree, hf_zbee_zcl_scenes_scene_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2649     *offset += 1;
2650 
2651     if(status == ZBEE_ZCL_STAT_SUCCESS)
2652     {
2653         /* Retrieve "Transition Time" field */
2654         proto_tree_add_item(tree, enhanced ? hf_zbee_zcl_scenes_enh_transit_time : hf_zbee_zcl_scenes_transit_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2655         *offset += 2;
2656 
2657         /* Retrieve Scene Name */
2658         attr_uint = tvb_get_guint8(tvb, *offset); /* string length */
2659         if (attr_uint == 0xff) attr_uint = 0;
2660 
2661         proto_tree_add_uint(tree, hf_zbee_zcl_scenes_attr_str_len, tvb, *offset, 1, attr_uint);
2662 
2663         *offset += 1;
2664 
2665         attr_string = tvb_get_string_enc(wmem_packet_scope(), tvb, *offset, attr_uint, ENC_ASCII);
2666 
2667         proto_item_append_text(tree, ", String: %s", attr_string);
2668         proto_tree_add_string(tree, hf_zbee_zcl_scenes_attr_str, tvb, *offset, attr_uint, attr_string);
2669 
2670         *offset += attr_uint;
2671 
2672         /* Retrieve "Extension Set" field */
2673         dissect_zcl_scenes_extension_fields(tvb, tree, offset);
2674 
2675     }
2676 
2677 } /*dissect_zcl_scenes_view_scene_response*/
2678 
2679 
2680 /*FUNCTION:------------------------------------------------------
2681 *  NAME
2682 *      dissect_zcl_scenes_remove_all_scenes_response
2683 *  DESCRIPTION
2684 *      this function decodes the Remove All Scenes Response payload
2685 *  PARAMETERS
2686 *      tvb     - the tv buffer of the current data_type
2687 *      tree    - the tree to append this item to
2688 *      offset  - offset of data in tvb
2689 *  RETURNS
2690 *      none
2691 *---------------------------------------------------------------
2692 */
2693 static void
dissect_zcl_scenes_remove_all_scenes_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)2694 dissect_zcl_scenes_remove_all_scenes_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
2695 {
2696    /* Retrieve "Status" field */
2697    proto_tree_add_item(tree, hf_zbee_zcl_scenes_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2698    *offset += 1;
2699 
2700    /* Retrieve "Group ID" field */
2701    proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2702    *offset += 2;
2703 
2704 } /*dissect_zcl_scenes_remove_all_scenes_response*/
2705 
2706 
2707 /*FUNCTION:------------------------------------------------------
2708 *  NAME
2709 *      dissect_zcl_scenes_get_scene_membership_response
2710 *  DESCRIPTION
2711 *      this function decodes the Get Scene Membership Response payload.
2712 *  PARAMETERS
2713 *      tvb     - the tv buffer of the current data_type
2714 *      tree    - the tree to append this item to
2715 *      offset  - offset of data in tvb
2716 *  RETURNS
2717 *      none
2718 *---------------------------------------------------------------
2719 */
2720 static void
dissect_zcl_scenes_get_scene_membership_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)2721 dissect_zcl_scenes_get_scene_membership_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
2722 {
2723    proto_item *scene_list;
2724    proto_tree *scene_list_tree;
2725    guint8 status, count, i;
2726 
2727    /* Retrieve "Status" field */
2728    status = tvb_get_guint8(tvb, *offset);
2729    proto_tree_add_item(tree, hf_zbee_zcl_scenes_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2730    *offset += 1;
2731 
2732    /* Retrieve "Capacity" field */
2733    proto_tree_add_item(tree, hf_zbee_zcl_scenes_capacity, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2734    *offset += 1;
2735 
2736    /* Retrieve "Group ID" field */
2737    proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2738    *offset += 2;
2739 
2740    if(status == ZBEE_ZCL_STAT_SUCCESS)
2741    {
2742        /* Retrieve "Scene Count" field */
2743        count = tvb_get_guint8(tvb, *offset);
2744        proto_tree_add_uint(tree, hf_zbee_zcl_scenes_scene_count, tvb, *offset, 1, count);
2745        *offset += 1;
2746 
2747        if(count>0)
2748          {
2749             scene_list=proto_tree_add_item(tree, hf_zbee_zcl_scenes_scene_list, tvb, *offset, count, ENC_NA);
2750             scene_list_tree = proto_item_add_subtree(scene_list, ett_zbee_zcl_scenes_scene_ctrl);
2751             /* Retrieve "Scene List" */
2752             for( i = 0; i < count; i++)
2753             {
2754               proto_tree_add_item(scene_list_tree, hf_zbee_zcl_scenes_scene_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2755               *offset += 1;
2756             }
2757          }
2758    }
2759 
2760 } /*dissect_zcl_scenes_get_scene_membership_response*/
2761 
2762 
2763 /*FUNCTION:------------------------------------------------------
2764  *  NAME
2765  *      dissect_zcl_scenes_copy_scene_response
2766  *  DESCRIPTION
2767  *      this function decodes the Copy Scene payload.
2768  *  PARAMETERS
2769  *      tvb     - the tv buffer of the current data_type
2770  *      tree    - the tree to append this item to
2771  *      offset  - offset of data in tvb
2772  *  RETURNS
2773  *      none
2774  *---------------------------------------------------------------
2775  */
2776 static void
dissect_zcl_scenes_copy_scene_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)2777 dissect_zcl_scenes_copy_scene_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
2778 {
2779    /* Retrieve "Status" field */
2780    proto_tree_add_item(tree, hf_zbee_zcl_scenes_status, tvb, *offset, 1, ENC_NA);
2781    *offset += 1;
2782 
2783    /* Retrieve "Group ID From" field */
2784    proto_tree_add_item(tree, hf_zbee_zcl_scenes_group_id_from, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2785    *offset += 2;
2786 
2787    /* Retrieve "Scene ID From" field */
2788    proto_tree_add_item(tree, hf_zbee_zcl_scenes_scene_id_from, tvb, *offset, 1, ENC_NA);
2789    *offset += 1;
2790 
2791 } /*dissect_zcl_scenes_copy_scene_response*/
2792 
2793 
2794 /*FUNCTION:------------------------------------------------------
2795  *  NAME
2796  *      dissect_zcl_scenes_extension_fields
2797  *  DESCRIPTION
2798  *      this function decodes the extension set fields
2799  *  PARAMETERS
2800  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
2801  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
2802  *      guint *offset       - pointer to buffer offset
2803  *  RETURNS
2804  *      none
2805  *---------------------------------------------------------------
2806  */
dissect_zcl_scenes_extension_fields(tvbuff_t * tvb,proto_tree * tree,guint * offset)2807 static void dissect_zcl_scenes_extension_fields(tvbuff_t *tvb, proto_tree *tree, guint *offset)
2808 {
2809     guint8      set = 1;
2810     proto_tree *subtree;
2811 
2812     // Is there an extension field?
2813     gboolean hasExtensionField = tvb_offset_exists(tvb, *offset+2);
2814 
2815     while (hasExtensionField)
2816     {
2817         // Retrieve the cluster and the length
2818         guint32 cluster = tvb_get_guint16(tvb, *offset, ENC_LITTLE_ENDIAN);
2819         guint8  length  = tvb_get_guint8 (tvb, *offset+2);
2820 
2821         // Create a subtree
2822         subtree = proto_tree_add_subtree_format(tree, tvb, *offset, length, ett_zbee_zcl_scenes_extension_field_set, NULL, "Extension field set %d", set++);
2823         proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_cluster, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2824         *offset += 3;
2825 
2826         switch (cluster)
2827         {
2828         case ZBEE_ZCL_CID_ON_OFF:
2829             if (length >= 1)
2830             {
2831                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_onoff, tvb, *offset, 1, ENC_NA);
2832                 length  -= 1;
2833                 *offset += 1;
2834             }
2835             break;
2836 
2837         case ZBEE_ZCL_CID_LEVEL_CONTROL:
2838             if (length >= 1)
2839             {
2840                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_level, tvb, *offset, 1, ENC_NA);
2841                 length  -= 1;
2842                 *offset += 1;
2843             }
2844             break;
2845 
2846         case ZBEE_ZCL_CID_COLOR_CONTROL:
2847             if (length >= 2)
2848             {
2849                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_x, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2850                 length  -= 2;
2851                 *offset += 2;
2852             }
2853             if (length >= 2)
2854             {
2855                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_y, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2856                 length  -= 2;
2857                 *offset += 2;
2858             }
2859             if (length >= 2)
2860             {
2861                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_hue, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2862                 length  -= 2;
2863                 *offset += 2;
2864             }
2865             if (length >= 1)
2866             {
2867                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_saturation, tvb, *offset, 1, ENC_NA);
2868                 length  -= 1;
2869                 *offset += 1;
2870             }
2871             if (length >= 1)
2872             {
2873                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_color_loop_active, tvb, *offset, 1, ENC_NA);
2874                 length  -= 1;
2875                 *offset += 1;
2876             }
2877             if (length >= 1)
2878             {
2879                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_color_loop_direction, tvb, *offset, 1, ENC_NA);
2880                 length  -= 1;
2881                 *offset += 1;
2882             }
2883             if (length >= 2)
2884             {
2885                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_color_loop_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2886                 length  -= 2;
2887                 *offset += 2;
2888             }
2889             break;
2890 
2891         case ZBEE_ZCL_CID_DOOR_LOCK:
2892             if (length >= 1)
2893             {
2894                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_lock_state, tvb, *offset, 1, ENC_NA);
2895                 length  -= 1;
2896                 *offset += 1;
2897             }
2898             break;
2899 
2900         case ZBEE_ZCL_CID_WINDOW_COVERING:
2901             if (length >= 1)
2902             {
2903                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_lift_percentage, tvb, *offset, 1, ENC_NA);
2904                 length  -= 1;
2905                 *offset += 1;
2906             }
2907             if (length >= 1)
2908             {
2909                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_tilt_percentage, tvb, *offset, 1, ENC_NA);
2910                 length  -= 1;
2911                 *offset += 1;
2912             }
2913             break;
2914 
2915         case ZBEE_ZCL_CID_THERMOSTAT:
2916             if (length >= 2)
2917             {
2918                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_cooling_setpoint, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2919                 length  -= 2;
2920                 *offset += 2;
2921             }
2922             if (length >= 2)
2923             {
2924                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_heating_setpoint, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
2925                 length  -= 2;
2926                 *offset += 2;
2927             }
2928             if (length >= 1)
2929             {
2930                 proto_tree_add_item(subtree, hf_zbee_zcl_scenes_extension_set_system_mode, tvb, *offset, 1, ENC_NA);
2931                 length  -= 1;
2932                 *offset += 1;
2933             }
2934             break;
2935         }
2936 
2937         *offset += length;
2938         hasExtensionField = tvb_offset_exists(tvb, *offset+2);
2939     }
2940 }
2941 
2942 
2943 /*FUNCTION:------------------------------------------------------
2944  *  NAME
2945  *      dissect_zcl_scenes_attr_data
2946  *  DESCRIPTION
2947  *      this function is called by ZCL foundation dissector in order to decode
2948  *      specific cluster attributes data.
2949  *  PARAMETERS
2950  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
2951  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
2952  *      guint *offset       - pointer to buffer offset
2953  *      guint16 attr_id     - attribute identifier
2954  *      guint data_type     - attribute data type
2955  *      gboolean client_attr- ZCL client
2956  *  RETURNS
2957  *      none
2958  *---------------------------------------------------------------
2959  */
2960 void
dissect_zcl_scenes_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)2961 dissect_zcl_scenes_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
2962 {
2963     /* Dissect attribute data type and data */
2964     switch ( attr_id ) {
2965 
2966         case ZBEE_ZCL_ATTR_ID_SCENES_SCENE_VALID:
2967             proto_tree_add_item(tree, hf_zbee_zcl_scenes_attr_id_scene_valid, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2968             *offset += 1;
2969             break;
2970 
2971         case ZBEE_ZCL_ATTR_ID_SCENES_NAME_SUPPORT:
2972             proto_tree_add_item(tree, hf_zbee_zcl_scenes_attr_id_name_support, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
2973             *offset += 1;
2974             break;
2975 
2976         case ZBEE_ZCL_ATTR_ID_SCENES_SCENE_COUNT:
2977         case ZBEE_ZCL_ATTR_ID_SCENES_CURRENT_SCENE:
2978         case ZBEE_ZCL_ATTR_ID_SCENES_CURRENT_GROUP:
2979         case ZBEE_ZCL_ATTR_ID_SCENES_LAST_CONFIGURED_BY:
2980         default:
2981             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
2982             break;
2983     }
2984 
2985 } /*dissect_zcl_scenes_attr_data*/
2986 
2987 
2988 /*FUNCTION:------------------------------------------------------
2989  *  NAME
2990  *      proto_register_zbee_zcl_scenes
2991  *  DESCRIPTION
2992  *      ZigBee ZCL Scenes cluster protocol registration routine.
2993  *  PARAMETERS
2994  *      none
2995  *  RETURNS
2996  *      void
2997  *---------------------------------------------------------------
2998  */
2999 void
proto_register_zbee_zcl_scenes(void)3000 proto_register_zbee_zcl_scenes(void)
3001 {
3002     /* Setup list of header fields */
3003     static hf_register_info hf[] = {
3004 
3005         { &hf_zbee_zcl_scenes_attr_id,
3006             { "Attribute", "zbee_zcl_general.scenes.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_scenes_attr_names),
3007             0x00, NULL, HFILL } },
3008 
3009        { &hf_zbee_zcl_scenes_scene_list,
3010             {"Scene List", "zbee_zcl_general.groups.scene_list",FT_NONE,BASE_NONE, NULL,
3011             0x00, NULL, HFILL } },
3012 
3013         { &hf_zbee_zcl_scenes_group_id,
3014             { "Group ID", "zbee_zcl_general.scenes.group_id", FT_UINT16, BASE_HEX, NULL,
3015             0x00, NULL, HFILL } },
3016 
3017         { &hf_zbee_zcl_scenes_group_id_from,
3018             { "Group ID From", "zbee_zcl_general.scenes.group_id_from", FT_UINT16, BASE_HEX, NULL,
3019             0x00, NULL, HFILL } },
3020 
3021         { &hf_zbee_zcl_scenes_group_id_to,
3022             { "Group ID To", "zbee_zcl_general.scenes.group_id_to", FT_UINT16, BASE_HEX, NULL,
3023             0x00, NULL, HFILL } },
3024 
3025         { &hf_zbee_zcl_scenes_scene_id,
3026             { "Scene ID", "zbee_zcl_general.scenes.scene_id", FT_UINT8, BASE_HEX, NULL,
3027             0x00, NULL, HFILL } },
3028 
3029         { &hf_zbee_zcl_scenes_scene_id_from,
3030             { "Scene ID From", "zbee_zcl_general.scenes.scene_id_from", FT_UINT8, BASE_HEX, NULL,
3031             0x00, NULL, HFILL } },
3032 
3033         { &hf_zbee_zcl_scenes_scene_id_to,
3034             { "Scene ID To", "zbee_zcl_general.scenes.scene_id_to", FT_UINT8, BASE_HEX, NULL,
3035             0x00, NULL, HFILL } },
3036 
3037         { &hf_zbee_zcl_scenes_transit_time,
3038             { "Transition Time", "zbee_zcl_general.scenes.transit_time", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_seconds),
3039             0x00, NULL, HFILL } },
3040 
3041         { &hf_zbee_zcl_scenes_enh_transit_time,
3042             { "Transition Time", "zbee_zcl_general.scenes.enh_transit_time", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_100ms),
3043             0x00, NULL, HFILL } },
3044 
3045         { &hf_zbee_zcl_scenes_status,
3046             { "Scenes Status", "zbee_zcl_general.scenes.scenes_status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_status_names),
3047             0x00, NULL, HFILL } },
3048 
3049         { &hf_zbee_zcl_scenes_capacity,
3050             { "Scene Capacity", "zbee_zcl_general.scenes.scene_capacity", FT_UINT8, BASE_DEC, NULL,
3051             0x00, NULL, HFILL } },
3052 
3053         { &hf_zbee_zcl_scenes_scene_count,
3054             { "Scene Count", "zbee_zcl_general.scenes.scene_count", FT_UINT8, BASE_DEC, NULL,
3055             0x00, NULL, HFILL } },
3056 
3057         { &hf_zbee_zcl_scenes_attr_id_name_support,
3058             { "Scene Name Support", "zbee_zcl_general.scenes.attr.name_support", FT_UINT8, BASE_HEX, VALS(zbee_zcl_scenes_group_names_support_values),
3059             ZBEE_ZCL_CMD_ID_SCENES_NAME_SUPPORT_MASK, NULL, HFILL } },
3060 
3061         { &hf_zbee_zcl_scenes_attr_id_scene_valid,
3062             { "Scene Valid", "zbee_zcl_general.scenes.scene_valid", FT_BOOLEAN, 8, TFS(&tfs_true_false),
3063             ZBEE_ZCL_ATTR_SCENES_SCENE_VALID_MASK, NULL, HFILL } },
3064 
3065         { &hf_zbee_zcl_scenes_attr_str_len,
3066             { "Length", "zbee_zcl_general.scenes.attr_str_len", FT_UINT8, BASE_DEC, NULL,
3067             0x00, NULL, HFILL }},
3068 
3069         { &hf_zbee_zcl_scenes_attr_str,
3070             { "String", "zbee_zcl_general.scenes.attr_str", FT_STRING, BASE_NONE, NULL,
3071             0x00, NULL, HFILL }},
3072 
3073         { &hf_zbee_zcl_scenes_extension_set_cluster,
3074             { "Cluster", "zbee_zcl_general.scenes.extension_set.cluster", FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_aps_cid_names),
3075             0x00, NULL, HFILL }},
3076 
3077         { &hf_zbee_zcl_scenes_extension_set_onoff,
3078             { "On/Off", "zbee_zcl_general.scenes.extension_set.onoff", FT_UINT8, BASE_DEC, NULL,
3079             0x00, NULL, HFILL }},
3080 
3081         { &hf_zbee_zcl_scenes_extension_set_level,
3082             { "Level", "zbee_zcl_general.scenes.extension_set.level", FT_UINT8, BASE_DEC, NULL,
3083             0x00, NULL, HFILL }},
3084 
3085         { &hf_zbee_zcl_scenes_extension_set_x,
3086             { "Color X", "zbee_zcl_general.scenes.extension_set.color_x", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_color_xy),
3087             0x00, NULL, HFILL }},
3088 
3089         { &hf_zbee_zcl_scenes_extension_set_y,
3090             { "Color Y", "zbee_zcl_general.scenes.extension_set.color_y", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_color_xy),
3091             0x00, NULL, HFILL }},
3092 
3093         { &hf_zbee_zcl_scenes_extension_set_hue,
3094             { "Enhanced Hue", "zbee_zcl_general.scenes.extension_set.hue", FT_UINT16, BASE_DEC, NULL,
3095             0x00, NULL, HFILL }},
3096 
3097         { &hf_zbee_zcl_scenes_extension_set_saturation,
3098             { "Saturation", "zbee_zcl_general.scenes.extension_set.saturation", FT_UINT8, BASE_DEC, NULL,
3099             0x00, NULL, HFILL }},
3100 
3101         { &hf_zbee_zcl_scenes_extension_set_color_loop_active,
3102             { "Color Loop Active", "zbee_zcl_general.scenes.extension_set.color_loop_active", FT_BOOLEAN, 8, TFS(&tfs_true_false),
3103             0x00, NULL, HFILL }},
3104 
3105         { &hf_zbee_zcl_scenes_extension_set_color_loop_direction,
3106             { "Color Loop Direction", "zbee_zcl_general.scenes.extension_set.color_loop_direction", FT_UINT8, BASE_DEC, VALS(zbee_zcl_scenes_color_loop_direction_values),
3107             0x00, NULL, HFILL }},
3108 
3109         { &hf_zbee_zcl_scenes_extension_set_color_loop_time,
3110             { "Color Loop Time", "zbee_zcl_general.scenes.extension_set.color_loop_time", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_seconds),
3111             0x00, NULL, HFILL }},
3112 
3113         { &hf_zbee_zcl_scenes_extension_set_lock_state,
3114             { "Lock State", "zbee_zcl_general.scenes.extension_set.lock_state", FT_UINT8, BASE_DEC, NULL,
3115             0x00, NULL, HFILL }},
3116 
3117         { &hf_zbee_zcl_scenes_extension_set_lift_percentage,
3118             { "Current Position Lift Percentage", "zbee_zcl_general.scenes.extension_set.current_position_lift_percentage", FT_UINT8, BASE_DEC, NULL,
3119             0x00, NULL, HFILL }},
3120 
3121         { &hf_zbee_zcl_scenes_extension_set_tilt_percentage,
3122             { "Current Position Tilt Percentage", "zbee_zcl_general.scenes.extension_set.current_position_tilt_percentage", FT_UINT8, BASE_DEC, NULL,
3123             0x00, NULL, HFILL }},
3124 
3125         { &hf_zbee_zcl_scenes_extension_set_cooling_setpoint,
3126             { "Occupied Cooling Setpoint", "zbee_zcl_general.scenes.extension_set.occupied_cooling_setpoint", FT_INT16, BASE_CUSTOM, CF_FUNC(decode_setpoint),
3127             0x00, NULL, HFILL }},
3128 
3129         { &hf_zbee_zcl_scenes_extension_set_heating_setpoint,
3130             { "Occupied Heating Setpoint", "zbee_zcl_general.scenes.extension_set.occupied_heating_setpoint", FT_INT16, BASE_CUSTOM, CF_FUNC(decode_setpoint),
3131             0x00, NULL, HFILL }},
3132 
3133         { &hf_zbee_zcl_scenes_extension_set_system_mode,
3134             { "System Mode", "zbee_zcl_general.scenes.extension_set.system_mode", FT_UINT8, BASE_DEC, NULL,
3135             0x00, NULL, HFILL }},
3136 
3137         { &hf_zbee_zcl_scenes_copy_mode,
3138             { "Scene Copy Mode", "zbee_zcl_general.scenes.copy_mode", FT_UINT8, BASE_DEC, VALS(zbee_zcl_scenes_copy_mode_values),
3139             0x00, NULL, HFILL } },
3140 
3141         { &hf_zbee_zcl_scenes_srv_rx_cmd_id,
3142           { "Command", "zbee_zcl_general.scenes.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_scenes_srv_rx_cmd_names),
3143             0x00, NULL, HFILL } },
3144 
3145         { &hf_zbee_zcl_scenes_srv_tx_cmd_id,
3146           { "Command", "zbee_zcl_general.scenes.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_scenes_srv_tx_cmd_names),
3147             0x00, NULL, HFILL } }
3148 
3149     };
3150 
3151     /* ZCL Scenes subtrees */
3152     static gint *ett[] = {
3153         &ett_zbee_zcl_scenes,
3154         &ett_zbee_zcl_scenes_scene_ctrl,
3155         &ett_zbee_zcl_scenes_extension_field_set
3156     };
3157 
3158     /* Register the ZigBee ZCL Scenes cluster protocol name and description */
3159     proto_zbee_zcl_scenes = proto_register_protocol("ZigBee ZCL Scenes", "ZCL Scenes", ZBEE_PROTOABBREV_ZCL_SCENES);
3160     proto_register_field_array(proto_zbee_zcl_scenes, hf, array_length(hf));
3161     proto_register_subtree_array(ett, array_length(ett));
3162 
3163     /* Register the ZigBee ZCL Scenes dissector. */
3164     register_dissector(ZBEE_PROTOABBREV_ZCL_SCENES, dissect_zbee_zcl_scenes, proto_zbee_zcl_scenes);
3165 
3166 } /*proto_register_zbee_zcl_scenes*/
3167 
3168 
3169 /*FUNCTION:------------------------------------------------------
3170  *  NAME
3171  *      proto_reg_handoff_zbee_zcl_scenes
3172  *  DESCRIPTION
3173  *      Hands off the ZCL Scenes dissector.
3174  *  PARAMETERS
3175  *      none
3176  *  RETURNS
3177  *      none
3178  *---------------------------------------------------------------
3179  */
3180 void
proto_reg_handoff_zbee_zcl_scenes(void)3181 proto_reg_handoff_zbee_zcl_scenes(void)
3182 {
3183 
3184     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_SCENES,
3185                             proto_zbee_zcl_scenes,
3186                             ett_zbee_zcl_scenes,
3187                             ZBEE_ZCL_CID_SCENES,
3188                             ZBEE_MFG_CODE_NONE,
3189                             hf_zbee_zcl_scenes_attr_id,
3190                             hf_zbee_zcl_scenes_attr_id,
3191                             hf_zbee_zcl_scenes_srv_rx_cmd_id,
3192                             hf_zbee_zcl_scenes_srv_tx_cmd_id,
3193                             (zbee_zcl_fn_attr_data)dissect_zcl_scenes_attr_data
3194                          );
3195 } /*proto_reg_handoff_zbee_zcl_scenes*/
3196 
3197 
3198 /* ########################################################################## */
3199 /* #### (0x0006) ON/OFF CLUSTER ############################################# */
3200 /* ########################################################################## */
3201 
3202 /*************************/
3203 /* Defines               */
3204 /*************************/
3205 
3206 /* Attributes */
3207 #define ZBEE_ZCL_ON_OFF_ATTR_ID_ONOFF               0x0000
3208 #define ZBEE_ZCL_ON_OFF_ATTR_ID_GLOBALSCENECONTROL  0x4000
3209 #define ZBEE_ZCL_ON_OFF_ATTR_ID_ONTIME              0x4001
3210 #define ZBEE_ZCL_ON_OFF_ATTR_ID_OFFWAITTIME         0x4002
3211 #define ZBEE_ZCL_ON_OFF_ATTR_ID_STARTUPONOFF        0x4003
3212 
3213 /* Server Commands Received */
3214 #define ZBEE_ZCL_ON_OFF_CMD_OFF                         0x00  /* Off */
3215 #define ZBEE_ZCL_ON_OFF_CMD_ON                          0x01  /* On */
3216 #define ZBEE_ZCL_ON_OFF_CMD_TOGGLE                      0x02  /* Toggle */
3217 #define ZBEE_ZCL_ON_OFF_CMD_OFF_WITH_EFFECT             0x40  /* Off with effect */
3218 #define ZBEE_ZCL_ON_OFF_CMD_ON_WITH_RECALL_GLOBAL_SCENE 0x41  /* On with recall global scene */
3219 #define ZBEE_ZCL_ON_OFF_CMD_ON_WITH_TIMED_OFF           0x42  /* On with timed off */
3220 
3221 /* On/Off Control Field */
3222 #define ZBEE_ZCL_ON_OFF_TIMED_OFF_CONTROL_MASK_ACCEPT_ONLY_WHEN_ON   0x01
3223 #define ZBEE_ZCL_ON_OFF_TIMED_OFF_CONTROL_MASK_RESERVED              0xFE
3224 
3225 /*************************/
3226 /* Function Declarations */
3227 /*************************/
3228 
3229 void proto_register_zbee_zcl_on_off(void);
3230 void proto_reg_handoff_zbee_zcl_on_off(void);
3231 
3232 /* Command Dissector Helpers */
3233 static void dissect_zcl_on_off_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
3234 
3235 /* Private functions prototype */
3236 
3237 /*************************/
3238 /* Global Variables      */
3239 /*************************/
3240 
3241 /* Initialize the protocol and registered fields */
3242 static int proto_zbee_zcl_on_off = -1;
3243 
3244 static int hf_zbee_zcl_on_off_attr_id = -1;
3245 static int hf_zbee_zcl_on_off_attr_onoff = -1;
3246 static int hf_zbee_zcl_on_off_attr_globalscenecontrol = -1;
3247 static int hf_zbee_zcl_on_off_attr_ontime = -1;
3248 static int hf_zbee_zcl_on_off_attr_offwaittime = -1;
3249 static int hf_zbee_zcl_on_off_attr_startuponoff = -1;
3250 static int hf_zbee_zcl_on_off_srv_rx_cmd_id = -1;
3251 
3252 static int hf_zbee_zcl_on_off_effect_identifier = -1;
3253 static int hf_zbee_zcl_on_off_effect_variant_delayed_all_off = -1;
3254 static int hf_zbee_zcl_on_off_effect_variant_dying_light = -1;
3255 static int hf_zbee_zcl_on_off_effect_variant_reserved = -1;
3256 
3257 static int hf_zbee_zcl_on_off_timed_off_control_mask = -1;
3258 static int hf_zbee_zcl_on_off_timed_off_control_mask_accept_only_when_on = -1;
3259 static int hf_zbee_zcl_on_off_timed_off_control_mask_reserved = -1;
3260 
3261 /* Initialize the subtree pointers */
3262 static gint ett_zbee_zcl_on_off = -1;
3263 static gint ett_zbee_zcl_on_off_timed_off_control_mask = -1;
3264 
3265 /* Attributes */
3266 static const value_string zbee_zcl_on_off_attr_names[] = {
3267     { ZBEE_ZCL_ON_OFF_ATTR_ID_ONOFF,                "OnOff" },
3268     { ZBEE_ZCL_ON_OFF_ATTR_ID_GLOBALSCENECONTROL,   "GlobalSceneControl" },
3269     { ZBEE_ZCL_ON_OFF_ATTR_ID_ONTIME,               "OnTime" },
3270     { ZBEE_ZCL_ON_OFF_ATTR_ID_OFFWAITTIME,          "OffWaitTime" },
3271     { ZBEE_ZCL_ON_OFF_ATTR_ID_STARTUPONOFF,         "StartUpOnOff" },
3272     { 0, NULL }
3273 };
3274 
3275 /* Server Commands Generated */
3276 static const value_string zbee_zcl_on_off_srv_rx_cmd_names[] = {
3277     { ZBEE_ZCL_ON_OFF_CMD_OFF,                          "Off" },
3278     { ZBEE_ZCL_ON_OFF_CMD_ON,                           "On" },
3279     { ZBEE_ZCL_ON_OFF_CMD_TOGGLE,                       "Toggle" },
3280     { ZBEE_ZCL_ON_OFF_CMD_OFF_WITH_EFFECT,              "Off with effect" },
3281     { ZBEE_ZCL_ON_OFF_CMD_ON_WITH_RECALL_GLOBAL_SCENE,  "On with recall global scene" },
3282     { ZBEE_ZCL_ON_OFF_CMD_ON_WITH_TIMED_OFF,            "On with timed off" },
3283     { 0, NULL }
3284 };
3285 
3286 /* OnOff Names */
3287 static const value_string zbee_zcl_on_off_timed_off_names[] = {
3288     { 0, "Off" },
3289     { 1, "On" },
3290     { 0, NULL }
3291 };
3292 
3293 /* GlobalSceneControl Names */
3294 static const value_string zbee_zcl_on_off_globalscenecontrol_names[] = {
3295     { 0, "False" },
3296     { 1, "True" },
3297     { 0, NULL }
3298 };
3299 
3300 static const range_string zbee_zcl_on_off_effect_identifier_names[] = {
3301     { 0x00, 0x00, "Delayed All Off" },
3302     { 0x01, 0x01, "Dying Light" },
3303     { 0x02, 0xFF, "Reserved" },
3304     { 0, 0, NULL }
3305 };
3306 
3307 static const range_string zbee_zcl_on_off_effect_variant_delayed_all_off_names[] = {
3308     { 0x00, 0x00, "Fade to off in 0.8 seconds" },
3309     { 0x01, 0x01, "No fade" },
3310     { 0x02, 0x02, "50% dim down in 0.8 seconds then fade to off in 12 seconds" },
3311     { 0x03, 0xFF, "Reserved" },
3312     { 0, 0, NULL }
3313 };
3314 
3315 static const range_string zbee_zcl_on_off_effect_variant_dying_light_names[] = {
3316     { 0x00, 0x00, "20% dim up in 0.5s then fade to off in 1 second" },
3317     { 0x01, 0xFF, "Reserved" },
3318     { 0, 0, NULL }
3319 };
3320 
3321 static const range_string zbee_zcl_on_off_effect_variant_reserved_names[] = {
3322     { 0x00, 0xFF, "Reserved" },
3323     { 0, 0, NULL }
3324 };
3325 
3326 static const range_string zbee_zcl_on_off_startup_on_off_names[] = {
3327     { 0x00, 0x00, "Set the OnOff attribute to Off" },
3328     { 0x01, 0x01, "Set the OnOff attribute to On" },
3329     { 0x02, 0x02, "Toggle the OnOff attribute" },
3330     { 0x03, 0xFE, "Reserved" },
3331     { 0xFF, 0xFF, "Set the OnOff attribute to its previous value" },
3332     { 0, 0, NULL }
3333 };
3334 
3335 /*************************/
3336 /* Function Bodies       */
3337 /*************************/
3338 
3339 /*FUNCTION:------------------------------------------------------
3340  *  NAME
3341  *      dissect_zbee_zcl_onoff
3342  *  DESCRIPTION
3343  *      ZigBee ZCL OnOff cluster dissector for wireshark.
3344  *  PARAMETERS
3345  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
3346  *      packet_info *pinfo  - pointer to packet information fields
3347  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
3348  *      void *data          - pointer to ZCL packet structure.
3349  *  RETURNS
3350  *      int                 - length of parsed data.
3351  *---------------------------------------------------------------
3352  */
3353 static int
dissect_zbee_zcl_on_off(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3354 dissect_zbee_zcl_on_off(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
3355 {
3356     proto_tree       *payload_tree;
3357     zbee_zcl_packet  *zcl;
3358     guint   offset = 0;
3359     guint8  cmd_id;
3360     gint    rem_len;
3361     guint8  effect_identifier = 0;
3362 
3363     static int * const onoff_control_mask[] = {
3364         &hf_zbee_zcl_on_off_timed_off_control_mask_accept_only_when_on,
3365         &hf_zbee_zcl_on_off_timed_off_control_mask_reserved,
3366         NULL
3367     };
3368 
3369     /* Reject the packet if data is NULL */
3370     if (data == NULL)
3371         return 0;
3372     zcl = (zbee_zcl_packet *)data;
3373     cmd_id = zcl->cmd_id;
3374 
3375     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
3376     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
3377         /* Append the command name to the info column. */
3378         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
3379             val_to_str_const(cmd_id, zbee_zcl_on_off_srv_rx_cmd_names, "Unknown Command"),
3380             zcl->tran_seqno);
3381 
3382         /* Add the command ID. */
3383         proto_tree_add_item(tree, hf_zbee_zcl_on_off_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
3384         rem_len = tvb_reported_length_remaining(tvb, ++offset);
3385         if (rem_len > 0) {
3386             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_on_off, NULL, "Payload");
3387 
3388             switch (cmd_id) {
3389                 case ZBEE_ZCL_ON_OFF_CMD_OFF_WITH_EFFECT:
3390                     proto_tree_add_item(payload_tree, hf_zbee_zcl_on_off_effect_identifier, tvb, offset, 1, ENC_NA);
3391                     effect_identifier = tvb_get_guint8(tvb, offset);
3392                     offset += 1;
3393                     switch (effect_identifier) {
3394                         case 0x00:
3395                             proto_tree_add_item(payload_tree, hf_zbee_zcl_on_off_effect_variant_delayed_all_off, tvb, offset, 1, ENC_NA);
3396                             break;
3397                         case 0x01:
3398                             proto_tree_add_item(payload_tree, hf_zbee_zcl_on_off_effect_variant_dying_light, tvb, offset, 1, ENC_NA);
3399                             break;
3400                         default:
3401                             proto_tree_add_item(payload_tree, hf_zbee_zcl_on_off_effect_variant_reserved, tvb, offset, 1, ENC_NA);
3402                             break;
3403                     }
3404                     break;
3405 
3406                 case ZBEE_ZCL_ON_OFF_CMD_ON_WITH_TIMED_OFF:
3407                     proto_tree_add_bitmask(payload_tree, tvb, offset, hf_zbee_zcl_on_off_timed_off_control_mask, ett_zbee_zcl_on_off_timed_off_control_mask, onoff_control_mask, ENC_LITTLE_ENDIAN);
3408                     offset += 1;
3409 
3410                     dissect_zcl_on_off_attr_data(payload_tree, tvb, &offset, ZBEE_ZCL_ON_OFF_ATTR_ID_ONTIME, FT_UINT16, FALSE);
3411                     dissect_zcl_on_off_attr_data(payload_tree, tvb, &offset, ZBEE_ZCL_ON_OFF_ATTR_ID_OFFWAITTIME, FT_UINT16, FALSE);
3412                     break;
3413 
3414                 default:
3415                     break;
3416             }
3417         }
3418     }
3419 
3420     return tvb_captured_length(tvb);
3421 } /*dissect_zbee_zcl_on_off*/
3422 
3423 
3424 /*FUNCTION:------------------------------------------------------
3425  *  NAME
3426  *      dissect_zcl_on_off_attr_data
3427  *  DESCRIPTION
3428  *      this function is called by ZCL foundation dissector in order to decode
3429  *      specific cluster attributes data.
3430  *  PARAMETERS
3431  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
3432  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
3433  *      guint *offset       - pointer to buffer offset
3434  *      guint16 attr_id     - attribute identifier
3435  *      guint data_type     - attribute data type
3436  *      gboolean client_attr- ZCL client
3437  *  RETURNS
3438  *      none
3439  *---------------------------------------------------------------
3440  */
3441 void
dissect_zcl_on_off_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)3442 dissect_zcl_on_off_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
3443 {
3444     /* Dissect attribute data type and data */
3445     switch (attr_id) {
3446 
3447         case ZBEE_ZCL_ON_OFF_ATTR_ID_ONOFF:
3448             proto_tree_add_item(tree, hf_zbee_zcl_on_off_attr_onoff, tvb, *offset, 1, ENC_NA);
3449             *offset += 1;
3450             break;
3451 
3452         case ZBEE_ZCL_ON_OFF_ATTR_ID_GLOBALSCENECONTROL:
3453             proto_tree_add_item(tree, hf_zbee_zcl_on_off_attr_globalscenecontrol, tvb, *offset, 1, ENC_NA);
3454             *offset += 1;
3455             break;
3456 
3457         case ZBEE_ZCL_ON_OFF_ATTR_ID_ONTIME:
3458             proto_tree_add_item(tree, hf_zbee_zcl_on_off_attr_ontime, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
3459             *offset += 2;
3460             break;
3461 
3462         case ZBEE_ZCL_ON_OFF_ATTR_ID_OFFWAITTIME:
3463             proto_tree_add_item(tree, hf_zbee_zcl_on_off_attr_offwaittime, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
3464             *offset += 2;
3465             break;
3466 
3467         case ZBEE_ZCL_ON_OFF_ATTR_ID_STARTUPONOFF:
3468             proto_tree_add_item(tree, hf_zbee_zcl_on_off_attr_startuponoff, tvb, *offset, 1, ENC_NA);
3469             *offset += 1;
3470             break;
3471 
3472         default:
3473             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
3474             break;
3475     }
3476 
3477 } /*dissect_zcl_on_off_attr_data*/
3478 
3479 /*FUNCTION:------------------------------------------------------
3480  *  NAME
3481  *      proto_register_zbee_zcl_on_off
3482  *  DESCRIPTION
3483  *      ZigBee ZCL OnOff cluster protocol registration routine.
3484  *  PARAMETERS
3485  *      none
3486  *  RETURNS
3487  *      void
3488  *---------------------------------------------------------------
3489  */
3490 void
proto_register_zbee_zcl_on_off(void)3491 proto_register_zbee_zcl_on_off(void)
3492 {
3493     /* Setup list of header fields */
3494     static hf_register_info hf[] = {
3495 
3496         { &hf_zbee_zcl_on_off_attr_id,
3497             { "Attribute", "zbee_zcl_general.onoff.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_on_off_attr_names),
3498             0x00, NULL, HFILL } },
3499 
3500         { &hf_zbee_zcl_on_off_attr_onoff,
3501             { "On/off Control", "zbee_zcl_general.onoff.attr.onoff", FT_UINT8, BASE_HEX, VALS(zbee_zcl_on_off_timed_off_names),
3502             0x00, NULL, HFILL } },
3503 
3504         { &hf_zbee_zcl_on_off_attr_globalscenecontrol,
3505             { "Global Scene Control", "zbee_zcl_general.onoff.attr.globalscenecontrol", FT_UINT8, BASE_HEX, VALS(zbee_zcl_on_off_globalscenecontrol_names),
3506             0x00, NULL, HFILL } },
3507 
3508         { &hf_zbee_zcl_on_off_attr_ontime,
3509             { "On Time", "zbee_zcl_general.onoff.attr.ontime", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_100ms),
3510             0x00, NULL, HFILL } },
3511 
3512         { &hf_zbee_zcl_on_off_attr_offwaittime,
3513             { "Off Wait Time", "zbee_zcl_general.onoff.attr.offwaittime", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_100ms),
3514             0x00, NULL, HFILL } },
3515 
3516         { &hf_zbee_zcl_on_off_attr_startuponoff,
3517             { "Startup On Off", "zbee_zcl_general.onoff.attr.startuponoff", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_zcl_on_off_startup_on_off_names),
3518             0x00, NULL, HFILL } },
3519 
3520         { &hf_zbee_zcl_on_off_effect_identifier,
3521             { "Effect Identifier", "zbee_zcl_general.onoff.effect_identifier", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_zcl_on_off_effect_identifier_names),
3522             0x00, NULL, HFILL } },
3523 
3524         { &hf_zbee_zcl_on_off_effect_variant_delayed_all_off,
3525             { "Effect Variant", "zbee_zcl_general.onoff.effect_variant", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_zcl_on_off_effect_variant_delayed_all_off_names),
3526             0x00, NULL, HFILL } },
3527 
3528         { &hf_zbee_zcl_on_off_effect_variant_dying_light,
3529             { "Effect Variant", "zbee_zcl_general.onoff.effect_variant", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_zcl_on_off_effect_variant_dying_light_names),
3530             0x00, NULL, HFILL } },
3531 
3532         { &hf_zbee_zcl_on_off_effect_variant_reserved,
3533             { "Effect Variant", "zbee_zcl_general.onoff.effect_variant", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_zcl_on_off_effect_variant_reserved_names),
3534             0x00, NULL, HFILL } },
3535 
3536         { &hf_zbee_zcl_on_off_timed_off_control_mask,
3537             { "On/Off Control Mask", "zbee_zcl_general.onoff.onoff_control_mask", FT_UINT8, BASE_HEX, NULL,
3538             0x00, NULL, HFILL } },
3539 
3540         { &hf_zbee_zcl_on_off_timed_off_control_mask_accept_only_when_on,
3541             { "Accept Only When On", "zbee_zcl_general.onoff.onoff_control_mask.accept_only_when_on", FT_UINT8, BASE_DEC, NULL,
3542             ZBEE_ZCL_ON_OFF_TIMED_OFF_CONTROL_MASK_ACCEPT_ONLY_WHEN_ON, NULL, HFILL } },
3543 
3544         { &hf_zbee_zcl_on_off_timed_off_control_mask_reserved,
3545             { "Reserved", "zbee_zcl_general.onoff.onoff_control_mask.reserved", FT_UINT8, BASE_DEC, NULL,
3546             ZBEE_ZCL_ON_OFF_TIMED_OFF_CONTROL_MASK_RESERVED, NULL, HFILL } },
3547 
3548         { &hf_zbee_zcl_on_off_srv_rx_cmd_id,
3549             { "Command", "zbee_zcl_general.onoff.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_on_off_srv_rx_cmd_names),
3550             0x00, NULL, HFILL } }
3551 
3552     };
3553 
3554     /* ZCL OnOff subtrees */
3555     static gint *ett[] = { &ett_zbee_zcl_on_off,
3556                           &ett_zbee_zcl_on_off_timed_off_control_mask };
3557 
3558     /* Register the ZigBee ZCL OnOff cluster protocol name and description */
3559     proto_zbee_zcl_on_off = proto_register_protocol("ZigBee ZCL OnOff", "ZCL OnOff", ZBEE_PROTOABBREV_ZCL_ONOFF);
3560     proto_register_field_array(proto_zbee_zcl_on_off, hf, array_length(hf));
3561     proto_register_subtree_array(ett, array_length(ett));
3562 
3563     /* Register the ZigBee ZCL OnOff dissector. */
3564     register_dissector(ZBEE_PROTOABBREV_ZCL_ONOFF, dissect_zbee_zcl_on_off, proto_zbee_zcl_on_off);
3565 } /* proto_register_zbee_zcl_on_off */
3566 
3567 /*FUNCTION:------------------------------------------------------
3568  *  NAME
3569  *      proto_reg_handoff_zbee_zcl_on_off
3570  *  DESCRIPTION
3571  *      Hands off the Zcl OnOff cluster dissector.
3572  *  PARAMETERS
3573  *      none
3574  *  RETURNS
3575  *      void
3576  *---------------------------------------------------------------
3577  */
3578 void
proto_reg_handoff_zbee_zcl_on_off(void)3579 proto_reg_handoff_zbee_zcl_on_off(void)
3580 {
3581     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_ONOFF,
3582                             proto_zbee_zcl_on_off,
3583                             ett_zbee_zcl_on_off,
3584                             ZBEE_ZCL_CID_ON_OFF,
3585                             ZBEE_MFG_CODE_NONE,
3586                             hf_zbee_zcl_on_off_attr_id,
3587                             hf_zbee_zcl_on_off_attr_id,
3588                             hf_zbee_zcl_on_off_srv_rx_cmd_id,
3589                             -1,
3590                             (zbee_zcl_fn_attr_data)dissect_zcl_on_off_attr_data
3591                          );
3592 } /*proto_reg_handoff_zbee_zcl_on_off*/
3593 
3594 /* ############################################################################################### */
3595 /* #### (0x0007) ON/OFF SWITCH CONFIGURATION CLUSTER ############################################# */
3596 /* ############################################################################################### */
3597 
3598 /*************************/
3599 /* Defines               */
3600 /*************************/
3601 
3602 /* Attributes */
3603 #define ZBEE_ZCL_ON_OFF_SWITCH_CONFIGURATION_ATTR_ID_SWITCH_TYPE     0x0000     /* Switch Type */
3604 #define ZBEE_ZCL_ON_OFF_SWITCH_CONFIGURATION_ATTR_ID_SWITCH_ACTIONS  0x0010  /* Switch Actions */
3605 
3606 /* No Server Commands Received */
3607 
3608 /*************************/
3609 /* Function Declarations */
3610 /*************************/
3611 
3612 void proto_register_zbee_zcl_on_off_switch_configuration(void);
3613 void proto_reg_handoff_zbee_zcl_on_off_switch_configuration(void);
3614 
3615 /* Command Dissector Helpers */
3616 static void dissect_zcl_on_off_switch_configuration_attr_data     (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
3617 
3618 /* Private functions prototype */
3619 
3620 /*************************/
3621 /* Global Variables      */
3622 /*************************/
3623 
3624 /* Initialize the protocol and registered fields */
3625 static int proto_zbee_zcl_on_off_switch_configuration = -1;
3626 
3627 static int hf_zbee_zcl_on_off_switch_configuration_attr_id = -1;
3628 static int hf_zbee_zcl_on_off_switch_configuration_attr_switch_type = -1;
3629 static int hf_zbee_zcl_on_off_switch_configuration_attr_switch_actions = -1;
3630 
3631 /* Initialize the subtree pointers */
3632 static gint ett_zbee_zcl_on_off_switch_configuration = -1;
3633 
3634 /* Attributes */
3635 static const value_string zbee_zcl_on_off_switch_configuration_attr_names[] = {
3636     { ZBEE_ZCL_ON_OFF_SWITCH_CONFIGURATION_ATTR_ID_SWITCH_TYPE,     "Switch Type" },
3637     { ZBEE_ZCL_ON_OFF_SWITCH_CONFIGURATION_ATTR_ID_SWITCH_ACTIONS,  "Switch Actions" },
3638     { 0, NULL }
3639 };
3640 
3641 /* Switch Type Names */
3642 static const value_string zbee_zcl_on_off_switch_configuration_switch_type_names[] = {
3643     { 0x00, "Toggle" },
3644     { 0x01, "Momentary" },
3645     { 0, NULL }
3646 };
3647 
3648 /* Switch Actions Names */
3649 static const value_string zbee_zcl_on_off_switch_configuration_switch_actions_names[] = {
3650     { 0x00, "On" },
3651     { 0x01, "Off" },
3652     { 0x02, "Toggle" },
3653     { 0, NULL }
3654 };
3655 
3656 /*************************/
3657 /* Function Bodies       */
3658 /*************************/
3659 
3660 /*FUNCTION:------------------------------------------------------
3661  *  NAME
3662  *      dissect_zbee_zcl_on_off_switch_configuration
3663  *  DESCRIPTION
3664  *      ZigBee ZCL OnOff Switch Configuration cluster dissector for wireshark.
3665  *  PARAMETERS
3666  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
3667  *      packet_info *pinfo  - pointer to packet information fields
3668  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
3669  *  RETURNS
3670  *      int                 - length of parsed data.
3671  *---------------------------------------------------------------
3672  */
3673 static int
dissect_zbee_zcl_on_off_switch_configuration(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)3674 dissect_zbee_zcl_on_off_switch_configuration(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
3675 {
3676     return tvb_captured_length(tvb);
3677 } /*dissect_zbee_zcl_on_off_switch_configuration*/
3678 
3679 
3680 /*FUNCTION:------------------------------------------------------
3681  *  NAME
3682  *      dissect_zcl_on_off_switch_configuration_attr_data
3683  *  DESCRIPTION
3684  *      this function is called by ZCL foundation dissector in order to decode
3685  *      specific cluster attributes data.
3686  *  PARAMETERS
3687  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
3688  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
3689  *      guint *offset       - pointer to buffer offset
3690  *      guint16 attr_id     - attribute identifier
3691  *      guint data_type     - attribute data type
3692  *      gboolean client_attr- ZCL client
3693  *  RETURNS
3694  *      none
3695  *---------------------------------------------------------------
3696  */
3697 void
dissect_zcl_on_off_switch_configuration_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)3698 dissect_zcl_on_off_switch_configuration_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
3699 {
3700     /* Dissect attribute data type and data */
3701     switch (attr_id) {
3702 
3703         case ZBEE_ZCL_ON_OFF_SWITCH_CONFIGURATION_ATTR_ID_SWITCH_TYPE:
3704             proto_tree_add_item(tree, hf_zbee_zcl_on_off_switch_configuration_attr_switch_type, tvb, *offset, 1, ENC_NA);
3705             *offset += 1;
3706             break;
3707 
3708         case ZBEE_ZCL_ON_OFF_SWITCH_CONFIGURATION_ATTR_ID_SWITCH_ACTIONS:
3709             proto_tree_add_item(tree, hf_zbee_zcl_on_off_switch_configuration_attr_switch_actions, tvb, *offset, 1, ENC_NA);
3710             *offset += 1;
3711             break;
3712 
3713         default:
3714             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
3715             break;
3716     }
3717 
3718 } /*dissect_zcl_on_off_switch_configuration_attr_data*/
3719 
3720 
3721 /*FUNCTION:------------------------------------------------------
3722  *  NAME
3723  *      proto_register_zbee_zcl_on_off_switch_configuration
3724  *  DESCRIPTION
3725  *      ZigBee ZCL OnOff cluster protocol registration routine.
3726  *  PARAMETERS
3727  *      none
3728  *  RETURNS
3729  *      void
3730  *---------------------------------------------------------------
3731  */
3732 void
proto_register_zbee_zcl_on_off_switch_configuration(void)3733 proto_register_zbee_zcl_on_off_switch_configuration(void)
3734 {
3735     /* Setup list of header fields */
3736     static hf_register_info hf[] = {
3737 
3738         { &hf_zbee_zcl_on_off_switch_configuration_attr_id,
3739             { "Attribute", "zbee_zcl_general.onoff_switch_configuration.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_on_off_switch_configuration_attr_names),
3740             0x00, NULL, HFILL } },
3741 
3742         { &hf_zbee_zcl_on_off_switch_configuration_attr_switch_type,
3743             { "Switch Type", "zbee_zcl_general.onoff.attr.switch_type", FT_UINT8, BASE_HEX, VALS(zbee_zcl_on_off_switch_configuration_switch_type_names),
3744             0x00, NULL, HFILL } },
3745 
3746         { &hf_zbee_zcl_on_off_switch_configuration_attr_switch_actions,
3747             { "Switch Action", "zbee_zcl_general.onoff.attr.switch_actions", FT_UINT8, BASE_HEX, VALS(zbee_zcl_on_off_switch_configuration_switch_actions_names),
3748             0x00, NULL, HFILL } }
3749 
3750     };
3751 
3752     /* ZCL Identify subtrees */
3753     static gint *ett[] = {
3754         &ett_zbee_zcl_on_off_switch_configuration
3755     };
3756 
3757     /* Register the ZigBee ZCL OnOff Switch Configuration cluster protocol name and description */
3758     proto_zbee_zcl_on_off_switch_configuration = proto_register_protocol("ZigBee ZCL OnOff Switch Configuration", "ZCL OnOff Switch Configuration", ZBEE_PROTOABBREV_ZCL_ONOFF_SWITCH_CONFIG);
3759     proto_register_field_array(proto_zbee_zcl_on_off_switch_configuration, hf, array_length(hf));
3760     proto_register_subtree_array(ett, array_length(ett));
3761 
3762     /* Register the ZigBee ZCL OnOff dissector. */
3763     register_dissector(ZBEE_PROTOABBREV_ZCL_ONOFF_SWITCH_CONFIG, dissect_zbee_zcl_on_off_switch_configuration, proto_zbee_zcl_on_off_switch_configuration);
3764 } /* proto_register_zbee_zcl_on_off_switch_configuration */
3765 
3766 /*FUNCTION:------------------------------------------------------
3767  *  NAME
3768  *      proto_reg_handoff_zbee_zcl_on_off_switch_configuration
3769  *  DESCRIPTION
3770  *      Hands off the Zcl OnOff cluster dissector.
3771  *  PARAMETERS
3772  *      none
3773  *  RETURNS
3774  *      none
3775  *---------------------------------------------------------------
3776  */
3777 void
proto_reg_handoff_zbee_zcl_on_off_switch_configuration(void)3778 proto_reg_handoff_zbee_zcl_on_off_switch_configuration(void)
3779 {
3780     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_ONOFF_SWITCH_CONFIG,
3781                             proto_zbee_zcl_on_off_switch_configuration,
3782                             ett_zbee_zcl_on_off_switch_configuration,
3783                             ZBEE_ZCL_CID_ON_OFF_SWITCH_CONFIG,
3784                             ZBEE_MFG_CODE_NONE,
3785                             hf_zbee_zcl_on_off_switch_configuration_attr_id,
3786                             hf_zbee_zcl_on_off_switch_configuration_attr_id,
3787                             -1, -1,
3788                             (zbee_zcl_fn_attr_data)dissect_zcl_on_off_switch_configuration_attr_data
3789                          );
3790 } /*proto_reg_handoff_zbee_zcl_on_off_switch_configuration*/
3791 
3792 /* ########################################################################## */
3793 /* #### (0x0009) ALARMS CLUSTER ############################################# */
3794 /* ########################################################################## */
3795 
3796 /*************************/
3797 /* Defines               */
3798 /*************************/
3799 
3800 /* Attributes */
3801 #define ZBEE_ZCL_ATTR_ID_ALARMS_ALARM_COUNT         0x0000  /* Alarm Count */
3802 
3803 /* Server Commands Received */
3804 #define ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALARM          0x00  /* Reset Alarm */
3805 #define ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALL_ALARMS     0x01  /* Reset All Alarms */
3806 #define ZBEE_ZCL_CMD_ID_ALARMS_GET_ALARM            0x02  /* Get Alarm */
3807 #define ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALARM_LOG      0x03  /* Reset Alarm Log */
3808 
3809 /* Server Commands Generated */
3810 #define ZBEE_ZCL_CMD_ID_ALARMS_ALARM                0x00  /* Alarm */
3811 #define ZBEE_ZCL_CMD_ID_ALARMS_GET_ALARM_RESPONSE   0x01  /* Get Alarm Response */
3812 
3813 /*************************/
3814 /* Function Declarations */
3815 /*************************/
3816 
3817 void proto_register_zbee_zcl_alarms(void);
3818 void proto_reg_handoff_zbee_zcl_alarms(void);
3819 
3820 /* Private functions prototype */
3821 
3822 /*************************/
3823 /* Global Variables      */
3824 /*************************/
3825 /* Initialize the protocol and registered fields */
3826 static int proto_zbee_zcl_alarms = -1;
3827 
3828 static int hf_zbee_zcl_alarms_attr_id = -1;
3829 static int hf_zbee_zcl_alarms_alarm_code = -1;
3830 static int hf_zbee_zcl_alarms_cluster_id = -1;
3831 static int hf_zbee_zcl_alarms_status = -1;
3832 static int hf_zbee_zcl_alarms_timestamp = -1;
3833 static int hf_zbee_zcl_alarms_srv_rx_cmd_id = -1;
3834 static int hf_zbee_zcl_alarms_srv_tx_cmd_id = -1;
3835 
3836 /* Initialize the subtree pointers */
3837 static gint ett_zbee_zcl_alarms = -1;
3838 
3839 /* Attributes */
3840 static const value_string zbee_zcl_alarms_attr_names[] = {
3841     { ZBEE_ZCL_ATTR_ID_ALARMS_ALARM_COUNT,      "Alarm Count" },
3842     { 0, NULL }
3843 };
3844 
3845 /* Server Commands Received */
3846 static const value_string zbee_zcl_alarms_srv_rx_cmd_names[] = {
3847     { ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALARM,       "Reset Alarm" },
3848     { ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALL_ALARMS,  "Reset All Alarms" },
3849     { ZBEE_ZCL_CMD_ID_ALARMS_GET_ALARM,         "Get Alarm" },
3850     { ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALARM_LOG,   "Reset Alarm Log" },
3851     { 0, NULL }
3852 };
3853 
3854 /* Server Commands Generated */
3855 static const value_string zbee_zcl_alarms_srv_tx_cmd_names[] = {
3856     { ZBEE_ZCL_CMD_ID_ALARMS_ALARM,             "Alarm" },
3857     { ZBEE_ZCL_CMD_ID_ALARMS_GET_ALARM_RESPONSE,"Get Alarm Response" },
3858     { 0, NULL }
3859 };
3860 
3861 /*************************/
3862 /* Function Bodies       */
3863 /*************************/
3864 
3865 /*FUNCTION:------------------------------------------------------
3866  *  NAME
3867  *      dissect_zcl_alarms_attr_data
3868  *  DESCRIPTION
3869  *      this function is called by ZCL foundation dissector in order to decode
3870  *      specific cluster attributes data.
3871  *  PARAMETERS
3872  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
3873  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
3874  *      guint *offset       - pointer to buffer offset
3875  *      guint16 attr_id     - attribute identifier
3876  *      guint data_type     - attribute data type
3877  *      gboolean client_attr- ZCL client
3878  *  RETURNS
3879  *      none
3880  *--------------------------------------------------------------- */
3881 static void
dissect_zcl_alarms_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)3882 dissect_zcl_alarms_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
3883 {
3884     /* Dissect attribute data type and data */
3885     switch ( attr_id ) {
3886         case ZBEE_ZCL_ATTR_ID_ALARMS_ALARM_COUNT:
3887         default:
3888             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
3889             break;
3890     }
3891 
3892 } /*dissect_zcl_alarms_attr_data*/
3893 
3894 /*FUNCTION:------------------------------------------------------
3895  *  NAME
3896  *      dissect_zcl_alarms_alarm_and_reset_alarm
3897  *  DESCRIPTION
3898  *      this function decodes the Alarm and Reset Alarm payload.
3899  *  PARAMETERS
3900  *      tvb     - the tv buffer of the current data_type
3901  *      tree    - the tree to append this item to
3902  *      offset  - offset of data in tvb
3903  *  RETURNS
3904  *      none
3905  *---------------------------------------------------------------
3906  */
3907 static void
dissect_zcl_alarms_alarm_and_reset_alarm(tvbuff_t * tvb,proto_tree * tree,guint * offset)3908 dissect_zcl_alarms_alarm_and_reset_alarm(tvbuff_t *tvb, proto_tree *tree, guint *offset)
3909 {
3910     /* Retrieve "Alarm Code" field */
3911     proto_tree_add_item(tree, hf_zbee_zcl_alarms_alarm_code, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
3912     *offset += 1;
3913 
3914     /* Retrieve "Cluster ID" field */
3915     proto_tree_add_item(tree, hf_zbee_zcl_alarms_cluster_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
3916     *offset += 2;
3917 
3918 } /*dissect_zcl_alarms_alarm_and_reset_alarm*/
3919 
3920 
3921  /*FUNCTION:--------------------------------------------------------------------
3922  *  NAME
3923  *      dissect_zcl_alarms_get_alarm_response
3924  *  DESCRIPTION
3925  *      this function decodes the Get Alarm Response payload
3926  *  PARAMETERS
3927  *      tvb     - the tv buffer of the current data_type
3928  *      tree    - the tree to append this item to
3929  *      offset  - offset of data in tvb
3930  *  RETURNS
3931  *      none
3932  *------------------------------------------------------------------------------
3933  */
3934 
3935 static void
dissect_zcl_alarms_get_alarm_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)3936 dissect_zcl_alarms_get_alarm_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
3937 {
3938      guint8 status;
3939 
3940     /* Retrieve "Status" field */
3941     status = tvb_get_guint8(tvb, *offset);
3942     proto_tree_add_item(tree, hf_zbee_zcl_alarms_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
3943     *offset += 1;
3944 
3945     if(status == ZBEE_ZCL_STAT_SUCCESS)
3946     {
3947         /* Retrieve "Alarm Code" field */
3948         proto_tree_add_item(tree, hf_zbee_zcl_alarms_alarm_code, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
3949         *offset += 1;
3950 
3951         /* Retrieve "Cluster ID" field */
3952         proto_tree_add_item(tree, hf_zbee_zcl_alarms_cluster_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
3953         *offset += 2;
3954 
3955         /* Retrieve "Timestamp" field */
3956         proto_tree_add_item(tree, hf_zbee_zcl_alarms_timestamp, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
3957         *offset += 4;
3958     }
3959 
3960 } /*dissect_zcl_alarms_get_alarm_response*/
3961 
3962 
3963 
3964 /*FUNCTION:------------------------------------------------------
3965  *  NAME
3966  *      dissect_zbee_zcl_alarms
3967  *  DESCRIPTION
3968  *      ZigBee ZCL Alarms cluster dissector for wireshark.
3969  *  PARAMETERS
3970  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
3971  *      packet_info *pinfo  - pointer to packet information fields
3972  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
3973  *  RETURNS
3974  *      none
3975  *---------------------------------------------------------------
3976  */
3977 static int
dissect_zbee_zcl_alarms(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3978 dissect_zbee_zcl_alarms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
3979 {
3980     proto_tree        *payload_tree;
3981     zbee_zcl_packet   *zcl;
3982     guint             offset = 0;
3983     guint8            cmd_id;
3984     gint              rem_len;
3985 
3986     /* Reject the packet if data is NULL */
3987     if (data == NULL)
3988         return 0;
3989     zcl = (zbee_zcl_packet *)data;
3990     cmd_id = zcl->cmd_id;
3991 
3992     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
3993     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
3994         /* Append the command name to the info column. */
3995         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
3996             val_to_str_const(cmd_id, zbee_zcl_alarms_srv_rx_cmd_names, "Unknown Command"),
3997             zcl->tran_seqno);
3998 
3999         /* Add the command ID. */
4000         proto_tree_add_item(tree, hf_zbee_zcl_alarms_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4001 
4002         /* Check if this command has a payload, then add the payload tree */
4003         rem_len = tvb_reported_length_remaining(tvb, ++offset);
4004         if (rem_len > 0) {
4005             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_alarms, NULL, "Payload");
4006 
4007             /* Call the appropriate command dissector */
4008             switch (cmd_id) {
4009                 case ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALARM:
4010                     dissect_zcl_alarms_alarm_and_reset_alarm(tvb, payload_tree, &offset);
4011                     break;
4012 
4013                 case ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALL_ALARMS:
4014                 case ZBEE_ZCL_CMD_ID_ALARMS_GET_ALARM:
4015                 case ZBEE_ZCL_CMD_ID_ALARMS_RESET_ALARM_LOG:
4016                     /* No Payload */
4017                 default:
4018                     break;
4019             }
4020         }
4021     }
4022     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
4023         /* Append the command name to the info column. */
4024         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
4025             val_to_str_const(cmd_id, zbee_zcl_alarms_srv_tx_cmd_names, "Unknown Command"),
4026             zcl->tran_seqno);
4027 
4028         /* Add the command ID. */
4029         proto_tree_add_item(tree, hf_zbee_zcl_alarms_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4030 
4031         /* Check if this command has a payload, then add the payload tree */
4032         rem_len = tvb_reported_length_remaining(tvb, ++offset);
4033         if (rem_len > 0) {
4034             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_alarms, NULL, "Payload");
4035 
4036             /* Call the appropriate command dissector */
4037             switch (cmd_id) {
4038                 case ZBEE_ZCL_CMD_ID_ALARMS_ALARM:
4039                     dissect_zcl_alarms_alarm_and_reset_alarm(tvb, payload_tree, &offset);
4040                     break;
4041 
4042                 case ZBEE_ZCL_CMD_ID_ALARMS_GET_ALARM_RESPONSE:
4043                     dissect_zcl_alarms_get_alarm_response(tvb, payload_tree, &offset);
4044                     break;
4045 
4046                 default:
4047                     break;
4048             }
4049         }
4050     }
4051 
4052     return tvb_captured_length(tvb);
4053 } /*dissect_zbee_zcl_alarms*/
4054 
4055 
4056 
4057 
4058 
4059 /*FUNCTION:------------------------------------------------------
4060  *  NAME
4061  *      proto_register_zbee_zcl_alarms
4062  *  DESCRIPTION
4063  *      ZigBee ZCL Alarms cluster protocol registration routine.
4064  *  PARAMETERS
4065  *      none
4066  *  RETURNS
4067  *      void
4068  *---------------------------------------------------------------
4069  */
4070 void
proto_register_zbee_zcl_alarms(void)4071 proto_register_zbee_zcl_alarms(void)
4072 {
4073     /* Setup list of header fields */
4074     static hf_register_info hf[] = {
4075 
4076         { &hf_zbee_zcl_alarms_attr_id,
4077             { "Attribute", "zbee_zcl_general.alarms.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_alarms_attr_names),
4078             0x00, NULL, HFILL } },
4079 
4080         { &hf_zbee_zcl_alarms_alarm_code,
4081             { "Alarm Code", "zbee_zcl_general.alarms.alarm_code", FT_UINT8, BASE_HEX, NULL,
4082             0x00, NULL, HFILL } },
4083 
4084         { &hf_zbee_zcl_alarms_cluster_id,
4085             { "Cluster ID", "zbee_zcl_general.alarms.cluster_id", FT_UINT16, BASE_HEX, NULL,
4086             0x00, NULL, HFILL } },
4087 
4088         { &hf_zbee_zcl_alarms_status,
4089             { "Status", "zbee_zcl_general.alarms.status", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_names),
4090             0x00, NULL, HFILL } },
4091 
4092         { &hf_zbee_zcl_alarms_timestamp,
4093             { "Timestamp", "zbee_zcl_general.alarms.timestamp", FT_UINT32, BASE_HEX, NULL,
4094             0x00, NULL, HFILL } },
4095 
4096         { &hf_zbee_zcl_alarms_srv_rx_cmd_id,
4097           { "Command", "zbee_zcl_general.alarms.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_alarms_srv_rx_cmd_names),
4098             0x00, NULL, HFILL } },
4099 
4100         { &hf_zbee_zcl_alarms_srv_tx_cmd_id,
4101           { "Command", "zbee_zcl_general.alarms.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_alarms_srv_tx_cmd_names),
4102             0x00, NULL, HFILL } }
4103 
4104     };
4105 
4106     /* ZCL Alarms subtrees */
4107     static gint *ett[] = {
4108         &ett_zbee_zcl_alarms
4109     };
4110 
4111     /* Register the ZigBee ZCL Alarms cluster protocol name and description */
4112     proto_zbee_zcl_alarms = proto_register_protocol("ZigBee ZCL Alarms", "ZCL Alarms", ZBEE_PROTOABBREV_ZCL_ALARMS);
4113     proto_register_field_array(proto_zbee_zcl_alarms, hf, array_length(hf));
4114     proto_register_subtree_array(ett, array_length(ett));
4115 
4116     /* Register the ZigBee ZCL Alarms dissector. */
4117     register_dissector(ZBEE_PROTOABBREV_ZCL_ALARMS, dissect_zbee_zcl_alarms, proto_zbee_zcl_alarms);
4118 
4119 } /*proto_register_zbee_zcl_alarms*/
4120 
4121 
4122 /*FUNCTION:------------------------------------------------------
4123  *  NAME
4124  *      proto_reg_handoff_zbee_zcl_alarms
4125  *  DESCRIPTION
4126  *      Hands off the ZCL Alarms dissector.
4127  *  PARAMETERS
4128  *      none
4129  *  RETURNS
4130  *      none
4131  *---------------------------------------------------------------
4132  */
4133 void
proto_reg_handoff_zbee_zcl_alarms(void)4134 proto_reg_handoff_zbee_zcl_alarms(void)
4135 {
4136     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_ALARMS,
4137                             proto_zbee_zcl_alarms,
4138                             ett_zbee_zcl_alarms,
4139                             ZBEE_ZCL_CID_ALARMS,
4140                             ZBEE_MFG_CODE_NONE,
4141                             hf_zbee_zcl_alarms_attr_id,
4142                             hf_zbee_zcl_alarms_attr_id,
4143                             hf_zbee_zcl_alarms_srv_rx_cmd_id,
4144                             hf_zbee_zcl_alarms_srv_tx_cmd_id,
4145                             (zbee_zcl_fn_attr_data)dissect_zcl_alarms_attr_data
4146                          );
4147 } /*proto_reg_handoff_zbee_zcl_alarms*/
4148 
4149 
4150 /* ########################################################################## */
4151 /* #### (0x000A) TIME CLUSTER ############################################### */
4152 /* ########################################################################## */
4153 
4154 /*************************/
4155 /* Defines               */
4156 /*************************/
4157 
4158 /* Attributes */
4159 #define ZBEE_ZCL_ATTR_ID_TIME_TIME              0x0000  /* Time */
4160 #define ZBEE_ZCL_ATTR_ID_TIME_TIME_STATUS       0x0001  /* Time Status */
4161 #define ZBEE_ZCL_ATTR_ID_TIME_TIME_ZONE         0x0002  /* Time Zone */
4162 #define ZBEE_ZCL_ATTR_ID_TIME_DST_START         0x0003  /* Daylight Saving Time Start*/
4163 #define ZBEE_ZCL_ATTR_ID_TIME_DST_END           0x0004  /* Daylight Saving Time End */
4164 #define ZBEE_ZCL_ATTR_ID_TIME_DST_SHIFT         0x0005  /* Daylight Saving Time Shift */
4165 #define ZBEE_ZCL_ATTR_ID_TIME_STD_TIME          0x0006  /* Standard Time */
4166 #define ZBEE_ZCL_ATTR_ID_TIME_LOCAL_TIME        0x0007  /* Local Time */
4167 #define ZBEE_ZCL_ATTR_ID_TIME_LAST_SET_TIME     0x0008  /* Last Set Time */
4168 #define ZBEE_ZCL_ATTR_ID_TIME_VALID_UNTIL_TIME  0x0009  /* Valid Until Time */
4169 
4170 /* Server commands received - none */
4171 
4172 /* Server commands generated - none */
4173 
4174 /* Time Status Mask Value */
4175 #define ZBEE_ZCL_TIME_MASTER                     0x01    /* Master Clock */
4176 #define ZBEE_ZCL_TIME_SYNCHRONIZED               0x02    /* Synchronized */
4177 #define ZBEE_ZCL_TIME_MASTER_ZONE_DST            0x04    /* Master for Time Zone and DST */
4178 #define ZBEE_ZCL_TIME_SUPERSEDING                0x08    /* Superseded */
4179 
4180 /*************************/
4181 /* Function Declarations */
4182 /*************************/
4183 
4184 void proto_register_zbee_zcl_time(void);
4185 void proto_reg_handoff_zbee_zcl_time(void);
4186 
4187 
4188 /*************************/
4189 /* Global Variables      */
4190 /*************************/
4191 /* Initialize the protocol and registered fields */
4192 static int proto_zbee_zcl_time = -1;
4193 
4194 static int hf_zbee_zcl_time_attr_id = -1;
4195 static int hf_zbee_zcl_time_status = -1;
4196 static int hf_zbee_zcl_time_status_master = -1;
4197 static int hf_zbee_zcl_time_status_synchronized = -1;
4198 static int hf_zbee_zcl_time_status_master_zone_dst = -1;
4199 static int hf_zbee_zcl_time_status_superseding = -1;
4200 
4201 /* Initialize the subtree pointers */
4202 static gint ett_zbee_zcl_time = -1;
4203 static gint ett_zbee_zcl_time_status_mask = -1;
4204 
4205 /* Attributes */
4206 static const value_string zbee_zcl_time_attr_names[] = {
4207     { ZBEE_ZCL_ATTR_ID_TIME_TIME,               "Time" },
4208     { ZBEE_ZCL_ATTR_ID_TIME_TIME_STATUS,        "Time Status" },
4209     { ZBEE_ZCL_ATTR_ID_TIME_TIME_ZONE,          "Time Zone" },
4210     { ZBEE_ZCL_ATTR_ID_TIME_DST_START,          "Daylight Saving Time Start" },
4211     { ZBEE_ZCL_ATTR_ID_TIME_DST_END,            "Daylight Saving Time End" },
4212     { ZBEE_ZCL_ATTR_ID_TIME_DST_SHIFT,          "Daylight Saving Time Shift" },
4213     { ZBEE_ZCL_ATTR_ID_TIME_STD_TIME,           "Standard Time" },
4214     { ZBEE_ZCL_ATTR_ID_TIME_LOCAL_TIME,         "Local Time" },
4215     { ZBEE_ZCL_ATTR_ID_TIME_LAST_SET_TIME,      "Last Set Time" },
4216     { ZBEE_ZCL_ATTR_ID_TIME_VALID_UNTIL_TIME,   "Valid Until Time" },
4217     { 0, NULL }
4218 };
4219 
4220 /*************************/
4221 /* Function Bodies       */
4222 /*************************/
4223 
4224 /*FUNCTION:------------------------------------------------------
4225  *  NAME
4226  *      dissect_zcl_time_attr_data
4227  *  DESCRIPTION
4228  *      this function is called by ZCL foundation dissector in order to decode
4229  *      specific cluster attributes data.
4230  *  PARAMETERS
4231  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
4232  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
4233  *      guint *offset       - pointer to buffer offset
4234  *      guint16 attr_id     - attribute identifier
4235  *      guint data_type     - attribute data type
4236  *      gboolean client_attr- ZCL client
4237  *  RETURNS
4238  *      none
4239  *--------------------------------------------------------------- */
4240 static void
dissect_zcl_time_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)4241 dissect_zcl_time_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
4242 {
4243     static int * const time_status_mask[] = {
4244         &hf_zbee_zcl_time_status_master,
4245         &hf_zbee_zcl_time_status_synchronized,
4246         &hf_zbee_zcl_time_status_master_zone_dst,
4247         &hf_zbee_zcl_time_status_superseding,
4248         NULL
4249     };
4250 
4251     /* Dissect attribute data type and data */
4252     switch (attr_id) {
4253 
4254         case ZBEE_ZCL_ATTR_ID_TIME_TIME_STATUS:
4255             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_time_status, ett_zbee_zcl_time_status_mask, time_status_mask, ENC_LITTLE_ENDIAN);
4256             *offset += 1;
4257             break;
4258 
4259         case ZBEE_ZCL_ATTR_ID_TIME_TIME:
4260         case ZBEE_ZCL_ATTR_ID_TIME_TIME_ZONE:
4261         case ZBEE_ZCL_ATTR_ID_TIME_DST_START:
4262         case ZBEE_ZCL_ATTR_ID_TIME_DST_END:
4263         case ZBEE_ZCL_ATTR_ID_TIME_DST_SHIFT:
4264         case ZBEE_ZCL_ATTR_ID_TIME_STD_TIME:
4265         case ZBEE_ZCL_ATTR_ID_TIME_LOCAL_TIME:
4266         case ZBEE_ZCL_ATTR_ID_TIME_LAST_SET_TIME:
4267         case ZBEE_ZCL_ATTR_ID_TIME_VALID_UNTIL_TIME:
4268         default:
4269             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
4270             break;
4271     }
4272 
4273 } /*dissect_zcl_time_attr_data*/
4274 /*FUNCTION:------------------------------------------------------
4275  *  NAME
4276  *      dissect_zbee_zcl_time
4277  *  DESCRIPTION
4278  *      ZigBee ZCL Time cluster dissector for wireshark.
4279  *  PARAMETERS
4280  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
4281  *      packet_info *pinfo  - pointer to packet information fields
4282  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
4283  *  RETURNS
4284  *      none
4285  *---------------------------------------------------------------
4286  */
4287 
4288 static int
dissect_zbee_zcl_time(tvbuff_t _U_ * tvb,packet_info _U_ * pinfo,proto_tree _U_ * tree,void _U_ * data)4289 dissect_zbee_zcl_time(tvbuff_t _U_ *tvb, packet_info _U_ * pinfo, proto_tree _U_* tree, void _U_* data)
4290 {
4291     /* No commands is being received and generated by server
4292      * No cluster specific commands  are received by client
4293      */
4294     return 0;
4295 } /*dissect_zbee_zcl_time*/
4296 
4297 /*FUNCTION:------------------------------------------------------
4298  *  NAME
4299  *      proto_register_zbee_zcl_time
4300  *  DESCRIPTION
4301  *      ZigBee ZCL Time cluster protocol registration routine.
4302  *  PARAMETERS
4303  *      none
4304  *  RETURNS
4305  *      void
4306  *---------------------------------------------------------------
4307  */
4308 void
proto_register_zbee_zcl_time(void)4309 proto_register_zbee_zcl_time(void)
4310 {
4311     /* Setup list of header fields */
4312     static hf_register_info hf[] = {
4313 
4314         { &hf_zbee_zcl_time_attr_id,
4315             { "Attribute", "zbee_zcl_general.time.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_time_attr_names),
4316             0x00, NULL, HFILL } },
4317 
4318         /* start Time Status Mask fields */
4319         { &hf_zbee_zcl_time_status,
4320             { "Time Status", "zbee_zcl_general.time.attr.time_status", FT_UINT8, BASE_HEX, NULL,
4321             0x00, NULL, HFILL } },
4322 
4323         { &hf_zbee_zcl_time_status_master,
4324             { "Master", "zbee_zcl_general.time.attr.time_status.master",  FT_BOOLEAN, 8, TFS(&tfs_true_false),
4325             ZBEE_ZCL_TIME_MASTER, NULL, HFILL } },
4326 
4327         { &hf_zbee_zcl_time_status_synchronized,
4328             { "Synchronized", "zbee_zcl_general.time.attr.time_status.synchronized", FT_BOOLEAN, 8, TFS(&tfs_true_false),
4329             ZBEE_ZCL_TIME_SYNCHRONIZED, NULL, HFILL } },
4330 
4331         { &hf_zbee_zcl_time_status_master_zone_dst,
4332             { "Master for Time Zone and DST", "zbee_zcl_general.time.attr.time_status.master_zone_dst", FT_BOOLEAN, 8, TFS(&tfs_true_false),
4333             ZBEE_ZCL_TIME_MASTER_ZONE_DST, NULL, HFILL } },
4334 
4335         { &hf_zbee_zcl_time_status_superseding,
4336             { "Superseded", "zbee_zcl_general.time.attr.time_status.superseding", FT_BOOLEAN, 8, TFS(&tfs_true_false),
4337             ZBEE_ZCL_TIME_SUPERSEDING, NULL, HFILL } }
4338         /* end Time Status Mask fields */
4339     };
4340 
4341     /* ZCL Time subtrees */
4342     static gint *ett[] = {
4343         &ett_zbee_zcl_time,
4344         &ett_zbee_zcl_time_status_mask
4345     };
4346 
4347     /* Register the ZigBee ZCL Time cluster protocol name and description */
4348     proto_zbee_zcl_time = proto_register_protocol("ZigBee ZCL Time", "ZCL Time", ZBEE_PROTOABBREV_ZCL_TIME);
4349     proto_register_field_array(proto_zbee_zcl_time, hf, array_length(hf));
4350     proto_register_subtree_array(ett, array_length(ett));
4351 
4352     /* Register the ZigBee ZCL Time dissector. */
4353     register_dissector(ZBEE_PROTOABBREV_ZCL_TIME, dissect_zbee_zcl_time, proto_zbee_zcl_time);
4354 } /*proto_register_zbee_zcl_time*/
4355 
4356 /*FUNCTION:------------------------------------------------------
4357  *  NAME
4358  *      proto_reg_handoff_zbee_zcl_time
4359  *  DESCRIPTION
4360  *      Hands off the ZCL Time dissector.
4361  *  PARAMETERS
4362  *      none
4363  *  RETURNS
4364  *      none
4365  *---------------------------------------------------------------
4366  */
4367 void
proto_reg_handoff_zbee_zcl_time(void)4368 proto_reg_handoff_zbee_zcl_time(void)
4369 {
4370     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_TIME,
4371                             proto_zbee_zcl_time,
4372                             ett_zbee_zcl_time,
4373                             ZBEE_ZCL_CID_TIME,
4374                             ZBEE_MFG_CODE_NONE,
4375                             hf_zbee_zcl_time_attr_id,
4376                             hf_zbee_zcl_time_attr_id,
4377                             -1, -1,
4378                             (zbee_zcl_fn_attr_data)dissect_zcl_time_attr_data
4379                          );
4380 } /*proto_reg_handoff_zbee_zcl_time*/
4381 
4382 
4383 
4384 
4385 /* ########################################################################## */
4386 /* #### (0x0008) LEVEL_CONTROL CLUSTER ###################################### */
4387 /* ########################################################################## */
4388 
4389 /*************************/
4390 /* Defines               */
4391 /*************************/
4392 
4393 /* Attributes */
4394 #define ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_CURRENT_LEVEL            0x0000  /* Current Level */
4395 #define ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_REMAINING_TIME           0x0001  /* Remaining Time */
4396 #define ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_ONOFF_TRANSIT_TIME       0x0010  /* OnOff Transition Time */
4397 #define ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_ON_LEVEL                 0x0011  /* On Level */
4398 #define ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_STARTUP_LEVEL            0x4000  /* Startup Level */
4399 
4400 /* Server Commands Received */
4401 #define ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_TO_LEVEL             0x00  /* Move to Level */
4402 #define ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE                      0x01  /* Move */
4403 #define ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STEP                      0x02  /* Step */
4404 #define ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STOP                      0x03  /* Stop */
4405 #define ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_TO_LEVEL_WITH_ONOFF  0x04  /* Move to Level with OnOff */
4406 #define ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_WITH_ONOFF           0x05  /* Move with OnOff */
4407 #define ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STEP_WITH_ONOFF           0x06  /* Step with OnOff */
4408 #define ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STOP_WITH_ONOFF           0x07  /* Stop with OnOff */
4409 
4410 /*************************/
4411 /* Function Declarations */
4412 /*************************/
4413 
4414 void proto_register_zbee_zcl_level_control(void);
4415 void proto_reg_handoff_zbee_zcl_level_control(void);
4416 
4417 /* Private functions prototype */
4418 
4419 /*************************/
4420 /* Global Variables      */
4421 /*************************/
4422 /* Initialize the protocol and registered fields */
4423 static int proto_zbee_zcl_level_control = -1;
4424 
4425 static int hf_zbee_zcl_level_control_attr_id = -1;
4426 static int hf_zbee_zcl_level_control_attr_current_level = -1;
4427 static int hf_zbee_zcl_level_control_attr_remaining_time = -1;
4428 static int hf_zbee_zcl_level_control_attr_onoff_transmit_time = -1;
4429 static int hf_zbee_zcl_level_control_attr_on_level = -1;
4430 static int hf_zbee_zcl_level_control_attr_startup_level = -1;
4431 static int hf_zbee_zcl_level_control_level = -1;
4432 static int hf_zbee_zcl_level_control_move_mode = -1;
4433 static int hf_zbee_zcl_level_control_rate = -1;
4434 static int hf_zbee_zcl_level_control_step_mode = -1;
4435 static int hf_zbee_zcl_level_control_step_size = -1;
4436 static int hf_zbee_zcl_level_control_transit_time = -1;
4437 static int hf_zbee_zcl_level_control_srv_rx_cmd_id = -1;
4438 
4439 /* Initialize the subtree pointers */
4440 static gint ett_zbee_zcl_level_control = -1;
4441 
4442 /* Attributes */
4443 static const value_string zbee_zcl_level_control_attr_names[] = {
4444     { ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_CURRENT_LEVEL,             "Current Level" },
4445     { ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_REMAINING_TIME,            "Remaining Time" },
4446     { ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_ONOFF_TRANSIT_TIME,        "OnOff Transition Time" },
4447     { ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_ON_LEVEL,                  "On Level" },
4448     { ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_STARTUP_LEVEL,             "Startup Level" },
4449     { 0, NULL }
4450 };
4451 
4452 /* Server Commands Received */
4453 static const value_string zbee_zcl_level_control_srv_rx_cmd_names[] = {
4454     { ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_TO_LEVEL,              "Move to Level" },
4455     { ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE,                       "Move" },
4456     { ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STEP,                       "Step" },
4457     { ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STOP,                       "Stop" },
4458     { ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_TO_LEVEL_WITH_ONOFF,   "Move to Level with OnOff" },
4459     { ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_WITH_ONOFF,            "Move with OnOff" },
4460     { ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STEP_WITH_ONOFF,            "Step with OnOff" },
4461     { ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STOP_WITH_ONOFF,            "Stop with OnOff" },
4462     { 0, NULL }
4463 };
4464 
4465 /* Move Mode Values */
4466 static const value_string zbee_zcl_level_control_move_step_mode_values[] = {
4467     { 0x00,   "Up" },
4468     { 0x01,   "Down" },
4469     { 0, NULL }
4470 };
4471 
4472 static const range_string zbee_zcl_level_control_startup_level_names[] = {
4473     { 0x00, 0x00, "Set the CurrentLevel attribute to the minimum" },
4474     { 0x01, 0xFE, "Set the CurrentLevel attribute to this value" },
4475     { 0xFF, 0xFF, "Set the CurrentLevel attribute to its previous value" },
4476     { 0, 0, NULL }
4477 };
4478 
4479 /*************************/
4480 /* Function Bodies       */
4481 /*************************/
4482 /*FUNCTION:------------------------------------------------------
4483  *  NAME
4484  *      dissect_zcl_level_control_move_to_level
4485  *  DESCRIPTION
4486  *      this function decodes the Move to Level payload.
4487  *  PARAMETERS
4488  *      tvb     - the tv buffer of the current data_type
4489  *      tree    - the tree to append this item to
4490  *      offset  - offset of data in tvb
4491  *  RETURNS
4492  *      none
4493  *---------------------------------------------------------------
4494  */
4495 static void
dissect_zcl_level_control_move_to_level(tvbuff_t * tvb,proto_tree * tree,guint * offset)4496 dissect_zcl_level_control_move_to_level(tvbuff_t *tvb, proto_tree *tree, guint *offset)
4497 {
4498     /* Retrieve "Level" field */
4499     proto_tree_add_item(tree, hf_zbee_zcl_level_control_level, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
4500     *offset += 1;
4501 
4502     /* Retrieve "Transition Time" field */
4503     proto_tree_add_item(tree, hf_zbee_zcl_level_control_transit_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
4504     *offset += 2;
4505 
4506 } /*dissect_zcl_level_control_move_to_level*/
4507 
4508 
4509  /*FUNCTION:--------------------------------------------------------------------
4510  *  NAME
4511  *      dissect_zcl_level_control_move
4512  *  DESCRIPTION
4513  *      this function decodes the Move payload
4514  *  PARAMETERS
4515  *      tvb     - the tv buffer of the current data_type
4516  *      tree    - the tree to append this item to
4517  *      offset  - offset of data in tvb
4518  *  RETURNS
4519  *      none
4520  *------------------------------------------------------------------------------
4521  */
4522 
4523 static void
dissect_zcl_level_control_move(tvbuff_t * tvb,proto_tree * tree,guint * offset)4524 dissect_zcl_level_control_move(tvbuff_t *tvb, proto_tree *tree, guint *offset)
4525 {
4526     /* Retrieve "Move Mode" field */
4527     proto_tree_add_item(tree, hf_zbee_zcl_level_control_move_mode, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
4528     *offset += 1;
4529 
4530     /* Retrieve "Rate" field */
4531     proto_tree_add_item(tree, hf_zbee_zcl_level_control_rate, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
4532     *offset += 1;
4533 
4534 } /*dissect_zcl_level_control_move*/
4535 
4536 
4537 /*FUNCTION:-------------------------------------------------------------------
4538 *  NAME
4539 *      dissect_zcl_level_control_step
4540 *  DESCRIPTION
4541 *      this function decodes the Step payload.
4542 *  PARAMETERS
4543 *      tvb     - the tv buffer of the current data_type
4544 *      tree    - the tree to append this item to
4545 *      offset  - offset of data in tvb
4546 *  RETURNS
4547 *      none
4548 *-----------------------------------------------------------------------------
4549 */
4550 static void
dissect_zcl_level_control_step(tvbuff_t * tvb,proto_tree * tree,guint * offset)4551 dissect_zcl_level_control_step(tvbuff_t *tvb, proto_tree *tree, guint *offset)
4552 {
4553     /* Retrieve "Step Mode" field */
4554     proto_tree_add_item(tree, hf_zbee_zcl_level_control_step_mode, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
4555     *offset += 1;
4556 
4557     /* Retrieve "Step Size" field */
4558     proto_tree_add_item(tree, hf_zbee_zcl_level_control_step_size, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
4559     *offset += 1;
4560 
4561     /* Retrieve "Transition Time" field */
4562     proto_tree_add_item(tree, hf_zbee_zcl_level_control_transit_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
4563     *offset += 2;
4564 
4565 } /*dissect_zcl_level_control_step*/
4566 
4567 
4568 /*FUNCTION:------------------------------------------------------
4569  *  NAME
4570  *      dissect_zcl_level_control_attr_data
4571  *  DESCRIPTION
4572  *      this function is called by ZCL foundation dissector in order to decode
4573  *      specific cluster attributes data.
4574  *  PARAMETERS
4575  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
4576  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
4577  *      guint *offset       - pointer to buffer offset
4578  *      guint16 attr_id     - attribute identifier
4579  *      guint data_type     - attribute data type
4580  *  RETURNS
4581  *      none
4582  *---------------------------------------------------------------
4583  */
4584 
4585 /*FUNCTION:------------------------------------------------------
4586  *  NAME
4587  *      dissect_zbee_zcl_level_control
4588  *  DESCRIPTION
4589  *      ZigBee ZCL Level Control cluster dissector for wireshark.
4590  *  PARAMETERS
4591  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
4592  *      packet_info *pinfo  - pointer to packet information fields
4593  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
4594  *  RETURNS
4595  *      none
4596  *---------------------------------------------------------------
4597  */
4598 static int
dissect_zbee_zcl_level_control(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)4599 dissect_zbee_zcl_level_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
4600 {
4601     proto_tree        *payload_tree;
4602     zbee_zcl_packet   *zcl;
4603     guint             offset = 0;
4604     guint8            cmd_id;
4605     gint              rem_len;
4606 
4607     /* Reject the packet if data is NULL */
4608     if (data == NULL)
4609         return 0;
4610     zcl = (zbee_zcl_packet *)data;
4611     cmd_id = zcl->cmd_id;
4612 
4613     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
4614     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
4615         /* Append the command name to the info column. */
4616         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
4617             val_to_str_const(cmd_id, zbee_zcl_level_control_srv_rx_cmd_names, "Unknown Command"),
4618             zcl->tran_seqno);
4619 
4620         /* Add the command ID. */
4621         proto_tree_add_item(tree, hf_zbee_zcl_level_control_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
4622 
4623         /* Check if this command has a payload, then add the payload tree */
4624         rem_len = tvb_reported_length_remaining(tvb, ++offset);
4625         if (rem_len > 0) {
4626             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_level_control, NULL, "Payload");
4627 
4628             /* Call the appropriate command dissector */
4629             switch (cmd_id) {
4630                 case ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_TO_LEVEL:
4631                 case ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_TO_LEVEL_WITH_ONOFF:
4632                     dissect_zcl_level_control_move_to_level(tvb, payload_tree, &offset);
4633                     break;
4634 
4635                 case ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE:
4636                 case ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_MOVE_WITH_ONOFF:
4637                     dissect_zcl_level_control_move(tvb, payload_tree, &offset);
4638                     break;
4639 
4640                 case ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STEP:
4641                 case ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STEP_WITH_ONOFF:
4642                     dissect_zcl_level_control_step(tvb, payload_tree, &offset);
4643                     break;
4644 
4645                 case ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STOP:
4646                 case ZBEE_ZCL_CMD_ID_LEVEL_CONTROL_STOP_WITH_ONOFF:
4647                     /* No Payload */
4648                 default:
4649                     break;
4650             }
4651         }
4652     }
4653 
4654     return tvb_captured_length(tvb);
4655 } /*dissect_zbee_zcl_level_control*/
4656 
4657 
4658 
4659 static void
dissect_zcl_level_control_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)4660 dissect_zcl_level_control_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
4661 {
4662     /* Dissect attribute data type and data */
4663     switch ( attr_id ) {
4664         case ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_CURRENT_LEVEL:
4665             proto_tree_add_item(tree, hf_zbee_zcl_level_control_attr_current_level, tvb, *offset, 1, ENC_NA);
4666             *offset += 1;
4667             break;
4668 
4669         case ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_REMAINING_TIME:
4670             proto_tree_add_item(tree, hf_zbee_zcl_level_control_attr_remaining_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
4671             *offset += 2;
4672             break;
4673 
4674         case ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_ONOFF_TRANSIT_TIME:
4675             proto_tree_add_item(tree, hf_zbee_zcl_level_control_attr_onoff_transmit_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
4676             *offset += 2;
4677             break;
4678 
4679         case ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_ON_LEVEL:
4680             proto_tree_add_item(tree, hf_zbee_zcl_level_control_attr_on_level, tvb, *offset, 1, ENC_NA);
4681             *offset += 1;
4682             break;
4683 
4684         case ZBEE_ZCL_ATTR_ID_LEVEL_CONTROL_STARTUP_LEVEL:
4685             proto_tree_add_item(tree, hf_zbee_zcl_level_control_attr_startup_level, tvb, *offset, 1, ENC_NA);
4686             *offset += 1;
4687             break;
4688 
4689         default:
4690             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
4691             break;
4692     }
4693 
4694 } /*dissect_zcl_level_control_attr_data*/
4695 
4696 
4697 /*FUNCTION:------------------------------------------------------
4698  *  NAME
4699  *      proto_register_zbee_zcl_level_control
4700  *  DESCRIPTION
4701  *      ZigBee ZCL Level Control cluster protocol registration routine.
4702  *  PARAMETERS
4703  *      none
4704  *  RETURNS
4705  *      void
4706  *---------------------------------------------------------------
4707  */
4708 void
proto_register_zbee_zcl_level_control(void)4709 proto_register_zbee_zcl_level_control(void)
4710 {
4711     /* Setup list of header fields */
4712     static hf_register_info hf[] = {
4713 
4714         { &hf_zbee_zcl_level_control_attr_id,
4715             { "Attribute", "zbee_zcl_general.level_control.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_level_control_attr_names),
4716             0x00, NULL, HFILL } },
4717 
4718         { &hf_zbee_zcl_level_control_attr_current_level,
4719             { "Current Level", "zbee_zcl_general.level_control.attr.current_level", FT_UINT8, BASE_DEC, NULL,
4720             0x00, NULL, HFILL } },
4721 
4722         { &hf_zbee_zcl_level_control_attr_remaining_time,
4723             { "Remaining Time", "zbee_zcl_general.level_control.attr.remaining_time", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_100ms),
4724             0x00, NULL, HFILL } },
4725 
4726         { &hf_zbee_zcl_level_control_attr_onoff_transmit_time,
4727             { "Current Level", "zbee_zcl_general.level_control.attr.onoff_transmit_time", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_100ms),
4728             0x00, NULL, HFILL } },
4729 
4730         { &hf_zbee_zcl_level_control_attr_on_level,
4731             { "On Level", "zbee_zcl_general.level_control.attr.on_level", FT_UINT8, BASE_DEC, NULL,
4732             0x00, NULL, HFILL } },
4733 
4734         { &hf_zbee_zcl_level_control_attr_startup_level,
4735             { "Startup Level", "zbee_zcl_general.level_control.attr.startup_level", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_zcl_level_control_startup_level_names),
4736             0x00, NULL, HFILL } },
4737 
4738         { &hf_zbee_zcl_level_control_level,
4739             { "Level", "zbee_zcl_general.level_control.level", FT_UINT8, BASE_DEC, NULL,
4740             0x00, NULL, HFILL } },
4741 
4742         { &hf_zbee_zcl_level_control_move_mode,
4743             { "Move Mode", "zbee_zcl_general.level_control.move_mode", FT_UINT8, BASE_HEX, VALS(zbee_zcl_level_control_move_step_mode_values),
4744             0x00, NULL, HFILL } },
4745 
4746         { &hf_zbee_zcl_level_control_rate,
4747             { "Rate", "zbee_zcl_general.level_control.rate", FT_UINT8, BASE_DEC, NULL,
4748             0x00, NULL, HFILL } },
4749 
4750         { &hf_zbee_zcl_level_control_step_mode,
4751             { "Step Mode", "zbee_zcl_general.level_control.step_mode", FT_UINT8, BASE_HEX, VALS(zbee_zcl_level_control_move_step_mode_values),
4752             0x00, NULL, HFILL } },
4753 
4754         { &hf_zbee_zcl_level_control_step_size,
4755             { "Step Size", "zbee_zcl_general.level_control.step_size", FT_UINT8, BASE_DEC, NULL,
4756             0x00, NULL, HFILL } },
4757 
4758         { &hf_zbee_zcl_level_control_transit_time,
4759             { "Transition Time", "zbee_zcl_general.level_control.transit_time", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_100ms),
4760             0x00, NULL, HFILL } },
4761 
4762         { &hf_zbee_zcl_level_control_srv_rx_cmd_id,
4763           { "Command", "zbee_zcl_general.level_control.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_level_control_srv_rx_cmd_names),
4764             0x00, NULL, HFILL } }
4765 
4766     };
4767 
4768     /* ZCL Identify subtrees */
4769     static gint *ett[] = {
4770         &ett_zbee_zcl_level_control
4771     };
4772 
4773     /* Register the ZigBee ZCL Level Control cluster protocol name and description */
4774     proto_zbee_zcl_level_control = proto_register_protocol("ZigBee ZCL Level Control", "ZCL Level Control", ZBEE_PROTOABBREV_ZCL_LEVEL_CONTROL);
4775     proto_register_field_array(proto_zbee_zcl_level_control, hf, array_length(hf));
4776     proto_register_subtree_array(ett, array_length(ett));
4777 
4778     /* Register the ZigBee ZCL Level Control dissector. */
4779     register_dissector(ZBEE_PROTOABBREV_ZCL_LEVEL_CONTROL, dissect_zbee_zcl_level_control, proto_zbee_zcl_level_control);
4780 
4781 } /*proto_register_zbee_zcl_level_control*/
4782 
4783 
4784 /*FUNCTION:------------------------------------------------------
4785  *  NAME
4786  *      proto_reg_handoff_zbee_zcl_level_control
4787  *  DESCRIPTION
4788  *      Hands off the ZCL Level Control dissector.
4789  *  PARAMETERS
4790  *      none
4791  *  RETURNS
4792  *      none
4793  *---------------------------------------------------------------
4794  */
4795 void
proto_reg_handoff_zbee_zcl_level_control(void)4796 proto_reg_handoff_zbee_zcl_level_control(void)
4797 {
4798     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_LEVEL_CONTROL,
4799                             proto_zbee_zcl_level_control,
4800                             ett_zbee_zcl_level_control,
4801                             ZBEE_ZCL_CID_LEVEL_CONTROL,
4802                             ZBEE_MFG_CODE_NONE,
4803                             hf_zbee_zcl_level_control_attr_id,
4804                             hf_zbee_zcl_level_control_attr_id,
4805                             hf_zbee_zcl_level_control_srv_rx_cmd_id,
4806                             -1,
4807                             (zbee_zcl_fn_attr_data)dissect_zcl_level_control_attr_data
4808                          );
4809 } /*proto_reg_handoff_zbee_zcl_level_control*/
4810 
4811 
4812 /* ########################################################################## */
4813 /* #### (0x000B) RSSI LOCATION CLUSTER ###################################### */
4814 /* ########################################################################## */
4815 
4816 /*************************/
4817 /* Defines               */
4818 /*************************/
4819 
4820 /* Attributes */
4821 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE                        0x0000  /* Location Type */
4822 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD                      0x0001  /* Location Method */
4823 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_AGE                         0x0002  /* Location Age */
4824 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_QUALITY_MEASURE                      0x0003  /* Quality Measure */
4825 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_NUMBER_OF_DEVICES                    0x0004  /* Number of Devices */
4826 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_1                         0x0010  /* Coordinate 1 */
4827 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_2                         0x0011  /* Coordinate 2 */
4828 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_3                         0x0012  /* Coordinate 3 */
4829 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_POWER                                0x0013  /* Power */
4830 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_PATH_LOSS_EXPONENT                   0x0014  /* Path Loss Exponent */
4831 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_REPORTING_PERIOD                     0x0015  /* Reporting Period */
4832 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_CALCULATION_PERIOD                   0x0016  /* Calculation Period */
4833 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_NUMBER_RSSI_MEAS                     0x0017  /* Number RSSI Measurements */
4834 
4835 /* Location Type Mask Values */
4836 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_ABSOLUTE               0x01    /* Absolute/Measured */
4837 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_2D                     0x02    /* 2D/3D */
4838 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_COORDINATE             0x0C    /* Coordinate System */
4839 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_RESERVED               0xF0    /* Coordinate System */
4840 
4841 /* Location Method Values */
4842 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_LATERATION           0x00    /* Lateration */
4843 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_SIGNPOSTING          0x01    /* Signposting */
4844 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_RF_FINGERPRINTING    0x02    /* RF Fingerprinting */
4845 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_OUT_OF_BAND          0x03    /* Out of Band */
4846 #define ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_CENTRALIZED          0x04    /* Centralized */
4847 
4848 /* Server Commands Received */
4849 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SET_ABSOLUTE_LOCATION                 0x00    /* Set Absolute Location */
4850 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SET_DEVICE_CONFIG                     0x01    /* Set Device Configuration */
4851 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_GET_DEVICE_CONFIG                     0x02    /* Get Device Configuration */
4852 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_GET_LOCATION_DATA                     0x03    /* Get Location Data */
4853 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_RESPONSE                         0x04    /* RSSI Response */
4854 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SEND_PINGS                            0x05    /* Send Pings */
4855 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_ANCHOR_NODE_ANNOUNCE                  0x06    /* Anchor Node Announce */
4856 
4857 
4858 /* Server Commands Generated */
4859 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_DEVICE_CONFIG_RESPONSE                0x00    /* Device Configuration Response */
4860 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_LOCATION_DATA_RESPONSE                0x01    /* Location Data Response */
4861 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_LOCATION_DATA_NOTIF                   0x02    /* Location Data Notification */
4862 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_COMPACT_LOCATION_DATA_NOTIF           0x03    /* Compact Location Data Notification */
4863 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_PING                             0x04    /* RSSI Ping */
4864 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_REQUEST                          0x05    /* RSSI Request */
4865 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_REPORT_RSSI_MEAS                      0x06    /* Report RSSI Measurements */
4866 #define ZBEE_ZCL_CMD_ID_RSSI_LOCATION_REQUEST_OWN_LOCATION                  0x07    /* Request Own Location */
4867 
4868 
4869 /*************************/
4870 /* Function Declarations */
4871 /*************************/
4872 
4873 void proto_register_zbee_zcl_rssi_location(void);
4874 void proto_reg_handoff_zbee_zcl_rssi_location(void);
4875 
4876 /* Command Dissector Helpers */
4877 static void dissect_zcl_rssi_location_set_absolute_location                         (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4878 static void dissect_zcl_rssi_location_set_device_config                             (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4879 static void dissect_zcl_rssi_location_get_device_config                             (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4880 static void dissect_zcl_rssi_location_get_location_data                             (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4881 static void dissect_zcl_rssi_location_rssi_response                                 (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4882 static void dissect_zcl_rssi_location_send_pings                                    (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4883 static void dissect_zcl_rssi_location_anchor_node_announce                          (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4884 
4885 static void dissect_zcl_rssi_location_device_config_response                        (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4886 static void dissect_zcl_rssi_location_location_data_response                        (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4887 static void dissect_zcl_rssi_location_location_data_notif                           (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4888 static void dissect_zcl_rssi_location_compact_location_data_notif                   (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4889 static void dissect_zcl_rssi_location_rssi_ping                                     (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4890 static void dissect_zcl_rssi_location_report_rssi_meas                              (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4891 static void dissect_zcl_rssi_location_request_own_location                          (tvbuff_t *tvb, proto_tree *tree, guint *offset);
4892 
4893 static void dissect_zcl_rssi_location_attr_data                        (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
4894 
4895 /* Private functions prototype */
4896 
4897 /*************************/
4898 /* Global Variables      */
4899 /*************************/
4900 /* Initialize the protocol and registered fields */
4901 static int proto_zbee_zcl_rssi_location = -1;
4902 
4903 static int hf_zbee_zcl_rssi_location_attr_id = -1;
4904 static int hf_zbee_zcl_rssi_location_location_type = -1;
4905 static int hf_zbee_zcl_rssi_location_location_type_absolute = -1;
4906 static int hf_zbee_zcl_rssi_location_location_type_2D = -1;
4907 static int hf_zbee_zcl_rssi_location_location_type_coordinate_system = -1;
4908 static int hf_zbee_zcl_rssi_location_location_type_reserved = -1;
4909 static int hf_zbee_zcl_rssi_location_attr_id_location_method = -1;
4910 static int hf_zbee_zcl_rssi_location_coordinate1 = -1;
4911 static int hf_zbee_zcl_rssi_location_coordinate2 = -1;
4912 static int hf_zbee_zcl_rssi_location_coordinate3 = -1;
4913 static int hf_zbee_zcl_rssi_location_power = -1;
4914 static int hf_zbee_zcl_rssi_location_path_loss_expo = -1;
4915 static int hf_zbee_zcl_rssi_location_calc_period = -1;
4916 static int hf_zbee_zcl_rssi_location_number_rssi_meas = -1;
4917 static int hf_zbee_zcl_rssi_location_reporting_period = -1;
4918 static int hf_zbee_zcl_rssi_location_target_add = -1;
4919 static int hf_zbee_zcl_rssi_location_header = -1;
4920 static int hf_zbee_zcl_rssi_location_header_abs_only = -1;
4921 static int hf_zbee_zcl_rssi_location_header_recalc = -1;
4922 static int hf_zbee_zcl_rssi_location_header_bcast_ind = -1;
4923 static int hf_zbee_zcl_rssi_location_header_bcast_res = -1;
4924 static int hf_zbee_zcl_rssi_location_header_compact_res = -1;
4925 static int hf_zbee_zcl_rssi_location_header_res = -1;
4926 static int hf_zbee_zcl_rssi_location_number_responses = -1;
4927 static int hf_zbee_zcl_rssi_location_replaying_device = -1;
4928 static int hf_zbee_zcl_rssi_location_rssi = -1;
4929 static int hf_zbee_zcl_rssi_location_anchor_node_add = -1;
4930 static int hf_zbee_zcl_rssi_location_status = -1;
4931 static int hf_zbee_zcl_rssi_location_quality_measure = -1;
4932 static int hf_zbee_zcl_rssi_location_location_age = -1;
4933 static int hf_zbee_zcl_rssi_location_reporting_add = -1;
4934 static int hf_zbee_zcl_rssi_location_no_of_neigh = -1;
4935 static int hf_zbee_zcl_rssi_location_neighbour_add = -1;
4936 static int hf_zbee_zcl_rssi_location_request_add = -1;
4937 static int hf_zbee_zcl_rssi_location_srv_rx_cmd_id = -1;
4938 static int hf_zbee_zcl_rssi_location_srv_tx_cmd_id = -1;
4939 
4940 /* Initialize the subtree pointers */
4941 static gint ett_zbee_zcl_rssi_location = -1;
4942 static gint ett_zbee_zcl_rssi_location_location_type = -1;
4943 static gint ett_zbee_zcl_rssi_location_header = -1;
4944 
4945 /* Attributes */
4946 static const value_string zbee_zcl_rssi_location_attr_names[] = {
4947     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE,                     "Location Type" },
4948     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD,                   "Location Method" },
4949     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_AGE,                      "Location Age" },
4950     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_QUALITY_MEASURE,                   "Quality Measure" },
4951     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_NUMBER_OF_DEVICES,                 "Number of Devices" },
4952     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_1,                      "Coordinate 1" },
4953     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_2,                      "Coordinate 2" },
4954     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_3,                      "Coordinate 3" },
4955     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_POWER,                             "Power" },
4956     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_PATH_LOSS_EXPONENT,                "Path Loss Exponent" },
4957     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_REPORTING_PERIOD,                  "Reporting Period" },
4958     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_CALCULATION_PERIOD,                "Calculation Period" },
4959     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_NUMBER_RSSI_MEAS,                  "Number RSSI Measurements" },
4960     { 0, NULL }
4961 };
4962 
4963 /* Server Commands Received */
4964 static const value_string zbee_zcl_rssi_location_srv_rx_cmd_names[] = {
4965     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SET_ABSOLUTE_LOCATION,              "Set Absolute Location" },
4966     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SET_DEVICE_CONFIG,                  "Set Device Configuration" },
4967     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_GET_DEVICE_CONFIG,                  "Get Device Configuration" },
4968     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_GET_LOCATION_DATA,                  "Get Location Data" },
4969     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_RESPONSE,                      "RSSI Response" },
4970     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SEND_PINGS,                         "Send Pings" },
4971     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_ANCHOR_NODE_ANNOUNCE,               "Anchor Node Announce" },
4972     { 0, NULL }
4973 };
4974 
4975 /* Server Commands Generated */
4976 static const value_string zbee_zcl_rssi_location_srv_tx_cmd_names[] = {
4977     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_DEVICE_CONFIG_RESPONSE,             "Device Configuration Response" },
4978     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_LOCATION_DATA_RESPONSE,             "Location Data Response" },
4979     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_LOCATION_DATA_NOTIF,                "Location Data Notification" },
4980     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_COMPACT_LOCATION_DATA_NOTIF,        "Compact Location Data Notification" },
4981     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_PING,                          "RSSI Ping" },
4982     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_REQUEST,                       "RSSI Request" },
4983     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_REPORT_RSSI_MEAS,                   "Report RSSI Measurements" },
4984     { ZBEE_ZCL_CMD_ID_RSSI_LOCATION_REQUEST_OWN_LOCATION,               "Request Own Location" },
4985     { 0, NULL }
4986 };
4987 
4988 /* Location Method Values */
4989 static const value_string zbee_zcl_rssi_location_location_method_values[] = {
4990     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_LATERATION,        "Lateration" },
4991     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_SIGNPOSTING,       "Signposting" },
4992     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_RF_FINGERPRINTING, "RF Fingerprinting" },
4993     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_OUT_OF_BAND,       "Out of Band" },
4994     { ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD_CENTRALIZED,       "Centralized" },
4995     { 0, NULL }
4996 };
4997 
4998 /* Location type absolute values*/
4999 static const value_string zbee_zcl_rssi_location_location_type_abs_values[] = {
5000     {0, "Measured Location"},
5001     {1, "Absolute Location"},
5002     {0, NULL}
5003 };
5004 
5005 /* Location type 2D/3D values*/
5006 static const value_string zbee_zcl_rssi_location_location_type_2D_values[] = {
5007     {0, "Three Dimensional"},
5008     {1, "Two Dimensional"},
5009     {0, NULL}
5010 };
5011 
5012 /* Location type Coordinate System values*/
5013 static const value_string zbee_zcl_rssi_location_location_type_coordinate_values[] = {
5014     {0, "Rectangular"},
5015     {1, "Reserved"},
5016     {2, "Reserved"},
5017     {3, "Reserved"},
5018     {0, NULL}
5019 };
5020 
5021 /*************************/
5022 /* Function Bodies       */
5023 /*************************/
5024 
5025 /*FUNCTION:------------------------------------------------------
5026  *  NAME
5027  *      dissect_zbee_zcl_rssi_location
5028  *  DESCRIPTION
5029  *      ZigBee ZCL RSSI Location cluster dissector for wireshark.
5030  *  PARAMETERS
5031  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
5032  *      packet_info *pinfo  - pointer to packet information fields
5033  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
5034  *  RETURNS
5035  *      none
5036  *---------------------------------------------------------------
5037  */
5038 static int
dissect_zbee_zcl_rssi_location(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)5039 dissect_zbee_zcl_rssi_location(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
5040 {
5041     proto_tree        *payload_tree;
5042     zbee_zcl_packet   *zcl;
5043     guint             offset = 0;
5044     guint8            cmd_id;
5045     gint              rem_len;
5046 
5047     /* Reject the packet if data is NULL */
5048     if (data == NULL)
5049         return 0;
5050     zcl = (zbee_zcl_packet *)data;
5051     cmd_id = zcl->cmd_id;
5052 
5053     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
5054     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
5055         /* Append the command name to the info column. */
5056         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
5057             val_to_str_const(cmd_id, zbee_zcl_rssi_location_srv_rx_cmd_names, "Unknown Command"),
5058             zcl->tran_seqno);
5059 
5060         /* Add the command ID. */
5061         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5062 
5063         /* Check if this command has a payload, then add the payload tree */
5064         rem_len = tvb_reported_length_remaining(tvb, ++offset);
5065         if (rem_len > 0) {
5066             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_rssi_location, NULL, "Payload");
5067 
5068             /* Call the appropriate command dissector */
5069             switch (cmd_id) {
5070                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SET_ABSOLUTE_LOCATION:
5071                     dissect_zcl_rssi_location_set_absolute_location(tvb, payload_tree, &offset);
5072                     break;
5073 
5074                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SET_DEVICE_CONFIG:
5075                     dissect_zcl_rssi_location_set_device_config(tvb, payload_tree, &offset);
5076                     break;
5077 
5078                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_GET_DEVICE_CONFIG:
5079                     dissect_zcl_rssi_location_get_device_config(tvb, payload_tree, &offset);
5080                     break;
5081 
5082                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_GET_LOCATION_DATA:
5083                     dissect_zcl_rssi_location_get_location_data(tvb, payload_tree, &offset);
5084                     break;
5085 
5086                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_RESPONSE:
5087                     dissect_zcl_rssi_location_rssi_response(tvb, payload_tree, &offset);
5088                     break;
5089 
5090                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_SEND_PINGS:
5091                     dissect_zcl_rssi_location_send_pings(tvb, payload_tree, &offset);
5092                     break;
5093 
5094                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_ANCHOR_NODE_ANNOUNCE:
5095                     dissect_zcl_rssi_location_anchor_node_announce(tvb, payload_tree, &offset);
5096                     break;
5097 
5098                 default:
5099                     break;
5100             }
5101         }
5102     }
5103     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
5104         /* Append the command name to the info column. */
5105         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
5106             val_to_str_const(cmd_id, zbee_zcl_rssi_location_srv_tx_cmd_names, "Unknown Command"),
5107             zcl->tran_seqno);
5108 
5109         /* Add the command ID. */
5110         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
5111 
5112         /* Check if this command has a payload, then add the payload tree */
5113         rem_len = tvb_reported_length_remaining(tvb, ++offset);
5114         if (rem_len > 0) {
5115             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_rssi_location, NULL, "Payload");
5116 
5117             /* Call the appropriate command dissector */
5118             switch (cmd_id) {
5119                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_DEVICE_CONFIG_RESPONSE:
5120                     dissect_zcl_rssi_location_device_config_response(tvb, payload_tree, &offset);
5121                     break;
5122                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_LOCATION_DATA_RESPONSE:
5123                     dissect_zcl_rssi_location_location_data_response(tvb, payload_tree, &offset);
5124                     break;
5125 
5126                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_LOCATION_DATA_NOTIF:
5127                     dissect_zcl_rssi_location_location_data_notif(tvb, payload_tree, &offset);
5128                     break;
5129 
5130                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_COMPACT_LOCATION_DATA_NOTIF:
5131                     dissect_zcl_rssi_location_compact_location_data_notif(tvb, payload_tree, &offset);
5132                     break;
5133 
5134                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_PING:
5135                     dissect_zcl_rssi_location_rssi_ping(tvb, payload_tree, &offset);
5136                     break;
5137 
5138                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_RSSI_REQUEST:
5139                     /* No Payload */
5140                     break;
5141 
5142                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_REPORT_RSSI_MEAS:
5143                     dissect_zcl_rssi_location_report_rssi_meas(tvb, payload_tree, &offset);
5144                     break;
5145 
5146                 case ZBEE_ZCL_CMD_ID_RSSI_LOCATION_REQUEST_OWN_LOCATION:
5147                     dissect_zcl_rssi_location_request_own_location(tvb, payload_tree, &offset);
5148                     break;
5149 
5150                 default:
5151                     break;
5152             }
5153         }
5154     }
5155 
5156     return tvb_captured_length(tvb);
5157 } /*dissect_zbee_zcl_rssi_location*/
5158 
5159 
5160  /*FUNCTION:------------------------------------------------------
5161  *  NAME
5162  *      dissect_zcl_rssi_location_set_absolute_location
5163  *  DESCRIPTION
5164  *      this function decodes the Set Absolute Location payload.
5165  *  PARAMETERS
5166  *      tvb     - the tv buffer of the current data_type
5167  *      tree    - the tree to append this item to
5168  *      offset  - offset of data in tvb
5169  *  RETURNS
5170  *      none
5171  *---------------------------------------------------------------
5172  */
5173 static void
dissect_zcl_rssi_location_set_absolute_location(tvbuff_t * tvb,proto_tree * tree,guint * offset)5174 dissect_zcl_rssi_location_set_absolute_location(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5175 {
5176     /* Retrieve "Coordinate 1" field */
5177     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate1, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5178     *offset += 2;
5179 
5180     /* Retrieve "Coordinate 2" field */
5181     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5182     *offset += 2;
5183 
5184     /* Retrieve "Coordinate 3" field */
5185     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate3, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5186     *offset += 2;
5187 
5188     /* Retrieve "Power" field */
5189     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_power, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5190     *offset += 2;
5191 
5192     /* Retrieve "Path Loss Exponent" field */
5193     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_path_loss_expo, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5194     *offset += 2;
5195 
5196 } /*dissect_zcl_rssi_location_set_absolute_location*/
5197 
5198 
5199  /*FUNCTION:--------------------------------------------------------------------
5200  *  NAME
5201  *      dissect_zcl_rssi_location_set_device_config
5202  *  DESCRIPTION
5203  *      this function decodes the Set Device Configuration payload.
5204  *  PARAMETERS
5205  *      tvb     - the tv buffer of the current data_type
5206  *      tree    - the tree to append this item to
5207  *      offset  - offset of data in tvb
5208  *  RETURNS
5209  *      none
5210  *------------------------------------------------------------------------------
5211  */
5212 static void
dissect_zcl_rssi_location_set_device_config(tvbuff_t * tvb,proto_tree * tree,guint * offset)5213 dissect_zcl_rssi_location_set_device_config(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5214 {
5215     /* Retrieve "Power" field */
5216     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_power, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5217     *offset += 2;
5218 
5219     /* Retrieve "Path Loss Exponent" field */
5220     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_path_loss_expo, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5221     *offset += 2;
5222 
5223     /* Retrieve "Calculation Period" field */
5224     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_calc_period, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5225     *offset += 2;
5226 
5227     /* Retrieve "Number RSSI Measurements" field */
5228     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_number_rssi_meas, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5229     *offset += 1;
5230 
5231     /* Retrieve "Reporting Period" field */
5232     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_reporting_period, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5233     *offset += 2;
5234 
5235 } /*dissect_zcl_rssi_location_set_device_config*/
5236 
5237 
5238 /*FUNCTION:-------------------------------------------------------------------
5239 *  NAME
5240 *      dissect_zcl_rssi_location_get_device_config
5241 *  DESCRIPTION
5242 *      this function decodes the Get Device Configuration payload.
5243 *  PARAMETERS
5244 *      tvb     - the tv buffer of the current data_type
5245 *      tree    - the tree to append this item to
5246 *      offset  - offset of data in tvb
5247 *  RETURNS
5248 *      none
5249 *-----------------------------------------------------------------------------
5250 */
5251 static void
dissect_zcl_rssi_location_get_device_config(tvbuff_t * tvb,proto_tree * tree,guint * offset)5252 dissect_zcl_rssi_location_get_device_config(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5253 {
5254     /* Retrieve "Target Address" field */
5255     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_target_add, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
5256     *offset += 8;
5257 
5258 } /*dissect_zcl_rssi_location_get_device_config*/
5259 
5260 
5261 /*FUNCTION:-------------------------------------------------------------------
5262 *  NAME
5263 *      dissect_zcl_rssi_location_get_location_data
5264 *  DESCRIPTION
5265 *      this function decodes the Get Location Data payload.
5266 *  PARAMETERS
5267 *      tvb     - the tv buffer of the current data_type
5268 *      tree    - the tree to append this item to
5269 *      offset  - offset of data in tvb
5270 *  RETURNS
5271 *      none
5272 *-----------------------------------------------------------------------------
5273 */
5274 static void
dissect_zcl_rssi_location_get_location_data(tvbuff_t * tvb,proto_tree * tree,guint * offset)5275 dissect_zcl_rssi_location_get_location_data(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5276 {
5277      guint8 header;
5278 
5279     static int * const location_header_fields[] = {
5280         &hf_zbee_zcl_rssi_location_header_abs_only,
5281         &hf_zbee_zcl_rssi_location_header_recalc,
5282         &hf_zbee_zcl_rssi_location_header_bcast_ind,
5283         &hf_zbee_zcl_rssi_location_header_bcast_res,
5284         &hf_zbee_zcl_rssi_location_header_compact_res,
5285         &hf_zbee_zcl_rssi_location_header_res,
5286         NULL
5287     };
5288 
5289     /* Retrieve "8-bit header" field */
5290     header = tvb_get_guint8(tvb, *offset);
5291     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_rssi_location_header, ett_zbee_zcl_rssi_location_header, location_header_fields, ENC_LITTLE_ENDIAN);
5292     *offset += 1;
5293 
5294     /* Retrieve the number responses field */
5295     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_number_responses, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5296     *offset += 1;
5297 
5298     /* Retrieve the IEEE address field */
5299     if(header & 0x04)
5300     {
5301         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_target_add, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
5302         *offset += 8;
5303     }
5304 
5305 } /*dissect_zcl_rssi_location_get_location_data*/
5306 
5307 
5308 /*FUNCTION:--------------------------------------------------------------------
5309 *  NAME
5310 *      dissect_zcl_rssi_location_rssi_response
5311 *  DESCRIPTION
5312 *      this function decodes the RSSI Response payload.
5313 *  PARAMETERS
5314 *      tvb     - the tv buffer of the current data_type
5315 *      tree    - the tree to append this item to
5316 *      offset  - offset of data in tvb
5317 *  RETURNS
5318 *      none
5319 *------------------------------------------------------------------------------
5320 */
5321 static void
dissect_zcl_rssi_location_rssi_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)5322 dissect_zcl_rssi_location_rssi_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5323 {
5324    /* Retrieve "Replaying Device" field */
5325    proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_replaying_device, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
5326    *offset += 8;
5327 
5328    /* Retrieve "Coordinate 1" field */
5329    proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate1, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5330    *offset += 2;
5331 
5332    /* Retrieve "Coordinate 2" field */
5333    proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5334    *offset += 2;
5335 
5336    /* Retrieve "Coordinate 3" field */
5337    proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate3, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5338    *offset += 2;
5339 
5340    /* Retrieve "RSSI" field */
5341    proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_rssi, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5342    *offset += 1;
5343 
5344    /* Retrieve "Number RSSI Measurements" field */
5345    proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_number_rssi_meas, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5346    *offset += 1;
5347 
5348 } /*dissect_zcl_rssi_location_rssi_response*/
5349 
5350 
5351 /*FUNCTION:------------------------------------------------------
5352 *  NAME
5353 *      dissect_zcl_rssi_location_send_pings
5354 *  DESCRIPTION
5355 *      this function decodes the Send Pings payload.
5356 *  PARAMETERS
5357 *      tvb     - the tv buffer of the current data_type
5358 *      tree    - the tree to append this item to
5359 *      offset  - offset of data in tvb
5360 *  RETURNS
5361 *      none
5362 *---------------------------------------------------------------
5363 */
5364 static void
dissect_zcl_rssi_location_send_pings(tvbuff_t * tvb,proto_tree * tree,guint * offset)5365 dissect_zcl_rssi_location_send_pings(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5366 {
5367     /* Retrieve "Target Address" field */
5368     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_target_add, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
5369     *offset += 8;
5370 
5371     /* Retrieve "Number RSSI Measurements" field */
5372     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_number_rssi_meas, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5373     *offset += 1;
5374 
5375     /* Retrieve "Calculation Period" field */
5376     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_calc_period, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5377     *offset += 2;
5378 
5379 } /*dissect_zcl_rssi_location_send_pings*/
5380 
5381 
5382 /*FUNCTION:------------------------------------------------------
5383 *  NAME
5384 *      dissect_zcl_rssi_location_anchor_node_announce
5385 *  DESCRIPTION
5386 *      this function decodes the Anchor Node Announce payload
5387 *  PARAMETERS
5388 *      tvb     - the tv buffer of the current data_type
5389 *      tree    - the tree to append this item to
5390 *      offset  - offset of data in tvb
5391 *  RETURNS
5392 *      none
5393 *---------------------------------------------------------------
5394 */
5395 static void
dissect_zcl_rssi_location_anchor_node_announce(tvbuff_t * tvb,proto_tree * tree,guint * offset)5396 dissect_zcl_rssi_location_anchor_node_announce(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5397 {
5398     /* Retrieve "Anchor Node Address" field */
5399     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_anchor_node_add, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
5400     *offset += 8;
5401 
5402     /* Retrieve "Coordinate 1" field */
5403     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate1, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5404     *offset += 2;
5405 
5406     /* Retrieve "Coordinate 2" field */
5407     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5408     *offset += 2;
5409 
5410     /* Retrieve "Coordinate 3" field */
5411     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate3, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5412     *offset += 2;
5413 
5414 } /*dissect_zcl_rssi_location_anchor_node_announce*/
5415 
5416 
5417 /*FUNCTION:--------------------------------------------------------------------
5418 *  NAME
5419 *      dissect_zcl_rssi_location_device_config_response
5420 *  DESCRIPTION
5421 *      this function decodes the Device Configuration Response payload.
5422 *  PARAMETERS
5423 *      tvb     - the tv buffer of the current data_type
5424 *      tree    - the tree to append this item to
5425 *      offset  - offset of data in tvb
5426 *  RETURNS
5427 *      none
5428 *------------------------------------------------------------------------------
5429 */
5430 static void
dissect_zcl_rssi_location_device_config_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)5431 dissect_zcl_rssi_location_device_config_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5432 {
5433    guint8 status;
5434 
5435    /* Retrieve "Status" field */
5436    status = tvb_get_guint8(tvb, *offset);
5437    proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5438    *offset += 1;
5439 
5440    if(status == ZBEE_ZCL_STAT_SUCCESS)
5441    {
5442        /* Retrieve "Power" field */
5443        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_power, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5444        *offset += 2;
5445 
5446        /* Retrieve "Path Loss Exponent" field */
5447        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_path_loss_expo, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5448        *offset += 2;
5449 
5450        /* Retrieve "Calculation Period" field */
5451        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_calc_period, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5452        *offset += 2;
5453 
5454        /* Retrieve "Number RSSI Measurements" field */
5455        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_number_rssi_meas, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5456        *offset += 1;
5457 
5458        /* Retrieve "Reporting Period" field */
5459        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_reporting_period, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5460        *offset += 2;
5461    }
5462 
5463 } /*dissect_zcl_rssi_location_device_config_response*/
5464 
5465 
5466 /*FUNCTION:------------------------------------------------------
5467 *  NAME
5468 *      dissect_zcl_rssi_location_location_data_response
5469 *  DESCRIPTION
5470 *      this function decodes the Location Data Response payload.
5471 *  PARAMETERS
5472 *      tvb     - the tv buffer of the current data_type
5473 *      tree    - the tree to append this item to
5474 *      offset  - offset of data in tvb
5475 *  RETURNS
5476 *      none
5477 *---------------------------------------------------------------
5478 */
5479 static void
dissect_zcl_rssi_location_location_data_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)5480 dissect_zcl_rssi_location_location_data_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5481 {
5482    guint8 status;
5483 
5484    /* Retrieve "Status" field */
5485    status = tvb_get_guint8(tvb, *offset);
5486    proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5487    *offset += 1;
5488 
5489    if(status == ZBEE_ZCL_STAT_SUCCESS)
5490    {
5491        /* Retrieve "Location Type" field */
5492        dissect_zcl_rssi_location_attr_data(tree, tvb, offset, ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE, ZBEE_ZCL_8_BIT_DATA, FALSE);
5493 
5494        /* Retrieve "Coordinate 1" field */
5495        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate1, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5496        *offset += 2;
5497 
5498        /* Retrieve "Coordinate 2" field */
5499        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5500        *offset += 2;
5501 
5502        /* Retrieve "Coordinate 3" field */
5503        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate3, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5504        *offset += 2;
5505 
5506        /* Retrieve "Power" field */
5507        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_power, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5508        *offset += 2;
5509 
5510        /* Retrieve "Path Loss Exponent" field */
5511        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_path_loss_expo, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5512        *offset += 2;
5513 
5514        /* Retrieve "Location Method" field */
5515        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_attr_id_location_method, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5516        *offset += 1;
5517 
5518        /* Retrieve "Quality Measure" field */
5519        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_quality_measure, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5520        *offset += 1;
5521 
5522        /* Retrieve "Location Age" field */
5523        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_location_age, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5524        *offset += 2;
5525    }
5526 
5527 } /*dissect_zcl_rssi_location_location_data_response*/
5528 
5529 
5530 /*FUNCTION:------------------------------------------------------
5531 *  NAME
5532 *      dissect_zcl_rssi_location_location_data_notif
5533 *  DESCRIPTION
5534 *      this function decodes the Location Data Notification payload.
5535 *  PARAMETERS
5536 *      tvb     - the tv buffer of the current data_type
5537 *      tree    - the tree to append this item to
5538 *      offset  - offset of data in tvb
5539 *  RETURNS
5540 *      none
5541 *---------------------------------------------------------------
5542 */
5543 static void
dissect_zcl_rssi_location_location_data_notif(tvbuff_t * tvb,proto_tree * tree,guint * offset)5544 dissect_zcl_rssi_location_location_data_notif(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5545 {
5546     guint8 temp;
5547 
5548     /* Retrieve "Location Type" field */
5549     temp = tvb_get_guint8(tvb, *offset);
5550     dissect_zcl_rssi_location_attr_data(tree, tvb, offset, ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE, ZBEE_ZCL_8_BIT_DATA, FALSE);
5551 
5552     /* Retrieve "Coordinate 1" field */
5553     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate1, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5554     *offset += 2;
5555 
5556     /* Retrieve "Coordinate 2" field */
5557     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5558     *offset += 2;
5559 
5560    if((temp & ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_2D) != 0x02)
5561    {
5562        /* Retrieve "Coordinate 3" field */
5563        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate3, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5564        *offset += 2;
5565    }
5566 
5567        /* Retrieve "Power" field */
5568        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_power, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5569        *offset += 2;
5570 
5571        /* Retrieve "Path Loss Exponent" field */
5572        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_path_loss_expo, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5573        *offset += 2;
5574 
5575    if((temp & ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_COORDINATE) != 0x0C)
5576    {
5577        /* Retrieve "Location Method" field */
5578        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_attr_id_location_method, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5579        *offset += 1;
5580 
5581        /* Retrieve "Quality Measure" field */
5582        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_quality_measure, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5583        *offset += 1;
5584 
5585        /* Retrieve "Location Age" field */
5586        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_location_age, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5587        *offset += 2;
5588 
5589    }
5590 
5591 } /*dissect_zcl_rssi_location_location_data_notif*/
5592 
5593 
5594 /*FUNCTION:------------------------------------------------------
5595 *  NAME
5596 *      dissect_zcl_rssi_location_compact_location_data_notif
5597 *  DESCRIPTION
5598 *      this function decodes the Location Data Notification payload.
5599 *  PARAMETERS
5600 *      tvb     - the tv buffer of the current data_type
5601 *      tree    - the tree to append this item to
5602 *      offset  - offset of data in tvb
5603 *  RETURNS
5604 *      none
5605 *---------------------------------------------------------------
5606 */
5607 static void
dissect_zcl_rssi_location_compact_location_data_notif(tvbuff_t * tvb,proto_tree * tree,guint * offset)5608 dissect_zcl_rssi_location_compact_location_data_notif(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5609 {
5610     guint8 temp;
5611 
5612     /* Retrieve "Location Type" field */
5613     temp = tvb_get_guint8(tvb, *offset);
5614     dissect_zcl_rssi_location_attr_data(tree, tvb, offset, ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE, ZBEE_ZCL_8_BIT_DATA, FALSE);
5615 
5616     /* Retrieve "Coordinate 1" field */
5617     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate1, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5618     *offset += 2;
5619 
5620     /* Retrieve "Coordinate 2" field */
5621     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5622     *offset += 2;
5623 
5624    if((temp & ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_2D) != 0x02)
5625    {
5626        /* Retrieve "Coordinate 3" field */
5627        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate3, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5628        *offset += 2;
5629    }
5630 
5631    if((temp & ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_COORDINATE) != 0x0C)
5632    {
5633        /* Retrieve "Quality Measure" field */
5634        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_quality_measure, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5635        *offset += 1;
5636 
5637        /* Retrieve "Location Age" field */
5638        proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_location_age, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5639        *offset += 2;
5640 
5641    }
5642 
5643 } /*dissect_zcl_rssi_location_compact_location_data_notif*/
5644 
5645 /*FUNCTION:------------------------------------------------------
5646 *  NAME
5647 *      dissect_zcl_rssi_location_rssi_ping
5648 *  DESCRIPTION
5649 *      this function decodes the RSSI Ping payload.
5650 *  PARAMETERS
5651 *      tvb     - the tv buffer of the current data_type
5652 *      tree    - the tree to append this item to
5653 *      offset  - offset of data in tvb
5654 *  RETURNS
5655 *      none
5656 *---------------------------------------------------------------
5657 */
5658 static void
dissect_zcl_rssi_location_rssi_ping(tvbuff_t * tvb,proto_tree * tree,guint * offset)5659 dissect_zcl_rssi_location_rssi_ping(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5660 {
5661    /* Retrieve "Location Type" field */
5662     dissect_zcl_rssi_location_attr_data(tree, tvb, offset, ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE, ZBEE_ZCL_8_BIT_DATA, FALSE);
5663 
5664 
5665 } /*dissect_zcl_rssi_location_rssi_ping*/
5666 
5667 
5668 /*FUNCTION:------------------------------------------------------
5669 *  NAME
5670 *      dissect_zcl_rssi_location_report_rssi_meas
5671 *  DESCRIPTION
5672 *      this function decodes the Report RSSI Measurements payload
5673 *  PARAMETERS
5674 *      tvb     - the tv buffer of the current data_type
5675 *      tree    - the tree to append this item to
5676 *      offset  - offset of data in tvb
5677 *  RETURNS
5678 *      none
5679 *---------------------------------------------------------------
5680 */
5681 static void
dissect_zcl_rssi_location_report_rssi_meas(tvbuff_t * tvb,proto_tree * tree,guint * offset)5682 dissect_zcl_rssi_location_report_rssi_meas(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5683 {
5684     guint8 count, i;
5685     /* Retrieve "Reporting Address" field */
5686     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_reporting_add, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
5687     *offset += 8;
5688 
5689     /* Retrieve "Number of Neighbours" field */
5690     count = tvb_get_guint8(tvb, *offset);
5691     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_no_of_neigh, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5692     *offset += 1;
5693 
5694     for( i = 0; i < count; i++)
5695     {
5696         /* Retrieve "Neighbour Address" field */
5697         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_neighbour_add, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
5698         *offset += 8;
5699 
5700         /* Retrieve "Coordinate 1" field */
5701         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate1, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5702         *offset += 2;
5703 
5704         /* Retrieve "Coordinate 2" field */
5705         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate2, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5706         *offset += 2;
5707 
5708         /* Retrieve "Coordinate 3" field */
5709         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_coordinate3, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
5710         *offset += 2;
5711 
5712         /* Retrieve "RSSI" field */
5713         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_rssi, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5714         *offset += 1;
5715 
5716         /* Retrieve "Number RSSI Measurements" field */
5717         proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_number_rssi_meas, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5718         *offset += 1;
5719     }
5720 
5721 } /*dissect_zcl_rssi_location_report_rssi_meas*/
5722 
5723 
5724 /*FUNCTION:-------------------------------------------------------------------
5725 *  NAME
5726 *      dissect_zcl_rssi_location_request_own_location
5727 *  DESCRIPTION
5728 *      this function decodes the Request Own Location payload.
5729 *  PARAMETERS
5730 *      tvb     - the tv buffer of the current data_type
5731 *      tree    - the tree to append this item to
5732 *      offset  - offset of data in tvb
5733 *  RETURNS
5734 *      none
5735 *-----------------------------------------------------------------------------
5736 */
5737 static void
dissect_zcl_rssi_location_request_own_location(tvbuff_t * tvb,proto_tree * tree,guint * offset)5738 dissect_zcl_rssi_location_request_own_location(tvbuff_t *tvb, proto_tree *tree, guint *offset)
5739 {
5740     /* Retrieve "Requesting Address Address" field */
5741     proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_request_add, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
5742     *offset += 8;
5743 
5744 } /*dissect_zcl_rssi_location_request_own_location*/
5745 
5746 
5747 /*FUNCTION:------------------------------------------------------
5748  *  NAME
5749  *      dissect_zcl_rssi_location_attr_data
5750  *  DESCRIPTION
5751  *      this function is called by ZCL foundation dissector in order to decode
5752  *      specific cluster attributes data.
5753  *  PARAMETERS
5754  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
5755  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
5756  *      guint *offset       - pointer to buffer offset
5757  *      guint16 attr_id     - attribute identifier
5758  *      guint data_type     - attribute data type
5759  *      gboolean client_attr- ZCL client
5760  *  RETURNS
5761  *      none
5762  *---------------------------------------------------------------
5763  */
5764 void
dissect_zcl_rssi_location_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)5765 dissect_zcl_rssi_location_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
5766 {
5767     static int * const location_type[] = {
5768         &hf_zbee_zcl_rssi_location_location_type_absolute,
5769         &hf_zbee_zcl_rssi_location_location_type_2D,
5770         &hf_zbee_zcl_rssi_location_location_type_coordinate_system,
5771         &hf_zbee_zcl_rssi_location_location_type_reserved,
5772         NULL
5773     };
5774 
5775     /* Dissect attribute data type and data */
5776     switch ( attr_id ) {
5777 
5778         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE:
5779             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_rssi_location_location_type, ett_zbee_zcl_rssi_location_location_type, location_type, ENC_LITTLE_ENDIAN);
5780             *offset += 1;
5781             break;
5782 
5783         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_METHOD:
5784             proto_tree_add_item(tree, hf_zbee_zcl_rssi_location_attr_id_location_method, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
5785             *offset += 1;
5786             break;
5787 
5788         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_AGE:
5789         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_QUALITY_MEASURE:
5790         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_NUMBER_OF_DEVICES:
5791         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_1:
5792         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_2:
5793         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_COORDINATE_3:
5794         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_POWER:
5795         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_PATH_LOSS_EXPONENT:
5796         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_REPORTING_PERIOD:
5797         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_CALCULATION_PERIOD:
5798         case ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_NUMBER_RSSI_MEAS:
5799         default:
5800             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
5801             break;
5802     }
5803 
5804 } /*dissect_zcl_rssi_location_attr_data*/
5805 
5806 
5807 /*FUNCTION:------------------------------------------------------
5808  *  NAME
5809  *      proto_register_zbee_zcl_rssi_location
5810  *  DESCRIPTION
5811  *      ZigBee ZCL RSSI Location cluster protocol registration routine.
5812  *  PARAMETERS
5813  *      none
5814  *  RETURNS
5815  *      void
5816  *---------------------------------------------------------------
5817  */
5818 void
proto_register_zbee_zcl_rssi_location(void)5819 proto_register_zbee_zcl_rssi_location(void)
5820 {
5821     /* Setup list of header fields */
5822     static hf_register_info hf[] = {
5823 
5824         { &hf_zbee_zcl_rssi_location_attr_id,
5825             { "Attribute", "zbee_zcl_general.rssi_location.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_rssi_location_attr_names),
5826             0x00, NULL, HFILL } },
5827 
5828         /* start Location Type fields */
5829         { &hf_zbee_zcl_rssi_location_location_type,
5830             { "Location Type", "zbee_zcl_general.rssi_location.attr_id.location_type", FT_UINT8, BASE_HEX, NULL,
5831             0x00, NULL, HFILL } },
5832 
5833         { &hf_zbee_zcl_rssi_location_location_type_absolute,
5834             { "Location Type Absolute/Measured", "zbee_zcl_general.rssi_location.attr_id.location_type.abs", FT_UINT8, BASE_HEX, VALS(zbee_zcl_rssi_location_location_type_abs_values),
5835             ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_ABSOLUTE, NULL, HFILL } },
5836 
5837         { &hf_zbee_zcl_rssi_location_location_type_2D,
5838             { "Location Type 2D/3D", "zbee_zcl_general.rssi_location.attr_id.location_type.2D", FT_UINT8, BASE_HEX, VALS(zbee_zcl_rssi_location_location_type_2D_values),
5839             ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_2D, NULL, HFILL } },
5840 
5841         { &hf_zbee_zcl_rssi_location_location_type_coordinate_system,
5842             { "Location Type Coordinate System", "zbee_zcl_general.rssi_location.attr_id.location_type.coordinate", FT_UINT8, BASE_HEX, VALS(zbee_zcl_rssi_location_location_type_coordinate_values),
5843             ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_COORDINATE, NULL, HFILL } },
5844 
5845         { &hf_zbee_zcl_rssi_location_location_type_reserved,
5846             { "Reserved", "zbee_zcl_general.rssi_location.attr_id.location_type.reserved", FT_BOOLEAN, 8, NULL,
5847             ZBEE_ZCL_ATTR_ID_RSSI_LOCATION_LOCATION_TYPE_RESERVED, NULL, HFILL } },
5848         /* end Location Type fields */
5849 
5850         { &hf_zbee_zcl_rssi_location_attr_id_location_method,
5851             { "Location Method", "zbee_zcl_general.rssi_location.attr_id.location_method", FT_UINT8, BASE_HEX, VALS(zbee_zcl_rssi_location_location_method_values),
5852             0x00, NULL, HFILL } },
5853 
5854         { &hf_zbee_zcl_rssi_location_coordinate1,
5855             { "Coordinate 1", "zbee_zcl_general.rssi_location.coordinate1", FT_UINT16, BASE_HEX, NULL,
5856             0x00, NULL, HFILL } },
5857 
5858         { &hf_zbee_zcl_rssi_location_coordinate2,
5859             { "Coordinate 2", "zbee_zcl_general.rssi_location.coordinate2", FT_UINT16, BASE_HEX, NULL,
5860             0x00, NULL, HFILL } },
5861 
5862         { &hf_zbee_zcl_rssi_location_coordinate3,
5863             { "Coordinate 3", "zbee_zcl_general.rssi_location.coordinate3", FT_UINT16, BASE_HEX, NULL,
5864             0x00, NULL, HFILL } },
5865 
5866         { &hf_zbee_zcl_rssi_location_power,
5867             { "Power", "zbee_zcl_general.rssi_location.power", FT_UINT16, BASE_HEX, NULL,
5868             0x00, NULL, HFILL } },
5869 
5870         { &hf_zbee_zcl_rssi_location_path_loss_expo,
5871             { "Path Loss Exponent", "zbee_zcl_general.rssi_location.path_loss_exponent", FT_UINT16, BASE_HEX, NULL,
5872             0x00, NULL, HFILL } },
5873 
5874         { &hf_zbee_zcl_rssi_location_calc_period,
5875             { "Calculation Period", "zbee_zcl_general.rssi_location.calc_period", FT_UINT16, BASE_HEX, NULL,
5876             0x00, NULL, HFILL } },
5877 
5878         { &hf_zbee_zcl_rssi_location_number_rssi_meas,
5879             { "Number RSSI Measurements", "zbee_zcl_general.rssi_location.number_rssi_meas", FT_UINT8, BASE_HEX, NULL,
5880             0x00, NULL, HFILL } },
5881 
5882         { &hf_zbee_zcl_rssi_location_reporting_period,
5883             { "Reporting Period", "zbee_zcl_general.rssi_location.reporting_period", FT_UINT16, BASE_HEX, NULL,
5884             0x00, NULL, HFILL } },
5885 
5886         { &hf_zbee_zcl_rssi_location_target_add,
5887             { "Target Address", "zbee_zcl_general.rssi_location.target_add", FT_UINT64, BASE_HEX, NULL,
5888             0x00, NULL, HFILL } },
5889 
5890         { &hf_zbee_zcl_rssi_location_header,
5891             { "Header Data", "zbee_zcl_general.rssi_location.location_header", FT_UINT8, BASE_HEX, NULL,
5892             0x00, NULL, HFILL } },
5893 
5894         { &hf_zbee_zcl_rssi_location_header_abs_only,
5895             { "Absolute Only", "zbee_zcl_general.rssi_location.header.abs_only", FT_BOOLEAN, 8, NULL,
5896             0x01, NULL, HFILL } },
5897 
5898         { &hf_zbee_zcl_rssi_location_header_recalc,
5899             { "Recalculate", "zbee_zcl_general.rssi_location.header.recalc", FT_BOOLEAN, 8, NULL,
5900             0x02, NULL, HFILL } },
5901 
5902         { &hf_zbee_zcl_rssi_location_header_bcast_ind,
5903             { "Broadcast Indicator", "zbee_zcl_general.rssi_location.header.bcast_ind", FT_BOOLEAN, 8, NULL,
5904             0x04, NULL, HFILL } },
5905 
5906         { &hf_zbee_zcl_rssi_location_header_bcast_res,
5907             { "Broadcast Response", "zbee_zcl_general.rssi_location.header.bcast_response", FT_BOOLEAN, 8, NULL,
5908             0x08, NULL, HFILL } },
5909 
5910         { &hf_zbee_zcl_rssi_location_header_compact_res,
5911             { "Compact Response", "zbee_zcl_general.rssi_location.compact_res", FT_BOOLEAN, 8, NULL,
5912             0x10, NULL, HFILL } },
5913 
5914         { &hf_zbee_zcl_rssi_location_header_res,
5915             { "Reserved", "zbee_zcl_general.rssi_location.reserved", FT_BOOLEAN, 8, NULL,
5916             0xE0, NULL, HFILL } },
5917 
5918         { &hf_zbee_zcl_rssi_location_number_responses,
5919             { "Number Responses", "zbee_zcl_general.rssi_location.number_responses", FT_UINT8, BASE_HEX, NULL,
5920             0x00, NULL, HFILL } },
5921 
5922         { &hf_zbee_zcl_rssi_location_replaying_device,
5923             { "Replying Device", "zbee_zcl_general.rssi_location.replying_device", FT_UINT64, BASE_HEX, NULL,
5924             0x00, NULL, HFILL } },
5925 
5926         { &hf_zbee_zcl_rssi_location_rssi,
5927             { "RSSI", "zbee_zcl_general.rssi_location.rssi", FT_UINT8, BASE_DEC, NULL,
5928             0x00, NULL, HFILL } },
5929 
5930         { &hf_zbee_zcl_rssi_location_anchor_node_add,
5931             { "Anchor Node Address", "zbee_zcl_general.rssi_location.anchor_node_add", FT_UINT64, BASE_HEX, NULL,
5932             0x00, NULL, HFILL } },
5933 
5934         { &hf_zbee_zcl_rssi_location_status,
5935             { "Status", "zbee_zcl_general.rssi_location.status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_status_names),
5936             0x00, NULL, HFILL } },
5937 
5938         { &hf_zbee_zcl_rssi_location_quality_measure,
5939             { "Quality Measure", "zbee_zcl_general.rssi_location.quality_measure", FT_UINT8, BASE_HEX, NULL,
5940             0x00, NULL, HFILL } },
5941 
5942         { &hf_zbee_zcl_rssi_location_location_age,
5943             { "Location Age", "zbee_zcl_general.rssi_location.location_age", FT_UINT16, BASE_HEX, NULL,
5944             0x00, NULL, HFILL } },
5945 
5946         { &hf_zbee_zcl_rssi_location_reporting_add,
5947             { "Reporting Address", "zbee_zcl_general.rssi_location.reporting_add", FT_UINT64, BASE_HEX, NULL,
5948             0x00, NULL, HFILL } },
5949 
5950         { &hf_zbee_zcl_rssi_location_no_of_neigh,
5951             { "Number of Neighbours", "zbee_zcl_general.rssi_location.no_of_neigh", FT_UINT8, BASE_DEC, NULL,
5952             0x00, NULL, HFILL } },
5953 
5954         { &hf_zbee_zcl_rssi_location_neighbour_add,
5955             { "Neighbour Address", "zbee_zcl_general.rssi_location.neighbour_add", FT_UINT64, BASE_HEX, NULL,
5956             0x00, NULL, HFILL } },
5957 
5958         { &hf_zbee_zcl_rssi_location_request_add,
5959             { "Requesting Address", "zbee_zcl_general.rssi_location.request_add", FT_UINT64, BASE_HEX, NULL,
5960             0x00, NULL, HFILL } },
5961 
5962         { &hf_zbee_zcl_rssi_location_srv_rx_cmd_id,
5963           { "Command", "zbee_zcl_general.rssi_location.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_rssi_location_srv_rx_cmd_names),
5964             0x00, NULL, HFILL } },
5965 
5966         { &hf_zbee_zcl_rssi_location_srv_tx_cmd_id,
5967           { "Command", "zbee_zcl_general.rssi_location.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_rssi_location_srv_tx_cmd_names),
5968             0x00, NULL, HFILL } }
5969 
5970     };
5971 
5972     /* ZCL RSSI Location subtrees */
5973     static gint *ett[] = {
5974         &ett_zbee_zcl_rssi_location,
5975         &ett_zbee_zcl_rssi_location_location_type,
5976         &ett_zbee_zcl_rssi_location_header
5977     };
5978 
5979     /* Register the ZigBee ZCL RSSI Location cluster protocol name and description */
5980     proto_zbee_zcl_rssi_location = proto_register_protocol("ZigBee ZCL RSSI Location", "ZCL RSSI Location", ZBEE_PROTOABBREV_ZCL_RSSI_LOCATION);
5981     proto_register_field_array(proto_zbee_zcl_rssi_location, hf, array_length(hf));
5982     proto_register_subtree_array(ett, array_length(ett));
5983 
5984     /* Register the ZigBee ZCL RSSI Location dissector. */
5985     register_dissector(ZBEE_PROTOABBREV_ZCL_RSSI_LOCATION, dissect_zbee_zcl_rssi_location, proto_zbee_zcl_rssi_location);
5986 
5987 } /*proto_register_zbee_zcl_rssi_location*/
5988 
5989 
5990 /*FUNCTION:------------------------------------------------------
5991  *  NAME
5992  *      proto_reg_handoff_zbee_zcl_rssi_location
5993  *  DESCRIPTION
5994  *      Hands off the ZCL RSSI Location dissector.
5995  *  PARAMETERS
5996  *      none
5997  *  RETURNS
5998  *      none
5999  *---------------------------------------------------------------
6000  */
6001 void
proto_reg_handoff_zbee_zcl_rssi_location(void)6002 proto_reg_handoff_zbee_zcl_rssi_location(void)
6003 {
6004     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_RSSI_LOCATION,
6005                             proto_zbee_zcl_rssi_location,
6006                             ett_zbee_zcl_rssi_location,
6007                             ZBEE_ZCL_CID_RSSI_LOCATION,
6008                             ZBEE_MFG_CODE_NONE,
6009                             hf_zbee_zcl_rssi_location_attr_id,
6010                             hf_zbee_zcl_rssi_location_attr_id,
6011                             hf_zbee_zcl_rssi_location_srv_rx_cmd_id,
6012                             hf_zbee_zcl_rssi_location_srv_tx_cmd_id,
6013                             (zbee_zcl_fn_attr_data)dissect_zcl_rssi_location_attr_data
6014                          );
6015 } /*proto_reg_handoff_zbee_zcl_rssi_location*/
6016 
6017 /****************************************************************************************************/
6018 /****************************************************************************************************/
6019 /****************************************************************************************************/
6020 
6021 
6022 /* Reliability Enumeration Values */
6023 #define ZBEE_ZCL_RELIABILITY_NO_FAULT_DETECTED              0x00    /* No Fault Detected */
6024 #define ZBEE_ZCL_RELIABILITY_NO_SENSOR                      0x01    /* No Sensor */
6025 #define ZBEE_ZCL_RELIABILITY_OVER_RANGE                     0x02    /* Over Range */
6026 #define ZBEE_ZCL_RELIABILITY_UNDER_RANGE                    0x03    /* Under Range */
6027 #define ZBEE_ZCL_RELIABILITY_OPEN_LOOP                      0x04    /* Open Loop */
6028 #define ZBEE_ZCL_RELIABILITY_SHORTED_LOOP                   0x05    /* Shorted Loop */
6029 #define ZBEE_ZCL_RELIABILITY_NO_OUTPUT                      0x06    /* No Output */
6030 #define ZBEE_ZCL_RELIABILITY_UNRELIABLE_OTHER               0x07    /* Unreliable Other */
6031 #define ZBEE_ZCL_RELIABILITY_PROCESS_ERROR                  0x08    /* Process Error */
6032 #define ZBEE_ZCL_RELIABILITY_MULTI_STATE_FAULT              0x09    /* Multi-State Fault */
6033 #define ZBEE_ZCL_RELIABILITY_CONFIGURATION_ERROR            0x0A    /* Configuration Error */
6034 
6035 static const value_string zbee_zcl_reliability_names[] = {
6036     {ZBEE_ZCL_RELIABILITY_NO_FAULT_DETECTED,    "No Fault Detected"},
6037     {ZBEE_ZCL_RELIABILITY_NO_SENSOR,            "No Sensor"},
6038     {ZBEE_ZCL_RELIABILITY_OVER_RANGE,           "Over Range"},
6039     {ZBEE_ZCL_RELIABILITY_UNDER_RANGE,          "Under Range"},
6040     {ZBEE_ZCL_RELIABILITY_OPEN_LOOP,            "Open Loop"},
6041     {ZBEE_ZCL_RELIABILITY_SHORTED_LOOP,         "Shorted Loop"},
6042     {ZBEE_ZCL_RELIABILITY_NO_OUTPUT,            "No Output"},
6043     {ZBEE_ZCL_RELIABILITY_UNRELIABLE_OTHER,     "Unreliable Other"},
6044     {ZBEE_ZCL_RELIABILITY_PROCESS_ERROR,        "Process Error"},
6045     {ZBEE_ZCL_RELIABILITY_MULTI_STATE_FAULT,    "Multi-State Fault"},
6046     {ZBEE_ZCL_RELIABILITY_CONFIGURATION_ERROR,  "Configuration Error"},
6047     {0, NULL}
6048 };
6049 
6050 /* Status Flags Mask Values */
6051 #define ZBEE_ZCL_STATUS_IN_ALARM                0x01      /* In Alarm Flag */
6052 #define ZBEE_ZCL_STATUS_FAULT                   0x02      /* Fault Flag */
6053 #define ZBEE_ZCL_STATUS_OVERRIDDEN              0x04      /* Overridden Flag */
6054 #define ZBEE_ZCL_STATUS_OUT_OF_SERVICE          0x08      /* Out of Service Flag */
6055 
6056 static const value_string zbee_zcl_status_values[] = {
6057     {0, "False"},
6058     {1, "True"},
6059     {0, NULL}
6060 };
6061 
6062 /* ########################################################################## */
6063 /* #### (0x000C) ANALOG INPUT (BASIC) CLUSTER ############################### */
6064 /* ########################################################################## */
6065 
6066 /*************************/
6067 /* Defines               */
6068 /*************************/
6069 
6070 /*Attributes*/
6071 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_DESCRIPTION                     0x001C  /* Description */
6072 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_MAX_PRESENT_VALUE               0x0041  /* Max Present Value */
6073 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_MIN_PRESENT_VALUE               0x0045  /* Min Present Value */
6074 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
6075 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
6076 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_RELIABILITY                     0x0067  /* Reliability */
6077 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_RESOLUTION                      0x006A  /* Resolution */
6078 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
6079 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_ENGINEERING_UNITS               0x0075  /* Engineering Units */
6080 #define ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
6081 
6082 /*Server commands received - none*/
6083 
6084 /*Server commands generated - none*/
6085 
6086 /*************************/
6087 /* Function Declarations */
6088 /*************************/
6089 
6090 void proto_register_zbee_zcl_analog_input_basic(void);
6091 void proto_reg_handoff_zbee_zcl_analog_input_basic(void);
6092 
6093 /* Command Dissector Helpers */
6094 static void dissect_zcl_analog_input_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
6095 
6096 /* Private functions prototype */
6097 
6098 /*************************/
6099 /* Global Variables      */
6100 /*************************/
6101 /* Initialize the protocol and registered fields */
6102 static int proto_zbee_zcl_analog_input_basic = -1;
6103 
6104 static int hf_zbee_zcl_analog_input_basic_attr_id = -1;
6105 static int hf_zbee_zcl_analog_input_basic_reliability = -1;
6106 static int hf_zbee_zcl_analog_input_basic_status_flags = -1;
6107 static int hf_zbee_zcl_analog_input_basic_status_in_alarm = -1;
6108 static int hf_zbee_zcl_analog_input_basic_status_fault = -1;
6109 static int hf_zbee_zcl_analog_input_basic_status_overridden = -1;
6110 static int hf_zbee_zcl_analog_input_basic_status_out_of_service = -1;
6111 
6112 /* Initialize the subtree pointers */
6113 static gint ett_zbee_zcl_analog_input_basic = -1;
6114 static gint ett_zbee_zcl_analog_input_basic_status_flags = -1;
6115 
6116 /* Attributes */
6117 static const value_string zbee_zcl_analog_input_basic_attr_names[] = {
6118     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_DESCRIPTION,          "Description" },
6119     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_MAX_PRESENT_VALUE,    "Max Present Value" },
6120     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_MIN_PRESENT_VALUE,    "Min Present Value" },
6121     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_OUT_OF_SERVICE,       "Out of Service" },
6122     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_PRESENT_VALUE,        "Present Value" },
6123     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_RELIABILITY,          "Reliability" },
6124     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_RESOLUTION,           "Resolution" },
6125     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_STATUS_FLAGS,         "Status Flags" },
6126     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_ENGINEERING_UNITS,    "Engineering Units" },
6127     { ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_APPLICATION_TYPE,     "Application Type" },
6128     { 0, NULL }
6129 };
6130 
6131 /*************************/
6132 /* Function Bodies       */
6133 /*************************/
6134 
6135 /*FUNCTION:------------------------------------------------------
6136  *  NAME
6137  *      dissect_zbee_zcl_analog_input_basic
6138  *  DESCRIPTION
6139  *      ZigBee ZCL Analog Input Basic cluster dissector for wireshark.
6140  *  PARAMETERS
6141  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
6142  *      packet_info *pinfo  - pointer to packet information fields
6143  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
6144  *  RETURNS
6145  *      int                 - length of parsed data.
6146  *---------------------------------------------------------------
6147  */
6148 
6149 static int
dissect_zbee_zcl_analog_input_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)6150 dissect_zbee_zcl_analog_input_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
6151 {
6152 	return tvb_captured_length(tvb);
6153 } /*dissect_zbee_zcl_analog_input_basic*/
6154 
6155 
6156 /*FUNCTION:------------------------------------------------------
6157  *  NAME
6158  *      dissect_zcl_analog_input_basic_attr_data
6159  *  DESCRIPTION
6160  *      this function is called by ZCL foundation dissector in order to decode
6161  *      specific cluster attributes data.
6162  *  PARAMETERS
6163  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
6164  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
6165  *      guint *offset       - pointer to buffer offset
6166  *      guint16 attr_id     - attribute identifier
6167  *      guint data_type     - attribute data type
6168  *      gboolean client_attr- ZCL client
6169  *  RETURNS
6170  *      none
6171  *---------------------------------------------------------------
6172  */
6173 void
dissect_zcl_analog_input_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)6174 dissect_zcl_analog_input_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
6175 {
6176     static int * const status_flags[] = {
6177         &hf_zbee_zcl_analog_input_basic_status_in_alarm,
6178         &hf_zbee_zcl_analog_input_basic_status_fault,
6179         &hf_zbee_zcl_analog_input_basic_status_overridden,
6180         &hf_zbee_zcl_analog_input_basic_status_out_of_service,
6181         NULL
6182     };
6183 
6184     /* Dissect attribute data type and data */
6185     switch (attr_id) {
6186 
6187         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_RELIABILITY:
6188             proto_tree_add_item(tree, hf_zbee_zcl_analog_input_basic_reliability, tvb, *offset, 1, ENC_NA);
6189             *offset += 1;
6190             break;
6191 
6192         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_STATUS_FLAGS:
6193             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_analog_input_basic_status_flags, ett_zbee_zcl_analog_input_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
6194             *offset += 1;
6195             break;
6196 
6197         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_DESCRIPTION:
6198         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_MAX_PRESENT_VALUE:
6199         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_MIN_PRESENT_VALUE:
6200         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_OUT_OF_SERVICE:
6201         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_PRESENT_VALUE:
6202         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_RESOLUTION:
6203         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_ENGINEERING_UNITS:
6204         case ZBEE_ZCL_ATTR_ID_ANALOG_INPUT_BASIC_APPLICATION_TYPE:
6205         default:
6206             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
6207             break;
6208     }
6209 
6210 } /*dissect_zcl_analog_input_basic_attr_data*/
6211 
6212 
6213 /*FUNCTION:------------------------------------------------------
6214  *  NAME
6215  *      proto_register_zbee_zcl_analog_input_basic
6216  *  DESCRIPTION
6217  *      ZigBee ZCL Analog Input Basic cluster protocol registration routine.
6218  *  PARAMETERS
6219  *      none
6220  *  RETURNS
6221  *      none
6222  *---------------------------------------------------------------
6223  */
6224 void
proto_register_zbee_zcl_analog_input_basic(void)6225 proto_register_zbee_zcl_analog_input_basic(void)
6226 {
6227     /* Setup list of header fields */
6228     static hf_register_info hf[] = {
6229 
6230         { &hf_zbee_zcl_analog_input_basic_attr_id,
6231             { "Attribute", "zbee_zcl_general.analog_input_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_analog_input_basic_attr_names),
6232             0x00, NULL, HFILL } },
6233 
6234         { &hf_zbee_zcl_analog_input_basic_reliability,
6235             { "Reliability", "zbee_zcl_general.analog_input_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
6236             0x00, NULL, HFILL } },
6237 
6238         /* start Status Flags fields */
6239         { &hf_zbee_zcl_analog_input_basic_status_flags,
6240             { "Status Flags", "zbee_zcl_general.analog_input_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
6241             0x00, NULL, HFILL } },
6242 
6243         { &hf_zbee_zcl_analog_input_basic_status_in_alarm,
6244             { "In Alarm Status", "zbee_zcl_general.analog_input_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6245             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
6246 
6247         { &hf_zbee_zcl_analog_input_basic_status_fault,
6248             { "Fault Status", "zbee_zcl_general.analog_input_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6249             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
6250 
6251         { &hf_zbee_zcl_analog_input_basic_status_overridden,
6252             { "Overridden Status", "zbee_zcl_general.analog_input_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6253             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
6254 
6255         { &hf_zbee_zcl_analog_input_basic_status_out_of_service,
6256             { "Out of Service Status", "zbee_zcl_general.analog_input_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6257             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } }
6258         /* end Status Flags fields */
6259     };
6260 
6261     /* ZCL Analog Input Basic subtrees */
6262     static gint *ett[] = {
6263         &ett_zbee_zcl_analog_input_basic,
6264         &ett_zbee_zcl_analog_input_basic_status_flags
6265     };
6266 
6267 
6268 
6269     /* Register the ZigBee ZCL Analog Input Basic cluster protocol name and description */
6270     proto_zbee_zcl_analog_input_basic = proto_register_protocol("ZigBee ZCL Analog Input Basic", "ZCL Analog Input Basic", ZBEE_PROTOABBREV_ZCL_ANALOG_INPUT_BASIC);
6271     proto_register_field_array(proto_zbee_zcl_analog_input_basic, hf, array_length(hf));
6272     proto_register_subtree_array(ett, array_length(ett));
6273 
6274     /* Register the ZigBee ZCL Analog Input Basic dissector. */
6275     register_dissector(ZBEE_PROTOABBREV_ZCL_ANALOG_INPUT_BASIC, dissect_zbee_zcl_analog_input_basic, proto_zbee_zcl_analog_input_basic);
6276 } /*proto_register_zbee_zcl_analog_input_basic*/
6277 
6278 /*FUNCTION:------------------------------------------------------
6279  *  NAME
6280  *      proto_reg_handoff_zbee_zcl_analog_input_basic
6281  *  DESCRIPTION
6282  *      Hands off the ZCL Analog Input Basic dissector.
6283  *  PARAMETERS
6284  *      none
6285  *  RETURNS
6286  *      none
6287  *---------------------------------------------------------------
6288  */
6289 void
proto_reg_handoff_zbee_zcl_analog_input_basic(void)6290 proto_reg_handoff_zbee_zcl_analog_input_basic(void)
6291 {
6292     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_ANALOG_INPUT_BASIC,
6293                             proto_zbee_zcl_analog_input_basic,
6294                             ett_zbee_zcl_analog_input_basic,
6295                             ZBEE_ZCL_CID_ANALOG_INPUT_BASIC,
6296                             ZBEE_MFG_CODE_NONE,
6297                             hf_zbee_zcl_analog_input_basic_attr_id,
6298                             hf_zbee_zcl_analog_input_basic_attr_id,
6299                             -1, -1,
6300                             (zbee_zcl_fn_attr_data)dissect_zcl_analog_input_basic_attr_data
6301                          );
6302 } /*proto_reg_handoff_zbee_zcl_analog_input_basic*/
6303 
6304 
6305 /* ########################################################################## */
6306 /* #### (0x000D) ANALOG OUTPUT (BASIC) CLUSTER ############################## */
6307 /* ########################################################################## */
6308 
6309 /*************************/
6310 /* Defines               */
6311 /*************************/
6312 
6313 /*Attributes*/
6314 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_DESCRIPTION                     0x001C  /* Description */
6315 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_MAX_PRESENT_VALUE               0x0041  /* Max Present Value */
6316 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_MIN_PRESENT_VALUE               0x0045  /* Min Present Value */
6317 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
6318 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
6319 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_PRIORITY_ARRAY                  0x0057  /* Priority Array */
6320 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RELIABILITY                     0x0067  /* Reliability */
6321 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RELINQUISH_DEFAULT              0x0068  /* Relinquish Default */
6322 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RESOLUTION                      0x006A  /* Resolution */
6323 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
6324 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_ENGINEERING_UNITS               0x0075  /* Engineering Units */
6325 #define ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
6326 
6327 /*Server commands received - none*/
6328 
6329 /*Server commands generated - none*/
6330 
6331 /*************************/
6332 /* Function Declarations */
6333 /*************************/
6334 
6335 void proto_register_zbee_zcl_analog_output_basic(void);
6336 void proto_reg_handoff_zbee_zcl_analog_output_basic(void);
6337 
6338 /* Command Dissector Helpers */
6339 static void dissect_zcl_analog_output_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
6340 
6341 /* Private functions prototype */
6342 
6343 /*************************/
6344 /* Global Variables      */
6345 /*************************/
6346 /* Initialize the protocol and registered fields */
6347 static int proto_zbee_zcl_analog_output_basic = -1;
6348 
6349 static int hf_zbee_zcl_analog_output_basic_attr_id = -1;
6350 static int hf_zbee_zcl_analog_output_basic_reliability = -1;
6351 static int hf_zbee_zcl_analog_output_basic_status_flags = -1;
6352 static int hf_zbee_zcl_analog_output_basic_status_in_alarm = -1;
6353 static int hf_zbee_zcl_analog_output_basic_status_fault = -1;
6354 static int hf_zbee_zcl_analog_output_basic_status_overridden = -1;
6355 static int hf_zbee_zcl_analog_output_basic_status_out_of_service = -1;
6356 static int hf_zbee_zcl_analog_output_basic_priority_array_bool = -1;
6357 static int hf_zbee_zcl_analog_output_basic_priority_array_sing_prec = -1;
6358 static int hf_zbee_zcl_analog_output_basic_priority_array = -1;
6359 static int hf_zbee_zcl_analog_output_basic_structure = -1;
6360 
6361 /* Initialize the subtree pointers */
6362 static gint ett_zbee_zcl_analog_output_basic = -1;
6363 static gint ett_zbee_zcl_analog_output_basic_status_flags = -1;
6364 static gint ett_zbee_zcl_analog_output_basic_priority_array = -1;
6365 static gint ett_zbee_zcl_analog_output_basic_priority_array_structure = -1;
6366 
6367 /* Attributes */
6368 static const value_string zbee_zcl_analog_output_basic_attr_names[] = {
6369     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_DESCRIPTION,          "Description" },
6370     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_MAX_PRESENT_VALUE,    "Max Present Value" },
6371     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_MIN_PRESENT_VALUE,    "Min Present Value" },
6372     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_OUT_OF_SERVICE,       "Out of Service" },
6373     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_PRESENT_VALUE,        "Present Value" },
6374     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_PRIORITY_ARRAY,       "Priority Array" },
6375     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RELIABILITY,          "Reliability" },
6376     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RELINQUISH_DEFAULT,   "Relinquish Default" },
6377     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RESOLUTION,           "Resolution" },
6378     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_STATUS_FLAGS,         "Status Flags" },
6379     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_ENGINEERING_UNITS,    "Engineering Units" },
6380     { ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_APPLICATION_TYPE,     "Application Type" },
6381     { 0, NULL }
6382 };
6383 
6384 /*************************/
6385 /* Function Bodies       */
6386 /*************************/
6387 
6388 /*FUNCTION:------------------------------------------------------
6389  *  NAME
6390  *      dissect_zbee_zcl_analog_output_basic
6391  *  DESCRIPTION
6392  *      ZigBee ZCL Analog Output Basic cluster dissector for wireshark.
6393  *  PARAMETERS
6394  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
6395  *      packet_info *pinfo  - pointer to packet information fields
6396  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
6397  *  RETURNS
6398  *      int                 - length of parsed data.
6399  *---------------------------------------------------------------
6400  */
6401 
6402 static int
dissect_zbee_zcl_analog_output_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)6403 dissect_zbee_zcl_analog_output_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
6404 {
6405 	return tvb_captured_length(tvb);
6406 } /*dissect_zbee_zcl_analog_output_basic*/
6407 
6408 
6409 /*FUNCTION:------------------------------------------------------
6410  *  NAME
6411  *      dissect_zcl_analog_output_basic_attr_data
6412  *  DESCRIPTION
6413  *      this function is called by ZCL foundation dissector in order to decode
6414  *      specific cluster attributes data.
6415  *  PARAMETERS
6416  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
6417  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
6418  *      guint *offset       - pointer to buffer offset
6419  *      guint16 attr_id     - attribute identifier
6420  *      guint data_type     - attribute data type
6421  *      gboolean client_attr- ZCL client
6422  *  RETURNS
6423  *      none
6424  *---------------------------------------------------------------
6425  */
6426 void
dissect_zcl_analog_output_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)6427 dissect_zcl_analog_output_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
6428 {
6429     proto_item  *ti = NULL, *tj = NULL;
6430     proto_tree  *sub_tree = NULL, *sub = NULL;
6431     int i;
6432 
6433     static int * const status_flags[] = {
6434         &hf_zbee_zcl_analog_output_basic_status_in_alarm,
6435         &hf_zbee_zcl_analog_output_basic_status_fault,
6436         &hf_zbee_zcl_analog_output_basic_status_overridden,
6437         &hf_zbee_zcl_analog_output_basic_status_out_of_service,
6438         NULL
6439     };
6440 
6441     /* Dissect attribute data type and data */
6442     switch (attr_id) {
6443 
6444         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_PRIORITY_ARRAY:
6445             ti = proto_tree_add_item(tree,hf_zbee_zcl_analog_output_basic_priority_array, tvb, *offset, 80, ENC_NA);
6446             sub_tree = proto_item_add_subtree(ti, ett_zbee_zcl_analog_output_basic_priority_array);
6447 
6448             for(i = 1; i <= 16; i++)
6449             {
6450                 tj = proto_tree_add_item(sub_tree, hf_zbee_zcl_analog_output_basic_structure, tvb, *offset, 5, ENC_NA);
6451                 proto_item_append_text(tj," %d",i);
6452                 sub = proto_item_add_subtree(tj, ett_zbee_zcl_analog_output_basic_priority_array_structure);
6453                 proto_tree_add_item(sub, hf_zbee_zcl_analog_output_basic_priority_array_bool, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
6454                 *offset += 1;
6455                 proto_tree_add_item(sub, hf_zbee_zcl_analog_output_basic_priority_array_sing_prec, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6456                 *offset += 4;
6457             }
6458             break;
6459 
6460         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RELIABILITY:
6461             proto_tree_add_item(tree, hf_zbee_zcl_analog_output_basic_reliability, tvb, *offset, 1, ENC_NA);
6462             *offset += 1;
6463             break;
6464 
6465         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_STATUS_FLAGS:
6466             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_analog_output_basic_status_flags, ett_zbee_zcl_analog_output_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
6467             *offset += 1;
6468             break;
6469 
6470         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_DESCRIPTION:
6471         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_MAX_PRESENT_VALUE:
6472         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_MIN_PRESENT_VALUE:
6473         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_OUT_OF_SERVICE:
6474         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_PRESENT_VALUE:
6475         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RELINQUISH_DEFAULT:
6476         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_RESOLUTION:
6477         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_ENGINEERING_UNITS:
6478         case ZBEE_ZCL_ATTR_ID_ANALOG_OUTPUT_BASIC_APPLICATION_TYPE:
6479         default:
6480             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
6481             break;
6482     }
6483 
6484 } /*dissect_zcl_analog_output_basic_attr_data*/
6485 
6486 
6487 /*FUNCTION:------------------------------------------------------
6488  *  NAME
6489  *      proto_register_zbee_zcl_analog_output_basic
6490  *  DESCRIPTION
6491  *      ZigBee ZCL Analog Output Basic cluster protocol registration routine.
6492  *  PARAMETERS
6493  *      none
6494  *  RETURNS
6495  *      none
6496  *---------------------------------------------------------------
6497  */
6498 void
proto_register_zbee_zcl_analog_output_basic(void)6499 proto_register_zbee_zcl_analog_output_basic(void)
6500 {
6501     /* Setup list of header fields */
6502     static hf_register_info hf[] = {
6503 
6504         { &hf_zbee_zcl_analog_output_basic_attr_id,
6505             { "Attribute", "zbee_zcl_general.analog_output_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_analog_output_basic_attr_names),
6506             0x00, NULL, HFILL } },
6507 
6508         { &hf_zbee_zcl_analog_output_basic_reliability,
6509             { "Reliability", "zbee_zcl_general.analog_output_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
6510             0x00, NULL, HFILL } },
6511 
6512         /* start Status Flags fields */
6513         { &hf_zbee_zcl_analog_output_basic_status_flags,
6514             { "Status Flags", "zbee_zcl_general.analog_output_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
6515             0x00, NULL, HFILL } },
6516 
6517         { &hf_zbee_zcl_analog_output_basic_status_in_alarm,
6518             { "In Alarm Status", "zbee_zcl_general.analog_output_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6519             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
6520 
6521         { &hf_zbee_zcl_analog_output_basic_status_fault,
6522             { "Fault Status", "zbee_zcl_general.analog_output_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6523             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
6524 
6525         { &hf_zbee_zcl_analog_output_basic_status_overridden,
6526             { "Overridden Status", "zbee_zcl_general.analog_output_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6527             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
6528 
6529         { &hf_zbee_zcl_analog_output_basic_status_out_of_service,
6530             { "Out of Service Status", "zbee_zcl_general.analog_output_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6531             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } },
6532         /* end Status Flags fields */
6533 
6534         { &hf_zbee_zcl_analog_output_basic_priority_array_bool,
6535             { "Valid/Invalid", "zbee_zcl_general.analog_output_basic.attr.priority_array.bool", FT_BOOLEAN, 8, TFS(&tfs_invalid_valid),
6536             0x00, NULL, HFILL } },
6537 
6538         { &hf_zbee_zcl_analog_output_basic_priority_array_sing_prec,
6539             { "Priority Value", "zbee_zcl_general.analog_output_basic.attr.priority_array.sing_prec", FT_UINT16, BASE_HEX, NULL,
6540             0x00, NULL, HFILL } },
6541 
6542         { &hf_zbee_zcl_analog_output_basic_priority_array,
6543             { "Priority Array", "zbee_zcl_general.analog_output_basic.priority_array", FT_NONE, BASE_NONE, NULL,
6544             0x00, NULL, HFILL } },
6545 
6546         { &hf_zbee_zcl_analog_output_basic_structure,
6547             { "Structure", "zbee_zcl_general.analog_output_basic.structure", FT_NONE, BASE_NONE, NULL,
6548             0x00, NULL, HFILL } }
6549     };
6550 
6551     /* ZCL Analog Output Basic subtrees */
6552     static gint *ett[] = {
6553         &ett_zbee_zcl_analog_output_basic,
6554         &ett_zbee_zcl_analog_output_basic_status_flags,
6555         &ett_zbee_zcl_analog_output_basic_priority_array,
6556         &ett_zbee_zcl_analog_output_basic_priority_array_structure
6557     };
6558 
6559 
6560 
6561     /* Register the ZigBee ZCL Analog Output Basic cluster protocol name and description */
6562     proto_zbee_zcl_analog_output_basic = proto_register_protocol("ZigBee ZCL Analog Output Basic", "ZCL Analog Output Basic", ZBEE_PROTOABBREV_ZCL_ANALOG_OUTPUT_BASIC);
6563     proto_register_field_array(proto_zbee_zcl_analog_output_basic, hf, array_length(hf));
6564     proto_register_subtree_array(ett, array_length(ett));
6565 
6566     /* Register the ZigBee ZCL Analog Output Basic dissector. */
6567     register_dissector(ZBEE_PROTOABBREV_ZCL_ANALOG_OUTPUT_BASIC, dissect_zbee_zcl_analog_output_basic, proto_zbee_zcl_analog_output_basic);
6568 } /*proto_register_zbee_zcl_analog_output_basic*/
6569 
6570 /*FUNCTION:------------------------------------------------------
6571  *  NAME
6572  *      proto_reg_handoff_zbee_zcl_analog_output_basic
6573  *  DESCRIPTION
6574  *      Hands off the ZCL Analog Output Basic dissector.
6575  *  PARAMETERS
6576  *      none
6577  *  RETURNS
6578  *      none
6579  *---------------------------------------------------------------
6580  */
6581 void
proto_reg_handoff_zbee_zcl_analog_output_basic(void)6582 proto_reg_handoff_zbee_zcl_analog_output_basic(void)
6583 {
6584     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_ANALOG_OUTPUT_BASIC,
6585                             proto_zbee_zcl_analog_output_basic,
6586                             ett_zbee_zcl_analog_output_basic,
6587                             ZBEE_ZCL_CID_ANALOG_OUTPUT_BASIC,
6588                             ZBEE_MFG_CODE_NONE,
6589                             hf_zbee_zcl_analog_output_basic_attr_id,
6590                             hf_zbee_zcl_analog_output_basic_attr_id,
6591                             -1, -1,
6592                             (zbee_zcl_fn_attr_data)dissect_zcl_analog_output_basic_attr_data
6593                          );
6594 } /*proto_reg_handoff_zbee_zcl_analog_output_basic*/
6595 
6596 
6597 /* ########################################################################## */
6598 /* #### (0x000E) ANALOG VALUE (BASIC) CLUSTER ############################### */
6599 /* ########################################################################## */
6600 
6601 /*************************/
6602 /* Defines               */
6603 /*************************/
6604 
6605 /*Attributes*/
6606 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_DESCRIPTION                     0x001C  /* Description */
6607 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
6608 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
6609 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_PRIORITY_ARRAY                  0x0057  /* Priority Array */
6610 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_RELIABILITY                     0x0067  /* Reliability */
6611 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_RELINQUISH_DEFAULT              0x0068  /* Relinquish Default */
6612 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
6613 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_ENGINEERING_UNITS               0x0075  /* Engineering Units */
6614 #define ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
6615 
6616 /*Server commands received - none*/
6617 
6618 /*Server commands generated - none*/
6619 
6620 /*************************/
6621 /* Function Declarations */
6622 /*************************/
6623 
6624 void proto_register_zbee_zcl_analog_value_basic(void);
6625 void proto_reg_handoff_zbee_zcl_analog_value_basic(void);
6626 
6627 /* Command Dissector Helpers */
6628 static void dissect_zcl_analog_value_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
6629 
6630 /* Private functions prototype */
6631 
6632 /*************************/
6633 /* Global Variables      */
6634 /*************************/
6635 /* Initialize the protocol and registered fields */
6636 static int proto_zbee_zcl_analog_value_basic = -1;
6637 
6638 static int hf_zbee_zcl_analog_value_basic_attr_id = -1;
6639 static int hf_zbee_zcl_analog_value_basic_reliability = -1;
6640 static int hf_zbee_zcl_analog_value_basic_status_flags = -1;
6641 static int hf_zbee_zcl_analog_value_basic_status_in_alarm = -1;
6642 static int hf_zbee_zcl_analog_value_basic_status_fault = -1;
6643 static int hf_zbee_zcl_analog_value_basic_status_overridden = -1;
6644 static int hf_zbee_zcl_analog_value_basic_status_out_of_service = -1;
6645 static int hf_zbee_zcl_analog_value_basic_priority_array_bool = -1;
6646 static int hf_zbee_zcl_analog_value_basic_priority_array_sing_prec = -1;
6647 static int hf_zbee_zcl_analog_value_basic_priority_array = -1;
6648 static int hf_zbee_zcl_analog_value_basic_structure = -1;
6649 
6650 /* Initialize the subtree pointers */
6651 static gint ett_zbee_zcl_analog_value_basic = -1;
6652 static gint ett_zbee_zcl_analog_value_basic_status_flags = -1;
6653 static gint ett_zbee_zcl_analog_value_basic_priority_array = -1;
6654 static gint ett_zbee_zcl_analog_value_basic_priority_array_structure = -1;
6655 
6656 /* Attributes */
6657 static const value_string zbee_zcl_analog_value_basic_attr_names[] = {
6658     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_DESCRIPTION,          "Description" },
6659     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_OUT_OF_SERVICE,       "Out of Service" },
6660     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_PRESENT_VALUE,        "Present Value" },
6661     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_PRIORITY_ARRAY,       "Priority Array" },
6662     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_RELIABILITY,          "Reliability" },
6663     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_RELINQUISH_DEFAULT,   "Relinquish Default" },
6664     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_STATUS_FLAGS,         "Status Flags" },
6665     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_ENGINEERING_UNITS,    "Engineering Units" },
6666     { ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_APPLICATION_TYPE,     "Application Type" },
6667     { 0, NULL }
6668 };
6669 
6670 /*************************/
6671 /* Function Bodies       */
6672 /*************************/
6673 
6674 /*FUNCTION:------------------------------------------------------
6675  *  NAME
6676  *      dissect_zbee_zcl_analog_value_basic
6677  *  DESCRIPTION
6678  *      ZigBee ZCL Analog Value Basic cluster dissector for wireshark.
6679  *  PARAMETERS
6680  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
6681  *      packet_info *pinfo  - pointer to packet information fields
6682  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
6683  *  RETURNS
6684  *      int                 - length of parsed data.
6685  *---------------------------------------------------------------
6686  */
6687 
6688 static int
dissect_zbee_zcl_analog_value_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)6689 dissect_zbee_zcl_analog_value_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
6690 {
6691 	return tvb_captured_length(tvb);
6692 } /*dissect_zbee_zcl_analog_value_basic*/
6693 
6694 
6695 /*FUNCTION:------------------------------------------------------
6696  *  NAME
6697  *      dissect_zcl_analog_value_basic_attr_data
6698  *  DESCRIPTION
6699  *      this function is called by ZCL foundation dissector in order to decode
6700  *      specific cluster attributes data.
6701  *  PARAMETERS
6702  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
6703  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
6704  *      guint *offset       - pointer to buffer offset
6705  *      guint16 attr_id     - attribute identifier
6706  *      guint data_type     - attribute data type
6707  *      gboolean client_attr- ZCL client
6708  *  RETURNS
6709  *      none
6710  *---------------------------------------------------------------
6711  */
6712 void
dissect_zcl_analog_value_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)6713 dissect_zcl_analog_value_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
6714 {
6715     proto_item  *ti = NULL, *tj = NULL;
6716     proto_tree  *sub_tree = NULL, *sub = NULL;
6717     int i;
6718 
6719     static int * const status_flags[] = {
6720         &hf_zbee_zcl_analog_value_basic_status_in_alarm,
6721         &hf_zbee_zcl_analog_value_basic_status_fault,
6722         &hf_zbee_zcl_analog_value_basic_status_overridden,
6723         &hf_zbee_zcl_analog_value_basic_status_out_of_service,
6724         NULL
6725     };
6726 
6727     /* Dissect attribute data type and data */
6728     switch (attr_id) {
6729 
6730         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_PRIORITY_ARRAY:
6731             ti = proto_tree_add_item(tree,hf_zbee_zcl_analog_value_basic_priority_array, tvb, *offset, 80, ENC_NA);
6732             sub_tree = proto_item_add_subtree(ti, ett_zbee_zcl_analog_value_basic_priority_array);
6733 
6734             for( i = 1; i <= 16; i++)
6735             {
6736                 tj = proto_tree_add_item(sub_tree, hf_zbee_zcl_analog_value_basic_structure, tvb, *offset, 5, ENC_NA);
6737                 proto_item_append_text(tj," %d",i);
6738                 sub = proto_item_add_subtree(tj, ett_zbee_zcl_analog_value_basic_priority_array_structure);
6739                 proto_tree_add_item(sub, hf_zbee_zcl_analog_value_basic_priority_array_bool, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
6740                 *offset += 1;
6741                 proto_tree_add_item(sub, hf_zbee_zcl_analog_value_basic_priority_array_sing_prec, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
6742                 *offset += 4;
6743             }
6744             break;
6745 
6746         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_RELIABILITY:
6747             proto_tree_add_item(tree, hf_zbee_zcl_analog_value_basic_reliability, tvb, *offset, 1, ENC_NA);
6748             *offset += 1;
6749             break;
6750 
6751         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_STATUS_FLAGS:
6752             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_analog_value_basic_status_flags, ett_zbee_zcl_analog_value_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
6753             *offset += 1;
6754             break;
6755 
6756         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_DESCRIPTION:
6757         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_OUT_OF_SERVICE:
6758         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_PRESENT_VALUE:
6759         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_RELINQUISH_DEFAULT:
6760         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_ENGINEERING_UNITS:
6761         case ZBEE_ZCL_ATTR_ID_ANALOG_VALUE_BASIC_APPLICATION_TYPE:
6762         default:
6763             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
6764             break;
6765     }
6766 
6767 } /*dissect_zcl_analog_value_basic_attr_data*/
6768 
6769 
6770 /*FUNCTION:------------------------------------------------------
6771  *  NAME
6772  *      proto_register_zbee_zcl_analog_value_basic
6773  *  DESCRIPTION
6774  *      ZigBee ZCL Analog Value Basic cluster protocol registration routine.
6775  *  PARAMETERS
6776  *      none
6777  *  RETURNS
6778  *      none
6779  *---------------------------------------------------------------
6780  */
6781 void
proto_register_zbee_zcl_analog_value_basic(void)6782 proto_register_zbee_zcl_analog_value_basic(void)
6783 {
6784     /* Setup list of header fields */
6785     static hf_register_info hf[] = {
6786 
6787         { &hf_zbee_zcl_analog_value_basic_attr_id,
6788             { "Attribute", "zbee_zcl_general.analog_value_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_analog_value_basic_attr_names),
6789             0x00, NULL, HFILL } },
6790 
6791         { &hf_zbee_zcl_analog_value_basic_reliability,
6792             { "Reliability", "zbee_zcl_general.analog_value_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
6793             0x00, NULL, HFILL } },
6794 
6795         /* start Status Flags fields */
6796         { &hf_zbee_zcl_analog_value_basic_status_flags,
6797             { "Status Flags", "zbee_zcl_general.analog_value_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
6798             0x00, NULL, HFILL } },
6799 
6800         { &hf_zbee_zcl_analog_value_basic_status_in_alarm,
6801             { "In Alarm Status", "zbee_zcl_general.analog_value_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6802             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
6803 
6804         { &hf_zbee_zcl_analog_value_basic_status_fault,
6805             { "Fault Status", "zbee_zcl_general.analog_value_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6806             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
6807 
6808         { &hf_zbee_zcl_analog_value_basic_status_overridden,
6809             { "Overridden Status", "zbee_zcl_general.analog_value_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6810             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
6811 
6812         { &hf_zbee_zcl_analog_value_basic_status_out_of_service,
6813             { "Out of Service Status", "zbee_zcl_general.analog_value_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
6814             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } },
6815         /* end Status Flags fields */
6816 
6817         { &hf_zbee_zcl_analog_value_basic_priority_array_bool,
6818             { "Valid/Invalid", "zbee_zcl_general.analog_value_basic.attr.priority_array.bool", FT_BOOLEAN, 8, TFS(&tfs_invalid_valid),
6819             0x00, NULL, HFILL } },
6820 
6821         { &hf_zbee_zcl_analog_value_basic_priority_array_sing_prec,
6822             { "Priority Value", "zbee_zcl_general.analog_value_basic.attr.priority_array.sing_prec", FT_UINT16, BASE_HEX, NULL,
6823             0x00, NULL, HFILL } },
6824 
6825         { &hf_zbee_zcl_analog_value_basic_priority_array,
6826             { "Priority Array", "zbee_zcl_general.analog_value_basic.priority_array", FT_NONE, BASE_NONE, NULL,
6827             0x00, NULL, HFILL } },
6828 
6829         { &hf_zbee_zcl_analog_value_basic_structure,
6830             { "Structure", "zbee_zcl_general.analog_value_basic.structure", FT_NONE, BASE_NONE, NULL,
6831             0x00, NULL, HFILL } }
6832     };
6833 
6834     /* ZCL Analog Value Basic subtrees */
6835     static gint *ett[] = {
6836         &ett_zbee_zcl_analog_value_basic,
6837         &ett_zbee_zcl_analog_value_basic_status_flags,
6838         &ett_zbee_zcl_analog_value_basic_priority_array,
6839         &ett_zbee_zcl_analog_value_basic_priority_array_structure
6840     };
6841 
6842     /* Register the ZigBee ZCL Analog Value Basic cluster protocol name and description */
6843     proto_zbee_zcl_analog_value_basic = proto_register_protocol("ZigBee ZCL Analog Value Basic", "ZCL Analog Value Basic", ZBEE_PROTOABBREV_ZCL_ANALOG_VALUE_BASIC);
6844     proto_register_field_array(proto_zbee_zcl_analog_value_basic, hf, array_length(hf));
6845     proto_register_subtree_array(ett, array_length(ett));
6846 
6847     /* Register the ZigBee ZCL Analog Value Basic dissector. */
6848     register_dissector(ZBEE_PROTOABBREV_ZCL_ANALOG_VALUE_BASIC, dissect_zbee_zcl_analog_value_basic, proto_zbee_zcl_analog_value_basic);
6849 } /*proto_register_zbee_zcl_analog_value_basic*/
6850 
6851 /*FUNCTION:------------------------------------------------------
6852  *  NAME
6853  *      proto_reg_handoff_zbee_zcl_analog_value_basic
6854  *  DESCRIPTION
6855  *      Hands off the ZCL Analog Value Basic dissector.
6856  *  PARAMETERS
6857  *      none
6858  *  RETURNS
6859  *      none
6860  *---------------------------------------------------------------
6861  */
6862 void
proto_reg_handoff_zbee_zcl_analog_value_basic(void)6863 proto_reg_handoff_zbee_zcl_analog_value_basic(void)
6864 {
6865     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_ANALOG_VALUE_BASIC,
6866                             proto_zbee_zcl_analog_value_basic,
6867                             ett_zbee_zcl_analog_value_basic,
6868                             ZBEE_ZCL_CID_ANALOG_VALUE_BASIC,
6869                             ZBEE_MFG_CODE_NONE,
6870                             hf_zbee_zcl_analog_value_basic_attr_id,
6871                             hf_zbee_zcl_analog_value_basic_attr_id,
6872                             -1, -1,
6873                             (zbee_zcl_fn_attr_data)dissect_zcl_analog_value_basic_attr_data
6874                          );
6875 } /*proto_reg_handoff_zbee_zcl_analog_value_basic*/
6876 
6877 
6878 /* ########################################################################## */
6879 /* #### (0x000F) BINARY INPUT (BASIC) CLUSTER ############################### */
6880 /* ########################################################################## */
6881 
6882 /*************************/
6883 /* Defines               */
6884 /*************************/
6885 
6886 /*Attributes*/
6887 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_ACTIVE_TEXT                     0x0004  /* Active Text */
6888 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_DESCRIPTION                     0x001C  /* Description */
6889 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_INACTIVE_TEXT                   0x002E  /* Inactive Text */
6890 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
6891 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_POLARITY                        0x0054  /* Polarity */
6892 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
6893 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_RELIABILITY                     0x0067  /* Reliability */
6894 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
6895 #define ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
6896 
6897 /*Server commands received - none*/
6898 
6899 /*Server commands generated - none*/
6900 
6901 static const value_string zbee_zcl_binary_input_polarity_values[] = {
6902     {0, "Normal"},
6903     {1, "Reversed"},
6904     {0, NULL}
6905 };
6906 
6907 /*************************/
6908 /* Function Declarations */
6909 /*************************/
6910 
6911 void proto_register_zbee_zcl_binary_input_basic(void);
6912 void proto_reg_handoff_zbee_zcl_binary_input_basic(void);
6913 
6914 /* Command Dissector Helpers */
6915 static void dissect_zcl_binary_input_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
6916 
6917 /* Private functions prototype */
6918 
6919 /*************************/
6920 /* Global Variables      */
6921 /*************************/
6922 /* Initialize the protocol and registered fields */
6923 static int proto_zbee_zcl_binary_input_basic = -1;
6924 
6925 static int hf_zbee_zcl_binary_input_basic_attr_id = -1;
6926 static int hf_zbee_zcl_binary_input_basic_status_flags = -1;
6927 static int hf_zbee_zcl_binary_input_basic_status_in_alarm = -1;
6928 static int hf_zbee_zcl_binary_input_basic_status_fault = -1;
6929 static int hf_zbee_zcl_binary_input_basic_status_overridden = -1;
6930 static int hf_zbee_zcl_binary_input_basic_status_out_of_service = -1;
6931 static int hf_zbee_zcl_binary_input_basic_polarity = -1;
6932 static int hf_zbee_zcl_binary_input_basic_reliability= -1;
6933 
6934 /* Initialize the subtree pointers */
6935 static gint ett_zbee_zcl_binary_input_basic = -1;
6936 static gint ett_zbee_zcl_binary_input_basic_status_flags = -1;
6937 
6938 /* Attributes */
6939 static const value_string zbee_zcl_binary_input_basic_attr_names[] = {
6940     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_ACTIVE_TEXT,          "Active Text" },
6941     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_DESCRIPTION,          "Description" },
6942     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_INACTIVE_TEXT,        "Inactive Text" },
6943     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_OUT_OF_SERVICE,       "Out of Service" },
6944     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_POLARITY,             "Polarity" },
6945     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_PRESENT_VALUE,        "Present Value" },
6946     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_RELIABILITY,          "Reliability" },
6947     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_STATUS_FLAGS,         "Status Flags" },
6948     { ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_APPLICATION_TYPE,     "Application Type" },
6949     { 0, NULL }
6950 };
6951 
6952 /*************************/
6953 /* Function Bodies       */
6954 /*************************/
6955 
6956 /*FUNCTION:------------------------------------------------------
6957  *  NAME
6958  *      dissect_zbee_zcl_binary_input_basic
6959  *  DESCRIPTION
6960  *      ZigBee ZCL Binary Input Basic cluster dissector for wireshark.
6961  *  PARAMETERS
6962  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
6963  *      packet_info *pinfo  - pointer to packet information fields
6964  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
6965  *  RETURNS
6966  *      int                 - length of parsed data.
6967  *---------------------------------------------------------------
6968  */
6969 
6970 static int
dissect_zbee_zcl_binary_input_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)6971 dissect_zbee_zcl_binary_input_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
6972 {
6973     return tvb_captured_length(tvb);
6974 } /*dissect_zbee_zcl_binary_input_basic*/
6975 
6976 
6977 /*FUNCTION:------------------------------------------------------
6978  *  NAME
6979  *      dissect_zcl_binary_input_basic_attr_data
6980  *  DESCRIPTION
6981  *      this function is called by ZCL foundation dissector in order to decode
6982  *      specific cluster attributes data.
6983  *  PARAMETERS
6984  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
6985  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
6986  *      guint *offset       - pointer to buffer offset
6987  *      guint16 attr_id     - attribute identifier
6988  *      guint data_type     - attribute data type
6989  *      gboolean client_attr- ZCL client
6990  *  RETURNS
6991  *      none
6992  *---------------------------------------------------------------
6993  */
6994 void
dissect_zcl_binary_input_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)6995 dissect_zcl_binary_input_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
6996 {
6997     static int * const status_flags[] = {
6998         &hf_zbee_zcl_binary_input_basic_status_in_alarm,
6999         &hf_zbee_zcl_binary_input_basic_status_fault,
7000         &hf_zbee_zcl_binary_input_basic_status_overridden,
7001         &hf_zbee_zcl_binary_input_basic_status_out_of_service,
7002         NULL
7003     };
7004 
7005     /* Dissect attribute data type and data */
7006     switch (attr_id) {
7007 
7008         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_POLARITY:
7009             proto_tree_add_item(tree, hf_zbee_zcl_binary_input_basic_polarity, tvb, *offset, 1, ENC_NA);
7010             *offset += 1;
7011             break;
7012 
7013         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_RELIABILITY:
7014             proto_tree_add_item(tree, hf_zbee_zcl_binary_input_basic_reliability, tvb, *offset, 1, ENC_NA);
7015             *offset += 1;
7016             break;
7017 
7018         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_STATUS_FLAGS:
7019             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_binary_input_basic_status_flags, ett_zbee_zcl_binary_input_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
7020             *offset += 1;
7021             break;
7022 
7023         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_ACTIVE_TEXT:
7024         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_INACTIVE_TEXT:
7025         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_DESCRIPTION:
7026         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_OUT_OF_SERVICE:
7027         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_PRESENT_VALUE:
7028         case ZBEE_ZCL_ATTR_ID_BINARY_INPUT_BASIC_APPLICATION_TYPE:
7029         default:
7030             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
7031             break;
7032     }
7033 
7034 } /*dissect_zcl_binary_input_basic_attr_data*/
7035 
7036 
7037 /*FUNCTION:------------------------------------------------------
7038  *  NAME
7039  *      proto_register_zbee_zcl_binary_input_basic
7040  *  DESCRIPTION
7041  *      ZigBee ZCL Binary Input Basic cluster protocol registration routine.
7042  *  PARAMETERS
7043  *      none
7044  *  RETURNS
7045  *      none
7046  *---------------------------------------------------------------
7047  */
7048 void
proto_register_zbee_zcl_binary_input_basic(void)7049 proto_register_zbee_zcl_binary_input_basic(void)
7050 {
7051     /* Setup list of header fields */
7052     static hf_register_info hf[] = {
7053 
7054         { &hf_zbee_zcl_binary_input_basic_attr_id,
7055             { "Attribute", "zbee_zcl_general.binary_input_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_binary_input_basic_attr_names),
7056             0x00, NULL, HFILL } },
7057 
7058         { &hf_zbee_zcl_binary_input_basic_reliability,
7059             { "Reliability", "zbee_zcl_general.binary_input_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
7060             0x00, NULL, HFILL } },
7061 
7062         /* start Status Flags fields */
7063         { &hf_zbee_zcl_binary_input_basic_status_flags,
7064             { "Status Flags", "zbee_zcl_general.binary_input_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
7065             0x00, NULL, HFILL } },
7066 
7067         { &hf_zbee_zcl_binary_input_basic_status_in_alarm,
7068             { "In Alarm Status", "zbee_zcl_general.binary_input_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7069             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
7070 
7071         { &hf_zbee_zcl_binary_input_basic_status_fault,
7072             { "Fault Status", "zbee_zcl_general.binary_input_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7073             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
7074 
7075         { &hf_zbee_zcl_binary_input_basic_status_overridden,
7076             { "Overridden Status", "zbee_zcl_general.binary_input_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7077             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
7078 
7079         { &hf_zbee_zcl_binary_input_basic_status_out_of_service,
7080             { "Out of Service Status", "zbee_zcl_general.binary_input_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7081             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } },
7082         /* end Status Flags fields */
7083 
7084         { &hf_zbee_zcl_binary_input_basic_polarity,
7085             { "Polarity", "zbee_zcl_general.binary_input_basic.attr.polarity", FT_UINT8, BASE_HEX, VALS(zbee_zcl_binary_input_polarity_values),
7086             0x00, NULL, HFILL } }
7087 
7088     };
7089 
7090     /* ZCL Binary Input Basic subtrees */
7091     static gint *ett[] = {
7092              &ett_zbee_zcl_binary_input_basic,
7093              &ett_zbee_zcl_binary_input_basic_status_flags
7094     };
7095 
7096     /* Register the ZigBee ZCL Binary Input Basic cluster protocol name and description */
7097     proto_zbee_zcl_binary_input_basic = proto_register_protocol("ZigBee ZCL Binary Input Basic", "ZCL Binary Input Basic", ZBEE_PROTOABBREV_ZCL_BINARY_INPUT_BASIC);
7098     proto_register_field_array(proto_zbee_zcl_binary_input_basic, hf, array_length(hf));
7099     proto_register_subtree_array(ett, array_length(ett));
7100 
7101     /* Register the ZigBee ZCL Binary Input Basic dissector. */
7102     register_dissector(ZBEE_PROTOABBREV_ZCL_BINARY_INPUT_BASIC, dissect_zbee_zcl_binary_input_basic, proto_zbee_zcl_binary_input_basic);
7103 } /*proto_register_zbee_zcl_binary_input_basic*/
7104 
7105 /*FUNCTION:------------------------------------------------------
7106  *  NAME
7107  *      proto_reg_handoff_zbee_zcl_binary_input_basic
7108  *  DESCRIPTION
7109  *      Hands off the ZCL Binary Input Basic dissector.
7110  *  PARAMETERS
7111  *      none
7112  *  RETURNS
7113  *      none
7114  *---------------------------------------------------------------
7115  */
7116 void
proto_reg_handoff_zbee_zcl_binary_input_basic(void)7117 proto_reg_handoff_zbee_zcl_binary_input_basic(void)
7118 {
7119     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_BINARY_INPUT_BASIC,
7120                             proto_zbee_zcl_binary_input_basic,
7121                             ett_zbee_zcl_binary_input_basic,
7122                             ZBEE_ZCL_CID_BINARY_INPUT_BASIC,
7123                             ZBEE_MFG_CODE_NONE,
7124                             hf_zbee_zcl_binary_input_basic_attr_id,
7125                             hf_zbee_zcl_binary_input_basic_attr_id,
7126                             -1, -1,
7127                             (zbee_zcl_fn_attr_data)dissect_zcl_binary_input_basic_attr_data
7128                          );
7129 } /*proto_reg_handoff_zbee_zcl_binary_input_basic*/
7130 
7131 /* ########################################################################## */
7132 /* #### (0x0010) BINARY OUTPUT (BASIC) CLUSTER ############################## */
7133 /* ########################################################################## */
7134 
7135 /*************************/
7136 /* Defines               */
7137 /*************************/
7138 
7139 /*Attributes*/
7140 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_ACTIVE_TEXT                     0x0004  /* Active Text */
7141 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_DESCRIPTION                     0x001C  /* Description */
7142 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_INACTIVE_TEXT                   0x002E  /* Inactive Text */
7143 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_MIN_OFF_TIME                    0x0042  /* Maximum Off Time */
7144 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_MIN_ON_TIME                     0x0043  /* Minimum On Time */
7145 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
7146 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_POLARITY                        0x0054  /* Polarity */
7147 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
7148 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_PRIORITY_ARRAY                  0x0057  /* Priority Array */
7149 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_RELIABILITY                     0x0067  /* Reliability */
7150 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_RELINQUISH_DEFAULT              0x0068  /* Relinquish Default */
7151 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
7152 #define ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
7153 
7154 /*Server commands received - none*/
7155 
7156 /*Server commands generated - none*/
7157 
7158 static const value_string zbee_zcl_binary_output_polarity_values[] = {
7159     {0, "Normal"},
7160     {1, "Reversed"},
7161     {0, NULL}
7162 };
7163 
7164 /*************************/
7165 /* Function Declarations */
7166 /*************************/
7167 
7168 void proto_register_zbee_zcl_binary_output_basic(void);
7169 void proto_reg_handoff_zbee_zcl_binary_output_basic(void);
7170 
7171 /* Command Dissector Helpers */
7172 static void dissect_zcl_binary_output_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
7173 
7174 /* Private functions prototype */
7175 
7176 /*************************/
7177 /* Global Variables      */
7178 /*************************/
7179 /* Initialize the protocol and registered fields */
7180 static int proto_zbee_zcl_binary_output_basic = -1;
7181 
7182 static int hf_zbee_zcl_binary_output_basic_attr_id = -1;
7183 static int hf_zbee_zcl_binary_output_basic_status_flags = -1;
7184 static int hf_zbee_zcl_binary_output_basic_status_in_alarm = -1;
7185 static int hf_zbee_zcl_binary_output_basic_status_fault = -1;
7186 static int hf_zbee_zcl_binary_output_basic_status_overridden = -1;
7187 static int hf_zbee_zcl_binary_output_basic_status_out_of_service = -1;
7188 static int hf_zbee_zcl_binary_output_basic_priority_array_bool = -1;
7189 static int hf_zbee_zcl_binary_output_basic_priority_array_sing_prec = -1;
7190 static int hf_zbee_zcl_binary_output_basic_polarity = -1;
7191 static int hf_zbee_zcl_binary_output_basic_reliability = -1;
7192 static int hf_zbee_zcl_binary_output_basic_priority_array = -1;
7193 static int hf_zbee_zcl_binary_output_basic_structure = -1;
7194 
7195 /* Initialize the subtree pointers */
7196 static gint ett_zbee_zcl_binary_output_basic = -1;
7197 static gint ett_zbee_zcl_binary_output_basic_status_flags = -1;
7198 static gint ett_zbee_zcl_binary_output_basic_priority_array = -1;
7199 static gint ett_zbee_zcl_binary_output_basic_priority_array_structure = -1;
7200 
7201 /* Attributes */
7202 static const value_string zbee_zcl_binary_output_basic_attr_names[] = {
7203     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_ACTIVE_TEXT,          "Active Text" },
7204     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_DESCRIPTION,          "Description" },
7205     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_INACTIVE_TEXT,        "Inactive Text" },
7206     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_MIN_OFF_TIME,         "Minimum Off Time" },
7207     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_MIN_ON_TIME,          "Minimum On Time" },
7208     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_OUT_OF_SERVICE,       "Out of Service" },
7209     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_POLARITY,             "Polarity" },
7210     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_PRESENT_VALUE,        "Present Value" },
7211     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_PRIORITY_ARRAY,       "Priority Array" },
7212     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_RELIABILITY,          "Reliability" },
7213     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_RELINQUISH_DEFAULT,   "Relinquish Default" },
7214     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_STATUS_FLAGS,         "Status Flags" },
7215     { ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_APPLICATION_TYPE,     "Application Type" },
7216     { 0, NULL }
7217 };
7218 
7219 /*************************/
7220 /* Function Bodies       */
7221 /*************************/
7222 
7223 /*FUNCTION:------------------------------------------------------
7224  *  NAME
7225  *      dissect_zbee_zcl_binary_output_basic
7226  *  DESCRIPTION
7227  *      ZigBee ZCL Binary Output Basic cluster dissector for wireshark.
7228  *  PARAMETERS
7229  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
7230  *      packet_info *pinfo  - pointer to packet information fields
7231  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
7232  *  RETURNS
7233  *      int                 - length of parsed data.
7234  *---------------------------------------------------------------
7235  */
7236 
7237 static int
dissect_zbee_zcl_binary_output_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)7238 dissect_zbee_zcl_binary_output_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
7239 {
7240     return tvb_captured_length(tvb);
7241 } /*dissect_zbee_zcl_binary_output_basic*/
7242 
7243 
7244 /*FUNCTION:------------------------------------------------------
7245  *  NAME
7246  *      dissect_zcl_binary_output_basic_attr_data
7247  *  DESCRIPTION
7248  *      this function is called by ZCL foundation dissector in order to decode
7249  *      specific cluster attributes data.
7250  *  PARAMETERS
7251  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
7252  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
7253  *      guint *offset       - pointer to buffer offset
7254  *      guint16 attr_id     - attribute identifier
7255  *      guint data_type     - attribute data type
7256  *      gboolean client_attr- ZCL client
7257  *  RETURNS
7258  *      none
7259  *---------------------------------------------------------------
7260  */
7261 void
dissect_zcl_binary_output_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)7262 dissect_zcl_binary_output_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
7263 {
7264     proto_item  *ti = NULL, *tj = NULL;
7265     proto_tree  *sub_tree = NULL, *sub = NULL;
7266     int i;
7267 
7268     static int * const status_flags[] = {
7269         &hf_zbee_zcl_binary_output_basic_status_in_alarm,
7270         &hf_zbee_zcl_binary_output_basic_status_fault,
7271         &hf_zbee_zcl_binary_output_basic_status_overridden,
7272         &hf_zbee_zcl_binary_output_basic_status_out_of_service,
7273         NULL
7274     };
7275 
7276     /* Dissect attribute data type and data */
7277     switch (attr_id) {
7278 
7279         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_PRIORITY_ARRAY:
7280             ti = proto_tree_add_item(tree,hf_zbee_zcl_binary_output_basic_priority_array, tvb, *offset, 80, ENC_NA);
7281             sub_tree = proto_item_add_subtree(ti, ett_zbee_zcl_binary_output_basic_priority_array);
7282 
7283             for(i = 1; i <= 16; i++)
7284             {
7285                 tj = proto_tree_add_item(sub_tree, hf_zbee_zcl_binary_output_basic_structure, tvb, *offset, 5, ENC_NA);
7286                 proto_item_append_text(tj," %d",i);
7287                 sub = proto_item_add_subtree(tj, ett_zbee_zcl_binary_output_basic_priority_array_structure);
7288                 proto_tree_add_item(sub, hf_zbee_zcl_binary_output_basic_priority_array_bool, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
7289                 *offset += 1;
7290                 proto_tree_add_item(sub, hf_zbee_zcl_binary_output_basic_priority_array_sing_prec, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
7291                 *offset += 4;
7292             }
7293             break;
7294 
7295         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_POLARITY:
7296             proto_tree_add_item(tree, hf_zbee_zcl_binary_output_basic_polarity, tvb, *offset, 1, ENC_NA);
7297             *offset += 1;
7298             break;
7299 
7300         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_RELIABILITY:
7301             proto_tree_add_item(tree, hf_zbee_zcl_binary_output_basic_reliability, tvb, *offset, 1, ENC_NA);
7302             *offset += 1;
7303             break;
7304 
7305         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_STATUS_FLAGS:
7306             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_binary_output_basic_status_flags, ett_zbee_zcl_binary_output_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
7307             *offset += 1;
7308             break;
7309 
7310         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_ACTIVE_TEXT:
7311         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_DESCRIPTION:
7312         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_INACTIVE_TEXT:
7313         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_MIN_OFF_TIME:
7314         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_MIN_ON_TIME:
7315         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_OUT_OF_SERVICE:
7316         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_PRESENT_VALUE:
7317         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_RELINQUISH_DEFAULT:
7318         case ZBEE_ZCL_ATTR_ID_BINARY_OUTPUT_BASIC_APPLICATION_TYPE:
7319         default:
7320             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
7321             break;
7322     }
7323 
7324 } /*dissect_zcl_binary_output_basic_attr_data*/
7325 
7326 
7327 /*FUNCTION:------------------------------------------------------
7328  *  NAME
7329  *      proto_register_zbee_zcl_binary_output_basic
7330  *  DESCRIPTION
7331  *      ZigBee ZCL Binary Output Basic cluster protocol registration routine.
7332  *  PARAMETERS
7333  *      none
7334  *  RETURNS
7335  *      none
7336  *---------------------------------------------------------------
7337  */
7338 void
proto_register_zbee_zcl_binary_output_basic(void)7339 proto_register_zbee_zcl_binary_output_basic(void)
7340 {
7341     /* Setup list of header fields */
7342     static hf_register_info hf[] = {
7343 
7344         { &hf_zbee_zcl_binary_output_basic_attr_id,
7345             { "Attribute", "zbee_zcl_general.binary_output_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_binary_output_basic_attr_names),
7346             0x00, NULL, HFILL } },
7347 
7348         { &hf_zbee_zcl_binary_output_basic_reliability,
7349             { "Reliability", "zbee_zcl_general.binary_output_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
7350             0x00, NULL, HFILL } },
7351 
7352         /* start Status Flags fields */
7353         { &hf_zbee_zcl_binary_output_basic_status_flags,
7354             { "Status Flags", "zbee_zcl_general.binary_output_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
7355             0x00, NULL, HFILL } },
7356 
7357         { &hf_zbee_zcl_binary_output_basic_status_in_alarm,
7358             { "In Alarm Status", "zbee_zcl_general.binary_output_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7359             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
7360 
7361         { &hf_zbee_zcl_binary_output_basic_status_fault,
7362             { "Fault Status", "zbee_zcl_general.binary_output_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7363             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
7364 
7365         { &hf_zbee_zcl_binary_output_basic_status_overridden,
7366             { "Overridden Status", "zbee_zcl_general.binary_output_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7367             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
7368 
7369         { &hf_zbee_zcl_binary_output_basic_status_out_of_service,
7370             { "Out of Service Status", "zbee_zcl_general.binary_output_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7371             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } },
7372         /* end Status Flags fields */
7373 
7374         { &hf_zbee_zcl_binary_output_basic_polarity,
7375             { "Polarity", "zbee_zcl_general.binary_output_basic.attr.polarity", FT_UINT8, BASE_HEX, VALS(zbee_zcl_binary_output_polarity_values),
7376             0x00, NULL, HFILL } },
7377 
7378         { &hf_zbee_zcl_binary_output_basic_priority_array_bool,
7379             { "Valid/Invalid", "zbee_zcl_general.binary_output_basic.attr.priority_array.bool", FT_BOOLEAN, 8, TFS(&tfs_invalid_valid),
7380             0x00, NULL, HFILL } },
7381 
7382         { &hf_zbee_zcl_binary_output_basic_priority_array_sing_prec,
7383             { "Priority Value", "zbee_zcl_general.binary_output_basic.attr.priority_array.sing_prec", FT_UINT16, BASE_HEX, NULL,
7384             0x00, NULL, HFILL } },
7385 
7386         { &hf_zbee_zcl_binary_output_basic_priority_array,
7387             { "Priority Array", "zbee_zcl_general.binary_output_basic.priority_array", FT_NONE, BASE_NONE, NULL,
7388             0x00, NULL, HFILL } },
7389 
7390         { &hf_zbee_zcl_binary_output_basic_structure,
7391             { "Structure", "zbee_zcl_general.binary_output_basic.structure", FT_NONE, BASE_NONE, NULL,
7392             0x00, NULL, HFILL } }
7393     };
7394 
7395     /* ZCL Binary Output Basic subtrees */
7396     static gint *ett[] = {
7397             &ett_zbee_zcl_binary_output_basic,
7398             &ett_zbee_zcl_binary_output_basic_status_flags,
7399             &ett_zbee_zcl_binary_output_basic_priority_array,
7400             &ett_zbee_zcl_binary_output_basic_priority_array_structure
7401     };
7402 
7403     /* Register the ZigBee ZCL Binary Output Basic cluster protocol name and description */
7404     proto_zbee_zcl_binary_output_basic = proto_register_protocol("ZigBee ZCL Binary Output Basic", "ZCL Binary Output Basic", ZBEE_PROTOABBREV_ZCL_BINARY_OUTPUT_BASIC);
7405     proto_register_field_array(proto_zbee_zcl_binary_output_basic, hf, array_length(hf));
7406     proto_register_subtree_array(ett, array_length(ett));
7407 
7408     /* Register the ZigBee ZCL Binary Output Basic dissector. */
7409     register_dissector(ZBEE_PROTOABBREV_ZCL_BINARY_OUTPUT_BASIC, dissect_zbee_zcl_binary_output_basic, proto_zbee_zcl_binary_output_basic);
7410 } /*proto_register_zbee_zcl_binary_output_basic*/
7411 
7412 /*FUNCTION:------------------------------------------------------
7413  *  NAME
7414  *      proto_reg_handoff_zbee_zcl_binary_output_basic
7415  *  DESCRIPTION
7416  *      Hands off the ZCL Binary Output Basic dissector.
7417  *  PARAMETERS
7418  *      none
7419  *  RETURNS
7420  *      none
7421  *---------------------------------------------------------------
7422  */
7423 void
proto_reg_handoff_zbee_zcl_binary_output_basic(void)7424 proto_reg_handoff_zbee_zcl_binary_output_basic(void)
7425 {
7426     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_BINARY_OUTPUT_BASIC,
7427                             proto_zbee_zcl_binary_output_basic,
7428                             ett_zbee_zcl_binary_output_basic,
7429                             ZBEE_ZCL_CID_BINARY_OUTPUT_BASIC,
7430                             ZBEE_MFG_CODE_NONE,
7431                             hf_zbee_zcl_binary_output_basic_attr_id,
7432                             hf_zbee_zcl_binary_output_basic_attr_id,
7433                             -1, -1,
7434                             (zbee_zcl_fn_attr_data)dissect_zcl_binary_output_basic_attr_data
7435                          );
7436 } /*proto_reg_handoff_zbee_zcl_binary_output_basic*/
7437 
7438 /* ########################################################################## */
7439 /* #### (0x0011) BINARY VALUE (BASIC) CLUSTER ############################### */
7440 /* ########################################################################## */
7441 
7442 /*************************/
7443 /* Defines               */
7444 /*************************/
7445 
7446 /*Attributes*/
7447 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_ACTIVE_TEXT                     0x0004  /* Active Text */
7448 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_DESCRIPTION                     0x001C  /* Description */
7449 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_INACTIVE_TEXT                   0x002E  /* Inactive Text */
7450 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_MIN_OFF_TIME                    0x0042  /* Maximum Off Time */
7451 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_MIN_ON_TIME                     0x0043  /* Minimum On Time */
7452 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
7453 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
7454 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_PRIORITY_ARRAY                  0x0057  /* Priority Array */
7455 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_RELIABILITY                     0x0067  /* Reliability */
7456 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_RELINQUISH_DEFAULT              0x0068  /* Relinquish Default */
7457 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
7458 #define ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
7459 
7460 /*Server commands received - none*/
7461 
7462 /*Server commands generated - none*/
7463 
7464 /*************************/
7465 /* Function Declarations */
7466 /*************************/
7467 
7468 void proto_register_zbee_zcl_binary_value_basic(void);
7469 void proto_reg_handoff_zbee_zcl_binary_value_basic(void);
7470 
7471 /* Command Dissector Helpers */
7472 static void dissect_zcl_binary_value_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
7473 
7474 /* Private functions prototype */
7475 
7476 /*************************/
7477 /* Global Variables      */
7478 /*************************/
7479 /* Initialize the protocol and registered fields */
7480 static int proto_zbee_zcl_binary_value_basic = -1;
7481 
7482 static int hf_zbee_zcl_binary_value_basic_attr_id = -1;
7483 static int hf_zbee_zcl_binary_value_basic_status_flags = -1;
7484 static int hf_zbee_zcl_binary_value_basic_status_in_alarm = -1;
7485 static int hf_zbee_zcl_binary_value_basic_status_fault = -1;
7486 static int hf_zbee_zcl_binary_value_basic_status_overridden = -1;
7487 static int hf_zbee_zcl_binary_value_basic_status_out_of_service = -1;
7488 static int hf_zbee_zcl_binary_value_basic_priority_array_bool = -1;
7489 static int hf_zbee_zcl_binary_value_basic_priority_array_sing_prec = -1;
7490 static int hf_zbee_zcl_binary_value_basic_reliability = -1;
7491 static int hf_zbee_zcl_binary_value_basic_priority_array = -1;
7492 static int hf_zbee_zcl_binary_value_basic_structure = -1;
7493 
7494 /* Initialize the subtree pointers */
7495 static gint ett_zbee_zcl_binary_value_basic = -1;
7496 static gint ett_zbee_zcl_binary_value_basic_status_flags = -1;
7497 static gint ett_zbee_zcl_binary_value_basic_priority_array = -1;
7498 static gint ett_zbee_zcl_binary_value_basic_priority_array_structure = -1;
7499 
7500 /* Attributes */
7501 static const value_string zbee_zcl_binary_value_basic_attr_names[] = {
7502     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_ACTIVE_TEXT,          "Active Text" },
7503     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_DESCRIPTION,          "Description" },
7504     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_INACTIVE_TEXT,        "Inactive Text" },
7505     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_MIN_OFF_TIME,         "Minimum Off Time" },
7506     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_MIN_ON_TIME,          "Minimum On Time" },
7507     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_OUT_OF_SERVICE,       "Out of Service" },
7508     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_PRESENT_VALUE,        "Present Value" },
7509     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_PRIORITY_ARRAY,       "Priority Array" },
7510     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_RELIABILITY,          "Reliability" },
7511     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_RELINQUISH_DEFAULT,   "Relinquish Default" },
7512     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_STATUS_FLAGS,         "Status Flags" },
7513     { ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_APPLICATION_TYPE,     "Application Type" },
7514     { 0, NULL }
7515 };
7516 
7517 /*************************/
7518 /* Function Bodies       */
7519 /*************************/
7520 
7521 /*FUNCTION:------------------------------------------------------
7522  *  NAME
7523  *      dissect_zbee_zcl_binary_value_basic
7524  *  DESCRIPTION
7525  *      ZigBee ZCL Binary Value Basic cluster dissector for wireshark.
7526  *  PARAMETERS
7527  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
7528  *      packet_info *pinfo  - pointer to packet information fields
7529  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
7530  *  RETURNS
7531  *      int                 - length of parsed data.
7532  *---------------------------------------------------------------
7533  */
7534 
7535 static int
dissect_zbee_zcl_binary_value_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)7536 dissect_zbee_zcl_binary_value_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
7537 {
7538     return tvb_captured_length(tvb);
7539 } /*dissect_zbee_zcl_binary_value_basic*/
7540 
7541 
7542 /*FUNCTION:------------------------------------------------------
7543  *  NAME
7544  *      dissect_zcl_binary_value_basic_attr_data
7545  *  DESCRIPTION
7546  *      this function is called by ZCL foundation dissector in order to decode
7547  *      specific cluster attributes data.
7548  *  PARAMETERS
7549  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
7550  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
7551  *      guint *offset       - pointer to buffer offset
7552  *      guint16 attr_id     - attribute identifier
7553  *      guint data_type     - attribute data type
7554  *      gboolean client_attr- ZCL client
7555  *  RETURNS
7556  *      none
7557  *---------------------------------------------------------------
7558  */
7559 void
dissect_zcl_binary_value_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)7560 dissect_zcl_binary_value_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
7561 {
7562     proto_item  *ti = NULL, *tj = NULL;
7563     proto_tree  *sub_tree = NULL, *sub = NULL;
7564     int i;
7565 
7566     static int * const status_flags[] = {
7567         &hf_zbee_zcl_binary_value_basic_status_in_alarm,
7568         &hf_zbee_zcl_binary_value_basic_status_fault,
7569         &hf_zbee_zcl_binary_value_basic_status_overridden,
7570         &hf_zbee_zcl_binary_value_basic_status_out_of_service,
7571         NULL
7572     };
7573 
7574     /* Dissect attribute data type and data */
7575     switch (attr_id) {
7576 
7577         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_PRIORITY_ARRAY:
7578             ti = proto_tree_add_item(tree,hf_zbee_zcl_binary_value_basic_priority_array, tvb, *offset, 80, ENC_NA);
7579             sub_tree = proto_item_add_subtree(ti, ett_zbee_zcl_binary_value_basic_priority_array);
7580 
7581             for( i = 1; i <= 16; i++)
7582             {
7583                 tj = proto_tree_add_item(sub_tree, hf_zbee_zcl_binary_value_basic_structure, tvb, *offset, 5, ENC_NA);
7584                 proto_item_append_text(tj," %d",i);
7585                 sub = proto_item_add_subtree(tj, ett_zbee_zcl_binary_value_basic_priority_array_structure);
7586                 proto_tree_add_item(sub, hf_zbee_zcl_binary_value_basic_priority_array_bool, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
7587                 *offset += 1;
7588                 proto_tree_add_item(sub, hf_zbee_zcl_binary_value_basic_priority_array_sing_prec, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
7589                 *offset += 4;
7590             }
7591             break;
7592 
7593         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_RELIABILITY:
7594             proto_tree_add_item(tree, hf_zbee_zcl_binary_value_basic_reliability, tvb, *offset, 1, ENC_NA);
7595             *offset += 1;
7596             break;
7597 
7598         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_STATUS_FLAGS:
7599             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_binary_value_basic_status_flags, ett_zbee_zcl_binary_value_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
7600             *offset += 1;
7601             break;
7602 
7603         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_ACTIVE_TEXT:
7604         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_DESCRIPTION:
7605         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_INACTIVE_TEXT:
7606         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_MIN_OFF_TIME:
7607         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_MIN_ON_TIME:
7608         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_OUT_OF_SERVICE:
7609         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_PRESENT_VALUE:
7610         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_RELINQUISH_DEFAULT:
7611         case ZBEE_ZCL_ATTR_ID_BINARY_VALUE_BASIC_APPLICATION_TYPE:
7612         default:
7613             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
7614             break;
7615     }
7616 
7617 } /*dissect_zcl_binary_value_basic_attr_data*/
7618 
7619 
7620 /*FUNCTION:------------------------------------------------------
7621  *  NAME
7622  *      proto_register_zbee_zcl_binary_value_basic
7623  *  DESCRIPTION
7624  *      ZigBee ZCL Binary Value Basic cluster protocol registration routine.
7625  *  PARAMETERS
7626  *      none
7627  *  RETURNS
7628  *      none
7629  *---------------------------------------------------------------
7630  */
7631 void
proto_register_zbee_zcl_binary_value_basic(void)7632 proto_register_zbee_zcl_binary_value_basic(void)
7633 {
7634     /* Setup list of header fields */
7635     static hf_register_info hf[] = {
7636 
7637         { &hf_zbee_zcl_binary_value_basic_attr_id,
7638             { "Attribute", "zbee_zcl_general.binary_value_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_binary_value_basic_attr_names),
7639             0x00, NULL, HFILL } },
7640 
7641         { &hf_zbee_zcl_binary_value_basic_reliability,
7642             { "Reliability", "zbee_zcl_general.binary_value_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
7643             0x00, NULL, HFILL } },
7644 
7645         /* start Status Flags fields */
7646         { &hf_zbee_zcl_binary_value_basic_status_flags,
7647             { "Status Flags", "zbee_zcl_general.binary_value_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
7648             0x00, NULL, HFILL } },
7649 
7650         { &hf_zbee_zcl_binary_value_basic_status_in_alarm,
7651             { "In Alarm Status", "zbee_zcl_general.binary_value_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7652             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
7653 
7654         { &hf_zbee_zcl_binary_value_basic_status_fault,
7655             { "Fault Status", "zbee_zcl_general.binary_value_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7656             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
7657 
7658         { &hf_zbee_zcl_binary_value_basic_status_overridden,
7659             { "Overridden Status", "zbee_zcl_general.binary_value_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7660             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
7661 
7662         { &hf_zbee_zcl_binary_value_basic_status_out_of_service,
7663             { "Out of Service Status", "zbee_zcl_general.binary_value_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7664             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } },
7665         /* end Status Flags fields */
7666 
7667         { &hf_zbee_zcl_binary_value_basic_priority_array_bool,
7668             { "Valid/Invalid", "zbee_zcl_general.binary_value_basic.attr.priority_array.bool", FT_BOOLEAN, 8,TFS(&tfs_invalid_valid),
7669             0x00, NULL, HFILL } },
7670 
7671         { &hf_zbee_zcl_binary_value_basic_priority_array_sing_prec,
7672             { "Priority Value", "zbee_zcl_general.binary_value_basic.attr.priority_array.sing_prec", FT_UINT16, BASE_HEX, NULL,
7673             0x00, NULL, HFILL } },
7674 
7675         { &hf_zbee_zcl_binary_value_basic_priority_array,
7676             { "Priority Array", "zbee_zcl_general.binary_value_basic.priority_array", FT_NONE, BASE_NONE, NULL,
7677             0x00, NULL, HFILL } },
7678 
7679         { &hf_zbee_zcl_binary_value_basic_structure,
7680             { "Structure", "zbee_zcl_general.binary_value_basic.structure", FT_NONE, BASE_NONE, NULL,
7681             0x00, NULL, HFILL } }
7682     };
7683 
7684     /* ZCL Binary Value Basic subtrees */
7685     static gint *ett[] = {
7686         &ett_zbee_zcl_binary_value_basic,
7687         &ett_zbee_zcl_binary_value_basic_status_flags,
7688         &ett_zbee_zcl_binary_value_basic_priority_array,
7689         &ett_zbee_zcl_binary_value_basic_priority_array_structure
7690     };
7691 
7692     /* Register the ZigBee ZCL Binary Value Basic cluster protocol name and description */
7693     proto_zbee_zcl_binary_value_basic = proto_register_protocol("ZigBee ZCL Binary Value Basic", "ZCL Binary Value Basic", ZBEE_PROTOABBREV_ZCL_BINARY_VALUE_BASIC);
7694     proto_register_field_array(proto_zbee_zcl_binary_value_basic, hf, array_length(hf));
7695     proto_register_subtree_array(ett, array_length(ett));
7696 
7697     /* Register the ZigBee ZCL Binary Value Basic dissector. */
7698     register_dissector(ZBEE_PROTOABBREV_ZCL_BINARY_VALUE_BASIC, dissect_zbee_zcl_binary_value_basic, proto_zbee_zcl_binary_value_basic);
7699 } /*proto_register_zbee_zcl_binary_value_basic*/
7700 
7701 /*FUNCTION:------------------------------------------------------
7702  *  NAME
7703  *      proto_reg_handoff_zbee_zcl_binary_value_basic
7704  *  DESCRIPTION
7705  *      Hands off the ZCL Binary Value Basic dissector.
7706  *  PARAMETERS
7707  *      none
7708  *  RETURNS
7709  *      none
7710  *---------------------------------------------------------------
7711  */
7712 void
proto_reg_handoff_zbee_zcl_binary_value_basic(void)7713 proto_reg_handoff_zbee_zcl_binary_value_basic(void)
7714 {
7715     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_BINARY_VALUE_BASIC,
7716                             proto_zbee_zcl_binary_value_basic,
7717                             ett_zbee_zcl_binary_value_basic,
7718                             ZBEE_ZCL_CID_BINARY_VALUE_BASIC,
7719                             ZBEE_MFG_CODE_NONE,
7720                             hf_zbee_zcl_binary_value_basic_attr_id,
7721                             hf_zbee_zcl_binary_value_basic_attr_id,
7722                             -1, -1,
7723                             (zbee_zcl_fn_attr_data)dissect_zcl_binary_value_basic_attr_data
7724                          );
7725 } /*proto_reg_handoff_zbee_zcl_binary_value_basic*/
7726 
7727 
7728 /* ########################################################################## */
7729 /* #### (0x0012) MULTISTATE INPUT (BASIC) CLUSTER ########################### */
7730 /* ########################################################################## */
7731 
7732 /*************************/
7733 /* Defines               */
7734 /*************************/
7735 
7736 /*Attributes*/
7737 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_STATE_TEXT                      0x000E  /* State Text */
7738 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_DESCRIPTION                     0x001C  /* Description */
7739 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_NUMBER_OF_STATES                0x004A  /* Number of States */
7740 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
7741 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
7742 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_RELIABILITY                     0x0067  /* Reliability */
7743 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
7744 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
7745 
7746 /*Server commands received - none*/
7747 
7748 /*Server commands generated - none*/
7749 
7750 /*************************/
7751 /* Function Declarations */
7752 /*************************/
7753 
7754 void proto_register_zbee_zcl_multistate_input_basic(void);
7755 void proto_reg_handoff_zbee_zcl_multistate_input_basic(void);
7756 
7757 /* Command Dissector Helpers */
7758 static void dissect_zcl_multistate_input_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
7759 
7760 /* Private functions prototype */
7761 
7762 /*************************/
7763 /* Global Variables      */
7764 /*************************/
7765 /* Initialize the protocol and registered fields */
7766 static int proto_zbee_zcl_multistate_input_basic = -1;
7767 
7768 static int hf_zbee_zcl_multistate_input_basic_attr_id = -1;
7769 static int hf_zbee_zcl_multistate_input_basic_status_flags = -1;
7770 static int hf_zbee_zcl_multistate_input_basic_status_in_alarm = -1;
7771 static int hf_zbee_zcl_multistate_input_basic_status_fault = -1;
7772 static int hf_zbee_zcl_multistate_input_basic_status_overridden = -1;
7773 static int hf_zbee_zcl_multistate_input_basic_status_out_of_service = -1;
7774 static int hf_zbee_zcl_multistate_input_basic_reliability = -1;
7775 
7776 /* Initialize the subtree pointers */
7777 static gint ett_zbee_zcl_multistate_input_basic = -1;
7778 static gint ett_zbee_zcl_multistate_input_basic_status_flags = -1;
7779 
7780 /* Attributes */
7781 static const value_string zbee_zcl_multistate_input_basic_attr_names[] = {
7782     { ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_STATE_TEXT,           "State Text" },
7783     { ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_DESCRIPTION,          "Description" },
7784     { ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_NUMBER_OF_STATES,     "Number of States" },
7785     { ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_OUT_OF_SERVICE,       "Out of Service" },
7786     { ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_PRESENT_VALUE,        "Present Value" },
7787     { ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_RELIABILITY,          "Reliability" },
7788     { ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_STATUS_FLAGS,         "Status Flags" },
7789     { ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_APPLICATION_TYPE,     "Application Type" },
7790     { 0, NULL }
7791 };
7792 
7793 /*************************/
7794 /* Function Bodies       */
7795 /*************************/
7796 
7797 /*FUNCTION:------------------------------------------------------
7798  *  NAME
7799  *      dissect_zbee_zcl_multistate_input_basic
7800  *  DESCRIPTION
7801  *      ZigBee ZCL Multistate Input Basic cluster dissector for wireshark.
7802  *  PARAMETERS
7803  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
7804  *      packet_info *pinfo  - pointer to packet information fields
7805  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
7806  *  RETURNS
7807  *      none
7808  *---------------------------------------------------------------
7809  */
7810 
7811 static int
dissect_zbee_zcl_multistate_input_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)7812 dissect_zbee_zcl_multistate_input_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
7813 {
7814     return tvb_captured_length(tvb);
7815 } /*dissect_zbee_zcl_multistate_input_basic*/
7816 
7817 
7818 /*FUNCTION:------------------------------------------------------
7819  *  NAME
7820  *      dissect_zcl_multistate_input_basic_attr_data
7821  *  DESCRIPTION
7822  *      this function is called by ZCL foundation dissector in order to decode
7823  *      specific cluster attributes data.
7824  *  PARAMETERS
7825  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
7826  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
7827  *      guint *offset       - pointer to buffer offset
7828  *      guint16 attr_id     - attribute identifier
7829  *      guint data_type     - attribute data type
7830  *      gboolean client_attr- ZCL client
7831  *  RETURNS
7832  *      none
7833  *---------------------------------------------------------------
7834  */
7835 void
dissect_zcl_multistate_input_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)7836 dissect_zcl_multistate_input_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
7837 {
7838     static int * const status_flags[] = {
7839         &hf_zbee_zcl_multistate_input_basic_status_in_alarm,
7840         &hf_zbee_zcl_multistate_input_basic_status_fault,
7841         &hf_zbee_zcl_multistate_input_basic_status_overridden,
7842         &hf_zbee_zcl_multistate_input_basic_status_out_of_service,
7843         NULL
7844     };
7845 
7846     /* Dissect attribute data type and data */
7847     switch (attr_id) {
7848 
7849         case ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_RELIABILITY:
7850             proto_tree_add_item(tree, hf_zbee_zcl_multistate_input_basic_reliability, tvb, *offset, 1, ENC_NA);
7851             *offset += 1;
7852             break;
7853 
7854         case ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_STATUS_FLAGS:
7855             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_multistate_input_basic_status_flags, ett_zbee_zcl_multistate_input_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
7856             *offset += 1;
7857             break;
7858 
7859         case ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_DESCRIPTION:
7860         case ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_NUMBER_OF_STATES:
7861         case ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_OUT_OF_SERVICE:
7862         case ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_PRESENT_VALUE:
7863         case ZBEE_ZCL_ATTR_ID_MULTISTATE_INPUT_BASIC_APPLICATION_TYPE:
7864         default:
7865             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
7866             break;
7867     }
7868 
7869 } /*dissect_zcl_multistate_input_basic_attr_data*/
7870 
7871 
7872 /*FUNCTION:------------------------------------------------------
7873  *  NAME
7874  *      proto_register_zbee_zcl_multistate_input_basic
7875  *  DESCRIPTION
7876  *      ZigBee ZCL Multistate Input Basic cluster protocol registration routine.
7877  *  PARAMETERS
7878  *      none
7879  *  RETURNS
7880  *      void
7881  *---------------------------------------------------------------
7882  */
7883 void
proto_register_zbee_zcl_multistate_input_basic(void)7884 proto_register_zbee_zcl_multistate_input_basic(void)
7885 {
7886     /* Setup list of header fields */
7887     static hf_register_info hf[] = {
7888 
7889         { &hf_zbee_zcl_multistate_input_basic_attr_id,
7890             { "Attribute", "zbee_zcl_general.multistate_input_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_multistate_input_basic_attr_names),
7891             0x00, NULL, HFILL } },
7892 
7893         { &hf_zbee_zcl_multistate_input_basic_reliability,
7894             { "Reliability", "zbee_zcl_general.multistate_input_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
7895             0x00, NULL, HFILL } },
7896 
7897         /* start Status Flags fields */
7898         { &hf_zbee_zcl_multistate_input_basic_status_flags,
7899             { "Status Flags", "zbee_zcl_general.multistate_input_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
7900             0x00, NULL, HFILL } },
7901 
7902         { &hf_zbee_zcl_multistate_input_basic_status_in_alarm,
7903             { "In Alarm Status", "zbee_zcl_general.multistate_input_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7904             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
7905 
7906         { &hf_zbee_zcl_multistate_input_basic_status_fault,
7907             { "Fault Status", "zbee_zcl_general.multistate_input_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7908             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
7909 
7910         { &hf_zbee_zcl_multistate_input_basic_status_overridden,
7911             { "Overridden Status", "zbee_zcl_general.multistate_input_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7912             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
7913 
7914         { &hf_zbee_zcl_multistate_input_basic_status_out_of_service,
7915             { "Out of Service Status", "zbee_zcl_general.multistate_input_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
7916             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } }
7917         /* end Status Flags fields */
7918     };
7919 
7920     /* ZCL Multistate Input Basic subtrees */
7921     static gint *ett[] = {
7922         &ett_zbee_zcl_multistate_input_basic,
7923         &ett_zbee_zcl_multistate_input_basic_status_flags
7924     };
7925 
7926     /* Register the ZigBee ZCL Multistate Input Basic cluster protocol name and description */
7927     proto_zbee_zcl_multistate_input_basic = proto_register_protocol("ZigBee ZCL Multistate Input Basic", "ZCL Multistate Input Basic", ZBEE_PROTOABBREV_ZCL_MULTISTATE_INPUT_BASIC);
7928     proto_register_field_array(proto_zbee_zcl_multistate_input_basic, hf, array_length(hf));
7929     proto_register_subtree_array(ett, array_length(ett));
7930 
7931     /* Register the ZigBee ZCL Multistate Input Basic dissector. */
7932     register_dissector(ZBEE_PROTOABBREV_ZCL_MULTISTATE_INPUT_BASIC, dissect_zbee_zcl_multistate_input_basic, proto_zbee_zcl_multistate_input_basic);
7933 } /*proto_register_zbee_zcl_multistate_input_basic*/
7934 
7935 /*FUNCTION:------------------------------------------------------
7936  *  NAME
7937  *      proto_reg_handoff_zbee_zcl_multistate_input_basic
7938  *  DESCRIPTION
7939  *      Hands off the ZCL Multistate Input Basic dissector.
7940  *  PARAMETERS
7941  *      none
7942  *  RETURNS
7943  *      none
7944  *---------------------------------------------------------------
7945  */
7946 void
proto_reg_handoff_zbee_zcl_multistate_input_basic(void)7947 proto_reg_handoff_zbee_zcl_multistate_input_basic(void)
7948 {
7949     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_MULTISTATE_INPUT_BASIC,
7950                             proto_zbee_zcl_multistate_input_basic,
7951                             ett_zbee_zcl_multistate_input_basic,
7952                             ZBEE_ZCL_CID_MULTISTATE_INPUT_BASIC,
7953                             ZBEE_MFG_CODE_NONE,
7954                             hf_zbee_zcl_multistate_input_basic_attr_id,
7955                             hf_zbee_zcl_multistate_input_basic_attr_id,
7956                             -1, -1,
7957                             (zbee_zcl_fn_attr_data)dissect_zcl_multistate_input_basic_attr_data
7958                          );
7959 } /*proto_reg_handoff_zbee_zcl_multistate_input_basic*/
7960 
7961 
7962 /* ########################################################################## */
7963 /* #### (0x0013) MULTISTATE OUTPUT (BASIC) CLUSTER ########################## */
7964 /* ########################################################################## */
7965 
7966 /*************************/
7967 /* Defines               */
7968 /*************************/
7969 
7970 /*Attributes*/
7971 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_STATE_TEXT                      0x000E  /* State Text */
7972 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_DESCRIPTION                     0x001C  /* Description */
7973 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_NUMBER_OF_STATES                0x004A  /* Number of States */
7974 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
7975 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
7976 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_PRIORITY_ARRAY                  0x0057  /* Priority Array */
7977 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_RELIABILITY                     0x0067  /* Reliability */
7978 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_RELINQUISH_DEFAULT              0x0068  /* Relinquish Default */
7979 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
7980 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
7981 
7982 /*Server commands received - none*/
7983 
7984 /*Server commands generated - none*/
7985 
7986 /*************************/
7987 /* Function Declarations */
7988 /*************************/
7989 
7990 void proto_register_zbee_zcl_multistate_output_basic(void);
7991 void proto_reg_handoff_zbee_zcl_multistate_output_basic(void);
7992 
7993 /* Command Dissector Helpers */
7994 static void dissect_zcl_multistate_output_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
7995 
7996 /* Private functions prototype */
7997 
7998 /*************************/
7999 /* Global Variables      */
8000 /*************************/
8001 /* Initialize the protocol and registered fields */
8002 static int proto_zbee_zcl_multistate_output_basic = -1;
8003 
8004 static int hf_zbee_zcl_multistate_output_basic_attr_id = -1;
8005 static int hf_zbee_zcl_multistate_output_basic_status_flags = -1;
8006 static int hf_zbee_zcl_multistate_output_basic_status_in_alarm = -1;
8007 static int hf_zbee_zcl_multistate_output_basic_status_fault = -1;
8008 static int hf_zbee_zcl_multistate_output_basic_status_overridden = -1;
8009 static int hf_zbee_zcl_multistate_output_basic_status_out_of_service = -1;
8010 static int hf_zbee_zcl_multistate_output_basic_reliability = -1;
8011 static int hf_zbee_zcl_multistate_output_basic_priority_array_bool = -1;
8012 static int hf_zbee_zcl_multistate_output_basic_priority_array_sing_prec = -1;
8013 static int hf_zbee_zcl_multistate_output_basic_priority_array = -1;
8014 static int hf_zbee_zcl_multistate_output_basic_structure = -1;
8015 
8016 /* Initialize the subtree pointers */
8017 static gint ett_zbee_zcl_multistate_output_basic = -1;
8018 static gint ett_zbee_zcl_multistate_output_basic_status_flags = -1;
8019 static gint ett_zbee_zcl_multistate_output_basic_priority_array = -1;
8020 static gint ett_zbee_zcl_multistate_output_basic_priority_array_structure = -1;
8021 
8022 /* Attributes */
8023 static const value_string zbee_zcl_multistate_output_basic_attr_names[] = {
8024     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_STATE_TEXT,           "State Text" },
8025     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_DESCRIPTION,          "Description" },
8026     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_NUMBER_OF_STATES,     "Number of States" },
8027     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_OUT_OF_SERVICE,       "Out of Service" },
8028     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_PRESENT_VALUE,        "Present Value" },
8029     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_PRIORITY_ARRAY,       "Priority Array" },
8030     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_RELIABILITY,          "Reliability" },
8031     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_RELINQUISH_DEFAULT,   "Relinquish Default" },
8032     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_STATUS_FLAGS,         "Status Flags" },
8033     { ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_APPLICATION_TYPE,     "Application Type" },
8034     { 0, NULL }
8035 };
8036 
8037 static const value_string zbee_zcl_multistate_output_basic_priority_array_bool_values[] = {
8038     { 0x01, "Valid" },
8039     { 0x00, "Invalid" },
8040     { 0, NULL }
8041 };
8042 
8043 /*************************/
8044 /* Function Bodies       */
8045 /*************************/
8046 
8047 /*FUNCTION:------------------------------------------------------
8048  *  NAME
8049  *      dissect_zbee_zcl_multistate_output_basic
8050  *  DESCRIPTION
8051  *      ZigBee ZCL Multistate Output Basic cluster dissector for wireshark.
8052  *  PARAMETERS
8053  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
8054  *      packet_info *pinfo  - pointer to packet information fields
8055  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
8056  *  RETURNS
8057  *      none
8058  *---------------------------------------------------------------
8059  */
8060 
8061 static int
dissect_zbee_zcl_multistate_output_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)8062 dissect_zbee_zcl_multistate_output_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
8063 {
8064     return tvb_captured_length(tvb);
8065 } /*dissect_zbee_zcl_multistate_output_basic*/
8066 
8067 
8068 /*FUNCTION:------------------------------------------------------
8069  *  NAME
8070  *      dissect_zcl_multistate_output_basic_attr_data
8071  *  DESCRIPTION
8072  *      this function is called by ZCL foundation dissector in order to decode
8073  *      specific cluster attributes data.
8074  *  PARAMETERS
8075  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
8076  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
8077  *      guint *offset       - pointer to buffer offset
8078  *      guint16 attr_id     - attribute identifier
8079  *      guint data_type     - attribute data type
8080  *      gboolean client_attr- ZCL client
8081  *  RETURNS
8082  *      none
8083  *---------------------------------------------------------------
8084  */
8085 void
dissect_zcl_multistate_output_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)8086 dissect_zcl_multistate_output_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
8087 {
8088     proto_item  *ti = NULL, *tj = NULL;
8089     proto_tree  *sub_tree = NULL, *sub = NULL;
8090     int i;
8091 
8092     static int * const status_flags[] = {
8093         &hf_zbee_zcl_multistate_output_basic_status_in_alarm,
8094         &hf_zbee_zcl_multistate_output_basic_status_fault,
8095         &hf_zbee_zcl_multistate_output_basic_status_overridden,
8096         &hf_zbee_zcl_multistate_output_basic_status_out_of_service,
8097         NULL
8098     };
8099 
8100     /* Dissect attribute data type and data */
8101     switch (attr_id) {
8102 
8103         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_PRIORITY_ARRAY:
8104             ti = proto_tree_add_item(tree,hf_zbee_zcl_multistate_output_basic_priority_array, tvb, *offset, 80, ENC_NA);
8105             sub_tree = proto_item_add_subtree(ti, ett_zbee_zcl_multistate_output_basic_priority_array);
8106 
8107             for( i = 1; i <= 16; i++)
8108             {
8109                 tj = proto_tree_add_item(sub_tree, hf_zbee_zcl_multistate_output_basic_structure, tvb, *offset, 5, ENC_NA);
8110                 proto_item_append_text(tj," %d",i);
8111                 sub = proto_item_add_subtree(tj, ett_zbee_zcl_multistate_output_basic_priority_array_structure);
8112                 proto_tree_add_item(sub, hf_zbee_zcl_multistate_output_basic_priority_array_bool, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8113                 *offset += 1;
8114                 proto_tree_add_item(sub, hf_zbee_zcl_multistate_output_basic_priority_array_sing_prec, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
8115                 *offset += 4;
8116             }
8117             break;
8118 
8119         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_RELIABILITY:
8120             proto_tree_add_item(tree, hf_zbee_zcl_multistate_output_basic_reliability, tvb, *offset, 1, ENC_NA);
8121             *offset += 1;
8122             break;
8123 
8124         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_STATUS_FLAGS:
8125             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_multistate_output_basic_status_flags, ett_zbee_zcl_multistate_output_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
8126             *offset += 1;
8127             break;
8128 
8129         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_DESCRIPTION:
8130         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_NUMBER_OF_STATES:
8131         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_OUT_OF_SERVICE:
8132         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_RELINQUISH_DEFAULT:
8133         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_PRESENT_VALUE:
8134         case ZBEE_ZCL_ATTR_ID_MULTISTATE_OUTPUT_BASIC_APPLICATION_TYPE:
8135         default:
8136             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
8137             break;
8138     }
8139 
8140 } /*dissect_zcl_multistate_output_basic_attr_data*/
8141 
8142 
8143 /*FUNCTION:------------------------------------------------------
8144  *  NAME
8145  *      proto_register_zbee_zcl_multistate_output_basic
8146  *  DESCRIPTION
8147  *      ZigBee ZCL Multistate Output Basic cluster protocol registration routine.
8148  *  PARAMETERS
8149  *      none
8150  *  RETURNS
8151  *      void
8152  *---------------------------------------------------------------
8153  */
8154 void
proto_register_zbee_zcl_multistate_output_basic(void)8155 proto_register_zbee_zcl_multistate_output_basic(void)
8156 {
8157     /* Setup list of header fields */
8158     static hf_register_info hf[] = {
8159 
8160         { &hf_zbee_zcl_multistate_output_basic_attr_id,
8161             { "Attribute", "zbee_zcl_general.multistate_output_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_multistate_output_basic_attr_names),
8162             0x00, NULL, HFILL } },
8163 
8164         { &hf_zbee_zcl_multistate_output_basic_reliability,
8165             { "Reliability", "zbee_zcl_general.multistate_output_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
8166             0x00, NULL, HFILL } },
8167 
8168         /* start Status Flags fields */
8169         { &hf_zbee_zcl_multistate_output_basic_status_flags,
8170             { "Status Flags", "zbee_zcl_general.multistate_output_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
8171             0x00, NULL, HFILL } },
8172 
8173         { &hf_zbee_zcl_multistate_output_basic_status_in_alarm,
8174             { "In Alarm Status", "zbee_zcl_general.multistate_output_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
8175             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
8176 
8177         { &hf_zbee_zcl_multistate_output_basic_status_fault,
8178             { "Fault Status", "zbee_zcl_general.multistate_output_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
8179             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
8180 
8181         { &hf_zbee_zcl_multistate_output_basic_status_overridden,
8182             { "Overridden Status", "zbee_zcl_general.multistate_output_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
8183             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
8184 
8185         { &hf_zbee_zcl_multistate_output_basic_status_out_of_service,
8186             { "Out of Service Status", "zbee_zcl_general.multistate_output_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
8187             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } },
8188         /* end Status Flags fields */
8189 
8190         { &hf_zbee_zcl_multistate_output_basic_priority_array_bool,
8191             { "Valid/Invalid", "zbee_zcl_general.multistate_output_basic.attr.priority_array.bool", FT_UINT8, BASE_HEX, VALS(zbee_zcl_multistate_output_basic_priority_array_bool_values),
8192             0x00, NULL, HFILL } },
8193 
8194         { &hf_zbee_zcl_multistate_output_basic_priority_array_sing_prec,
8195             { "Priority Value", "zbee_zcl_general.multistate_output_basic.attr.priority_array.sing_prec", FT_UINT16, BASE_HEX, NULL,
8196             0x00, NULL, HFILL } } ,
8197 
8198         { &hf_zbee_zcl_multistate_output_basic_priority_array,
8199             { "Priority Array", "zbee_zcl_general.multistate_output_basic.priority_array", FT_NONE, BASE_NONE, NULL,
8200             0x00, NULL, HFILL } },
8201 
8202         { &hf_zbee_zcl_multistate_output_basic_structure,
8203             { "Structure", "zbee_zcl_general.multistate_output_basic.structure", FT_NONE, BASE_NONE, NULL,
8204             0x00, NULL, HFILL } }
8205 };
8206 
8207     /* ZCL Multistate Output Basic subtrees */
8208     static gint *ett[] = {
8209         &ett_zbee_zcl_multistate_output_basic,
8210         &ett_zbee_zcl_multistate_output_basic_status_flags,
8211         &ett_zbee_zcl_multistate_output_basic_priority_array,
8212         &ett_zbee_zcl_multistate_output_basic_priority_array_structure
8213     };
8214 
8215     /* Register the ZigBee ZCL Multistate Output Basic cluster protocol name and description */
8216     proto_zbee_zcl_multistate_output_basic = proto_register_protocol("ZigBee ZCL Multistate Output Basic", "ZCL Multistate Output Basic", ZBEE_PROTOABBREV_ZCL_MULTISTATE_OUTPUT_BASIC);
8217     proto_register_field_array(proto_zbee_zcl_multistate_output_basic, hf, array_length(hf));
8218     proto_register_subtree_array(ett, array_length(ett));
8219 
8220     /* Register the ZigBee ZCL Multistate Output Basic dissector. */
8221     register_dissector(ZBEE_PROTOABBREV_ZCL_MULTISTATE_OUTPUT_BASIC, dissect_zbee_zcl_multistate_output_basic, proto_zbee_zcl_multistate_output_basic);
8222 } /*proto_register_zbee_zcl_multistate_output_basic*/
8223 
8224 /*FUNCTION:------------------------------------------------------
8225  *  NAME
8226  *      proto_reg_handoff_zbee_zcl_multistate_output_basic
8227  *  DESCRIPTION
8228  *      Hands off the ZCL Multistate Output Basic dissector.
8229  *  PARAMETERS
8230  *      none
8231  *  RETURNS
8232  *      none
8233  *---------------------------------------------------------------
8234  */
8235 void
proto_reg_handoff_zbee_zcl_multistate_output_basic(void)8236 proto_reg_handoff_zbee_zcl_multistate_output_basic(void)
8237 {
8238     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_MULTISTATE_OUTPUT_BASIC,
8239                             proto_zbee_zcl_multistate_output_basic,
8240                             ett_zbee_zcl_multistate_output_basic,
8241                             ZBEE_ZCL_CID_MULTISTATE_OUTPUT_BASIC,
8242                             ZBEE_MFG_CODE_NONE,
8243                             hf_zbee_zcl_multistate_output_basic_attr_id,
8244                             hf_zbee_zcl_multistate_output_basic_attr_id,
8245                             -1,-1,
8246                             (zbee_zcl_fn_attr_data)dissect_zcl_multistate_output_basic_attr_data
8247                          );
8248 } /*proto_reg_handoff_zbee_zcl_multistate_output_basic*/
8249 
8250 
8251 /* ########################################################################## */
8252 /* #### (0x0014) MULTISTATE VALUE (BASIC) CLUSTER ########################### */
8253 /* ########################################################################## */
8254 
8255 /*************************/
8256 /* Defines               */
8257 /*************************/
8258 
8259 /*Attributes*/
8260 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_STATE_TEXT                      0x000E  /* State Text */
8261 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_DESCRIPTION                     0x001C  /* Description */
8262 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_NUMBER_OF_STATES                0x004A  /* Number of States */
8263 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_OUT_OF_SERVICE                  0x0051  /* Out of Service */
8264 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_PRESENT_VALUE                   0x0055  /* Present Value */
8265 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_PRIORITY_ARRAY                  0x0057  /* Priority Array */
8266 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_RELIABILITY                     0x0067  /* Reliability */
8267 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_RELINQUISH_DEFAULT              0x0068  /* Relinquish Default */
8268 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_STATUS_FLAGS                    0x006F  /* Status Flags */
8269 #define ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_APPLICATION_TYPE                0x0100  /* Application Type */
8270 
8271 /*Server commands received - none*/
8272 
8273 /*Server commands generated - none*/
8274 
8275 /*************************/
8276 /* Function Declarations */
8277 /*************************/
8278 
8279 void proto_register_zbee_zcl_multistate_value_basic(void);
8280 void proto_reg_handoff_zbee_zcl_multistate_value_basic(void);
8281 
8282 /* Command Dissector Helpers */
8283 static void dissect_zcl_multistate_value_basic_attr_data      (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
8284 
8285 /* Private functions prototype */
8286 
8287 /*************************/
8288 /* Global Variables      */
8289 /*************************/
8290 /* Initialize the protocol and registered fields */
8291 static int proto_zbee_zcl_multistate_value_basic = -1;
8292 
8293 static int hf_zbee_zcl_multistate_value_basic_attr_id = -1;
8294 static int hf_zbee_zcl_multistate_value_basic_status_flags = -1;
8295 static int hf_zbee_zcl_multistate_value_basic_status_in_alarm = -1;
8296 static int hf_zbee_zcl_multistate_value_basic_status_fault = -1;
8297 static int hf_zbee_zcl_multistate_value_basic_status_overridden = -1;
8298 static int hf_zbee_zcl_multistate_value_basic_status_out_of_service = -1;
8299 static int hf_zbee_zcl_multistate_value_basic_reliability = -1;
8300 static int hf_zbee_zcl_multistate_value_basic_priority_array_bool = -1;
8301 static int hf_zbee_zcl_multistate_value_basic_priority_array_sing_prec = -1;
8302 static int hf_zbee_zcl_multistate_value_basic_priority_array = -1;
8303 static int hf_zbee_zcl_multistate_value_basic_structure = -1;
8304 
8305 
8306 /* Initialize the subtree pointers */
8307 static gint ett_zbee_zcl_multistate_value_basic = -1;
8308 static gint ett_zbee_zcl_multistate_value_basic_status_flags = -1;
8309 static gint ett_zbee_zcl_multistate_value_basic_priority_array = -1;
8310 static gint ett_zbee_zcl_multistate_value_basic_priority_array_structure = -1;
8311 
8312 /* Attributes */
8313 static const value_string zbee_zcl_multistate_value_basic_attr_names[] = {
8314     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_STATE_TEXT,           "State Text" },
8315     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_DESCRIPTION,          "Description" },
8316     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_NUMBER_OF_STATES,     "Number of States" },
8317     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_OUT_OF_SERVICE,       "Out of Service" },
8318     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_PRESENT_VALUE,        "Present Value" },
8319     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_PRIORITY_ARRAY,       "Priority Array" },
8320     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_RELIABILITY,          "Reliability" },
8321     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_RELINQUISH_DEFAULT,   "Relinquish Default" },
8322     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_STATUS_FLAGS,         "Status Flags" },
8323     { ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_APPLICATION_TYPE,     "Application Type" },
8324     { 0, NULL }
8325 };
8326 
8327 static const value_string zbee_zcl_multistate_value_basic_priority_array_bool_values[] = {
8328     { 0x01, "Valid" },
8329     { 0x00, "Invalid" },
8330     { 0, NULL }
8331 };
8332 
8333 /*************************/
8334 /* Function Bodies       */
8335 /*************************/
8336 
8337 /*FUNCTION:------------------------------------------------------
8338  *  NAME
8339  *      dissect_zbee_zcl_multistate_value_basic
8340  *  DESCRIPTION
8341  *      ZigBee ZCL Multistate Value Basic cluster dissector for wireshark.
8342  *  PARAMETERS
8343  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
8344  *      packet_info *pinfo  - pointer to packet information fields
8345  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
8346  *  RETURNS
8347  *      none
8348  *---------------------------------------------------------------
8349  */
8350 
8351 static int
dissect_zbee_zcl_multistate_value_basic(tvbuff_t * tvb _U_,packet_info * pinfo _U_,proto_tree * tree _U_,void * data _U_)8352 dissect_zbee_zcl_multistate_value_basic(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
8353 {
8354     return tvb_captured_length(tvb);
8355 } /*dissect_zbee_zcl_multistate_value_basic*/
8356 
8357 
8358 /*FUNCTION:------------------------------------------------------
8359  *  NAME
8360  *      dissect_zcl_multistate_value_basic_attr_data
8361  *  DESCRIPTION
8362  *      this function is called by ZCL foundation dissector in order to decode
8363  *      specific cluster attributes data.
8364  *  PARAMETERS
8365  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
8366  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
8367  *      guint *offset       - pointer to buffer offset
8368  *      guint16 attr_id     - attribute identifier
8369  *      guint data_type     - attribute data type
8370  *      gboolean client_attr- ZCL client
8371  *  RETURNS
8372  *      none
8373  *---------------------------------------------------------------
8374  */
8375 void
dissect_zcl_multistate_value_basic_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)8376 dissect_zcl_multistate_value_basic_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
8377 {
8378     proto_item  *ti = NULL, *tj = NULL;
8379     proto_tree  *sub_tree = NULL, *sub = NULL;
8380     int i;
8381 
8382     static int * const status_flags[] = {
8383         &hf_zbee_zcl_multistate_value_basic_status_in_alarm,
8384         &hf_zbee_zcl_multistate_value_basic_status_fault,
8385         &hf_zbee_zcl_multistate_value_basic_status_overridden,
8386         &hf_zbee_zcl_multistate_value_basic_status_out_of_service,
8387         NULL
8388     };
8389 
8390     /* Dissect attribute data type and data */
8391     switch (attr_id) {
8392 
8393         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_PRIORITY_ARRAY:
8394             ti = proto_tree_add_item(tree,hf_zbee_zcl_multistate_value_basic_priority_array, tvb, *offset, 80, ENC_NA);
8395             sub_tree = proto_item_add_subtree(ti, ett_zbee_zcl_multistate_value_basic_priority_array);
8396 
8397             for( i = 1; i <= 16; i++)
8398             {
8399                 tj = proto_tree_add_item(sub_tree,hf_zbee_zcl_multistate_value_basic_structure, tvb, *offset, 5,ENC_NA);
8400                 proto_item_append_text(tj," %d",i);
8401                 sub = proto_item_add_subtree(tj, ett_zbee_zcl_multistate_value_basic_priority_array_structure);
8402                 proto_tree_add_item(sub, hf_zbee_zcl_multistate_value_basic_priority_array_bool, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8403                 *offset += 1;
8404                 proto_tree_add_item(sub, hf_zbee_zcl_multistate_value_basic_priority_array_sing_prec, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
8405                 *offset += 4;
8406             }
8407             break;
8408 
8409         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_RELIABILITY:
8410             proto_tree_add_item(tree, hf_zbee_zcl_multistate_value_basic_reliability, tvb, *offset, 1, ENC_NA);
8411             *offset += 1;
8412             break;
8413 
8414         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_STATUS_FLAGS:
8415             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_multistate_value_basic_status_flags, ett_zbee_zcl_multistate_value_basic_status_flags, status_flags, ENC_LITTLE_ENDIAN);
8416             *offset += 1;
8417             break;
8418 
8419         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_DESCRIPTION:
8420         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_NUMBER_OF_STATES:
8421         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_OUT_OF_SERVICE:
8422         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_RELINQUISH_DEFAULT:
8423         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_PRESENT_VALUE:
8424         case ZBEE_ZCL_ATTR_ID_MULTISTATE_VALUE_BASIC_APPLICATION_TYPE:
8425         default:
8426             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
8427             break;
8428     }
8429 
8430 } /*dissect_zcl_multistate_value_basic_attr_data*/
8431 
8432 
8433 /*FUNCTION:------------------------------------------------------
8434  *  NAME
8435  *      proto_register_zbee_zcl_multistate_value_basic
8436  *  DESCRIPTION
8437  *      ZigBee ZCL Multistate Value Basic cluster protocol registration routine.
8438  *  PARAMETERS
8439  *      none
8440  *  RETURNS
8441  *      void
8442  *---------------------------------------------------------------
8443  */
8444 void
proto_register_zbee_zcl_multistate_value_basic(void)8445 proto_register_zbee_zcl_multistate_value_basic(void)
8446 {
8447     /* Setup list of header fields */
8448     static hf_register_info hf[] = {
8449 
8450         { &hf_zbee_zcl_multistate_value_basic_attr_id,
8451             { "Attribute", "zbee_zcl_general.multistate_value_basic.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_multistate_value_basic_attr_names),
8452             0x00, NULL, HFILL } },
8453 
8454         { &hf_zbee_zcl_multistate_value_basic_reliability,
8455             { "Reliability", "zbee_zcl_general.multistate_value_basic.attr.reliability", FT_UINT8, BASE_HEX, VALS(zbee_zcl_reliability_names),
8456             0x00, NULL, HFILL } },
8457 
8458         /* start Status Flags fields */
8459         { &hf_zbee_zcl_multistate_value_basic_status_flags,
8460             { "Status Flags", "zbee_zcl_general.multistate_value_basic.attr.status", FT_UINT8, BASE_HEX, NULL,
8461             0x00, NULL, HFILL } },
8462 
8463         { &hf_zbee_zcl_multistate_value_basic_status_in_alarm,
8464             { "In Alarm Status", "zbee_zcl_general.multistate_value_basic.attr.status.in_alarm", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
8465             ZBEE_ZCL_STATUS_IN_ALARM, NULL, HFILL } },
8466 
8467         { &hf_zbee_zcl_multistate_value_basic_status_fault,
8468             { "Fault Status", "zbee_zcl_general.multistate_value_basic.attr.status.fault", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
8469             ZBEE_ZCL_STATUS_FAULT, NULL, HFILL } },
8470 
8471         { &hf_zbee_zcl_multistate_value_basic_status_overridden,
8472             { "Overridden Status", "zbee_zcl_general.multistate_value_basic.attr.status.overridden", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
8473             ZBEE_ZCL_STATUS_OVERRIDDEN, NULL, HFILL } },
8474 
8475         { &hf_zbee_zcl_multistate_value_basic_status_out_of_service,
8476             { "Out of Service Status", "zbee_zcl_general.multistate_value_basic.attr.status.out_of_service", FT_UINT8, BASE_DEC, VALS(zbee_zcl_status_values),
8477             ZBEE_ZCL_STATUS_OUT_OF_SERVICE, NULL, HFILL } },
8478         /* end Status Flags fields */
8479 
8480         { &hf_zbee_zcl_multistate_value_basic_priority_array_bool,
8481             { "Valid/Invalid", "zbee_zcl_general.multistate_value_basic.attr.priority_array.bool", FT_UINT8, BASE_HEX, VALS(zbee_zcl_multistate_value_basic_priority_array_bool_values),
8482             0x00, NULL, HFILL } },
8483 
8484         { &hf_zbee_zcl_multistate_value_basic_priority_array_sing_prec,
8485             { "Priority Value", "zbee_zcl_general.multistate_value_basic.attr.priority_array.sing_prec", FT_UINT16, BASE_HEX, NULL,
8486             0x00, NULL, HFILL } },
8487 
8488         { &hf_zbee_zcl_multistate_value_basic_priority_array,
8489             { "Priority Array", "zbee_zcl_general.multistate_value_basic.priority_array", FT_NONE, BASE_NONE, NULL,
8490             0x00, NULL, HFILL } },
8491 
8492         { &hf_zbee_zcl_multistate_value_basic_structure,
8493             { "Structure", "zbee_zcl_general.multistate_value_basic.structure", FT_NONE, BASE_NONE, NULL,
8494             0x00, NULL, HFILL } }
8495     };
8496 
8497     /* ZCL Multistate Value Basic subtrees */
8498     static gint *ett[] = {
8499         &ett_zbee_zcl_multistate_value_basic,
8500         &ett_zbee_zcl_multistate_value_basic_status_flags,
8501         &ett_zbee_zcl_multistate_value_basic_priority_array,
8502         &ett_zbee_zcl_multistate_value_basic_priority_array_structure
8503     };
8504 
8505     /* Register the ZigBee ZCL Multistate Value Basic cluster protocol name and description */
8506     proto_zbee_zcl_multistate_value_basic = proto_register_protocol("ZigBee ZCL Multistate Value Basic", "ZCL Multistate Value Basic", ZBEE_PROTOABBREV_ZCL_MULTISTATE_VALUE_BASIC);
8507     proto_register_field_array(proto_zbee_zcl_multistate_value_basic, hf, array_length(hf));
8508     proto_register_subtree_array(ett, array_length(ett));
8509 
8510     /* Register the ZigBee ZCL Multistate Value Basic dissector. */
8511     register_dissector(ZBEE_PROTOABBREV_ZCL_MULTISTATE_VALUE_BASIC, dissect_zbee_zcl_multistate_value_basic, proto_zbee_zcl_multistate_value_basic);
8512 } /*proto_register_zbee_zcl_multistate_value_basic*/
8513 
8514 /*FUNCTION:------------------------------------------------------
8515  *  NAME
8516  *      proto_reg_handoff_zbee_zcl_multistate_value_basic
8517  *  DESCRIPTION
8518  *      Hands off the ZCL Multistate Value Basic dissector.
8519  *  PARAMETERS
8520  *      none
8521  *  RETURNS
8522  *      none
8523  *---------------------------------------------------------------
8524  */
8525 void
proto_reg_handoff_zbee_zcl_multistate_value_basic(void)8526 proto_reg_handoff_zbee_zcl_multistate_value_basic(void)
8527 {
8528     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_MULTISTATE_VALUE_BASIC,
8529                             proto_zbee_zcl_multistate_value_basic,
8530                             ett_zbee_zcl_multistate_value_basic,
8531                             ZBEE_ZCL_CID_MULTISTATE_VALUE_BASIC,
8532                             ZBEE_MFG_CODE_NONE,
8533                             hf_zbee_zcl_multistate_value_basic_attr_id,
8534                             hf_zbee_zcl_multistate_value_basic_attr_id,
8535                             -1, -1,
8536                             (zbee_zcl_fn_attr_data)dissect_zcl_multistate_value_basic_attr_data
8537                          );
8538 } /*proto_reg_handoff_zbee_zcl_multistate_value_basic*/
8539 
8540 /* ########################################################################## */
8541 /* #### (0x0015) COMMISSIONING CLUSTER ###################################### */
8542 /* ########################################################################## */
8543 
8544 /*************************/
8545 /* Defines               */
8546 /*************************/
8547 
8548 /* Attributes */
8549 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_SHORT_ADDRESS                        0x0000  /* Short Address */
8550 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_EXTENDED_PAN_ID                      0x0001  /* Extended PAN Id */
8551 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_PAN_ID                               0x0002  /* PAN Id */
8552 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_CHANNEL_MASK                         0x0003  /* Channel Mask */
8553 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_PROTOCOL_VERSION                     0x0004  /* Protocol Version */
8554 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_STACK_PROFILE                        0x0005  /* Stack Profile */
8555 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_STARTUP_CONTROL                      0x0006  /* Startup Control */
8556 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_TRUST_CENTER_ADDRESS                 0x0010  /* Trust Center Address */
8557 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_TRUST_CENTER_MASTER_KEY              0x0011  /* Trust Center Master Key */
8558 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY                          0x0012  /* Network Key */
8559 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_USE_INSECURE_JOIN                    0x0013  /* Use Insecure Join */
8560 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_PRECONFIGURED_LINK_KEY               0x0014  /* Preconfigured Link Key */
8561 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY_SEQ_NUM                  0x0015  /* Network Key Sequence Number */
8562 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY_TYPE                     0x0016  /* Network Key Type */
8563 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_MANAGER_ADDRESS              0x0017  /* Network Manager Address */
8564 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_SCAN_ATTEMPTS                        0x0020  /* Scan Attempts */
8565 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_TIME_BETWEEN_SCANS                   0x0021  /* Time Between Scans */
8566 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_REJOIN_INTERVAL                      0x0022  /* Rejoin Interval */
8567 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_MAX_REJOIN_INTERVAL                  0x0023  /* Max Rejoin Interval */
8568 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_INDIRECT_POLL_RATE                   0x0030  /* Indirect Poll Rate */
8569 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_PARENT_RETRY_THRESHOLD               0x0031  /* Parent Retry Threshold */
8570 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_FLAG                    0x0040  /* Concentrator Flag */
8571 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_RADIUS                  0x0041  /* Concentrator Radius */
8572 #define ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_DISCOVERY_TIME          0x0042  /* Concentrator Discovery Time */
8573 
8574 /* Server Commands Received */
8575 #define ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTART_DEVICE                        0x00  /* Restart Device */
8576 #define ZBEE_ZCL_CMD_ID_COMMISSIONING_SAVE_STARTUP_PARAMETERS               0x01  /* Save Startup Parameters */
8577 #define ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTORE_STARTUP_PARAMETERS            0x02  /* Restore Startup Parameters */
8578 #define ZBEE_ZCL_CMD_ID_COMMISSIONING_RESET_STARTUP_PARAMETERS              0x03  /* Reset Startup Parameters */
8579 
8580 /* Server Commands Generated */
8581 #define ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTART_DEVICE_RESPONSE               0x00  /* Restart Device Response */
8582 #define ZBEE_ZCL_CMD_ID_COMMISSIONING_SAVE_STARTUP_PARAMETERS_RESPONSE      0x01  /* Save Startup Parameters Response */
8583 #define ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTORE_STARTUP_PARAMETERS_RESPONSE   0x02  /* Restore Startup Parameters Response */
8584 #define ZBEE_ZCL_CMD_ID_COMMISSIONING_RESET_STARTUP_PARAMETERS_RESPONSE     0x03  /* Reset Startup Parameters Response */
8585 
8586 /* Restart Device Options Field Mask Values */
8587 #define ZBEE_ZCL_COMMISSIONING_RESTART_DEVICE_OPTIONS_STARTUP_MODE          0x07
8588 #define ZBEE_ZCL_COMMISSIONING_RESTART_DEVICE_OPTIONS_IMMEDIATE             0x08
8589 #define ZBEE_ZCL_COMMISSIONING_RESTART_DEVICE_OPTIONS_RESERVED              0xF0
8590 
8591 /* Reset Startup Parameters Options Field Mask Values */
8592 #define ZBEE_ZCL_COMMISSIONING_RESET_STARTUP_OPTIONS_RESET_CURRENT          0x01
8593 #define ZBEE_ZCL_COMMISSIONING_RESET_STARTUP_OPTIONS_RESET_ALL              0x02
8594 #define ZBEE_ZCL_COMMISSIONING_RESET_STARTUP_OPTIONS_ERASE_INDEX            0x04
8595 #define ZBEE_ZCL_COMMISSIONING_RESET_STARTUP_OPTIONS_RESERVED               0xFC
8596 
8597 
8598 /*************************/
8599 /* Function Declarations */
8600 /*************************/
8601 
8602 void proto_register_zbee_zcl_commissioning(void);
8603 void proto_reg_handoff_zbee_zcl_commissioning(void);
8604 
8605 /* Command Dissector Helpers */
8606 static void dissect_zcl_commissioning_restart_device                        (tvbuff_t *tvb, proto_tree *tree, guint *offset);
8607 static void dissect_zcl_commissioning_save_restore_startup_parameters       (tvbuff_t *tvb, proto_tree *tree, guint *offset);
8608 static void dissect_zcl_commissioning_reset_startup_parameters              (tvbuff_t *tvb, proto_tree *tree, guint *offset);
8609 static void dissect_zcl_commissioning_response                              (tvbuff_t *tvb, proto_tree *tree, guint *offset);
8610 
8611 static void dissect_zcl_commissioning_attr_data                             (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
8612 
8613 /* Private functions prototype */
8614 
8615 /*************************/
8616 /* Global Variables      */
8617 /*************************/
8618 /* Initialize the protocol and registered fields */
8619 static int proto_zbee_zcl_commissioning = -1;
8620 
8621 static int hf_zbee_zcl_commissioning_attr_id = -1;
8622 static int hf_zbee_zcl_commissioning_attr_stack_profile = -1;
8623 static int hf_zbee_zcl_commissioning_attr_startup_control = -1;
8624 static int hf_zbee_zcl_commissioning_restart_device_options = -1;
8625 static int hf_zbee_zcl_commissioning_restart_device_options_startup_mode = -1;
8626 static int hf_zbee_zcl_commissioning_restart_device_options_immediate = -1;
8627 static int hf_zbee_zcl_commissioning_restart_device_options_reserved = -1;
8628 static int hf_zbee_zcl_commissioning_delay = -1;
8629 static int hf_zbee_zcl_commissioning_jitter = -1;
8630 static int hf_zbee_zcl_commissioning_options = -1;
8631 static int hf_zbee_zcl_commissioning_index = -1;
8632 static int hf_zbee_zcl_commissioning_reset_startup_options = -1;
8633 static int hf_zbee_zcl_commissioning_reset_startup_options_reset_current = -1;
8634 static int hf_zbee_zcl_commissioning_reset_startup_options_reset_all = -1;
8635 static int hf_zbee_zcl_commissioning_reset_startup_options_erase_index = -1;
8636 static int hf_zbee_zcl_commissioning_reset_startup_options_reserved = -1;
8637 static int hf_zbee_zcl_commissioning_status = -1;
8638 static int hf_zbee_zcl_commissioning_srv_rx_cmd_id = -1;
8639 static int hf_zbee_zcl_commissioning_srv_tx_cmd_id = -1;
8640 
8641 /* Initialize the subtree pointers */
8642 static gint ett_zbee_zcl_commissioning = -1;
8643 static gint ett_zbee_zcl_commissioning_restart_device_options = -1;
8644 static gint ett_zbee_zcl_commissioning_reset_startup_options = -1;
8645 
8646 /* Attributes */
8647 static const value_string zbee_zcl_commissioning_attr_names[] = {
8648     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_SHORT_ADDRESS,                         "Short Address" },
8649     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_EXTENDED_PAN_ID,                       "Extended PAN Id" },
8650     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_PAN_ID,                                "PAN Id" },
8651     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_CHANNEL_MASK,                          "Channel Mask" },
8652     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_PROTOCOL_VERSION,                      "Protocol Version" },
8653     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_STACK_PROFILE,                         "Stack Profile" },
8654     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_STARTUP_CONTROL,                       "Startup Control" },
8655     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_TRUST_CENTER_ADDRESS,                  "Trust Center Address" },
8656     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_TRUST_CENTER_MASTER_KEY,               "Trust Center Master Key" },
8657     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY,                           "Network Key" },
8658     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_USE_INSECURE_JOIN,                     "Use Insecure Join" },
8659     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_PRECONFIGURED_LINK_KEY,                "Preconfigured Link Key" },
8660     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY_SEQ_NUM,                   "Network Key Sequence Number" },
8661     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY_TYPE,                      "Network Key Type" },
8662     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_MANAGER_ADDRESS,               "Network Manager Address" },
8663     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_SCAN_ATTEMPTS,                         "Scan Attempts" },
8664     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_TIME_BETWEEN_SCANS,                    "Time Between Scans" },
8665     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_REJOIN_INTERVAL,                       "Rejoin Interval" },
8666     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_MAX_REJOIN_INTERVAL,                   "Max Rejoin Interval" },
8667     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_INDIRECT_POLL_RATE,                    "Indirect Poll Rate" },
8668     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_PARENT_RETRY_THRESHOLD,                "Parent Retry Threshold" },
8669     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_FLAG,                     "Concentrator Flag" },
8670     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_RADIUS,                   "Concentrator Radius" },
8671     { ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_DISCOVERY_TIME,           "Concentrator Discovery Time" },
8672     { 0, NULL }
8673 };
8674 
8675 /* Server Commands Received */
8676 static const value_string zbee_zcl_commissioning_srv_rx_cmd_names[] = {
8677     { ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTART_DEVICE,                         "Commissioning" },
8678     { ZBEE_ZCL_CMD_ID_COMMISSIONING_SAVE_STARTUP_PARAMETERS,                "Commissioning" },
8679     { ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTORE_STARTUP_PARAMETERS,             "Commissioning" },
8680     { ZBEE_ZCL_CMD_ID_COMMISSIONING_RESET_STARTUP_PARAMETERS,               "Commissioning" },
8681     { 0, NULL }
8682 };
8683 
8684 /* Server Commands Generated */
8685 static const value_string zbee_zcl_commissioning_srv_tx_cmd_names[] = {
8686     { ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTART_DEVICE_RESPONSE,                "Commissioning" },
8687     { ZBEE_ZCL_CMD_ID_COMMISSIONING_SAVE_STARTUP_PARAMETERS_RESPONSE,       "Commissioning" },
8688     { ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTORE_STARTUP_PARAMETERS_RESPONSE,    "Commissioning" },
8689     { ZBEE_ZCL_CMD_ID_COMMISSIONING_RESET_STARTUP_PARAMETERS_RESPONSE,      "Commissioning" },
8690     { 0, NULL }
8691 };
8692 
8693 static const value_string zbee_zcl_commissioning_stack_profile_values[] = {
8694     {0x01, "ZigBee Stack Profile"},
8695     {0x02, "ZigBee PRO Stack Profile"},
8696     {0, NULL}
8697 };
8698 
8699 static const value_string zbee_zcl_commissioning_startup_control_values[] = {
8700     {0x00, "Device is part of the network indicated by the Extended PAN Id"},
8701     {0x01, "Device should form a network with the Extended PAN Id"},
8702     {0x02, "Device should rejoin the network with Extended PAN Id"},
8703     {0x03, "Device should join the network using MAC Association"},
8704     {0, NULL}
8705 };
8706 
8707 static const value_string zbee_zcl_commissioning_startup_mode_values[] ={
8708     {0, "Restart Device using current set of startup parameters"},
8709     {1, "Restart Device using current set of stack attributes"},
8710     {0, NULL}
8711 };
8712 
8713 /*************************/
8714 /* Function Bodies       */
8715 /*************************/
8716 
8717 /*FUNCTION:------------------------------------------------------
8718  *  NAME
8719  *      dissect_zbee_zcl_commissioning
8720  *  DESCRIPTION
8721  *      ZigBee ZCL Commissioning cluster dissector for wireshark.
8722  *  PARAMETERS
8723  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
8724  *      packet_info *pinfo  - pointer to packet information fields
8725  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
8726  *  RETURNS
8727  *      none
8728  *---------------------------------------------------------------
8729  */
8730 static int
dissect_zbee_zcl_commissioning(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)8731 dissect_zbee_zcl_commissioning(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
8732 {
8733     proto_tree        *payload_tree;
8734     zbee_zcl_packet   *zcl;
8735     guint             offset = 0;
8736     guint8            cmd_id;
8737     gint              rem_len;
8738 
8739     /* Reject the packet if data is NULL */
8740     if (data == NULL)
8741         return 0;
8742     zcl = (zbee_zcl_packet *)data;
8743     cmd_id = zcl->cmd_id;
8744 
8745     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
8746     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
8747         /* Append the command name to the info column. */
8748         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
8749             val_to_str_const(cmd_id, zbee_zcl_commissioning_srv_rx_cmd_names, "Unknown Command"),
8750             zcl->tran_seqno);
8751 
8752         /* Add the command ID. */
8753         proto_tree_add_item(tree, hf_zbee_zcl_commissioning_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
8754 
8755         /* Check if this command has a payload, then add the payload tree */
8756         rem_len = tvb_reported_length_remaining(tvb, ++offset);
8757         if (rem_len > 0) {
8758             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_commissioning, NULL, "Payload");
8759 
8760             /* Call the appropriate command dissector */
8761             switch (cmd_id) {
8762                 case ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTART_DEVICE:
8763                     dissect_zcl_commissioning_restart_device(tvb, payload_tree, &offset);
8764                     break;
8765 
8766                 case ZBEE_ZCL_CMD_ID_COMMISSIONING_RESET_STARTUP_PARAMETERS:
8767                     dissect_zcl_commissioning_reset_startup_parameters(tvb, payload_tree, &offset);
8768                     break;
8769 
8770                 case ZBEE_ZCL_CMD_ID_COMMISSIONING_SAVE_STARTUP_PARAMETERS:
8771                 case ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTORE_STARTUP_PARAMETERS:
8772                     dissect_zcl_commissioning_save_restore_startup_parameters(tvb, payload_tree, &offset);
8773                     break;
8774 
8775                 default:
8776                     break;
8777             }
8778         }
8779     }
8780     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
8781         /* Append the command name to the info column. */
8782         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
8783             val_to_str_const(cmd_id, zbee_zcl_commissioning_srv_tx_cmd_names, "Unknown Command"),
8784             zcl->tran_seqno);
8785 
8786         /* Add the command ID. */
8787         proto_tree_add_item(tree, hf_zbee_zcl_commissioning_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
8788 
8789         /* Check if this command has a payload, then add the payload tree */
8790         rem_len = tvb_reported_length_remaining(tvb, ++offset);
8791         if (rem_len > 0) {
8792             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_commissioning, NULL, "Payload");
8793 
8794             /* Call the appropriate command dissector */
8795             switch (cmd_id) {
8796                 case ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTART_DEVICE_RESPONSE:
8797                 case ZBEE_ZCL_CMD_ID_COMMISSIONING_SAVE_STARTUP_PARAMETERS_RESPONSE:
8798                 case ZBEE_ZCL_CMD_ID_COMMISSIONING_RESTORE_STARTUP_PARAMETERS_RESPONSE:
8799                 case ZBEE_ZCL_CMD_ID_COMMISSIONING_RESET_STARTUP_PARAMETERS_RESPONSE:
8800                     dissect_zcl_commissioning_response(tvb, payload_tree, &offset);
8801                     break;
8802 
8803                 default:
8804                     break;
8805             }
8806         }
8807     }
8808 
8809     return tvb_captured_length(tvb);
8810 } /*dissect_zbee_zcl_commissioning*/
8811 
8812 
8813  /*FUNCTION:------------------------------------------------------
8814  *  NAME
8815  *      dissect_zcl_commissioning_restart_device
8816  *  DESCRIPTION
8817  *      this function decodes the Restart Device payload.
8818  *  PARAMETERS
8819  *      tvb     - the tv buffer of the current data_type
8820  *      tree    - the tree to append this item to
8821  *      offset  - offset of data in tvb
8822  *  RETURNS
8823  *      none
8824  *---------------------------------------------------------------
8825  */
8826 static void
dissect_zcl_commissioning_restart_device(tvbuff_t * tvb,proto_tree * tree,guint * offset)8827 dissect_zcl_commissioning_restart_device(tvbuff_t *tvb, proto_tree *tree, guint *offset)
8828 {
8829     static int * const restart_device_mask[] = {
8830         &hf_zbee_zcl_commissioning_restart_device_options_startup_mode,
8831         &hf_zbee_zcl_commissioning_restart_device_options_immediate,
8832         &hf_zbee_zcl_commissioning_restart_device_options_reserved,
8833         NULL
8834     };
8835 
8836     /* Retrieve "Options" field */
8837     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_commissioning_restart_device_options, ett_zbee_zcl_commissioning_restart_device_options, restart_device_mask, ENC_LITTLE_ENDIAN);
8838     *offset += 1;
8839 
8840     /* Retrieve "Delay" field */
8841     proto_tree_add_item(tree, hf_zbee_zcl_commissioning_delay, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8842     *offset += 1;
8843 
8844     /* Retrieve "Jitter" field */
8845     proto_tree_add_item(tree, hf_zbee_zcl_commissioning_jitter, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8846     *offset += 1;
8847 
8848 } /*dissect_zcl_commissioning_restart_device*/
8849 
8850 
8851  /*FUNCTION:------------------------------------------------------
8852  *  NAME
8853  *      dissect_zcl_commissioning_save_restore_startup_parameters
8854  *  DESCRIPTION
8855  *      this function decodes the Save and Restore payload.
8856  *  PARAMETERS
8857  *      tvb     - the tv buffer of the current data_type
8858  *      tree    - the tree to append this item to
8859  *      offset  - offset of data in tvb
8860  *  RETURNS
8861  *      none
8862  *---------------------------------------------------------------
8863  */
8864 static void
dissect_zcl_commissioning_save_restore_startup_parameters(tvbuff_t * tvb,proto_tree * tree,guint * offset)8865 dissect_zcl_commissioning_save_restore_startup_parameters(tvbuff_t *tvb, proto_tree *tree, guint *offset)
8866 {
8867     /* Retrieve "Options" field */
8868     proto_tree_add_item(tree, hf_zbee_zcl_commissioning_options, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8869     *offset += 1;
8870 
8871     /* Retrieve "Index" field */
8872     proto_tree_add_item(tree, hf_zbee_zcl_commissioning_index, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8873     *offset += 1;
8874 
8875 } /*dissect_zcl_commissioning_save_restore_startup_parameters*/
8876 
8877 /*FUNCTION:------------------------------------------------------
8878 *  NAME
8879 *      dissect_zcl_commissioning_reset_startup_parameters
8880 *  DESCRIPTION
8881 *      this function decodes the Reset Startup Parameters payload.
8882 *  PARAMETERS
8883 *      tvb     - the tv buffer of the current data_type
8884 *      tree    - the tree to append this item to
8885 *      offset  - offset of data in tvb
8886 *  RETURNS
8887 *      none
8888 *---------------------------------------------------------------
8889 */
8890 static void
dissect_zcl_commissioning_reset_startup_parameters(tvbuff_t * tvb,proto_tree * tree,guint * offset)8891 dissect_zcl_commissioning_reset_startup_parameters(tvbuff_t *tvb, proto_tree *tree, guint *offset)
8892 {
8893     static int * const reset_startup_mask[] = {
8894         &hf_zbee_zcl_commissioning_reset_startup_options_reset_current,
8895         &hf_zbee_zcl_commissioning_reset_startup_options_reset_all,
8896         &hf_zbee_zcl_commissioning_reset_startup_options_erase_index,
8897         &hf_zbee_zcl_commissioning_reset_startup_options_reserved,
8898         NULL
8899     };
8900 
8901    /* Retrieve "Options" field */
8902     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_commissioning_reset_startup_options, ett_zbee_zcl_commissioning_reset_startup_options, reset_startup_mask, ENC_LITTLE_ENDIAN);
8903    *offset += 1;
8904 
8905    /* Retrieve "Index" field */
8906    proto_tree_add_item(tree, hf_zbee_zcl_commissioning_index, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8907    *offset += 1;
8908 
8909 } /*dissect_zcl_commissioning_reset_startup_parameters*/
8910 
8911 /*FUNCTION:------------------------------------------------------
8912 *  NAME
8913 *      dissect_zcl_commissioning_response
8914 *  DESCRIPTION
8915 *      this function decodes the Response payload.
8916 *  PARAMETERS
8917 *      tvb     - the tv buffer of the current data_type
8918 *      tree    - the tree to append this item to
8919 *      offset  - offset of data in tvb
8920 *  RETURNS
8921 *      none
8922 *---------------------------------------------------------------
8923 */
8924 static void
dissect_zcl_commissioning_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)8925 dissect_zcl_commissioning_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
8926 {
8927    /* Retrieve "Status" field */
8928    proto_tree_add_item(tree, hf_zbee_zcl_commissioning_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8929    *offset += 1;
8930 
8931 } /*dissect_zcl_commissioning_response*/
8932 
8933 
8934 /*FUNCTION:------------------------------------------------------
8935  *  NAME
8936  *      dissect_zcl_commissioning_attr_data
8937  *  DESCRIPTION
8938  *      this function is called by ZCL foundation dissector in order to decode
8939  *      specific cluster attributes data.
8940  *  PARAMETERS
8941  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
8942  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
8943  *      guint *offset       - pointer to buffer offset
8944  *      guint16 attr_id     - attribute identifier
8945  *      guint data_type     - attribute data type
8946  *      gboolean client_attr- ZCL client
8947  *  RETURNS
8948  *      none
8949  *---------------------------------------------------------------
8950  */
8951 void
dissect_zcl_commissioning_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)8952 dissect_zcl_commissioning_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
8953 {
8954     /* Dissect attribute data type and data */
8955     switch ( attr_id ) {
8956 
8957         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_STACK_PROFILE:
8958             proto_tree_add_item(tree, hf_zbee_zcl_commissioning_attr_stack_profile, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8959             *offset += 1;
8960             break;
8961 
8962         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_STARTUP_CONTROL:
8963             proto_tree_add_item(tree, hf_zbee_zcl_commissioning_attr_startup_control, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
8964             *offset += 1;
8965             break;
8966 
8967         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_SHORT_ADDRESS:
8968         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_EXTENDED_PAN_ID:
8969         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_PAN_ID:
8970         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_CHANNEL_MASK:
8971         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_PROTOCOL_VERSION:
8972         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_TRUST_CENTER_ADDRESS:
8973         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_TRUST_CENTER_MASTER_KEY:
8974         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY:
8975         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_USE_INSECURE_JOIN:
8976         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_PRECONFIGURED_LINK_KEY:
8977         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY_SEQ_NUM:
8978         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_KEY_TYPE:
8979         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_NETWORK_MANAGER_ADDRESS:
8980         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_SCAN_ATTEMPTS:
8981         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_TIME_BETWEEN_SCANS:
8982         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_REJOIN_INTERVAL:
8983         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_MAX_REJOIN_INTERVAL:
8984         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_INDIRECT_POLL_RATE:
8985         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_PARENT_RETRY_THRESHOLD:
8986         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_FLAG:
8987         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_RADIUS:
8988         case ZBEE_ZCL_ATTR_ID_COMMISSIONING_CONCENTRATOR_DISCOVERY_TIME:
8989         default:
8990             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
8991             break;
8992     }
8993 
8994 } /*dissect_zcl_commissioning_attr_data*/
8995 
8996 
8997 /*FUNCTION:------------------------------------------------------
8998  *  NAME
8999  *      proto_register_zbee_zcl_commissioning
9000  *  DESCRIPTION
9001  *      ZigBee ZCL Commissioning cluster protocol registration routine.
9002  *  PARAMETERS
9003  *      none
9004  *  RETURNS
9005  *      void
9006  *---------------------------------------------------------------
9007  */
9008 void
proto_register_zbee_zcl_commissioning(void)9009 proto_register_zbee_zcl_commissioning(void)
9010 {
9011     /* Setup list of header fields */
9012     static hf_register_info hf[] = {
9013 
9014         { &hf_zbee_zcl_commissioning_attr_id,
9015             { "Attribute", "zbee_zcl_general.commissioning.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_commissioning_attr_names),
9016             0x00, NULL, HFILL } },
9017 
9018         { &hf_zbee_zcl_commissioning_attr_stack_profile,
9019             { "Stack Profile", "zbee_zcl_general.commissioning.attr.stack_profile", FT_UINT8, BASE_HEX, VALS(zbee_zcl_commissioning_stack_profile_values),
9020             0x00, NULL, HFILL } },
9021 
9022         { &hf_zbee_zcl_commissioning_attr_startup_control,
9023             { "Startup Control", "zbee_zcl_general.commissioning.attr.startup_control", FT_UINT8, BASE_HEX, VALS(zbee_zcl_commissioning_startup_control_values),
9024             0x00, NULL, HFILL } },
9025 
9026         /* start Restart Device Options fields */
9027         { &hf_zbee_zcl_commissioning_restart_device_options,
9028             { "Restart Device Options", "zbee_zcl_general.commissioning.restart_device_options", FT_UINT8, BASE_HEX, NULL,
9029             0x00, NULL, HFILL } },
9030 
9031         { &hf_zbee_zcl_commissioning_restart_device_options_startup_mode,
9032             { "Startup Mode", "zbee_zcl_general.commissioning.restart_device_options.startup_mode", FT_UINT8, BASE_HEX, VALS(zbee_zcl_commissioning_startup_mode_values),
9033             ZBEE_ZCL_COMMISSIONING_RESTART_DEVICE_OPTIONS_STARTUP_MODE, NULL, HFILL } },
9034 
9035         { &hf_zbee_zcl_commissioning_restart_device_options_immediate,
9036             { "Immediate", "zbee_zcl_general.commissioning.restart_device_options.immediate", FT_BOOLEAN, 8, NULL,
9037             ZBEE_ZCL_COMMISSIONING_RESTART_DEVICE_OPTIONS_IMMEDIATE, NULL, HFILL } },
9038 
9039         { &hf_zbee_zcl_commissioning_restart_device_options_reserved,
9040             { "Reserved", "zbee_zcl_general.commissioning.restart_device_options.reserved", FT_BOOLEAN, 8, NULL,
9041             ZBEE_ZCL_COMMISSIONING_RESTART_DEVICE_OPTIONS_RESERVED, NULL, HFILL } },
9042         /* end Restart Device Options fields */
9043 
9044         { &hf_zbee_zcl_commissioning_delay,
9045             { "Delay", "zbee_zcl_general.commissioning.delay", FT_UINT8, BASE_DEC, NULL,
9046             0x0, NULL, HFILL } },
9047 
9048         { &hf_zbee_zcl_commissioning_jitter,
9049             { "Jitter", "zbee_zcl_general.commissioning.jitter", FT_UINT8, BASE_DEC, NULL,
9050             0x0, NULL, HFILL } },
9051 
9052         { &hf_zbee_zcl_commissioning_options,
9053             { "Options (Reserved)", "zbee_zcl_general.commissioning.options", FT_UINT8, BASE_HEX, NULL,
9054             0x0, NULL, HFILL } },
9055 
9056         { &hf_zbee_zcl_commissioning_index,
9057             { "Index", "zbee_zcl_general.commissioning.index", FT_UINT8, BASE_DEC, NULL,
9058             0x0, NULL, HFILL } },
9059 
9060         /* start Reset Startup Options fields */
9061         { &hf_zbee_zcl_commissioning_reset_startup_options,
9062             { "Reset Startup Options", "zbee_zcl_general.commissioning.reset_startup_options", FT_UINT8, BASE_HEX, NULL,
9063             0x00, NULL, HFILL } },
9064 
9065         { &hf_zbee_zcl_commissioning_reset_startup_options_reset_current,
9066             { "Reset Current", "zbee_zcl_general.commissioning.reset_startup_options.current", FT_BOOLEAN, 8, NULL,
9067             ZBEE_ZCL_COMMISSIONING_RESET_STARTUP_OPTIONS_RESET_CURRENT, NULL, HFILL } },
9068 
9069         { &hf_zbee_zcl_commissioning_reset_startup_options_reset_all,
9070             { "Reset All", "zbee_zcl_general.commissioning.reset_startup_options.reset_all", FT_BOOLEAN, 8, NULL,
9071             ZBEE_ZCL_COMMISSIONING_RESET_STARTUP_OPTIONS_RESET_ALL, NULL, HFILL } },
9072 
9073         { &hf_zbee_zcl_commissioning_reset_startup_options_erase_index,
9074             { "Erase Index", "zbee_zcl_general.commissioning.reset_startup_options.erase_index", FT_BOOLEAN, 8, NULL,
9075             ZBEE_ZCL_COMMISSIONING_RESET_STARTUP_OPTIONS_ERASE_INDEX, NULL, HFILL } },
9076 
9077         { &hf_zbee_zcl_commissioning_reset_startup_options_reserved,
9078             { "Reserved", "zbee_zcl_general.commissioning.reset_startup_options.reserved", FT_BOOLEAN, 8, NULL,
9079             ZBEE_ZCL_COMMISSIONING_RESET_STARTUP_OPTIONS_RESERVED, NULL, HFILL } },
9080         /* end Reset Startup Options fields */
9081 
9082         { &hf_zbee_zcl_commissioning_status,
9083             { "Status", "zbee_zcl_general.commissioning.status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_status_names),
9084             0x0, NULL, HFILL } },
9085 
9086         { &hf_zbee_zcl_commissioning_srv_rx_cmd_id,
9087           { "Command", "zbee_zcl_general.commissioning.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_commissioning_srv_rx_cmd_names),
9088             0x00, NULL, HFILL } },
9089 
9090         { &hf_zbee_zcl_commissioning_srv_tx_cmd_id,
9091           { "Command", "zbee_zcl_general.commissioning.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_commissioning_srv_tx_cmd_names),
9092             0x00, NULL, HFILL } }
9093 
9094     };
9095 
9096     /* ZCL Commissioning subtrees */
9097     static gint *ett[] = {
9098         &ett_zbee_zcl_commissioning,
9099         &ett_zbee_zcl_commissioning_restart_device_options,
9100         &ett_zbee_zcl_commissioning_reset_startup_options
9101     };
9102 
9103     /* Register the ZigBee ZCL Commissioning cluster protocol name and description */
9104     proto_zbee_zcl_commissioning = proto_register_protocol("ZigBee ZCL Commissioning", "ZCL Commissioning", ZBEE_PROTOABBREV_ZCL_COMMISSIONING);
9105     proto_register_field_array(proto_zbee_zcl_commissioning, hf, array_length(hf));
9106     proto_register_subtree_array(ett, array_length(ett));
9107 
9108     /* Register the ZigBee ZCL Commissioning dissector. */
9109     register_dissector(ZBEE_PROTOABBREV_ZCL_COMMISSIONING, dissect_zbee_zcl_commissioning, proto_zbee_zcl_commissioning);
9110 
9111 } /*proto_register_zbee_zcl_commissioning*/
9112 
9113 
9114 /*FUNCTION:------------------------------------------------------
9115  *  NAME
9116  *      proto_reg_handoff_zbee_zcl_commissioning
9117  *  DESCRIPTION
9118  *      Hands off the ZCL Commissioning dissector.
9119  *  PARAMETERS
9120  *      none
9121  *  RETURNS
9122  *      none
9123  *---------------------------------------------------------------
9124  */
9125 void
proto_reg_handoff_zbee_zcl_commissioning(void)9126 proto_reg_handoff_zbee_zcl_commissioning(void)
9127 {
9128     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_COMMISSIONING,
9129                             proto_zbee_zcl_commissioning,
9130                             ett_zbee_zcl_commissioning,
9131                             ZBEE_ZCL_CID_COMMISSIONING,
9132                             ZBEE_MFG_CODE_NONE,
9133                             hf_zbee_zcl_commissioning_attr_id,
9134                             hf_zbee_zcl_commissioning_attr_id,
9135                             hf_zbee_zcl_commissioning_srv_rx_cmd_id,
9136                             hf_zbee_zcl_commissioning_srv_tx_cmd_id,
9137                             (zbee_zcl_fn_attr_data)dissect_zcl_commissioning_attr_data
9138                          );
9139 } /*proto_reg_handoff_zbee_zcl_commissioning*/
9140 
9141 
9142 /* ########################################################################## */
9143 /* #### (0x0016) PARTITION ################################################## */
9144 /* ########################################################################## */
9145 
9146 /*************************/
9147 /* Defines               */
9148 /*************************/
9149 
9150 #define ZBEE_ZCL_PART_NUM_GENERIC_ETT                   3
9151 #define ZBEE_ZCL_PART_NUM_NACK_ID_ETT                   16
9152 #define ZBEE_ZCL_PART_NUM_ATTRS_ID_ETT                  16
9153 #define ZBEE_ZCL_PART_NUM_ETT                           (ZBEE_ZCL_PART_NUM_GENERIC_ETT + \
9154                                                         ZBEE_ZCL_PART_NUM_NACK_ID_ETT + \
9155                                                         ZBEE_ZCL_PART_NUM_ATTRS_ID_ETT)
9156 
9157 #define ZBEE_ZCL_PART_OPT_1_BLOCK                       0x01
9158 #define ZBEE_ZCL_PART_OPT_INDIC_LEN                     0x02
9159 #define ZBEE_ZCL_PART_OPT_RESERVED                      0xc0
9160 
9161 #define ZBEE_ZCL_PART_ACK_OPT_NACK_LEN                  0x01
9162 #define ZBEE_ZCL_PART_ACK_OPT_RESERVED                  0xFE
9163 
9164 /* Attributes */
9165 #define ZBEE_ZCL_ATTR_ID_PART_MAX_IN_TRANSF_SIZE        0x0000  /* Maximum Incoming Transfer Size */
9166 #define ZBEE_ZCL_ATTR_ID_PART_MAX_OUT_TRANSF_SIZE       0x0001  /* Maximum Outgoing Transfer Size */
9167 #define ZBEE_ZCL_ATTR_ID_PART_PARTITIONED_FRAME_SIZE    0x0002  /* Partitioned Frame Size */
9168 #define ZBEE_ZCL_ATTR_ID_PART_LARGE_FRAME_SIZE          0x0003  /* Large Frame Size */
9169 #define ZBEE_ZCL_ATTR_ID_PART_ACK_FRAME_NUM             0x0004  /* Number of Ack Frame*/
9170 #define ZBEE_ZCL_ATTR_ID_PART_NACK_TIMEOUT              0x0005  /* Nack Timeout */
9171 #define ZBEE_ZCL_ATTR_ID_PART_INTERFRAME_DELEAY         0x0006  /* Interframe Delay */
9172 #define ZBEE_ZCL_ATTR_ID_PART_SEND_RETRIES_NUM          0x0007  /* Number of Send Retries */
9173 #define ZBEE_ZCL_ATTR_ID_PART_SENDER_TIMEOUT            0x0008  /* Sender Timeout */
9174 #define ZBEE_ZCL_ATTR_ID_PART_RECEIVER_TIMEOUT          0x0009  /* Receiver Timeout */
9175 
9176 /* Server Commands Received */
9177 #define ZBEE_ZCL_CMD_ID_PART_TRANSF_PART_FRAME          0x00  /* Transfer Partitioned Frame */
9178 #define ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM         0x01  /* Read Handshake Param */
9179 #define ZBEE_ZCL_CMD_ID_PART_WR_HANDSHAKE_PARAM         0x02  /* Write Handshake Param */
9180 
9181 /* Server Commands Generated */
9182 #define ZBEE_ZCL_CMD_ID_PART_MULTI_ACK                  0x00  /* Multiple Ack */
9183 #define ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM_RSP     0x01  /* Read Handshake Param Response */
9184 
9185 
9186 /*************************/
9187 /* Function Declarations */
9188 /*************************/
9189 
9190 void proto_register_zbee_zcl_part(void);
9191 void proto_reg_handoff_zbee_zcl_part(void);
9192 
9193 /* Command Dissector Helpers */
9194 static void dissect_zcl_part_trasfpartframe         (tvbuff_t *tvb, proto_tree *tree, guint *offset);
9195 static void dissect_zcl_part_rdhandshakeparam       (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset, gboolean direction);
9196 static void dissect_zcl_part_wrhandshakeparam       (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset, gboolean direction);
9197 static void dissect_zcl_part_multiack               (tvbuff_t *tvb, proto_tree *tree, guint *offset);
9198 static void dissect_zcl_part_rdhandshakeparamrsp    (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset, gboolean direction);
9199 
9200 /* Private functions prototype */
9201 
9202 /*************************/
9203 /* Global Variables      */
9204 /*************************/
9205 
9206 /* Initialize the protocol and registered fields */
9207 static int proto_zbee_zcl_part = -1;
9208 
9209 static int hf_zbee_zcl_part_attr_id = -1;
9210 static int hf_zbee_zcl_part_srv_tx_cmd_id = -1;
9211 static int hf_zbee_zcl_part_srv_rx_cmd_id = -1;
9212 static int hf_zbee_zcl_part_opt = -1;
9213 static int hf_zbee_zcl_part_opt_first_block = -1;
9214 static int hf_zbee_zcl_part_opt_indic_len = -1;
9215 static int hf_zbee_zcl_part_opt_res = -1;
9216 static int hf_zbee_zcl_part_first_frame_id = -1;
9217 static int hf_zbee_zcl_part_part_indicator = -1;
9218 static int hf_zbee_zcl_part_part_frame = -1;
9219 static int hf_zbee_zcl_part_partitioned_cluster_id = -1;
9220 static int hf_zbee_zcl_part_ack_opt = -1;
9221 static int hf_zbee_zcl_part_ack_opt_nack_id_len = -1;
9222 static int hf_zbee_zcl_part_ack_opt_res = -1;
9223 static int hf_zbee_zcl_part_nack_id = -1;
9224 
9225 /* Initialize the subtree pointers */
9226 static gint ett_zbee_zcl_part = -1;
9227 static gint ett_zbee_zcl_part_fragm_options = -1;
9228 static gint ett_zbee_zcl_part_ack_opts = -1;
9229 static gint ett_zbee_zcl_part_nack_id_list[ZBEE_ZCL_PART_NUM_NACK_ID_ETT];
9230 static gint ett_zbee_zcl_part_attrs_id_list[ZBEE_ZCL_PART_NUM_ATTRS_ID_ETT];
9231 
9232 /* Attributes */
9233 static const value_string zbee_zcl_part_attr_names[] = {
9234     { ZBEE_ZCL_ATTR_ID_PART_MAX_IN_TRANSF_SIZE,     "Maximum Incoming Transfer Size" },
9235     { ZBEE_ZCL_ATTR_ID_PART_MAX_OUT_TRANSF_SIZE,    "Maximum Outgoing Transfer Size" },
9236     { ZBEE_ZCL_ATTR_ID_PART_PARTITIONED_FRAME_SIZE, "Partitioned Frame Size" },
9237     { ZBEE_ZCL_ATTR_ID_PART_LARGE_FRAME_SIZE,       "Large Frame Size" },
9238     { ZBEE_ZCL_ATTR_ID_PART_ACK_FRAME_NUM,          "Number of Ack Frame" },
9239     { ZBEE_ZCL_ATTR_ID_PART_NACK_TIMEOUT,           "Nack Timeout" },
9240     { ZBEE_ZCL_ATTR_ID_PART_INTERFRAME_DELEAY,      "Interframe Delay" },
9241     { ZBEE_ZCL_ATTR_ID_PART_SEND_RETRIES_NUM,       "Number of Send Retries" },
9242     { ZBEE_ZCL_ATTR_ID_PART_SENDER_TIMEOUT,         "Sender Timeout" },
9243     { ZBEE_ZCL_ATTR_ID_PART_RECEIVER_TIMEOUT,       "Receiver Timeout" },
9244     { 0, NULL }
9245 };
9246 
9247 /* Server Commands Received */
9248 static const value_string zbee_zcl_part_srv_rx_cmd_names[] = {
9249     { ZBEE_ZCL_CMD_ID_PART_TRANSF_PART_FRAME,       "Transfer Partitioned Frame" },
9250     { ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM,      "Read Handshake Param" },
9251     { ZBEE_ZCL_CMD_ID_PART_WR_HANDSHAKE_PARAM,      "Write Handshake Param" },
9252     { 0, NULL }
9253 };
9254 
9255 /* Server Commands Generated */
9256 static const value_string zbee_zcl_part_srv_tx_cmd_names[] = {
9257     { ZBEE_ZCL_CMD_ID_PART_MULTI_ACK,               "Multiple Ack" },
9258     { ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM_RSP,  "Read Handshake Param Response" },
9259     { 0, NULL }
9260 };
9261 
9262 /* ID Length */
9263 static const value_string zbee_zcl_part_id_length_names[] = {
9264     { 0,        "1-Byte length" },
9265     { 1,        "2-Bytes length" },
9266     { 0, NULL }
9267 };
9268 
9269 /*************************/
9270 /* Function Bodies       */
9271 /*************************/
9272 
9273 /*FUNCTION:------------------------------------------------------
9274  *  NAME
9275  *      dissect_zbee_zcl_part
9276  *  DESCRIPTION
9277  *      ZigBee ZCL Partition cluster dissector for wireshark.
9278  *  PARAMETERS
9279  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
9280  *      packet_info *pinfo  - pointer to packet information fields
9281  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
9282  *      void *data          - pointer to ZCL packet structure.
9283  *  RETURNS
9284  *      int                 - length of parsed data.
9285  *---------------------------------------------------------------
9286  */
9287 static int
dissect_zbee_zcl_part(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)9288 dissect_zbee_zcl_part(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
9289 {
9290     proto_tree  *payload_tree;
9291     zbee_zcl_packet  *zcl;
9292     guint       offset = 0;
9293     guint8      cmd_id;
9294     gint        rem_len;
9295 
9296     /* Reject the packet if data is NULL */
9297     if (data == NULL)
9298         return 0;
9299     zcl = (zbee_zcl_packet *)data;
9300     cmd_id = zcl->cmd_id;
9301 
9302     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
9303     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
9304         /* Append the command name to the info column. */
9305         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
9306             val_to_str_const(cmd_id, zbee_zcl_part_srv_rx_cmd_names, "Unknown Command"),
9307             zcl->tran_seqno);
9308 
9309         /* Add the command ID. */
9310         proto_tree_add_item(tree, hf_zbee_zcl_part_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9311 
9312         /* Check is this command has a payload, than add the payload tree */
9313         rem_len = tvb_reported_length_remaining(tvb, ++offset);
9314         if (rem_len > 0) {
9315             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_part, NULL, "Payload");
9316 
9317             /* Call the appropriate command dissector */
9318             switch (cmd_id) {
9319                 case ZBEE_ZCL_CMD_ID_PART_TRANSF_PART_FRAME:
9320                     dissect_zcl_part_trasfpartframe(tvb, payload_tree, &offset);
9321                     break;
9322 
9323                 case ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM:
9324                     dissect_zcl_part_rdhandshakeparam(tvb, pinfo, payload_tree, &offset, zcl->direction);
9325                     break;
9326 
9327                 case ZBEE_ZCL_CMD_ID_PART_WR_HANDSHAKE_PARAM:
9328                     dissect_zcl_part_wrhandshakeparam(tvb, pinfo, payload_tree, &offset, zcl->direction);
9329                     break;
9330 
9331                 default:
9332                     break;
9333             }
9334         }
9335     }
9336     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
9337         /* Append the command name to the info column. */
9338         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
9339             val_to_str_const(cmd_id, zbee_zcl_part_srv_tx_cmd_names, "Unknown Command"),
9340             zcl->tran_seqno);
9341 
9342         /* Add the command ID. */
9343         proto_tree_add_item(tree, hf_zbee_zcl_part_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
9344 
9345         /* Check is this command has a payload, than add the payload tree */
9346         rem_len = tvb_reported_length_remaining(tvb, ++offset);
9347         if (rem_len > 0) {
9348             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_part, NULL, "Payload");
9349 
9350             /* Call the appropriate command dissector */
9351             switch (cmd_id) {
9352                 case ZBEE_ZCL_CMD_ID_PART_MULTI_ACK:
9353                     dissect_zcl_part_multiack(tvb, payload_tree, &offset);
9354                     break;
9355 
9356                 case ZBEE_ZCL_CMD_ID_PART_RD_HANDSHAKE_PARAM_RSP:
9357                     dissect_zcl_part_rdhandshakeparamrsp(tvb, pinfo, payload_tree, &offset, zcl->direction);
9358                     break;
9359 
9360                 default:
9361                     break;
9362             }
9363         }
9364     }
9365 
9366     return tvb_captured_length(tvb);
9367 } /*dissect_zbee_zcl_part*/
9368 
9369  /*FUNCTION:------------------------------------------------------
9370  *  NAME
9371  *      dissect_zcl_part_trasfpartframe
9372  *  DESCRIPTION
9373  *      This function manages the Transfer Partition Frame payload
9374  *  PARAMETERS
9375  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
9376  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
9377  *      offset              - pointer of buffer offset
9378  *  RETURNS
9379  *      none
9380  *---------------------------------------------------------------
9381  */
dissect_zcl_part_trasfpartframe(tvbuff_t * tvb,proto_tree * tree,guint * offset)9382 static void dissect_zcl_part_trasfpartframe(tvbuff_t *tvb, proto_tree *tree, guint *offset)
9383 {
9384 
9385     guint8    options;
9386     gint      frame_len;
9387 
9388     static int * const part_opt[] = {
9389         &hf_zbee_zcl_part_opt_first_block,
9390         &hf_zbee_zcl_part_opt_indic_len,
9391         &hf_zbee_zcl_part_opt_res,
9392         NULL
9393     };
9394 
9395     /* Retrieve "Fragmentation Options" field */
9396     options = tvb_get_guint8(tvb, *offset);
9397     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_part_opt, ett_zbee_zcl_part_fragm_options, part_opt, ENC_NA);
9398     *offset += 1;
9399 
9400     /* Retrieve "PartitionIndicator" field */
9401     if ((options & ZBEE_ZCL_PART_OPT_INDIC_LEN) ==  0)
9402     {
9403         /* 1-byte length */
9404         proto_tree_add_item(tree, hf_zbee_zcl_part_part_indicator, tvb, *offset, 1, ENC_NA);
9405         *offset += 1;
9406     }
9407     else {
9408         /* 2-bytes length */
9409         proto_tree_add_item(tree, hf_zbee_zcl_part_part_indicator, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
9410         *offset += 2;
9411     }
9412 
9413     /* Retrieve "PartitionedFrame" field */
9414     proto_tree_add_item_ret_length(tree, hf_zbee_zcl_part_part_frame, tvb, *offset, 1, ENC_NA|ENC_ZIGBEE, &frame_len);
9415     *offset += frame_len;
9416 
9417 } /*dissect_zcl_part_trasfpartframe*/
9418 
9419  /*FUNCTION:------------------------------------------------------
9420  *  NAME
9421  *      dissect_zcl_part_rdhandshakeparam
9422  *  DESCRIPTION
9423  *      This function manages the ReadHandshakeParam payload
9424  *  PARAMETERS
9425  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
9426  *      packet_info *pinfo  - pointer to packet information fields
9427  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
9428  *      offset              - offset
9429  *      direction           - ZCL direction
9430  *  RETURNS
9431  *      none
9432  *---------------------------------------------------------------
9433  */
9434 static void
dissect_zcl_part_rdhandshakeparam(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint * offset,gboolean direction)9435 dissect_zcl_part_rdhandshakeparam(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset, gboolean direction)
9436 {
9437     /* Retrieve "Partitioned Cluster ID" field */
9438     proto_tree_add_item(tree, hf_zbee_zcl_part_partitioned_cluster_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
9439     *offset += 2;
9440 
9441     /* Dissect the attribute id list */
9442     dissect_zcl_read_attr(tvb, pinfo, tree, offset, ZBEE_ZCL_CID_PARTITION, ZBEE_MFG_CODE_NONE, direction);
9443 } /*dissect_zcl_part_rdhandshakeparam*/
9444 
9445  /*FUNCTION:------------------------------------------------------
9446  *  NAME
9447  *      dissect_zcl_part_wrhandshakeparam
9448  *  DESCRIPTION
9449  *      This function manages the WriteAndShakeParam payload
9450  *  PARAMETERS
9451  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
9452  *      packet_info *pinfo  - pointer to packet information fields
9453  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
9454  *      offset              - offset
9455  *      direction           - ZCL direction
9456  *  RETURNS
9457  *      none
9458  *---------------------------------------------------------------
9459  */
9460 static void
dissect_zcl_part_wrhandshakeparam(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint * offset,gboolean direction)9461 dissect_zcl_part_wrhandshakeparam(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset, gboolean direction)
9462 {
9463     /* Retrieve "Partitioned Cluster ID" field */
9464     proto_tree_add_item(tree, hf_zbee_zcl_part_partitioned_cluster_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
9465     *offset += 2;
9466 
9467     /* Dissect the attributes list */
9468     dissect_zcl_write_attr(tvb, pinfo, tree, offset, ZBEE_ZCL_CID_PARTITION, ZBEE_MFG_CODE_NONE, direction);
9469 
9470 } /*dissect_zcl_part_wrhandshakeparam*/
9471 
9472 
9473 /* Management of Cluster specific commands sent by the server */
9474 
9475  /*FUNCTION:------------------------------------------------------
9476  *  NAME
9477  *      dissect_zcl_part_multiack
9478  *  DESCRIPTION
9479  *      This function manages the MultipleACK payload
9480  *  PARAMETERS
9481  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
9482  *      packet_info *pinfo, -
9483  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
9484  *      offset              - offset
9485  *  RETURNS
9486  *      none
9487  *---------------------------------------------------------------
9488  */
9489 static void
dissect_zcl_part_multiack(tvbuff_t * tvb,proto_tree * tree,guint * offset)9490 dissect_zcl_part_multiack(tvbuff_t *tvb, proto_tree *tree, guint *offset)
9491 {
9492     guint   tvb_len = tvb_reported_length(tvb);
9493     guint   i = 0;
9494     guint8  options;
9495     guint16 first_frame_id;
9496     guint16 nack_id;
9497 
9498     static int * const ack_opts[] = {
9499         &hf_zbee_zcl_part_ack_opt_nack_id_len,
9500         &hf_zbee_zcl_part_ack_opt_res,
9501         NULL
9502     };
9503 
9504     /* Retrieve "Ack Options" field */
9505     options = tvb_get_guint8(tvb, *offset);
9506     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_part_ack_opt, ett_zbee_zcl_part_ack_opts, ack_opts, ENC_NA);
9507     *offset += 1;
9508 
9509     /* Retrieve "First Frame ID" field */
9510     if ((options & ZBEE_ZCL_PART_ACK_OPT_NACK_LEN) ==  0)
9511     {
9512         /* 1-byte length */
9513         first_frame_id = (guint16)tvb_get_guint8(tvb, *offset);
9514         proto_tree_add_item(tree, hf_zbee_zcl_part_first_frame_id, tvb, *offset, 1, (first_frame_id & 0xFF));
9515         *offset += 1;
9516     }
9517     else {
9518         /* 2-bytes length */
9519         first_frame_id = tvb_get_letohs(tvb, *offset);
9520         proto_tree_add_item(tree, hf_zbee_zcl_part_first_frame_id, tvb, *offset, 2, first_frame_id);
9521         *offset += 2;
9522     }
9523 
9524     /* Dissect the nack id list */
9525     while ( *offset < tvb_len && i < ZBEE_ZCL_PART_NUM_NACK_ID_ETT )
9526     {
9527         if ((options & ZBEE_ZCL_PART_ACK_OPT_NACK_LEN) ==  0)
9528         {
9529             /* 1-byte length */
9530             nack_id = (guint16)tvb_get_guint8(tvb, *offset);
9531             proto_tree_add_item(tree, hf_zbee_zcl_part_nack_id, tvb, *offset, 1, (nack_id & 0xFF));
9532             *offset += 1;
9533         }
9534         else {
9535             /* 2-bytes length */
9536             nack_id = tvb_get_letohs(tvb, *offset);
9537             proto_tree_add_item(tree, hf_zbee_zcl_part_nack_id, tvb, *offset, 2, nack_id);
9538             *offset += 2;
9539         }
9540 
9541         i++;
9542     }
9543 } /*dissect_zcl_part_multiack*/
9544 
9545  /*FUNCTION:------------------------------------------------------
9546  *  NAME
9547  *      dissect_zcl_part_rdhandshakeparamrsp
9548  *  DESCRIPTION
9549  *      This function manages the ReadHandshakeParamResponse payload
9550  *  PARAMETERS
9551  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
9552  *      packet_info *pinfo  - pointer to packet information fields
9553  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
9554  *      offset              - offset
9555  *      direction           - ZCL direction
9556  *  RETURNS
9557  *      none
9558  *---------------------------------------------------------------
9559  */
9560 static void
dissect_zcl_part_rdhandshakeparamrsp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint * offset,gboolean direction)9561 dissect_zcl_part_rdhandshakeparamrsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint *offset, gboolean direction)
9562 {
9563     /* Retrieve "Partitioned Cluster ID" field */
9564     proto_tree_add_item(tree, hf_zbee_zcl_part_partitioned_cluster_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
9565     *offset += 2;
9566 
9567     /* Dissect the attributes list */
9568     dissect_zcl_read_attr_resp(tvb, pinfo, tree, offset, ZBEE_ZCL_CID_PARTITION, ZBEE_MFG_CODE_NONE, direction);
9569 } /*dissect_zcl_part_rdhandshakeparamrsp*/
9570 
9571 
9572 /*FUNCTION:------------------------------------------------------
9573  *  NAME
9574  *      proto_register_zbee_zcl_part
9575  *  DESCRIPTION
9576  *      this function is called by ZCL foundation dissector in order to decode
9577  *      specific cluster attributes data.
9578  *  PARAMETERS
9579  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
9580  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
9581  *      guint *offset       - pointer to buffer offset
9582  *      guint16 attr_id     - attribute identifier
9583  *      guint data_type     - attribute data type
9584  *  RETURNS
9585  *      none
9586  *---------------------------------------------------------------
9587  */
proto_register_zbee_zcl_part(void)9588 void proto_register_zbee_zcl_part(void)
9589 {
9590     guint8  i, j;
9591 
9592     static hf_register_info hf[] = {
9593 
9594         { &hf_zbee_zcl_part_attr_id,
9595             { "Attribute", "zbee_zcl_general.part.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_part_attr_names),
9596             0x0, NULL, HFILL } },
9597 
9598         { &hf_zbee_zcl_part_srv_tx_cmd_id,
9599             { "Command", "zbee_zcl_general.part.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_part_srv_tx_cmd_names),
9600             0x0, NULL, HFILL } },
9601 
9602         { &hf_zbee_zcl_part_srv_rx_cmd_id,
9603             { "Command", "zbee_zcl_general.part.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_part_srv_rx_cmd_names),
9604             0x0, NULL, HFILL } },
9605 
9606         { &hf_zbee_zcl_part_opt,
9607             { "Fragmentation Options", "zbee_zcl_general.part.opt", FT_UINT8, BASE_HEX,
9608                 NULL, 0x0, NULL, HFILL }},
9609 
9610         { &hf_zbee_zcl_part_opt_first_block,
9611             { "First Block", "zbee_zcl_general.part.opt.first_block", FT_UINT8, BASE_HEX, NULL,
9612             ZBEE_ZCL_PART_OPT_1_BLOCK, NULL, HFILL } },
9613 
9614         { &hf_zbee_zcl_part_opt_indic_len,
9615             { "Indicator length", "zbee_zcl_general.part.opt.indic_len", FT_UINT8, BASE_DEC, VALS(zbee_zcl_part_id_length_names),
9616             ZBEE_ZCL_PART_OPT_INDIC_LEN, NULL, HFILL } },
9617 
9618         { &hf_zbee_zcl_part_opt_res,
9619             { "Reserved", "zbee_zcl_general.part.opt.res", FT_UINT8, BASE_HEX, NULL,
9620             ZBEE_ZCL_PART_OPT_RESERVED, NULL, HFILL } },
9621 
9622         { &hf_zbee_zcl_part_first_frame_id,
9623             { "First Frame ID", "zbee_zcl_general.part.first_frame_id", FT_UINT16, BASE_DEC, NULL,
9624             0x00, NULL, HFILL } },
9625 
9626         { &hf_zbee_zcl_part_part_indicator,
9627             { "Partition Indicator", "zbee_zcl_general.part.part_indicator", FT_UINT16, BASE_DEC, NULL,
9628             0x00, NULL, HFILL } },
9629 
9630         { &hf_zbee_zcl_part_part_frame,
9631             { "Partition Frame", "zbee_zcl_general.part.part_frame", FT_UINT_BYTES, SEP_COLON, NULL,
9632             0x00, NULL, HFILL } },
9633 
9634         { &hf_zbee_zcl_part_partitioned_cluster_id,
9635             { "Partitioned Cluster ID", "zbee_zcl_general.part.part_cluster_id", FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_aps_cid_names),
9636             0x00, NULL, HFILL } },
9637 
9638         { &hf_zbee_zcl_part_ack_opt,
9639             { "Ack Options", "zbee_zcl_general.ack_opt.part", FT_UINT8, BASE_HEX,
9640                 NULL, 0x0, NULL, HFILL }},
9641 
9642         { &hf_zbee_zcl_part_ack_opt_nack_id_len,
9643             { "Nack Id Length", "zbee_zcl_general.ack_opt.part.nack_id.len", FT_UINT8, BASE_HEX, VALS(zbee_zcl_part_id_length_names),
9644             ZBEE_ZCL_PART_ACK_OPT_NACK_LEN, NULL, HFILL } },
9645 
9646         { &hf_zbee_zcl_part_ack_opt_res,
9647             { "Reserved", "zbee_zcl_general.part.ack_opt.reserved", FT_UINT8, BASE_HEX, NULL,
9648             ZBEE_ZCL_PART_ACK_OPT_RESERVED, NULL, HFILL } },
9649 
9650         { &hf_zbee_zcl_part_nack_id,
9651             { "Nack Id", "zbee_zcl_general.part.nack_id", FT_UINT16, BASE_DEC, NULL,
9652             0x00, NULL, HFILL } }
9653 
9654     };
9655 
9656     /* ZCL Partition subtrees */
9657     gint *ett[ZBEE_ZCL_PART_NUM_ETT] = {
9658         &ett_zbee_zcl_part,
9659         &ett_zbee_zcl_part_fragm_options,
9660         &ett_zbee_zcl_part_ack_opts
9661     };
9662 
9663     /* initialize attribute subtree types */
9664     for ( i = 0, j = ZBEE_ZCL_PART_NUM_GENERIC_ETT; i < ZBEE_ZCL_PART_NUM_NACK_ID_ETT; i++, j++) {
9665         ett_zbee_zcl_part_nack_id_list[i] = -1;
9666         ett[j] = &ett_zbee_zcl_part_nack_id_list[i];
9667     }
9668 
9669     for ( i = 0; i < ZBEE_ZCL_PART_NUM_ATTRS_ID_ETT; i++, j++) {
9670         ett_zbee_zcl_part_attrs_id_list[i] = -1;
9671         ett[j] = &ett_zbee_zcl_part_attrs_id_list[i];
9672     }
9673 
9674     /* Register ZigBee ZCL Partition protocol with Wireshark. */
9675     proto_zbee_zcl_part = proto_register_protocol("ZigBee ZCL Partition", "ZCL Partition", ZBEE_PROTOABBREV_ZCL_PART);
9676     proto_register_field_array(proto_zbee_zcl_part, hf, array_length(hf));
9677     proto_register_subtree_array(ett, array_length(ett));
9678 
9679     /* Register the ZigBee ZCL Partition dissector. */
9680     register_dissector(ZBEE_PROTOABBREV_ZCL_PART, dissect_zbee_zcl_part, proto_zbee_zcl_part);
9681 } /* proto_register_zbee_zcl_part */
9682 
9683 
9684 /*FUNCTION:------------------------------------------------------
9685  *  NAME
9686  *      proto_reg_handoff_zbee_zcl_part
9687  *  DESCRIPTION
9688  *      Registers the zigbee ZCL Partition cluster dissector with Wireshark.
9689  *  PARAMETERS
9690  *      none
9691  *  RETURNS
9692  *      void
9693  *---------------------------------------------------------------
9694  */
proto_reg_handoff_zbee_zcl_part(void)9695 void proto_reg_handoff_zbee_zcl_part(void)
9696 {
9697     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_PART,
9698                             proto_zbee_zcl_part,
9699                             ett_zbee_zcl_part,
9700                             ZBEE_ZCL_CID_PARTITION,
9701                             ZBEE_MFG_CODE_NONE,
9702                             hf_zbee_zcl_part_attr_id,
9703                             hf_zbee_zcl_part_attr_id,
9704                             hf_zbee_zcl_part_srv_rx_cmd_id,
9705                             hf_zbee_zcl_part_srv_tx_cmd_id,
9706                             NULL
9707                          );
9708 
9709 } /*proto_reg_handoff_zbee_zcl_part*/
9710 
9711 /* ########################################################################## */
9712 /* #### (0x0019) OTA UPGRADE CLUSTER ######################################## */
9713 /* ########################################################################## */
9714 
9715 /*************************/
9716 /* Defines               */
9717 /*************************/
9718 
9719 /* Attributes */
9720 #define ZBEE_ZCL_ATTR_ID_OTA_UPGRADE_SERVER_ID              0x0000  /* Upgrade Server ID */
9721 #define ZBEE_ZCL_ATTR_ID_OTA_FILE_OFFSET                    0x0001  /* File Offset */
9722 #define ZBEE_ZCL_ATTR_ID_OTA_CURRENT_FILE_VERSION           0x0002  /* Current File Version */
9723 #define ZBEE_ZCL_ATTR_ID_OTA_CURRENT_ZB_STACK_VERSION       0x0003  /* Current ZigBee Stack Version */
9724 #define ZBEE_ZCL_ATTR_ID_OTA_DOWNLOADED_FILE_VERSION        0x0004  /* Downloaded File Version */
9725 #define ZBEE_ZCL_ATTR_ID_OTA_DOWNLOADED_ZB_STACK_VERSION    0x0005  /* Downloaded ZigBee Stack Version */
9726 #define ZBEE_ZCL_ATTR_ID_OTA_IMAGE_UPGRADE_STATUS           0x0006  /* Image Upgrade Status */
9727 #define ZBEE_ZCL_ATTR_ID_OTA_MANUFACTURER_ID                0x0007  /* Manufacturer ID */
9728 #define ZBEE_ZCL_ATTR_ID_OTA_IMAGE_TYPE_ID                  0x0008  /* Image Type ID */
9729 #define ZBEE_ZCL_ATTR_ID_OTA_MIN_BLOCK_REQ_DELAY            0x0009  /* Minimum Block Request Delay */
9730 
9731 /* Server Commands Generated */
9732 #define ZBEE_ZCL_CMD_ID_OTA_IMAGE_NOTIFY                      0x00  /* Image Notify */
9733 #define ZBEE_ZCL_CMD_ID_OTA_QUERY_NEXT_IMAGE_RSP              0x02  /* Query Next Image Response */
9734 #define ZBEE_ZCL_CMD_ID_OTA_IMAGE_BLOCK_RSP                   0x05  /* Image Block Response */
9735 #define ZBEE_ZCL_CMD_ID_OTA_UPGRADE_END_RSP                   0x07  /* Upgrade End Response */
9736 #define ZBEE_ZCL_CMD_ID_OTA_QUERY_SPEC_FILE_RSP               0x09  /* Query Specific File Response */
9737 
9738 /* Server Commands Received */
9739 #define ZBEE_ZCL_CMD_ID_OTA_QUERY_NEXT_IMAGE_REQ              0x01  /* Query Next Image Request */
9740 #define ZBEE_ZCL_CMD_ID_OTA_IMAGE_BLOCK_REQ                   0x03  /* Image Block Request */
9741 #define ZBEE_ZCL_CMD_ID_OTA_IMAGE_PAGE_REQ                    0x04  /* Image Page Request */
9742 #define ZBEE_ZCL_CMD_ID_OTA_UPGRADE_END_REQ                   0x06  /* Upgrade End Request */
9743 #define ZBEE_ZCL_CMD_ID_OTA_QUERY_SPEC_FILE_REQ               0x08  /* Query Specific File Request */
9744 
9745 /* Payload Type */
9746 #define ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ                          0x00  /* Query Jitter */
9747 #define ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC                       0x01  /* Query Jitter and Manufacturer Code */
9748 #define ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC_IT                    0x02  /* Query Jitter, Manufacturer Code and Image Type */
9749 #define ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC_IT_FV                 0x03  /* Query Jitter, Manufacturer Code, Image Type and File Version */
9750 
9751 /* Image Type */
9752 #define ZBEE_ZCL_OTA_IMG_TYPE_MFR_LOW                       0x0000  /* Manufacturer Specific (Low value) */
9753 #define ZBEE_ZCL_OTA_IMG_TYPE_MFR_HIGH                      0xffbf  /* Manufacturer Specific (High value) */
9754 #define ZBEE_ZCL_OTA_IMG_TYPE_SECURITY                      0xffc0  /* Security Credential */
9755 #define ZBEE_ZCL_OTA_IMG_TYPE_CONFIG                        0xffc1  /* Configuration */
9756 #define ZBEE_ZCL_OTA_IMG_TYPE_LOG                           0xffc2  /* Log */
9757 #define ZBEE_ZCL_OTA_IMG_TYPE_UNASSIGNED_LOW                0xffc3  /* Reserved: Unassigned (Low value) */
9758 #define ZBEE_ZCL_OTA_IMG_TYPE_UNASSIGNED_HIGH               0xfffe  /* Reserved: Unassigned (High value) */
9759 #define ZBEE_ZCL_OTA_IMG_TYPE_WILD_CARD                     0xffff  /* Reserved: Wild Card */
9760 
9761 /* ZigBee Stack Version */
9762 #define ZBEE_ZCL_OTA_ZB_STACK_VER_2006                      0x0000  /* ZigBee 2006 */
9763 #define ZBEE_ZCL_OTA_ZB_STACK_VER_2007                      0x0001  /* ZigBee 2007 */
9764 #define ZBEE_ZCL_OTA_ZB_STACK_VER_PRO                       0x0002  /* ZigBee Pro */
9765 #define ZBEE_ZCL_OTA_ZB_STACK_VER_IP                        0x0003  /* ZigBee IP */
9766 #define ZBEE_ZCL_OTA_ZB_STACK_VER_RESERVED_LO               0x0004  /* Reserved Low */
9767 #define ZBEE_ZCL_OTA_ZB_STACK_VER_RESERVED_HI               0xffff  /* Reserved High */
9768 
9769 /* Image Upgrade Status */
9770 #define ZBEE_ZCL_OTA_STATUS_NORMAL                            0x00  /* Normal */
9771 #define ZBEE_ZCL_OTA_STATUS_DOWNLOAD_IN_PROGRESS              0x01  /* Download in progress */
9772 #define ZBEE_ZCL_OTA_STATUS_DOWNLOAD_COMPLETE                 0x02  /* Download complete */
9773 #define ZBEE_ZCL_OTA_STATUS_WAITING_TO_UPGRADE                0x03  /* Waiting to upgrade */
9774 #define ZBEE_ZCL_OTA_STATUS_COUNT_DOWN                        0x04  /* Count down */
9775 #define ZBEE_ZCL_OTA_STATUS_WAIT_FOR_MORE                     0x05  /* Wait for more */
9776                                                                     /* 0x06-0xff - Reserved */
9777 /* File Version mask */
9778 #define ZBEE_ZCL_OTA_FILE_VERS_APPL_RELEASE             0xFF000000  /* Application Release */
9779 #define ZBEE_ZCL_OTA_FILE_VERS_APPL_BUILD               0x00FF0000  /* Application Build */
9780 #define ZBEE_ZCL_OTA_FILE_VERS_STACK_RELEASE            0x0000FF00  /* Stack Release */
9781 #define ZBEE_ZCL_OTA_FILE_VERS_STACK_BUILD              0x000000FF  /* Stack Build */
9782 
9783 /* Field Control bitmask field list for Query Next Image Request */
9784 #define ZBEE_ZCL_OTA_QUERY_NEXT_IMAGE_REQ_FIELD_CTRL_HW_VER_PRESENT         0x01  /* bit 0 */
9785 #define ZBEE_ZCL_OTA_QUERY_NEXT_IMAGE_REQ_FIELD_CTRL_RESERVED               0xfe  /* bit 1-7 */
9786 
9787 /* Field Control bitmask field list for Image Block Request */
9788 #define ZBEE_ZCL_OTA_IMAGE_BLOCK_REQ_FIELD_CTRL_REQUEST_NODE_ADDR_PRESENT   0x01  /* bit 0 - Request node IEEE address Present */
9789 #define ZBEE_ZCL_OTA_IMAGE_BLOCK_REQ_FIELD_CTRL_MIN_BLOCK_PERIOD_PRESENT    0x02  /* bit 1 - Minimum block period Present */
9790 #define ZBEE_ZCL_OTA_IMAGE_BLOCK_REQ_FIELD_CTRL_RESERVED                    0xfc  /* bit 2-7 */
9791 
9792 /* Field Control bitmask field list for Image Page Request */
9793 #define ZBEE_ZCL_OTA_IMAGE_PAGE_REQ_FIELD_CTRL_REQUEST_NODE_ADDR_PRESENT    0x01  /* bit 0 - Request node IEEE address Present */
9794 #define ZBEE_ZCL_OTA_IMAGE_PAGE_REQ_FIELD_CTRL_RESERVED                     0xfe  /* bit 1-7 */
9795 
9796 /* OTA Time */
9797 #define ZBEE_ZCL_OTA_TIME_NOW                           0x00000000  /* Now */
9798 #define ZBEE_ZCL_OTA_TIME_UTC_LO                        0x00000001  /* UTC Low Boundary */
9799 #define ZBEE_ZCL_OTA_TIME_UTC_HI                        0xfffffffe  /* UTC High Boundary */
9800 #define ZBEE_ZCL_OTA_TIME_WAIT                          0xffffffff  /* Wait for a Upgrade command (not used for RequesTime) */
9801 
9802 /*************************/
9803 /* Function Declarations */
9804 /*************************/
9805 
9806 void proto_register_zbee_zcl_ota(void);
9807 void proto_reg_handoff_zbee_zcl_ota(void);
9808 
9809 /*************************/
9810 /* Global Variables      */
9811 /*************************/
9812 /* Initialize the protocol and registered fields */
9813 static int proto_zbee_zcl_ota = -1;
9814 
9815 static int hf_zbee_zcl_ota_attr_id = -1;
9816 static int hf_zbee_zcl_ota_srv_tx_cmd_id = -1;
9817 static int hf_zbee_zcl_ota_srv_rx_cmd_id = -1;
9818 static int hf_zbee_zcl_ota_image_upgrade_status = -1;
9819 static int hf_zbee_zcl_ota_zb_stack_ver = -1;
9820 static int hf_zbee_zcl_ota_file_offset = -1;
9821 static int hf_zbee_zcl_ota_payload_type = -1;
9822 static int hf_zbee_zcl_ota_query_jitter = -1;
9823 static int hf_zbee_zcl_ota_manufacturer_code = -1;
9824 static int hf_zbee_zcl_ota_image_type = -1;
9825 static int hf_zbee_zcl_ota_file_version = -1;
9826 static int hf_zbee_zcl_ota_file_version_appl_release = -1;
9827 static int hf_zbee_zcl_ota_file_version_appl_build = -1;
9828 static int hf_zbee_zcl_ota_file_version_stack_release = -1;
9829 static int hf_zbee_zcl_ota_file_version_stack_build = -1;
9830 static int hf_zbee_zcl_ota_query_next_image_req_field_ctrl = -1;
9831 static int hf_zbee_zcl_ota_query_next_image_req_field_ctrl_hw_ver_present = -1;
9832 static int hf_zbee_zcl_ota_query_next_image_req_field_ctrl_reserved = -1;
9833 static int hf_zbee_zcl_ota_image_block_req_field_ctrl = -1;
9834 static int hf_zbee_zcl_ota_image_block_req_field_ctrl_ieee_addr_present = -1;
9835 static int hf_zbee_zcl_ota_image_block_req_field_ctrl_min_block_period_present = -1;
9836 static int hf_zbee_zcl_ota_image_block_req_field_ctrl_reserved = -1;
9837 static int hf_zbee_zcl_ota_image_page_req_field_ctrl = -1;
9838 static int hf_zbee_zcl_ota_image_page_req_field_ctrl_ieee_addr_present = -1;
9839 static int hf_zbee_zcl_ota_image_page_req_field_ctrl_reserved = -1;
9840 static int hf_zbee_zcl_ota_hw_version = -1;
9841 static int hf_zbee_zcl_ota_status = -1;
9842 static int hf_zbee_zcl_ota_image_size = -1;
9843 static int hf_zbee_zcl_ota_max_data_size = -1;
9844 static int hf_zbee_zcl_ota_min_block_period = -1;
9845 static int hf_zbee_zcl_ota_req_node_addr = -1;
9846 static int hf_zbee_zcl_ota_current_time = -1;
9847 static int hf_zbee_zcl_ota_request_time = -1;
9848 static int hf_zbee_zcl_ota_upgrade_time = -1;
9849 static int hf_zbee_zcl_ota_data_size = -1;
9850 static int hf_zbee_zcl_ota_image_data = -1;
9851 static int hf_zbee_zcl_ota_page_size = -1;
9852 static int hf_zbee_zcl_ota_rsp_spacing = -1;
9853 
9854 /* Initialize the subtree pointers */
9855 static gint ett_zbee_zcl_ota = -1;
9856 static gint ett_zbee_zcl_ota_query_next_image_req_field_ctrl = -1;
9857 static gint ett_zbee_zcl_ota_image_block_req_field_ctrl = -1;
9858 static gint ett_zbee_zcl_ota_image_page_req_field_ctrl = -1;
9859 static gint ett_zbee_zcl_ota_file_version = -1;
9860 
9861 /* Attributes */
9862 static const value_string zbee_zcl_ota_attr_names[] = {
9863     { ZBEE_ZCL_ATTR_ID_OTA_UPGRADE_SERVER_ID,               "Upgrade Server ID" },
9864     { ZBEE_ZCL_ATTR_ID_OTA_FILE_OFFSET,                     "File Offset" },
9865     { ZBEE_ZCL_ATTR_ID_OTA_CURRENT_FILE_VERSION,            "Current File Version" },
9866     { ZBEE_ZCL_ATTR_ID_OTA_CURRENT_ZB_STACK_VERSION,        "Current ZigBee Stack Version" },
9867     { ZBEE_ZCL_ATTR_ID_OTA_DOWNLOADED_FILE_VERSION,         "Downloaded File Version" },
9868     { ZBEE_ZCL_ATTR_ID_OTA_DOWNLOADED_ZB_STACK_VERSION,     "Downloaded ZigBee Stack Version" },
9869     { ZBEE_ZCL_ATTR_ID_OTA_IMAGE_UPGRADE_STATUS,            "Image Upgrade Status" },
9870     { ZBEE_ZCL_ATTR_ID_OTA_MANUFACTURER_ID,                 "Manufacturer ID" },
9871     { ZBEE_ZCL_ATTR_ID_OTA_IMAGE_TYPE_ID,                   "Image Type ID" },
9872     { ZBEE_ZCL_ATTR_ID_OTA_MIN_BLOCK_REQ_DELAY,             "Minimum Block Request Delay" },
9873     { 0, NULL }
9874 };
9875 
9876 /* Server Commands Received */
9877 static const value_string zbee_zcl_ota_srv_rx_cmd_names[] = {
9878     { ZBEE_ZCL_CMD_ID_OTA_QUERY_NEXT_IMAGE_REQ,             "Query Next Image Request" },
9879     { ZBEE_ZCL_CMD_ID_OTA_IMAGE_BLOCK_REQ,                  "Image Block Request" },
9880     { ZBEE_ZCL_CMD_ID_OTA_IMAGE_PAGE_REQ,                   "Image Page Request" },
9881     { ZBEE_ZCL_CMD_ID_OTA_UPGRADE_END_REQ,                  "Upgrade End Request" },
9882     { ZBEE_ZCL_CMD_ID_OTA_QUERY_SPEC_FILE_REQ,              "Query Specific File Request" },
9883     { 0, NULL }
9884 };
9885 
9886 /* Server Commands Generated */
9887 static const value_string zbee_zcl_ota_srv_tx_cmd_names[] = {
9888     { ZBEE_ZCL_CMD_ID_OTA_IMAGE_NOTIFY,                     "Image Notify" },
9889     { ZBEE_ZCL_CMD_ID_OTA_QUERY_NEXT_IMAGE_RSP,             "Query Next Image Response" },
9890     { ZBEE_ZCL_CMD_ID_OTA_IMAGE_BLOCK_RSP,                  "Image Block Response" },
9891     { ZBEE_ZCL_CMD_ID_OTA_UPGRADE_END_RSP,                  "Upgrade End Response" },
9892     { ZBEE_ZCL_CMD_ID_OTA_QUERY_SPEC_FILE_RSP,              "Query Specific File Response" },
9893     { 0, NULL }
9894 };
9895 
9896 /* Payload Type */
9897 static const value_string zbee_zcl_ota_paylaod_type_names[] = {
9898     { ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ,                         "Query Jitter" },
9899     { ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC,                      "Query Jitter and Manufacturer Code" },
9900     { ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC_IT,                   "Query Jitter, Manufacturer Code and Image Type" },
9901     { ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC_IT_FV,                "Query Jitter, Manufacturer Code, Image Type and File Version" },
9902     { 0, NULL }
9903 };
9904 
9905 /* Image Upgrade Status */
9906 static const value_string zbee_zcl_ota_image_upgrade_attr_status_names[] = {
9907     { ZBEE_ZCL_OTA_STATUS_NORMAL,                           "Normal" },
9908     { ZBEE_ZCL_OTA_STATUS_DOWNLOAD_IN_PROGRESS,             "Download in progress" },
9909     { ZBEE_ZCL_OTA_STATUS_DOWNLOAD_COMPLETE,                "Download complete" },
9910     { ZBEE_ZCL_OTA_STATUS_WAITING_TO_UPGRADE,               "Waiting to upgrade" },
9911     { ZBEE_ZCL_OTA_STATUS_COUNT_DOWN,                       "Count down" },
9912     { ZBEE_ZCL_OTA_STATUS_WAIT_FOR_MORE,                    "Wait for more" },
9913     { 0, NULL }
9914 };
9915 
9916 /* ZigBee Stack Version */
9917 static const range_string zbee_zcl_ota_zb_stack_ver_names[] = {
9918     { ZBEE_ZCL_OTA_ZB_STACK_VER_2006,         ZBEE_ZCL_OTA_ZB_STACK_VER_2006,         "ZigBee 2006" },
9919     { ZBEE_ZCL_OTA_ZB_STACK_VER_2007,         ZBEE_ZCL_OTA_ZB_STACK_VER_2007,         "ZigBee 2007" },
9920     { ZBEE_ZCL_OTA_ZB_STACK_VER_PRO,          ZBEE_ZCL_OTA_ZB_STACK_VER_PRO,          "ZigBee Pro" },
9921     { ZBEE_ZCL_OTA_ZB_STACK_VER_IP,           ZBEE_ZCL_OTA_ZB_STACK_VER_IP,           "ZigBee IP" },
9922     { ZBEE_ZCL_OTA_ZB_STACK_VER_RESERVED_LO,  ZBEE_ZCL_OTA_ZB_STACK_VER_RESERVED_HI,  "Reserved" },
9923     { 0, 0, NULL },
9924 };
9925 
9926 /* Image Type */
9927 static const range_string zbee_zcl_ota_image_type_names[] = {
9928     {ZBEE_ZCL_OTA_IMG_TYPE_MFR_LOW,         ZBEE_ZCL_OTA_IMG_TYPE_MFR_HIGH,         "Manufacturer Specific" },
9929     {ZBEE_ZCL_OTA_IMG_TYPE_SECURITY,        ZBEE_ZCL_OTA_IMG_TYPE_SECURITY,         "Security Credential" },
9930     {ZBEE_ZCL_OTA_IMG_TYPE_CONFIG,          ZBEE_ZCL_OTA_IMG_TYPE_CONFIG,           "Configuration" },
9931     {ZBEE_ZCL_OTA_IMG_TYPE_LOG,             ZBEE_ZCL_OTA_IMG_TYPE_LOG,              "Log" },
9932     {ZBEE_ZCL_OTA_IMG_TYPE_UNASSIGNED_LOW,  ZBEE_ZCL_OTA_IMG_TYPE_UNASSIGNED_HIGH,  "Reserved: Unassigned" },
9933     {ZBEE_ZCL_OTA_IMG_TYPE_WILD_CARD,       ZBEE_ZCL_OTA_IMG_TYPE_WILD_CARD,        "Reserved: Wild Card" },
9934     { 0, 0, NULL }
9935 };
9936 
9937 /*************************/
9938 /* Function Bodies       */
9939 /*************************/
9940 
9941 /*FUNCTION:------------------------------------------------------
9942  *  NAME
9943  *      decode_zcl_ota_curr_time
9944  *  DESCRIPTION
9945  *    this function decode the current time field
9946  *  PARAMETERS
9947  *  RETURNS
9948  *      none
9949  *---------------------------------------------------------------
9950  */
9951 static void
decode_zcl_ota_curr_time(gchar * s,guint32 value)9952 decode_zcl_ota_curr_time(gchar *s, guint32 value)
9953 {
9954     if (value == ZBEE_ZCL_OTA_TIME_NOW) {
9955         g_snprintf(s, ITEM_LABEL_LENGTH, "Now");
9956     }
9957     else {
9958         gchar *tmp;
9959         value += ZBEE_ZCL_NSTIME_UTC_OFFSET;
9960         tmp = abs_time_secs_to_str(NULL, value, ABSOLUTE_TIME_LOCAL, 1);
9961         g_snprintf(s, ITEM_LABEL_LENGTH, "%s", tmp);
9962         wmem_free(NULL, tmp);
9963     }
9964 
9965     return;
9966 } /*decode_zcl_ota_curr_time*/
9967 
9968 /*FUNCTION:------------------------------------------------------
9969  *  NAME
9970  *      decode_zcl_ota_req_time
9971  *  DESCRIPTION
9972  *    this function decode the request time field
9973  *  PARAMETERS
9974  *  RETURNS
9975  *      none
9976  *---------------------------------------------------------------
9977  */
9978 static void
decode_zcl_ota_req_time(gchar * s,guint32 value)9979 decode_zcl_ota_req_time(gchar *s, guint32 value)
9980 {
9981     if (value == ZBEE_ZCL_OTA_TIME_WAIT) {
9982         g_snprintf(s, ITEM_LABEL_LENGTH, "Wrong Value");
9983     }
9984     else {
9985         /* offset from now */
9986         gchar *tmp = signed_time_secs_to_str(NULL, value);
9987         g_snprintf(s, ITEM_LABEL_LENGTH, "%s from now", tmp);
9988         wmem_free(NULL, tmp);
9989     }
9990 
9991     return;
9992 } /*decode_zcl_ota_req_time*/
9993 
9994 /*FUNCTION:------------------------------------------------------
9995  *  NAME
9996  *      decode_zcl_ota_upgr_time
9997  *  DESCRIPTION
9998  *    this function decode the upgrade time field
9999  *  PARAMETERS
10000  *  RETURNS
10001  *      none
10002  *---------------------------------------------------------------
10003  */
10004 static void
decode_zcl_ota_upgr_time(gchar * s,guint32 value)10005 decode_zcl_ota_upgr_time(gchar *s, guint32 value)
10006 {
10007     if (value == ZBEE_ZCL_OTA_TIME_WAIT) {
10008         g_snprintf(s, ITEM_LABEL_LENGTH, "Wait for upgrade command");
10009     }
10010     else {
10011         /* offset from now */
10012         gchar *tmp = signed_time_secs_to_str(NULL, value);
10013         g_snprintf(s, ITEM_LABEL_LENGTH, "%s from now", tmp);
10014         wmem_free(NULL, tmp);
10015     }
10016 
10017     return;
10018 } /*decode_zcl_ota_upgr_time*/
10019 
10020 /*FUNCTION:------------------------------------------------------
10021  *  NAME
10022  *      decode_zcl_ota_size_in_bytes
10023  *  DESCRIPTION
10024  *    this function decodes size in bytes
10025  *  PARAMETERS
10026  *  RETURNS
10027  *      none
10028  *---------------------------------------------------------------
10029  */
10030 static void
decode_zcl_ota_size_in_bytes(gchar * s,guint32 value)10031 decode_zcl_ota_size_in_bytes(gchar *s, guint32 value)
10032 {
10033     g_snprintf(s, ITEM_LABEL_LENGTH, "%d [Bytes]", value);
10034 } /*decode_zcl_ota_size_in_bytes*/
10035 
10036 /*FUNCTION:------------------------------------------------------
10037  *  NAME
10038  *      dissect_zcl_ota_file_version_field
10039  *  DESCRIPTION
10040  *      this function is called in order to decode "FileVersion" field,
10041  *  PARAMETERS
10042  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10043  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10044  *      guint *offset       - pointer to buffer offset
10045  *  RETURNS
10046  *      none
10047  *---------------------------------------------------------------
10048  */
10049 static void
dissect_zcl_ota_file_version_field(tvbuff_t * tvb,proto_tree * tree,guint * offset)10050 dissect_zcl_ota_file_version_field(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10051 {
10052     static int * const file_version[] = {
10053         &hf_zbee_zcl_ota_file_version_appl_release,
10054         &hf_zbee_zcl_ota_file_version_appl_build,
10055         &hf_zbee_zcl_ota_file_version_stack_release,
10056         &hf_zbee_zcl_ota_file_version_stack_build,
10057         NULL
10058     };
10059 
10060     /* 'File Version' field present, retrieves it */
10061     /* File version is Little endian. as well as all ZigBee data structures:
10062        "The endianness used in each data field shall be little endian in order
10063        to be compliant with general ZigBee messages."
10064        File version A: 0x10053519 represents application release 1.0 build 05 with stack release 3.5 b19
10065     */
10066     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_ota_file_version, ett_zbee_zcl_ota_file_version, file_version, ENC_LITTLE_ENDIAN);
10067     *offset += 4;
10068 } /*dissect_zcl_ota_file_version_field*/
10069 
10070 /*FUNCTION:------------------------------------------------------
10071  *  NAME
10072  *      dissect_zcl_ota_field_ctrl_field
10073  *  DESCRIPTION
10074  *      this function is called in order to decode "FileVersion" field,
10075  *  PARAMETERS
10076  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10077  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10078  *      guint *offset       - pointer to buffer offset
10079  *      int hf_hdr          - hf_hdr
10080  *      gint ett            - ett subtree index
10081  *      int* const *fields  - fields an array of pointers to int that lists all the fields of the bitmask
10082  *  RETURNS
10083  *      guint8              - field ctrl value
10084  *---------------------------------------------------------------
10085  */
10086 static guint8
dissect_zcl_ota_field_ctrl_field(tvbuff_t * tvb,proto_tree * tree,guint * offset,int hf_hdr,gint ett,int * const * fields)10087 dissect_zcl_ota_field_ctrl_field(tvbuff_t *tvb, proto_tree *tree, guint *offset, int hf_hdr, gint ett, int * const *fields)
10088 {
10089     guint8      field;
10090 
10091     /* Retrieve 'Field Control' field */
10092     field = tvb_get_guint8(tvb, *offset);
10093     proto_tree_add_bitmask(tree, tvb, *offset, hf_hdr, ett, fields, ENC_NA);
10094     *offset += 1;
10095 
10096     return field;
10097 } /*dissect_zcl_ota_field_ctrl_field*/
10098 
10099 /*FUNCTION:------------------------------------------------------
10100  *  NAME
10101  *      dissect_zcl_ota_imagenotify
10102  *  DESCRIPTION
10103  *      this function is called in order to decode "ImageNotify",
10104  *  PARAMETERS
10105  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10106  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10107  *      guint *offset       - pointer to buffer offset
10108  *  RETURNS
10109  *      none
10110  *---------------------------------------------------------------
10111  */
10112 static void
dissect_zcl_ota_imagenotify(tvbuff_t * tvb,proto_tree * tree,guint * offset)10113 dissect_zcl_ota_imagenotify(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10114 {
10115     guint8  payload_type;
10116 
10117     /* Retrieve 'Payload type' field */
10118     payload_type = tvb_get_guint8(tvb, *offset);
10119     proto_tree_add_item(tree, hf_zbee_zcl_ota_payload_type, tvb, *offset, 1, ENC_NA);
10120     *offset += 1;
10121 
10122     /* Retrieve 'Query Jitter' field */
10123     proto_tree_add_item(tree, hf_zbee_zcl_ota_query_jitter, tvb, *offset, 1, ENC_NA);
10124     *offset += 1;
10125 
10126     /* Check if there are optional fields */
10127 
10128     if (payload_type >= ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC) {
10129         /* 'Manufacturer Code' field present, retrieves it */
10130         proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10131         *offset += 2;
10132     }
10133 
10134     if (payload_type >= ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC_IT) {
10135         /* 'Image Type' field present, retrieves it */
10136         proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10137         *offset += 2;
10138     }
10139 
10140     if (payload_type >= ZBEE_ZCL_OTA_PAYLOAD_TYPE_QJ_MC_IT_FV) {
10141         /* 'File Version' field present, retrieves it */
10142         dissect_zcl_ota_file_version_field(tvb, tree, offset);
10143     }
10144 
10145 } /*dissect_zcl_ota_imagenotify*/
10146 
10147 /*FUNCTION:------------------------------------------------------
10148  *  NAME
10149  *      dissect_zcl_ota_querynextimagereq
10150  *  DESCRIPTION
10151  *      this function is called in order to decode "QueryNextImageRequest",
10152  *  PARAMETERS
10153  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10154  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10155  *      guint *offset       - pointer to buffer offset
10156  *  RETURNS
10157  *      none
10158  *---------------------------------------------------------------
10159  */
10160 static void
dissect_zcl_ota_querynextimagereq(tvbuff_t * tvb,proto_tree * tree,guint * offset)10161 dissect_zcl_ota_querynextimagereq(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10162 {
10163     static int * const fields[] = {
10164         &hf_zbee_zcl_ota_query_next_image_req_field_ctrl_hw_ver_present,
10165         &hf_zbee_zcl_ota_query_next_image_req_field_ctrl_reserved,
10166         NULL
10167     };
10168 
10169     guint8  field_ctrl;
10170 
10171     /* Retrieve 'Field Control' field */
10172     field_ctrl = dissect_zcl_ota_field_ctrl_field(tvb, tree, offset, hf_zbee_zcl_ota_query_next_image_req_field_ctrl, ett_zbee_zcl_ota_query_next_image_req_field_ctrl, fields);
10173 
10174     /* Retrieve 'Manufacturer Code' field */
10175     proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10176     *offset += 2;
10177 
10178     /* Retrieve 'Image Type' field */
10179     proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10180     *offset += 2;
10181 
10182     /* Retrieve 'File Version' field */
10183     dissect_zcl_ota_file_version_field(tvb, tree, offset);
10184 
10185     /* Check if there are optional fields */
10186     if (field_ctrl & ZBEE_ZCL_OTA_QUERY_NEXT_IMAGE_REQ_FIELD_CTRL_HW_VER_PRESENT) {
10187         /* 'Hardware Version' field present, retrieves it */
10188         proto_tree_add_item(tree, hf_zbee_zcl_ota_hw_version, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10189         *offset += 2;
10190     }
10191 } /*dissect_zcl_ota_querynextimagereq*/
10192 
10193 /*FUNCTION:------------------------------------------------------
10194  *  NAME
10195  *      dissect_zcl_ota_querynextimagersp
10196  *  DESCRIPTION
10197  *      this function is called in order to decode "QueryNextImageResponse",
10198  *  PARAMETERS
10199  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10200  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10201  *      guint *offset       - pointer to buffer offset
10202  *  RETURNS
10203  *      none
10204  *---------------------------------------------------------------
10205  */
10206 static void
dissect_zcl_ota_querynextimagersp(tvbuff_t * tvb,proto_tree * tree,guint * offset)10207 dissect_zcl_ota_querynextimagersp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10208 {
10209     guint8  status;
10210 
10211     /* Retrieve 'Status' field */
10212     status = tvb_get_guint8(tvb, *offset);
10213     proto_tree_add_item(tree, hf_zbee_zcl_ota_status, tvb, *offset, 1, ENC_NA);
10214     *offset += 1;
10215 
10216     /* Check if there are optional fields */
10217     if (status == ZBEE_ZCL_STAT_SUCCESS) {
10218         /* Retrieve 'Manufacturer Code' field */
10219         proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10220         *offset += 2;
10221 
10222         /* Retrieve 'Image Type' field */
10223         proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10224         *offset += 2;
10225 
10226         /* Retrieve 'File Version' field */
10227         dissect_zcl_ota_file_version_field(tvb, tree, offset);
10228 
10229         /* Retrieve 'Image Size' field */
10230         proto_tree_add_item(tree, hf_zbee_zcl_ota_image_size, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10231         *offset += 4;
10232     }
10233 
10234 } /*dissect_zcl_ota_querynextimagersp*/
10235 
10236 /*FUNCTION:------------------------------------------------------
10237  *  NAME
10238  *      dissect_zcl_ota_imageblockreq
10239  *  DESCRIPTION
10240  *      this function is called in order to decode "ImageBlockRequest",
10241  *  PARAMETERS
10242  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10243  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10244  *      guint *offset       - pointer to buffer offset
10245  *  RETURNS
10246  *      none
10247  *---------------------------------------------------------------
10248  */
10249 static void
dissect_zcl_ota_imageblockreq(tvbuff_t * tvb,proto_tree * tree,guint * offset)10250 dissect_zcl_ota_imageblockreq(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10251 {
10252     static int * const fields[] = {
10253         &hf_zbee_zcl_ota_image_block_req_field_ctrl_ieee_addr_present,
10254         &hf_zbee_zcl_ota_image_block_req_field_ctrl_min_block_period_present,
10255         &hf_zbee_zcl_ota_image_block_req_field_ctrl_reserved,
10256         NULL
10257     };
10258 
10259     guint8  field_ctrl;
10260 
10261     /* Retrieve 'Field Control' field */
10262     field_ctrl = dissect_zcl_ota_field_ctrl_field(tvb, tree, offset, hf_zbee_zcl_ota_image_block_req_field_ctrl, ett_zbee_zcl_ota_image_block_req_field_ctrl, fields);
10263 
10264     /* Retrieve 'Manufacturer Code' field */
10265     proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10266     *offset += 2;
10267 
10268     /* Retrieve 'Image Type' field */
10269     proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10270     *offset += 2;
10271 
10272     /* Retrieve 'File Version' field */
10273     dissect_zcl_ota_file_version_field(tvb, tree, offset);
10274 
10275     /* Retrieve 'File Offset' field */
10276     proto_tree_add_item(tree, hf_zbee_zcl_ota_file_offset, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10277     *offset += 4;
10278 
10279     /* Retrieve 'Maximum Data Size' field */
10280     proto_tree_add_item(tree, hf_zbee_zcl_ota_max_data_size, tvb, *offset, 1, ENC_NA);
10281     *offset += 1;
10282 
10283     /* Check if there are optional fields */
10284     if (field_ctrl & ZBEE_ZCL_OTA_IMAGE_BLOCK_REQ_FIELD_CTRL_REQUEST_NODE_ADDR_PRESENT) {
10285         /* 'Request Node Address' field present, retrieve it */
10286         proto_tree_add_item(tree, hf_zbee_zcl_ota_req_node_addr, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
10287         *offset += 8;
10288     }
10289     if (field_ctrl & ZBEE_ZCL_OTA_IMAGE_BLOCK_REQ_FIELD_CTRL_MIN_BLOCK_PERIOD_PRESENT) {
10290         /* 'Minimum Block Period' field present, retrieve it */
10291         proto_tree_add_item(tree, hf_zbee_zcl_ota_min_block_period, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10292         *offset += 2;
10293     }
10294 } /*dissect_zcl_ota_imageblockreq*/
10295 
10296 /*FUNCTION:------------------------------------------------------
10297  *  NAME
10298  *      dissect_zcl_ota_imagepagereq
10299  *  DESCRIPTION
10300  *      this function is called in order to decode "ImagePageRequest",
10301  *  PARAMETERS
10302  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10303  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10304  *      guint *offset       - pointer to buffer offset
10305  *  RETURNS
10306  *      none
10307  *---------------------------------------------------------------
10308  */
10309 static void
dissect_zcl_ota_imagepagereq(tvbuff_t * tvb,proto_tree * tree,guint * offset)10310 dissect_zcl_ota_imagepagereq(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10311 {
10312     static int * const fields[] = {
10313         &hf_zbee_zcl_ota_image_page_req_field_ctrl_ieee_addr_present,
10314         &hf_zbee_zcl_ota_image_page_req_field_ctrl_reserved,
10315         NULL
10316     };
10317 
10318     guint8  field_ctrl;
10319 
10320     /* Retrieve 'Field Control' field */
10321     field_ctrl = dissect_zcl_ota_field_ctrl_field(tvb, tree, offset, hf_zbee_zcl_ota_image_page_req_field_ctrl, ett_zbee_zcl_ota_image_page_req_field_ctrl, fields);
10322 
10323     /* Retrieve 'Manufacturer Code' field */
10324     proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10325     *offset += 2;
10326 
10327     /* Retrieve 'Image Type' field */
10328     proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10329     *offset += 2;
10330 
10331     /* Retrieve 'File Version' field */
10332     dissect_zcl_ota_file_version_field(tvb, tree, offset);
10333 
10334     /* Retrieve 'File Offset' field */
10335     proto_tree_add_item(tree, hf_zbee_zcl_ota_file_offset, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10336     *offset += 4;
10337 
10338     /* Retrieve 'Maximum Data Size' field */
10339     proto_tree_add_item(tree, hf_zbee_zcl_ota_max_data_size, tvb, *offset, 1, ENC_NA);
10340     *offset += 1;
10341 
10342     /* Retrieve 'Page Size' field */
10343     proto_tree_add_item(tree, hf_zbee_zcl_ota_page_size, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10344     *offset += 2;
10345 
10346     /* Retrieve 'Response Spacing' field */
10347     proto_tree_add_item(tree, hf_zbee_zcl_ota_rsp_spacing, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10348     *offset += 2;
10349 
10350     /* Check if there are optional fields */
10351     if (field_ctrl & ZBEE_ZCL_OTA_IMAGE_PAGE_REQ_FIELD_CTRL_REQUEST_NODE_ADDR_PRESENT) {
10352         /* 'Request Node Address' field present, retrieves it */
10353         proto_tree_add_item(tree, hf_zbee_zcl_ota_req_node_addr, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
10354         *offset += 8;
10355     }
10356 } /*dissect_zcl_ota_imagepagereq*/
10357 
10358 /*FUNCTION:------------------------------------------------------
10359  *  NAME
10360  *      dissect_zcl_ota_imageblockrsp
10361  *  DESCRIPTION
10362  *      this function is called in order to decode "ImageBlockResponse",
10363  *  PARAMETERS
10364  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10365  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10366  *      guint *offset       - pointer to buffer offset
10367  *  RETURNS
10368  *      none
10369  *---------------------------------------------------------------
10370  */
10371 static void
dissect_zcl_ota_imageblockrsp(tvbuff_t * tvb,proto_tree * tree,guint * offset)10372 dissect_zcl_ota_imageblockrsp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10373 {
10374     guint8  status;
10375     guint8  data_size;
10376 
10377     /* Retrieve 'Status' field */
10378     status = tvb_get_guint8(tvb, *offset);
10379     proto_tree_add_item(tree, hf_zbee_zcl_ota_status, tvb, *offset, 1, ENC_NA);
10380     *offset += 1;
10381 
10382     if (status == ZBEE_ZCL_STAT_SUCCESS) {
10383         /* Retrieve 'Manufacturer Code' field */
10384         proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10385         *offset += 2;
10386 
10387         /* Retrieve 'Image Type' field */
10388         proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10389         *offset += 2;
10390 
10391         /* Retrieve 'File Version' field */
10392         dissect_zcl_ota_file_version_field(tvb, tree, offset);
10393 
10394         /* Retrieve 'File Offset' field */
10395         proto_tree_add_item(tree, hf_zbee_zcl_ota_file_offset, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10396         *offset += 4;
10397 
10398         /* Retrieve 'Data Size' field */
10399         data_size = tvb_get_guint8(tvb, *offset);
10400         proto_tree_add_item(tree, hf_zbee_zcl_ota_data_size, tvb, *offset, 1, ENC_NA);
10401         *offset += 1;
10402 
10403         /* Retrieve 'Image Data' field */
10404         proto_tree_add_item(tree, hf_zbee_zcl_ota_image_data, tvb, *offset, data_size, ENC_NA);
10405         *offset += data_size;
10406     }
10407     else if (status == ZBEE_ZCL_STAT_OTA_WAIT_FOR_DATA) {
10408         /* Retrieve 'Current Time' field */
10409         proto_tree_add_item(tree, hf_zbee_zcl_ota_current_time, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10410         *offset += 4;
10411 
10412         /* Retrieve 'Request Time' field */
10413         proto_tree_add_item(tree, hf_zbee_zcl_ota_request_time, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10414         *offset += 4;
10415     }
10416     else {
10417       /* */
10418     }
10419 
10420 } /*dissect_zcl_ota_imageblockrsp*/
10421 
10422 /*FUNCTION:------------------------------------------------------
10423  *  NAME
10424  *      dissect_zcl_ota_upgradeendreq
10425  *  DESCRIPTION
10426  *      this function is called in order to decode "UpgradeEndRequest",
10427  *  PARAMETERS
10428  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10429  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10430  *      guint *offset       - pointer to buffer offset
10431  *  RETURNS
10432  *      none
10433  *---------------------------------------------------------------
10434  */
10435 static void
dissect_zcl_ota_upgradeendreq(tvbuff_t * tvb,proto_tree * tree,guint * offset)10436 dissect_zcl_ota_upgradeendreq(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10437 {
10438     /* Retrieve 'Status' field */
10439     proto_tree_add_item(tree, hf_zbee_zcl_ota_status, tvb, *offset, 1, ENC_NA);
10440     *offset += 1;
10441 
10442     /* Retrieve 'Manufacturer Code' field */
10443     proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10444     *offset += 2;
10445 
10446     /* Retrieve 'Image Type' field */
10447     proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10448     *offset += 2;
10449 
10450     /* Retrieve 'File Version' field */
10451     dissect_zcl_ota_file_version_field(tvb, tree, offset);
10452 
10453 } /*dissect_zcl_ota_upgradeendreq*/
10454 
10455 /*FUNCTION:------------------------------------------------------
10456  *  NAME
10457  *      dissect_zcl_ota_upgradeendrsp
10458  *  DESCRIPTION
10459  *      this function is called in order to decode "UpgradeEndResponse",
10460  *  PARAMETERS
10461  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10462  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10463  *      guint *offset       - pointer to buffer offset
10464  *  RETURNS
10465  *      none
10466  *---------------------------------------------------------------
10467  */
10468 static void
dissect_zcl_ota_upgradeendrsp(tvbuff_t * tvb,proto_tree * tree,guint * offset)10469 dissect_zcl_ota_upgradeendrsp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10470 {
10471     /* Retrieve 'Manufacturer Code' field */
10472     proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10473     *offset += 2;
10474 
10475     /* Retrieve 'Image Type' field */
10476     proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10477     *offset += 2;
10478 
10479     /* Retrieve 'File Version' field */
10480     dissect_zcl_ota_file_version_field(tvb, tree, offset);
10481 
10482     /* Retrieve 'Current Time' field */
10483     proto_tree_add_item(tree, hf_zbee_zcl_ota_current_time, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10484     *offset += 4;
10485 
10486     /* Retrieve 'Upgrade Time' field */
10487     proto_tree_add_item(tree, hf_zbee_zcl_ota_upgrade_time, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10488     *offset += 4;
10489 
10490 } /*dissect_zcl_ota_upgradeendrsp*/
10491 
10492 /*FUNCTION:------------------------------------------------------
10493  *  NAME
10494  *      dissect_zcl_ota_queryspecfilereq
10495  *  DESCRIPTION
10496  *      this function is called in order to decode "QuerySpecificFileRequest",
10497  *  PARAMETERS
10498  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10499  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10500  *      guint *offset       - pointer to buffer offset
10501  *  RETURNS
10502  *      none
10503  *---------------------------------------------------------------
10504  */
10505 static void
dissect_zcl_ota_queryspecfilereq(tvbuff_t * tvb,proto_tree * tree,guint * offset)10506 dissect_zcl_ota_queryspecfilereq(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10507 {
10508     /* 'Request Node Address' field present, retrieves it */
10509     proto_tree_add_item(tree, hf_zbee_zcl_ota_req_node_addr, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
10510     *offset += 8;
10511 
10512     /* Retrieve 'Manufacturer Code' field */
10513     proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10514     *offset += 2;
10515 
10516     /* Retrieve 'Image Type' field */
10517     proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10518     *offset += 2;
10519 
10520     /* Retrieve 'File Version' field */
10521     dissect_zcl_ota_file_version_field(tvb, tree, offset);
10522 
10523     /* Retrieve 'ZigBee Stack Version' field */
10524     proto_tree_add_item(tree, hf_zbee_zcl_ota_zb_stack_ver, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10525     *offset += 2;
10526 
10527 } /*dissect_zcl_ota_queryspecfilereq*/
10528 
10529 /*FUNCTION:------------------------------------------------------
10530  *  NAME
10531  *      dissect_zcl_ota_queryspecfilersp
10532  *  DESCRIPTION
10533  *      this function is called in order to decode "QuerySpecificFileResponse",
10534  *  PARAMETERS
10535  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10536  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10537  *      guint *offset       - pointer to buffer offset
10538  *  RETURNS
10539  *      none
10540  *---------------------------------------------------------------
10541  */
10542 static void
dissect_zcl_ota_queryspecfilersp(tvbuff_t * tvb,proto_tree * tree,guint * offset)10543 dissect_zcl_ota_queryspecfilersp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
10544 {
10545     guint8  status;
10546 
10547     /* Retrieve 'Status' field */
10548     status = tvb_get_guint8(tvb, *offset);
10549     proto_tree_add_item(tree, hf_zbee_zcl_ota_status, tvb, *offset, 1, ENC_NA);
10550     *offset += 1;
10551 
10552     if (status == ZBEE_ZCL_STAT_SUCCESS) {
10553         /* Retrieve 'Manufacturer Code' field */
10554         proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10555         *offset += 2;
10556 
10557         /* Retrieve 'Image Type' field */
10558         proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10559         *offset += 2;
10560 
10561         /* Retrieve 'File Version' field */
10562         dissect_zcl_ota_file_version_field(tvb, tree, offset);
10563 
10564         /* Retrieve 'Image Size' field */
10565         proto_tree_add_item(tree, hf_zbee_zcl_ota_image_size, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
10566         *offset += 4;
10567     }
10568 
10569 } /*dissect_zcl_ota_queryspecfilersp*/
10570 
10571 
10572 /*FUNCTION:------------------------------------------------------
10573  *  NAME
10574  *      dissect_zcl_ota_attr_data
10575  *  DESCRIPTION
10576  *      this function is called by ZCL foundation dissector in order to decode
10577  *      specific cluster attributes data.
10578  *  PARAMETERS
10579  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10580  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10581  *      guint *offset       - pointer to buffer offset
10582  *      guint16 attr_id     - attribute identifier
10583  *      guint data_type     - attribute data type
10584  *      gboolean client_attr- ZCL client
10585  *  RETURNS
10586  *      none
10587  *---------------------------------------------------------------
10588  */
10589 static void
dissect_zcl_ota_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)10590 dissect_zcl_ota_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
10591 {
10592     /* Dissect attribute data type and data */
10593     switch ( attr_id )
10594     {
10595         case ZBEE_ZCL_ATTR_ID_OTA_CURRENT_FILE_VERSION:
10596         case ZBEE_ZCL_ATTR_ID_OTA_DOWNLOADED_FILE_VERSION:
10597             dissect_zcl_ota_file_version_field(tvb, tree, offset);
10598             break;
10599 
10600         case ZBEE_ZCL_ATTR_ID_OTA_CURRENT_ZB_STACK_VERSION:
10601         case ZBEE_ZCL_ATTR_ID_OTA_DOWNLOADED_ZB_STACK_VERSION:
10602             proto_tree_add_item(tree, hf_zbee_zcl_ota_zb_stack_ver, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10603             *offset += 2;
10604             break;
10605 
10606         case ZBEE_ZCL_ATTR_ID_OTA_IMAGE_UPGRADE_STATUS:
10607             proto_tree_add_item(tree, hf_zbee_zcl_ota_image_upgrade_status, tvb, *offset, 1, ENC_NA);
10608             *offset += 1;
10609             break;
10610 
10611         case ZBEE_ZCL_ATTR_ID_OTA_MANUFACTURER_ID:
10612             proto_tree_add_item(tree, hf_zbee_zcl_ota_manufacturer_code, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10613             *offset += 2;
10614             break;
10615 
10616         case ZBEE_ZCL_ATTR_ID_OTA_IMAGE_TYPE_ID:
10617             proto_tree_add_item(tree, hf_zbee_zcl_ota_image_type, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
10618             *offset += 2;
10619             break;
10620 
10621         case ZBEE_ZCL_ATTR_ID_OTA_MIN_BLOCK_REQ_DELAY:
10622         default:
10623             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
10624             break;
10625     }
10626 } /*dissect_zcl_ota_attr_data*/
10627 
10628 
10629 /*FUNCTION:------------------------------------------------------
10630  *  NAME
10631  *      dissect_zbee_zcl_ota
10632  *  DESCRIPTION
10633  *      ZigBee ZCL OTA cluster dissector for wireshark.
10634  *  PARAMETERS
10635  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10636  *      packet_info *pinfo  - pointer to packet information fields
10637  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10638  *      void *data          - pointer to ZCL packet structure.
10639  *  RETURNS
10640  *      int                 - length of parsed data.
10641  *---------------------------------------------------------------
10642  */
10643 static int
dissect_zbee_zcl_ota(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)10644 dissect_zbee_zcl_ota(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
10645 {
10646     proto_tree        *payload_tree;
10647     zbee_zcl_packet   *zcl;
10648     guint             offset = 0;
10649     guint8            cmd_id;
10650     gint              rem_len;
10651 
10652     /* Reject the packet if data is NULL */
10653     if (data == NULL)
10654         return 0;
10655     zcl = (zbee_zcl_packet *)data;
10656     cmd_id = zcl->cmd_id;
10657 
10658     /* Create a subtree for the ZCL Command frame, and add the command ID to it. */
10659     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
10660         /* Append the command name to the info column. */
10661         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
10662             val_to_str_const(cmd_id, zbee_zcl_ota_srv_rx_cmd_names, "Unknown Command"),
10663             zcl->tran_seqno);
10664 
10665         /* Add the command ID. */
10666         proto_tree_add_item(tree, hf_zbee_zcl_ota_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10667 
10668         /* Check is this command has a payload, than add the payload tree */
10669         rem_len = tvb_reported_length_remaining(tvb, ++offset);
10670         if (rem_len > 0) {
10671             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_ota, NULL, "Payload");
10672 
10673             /* Call the appropriate command dissector */
10674             switch (cmd_id) {
10675                 case ZBEE_ZCL_CMD_ID_OTA_QUERY_NEXT_IMAGE_REQ:
10676                     dissect_zcl_ota_querynextimagereq(tvb, payload_tree, &offset);
10677                     break;
10678 
10679                 case ZBEE_ZCL_CMD_ID_OTA_IMAGE_BLOCK_REQ:
10680                     dissect_zcl_ota_imageblockreq(tvb, payload_tree, &offset);
10681                     break;
10682 
10683                 case ZBEE_ZCL_CMD_ID_OTA_IMAGE_PAGE_REQ:
10684                     dissect_zcl_ota_imagepagereq(tvb, payload_tree, &offset);
10685                     break;
10686 
10687                 case ZBEE_ZCL_CMD_ID_OTA_UPGRADE_END_REQ:
10688                     dissect_zcl_ota_upgradeendreq(tvb, payload_tree, &offset);
10689                     break;
10690 
10691                 case ZBEE_ZCL_CMD_ID_OTA_QUERY_SPEC_FILE_REQ:
10692                     dissect_zcl_ota_queryspecfilereq(tvb, payload_tree, &offset);
10693                     break;
10694 
10695                 default:
10696                     break;
10697             }
10698         }
10699     }
10700     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
10701         /* Append the command name to the info column. */
10702         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
10703             val_to_str_const(cmd_id, zbee_zcl_ota_srv_tx_cmd_names, "Unknown Command"),
10704             zcl->tran_seqno);
10705 
10706         /* Add the command ID. */
10707         proto_tree_add_item(tree, hf_zbee_zcl_ota_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
10708 
10709         /* Check is this command has a payload, than add the payload tree */
10710         rem_len = tvb_reported_length_remaining(tvb, ++offset);
10711         if (rem_len > 0) {
10712             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_ota, NULL, "Payload");
10713 
10714             /* Call the appropriate command dissector */
10715             switch (cmd_id) {
10716                 case ZBEE_ZCL_CMD_ID_OTA_IMAGE_NOTIFY:
10717                     dissect_zcl_ota_imagenotify(tvb, payload_tree, &offset);
10718                     break;
10719 
10720                 case ZBEE_ZCL_CMD_ID_OTA_QUERY_NEXT_IMAGE_RSP:
10721                     dissect_zcl_ota_querynextimagersp(tvb, payload_tree, &offset);
10722                     break;
10723 
10724                 case ZBEE_ZCL_CMD_ID_OTA_IMAGE_BLOCK_RSP:
10725                     dissect_zcl_ota_imageblockrsp(tvb, payload_tree, &offset);
10726                     break;
10727 
10728                 case ZBEE_ZCL_CMD_ID_OTA_UPGRADE_END_RSP:
10729                     dissect_zcl_ota_upgradeendrsp(tvb, payload_tree, &offset);
10730                     break;
10731 
10732                 case ZBEE_ZCL_CMD_ID_OTA_QUERY_SPEC_FILE_RSP:
10733                     dissect_zcl_ota_queryspecfilersp(tvb, payload_tree, &offset);
10734                     break;
10735 
10736                 default:
10737                     break;
10738             }
10739         }
10740     }
10741 
10742     return tvb_captured_length(tvb);
10743 } /*dissect_zbee_zcl_ota*/
10744 
10745 /*FUNCTION:------------------------------------------------------
10746  *  NAME
10747  *      proto_register_zbee_zcl_ota
10748  *  DESCRIPTION
10749  *      this function is called by ZCL foundation dissector in order to decode
10750  *      specific cluster attributes data.
10751  *  PARAMETERS
10752  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
10753  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
10754  *      guint *offset       - pointer to buffer offset
10755  *      guint16 attr_id     - attribute identifier
10756  *      guint data_type     - attribute data type
10757  *  RETURNS
10758  *      none
10759  *---------------------------------------------------------------
10760  */
proto_register_zbee_zcl_ota(void)10761 void proto_register_zbee_zcl_ota(void)
10762 {
10763     static hf_register_info hf[] = {
10764 
10765         { &hf_zbee_zcl_ota_attr_id,
10766             { "Attribute", "zbee_zcl_general.ota.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_ota_attr_names),
10767             0x0, NULL, HFILL } },
10768 
10769         { &hf_zbee_zcl_ota_srv_tx_cmd_id,
10770             { "Command", "zbee_zcl_general.ota.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_ota_srv_tx_cmd_names),
10771             0x0, NULL, HFILL } },
10772 
10773         { &hf_zbee_zcl_ota_srv_rx_cmd_id,
10774             { "Command", "zbee_zcl_general.ota.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_ota_srv_rx_cmd_names),
10775             0x0, NULL, HFILL } },
10776 
10777         { &hf_zbee_zcl_ota_image_upgrade_status,
10778             { "Image Upgrade Status", "zbee_zcl_general.ota.status_attr", FT_UINT8, BASE_HEX, VALS(zbee_zcl_ota_image_upgrade_attr_status_names),
10779             0x0, NULL, HFILL } },
10780 
10781         { &hf_zbee_zcl_ota_zb_stack_ver,
10782             { "ZigBee Stack Version", "zbee_zcl_general.ota.zb_stack.ver", FT_UINT16, BASE_HEX | BASE_RANGE_STRING,
10783             RVALS(zbee_zcl_ota_zb_stack_ver_names), 0x0, NULL, HFILL } },
10784 
10785         { &hf_zbee_zcl_ota_payload_type,
10786             { "Payload Type", "zbee_zcl_general.ota.payload.type", FT_UINT8, BASE_HEX, VALS(zbee_zcl_ota_paylaod_type_names),
10787             0x0, NULL, HFILL } },
10788 
10789         { &hf_zbee_zcl_ota_query_jitter,
10790             { "Query Jitter", "zbee_zcl_general.ota.query_jitter", FT_UINT8, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_seconds),
10791             0x0, NULL, HFILL } },
10792 
10793         { &hf_zbee_zcl_ota_manufacturer_code,
10794             { "Manufacturer Code", "zbee_zcl_general.ota.manufacturer_code", FT_UINT16, BASE_HEX, VALS(zbee_mfr_code_names),
10795             0x0, NULL, HFILL } },
10796 
10797         { &hf_zbee_zcl_ota_image_type,
10798             { "Image Type", "zbee_zcl_general.ota.image.type", FT_UINT16, BASE_HEX | BASE_RANGE_STRING,
10799             RVALS(zbee_zcl_ota_image_type_names), 0x0, NULL, HFILL } },
10800 
10801 /* Begin FileVersion fields */
10802         { &hf_zbee_zcl_ota_file_version,
10803             { "File Version", "zbee_zcl_general.ota.file.version", FT_UINT32, BASE_HEX, NULL,
10804             0x0, NULL, HFILL } },
10805 
10806         { &hf_zbee_zcl_ota_file_version_appl_release,
10807             { "Application Release", "zbee_zcl_general.ota.file.version.appl.release", FT_UINT32, BASE_DEC, NULL,
10808             ZBEE_ZCL_OTA_FILE_VERS_APPL_RELEASE, NULL, HFILL } },
10809 
10810         { &hf_zbee_zcl_ota_file_version_appl_build,
10811             { "Application Build", "zbee_zcl_general.ota.file.version.appl.build", FT_UINT32, BASE_DEC, NULL,
10812             ZBEE_ZCL_OTA_FILE_VERS_APPL_BUILD, NULL, HFILL } },
10813 
10814         { &hf_zbee_zcl_ota_file_version_stack_release,
10815             { "Stack Release", "zbee_zcl_general.ota.file.version.stack.release", FT_UINT32, BASE_DEC, NULL,
10816             ZBEE_ZCL_OTA_FILE_VERS_STACK_RELEASE, NULL, HFILL } },
10817 
10818         { &hf_zbee_zcl_ota_file_version_stack_build,
10819             { "Stack Build", "zbee_zcl_general.ota.file.version.stack.build", FT_UINT32, BASE_DEC, NULL,
10820             ZBEE_ZCL_OTA_FILE_VERS_STACK_BUILD, NULL, HFILL } },
10821 /* End FileVersion fields */
10822 
10823 /* Begin FieldControl fields Query Next Image Request */
10824         { &hf_zbee_zcl_ota_query_next_image_req_field_ctrl,
10825             { "Field Control", "zbee_zcl_general.ota.query_next_image_req.field_ctrl",
10826             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
10827 
10828         { &hf_zbee_zcl_ota_query_next_image_req_field_ctrl_hw_ver_present,
10829             { "Hardware Version", "zbee_zcl_general.ota.query_next_image_req.field_ctrl.hw_ver_present",
10830             FT_BOOLEAN, 8, TFS(&tfs_present_not_present), ZBEE_ZCL_OTA_QUERY_NEXT_IMAGE_REQ_FIELD_CTRL_HW_VER_PRESENT, NULL, HFILL } },
10831 
10832         { &hf_zbee_zcl_ota_query_next_image_req_field_ctrl_reserved,
10833             { "Reserved", "zbee_zcl_general.ota.query_next_image_req.field_ctrl.reserved", FT_UINT8, BASE_HEX, NULL,
10834             ZBEE_ZCL_OTA_QUERY_NEXT_IMAGE_REQ_FIELD_CTRL_RESERVED, NULL, HFILL } },
10835 /* End FieldControl fields Query Next Image Request */
10836 
10837 /* Begin FieldControl fields Image Block Request */
10838         { &hf_zbee_zcl_ota_image_block_req_field_ctrl,
10839             { "Field Control", "zbee_zcl_general.ota.image_block_req.field_ctrl",
10840             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
10841 
10842         { &hf_zbee_zcl_ota_image_block_req_field_ctrl_ieee_addr_present,
10843             { "Request Node Address", "zbee_zcl_general.ota.image_block_req.field_ctrl.request_node_addr_present",
10844             FT_BOOLEAN, 8, TFS(&tfs_present_not_present), ZBEE_ZCL_OTA_IMAGE_BLOCK_REQ_FIELD_CTRL_REQUEST_NODE_ADDR_PRESENT, NULL, HFILL } },
10845 
10846         { &hf_zbee_zcl_ota_image_block_req_field_ctrl_min_block_period_present,
10847             { "Minimum Block Period", "zbee_zcl_general.ota.image_block_req.field_ctrl.min_block_period",
10848             FT_BOOLEAN, 8, TFS(&tfs_present_not_present), ZBEE_ZCL_OTA_IMAGE_BLOCK_REQ_FIELD_CTRL_MIN_BLOCK_PERIOD_PRESENT, NULL, HFILL } },
10849 
10850         { &hf_zbee_zcl_ota_image_block_req_field_ctrl_reserved,
10851             { "Reserved", "zbee_zcl_general.ota.query_next_image_req.field_ctrl.reserved", FT_UINT8, BASE_HEX, NULL,
10852             ZBEE_ZCL_OTA_IMAGE_BLOCK_REQ_FIELD_CTRL_RESERVED, NULL, HFILL } },
10853 /* End FieldControl fields Image Block Request */
10854 
10855 /* Begin FieldControl fields Image Page Request */
10856         { &hf_zbee_zcl_ota_image_page_req_field_ctrl,
10857             { "Field Control", "zbee_zcl_general.ota.image_page_req.field_ctrl",
10858             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
10859 
10860         { &hf_zbee_zcl_ota_image_page_req_field_ctrl_ieee_addr_present,
10861             { "Request Node Address", "zbee_zcl_general.ota.query_next_image_req.field_ctrl.request_node_addr_present",
10862             FT_BOOLEAN, 8, TFS(&tfs_present_not_present), ZBEE_ZCL_OTA_IMAGE_PAGE_REQ_FIELD_CTRL_REQUEST_NODE_ADDR_PRESENT, NULL, HFILL } },
10863 
10864         { &hf_zbee_zcl_ota_image_page_req_field_ctrl_reserved,
10865             { "Reserved", "zbee_zcl_general.ota.image_page_req.field_ctrl.reserved", FT_UINT8, BASE_HEX, NULL,
10866             ZBEE_ZCL_OTA_IMAGE_PAGE_REQ_FIELD_CTRL_RESERVED, NULL, HFILL } },
10867 /* End FieldControl fields Image Page Request */
10868 
10869         { &hf_zbee_zcl_ota_hw_version,
10870             { "Hardware Version", "zbee_zcl_general.ota.hw_ver", FT_UINT16, BASE_HEX, NULL,
10871             0x0, NULL, HFILL } },
10872 
10873         { &hf_zbee_zcl_ota_status,
10874             { "Status", "zbee_zcl_general.ota.status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_status_names),
10875             0x0, NULL, HFILL } },
10876 
10877         { &hf_zbee_zcl_ota_image_size,
10878             { "Image Size", "zbee_zcl_general.ota.image.size", FT_UINT32, BASE_CUSTOM, CF_FUNC(decode_zcl_ota_size_in_bytes),
10879             0x0, NULL, HFILL } },
10880 
10881         { &hf_zbee_zcl_ota_file_offset,
10882             { "File Offset", "zbee_zcl_general.ota.file.offset", FT_UINT32, BASE_DEC, NULL,
10883             0x0, NULL, HFILL } },
10884 
10885         { &hf_zbee_zcl_ota_max_data_size,
10886             { "Max Data Size", "zbee_zcl_general.ota.max_data_size", FT_UINT8, BASE_DEC, NULL,
10887             0x0, NULL, HFILL } },
10888 
10889         { &hf_zbee_zcl_ota_min_block_period,
10890             { "Minimum Block Period", "zbee_zcl_general.ota.min_block_period", FT_UINT16, BASE_DEC, NULL,
10891             0x0, NULL, HFILL } },
10892 
10893         { &hf_zbee_zcl_ota_req_node_addr,
10894             { "Ieee Address", "zbee_zcl_general.ota.ieee_addr", FT_UINT64, BASE_HEX, NULL,
10895             0x0, NULL, HFILL } },
10896 
10897         { &hf_zbee_zcl_ota_page_size,
10898             { "Page Size", "zbee_zcl_general.ota.page.size", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_ota_size_in_bytes),
10899             0x0, NULL, HFILL } },
10900 
10901         { &hf_zbee_zcl_ota_rsp_spacing,
10902             { "Response Spacing", "zbee_zcl_general.ota.rsp_spacing", FT_UINT16, BASE_HEX, NULL,
10903             0x0, NULL, HFILL } },
10904 
10905         { &hf_zbee_zcl_ota_current_time,
10906             { "Current Time", "zbee_zcl_general.ota.current_time", FT_UINT32, BASE_CUSTOM, CF_FUNC(decode_zcl_ota_curr_time),
10907             0x0, NULL, HFILL }},
10908 
10909         { &hf_zbee_zcl_ota_request_time,
10910             { "Request Time", "zbee_zcl_general.ota.request_time", FT_UINT32, BASE_CUSTOM, CF_FUNC(decode_zcl_ota_req_time),
10911             0x0, NULL, HFILL }},
10912 
10913         { &hf_zbee_zcl_ota_upgrade_time,
10914             { "Upgrade Time", "zbee_zcl_general.ota.upgrade_time", FT_UINT32, BASE_CUSTOM, CF_FUNC(decode_zcl_ota_upgr_time),
10915             0x0, NULL, HFILL }},
10916 
10917         { &hf_zbee_zcl_ota_data_size,
10918             { "Data Size", "zbee_zcl_general.ota.data_size", FT_UINT8, BASE_DEC, NULL,
10919             0x00, NULL, HFILL } },
10920 
10921         { &hf_zbee_zcl_ota_image_data,
10922             { "Image Data", "zbee_zcl_general.ota.image.data", FT_BYTES, SEP_COLON, NULL,
10923             0x00, NULL, HFILL } }
10924    };
10925 
10926     /* ZCL OTA subtrees */
10927     gint *ett[] = {
10928         &ett_zbee_zcl_ota,
10929         &ett_zbee_zcl_ota_query_next_image_req_field_ctrl,
10930         &ett_zbee_zcl_ota_image_block_req_field_ctrl,
10931         &ett_zbee_zcl_ota_image_page_req_field_ctrl,
10932         &ett_zbee_zcl_ota_file_version
10933     };
10934 
10935     /* Register ZigBee ZCL Ota protocol with Wireshark. */
10936     proto_zbee_zcl_ota = proto_register_protocol("ZigBee ZCL OTA", "ZCL OTA", ZBEE_PROTOABBREV_ZCL_OTA);
10937     proto_register_field_array(proto_zbee_zcl_ota, hf, array_length(hf));
10938     proto_register_subtree_array(ett, array_length(ett));
10939 
10940     /* Register the ZigBee ZCL OTA dissector. */
10941     register_dissector(ZBEE_PROTOABBREV_ZCL_OTA, dissect_zbee_zcl_ota, proto_zbee_zcl_ota);
10942 
10943 } /* proto_register_zbee_zcl_ota */
10944 
10945 
10946 /*FUNCTION:------------------------------------------------------
10947  *  NAME
10948  *      proto_reg_handoff_zbee_zcl_ota
10949  *  DESCRIPTION
10950  *      Registers the zigbee ZCL OTA cluster dissector with Wireshark.
10951  *  PARAMETERS
10952  *      none
10953  *  RETURNS
10954  *      void
10955  *---------------------------------------------------------------
10956  */
proto_reg_handoff_zbee_zcl_ota(void)10957 void proto_reg_handoff_zbee_zcl_ota(void)
10958 {
10959     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_OTA,
10960                             proto_zbee_zcl_ota,
10961                             ett_zbee_zcl_ota,
10962                             ZBEE_ZCL_CID_OTA_UPGRADE,
10963                             ZBEE_MFG_CODE_NONE,
10964                             hf_zbee_zcl_ota_attr_id,
10965                             hf_zbee_zcl_ota_attr_id,
10966                             hf_zbee_zcl_ota_srv_rx_cmd_id,
10967                             hf_zbee_zcl_ota_srv_tx_cmd_id,
10968                             (zbee_zcl_fn_attr_data)dissect_zcl_ota_attr_data
10969                          );
10970 
10971 } /*proto_reg_handoff_zbee_zcl_ota*/
10972 
10973 /* ########################################################################## */
10974 /* #### (0x001A) POWER PROFILE CLUSTER ###################################### */
10975 /* ########################################################################## */
10976 
10977 /*************************/
10978 /* Defines               */
10979 /*************************/
10980 
10981 #define ZBEE_ZCL_PWR_PROF_NUM_GENERIC_ETT         4
10982 #define ZBEE_ZCL_PWR_PROF_NUM_PWR_PROF_ETT        5
10983 #define ZBEE_ZCL_PWR_PROF_NUM_EN_PHS_ETT          16
10984 #define ZBEE_ZCL_PWR_PROF_NUM_ETT                 (ZBEE_ZCL_PWR_PROF_NUM_GENERIC_ETT +  \
10985                                                    ZBEE_ZCL_PWR_PROF_NUM_PWR_PROF_ETT + \
10986                                                    ZBEE_ZCL_PWR_PROF_NUM_EN_PHS_ETT)
10987 
10988 /* Attributes */
10989 #define ZBEE_ZCL_ATTR_ID_PWR_PROF_TOT_PROF_NUM              0x0000  /* Total Profile Number */
10990 #define ZBEE_ZCL_ATTR_ID_PWR_PROF_MULTIPLE_SCHED            0x0001  /* Multiple Schedule */
10991 #define ZBEE_ZCL_ATTR_ID_PWR_PROF_ENERGY_FORMAT             0x0002  /* Energy Formatting */
10992 #define ZBEE_ZCL_ATTR_ID_PWR_PROF_ENERGY_REMOTE             0x0003  /* Energy Remote */
10993 #define ZBEE_ZCL_ATTR_ID_PWR_PROF_SCHED_MODE                0x0004  /* Schedule Mode */
10994 
10995 /* Server Commands Received */
10996 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_REQ                           0x00  /* Power Profile Request */
10997 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_REQ                     0x01  /* Power Profile State Request */
10998 #define ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_RSP                 0x02  /* Get Power Profile Price Response */
10999 #define ZBEE_ZCL_CMD_ID_PWR_PROF_GET_OVERALL_SCHED_PRICE_RSP            0x03  /* Get Overall Schedule Price Response */
11000 #define ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_NOTIF              0x04  /* Energy Phases Schedule Notification */
11001 #define ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_RSP                0x05  /* Energy Phases Schedule Response */
11002 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_REQ             0x06  /* Power Profile Schedule Constraints Request */
11003 #define ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_REQ          0x07  /* Energy Phases Schedule State Request */
11004 #define ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_EXT_RSP             0x08  /* Get Power Profile Price Extended Response */
11005 
11006 /* Server Commands Generated */
11007 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_NOTIF                         0x00  /* Power Profile Notification */
11008 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_RSP                           0x01  /* Power Profile Response */
11009 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_RSP                     0x02  /* Power Profile State Response */
11010 #define ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE                     0x03  /* Get Power Profile Price */
11011 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_NOTIF                   0x04  /* Power Profile State Notification */
11012 #define ZBEE_ZCL_CMD_ID_PWR_PROF_GET_OVERALL_SCHED_PRICE                0x05  /* Get Overall Schedule Price */
11013 #define ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_REQ                0x06  /* Energy Phases Schedule Request */
11014 #define ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_RSP          0x07  /* Energy Phases Schedule State Response */
11015 #define ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_NOITIF       0x08  /* Energy Phases Schedule State Notification */
11016 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_NOTIF           0x09  /* Power Profile Schedule Constraints Notification */
11017 #define ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_RSP             0x0A  /* Power Profile Schedule Constraints Response */
11018 #define ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_EXT                 0x0B  /* Get Power Profile Price Extended */
11019 
11020 /* Power Profile StateId */
11021 #define ZBEE_ZCL_PWR_PROF_STATE_ID_PWR_PROF_IDLE                        0x00  /* Power Profile Idle */
11022 #define ZBEE_ZCL_PWR_PROF_STATE_ID_PWR_PROF_PROGRAMMED                  0x01  /* Power Profile Programmed */
11023 #define ZBEE_ZCL_PWR_PROF_STATE_ID_EN_PH_RUNNING                        0x03  /* Energy Phase Running */
11024 #define ZBEE_ZCL_PWR_PROF_STATE_ID_EN_PH_PAUSE                          0x04  /* Energy Phase Pause */
11025 #define ZBEE_ZCL_PWR_PROF_STATE_ID_EN_PH_WAITING_TO_START               0x05  /* Energy Phase Waiting to Start */
11026 #define ZBEE_ZCL_PWR_PROF_STATE_ID_EN_PH_WAITING_PAUSED                 0x06  /* Energy Phase Waiting Pause */
11027 #define ZBEE_ZCL_PWR_PROF_STATE_ID_PWR_PROF_ENDED                       0x07  /* Power Profile Ended */
11028 
11029 /* Energy Formatting bitmask field list */
11030 #define ZBEE_ZCL_OPT_PWRPROF_NUM_R_DIGIT                                0x07  /* bits 0..2 */
11031 #define ZBEE_ZCL_OPT_PWRPROF_NUM_L_DIGIT                                0x78  /* bits 3..6 */
11032 #define ZBEE_ZCL_OPT_PWRPROF_NO_LEADING_ZERO                            0x80  /* bit     7 */
11033 
11034 /* Schedule Mode bitmask field list */
11035 #define ZBEE_ZCL_OPT_PWRPROF_SCHED_CHEAPEST                             0x01  /* bit     0 */
11036 #define ZBEE_ZCL_OPT_PWRPROF_SCHED_GREENEST                             0x02  /* bit     1 */
11037 #define ZBEE_ZCL_OPT_PWRPROF_SCHED_RESERVED                             0xfc  /* bits 2..7 */
11038 
11039 /* Options bitmask field list */
11040 #define ZBEE_ZCL_OPT_PWRPROF_STIME_PRESENT                              0x01  /* bit     0 */
11041 #define ZBEE_ZCL_OPT_PWRPROF_RESERVED                                   0xfe  /* bits 1..7 */
11042 
11043 /*************************/
11044 /* Function Declarations */
11045 /*************************/
11046 
11047 void proto_register_zbee_zcl_pwr_prof(void);
11048 void proto_reg_handoff_zbee_zcl_pwr_prof(void);
11049 
11050 /* Command Dissector Helpers */
11051 static void dissect_zcl_pwr_prof_pwrprofreq                 (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11052 static void dissect_zcl_pwr_prof_getpwrprofpricersp         (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11053 static void dissect_zcl_pwr_prof_getoverallschedpricersp    (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11054 static void dissect_zcl_pwr_prof_enphsschednotif            (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11055 
11056 static void dissect_zcl_energy_phase                        (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11057 static void dissect_zcl_pwr_prof_pwrprofnotif               (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11058 static void dissect_zcl_power_profile                       (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11059 static void dissect_zcl_pwr_prof_pwrprofstatersp            (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11060 static void dissect_zcl_pwr_prof_pwrprofschedcontrsnotif    (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11061 static void dissect_zcl_pwr_prof_pwrprofpriceext            (tvbuff_t *tvb, proto_tree *tree, guint *offset);
11062 
11063 static void dissect_zcl_pwr_prof_attr_data  (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
11064 
11065 /* Private functions prototype */
11066 static void decode_power_profile_id     (gchar *s, guint8 id);
11067 static void decode_price_in_cents       (gchar *s, guint32 value);
11068 static void decode_power_in_watt        (gchar *s, guint16 value);
11069 static void decode_energy               (gchar *s, guint16 value);
11070 
11071 /*************************/
11072 /* Global Variables      */
11073 /*************************/
11074 /* Initialize the protocol and registered fields */
11075 static int proto_zbee_zcl_pwr_prof = -1;
11076 
11077 static int hf_zbee_zcl_pwr_prof_attr_id = -1;
11078 static int hf_zbee_zcl_pwr_prof_tot_prof_num = -1;
11079 static int hf_zbee_zcl_pwr_prof_multiple_sched = -1;
11080 static int hf_zbee_zcl_pwr_prof_energy_format = -1;
11081 static int hf_zbee_zcl_pwr_prof_energy_format_rdigit = -1;
11082 static int hf_zbee_zcl_pwr_prof_energy_format_ldigit = -1;
11083 static int hf_zbee_zcl_pwr_prof_energy_format_noleadingzero = -1;
11084 static int hf_zbee_zcl_pwr_prof_energy_remote = -1;
11085 static int hf_zbee_zcl_pwr_prof_sched_mode = -1;
11086 static int hf_zbee_zcl_pwr_prof_sched_mode_cheapest = -1;
11087 static int hf_zbee_zcl_pwr_prof_sched_mode_greenest = -1;
11088 static int hf_zbee_zcl_pwr_prof_sched_mode_reserved = -1;
11089 static int hf_zbee_zcl_pwr_prof_srv_tx_cmd_id = -1;
11090 static int hf_zbee_zcl_pwr_prof_srv_rx_cmd_id = -1;
11091 static int hf_zbee_zcl_pwr_prof_pwr_prof_id = -1;
11092 static int hf_zbee_zcl_pwr_prof_currency = -1;
11093 static int hf_zbee_zcl_pwr_prof_price = -1;
11094 static int hf_zbee_zcl_pwr_prof_price_trailing_digit = -1;
11095 static int hf_zbee_zcl_pwr_prof_num_of_sched_phases = -1;
11096 static int hf_zbee_zcl_pwr_prof_scheduled_time = -1;
11097 static int hf_zbee_zcl_pwr_prof_pwr_prof_count = -1;
11098 static int hf_zbee_zcl_pwr_prof_num_of_trans_phases = -1;
11099 static int hf_zbee_zcl_pwr_prof_energy_phase_id = -1;
11100 static int hf_zbee_zcl_pwr_prof_macro_phase_id = -1;
11101 static int hf_zbee_zcl_pwr_prof_expect_duration = -1;
11102 static int hf_zbee_zcl_pwr_prof_peak_power = -1;
11103 static int hf_zbee_zcl_pwr_prof_energy = -1;
11104 static int hf_zbee_zcl_pwr_prof_max_active_delay = -1;
11105 static int hf_zbee_zcl_pwr_prof_pwr_prof_rem_ctrl = -1;
11106 static int hf_zbee_zcl_pwr_prof_pwr_prof_state = -1;
11107 static int hf_zbee_zcl_pwr_prof_start_after = -1;
11108 static int hf_zbee_zcl_pwr_prof_stop_before = -1;
11109 static int hf_zbee_zcl_pwr_prof_options = -1;
11110 static int hf_zbee_zcl_pwr_prof_options_01 = -1;
11111 static int hf_zbee_zcl_pwr_prof_options_res = -1;
11112 static int hf_zbee_zcl_pwr_prof_pwr_prof_stime = -1;
11113 
11114 /* Initialize the subtree pointers */
11115 static gint ett_zbee_zcl_pwr_prof = -1;
11116 static gint ett_zbee_zcl_pwr_prof_options = -1;
11117 static gint ett_zbee_zcl_pwr_prof_en_format = -1;
11118 static gint ett_zbee_zcl_pwr_prof_sched_mode = -1;
11119 static gint ett_zbee_zcl_pwr_prof_pwrprofiles[ZBEE_ZCL_PWR_PROF_NUM_PWR_PROF_ETT];
11120 static gint ett_zbee_zcl_pwr_prof_enphases[ZBEE_ZCL_PWR_PROF_NUM_EN_PHS_ETT];
11121 
11122 /* Attributes */
11123 static const value_string zbee_zcl_pwr_prof_attr_names[] = {
11124     { ZBEE_ZCL_ATTR_ID_PWR_PROF_TOT_PROF_NUM,                    "Total Profile Number" },
11125     { ZBEE_ZCL_ATTR_ID_PWR_PROF_MULTIPLE_SCHED,                  "Multiple Scheduling" },
11126     { ZBEE_ZCL_ATTR_ID_PWR_PROF_ENERGY_FORMAT,                   "Energy Formatting" },
11127     { ZBEE_ZCL_ATTR_ID_PWR_PROF_ENERGY_REMOTE,                   "Energy Remote" },
11128     { ZBEE_ZCL_ATTR_ID_PWR_PROF_SCHED_MODE,                      "Schedule Mode" },
11129     { 0, NULL }
11130 };
11131 
11132 /* Server Commands Received */
11133 static const value_string zbee_zcl_pwr_prof_srv_rx_cmd_names[] = {
11134     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_REQ,                     "Power Profile Request" },
11135     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_REQ,               "Power Profile State Request" },
11136     { ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_RSP,           "Get Power Profile Price Response" },
11137     { ZBEE_ZCL_CMD_ID_PWR_PROF_GET_OVERALL_SCHED_PRICE_RSP,      "Get Overall Schedule Price Response" },
11138     { ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_NOTIF,        "Energy Phases Schedule Notification" },
11139     { ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_RSP,          "Energy Phases Schedule Response" },
11140     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_REQ,       "Power Profile Schedule Constraints Request" },
11141     { ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_REQ,    "Energy Phases Schedule State Request" },
11142     { ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_EXT_RSP,       "Get Power Profile Price Extended Response" },
11143     { 0, NULL }
11144 };
11145 
11146 /* Server Commands Generated */
11147 static const value_string zbee_zcl_pwr_prof_srv_tx_cmd_names[] = {
11148     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_NOTIF,                   "Power Profile Notification" },
11149     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_RSP,                     "Power Profile Response" },
11150     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_RSP,               "Power Profile State Response" },
11151     { ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE,               "Get Power Profile Price" },
11152     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_NOTIF,             "Power Profile State Notification" },
11153     { ZBEE_ZCL_CMD_ID_PWR_PROF_GET_OVERALL_SCHED_PRICE,          "Get Overall Schedule Price" },
11154     { ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_REQ,          "Energy Phases Schedule Request" },
11155     { ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_RSP,    "Energy Phases Schedule State Response" },
11156     { ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_NOITIF, "Energy Phases Schedule State Notification" },
11157     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_NOTIF,     "Power Profile Schedule Constraints Notification" },
11158     { ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_RSP,       "Power Profile Schedule Constraints Response" },
11159     { ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_EXT,           "Get Power Profile Price Extended" },
11160     { 0, NULL }
11161 };
11162 
11163 /* Currencies (values defined by ISO 4217) */
11164 static const value_string zbee_zcl_currecy_names[] = {
11165     { 0x03D2,                                                    "EUR" },
11166     { 0x033A,                                                    "GBP" },
11167     { 0x0348,                                                    "USD" },
11168     { 0, NULL }
11169 };
11170 
11171 /* Power Profile State */
11172 static const value_string zbee_zcl_pwr_prof_state_names[] = {
11173     { ZBEE_ZCL_PWR_PROF_STATE_ID_PWR_PROF_IDLE,                  "Power Profile Idle" },
11174     { ZBEE_ZCL_PWR_PROF_STATE_ID_PWR_PROF_PROGRAMMED,            "Power Profile Programmed" },
11175     { ZBEE_ZCL_PWR_PROF_STATE_ID_EN_PH_RUNNING,                  "Energy Phase Running" },
11176     { ZBEE_ZCL_PWR_PROF_STATE_ID_EN_PH_PAUSE,                    "Energy Phase Pause" },
11177     { ZBEE_ZCL_PWR_PROF_STATE_ID_EN_PH_WAITING_TO_START,         "Energy Phase Waiting to Start" },
11178     { ZBEE_ZCL_PWR_PROF_STATE_ID_EN_PH_WAITING_PAUSED,           "Energy Phase Waiting Paused" },
11179     { ZBEE_ZCL_PWR_PROF_STATE_ID_PWR_PROF_ENDED,                 "Power Profile Ended" },
11180     { 0, NULL }
11181 };
11182 
11183 /*************************/
11184 /* Function Bodies       */
11185 /*************************/
11186 
11187 /*FUNCTION:------------------------------------------------------
11188  *  NAME
11189  *      dissect_zbee_zcl_pwr_prof
11190  *  DESCRIPTION
11191  *      ZigBee ZCL Power Profile cluster dissector for wireshark.
11192  *  PARAMETERS
11193  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11194  *      packet_info *pinfo  - pointer to packet information fields
11195  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11196  *      void *data          - pointer to ZCL packet structure.
11197  *  RETURNS
11198  *      int                 - length of parsed data.
11199  *---------------------------------------------------------------
11200  */
11201 static int
dissect_zbee_zcl_pwr_prof(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)11202 dissect_zbee_zcl_pwr_prof (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
11203 {
11204     proto_tree        *payload_tree;
11205     zbee_zcl_packet   *zcl;
11206     guint             offset = 0;
11207     guint8            cmd_id;
11208     gint              rem_len;
11209 
11210     /* Reject the packet if data is NULL */
11211     if (data == NULL)
11212         return 0;
11213     zcl = (zbee_zcl_packet *)data;
11214     cmd_id = zcl->cmd_id;
11215 
11216     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
11217     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
11218         /* Append the command name to the info column. */
11219         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
11220             val_to_str_const(cmd_id, zbee_zcl_pwr_prof_srv_rx_cmd_names, "Unknown Command"),
11221             zcl->tran_seqno);
11222 
11223         /* Add the command ID. */
11224         proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
11225 
11226         /* Check is this command has a payload, than add the payload tree */
11227         rem_len = tvb_reported_length_remaining(tvb, ++offset);
11228         if (rem_len > 0) {
11229             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_pwr_prof, NULL, "Payload");
11230 
11231             /* Call the appropriate command dissector */
11232             switch (cmd_id) {
11233                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_REQ:
11234                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_REQ:
11235                 case ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_REQ:
11236                     dissect_zcl_pwr_prof_pwrprofreq(tvb, payload_tree, &offset);
11237                     break;
11238 
11239                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_REQ:
11240                     /* No payload */
11241                     break;
11242 
11243                 case ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_RSP:
11244                 case ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_EXT_RSP:
11245                     dissect_zcl_pwr_prof_getpwrprofpricersp(tvb, payload_tree, &offset);
11246                     break;
11247 
11248                 case ZBEE_ZCL_CMD_ID_PWR_PROF_GET_OVERALL_SCHED_PRICE_RSP:
11249                     dissect_zcl_pwr_prof_getoverallschedpricersp(tvb, payload_tree, &offset);
11250                     break;
11251 
11252                 case ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_NOTIF:
11253                 case ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_RSP:
11254                     dissect_zcl_pwr_prof_enphsschednotif(tvb, payload_tree, &offset);
11255                     break;
11256 
11257                 default:
11258                     break;
11259             }
11260         }
11261     }
11262     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
11263         /* Append the command name to the info column. */
11264         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
11265             val_to_str_const(cmd_id, zbee_zcl_pwr_prof_srv_tx_cmd_names, "Unknown Command"),
11266             zcl->tran_seqno);
11267 
11268         /* Add the command ID. */
11269         proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
11270 
11271         /* Check is this command has a payload, than add the payload tree */
11272         rem_len = tvb_reported_length_remaining(tvb, ++offset);
11273         if (rem_len > 0) {
11274             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_pwr_prof, NULL, "Payload");
11275 
11276             /* Call the appropriate command dissector */
11277             switch (cmd_id) {
11278                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_NOTIF:
11279                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_RSP:
11280                     dissect_zcl_pwr_prof_pwrprofnotif(tvb, payload_tree, &offset);
11281                     break;
11282 
11283                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_RSP:
11284                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_STATE_NOTIF:
11285                     dissect_zcl_pwr_prof_pwrprofstatersp(tvb, payload_tree, &offset);
11286                     break;
11287 
11288                 case ZBEE_ZCL_CMD_ID_PWR_PROF_GET_OVERALL_SCHED_PRICE:
11289                     /* no payload */
11290                     break;
11291 
11292                 case ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_RSP:
11293                 case ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_STATE_NOITIF:
11294                     dissect_zcl_pwr_prof_enphsschednotif(tvb, payload_tree, &offset);
11295                     break;
11296 
11297                 case ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE:
11298                 case ZBEE_ZCL_CMD_ID_PWR_PROF_ENERGY_PHASES_SCHED_REQ:
11299                     dissect_zcl_pwr_prof_pwrprofreq(tvb, payload_tree, &offset);
11300                     break;
11301 
11302                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_NOTIF:
11303                 case ZBEE_ZCL_CMD_ID_PWR_PROF_PWR_PROF_SCHED_CONSTRS_RSP:
11304                     dissect_zcl_pwr_prof_pwrprofschedcontrsnotif(tvb, payload_tree, &offset);
11305                     break;
11306 
11307                 case ZBEE_ZCL_CMD_ID_PWR_PROF_GET_PWR_PROF_PRICE_EXT:
11308                     dissect_zcl_pwr_prof_pwrprofpriceext(tvb, payload_tree, &offset);
11309                     break;
11310 
11311                 default:
11312                     break;
11313             }
11314         }
11315     }
11316 
11317     return tvb_captured_length(tvb);
11318 } /*dissect_zbee_zcl_pwr_prof*/
11319 
11320 /*FUNCTION:------------------------------------------------------
11321  *  NAME
11322  *      dissect_zcl_pwr_prof_pwrprofreq
11323  *  DESCRIPTION
11324  *      this function is called in order to decode "PowerProfileRequest",
11325  *      "PowerProfileScheduleConstraintsRequest", "EnergyPhasesScheduleStateRequest",
11326  *      "GetPowerProfilePrice" and "EnergyPhasesScheduleRequest" payload.
11327  *  PARAMETERS
11328  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11329  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11330  *      guint *offset       - pointer to buffer offset
11331  *  RETURNS
11332  *      none
11333  *---------------------------------------------------------------
11334  */
11335 static void
dissect_zcl_pwr_prof_pwrprofreq(tvbuff_t * tvb,proto_tree * tree,guint * offset)11336 dissect_zcl_pwr_prof_pwrprofreq(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11337 {
11338     /* Retrieve "Power Profile Id" field */
11339     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_id, tvb, *offset, 1, ENC_NA);
11340     *offset += 1;
11341 
11342 } /*dissect_zcl_pwr_prof_pwrprofreq*/
11343 
11344 
11345 /*FUNCTION:------------------------------------------------------
11346  *  NAME
11347  *      dissect_zcl_pwr_prof_getpwrprofpricersp
11348  *  DESCRIPTION
11349  *      this function is called in order to decode "GetPowerProfilePriceResponse"
11350  *      and "PowerProfilePriceExtendedResponse" payload.
11351  *  PARAMETERS
11352  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11353  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11354  *      guint *offset       - pointer to buffer offset
11355  *  RETURNS
11356  *      none
11357  *---------------------------------------------------------------
11358  */
11359 static void
dissect_zcl_pwr_prof_getpwrprofpricersp(tvbuff_t * tvb,proto_tree * tree,guint * offset)11360 dissect_zcl_pwr_prof_getpwrprofpricersp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11361 {
11362     /* Retrieve "Power Profile Id" field */
11363     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_id, tvb, *offset, 1, ENC_NA);
11364     *offset += 1;
11365 
11366     /* Retrieve "Currency" field */
11367     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_currency, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11368     *offset += 2;
11369 
11370     /* Retrieve "Price" field */
11371     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_price, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
11372     *offset += 4;
11373 
11374     /* Retrieve "Price Trailing Digit" field */
11375     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_price_trailing_digit, tvb, *offset, 1, ENC_NA);
11376     *offset += 1;
11377 
11378 } /*dissect_zcl_pwr_prof_getpwrprofpricersp*/
11379 
11380 
11381 /*FUNCTION:------------------------------------------------------
11382  *  NAME
11383  *      dissect_zcl_pwr_prof_getoverallschedpricersp
11384  *  DESCRIPTION
11385  *      this function is called in order to decode "GetOverallSchedulePriceResponse"
11386  *      payload.
11387  *  PARAMETERS
11388  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11389  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11390  *      guint *offset       - pointer to buffer offset
11391  *  RETURNS
11392  *      none
11393  *---------------------------------------------------------------
11394  */
11395 static void
dissect_zcl_pwr_prof_getoverallschedpricersp(tvbuff_t * tvb,proto_tree * tree,guint * offset)11396 dissect_zcl_pwr_prof_getoverallschedpricersp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11397 {
11398     /* Retrieve "Currency" field */
11399     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_currency, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11400     *offset += 2;
11401 
11402     /* Retrieve "Price" field */
11403     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_price, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
11404     *offset += 4;
11405 
11406     /* Retrieve "Price Trailing Digit" field */
11407     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_price_trailing_digit, tvb, *offset, 1, ENC_NA);
11408     *offset += 1;
11409 
11410 } /*dissect_zcl_pwr_prof_getoverallschedpricersp*/
11411 
11412 
11413 /*FUNCTION:------------------------------------------------------
11414  *  NAME
11415  *      dissect_zcl_sched_energy_phase
11416  *  DESCRIPTION
11417  *      this function is called in order to decode "ScheduledEnergyPhases"
11418  *      element.
11419  *  PARAMETERS
11420  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11421  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11422  *      guint *offset       - pointer to buffer offset
11423  *  RETURNS
11424  *      none
11425  *---------------------------------------------------------------
11426  */
11427 static void
dissect_zcl_sched_energy_phase(tvbuff_t * tvb,proto_tree * tree,guint * offset)11428 dissect_zcl_sched_energy_phase(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11429 {
11430     /* Energy Phase ID */
11431     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_energy_phase_id, tvb, *offset, 1, ENC_NA);
11432     *offset += 1;
11433 
11434     /* Scheduled Time */
11435     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_scheduled_time, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11436     *offset += 2;
11437 
11438 } /*dissect_zcl_sched_energy_phase*/
11439 
11440 
11441 /*FUNCTION:------------------------------------------------------
11442  *  NAME
11443  *      dissect_zcl_pwr_prof_enphsschednotif
11444  *  DESCRIPTION
11445  *      this function is called in order to decode "EnergyPhasesScheduleNotification"
11446  *      and "EnergyPhasesScheduleResoponse" payload.
11447  *  PARAMETERS
11448  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11449  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11450  *      guint *offset       - pointer to buffer offset
11451  *  RETURNS
11452  *      none
11453  *---------------------------------------------------------------
11454  */
11455 static void
dissect_zcl_pwr_prof_enphsschednotif(tvbuff_t * tvb,proto_tree * tree,guint * offset)11456 dissect_zcl_pwr_prof_enphsschednotif(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11457 {
11458     proto_tree  *sub_tree = NULL;
11459 
11460     guint i;
11461     guint8 num_of_sched_phases;
11462 
11463     /* Retrieve "Power Profile Id" field */
11464     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_id, tvb, *offset, 1, ENC_NA);
11465     *offset += 1;
11466 
11467     /* Retrieve "Number of Scheduled Phases" field */
11468     num_of_sched_phases = tvb_get_guint8(tvb, *offset);
11469     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_num_of_sched_phases, tvb, *offset, 1, ENC_NA);
11470     *offset += 1;
11471 
11472     /* Scheduled Energy Phases decoding */
11473     for (i=0 ; (i<num_of_sched_phases && i < ZBEE_ZCL_PWR_PROF_NUM_EN_PHS_ETT); i++) {
11474         /* Create subtree */
11475         sub_tree = proto_tree_add_subtree_format(tree, tvb, *offset, 1,
11476                         ett_zbee_zcl_pwr_prof_enphases[i], NULL, "Energy Phase #%u", i);
11477 
11478         dissect_zcl_sched_energy_phase(tvb, sub_tree, offset);
11479     }
11480 } /*dissect_zcl_pwr_prof_enphsschednotif*/
11481 
11482 
11483 /*FUNCTION:------------------------------------------------------
11484  *  NAME
11485  *      dissect_zcl_energy_phase
11486  *  DESCRIPTION
11487  *      this function is called in order to decode "EnergyPhases"
11488  *      element.
11489  *  PARAMETERS
11490  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11491  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11492  *      guint *offset       - pointer to buffer offset
11493  *  RETURNS
11494  *      none
11495  *---------------------------------------------------------------
11496  */
11497 static void
dissect_zcl_energy_phase(tvbuff_t * tvb,proto_tree * tree,guint * offset)11498 dissect_zcl_energy_phase(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11499 {
11500     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_energy_phase_id, tvb, *offset, 1, ENC_NA);
11501     *offset += 1;
11502 
11503     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_macro_phase_id, tvb, *offset, 1, ENC_NA);
11504     *offset += 1;
11505 
11506     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_expect_duration, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11507     *offset += 2;
11508 
11509     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_peak_power, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11510     *offset += 2;
11511 
11512     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_energy, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11513     *offset += 2;
11514 
11515     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_max_active_delay, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11516     *offset += 2;
11517 
11518 } /*dissect_zcl_energy_phase*/
11519 
11520 
11521 /*FUNCTION:------------------------------------------------------
11522  *  NAME
11523  *      dissect_zcl_pwr_prof_pwrprofnotif
11524  *  DESCRIPTION
11525  *      this function is called in order to decode "PowerProfileNotification"
11526  *      and "PowerProfileResponse" payload.
11527  *  PARAMETERS
11528  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11529  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11530  *      guint *offset       - pointer to buffer offset
11531  *  RETURNS
11532  *      none
11533  *---------------------------------------------------------------
11534  */
11535 static void
dissect_zcl_pwr_prof_pwrprofnotif(tvbuff_t * tvb,proto_tree * tree,guint * offset)11536 dissect_zcl_pwr_prof_pwrprofnotif(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11537 {
11538     proto_tree  *sub_tree = NULL;
11539 
11540     guint i;
11541     guint8 total_profile_number;
11542     guint8 num_of_transferred_phases;
11543 
11544     /* Retrieve "Total Profile Number" field */
11545     total_profile_number = tvb_get_guint8(tvb, *offset);
11546     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_tot_prof_num, tvb, *offset, 1, ENC_NA);
11547     *offset += 1;
11548 
11549     if ( total_profile_number != 0 ) {
11550         /* Retrieve "Power Profile Id" field */
11551         proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_id, tvb, *offset, 1, ENC_NA);
11552         *offset += 1;
11553 
11554         /* Retrieve "Number of Transferred Phases" field */
11555         num_of_transferred_phases = tvb_get_guint8(tvb, *offset);
11556         proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_num_of_trans_phases, tvb, *offset, 1, ENC_NA);
11557         *offset += 1;
11558 
11559         /* Energy Phases decoding */
11560         for ( i=0 ; (i<num_of_transferred_phases && i < ZBEE_ZCL_PWR_PROF_NUM_EN_PHS_ETT); i++) {
11561             /* Create subtree */
11562             sub_tree = proto_tree_add_subtree_format(tree, tvb, *offset, 1,
11563                         ett_zbee_zcl_pwr_prof_enphases[i], NULL, "Energy Phase #%u", i);
11564 
11565             dissect_zcl_energy_phase(tvb, sub_tree, offset);
11566         }
11567     }
11568 }
11569 
11570 
11571 /*FUNCTION:------------------------------------------------------
11572  *  NAME
11573  *      dissect_zcl_power_profile
11574  *  DESCRIPTION
11575  *      this function is called in order to decode "PowerProfile"
11576  *      element.
11577  *  PARAMETERS
11578  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11579  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11580  *      guint *offset       - pointer to buffer offset
11581  *  RETURNS
11582  *      none
11583  *---------------------------------------------------------------
11584  */
11585 static void
dissect_zcl_power_profile(tvbuff_t * tvb,proto_tree * tree,guint * offset)11586 dissect_zcl_power_profile(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11587 {
11588     /* Power Profile Id */
11589     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_id, tvb, *offset, 1, ENC_NA);
11590     *offset += 1;
11591 
11592     /* Energy Phase Id */
11593     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_energy_phase_id, tvb, *offset, 1, ENC_NA);
11594     *offset += 1;
11595 
11596     /* Power Profile Remote Control */
11597     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_rem_ctrl, tvb, *offset, 1, ENC_NA);
11598     *offset += 1;
11599 
11600     /* Power Profile State */
11601     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_state, tvb, *offset, 1, ENC_NA);
11602     *offset += 1;
11603 
11604 } /*dissect_zcl_power_profile*/
11605 
11606 
11607 /*FUNCTION:------------------------------------------------------
11608  *  NAME
11609  *      dissect_zcl_pwr_prof_pwrprofstatersp
11610  *  DESCRIPTION
11611  *      this function is called in order to decode "PowerProfileStateResponse"
11612  *      and "PowerProfileStateNotification" payload.
11613  *  PARAMETERS
11614  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11615  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11616  *      guint *offset       - pointer to buffer offset
11617  *  RETURNS
11618  *      none
11619  *---------------------------------------------------------------
11620  */
11621 static void
dissect_zcl_pwr_prof_pwrprofstatersp(tvbuff_t * tvb,proto_tree * tree,guint * offset)11622 dissect_zcl_pwr_prof_pwrprofstatersp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11623 {
11624     proto_tree  *sub_tree = NULL;
11625 
11626     guint i;
11627     guint8 power_profile_count;
11628 
11629     /* Retrieve "Total Profile Number" field */
11630     power_profile_count = MIN(tvb_get_guint8(tvb, *offset), ZBEE_ZCL_PWR_PROF_NUM_PWR_PROF_ETT);
11631     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_count, tvb, *offset, 1, ENC_NA);
11632     *offset += 1;
11633 
11634     /* Energy Phases decoding */
11635     for (i=0 ; i<power_profile_count ; i++) {
11636         /* Create subtree */
11637         sub_tree = proto_tree_add_subtree_format(tree, tvb, *offset, 1,
11638                     ett_zbee_zcl_pwr_prof_pwrprofiles[i], NULL, "Power Profile #%u", i);
11639 
11640         dissect_zcl_power_profile(tvb, sub_tree, offset);
11641     }
11642 } /*dissect_zcl_pwr_prof_pwrprofstatersp*/
11643 
11644 
11645 /*FUNCTION:------------------------------------------------------
11646  *  NAME
11647  *      dissect_zcl_pwr_prof_pwrprofschedcontrsnotif
11648  *  DESCRIPTION
11649  *      this function is called in order to decode "PowerProfileScheduleConstraintsNotification"
11650  *      and "PowerProfileScheduleConstraintsResponse" payload.
11651  *  PARAMETERS
11652  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11653  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11654  *      guint *offset       - pointer to buffer offset
11655  *  RETURNS
11656  *      none
11657  *---------------------------------------------------------------
11658  */
11659 static void
dissect_zcl_pwr_prof_pwrprofschedcontrsnotif(tvbuff_t * tvb,proto_tree * tree,guint * offset)11660 dissect_zcl_pwr_prof_pwrprofschedcontrsnotif(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11661 {
11662     /* Retrieve "Power Profile Id" field */
11663     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_id, tvb, *offset, 1, ENC_NA);
11664     *offset += 1;
11665 
11666     /* Retrieve "Start After" field */
11667     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_start_after, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11668     *offset += 2;
11669 
11670     /* Retrieve "Stop Before" field */
11671     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_stop_before, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11672     *offset += 2;
11673 
11674 } /*dissect_zcl_pwr_prof_pwrprofschedcontrsnotif*/
11675 
11676 
11677 /*FUNCTION:------------------------------------------------------
11678  *  NAME
11679  *      dissect_zcl_pwr_prof_pwrprofpriceext
11680  *  DESCRIPTION
11681  *      this function is called in order to decode "GetPowerProfilePriceExtended"
11682  *      and "PowerProfileScheduleConstraintsResponse" payload.
11683  *  PARAMETERS
11684  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11685  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11686  *      guint *offset       - pointer to buffer offset
11687  *  RETURNS
11688  *      none
11689  *---------------------------------------------------------------
11690  */
11691 static void
dissect_zcl_pwr_prof_pwrprofpriceext(tvbuff_t * tvb,proto_tree * tree,guint * offset)11692 dissect_zcl_pwr_prof_pwrprofpriceext(tvbuff_t *tvb, proto_tree *tree, guint *offset)
11693 {
11694     static int * const options[] = {
11695         &hf_zbee_zcl_pwr_prof_options_01,
11696         &hf_zbee_zcl_pwr_prof_options_res,
11697         NULL
11698     };
11699 
11700     /* Retrieve "Options" field */
11701     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_pwr_prof_options, ett_zbee_zcl_pwr_prof_options, options, ENC_NA);
11702     *offset += 1;
11703 
11704     /* Retrieve "Power Profile Id" field */
11705     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_id, tvb, *offset, 1, ENC_NA);
11706     *offset += 1;
11707 
11708     /* Retrieve "Power Profile Start Time" field */
11709     proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_pwr_prof_stime, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
11710     *offset += 2;
11711 
11712 } /*dissect_zcl_pwr_prof_pwrprofpriceext*/
11713 
11714 
11715 /*FUNCTION:------------------------------------------------------
11716  *  NAME
11717  *      dissect_zcl_pwr_prof_attr_data
11718  *  DESCRIPTION
11719  *      this function is called by ZCL foundation dissector in order to decode
11720  *      specific cluster attributes data.
11721  *  PARAMETERS
11722  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
11723  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
11724  *      guint *offset       - pointer to buffer offset
11725  *      guint16 attr_id     - attribute identifier
11726  *      guint data_type     - attribute data type
11727  *      gboolean client_attr- ZCL client
11728  *  RETURNS
11729  *      none
11730  *---------------------------------------------------------------
11731  */
11732 static void
dissect_zcl_pwr_prof_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)11733 dissect_zcl_pwr_prof_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
11734 {
11735     static int * const format_fields[] = {
11736         &hf_zbee_zcl_pwr_prof_energy_format_rdigit,
11737         &hf_zbee_zcl_pwr_prof_energy_format_ldigit,
11738         &hf_zbee_zcl_pwr_prof_energy_format_noleadingzero,
11739         NULL
11740     };
11741     static int * const modes[] = {
11742         &hf_zbee_zcl_pwr_prof_sched_mode_cheapest,
11743         &hf_zbee_zcl_pwr_prof_sched_mode_greenest,
11744         &hf_zbee_zcl_pwr_prof_sched_mode_reserved,
11745         NULL
11746     };
11747 
11748     /* Dissect attribute data type and data */
11749     switch ( attr_id )
11750     {
11751         case ZBEE_ZCL_ATTR_ID_PWR_PROF_TOT_PROF_NUM:
11752             proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_tot_prof_num, tvb, *offset, 1, ENC_NA);
11753             *offset += 1;
11754             break;
11755 
11756         case ZBEE_ZCL_ATTR_ID_PWR_PROF_MULTIPLE_SCHED:
11757             proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_multiple_sched, tvb, *offset, 1, ENC_NA);
11758             *offset += 1;
11759             break;
11760 
11761         case ZBEE_ZCL_ATTR_ID_PWR_PROF_ENERGY_FORMAT:
11762             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_pwr_prof_energy_format, ett_zbee_zcl_pwr_prof_en_format, format_fields, ENC_NA);
11763             *offset += 1;
11764             break;
11765 
11766         case ZBEE_ZCL_ATTR_ID_PWR_PROF_ENERGY_REMOTE:
11767             proto_tree_add_item(tree, hf_zbee_zcl_pwr_prof_energy_remote, tvb, *offset, 1, ENC_NA);
11768             *offset += 1;
11769             break;
11770 
11771         case ZBEE_ZCL_ATTR_ID_PWR_PROF_SCHED_MODE:
11772             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_pwr_prof_sched_mode, ett_zbee_zcl_pwr_prof_sched_mode, modes, ENC_NA);
11773             *offset += 1;
11774             break;
11775 
11776         default:
11777             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
11778         break;
11779     }
11780 } /*dissect_zcl_pwr_prof_attr_data*/
11781 
11782 
11783 /*FUNCTION:------------------------------------------------------
11784  *  NAME
11785  *      decode_power_profile_id
11786  *  DESCRIPTION
11787  *      this function decodes the power profile custom type
11788  *  PARAMETERS
11789  *      guint *s        - string to display
11790  *      guint16 value   - value to decode
11791  *  RETURNS
11792  *      none
11793  *---------------------------------------------------------------
11794  */
11795 static void
decode_power_profile_id(gchar * s,guint8 id)11796 decode_power_profile_id(gchar *s, guint8 id)
11797 {
11798     if (id == 0) {
11799         g_snprintf(s, ITEM_LABEL_LENGTH, "%d (All)", id);
11800     }
11801     else {
11802         g_snprintf(s, ITEM_LABEL_LENGTH, "%d", id);
11803     }
11804 } /*decode_power_profile_id*/
11805 
11806 
11807 /*FUNCTION:------------------------------------------------------
11808  *  NAME
11809  *      decode_price_in_cents
11810  *  DESCRIPTION
11811  *      this function decodes price type variable
11812  *  PARAMETERS
11813  *      guint *s        - string to display
11814  *      guint16 value   - value to decode
11815  *  RETURNS
11816  *      none
11817  *---------------------------------------------------------------
11818  */
11819 static void
decode_price_in_cents(gchar * s,guint32 value)11820 decode_price_in_cents(gchar *s, guint32 value)
11821 {
11822     g_snprintf(s, ITEM_LABEL_LENGTH, "%d cents", value);
11823 } /* decode_price_in_cents */
11824 
11825 
11826 /*FUNCTION:------------------------------------------------------
11827  *  NAME
11828  *      decode_power_in_watt
11829  *  DESCRIPTION
11830  *      this function decodes watt power type variable
11831  *  PARAMETERS
11832  *      guint *s        - string to display
11833  *      guint16 value   - value to decode
11834  *  RETURNS
11835  *      none
11836  *---------------------------------------------------------------
11837  */
11838 static void
decode_power_in_watt(gchar * s,guint16 value)11839 decode_power_in_watt(gchar *s, guint16 value)
11840 {
11841     g_snprintf(s, ITEM_LABEL_LENGTH, "%d Watt", value);
11842 } /* decode_power_in_watt */
11843 
11844 /*FUNCTION:------------------------------------------------------
11845  *  NAME
11846  *      decode_energy
11847  *  DESCRIPTION
11848  *      this function decodes energy type variable
11849  *  PARAMETERS
11850  *      guint *s        - string to display
11851  *      guint16 value   - value to decode
11852  *  RETURNS
11853  *      none
11854  *---------------------------------------------------------------
11855  */
11856 static void
decode_energy(gchar * s,guint16 value)11857 decode_energy(gchar *s, guint16 value)
11858 {
11859     g_snprintf(s, ITEM_LABEL_LENGTH, "%d Watt per hours", value);
11860 } /* decode_energy */
11861 
11862 /*FUNCTION:------------------------------------------------------
11863  *  NAME
11864  *      func_decode_delayinminute
11865  *  DESCRIPTION
11866  *    this function decodes minute delay type variable
11867  *  PARAMETERS
11868  *      guint *s        - string to display
11869  *      guint16 value   - value to decode
11870  *  RETURNS
11871  *      none
11872  *---------------------------------------------------------------
11873  */
11874 static void
func_decode_delayinminute(gchar * s,guint16 value)11875 func_decode_delayinminute(gchar *s, guint16 value)
11876 {
11877     if (value == 0) {
11878         g_snprintf(s, ITEM_LABEL_LENGTH, "%d minutes (Not permitted)", value);
11879     }
11880     else {
11881         g_snprintf(s, ITEM_LABEL_LENGTH, "%d minutes", value);
11882     }
11883 
11884 } /* func_decode_delayinminute*/
11885 
11886 
11887 /*FUNCTION:------------------------------------------------------
11888  *  NAME
11889  *      proto_register_zbee_zcl_pwr_prof
11890  *  DESCRIPTION
11891  *      ZigBee ZCL PowerProfile cluster protocol registration routine.
11892  *  PARAMETERS
11893  *      none
11894  *  RETURNS
11895  *      void
11896  *---------------------------------------------------------------
11897  */
11898 void
proto_register_zbee_zcl_pwr_prof(void)11899 proto_register_zbee_zcl_pwr_prof(void)
11900 {
11901     guint i, j;
11902 
11903     static hf_register_info hf[] = {
11904 
11905         { &hf_zbee_zcl_pwr_prof_tot_prof_num,
11906             { "Total Profile Number", "zbee_zcl_general.pwrprof.attr.totprofnum", FT_UINT8, BASE_DEC, NULL, 0x0,
11907             NULL, HFILL } },
11908 
11909         { &hf_zbee_zcl_pwr_prof_multiple_sched,
11910             { "Multiple Scheduling", "zbee_zcl_general.pwrprof.attr.multiplesched", FT_BOOLEAN, BASE_NONE,
11911             TFS(&tfs_supported_not_supported), 0x0, NULL, HFILL } },
11912 
11913 /* Begin EnergyFormatting fields */
11914         { &hf_zbee_zcl_pwr_prof_energy_format,
11915             { "Data", "zbee_zcl_general.pwrprof.attr.energyformat",
11916             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
11917 
11918         { &hf_zbee_zcl_pwr_prof_energy_format_rdigit,
11919             { "Number of Digits to the right of the Decimal Point", "zbee_zcl_general.pwrprof.attr.energyformat.rdigit",
11920             FT_UINT8, BASE_DEC, NULL, ZBEE_ZCL_OPT_PWRPROF_NUM_R_DIGIT, NULL, HFILL } },
11921 
11922         { &hf_zbee_zcl_pwr_prof_energy_format_ldigit,
11923             { "Number of Digits to the left of the Decimal Point", "zbee_zcl_general.pwrprof.attr.energyformat.ldigit",
11924             FT_UINT8, BASE_DEC, NULL, ZBEE_ZCL_OPT_PWRPROF_NUM_L_DIGIT, NULL, HFILL } },
11925 
11926         { &hf_zbee_zcl_pwr_prof_energy_format_noleadingzero,
11927             { "Suppress leading zeros.", "zbee_zcl_general.pwrprof.attr.energyformat.noleadingzero",
11928             FT_BOOLEAN, 8, TFS(&tfs_true_false), ZBEE_ZCL_OPT_PWRPROF_NO_LEADING_ZERO, NULL, HFILL } },
11929 /* End EnergyFormatting fields */
11930 
11931         { &hf_zbee_zcl_pwr_prof_energy_remote,
11932             { "Energy Remote", "zbee_zcl_general.pwrprof.attr.energyremote", FT_BOOLEAN, BASE_NONE,
11933             TFS(&tfs_enabled_disabled), 0x0, NULL, HFILL } },
11934 
11935 /* Begin ScheduleMode fields */
11936         { &hf_zbee_zcl_pwr_prof_sched_mode,
11937             { "Schedule Mode", "zbee_zcl_general.pwrprof.attr.schedmode",
11938             FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
11939 
11940         { &hf_zbee_zcl_pwr_prof_sched_mode_cheapest,
11941             { "Schedule Mode Cheapest", "zbee_zcl_general.pwrprof.attr.schedmode.cheapest",
11942             FT_BOOLEAN, 8, TFS(&tfs_active_inactive), ZBEE_ZCL_OPT_PWRPROF_SCHED_CHEAPEST, NULL, HFILL } },
11943 
11944         { &hf_zbee_zcl_pwr_prof_sched_mode_greenest,
11945             { "Schedule Mode Greenest", "zbee_zcl_general.pwrprof.attr.schedmode.greenest",
11946             FT_BOOLEAN, 8, TFS(&tfs_active_inactive), ZBEE_ZCL_OPT_PWRPROF_SCHED_GREENEST, NULL, HFILL } },
11947 
11948         { &hf_zbee_zcl_pwr_prof_sched_mode_reserved,
11949             { "Schedule Mode Reserved", "zbee_zcl_general.pwrprof.attr.schedmode.reserved",
11950             FT_UINT8, BASE_HEX, NULL, ZBEE_ZCL_OPT_PWRPROF_SCHED_RESERVED, NULL, HFILL } },
11951 /* End ScheduleMode fields */
11952 
11953         { &hf_zbee_zcl_pwr_prof_attr_id,
11954             { "Attribute",   "zbee_zcl_general.pwrprof.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_pwr_prof_attr_names),
11955             0x0, NULL, HFILL } },
11956 
11957         { &hf_zbee_zcl_pwr_prof_srv_tx_cmd_id,
11958             { "Command",   "zbee_zcl_general.pwrprof.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_pwr_prof_srv_tx_cmd_names),
11959             0x0, NULL, HFILL } },
11960 
11961         { &hf_zbee_zcl_pwr_prof_srv_rx_cmd_id,
11962             { "Command",   "zbee_zcl_general.pwrprof.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_pwr_prof_srv_rx_cmd_names),
11963             0x0, NULL, HFILL } },
11964 
11965         { &hf_zbee_zcl_pwr_prof_pwr_prof_id,
11966             { "Power Profile ID", "zbee_zcl_general.pwrprof.pwrprofid", FT_UINT8, BASE_CUSTOM, CF_FUNC(decode_power_profile_id), 0x00,
11967             "Identifier of the specific profile", HFILL } },
11968 
11969         { &hf_zbee_zcl_pwr_prof_currency,
11970             { "Currency", "zbee_zcl_general.pwrprof.currency", FT_UINT16, BASE_HEX, VALS(zbee_zcl_currecy_names), 0x0,
11971             "Local unit of currency (ISO 4217) used in the price field.", HFILL } },
11972 
11973         { &hf_zbee_zcl_pwr_prof_price,
11974             { "Price", "zbee_zcl_general.pwrprof.price", FT_UINT32, BASE_CUSTOM, CF_FUNC(decode_price_in_cents), 0x0,
11975             "Price of the energy of a specific Power Profile.", HFILL } },
11976 
11977         { &hf_zbee_zcl_pwr_prof_price_trailing_digit,
11978             { "Price Trailing Digit", "zbee_zcl_general.pwrprof.pricetrailingdigit", FT_UINT8, BASE_DEC, NULL, 0x0,
11979             "Number of digits to the right of the decimal point.", HFILL } },
11980 
11981         { &hf_zbee_zcl_pwr_prof_num_of_sched_phases,
11982             { "Number of Scheduled Phases", "zbee_zcl_general.pwrprof.numofschedphases", FT_UINT8, BASE_DEC, NULL, 0x0,
11983             "Total number of the energy phases of the Power Profile that need to be scheduled.", HFILL } },
11984 
11985         { &hf_zbee_zcl_pwr_prof_energy_phase_id,
11986             { "Energy Phase ID", "zbee_zcl_general.pwrprof.energyphaseid", FT_UINT8, BASE_DEC, NULL, 0x0,
11987             "Identifier of the specific phase.", HFILL } },
11988 
11989         { &hf_zbee_zcl_pwr_prof_scheduled_time,
11990             { "Scheduled Time", "zbee_zcl_general.pwrprof.scheduledtime", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_minutes), 0x0,
11991             NULL, HFILL } },
11992 
11993         { &hf_zbee_zcl_pwr_prof_macro_phase_id,
11994             { "Macro Phase ID", "zbee_zcl_general.pwrprof.macrophaseid", FT_UINT8, BASE_DEC, NULL, 0x0,
11995             "Identifier of the specific energy phase.", HFILL } },
11996 
11997         { &hf_zbee_zcl_pwr_prof_expect_duration,
11998             { "Expected Duration", "zbee_zcl_general.pwrprof.expectduration", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_minutes), 0x0,
11999             "The estimated duration of the specific phase.", HFILL } },
12000 
12001         { &hf_zbee_zcl_pwr_prof_num_of_trans_phases,
12002             { "Number of Transferred Phases", "zbee_zcl_general.pwrprof.numoftransphases", FT_UINT8, BASE_DEC, NULL, 0x0,
12003             NULL, HFILL } },
12004 
12005         { &hf_zbee_zcl_pwr_prof_peak_power,
12006             { "Peak Power", "zbee_zcl_general.pwrprof.peakpower", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_power_in_watt), 0x0,
12007             "The estimated power for the specific phase.", HFILL } },
12008 
12009         { &hf_zbee_zcl_pwr_prof_energy,
12010             { "Energy", "zbee_zcl_general.pwrprof.energy", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_energy), 0x0,
12011             "The estimated energy consumption for the accounted phase.", HFILL } },
12012 
12013         { &hf_zbee_zcl_pwr_prof_max_active_delay,
12014             { "Max Activation Delay", "zbee_zcl_general.pwrprof.maxactivdelay", FT_UINT16, BASE_CUSTOM, CF_FUNC(func_decode_delayinminute), 0x0,
12015             "The maximum interruption time between the end of the previous phase and the beginning of the specific phase.", HFILL } },
12016 
12017         { &hf_zbee_zcl_pwr_prof_pwr_prof_count,
12018             { "Power Profile Count", "zbee_zcl_general.pwrprof.pwrprofcount", FT_UINT8, BASE_DEC, NULL, 0x0,
12019             NULL, HFILL } },
12020 
12021         { &hf_zbee_zcl_pwr_prof_pwr_prof_rem_ctrl,
12022             { "Power Profile Remote Control", "zbee_zcl_general.pwrprof.pwrprofremctrl", FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x00,
12023             "It indicates if the PowerProfile is currently remotely controllable or not.", HFILL } },
12024 
12025         { &hf_zbee_zcl_pwr_prof_pwr_prof_state,
12026             { "Power Profile State", "zbee_zcl_general.pwrprof.pwrprofstate", FT_UINT8, BASE_HEX, VALS(zbee_zcl_pwr_prof_state_names),
12027             0x0, NULL, HFILL } },
12028 
12029         { &hf_zbee_zcl_pwr_prof_start_after,
12030             { "Start After", "zbee_zcl_general.pwrprof.startafter", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_minutes), 0x0,
12031             NULL, HFILL } },
12032 
12033         { &hf_zbee_zcl_pwr_prof_stop_before,
12034             { "Stop Before", "zbee_zcl_general.pwrprof.stopbefore", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_minutes), 0x0,
12035             NULL, HFILL } },
12036 
12037 /* Begin Options fields */
12038         { &hf_zbee_zcl_pwr_prof_options,
12039             { "Options", "zbee_zcl_general.pwrprof.options", FT_UINT8, BASE_HEX, NULL,
12040             0x0, NULL, HFILL } },
12041 
12042         { &hf_zbee_zcl_pwr_prof_options_01,
12043             { "PowerProfileStartTime Field Present", "zbee_zcl_general.pwrprof.options.01", FT_BOOLEAN, 8, TFS(&tfs_true_false),
12044             ZBEE_ZCL_OPT_PWRPROF_STIME_PRESENT, NULL, HFILL } },
12045 
12046         { &hf_zbee_zcl_pwr_prof_options_res,
12047             { "Reserved", "zbee_zcl_general.pwrprof.options.reserved", FT_UINT8, BASE_HEX, NULL,
12048             ZBEE_ZCL_OPT_PWRPROF_RESERVED, NULL, HFILL } },
12049 /* End Options fields */
12050 
12051         { &hf_zbee_zcl_pwr_prof_pwr_prof_stime,
12052             { "Power Profile Start Time", "zbee_zcl_general.pwrprof.pwrprofstime", FT_UINT16, BASE_CUSTOM, CF_FUNC(decode_zcl_time_in_minutes), 0x0,
12053             NULL, HFILL } }
12054 
12055   };
12056 
12057     /* ZCL PowerProfile subtrees */
12058     static gint *ett[ZBEE_ZCL_PWR_PROF_NUM_ETT] = {
12059         &ett_zbee_zcl_pwr_prof,
12060         &ett_zbee_zcl_pwr_prof_options,
12061         &ett_zbee_zcl_pwr_prof_en_format,
12062         &ett_zbee_zcl_pwr_prof_sched_mode
12063     };
12064 
12065     /* initialize attribute subtree types */
12066     for ( i = 0, j = ZBEE_ZCL_PWR_PROF_NUM_GENERIC_ETT; i < ZBEE_ZCL_PWR_PROF_NUM_PWR_PROF_ETT; i++, j++ ) {
12067         ett_zbee_zcl_pwr_prof_pwrprofiles[i] = -1;
12068         ett[j] = &ett_zbee_zcl_pwr_prof_pwrprofiles[i];
12069     }
12070 
12071     for ( i = 0; i < ZBEE_ZCL_PWR_PROF_NUM_EN_PHS_ETT; i++, j++ ) {
12072         ett_zbee_zcl_pwr_prof_enphases[i] = -1;
12073         ett[j] = &ett_zbee_zcl_pwr_prof_enphases[i];
12074     }
12075 
12076     /* Register the ZigBee ZCL PowerProfile cluster protocol name and description */
12077     proto_zbee_zcl_pwr_prof = proto_register_protocol("ZigBee ZCL Power Profile", "ZCL Power Profile", ZBEE_PROTOABBREV_ZCL_PWRPROF);
12078     proto_register_field_array(proto_zbee_zcl_pwr_prof, hf, array_length(hf));
12079     proto_register_subtree_array(ett, array_length(ett));
12080 
12081     /* Register the ZigBee ZCL Power Profile dissector. */
12082     register_dissector(ZBEE_PROTOABBREV_ZCL_PWRPROF, dissect_zbee_zcl_pwr_prof, proto_zbee_zcl_pwr_prof);
12083 } /* proto_register_zbee_zcl_pwr_prof */
12084 
12085 
12086 /*FUNCTION:------------------------------------------------------
12087  *  NAME
12088  *      proto_reg_handoff_zbee_zcl_pwr_prof
12089  *  DESCRIPTION
12090  *      Hands off the Zcl Power Profile cluster dissector.
12091  *  PARAMETERS
12092  *      none
12093  *  RETURNS
12094  *      void
12095  *---------------------------------------------------------------
12096  */
12097 void
proto_reg_handoff_zbee_zcl_pwr_prof(void)12098 proto_reg_handoff_zbee_zcl_pwr_prof(void)
12099 {
12100     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_PWRPROF,
12101                             proto_zbee_zcl_pwr_prof,
12102                             ett_zbee_zcl_pwr_prof,
12103                             ZBEE_ZCL_CID_POWER_PROFILE,
12104                             ZBEE_MFG_CODE_NONE,
12105                             hf_zbee_zcl_pwr_prof_attr_id,
12106                             hf_zbee_zcl_pwr_prof_attr_id,
12107                             hf_zbee_zcl_pwr_prof_srv_rx_cmd_id,
12108                             hf_zbee_zcl_pwr_prof_srv_tx_cmd_id,
12109                             (zbee_zcl_fn_attr_data)dissect_zcl_pwr_prof_attr_data
12110                          );
12111 } /*proto_reg_handoff_zbee_zcl_pwr_prof*/
12112 
12113 /* ########################################################################## */
12114 /* #### (0x001B) APPLIANCE CONTROL CLUSTER ################################## */
12115 /* ########################################################################## */
12116 
12117 /*************************/
12118 /* Defines               */
12119 /*************************/
12120 
12121 #define ZBEE_ZCL_APPL_CTRL_NUM_GENERIC_ETT                      3
12122 #define ZBEE_ZCL_APPL_CTRL_NUM_FUNC_ETT                         32
12123 #define ZBEE_ZCL_APPL_CTRL_NUM_ETT                              (ZBEE_ZCL_APPL_CTRL_NUM_GENERIC_ETT + \
12124                                                                 ZBEE_ZCL_APPL_CTRL_NUM_FUNC_ETT)
12125 
12126 /* Attributes */
12127 #define ZBEE_ZCL_ATTR_ID_APPL_CTRL_START_TIME                   0x0000  /* Start Time */
12128 #define ZBEE_ZCL_ATTR_ID_APPL_CTRL_FINISH_TIME                  0x0001  /* Finish Time */
12129 #define ZBEE_ZCL_ATTR_ID_APPL_CTRL_REMAINING_TIME               0x0002  /* Remaining Time */
12130 
12131 /* Server Commands Received */
12132 #define ZBEE_ZCL_CMD_ID_APPL_CTRL_EXECUTION_CMD                 0x00  /* Execution of a Command */
12133 #define ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE                  0x01  /* Signal State */
12134 #define ZBEE_ZCL_CMD_ID_APPL_CTRL_WRITE_FUNCS                   0x02  /* Write Functions */
12135 #define ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_PAUSE_RESUME         0x03  /* Overload Pause Resume */
12136 #define ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_PAUSE                0x04  /* Overload Pause */
12137 #define ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_WARNING              0x05  /* Overload Warning */
12138 
12139 /* Server Commands Generated */
12140 #define ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE_RSP              0x00  /* Signal State Response */
12141 #define ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE_NOTIF            0x01  /* Signal State Notification */
12142 
12143 /* Execution Of a Command - Command Ids list */
12144 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_RESERVED                 0x00  /* Reserved */
12145 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_START                    0x01  /* Start appliance cycle */
12146 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_STOP                     0x02  /* Stop appliance cycle */
12147 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_PAUSE                    0x03  /* Pause appliance cycle */
12148 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_START_SUPERFREEZING      0x04  /* Start superfreezing cycle */
12149 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_STOP_SUPERFREEZING       0x05  /* Stop superfreezing cycle */
12150 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_START_SUPERCOOLING       0x06  /* Start supercooling cycle */
12151 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_STOP_SUPERCOOLING        0x07  /* Stop supercooling cycle */
12152 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_DISABLE_GAS              0x08  /* Disable gas */
12153 #define ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_ENABLE_GAS               0x09  /* Enable gas */
12154 
12155 /* CECED Time mask */
12156 #define ZBEE_ZCL_APPL_CTRL_TIME_MM                              0x003f  /* Minutes */
12157 #define ZBEE_ZCL_APPL_CTRL_TIME_ENCOD_TYPE                      0x00c0  /* Encoding Type */
12158 #define ZBEE_ZCL_APPL_CTRL_TIME_HH                              0xff00  /* Hours */
12159 
12160 /* Time encoding values */
12161 #define ZBEE_ZCL_APPL_CTRL_TIME_ENCOD_REL                       0x00
12162 #define ZBEE_ZCL_APPL_CTRL_TIME_ENCOD_ABS                       0x01
12163 
12164 /* Overload Warnings */
12165 #define ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_1                       0x00
12166 #define ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_2                       0x01
12167 #define ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_3                       0x02
12168 #define ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_4                       0x03
12169 #define ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_5                       0x04
12170 
12171 /* Appliance Status Ids list */
12172 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_RESERVED                   0x00  /* Reserved */
12173 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_OFF                        0x01  /* Appliance in off state */
12174 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_STANDBY                    0x02  /* Appliance in stand-by */
12175 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_PRG                        0x03  /* Appliance already programmed */
12176 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_PRG_WAITING_TO_START       0x04  /* Appliance already programmed and ready to start */
12177 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_RUNNING                    0x05  /* Appliance is running */
12178 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_PAUSE                      0x06  /* Appliance is in pause */
12179 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_END_PRG                    0x07  /* Appliance end programmed tasks */
12180 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_FAILURE                    0x08  /* Appliance is in a failure state */
12181 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_PRG_INTERRUPTED            0x09  /* The appliance programmed tasks have been interrupted */
12182 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_IDLE                       0x1a  /* Appliance in idle state */
12183 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_RINSE_HOLD                 0x1b  /* Appliance rinse hold */
12184 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_SERVICE                    0x1c  /* Appliance in service state */
12185 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_SUPERFREEZING              0x1d  /* Appliance in superfreezing state */
12186 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_SUPERCOOLING               0x1e  /* Appliance in supercooling state */
12187 #define ZBEE_ZCL_APPL_CTRL_ID_STATUS_SUPERHEATING               0x1f  /* Appliance in superheating state */
12188 
12189 /* Remote Enable Flags mask */
12190 #define ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_FLAGS                   0x0f
12191 #define ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_STATUS2                 0xf0
12192 
12193 /* Remote Enable Flags values */
12194 #define ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_DIS                     0x00  /* Disabled */
12195 #define ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_EN_REM_EN_CTRL          0x01  /* Enable Remote and Energy Control */
12196 #define ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_TEMP_LOCK_DIS           0x07  /* Temporarily locked/disabled */
12197 #define ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_EN_REM_CTRL             0x0f  /* Enable Remote Control */
12198 
12199 /* Device Status 2 values */
12200 #define ZBEE_ZCL_APPL_CTRL_STATUS2_PROPRIETARY_0                0x00  /* Proprietary */
12201 #define ZBEE_ZCL_APPL_CTRL_STATUS2_PROPRIETARY_1                0x01  /* Proprietary */
12202 #define ZBEE_ZCL_APPL_CTRL_STATUS2_IRIS_SYMPTOM_CODE            0x02  /* Iris symptom code */
12203 
12204 /*************************/
12205 /* Function Declarations */
12206 /*************************/
12207 
12208 void proto_register_zbee_zcl_appl_ctrl(void);
12209 void proto_reg_handoff_zbee_zcl_appl_ctrl(void);
12210 
12211 /* Command Dissector Helpers */
12212 static void dissect_zcl_appl_ctrl_exec_cmd              (tvbuff_t *tvb, proto_tree *tree, guint *offset);
12213 static void dissect_zcl_appl_ctrl_attr_func             (tvbuff_t *tvb, proto_tree *tree, guint *offset);
12214 static void dissect_zcl_appl_ctrl_wr_funcs              (tvbuff_t *tvb, proto_tree *tree, guint *offset);
12215 static void dissect_zcl_appl_ctrl_ovrl_warning          (tvbuff_t *tvb, proto_tree *tree, guint *offset);
12216 static void dissect_zcl_appl_ctrl_signal_state_rsp      (tvbuff_t *tvb, proto_tree *tree, guint *offset);
12217 
12218 static void dissect_zcl_appl_ctrl_attr_data             (proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr);
12219 
12220 /* Private functions prototype */
12221 
12222 /*************************/
12223 /* Global Variables      */
12224 /*************************/
12225 /* Initialize the protocol and registered fields */
12226 static int proto_zbee_zcl_appl_ctrl = -1;
12227 
12228 static int hf_zbee_zcl_appl_ctrl_attr_id = -1;
12229 static int hf_zbee_zcl_appl_ctrl_time = -1;
12230 static int hf_zbee_zcl_appl_ctrl_time_mm = -1;
12231 static int hf_zbee_zcl_appl_ctrl_time_encoding_type = -1;
12232 static int hf_zbee_zcl_appl_ctrl_time_hh = -1;
12233 static int hf_zbee_zcl_appl_ctrl_srv_tx_cmd_id = -1;
12234 static int hf_zbee_zcl_appl_ctrl_srv_rx_cmd_id = -1;
12235 static int hf_zbee_zcl_appl_ctrl_exec_cmd_id = -1;
12236 static int hf_zbee_zcl_appl_ctrl_attr_func_id = -1;
12237 static int hf_zbee_zcl_appl_ctrl_attr_func_data_type = -1;
12238 static int hf_zbee_zcl_appl_ctrl_warning_id = -1;
12239 static int hf_zbee_zcl_appl_ctrl_appl_status = -1;
12240 static int hf_zbee_zcl_appl_ctrl_rem_en_flags_raw = -1;
12241 static int hf_zbee_zcl_appl_ctrl_rem_en_flags = -1;
12242 static int hf_zbee_zcl_appl_ctrl_status2 = -1;
12243 static int hf_zbee_zcl_appl_ctrl_status2_array = -1;
12244 
12245 /* Initialize the subtree pointers */
12246 static gint ett_zbee_zcl_appl_ctrl = -1;
12247 static gint ett_zbee_zcl_appl_ctrl_flags = -1;
12248 static gint ett_zbee_zcl_appl_ctrl_time = -1;
12249 static gint ett_zbee_zcl_appl_ctrl_func[ZBEE_ZCL_APPL_CTRL_NUM_FUNC_ETT];
12250 
12251 /* Attributes */
12252 static const value_string zbee_zcl_appl_ctrl_attr_names[] = {
12253     { ZBEE_ZCL_ATTR_ID_APPL_CTRL_START_TIME,                    "Start Time" },
12254     { ZBEE_ZCL_ATTR_ID_APPL_CTRL_FINISH_TIME,                   "Finish Time" },
12255     { ZBEE_ZCL_ATTR_ID_APPL_CTRL_REMAINING_TIME,                "Remaining Time" },
12256     { 0, NULL }
12257 };
12258 static value_string_ext zbee_zcl_appl_ctrl_attr_names_ext = VALUE_STRING_EXT_INIT(zbee_zcl_appl_ctrl_attr_names);
12259 
12260 /* Server Commands Received */
12261 static const value_string zbee_zcl_appl_ctrl_srv_rx_cmd_names[] = {
12262     { ZBEE_ZCL_CMD_ID_APPL_CTRL_EXECUTION_CMD,                  "Execution of a Command" },
12263     { ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE,                   "Signal State" },
12264     { ZBEE_ZCL_CMD_ID_APPL_CTRL_WRITE_FUNCS,                    "Write Functions" },
12265     { ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_PAUSE_RESUME,          "Overload Pause Resume" },
12266     { ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_PAUSE,                 "Overload Pause" },
12267     { ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_WARNING,               "Overload Warning" },
12268     { 0, NULL }
12269 };
12270 
12271 /* Server Commands Generated */
12272 static const value_string zbee_zcl_appl_ctrl_srv_tx_cmd_names[] = {
12273     { ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE_RSP,               "Signal State Response" },
12274     { ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE_NOTIF,             "Signal State Notification" },
12275     { 0, NULL }
12276 };
12277 
12278 /* Execution Of a Command - Command Name */
12279 static const value_string zbee_zcl_appl_ctrl_exec_cmd_names[] = {
12280     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_RESERVED,                  "Reserved" },
12281     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_START,                     "Start" },
12282     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_STOP,                      "Stop" },
12283     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_PAUSE,                     "Pause" },
12284     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_START_SUPERFREEZING,       "Start Superfreezing" },
12285     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_STOP_SUPERFREEZING,        "Stop Superfreezing" },
12286     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_START_SUPERCOOLING,        "Start Supercooling" },
12287     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_STOP_SUPERCOOLING,         "Stop Supercooling" },
12288     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_DISABLE_GAS,               "Disable Gas" },
12289     { ZBEE_ZCL_APPL_CTRL_EXEC_CMD_ID_ENABLE_GAS,                "Enable Gas" },
12290     { 0, NULL }
12291 };
12292 
12293 /* Appliance Status Names list */
12294 static const value_string zbee_zcl_appl_ctrl_appl_status_names[] = {
12295     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_RESERVED,                    "Reserved" },
12296     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_OFF,                         "Off" },
12297     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_STANDBY,                     "Stand-by" },
12298     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_PRG,                         "Programmed" },
12299     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_PRG_WAITING_TO_START,        "Waiting to Start" },
12300     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_RUNNING,                     "Running" },
12301     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_PAUSE,                       "Pause" },
12302     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_END_PRG,                     "End Programmed" },
12303     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_FAILURE,                     "Failure" },
12304     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_PRG_INTERRUPTED,             "Programme Interrupted" },
12305     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_IDLE,                        "Idle" },
12306     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_RINSE_HOLD,                  "Raise Hold" },
12307     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_SERVICE,                     "Service" },
12308     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_SUPERFREEZING,               "Superfreezing" },
12309     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_SUPERCOOLING,                "Supercooling" },
12310     { ZBEE_ZCL_APPL_CTRL_ID_STATUS_SUPERHEATING,                "Superheating" },
12311     { 0, NULL }
12312 };
12313 
12314 /* Remote Enable Flags Names list */
12315 static const value_string zbee_zcl_appl_ctrl_rem_flags_names[] = {
12316     { ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_DIS,                      "Disable" },
12317     { ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_EN_REM_EN_CTRL,           "Enable Remote and Energy Control" },
12318     { ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_TEMP_LOCK_DIS,            "Temporarily locked/disabled" },
12319     { ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_EN_REM_CTRL,              "Enable Remote Control" },
12320     { 0, NULL }
12321 };
12322 
12323 /* Appliance Status 2 Names list */
12324 static const value_string zbee_zcl_appl_ctrl_status2_names[] = {
12325     { ZBEE_ZCL_APPL_CTRL_STATUS2_PROPRIETARY_0,                 "Proprietary" },
12326     { ZBEE_ZCL_APPL_CTRL_STATUS2_PROPRIETARY_1,                 "Proprietary" },
12327     { ZBEE_ZCL_APPL_CTRL_STATUS2_IRIS_SYMPTOM_CODE,             "Iris symptom code" },
12328     { 0, NULL }
12329 };
12330 
12331 /* Overload Warning Names list */
12332 static const value_string zbee_zcl_appl_ctrl_ovrl_warning_names[] = {
12333     { ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_1,    "Overall power above 'available power' level" },
12334     { ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_2,    "Overall power above 'power threshold' level" },
12335     { ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_3,    "Overall power back below the 'available power' level" },
12336     { ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_4,    "Overall power back below the 'power threshold' level" },
12337     { ZBEE_ZCL_APPL_CTRL_ID_OVRL_WARN_5,    "Overall power will be potentially above 'available power' level if the appliance starts" },
12338     { 0, NULL }
12339 };
12340 
12341 /* CEDEC Time Encoding Names list */
12342 static const value_string zbee_zcl_appl_ctrl_time_encoding_type_names[] = {
12343     { ZBEE_ZCL_APPL_CTRL_TIME_ENCOD_REL,    "Relative" },
12344     { ZBEE_ZCL_APPL_CTRL_TIME_ENCOD_ABS,    "Absolute" },
12345     { 0, NULL }
12346 };
12347 
12348 /*************************/
12349 /* Function Bodies       */
12350 /*************************/
12351 
12352 /*FUNCTION:------------------------------------------------------
12353  *  NAME
12354  *      dissect_zbee_zcl_appl_ctrl
12355  *  DESCRIPTION
12356  *      ZigBee ZCL Appliance Control cluster dissector for wireshark.
12357  *  PARAMETERS
12358  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12359  *      packet_info *pinfo  - pointer to packet information fields
12360  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12361  *      void *data          - pointer to ZCL packet structure.
12362  *  RETURNS
12363  *      int                 - length of parsed data.
12364  *---------------------------------------------------------------
12365  */
12366 static int
dissect_zbee_zcl_appl_ctrl(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)12367 dissect_zbee_zcl_appl_ctrl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
12368 {
12369     proto_tree        *payload_tree;
12370     zbee_zcl_packet   *zcl;
12371     guint             offset = 0;
12372     guint8            cmd_id;
12373     gint              rem_len;
12374 
12375     /* Reject the packet if data is NULL */
12376     if (data == NULL)
12377         return 0;
12378     zcl = (zbee_zcl_packet *)data;
12379     cmd_id = zcl->cmd_id;
12380 
12381     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
12382     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
12383         /* Append the command name to the info column. */
12384         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
12385             val_to_str_const(cmd_id, zbee_zcl_appl_ctrl_srv_rx_cmd_names, "Unknown Command"),
12386             zcl->tran_seqno);
12387 
12388         /* Add the command ID. */
12389         proto_tree_add_item(tree, hf_zbee_zcl_appl_ctrl_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12390 
12391         /* Check is this command has a payload, than add the payload tree */
12392         rem_len = tvb_reported_length_remaining(tvb, ++offset);
12393         if (rem_len > 0) {
12394             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_appl_ctrl, NULL, "Payload");
12395 
12396             /* Call the appropriate command dissector */
12397             switch (cmd_id) {
12398                 case ZBEE_ZCL_CMD_ID_APPL_CTRL_EXECUTION_CMD:
12399                     dissect_zcl_appl_ctrl_exec_cmd(tvb, payload_tree, &offset);
12400                     break;
12401 
12402                 case ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE:
12403                 case ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_PAUSE_RESUME:
12404                 case ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_PAUSE:
12405                     /* No payload */
12406                     break;
12407 
12408                 case ZBEE_ZCL_CMD_ID_APPL_CTRL_WRITE_FUNCS:
12409                     dissect_zcl_appl_ctrl_wr_funcs(tvb, payload_tree, &offset);
12410                     break;
12411 
12412                 case ZBEE_ZCL_CMD_ID_APPL_CTRL_OVERLOAD_WARNING:
12413                     dissect_zcl_appl_ctrl_ovrl_warning(tvb, payload_tree, &offset);
12414                     break;
12415 
12416                 default:
12417                     break;
12418             }
12419         }
12420     }
12421     else { /* ZBEE_ZCL_FCF_TO_CLIENT */
12422         /* Append the command name to the info column. */
12423         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
12424             val_to_str_const(cmd_id, zbee_zcl_appl_ctrl_srv_tx_cmd_names, "Unknown Command"),
12425             zcl->tran_seqno);
12426 
12427         /* Add the command ID. */
12428         proto_tree_add_item(tree, hf_zbee_zcl_appl_ctrl_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12429 
12430         /* Check is this command has a payload, than add the payload tree */
12431         rem_len = tvb_reported_length_remaining(tvb, ++offset);
12432         if (rem_len > 0) {
12433             payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_appl_ctrl, NULL, "Payload");
12434 
12435             /* Call the appropriate command dissector */
12436             switch (cmd_id) {
12437                 case ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE_RSP:
12438                 case ZBEE_ZCL_CMD_ID_APPL_CTRL_SIGNAL_STATE_NOTIF:
12439                     dissect_zcl_appl_ctrl_signal_state_rsp(tvb, payload_tree, &offset);
12440                     break;
12441 
12442                 default:
12443                     break;
12444             }
12445         }
12446     }
12447 
12448     return tvb_captured_length(tvb);
12449 }
12450 
12451 
12452 /*FUNCTION:------------------------------------------------------
12453  *  NAME
12454  *      dissect_zcl_appl_ctrl_exec_cmd
12455  *  DESCRIPTION
12456  *      this function is called in order to decode "ExecutionOfACommand"
12457  *      payload.
12458  *  PARAMETERS
12459  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12460  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12461  *      guint *offset       - pointer to buffer offset
12462  *  RETURNS
12463  *      none
12464  *---------------------------------------------------------------
12465  */
12466 static void
dissect_zcl_appl_ctrl_exec_cmd(tvbuff_t * tvb,proto_tree * tree,guint * offset)12467 dissect_zcl_appl_ctrl_exec_cmd(tvbuff_t *tvb, proto_tree *tree, guint *offset)
12468 {
12469     /* Retrieve "Command Id" field */
12470     proto_tree_add_item(tree, hf_zbee_zcl_appl_ctrl_exec_cmd_id, tvb, *offset, 1, ENC_NA);
12471     *offset += 1;
12472 } /*dissect_zcl_appl_ctrl_exec_cmd*/
12473 
12474 
12475 /*FUNCTION:------------------------------------------------------
12476  *  NAME
12477  *      dissect_zcl_appl_ctrl_attr_func
12478  *  DESCRIPTION
12479  *      this function is called in order to decode "Function" element.
12480  *  PARAMETERS
12481  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12482  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12483  *      guint *offset       - pointer to buffer offset
12484  *  RETURNS
12485  *      none
12486  *---------------------------------------------------------------
12487  */
12488 static void
dissect_zcl_appl_ctrl_attr_func(tvbuff_t * tvb,proto_tree * tree,guint * offset)12489 dissect_zcl_appl_ctrl_attr_func(tvbuff_t *tvb, proto_tree *tree, guint *offset)
12490 {
12491     guint8  func_data_type;
12492     guint16 func_id;
12493 
12494     /* ID */
12495     func_id = tvb_get_letohs(tvb, *offset);
12496     proto_tree_add_item(tree, hf_zbee_zcl_appl_ctrl_attr_func_id, tvb, *offset, 2,ENC_LITTLE_ENDIAN);
12497     *offset += 2;
12498 
12499     proto_item_append_text(tree, ", %s",
12500     val_to_str_ext_const(func_id, &zbee_zcl_appl_ctrl_attr_names_ext, "Reserved"));
12501 
12502     /* Data Type */
12503     func_data_type = tvb_get_guint8(tvb, *offset);
12504     proto_tree_add_item(tree, hf_zbee_zcl_appl_ctrl_attr_func_data_type, tvb, *offset, 1, ENC_NA);
12505     *offset += 1;
12506 
12507     /* Function Data Dissector */
12508     dissect_zcl_appl_ctrl_attr_data(tree, tvb, offset, func_id, func_data_type, FALSE);
12509 
12510 } /*dissect_zcl_appl_ctrl_attr_func*/
12511 
12512 
12513 /*FUNCTION:------------------------------------------------------
12514  *  NAME
12515  *      dissect_zcl_appl_ctrl_wr_funcs
12516  *  DESCRIPTION
12517  *      this function is called in order to decode "WriteFunctions"
12518  *      payload.
12519  *  PARAMETERS
12520  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12521  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12522  *      guint *offset       - pointer to buffer offset
12523  *  RETURNS
12524  *      none
12525  *---------------------------------------------------------------
12526  */
12527 static void
dissect_zcl_appl_ctrl_wr_funcs(tvbuff_t * tvb,proto_tree * tree,guint * offset)12528 dissect_zcl_appl_ctrl_wr_funcs(tvbuff_t *tvb, proto_tree *tree, guint *offset)
12529 {
12530   proto_tree  *sub_tree = NULL;
12531   guint tvb_len;
12532   guint i = 0;
12533 
12534   tvb_len = tvb_reported_length(tvb);
12535   while ( *offset < tvb_len && i < ZBEE_ZCL_APPL_CTRL_NUM_FUNC_ETT ) {
12536     /* Create subtree for attribute status field */
12537     sub_tree = proto_tree_add_subtree_format(tree, tvb, *offset, 0,
12538             ett_zbee_zcl_appl_ctrl_func[i], NULL, "Function #%d", i);
12539     i++;
12540 
12541     /* Dissect the attribute identifier */
12542     dissect_zcl_appl_ctrl_attr_func(tvb, sub_tree, offset);
12543   }
12544 
12545 } /*dissect_zcl_appl_ctrl_wr_funcs*/
12546 
12547 
12548 /*FUNCTION:------------------------------------------------------
12549  *  NAME
12550  *      dissect_zcl_appl_ctrl_ovrl_warning
12551  *  DESCRIPTION
12552  *      this function is called in order to decode "OverloadWarning"
12553  *      payload.
12554  *  PARAMETERS
12555  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12556  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12557  *      guint *offset       - pointer to buffer offset
12558  *  RETURNS
12559  *      none
12560  *---------------------------------------------------------------
12561  */
12562 static void
dissect_zcl_appl_ctrl_ovrl_warning(tvbuff_t * tvb,proto_tree * tree,guint * offset)12563 dissect_zcl_appl_ctrl_ovrl_warning(tvbuff_t *tvb, proto_tree *tree, guint *offset)
12564 {
12565     /* Retrieve "Warning Id" field */
12566     proto_tree_add_item(tree, hf_zbee_zcl_appl_ctrl_warning_id, tvb, *offset, 1, ENC_NA);
12567     *offset += 1;
12568 
12569 } /*dissect_zcl_appl_ctrl_ovrl_warning*/
12570 
12571 
12572 /*FUNCTION:------------------------------------------------------
12573  *  NAME
12574  *      dissect_zcl_appl_ctrl_signal_state_rsp
12575  *  DESCRIPTION
12576  *      this function is called in order to decode "SignalStateResponse"
12577  *      "SignalStateNotification" payload.
12578  *  PARAMETERS
12579  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12580  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12581  *      guint *offset       - pointer to buffer offset
12582  *  RETURNS
12583  *      none
12584  *---------------------------------------------------------------
12585  */
12586 static void
dissect_zcl_appl_ctrl_signal_state_rsp(tvbuff_t * tvb,proto_tree * tree,guint * offset)12587 dissect_zcl_appl_ctrl_signal_state_rsp(tvbuff_t *tvb, proto_tree *tree, guint *offset)
12588 {
12589     static int * const flags[] = {
12590         &hf_zbee_zcl_appl_ctrl_rem_en_flags,
12591         &hf_zbee_zcl_appl_ctrl_status2,
12592         NULL
12593     };
12594 
12595     /* Retrieve "Appliance Status" field */
12596     proto_tree_add_item(tree, hf_zbee_zcl_appl_ctrl_appl_status, tvb, *offset, 1, ENC_NA);
12597     *offset += 1;
12598 
12599     /* Retrieve "Remote Enable" field */
12600     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_appl_ctrl_rem_en_flags_raw, ett_zbee_zcl_appl_ctrl_flags, flags, ENC_NA);
12601     *offset += 1;
12602 
12603     /* Retrieve "Appliance Status 2" field */
12604     proto_tree_add_item(tree, hf_zbee_zcl_appl_ctrl_status2_array, tvb, *offset, 3, ENC_BIG_ENDIAN);
12605 } /*dissect_zcl_appl_ctrl_signal_state_rsp*/
12606 
12607 /*FUNCTION:------------------------------------------------------
12608  *  NAME
12609  *      dissect_zcl_appl_ctrl_attr_data
12610  *  DESCRIPTION
12611  *      this function is called by ZCL foundation dissector in order to decode
12612  *      specific cluster attributes data.
12613  *  PARAMETERS
12614  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12615  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12616  *      guint *offset       - pointer to buffer offset
12617  *      guint16 attr_id     - attribute identifier
12618  *      guint data_type     - attribute data type
12619  *      gboolean client_attr- ZCL client
12620  *  RETURNS
12621  *      none
12622  *---------------------------------------------------------------
12623  */
12624 static void
dissect_zcl_appl_ctrl_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id,guint data_type,gboolean client_attr)12625 dissect_zcl_appl_ctrl_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id, guint data_type, gboolean client_attr)
12626 {
12627     static int * const flags[] = {
12628         &hf_zbee_zcl_appl_ctrl_time_mm,
12629         &hf_zbee_zcl_appl_ctrl_time_encoding_type,
12630         &hf_zbee_zcl_appl_ctrl_time_hh,
12631         NULL
12632     };
12633 
12634     /* Dissect attribute data type and data */
12635     switch (attr_id) {
12636 
12637         case ZBEE_ZCL_ATTR_ID_APPL_CTRL_START_TIME:
12638         case ZBEE_ZCL_ATTR_ID_APPL_CTRL_FINISH_TIME:
12639         case ZBEE_ZCL_ATTR_ID_APPL_CTRL_REMAINING_TIME:
12640             proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_appl_ctrl_time, ett_zbee_zcl_appl_ctrl_time, flags, ENC_LITTLE_ENDIAN);
12641             *offset += 2;
12642             break;
12643 
12644         default:
12645             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
12646             break;
12647     }
12648 } /*dissect_zcl_appl_ctrl_attr_data*/
12649 
12650 
12651 /*FUNCTION:------------------------------------------------------
12652  *  NAME
12653  *      proto_register_zbee_zcl_appl_ctrl
12654  *  DESCRIPTION
12655  *      this function registers the ZCL Appliance Control dissector
12656  *      and all its information.
12657  *  PARAMETERS
12658  *      none
12659  *  RETURNS
12660  *      none
12661  *---------------------------------------------------------------
12662  */
12663 void
proto_register_zbee_zcl_appl_ctrl(void)12664 proto_register_zbee_zcl_appl_ctrl(void)
12665 {
12666     guint i, j;
12667 
12668     static hf_register_info hf[] = {
12669 
12670         { &hf_zbee_zcl_appl_ctrl_attr_id,
12671             { "Attribute", "zbee_zcl_general.applctrl.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_appl_ctrl_attr_names),
12672             0x0, NULL, HFILL } },
12673 
12674         { &hf_zbee_zcl_appl_ctrl_time,
12675             { "Data", "zbee_zcl_general.applctrl.time", FT_UINT16, BASE_HEX, NULL, 0x0,
12676             NULL, HFILL } },
12677 
12678         { &hf_zbee_zcl_appl_ctrl_time_mm,
12679             { "Minutes", "zbee_zcl_general.applctrl.time.mm", FT_UINT16, BASE_DEC, NULL, ZBEE_ZCL_APPL_CTRL_TIME_MM,
12680             NULL, HFILL } },
12681 
12682         { &hf_zbee_zcl_appl_ctrl_time_encoding_type,
12683             { "Encoding Type", "zbee_zcl_general.applctrl.time.encoding_type", FT_UINT16, BASE_HEX, VALS(zbee_zcl_appl_ctrl_time_encoding_type_names),
12684             ZBEE_ZCL_APPL_CTRL_TIME_ENCOD_TYPE, NULL, HFILL } },
12685 
12686         { &hf_zbee_zcl_appl_ctrl_time_hh,
12687             { "Hours", "zbee_zcl_general.applctrl.time.hh", FT_UINT16, BASE_DEC, NULL, ZBEE_ZCL_APPL_CTRL_TIME_HH,
12688             NULL, HFILL } },
12689 
12690         { &hf_zbee_zcl_appl_ctrl_srv_tx_cmd_id,
12691             { "Command", "zbee_zcl_general.applctrl.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_appl_ctrl_srv_tx_cmd_names),
12692             0x0, NULL, HFILL } },
12693 
12694         { &hf_zbee_zcl_appl_ctrl_srv_rx_cmd_id,
12695             { "Command", "zbee_zcl_general.applctrl.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_appl_ctrl_srv_rx_cmd_names),
12696             0x0, NULL, HFILL } },
12697 
12698         { &hf_zbee_zcl_appl_ctrl_appl_status,
12699             { "Appliance Status", "zbee_zcl_general.applctrl.status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_appl_ctrl_appl_status_names),
12700             0x0, NULL, HFILL } },
12701 
12702         { &hf_zbee_zcl_appl_ctrl_rem_en_flags_raw,
12703             { "Remote Enable Flags", "zbee_zcl_general.applctrl.remote_enable_flags", FT_UINT8, BASE_HEX, NULL,
12704             0x0, NULL, HFILL } },
12705 
12706         { &hf_zbee_zcl_appl_ctrl_rem_en_flags,
12707             { "Remote Enable Flags", "zbee_zcl_general.applctrl.remenflags", FT_UINT8, BASE_HEX, VALS(zbee_zcl_appl_ctrl_rem_flags_names),
12708             ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_FLAGS, NULL, HFILL } },
12709 
12710         { &hf_zbee_zcl_appl_ctrl_status2,
12711             { "Appliance Status 2", "zbee_zcl_general.applctrl.status2", FT_UINT8, BASE_HEX, VALS(zbee_zcl_appl_ctrl_status2_names),
12712             ZBEE_ZCL_APPL_CTRL_REM_EN_FLAGS_STATUS2, NULL, HFILL } },
12713 
12714         { &hf_zbee_zcl_appl_ctrl_status2_array,
12715             { "Appliance Status 2", "zbee_zcl_general.applctrl.status2.array", FT_UINT24, BASE_HEX, NULL,
12716             0x00, NULL, HFILL } },
12717 
12718         { &hf_zbee_zcl_appl_ctrl_exec_cmd_id,
12719             { "Command", "zbee_zcl_general.applctrl.execcmd.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_appl_ctrl_exec_cmd_names),
12720             0x0, NULL, HFILL } },
12721 
12722         { &hf_zbee_zcl_appl_ctrl_attr_func_id,
12723             { "ID", "zbee_zcl_general.applctrl.attr_func.id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_appl_ctrl_attr_names),
12724             0x0, NULL, HFILL } },
12725 
12726         { &hf_zbee_zcl_appl_ctrl_attr_func_data_type,
12727             { "Data Type", "zbee_zcl_general.applctrl.attr_func.datatype", FT_UINT8, BASE_HEX, VALS(zbee_zcl_short_data_type_names),
12728             0x0, NULL, HFILL } },
12729 
12730         { &hf_zbee_zcl_appl_ctrl_warning_id,
12731             { "Warning", "zbee_zcl_general.applctrl.ovrlwarning.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_appl_ctrl_ovrl_warning_names),
12732             0x0, NULL, HFILL } }
12733 
12734     };
12735 
12736     /* ZCL ApplianceControl subtrees */
12737     gint *ett[ZBEE_ZCL_APPL_CTRL_NUM_ETT] = {
12738         &ett_zbee_zcl_appl_ctrl,
12739         &ett_zbee_zcl_appl_ctrl_flags,
12740         &ett_zbee_zcl_appl_ctrl_time
12741     };
12742 
12743     /* initialize attribute subtree types */
12744     for ( i = 0, j = ZBEE_ZCL_APPL_CTRL_NUM_GENERIC_ETT; i < ZBEE_ZCL_APPL_CTRL_NUM_FUNC_ETT; i++, j++) {
12745         ett_zbee_zcl_appl_ctrl_func[i] = -1;
12746         ett[j] = &ett_zbee_zcl_appl_ctrl_func[i];
12747     }
12748 
12749     /* Register the ZigBee ZCL ApplianceControl cluster protocol name and description */
12750     proto_zbee_zcl_appl_ctrl = proto_register_protocol("ZigBee ZCL Appliance Control", "ZCL Appliance Control", ZBEE_PROTOABBREV_ZCL_APPLCTRL);
12751     proto_register_field_array(proto_zbee_zcl_appl_ctrl, hf, array_length(hf));
12752     proto_register_subtree_array(ett, array_length(ett));
12753 
12754     /* Register the ZigBee ZCL Appliance Control dissector. */
12755     register_dissector(ZBEE_PROTOABBREV_ZCL_APPLCTRL, dissect_zbee_zcl_appl_ctrl, proto_zbee_zcl_appl_ctrl);
12756 } /*proto_register_zbee_zcl_appl_ctrl*/
12757 
12758 
12759 /*FUNCTION:------------------------------------------------------
12760  *  NAME
12761  *      proto_reg_handoff_zbee_zcl_appl_ctrl
12762  *  DESCRIPTION
12763  *      Hands off the Zcl Appliance Control dissector.
12764  *  PARAMETERS
12765  *      none
12766  *  RETURNS
12767  *      void
12768  *---------------------------------------------------------------
12769  */
12770 void
proto_reg_handoff_zbee_zcl_appl_ctrl(void)12771 proto_reg_handoff_zbee_zcl_appl_ctrl(void)
12772 {
12773     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_APPLCTRL,
12774                             proto_zbee_zcl_appl_ctrl,
12775                             ett_zbee_zcl_appl_ctrl,
12776                             ZBEE_ZCL_CID_APPLIANCE_CONTROL,
12777                             ZBEE_MFG_CODE_NONE,
12778                             hf_zbee_zcl_appl_ctrl_attr_id,
12779                             hf_zbee_zcl_appl_ctrl_attr_id,
12780                             hf_zbee_zcl_appl_ctrl_srv_rx_cmd_id,
12781                             hf_zbee_zcl_appl_ctrl_srv_tx_cmd_id,
12782                             (zbee_zcl_fn_attr_data)dissect_zcl_appl_ctrl_attr_data
12783                          );
12784 } /*proto_reg_handoff_zbee_zcl_appl_ctrl*/
12785 
12786 /* ########################################################################## */
12787 /* #### (0x0020) POLL CONTROL CLUSTER ####################################### */
12788 /* ########################################################################## */
12789 
12790 /*************************/
12791 /* Defines               */
12792 /*************************/
12793 
12794 /* Poll Control Attributes */
12795 #define ZBEE_ZCL_ATTR_ID_POLL_CTRL_CHECK_IN             0x0000
12796 #define ZBEE_ZCL_ATTR_ID_POLL_CTRL_LONG_POLL            0x0001
12797 #define ZBEE_ZCL_ATTR_ID_POLL_CTRL_SHORT_POLL           0x0002
12798 #define ZBEE_ZCL_ATTR_ID_POLL_CTRL_FAST_POLL            0x0003
12799 #define ZBEE_ZCL_ATTR_ID_POLL_CTRL_CHECK_IN_MIN         0x0004
12800 #define ZBEE_ZCL_ATTR_ID_POLL_CTRL_LONG_POLL_MIN        0x0005
12801 #define ZBEE_ZCL_ATTR_ID_POLL_CTRL_FAST_POLL_TIMEOUT    0x0006
12802 
12803 static const value_string zbee_zcl_poll_ctrl_attr_names[] = {
12804     { ZBEE_ZCL_ATTR_ID_POLL_CTRL_CHECK_IN,          "Check-inInterval" },
12805     { ZBEE_ZCL_ATTR_ID_POLL_CTRL_LONG_POLL,         "LongPollInterval" },
12806     { ZBEE_ZCL_ATTR_ID_POLL_CTRL_SHORT_POLL,        "ShortPollInterval" },
12807     { ZBEE_ZCL_ATTR_ID_POLL_CTRL_FAST_POLL,         "FastPollTimeout" },
12808     { ZBEE_ZCL_ATTR_ID_POLL_CTRL_CHECK_IN_MIN,      "Check-inIntervalMin" },
12809     { ZBEE_ZCL_ATTR_ID_POLL_CTRL_LONG_POLL_MIN,     "LongPollIntervalMin" },
12810     { ZBEE_ZCL_ATTR_ID_POLL_CTRL_FAST_POLL_TIMEOUT, "FastPollTimeoutMax" },
12811     { 0, NULL }
12812 };
12813 
12814 /* Server-to-client command IDs. */
12815 #define ZBEE_ZCL_CMD_ID_POLL_CTRL_CHECK_IN          0x00
12816 static const value_string zbee_zcl_poll_ctrl_srv_tx_cmd_names[] = {
12817     { ZBEE_ZCL_CMD_ID_POLL_CTRL_CHECK_IN,           "Check-in" },
12818     { 0, NULL }
12819 };
12820 
12821 /* Client-to-server command IDs. */
12822 #define ZBEE_ZCL_CMD_ID_POLL_CTRL_CHECK_IN_RESPONSE 0x00
12823 #define ZBEE_ZCL_CMD_ID_POLL_CTRL_FAST_POLL_STOP    0x01
12824 #define ZBEE_ZCL_CMD_ID_POLL_CTRL_SET_LONG_POLL     0x02
12825 #define ZBEE_ZCL_CMD_ID_POLL_CTRL_SET_SHORT_POLL    0x03
12826 static const value_string zbee_zcl_poll_ctrl_srv_rx_cmd_names[] = {
12827     { ZBEE_ZCL_CMD_ID_POLL_CTRL_CHECK_IN_RESPONSE,  "Check-in Response" },
12828     { ZBEE_ZCL_CMD_ID_POLL_CTRL_FAST_POLL_STOP,     "Fast Poll Stop" },
12829     { ZBEE_ZCL_CMD_ID_POLL_CTRL_SET_LONG_POLL,      "Set Long Poll Interval" },
12830     { ZBEE_ZCL_CMD_ID_POLL_CTRL_SET_SHORT_POLL,     "Set Short Poll Interval" },
12831     { 0, NULL }
12832 };
12833 
12834 /*************************/
12835 /* Global Variables      */
12836 /*************************/
12837 /* Initialize the protocol and registered fields */
12838 static int proto_zbee_zcl_poll_ctrl = -1;
12839 
12840 static int hf_zbee_zcl_poll_ctrl_attr_id = -1;
12841 static int hf_zbee_zcl_poll_ctrl_srv_rx_cmd_id = -1;
12842 static int hf_zbee_zcl_poll_ctrl_srv_tx_cmd_id = -1;
12843 static int hf_zbee_zcl_poll_ctrl_start_fast_polling = -1;
12844 static int hf_zbee_zcl_poll_ctrl_fast_poll_timeout = -1;
12845 static int hf_zbee_zcl_poll_ctrl_new_long_poll_interval = -1;
12846 static int hf_zbee_zcl_poll_ctrl_new_short_poll_interval = -1;
12847 
12848 static gint ett_zbee_zcl_poll_ctrl = -1;
12849 
12850 /*************************/
12851 /* Function Declarations */
12852 /*************************/
12853 void proto_register_zbee_zcl_poll_ctrl(void);
12854 void proto_reg_handoff_zbee_zcl_poll_ctrl(void);
12855 
12856 /*FUNCTION:------------------------------------------------------
12857  *  NAME
12858  *      dissect_zbee_zcl_poll_ctrl
12859  *  DESCRIPTION
12860  *      ZigBee ZCL Poll Control cluster dissector for wireshark.
12861  *  PARAMETERS
12862  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12863  *      packet_info *pinfo  - pointer to packet information fields
12864  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12865  *      void *data          - pointer to ZCL packet structure.
12866  *  RETURNS
12867  *      int                 - length of parsed data.
12868  *---------------------------------------------------------------
12869  */
12870 static int
dissect_zbee_zcl_poll_ctrl(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)12871 dissect_zbee_zcl_poll_ctrl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
12872 {
12873     zbee_zcl_packet   *zcl;
12874     guint             offset = 0;
12875     guint8            cmd_id;
12876 
12877     /* Reject the packet if data is NULL */
12878     if (data == NULL)
12879         return 0;
12880     zcl = (zbee_zcl_packet *)data;
12881     cmd_id = zcl->cmd_id;
12882 
12883     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
12884         /* Append the command name to the info column. */
12885         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
12886             val_to_str_const(cmd_id, zbee_zcl_poll_ctrl_srv_rx_cmd_names, "Unknown Command"),
12887             zcl->tran_seqno);
12888 
12889         /* Add the command ID. */
12890         proto_tree_add_item(tree, hf_zbee_zcl_poll_ctrl_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
12891         offset++;
12892 
12893         /* Handle the command dissection. */
12894         switch (cmd_id) {
12895             case ZBEE_ZCL_CMD_ID_POLL_CTRL_CHECK_IN_RESPONSE:
12896                 proto_tree_add_item(tree, hf_zbee_zcl_poll_ctrl_start_fast_polling, tvb, offset, 1, ENC_NA);
12897                 offset++;
12898                 proto_tree_add_item(tree, hf_zbee_zcl_poll_ctrl_fast_poll_timeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12899                 break;
12900 
12901             case ZBEE_ZCL_CMD_ID_POLL_CTRL_FAST_POLL_STOP:
12902                 /* no payload. */
12903                 break;
12904 
12905             case ZBEE_ZCL_CMD_ID_POLL_CTRL_SET_LONG_POLL:
12906                 proto_tree_add_item(tree, hf_zbee_zcl_poll_ctrl_new_long_poll_interval, tvb, offset, 4, ENC_LITTLE_ENDIAN);
12907                 break;
12908 
12909             case ZBEE_ZCL_CMD_ID_POLL_CTRL_SET_SHORT_POLL:
12910                 proto_tree_add_item(tree, hf_zbee_zcl_poll_ctrl_new_short_poll_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
12911                 break;
12912 
12913             default:
12914                 break;
12915         } /* switch */
12916     } else {
12917         /* Append the command name to the info column. */
12918         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
12919             val_to_str_const(cmd_id, zbee_zcl_poll_ctrl_srv_tx_cmd_names, "Unknown Command"),
12920             zcl->tran_seqno);
12921 
12922         /* Add the command ID. */
12923         proto_tree_add_item(tree, hf_zbee_zcl_poll_ctrl_srv_tx_cmd_id, tvb, offset, 1, ENC_NA);
12924         offset++;
12925 
12926         /* Handle the command dissection. */
12927         switch (cmd_id) {
12928             case ZBEE_ZCL_CMD_ID_POLL_CTRL_CHECK_IN:
12929                 /* No payload - fall through. */
12930             default:
12931                 break;
12932         } /* switch */
12933     }
12934 
12935     return tvb_captured_length(tvb);
12936 } /* dissect_zbee_zcl_poll_ctrl */
12937 
12938 
12939 /*FUNCTION:------------------------------------------------------
12940  *  NAME
12941  *      dissect_zcl_poll_ctrl_attr_data
12942  *  DESCRIPTION
12943  *      this function is called by ZCL foundation dissector in order to decode
12944  *      specific cluster attributes data.
12945  *  PARAMETERS
12946  *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
12947  *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
12948  *      guint *offset       - pointer to buffer offset
12949  *      guint16 attr_id     - attribute identifier
12950  *      guint data_type     - attribute data type
12951  *      gboolean client_attr- ZCL client
12952  *  RETURNS
12953  *      none
12954  *---------------------------------------------------------------
12955  */
12956 static void
dissect_zcl_poll_ctrl_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id _U_,guint data_type,gboolean client_attr)12957 dissect_zcl_poll_ctrl_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id _U_, guint data_type, gboolean client_attr)
12958 {
12959     /* Dissect attribute data type and data */
12960     dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
12961 
12962 } /*dissect_zcl_poll_ctrl_attr_data*/
12963 
12964 /*FUNCTION:------------------------------------------------------
12965  *  NAME
12966  *      proto_register_zbee_zcl_poll_ctrl
12967  *  DESCRIPTION
12968  *      ZigBee ZCL Poll Control cluster protocol registration.
12969  *  PARAMETERS
12970  *      none
12971  *  RETURNS
12972  *      void
12973  *---------------------------------------------------------------
12974  */
12975 void
proto_register_zbee_zcl_poll_ctrl(void)12976 proto_register_zbee_zcl_poll_ctrl(void)
12977 {
12978     /* Setup list of header fields */
12979     static hf_register_info hf[] = {
12980 
12981         { &hf_zbee_zcl_poll_ctrl_attr_id,
12982             { "Attribute", "zbee_zcl_general.poll.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_poll_ctrl_attr_names),
12983             0x0, NULL, HFILL } },
12984 
12985         { &hf_zbee_zcl_poll_ctrl_srv_rx_cmd_id,
12986             { "Command", "zbee_zcl_general.poll.cmd.srv_rx.id", FT_UINT8, BASE_HEX,
12987                 VALS(zbee_zcl_poll_ctrl_srv_rx_cmd_names), 0x0, NULL, HFILL }},
12988 
12989         { &hf_zbee_zcl_poll_ctrl_srv_tx_cmd_id,
12990             { "Command", "zbee_zcl_general.poll.cmd.srv_tx.id", FT_UINT8, BASE_HEX,
12991                 VALS(zbee_zcl_poll_ctrl_srv_tx_cmd_names), 0x0, NULL, HFILL }},
12992 
12993         { &hf_zbee_zcl_poll_ctrl_start_fast_polling,
12994             { "Start Fast Polling", "zbee_zcl_general.poll.start", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x0,
12995                 NULL, HFILL }},
12996 
12997         { &hf_zbee_zcl_poll_ctrl_fast_poll_timeout,
12998             { "Fast Poll Timeout (quarterseconds)", "zbee_zcl_general.poll.fast_timeout", FT_UINT16, BASE_DEC, NULL,
12999                 0x0, NULL, HFILL }},
13000 
13001         { &hf_zbee_zcl_poll_ctrl_new_long_poll_interval,
13002             { "New Long Poll Interval", "zbee_zcl_general.poll.new_long_interval", FT_UINT32, BASE_DEC, NULL, 0x0, NULL,
13003                 HFILL }},
13004 
13005         { &hf_zbee_zcl_poll_ctrl_new_short_poll_interval,
13006             { "New Short Poll Interval", "zbee_zcl_general.poll.new_short_interval", FT_UINT16, BASE_DEC, NULL, 0x0, NULL,
13007                 HFILL }}
13008     };
13009 
13010     /* ZCL Poll Control subtrees */
13011     static gint *ett[] = {
13012         &ett_zbee_zcl_poll_ctrl
13013     };
13014 
13015     /* Register the ZigBee ZCL Poll Control cluster protocol name and description */
13016     proto_zbee_zcl_poll_ctrl = proto_register_protocol("ZigBee ZCL Poll Control", "ZCL Poll Control", ZBEE_PROTOABBREV_ZCL_POLL);
13017     proto_register_field_array(proto_zbee_zcl_poll_ctrl, hf, array_length(hf));
13018     proto_register_subtree_array(ett, array_length(ett));
13019 
13020     /* Register the ZigBee ZCL Poll Control dissector. */
13021     register_dissector(ZBEE_PROTOABBREV_ZCL_POLL, dissect_zbee_zcl_poll_ctrl, proto_zbee_zcl_poll_ctrl);
13022 } /*proto_register_zbee_zcl_poll_ctrl*/
13023 
13024 /*FUNCTION:------------------------------------------------------
13025  *  NAME
13026  *      proto_reg_handoff_zbee_zcl_poll_ctrl
13027  *  DESCRIPTION
13028  *      Hands off the ZCL Poll Control dissector.
13029  *  PARAMETERS
13030  *      none
13031  *  RETURNS
13032  *      none
13033  *---------------------------------------------------------------
13034  */
13035 void
proto_reg_handoff_zbee_zcl_poll_ctrl(void)13036 proto_reg_handoff_zbee_zcl_poll_ctrl(void)
13037 {
13038     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_POLL,
13039                             proto_zbee_zcl_poll_ctrl,
13040                             ett_zbee_zcl_poll_ctrl,
13041                             ZBEE_ZCL_CID_POLL_CONTROL,
13042                             ZBEE_MFG_CODE_NONE,
13043                             hf_zbee_zcl_poll_ctrl_attr_id,
13044                             hf_zbee_zcl_poll_ctrl_attr_id,
13045                             hf_zbee_zcl_poll_ctrl_srv_rx_cmd_id,
13046                             hf_zbee_zcl_poll_ctrl_srv_tx_cmd_id,
13047                             (zbee_zcl_fn_attr_data)dissect_zcl_poll_ctrl_attr_data
13048                          );
13049 } /*proto_reg_handoff_zbee_zcl_poll_ctrl*/
13050 
13051 
13052 
13053 /* ########################################################################## */
13054 /* #### (0x0021) GREEN POWER CLUSTER ######################################## */
13055 /* ########################################################################## */
13056 
13057 /*************************/
13058 /* Defines               */
13059 /*************************/
13060 
13061 /* Green Power Attributes */
13062 
13063 #define ZBEE_ZCL_ATTR_GPS_MAX_SINK_TABLE_ENTRIES     0x0000
13064 #define ZBEE_ZCL_ATTR_GPS_SINK_TABLE                 0x0001
13065 #define ZBEE_ZCL_ATTR_GPS_COMMUNICATION_MODE         0x0002
13066 #define ZBEE_ZCL_ATTR_GPS_COMMISSIONING_EXIT_MODE    0x0003
13067 #define ZBEE_ZCL_ATTR_GPS_COMMISSIONING_WINDOW       0x0004
13068 #define ZBEE_ZCL_ATTR_GPS_SECURITY_LEVEL             0x0005
13069 #define ZBEE_ZCL_ATTR_GPS_FUNCTIONALITY              0x0006
13070 #define ZBEE_ZCL_ATTR_GPS_ACTIVE_FUNCTIONALITY       0x0007
13071 #define ZBEE_ZCL_ATTR_GPP_MAX_PROXY_TABLE_ENTRIES    0x0010
13072 #define ZBEE_ZCL_ATTR_GPP_PROXY_TABLE                0x0011
13073 #define ZBEE_ZCL_ATTR_GPP_NOTIFICATION_RETRY_NUMBER  0x0012
13074 #define ZBEE_ZCL_ATTR_GPP_NOTIFICATION_RETRY_TIMER   0x0013
13075 #define ZBEE_ZCL_ATTR_GPP_MAX_SEARCH_COUNTER         0x0014
13076 #define ZBEE_ZCL_ATTR_GPP_BLOCKED_GPDID              0x0015
13077 #define ZBEE_ZCL_ATTR_GPP_FUNCTIONALITY              0x0016
13078 #define ZBEE_ZCL_ATTR_GPP_ACTIVE_FUNCTIONALITY       0x0017
13079 #define ZBEE_ZCL_ATTR_GP_SHARED_SECURITY_KEY_TYPE    0x0020
13080 #define ZBEE_ZCL_ATTR_GP_SHARED_SECURITY_KEY         0x0021
13081 #define ZBEE_ZCL_ATTR_GP_LINK_KEY                    0x0022
13082 
13083 static const value_string zbee_zcl_gp_attr_names[] = {
13084     { ZBEE_ZCL_ATTR_GPS_MAX_SINK_TABLE_ENTRIES,     "gpsMaxSinkTableEntries" },
13085     { ZBEE_ZCL_ATTR_GPS_SINK_TABLE,                 "SinkTable" },
13086     { ZBEE_ZCL_ATTR_GPS_COMMUNICATION_MODE,         "gpsCommunicationMode" },
13087     { ZBEE_ZCL_ATTR_GPS_COMMISSIONING_EXIT_MODE,    "gpsCommissioningExitMode" },
13088     { ZBEE_ZCL_ATTR_GPS_COMMISSIONING_WINDOW,       "gpsCommissioningWindow" },
13089     { ZBEE_ZCL_ATTR_GPS_SECURITY_LEVEL,             "gpsSecurityLevel" },
13090     { ZBEE_ZCL_ATTR_GPS_FUNCTIONALITY,              "gpsFunctionality" },
13091     { ZBEE_ZCL_ATTR_GPS_ACTIVE_FUNCTIONALITY,       "gpsActiveFunctionality" },
13092     { ZBEE_ZCL_ATTR_GPP_MAX_PROXY_TABLE_ENTRIES,    "gppMaxProxyTableEntries" },
13093     { ZBEE_ZCL_ATTR_GPP_PROXY_TABLE,                "ProxyTable" },
13094     { ZBEE_ZCL_ATTR_GPP_NOTIFICATION_RETRY_NUMBER,  "gppNotificationRetryNumber" },
13095     { ZBEE_ZCL_ATTR_GPP_NOTIFICATION_RETRY_TIMER,   "gppNotificationRetryTimer" },
13096     { ZBEE_ZCL_ATTR_GPP_MAX_SEARCH_COUNTER,         "gppMaxSearchCounter" },
13097     { ZBEE_ZCL_ATTR_GPP_BLOCKED_GPDID,              "gppBlockedGPDID" },
13098     { ZBEE_ZCL_ATTR_GPP_FUNCTIONALITY,              "gppFunctionality" },
13099     { ZBEE_ZCL_ATTR_GPP_ACTIVE_FUNCTIONALITY,       "gppActiveFunctionality" },
13100     { ZBEE_ZCL_ATTR_GP_SHARED_SECURITY_KEY_TYPE,    "gpSharedSecurityKeyType" },
13101     { ZBEE_ZCL_ATTR_GP_SHARED_SECURITY_KEY,         "gpSharedSecurityKey" },
13102     { ZBEE_ZCL_ATTR_GP_LINK_KEY,                    "gpLinkKey" },
13103     { 0, NULL }
13104 };
13105 
13106 /* Server-to-client command IDs. */
13107 #define ZBEE_ZCL_CMD_ID_GP_NOTIFICATION_RESPONSE     0x00
13108 #define ZBEE_ZCL_CMD_ID_GP_PAIRING                   0x01
13109 #define ZBEE_ZCL_CMD_ID_GP_PROXY_COMMISSIONING_MODE  0x02
13110 #define ZBEE_ZCL_CMD_ID_GP_RESPONSE                  0x06
13111 #define ZBEE_ZCL_CMD_ID_GP_TRANS_TBL_RESPONSE        0x08
13112 #define ZBEE_ZCL_CMD_ID_GP_SINK_TABLE_RESPONSE       0x0a
13113 #define ZBEE_ZCL_CMD_ID_GP_PROXY_TABLE_REQUEST       0x0b
13114 
13115 static const value_string zbee_zcl_gp_srv_tx_cmd_names[] = {
13116     { ZBEE_ZCL_CMD_ID_GP_NOTIFICATION_RESPONSE,     "GP Notification Response" },
13117     { ZBEE_ZCL_CMD_ID_GP_PAIRING,                   "GP Pairing" },
13118     { ZBEE_ZCL_CMD_ID_GP_PROXY_COMMISSIONING_MODE,  "GP Proxy Commissioning Mode" },
13119     { ZBEE_ZCL_CMD_ID_GP_RESPONSE,                  "GP Response" },
13120     { ZBEE_ZCL_CMD_ID_GP_TRANS_TBL_RESPONSE,        "GP Translation Table Response" },
13121     { ZBEE_ZCL_CMD_ID_GP_SINK_TABLE_RESPONSE,       "GP Sink Table Response" },
13122     { ZBEE_ZCL_CMD_ID_GP_PROXY_TABLE_REQUEST,       "GP Proxy Table Request" },
13123     { 0, NULL }
13124 };
13125 
13126 /* Client-to-server command IDs. */
13127 #define ZBEE_CMD_ID_GP_NOTIFICATION                        0x00
13128 #define ZBEE_CMD_ID_GP_PAIRING_SEARCH                      0x01
13129 #define ZBEE_CMD_ID_GP_TUNNELING_STOP                      0x03
13130 #define ZBEE_CMD_ID_GP_COMMISSIONING_NOTIFICATION          0x04
13131 #define ZBEE_CMD_ID_GP_SINK_COMMISSIONING_MODE             0x05
13132 #define ZBEE_CMD_ID_GP_TRANSLATION_TABLE_UPDATE_COMMAND    0x07
13133 #define ZBEE_CMD_ID_GP_TRANSLATION_TABLE_REQUEST           0x08
13134 #define ZBEE_CMD_ID_GP_PAIRING_CONFIGURATION               0x09
13135 #define ZBEE_CMD_ID_GP_SINK_TABLE_REQUEST                  0x0a
13136 #define ZBEE_CMD_ID_GP_PROXY_TABLE_RESPONSE                0x0b
13137 
13138 static const value_string zbee_zcl_gp_srv_rx_cmd_names[] = {
13139     { ZBEE_CMD_ID_GP_NOTIFICATION,                      "GP Notification" },
13140     { ZBEE_CMD_ID_GP_PAIRING_SEARCH,                    "GP Pairing Search" },
13141     { ZBEE_CMD_ID_GP_TUNNELING_STOP,                    "GP Tunneling Stop" },
13142     { ZBEE_CMD_ID_GP_COMMISSIONING_NOTIFICATION,        "GP Commissioning Notification" },
13143     { ZBEE_CMD_ID_GP_SINK_COMMISSIONING_MODE,           "GP Sink Commissioning Mode" },
13144     { ZBEE_CMD_ID_GP_TRANSLATION_TABLE_UPDATE_COMMAND,  "GP Translation Table Update" },
13145     { ZBEE_CMD_ID_GP_TRANSLATION_TABLE_REQUEST,         "GP Translation Table Request" },
13146     { ZBEE_CMD_ID_GP_PAIRING_CONFIGURATION,             "GP Pairing Configuration" },
13147     { ZBEE_CMD_ID_GP_SINK_TABLE_REQUEST,                "GP Sink Table Request" },
13148     { ZBEE_CMD_ID_GP_PROXY_TABLE_RESPONSE,              "GP Proxy Table Response" },
13149     { 0, NULL }
13150 };
13151 
13152 static const value_string zbee_zcl_gp_comm_mode_actions[] = {
13153     { 0, "Exit commissioning mode" },
13154     { 1, "Enter commissioning mode" },
13155     { 0, NULL }
13156 };
13157 
13158 static const value_string zbee_zcl_gp_app_ids[] = {
13159     { 0, "0b000 4b SrcID; no Endpoint" },
13160     { 2, "0b010 8b IEEE; Endpoint presents" },
13161     { 0, NULL }
13162 };
13163 
13164 static const value_string zbee_zcl_gp_secur_levels[] = {
13165     { 0, "No security" },
13166     { 1, "Reserved" },
13167     { 2, "4B frame counter and 4B MIC only" },
13168     { 3, "Encryption & 4B frame counter and 4B MIC" },
13169     { 0, NULL }
13170 };
13171 
13172 static const value_string zbee_zcl_gp_secur_key_types[] = {
13173     { 0, "No key" },
13174     { 1, "ZigBee NWK key" },
13175     { 2, "GPD group key" },
13176     { 3, "NWK-key derived GPD group key" },
13177     { 4, "(individual) out-of-the-box GPD key" },
13178     { 7, "Derived individual GPD key" },
13179     { 0, NULL }
13180 };
13181 
13182 static const value_string zbee_zcl_gp_communication_modes[] = {
13183     { 0, "Full unicast" },
13184     { 1, "Groupcast to DGroupID" },
13185     { 2, "Groupcast to pre-commissioned GroupID" },
13186     { 3, "Lightweight unicast" },
13187     { 0, NULL }
13188 };
13189 
13190 static const value_string zbee_zcl_gp_lqi_vals[] = {
13191     { 0, "Poor" },
13192     { 1, "Moderate" },
13193     { 2, "High" },
13194     { 3, "Excellent" },
13195     { 0, NULL }
13196 };
13197 
13198 static const value_string zbee_zcl_gp_channels[] = {
13199     { 0, "Channel 11" },
13200     { 1, "Channel 12" },
13201     { 2, "Channel 13" },
13202     { 3, "Channel 14" },
13203     { 4, "Channel 15" },
13204     { 5, "Channel 16" },
13205     { 6, "Channel 17" },
13206     { 7, "Channel 18" },
13207     { 8, "Channel 19" },
13208     { 9, "Channel 20" },
13209     { 10, "Channel 21" },
13210     { 11, "Channel 22" },
13211     { 12, "Channel 23" },
13212     { 13, "Channel 24" },
13213     { 14, "Channel 25" },
13214     { 15, "Channel 26" },
13215     { 0, NULL }
13216 };
13217 
13218 static const value_string zbee_gp_pc_actions[] = {
13219     { 0, "No action" },
13220     { 1, "Extend Sink Table entry" },
13221     { 2, "Replace Sink Table entry" },
13222     { 3, "Remove a pairing" },
13223     { 4, "Remove GPD" },
13224     { 0, NULL }
13225 };
13226 
13227 static const value_string zbee_zcl_gp_proxy_sink_tbl_req_type[] = {
13228     { 0, "Request table entries by GPD ID" },
13229     { 1, "Request table entries by Index" },
13230     { 0, NULL }
13231 };
13232 
13233 #define ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ACTION                             1
13234 #define ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_EXIT_MODE                          (7<<1)
13235 #define ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ON_COMMISSIONING_WINDOW_EXPIRATION ((1<<0)<<1)
13236 #define ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ON_PAIRING_SUCCESS                 ((1<<1)<<1)
13237 #define ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ON_GP_PROXY_COMM_MODE              ((1<<2)<<1)
13238 #define ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_CHANNEL_PRESENT                    (1<<4)
13239 #define ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_UNICAST                            (1<<5)
13240 
13241 
13242 #define ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_APP_ID                           (7<<0)
13243 #define ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_RX_AFTER_TX                      (1<<3)
13244 #define ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_SECUR_LEVEL                      (3<<4)
13245 #define ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_SECUR_KEY_TYPE                   (7<<6)
13246 #define ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_SECUR_FAILED                     (1<<9)
13247 #define ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_BIDIR_CAP                        (1<<10)
13248 #define ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_PROXY_INFO_PRESENT               (1<<11)
13249 
13250 #define ZBEE_ZCL_GP_GPP_GPD_LINK_RSSI                                                  0x3f
13251 #define ZBEE_ZCL_GP_GPP_GPD_LINK_LQI                                                   (3<<6)
13252 
13253 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_APP_ID                                         (7<<0)
13254 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_ALSO_UNICAST                                   (1<<3)
13255 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_ALSO_DERIVED_GROUP                             (1<<4)
13256 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_ALSO_COMMISSIONED_GROUP                        (1<<5)
13257 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_SECUR_LEVEL                                    (3<<6)
13258 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_SECUR_KEY_TYPE                                 (7<<8)
13259 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_RX_AFTER_TX                                    (1<<11)
13260 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_TX_Q_FULL                                      (1<<12)
13261 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_BIDIR_CAP                                      (1<<13)
13262 #define ZBEE_ZCL_GP_NOTIFICATION_OPTION_PROXY_INFO_PRESENT                             (1<<14)
13263 
13264 #define ZBEE_ZCL_GP_PAIRING_OPTION_APP_ID                                              (7<<0)
13265 #define ZBEE_ZCL_GP_PAIRING_OPTION_ADD_SINK                                            (1<<3)
13266 #define ZBEE_ZCL_GP_PAIRING_OPTION_REMOVE_GPD                                          (1<<4)
13267 #define ZBEE_ZCL_GP_PAIRING_OPTION_COMMUNICATION_MODE                                  (3<<5)
13268 #define ZBEE_ZCL_GP_PAIRING_OPTION_GPD_FIXED                                           (1<<7)
13269 #define ZBEE_ZCL_GP_PAIRING_OPTION_GPD_MAC_SEQ_NUM_CAP                                 (1<<8)
13270 #define ZBEE_ZCL_GP_PAIRING_OPTION_SECUR_LEVEL                                         (3<<9)
13271 #define ZBEE_ZCL_GP_PAIRING_OPTION_SECUR_KEY_TYPE                                      (7<<11)
13272 #define ZBEE_ZCL_GP_PAIRING_OPTION_GPD_FRAME_CNT_PRESENT                               (1<<14)
13273 #define ZBEE_ZCL_GP_PAIRING_OPTION_GPD_SECUR_KEY_PRESENT                               (1<<15)
13274 #define ZBEE_ZCL_GP_PAIRING_OPTION_ASSIGNED_ALIAS_PRESENT                              (1<<16)
13275 #define ZBEE_ZCL_GP_PAIRING_OPTION_FWD_RADIUS_PRESENT                                  (1<<17)
13276 
13277 #define ZBEE_ZCL_GP_RESPONSE_OPTION_APP_ID                                             (7<<0)
13278 #define ZBEE_ZCL_GP_RESPONSE_OPTION_TX_ON_ENDPOINT_MATCH                               (1<<3)
13279 
13280 #define ZBEE_ZCL_GP_RESPONSE_TX_CHANNEL                                                (0xf<<0)
13281 
13282 #define ZBEE_ZCL_GP_CMD_PC_ACTIONS_ACTION                                              (7<<0)
13283 #define ZBEE_ZCL_GP_CMD_PC_ACTIONS_SEND_GP_PAIRING                                     (1<<3)
13284 
13285 #define ZBEE_ZCL_GP_CMD_PC_OPT_APP_ID                                                  (7<<0)
13286 #define ZBEE_ZCL_GP_CMD_PC_OPT_COMMUNICATION_MODE                                      (3<<3)
13287 #define ZBEE_ZCL_GP_CMD_PC_OPT_SEQ_NUMBER_CAP                                          (1<<5)
13288 #define ZBEE_ZCL_GP_CMD_PC_OPT_RX_ON_CAP                                               (1<<6)
13289 #define ZBEE_ZCL_GP_CMD_PC_OPT_FIXED_LOCATION                                          (1<<7)
13290 #define ZBEE_ZCL_GP_CMD_PC_OPT_ASSIGNED_ALIAS                                          (1<<8)
13291 #define ZBEE_ZCL_GP_CMD_PC_OPT_SECURITY_USE                                            (1<<9)
13292 #define ZBEE_ZCL_GP_CMD_PC_OPT_APP_INFO_PRESENT                                        (1<<10)
13293 #define ZBEE_ZCL_GP_COMMUNICATION_MODE_GROUPCAST_PRECOMMISSIONED                       2
13294 #define ZBEE_ZCL_GP_PAIRING_CONFIGURATION_OPTION_COMMUNICATION_MODE_SHIFT              3
13295 #define ZBEE_ZCL_GP_CMD_PC_SECUR_LEVEL                                                 (3<<0)
13296 #define ZBEE_ZCL_GP_CMD_PC_SECUR_KEY_TYPE                                              (7<<2)
13297 #define ZBEE_ZCL_GP_CMD_PC_APP_INFO_MANUF_ID_PRESENT                                   (1<<0)
13298 #define ZBEE_ZCL_GP_CMD_PC_APP_INFO_MODEL_ID_PRESENT                                   (1<<1)
13299 #define ZBEE_ZCL_GP_CMD_PC_APP_INFO_GPD_COMMANDS_PRESENT                               (1<<2)
13300 #define ZBEE_ZCL_GP_CMD_PC_APP_INFO_CLUSTER_LIST_PRESENT                               (1<<3)
13301 #define ZBEE_ZCL_GP_CLUSTER_LIST_LEN_SRV                                               (0xf<<0)
13302 #define ZBEE_ZCL_GP_CLUSTER_LIST_LEN_CLI                                               (0xf<<4)
13303 #define ZBEE_ZCL_GP_CLUSTER_LIST_LEN_CLI_SHIFT                                         4
13304 
13305 #define ZBEE_ZCL_GP_PROXY_SINK_TBL_REQ_CMD_APP_ID                                      (0x07<<0)
13306 #define ZBEE_ZCL_GP_PROXY_SINK_TBL_REQ_CMD_REQ_TYPE                                    (0x03<<3)
13307 #define ZBEE_ZCL_GP_PROXY_SINK_TBL_REQ_CMD_REQ_TYPE_SHIFT                              3
13308 
13309 #define ZBEE_ZCL_GP_SINK_TBL_OPT_APP_ID                                                (7<<0)
13310 #define ZBEE_ZCL_GP_SINK_TBL_OPT_COMMUNICATION_MODE                                    (3<<3)
13311 #define ZBEE_ZCL_GP_SINK_TBL_OPT_SEQ_NUMBER_CAP                                        (1<<5)
13312 #define ZBEE_ZCL_GP_SINK_TBL_OPT_RX_ON_CAP                                             (1<<6)
13313 #define ZBEE_ZCL_GP_SINK_TBL_OPT_FIXED_LOCATION                                        (1<<7)
13314 #define ZBEE_ZCL_GP_SINK_TBL_OPT_ASSIGNED_ALIAS                                        (1<<8)
13315 #define ZBEE_ZCL_GP_SINK_TBL_OPT_SECURITY_USE                                          (1<<9)
13316 
13317 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_APP_ID                                               (7<<0)
13318 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_ENTRY_ACTIVE                                         (1<<3)
13319 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_ENTRY_VALID                                          (1<<4)
13320 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_SEQ_NUMBER_CAP                                       (1<<5)
13321 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_LW_UCAST_GPS                                         (1<<6)
13322 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_DERIVED_GROUP_GPS                                    (1<<7)
13323 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_COMM_GROUP_GPS                                       (1<<8)
13324 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_FIRST_TO_FORWARD                                     (1<<9)
13325 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_IN_RANGE                                             (1<<10)
13326 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_GPD_FIXED                                            (1<<11)
13327 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_HAS_ALL_UCAST_ROUTES                                 (1<<12)
13328 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_ASSIGNED_ALIAS                                       (1<<13)
13329 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_SECURITY_USE                                         (1<<14)
13330 #define ZBEE_ZCL_GP_PROXY_TBL_OPT_OPTIONS_EXTENTIONS                                   (1<<15)
13331 
13332 #define ZBEE_ZCL_GP_PROXY_TBL_EXT_OPT_FULL_UCAST_GPS                                   (1<<0)
13333 
13334 #define ZBEE_ZCL_GP_SECUR_OPT_SECUR_LEVEL                                              (3<<0)
13335 #define ZBEE_ZCL_GP_SECUR_OPT_SECUR_KEY_TYPE                                           (7<<2)
13336 
13337 /* Sink Commissioning Mode command */
13338 #define ZBEE_ZCL_GP_CMD_SINK_COMM_MODE_OPTIONS_FLD_ACTION                              (1<<0)
13339 #define ZBEE_ZCL_GP_CMD_SINK_COMM_MODE_OPTIONS_FLD_INV_GPM_IN_SECUR                    (1<<1)
13340 #define ZBEE_ZCL_GP_CMD_SINK_COMM_MODE_OPTIONS_FLD_INV_GPM_IN_PAIRING                  (1<<2)
13341 #define ZBEE_ZCL_GP_CMD_SINK_COMM_MODE_OPTIONS_FLD_INV_PROXIES                         (1<<3)
13342 
13343 /* gppFunctionality attribute */
13344 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GP_FEATURE                                       (1<<0)
13345 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_DIRECT_COMM                                      (1<<1)
13346 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_DERIVED_GCAST_COMM                               (1<<2)
13347 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_PRE_COMMISSIONED_GCAST_COMM                      (1<<3)
13348 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_FULL_UCAST_COMM                                  (1<<4)
13349 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_LW_UCAST_COMM                                    (1<<5)
13350 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_BIDIR_OP                                         (1<<7)
13351 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_PROXY_TBL_MAINTENANCE                            (1<<8)
13352 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GP_COMMISSIONING                                 (1<<10)
13353 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_CT_BASED_COMMISSIONING                           (1<<11)
13354 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_MAINTENANCE_OF_GPD                               (1<<12)
13355 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_SECUR_LVL_00                                 (1<<13)
13356 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_SECUR_LVL_01                                 (1<<14)
13357 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_SECUR_LVL_10                                 (1<<15)
13358 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_SECUR_LVL_11                                 (1<<16)
13359 #define ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_IEEE_ADDRESS                                 (1<<19)
13360 /* gppActiveFunctionality attribute */
13361 #define ZBEE_ZCL_GP_ATTR_GPP_ACTIVE_FUNC_FLD_GP_FUNCTIONALITY                          (1<<0)
13362 
13363 /* gpsFunctionality attribute */
13364 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GP_FEATURE                                       (1<<0)
13365 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_DIRECT_COMM                                      (1<<1)
13366 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_DERIVED_GCAST_COMM                               (1<<2)
13367 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_PRE_COMMISSIONED_GCAST_COMM                      (1<<3)
13368 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_FULL_UCAST_COMM                                  (1<<4)
13369 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_LW_UCAST_COMM                                    (1<<5)
13370 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_PROXIMITY_BIDIR_OP                               (1<<6)
13371 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_MULTI_HOP_BIDIR_OP                               (1<<7)
13372 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_PROXY_TBL_MAINTENANCE                            (1<<8)
13373 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_PROXIMITY_COMMISSIONING                          (1<<9)
13374 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_MULTI_HOP_COMMISSIONING                          (1<<10)
13375 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_CT_BASED_COMMISSIONING                           (1<<11)
13376 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_MAINTENANCE_OF_GPD                               (1<<12)
13377 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_SECUR_LVL_00                                 (1<<13)
13378 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_SECUR_LVL_01                                 (1<<14)
13379 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_SECUR_LVL_10                                 (1<<15)
13380 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_SECUR_LVL_11                                 (1<<16)
13381 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_SINK_TBL_BASED_GCAST_FORWARDING                  (1<<17)
13382 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_TRANSLATION_TABLE                                (1<<18)
13383 #define ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_IEEE_ADDRESS                                 (1<<19)
13384 /* gpsActiveFunctionality attribute */
13385 #define ZBEE_ZCL_GP_ATTR_GPS_ACTIVE_FUNC_FLD_GP_FUNCTIONALITY                          (1<<0)
13386 
13387 /* gpsCommissioningExitMode attribute */
13388 #define ZBEE_ZCL_GP_ATTR_GPS_COMM_EXIT_MODE_FLD_ON_COMM_WINDOW_EXPIRE                  (1<<0)
13389 #define ZBEE_ZCL_GP_ATTR_GPS_COMM_EXIT_MODE_FLD_ON_PAIRING_SUCCESS                     (1<<1)
13390 #define ZBEE_ZCL_GP_ATTR_GPS_COMM_EXIT_MODE_FLD_ON_GP_PROXY_COMM_MODE                  (1<<2)
13391 
13392 /* gpsCommunicationMode attribute */
13393 #define ZBEE_ZCL_GP_ATTR_GPS_COMMUNICATION_MODE_FLD_MODE                               (3<<0)
13394 
13395 /* gpsSecurityLevel attribute */
13396 #define ZBEE_ZCL_GP_ATTR_GPS_SECUR_LVL_FLD_MIN_GPD_SECUR_LVL                           (3<<0)
13397 #define ZBEE_ZCL_GP_ATTR_GPS_SECUR_LVL_FLD_PROTECTION_WITH_GP_LINK_KEY                 (1<<2)
13398 #define ZBEE_ZCL_GP_ATTR_GPS_SECUR_LVL_FLD_INVOLVE_TC                                  (1<<3)
13399 
13400 /* Definitions for application IDs. */
13401 #define ZBEE_ZCL_GP_APP_ID_DEFAULT                                                     0x00
13402 #define ZBEE_ZCL_GP_APP_ID_ZGP                                                         0x02
13403 
13404 /** Definitions for Request type sub-field of the Options field of the
13405  *  GP Sink Table Request and GP Proxy Table request commands
13406  */
13407 #define ZBEE_ZCL_GP_PROXY_SINK_TABLE_REQ_CMD_REQUSET_BY_GPD_ID                          0
13408 #define ZBEE_ZCL_GP_PROXY_SINK_TABLE_REQ_CMD_REQUSET_BY_INDEX                           1
13409 
13410 /*************************/
13411 /* Global Variables      */
13412 /*************************/
13413 /* Initialize the protocol and registered fields */
13414 static int proto_zbee_zcl_gp = -1;
13415 
13416 static int hf_zbee_zcl_gp_attr_id = -1;
13417 static int hf_zbee_zcl_gp_srv_rx_cmd_id = -1;
13418 static int hf_zbee_zcl_gp_srv_tx_cmd_id = -1;
13419 
13420 static gint ett_zbee_zcl_gp = -1;
13421 
13422 /* GP_PROXY_COMMISSIONING_MODE */
13423 static gint ett_zbee_gp_cmd_proxy_commissioning_mode_options = -1;
13424 static gint ett_zbee_gp_cmd_proxy_commissioning_mode_exit_mode = -1;
13425 static gint hf_zbee_gp_cmd_proxy_commissioning_mode_options = -1;
13426 static gint hf_zbee_gp_cmd_pcm_opt_action = -1;
13427 static gint hf_zbee_gp_cmd_pcm_opt_exit_mode = -1;
13428 static gint hf_zbee_gp_cmd_pcm_opt_channel_present = -1;
13429 static gint hf_zbee_gp_cmd_pcm_opt_unicast_comm = -1;
13430 static gint hf_zbee_gp_cmd_proxy_commissioning_mode_exit_mode = -1;
13431 static gint hf_zbee_gp_cmd_pcm_exit_mode_on_comm_window_expire = -1;
13432 static gint hf_zbee_gp_cmd_pcm_exit_mode_on_pairing_success = -1;
13433 static gint hf_zbee_gp_cmd_pcm_exit_mode_on_gp_proxy_comm_mode = -1;
13434 static gint hf_zbee_zcl_gp_commissioning_window = -1;
13435 static gint hf_zbee_zcl_gp_channel = -1;
13436 
13437 /* GP_COMMISSIONING_NOTIFICATION */
13438 static gint hf_zbee_gp_cmd_comm_notif_opt_app_id = -1;
13439 static gint hf_zbee_gp_cmd_comm_notif_opt_rx_after_tx = -1;
13440 static gint hf_zbee_gp_cmd_comm_notif_opt_secur_level = -1;
13441 static gint hf_zbee_gp_cmd_comm_notif_opt_secur_key_type = -1;
13442 static gint hf_zbee_gp_cmd_comm_notif_opt_secur_fail = -1;
13443 static gint hf_zbee_gp_cmd_comm_notif_opt_bidir_cap = -1;
13444 static gint hf_zbee_gp_cmd_comm_notif_opt_proxy_info_present = -1;
13445 static gint hf_zbee_gp_cmd_commissioning_notification_options = -1;
13446 static gint ett_zbee_gp_cmd_commissioning_notification_options = -1;
13447 static gint hf_zbee_gp_src_id = -1;
13448 static gint hf_zbee_gp_ieee = -1;
13449 static gint hf_zbee_gp_endpoint = -1;
13450 static gint hf_zbee_gp_secur_frame_counter = -1;
13451 static gint hf_zbee_gp_gpd_command_id = -1;
13452 static gint hf_zbee_gp_short_addr = -1;
13453 static gint hf_zbee_gp_gpp_gpd_link = -1;
13454 static gint hf_zbee_gp_mic = -1;
13455 static gint ett_zbee_gp_gpp_gpd_link = -1;
13456 static gint hf_zbee_gpp_gpd_link_rssi = -1;
13457 static gint hf_zbee_gpp_gpd_link_lqi = -1;
13458 static gint hf_zbee_gp_gpd_payload_size = -1;
13459 
13460 
13461 /* GP_NOTIFICATION */
13462 static gint hf_zbee_gp_cmd_notification_options = -1;
13463 static gint ett_zbee_gp_cmd_notification_options = -1;
13464 static gint hf_zbee_gp_cmd_notif_opt_app_id = -1;
13465 static gint hf_zbee_gp_cmd_notif_opt_also_unicast = -1;
13466 static gint hf_zbee_gp_cmd_notif_opt_also_derived_group = -1;
13467 static gint hf_zbee_gp_cmd_notif_opt_also_comm_group = -1;
13468 static gint hf_zbee_gp_cmd_notif_opt_secur_level = -1;
13469 static gint hf_zbee_gp_cmd_notif_opt_secur_key_type = -1;
13470 static gint hf_zbee_gp_cmd_notif_opt_rx_after_tx = -1;
13471 static gint hf_zbee_gp_cmd_notif_opt_tx_q_full = -1;
13472 static gint hf_zbee_gp_cmd_notif_opt_bidir_cap = -1;
13473 static gint hf_zbee_gp_cmd_notif_opt_proxy_info_present = -1;
13474 
13475 /* GP_PAIRING */
13476 static gint hf_zbee_gp_cmd_pairing_opt_app_id = -1;
13477 static gint hf_zbee_gp_cmd_pairing_opt_add_sink = -1;
13478 static gint hf_zbee_gp_cmd_pairing_opt_remove_gpd = -1;
13479 static gint hf_zbee_gp_cmd_pairing_opt_communication_mode = -1;
13480 static gint hf_zbee_gp_cmd_pairing_opt_gpd_fixed = -1;
13481 static gint hf_zbee_gp_cmd_pairing_opt_gpd_mac_seq_num_cap = -1;
13482 static gint hf_zbee_gp_cmd_pairing_opt_secur_level = -1;
13483 static gint hf_zbee_gp_cmd_pairing_opt_secur_key_type = -1;
13484 static gint hf_zbee_gp_cmd_pairing_opt_gpd_frame_cnt_present = -1;
13485 static gint hf_zbee_gp_cmd_pairing_opt_gpd_secur_key_present = -1;
13486 static gint hf_zbee_gp_cmd_pairing_opt_assigned_alias_present = -1;
13487 static gint hf_zbee_gp_cmd_pairing_opt_fwd_radius_present = -1;
13488 static gint hf_zbee_gp_cmd_pairing_options = -1;
13489 static gint ett_zbee_gp_cmd_pairing_options = -1;
13490 static gint hf_zbee_gp_sink_ieee = -1;
13491 static gint hf_zbee_gp_sink_nwk = -1;
13492 static gint hf_zbee_gp_sink_group_id = -1;
13493 static gint hf_zbee_gp_device_id = -1;
13494 static gint hf_zbee_gp_assigned_alias = -1;
13495 static gint hf_zbee_gp_forwarding_radius = -1;
13496 static gint hf_zbee_gp_gpd_key = -1;
13497 static gint hf_zbee_gp_groupcast_radius = -1;
13498 
13499 /* GP Response */
13500 static gint hf_zbee_gp_cmd_response_options = -1;
13501 static gint ett_zbee_gp_cmd_response_options = -1;
13502 static gint hf_zbee_gp_cmd_response_tx_channel = -1;
13503 static gint ett_zbee_gp_cmd_response_tx_channel = -1;
13504 static gint hf_zbee_gp_cmd_resp_opt_app_id = -1;
13505 static gint hf_zbee_gp_cmd_resp_opt_tx_on_ep_match = -1;
13506 static gint hf_zbee_gp_tmp_master_short_addr = -1;
13507 static gint hf_zbee_gp_cmd_resp_tx_channel = -1;
13508 
13509 /* GP_PAIRING_CONFIGURATION */
13510 static int hf_zbee_gp_cmd_pc_actions_action = -1;
13511 static int hf_zbee_gp_cmd_pc_actions_send_gp_pairing = -1;
13512 static int hf_zbee_gp_cmd_pc_opt_app_id = -1;
13513 static int hf_zbee_gp_cmd_pc_opt_communication_mode = -1;
13514 static int hf_zbee_gp_cmd_pc_opt_seq_number_cap = -1;
13515 static int hf_zbee_gp_cmd_px_opt_rx_on_cap = -1;
13516 static int hf_zbee_gp_cmd_pc_opt_fixed_location = -1;
13517 static int hf_zbee_gp_cmd_pc_opt_assigned_alias = -1;
13518 static int hf_zbee_gp_cmd_pc_opt_security_use = -1;
13519 static int hf_zbee_gp_cmd_pc_opt_app_info_present = -1;
13520 static int hf_zbee_gp_cmd_pc_secur_level = -1;
13521 static int hf_zbee_gp_cmd_pc_secur_key_type = -1;
13522 static int hf_zbee_gp_cmd_pc_app_info_manuf_id_present = -1;
13523 static int hf_zbee_gp_cmd_pc_app_info_model_id_present = -1;
13524 static int hf_zbee_gp_cmd_pc_app_info_gpd_commands_present = -1;
13525 static int hf_zbee_gp_cmd_pc_app_info_cluster_list_present = -1;
13526 static int hf_zbee_gp_cmd_pc_actions = -1;
13527 static guint ett_zbee_gp_cmd_pc_actions = -1;
13528 static int hf_zbee_gp_cmd_pc_options = -1;
13529 static guint ett_zbee_gp_cmd_pc_options = -1;
13530 static guint ett_zbee_zcl_gp_group_list = -1;
13531 static int hf_zbee_gp_group_list_len = -1;
13532 static int hf_zbee_gp_group_list_group_id = -1;
13533 static int hf_zbee_gp_group_list_alias = -1;
13534 static int hf_zbee_gp_cmd_pc_secur_options = -1;
13535 static guint ett_zbee_gp_cmd_pc_secur_options = -1;
13536 static int hf_zbee_gp_n_paired_endpoints = -1;
13537 static int hf_zbee_gp_paired_endpoint = -1;
13538 static int hf_zbee_gp_cmd_pc_app_info = -1;
13539 static guint ett_zbee_gp_cmd_pc_app_info = -1;
13540 static int hf_zbee_zcl_gp_manufacturer_id = -1;
13541 static int hf_zbee_zcl_gp_model_id = -1;
13542 static int hf_zbee_gp_n_gpd_commands = -1;
13543 static int hf_zbee_gp_gpd_command = -1;
13544 static int hf_zbee_gp_n_srv_clusters = -1;
13545 static int hf_zbee_gp_n_cli_clusters = -1;
13546 static int hf_zbee_gp_gpd_cluster_id = -1;
13547 static guint ett_zbee_zcl_gp_ep = -1;
13548 static guint ett_zbee_zcl_gp_cmds = -1;
13549 static guint ett_zbee_zcl_gp_clusters = -1;
13550 static guint ett_zbee_zcl_gp_srv_clusters = -1;
13551 static guint ett_zbee_zcl_gp_cli_clusters = -1;
13552 
13553 /* GP_SINK_TABLE_REQUEST and GP_PROXY_TABLE_REQUEST */
13554 static guint ett_zbee_zcl_proxy_sink_tbl_req_options = -1;
13555 static int hf_zbee_zcl_proxy_sink_tbl_req_options = -1;
13556 static int hf_zbee_zcl_proxy_sink_tbl_req_fld_app_id = -1;
13557 static int hf_zbee_zcl_proxy_sink_tbl_req_fld_req_type = -1;
13558 static int hf_zbee_zcl_proxy_sink_tbl_req_index = -1;
13559 
13560 /* GP_SINK_TABLE_RESPONSE and GP_PROXY_TABLE_RESPONSE */
13561 static int hf_zbee_zcl_proxy_sink_tbl_resp_status = -1;
13562 static int hf_zbee_zcl_proxy_sink_tbl_resp_entries_total = -1;
13563 static int hf_zbee_zcl_proxy_sink_tbl_resp_start_index = -1;
13564 static int hf_zbee_zcl_proxy_sink_tbl_resp_entries_count = -1;
13565 
13566 /* GP SINK_COMMISSIONING_MODE */
13567 static gint ett_zbee_zcl_gp_cmd_sink_comm_mode_options = -1;
13568 static gint hf_zbee_zcl_gp_cmd_sink_comm_mode_options = -1;
13569 
13570 static gint hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_action = -1;
13571 static gint hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_gpm_in_secur = -1;
13572 static gint hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_gpm_in_pairing = -1;
13573 static gint hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_proxies = -1;
13574 
13575 static gint hf_zbee_gp_zcl_cmd_sink_comm_mode_gpm_addr_for_secur = -1;
13576 static gint hf_zbee_gp_zcl_cmd_sink_comm_mode_gpm_addr_for_pairing = -1;
13577 static gint hf_zbee_gp_zcl_cmd_sink_comm_mode_sink_ep = -1;
13578 
13579 /* GP Sink Table Attribute */
13580 static gint ett_zbee_gp_sink_tbl = -1;
13581 static gint ett_zbee_gp_sink_tbl_entry = -1;
13582 static gint ett_zbee_gp_sink_tbl_entry_options = -1;
13583 
13584 static gint hf_zbee_gp_sink_tbl_length = -1;
13585 static gint hf_zbee_gp_sink_tbl_entry_options = -1;
13586 
13587 static gint hf_zbee_gp_sink_tbl_entry_options_app_id = -1;
13588 static gint hf_zbee_gp_sink_tbl_entry_options_comm_mode = -1;
13589 static gint hf_zbee_gp_sink_tbl_entry_options_seq_num_cap = -1;
13590 static gint hf_zbee_gp_sink_tbl_entry_options_rx_on_cap = -1;
13591 static gint hf_zbee_gp_sink_tbl_entry_options_fixed_loc = -1;
13592 static gint hf_zbee_gp_sink_tbl_entry_options_assigned_alias = -1;
13593 static gint hf_zbee_gp_sink_tbl_entry_options_sec_use = -1;
13594 
13595 static gint ett_zbee_gp_sec_options = -1;
13596 static gint hf_zbee_gp_sec_options = -1;
13597 static gint hf_zbee_gp_sec_options_sec_level = -1;
13598 static gint hf_zbee_gp_sec_options_sec_key_type = -1;
13599 
13600 /* GP Proxy Table Attribute */
13601 static gint ett_zbee_gp_proxy_tbl = -1;
13602 static gint ett_zbee_gp_proxy_tbl_entry = -1;
13603 static gint ett_zbee_gp_proxy_tbl_entry_options = -1;
13604 static gint ett_zbee_gp_proxy_tbl_entry_ext_options = -1;
13605 
13606 static gint hf_zbee_gp_proxy_tbl_length = -1;
13607 static gint hf_zbee_gp_proxy_tbl_entry_options = -1;
13608 static gint hf_zbee_gp_proxy_tbl_entry_ext_options = -1;
13609 
13610 static gint hf_zbee_gp_proxy_tbl_entry_options_app_id = -1;
13611 static gint hf_zbee_gp_proxy_tbl_entry_options_entry_active = -1;
13612 static gint hf_zbee_gp_proxy_tbl_entry_options_entry_valid = -1;
13613 static gint hf_zbee_gp_proxy_tbl_entry_options_seq_num_cap = -1;
13614 static gint hf_zbee_gp_proxy_tbl_entry_options_lw_ucast_gps = -1;
13615 static gint hf_zbee_gp_proxy_tbl_entry_options_derived_group_gps = -1;
13616 static gint hf_zbee_gp_proxy_tbl_entry_options_comm_group_gps = -1;
13617 static gint hf_zbee_gp_proxy_tbl_entry_options_first_to_forward = -1;
13618 static gint hf_zbee_gp_proxy_tbl_entry_options_in_range = -1;
13619 static gint hf_zbee_gp_proxy_tbl_entry_options_gpd_fixed = -1;
13620 static gint hf_zbee_gp_proxy_tbl_entry_options_has_all_ucast_routes = -1;
13621 static gint hf_zbee_gp_proxy_tbl_entry_options_assigned_alias = -1;
13622 static gint hf_zbee_gp_proxy_tbl_entry_options_sec_use = -1;
13623 static gint hf_zbee_gp_proxy_tbl_entry_options_opt_ext = -1;
13624 
13625 static gint hf_zbee_gp_proxy_tbl_entry_search_counter = -1;
13626 
13627 static gint hf_zbee_gp_proxy_tbl_entry_ext_options_full_ucast_gps = -1;
13628 
13629 static gint ett_zbee_gp_sink_address_list = -1;
13630 static gint hf_zbee_gp_sink_address_list_length = -1;
13631 
13632 /* GP gppFunctionality Attribute */
13633 static gint ett_zbee_zcl_gp_attr_gpp_func = -1;
13634 static gint hf_zbee_zcl_gp_attr_gpp_func = -1;
13635 
13636 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_gp_feature = -1;
13637 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_direct_comm = -1;
13638 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_derived_gcast_comm = -1;
13639 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_pre_commissioned_gcast_comm = -1;
13640 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_full_ucast_comm = -1;
13641 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_lw_ucast_comm = -1;
13642 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_bidir_op = -1;
13643 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_proxy_tbl_maintenance = -1;
13644 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_gp_commissioning = -1;
13645 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_ct_based_commissioning = -1;
13646 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_maintenance_of_gpd = -1;
13647 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_00 = -1;
13648 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_01 = -1;
13649 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_10 = -1;
13650 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_11 = -1;
13651 static gint hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_ieee_address = -1;
13652 
13653 /* GP gppActiveFunctionality Attribute */
13654 static gint ett_zbee_zcl_gp_attr_gpp_active_func = -1;
13655 static gint hf_zbee_zcl_gp_attr_gpp_active_func = -1;
13656 static gint hf_zbee_zcl_gp_attr_gpp_active_func_fld_gp_functionality = -1;
13657 
13658 /* GP gpsFunctionality Attribute */
13659 static gint ett_zbee_zcl_gp_attr_gps_func = -1;
13660 static gint hf_zbee_zcl_gp_attr_gps_func = -1;
13661 
13662 static gint hf_zbee_zcl_gp_attr_gps_func_fld_gp_feature = -1;
13663 static gint hf_zbee_zcl_gp_attr_gps_func_fld_direct_comm = -1;
13664 static gint hf_zbee_zcl_gp_attr_gps_func_fld_derived_gcast_comm = -1;
13665 static gint hf_zbee_zcl_gp_attr_gps_func_fld_pre_commissioned_gcast_comm = -1;
13666 static gint hf_zbee_zcl_gp_attr_gps_func_fld_full_ucast_comm = -1;
13667 static gint hf_zbee_zcl_gp_attr_gps_func_fld_lw_ucast_comm = -1;
13668 static gint hf_zbee_zcl_gp_attr_gps_func_fld_proximity_bidir_op = -1;
13669 static gint hf_zbee_zcl_gp_attr_gps_func_fld_multi_hop_bidir_op = -1;
13670 static gint hf_zbee_zcl_gp_attr_gps_func_fld_proxy_tbl_maintenance = -1;
13671 static gint hf_zbee_zcl_gp_attr_gps_func_fld_proximity_commissioning = -1;
13672 static gint hf_zbee_zcl_gp_attr_gps_func_fld_multi_hop_commissioning = -1;
13673 static gint hf_zbee_zcl_gp_attr_gps_func_fld_ct_based_commissioning = -1;
13674 static gint hf_zbee_zcl_gp_attr_gps_func_fld_maintenance_of_gpd = -1;
13675 static gint hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_00 = -1;
13676 static gint hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_01 = -1;
13677 static gint hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_10 = -1;
13678 static gint hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_11 = -1;
13679 static gint hf_zbee_zcl_gp_attr_gps_func_fld_sink_tbl_based_gcast_forwarding = -1;
13680 static gint hf_zbee_zcl_gp_attr_gps_func_fld_translation_table = -1;
13681 static gint hf_zbee_zcl_gp_attr_gps_func_fld_gpd_ieee_address = -1;
13682 
13683 /* GP gppActiveFunctionality Attribute */
13684 static gint ett_zbee_zcl_gp_attr_gps_active_func = -1;
13685 static gint hf_zbee_zcl_gp_attr_gps_active_func = -1;
13686 static gint hf_zbee_zcl_gp_attr_gps_active_func_fld_gp_functionality = -1;
13687 
13688 /* GP gpsCommissioningExitMode Attribute */
13689 static gint ett_zbee_zcl_gp_attr_gps_comm_exit_mode = -1;
13690 static gint hf_zbee_zcl_gp_attr_gps_comm_exit_mode = -1;
13691 static gint hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_comm_window_expire = -1;
13692 static gint hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_pairing_success = -1;
13693 static gint hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_gp_proxy_comm_mode = -1;
13694 
13695 /* GP gpsCommunicationMode Attribute */
13696 static gint ett_zbee_zcl_gp_attr_gps_communication_mode = -1;
13697 static gint hf_zbee_zcl_gp_attr_gps_communication_mode = -1;
13698 static gint hf_zbee_zcl_gp_attr_gps_communication_mode_fld_mode = -1;
13699 
13700 /* GP gpsSecurityLevel Attribute */
13701 static gint ett_zbee_zcl_gp_attr_gps_secur_lvl = -1;
13702 static gint hf_zbee_zcl_gp_attr_gps_secur_lvl = -1;
13703 static gint hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_min_gpd_secur_lvl = -1;
13704 static gint hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_protection_with_gp_link_key = -1;
13705 static gint hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_involve_tc = -1;
13706 
13707 /* reuse ZGPD command names */
13708 extern value_string_ext zbee_nwk_gp_cmd_names_ext;
13709 /* reuse devices table from ZGPD parser */
13710 extern const value_string zbee_nwk_gp_device_ids_names[];
13711 
13712 /*************************/
13713 /* Function Declarations */
13714 /*************************/
13715 void proto_register_zbee_zcl_gp(void);
13716 void proto_reg_handoff_zbee_zcl_gp(void);
13717 
13718 static dissector_handle_t zgp_handle;
13719 
13720 
13721 /**
13722  *      dissect_zbee_zcl_gp_payload
13723  *
13724  *      ZigBee ZCL Green Power data payload cluster dissector for wireshark.
13725  *
13726  *      @param tvb    - pointer to buffer containing raw packet.
13727  *      @param pinfo  - pointer to packet information fields
13728  *      @param tree   - pointer to data tree Wireshark uses to display packet.
13729  *      @param offset - offset in a buffer
13730  *
13731  *      @return new offset.
13732  */
13733 static int
dissect_zbee_zcl_gp_payload(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint offset)13734 dissect_zbee_zcl_gp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
13735 {
13736     guint             payload_size;
13737 
13738     proto_tree_add_item(tree, hf_zbee_gp_gpd_command_id, tvb, offset, 1, ENC_NA);
13739     offset += 1;
13740 
13741     payload_size = tvb_get_guint8(tvb, offset);
13742     proto_tree_add_item(tree, hf_zbee_gp_gpd_payload_size, tvb, offset, 1, ENC_NA);
13743     offset += 1;
13744 
13745     if (payload_size != 0 && payload_size != 0xff) {
13746         tvbuff_t *gtvb = tvb_new_composite();
13747         gboolean writable = col_get_writable(pinfo->cinfo, COL_INFO);
13748 
13749         /* remove payload length and put command id instead */
13750         tvb_composite_append(gtvb, tvb_new_subset_length(tvb, offset-2, 1));
13751         tvb_composite_append(gtvb, tvb_new_subset_length(tvb, offset, payload_size));
13752         tvb_composite_finalize(gtvb);
13753         /* prevent overwriting COL_INFO */
13754         col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
13755         call_dissector_only(zgp_handle, gtvb, pinfo, tree, NULL);
13756         col_set_writable(pinfo->cinfo, COL_INFO, writable);
13757         offset += payload_size;
13758     }
13759     return offset;
13760 }
13761 
13762 /**
13763  *      dissect_zbee_zcl_gp_group_list
13764  *
13765  *      ZigBee ZCL Green Power Group List dissector for wireshark.
13766  *
13767  *      @param tvb    - pointer to buffer containing raw packet.
13768  *      @param tree   - pointer to data tree Wireshark uses to display packet.
13769  *      @param offset - offset in a buffer
13770  *      @param text   - string attached to Group list subtree
13771  *      @return new offset.
13772  */
13773 static int
dissect_zbee_zcl_gp_group_list(tvbuff_t * tvb,proto_tree * tree,guint offset,const char * text)13774 dissect_zbee_zcl_gp_group_list(tvbuff_t *tvb, proto_tree *tree, guint offset, const char* text)
13775 {
13776     guint8 len = tvb_get_guint8(tvb, offset);
13777     proto_tree *gl_tree  = proto_tree_add_subtree_format(tree, tvb, offset, len*4+1,
13778                                ett_zbee_zcl_gp_group_list, NULL, "%s #%d", text, len);
13779 
13780     proto_tree_add_item(gl_tree, hf_zbee_gp_group_list_len, tvb, offset, 1, ENC_NA);
13781     offset += 1;
13782     while (len) {
13783         proto_tree_add_item(gl_tree, hf_zbee_gp_group_list_group_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
13784         offset += 2;
13785         proto_tree_add_item(gl_tree, hf_zbee_gp_group_list_alias, tvb, offset, 2, ENC_LITTLE_ENDIAN);
13786         offset += 2;
13787         len--;
13788     }
13789 
13790     return offset;
13791 } /*dissect_zbee_zcl_gp_group_list*/
13792 
13793 /**
13794  *      dissect_zbee_zcl_gp_sink_address_list
13795  *
13796  *      ZigBee ZCL Green Power Sink Address List dissector for wireshark.
13797  *
13798  *      @param tvb    - pointer to buffer containing raw packet.
13799  *      @param tree   - pointer to data tree Wireshark uses to display packet.
13800  *      @param offset - offset in a buffer
13801  *      @param text   - string attached to Sink Address list subtree
13802  *      @return new offset.
13803  */
13804 static int
dissect_zbee_zcl_gp_sink_address_list(tvbuff_t * tvb,proto_tree * tree,guint offset,const char * text)13805 dissect_zbee_zcl_gp_sink_address_list(tvbuff_t *tvb, proto_tree *tree, guint offset, const char* text)
13806 {
13807     guint8 len = tvb_get_guint8(tvb, offset);
13808     proto_tree *subtree  = proto_tree_add_subtree_format(tree, tvb, offset, len*10+1,
13809                                ett_zbee_gp_sink_address_list, NULL, "%s #%d", text, len);
13810 
13811     proto_tree_add_item(subtree, hf_zbee_gp_sink_address_list_length, tvb, offset, 1, ENC_NA);
13812     offset += 1;
13813     while (len) {
13814         proto_tree_add_item(subtree, hf_zbee_gp_sink_ieee, tvb, offset, 8, ENC_LITTLE_ENDIAN);
13815         offset += 8;
13816         proto_tree_add_item(subtree, hf_zbee_gp_sink_nwk, tvb, offset, 2, ENC_LITTLE_ENDIAN);
13817         offset += 2;
13818         len--;
13819     }
13820 
13821     return offset;
13822 } /*dissect_zbee_zcl_gp_sink_address_list*/
13823 
13824 /**
13825  *      dissect_zbee_zcl_gp_sink_table_entry
13826  *
13827  *      ZigBee ZCL Green Power Sink Table entry dissector for wireshark.
13828  *
13829  *      @param tvb    - pointer to buffer containing raw packet.
13830  *      @param tree   - pointer to data tree Wireshark uses to display packet.
13831  *      @param offset - offset in a buffer
13832  *      @param idx    - entry index
13833  *
13834  *      @return 1 if entry parsed, 0 - otherwise.
13835  */
13836 static int
dissect_zbee_zcl_gp_sink_table_entry(tvbuff_t * tvb,proto_tree * tree,guint * offset,guint idx)13837 dissect_zbee_zcl_gp_sink_table_entry(tvbuff_t *tvb, proto_tree *tree, guint *offset, guint idx)
13838 {
13839     guint16 options = 0;
13840     guint16 app_id, comm_mode;
13841     proto_tree *subtree;
13842     static int * const n_options[] = {
13843         &hf_zbee_gp_sink_tbl_entry_options_app_id,
13844         &hf_zbee_gp_sink_tbl_entry_options_comm_mode,
13845         &hf_zbee_gp_sink_tbl_entry_options_seq_num_cap,
13846         &hf_zbee_gp_sink_tbl_entry_options_rx_on_cap,
13847         &hf_zbee_gp_sink_tbl_entry_options_fixed_loc,
13848         &hf_zbee_gp_sink_tbl_entry_options_assigned_alias,
13849         &hf_zbee_gp_sink_tbl_entry_options_sec_use,
13850         NULL
13851     };
13852     static int * const n_secur_options[] = {
13853         &hf_zbee_gp_sec_options_sec_level,
13854         &hf_zbee_gp_sec_options_sec_key_type,
13855         NULL
13856     };
13857 
13858     subtree = proto_tree_add_subtree_format(tree, tvb, *offset, -1, ett_zbee_gp_sink_tbl_entry,
13859                                             NULL, "Sink Table Entry #%d", idx);
13860 
13861     /* Options - 2 bytes */
13862     options = tvb_get_guint16(tvb, *offset, ENC_LITTLE_ENDIAN);
13863     proto_tree_add_bitmask(subtree, tvb, *offset, hf_zbee_gp_sink_tbl_entry_options,
13864                            ett_zbee_gp_sink_tbl_entry_options, n_options, ENC_LITTLE_ENDIAN);
13865     *offset += 2;
13866 
13867     app_id = (options & ZBEE_ZCL_GP_SINK_TBL_OPT_APP_ID) >> ws_ctz(ZBEE_ZCL_GP_SINK_TBL_OPT_APP_ID);
13868     switch (app_id) {
13869         case ZBEE_ZCL_GP_APP_ID_DEFAULT:
13870             /* Add 4 byte SRC ID */
13871             proto_tree_add_item(subtree, hf_zbee_gp_src_id, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
13872             *offset += 4;
13873             break;
13874         case ZBEE_ZCL_GP_APP_ID_ZGP:
13875             /* Add IEEE address and endpoint (9 bytes) */
13876             proto_tree_add_item(subtree, hf_zbee_gp_ieee, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
13877             *offset += 8;
13878             proto_tree_add_item(subtree, hf_zbee_gp_endpoint, tvb, *offset, 1, ENC_NA);
13879             *offset += 1;
13880             break;
13881         default:
13882             /* Bad entry - stop Sink Table Entry parsing */
13883             return 0;
13884     }
13885 
13886     /* Device ID - 1 byte */
13887     proto_tree_add_item(subtree, hf_zbee_gp_device_id, tvb, *offset, 1, ENC_NA);
13888     *offset += 1;
13889 
13890     /* Group list */
13891     comm_mode = (options & ZBEE_ZCL_GP_SINK_TBL_OPT_COMMUNICATION_MODE) >>
13892         ws_ctz(ZBEE_ZCL_GP_SINK_TBL_OPT_COMMUNICATION_MODE);
13893     if (comm_mode == ZBEE_ZCL_GP_COMMUNICATION_MODE_GROUPCAST_PRECOMMISSIONED) {
13894         *offset = dissect_zbee_zcl_gp_group_list(tvb, subtree, *offset, "GroupList");
13895     }
13896 
13897     /* GPD Assigned Alias: 2 bytes */
13898     if (options & ZBEE_ZCL_GP_SINK_TBL_OPT_ASSIGNED_ALIAS) {
13899         proto_tree_add_item(subtree, hf_zbee_gp_assigned_alias, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
13900         *offset += 2;
13901     }
13902 
13903     /* Groupcast radius: 1 byte */
13904     proto_tree_add_item(subtree, hf_zbee_gp_groupcast_radius, tvb, *offset, 1, ENC_NA);
13905     *offset += 1;
13906 
13907     /* Security options: 1 byte */
13908     if (options & ZBEE_ZCL_GP_SINK_TBL_OPT_SECURITY_USE) {
13909         proto_tree_add_bitmask(subtree, tvb, *offset, hf_zbee_gp_sec_options,
13910                                ett_zbee_gp_sec_options, n_secur_options, ENC_NA);
13911         *offset += 1;
13912     }
13913 
13914     /* GPD Frame Counter: 4 bytes */
13915     if ((options & ZBEE_ZCL_GP_SINK_TBL_OPT_SECURITY_USE) || (options & ZBEE_ZCL_GP_SINK_TBL_OPT_SEQ_NUMBER_CAP)) {
13916         proto_tree_add_item(subtree, hf_zbee_gp_secur_frame_counter, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
13917         *offset += 4;
13918     }
13919 
13920     /* GPD key: 16 bytes */
13921     if (options & ZBEE_ZCL_GP_SINK_TBL_OPT_SECURITY_USE) {
13922       proto_tree_add_item(subtree, hf_zbee_gp_gpd_key, tvb, *offset, 16, ENC_NA);
13923       *offset += 16;
13924     }
13925 
13926     return 1;
13927 }
13928 
13929 /**
13930  *      dissect_zbee_zcl_gp_sink_table
13931  *
13932  *      ZigBee ZCL Green Power Sink Table dissector for wireshark.
13933  *
13934  *      @param tvb    - pointer to buffer containing raw packet.
13935  *      @param tree   - pointer to data tree Wireshark uses to display packet.
13936  *      @param offset - offset in a buffer
13937  *
13938  *      @return new offset.
13939  */
13940 static int
dissect_zbee_zcl_gp_sink_table(tvbuff_t * tvb,proto_tree * tree,guint offset)13941 dissect_zbee_zcl_gp_sink_table(tvbuff_t *tvb, proto_tree *tree, guint offset)
13942 {
13943     guint16 sink_tbl_len, n_parsed_octets;
13944     guint8 n_tbl_entries;
13945     proto_tree *sink_tbl_tree;
13946 
13947     n_parsed_octets = 0;
13948     n_tbl_entries = 0;
13949     sink_tbl_len = tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN);
13950 
13951     sink_tbl_tree = proto_tree_add_subtree_format(tree, tvb, offset, sink_tbl_len,
13952                          ett_zbee_gp_sink_tbl, NULL, "Sink Table: length = %d", sink_tbl_len);
13953     proto_tree_add_item(sink_tbl_tree, hf_zbee_gp_sink_tbl_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
13954     offset += 2;
13955     if (sink_tbl_len == 0) {
13956         return offset;
13957     }
13958 
13959     while (n_parsed_octets < sink_tbl_len) {
13960         guint old_offset = offset;
13961         if (dissect_zbee_zcl_gp_sink_table_entry(tvb, sink_tbl_tree, &offset, n_tbl_entries + 1)) {
13962             n_parsed_octets += offset - old_offset;
13963         }
13964         else {
13965             /* Bad Sink Table Entry - stop Sink Table attribute dissection */
13966             break;
13967         }
13968 
13969         ++n_tbl_entries;
13970     }
13971 
13972     return offset;
13973 } /*dissect_zbee_zcl_gp_sink_table*/
13974 
13975 /**
13976  *      dissect_zbee_zcl_gp_proxy_table_entry
13977  *
13978  *      ZigBee ZCL Green Power Proxy Table entry dissector for wireshark.
13979  *
13980  *      @param tvb    - pointer to buffer containing raw packet.
13981  *      @param tree   - pointer to data tree Wireshark uses to display packet.
13982  *      @param offset - offset in a buffer
13983  *      @param idx    - entry index
13984  *
13985  *      @return 1 if entry parsed, 0 - otherwise.
13986  */
13987 static int
dissect_zbee_zcl_gp_proxy_table_entry(tvbuff_t * tvb,proto_tree * tree,guint * offset,guint idx)13988 dissect_zbee_zcl_gp_proxy_table_entry(tvbuff_t *tvb, proto_tree *tree, guint *offset, guint idx)
13989 {
13990     guint16 options = 0;
13991     guint16 ext_options = 0;
13992     guint16 app_id;
13993     proto_tree *subtree;
13994     static int * const n_options[] = {
13995         &hf_zbee_gp_proxy_tbl_entry_options_app_id,
13996         &hf_zbee_gp_proxy_tbl_entry_options_entry_active,
13997         &hf_zbee_gp_proxy_tbl_entry_options_entry_valid,
13998         &hf_zbee_gp_proxy_tbl_entry_options_seq_num_cap,
13999         &hf_zbee_gp_proxy_tbl_entry_options_lw_ucast_gps,
14000         &hf_zbee_gp_proxy_tbl_entry_options_derived_group_gps,
14001         &hf_zbee_gp_proxy_tbl_entry_options_comm_group_gps,
14002         &hf_zbee_gp_proxy_tbl_entry_options_first_to_forward,
14003         &hf_zbee_gp_proxy_tbl_entry_options_in_range,
14004         &hf_zbee_gp_proxy_tbl_entry_options_gpd_fixed,
14005         &hf_zbee_gp_proxy_tbl_entry_options_has_all_ucast_routes,
14006         &hf_zbee_gp_proxy_tbl_entry_options_assigned_alias,
14007         &hf_zbee_gp_proxy_tbl_entry_options_sec_use,
14008         &hf_zbee_gp_proxy_tbl_entry_options_opt_ext,
14009         NULL
14010     };
14011     static int * const n_ext_options[] = {
14012         &hf_zbee_gp_proxy_tbl_entry_ext_options_full_ucast_gps,
14013         NULL
14014     };
14015     static int * const n_secur_options[] = {
14016         &hf_zbee_gp_sec_options_sec_level,
14017         &hf_zbee_gp_sec_options_sec_key_type,
14018         NULL
14019     };
14020 
14021     subtree = proto_tree_add_subtree_format(tree, tvb, *offset, -1,
14022                   ett_zbee_gp_proxy_tbl_entry, NULL, "Proxy Table Entry #%d", idx);
14023 
14024     /* Options - 2 bytes */
14025     options = tvb_get_guint16(tvb, *offset, ENC_LITTLE_ENDIAN);
14026     proto_tree_add_bitmask(subtree, tvb, *offset, hf_zbee_gp_proxy_tbl_entry_options,
14027                            ett_zbee_gp_proxy_tbl_entry_options, n_options, ENC_LITTLE_ENDIAN);
14028     *offset += 2;
14029 
14030     app_id = (options & ZBEE_ZCL_GP_PROXY_TBL_OPT_APP_ID) >> ws_ctz(ZBEE_ZCL_GP_PROXY_TBL_OPT_APP_ID);
14031     switch (app_id) {
14032         case ZBEE_ZCL_GP_APP_ID_DEFAULT:
14033             /* Add 4 byte SRC ID */
14034             proto_tree_add_item(subtree, hf_zbee_gp_src_id, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
14035             *offset += 4;
14036             break;
14037         case ZBEE_ZCL_GP_APP_ID_ZGP:
14038             /* Add IEEE address and endpoint (9 bytes) */
14039             proto_tree_add_item(subtree, hf_zbee_gp_ieee, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
14040             *offset += 8;
14041             proto_tree_add_item(subtree, hf_zbee_gp_endpoint, tvb, *offset, 1, ENC_NA);
14042             *offset += 1;
14043             break;
14044         default:
14045             /* Bad entry - stop Proxy Table entry parsing */
14046             return 0;
14047     }
14048 
14049 
14050     /* Assigned Alias - 2 bytes */
14051     if (options & ZBEE_ZCL_GP_PROXY_TBL_OPT_ASSIGNED_ALIAS) {
14052         proto_tree_add_item(subtree, hf_zbee_gp_assigned_alias, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
14053         *offset += 2;
14054     }
14055 
14056     /* Security Options - 1 byte */
14057     if (options & ZBEE_ZCL_GP_PROXY_TBL_OPT_SECURITY_USE) {
14058         proto_tree_add_bitmask(subtree, tvb, *offset, hf_zbee_gp_sec_options,
14059                                ett_zbee_gp_sec_options, n_secur_options, ENC_NA);
14060         *offset += 1;
14061     }
14062 
14063     /* GPD Frame Counter: 4 bytes */
14064     if ((options & ZBEE_ZCL_GP_PROXY_TBL_OPT_SECURITY_USE) || (options & ZBEE_ZCL_GP_PROXY_TBL_OPT_SEQ_NUMBER_CAP)) {
14065         proto_tree_add_item(subtree, hf_zbee_gp_secur_frame_counter, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
14066         *offset += 4;
14067     }
14068 
14069     /* GPD key: 16 bytes */
14070     if (options & ZBEE_ZCL_GP_PROXY_TBL_OPT_SECURITY_USE) {
14071       proto_tree_add_item(subtree, hf_zbee_gp_gpd_key, tvb, *offset, 16, ENC_NA);
14072       *offset += 16;
14073     }
14074 
14075     if (options & ZBEE_ZCL_GP_PROXY_TBL_OPT_LW_UCAST_GPS) {
14076         *offset = dissect_zbee_zcl_gp_sink_address_list(tvb, subtree, *offset, "Lightweight Sink Address list");
14077     }
14078 
14079     /* Sink Group list */
14080     if (options & ZBEE_ZCL_GP_PROXY_TBL_OPT_COMM_GROUP_GPS) {
14081         *offset = dissect_zbee_zcl_gp_group_list(tvb, subtree, *offset, "Sink GroupList");
14082     }
14083 
14084     /* Groupcast radius: 1 byte */
14085     proto_tree_add_item(subtree, hf_zbee_gp_groupcast_radius, tvb, *offset, 1, ENC_NA);
14086     *offset += 1;
14087 
14088     /* Search Counter: 1 byte */
14089     if (!(options & ZBEE_ZCL_GP_PROXY_TBL_OPT_ENTRY_ACTIVE) || !(options & ZBEE_ZCL_GP_PROXY_TBL_OPT_ENTRY_VALID)) {
14090         proto_tree_add_item(subtree, hf_zbee_gp_proxy_tbl_entry_search_counter, tvb, *offset, 1, ENC_NA);
14091         *offset += 1;
14092     }
14093 
14094     /* Extended Options: 2 bytes */
14095     if (options & ZBEE_ZCL_GP_PROXY_TBL_OPT_OPTIONS_EXTENTIONS) {
14096       ext_options = tvb_get_guint16(tvb, *offset, ENC_LITTLE_ENDIAN);
14097       proto_tree_add_bitmask(subtree, tvb, *offset, hf_zbee_gp_proxy_tbl_entry_ext_options,
14098                              ett_zbee_gp_proxy_tbl_entry_ext_options, n_ext_options, ENC_LITTLE_ENDIAN);
14099       *offset += 1;
14100     }
14101 
14102     /* Full unicast sink address list */
14103     if (ext_options & ZBEE_ZCL_GP_PROXY_TBL_EXT_OPT_FULL_UCAST_GPS) {
14104         *offset = dissect_zbee_zcl_gp_sink_address_list(tvb, subtree, *offset, "Full unicast Sink Address list");
14105     }
14106 
14107     return 1;
14108 }
14109 
14110 /**
14111  *      dissect_zbee_zcl_gp_proxy_table
14112  *
14113  *      ZigBee ZCL Green Power Proxy Table dissector for wireshark.
14114  *
14115  *      @param tvb    - pointer to buffer containing raw packet.
14116  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14117  *      @param offset - offset in a buffer
14118  *
14119  *      @return new offset.
14120  */
14121 static int
dissect_zbee_zcl_gp_proxy_table(tvbuff_t * tvb,proto_tree * tree,guint offset)14122 dissect_zbee_zcl_gp_proxy_table(tvbuff_t *tvb, proto_tree *tree, guint offset)
14123 {
14124     guint16 proxy_tbl_len, n_parsed_octets;
14125     guint8 n_tbl_entries;
14126     proto_tree *proxy_tbl_tree;
14127 
14128     n_parsed_octets = 0;
14129     n_tbl_entries = 0;
14130     proxy_tbl_len = tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN);
14131 
14132     proxy_tbl_tree = proto_tree_add_subtree_format(tree, tvb, offset, proxy_tbl_len,
14133                          ett_zbee_gp_proxy_tbl, NULL, "Proxy Table: length = %d", proxy_tbl_len);
14134     proto_tree_add_item(proxy_tbl_tree, hf_zbee_gp_proxy_tbl_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14135     offset += 2;
14136     if (proxy_tbl_len == 0) {
14137         return offset;
14138     }
14139 
14140     while (n_parsed_octets < proxy_tbl_len) {
14141         guint old_offset = offset;
14142         if (dissect_zbee_zcl_gp_proxy_table_entry(tvb, proxy_tbl_tree, &offset, n_tbl_entries + 1)) {
14143             n_parsed_octets += offset - old_offset;
14144         }
14145         else {
14146             /* Bad Proxy Table entry - stop Proxy Table attribute dissection */
14147             break;
14148         }
14149 
14150         ++n_tbl_entries;
14151     }
14152 
14153     return offset;
14154 } /*dissect_zbee_zcl_gp_proxy_table*/
14155 
14156 /**
14157  *      dissect_zbee_zcl_gp_attr_gpp_functionality
14158  *
14159  *      ZigBee ZCL Green Power gppFunctionality dissector for wireshark.
14160  *
14161  *      @param tvb    - pointer to buffer containing raw packet.
14162  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14163  *      @param offset - offset in a buffer
14164  *
14165  *      @return new offset.
14166  */
14167 static int
dissect_zbee_zcl_gp_attr_gpp_functionality(tvbuff_t * tvb,proto_tree * tree,guint offset)14168 dissect_zbee_zcl_gp_attr_gpp_functionality(tvbuff_t *tvb, proto_tree *tree, guint offset)
14169 {
14170     static int * const n_fields[] = {
14171         &hf_zbee_zcl_gp_attr_gpp_func_fld_gp_feature,
14172         &hf_zbee_zcl_gp_attr_gpp_func_fld_direct_comm,
14173         &hf_zbee_zcl_gp_attr_gpp_func_fld_derived_gcast_comm,
14174         &hf_zbee_zcl_gp_attr_gpp_func_fld_pre_commissioned_gcast_comm,
14175         &hf_zbee_zcl_gp_attr_gpp_func_fld_full_ucast_comm,
14176         &hf_zbee_zcl_gp_attr_gpp_func_fld_lw_ucast_comm,
14177         &hf_zbee_zcl_gp_attr_gpp_func_fld_bidir_op,
14178         &hf_zbee_zcl_gp_attr_gpp_func_fld_proxy_tbl_maintenance,
14179         &hf_zbee_zcl_gp_attr_gpp_func_fld_gp_commissioning,
14180         &hf_zbee_zcl_gp_attr_gpp_func_fld_ct_based_commissioning,
14181         &hf_zbee_zcl_gp_attr_gpp_func_fld_maintenance_of_gpd,
14182         &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_00,
14183         &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_01,
14184         &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_10,
14185         &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_11,
14186         &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_ieee_address,
14187         NULL
14188     };
14189 
14190     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_gp_attr_gpp_func,
14191                            ett_zbee_zcl_gp_attr_gpp_func, n_fields, ENC_LITTLE_ENDIAN);
14192     offset += 3;
14193 
14194     return offset;
14195 } /*dissect_zbee_zcl_gp_attr_gpp_functionality*/
14196 
14197 /**
14198  *      dissect_zbee_zcl_gp_attr_gpp_active_functionality
14199  *
14200  *      ZigBee ZCL Green Power gppActiveFunctionality dissector for wireshark.
14201  *
14202  *      @param tvb    - pointer to buffer containing raw packet.
14203  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14204  *      @param offset - offset in a buffer
14205  *
14206  *      @return new offset.
14207  */
14208 static int
dissect_zbee_zcl_gp_attr_gpp_active_functionality(tvbuff_t * tvb,proto_tree * tree,guint offset)14209 dissect_zbee_zcl_gp_attr_gpp_active_functionality(tvbuff_t *tvb, proto_tree *tree, guint offset)
14210 {
14211     static int * const n_fields[] = {
14212         &hf_zbee_zcl_gp_attr_gpp_active_func_fld_gp_functionality,
14213         NULL
14214     };
14215 
14216     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_gp_attr_gpp_active_func,
14217                            ett_zbee_zcl_gp_attr_gpp_active_func, n_fields, ENC_LITTLE_ENDIAN);
14218     offset += 3;
14219 
14220     return offset;
14221 } /*dissect_zbee_zcl_gp_attr_gpp_active_functionality*/
14222 
14223 /**
14224  *      dissect_zbee_zcl_gp_attr_gps_functionality
14225  *
14226  *      ZigBee ZCL Green Power gpsFunctionality dissector for wireshark.
14227  *
14228  *      @param tvb    - pointer to buffer containing raw packet.
14229  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14230  *      @param offset - offset in a buffer
14231  *
14232  *      @return new offset.
14233  */
14234 static int
dissect_zbee_zcl_gp_attr_gps_functionality(tvbuff_t * tvb,proto_tree * tree,guint offset)14235 dissect_zbee_zcl_gp_attr_gps_functionality(tvbuff_t *tvb, proto_tree *tree, guint offset)
14236 {
14237     static int * const n_fields[] = {
14238         &hf_zbee_zcl_gp_attr_gps_func_fld_gp_feature,
14239         &hf_zbee_zcl_gp_attr_gps_func_fld_direct_comm,
14240         &hf_zbee_zcl_gp_attr_gps_func_fld_derived_gcast_comm,
14241         &hf_zbee_zcl_gp_attr_gps_func_fld_pre_commissioned_gcast_comm,
14242         &hf_zbee_zcl_gp_attr_gps_func_fld_full_ucast_comm,
14243         &hf_zbee_zcl_gp_attr_gps_func_fld_lw_ucast_comm,
14244         &hf_zbee_zcl_gp_attr_gps_func_fld_proximity_bidir_op,
14245         &hf_zbee_zcl_gp_attr_gps_func_fld_multi_hop_bidir_op,
14246         &hf_zbee_zcl_gp_attr_gps_func_fld_proxy_tbl_maintenance,
14247         &hf_zbee_zcl_gp_attr_gps_func_fld_proximity_commissioning,
14248         &hf_zbee_zcl_gp_attr_gps_func_fld_multi_hop_commissioning,
14249         &hf_zbee_zcl_gp_attr_gps_func_fld_ct_based_commissioning,
14250         &hf_zbee_zcl_gp_attr_gps_func_fld_maintenance_of_gpd,
14251         &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_00,
14252         &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_01,
14253         &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_10,
14254         &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_11,
14255         &hf_zbee_zcl_gp_attr_gps_func_fld_sink_tbl_based_gcast_forwarding,
14256         &hf_zbee_zcl_gp_attr_gps_func_fld_translation_table,
14257         &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_ieee_address,
14258         NULL
14259     };
14260 
14261     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_gp_attr_gps_func,
14262                            ett_zbee_zcl_gp_attr_gps_func, n_fields, ENC_LITTLE_ENDIAN);
14263     offset += 3;
14264 
14265     return offset;
14266 } /*dissect_zbee_zcl_gp_attr_gps_functionality*/
14267 
14268 /**
14269  *      dissect_zbee_zcl_gp_attr_gps_active_functionality
14270  *
14271  *      ZigBee ZCL Green Power gpsActiveFunctionality dissector for wireshark.
14272  *
14273  *      @param tvb    - pointer to buffer containing raw packet.
14274  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14275  *      @param offset - offset in a buffer
14276  *
14277  *      @return new offset.
14278  */
14279 static int
dissect_zbee_zcl_gp_attr_gps_active_functionality(tvbuff_t * tvb,proto_tree * tree,guint offset)14280 dissect_zbee_zcl_gp_attr_gps_active_functionality(tvbuff_t *tvb, proto_tree *tree, guint offset)
14281 {
14282     static int * const n_fields[] = {
14283         &hf_zbee_zcl_gp_attr_gps_active_func_fld_gp_functionality,
14284         NULL
14285     };
14286 
14287     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_gp_attr_gps_active_func,
14288                            ett_zbee_zcl_gp_attr_gps_active_func, n_fields, ENC_LITTLE_ENDIAN);
14289     offset += 3;
14290 
14291     return offset;
14292 } /*dissect_zbee_zcl_gp_attr_gps_active_functionality*/
14293 
14294 /**
14295  *      dissect_zbee_zcl_gp_attr_gps_communication_mode
14296  *
14297  *      ZigBee ZCL Green Power gpsCommunicationMode dissector for wireshark.
14298  *
14299  *      @param tvb    - pointer to buffer containing raw packet.
14300  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14301  *      @param offset - offset in a buffer
14302  *
14303  *      @return new offset.
14304  */
14305 static int
dissect_zbee_zcl_gp_attr_gps_communication_mode(tvbuff_t * tvb,proto_tree * tree,guint offset)14306 dissect_zbee_zcl_gp_attr_gps_communication_mode(tvbuff_t *tvb, proto_tree *tree, guint offset)
14307 {
14308     static int * const n_fields[] = {
14309         &hf_zbee_zcl_gp_attr_gps_communication_mode_fld_mode,
14310         NULL
14311     };
14312 
14313     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_gp_attr_gps_communication_mode,
14314                            ett_zbee_zcl_gp_attr_gps_communication_mode, n_fields, ENC_NA);
14315     offset += 1;
14316 
14317     return offset;
14318 } /*dissect_zbee_zcl_gp_attr_gps_communication_mode*/
14319 
14320 /**
14321  *      dissect_zbee_zcl_gp_attr_gps_comm_exit_mode
14322  *
14323  *      ZigBee ZCL Green Power gpsCommissioningExitMode dissector for wireshark.
14324  *
14325  *      @param tvb    - pointer to buffer containing raw packet.
14326  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14327  *      @param offset - offset in a buffer
14328  *
14329  *      @return new offset.
14330  */
14331 static int
dissect_zbee_zcl_gp_attr_gps_comm_exit_mode(tvbuff_t * tvb,proto_tree * tree,guint offset)14332 dissect_zbee_zcl_gp_attr_gps_comm_exit_mode(tvbuff_t *tvb, proto_tree *tree, guint offset)
14333 {
14334     static int * const n_fields[] = {
14335         &hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_comm_window_expire,
14336         &hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_pairing_success,
14337         &hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_gp_proxy_comm_mode,
14338         NULL
14339     };
14340 
14341     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_gp_attr_gps_comm_exit_mode,
14342                            ett_zbee_zcl_gp_attr_gps_comm_exit_mode, n_fields, ENC_NA);
14343     offset += 1;
14344 
14345     return offset;
14346 } /*dissect_zbee_zcl_gp_attr_gps_comm_exit_mode*/
14347 
14348 /**
14349  *      dissect_zbee_zcl_gp_attr_gps_secur_lvl
14350  *
14351  *      ZigBee ZCL Green Power gpsSecurityLevel dissector for wireshark.
14352  *
14353  *      @param tvb    - pointer to buffer containing raw packet.
14354  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14355  *      @param offset - offset in a buffer
14356  *
14357  *      @return new offset.
14358  */
14359 static int
dissect_zbee_zcl_gp_attr_gps_secur_lvl(tvbuff_t * tvb,proto_tree * tree,guint offset)14360 dissect_zbee_zcl_gp_attr_gps_secur_lvl(tvbuff_t *tvb, proto_tree *tree, guint offset)
14361 {
14362     static int * const n_fields[] = {
14363         &hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_min_gpd_secur_lvl,
14364         &hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_protection_with_gp_link_key,
14365         &hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_involve_tc,
14366         NULL
14367     };
14368 
14369     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_zcl_gp_attr_gps_secur_lvl,
14370                            ett_zbee_zcl_gp_attr_gps_secur_lvl, n_fields, ENC_NA);
14371     offset += 1;
14372 
14373     return offset;
14374 } /*dissect_zbee_zcl_gp_attr_gps_secur_lvl*/
14375 
14376 /**
14377  *      dissect_zcl_gp_proxy_sink_table_request
14378  *
14379  *      ZigBee ZCL Green Power cluster dissector for Proxy Table Request
14380  *      and Sink Table Request commands
14381  *
14382  *      @param tree      - pointer to data tree Wireshark uses to display packet.
14383  *      @param tvb       - pointer to buffer containing raw packet.
14384  *      @param offset    - pointer to buffer offset
14385  */
14386 static void
dissect_zcl_gp_proxy_sink_table_request(proto_tree * tree,tvbuff_t * tvb,guint * offset)14387 dissect_zcl_gp_proxy_sink_table_request(proto_tree *tree, tvbuff_t *tvb, guint *offset)
14388 {
14389     /* get Options field */
14390     guint8 options = tvb_get_guint8(tvb, *offset);
14391     guint8 app_id, req_type;
14392     static int * const n_options[] = {
14393         &hf_zbee_zcl_proxy_sink_tbl_req_fld_app_id,
14394         &hf_zbee_zcl_proxy_sink_tbl_req_fld_req_type,
14395         NULL
14396     };
14397 
14398     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_proxy_sink_tbl_req_options,
14399                            ett_zbee_zcl_proxy_sink_tbl_req_options, n_options, ENC_NA);
14400     *offset += 1;
14401     app_id = options & ZBEE_ZCL_GP_PROXY_SINK_TBL_REQ_CMD_APP_ID;
14402     req_type = (options & ZBEE_ZCL_GP_PROXY_SINK_TBL_REQ_CMD_REQ_TYPE) >>
14403         ZBEE_ZCL_GP_PROXY_SINK_TBL_REQ_CMD_REQ_TYPE_SHIFT;
14404     if (req_type == ZBEE_ZCL_GP_PROXY_SINK_TABLE_REQ_CMD_REQUSET_BY_GPD_ID) {
14405         /* Include GPD ID and/or Endpoint */
14406         if (app_id == ZBEE_ZCL_GP_APP_ID_DEFAULT) {
14407             /* App_id = 000: GPD SRC ID only */
14408             proto_tree_add_item(tree, hf_zbee_gp_src_id, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
14409             *offset += 4;
14410         }
14411         else if (app_id == ZBEE_ZCL_GP_APP_ID_ZGP) {
14412             /* App_id = 010: MAC address + Endoint */
14413             proto_tree_add_item(tree, hf_zbee_gp_ieee, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
14414             *offset += 8;
14415             proto_tree_add_item(tree, hf_zbee_gp_endpoint, tvb, *offset, 1, ENC_NA);
14416             *offset += 1;
14417         }
14418     }
14419     else if (req_type == ZBEE_ZCL_GP_PROXY_SINK_TABLE_REQ_CMD_REQUSET_BY_INDEX) {
14420         /* Include index only */
14421         proto_tree_add_item(tree, hf_zbee_zcl_proxy_sink_tbl_req_index, tvb, *offset, 1, ENC_NA);
14422         *offset += 1;
14423     }
14424 } /*dissect_zcl_gp_proxy_sink_table_request*/
14425 
14426 /**
14427  *      dissect_zcl_gp_proxy_sink_table_response
14428  *
14429  *      ZigBee ZCL Green Power cluster dissector for Proxy Table response
14430  *      and Sink Table Request commands
14431  *
14432  *      @param tree      - pointer to data tree Wireshark uses to display packet.
14433  *      @param tvb       - pointer to buffer containing raw packet.
14434  *      @param offset    - pointer to buffer offset
14435  *      @param attr_id   - attribute (should be ZBEE_ZCL_ATTR_GPS_SINK_TABLE or
14436  *                         ZBEE_ZCL_ATTR_GPP_PROXY_TABLE) that will be reported
14437  */
14438 static void
dissect_zcl_gp_proxy_sink_table_response(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id)14439 dissect_zcl_gp_proxy_sink_table_response(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id)
14440 {
14441     guint8 entries_count, start_index;
14442     guint i, stop;
14443 
14444     if ( !((attr_id == ZBEE_ZCL_ATTR_GPS_SINK_TABLE) || (attr_id == ZBEE_ZCL_ATTR_GPP_PROXY_TABLE)) ) {
14445         return;
14446     }
14447 
14448     proto_tree_add_item(tree, hf_zbee_zcl_proxy_sink_tbl_resp_status, tvb, *offset, 1, ENC_NA);
14449     *offset += 1;
14450     proto_tree_add_item(tree, hf_zbee_zcl_proxy_sink_tbl_resp_entries_total, tvb, *offset, 1, ENC_NA);
14451     *offset += 1;
14452     start_index = tvb_get_guint8(tvb, *offset);
14453     proto_tree_add_item(tree, hf_zbee_zcl_proxy_sink_tbl_resp_start_index, tvb, *offset, 1, ENC_NA);
14454     *offset += 1;
14455     entries_count = tvb_get_guint8(tvb, *offset);
14456     proto_tree_add_item(tree, hf_zbee_zcl_proxy_sink_tbl_resp_entries_count, tvb, *offset, 1, ENC_NA);
14457     *offset += 1;
14458 
14459     for (i = 0, stop = 0; i < entries_count && !stop; i++) {
14460         switch (attr_id) {
14461             case ZBEE_ZCL_ATTR_GPS_SINK_TABLE:
14462                 stop = !dissect_zbee_zcl_gp_sink_table_entry(tvb, tree, (guint*) offset, start_index + i);
14463                 break;
14464             case ZBEE_ZCL_ATTR_GPP_PROXY_TABLE:
14465                 stop = !dissect_zbee_zcl_gp_proxy_table_entry(tvb, tree, (guint*) offset, start_index + i);
14466                 break;
14467         }
14468     }
14469 } /*dissect_zcl_gp_proxy_sink_table_response*/
14470 
14471 /**
14472  *      dissect_zcl_gp_sink_comm_mode
14473  *
14474  *      ZigBee ZCL Green Power cluster dissector for Sink Commissioning Mode
14475  *      and Sink Table Request commands
14476  *
14477  *      @param tree      - pointer to data tree Wireshark uses to display packet.
14478  *      @param tvb       - pointer to buffer containing raw packet.
14479  *      @param offset    - pointer to buffer offset
14480  */
14481 static void
dissect_zcl_gp_sink_comm_mode(proto_tree * tree,tvbuff_t * tvb,guint * offset)14482 dissect_zcl_gp_sink_comm_mode(proto_tree *tree, tvbuff_t *tvb, guint *offset)
14483 {
14484     static int * const n_options[] = {
14485         &hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_action,
14486         &hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_gpm_in_secur,
14487         &hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_gpm_in_pairing,
14488         &hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_proxies,
14489         NULL
14490     };
14491 
14492     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_gp_cmd_sink_comm_mode_options,
14493                            ett_zbee_zcl_gp_cmd_sink_comm_mode_options, n_options, ENC_NA);
14494     *offset += 1;
14495     proto_tree_add_item(tree, hf_zbee_gp_zcl_cmd_sink_comm_mode_gpm_addr_for_secur, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
14496     *offset += 2;
14497     proto_tree_add_item(tree, hf_zbee_gp_zcl_cmd_sink_comm_mode_gpm_addr_for_pairing, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
14498     *offset += 2;
14499     proto_tree_add_item(tree, hf_zbee_gp_zcl_cmd_sink_comm_mode_sink_ep, tvb, *offset, 1, ENC_NA);
14500     *offset += 1;
14501 } /*dissect_zcl_gp_sink_comm_mode*/
14502 
14503 /**
14504  *      dissect_zbee_zcl_gp
14505  *
14506  *      ZigBee ZCL Green Power cluster dissector for wireshark.
14507  *
14508  *      @param tvb    - pointer to buffer containing raw packet.
14509  *      @param pinfo  - pointer to packet information fields
14510  *      @param tree   - pointer to data tree Wireshark uses to display packet.
14511  *      @param data   - pointer to ZCL packet structure.
14512  *
14513  *      @return length of parsed data.
14514  */
14515 static int
dissect_zbee_zcl_gp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)14516 dissect_zbee_zcl_gp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
14517 {
14518     static int * const gpp_gpd_link[] = {
14519         &hf_zbee_gpp_gpd_link_rssi,
14520         &hf_zbee_gpp_gpd_link_lqi,
14521         NULL
14522     };
14523 
14524     zbee_zcl_packet   *zcl;
14525     guint             offset = 0;
14526     guint8            cmd_id;
14527 
14528     /* Reject the packet if data is NULL */
14529     if (data == NULL)
14530         return 0;
14531     zcl = (zbee_zcl_packet *)data;
14532     cmd_id = zcl->cmd_id;
14533 
14534     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
14535         /* Append the command name to the info column. */
14536         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
14537                         val_to_str_const(cmd_id, zbee_zcl_gp_srv_rx_cmd_names, "Unknown Command"),
14538                         zcl->tran_seqno);
14539 
14540         /* Add the command ID. */
14541         proto_tree_add_item(tree, hf_zbee_zcl_gp_srv_rx_cmd_id, tvb, offset, 1, ENC_NA);
14542         offset++;
14543 
14544         /* Handle the command dissection. */
14545         switch (cmd_id) {
14546             case ZBEE_CMD_ID_GP_NOTIFICATION:
14547             {
14548                 static int * const n_options[] = {
14549                     &hf_zbee_gp_cmd_notif_opt_app_id,
14550                     &hf_zbee_gp_cmd_notif_opt_also_unicast,
14551                     &hf_zbee_gp_cmd_notif_opt_also_derived_group,
14552                     &hf_zbee_gp_cmd_notif_opt_also_comm_group,
14553                     &hf_zbee_gp_cmd_notif_opt_secur_level,
14554                     &hf_zbee_gp_cmd_notif_opt_secur_key_type,
14555                     &hf_zbee_gp_cmd_notif_opt_rx_after_tx,
14556                     &hf_zbee_gp_cmd_notif_opt_tx_q_full,
14557                     &hf_zbee_gp_cmd_notif_opt_bidir_cap,
14558                     &hf_zbee_gp_cmd_notif_opt_proxy_info_present,
14559                     NULL
14560                 };
14561                 guint16 options = tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN);
14562 
14563                 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_notification_options,
14564                                        ett_zbee_gp_cmd_notification_options, n_options, ENC_LITTLE_ENDIAN);
14565                 offset += 2;
14566                 if ((options & ZBEE_ZCL_GP_NOTIFICATION_OPTION_APP_ID) == 0) {
14567                     proto_tree_add_item(tree, hf_zbee_gp_src_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14568                     offset += 4;
14569                 }
14570                 else {
14571                     proto_tree_add_item(tree, hf_zbee_gp_ieee, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14572                     offset += 8;
14573                     proto_tree_add_item(tree, hf_zbee_gp_endpoint, tvb, offset, 1, ENC_NA);
14574                     offset += 1;
14575                 }
14576                 proto_tree_add_item(tree, hf_zbee_gp_secur_frame_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14577                 offset += 4;
14578 
14579                 offset = dissect_zbee_zcl_gp_payload(tvb, pinfo, tree, offset);
14580 
14581                 if (options & ZBEE_ZCL_GP_NOTIFICATION_OPTION_PROXY_INFO_PRESENT) {
14582                     proto_tree_add_item(tree, hf_zbee_gp_short_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14583                     offset += 2;
14584                     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_gpp_gpd_link,
14585                                            ett_zbee_gp_gpp_gpd_link,
14586                                            gpp_gpd_link, ENC_LITTLE_ENDIAN);
14587                     offset += 1;
14588                 }
14589                 break;
14590             }
14591 
14592             case ZBEE_CMD_ID_GP_PAIRING_SEARCH:
14593             case ZBEE_CMD_ID_GP_TUNNELING_STOP:
14594                 /* TODO: add commands parse */
14595                 break;
14596 
14597             case ZBEE_CMD_ID_GP_COMMISSIONING_NOTIFICATION:
14598             {
14599                 static int * const commn_options[] = {
14600                     &hf_zbee_gp_cmd_comm_notif_opt_app_id,
14601                     &hf_zbee_gp_cmd_comm_notif_opt_rx_after_tx,
14602                     &hf_zbee_gp_cmd_comm_notif_opt_secur_level,
14603                     &hf_zbee_gp_cmd_comm_notif_opt_secur_key_type,
14604                     &hf_zbee_gp_cmd_comm_notif_opt_secur_fail,
14605                     &hf_zbee_gp_cmd_comm_notif_opt_bidir_cap,
14606                     &hf_zbee_gp_cmd_comm_notif_opt_proxy_info_present,
14607                     NULL
14608                 };
14609                 guint16 options = tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN);
14610 
14611                 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_commissioning_notification_options,
14612                                        ett_zbee_gp_cmd_commissioning_notification_options, commn_options, ENC_LITTLE_ENDIAN);
14613                 offset += 2;
14614                 if ((options & ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_APP_ID) == 0) {
14615                     proto_tree_add_item(tree, hf_zbee_gp_src_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14616                     offset += 4;
14617                 }
14618                 else {
14619                     proto_tree_add_item(tree, hf_zbee_gp_ieee, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14620                     offset += 8;
14621                     proto_tree_add_item(tree, hf_zbee_gp_endpoint, tvb, offset, 1, ENC_NA);
14622                     offset += 1;
14623                 }
14624                 proto_tree_add_item(tree, hf_zbee_gp_secur_frame_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14625                 offset += 4;
14626 
14627                 offset = dissect_zbee_zcl_gp_payload(tvb, pinfo, tree, offset);
14628 
14629                 if (options & ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_PROXY_INFO_PRESENT) {
14630                     proto_tree_add_item(tree, hf_zbee_gp_short_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14631                     offset += 2;
14632                     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_gpp_gpd_link,
14633                                            ett_zbee_gp_gpp_gpd_link,
14634                                            gpp_gpd_link, ENC_LITTLE_ENDIAN);
14635                     offset += 1;
14636                 }
14637                 if (options & ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_SECUR_FAILED) {
14638                     proto_tree_add_item(tree, hf_zbee_gp_mic, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14639                     offset += 4;
14640                 }
14641                 break;
14642             }
14643 
14644             case ZBEE_CMD_ID_GP_PAIRING_CONFIGURATION:
14645             {
14646                 static int * const pc_actions[] = {
14647                     &hf_zbee_gp_cmd_pc_actions_action,
14648                     &hf_zbee_gp_cmd_pc_actions_send_gp_pairing,
14649                     NULL
14650                 };
14651                 static int * const pc_options[] = {
14652                     &hf_zbee_gp_cmd_pc_opt_app_id,
14653                     &hf_zbee_gp_cmd_pc_opt_communication_mode,
14654                     &hf_zbee_gp_cmd_pc_opt_seq_number_cap,
14655                     &hf_zbee_gp_cmd_px_opt_rx_on_cap,
14656                     &hf_zbee_gp_cmd_pc_opt_fixed_location,
14657                     &hf_zbee_gp_cmd_pc_opt_assigned_alias,
14658                     &hf_zbee_gp_cmd_pc_opt_security_use,
14659                     &hf_zbee_gp_cmd_pc_opt_app_info_present,
14660                     NULL
14661                 };
14662                 guint16 options;
14663 
14664                 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_pc_actions,
14665                                        ett_zbee_gp_cmd_pc_actions, pc_actions, ENC_NA);
14666                 offset += 1;
14667 
14668                 options = tvb_get_guint16(tvb, offset, ENC_LITTLE_ENDIAN);
14669 
14670                 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_pc_options,
14671                                        ett_zbee_gp_cmd_pc_options, pc_options, ENC_LITTLE_ENDIAN);
14672                 offset += 2;
14673 
14674                 if ((options & ZBEE_ZCL_GP_CMD_PC_OPT_APP_ID) == 0) {
14675                     proto_tree_add_item(tree, hf_zbee_gp_src_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14676                     offset += 4;
14677                 }
14678                 else {
14679                     proto_tree_add_item(tree, hf_zbee_gp_ieee, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14680                     offset += 8;
14681                     proto_tree_add_item(tree, hf_zbee_gp_endpoint, tvb, offset, 1, ENC_NA);
14682                     offset += 1;
14683                 }
14684 
14685                 proto_tree_add_item(tree, hf_zbee_gp_device_id, tvb, offset, 1, ENC_NA);
14686                 offset += 1;
14687 
14688                 if (((options & ZBEE_ZCL_GP_CMD_PC_OPT_COMMUNICATION_MODE) >> ZBEE_ZCL_GP_PAIRING_CONFIGURATION_OPTION_COMMUNICATION_MODE_SHIFT)
14689                     == ZBEE_ZCL_GP_COMMUNICATION_MODE_GROUPCAST_PRECOMMISSIONED) {
14690                     guint8      len = tvb_get_guint8(tvb, offset);
14691                     proto_tree  *gl_tree  = proto_tree_add_subtree_format(tree, tvb, offset, len*4+1, ett_zbee_zcl_gp_group_list, NULL, "GroupList #%d", len);
14692 
14693                     proto_tree_add_item(gl_tree, hf_zbee_gp_group_list_len, tvb, offset, 1, ENC_NA);
14694                     offset += 1;
14695                     while (len)
14696                     {
14697                         proto_tree_add_item(gl_tree, hf_zbee_gp_group_list_group_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14698                         offset += 2;
14699                         proto_tree_add_item(gl_tree, hf_zbee_gp_group_list_alias, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14700                         offset += 2;
14701                         len--;
14702                     }
14703                 }
14704 
14705                 if (options & ZBEE_ZCL_GP_CMD_PC_OPT_ASSIGNED_ALIAS) {
14706                     proto_tree_add_item(tree, hf_zbee_gp_assigned_alias, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14707                     offset += 2;
14708                 }
14709 
14710                 proto_tree_add_item(tree, hf_zbee_gp_forwarding_radius, tvb, offset, 1, ENC_NA);
14711                 offset += 1;
14712 
14713                 if (options & ZBEE_ZCL_GP_CMD_PC_OPT_SECURITY_USE) {
14714                     static int * const secur_options[] = {
14715                         &hf_zbee_gp_cmd_pc_secur_level,
14716                         &hf_zbee_gp_cmd_pc_secur_key_type,
14717                         NULL
14718                     };
14719                     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_pc_secur_options,
14720                                            ett_zbee_gp_cmd_pc_secur_options, secur_options, ENC_NA);
14721                     offset += 1;
14722                     proto_tree_add_item(tree, hf_zbee_gp_secur_frame_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14723                     offset += 4;
14724                     proto_tree_add_item(tree, hf_zbee_gp_gpd_key, tvb, offset, 16, ENC_NA);
14725                     offset += 16;
14726                 }
14727                 {
14728                     guint8 n_paired_endpoints = tvb_get_guint8(tvb, offset);
14729                     proto_tree  *ep_tree  = proto_tree_add_subtree_format(tree, tvb, offset, n_paired_endpoints+1, ett_zbee_zcl_gp_ep, NULL, "Paired Endpoints #%d", n_paired_endpoints);
14730                     proto_tree_add_item(ep_tree, hf_zbee_gp_n_paired_endpoints, tvb, offset, 1, ENC_NA);
14731                     offset += 1;
14732                     if (n_paired_endpoints != 0 && n_paired_endpoints != 0xfd
14733                         && n_paired_endpoints != 0xfe && n_paired_endpoints != 0xff)
14734                     {
14735                         while (n_paired_endpoints)
14736                         {
14737                             proto_tree_add_item(ep_tree, hf_zbee_gp_paired_endpoint, tvb, offset, 1, ENC_NA);
14738                             offset += 1;
14739                             n_paired_endpoints--;
14740                         }
14741                     }
14742                 }
14743                 if (options & ZBEE_ZCL_GP_CMD_PC_OPT_APP_INFO_PRESENT) {
14744                     static int * const app_info[] = {
14745                         &hf_zbee_gp_cmd_pc_app_info_manuf_id_present,
14746                         &hf_zbee_gp_cmd_pc_app_info_model_id_present,
14747                         &hf_zbee_gp_cmd_pc_app_info_gpd_commands_present,
14748                         &hf_zbee_gp_cmd_pc_app_info_cluster_list_present,
14749                         NULL
14750                     };
14751                     guint8 appi = tvb_get_guint8(tvb, offset);
14752 
14753                     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_pc_app_info,
14754                                            ett_zbee_gp_cmd_pc_app_info, app_info, ENC_NA);
14755                     offset += 1;
14756                     if (appi & ZBEE_ZCL_GP_CMD_PC_APP_INFO_MANUF_ID_PRESENT) {
14757                         proto_tree_add_item(tree, hf_zbee_zcl_gp_manufacturer_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14758                         offset += 2;
14759                     }
14760                     if (appi & ZBEE_ZCL_GP_CMD_PC_APP_INFO_MODEL_ID_PRESENT) {
14761                         proto_tree_add_item(tree, hf_zbee_zcl_gp_model_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14762                         offset += 2;
14763                     }
14764                     if (appi & ZBEE_ZCL_GP_CMD_PC_APP_INFO_GPD_COMMANDS_PRESENT) {
14765                         guint8 n_commands = tvb_get_guint8(tvb, offset);
14766                         proto_tree  *c_tree  = proto_tree_add_subtree_format(tree, tvb, offset, n_commands+1, ett_zbee_zcl_gp_cmds, NULL, "GPD CommandID list #%d", n_commands);
14767                         proto_tree_add_item(c_tree, hf_zbee_gp_n_gpd_commands, tvb, offset, 1, ENC_NA);
14768                         offset += 1;
14769                         while (n_commands)
14770                         {
14771                             proto_tree_add_item(c_tree, hf_zbee_gp_gpd_command, tvb, offset, 1, ENC_NA);
14772                             offset += 1;
14773                             n_commands--;
14774                         }
14775                     }
14776                     if (appi & ZBEE_ZCL_GP_CMD_PC_APP_INFO_CLUSTER_LIST_PRESENT) {
14777                         guint8 n = tvb_get_guint8(tvb, offset);
14778                         guint8 n_srv_clusters = n & ZBEE_ZCL_GP_CLUSTER_LIST_LEN_SRV;
14779                         guint8 n_cli_clusters = (n & ZBEE_ZCL_GP_CLUSTER_LIST_LEN_CLI) >> ZBEE_ZCL_GP_CLUSTER_LIST_LEN_CLI_SHIFT;
14780                         proto_tree  *cl_tree  = proto_tree_add_subtree_format(tree, tvb, offset, n*2+1, ett_zbee_zcl_gp_clusters, NULL, "Cluster List #%d/%d", n_srv_clusters, n_cli_clusters);
14781                         proto_tree_add_item(cl_tree, hf_zbee_gp_n_srv_clusters, tvb, offset, 1, ENC_NA);
14782                         proto_tree_add_item(cl_tree, hf_zbee_gp_n_cli_clusters, tvb, offset, 1, ENC_NA);
14783                         offset += 1;
14784                         if (n_srv_clusters)
14785                         {
14786                             proto_tree  *s_tree  = proto_tree_add_subtree_format(cl_tree, tvb, offset, n_srv_clusters*2, ett_zbee_zcl_gp_srv_clusters, NULL, "Server clusters #%d", n_srv_clusters);
14787                             while (n_srv_clusters)
14788                             {
14789                                 proto_tree_add_item(s_tree, hf_zbee_gp_gpd_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14790                                 offset += 2;
14791                                 n_srv_clusters--;
14792                             }
14793                         }
14794                         if (n_cli_clusters)
14795                         {
14796                             proto_tree  *c_tree  = proto_tree_add_subtree_format(cl_tree, tvb, offset, n_cli_clusters*2, ett_zbee_zcl_gp_cli_clusters, NULL, "Client clusters #%d", n_cli_clusters);
14797                             while (n_cli_clusters)
14798                             {
14799                                 proto_tree_add_item(c_tree, hf_zbee_gp_gpd_cluster_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14800                                 offset += 2;
14801                                 n_cli_clusters--;
14802                             }
14803                         }
14804                     }
14805                 }
14806                 break;
14807             }
14808 
14809             case ZBEE_CMD_ID_GP_SINK_COMMISSIONING_MODE:
14810                 dissect_zcl_gp_sink_comm_mode(tree, tvb, &offset);
14811                 break;
14812             case ZBEE_CMD_ID_GP_TRANSLATION_TABLE_UPDATE_COMMAND:
14813             case ZBEE_CMD_ID_GP_TRANSLATION_TABLE_REQUEST:
14814                 /* TODO: add commands parse */
14815                 break;
14816             case ZBEE_CMD_ID_GP_SINK_TABLE_REQUEST:
14817                 dissect_zcl_gp_proxy_sink_table_request(tree, tvb, &offset);
14818                 break;
14819             case ZBEE_CMD_ID_GP_PROXY_TABLE_RESPONSE:
14820                 dissect_zcl_gp_proxy_sink_table_response(tree, tvb, &offset, ZBEE_ZCL_ATTR_GPP_PROXY_TABLE);
14821                 break;
14822 
14823             default:
14824                 break;
14825         } /* switch */
14826     } else {
14827         /* Append the command name to the info column. */
14828         col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
14829                         val_to_str_const(cmd_id, zbee_zcl_gp_srv_tx_cmd_names, "Unknown Command"),
14830                         zcl->tran_seqno);
14831 
14832         /* Add the command ID. */
14833         proto_tree_add_item(tree, hf_zbee_zcl_gp_srv_tx_cmd_id, tvb, offset, 1, ENC_NA);
14834         offset++;
14835 
14836         /* Handle the command dissection. */
14837         switch (cmd_id) {
14838             case ZBEE_ZCL_CMD_ID_GP_NOTIFICATION_RESPONSE:
14839                 /* TODO: add commands parse */
14840                 break;
14841 
14842             case ZBEE_ZCL_CMD_ID_GP_PAIRING:
14843             {
14844                 static int * const p_options[] = {
14845                     &hf_zbee_gp_cmd_pairing_opt_app_id,
14846                     &hf_zbee_gp_cmd_pairing_opt_add_sink,
14847                     &hf_zbee_gp_cmd_pairing_opt_remove_gpd,
14848                     &hf_zbee_gp_cmd_pairing_opt_communication_mode,
14849                     &hf_zbee_gp_cmd_pairing_opt_gpd_fixed,
14850                     &hf_zbee_gp_cmd_pairing_opt_gpd_mac_seq_num_cap,
14851                     &hf_zbee_gp_cmd_pairing_opt_secur_level,
14852                     &hf_zbee_gp_cmd_pairing_opt_secur_key_type,
14853                     &hf_zbee_gp_cmd_pairing_opt_gpd_frame_cnt_present,
14854                     &hf_zbee_gp_cmd_pairing_opt_gpd_secur_key_present,
14855                     &hf_zbee_gp_cmd_pairing_opt_assigned_alias_present,
14856                     &hf_zbee_gp_cmd_pairing_opt_fwd_radius_present,
14857                     NULL
14858                 };
14859                 guint32 options = tvb_get_guint24(tvb, offset, ENC_LITTLE_ENDIAN);
14860 
14861                 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_pairing_options,
14862                                        ett_zbee_gp_cmd_pairing_options, p_options, ENC_LITTLE_ENDIAN);
14863                 offset += 3;
14864                 if ((options & ZBEE_ZCL_GP_PAIRING_OPTION_APP_ID) == 0) {
14865                     proto_tree_add_item(tree, hf_zbee_gp_src_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14866                     offset += 4;
14867                 }
14868                 else {
14869                     proto_tree_add_item(tree, hf_zbee_gp_ieee, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14870                     offset += 8;
14871                     proto_tree_add_item(tree, hf_zbee_gp_endpoint, tvb, offset, 1, ENC_NA);
14872                     offset += 1;
14873                 }
14874                 if ((options & ZBEE_ZCL_GP_PAIRING_OPTION_REMOVE_GPD) == 0 &&
14875                     /* see Table 37 */
14876                     (options & ZBEE_ZCL_GP_PAIRING_OPTION_COMMUNICATION_MODE) == ZBEE_ZCL_GP_PAIRING_OPTION_COMMUNICATION_MODE) {
14877                     proto_tree_add_item(tree, hf_zbee_gp_sink_ieee, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14878                     offset += 8;
14879                     proto_tree_add_item(tree, hf_zbee_gp_sink_nwk, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14880                     offset += 2;
14881                 }
14882                 if ((options & ZBEE_ZCL_GP_PAIRING_OPTION_REMOVE_GPD) == 0 &&
14883                     (options & ZBEE_ZCL_GP_PAIRING_OPTION_COMMUNICATION_MODE) != ZBEE_ZCL_GP_PAIRING_OPTION_COMMUNICATION_MODE &&
14884                     (options & ZBEE_ZCL_GP_PAIRING_OPTION_COMMUNICATION_MODE) != 0) {
14885                     proto_tree_add_item(tree, hf_zbee_gp_sink_group_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14886                     offset += 2;
14887                 }
14888                 if (options & ZBEE_ZCL_GP_PAIRING_OPTION_ADD_SINK) {
14889                     proto_tree_add_item(tree, hf_zbee_gp_device_id, tvb, offset, 1, ENC_NA);
14890                     offset += 1;
14891                 }
14892                 if (options & ZBEE_ZCL_GP_PAIRING_OPTION_GPD_FRAME_CNT_PRESENT) {
14893                     proto_tree_add_item(tree, hf_zbee_gp_secur_frame_counter, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14894                     offset += 4;
14895                 }
14896                 if (options & ZBEE_ZCL_GP_PAIRING_OPTION_GPD_SECUR_KEY_PRESENT) {
14897                     proto_tree_add_item(tree, hf_zbee_gp_gpd_key, tvb, offset, 16, ENC_NA);
14898                     offset += 16;
14899                 }
14900                 if (options & ZBEE_ZCL_GP_PAIRING_OPTION_ASSIGNED_ALIAS_PRESENT) {
14901                     proto_tree_add_item(tree, hf_zbee_gp_assigned_alias, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14902                     offset += 2;
14903                 }
14904                 if (options & ZBEE_ZCL_GP_PAIRING_OPTION_FWD_RADIUS_PRESENT) {
14905                     proto_tree_add_item(tree, hf_zbee_gp_forwarding_radius, tvb, offset, 1, ENC_NA);
14906                     offset += 1;
14907                 }
14908                 break;
14909             }
14910 
14911             case ZBEE_ZCL_CMD_ID_GP_PROXY_COMMISSIONING_MODE:
14912             {
14913                 static int * const pcm_options[] = {
14914                     &hf_zbee_gp_cmd_pcm_opt_action,
14915                     &hf_zbee_gp_cmd_pcm_opt_exit_mode,
14916                     &hf_zbee_gp_cmd_pcm_opt_channel_present,
14917                     &hf_zbee_gp_cmd_pcm_opt_unicast_comm,
14918                     NULL
14919                 };
14920                 guint8 options = tvb_get_guint8(tvb, offset);
14921                 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_proxy_commissioning_mode_options,
14922                                        ett_zbee_gp_cmd_proxy_commissioning_mode_options, pcm_options, ENC_NA);
14923                 if (options & ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ACTION) {
14924                     static int * const exit_mode[] = {
14925                         &hf_zbee_gp_cmd_pcm_exit_mode_on_comm_window_expire,
14926                         &hf_zbee_gp_cmd_pcm_exit_mode_on_pairing_success,
14927                         &hf_zbee_gp_cmd_pcm_exit_mode_on_gp_proxy_comm_mode,
14928                         NULL
14929                     };
14930                     proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_proxy_commissioning_mode_exit_mode,
14931                                            ett_zbee_gp_cmd_proxy_commissioning_mode_exit_mode, exit_mode, ENC_NA);
14932                 }
14933                 offset += 1;
14934                 if (options & ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ON_COMMISSIONING_WINDOW_EXPIRATION) {
14935                     proto_tree_add_item(tree, hf_zbee_zcl_gp_commissioning_window, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14936                     offset += 2;
14937                 }
14938                 if (options & ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_CHANNEL_PRESENT) {
14939                     proto_tree_add_item(tree, hf_zbee_zcl_gp_channel, tvb, offset, 1, ENC_NA);
14940                     offset += 1;
14941                 }
14942                 break;
14943             }
14944 
14945             case ZBEE_ZCL_CMD_ID_GP_RESPONSE:
14946             {
14947                 static int * const rsp_options[] = {
14948                     &hf_zbee_gp_cmd_resp_opt_app_id,
14949                     &hf_zbee_gp_cmd_resp_opt_tx_on_ep_match,
14950                     NULL
14951                 };
14952                 static int * const tx_ch[] = {
14953                     &hf_zbee_gp_cmd_resp_tx_channel,
14954                     NULL
14955                 };
14956                 guint8 options = tvb_get_guint8(tvb, offset);
14957 
14958                 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_response_options,
14959                                        ett_zbee_gp_cmd_response_options, rsp_options, ENC_LITTLE_ENDIAN);
14960                 offset += 1;
14961                 proto_tree_add_item(tree, hf_zbee_gp_tmp_master_short_addr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
14962                 offset += 2;
14963                 proto_tree_add_bitmask(tree, tvb, offset, hf_zbee_gp_cmd_response_tx_channel,
14964                                        ett_zbee_gp_cmd_response_tx_channel, tx_ch, ENC_LITTLE_ENDIAN);
14965                 offset += 1;
14966 
14967                 if ((options & ZBEE_ZCL_GP_RESPONSE_OPTION_APP_ID) == 0) {
14968                     proto_tree_add_item(tree, hf_zbee_gp_src_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
14969                     offset += 4;
14970                 }
14971                 else {
14972                     proto_tree_add_item(tree, hf_zbee_gp_ieee, tvb, offset, 8, ENC_LITTLE_ENDIAN);
14973                     offset += 8;
14974                     proto_tree_add_item(tree, hf_zbee_gp_endpoint, tvb, offset, 1, ENC_NA);
14975                     offset += 1;
14976                 }
14977 
14978                 offset = dissect_zbee_zcl_gp_payload(tvb, pinfo, tree, offset);
14979                 break;
14980             }
14981             case ZBEE_ZCL_CMD_ID_GP_TRANS_TBL_RESPONSE:
14982                 /* TODO: add commands parse */
14983                 break;
14984             case ZBEE_ZCL_CMD_ID_GP_SINK_TABLE_RESPONSE:
14985                 dissect_zcl_gp_proxy_sink_table_response(tree, tvb, &offset, ZBEE_ZCL_ATTR_GPS_SINK_TABLE);
14986                 break;
14987             case ZBEE_ZCL_CMD_ID_GP_PROXY_TABLE_REQUEST:
14988                 dissect_zcl_gp_proxy_sink_table_request(tree, tvb, &offset);
14989                 break;
14990             default:
14991                 break;
14992         } /* switch */
14993     }
14994 
14995     /* Call the data dissector for any leftover bytes. */
14996     if (tvb_captured_length(tvb) > offset) {
14997         call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
14998     }
14999 
15000     return tvb_captured_length(tvb);
15001 } /* dissect_zbee_zcl_gp */
15002 
15003 
15004 /**
15005  *      dissect_zcl_gp_attr_data
15006  *
15007  *      this function is called by ZCL foundation dissector in order to decode
15008  *      specific cluster attributes data.
15009  *
15010  *      @param tree        - pointer to data tree Wireshark uses to display packet.
15011  *      @param tvb         - pointer to buffer containing raw packet.
15012  *      @param offset      - pointer to buffer offset
15013  *      @param attr_id     - attribute identifier
15014  *      @param data_type   - attribute data type
15015  *      @param client_attr - ZCL client
15016  */
15017 static void
dissect_zcl_gp_attr_data(proto_tree * tree,tvbuff_t * tvb,guint * offset,guint16 attr_id _U_,guint data_type,gboolean client_attr)15018 dissect_zcl_gp_attr_data(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint16 attr_id _U_, guint data_type, gboolean client_attr)
15019 {
15020     /* Dissect attribute data type and data */
15021     switch (attr_id) {
15022         case ZBEE_ZCL_ATTR_GPS_SINK_TABLE:
15023             *offset = dissect_zbee_zcl_gp_sink_table(tvb, tree, *offset);
15024             break;
15025         case ZBEE_ZCL_ATTR_GPS_COMMUNICATION_MODE:
15026             *offset = dissect_zbee_zcl_gp_attr_gps_communication_mode(tvb, tree, *offset);
15027             break;
15028         case ZBEE_ZCL_ATTR_GPS_COMMISSIONING_EXIT_MODE:
15029             *offset = dissect_zbee_zcl_gp_attr_gps_comm_exit_mode(tvb, tree, *offset);
15030             break;
15031         case ZBEE_ZCL_ATTR_GPS_SECURITY_LEVEL:
15032             *offset = dissect_zbee_zcl_gp_attr_gps_secur_lvl(tvb, tree, *offset);
15033             break;
15034         case ZBEE_ZCL_ATTR_GPS_FUNCTIONALITY:
15035             *offset = dissect_zbee_zcl_gp_attr_gps_functionality(tvb, tree, *offset);
15036             break;
15037         case ZBEE_ZCL_ATTR_GPS_ACTIVE_FUNCTIONALITY:
15038             *offset = dissect_zbee_zcl_gp_attr_gps_active_functionality(tvb, tree, *offset);
15039             break;
15040         case ZBEE_ZCL_ATTR_GPP_PROXY_TABLE:
15041             *offset = dissect_zbee_zcl_gp_proxy_table(tvb, tree, *offset);
15042             break;
15043         case ZBEE_ZCL_ATTR_GPP_FUNCTIONALITY:
15044             *offset = dissect_zbee_zcl_gp_attr_gpp_functionality(tvb, tree, *offset);
15045             break;
15046         case ZBEE_ZCL_ATTR_GPP_ACTIVE_FUNCTIONALITY:
15047             *offset = dissect_zbee_zcl_gp_attr_gpp_active_functionality(tvb, tree, *offset);
15048             break;
15049         default:
15050             dissect_zcl_attr_data(tvb, tree, offset, data_type, client_attr);
15051     }
15052 
15053 
15054 } /*dissect_zcl_gp_attr_data*/
15055 
15056 /**
15057  *      proto_register_zbee_zcl_gp
15058  *
15059  *      ZigBee ZCL Green Power cluster protocol registration.
15060  */
15061 void
proto_register_zbee_zcl_gp(void)15062 proto_register_zbee_zcl_gp(void)
15063 {
15064     /* Setup list of header fields */
15065     static hf_register_info hf[] = {
15066 
15067         { &hf_zbee_zcl_gp_attr_id,
15068             { "Attribute", "zbee_zcl_general.gp.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_gp_attr_names),
15069             0x0, NULL, HFILL } },
15070 
15071         { &hf_zbee_zcl_gp_srv_rx_cmd_id,
15072             { "Command", "zbee_zcl_general.gp.cmd.srv_rx.id", FT_UINT8, BASE_HEX,
15073                 VALS(zbee_zcl_gp_srv_rx_cmd_names), 0x0, NULL, HFILL }},
15074 
15075         { &hf_zbee_zcl_gp_srv_tx_cmd_id,
15076             { "Command", "zbee_zcl_general.gp.cmd.srv_tx.id", FT_UINT8, BASE_HEX,
15077                 VALS(zbee_zcl_gp_srv_tx_cmd_names), 0x0, NULL, HFILL }},
15078 
15079         /* GP Proxy Commissioning Mode command  */
15080         { &hf_zbee_gp_cmd_proxy_commissioning_mode_options,
15081           { "Options", "zbee_zcl_general.gp.proxy_comm_mode.options", FT_UINT8, BASE_HEX,
15082             NULL, 0x0, NULL, HFILL }},
15083         { &hf_zbee_zcl_gp_commissioning_window,
15084           { "Commissioning window", "zbee_zcl_general.gp.proxy_comm_mode.comm_window", FT_UINT16, BASE_DEC,
15085             NULL, 0x0, "Commissioning window in seconds", HFILL }},
15086         { &hf_zbee_zcl_gp_channel,
15087           { "Channel", "zbee_zcl_general.gp.proxy_comm_mode.channel", FT_UINT8, BASE_DEC,
15088             NULL, 0x0, "Identifier of the channel the devices SHOULD switch to on reception", HFILL }},
15089         { &hf_zbee_gp_cmd_pcm_opt_action,
15090           { "Action", "zbee_zcl_general.gp.proxy_comm_mode.opt.action", FT_UINT8, BASE_DEC,
15091             VALS(zbee_zcl_gp_comm_mode_actions), ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ACTION, NULL, HFILL }},
15092         { &hf_zbee_gp_cmd_pcm_opt_exit_mode,
15093           { "Exit mode", "zbee_zcl_general.gp.proxy_comm_mode.opt.exit_mode", FT_UINT8, BASE_HEX,
15094             NULL, ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_EXIT_MODE, "Commissioning mode exit requirements", HFILL }},
15095         { &hf_zbee_gp_cmd_pcm_opt_channel_present,
15096           { "Channel present", "zbee_zcl_general.gp.proxy_comm_mode.opt.ch_present", FT_BOOLEAN, 8,
15097             NULL, ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_CHANNEL_PRESENT, "If set to 0b1, it indicates that the Channel field is present", HFILL }},
15098         { &hf_zbee_gp_cmd_pcm_opt_unicast_comm,
15099           { "Unicast", "zbee_zcl_general.gp.proxy_comm_mode.opt.unicast", FT_BOOLEAN, 8,
15100             NULL, ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_UNICAST, "Send the GP Commissioning Notification commands in broadcast (0) vs unicast (1)", HFILL }},
15101         { &hf_zbee_gp_cmd_proxy_commissioning_mode_exit_mode,
15102           { "Exit mode", "zbee_zcl_general.gp.proxy_comm_mode.opt.exit_mode", FT_UINT8, BASE_HEX,
15103             NULL, ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_EXIT_MODE, "Commissioning mode exit requirements", HFILL }},
15104         { &hf_zbee_gp_cmd_pcm_exit_mode_on_comm_window_expire,
15105           { "On Window expire", "zbee_zcl_general.gp.proxy_comm_mode.opt.exit_mode.win_expire", FT_BOOLEAN, 8,
15106             NULL, ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ON_COMMISSIONING_WINDOW_EXPIRATION, "On CommissioningWindow expiration", HFILL }},
15107         { &hf_zbee_gp_cmd_pcm_exit_mode_on_pairing_success,
15108           { "On first Pairing success", "zbee_zcl_general.gp.proxy_comm_mode.opt.exit_mode.pair_succs", FT_BOOLEAN, 8,
15109             NULL, ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ON_PAIRING_SUCCESS, NULL, HFILL }},
15110         { &hf_zbee_gp_cmd_pcm_exit_mode_on_gp_proxy_comm_mode,
15111           { "On GP Proxy Commissioning Mode", "zbee_zcl_general.gp.proxy_comm_mode.opt.exit_mode.proxy_comm_mode", FT_BOOLEAN, 8,
15112             NULL, ZBEE_ZCL_GP_PROXY_COMMISSIONING_MODE_OPTION_ON_GP_PROXY_COMM_MODE, "On GP Proxy Commissioning Mode (exit)", HFILL }},
15113 
15114         /* GP Commissioning Notification command */
15115         { &hf_zbee_gp_cmd_commissioning_notification_options,
15116           { "Options", "zbee_zcl_general.gp.comm_notif.options", FT_UINT16, BASE_HEX,
15117             NULL, 0x0, NULL, HFILL }},
15118         { &hf_zbee_gp_cmd_comm_notif_opt_app_id,
15119           { "ApplicationID", "zbee_zcl_general.gp.comm_notif.opt.app_id", FT_UINT16, BASE_HEX,
15120             VALS(zbee_zcl_gp_app_ids), ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_APP_ID, NULL, HFILL }},
15121         { &hf_zbee_gp_cmd_comm_notif_opt_rx_after_tx,
15122           { "RxAfterTx", "zbee_zcl_general.gp.comm_notif.opt.rx_after_tx", FT_BOOLEAN, 16,
15123             NULL, ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_RX_AFTER_TX, NULL, HFILL }},
15124         { &hf_zbee_gp_cmd_comm_notif_opt_secur_level,
15125           { "SecurityLevel", "zbee_zcl_general.gp.comm_notif.opt.secur_lev", FT_UINT16, BASE_HEX,
15126             VALS(zbee_zcl_gp_secur_levels), ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_SECUR_LEVEL, NULL, HFILL }},
15127         { &hf_zbee_gp_cmd_comm_notif_opt_secur_key_type,
15128           { "SecurityKeyType", "zbee_zcl_general.gp.comm_notif.opt.secur_key_type", FT_UINT16, BASE_HEX,
15129             VALS(zbee_zcl_gp_secur_key_types), ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_SECUR_KEY_TYPE, NULL, HFILL }},
15130         { &hf_zbee_gp_cmd_comm_notif_opt_secur_fail,
15131           { "Security processing failed", "zbee_zcl_general.gp.comm_notif.opt.secur_failed", FT_BOOLEAN, 16,
15132             NULL, ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_SECUR_FAILED, NULL, HFILL }},
15133         { &hf_zbee_gp_cmd_comm_notif_opt_bidir_cap,
15134           { "Bidirectional Capability", "zbee_zcl_general.gp.comm_notif.opt.bidir_cap", FT_BOOLEAN, 16,
15135             NULL, ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_BIDIR_CAP, NULL, HFILL }},
15136         { &hf_zbee_gp_cmd_comm_notif_opt_proxy_info_present,
15137           { "Proxy info present", "zbee_zcl_general.gp.comm_notif.opt.proxy_info", FT_BOOLEAN, 16,
15138             NULL, ZBEE_ZCL_GP_COMMISSIONING_NOTIFICATION_OPTION_PROXY_INFO_PRESENT, NULL, HFILL }},
15139         { &hf_zbee_gp_src_id,
15140           { "SrcID", "zbee_zcl_general.gp.src_id", FT_UINT32, BASE_HEX,
15141             NULL, 0, "GPD Source identifier", HFILL }},
15142         { &hf_zbee_gp_ieee,
15143           { "GPD IEEE", "zbee_zcl_general.gp.gpd_ieee", FT_EUI64, BASE_NONE,
15144             NULL, 0, "GPD IEEE address", HFILL }},
15145         { &hf_zbee_gp_endpoint,
15146           { "Endpoint", "zbee_zcl_general.gp.endpoint", FT_UINT8, BASE_HEX,
15147             NULL, 0, NULL, HFILL }},
15148         { &hf_zbee_gp_secur_frame_counter,
15149           { "Frame counter", "zbee_zcl_general.gp.frame_cnt", FT_UINT32, BASE_DEC,
15150             NULL, 0, "GPD security frame counter", HFILL }},
15151         { &hf_zbee_gp_gpd_command_id,
15152             { "ZGPD CommandID", "zbee_zcl_general.gp.command_id", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
15153               &zbee_nwk_gp_cmd_names_ext, 0x0, NULL, HFILL }},
15154         { &hf_zbee_gp_short_addr,
15155           { "GPP short address", "zbee_zcl_general.gp.gpp_short", FT_UINT16, BASE_HEX,
15156             NULL, 0, NULL, HFILL }},
15157         { &hf_zbee_gp_gpp_gpd_link,
15158           { "GPP-GPD link", "zbee_zcl_general.gp.gpd_gpp_link", FT_UINT8, BASE_HEX,
15159             NULL, 0, NULL, HFILL }},
15160         { &hf_zbee_gp_mic,
15161           { "MIC", "zbee_zcl_general.gp.mic", FT_UINT32, BASE_HEX,
15162             NULL, 0, NULL, HFILL }},
15163         { &hf_zbee_gpp_gpd_link_rssi,
15164           { "RSSI", "zbee_zcl_general.gp.gpp_gpd_link.rssi", FT_UINT8, BASE_HEX,
15165             NULL, ZBEE_ZCL_GP_GPP_GPD_LINK_RSSI, NULL, HFILL }},
15166         { &hf_zbee_gpp_gpd_link_lqi,
15167           { "LQI", "zbee_zcl_general.gp.gpp_gpd_link.lqi", FT_UINT8, BASE_HEX,
15168             VALS(zbee_zcl_gp_lqi_vals), ZBEE_ZCL_GP_GPP_GPD_LINK_LQI, NULL, HFILL }},
15169         { &hf_zbee_gp_gpd_payload_size,
15170           { "Payload size", "zbee_zcl_general.gp.payload_size", FT_UINT8, BASE_DEC,
15171             NULL, 0, NULL, HFILL }},
15172 
15173         /* GP Notification */
15174         { &hf_zbee_gp_cmd_notification_options,
15175           { "Options", "zbee_zcl_general.gp.notif.opt", FT_UINT16, BASE_HEX,
15176             NULL, 0, NULL, HFILL }},
15177         { &hf_zbee_gp_cmd_notif_opt_app_id,
15178           { "ApplicationID", "zbee_zcl_general.gp.notif.opt.app_id", FT_UINT16, BASE_HEX,
15179             VALS(zbee_zcl_gp_app_ids), ZBEE_ZCL_GP_NOTIFICATION_OPTION_APP_ID, NULL, HFILL }},
15180         { &hf_zbee_gp_cmd_notif_opt_also_unicast,
15181           { "Also Unicast", "zbee_zcl_general.gp.notif.opt.also_unicast", FT_BOOLEAN, 16,
15182             NULL, ZBEE_ZCL_GP_NOTIFICATION_OPTION_ALSO_UNICAST, NULL, HFILL }},
15183         { &hf_zbee_gp_cmd_notif_opt_also_derived_group,
15184           { "Also Derived Group", "zbee_zcl_general.gp.notif.opt.also_derived_grp", FT_BOOLEAN, 16,
15185             NULL, ZBEE_ZCL_GP_NOTIFICATION_OPTION_ALSO_DERIVED_GROUP, NULL, HFILL }},
15186         { &hf_zbee_gp_cmd_notif_opt_also_comm_group,
15187           { "Also Commissioned Group", "zbee_zcl_general.gp.notif.opt.also_comm_grp", FT_BOOLEAN, 16,
15188             NULL, ZBEE_ZCL_GP_NOTIFICATION_OPTION_ALSO_COMMISSIONED_GROUP, NULL, HFILL }},
15189         { &hf_zbee_gp_cmd_notif_opt_secur_level,
15190           { "SecurityLevel", "zbee_zcl_general.gp.notif.opt.secur_lev", FT_UINT16, BASE_HEX,
15191             VALS(zbee_zcl_gp_secur_levels), ZBEE_ZCL_GP_NOTIFICATION_OPTION_SECUR_LEVEL, NULL, HFILL }},
15192         { &hf_zbee_gp_cmd_notif_opt_secur_key_type,
15193           { "SecurityKeyType", "zbee_zcl_general.gp.notif.opt.secur_key_type", FT_UINT16, BASE_HEX,
15194             VALS(zbee_zcl_gp_secur_key_types), ZBEE_ZCL_GP_NOTIFICATION_OPTION_SECUR_KEY_TYPE, NULL, HFILL }},
15195         { &hf_zbee_gp_cmd_notif_opt_rx_after_tx,
15196           { "RxAfterTx", "zbee_zcl_general.gp.comm_notif.opt.rx_after_tx", FT_BOOLEAN, 16,
15197             NULL, ZBEE_ZCL_GP_NOTIFICATION_OPTION_RX_AFTER_TX, NULL, HFILL }},
15198         { &hf_zbee_gp_cmd_notif_opt_tx_q_full,
15199           { "gpTxQueueFull", "zbee_zcl_general.gp.comm_notif.opt.tx_q_full", FT_BOOLEAN, 16,
15200             NULL, ZBEE_ZCL_GP_NOTIFICATION_OPTION_TX_Q_FULL, NULL, HFILL }},
15201         { &hf_zbee_gp_cmd_notif_opt_bidir_cap,
15202           { "Bidirectional Capability", "zbee_zcl_general.gp.notif.opt.bidir_cap", FT_BOOLEAN, 16,
15203             NULL, ZBEE_ZCL_GP_NOTIFICATION_OPTION_BIDIR_CAP, NULL, HFILL }},
15204         { &hf_zbee_gp_cmd_notif_opt_proxy_info_present,
15205           { "Proxy info present", "zbee_zcl_general.gp.notif.opt.proxy_info", FT_BOOLEAN, 16,
15206             NULL, ZBEE_ZCL_GP_NOTIFICATION_OPTION_PROXY_INFO_PRESENT, NULL, HFILL }},
15207 
15208 
15209         /* GP Pairing */
15210         { &hf_zbee_gp_cmd_pairing_opt_app_id,
15211           { "ApplicationID", "zbee_zcl_general.gp.pairing.opt.app_id", FT_UINT24, BASE_HEX,
15212             VALS(zbee_zcl_gp_app_ids), ZBEE_ZCL_GP_PAIRING_OPTION_APP_ID, NULL, HFILL }},
15213         { &hf_zbee_gp_cmd_pairing_opt_add_sink,
15214           { "Add Sink", "zbee_zcl_general.gp.pairing.opt.add_sink", FT_BOOLEAN, 24,
15215             NULL, ZBEE_ZCL_GP_PAIRING_OPTION_ADD_SINK, NULL, HFILL }},
15216         { &hf_zbee_gp_cmd_pairing_opt_remove_gpd,
15217           { "Remove GPD", "zbee_zcl_general.gp.pairing.opt.remove_gpd", FT_BOOLEAN, 24,
15218             NULL, ZBEE_ZCL_GP_PAIRING_OPTION_REMOVE_GPD, NULL, HFILL }},
15219         { &hf_zbee_gp_cmd_pairing_opt_communication_mode,
15220           { "Communication mode", "zbee_zcl_general.gp.pairing.opt.comm_mode", FT_UINT24, BASE_HEX,
15221             VALS(zbee_zcl_gp_communication_modes), ZBEE_ZCL_GP_PAIRING_OPTION_COMMUNICATION_MODE, NULL, HFILL }},
15222         { &hf_zbee_gp_cmd_pairing_opt_gpd_fixed,
15223           { "GPD Fixed", "zbee_zcl_general.gp.pairing.opt.gpd_fixed", FT_BOOLEAN, 24,
15224             NULL, ZBEE_ZCL_GP_PAIRING_OPTION_GPD_FIXED, NULL, HFILL }},
15225         { &hf_zbee_gp_cmd_pairing_opt_gpd_mac_seq_num_cap,
15226           { "MAC Seq number cap", "zbee_zcl_general.gp.pairing.opt.seq_num_cap", FT_BOOLEAN, 24,
15227             NULL, ZBEE_ZCL_GP_PAIRING_OPTION_GPD_MAC_SEQ_NUM_CAP, "GPD MAC sequence number capabilities", HFILL }},
15228         { &hf_zbee_gp_cmd_pairing_opt_secur_level,
15229           { "SecurityLevel", "zbee_zcl_general.gp.pairing.opt.secur_lev", FT_UINT24, BASE_HEX,
15230             VALS(zbee_zcl_gp_secur_levels), ZBEE_ZCL_GP_PAIRING_OPTION_SECUR_LEVEL, NULL, HFILL }},
15231         { &hf_zbee_gp_cmd_pairing_opt_secur_key_type,
15232           { "SecurityKeyType", "zbee_zcl_general.gp.pairing.opt.secur_key_type", FT_UINT24, BASE_HEX,
15233             VALS(zbee_zcl_gp_secur_key_types), ZBEE_ZCL_GP_PAIRING_OPTION_SECUR_KEY_TYPE, NULL, HFILL }},
15234         { &hf_zbee_gp_cmd_pairing_opt_gpd_frame_cnt_present,
15235           { "Frame Counter present", "zbee_zcl_general.gp.pairing.opt.frame_counter_present", FT_BOOLEAN, 24,
15236             NULL, ZBEE_ZCL_GP_PAIRING_OPTION_GPD_FRAME_CNT_PRESENT, "GPD security Frame Counter present", HFILL }},
15237         { &hf_zbee_gp_cmd_pairing_opt_gpd_secur_key_present,
15238           { "Key present", "zbee_zcl_general.gp.pairing.opt.key_present", FT_BOOLEAN, 24,
15239             NULL, ZBEE_ZCL_GP_PAIRING_OPTION_GPD_SECUR_KEY_PRESENT, "GPD security key present", HFILL }},
15240         { &hf_zbee_gp_cmd_pairing_opt_assigned_alias_present,
15241           { "Assigned Alias present", "zbee_zcl_general.gp.pairing.opt.asn_alias_present", FT_BOOLEAN, 24,
15242             NULL, ZBEE_ZCL_GP_PAIRING_OPTION_ASSIGNED_ALIAS_PRESENT, NULL, HFILL }},
15243         { &hf_zbee_gp_cmd_pairing_opt_fwd_radius_present,
15244           { "Forwarding Radius present", "zbee_zcl_general.gp.pairing.opt.fwd_radius_present", FT_BOOLEAN, 24,
15245             NULL, ZBEE_ZCL_GP_PAIRING_OPTION_FWD_RADIUS_PRESENT, NULL, HFILL }},
15246         { &hf_zbee_gp_cmd_pairing_options,
15247           { "Options", "zbee_zcl_general.gp.pairing.opt", FT_UINT24, BASE_HEX,
15248             NULL, 0, NULL, HFILL }},
15249         { &hf_zbee_gp_sink_ieee,
15250           { "Sink IEEE", "zbee_zcl_general.gp.sink_ieee", FT_EUI64, BASE_NONE,
15251             NULL, 0, "Sink IEEE address", HFILL }},
15252         { &hf_zbee_gp_sink_nwk,
15253           { "Sink NWK", "zbee_zcl_general.gp.sink_nwk", FT_UINT16, BASE_HEX,
15254             NULL, 0, "Sink NWK address", HFILL }},
15255         { &hf_zbee_gp_sink_group_id,
15256           { "Sink GroupID", "zbee_zcl_general.gp.sink_grp", FT_UINT16, BASE_HEX,
15257             NULL, 0, NULL, HFILL }},
15258         { &hf_zbee_gp_device_id,
15259           { "DeviceID", "zbee_zcl_general.gp.dev_id", FT_UINT8, BASE_HEX,
15260             VALS(zbee_nwk_gp_device_ids_names), 0, NULL, HFILL }},
15261         { &hf_zbee_gp_assigned_alias,
15262           { "Assigned alias", "zbee_zcl_general.gp.asn_alias", FT_UINT16, BASE_HEX,
15263             NULL, 0, NULL, HFILL }},
15264         { &hf_zbee_gp_forwarding_radius,
15265           { "Forwarding Radius", "zbee_zcl_general.gp.fw_radius", FT_UINT8, BASE_HEX,
15266             NULL, 0, NULL, HFILL }},
15267         { &hf_zbee_gp_gpd_key,
15268           { "GPD key", "zbee_zcl_general.gp.gpd_key", FT_BYTES, BASE_NONE,
15269             NULL, 0, NULL, HFILL }},
15270         { &hf_zbee_gp_groupcast_radius,
15271           { "Groupcast radius", "zbee_zcl_general.gp.groupcast_radius", FT_UINT8, BASE_DEC,
15272             NULL, 0, NULL, HFILL }},
15273 
15274         /* GP Response */
15275         { &hf_zbee_gp_cmd_response_options,
15276           { "Options", "zbee_zcl_general.gp.response.opt", FT_UINT8, BASE_HEX,
15277             NULL, 0, NULL, HFILL }},
15278         { &hf_zbee_gp_cmd_resp_opt_app_id,
15279           { "ApplicationID", "zbee_zcl_general.gp.response.opt.app_id", FT_UINT8, BASE_HEX,
15280             NULL, ZBEE_ZCL_GP_RESPONSE_OPTION_APP_ID, NULL, HFILL }},
15281         { &hf_zbee_gp_cmd_resp_opt_tx_on_ep_match,
15282           { "Transmit on endpoint match", "zbee_zcl_general.gp.response.opt.tx_on_ep_match", FT_UINT8, BASE_HEX,
15283             NULL, ZBEE_ZCL_GP_RESPONSE_OPTION_TX_ON_ENDPOINT_MATCH, NULL, HFILL }},
15284         { &hf_zbee_gp_cmd_response_tx_channel,
15285           { "TempMaster Tx channel", "zbee_zcl_general.gp.response.tmpmaster_tx_chan", FT_UINT8, BASE_HEX,
15286             NULL, 0, NULL, HFILL }},
15287         { &hf_zbee_gp_cmd_resp_tx_channel,
15288           { "Transmit channel", "zbee_zcl_general.gp.response.opt.tx_chan", FT_UINT8, BASE_HEX,
15289             VALS(zbee_zcl_gp_channels), ZBEE_ZCL_GP_RESPONSE_TX_CHANNEL, NULL, HFILL }},
15290         { &hf_zbee_gp_tmp_master_short_addr,
15291           { "TempMaster short address", "zbee_zcl_general.gp.response.tmpmaster_addr", FT_UINT16, BASE_HEX,
15292             NULL, 0, NULL, HFILL }},
15293 
15294         /* GP Pairing Configuration */
15295         { &hf_zbee_gp_cmd_pc_actions_action,
15296           { "Action", "zbee_zcl_general.gp.pc.action.action", FT_UINT8, BASE_HEX,
15297             VALS(zbee_gp_pc_actions), ZBEE_ZCL_GP_CMD_PC_ACTIONS_ACTION, NULL, HFILL }},
15298         { &hf_zbee_gp_cmd_pc_actions_send_gp_pairing,
15299           { "Send GP Pairing", "zbee_zcl_general.gp.pc.action.send_gp_pairing", FT_BOOLEAN, 8,
15300             NULL, ZBEE_ZCL_GP_CMD_PC_ACTIONS_SEND_GP_PAIRING, NULL, HFILL }},
15301         { &hf_zbee_gp_cmd_pc_opt_app_id,
15302           { "ApplicationID", "zbee_zcl_general.gp.pp.opt.app_id", FT_UINT16, BASE_HEX,
15303             NULL, ZBEE_ZCL_GP_CMD_PC_OPT_APP_ID, NULL, HFILL }},
15304         { &hf_zbee_gp_cmd_pc_opt_communication_mode,
15305           { "Communication mode", "zbee_zcl_general.gp.pc.opt.comm_mode", FT_UINT16, BASE_HEX,
15306             VALS(zbee_zcl_gp_communication_modes), ZBEE_ZCL_GP_CMD_PC_OPT_COMMUNICATION_MODE, NULL, HFILL }},
15307         { &hf_zbee_gp_cmd_pc_opt_seq_number_cap,
15308           { "Sequence number capabilities", "zbee_zcl_general.gp.pc.opt.seq_num_cap", FT_BOOLEAN, 16,
15309             NULL, ZBEE_ZCL_GP_CMD_PC_OPT_SEQ_NUMBER_CAP, NULL, HFILL }},
15310         { &hf_zbee_gp_cmd_px_opt_rx_on_cap,
15311           { "RxOnCapability", "zbee_zcl_general.gp.pc.opt.rx_on_cap", FT_BOOLEAN, 16,
15312             NULL, ZBEE_ZCL_GP_CMD_PC_OPT_RX_ON_CAP, NULL, HFILL }},
15313         { &hf_zbee_gp_cmd_pc_opt_fixed_location,
15314           { "FixedLocation", "zbee_zcl_general.gp.pc.opt.fixed_loc", FT_BOOLEAN, 16,
15315             NULL, ZBEE_ZCL_GP_CMD_PC_OPT_FIXED_LOCATION, NULL, HFILL }},
15316         { &hf_zbee_gp_cmd_pc_opt_assigned_alias,
15317           { "AssignedAlias", "zbee_zcl_general.gp.pc.opt.asn_alias", FT_BOOLEAN, 16,
15318             NULL, ZBEE_ZCL_GP_CMD_PC_OPT_ASSIGNED_ALIAS, NULL, HFILL }},
15319         { &hf_zbee_gp_cmd_pc_opt_security_use,
15320           { "Security use", "zbee_zcl_general.gp.pc.opt.secur_use", FT_BOOLEAN, 16,
15321             NULL, ZBEE_ZCL_GP_CMD_PC_OPT_SECURITY_USE, NULL, HFILL }},
15322         { &hf_zbee_gp_cmd_pc_opt_app_info_present,
15323           { "Application in-formation present", "zbee_zcl_general.gp.pc.opt.app_info_present", FT_BOOLEAN, 16,
15324             NULL, ZBEE_ZCL_GP_CMD_PC_OPT_APP_INFO_PRESENT, NULL, HFILL }},
15325         { &hf_zbee_gp_cmd_pc_secur_level,
15326           { "SecurityLevel", "zbee_zcl_general.gp.pc.secur.secur_lev", FT_UINT8, BASE_HEX,
15327             VALS(zbee_zcl_gp_secur_levels), ZBEE_ZCL_GP_CMD_PC_SECUR_LEVEL, NULL, HFILL }},
15328         { &hf_zbee_gp_cmd_pc_secur_key_type,
15329           { "SecurityKeyType", "zbee_zcl_general.gp.pc.secur.secur_key_type", FT_UINT8, BASE_HEX,
15330             VALS(zbee_zcl_gp_secur_key_types), ZBEE_ZCL_GP_CMD_PC_SECUR_KEY_TYPE, NULL, HFILL }},
15331         { &hf_zbee_gp_cmd_pc_app_info_manuf_id_present,
15332           { "ManufacturerID present", "zbee_zcl_general.gp.pc.app.manuf_id_present", FT_BOOLEAN, 8,
15333             NULL, ZBEE_ZCL_GP_CMD_PC_APP_INFO_MANUF_ID_PRESENT, NULL, HFILL }},
15334         { &hf_zbee_gp_cmd_pc_app_info_model_id_present,
15335           { "ModelID present", "zbee_zcl_general.gp.pc.app.model_id_present", FT_BOOLEAN, 8,
15336             NULL, ZBEE_ZCL_GP_CMD_PC_APP_INFO_MODEL_ID_PRESENT, NULL, HFILL }},
15337         { &hf_zbee_gp_cmd_pc_app_info_gpd_commands_present,
15338           { "GPD commands present", "zbee_zcl_general.gp.pc.app.gpd_cmds_present", FT_BOOLEAN, 8,
15339             NULL, ZBEE_ZCL_GP_CMD_PC_APP_INFO_GPD_COMMANDS_PRESENT, NULL, HFILL }},
15340         { &hf_zbee_gp_cmd_pc_app_info_cluster_list_present,
15341           { "Cluster list present", "zbee_zcl_general.gp.pc.app.cluster_list_present", FT_BOOLEAN, 8,
15342             NULL, ZBEE_ZCL_GP_CMD_PC_APP_INFO_CLUSTER_LIST_PRESENT, NULL, HFILL }},
15343         { &hf_zbee_gp_cmd_pc_actions,
15344           { "Actions", "zbee_zcl_general.gp.pc.actions", FT_UINT8, BASE_HEX,
15345             NULL, 0, NULL, HFILL }},
15346         { &hf_zbee_gp_cmd_pc_options,
15347           { "Options", "zbee_zcl_general.gp.pc.options", FT_UINT16, BASE_HEX,
15348             NULL, 0, NULL, HFILL }},
15349         { &hf_zbee_gp_group_list_len,
15350           { "Group list length", "zbee_zcl_general.gp.group_list.len", FT_UINT8, BASE_DEC,
15351             NULL, 0, NULL, HFILL }},
15352         { &hf_zbee_gp_group_list_group_id,
15353           { "Group id", "zbee_zcl_general.gp.group_list.group", FT_UINT16, BASE_HEX,
15354             NULL, 0, NULL, HFILL }},
15355         { &hf_zbee_gp_group_list_alias,
15356           { "Alias", "zbee_zcl_general.gp.group_list.alias", FT_UINT16, BASE_HEX,
15357             NULL, 0, NULL, HFILL }},
15358         { &hf_zbee_gp_cmd_pc_secur_options,
15359           { "Security Options", "zbee_zcl_general.gp.pc.secur_options", FT_UINT8, BASE_HEX,
15360             NULL, 0, NULL, HFILL }},
15361         { &hf_zbee_gp_n_paired_endpoints,
15362           { "Number of paired endpoints", "zbee_zcl_general.gp.pc.n_ep", FT_UINT8, BASE_DEC,
15363             NULL, 0, NULL, HFILL }},
15364         { &hf_zbee_gp_paired_endpoint,
15365           { "Paired endpoint", "zbee_zcl_general.gp.pc.endpoint", FT_UINT8, BASE_HEX,
15366             NULL, 0, NULL, HFILL }},
15367         { &hf_zbee_gp_cmd_pc_app_info,
15368           { "Application information", "zbee_zcl_general.gp.pc.app_info", FT_UINT8, BASE_HEX,
15369             NULL, 0, NULL, HFILL }},
15370         { &hf_zbee_zcl_gp_manufacturer_id,
15371           { "Manufacturer ID", "zbee_zcl_general.gp.pc.manufacturer_id", FT_UINT16, BASE_HEX,
15372             VALS(zbee_mfr_code_names), 0x0, NULL, HFILL }},
15373         { &hf_zbee_zcl_gp_model_id,
15374           { "Model ID", "zbee_zcl_general.gp.pc.model_id", FT_UINT16, BASE_HEX,
15375             NULL, 0, NULL, HFILL }},
15376         { &hf_zbee_gp_n_gpd_commands,
15377           { "Number of GPD commands", "zbee_zcl_general.gp.pc.n_gpd_commands", FT_UINT8, BASE_DEC,
15378             NULL, 0, NULL, HFILL }},
15379         { &hf_zbee_gp_gpd_command,
15380           { "ZGPD Command ID", "zbee_zcl_general.gp.pc.gpd_command", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
15381             &zbee_nwk_gp_cmd_names_ext, 0x0, NULL, HFILL }},
15382         { &hf_zbee_gp_n_srv_clusters,
15383           { "Number of Server clusters", "zbee_zcl_general.gp.pc.n_srv_clusters", FT_UINT8, BASE_DEC,
15384             NULL, ZBEE_ZCL_GP_CLUSTER_LIST_LEN_SRV, NULL, HFILL }},
15385         { &hf_zbee_gp_n_cli_clusters,
15386           { "Number of Client clusters", "zbee_zcl_general.gp.pc.n_clnt_clusters", FT_UINT8, BASE_DEC,
15387             NULL, ZBEE_ZCL_GP_CLUSTER_LIST_LEN_CLI, NULL, HFILL }},
15388         { &hf_zbee_gp_gpd_cluster_id,
15389           { "Cluster ID", "zbee_zcl_general.gp.pc.cluster", FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_aps_cid_names),
15390             0x0, NULL, HFILL }},
15391 
15392         /* GP Sink Table Request and  GP Proxy Table Request commands */
15393         { &hf_zbee_zcl_proxy_sink_tbl_req_options,
15394           { "Options", "zbee_zcl_general.gp.proxy_sink_tbl_req.options", FT_UINT8, BASE_HEX,
15395             NULL, 0, NULL, HFILL }},
15396         { &hf_zbee_zcl_proxy_sink_tbl_req_fld_app_id,
15397           { "Application ID", "zbee_zcl_general.gp.proxy_sink_tbl_req.options.app_id", FT_UINT8, BASE_HEX,
15398             NULL, ZBEE_ZCL_GP_PROXY_SINK_TBL_REQ_CMD_APP_ID, NULL, HFILL }},
15399         { &hf_zbee_zcl_proxy_sink_tbl_req_fld_req_type,
15400           { "Request type", "zbee_zcl_general.gp.proxy_sink_tbl_req.options.req_type", FT_UINT8, BASE_HEX,
15401             VALS(zbee_zcl_gp_proxy_sink_tbl_req_type), ZBEE_ZCL_GP_PROXY_SINK_TBL_REQ_CMD_REQ_TYPE, NULL, HFILL }},
15402         { &hf_zbee_zcl_proxy_sink_tbl_req_index,
15403           { "Index", "zbee_zcl_general.gp.proxy_sink_tbl_req.index", FT_UINT8, BASE_DEC,
15404             NULL, 0, NULL, HFILL }},
15405 
15406         /* GP Sink Table Response and  GP Proxy Table Response commands */
15407         { &hf_zbee_zcl_proxy_sink_tbl_resp_status,
15408           { "Status", "zbee_zcl_general.gp.proxy_sink_tbl_resp.status", FT_UINT8, BASE_HEX,
15409             VALS(zbee_zcl_status_names), 0, NULL, HFILL }},
15410         { &hf_zbee_zcl_proxy_sink_tbl_resp_entries_total,
15411           { "Total number of non-empty entries", "zbee_zcl_general.gp.proxy_sink_tbl_resp.entries_total", FT_UINT8, BASE_DEC,
15412             NULL, 0, NULL, HFILL }},
15413         { &hf_zbee_zcl_proxy_sink_tbl_resp_start_index,
15414           { "Start index", "zbee_zcl_general.gp.proxy_sink_tbl_resp.start_index", FT_UINT8, BASE_DEC,
15415             NULL, 0, NULL, HFILL }},
15416         { &hf_zbee_zcl_proxy_sink_tbl_resp_entries_count,
15417           { "Entries count", "zbee_zcl_general.gp.proxy_sink_tbl_resp.entries_count", FT_UINT8, BASE_DEC,
15418             NULL, 0, NULL, HFILL }},
15419 
15420         /* GP Sink Commissioning Mode command */
15421         { &hf_zbee_zcl_gp_cmd_sink_comm_mode_options,
15422           { "Options", "zbee_zcl_general.gp.sink_comm_mode.options", FT_UINT8, BASE_HEX,
15423             NULL, 0, NULL, HFILL }},
15424 
15425         { &hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_action,
15426           { "Action", "zbee_zcl_general.gp.sink_comm_mode.options.action", FT_BOOLEAN, 8,
15427             NULL, ZBEE_ZCL_GP_CMD_SINK_COMM_MODE_OPTIONS_FLD_ACTION, NULL, HFILL }},
15428         { &hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_gpm_in_secur,
15429           { "Involve GPM in security", "zbee_zcl_general.gp.sink_comm_mode.options.inv_gpm_in_secur", FT_BOOLEAN, 8,
15430             NULL, ZBEE_ZCL_GP_CMD_SINK_COMM_MODE_OPTIONS_FLD_INV_GPM_IN_SECUR, NULL, HFILL }},
15431         { &hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_gpm_in_pairing,
15432           { "Involve GPM in pairing", "zbee_zcl_general.gp.sink_comm_mode.options.inv_gpm_in_pairing", FT_BOOLEAN, 8,
15433             NULL, ZBEE_ZCL_GP_CMD_SINK_COMM_MODE_OPTIONS_FLD_INV_GPM_IN_PAIRING, NULL, HFILL }},
15434         { &hf_zbee_zcl_gp_cmd_sink_comm_mode_options_fld_inv_proxies,
15435           { "Involve proxies", "zbee_zcl_general.gp.sink_comm_mode.options.inv_proxies", FT_BOOLEAN, 8,
15436             NULL, ZBEE_ZCL_GP_CMD_SINK_COMM_MODE_OPTIONS_FLD_INV_PROXIES, NULL, HFILL }},
15437 
15438         { &hf_zbee_gp_zcl_cmd_sink_comm_mode_gpm_addr_for_secur,
15439           { "GPM address for security", "zbee_zcl_general.gp.sink_comm_mode.gpm_addr_for_secur", FT_UINT16, BASE_HEX,
15440             NULL, 0, NULL, HFILL }},
15441         { &hf_zbee_gp_zcl_cmd_sink_comm_mode_gpm_addr_for_pairing,
15442           { "GPM address for pairing", "zbee_zcl_general.gp.sink_comm_mode.gpm_addr_for_pairing", FT_UINT16, BASE_HEX,
15443             NULL, 0, NULL, HFILL }},
15444         { &hf_zbee_gp_zcl_cmd_sink_comm_mode_sink_ep,
15445           { "Sink Endpoint", "zbee_zcl_general.gp.sink_comm_mode.sink_ep", FT_UINT8, BASE_DEC,
15446             NULL, 0, NULL, HFILL }},
15447 
15448         /* GP Sink Table attribute */
15449         { &hf_zbee_gp_sink_tbl_length,
15450           { "Sink Table length", "zbee_zcl_general.gp.sink_tbl_len", FT_UINT16, BASE_DEC,
15451             NULL, 0, NULL, HFILL }},
15452         { &hf_zbee_gp_sink_tbl_entry_options,
15453           { "Options", "zbee_zcl_general.gp.sink_tbl.entry.opt", FT_UINT16, BASE_HEX,
15454             NULL, 0, NULL, HFILL }},
15455         { &hf_zbee_gp_sec_options,
15456           { "Security Options", "zbee_zcl_general.gp.secur", FT_UINT8, BASE_HEX,
15457             NULL, 0, NULL, HFILL }},
15458 
15459         { &hf_zbee_gp_sink_tbl_entry_options_app_id,
15460           { "ApplicationID", "zbee_zcl_general.gp.sink_tbl.entry.opt.app_id", FT_UINT16, BASE_HEX,
15461             NULL, ZBEE_ZCL_GP_SINK_TBL_OPT_APP_ID, NULL, HFILL }},
15462         { &hf_zbee_gp_sink_tbl_entry_options_comm_mode,
15463           { "Communication Mode", "zbee_zcl_general.gp.sink_tbl.entry.opt.comm_mode", FT_UINT16, BASE_HEX,
15464             VALS(zbee_zcl_gp_communication_modes), ZBEE_ZCL_GP_SINK_TBL_OPT_COMMUNICATION_MODE, NULL, HFILL }},
15465         { &hf_zbee_gp_sink_tbl_entry_options_seq_num_cap,
15466           { "Sequence number capabilities", "zbee_zcl_general.gp.sink_tbl.entry.opt.seq_num_cap", FT_BOOLEAN, 16,
15467             NULL, ZBEE_ZCL_GP_SINK_TBL_OPT_SEQ_NUMBER_CAP, NULL, HFILL }},
15468         { &hf_zbee_gp_sink_tbl_entry_options_rx_on_cap,
15469           { "Rx On Capability", "zbee_zcl_general.gp.sink_tbl.entry.opt.rx_on_cap", FT_BOOLEAN, 16,
15470             NULL, ZBEE_ZCL_GP_SINK_TBL_OPT_RX_ON_CAP, NULL, HFILL }},
15471         { &hf_zbee_gp_sink_tbl_entry_options_fixed_loc,
15472           { "Fixed Location", "zbee_zcl_general.gp.sink_tbl.entry.opt.fixed_loc", FT_BOOLEAN, 16,
15473             NULL, ZBEE_ZCL_GP_SINK_TBL_OPT_FIXED_LOCATION, NULL, HFILL }},
15474         { &hf_zbee_gp_sink_tbl_entry_options_assigned_alias,
15475           { "Assigned Alias", "zbee_zcl_general.gp.sink_tbl.entry.opt.asn_alias", FT_BOOLEAN, 16,
15476             NULL, ZBEE_ZCL_GP_SINK_TBL_OPT_ASSIGNED_ALIAS, NULL, HFILL }},
15477         { &hf_zbee_gp_sink_tbl_entry_options_sec_use,
15478           { "Security use", "zbee_zcl_general.gp.sink_tbl.entry.opt.secur_use", FT_BOOLEAN, 16,
15479             NULL, ZBEE_ZCL_GP_SINK_TBL_OPT_SECURITY_USE, NULL, HFILL }},
15480 
15481         { &hf_zbee_gp_sec_options_sec_level,
15482           { "Security Level", "zbee_zcl_general.gp.secur.secur_lev", FT_UINT8, BASE_HEX,
15483             VALS(zbee_zcl_gp_secur_levels), ZBEE_ZCL_GP_SECUR_OPT_SECUR_LEVEL, NULL, HFILL }},
15484         { &hf_zbee_gp_sec_options_sec_key_type,
15485           { "Security Key Type", "zbee_zcl_general.gp.secur.secur_key_type", FT_UINT8, BASE_HEX,
15486             VALS(zbee_zcl_gp_secur_key_types), ZBEE_ZCL_GP_SECUR_OPT_SECUR_KEY_TYPE, NULL, HFILL }},
15487 
15488         /* GP Proxy Table attribute */
15489         { &hf_zbee_gp_proxy_tbl_length,
15490           { "Proxy Table length", "zbee_zcl_general.gp.proxy_tbl_len", FT_UINT16, BASE_DEC,
15491             NULL, 0, NULL, HFILL }},
15492         { &hf_zbee_gp_proxy_tbl_entry_options,
15493           { "Options", "zbee_zcl_general.gp.proxy_tbl.entry.opt", FT_UINT16, BASE_HEX,
15494             NULL, 0, NULL, HFILL }},
15495         { &hf_zbee_gp_proxy_tbl_entry_ext_options,
15496           { "Extended Options", "zbee_zcl_general.gp.proxy_tbl.entry.ext_opt", FT_UINT8, BASE_HEX,
15497             NULL, 0, NULL, HFILL }},
15498 
15499         { &hf_zbee_gp_proxy_tbl_entry_options_app_id,
15500           { "ApplicationID", "zbee_zcl_general.gp.proxy_tbl.entry.opt.app_id", FT_UINT16, BASE_HEX,
15501             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_APP_ID, NULL, HFILL }},
15502         { &hf_zbee_gp_proxy_tbl_entry_options_entry_active,
15503           { "EntryActive", "zbee_zcl_general.gp.proxy_tbl.entry.opt.entry_active", FT_BOOLEAN, 16,
15504             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_ENTRY_ACTIVE, NULL, HFILL }},
15505         { &hf_zbee_gp_proxy_tbl_entry_options_entry_valid,
15506           { "EntryValid", "zbee_zcl_general.gp.proxy_tbl.entry.opt.entry_valid", FT_BOOLEAN, 16,
15507             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_ENTRY_VALID, NULL, HFILL }},
15508         { &hf_zbee_gp_proxy_tbl_entry_options_seq_num_cap,
15509           { "Sequence number capabilities", "zbee_zcl_general.gp.proxy_tbl.entry.opt.seq_num_cap", FT_BOOLEAN, 16,
15510             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_SEQ_NUMBER_CAP, NULL, HFILL }},
15511         { &hf_zbee_gp_proxy_tbl_entry_options_lw_ucast_gps,
15512           { "Lightweight Unicast GPS", "zbee_zcl_general.gp.proxy_tbl.entry.opt.lw_ucast_gps", FT_BOOLEAN, 16,
15513             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_LW_UCAST_GPS, NULL, HFILL }},
15514         { &hf_zbee_gp_proxy_tbl_entry_options_derived_group_gps,
15515           { "Derived  Group GPS", "zbee_zcl_general.gp.proxy_tbl.entry.opt.derived_group_gps", FT_BOOLEAN, 16,
15516             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_DERIVED_GROUP_GPS, NULL, HFILL }},
15517         { &hf_zbee_gp_proxy_tbl_entry_options_comm_group_gps,
15518           { "Commissioned Group GPS", "zbee_zcl_general.gp.proxy_tbl.entry.opt.comm_group_gps", FT_BOOLEAN, 16,
15519             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_COMM_GROUP_GPS, NULL, HFILL }},
15520         { &hf_zbee_gp_proxy_tbl_entry_options_first_to_forward,
15521           { "FirstToForward", "zbee_zcl_general.gp.proxy_tbl.entry.opt.first_to_forward", FT_BOOLEAN, 16,
15522             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_FIRST_TO_FORWARD, NULL, HFILL }},
15523         { &hf_zbee_gp_proxy_tbl_entry_options_in_range,
15524           { "InRange", "zbee_zcl_general.gp.proxy_tbl.entry.opt.in_range", FT_BOOLEAN, 16,
15525             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_IN_RANGE, NULL, HFILL }},
15526         { &hf_zbee_gp_proxy_tbl_entry_options_gpd_fixed,
15527           { "GPD Fixed", "zbee_zcl_general.gp.proxy_tbl.entry.opt.gpd_fixed", FT_BOOLEAN, 16,
15528             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_GPD_FIXED, NULL, HFILL }},
15529         { &hf_zbee_gp_proxy_tbl_entry_options_has_all_ucast_routes,
15530           { "HasAllUnicastRoutes", "zbee_zcl_general.gp.proxy_tbl.entry.opt.has_all_ucast_routes", FT_BOOLEAN, 16,
15531             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_HAS_ALL_UCAST_ROUTES, NULL, HFILL }},
15532         { &hf_zbee_gp_proxy_tbl_entry_options_assigned_alias,
15533           { "AssignedAlias", "zbee_zcl_general.gp.proxy_tbl.entry.opt.asn_alias", FT_BOOLEAN, 16,
15534             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_ASSIGNED_ALIAS, NULL, HFILL }},
15535         { &hf_zbee_gp_proxy_tbl_entry_options_sec_use,
15536           { "SecurityUse", "zbee_zcl_general.gp.proxy_tbl.entry.opt.secur_use", FT_BOOLEAN, 16,
15537             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_SECURITY_USE, NULL, HFILL }},
15538         { &hf_zbee_gp_proxy_tbl_entry_options_opt_ext,
15539           { "Options Extension", "zbee_zcl_general.gp.proxy_tbl.entry.opt.ext_opt", FT_BOOLEAN, 16,
15540             NULL, ZBEE_ZCL_GP_PROXY_TBL_OPT_OPTIONS_EXTENTIONS, NULL, HFILL }},
15541 
15542         { &hf_zbee_gp_proxy_tbl_entry_search_counter,
15543           { "Search Counter", "zbee_zcl_general.gp.proxy_tbl.entry.search_counter", FT_UINT8, BASE_DEC,
15544             NULL, 0, NULL, HFILL }},
15545 
15546         { &hf_zbee_gp_proxy_tbl_entry_ext_options_full_ucast_gps,
15547           { "Full unicast GPS", "zbee_zcl_general.gp.proxy_tbl.entry.ext_opt.full_ucast_gps", FT_BOOLEAN, 16,
15548             NULL, ZBEE_ZCL_GP_PROXY_TBL_EXT_OPT_FULL_UCAST_GPS, NULL, HFILL }},
15549 
15550         { &hf_zbee_gp_sink_address_list_length,
15551           { "Sink Address list length", "zbee_zcl_general.gp.sink_addr_list_len", FT_UINT8, BASE_DEC,
15552             NULL, 0, NULL, HFILL }},
15553 
15554         /* gppFunctionality attribute */
15555         { &hf_zbee_zcl_gp_attr_gpp_func,
15556           { "gppFunctionality", "zbee_zcl_general.gp.attr.gpp_func", FT_UINT24, BASE_HEX,
15557             NULL, 0, NULL, HFILL }},
15558 
15559         { &hf_zbee_zcl_gp_attr_gpp_func_fld_gp_feature,
15560           { "GP feature", "zbee_zcl_general.gp.attr.gpp_func.gp_feature", FT_BOOLEAN, 24,
15561             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GP_FEATURE, NULL, HFILL }},
15562         { &hf_zbee_zcl_gp_attr_gpp_func_fld_direct_comm,
15563           { "Direct communication", "zbee_zcl_general.gp.attr.gpp_func.direct_comm", FT_BOOLEAN, 24,
15564             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_DIRECT_COMM, NULL, HFILL }},
15565         { &hf_zbee_zcl_gp_attr_gpp_func_fld_derived_gcast_comm,
15566           { "Derived groupcast communication", "zbee_zcl_general.gp.attr.gpp_func.derived_gcast_comm", FT_BOOLEAN, 24,
15567             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_DERIVED_GCAST_COMM, NULL, HFILL }},
15568         { &hf_zbee_zcl_gp_attr_gpp_func_fld_pre_commissioned_gcast_comm,
15569           { "Pre-commissioned groupcast communication", "zbee_zcl_general.gp.attr.gpp_func.pre_commissioned_gcast_comm", FT_BOOLEAN, 24,
15570             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_PRE_COMMISSIONED_GCAST_COMM, NULL, HFILL }},
15571         { &hf_zbee_zcl_gp_attr_gpp_func_fld_full_ucast_comm,
15572           { "Full unicast communication", "zbee_zcl_general.gp.attr.gpp_func.full_ucast_comm", FT_BOOLEAN, 24,
15573             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_FULL_UCAST_COMM, NULL, HFILL }},
15574         { &hf_zbee_zcl_gp_attr_gpp_func_fld_lw_ucast_comm,
15575           { "Lightweight unicast communication", "zbee_zcl_general.gp.attr.gpp_func.lw_ucast_comm", FT_BOOLEAN, 24,
15576             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_LW_UCAST_COMM, NULL, HFILL }},
15577         { &hf_zbee_zcl_gp_attr_gpp_func_fld_bidir_op,
15578           { "Bidirectional operation", "zbee_zcl_general.gp.attr.gpp_func.bidir_op", FT_BOOLEAN, 24,
15579             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_BIDIR_OP, NULL, HFILL }},
15580         { &hf_zbee_zcl_gp_attr_gpp_func_fld_proxy_tbl_maintenance,
15581           { "Proxy Table maintenance", "zbee_zcl_general.gp.attr.gpp_func.proxy_tbl_maintenance", FT_BOOLEAN, 24,
15582               NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_PROXY_TBL_MAINTENANCE, NULL, HFILL }},
15583         { &hf_zbee_zcl_gp_attr_gpp_func_fld_gp_commissioning,
15584           { "GP commissioning", "zbee_zcl_general.gp.attr.gpp_func.gp_commissioning", FT_BOOLEAN, 24,
15585             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GP_COMMISSIONING, NULL, HFILL }},
15586         { &hf_zbee_zcl_gp_attr_gpp_func_fld_ct_based_commissioning,
15587           { "CT-based commissioning", "zbee_zcl_general.gp.attr.gpp_func.ct_based_commissioning", FT_BOOLEAN, 24,
15588             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_CT_BASED_COMMISSIONING, NULL, HFILL }},
15589         { &hf_zbee_zcl_gp_attr_gpp_func_fld_maintenance_of_gpd,
15590           { "Maintenance of GPD", "zbee_zcl_general.gp.attr.gpp_func.maintenance_of_gpd", FT_BOOLEAN, 24,
15591             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_MAINTENANCE_OF_GPD, NULL, HFILL }},
15592         { &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_00,
15593           { "gpdSecurityLevel = 0b00", "zbee_zcl_general.gp.attr.gpp_func.gpd_secur_lvl_00", FT_BOOLEAN, 24,
15594             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_SECUR_LVL_00, NULL, HFILL }},
15595         { &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_01,
15596           { "Deprecated: gpdSecurityLevel = 0b01", "zbee_zcl_general.gp.attr.gpp_func.gpd_secur_lvl_01", FT_BOOLEAN, 24,
15597             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_SECUR_LVL_01, NULL, HFILL }},
15598         { &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_10,
15599           { "gpdSecurityLevel = 0b10", "zbee_zcl_general.gp.attr.gpp_func.gpd_secur_lvl_10", FT_BOOLEAN, 24,
15600             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_SECUR_LVL_10, NULL, HFILL }},
15601         { &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_secur_lvl_11,
15602           { "gpdSecurityLevel = 0b11", "zbee_zcl_general.gp.attr.gpp_func.gpd_secur_lvl_11", FT_BOOLEAN, 24,
15603             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_SECUR_LVL_11, NULL, HFILL }},
15604         { &hf_zbee_zcl_gp_attr_gpp_func_fld_gpd_ieee_address,
15605           { "GPD IEEE address", "zbee_zcl_general.gp.attr.gpp_func.gpd_ieee_address", FT_BOOLEAN, 24,
15606             NULL, ZBEE_ZCL_GP_ATTR_GPP_FUNC_FLD_GPD_IEEE_ADDRESS, NULL, HFILL }},
15607 
15608         /* gppActiveFunctionality attribute */
15609         { &hf_zbee_zcl_gp_attr_gpp_active_func,
15610           { "gppActiveFunctionality", "zbee_zcl_general.gp.attr.gpp_active_func", FT_UINT24, BASE_HEX,
15611             NULL, 0, NULL, HFILL }},
15612 
15613         { &hf_zbee_zcl_gp_attr_gpp_active_func_fld_gp_functionality,
15614           { "GP functionality", "zbee_zcl_general.gp.attr.gpp_active_func.gp_functionality", FT_BOOLEAN, 24,
15615             NULL, ZBEE_ZCL_GP_ATTR_GPP_ACTIVE_FUNC_FLD_GP_FUNCTIONALITY, NULL, HFILL }},
15616 
15617         /* gpsFunctionality attribute */
15618         { &hf_zbee_zcl_gp_attr_gps_func,
15619           { "gpsFunctionality", "zbee_zcl_general.gp.attr.gps_func", FT_UINT24, BASE_HEX,
15620             NULL, 0, NULL, HFILL }},
15621 
15622         { &hf_zbee_zcl_gp_attr_gps_func_fld_gp_feature,
15623           { "GP feature", "zbee_zcl_general.gp.attr.gps_func.gp_feature", FT_BOOLEAN, 24,
15624             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GP_FEATURE, NULL, HFILL }},
15625         { &hf_zbee_zcl_gp_attr_gps_func_fld_direct_comm,
15626           { "Direct communication", "zbee_zcl_general.gp.attr.gps_func.direct_comm", FT_BOOLEAN, 24,
15627             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_DIRECT_COMM, NULL, HFILL }},
15628         { &hf_zbee_zcl_gp_attr_gps_func_fld_derived_gcast_comm,
15629           { "Derived groupcast communication", "zbee_zcl_general.gp.attr.gps_func.derived_gcast_comm", FT_BOOLEAN, 24,
15630             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_DERIVED_GCAST_COMM, NULL, HFILL }},
15631         { &hf_zbee_zcl_gp_attr_gps_func_fld_pre_commissioned_gcast_comm,
15632           { "Pre-commissioned groupcast communication", "zbee_zcl_general.gp.attr.gps_func.pre_commissioned_gcast_comm", FT_BOOLEAN, 24,
15633             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_PRE_COMMISSIONED_GCAST_COMM, NULL, HFILL }},
15634         { &hf_zbee_zcl_gp_attr_gps_func_fld_full_ucast_comm,
15635           { "Full unicast communication", "zbee_zcl_general.gp.attr.gps_func.full_ucast_comm", FT_BOOLEAN, 24,
15636             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_FULL_UCAST_COMM, NULL, HFILL }},
15637         { &hf_zbee_zcl_gp_attr_gps_func_fld_lw_ucast_comm,
15638           { "Lightweight unicast communication", "zbee_zcl_general.gp.attr.gps_func.lw_ucast_comm", FT_BOOLEAN, 24,
15639             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_LW_UCAST_COMM, NULL, HFILL }},
15640         { &hf_zbee_zcl_gp_attr_gps_func_fld_proximity_bidir_op,
15641           { "Proximity bidirectional operation", "zbee_zcl_general.gp.attr.gps_func.proximity_bidir_op", FT_BOOLEAN, 24,
15642             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_PROXIMITY_BIDIR_OP, NULL, HFILL }},
15643         { &hf_zbee_zcl_gp_attr_gps_func_fld_multi_hop_bidir_op,
15644           { "Multi-hop bidirectional operation", "zbee_zcl_general.gp.attr.gps_func.multi_hop_bidir_op", FT_BOOLEAN, 24,
15645               NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_MULTI_HOP_BIDIR_OP, NULL, HFILL }},
15646         { &hf_zbee_zcl_gp_attr_gps_func_fld_proxy_tbl_maintenance,
15647           { "Proxy Table maintenance", "zbee_zcl_general.gp.attr.gps_func.proxy_tbl_maintenance", FT_BOOLEAN, 24,
15648               NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_PROXY_TBL_MAINTENANCE, NULL, HFILL }},
15649         { &hf_zbee_zcl_gp_attr_gps_func_fld_proximity_commissioning,
15650           { "Proximity commissioning", "zbee_zcl_general.gp.attr.gps_func.proximity_commissioning", FT_BOOLEAN, 24,
15651               NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_PROXIMITY_COMMISSIONING, NULL, HFILL }},
15652         { &hf_zbee_zcl_gp_attr_gps_func_fld_multi_hop_commissioning,
15653           { "Multi-hop commissioning","zbee_zcl_general.gp.attr.gps_func.multi_hop_commissioning", FT_BOOLEAN, 24,
15654               NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_MULTI_HOP_COMMISSIONING, NULL, HFILL }},
15655         { &hf_zbee_zcl_gp_attr_gps_func_fld_ct_based_commissioning,
15656           { "CT-based commissioning", "zbee_zcl_general.gp.attr.gps_func.ct_based_commissioning", FT_BOOLEAN, 24,
15657             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_CT_BASED_COMMISSIONING, NULL, HFILL }},
15658         { &hf_zbee_zcl_gp_attr_gps_func_fld_maintenance_of_gpd,
15659           { "Maintenance of GPD", "zbee_zcl_general.gp.attr.gps_func.maintenance_of_gpd", FT_BOOLEAN, 24,
15660               NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_MAINTENANCE_OF_GPD, NULL, HFILL }},
15661         { &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_00,
15662           { "gpdSecurityLevel = 0b00", "zbee_zcl_general.gp.attr.gps_func.gpd_secur_lvl_00", FT_BOOLEAN, 24,
15663             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_SECUR_LVL_00, NULL, HFILL }},
15664         { &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_01,
15665           { "Deprecated: gpdSecurityLevel = 0b01", "zbee_zcl_general.gp.attr.gps_func.gpd_secur_lvl_01", FT_BOOLEAN, 24,
15666             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_SECUR_LVL_01, NULL, HFILL }},
15667         { &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_10,
15668           { "gpdSecurityLevel = 0b10", "zbee_zcl_general.gp.attr.gps_func.gpd_secur_lvl_10", FT_BOOLEAN, 24,
15669             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_SECUR_LVL_10, NULL, HFILL }},
15670         { &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_secur_lvl_11,
15671           { "gpdSecurityLevel = 0b11", "zbee_zcl_general.gp.attr.gps_func.gpd_secur_lvl_11", FT_BOOLEAN, 24,
15672             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_SECUR_LVL_11, NULL, HFILL }},
15673         { &hf_zbee_zcl_gp_attr_gps_func_fld_sink_tbl_based_gcast_forwarding,
15674           { "Sink Table-based groupcast forwarding", "zbee_zcl_general.gp.attr.gps_func.sink_tbl_based_gcast_forwarding", FT_BOOLEAN, 24,
15675             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_SINK_TBL_BASED_GCAST_FORWARDING, NULL, HFILL }},
15676         { &hf_zbee_zcl_gp_attr_gps_func_fld_translation_table,
15677           { "Translation Table", "zbee_zcl_general.gp.attr.gps_func.translation_table", FT_BOOLEAN, 24,
15678             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_TRANSLATION_TABLE, NULL, HFILL }},
15679         { &hf_zbee_zcl_gp_attr_gps_func_fld_gpd_ieee_address,
15680           { "GPD IEEE address", "zbee_zcl_general.gp.attr.gps_func.gpd_ieee_address", FT_BOOLEAN, 24,
15681             NULL, ZBEE_ZCL_GP_ATTR_GPS_FUNC_FLD_GPD_IEEE_ADDRESS, NULL, HFILL }},
15682 
15683         /* gpsActiveFunctionality attribute */
15684         { &hf_zbee_zcl_gp_attr_gps_active_func,
15685           { "gpsActiveFunctionality", "zbee_zcl_general.gp.attr.gps_active_func", FT_UINT24, BASE_HEX,
15686             NULL, 0, NULL, HFILL }},
15687 
15688         { &hf_zbee_zcl_gp_attr_gps_active_func_fld_gp_functionality,
15689           { "GP functionality", "zbee_zcl_general.gp.attr.gps_active_func.gp_functionality", FT_BOOLEAN, 24,
15690             NULL, ZBEE_ZCL_GP_ATTR_GPS_ACTIVE_FUNC_FLD_GP_FUNCTIONALITY, NULL, HFILL }},
15691 
15692         /* gpsCommunicationMode attribute */
15693         { &hf_zbee_zcl_gp_attr_gps_communication_mode,
15694           { "gpsCommunicationMode", "zbee_zcl_general.gp.attr.gps_communication_mode", FT_UINT8, BASE_HEX,
15695             NULL, 0, NULL, HFILL }},
15696 
15697         { &hf_zbee_zcl_gp_attr_gps_communication_mode_fld_mode,
15698           { "Mode", "zbee_zcl_general.gp.attr.gps_communication_mode.mode", FT_UINT8, BASE_HEX,
15699             VALS(zbee_zcl_gp_communication_modes), ZBEE_ZCL_GP_ATTR_GPS_COMMUNICATION_MODE_FLD_MODE, NULL, HFILL }},
15700 
15701         /* gpsCommissioningExitMode attribute */
15702         { &hf_zbee_zcl_gp_attr_gps_comm_exit_mode,
15703           { "gpsCommissioningExitMode", "zbee_zcl_general.gp.attr.gps_comm_exit_mode", FT_UINT8, BASE_HEX,
15704             NULL, 0, NULL, HFILL }},
15705 
15706         { &hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_comm_window_expire,
15707           { "On CommissioningWindow expiration", "zbee_zcl_general.gp.attr.gps_comm_exit_mode.on_comm_window_expire",
15708             FT_BOOLEAN, 8, NULL, ZBEE_ZCL_GP_ATTR_GPS_COMM_EXIT_MODE_FLD_ON_COMM_WINDOW_EXPIRE, NULL, HFILL }},
15709         { &hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_pairing_success,
15710           { "On first Pairing success", "zbee_zcl_general.gp.attr.gps_comm_exit_mode.on_pairing_success",
15711             FT_BOOLEAN, 8, NULL, ZBEE_ZCL_GP_ATTR_GPS_COMM_EXIT_MODE_FLD_ON_PAIRING_SUCCESS, NULL, HFILL }},
15712         { &hf_zbee_zcl_gp_attr_gps_comm_exit_mode_fld_on_gp_proxy_comm_mode,
15713           { "On GP Proxy Commissioning Mode (exit)", "zbee_zcl_general.gp.attr.gps_comm_exit_mode.on_gp_proxy_comm_mode",
15714             FT_BOOLEAN, 8, NULL, ZBEE_ZCL_GP_ATTR_GPS_COMM_EXIT_MODE_FLD_ON_GP_PROXY_COMM_MODE, NULL, HFILL }},
15715 
15716         /* gpsSecurityLevel attribute */
15717         { &hf_zbee_zcl_gp_attr_gps_secur_lvl,
15718           { "gpsSecurityLevel", "zbee_zcl_general.gp.attr.gps_secur_lvl", FT_UINT8, BASE_HEX,
15719             NULL, 0, NULL, HFILL }},
15720 
15721         { &hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_min_gpd_secur_lvl,
15722           { "Minimal GPD Security Level", "zbee_zcl_general.gp.attr.gps_secur_lvl.min_gpd_secur_lvl", FT_UINT8, BASE_HEX,
15723             VALS(zbee_zcl_gp_secur_levels), ZBEE_ZCL_GP_ATTR_GPS_SECUR_LVL_FLD_MIN_GPD_SECUR_LVL, NULL, HFILL }},
15724         { &hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_protection_with_gp_link_key,
15725           { "Protection with  gpLinkKey", "zbee_zcl_general.gp.attr.gps_secur_lvl.protection_with_gp_link_key", FT_BOOLEAN, 8,
15726             NULL, ZBEE_ZCL_GP_ATTR_GPS_SECUR_LVL_FLD_PROTECTION_WITH_GP_LINK_KEY, NULL, HFILL }},
15727         { &hf_zbee_zcl_gp_attr_gps_secur_lvl_fld_involve_tc,
15728           { "Involve TC", "zbee_zcl_general.gp.attr.gps_secur_lvl.involve_tc", FT_BOOLEAN, 8,
15729             NULL, ZBEE_ZCL_GP_ATTR_GPS_SECUR_LVL_FLD_INVOLVE_TC, NULL, HFILL }}
15730     };
15731 
15732     /* ZCL Green Power subtrees */
15733     static gint *ett[] = {
15734         &ett_zbee_zcl_gp,
15735         &ett_zbee_gp_cmd_proxy_commissioning_mode_options,
15736         &ett_zbee_gp_cmd_proxy_commissioning_mode_exit_mode,
15737         &ett_zbee_gp_cmd_commissioning_notification_options,
15738         &ett_zbee_gp_gpp_gpd_link,
15739         &ett_zbee_gp_cmd_notification_options,
15740         &ett_zbee_gp_cmd_pairing_options,
15741         &ett_zbee_gp_cmd_response_options,
15742         &ett_zbee_gp_cmd_response_tx_channel,
15743         &ett_zbee_gp_cmd_pc_actions,
15744         &ett_zbee_gp_cmd_pc_options,
15745         &ett_zbee_zcl_gp_group_list,
15746         &ett_zbee_gp_cmd_pc_secur_options,
15747         &ett_zbee_gp_cmd_pc_app_info,
15748         &ett_zbee_zcl_gp_ep,
15749         &ett_zbee_zcl_gp_cmds,
15750         &ett_zbee_zcl_gp_clusters,
15751         &ett_zbee_zcl_gp_srv_clusters,
15752         &ett_zbee_zcl_gp_cli_clusters,
15753         &ett_zbee_zcl_proxy_sink_tbl_req_options,
15754         &ett_zbee_zcl_gp_cmd_sink_comm_mode_options,
15755         &ett_zbee_gp_sink_tbl,
15756         &ett_zbee_gp_sink_tbl_entry,
15757         &ett_zbee_gp_sink_tbl_entry_options,
15758         &ett_zbee_gp_sec_options,
15759         &ett_zbee_gp_proxy_tbl,
15760         &ett_zbee_gp_proxy_tbl_entry,
15761         &ett_zbee_gp_proxy_tbl_entry_options,
15762         &ett_zbee_gp_proxy_tbl_entry_ext_options,
15763         &ett_zbee_gp_sink_address_list,
15764         &ett_zbee_zcl_gp_attr_gpp_func,
15765         &ett_zbee_zcl_gp_attr_gpp_active_func,
15766         &ett_zbee_zcl_gp_attr_gps_func,
15767         &ett_zbee_zcl_gp_attr_gps_active_func,
15768         &ett_zbee_zcl_gp_attr_gps_communication_mode,
15769         &ett_zbee_zcl_gp_attr_gps_comm_exit_mode,
15770         &ett_zbee_zcl_gp_attr_gps_secur_lvl
15771     };
15772 
15773 
15774     /* Register the ZigBee ZCL Green Power cluster protocol name and description */
15775     proto_zbee_zcl_gp = proto_register_protocol("ZigBee ZCL Green Power", "ZCL Green Power", ZBEE_PROTOABBREV_ZCL_GP);
15776     proto_register_field_array(proto_zbee_zcl_gp, hf, array_length(hf));
15777     proto_register_subtree_array(ett, array_length(ett));
15778 
15779     /* Register the ZigBee ZCL Green Power dissector. */
15780     register_dissector(ZBEE_PROTOABBREV_ZCL_GP, dissect_zbee_zcl_gp, proto_zbee_zcl_gp);
15781 } /*proto_register_zbee_zcl_gp*/
15782 
15783 /**
15784  *      proto_reg_handoff_zbee_zcl_gp
15785  *
15786  *      Hands off the ZCL Green Power dissector.
15787  */
15788 void
proto_reg_handoff_zbee_zcl_gp(void)15789 proto_reg_handoff_zbee_zcl_gp(void)
15790 {
15791     zgp_handle = find_dissector(ZBEE_PROTOABBREV_NWK_GP_CMD);
15792 
15793     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_GP,
15794                             proto_zbee_zcl_gp,
15795                             ett_zbee_zcl_gp,
15796                             ZBEE_ZCL_CID_GP,
15797                             ZBEE_MFG_CODE_NONE,
15798                             hf_zbee_zcl_gp_attr_id,
15799                             hf_zbee_zcl_gp_attr_id,
15800                             hf_zbee_zcl_gp_srv_rx_cmd_id,
15801                             hf_zbee_zcl_gp_srv_tx_cmd_id,
15802                             (zbee_zcl_fn_attr_data)dissect_zcl_gp_attr_data
15803                          );
15804 } /*proto_reg_handoff_zbee_zcl_gp*/
15805 
15806 /* ########################################################################## */
15807 /* #### (0x1000) TOUCHLINK COMMISSIONING CLUSTER ############################ */
15808 /* ########################################################################## */
15809 
15810 /*************************/
15811 /* Defines               */
15812 /*************************/
15813 /*Server commands received*/
15814 #define ZBEE_ZCL_CMD_ID_SCAN_REQUEST                    0x00
15815 #define ZBEE_ZCL_CMD_ID_DEVICE_INFO_REQUEST             0x02
15816 #define ZBEE_ZCL_CMD_ID_IDENTIFY_REQUEST                0x06
15817 #define ZBEE_ZCL_CMD_ID_FACTORT_RESET_REQUEST           0x07
15818 #define ZBEE_ZCL_CMD_ID_NETWORK_START_REQUEST           0x10
15819 #define ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ROUTER_REQUEST     0x12
15820 #define ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ENDDEV_REQUEST     0x14
15821 #define ZBEE_ZCL_CMD_ID_NETWORK_UPDATE_REQUEST          0x16
15822 #define ZBEE_ZCL_CMD_ID_GET_GROUP_IDENTIFIERS_REQUEST   0x41
15823 #define ZBEE_ZCL_CMD_ID_GET_ENDPOINT_LIST_REQUEST       0x42
15824 
15825 /*Server commands generated*/
15826 #define ZBEE_ZCL_CMD_ID_SCAN_RESPONSE                   0x01
15827 #define ZBEE_ZCL_CMD_ID_DEVICE_INFO_RESPONSE            0x03
15828 #define ZBEE_ZCL_CMD_ID_NETWORK_START_RESPONSE          0x11
15829 #define ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ROUTER_RESPONSE    0x13
15830 #define ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ENDDEV_RESPONSE    0x15
15831 #define ZBEE_ZCL_CMD_ID_ENDPOINT_INFORMATION            0x40
15832 #define ZBEE_ZCL_CMD_ID_GET_GROUP_IDENTIFIERS_RESPONSE  0x41
15833 #define ZBEE_ZCL_CMD_ID_GET_ENDPOINT_LIST_RESPONSE      0x42
15834 
15835 /*ZigBee Information Mask Value*/
15836 #define ZBEE_ZCL_TOUCHLINK_ZBEE_INFO_TYPE       0x03
15837 #define ZBEE_ZCL_TOUCHLINK_ZBEE_INFO_RXIDLE     0x04
15838 
15839 /*Touchlink Information Mask Values*/
15840 #define ZBEE_ZCL_TOUCHLINK_INFO_FACTORY         0x01
15841 #define ZBEE_ZCL_TOUCHLINK_INFO_ASSIGNMENT      0x02
15842 #define ZBEE_ZCL_TOUCHLINK_INFO_INITIATOR       0x10
15843 #define ZBEE_ZCL_TOUCHLINK_INFO_UNDEFINED       0x20
15844 
15845 /*Touchlink Key Indicies*/
15846 #define ZBEE_ZCL_TOUCHLINK_KEYID_DEVELOPMENT    0
15847 #define ZBEE_ZCL_TOUCHLINK_KEYID_MASTER         4
15848 #define ZBEE_ZCL_TOUCHLINK_KEYID_CERTIFICATION  15
15849 
15850 /*************************/
15851 /* Function Declarations */
15852 /*************************/
15853 void proto_register_zbee_zcl_touchlink(void);
15854 void proto_reg_handoff_zbee_zcl_touchlink(void);
15855 
15856 /*************************/
15857 /* Global Variables      */
15858 /*************************/
15859 /* Initialize the protocol and registered fields */
15860 static int proto_zbee_zcl_touchlink = -1;
15861 
15862 static int hf_zbee_zcl_touchlink_rx_cmd_id = -1;
15863 static int hf_zbee_zcl_touchlink_tx_cmd_id = -1;
15864 static int hf_zbee_zcl_touchlink_transaction_id = -1;
15865 static int hf_zbee_zcl_touchlink_zbee = -1;
15866 static int hf_zbee_zcl_touchlink_zbee_type = -1;
15867 static int hf_zbee_zcl_touchlink_zbee_rxidle = -1;
15868 static int hf_zbee_zcl_touchlink_info = -1;
15869 static int hf_zbee_zcl_touchlink_info_factory = -1;
15870 static int hf_zbee_zcl_touchlink_info_assignment = -1;
15871 static int hf_zbee_zcl_touchlink_info_initiator = -1;
15872 static int hf_zbee_zcl_touchlink_info_undefined = -1;
15873 static int hf_zbee_zcl_touchlink_start_index = -1;
15874 static int hf_zbee_zcl_touchlink_ident_duration = -1;
15875 
15876 static int hf_zbee_zcl_touchlink_rssi_correction = -1;
15877 static int hf_zbee_zcl_touchlink_response_id = -1;
15878 static int hf_zbee_zcl_touchlink_ext_panid = -1;
15879 static int hf_zbee_zcl_touchlink_nwk_update_id = -1;
15880 static int hf_zbee_zcl_touchlink_channel = -1;
15881 static int hf_zbee_zcl_touchlink_nwk_addr = -1;
15882 static int hf_zbee_zcl_touchlink_ext_addr = -1;
15883 static int hf_zbee_zcl_touchlink_panid = -1;
15884 static int hf_zbee_zcl_touchlink_sub_devices = -1;
15885 static int hf_zbee_zcl_touchlink_total_groups = -1;
15886 static int hf_zbee_zcl_touchlink_endpoint = -1;
15887 static int hf_zbee_zcl_touchlink_profile_id = -1;
15888 static int hf_zbee_zcl_touchlink_device_id = -1;
15889 static int hf_zbee_zcl_touchlink_version = -1;
15890 static int hf_zbee_zcl_touchlink_group_count = -1;
15891 static int hf_zbee_zcl_touchlink_group_begin = -1;
15892 static int hf_zbee_zcl_touchlink_group_end = -1;
15893 static int hf_zbee_zcl_touchlink_group_type = -1;
15894 static int hf_zbee_zcl_touchlink_group_id = -1;
15895 static int hf_zbee_zcl_touchlink_addr_range_begin = -1;
15896 static int hf_zbee_zcl_touchlink_addr_range_end = -1;
15897 static int hf_zbee_zcl_touchlink_group_range_begin = -1;
15898 static int hf_zbee_zcl_touchlink_group_range_end = -1;
15899 static int hf_zbee_zcl_touchlink_key_bitmask = -1;
15900 static int hf_zbee_zcl_touchlink_key_bit_dev = -1;
15901 static int hf_zbee_zcl_touchlink_key_bit_master = -1;
15902 static int hf_zbee_zcl_touchlink_key_bit_cert = -1;
15903 static int hf_zbee_zcl_touchlink_key_index = -1;
15904 static int hf_zbee_zcl_touchlink_key = -1;
15905 static int hf_zbee_zcl_touchlink_init_addr = -1;
15906 static int hf_zbee_zcl_touchlink_init_eui64 = -1;
15907 static int hf_zbee_zcl_touchlink_status = -1;
15908 
15909 /* Initialize the subtree pointers */
15910 static gint ett_zbee_zcl_touchlink = -1;
15911 static gint ett_zbee_zcl_touchlink_zbee = -1;
15912 static gint ett_zbee_zcl_touchlink_info = -1;
15913 static gint ett_zbee_zcl_touchlink_keybits = -1;
15914 static gint ett_zbee_zcl_touchlink_groups = -1;
15915 
15916 /* Command names */
15917 static const value_string zbee_zcl_touchlink_rx_cmd_names[] = {
15918     { ZBEE_ZCL_CMD_ID_SCAN_REQUEST, "Scan Request" },
15919     { ZBEE_ZCL_CMD_ID_DEVICE_INFO_REQUEST, "Device Information Request" },
15920     { ZBEE_ZCL_CMD_ID_IDENTIFY_REQUEST, "Identify Request" },
15921     { ZBEE_ZCL_CMD_ID_FACTORT_RESET_REQUEST, "Reset to Factory New Request" },
15922     { ZBEE_ZCL_CMD_ID_NETWORK_START_REQUEST, "Network Start Request" },
15923     { ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ROUTER_REQUEST, "Network Join Router Request" },
15924     { ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ENDDEV_REQUEST, "Network Join End Device Request" },
15925     { ZBEE_ZCL_CMD_ID_NETWORK_UPDATE_REQUEST, "Network Update Request" },
15926     { ZBEE_ZCL_CMD_ID_GET_GROUP_IDENTIFIERS_REQUEST, "Get Group Identifiers Request" },
15927     { ZBEE_ZCL_CMD_ID_GET_ENDPOINT_LIST_REQUEST, "Get Group Identifiers Request" },
15928     { 0, NULL }
15929 };
15930 static const value_string zbee_zcl_touchlink_tx_cmd_names[] = {
15931     { ZBEE_ZCL_CMD_ID_SCAN_RESPONSE, "Scan Response" },
15932     { ZBEE_ZCL_CMD_ID_DEVICE_INFO_RESPONSE, "Device Information Response" },
15933     { ZBEE_ZCL_CMD_ID_NETWORK_START_RESPONSE, "Network Start Response" },
15934     { ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ROUTER_RESPONSE, "Network Join Router Response" },
15935     { ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ENDDEV_RESPONSE, "Network Join End Device Response" },
15936     { ZBEE_ZCL_CMD_ID_ENDPOINT_INFORMATION, "Endpoint Information" },
15937     { ZBEE_ZCL_CMD_ID_GET_GROUP_IDENTIFIERS_RESPONSE, "Get Group Identifiers Response" },
15938     { ZBEE_ZCL_CMD_ID_GET_ENDPOINT_LIST_RESPONSE, "Get Group Identifiers Response" },
15939     { 0, NULL }
15940 };
15941 
15942 /* ZigBee logical types */
15943 static const value_string zbee_zcl_touchlink_zbee_type_names[] = {
15944     { 0, "coordinator" },
15945     { 1, "router" },
15946     { 2, "end device" },
15947     { 0, NULL }
15948 };
15949 
15950 static const value_string zbee_zcl_touchlink_status_names[] = {
15951     { 0x00, "Success" },
15952     { 0x01, "Failure" },
15953     { 0, NULL }
15954 };
15955 
15956 static const value_string zbee_zcl_touchlink_keyid_names[] = {
15957     { ZBEE_ZCL_TOUCHLINK_KEYID_DEVELOPMENT, "Development Key" },
15958     { ZBEE_ZCL_TOUCHLINK_KEYID_MASTER, "Master Key" },
15959     { ZBEE_ZCL_TOUCHLINK_KEYID_CERTIFICATION, "Certification Key" },
15960     { 0, NULL }
15961 };
15962 
15963 #define ZBEE_ZCL_TOUCHLINK_NUM_KEYID    16
15964 #define ZBEE_ZCL_TOUCHLINK_KEY_SIZE     16
15965 
15966 /*************************/
15967 /* Function Bodies       */
15968 /*************************/
15969 /**
15970  *This function decodes the Scan Request payload.
15971  *
15972  *@param  tvb the tv buffer of the current data_type
15973  *@param  tree the tree to append this item to
15974  *@param  offset offset of data in tvb
15975 */
15976 static void
dissect_zcl_touchlink_scan_request(tvbuff_t * tvb,proto_tree * tree,guint * offset)15977 dissect_zcl_touchlink_scan_request(tvbuff_t *tvb, proto_tree *tree, guint *offset)
15978 {
15979     static int * const zbee_info_flags[] = {
15980         &hf_zbee_zcl_touchlink_zbee_type,
15981         &hf_zbee_zcl_touchlink_zbee_rxidle,
15982         NULL
15983     };
15984     static int * const zll_info_flags[] = {
15985         &hf_zbee_zcl_touchlink_info_factory,
15986         &hf_zbee_zcl_touchlink_info_assignment,
15987         &hf_zbee_zcl_touchlink_info_initiator,
15988         &hf_zbee_zcl_touchlink_info_undefined,
15989         NULL
15990     };
15991     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_touchlink_zbee, ett_zbee_zcl_touchlink_zbee, zbee_info_flags, ENC_LITTLE_ENDIAN);
15992     *offset += 1;
15993     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_touchlink_info, ett_zbee_zcl_touchlink_info, zll_info_flags, ENC_LITTLE_ENDIAN);
15994     *offset += 1;
15995 } /*dissect_zcl_touchlink_scan_request*/
15996 
15997 /**
15998  *This function decodes the Identify Request payload.
15999  *
16000  *@param  tvb the tv buffer of the current data_type
16001  *@param  tree the tree to append this item to
16002  *@param  offset offset of data in tvb
16003 */
16004 static void
dissect_zcl_touchlink_identify_request(tvbuff_t * tvb,proto_tree * tree,guint * offset)16005 dissect_zcl_touchlink_identify_request(tvbuff_t *tvb, proto_tree *tree, guint *offset)
16006 {
16007     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_ident_duration, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16008     *offset += 2;
16009 } /*dissect_zcl_touchlink_identify_request*/
16010 
16011 /**
16012  *This function decodes the Network Start Request payload.
16013  *
16014  *@param  tvb the tv buffer of the current data_type
16015  *@param  tree the tree to append this item to
16016  *@param  offset offset of data in tvb
16017 */
16018 static void
dissect_zcl_touchlink_network_start_request(tvbuff_t * tvb,proto_tree * tree,guint * offset)16019 dissect_zcl_touchlink_network_start_request(tvbuff_t *tvb, proto_tree *tree, guint *offset)
16020 {
16021     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_ext_panid, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
16022     *offset += 8;
16023     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_key_index, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16024     *offset += 1;
16025     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_key, tvb, *offset, 16, ENC_NA);
16026     *offset += 16;
16027     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_channel, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16028     *offset += 1;
16029     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_panid, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16030     *offset += 2;
16031     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16032     *offset += 2;
16033     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_begin, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16034     *offset += 2;
16035     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_end, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16036     *offset += 2;
16037     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_addr_range_begin, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16038     *offset += 2;
16039     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_addr_range_end, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16040     *offset += 2;
16041     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_range_begin, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16042     *offset += 2;
16043     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_range_end, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16044     *offset += 2;
16045     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_init_eui64, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
16046     *offset += 8;
16047     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_init_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16048     *offset += 2;
16049 } /*dissect_zcl_touchlink_network_start_request*/
16050 
16051 /**
16052  *This function decodes the Network Join Router/EndDevice Request payloads.
16053  *
16054  *@param  tvb the tv buffer of the current data_type
16055  *@param  tree the tree to append this item to
16056  *@param  offset offset of data in tvb
16057 */
16058 static void
dissect_zcl_touchlink_network_join_request(tvbuff_t * tvb,proto_tree * tree,guint * offset)16059 dissect_zcl_touchlink_network_join_request(tvbuff_t *tvb, proto_tree *tree, guint *offset)
16060 {
16061     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_ext_panid, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
16062     *offset += 8;
16063     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_key_index, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16064     *offset += 1;
16065     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_key, tvb, *offset, 16, ENC_NA);
16066     *offset += 16;
16067     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_update_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16068     *offset += 1;
16069     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_channel, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16070     *offset += 1;
16071     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_panid, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16072     *offset += 2;
16073     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16074     *offset += 2;
16075     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_begin, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16076     *offset += 2;
16077     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_end, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16078     *offset += 2;
16079     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_addr_range_begin, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16080     *offset += 2;
16081     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_addr_range_end, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16082     *offset += 2;
16083     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_range_begin, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16084     *offset += 2;
16085     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_range_end, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16086     *offset += 2;
16087 } /*dissect_zcl_touchlink_network_join_request*/
16088 
16089 /**
16090  *This function decodes the Scan Response payload.
16091  *
16092  *@param  tvb the tv buffer of the current data_type
16093  *@param  tree the tree to append this item to
16094  *@param  offset offset of data in tvb
16095 */
16096 static void
dissect_zcl_touchlink_network_update_request(tvbuff_t * tvb,proto_tree * tree,guint * offset)16097 dissect_zcl_touchlink_network_update_request(tvbuff_t *tvb, proto_tree *tree, guint *offset)
16098 {
16099     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_ext_panid, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
16100     *offset += 8;
16101     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_update_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16102     *offset += 1;
16103     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_channel, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16104     *offset += 1;
16105     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_panid, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16106     *offset += 2;
16107     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16108     *offset += 2;
16109 } /*dissect_zcl_touchlink_network_update_request*/
16110 
16111 /**
16112  *This function decodes the Scan Response payload.
16113  *
16114  *@param  tvb the tv buffer of the current data_type
16115  *@param  tree the tree to append this item to
16116  *@param  offset offset of data in tvb
16117 */
16118 static void
dissect_zcl_touchlink_scan_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)16119 dissect_zcl_touchlink_scan_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
16120 {
16121     static int * const zbee_info_flags[] = {
16122         &hf_zbee_zcl_touchlink_zbee_type,
16123         &hf_zbee_zcl_touchlink_zbee_rxidle,
16124         NULL
16125     };
16126     static int * const zll_info_flags[] = {
16127         &hf_zbee_zcl_touchlink_info_factory,
16128         &hf_zbee_zcl_touchlink_info_assignment,
16129         &hf_zbee_zcl_touchlink_info_initiator,
16130         &hf_zbee_zcl_touchlink_info_undefined,
16131         NULL
16132     };
16133     static int * const zll_keybit_flags[] = {
16134         &hf_zbee_zcl_touchlink_key_bit_dev,
16135         &hf_zbee_zcl_touchlink_key_bit_master,
16136         &hf_zbee_zcl_touchlink_key_bit_cert,
16137         NULL
16138     };
16139     guint8 subdev;
16140 
16141     /* Parse out the fixed-format stuff */
16142     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_rssi_correction, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16143     *offset += 1;
16144     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_touchlink_zbee, ett_zbee_zcl_touchlink_zbee, zbee_info_flags, ENC_LITTLE_ENDIAN);
16145     *offset += 1;
16146     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_touchlink_info, ett_zbee_zcl_touchlink_info, zll_info_flags, ENC_LITTLE_ENDIAN);
16147     *offset += 1;
16148     proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_touchlink_key_bitmask, ett_zbee_zcl_touchlink_keybits, zll_keybit_flags, ENC_LITTLE_ENDIAN);
16149     *offset += 2;
16150     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_response_id, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
16151     *offset += 4;
16152     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_ext_panid, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
16153     *offset += 8;
16154     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_update_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16155     *offset += 1;
16156     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_channel, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16157     *offset += 1;
16158     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_panid, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16159     *offset += 2;
16160     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16161     *offset += 2;
16162     subdev = tvb_get_guint8(tvb, *offset);
16163     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_sub_devices, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16164     *offset += 1;
16165     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_total_groups, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16166     *offset += 1;
16167 
16168     /* The remaining fields are only present when sub-devices is one. */
16169     if (subdev == 1) {
16170         proto_tree_add_item(tree, hf_zbee_zcl_touchlink_endpoint, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16171         *offset += 1;
16172         proto_tree_add_item(tree, hf_zbee_zcl_touchlink_profile_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16173         *offset += 2;
16174         proto_tree_add_item(tree, hf_zbee_zcl_touchlink_device_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16175         *offset += 2;
16176         proto_tree_add_item(tree, hf_zbee_zcl_touchlink_version, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16177         *offset += 1;
16178         proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_count, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16179         *offset += 1;
16180     }
16181 } /*dissect_zcl_touchlink_scan_response*/
16182 
16183 /**
16184  *This function decodes the Network Start Response payload.
16185  *
16186  *@param  tvb the tv buffer of the current data_type
16187  *@param  tree the tree to append this item to
16188  *@param  offset offset of data in tvb
16189 */
16190 static void
dissect_zcl_touchlink_network_start_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)16191 dissect_zcl_touchlink_network_start_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
16192 {
16193     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16194     *offset += 1;
16195     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_ext_panid, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
16196     *offset += 8;
16197     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_update_id, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16198     *offset += 1;
16199     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_channel, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16200     *offset += 1;
16201     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_panid, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16202     *offset += 2;
16203 } /* dissect_zcl_touchlink_network_start_response */
16204 
16205 /**
16206  *This function decodes the Endpoint Information payload.
16207  *
16208  *@param  tvb the tv buffer of the current data_type
16209  *@param  tree the tree to append this item to
16210  *@param  offset offset of data in tvb
16211 */
16212 static void
dissect_zcl_touchlink_endpoint_info(tvbuff_t * tvb,proto_tree * tree,guint * offset)16213 dissect_zcl_touchlink_endpoint_info(tvbuff_t *tvb, proto_tree *tree, guint *offset)
16214 {
16215     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_ext_addr, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
16216     *offset += 8;
16217     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_nwk_addr, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16218     *offset += 2;
16219     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_endpoint, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16220     *offset += 1;
16221     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_profile_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16222     *offset += 2;
16223     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_device_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16224     *offset += 2;
16225     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_version, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16226     *offset += 1;
16227 } /* dissect_zcl_touchlink_endpoint_info */
16228 
16229 /**
16230  *This function decodes the Get Group Identifiers Response payload.
16231  *
16232  *@param  tvb the tv buffer of the current data_type
16233  *@param  tree the tree to append this item to
16234  *@param  offset offset of data in tvb
16235 */
16236 static void
dissect_zcl_touchlink_group_id_response(tvbuff_t * tvb,proto_tree * tree,guint * offset)16237 dissect_zcl_touchlink_group_id_response(tvbuff_t *tvb, proto_tree *tree, guint *offset)
16238 {
16239     proto_tree *list_tree;
16240     guint8 count;
16241     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_total_groups, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16242     *offset += 1;
16243     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_start_index, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16244     *offset += 1;
16245     count = tvb_get_guint8(tvb, *offset);
16246     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_group_count, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16247     *offset += 1;
16248 
16249     list_tree = proto_tree_add_subtree(tree, tvb, *offset, count * 3, ett_zbee_zcl_touchlink_groups, NULL, "Group Information Records");
16250     while (count--) {
16251         proto_tree_add_item(list_tree, hf_zbee_zcl_touchlink_group_id, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
16252         *offset += 2;
16253         proto_tree_add_item(list_tree, hf_zbee_zcl_touchlink_group_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
16254         *offset += 1;
16255     }
16256 } /* dissect_zcl_touchlink_group_id_response */
16257 
16258 /**
16259  *ZigBee ZCL Touchlink Commissioining cluster dissector for wireshark.
16260  *
16261  *@param tvb pointer to buffer containing raw packet.
16262  *@param pinfo pointer to packet information fields
16263  *@param tree pointer to data tree Wireshark uses to display packet.
16264 */
16265 static int
dissect_zbee_zcl_touchlink(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)16266 dissect_zbee_zcl_touchlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
16267 {
16268     zbee_zcl_packet   *zcl;
16269     guint             offset = 0;
16270     guint8            cmd_id;
16271     int               hf_cmd_id;
16272     const value_string *vals_cmd_id;
16273 
16274     /* Reject the packet if data is NULL */
16275     if (data == NULL)
16276         return 0;
16277     zcl = (zbee_zcl_packet *)data;
16278     cmd_id = zcl->cmd_id;
16279 
16280     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
16281         hf_cmd_id = hf_zbee_zcl_touchlink_rx_cmd_id;
16282         vals_cmd_id = zbee_zcl_touchlink_rx_cmd_names;
16283     } else {
16284         hf_cmd_id = hf_zbee_zcl_touchlink_tx_cmd_id;
16285         vals_cmd_id = zbee_zcl_touchlink_tx_cmd_names;
16286     }
16287 
16288     /* Append the command name to the info column. */
16289     col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
16290         val_to_str_const(cmd_id, vals_cmd_id, "Unknown Command"),
16291         zcl->tran_seqno);
16292     /* Add the command ID. */
16293     if (tree) {
16294         proto_tree_add_item(tree, hf_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
16295     }
16296     offset++;
16297 
16298     /* All touchlink commands begin with a transaction identifier.  */
16299     proto_tree_add_item(tree, hf_zbee_zcl_touchlink_transaction_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
16300     offset += 4;
16301 
16302     /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
16303     if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
16304         /* Call the appropriate command dissector */
16305         switch (cmd_id) {
16306             case ZBEE_ZCL_CMD_ID_SCAN_REQUEST:
16307                 dissect_zcl_touchlink_scan_request(tvb, tree, &offset);
16308                 break;
16309 
16310             case ZBEE_ZCL_CMD_ID_IDENTIFY_REQUEST:
16311                 dissect_zcl_touchlink_identify_request(tvb, tree, &offset);
16312                 break;
16313 
16314             case ZBEE_ZCL_CMD_ID_FACTORT_RESET_REQUEST:
16315                 /* No payload */
16316                 break;
16317 
16318             case ZBEE_ZCL_CMD_ID_NETWORK_START_REQUEST:
16319                 dissect_zcl_touchlink_network_start_request(tvb, tree, &offset);
16320                 break;
16321 
16322             case ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ROUTER_REQUEST:
16323             case ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ENDDEV_REQUEST:
16324                 dissect_zcl_touchlink_network_join_request(tvb, tree, &offset);
16325                 break;
16326 
16327             case ZBEE_ZCL_CMD_ID_NETWORK_UPDATE_REQUEST:
16328                 dissect_zcl_touchlink_network_update_request(tvb, tree, &offset);
16329                 break;
16330 
16331             case ZBEE_ZCL_CMD_ID_DEVICE_INFO_REQUEST:
16332             case ZBEE_ZCL_CMD_ID_GET_GROUP_IDENTIFIERS_REQUEST:
16333             case ZBEE_ZCL_CMD_ID_GET_ENDPOINT_LIST_REQUEST:
16334                 proto_tree_add_item(tree, hf_zbee_zcl_touchlink_start_index, tvb, offset, 1, ENC_LITTLE_ENDIAN);
16335                 offset++;
16336                 break;
16337 
16338             default:
16339                 break;
16340         }
16341     }
16342     else {
16343         /* Call the appropriate command dissector */
16344         switch (cmd_id) {
16345             case ZBEE_ZCL_CMD_ID_SCAN_RESPONSE:
16346                 dissect_zcl_touchlink_scan_response(tvb, tree, &offset);
16347                 break;
16348 
16349             case ZBEE_ZCL_CMD_ID_NETWORK_START_RESPONSE:
16350                 dissect_zcl_touchlink_network_start_response(tvb, tree, &offset);
16351                 break;
16352 
16353             case ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ROUTER_RESPONSE:
16354             case ZBEE_ZCL_CMD_ID_NETWORK_JOIN_ENDDEV_RESPONSE:
16355                 proto_tree_add_item(tree, hf_zbee_zcl_touchlink_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
16356                 offset++;
16357                 break;
16358 
16359             case ZBEE_ZCL_CMD_ID_DEVICE_INFO_RESPONSE:
16360                 break;
16361 
16362             case ZBEE_ZCL_CMD_ID_ENDPOINT_INFORMATION:
16363                 dissect_zcl_touchlink_endpoint_info(tvb, tree, &offset);
16364                 break;
16365 
16366             case ZBEE_ZCL_CMD_ID_GET_GROUP_IDENTIFIERS_RESPONSE:
16367                 dissect_zcl_touchlink_group_id_response(tvb, tree, &offset);
16368                 break;
16369 
16370             case ZBEE_ZCL_CMD_ID_GET_ENDPOINT_LIST_RESPONSE:
16371                 /* No payload */
16372                 break;
16373 
16374             default:
16375                 break;
16376         }
16377     }
16378 
16379     /* Dump leftover data. */
16380     if (tvb_captured_length_remaining(tvb, offset) > 0) {
16381         tvbuff_t *excess = tvb_new_subset_remaining(tvb, offset);
16382         call_data_dissector(excess, pinfo, proto_tree_get_root(tree));
16383     }
16384     return offset;
16385 } /*dissect_zbee_zcl_touchlink*/
16386 
16387 /**
16388  *ZigBee ZCL Touchlink Commissioning cluster protocol registration routine.
16389  *
16390 */
16391 void
proto_register_zbee_zcl_touchlink(void)16392 proto_register_zbee_zcl_touchlink(void)
16393 {
16394     /* Setup list of header fields */
16395     static hf_register_info hf[] = {
16396         { &hf_zbee_zcl_touchlink_rx_cmd_id,
16397             { "Command", "zbee_zcl_general.touchlink.rx_cmd_id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_touchlink_rx_cmd_names),
16398             0x00, NULL, HFILL } },
16399         { &hf_zbee_zcl_touchlink_tx_cmd_id,
16400             { "Command", "zbee_zcl_general.touchlink.tx_cmd_d", FT_UINT8, BASE_HEX, VALS(zbee_zcl_touchlink_tx_cmd_names),
16401             0x00, NULL, HFILL } },
16402         { &hf_zbee_zcl_touchlink_transaction_id,
16403             { "Transaction ID", "zbee_zcl_general.touchlink.transaction_id", FT_UINT32, BASE_HEX, NULL,
16404             0x00, NULL, HFILL } },
16405 
16406         /* ZigBee Information Bitmask */
16407         { &hf_zbee_zcl_touchlink_zbee,
16408             { "ZigBee Information", "zbee_zcl_general.touchlink.zbee", FT_UINT8, BASE_HEX, NULL,
16409                 0x0, NULL, HFILL }},
16410 
16411         { &hf_zbee_zcl_touchlink_zbee_type,
16412             { "Logical type", "zbee_zcl_general.touchlink.zbee.type", FT_UINT8, BASE_HEX, VALS(zbee_zcl_touchlink_zbee_type_names),
16413             ZBEE_ZCL_TOUCHLINK_ZBEE_INFO_TYPE, NULL, HFILL } },
16414 
16415         { &hf_zbee_zcl_touchlink_zbee_rxidle,
16416             { "Rx on when idle", "zbee_zcl_general.touchlink.zbee.rxidle", FT_BOOLEAN, 8, TFS(&tfs_yes_no),
16417             ZBEE_ZCL_TOUCHLINK_ZBEE_INFO_RXIDLE, NULL, HFILL } },
16418 
16419         /* Touchlink Information Bitmask */
16420         { &hf_zbee_zcl_touchlink_info,
16421             { "Touchlink Information", "zbee_zcl_general.touchlink.info", FT_UINT8, BASE_HEX, NULL,
16422                 0x0, NULL, HFILL }},
16423 
16424         { &hf_zbee_zcl_touchlink_info_factory,
16425             { "Factory new", "zbee_zcl_general.touchlink.info.factory", FT_BOOLEAN, 8, TFS(&tfs_yes_no),
16426             ZBEE_ZCL_TOUCHLINK_INFO_FACTORY, NULL, HFILL } },
16427 
16428         { &hf_zbee_zcl_touchlink_info_assignment,
16429             { "Address assignment", "zbee_zcl_general.touchlink.info.assignment", FT_BOOLEAN, 8, TFS(&tfs_yes_no),
16430             ZBEE_ZCL_TOUCHLINK_INFO_ASSIGNMENT, NULL, HFILL } },
16431 
16432         { &hf_zbee_zcl_touchlink_info_initiator,
16433             { "Link initiator", "zbee_zcl_general.touchlink.info.initiator", FT_BOOLEAN, 8, TFS(&tfs_yes_no),
16434             ZBEE_ZCL_TOUCHLINK_INFO_INITIATOR, NULL, HFILL } },
16435 
16436         { &hf_zbee_zcl_touchlink_info_undefined,
16437             { "Undefined", "zbee_zcl_general.touchlink.info.undefined", FT_BOOLEAN, 8, NULL,
16438             ZBEE_ZCL_TOUCHLINK_INFO_UNDEFINED, NULL, HFILL } },
16439 
16440         /* Touchlink Key Information Bitmask */
16441         { &hf_zbee_zcl_touchlink_key_bitmask,
16442             { "Key Bitmask", "zbee_zcl_general.touchlink.key_bitmask", FT_UINT16, BASE_HEX, NULL,
16443             0x00, NULL, HFILL } },
16444 
16445         { &hf_zbee_zcl_touchlink_key_bit_dev,
16446             { "Development Key", "zbee_zcl_general.touchlink.key_bitmask.dev", FT_BOOLEAN, 16, TFS(&tfs_yes_no),
16447             (1<<ZBEE_ZCL_TOUCHLINK_KEYID_DEVELOPMENT), NULL, HFILL } },
16448 
16449         { &hf_zbee_zcl_touchlink_key_bit_master,
16450             { "Master Key", "zbee_zcl_general.touchlink.key_bitmask.master", FT_BOOLEAN, 16, TFS(&tfs_yes_no),
16451             (1<<ZBEE_ZCL_TOUCHLINK_KEYID_MASTER), NULL, HFILL } },
16452 
16453         { &hf_zbee_zcl_touchlink_key_bit_cert,
16454             { "Certification Key", "zbee_zcl_general.touchlink.key_bitmask.cert", FT_BOOLEAN, 16, TFS(&tfs_yes_no),
16455             (1<<ZBEE_ZCL_TOUCHLINK_KEYID_CERTIFICATION), NULL, HFILL } },
16456 
16457         { &hf_zbee_zcl_touchlink_start_index,
16458             { "Start index", "zbee_zcl_general.touchlink.index", FT_UINT8, BASE_DEC, NULL,
16459             0x00, NULL, HFILL } },
16460 
16461         { &hf_zbee_zcl_touchlink_ident_duration,
16462             { "Identify duration", "zbee_zcl_general.touchlink.duration", FT_UINT16, BASE_DEC, NULL,
16463             0x00, NULL, HFILL } },
16464 
16465         { &hf_zbee_zcl_touchlink_rssi_correction,
16466             { "RSSI Correction", "zbee_zcl_general.touchlink.rssi_correction", FT_UINT8, BASE_DEC, NULL,
16467             0x00, NULL, HFILL } },
16468 
16469         { &hf_zbee_zcl_touchlink_response_id,
16470             { "Response ID", "zbee_zcl_general.touchlink.response_id", FT_UINT32, BASE_HEX, NULL,
16471             0x00, NULL, HFILL } },
16472 
16473         { &hf_zbee_zcl_touchlink_ext_panid,
16474             { "Extended PAN ID", "zbee_zcl_general.touchlink.ext_panid", FT_EUI64, BASE_NONE, NULL,
16475             0x0, NULL, HFILL } },
16476 
16477         { &hf_zbee_zcl_touchlink_nwk_update_id,
16478             { "Network Update ID", "zbee_zcl_general.touchlink.nwk_update_id", FT_UINT8, BASE_DEC, NULL,
16479             0x00, NULL, HFILL } },
16480 
16481         { &hf_zbee_zcl_touchlink_channel,
16482             { "Logical Channel", "zbee_zcl_general.touchlink.channel", FT_UINT8, BASE_DEC, NULL,
16483             0x00, NULL, HFILL } },
16484 
16485         { &hf_zbee_zcl_touchlink_nwk_addr,
16486             { "Network Address", "zbee_zcl_general.touchlink.nwk_addr", FT_UINT16, BASE_DEC, NULL,
16487             0x00, NULL, HFILL } },
16488 
16489         { &hf_zbee_zcl_touchlink_ext_addr,
16490             { "Extended Address", "zbee_zcl_general.touchlink.ext_addr", FT_EUI64, BASE_NONE, NULL,
16491             0x00, NULL, HFILL } },
16492 
16493         { &hf_zbee_zcl_touchlink_panid,
16494             { "PAN ID", "zbee_zcl_general.touchlink.panid", FT_UINT16, BASE_HEX, NULL,
16495             0x00, NULL, HFILL } },
16496 
16497         { &hf_zbee_zcl_touchlink_sub_devices,
16498             { "Sub-devices", "zbee_zcl_general.touchlink.sub_devices", FT_UINT8, BASE_DEC, NULL,
16499             0x00, NULL, HFILL } },
16500 
16501         { &hf_zbee_zcl_touchlink_total_groups,
16502             { "Total Group Identifiers", "zbee_zcl_general.touchlink.total_groups", FT_UINT8, BASE_DEC, NULL,
16503             0x00, NULL, HFILL } },
16504 
16505         { &hf_zbee_zcl_touchlink_endpoint,
16506             { "Endpoint", "zbee_zcl_general.touchlink.endpoint", FT_UINT8, BASE_DEC, NULL,
16507             0x00, NULL, HFILL } },
16508 
16509         { &hf_zbee_zcl_touchlink_profile_id,
16510             { "Profile ID", "zbee_zcl_general.touchlink.profile_id", FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(zbee_aps_apid_names),
16511             0x00, NULL, HFILL } },
16512 
16513         { &hf_zbee_zcl_touchlink_device_id,
16514             { "Device ID", "zbee_zcl_general.touchlink.device_id", FT_UINT16, BASE_HEX, NULL,
16515             0x00, NULL, HFILL } },
16516 
16517         { &hf_zbee_zcl_touchlink_version,
16518             { "Version", "zbee_zcl_general.touchlink.version", FT_UINT8, BASE_HEX, NULL,
16519             0x00, NULL, HFILL } },
16520 
16521         { &hf_zbee_zcl_touchlink_group_count,
16522             { "Group ID Count", "zbee_zcl_general.touchlink.group_count", FT_UINT8, BASE_DEC, NULL,
16523             0x00, NULL, HFILL } },
16524 
16525         { &hf_zbee_zcl_touchlink_group_begin,
16526             { "Group ID Begin", "zbee_zcl_general.touchlink.group_begin", FT_UINT16, BASE_HEX, NULL,
16527             0x00, NULL, HFILL } },
16528 
16529         { &hf_zbee_zcl_touchlink_group_end,
16530             { "Group ID End", "zbee_zcl_general.touchlink.group_end", FT_UINT16, BASE_HEX, NULL,
16531             0x00, NULL, HFILL } },
16532 
16533         { &hf_zbee_zcl_touchlink_group_type,
16534             { "Group Type", "zbee_zcl_general.touchlink.group_type", FT_UINT8, BASE_HEX, NULL,
16535             0x00, NULL, HFILL } },
16536 
16537         { &hf_zbee_zcl_touchlink_group_id,
16538             { "Group ID", "zbee_zcl_general.touchlink.group_id", FT_UINT16, BASE_HEX, NULL,
16539             0x00, NULL, HFILL } },
16540 
16541         { &hf_zbee_zcl_touchlink_addr_range_begin,
16542             { "Free Address Range Begin", "zbee_zcl_general.touchlink.addr_range_begin", FT_UINT16, BASE_HEX, NULL,
16543             0x00, NULL, HFILL } },
16544 
16545         { &hf_zbee_zcl_touchlink_addr_range_end,
16546             { "Free Address Range End", "zbee_zcl_general.touchlink.addr_range_end", FT_UINT16, BASE_HEX, NULL,
16547             0x00, NULL, HFILL } },
16548 
16549         { &hf_zbee_zcl_touchlink_group_range_begin,
16550             { "Free Group ID Range Begin", "zbee_zcl_general.touchlink.group_range_begin", FT_UINT16, BASE_HEX, NULL,
16551             0x00, NULL, HFILL } },
16552 
16553         { &hf_zbee_zcl_touchlink_group_range_end,
16554             { "Free Group ID Range End", "zbee_zcl_general.touchlink.group_range_end", FT_UINT16, BASE_HEX, NULL,
16555             0x00, NULL, HFILL } },
16556 
16557         { &hf_zbee_zcl_touchlink_key_index,
16558             { "Key Index", "zbee_zcl_general.touchlink.key_index", FT_UINT8, BASE_DEC, VALS(zbee_zcl_touchlink_keyid_names),
16559             0x00, NULL, HFILL } },
16560 
16561         { &hf_zbee_zcl_touchlink_key,
16562             { "Encrypted Network Key", "zbee_zcl_general.touchlink.key", FT_BYTES, BASE_NONE, NULL,
16563             0x0, NULL, HFILL } },
16564 
16565         { &hf_zbee_zcl_touchlink_init_eui64,
16566             { "Initiator Extended Address", "zbee_zcl_general.touchlink.init_eui", FT_EUI64, BASE_NONE, NULL,
16567             0x00, NULL, HFILL } },
16568 
16569         { &hf_zbee_zcl_touchlink_init_addr,
16570             { "Initiator Network Address", "zbee_zcl_general.touchlink.init_addr", FT_UINT16, BASE_HEX, NULL,
16571             0x00, NULL, HFILL } },
16572 
16573         { &hf_zbee_zcl_touchlink_status,
16574             { "Status", "zbee_zcl_general.touchlink.status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_touchlink_status_names),
16575             0x00, NULL, HFILL } },
16576     };
16577 
16578     /* ZCL Touchlink subtrees */
16579     static gint *ett[] = {
16580         &ett_zbee_zcl_touchlink,
16581         &ett_zbee_zcl_touchlink_zbee,
16582         &ett_zbee_zcl_touchlink_info,
16583         &ett_zbee_zcl_touchlink_keybits,
16584         &ett_zbee_zcl_touchlink_groups,
16585     };
16586 
16587     /* Register the ZigBee ZCL Touchlink cluster protocol name and description */
16588     proto_zbee_zcl_touchlink = proto_register_protocol("ZigBee ZCL Touchlink", "ZCL Touchlink", ZBEE_PROTOABBREV_ZCL_TOUCHLINK);
16589     proto_register_field_array(proto_zbee_zcl_touchlink, hf, array_length(hf));
16590     proto_register_subtree_array(ett, array_length(ett));
16591 
16592     /* Register the ZigBee ZCL Touchlink Commissioning dissector. */
16593     register_dissector(ZBEE_PROTOABBREV_ZCL_TOUCHLINK, dissect_zbee_zcl_touchlink, proto_zbee_zcl_touchlink);
16594 } /*proto_register_zbee_zcl_touchlink*/
16595 
16596 /**
16597  *Hands off the ZCL Touchlink Commissioning dissector.
16598  *
16599 */
16600 void
proto_reg_handoff_zbee_zcl_touchlink(void)16601 proto_reg_handoff_zbee_zcl_touchlink(void)
16602 {
16603     zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_TOUCHLINK,
16604                             proto_zbee_zcl_touchlink,
16605                             ett_zbee_zcl_touchlink,
16606                             ZBEE_ZCL_CID_ZLL,
16607                             ZBEE_MFG_CODE_NONE,
16608                             -1, -1,
16609                             hf_zbee_zcl_touchlink_rx_cmd_id, hf_zbee_zcl_touchlink_tx_cmd_id,
16610                             NULL
16611                          );
16612 } /*proto_reg_handoff_zbee_zcl_touchlink*/
16613 
16614 /*
16615  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
16616  *
16617  * Local variables:
16618  * c-basic-offset: 4
16619  * tab-width: 8
16620  * indent-tabs-mode: nil
16621  * End:
16622  *
16623  * vi: set shiftwidth=4 tabstop=8 expandtab:
16624  * :indentSize=4:tabSize=8:noTabs=true:
16625  */
16626