Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-zbee-zcl-closures.c
Line
Count
Source
1
/* packet-zbee-zcl-closures.c
2
 * Dissector routines for the ZigBee ZCL Closures clusters
3
 * Shade configuration, Door Lock
4
 * By <aditya.jain@samsung.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
/*  Include Files */
14
#include "config.h"
15
16
#include <epan/packet.h>
17
#include <epan/tfs.h>
18
#include <wsutil/array.h>
19
20
#include "packet-zbee.h"
21
#include "packet-zbee-aps.h"
22
#include "packet-zbee-zcl.h"
23
24
25
/* ########################################################################## */
26
/* #### (0x0100) SHADE CONFIGURATION CLUSTER ################################ */
27
/* ########################################################################## */
28
29
/*************************/
30
/* Defines               */
31
/*************************/
32
33
/*Attributes*/
34
14
#define ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_PHYSICAL_CLOSED_LIMIT                 0x0000  /* Physical Closed Limit */
35
14
#define ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_MOTOR_STEP_SIZE                       0x0001  /* Motor Step Size */
36
1
#define ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_STATUS                                0x0002  /* Status */
37
14
#define ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_CLOSED_LIMIT                          0x0010  /* Closed Limit */
38
2
#define ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_MODE                                  0x0011  /* Mode */
39
40
/*Server commands received - none*/
41
42
/*Server commands generated - none*/
43
44
/*Status Mask Value*/
45
16
#define ZBEE_ZCL_SHADE_CONFIGURATION_STATUS_SHADE_OPERATIONAL                       0x01    /* Shade Operational */
46
16
#define ZBEE_ZCL_SHADE_CONFIGURATION_STATUS_SHADE_ADJUSTING                         0x02    /* Shade Adjusting */
47
16
#define ZBEE_ZCL_SHADE_CONFIGURATION_STATUS_SHADE_DIRECTION                         0x04    /* Shade Direction */
48
16
#define ZBEE_ZCL_SHADE_CONFIGURATION_STATUS_MOTOR_FORWARD_DIRECTION                 0x08    /* Motor Forward Direction */
49
50
/*************************/
51
/* Function Declarations */
52
/*************************/
53
54
void proto_register_zbee_zcl_shade_configuration(void);
55
void proto_reg_handoff_zbee_zcl_shade_configuration(void);
56
57
/* Private functions prototype */
58
59
/*************************/
60
/* Global Variables      */
61
/*************************/
62
/* Initialize the protocol and registered fields */
63
static int proto_zbee_zcl_shade_configuration;
64
65
static int hf_zbee_zcl_shade_configuration_attr_id;
66
static int hf_zbee_zcl_shade_configuration_status;
67
static int hf_zbee_zcl_shade_configuration_status_shade_operational;
68
static int hf_zbee_zcl_shade_configuration_status_shade_adjusting;
69
static int hf_zbee_zcl_shade_configuration_status_shade_direction;
70
static int hf_zbee_zcl_shade_configuration_status_motor_forward_direction;
71
static int hf_zbee_zcl_shade_configuration_mode;
72
73
/* Initialize the subtree pointers */
74
static int ett_zbee_zcl_shade_configuration;
75
static int ett_zbee_zcl_shade_configuration_status;
76
77
/* Attributes */
78
static const value_string zbee_zcl_shade_configuration_attr_names[] = {
79
    { ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_PHYSICAL_CLOSED_LIMIT,       "Physical Closed Limit" },
80
    { ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_MOTOR_STEP_SIZE,             "Motor Step Size" },
81
    { ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_STATUS,                      "Status" },
82
    { ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_CLOSED_LIMIT,                "Closed Limit" },
83
    { ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_MODE,                        "Mode" },
84
    { 0, NULL }
85
};
86
87
/*Shade and motor direction values*/
88
static const value_string zbee_zcl_shade_configuration_shade_motor_direction_names[] = {
89
    {0, "Closing"},
90
    {1, "Opening"},
91
    {0, NULL}
92
};
93
94
/*Mode Values*/
95
static const value_string zbee_zcl_shade_configuration_mode_names[] = {
96
    {0, "Normal"},
97
    {1, "Configure"},
98
    {0, NULL}
99
};
100
101
102
/*************************/
103
/* Function Bodies       */
104
/*************************/
105
106
/**
107
 *ZigBee ZCL Shade Configuration cluster dissector for wireshark.
108
 *
109
 *@param tvb pointer to buffer containing raw packet.
110
 *@param pinfo pointer to packet information fields
111
 *@param tree pointer to data tree Wireshark uses to display packet.
112
*/
113
114
static int
115
dissect_zbee_zcl_shade_configuration(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void* data _U_)
116
1
{
117
1
    return tvb_captured_length(tvb);
118
1
} /*dissect_zbee_zcl_shade_configuration*/
119
120
121
/**
122
 *This function is called by ZCL foundation dissector in order to decode
123
 *
124
 *@param tree pointer to data tree Wireshark uses to display packet.
125
 *@param tvb pointer to buffer containing raw packet.
126
 *@param offset pointer to buffer offset
127
 *@param attr_id attribute identifier
128
 *@param data_type attribute data type
129
 *@param client_attr ZCL client
130
*/
131
static void
132
dissect_zcl_shade_configuration_attr_data(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr)
133
101
{
134
101
    static int * const shade_config_status[] = {
135
101
        &hf_zbee_zcl_shade_configuration_status_shade_operational,
136
101
        &hf_zbee_zcl_shade_configuration_status_shade_adjusting,
137
101
        &hf_zbee_zcl_shade_configuration_status_shade_direction,
138
101
        &hf_zbee_zcl_shade_configuration_status_motor_forward_direction,
139
101
        NULL
140
101
    };
141
142
    /* Dissect attribute data type and data */
143
101
    switch (attr_id) {
144
145
1
        case ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_STATUS:
146
1
            proto_tree_add_bitmask(tree, tvb, *offset, hf_zbee_zcl_shade_configuration_status, ett_zbee_zcl_shade_configuration_status, shade_config_status, ENC_LITTLE_ENDIAN);
147
1
            *offset += 1;
148
1
            break;
149
150
2
        case ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_MODE:
151
2
            proto_tree_add_item(tree, hf_zbee_zcl_shade_configuration_mode, tvb, *offset, 1, ENC_NA);
152
2
            *offset += 1;
153
2
            break;
154
155
14
        case ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_PHYSICAL_CLOSED_LIMIT:
156
14
        case ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_MOTOR_STEP_SIZE:
157
14
        case ZBEE_ZCL_ATTR_ID_SHADE_CONFIGURATION_CLOSED_LIMIT:
158
98
        default:
159
98
            dissect_zcl_attr_data(tvb, pinfo, tree, offset, data_type, client_attr);
160
98
            break;
161
101
    }
162
163
101
} /*dissect_zcl_shade_configuration_attr_data*/
164
165
166
/**
167
 *ZigBee ZCL Shade Configuration cluster protocol registration routine.
168
 *
169
*/
170
void
171
proto_register_zbee_zcl_shade_configuration(void)
172
16
{
173
    /* Setup list of header fields */
174
16
    static hf_register_info hf[] = {
175
176
16
        { &hf_zbee_zcl_shade_configuration_attr_id,
177
16
            { "Attribute", "zbee_zcl_closures.shade_configuration.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_shade_configuration_attr_names),
178
16
            0x00, NULL, HFILL } },
179
180
        /* start Shade Configuration Status fields */
181
16
        { &hf_zbee_zcl_shade_configuration_status,
182
16
            { "Shade Configuration Status", "zbee_zcl_closures.shade_configuration.attr.status", FT_UINT8, BASE_HEX, NULL,
183
16
            0x00, NULL, HFILL } },
184
185
16
        { &hf_zbee_zcl_shade_configuration_status_shade_operational,
186
16
            { "Shade Operational", "zbee_zcl_closures.shade_configuration.attr.status.shade_operational", FT_BOOLEAN, 8, TFS(&tfs_no_yes),
187
16
            ZBEE_ZCL_SHADE_CONFIGURATION_STATUS_SHADE_OPERATIONAL, NULL, HFILL } },
188
189
16
        { &hf_zbee_zcl_shade_configuration_status_shade_adjusting,
190
16
            { "Shade Adjusting", "zbee_zcl_closures.shade_configuration.attr.status.shade_adjusting", FT_BOOLEAN, 8, TFS(&tfs_no_yes),
191
16
            ZBEE_ZCL_SHADE_CONFIGURATION_STATUS_SHADE_ADJUSTING, NULL, HFILL } },
192
193
16
        { &hf_zbee_zcl_shade_configuration_status_shade_direction,
194
16
            { "Shade Direction", "zbee_zcl_closures.shade_configuration.attr.status.shade_direction", FT_UINT8, BASE_DEC, VALS(zbee_zcl_shade_configuration_shade_motor_direction_names),
195
16
            ZBEE_ZCL_SHADE_CONFIGURATION_STATUS_SHADE_DIRECTION, NULL, HFILL } },
196
197
16
        { &hf_zbee_zcl_shade_configuration_status_motor_forward_direction,
198
16
            { "Motor Forward Direction", "zbee_zcl_closures.shade_configuration.attr.status.motor_forward_direction", FT_UINT8, BASE_DEC, VALS(zbee_zcl_shade_configuration_shade_motor_direction_names),
199
16
            ZBEE_ZCL_SHADE_CONFIGURATION_STATUS_MOTOR_FORWARD_DIRECTION, NULL, HFILL } },
200
        /* end Shade Configuration Status fields */
201
202
16
        { &hf_zbee_zcl_shade_configuration_mode,
203
16
            { "Mode", "zbee_zcl_closures.shade_configuration.attr.mode", FT_UINT8, BASE_HEX, VALS(zbee_zcl_shade_configuration_mode_names),
204
16
            0x00, NULL, HFILL } }
205
16
    };
206
207
    /* ZCL Shade Configuration subtrees */
208
16
    static int *ett[] = {
209
16
        &ett_zbee_zcl_shade_configuration,
210
16
        &ett_zbee_zcl_shade_configuration_status
211
16
    };
212
213
    /* Register the ZigBee ZCL Shade Configuration cluster protocol name and description */
214
16
    proto_zbee_zcl_shade_configuration = proto_register_protocol("ZigBee ZCL Shade Configuration", "ZCL Shade Configuration", ZBEE_PROTOABBREV_ZCL_SHADE_CONFIG);
215
16
    proto_register_field_array(proto_zbee_zcl_shade_configuration, hf, array_length(hf));
216
16
    proto_register_subtree_array(ett, array_length(ett));
217
218
    /* Register the ZigBee ZCL Shade Configuration dissector. */
219
16
    register_dissector(ZBEE_PROTOABBREV_ZCL_SHADE_CONFIG, dissect_zbee_zcl_shade_configuration, proto_zbee_zcl_shade_configuration);
220
16
} /*proto_register_zbee_zcl_shade_configuration*/
221
222
/**
223
 *Hands off the ZCL Shade Configuration dissector.
224
 *
225
*/
226
void
227
proto_reg_handoff_zbee_zcl_shade_configuration(void)
228
16
{
229
16
    zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_SHADE_CONFIG,
230
16
                            proto_zbee_zcl_shade_configuration,
231
16
                            ett_zbee_zcl_shade_configuration,
232
16
                            ZBEE_ZCL_CID_SHADE_CONFIG,
233
16
                            ZBEE_MFG_CODE_NONE,
234
16
                            hf_zbee_zcl_shade_configuration_attr_id,
235
16
                            hf_zbee_zcl_shade_configuration_attr_id,
236
16
                            -1, -1,
237
16
                            dissect_zcl_shade_configuration_attr_data
238
16
                         );
