/* packet-zbee-aps.h
 * Dissector routines for the ZigBee Application Support Sub-layer (APS)
 * By Owen Kirby <osk@exegin.com>
 * Copyright 2009 Exegin Technologies Limited
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#ifndef PACKET_ZBEE_APS_H
#define PACKET_ZBEE_APS_H

/* ZigBee APS */
#define ZBEE_APS_FCF_FRAME_TYPE     0x03
#define ZBEE_APS_FCF_DELIVERY_MODE  0x0c
#define ZBEE_APS_FCF_INDIRECT_MODE  0x10    /* ZigBee 2004 and earlier.  */
#define ZBEE_APS_FCF_ACK_FORMAT     0x10    /* ZigBee 2007 and later.    */
#define ZBEE_APS_FCF_SECURITY       0x20
#define ZBEE_APS_FCF_ACK_REQ        0x40
#define ZBEE_APS_FCF_EXT_HEADER     0x80

#define ZBEE_APS_FCF_DATA           0x00
#define ZBEE_APS_FCF_CMD            0x01
#define ZBEE_APS_FCF_ACK            0x02
#define ZBEE_APS_FCF_INTERPAN       0x03

#define ZBEE_APS_FCF_UNICAST        0x00
#define ZBEE_APS_FCF_INDIRECT       0x01
#define ZBEE_APS_FCF_BCAST          0x02
#define ZBEE_APS_FCF_GROUP          0x03    /* ZigBee 2006 and later.    */

#define ZBEE_APS_EXT_FCF_FRAGMENT           0x03
#define ZBEE_APS_EXT_FCF_FRAGMENT_NONE      0x00
#define ZBEE_APS_EXT_FCF_FRAGMENT_FIRST     0x01
#define ZBEE_APS_EXT_FCF_FRAGMENT_MIDDLE    0x02

#define ZBEE_APS_CMD_SKKE1                  0x01
#define ZBEE_APS_CMD_SKKE2                  0x02
#define ZBEE_APS_CMD_SKKE3                  0x03
#define ZBEE_APS_CMD_SKKE4                  0x04
#define ZBEE_APS_CMD_TRANSPORT_KEY          0x05
#define ZBEE_APS_CMD_UPDATE_DEVICE          0x06
#define ZBEE_APS_CMD_REMOVE_DEVICE          0x07
#define ZBEE_APS_CMD_REQUEST_KEY            0x08
#define ZBEE_APS_CMD_SWITCH_KEY             0x09
#define ZBEE_APS_CMD_EA_INIT_CHLNG          0x0a
#define ZBEE_APS_CMD_EA_RESP_CHLNG          0x0b
#define ZBEE_APS_CMD_EA_INIT_MAC_DATA       0x0c
#define ZBEE_APS_CMD_EA_RESP_MAC_DATA       0x0d
#define ZBEE_APS_CMD_TUNNEL                 0x0e
#define ZBEE_APS_CMD_VERIFY_KEY             0x0f
#define ZBEE_APS_CMD_CONFIRM_KEY            0x10
#define ZBEE_APS_CMD_RELAY_MSG_DOWNSTREAM   0x11
#define ZBEE_APS_CMD_RELAY_MSG_UPSTREAM     0x12

#define ZBEE_APS_CMD_KEY_TC_MASTER          0x00
#define ZBEE_APS_CMD_KEY_STANDARD_NWK       0x01
#define ZBEE_APS_CMD_KEY_APP_MASTER         0x02
#define ZBEE_APS_CMD_KEY_APP_LINK           0x03
#define ZBEE_APS_CMD_KEY_TC_LINK            0x04
#define ZBEE_APS_CMD_KEY_HIGH_SEC_NWK       0x05

#define ZBEE_APS_CMD_SKKE_DATA_LENGTH       16
#define ZBEE_APS_CMD_KEY_LENGTH             16

#define ZBEE_APS_CMD_REQ_NWK_KEY            0x01
#define ZBEE_APS_CMD_REQ_APP_KEY            0x02

#define ZBEE_APS_CMD_UPDATE_STANDARD_SEC_REJOIN     0x00
#define ZBEE_APS_CMD_UPDATE_STANDARD_UNSEC_JOIN     0x01
#define ZBEE_APS_CMD_UPDATE_LEAVE                   0x02
#define ZBEE_APS_CMD_UPDATE_STANDARD_UNSEC_REJOIN   0x03
#define ZBEE_APS_CMD_UPDATE_HIGH_SEC_REJOIN         0x04
#define ZBEE_APS_CMD_UPDATE_HIGH_UNSEC_JOIN         0x05
#define ZBEE_APS_CMD_UPDATE_HIGH_UNSEC_REJOIN       0x07

#define ZBEE_APS_CMD_EA_KEY_NWK             0x00
#define ZBEE_APS_CMD_EA_KEY_LINK            0x01
#define ZBEE_APS_CMD_EA_CHALLENGE_LENGTH    16
#define ZBEE_APS_CMD_EA_MAC_LENGTH          16
#define ZBEE_APS_CMD_EA_DATA_LENGTH         4

/* Fields for ZigBee 2004 and earlier. */
#define ZBEE_APP_TYPE                       0xF0
#define ZBEE_APP_COUNT                      0x0F

#define ZBEE_APP_TYPE_KVP                   0x01
#define ZBEE_APP_TYPE_MSG                   0x02

#define ZBEE_APP_KVP_CMD                    0x0F
#define ZBEE_APP_KVP_TYPE                   0xF0

#define ZBEE_APP_KVP_SET                    0x01
#define ZBEE_APP_KVP_EVENT                  0x02
#define ZBEE_APP_KVP_GET_ACK                0x04
#define ZBEE_APP_KVP_SET_ACK                0x05
#define ZBEE_APP_KVP_EVENT_ACK              0x06
#define ZBEE_APP_KVP_GET_RESP               0x08
#define ZBEE_APP_KVP_SET_RESP               0x09
#define ZBEE_APP_KVP_EVENT_RESP             0x0A

#define ZBEE_APP_KVP_NO_DATA                0x00
#define ZBEE_APP_KVP_UINT8                  0x01
#define ZBEE_APP_KVP_INT8                   0x02
#define ZBEE_APP_KVP_UINT16                 0x03
#define ZBEE_APP_KVP_INT16                  0x04
#define ZBEE_APP_KVP_FLOAT16                0x0B
#define ZBEE_APP_KVP_ABS_TIME               0x0C
#define ZBEE_APP_KVP_REL_TIME               0x0D
#define ZBEE_APP_KVP_CHAR_STRING            0x0E
#define ZBEE_APP_KVP_OCT_STRING             0x0F

#define ZBEE_APP_KVP_OVERHEAD               4

/* ZCL Cluster IDs - General */
#define ZBEE_ZCL_CID_BASIC                          0x0000
#define ZBEE_ZCL_CID_POWER_CONFIG                   0x0001
#define ZBEE_ZCL_CID_DEVICE_TEMP_CONFIG             0x0002
#define ZBEE_ZCL_CID_IDENTIFY                       0x0003
#define ZBEE_ZCL_CID_GROUPS                         0x0004
#define ZBEE_ZCL_CID_SCENES                         0x0005
#define ZBEE_ZCL_CID_ON_OFF                         0x0006
#define ZBEE_ZCL_CID_ON_OFF_SWITCH_CONFIG           0x0007
#define ZBEE_ZCL_CID_LEVEL_CONTROL                  0x0008
#define ZBEE_ZCL_CID_ALARMS                         0x0009
#define ZBEE_ZCL_CID_TIME                           0x000a
#define ZBEE_ZCL_CID_RSSI_LOCATION                  0x000b
#define ZBEE_ZCL_CID_ANALOG_INPUT_BASIC             0x000c
#define ZBEE_ZCL_CID_ANALOG_OUTPUT_BASIC            0x000d
#define ZBEE_ZCL_CID_ANALOG_VALUE_BASIC             0x000e
#define ZBEE_ZCL_CID_BINARY_INPUT_BASIC             0x000f
#define ZBEE_ZCL_CID_BINARY_OUTPUT_BASIC            0x0010
#define ZBEE_ZCL_CID_BINARY_VALUE_BASIC             0x0011
#define ZBEE_ZCL_CID_MULTISTATE_INPUT_BASIC         0x0012
#define ZBEE_ZCL_CID_MULTISTATE_OUTPUT_BASIC        0x0013
#define ZBEE_ZCL_CID_MULTISTATE_VALUE_BASIC         0x0014
#define ZBEE_ZCL_CID_COMMISSIONING                  0x0015
#define ZBEE_ZCL_CID_PARTITION                      0x0016
#define ZBEE_ZCL_CID_OTA_UPGRADE                    0x0019
#define ZBEE_ZCL_CID_POLL_CONTROL                   0x0020
#define ZBEE_ZCL_CID_GP                             0x0021
/* */
#define ZBEE_ZCL_CID_POWER_PROFILE                  0x001a
#define ZBEE_ZCL_CID_APPLIANCE_CONTROL              0x001b