239
16
} /*proto_reg_handoff_zbee_zcl_shade_configuration*/
240
241
242
/* ########################################################################## */
243
/* #### (0x0101) DOOR LOCK CLUSTER ########################################## */
244
/* ########################################################################## */
245
246
/*************************/
247
/* Defines               */
248
/*************************/
249
250
/* Attributes */
251
87
#define ZBEE_ZCL_ATTR_ID_DOOR_LOCK_LOCK_STATE                       0x0000  /* Lock State */
252
17
#define ZBEE_ZCL_ATTR_ID_DOOR_LOCK_LOCK_TYPE                        0x0001  /* Lock Type */
253
0
#define ZBEE_ZCL_ATTR_ID_DOOR_LOCK_ACTUATOR_ENABLED                 0x0002  /* Actuator Enabled */
254
6
#define ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_STATE                       0x0003  /* Door State */
255
0
#define ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_OPEN_EVENTS                 0x0004  /* Door Open Events */
256
0
#define ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_CLOSED_EVENTS               0x0005  /* Door Closed Events */
257
0
#define ZBEE_ZCL_ATTR_ID_DOOR_LOCK_OPEN_PERIOD                      0x0006  /* Open Period */
258
259
/* Server Commands Received */
260
0
#define ZBEE_ZCL_CMD_ID_DOOR_LOCK_LOCK_DOOR                         0x00  /* Lock Door */
261
0
#define ZBEE_ZCL_CMD_ID_DOOR_LOCK_UNLOCK_DOOR                       0x01  /* Unlock Door */
262
263
/* Server Commands Generated */
264
0
#define ZBEE_ZCL_CMD_ID_DOOR_LOCK_LOCK_DOOR_RESPONSE                0x00  /* Lock Door Response */
265
0
#define ZBEE_ZCL_CMD_ID_DOOR_LOCK_UNLOCK_DOOR_RESPONSE              0x01  /* Unlock Door Response */
266
267
268
/*************************/
269
/* Function Declarations */
270
/*************************/
271
272
void proto_register_zbee_zcl_door_lock(void);
273
void proto_reg_handoff_zbee_zcl_door_lock(void);
274
275
/* Command Dissector Helpers */
276
static void dissect_zcl_door_lock_lock_unlock_door_response        (tvbuff_t *tvb, proto_tree *tree, unsigned *offset);
277
278
/* Private functions prototype */
279
280
/*************************/
281
/* Global Variables      */
282
/*************************/
283
/* Initialize the protocol and registered fields */
284
static int proto_zbee_zcl_door_lock;
285
286
static int hf_zbee_zcl_door_lock_attr_id;
287
static int hf_zbee_zcl_door_lock_lock_state;
288
static int hf_zbee_zcl_door_lock_lock_type;
289
static int hf_zbee_zcl_door_lock_door_state;
290
static int hf_zbee_zcl_door_lock_actuator_enabled;
291
static int hf_zbee_zcl_door_lock_status;
292
static int hf_zbee_zcl_door_lock_srv_rx_cmd_id;
293
static int hf_zbee_zcl_door_lock_srv_tx_cmd_id;
294
295
/* Initialize the subtree pointers */
296
static int ett_zbee_zcl_door_lock;
297
298
/* Attributes */
299
static const value_string zbee_zcl_door_lock_attr_names[] = {
300
    { ZBEE_ZCL_ATTR_ID_DOOR_LOCK_LOCK_STATE,            "Lock State" },
301
    { ZBEE_ZCL_ATTR_ID_DOOR_LOCK_LOCK_TYPE,             "Lock Type" },
302
    { ZBEE_ZCL_ATTR_ID_DOOR_LOCK_ACTUATOR_ENABLED,      "Actuator Enabled" },
303
    { ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_STATE,            "Door State" },
304
    { ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_OPEN_EVENTS,      "Door Open Events" },
305
    { ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_CLOSED_EVENTS,    "Door Closed Events" },
306
    { ZBEE_ZCL_ATTR_ID_DOOR_LOCK_OPEN_PERIOD,           "Open Period" },
307
    { 0, NULL }
308
};
309
310
/* Server Commands Received */
311
static const value_string zbee_zcl_door_lock_srv_rx_cmd_names[] = {
312
    { ZBEE_ZCL_CMD_ID_DOOR_LOCK_LOCK_DOOR,              "Lock Door" },
313
    { ZBEE_ZCL_CMD_ID_DOOR_LOCK_UNLOCK_DOOR,            "Unlock Door" },
314
    { 0, NULL }
315
};
316
317
/* Server Commands Generated */
318
static const value_string zbee_zcl_door_lock_srv_tx_cmd_names[] = {
319
    { ZBEE_ZCL_CMD_ID_DOOR_LOCK_LOCK_DOOR_RESPONSE,     "Lock Door Response" },
320
    { ZBEE_ZCL_CMD_ID_DOOR_LOCK_UNLOCK_DOOR_RESPONSE,   "Unlock Door Response" },
321
    { 0, NULL }
322
};
323
324
/* Lock State Values */
325
static const value_string zbee_zcl_door_lock_lock_state_values[] = {
326
    { 0x00,   "Not Fully Locked" },
327
    { 0x01,   "Locked" },
328
    { 0x02,   "Unlocked" },
329
    { 0, NULL }
330
};
331
332
/* Lock Type Values */
333
static const value_string zbee_zcl_door_lock_lock_type_values[] = {
334
    { 0x00,   "Deadbolt" },
335
    { 0x01,   "Magnetic" },
336
    { 0x02,   "Other" },
337
    { 0, NULL }
338
};
339
340
/* Door State Values */
341
static const value_string zbee_zcl_door_lock_door_state_values[] = {
342
    { 0x00,   "Open" },
343
    { 0x01,   "Closed" },
344
    { 0x02,   "Error (Jammed)" },
345
    { 0x03,   "Error (Forced Open)" },
346
    { 0x04,   "Error (Unspecified)" },
347
    { 0, NULL }
348
};
349
350
351
/*************************/
352
/* Function Bodies       */
353
/*************************/
354
355
/**
356
 *ZigBee ZCL Door Lock cluster dissector for wireshark.
357
 *
358
 *@param tvb pointer to buffer containing raw packet.
359
 *@param pinfo pointer to packet information fields
360
 *@param tree pointer to data tree Wireshark uses to display packet.
361
*/
362
static int
363
dissect_zbee_zcl_door_lock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
364
2
{
365
2
    proto_tree        *payload_tree;
366
2
    zbee_zcl_packet   *zcl;
367
2
    unsigned          offset = 0;
368
2
    uint8_t           cmd_id;
369
2
    int               rem_len;
370
371
    /* Reject the packet if data is NULL */
372
2
    if (data == NULL)
373
0
        return 0;
374
2
    zcl = (zbee_zcl_packet *)data;
375
2
    cmd_id = zcl->cmd_id;
376
377
    /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
378
2
    if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
379
        /* Append the command name to the info column. */
380
1
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
381
1
            val_to_str_const(cmd_id, zbee_zcl_door_lock_srv_rx_cmd_names, "Unknown Command"),
382
1
            zcl->tran_seqno);