/* ZCL Cluster IDs - Closures */
#define ZBEE_ZCL_CID_SHADE_CONFIG                   0x0100
#define ZBEE_ZCL_CID_DOOR_LOCK                      0X0101
#define ZBEE_ZCL_CID_WINDOW_COVERING                0X0102

/* ZCL Cluster IDs - HVAC */
#define ZBEE_ZCL_CID_PUMP_CONFIG_CONTROL            0x0200
#define ZBEE_ZCL_CID_THERMOSTAT                     0x0201
#define ZBEE_ZCL_CID_FAN_CONTROL                    0x0202
#define ZBEE_ZCL_CID_DEHUMIDIFICATION_CONTROL       0x0203
#define ZBEE_ZCL_CID_THERMOSTAT_UI_CONFIG           0x0204

/* ZCL Cluster IDs - Lighting */
#define ZBEE_ZCL_CID_COLOR_CONTROL                  0x0300
#define ZBEE_ZCL_CID_BALLAST_CONFIG                 0x0301

/* ZCL Cluster IDs - Measurement and Sensing */
#define ZBEE_ZCL_CID_ILLUMINANCE_MEASUREMENT        0x0400
#define ZBEE_ZCL_CID_ILLUMINANCE_LEVEL_SENSING      0x0401
#define ZBEE_ZCL_CID_TEMPERATURE_MEASUREMENT        0x0402
#define ZBEE_ZCL_CID_PRESSURE_MEASUREMENT           0x0403
#define ZBEE_ZCL_CID_FLOW_MEASUREMENT               0x0404
#define ZBEE_ZCL_CID_REL_HUMIDITY_MEASUREMENT       0x0405
#define ZBEE_ZCL_CID_OCCUPANCY_SENSING              0x0406
#define ZBEE_ZCL_CID_ELECTRICAL_MEASUREMENT         0x0b04

/* ZCL Cluster IDs - Security and Safety */
#define ZBEE_ZCL_CID_IAS_ZONE                       0x0500
#define ZBEE_ZCL_CID_IAS_ACE                        0x0501
#define ZBEE_ZCL_CID_IAS_WD                         0x0502

/* ZCL Cluster IDs - Protocol Interfaces */
#define ZBEE_ZCL_CID_GENERIC_TUNNEL                 0x0600
#define ZBEE_ZCL_CID_BACNET_PROTOCOL_TUNNEL         0x0601
#define ZBEE_ZCL_CID_BACNET_ANALOG_INPUT_REG        0x0602
#define ZBEE_ZCL_CID_BACNET_ANALOG_INPUT_EXT        0x0603
#define ZBEE_ZCL_CID_BACNET_ANALOG_OUTPUT_REG       0x0604
#define ZBEE_ZCL_CID_BACNET_ANALOG_OUTPUT_EXT       0x0605
#define ZBEE_ZCL_CID_BACNET_ANALOG_VALUE_REG        0x0606
#define ZBEE_ZCL_CID_BACNET_ANALOG_VALUE_EXT        0x0607
#define ZBEE_ZCL_CID_BACNET_BINARY_INPUT_REG        0x0608
#define ZBEE_ZCL_CID_BACNET_BINARY_INPUT_EXT        0x0609
#define ZBEE_ZCL_CID_BACNET_BINARY_OUTPUT_REG       0x060a
#define ZBEE_ZCL_CID_BACNET_BINARY_OUTPUT_EXT       0x060b
#define ZBEE_ZCL_CID_BACNET_BINARY_VALUE_REG        0x060c
#define ZBEE_ZCL_CID_BACNET_BINARY_VALUE_EXT        0x060d
#define ZBEE_ZCL_CID_BACNET_MULTISTATE_INPUT_REG    0x060e
#define ZBEE_ZCL_CID_BACNET_MULTISTATE_INPUT_EXT    0x060f
#define ZBEE_ZCL_CID_BACNET_MULTISTATE_OUTPUT_REG   0x0610
#define ZBEE_ZCL_CID_BACNET_MULTISTATE_OUTPUT_EXT   0x0611
#define ZBEE_ZCL_CID_BACNET_MULTISTATE_VALUE_REG    0x0612
#define ZBEE_ZCL_CID_BACNET_MULTISTATE_VALUE_EXT    0x0613