383
384
        /* Add the command ID. */
385
1
        proto_tree_add_item(tree, hf_zbee_zcl_door_lock_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
386
387
        /* Check if this command has a payload, then add the payload tree */
388
1
        rem_len = tvb_reported_length_remaining(tvb, ++offset);
389
1
        if (rem_len > 0) {
390
1
            /*payload_tree =*/ proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_door_lock, NULL, "Payload");
391
392
            /* Call the appropriate command dissector */
393
1
            switch (cmd_id) {
394
0
                case ZBEE_ZCL_CMD_ID_DOOR_LOCK_LOCK_DOOR:
395
0
                case ZBEE_ZCL_CMD_ID_DOOR_LOCK_UNLOCK_DOOR:
396
                    /* No Payload */
397
1
                default:
398
1
                    break;
399
1
            }
400
1
        }
401
1
    }
402
1
    else { /* ZBEE_ZCL_FCF_TO_CLIENT */
403
        /* Append the command name to the info column. */
404
1
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
405
1
            val_to_str_const(cmd_id, zbee_zcl_door_lock_srv_tx_cmd_names, "Unknown Command"),
406
1
            zcl->tran_seqno);
407
408
        /* Add the command ID. */
409
1
        proto_tree_add_item(tree, hf_zbee_zcl_door_lock_srv_tx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
410
411
        /* Check if this command has a payload, then add the payload tree */
412
1
        rem_len = tvb_reported_length_remaining(tvb, ++offset);
413
1
        if (rem_len > 0) {
414
1
            payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_door_lock, NULL, "Payload");
415
416
            /* Call the appropriate command dissector */
417
1
            switch (cmd_id) {
418
0
                case ZBEE_ZCL_CMD_ID_DOOR_LOCK_LOCK_DOOR_RESPONSE:
419
0
                case ZBEE_ZCL_CMD_ID_DOOR_LOCK_UNLOCK_DOOR_RESPONSE:
420
0
                    dissect_zcl_door_lock_lock_unlock_door_response(tvb, payload_tree, &offset);
421
0
                    break;
422
423
1
                default:
424
1
                    break;
425
1
            }
426
1
        }