/* ZCL Cluster IDs - Smart Energy */
#define ZBEE_ZCL_CID_KEEP_ALIVE                     0x0025
#define ZBEE_ZCL_CID_PRICE                          0x0700
#define ZBEE_ZCL_CID_DEMAND_RESPONSE_LOAD_CONTROL   0x0701
#define ZBEE_ZCL_CID_SIMPLE_METERING                0x0702
#define ZBEE_ZCL_CID_MESSAGE                        0x0703
#define ZBEE_ZCL_CID_TUNNELING                      0x0704
#define ZBEE_ZCL_CID_PRE_PAYMENT                    0x0705
#define ZBEE_ZCL_CID_ENERGY_MANAGEMENT              0x0706
#define ZBEE_ZCL_CID_CALENDAR                       0x0707
#define ZBEE_ZCL_CID_DEVICE_MANAGEMENT              0x0708
#define ZBEE_ZCL_CID_EVENTS                         0x0709
#define ZBEE_ZCL_CID_MDU_PAIRING                    0x070A
#define ZBEE_ZCL_CID_SUB_GHZ                        0x070B
#define ZBEE_ZCL_CID_DAILY_SCHEDULE                 0x070D

/* ZCL Cluster IDs - Key Establishment */
#define ZBEE_ZCL_CID_KE                             0x0800

/* ZCL Cluster IDs - Home Automation */
#define ZBEE_ZCL_CID_APPLIANCE_IDENTIFICATION       0x0b00
#define ZBEE_ZCL_CID_METER_IDENTIFICATION           0x0b01
#define ZBEE_ZCL_CID_APPLIANCE_EVENTS_AND_ALERT     0x0b02
#define ZBEE_ZCL_CID_APPLIANCE_STATISTICS           0x0b03

#define ZBEE_ZCL_CID_ZLL                            0x1000

#define ZBEE_ZCL_CID_MANUFACTURER_SPECIFIC_MIN      0xFC00
#define ZBEE_ZCL_CID_MANUFACTURER_SPECIFIC_MAX      0xFFFF

/* ZCL Test Profile #2 Clusters */
#define ZBEE_APS_T2_CID_TCP                         0x0001
#define ZBEE_APS_T2_CID_RESPC                       0x0002
#define ZBEE_APS_T2_CID_RETPC                       0x0003
#define ZBEE_APS_T2_CID_PCR                         0x0004
#define ZBEE_APS_T2_CID_BTREQ                       0x001c
#define ZBEE_APS_T2_CID_BTGREQ                      0x001d
#define ZBEE_APS_T2_CID_BTRES                       0x0054
#define ZBEE_APS_T2_CID_BTRES_S_SBT                 0x00
#define ZBEE_APS_T2_CID_BTRES_S_TFOFA               0x01
#define ZBEE_APS_T2_CID_BTGRES                      0x0055
#define ZBEE_APS_T2_CID_RDREQ                       0x1000
#define ZBEE_APS_T2_CID_RDRES                       0x1001
#define ZBEE_APS_T2_CID_FREQ                        0xa0a8
#define ZBEE_APS_T2_CID_FRES                        0xe000
#define ZBEE_APS_T2_CID_FNDR                        0xe001
#define ZBEE_APS_T2_CID_BR                          0xf000
#define ZBEE_APS_T2_CID_BTADR                       0xf001
#define ZBEE_APS_T2_CID_BTARXOWIDR                  0xf00a
#define ZBEE_APS_T2_CID_BTARACR                     0xf00e


#define ZBEE_APP_STATUS_SUCCESS                     0x00 /*A request has been executed successfully.*/
#define ZBEE_APP_STATUS_ASDU_TOO_LONG               0xa0 /*A transmit request failed since the ASDU is too large and fragmentation is not supported.*/
#define ZBEE_APP_STATUS_DEFRAG_DEFERRED             0xa1 /*A received fragmented frame could not be defragmented at the current time.*/
#define ZBEE_APP_STATUS_DEFRAG_UNSUPPORTED          0xa2 /*A received fragmented frame could not be defragmented since the device does not support fragmentation.*/
#define ZBEE_APP_STATUS_ILLEGAL_REQUEST             0xa3 /*A parameter value was out of range.*/
#define ZBEE_APP_STATUS_INVALID_BINDING             0xa4 /*An APSME-UNBIND.request failed due to the requested binding link not existing in the binding table.*/
#define ZBEE_APP_STATUS_INVALID_GROUP               0xa5 /*An APSME-REMOVE-GROUP.request has been issued with a group identifier that does not appear in the group table.*/
#define ZBEE_APP_STATUS_INVALID_PARAMETER           0xa6 /*A parameter value was invalid or out of range.*/
#define ZBEE_APP_STATUS_NO_ACK                      0xa7 /*An APSDE-DATA.request requesting acknowledged trans-mission failed due to no acknowledgement being received.*/
#define ZBEE_APP_STATUS_NO_BOUND_DEVICE             0xa8 /*An APSDE-DATA.request with a destination addressing mode set to 0x00 failed due to there being no devices bound to this device.*/
#define ZBEE_APP_STATUS_NO_SHORT_ADDRESS            0xa9 /*An APSDE-DATA.request with a destination addressing mode set to 0x03 failed due to no corresponding short address found*/
#define ZBEE_APP_STATUS_NOT_SUPPORTED               0xaa /*An APSDE-DATA.request with a destination addressing mode set to 0x00 failed due to a binding table not being supported on the device.*/
#define ZBEE_APP_STATUS_SECURED_LINK_KEY            0xab /*An ASDU was received that was secured using a link key.*/
#define ZBEE_APP_STATUS_SECURED_NWK_KEY             0xac /*An ASDU was received that was secured using a network key.*/
#define ZBEE_APP_STATUS_SECURITY_FAIL               0xad /*An APSDE-DATA.request requesting security has resulted in an error during the corresponding security processing.*/
#define ZBEE_APP_STATUS_TABLE_FULL                  0xae /*An APSME-BIND.request or APSME.ADD-GROUP.request issued when the binding or group tables, respectively, were full.*/
#define ZBEE_APP_STATUS_UNSECURED                   0xaf /*An ASDU was received without any security.*/
#define ZBEE_APP_STATUS_UNSUPPORTED_ATTRIBUTE       0xb0 /*An APSME-GET.request or APSME-SET.request has been issued with an unknown attribute identifier.*/

#define ZBEE_APS_NODE_PROTO_DATA                    0

/*  Structure to contain the APS frame information */
typedef struct{
    bool        indirect_mode;  /* ZigBee 2004 and Earlier  */
    uint8_t     type;
    uint8_t     delivery;
    bool        ack_format;     /* ZigBee 2007 and Later    */
    bool        security;
    bool        ack_req;
    bool        ext_header;     /* ZigBee 2007 and Later    */

    uint8_t     dst;
    uint16_t    group;          /* ZigBee 2006 and Later    */
    uint16_t    profile;
    uint8_t     src;
    uint8_t     counter;

    /* Fragmentation Fields. */
    uint8_t     fragmentation;  /* ZigBee 2007 and Later    */
    uint8_t     block_number;   /* ZigBee 2007 and Later    */

    /* Some helpers for the upper layers. */
    bool        profile_present;
    bool        dst_present;
    bool        src_present;
} zbee_aps_packet;

/*  Structure to contain APS node information */
struct zbee_aps_node_info
{
    uint32_t extended_counter;                         /**> the counter, extended to a 32-bit
                                                       * int to guarantee it increasing monotonically
                                                       */
};

/*  Structure to contain APS node information for a packet */
struct zbee_aps_node_packet_info
{
    uint32_t extended_counter;                         /**> the counter, extended to a 32-bit
                                                       * int to guarantee it increasing monotonically
                                                       */
};

/* ZigBee Smart Energy version used for preferences */
extern int   gPREF_zbee_se_protocol_version;

enum {
    ZBEE_SE_VERSION_1_1B,
    ZBEE_SE_VERSION_1_2,
    ZBEE_SE_VERSION_1_2A,
    ZBEE_SE_VERSION_1_2B,
    ZBEE_SE_VERSION_1_4
};

/**************************************
 * Value Strings
 **************************************
 */

extern const range_string zbee_aps_cid_names[];
extern const range_string zbee_aps_apid_names[];

#endif /* PACKET_ZBEE_APS_H*/

/*
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 4
 * tab-width: 8
 * indent-tabs-mode: nil
 * End:
 *
 * vi: set shiftwidth=4 tabstop=8 expandtab:
 * :indentSize=4:tabSize=8:noTabs=true:
 */