427
1
    }
428
429
2
    return tvb_captured_length(tvb);
430
2
} /*dissect_zbee_zcl_door_lock*/
431
432
433
/**
434
 *This function decodes the lock and unlock door response
435
 *
436
 *@param  tvb the tv buffer of the current data_type
437
 *@param  tree the tree to append this item to
438
 *@param  offset offset of data in tvb
439
*/
440
static void
441
dissect_zcl_door_lock_lock_unlock_door_response(tvbuff_t *tvb, proto_tree *tree, unsigned *offset)
442
0
{
443
    /* Retrieve "Status" field */
444
0
    proto_tree_add_item(tree, hf_zbee_zcl_door_lock_status, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
445
0
    *offset += 1;
446
447
0
} /*dissect_zcl_door_lock_lock_unlock_door_response*/
448
449
450
/**
451
 *This function is called by ZCL foundation dissector in order to decode
452
 *
453
 *@param tree pointer to data tree Wireshark uses to display packet.
454
 *@param tvb pointer to buffer containing raw packet.
455
 *@param offset pointer to buffer offset
456
 *@param attr_id attribute identifier
457
 *@param data_type attribute data type
458
 *@param client_attr ZCL client
459
*/
460
static void
461
dissect_zcl_door_lock_attr_data(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr)
462
233
{
463
    /* Dissect attribute data type and data */
464
233
    switch ( attr_id ) {
465
466
87
        case ZBEE_ZCL_ATTR_ID_DOOR_LOCK_LOCK_STATE:
467
87
            proto_tree_add_item(tree, hf_zbee_zcl_door_lock_lock_state, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
468
87
            *offset += 1;
469
87
            break;
470
471
17
        case ZBEE_ZCL_ATTR_ID_DOOR_LOCK_LOCK_TYPE:
472
17
            proto_tree_add_item(tree, hf_zbee_zcl_door_lock_lock_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
473
17
            *offset += 1;
474
17
            break;
475
476
0
        case ZBEE_ZCL_ATTR_ID_DOOR_LOCK_ACTUATOR_ENABLED:
477
0
            proto_tree_add_item(tree, hf_zbee_zcl_door_lock_actuator_enabled, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
478
0
            *offset += 1;
479
0
            break;
480
481
6
        case ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_STATE:
482
6
            proto_tree_add_item(tree, hf_zbee_zcl_door_lock_door_state, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
483
6
            *offset += 1;
484
6
            break;
485
486
0
        case ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_OPEN_EVENTS:
487
0
        case ZBEE_ZCL_ATTR_ID_DOOR_LOCK_DOOR_CLOSED_EVENTS:
488
0
        case ZBEE_ZCL_ATTR_ID_DOOR_LOCK_OPEN_PERIOD:
489
123
        default:
490
123
            dissect_zcl_attr_data(tvb, pinfo, tree, offset, data_type, client_attr);
491
123
            break;
492
233
    }
493
494
233
} /*dissect_zcl_door_lock_attr_data*/
495
496
497
/**
498
 *ZigBee ZCL Door Lock cluster protocol registration routine.
499
 *
500
*/
501
void
502
proto_register_zbee_zcl_door_lock(void)
503
16
{
504
    /* Setup list of header fields */
505
16
    static hf_register_info hf[] = {
506
507
16
        { &hf_zbee_zcl_door_lock_attr_id,
508
16
            { "Attribute", "zbee_zcl_closures.door_lock.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_door_lock_attr_names),
509
16
            0x00, NULL, HFILL } },
510
511
16
        { &hf_zbee_zcl_door_lock_lock_state,
512
16
            { "Lock State", "zbee_zcl_closures.door_lock.attr.lock_state", FT_UINT8, BASE_HEX, VALS(zbee_zcl_door_lock_lock_state_values),
513
16
            0x00, NULL, HFILL } },
514
515
16
        { &hf_zbee_zcl_door_lock_lock_type,
516
16
            { "Lock Type", "zbee_zcl_closures.door_lock.attr.lock_type", FT_UINT8, BASE_HEX, VALS(zbee_zcl_door_lock_lock_type_values),
517
16
            0x00, NULL, HFILL } },
518
519
16
        { &hf_zbee_zcl_door_lock_door_state,
520
16
            { "Door State", "zbee_zcl_closures.door_lock.attr.door_state", FT_UINT8, BASE_HEX, VALS(zbee_zcl_door_lock_door_state_values),
521
16
            0x00, NULL, HFILL } },
522
523
16
        { &hf_zbee_zcl_door_lock_actuator_enabled,
524
16
            { "Actuator enabled", "zbee_zcl_closures.door_lock.attr.actuator_enabled", FT_BOOLEAN, 8, TFS(&tfs_disabled_enabled),
525
16
            0x01, NULL, HFILL } },
526
527
16
        { &hf_zbee_zcl_door_lock_status,
528
16
            { "Lock Status", "zbee_zcl_closures.door_lock.status", FT_UINT8, BASE_HEX, VALS(zbee_zcl_status_names),
529
16
            0x00, NULL, HFILL } },
530
531
16
        { &hf_zbee_zcl_door_lock_srv_rx_cmd_id,
532
16
          { "Command", "zbee_zcl_closures.door_lock.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_door_lock_srv_rx_cmd_names),
533
16
            0x00, NULL, HFILL } },
534
535
16
        { &hf_zbee_zcl_door_lock_srv_tx_cmd_id,
536
16
          { "Command", "zbee_zcl_closures.door_lock.cmd.srv_tx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_door_lock_srv_tx_cmd_names),
537
16
            0x00, NULL, HFILL } }
538
539
16
    };
540
541
    /* ZCL Door Lock subtrees */
542
16
    static int *ett[] = {
543
16
        &ett_zbee_zcl_door_lock
544
16
    };
545
546
    /* Register the ZigBee ZCL Door Lock cluster protocol name and description */
547
16
    proto_zbee_zcl_door_lock = proto_register_protocol("ZigBee ZCL Door Lock", "ZCL Door Lock", ZBEE_PROTOABBREV_ZCL_DOOR_LOCK);
548
16
    proto_register_field_array(proto_zbee_zcl_door_lock, hf, array_length(hf));
549
16
    proto_register_subtree_array(ett, array_length(ett));
550
551
    /* Register the ZigBee ZCL Door Lock dissector. */
552
16
    register_dissector(ZBEE_PROTOABBREV_ZCL_DOOR_LOCK, dissect_zbee_zcl_door_lock, proto_zbee_zcl_door_lock);
553
554
16
} /*proto_register_zbee_zcl_door_lock*/
555
556
557
/**
558
 *Hands off the ZCL Door Lock dissector.
559
 *
560
*/
561
void
562
proto_reg_handoff_zbee_zcl_door_lock(void)
563
16
{
564
16
    zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_DOOR_LOCK,
565
16
                            proto_zbee_zcl_door_lock,
566
16
                            ett_zbee_zcl_door_lock,
567
16
                            ZBEE_ZCL_CID_DOOR_LOCK,
568
16
                            ZBEE_MFG_CODE_NONE,
569
16
                            hf_zbee_zcl_door_lock_attr_id,
570
16
                            hf_zbee_zcl_door_lock_attr_id,
571
16
                            hf_zbee_zcl_door_lock_srv_rx_cmd_id,
572
16
                            hf_zbee_zcl_door_lock_srv_tx_cmd_id,
573
16
                            dissect_zcl_door_lock_attr_data
574
16
                         );
575
16
} /*proto_reg_handoff_zbee_zcl_door_lock*/
576
577
/* ########################################################################## */
578
/* #### (0x0102) WINDOW COVERING CLUSTER     ################################ */
579
/* ########################################################################## */
580
581
/*************************/
582
/* Defines               */
583
/*************************/
584
585
/*Attributes*/
586
32
#define ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_TYPE                                  0x0000  /* Type of shutter */
587
1
#define ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE      0x0008  /* Current position lift */
588
0
#define ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE      0x0009  /* Current position tilt */
589
590
/* Server commands received */
591
1
#define ZBEE_ZCL_CMD_ID_WINDOW_COVERING_UP_OPEN                           0x00  /* Open the shutter */
592
1
#define ZBEE_ZCL_CMD_ID_WINDOW_COVERING_DOWN_CLOSE                        0x01  /* Close the shutter */
593
1
#define ZBEE_ZCL_CMD_ID_WINDOW_COVERING_STOP                              0x02  /* Stop the shutter */
594
0
#define ZBEE_ZCL_CMD_ID_WINDOW_COVERING_GO_TO_LIFT_PERCENTAGE             0x05  /* Go to lift percentage */
595
0
#define ZBEE_ZCL_CMD_ID_WINDOW_COVERING_GO_TO_TILT_PERCENTAGE             0x08  /* Go to tilt percentage */
596
597
598
/*Server commands generated - none*/
599
600
/*Status Mask Value - none */
601
602
/*************************/
603
/* Function Declarations */
604
/*************************/
605
606
void proto_register_zbee_zcl_window_covering(void);
607
608
/* Command Dissector Helpers */
609
static void dissect_zcl_window_covering_go_to_percentage(tvbuff_t *tvb, proto_tree *tree, unsigned *offset);
610
611
/* Private functions prototype */
612
613
/*************************/
614
/* Global Variables      */
615
/*************************/
616
/* Initialize the protocol and registered fields */
617
static int proto_zbee_zcl_window_covering;
618
619
static int hf_zbee_zcl_window_covering_attr_id;
620
static int hf_zbee_zcl_window_covering_type;
621
static int hf_zbee_zcl_window_covering_current_position_lift_percentage;
622
static int hf_zbee_zcl_window_covering_current_position_tilt_percentage;
623
624
static int hf_zbee_zcl_window_covering_go_to_percentage;
625
static int hf_zbee_zcl_window_covering_srv_rx_cmd_id;
626
627
/* Initialize the subtree pointers */
628
static int ett_zbee_zcl_window_covering;
629
630
/* Attributes */
631
static const value_string zbee_zcl_window_covering_attr_names[] = {
632
    { ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_TYPE,                                "Window covering type" },
633
    { ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE,    "Current position lift percentage" },
634
    { ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE,    "Current position tilt percentage" },
635
    { 0, NULL }
636
};
637
638
/* Server Commands Received */
639
static const value_string zbee_zcl_window_covering_srv_rx_cmd_names[] = {
640
    { ZBEE_ZCL_CMD_ID_WINDOW_COVERING_UP_OPEN,               "Up / Open" },
641
    { ZBEE_ZCL_CMD_ID_WINDOW_COVERING_DOWN_CLOSE,            "Down / Close" },
642
    { ZBEE_ZCL_CMD_ID_WINDOW_COVERING_STOP,                  "Stop" },
643
    { ZBEE_ZCL_CMD_ID_WINDOW_COVERING_GO_TO_LIFT_PERCENTAGE, "Go to lift closed percentage" },
644
    { ZBEE_ZCL_CMD_ID_WINDOW_COVERING_GO_TO_TILT_PERCENTAGE, "Go to tilt percentage" },
645
    { 0, NULL }
646
};
647
648
/*************************/
649
/* Function Bodies       */
650
/*************************/
651
652
/**
653
 *ZigBee ZCL Window Covering cluster dissector for wireshark.
654
 *
655
 *@param tvb pointer to buffer containing raw packet.
656
 *@param pinfo pointer to packet information fields
657
 *@param tree pointer to data tree Wireshark uses to display packet.
658
*/
659
static int
660
dissect_zbee_zcl_window_covering(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
661
2
{
662
2
    proto_tree        *payload_tree;
663
2
    zbee_zcl_packet   *zcl;
664
2
    unsigned          offset = 0;
665
2
    uint8_t           cmd_id;
666
2
    int               rem_len;
667
668
    /* Reject the packet if data is NULL */
669
2
    if (data == NULL)
670
0
        return 0;
671
2
    zcl = (zbee_zcl_packet *)data;
672
2
    cmd_id = zcl->cmd_id;
673
674
    /*  Create a subtree for the ZCL Command frame, and add the command ID to it. */
675
2
    if (zcl->direction == ZBEE_ZCL_FCF_TO_SERVER) {
676
        /* Append the command name to the info column. */
677
1
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s, Seq: %u",
678
1
            val_to_str_const(cmd_id, zbee_zcl_window_covering_srv_rx_cmd_names, "Unknown Command"),
679
1
            zcl->tran_seqno);
680
681
        /* Add the command ID. */
682
1
        proto_tree_add_item(tree, hf_zbee_zcl_window_covering_srv_rx_cmd_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
683
684
        /* Check if this command has a payload, then add the payload tree */
685
1
        rem_len = tvb_reported_length_remaining(tvb, ++offset);
686
1
        if (rem_len > 0) {
687
1
            payload_tree = proto_tree_add_subtree(tree, tvb, offset, rem_len, ett_zbee_zcl_window_covering, NULL, "Payload");
688
689
            /* Call the appropriate command dissector */
690
1
            switch (cmd_id) {
691
0
                case ZBEE_ZCL_CMD_ID_WINDOW_COVERING_GO_TO_LIFT_PERCENTAGE:
692
0
                case ZBEE_ZCL_CMD_ID_WINDOW_COVERING_GO_TO_TILT_PERCENTAGE:
693
0
                    dissect_zcl_window_covering_go_to_percentage(tvb, payload_tree, &offset);
694
0
                    break;
695
696
1
                case ZBEE_ZCL_CMD_ID_WINDOW_COVERING_UP_OPEN:
697
1
                case ZBEE_ZCL_CMD_ID_WINDOW_COVERING_DOWN_CLOSE:
698
1
                case ZBEE_ZCL_CMD_ID_WINDOW_COVERING_STOP:
699
                    /* No Payload */
700
1
                default:
701
1
                    break;
702
1
            }
703
1
        }
704
1
    }
705
706
2
    return tvb_captured_length(tvb);
707
2
} /*dissect_zbee_zcl_window_covering */
708
709
/**
710
 *This function decodes the go to lift/tilt percentage
711
 *
712
 *@param  tvb the tv buffer of the current data_type
713
 *@param  tree the tree to append this item to
714
 *@param  offset offset of data in tvb
715
*/
716
static void
717
dissect_zcl_window_covering_go_to_percentage(tvbuff_t *tvb, proto_tree *tree, unsigned *offset)
718
0
{
719
    /* Retrieve "go to lift/tilt percentage" field */
720
0
    proto_tree_add_item(tree, hf_zbee_zcl_window_covering_go_to_percentage, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
721
0
    *offset += 1;
722
723
0
} /*dissect_zcl_window_covering_go_to_percentage*/
724
725
/**
726
 *This function is called by ZCL foundation dissector in order to decode
727
 *
728
 *@param tree pointer to data tree Wireshark uses to display packet.
729
 *@param tvb pointer to buffer containing raw packet.
730
 *@param offset pointer to buffer offset
731
 *@param attr_id attribute identifier
732
 *@param data_type attribute data type
733
 *@param client_attr ZCL client
734
*/
735
static void
736
dissect_zcl_window_covering_attr_data(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, unsigned *offset, uint16_t attr_id, unsigned data_type, bool client_attr)
737
173
{
738
    /* Dissect attribute data type and data */
739
173
    switch ( attr_id ) {
740
741
32
        case ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_TYPE:
742
32
            proto_tree_add_item(tree, hf_zbee_zcl_window_covering_type, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
743
32
            *offset += 1;
744
32
            break;
745
746
1
        case ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE:
747
1
            proto_tree_add_item(tree, hf_zbee_zcl_window_covering_current_position_lift_percentage, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
748
1
            *offset += 1;
749
1
            break;
750
751
0
        case ZBEE_ZCL_ATTR_ID_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE:
752
0
            proto_tree_add_item(tree, hf_zbee_zcl_window_covering_current_position_tilt_percentage, tvb, *offset, 1, ENC_LITTLE_ENDIAN);
753
0
            *offset += 1;
754
0
            break;
755
756
140
        default:
757
140
            dissect_zcl_attr_data(tvb, pinfo, tree, offset, data_type, client_attr);
758
140
            break;
759
173
    }
760
761
173
} /*dissect_zcl_window_covering_attr_data*/
762
763
/**
764
 *ZigBee ZCL Window Covering cluster protocol registration routine.
765
 *
766
*/
767
void
768
proto_register_zbee_zcl_window_covering(void)
769
16
{
770
    /* Setup list of header fields */
771
16
    static hf_register_info hf[] = {
772
773
16
        { &hf_zbee_zcl_window_covering_attr_id,
774
16
            { "Attribute", "zbee_zcl_closures.window_covering.attr_id", FT_UINT16, BASE_HEX, VALS(zbee_zcl_window_covering_attr_names),
775
16
            0x00, NULL, HFILL } },
776
777
16
        { &hf_zbee_zcl_window_covering_type,
778
16
            { "Type", "zbee_zcl_closures.window_covering.attr.type", FT_UINT8, BASE_HEX, NULL,
779
16
            0x00, NULL, HFILL } },
780
781
16
        { &hf_zbee_zcl_window_covering_current_position_lift_percentage,
782
16
            { "Current position lift percentage", "zbee_zcl_closures.window_covering.attr.current_position_lift_percentage", FT_UINT8, BASE_DEC, NULL,
783
16
            0x00, NULL, HFILL } },
784
785
16
        { &hf_zbee_zcl_window_covering_current_position_tilt_percentage,
786
16
            { "Current position tilt percentage", "zbee_zcl_closures.window_covering.attr.current_position_tilt_percentage", FT_UINT8, BASE_DEC, NULL,
787
16
            0x00, NULL, HFILL } },
788
789
16
        { &hf_zbee_zcl_window_covering_go_to_percentage,
790
16
            { "Go to", "zbee_zcl_closures.window_covering.go_to", FT_UINT8, BASE_DEC, NULL,
791
16
            0x00, NULL, HFILL } },
792
793
16
        { &hf_zbee_zcl_window_covering_srv_rx_cmd_id,
794
16
            { "Command", "zbee_zcl_closures.window_covering.cmd.srv_rx.id", FT_UINT8, BASE_HEX, VALS(zbee_zcl_window_covering_srv_rx_cmd_names),
795
16
            0x00, NULL, HFILL } },
796
16
    };
797
798
    /* ZCL Window Covering subtrees */
799
16
    static int *ett[] = {
800
16
        &ett_zbee_zcl_window_covering
801
16
    };
802
803
    /* Register the ZigBee ZCL Window Covering cluster protocol name and description */
804
16
    proto_zbee_zcl_window_covering = proto_register_protocol("ZigBee ZCL Window Covering", "ZCL Window Covering", ZBEE_PROTOABBREV_ZCL_WINDOW_COVERING);
805
16
    proto_register_field_array(proto_zbee_zcl_window_covering, hf, array_length(hf));
806
16
    proto_register_subtree_array(ett, array_length(ett));
807
808
    /* Register the ZigBee ZCL Window Covering dissector. */
809
16
    register_dissector(ZBEE_PROTOABBREV_ZCL_WINDOW_COVERING, dissect_zbee_zcl_window_covering, proto_zbee_zcl_window_covering);
810
811
16
} /*proto_register_zbee_zcl_window_covering*/
812
813
814
/**
815
 *Hands off the ZCL Window Covering dissector.
816
 *
817
*/
818
void
819
proto_reg_handoff_zbee_zcl_window_covering(void)
820
16
{
821
16
    zbee_zcl_init_cluster(  ZBEE_PROTOABBREV_ZCL_WINDOW_COVERING,
822
16
                            proto_zbee_zcl_window_covering,
823
16
                            ett_zbee_zcl_window_covering,
824
16
                            ZBEE_ZCL_CID_WINDOW_COVERING,
825
16
                            ZBEE_MFG_CODE_NONE,
826
16
                            hf_zbee_zcl_window_covering_attr_id,
827
16
                            hf_zbee_zcl_window_covering_attr_id,
828
16
                            hf_zbee_zcl_window_covering_srv_rx_cmd_id,
829
16
                            -1,
830
16
                            dissect_zcl_window_covering_attr_data
831
16
                         );
832
16
} /*proto_reg_handoff_zbee_zcl_window_covering*/
833
834
/*
835
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
836
 *
837
 * Local variables:
838
 * c-basic-offset: 4
839
 * tab-width: 8
840
 * indent-tabs-mode: nil
841
 * End:
842
 *
843
 * vi: set shiftwidth=4 tabstop=8 expandtab:
844
 * :indentSize=4:tabSize=8:noTabs=true:
845
 */