2 * Dissector routines for the ZigBee Application Support Sub-layer (APS)
3 * By Owen Kirby <osk@exegin.com>
4 * Copyright 2009 Exegin Technologies Limited
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/prefs.h> /* req'd for packet-zbee-security.h */
18 #include <epan/expert.h>
19 #include <epan/reassemble.h>
20 #include <epan/proto_data.h>
22 #include <wsutil/array.h>
24 #include "packet-zbee.h"
25 #include "packet-zbee-nwk.h"
26 #include "packet-zbee-security.h"
27 #include "packet-zbee-aps.h"
28 #include "packet-zbee-zdp.h"
29 #include "packet-zbee-tlv.h"
31 /*************************
32 * Function Declarations *
33 *************************
35 /* Dissector Routines */
36 static void dissect_zbee_aps_cmd (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, uint8_t version
, void *data
);
38 /* Command Dissector Helpers */
39 static unsigned dissect_zbee_aps_skke_challenge (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
40 static unsigned dissect_zbee_aps_skke_data (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
41 static unsigned dissect_zbee_aps_transport_key (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
42 static unsigned dissect_zbee_aps_update_device (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
, uint8_t version
);
43 static unsigned dissect_zbee_aps_remove_device (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
44 static unsigned dissect_zbee_aps_request_key (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
45 static unsigned dissect_zbee_aps_switch_key (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
46 static unsigned dissect_zbee_aps_auth_challenge (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
47 static unsigned dissect_zbee_aps_auth_data (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
48 static unsigned dissect_zbee_aps_tunnel (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
, void *data
);
49 static unsigned dissect_zbee_aps_verify_key (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
50 static unsigned dissect_zbee_aps_confirm_key (tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
);
51 static unsigned dissect_zbee_t2 (tvbuff_t
*tvb
, proto_tree
*tree
, uint16_t cluster_id
);
54 static unsigned zbee_apf_transaction_len (tvbuff_t
*tvb
, unsigned offset
, uint8_t type
);
56 void dissect_zbee_aps_status_code(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
);
57 void proto_register_zbee_aps(void);
64 static int proto_zbee_aps
;
65 static int hf_zbee_aps_fcf_frame_type
;
66 static int hf_zbee_aps_fcf_delivery
;
67 static int hf_zbee_aps_fcf_indirect_mode
; /* ZigBee 2004 and earlier. */
68 static int hf_zbee_aps_fcf_ack_format
; /* ZigBee 2007 and later. */
69 static int hf_zbee_aps_fcf_security
;
70 static int hf_zbee_aps_fcf_ack_req
;
71 static int hf_zbee_aps_fcf_ext_header
;
72 static int hf_zbee_aps_dst
;
73 static int hf_zbee_aps_group
;
74 static int hf_zbee_aps_cluster
;
75 static int hf_zbee_aps_profile
;
76 static int hf_zbee_aps_src
;
77 static int hf_zbee_aps_counter
;
78 static int hf_zbee_aps_fragmentation
;
79 static int hf_zbee_aps_block_number
;
80 static int hf_zbee_aps_block_ack
;
81 static int hf_zbee_aps_block_ack1
;
82 static int hf_zbee_aps_block_ack2
;
83 static int hf_zbee_aps_block_ack3
;
84 static int hf_zbee_aps_block_ack4
;
85 static int hf_zbee_aps_block_ack5
;
86 static int hf_zbee_aps_block_ack6
;
87 static int hf_zbee_aps_block_ack7
;
88 static int hf_zbee_aps_block_ack8
;
90 static int hf_zbee_aps_cmd_id
;
91 static int hf_zbee_aps_cmd_initiator
;
92 static int hf_zbee_aps_cmd_responder
;
93 static int hf_zbee_aps_cmd_partner
;
94 static int hf_zbee_aps_cmd_initiator_flag
;
95 static int hf_zbee_aps_cmd_device
;
96 static int hf_zbee_aps_cmd_challenge
;
97 static int hf_zbee_aps_cmd_mac
;
98 static int hf_zbee_aps_cmd_key
;
99 static int hf_zbee_aps_cmd_key_hash
;
100 static int hf_zbee_aps_cmd_key_type
;
101 static int hf_zbee_aps_cmd_dst
;
102 static int hf_zbee_aps_cmd_src
;
103 static int hf_zbee_aps_cmd_seqno
;
104 static int hf_zbee_aps_cmd_short_addr
;
105 static int hf_zbee_aps_cmd_device_status
;
106 static int hf_zbee_aps_cmd_status
;
107 static int hf_zbee_aps_cmd_ea_key_type
;
108 static int hf_zbee_aps_cmd_ea_data
;
110 /* Field indices for ZigBee 2003 & earlier Application Framework. */
111 static int proto_zbee_apf
;
112 static int hf_zbee_apf_count
;
113 static int hf_zbee_apf_type
;
115 /* Subtree indices. */
116 static int ett_zbee_aps
;
117 static int ett_zbee_aps_fcf
;
118 static int ett_zbee_aps_ext
;
119 static int ett_zbee_aps_cmd
;
121 /* Fragmentation indices. */
122 static int hf_zbee_aps_fragments
;
123 static int hf_zbee_aps_fragment
;
124 static int hf_zbee_aps_fragment_overlap
;
125 static int hf_zbee_aps_fragment_overlap_conflicts
;
126 static int hf_zbee_aps_fragment_multiple_tails
;
127 static int hf_zbee_aps_fragment_too_long_fragment
;
128 static int hf_zbee_aps_fragment_error
;
129 static int hf_zbee_aps_fragment_count
;
130 static int hf_zbee_aps_reassembled_in
;
131 static int hf_zbee_aps_reassembled_length
;
132 static int ett_zbee_aps_fragment
;
133 static int ett_zbee_aps_fragments
;
135 /* Test Profile #2 indices. */
136 static int hf_zbee_aps_t2_cluster
;
137 static int hf_zbee_aps_t2_btres_octet_sequence
;
138 static int hf_zbee_aps_t2_btres_octet_sequence_length_requested
;
139 static int hf_zbee_aps_t2_btres_status
;
140 static int hf_zbee_aps_t2_btreq_octet_sequence_length
;
143 static int hf_zbee_aps_zdp_cluster
;
145 /* Subtree indices for the ZigBee 2004 & earlier Application Framework. */
146 static int ett_zbee_apf
;
147 static int ett_zbee_aps_frag_ack
;
149 /* Subtree indices for the ZigBee Test Profile #2. */
150 static int ett_zbee_aps_t2
;
152 static expert_field ei_zbee_aps_invalid_delivery_mode
;
153 static expert_field ei_zbee_aps_missing_payload
;
155 /* Dissector Handles. */
156 static dissector_handle_t zbee_aps_handle
;
157 static dissector_handle_t zbee_apf_handle
;
159 /* Dissector List. */
160 static dissector_table_t zbee_aps_dissector_table
;
162 /* Reassembly table. */
163 static reassembly_table zbee_aps_reassembly_table
;
165 static const fragment_items zbee_aps_frag_items
= {
166 /* Fragment subtrees */
167 &ett_zbee_aps_fragment
,
168 &ett_zbee_aps_fragments
,
169 /* Fragment fields */
170 &hf_zbee_aps_fragments
,
171 &hf_zbee_aps_fragment
,
172 &hf_zbee_aps_fragment_overlap
,
173 &hf_zbee_aps_fragment_overlap_conflicts
,
174 &hf_zbee_aps_fragment_multiple_tails
,
175 &hf_zbee_aps_fragment_too_long_fragment
,
176 &hf_zbee_aps_fragment_error
,
177 &hf_zbee_aps_fragment_count
,
178 /* Reassembled in field */
179 &hf_zbee_aps_reassembled_in
,
180 /* Reassembled length field */
181 &hf_zbee_aps_reassembled_length
,
182 /* Reassembled data field */
185 "APS Message fragments"
188 static GHashTable
*zbee_table_aps_extended_counters
;
190 /********************/
192 /********************/
193 /* Frame Type Names */
194 static const value_string zbee_aps_frame_types
[] = {
195 { ZBEE_APS_FCF_DATA
, "Data" },
196 { ZBEE_APS_FCF_CMD
, "Command" },
197 { ZBEE_APS_FCF_ACK
, "Ack" },
198 { ZBEE_APS_FCF_INTERPAN
, "Interpan" },
202 /* Delivery Mode Names */
203 static const value_string zbee_aps_delivery_modes
[] = {
204 { ZBEE_APS_FCF_UNICAST
, "Unicast" },
205 { ZBEE_APS_FCF_INDIRECT
, "Indirect" },
206 { ZBEE_APS_FCF_BCAST
, "Broadcast" },
207 { ZBEE_APS_FCF_GROUP
, "Group" },
211 /* Fragmentation Mode Names */
212 static const value_string zbee_aps_fragmentation_modes
[] = {
213 { ZBEE_APS_EXT_FCF_FRAGMENT_NONE
, "None" },
214 { ZBEE_APS_EXT_FCF_FRAGMENT_FIRST
, "First Block" },
215 { ZBEE_APS_EXT_FCF_FRAGMENT_MIDDLE
, "Middle Block" },
219 /* APS Command Names */
220 static const value_string zbee_aps_cmd_names
[] = {
221 { ZBEE_APS_CMD_SKKE1
, "SKKE-1" },
222 { ZBEE_APS_CMD_SKKE2
, "SKKE-2" },
223 { ZBEE_APS_CMD_SKKE3
, "SKKE-3" },
224 { ZBEE_APS_CMD_SKKE4
, "SKKE-4" },
225 { ZBEE_APS_CMD_TRANSPORT_KEY
, "Transport Key" },
226 { ZBEE_APS_CMD_UPDATE_DEVICE
, "Update Device" },
227 { ZBEE_APS_CMD_REMOVE_DEVICE
, "Remove Device" },
228 { ZBEE_APS_CMD_REQUEST_KEY
, "Request Key" },
229 { ZBEE_APS_CMD_SWITCH_KEY
, "Switch Key" },
230 { ZBEE_APS_CMD_EA_INIT_CHLNG
, "EA Initiator Challenge" },
231 { ZBEE_APS_CMD_EA_RESP_CHLNG
, "EA Responder Challenge" },
232 { ZBEE_APS_CMD_EA_INIT_MAC_DATA
,"EA Initiator MAC" },
233 { ZBEE_APS_CMD_EA_RESP_MAC_DATA
,"EA Responder MAC" },
234 { ZBEE_APS_CMD_TUNNEL
, "Tunnel" },
235 { ZBEE_APS_CMD_VERIFY_KEY
, "Verify Key" },
236 { ZBEE_APS_CMD_CONFIRM_KEY
, "Confirm Key" },
237 { ZBEE_APS_CMD_RELAY_MSG_DOWNSTREAM
, "Relay Message Downstream" },
238 { ZBEE_APS_CMD_RELAY_MSG_UPSTREAM
, "Relay Message Upstream" },
243 static const value_string zbee_aps_key_names
[] = {
244 { ZBEE_APS_CMD_KEY_TC_MASTER
, "Trust Center Master Key" },
245 { ZBEE_APS_CMD_KEY_STANDARD_NWK
, "Standard Network Key" },
246 { ZBEE_APS_CMD_KEY_APP_MASTER
, "Application Master Key" },
247 { ZBEE_APS_CMD_KEY_APP_LINK
, "Application Link Key" },
248 { ZBEE_APS_CMD_KEY_TC_LINK
, "Trust Center Link Key" },
249 { ZBEE_APS_CMD_KEY_HIGH_SEC_NWK
, "High-Security Network Key" },
253 /* APS Key Names (Entity-Authentication). */
254 static const value_string zbee_aps_ea_key_names
[] = {
255 { ZBEE_APS_CMD_EA_KEY_NWK
, "Network Key" },
256 { ZBEE_APS_CMD_EA_KEY_LINK
, "Link Key" },
260 /* Update Device Status Names */
261 static const value_string zbee_aps_update_status_names
[] = {
262 { ZBEE_APS_CMD_UPDATE_STANDARD_SEC_REJOIN
, "Standard security, secured rejoin" },
263 { ZBEE_APS_CMD_UPDATE_STANDARD_UNSEC_JOIN
, "Standard security, unsecured join" },
264 { ZBEE_APS_CMD_UPDATE_LEAVE
, "Device left" },
265 { ZBEE_APS_CMD_UPDATE_STANDARD_UNSEC_REJOIN
,"Standard security, unsecured rejoin" },
266 { ZBEE_APS_CMD_UPDATE_HIGH_SEC_REJOIN
, "High security, secured rejoin" },
267 { ZBEE_APS_CMD_UPDATE_HIGH_UNSEC_JOIN
, "High security, unsecured join" },
268 { ZBEE_APS_CMD_UPDATE_HIGH_UNSEC_REJOIN
, "High security, unsecured rejoin" },
273 /* Update Device Status Names */
274 static const value_string zbee_aps_status_names
[] = {
275 { ZBEE_APP_STATUS_SUCCESS
, "SUCCESS" },
276 { ZBEE_APP_STATUS_ASDU_TOO_LONG
, "ASDU_TOO_LONG" },
277 { ZBEE_APP_STATUS_DEFRAG_DEFERRED
, "DEFRAG_DEFERRED" },
278 { ZBEE_APP_STATUS_DEFRAG_UNSUPPORTED
, "DEFRAG_UNSUPPORTED" },
279 { ZBEE_APP_STATUS_ILLEGAL_REQUEST
, "ILLEGAL_REQUEST" },
280 { ZBEE_APP_STATUS_INVALID_BINDING
, "INVALID_BINDING" },
281 { ZBEE_APP_STATUS_INVALID_GROUP
, "INVALID_GROUP" },
282 { ZBEE_APP_STATUS_INVALID_PARAMETER
, "INVALID_PARAMETER" },
283 { ZBEE_APP_STATUS_NO_ACK
, "NO_ACK" },
284 { ZBEE_APP_STATUS_NO_BOUND_DEVICE
, "NO_BOUND_DEVICE" },
285 { ZBEE_APP_STATUS_NO_SHORT_ADDRESS
, "NO_SHORT_ADDRESS" },
286 { ZBEE_APP_STATUS_NOT_SUPPORTED
, "NOT_SUPPORTED" },
287 { ZBEE_APP_STATUS_SECURED_LINK_KEY
, "SECURED_LINK_KEY" },
288 { ZBEE_APP_STATUS_SECURED_NWK_KEY
, "SECURED_NWK_KEY" },
289 { ZBEE_APP_STATUS_SECURITY_FAIL
, "SECURITY_FAIL" },
290 { ZBEE_APP_STATUS_TABLE_FULL
, "TABLE_FULL" },
291 { ZBEE_APP_STATUS_UNSECURED
, "UNSECURED" },
292 { ZBEE_APP_STATUS_UNSUPPORTED_ATTRIBUTE
, "UNSUPPORTED_ATTRIBUTE" },
297 /* Outdated ZigBee 2004 Value Strings. */
298 static const value_string zbee_apf_type_names
[] = {
299 { ZBEE_APP_TYPE_KVP
, "Key-Value Pair" },
300 { ZBEE_APP_TYPE_MSG
, "Message" },
305 static const value_string zbee_apf_kvp_command_names
[] = {
306 { ZBEE_APP_KVP_SET
, "Set" },
307 { ZBEE_APP_KVP_EVENT
, "Event" },
308 { ZBEE_APP_KVP_GET_ACK
, "Get Acknowledgement" },
309 { ZBEE_APP_KVP_SET_ACK
, "Set Acknowledgement" },
310 { ZBEE_APP_KVP_EVENT_ACK
, "Event Acknowledgement" },
311 { ZBEE_APP_KVP_GET_RESP
, "Get Response" },
312 { ZBEE_APP_KVP_SET_RESP
, "Set Response" },
313 { ZBEE_APP_KVP_EVENT_RESP
, "Event Response" },
319 static const value_string zbee_apf_kvp_type_names
[] = {
320 { ZBEE_APP_KVP_NO_DATA
, "No Data" },
321 { ZBEE_APP_KVP_UINT8
, "8-bit Unsigned Integer" },
322 { ZBEE_APP_KVP_INT8
, "8-bit Signed Integer" },
323 { ZBEE_APP_KVP_UINT16
, "16-bit Unsigned Integer" },
324 { ZBEE_APP_KVP_INT16
, "16-bit Signed Integer" },
325 { ZBEE_APP_KVP_FLOAT16
, "16-bit Floating Point" },
326 { ZBEE_APP_KVP_ABS_TIME
, "Absolute Time" },
327 { ZBEE_APP_KVP_REL_TIME
, "Relative Time" },
328 { ZBEE_APP_KVP_CHAR_STRING
, "Character String" },
329 { ZBEE_APP_KVP_OCT_STRING
, "Octet String" },
334 /* ZigBee Application Profile ID Names */
335 const range_string zbee_aps_apid_names
[] = {
336 { ZBEE_DEVICE_PROFILE
, ZBEE_DEVICE_PROFILE
, "ZigBee Device Profile" },
338 { ZBEE_PROFILE_IPM
, ZBEE_PROFILE_IPM
, "Industrial Plant Monitoring" },
340 { ZBEE_PROFILE_T1
, ZBEE_PROFILE_T1
, "Test Profile #1" },
341 { ZBEE_PROFILE_HA
, ZBEE_PROFILE_HA
, "Home Automation" },
342 { ZBEE_PROFILE_CBA
, ZBEE_PROFILE_CBA
, "Commercial Building Automation" },
343 { ZBEE_PROFILE_WSN
, ZBEE_PROFILE_WSN
, "Wireless Sensor Network" },
344 { ZBEE_PROFILE_TA
, ZBEE_PROFILE_TA
, "Telecom Automation" },
345 { ZBEE_PROFILE_HC
, ZBEE_PROFILE_HC
, "Health Care" },
346 { ZBEE_PROFILE_SE
, ZBEE_PROFILE_SE
, "Smart Energy" },
347 { ZBEE_PROFILE_RS
, ZBEE_PROFILE_RS
, "Retail Services" },
348 { ZBEE_PROFILE_STD_MIN
, ZBEE_PROFILE_STD_MAX
, "Unknown ZigBee Standard" },
350 { ZBEE_PROFILE_T2
, ZBEE_PROFILE_T2
, "Test Profile #2" },
351 { ZBEE_PROFILE_GP
, ZBEE_PROFILE_GP
, "Green Power" },
352 { ZBEE_PROFILE_RSVD0_MIN
, ZBEE_PROFILE_RSVD0_MAX
, "Unknown ZigBee Reserved" },
353 { ZBEE_PROFILE_RSVD1_MIN
, ZBEE_PROFILE_RSVD1_MAX
, "Unknown ZigBee Reserved" },
355 { ZBEE_PROFILE_IEEE_1451_5
, ZBEE_PROFILE_IEEE_1451_5
, "IEEE_1451_5" },
357 { ZBEE_PROFILE_MFR_SPEC_ORG_MIN
, ZBEE_PROFILE_MFR_SPEC_ORG_MAX
,
358 "Unallocated Manufacturer-Specific" },
360 /* Manufacturer Allocations */
361 { ZBEE_PROFILE_CIRRONET_0_MIN
, ZBEE_PROFILE_CIRRONET_0_MAX
, ZBEE_MFG_CIRRONET
},
362 { ZBEE_PROFILE_CHIPCON_MIN
, ZBEE_PROFILE_CHIPCON_MAX
, ZBEE_MFG_CHIPCON
},
363 { ZBEE_PROFILE_EMBER_MIN
, ZBEE_PROFILE_EMBER_MAX
, ZBEE_MFG_EMBER
},
364 { ZBEE_PROFILE_NTS_MIN
, ZBEE_PROFILE_NTS_MAX
, ZBEE_MFG_CHIPCON
},
365 { ZBEE_PROFILE_FREESCALE_MIN
, ZBEE_PROFILE_FREESCALE_MAX
, ZBEE_MFG_FREESCALE
},
366 { ZBEE_PROFILE_IPCOM_MIN
, ZBEE_PROFILE_IPCOM_MAX
, ZBEE_MFG_IPCOM
},
367 { ZBEE_PROFILE_SAN_JUAN_MIN
, ZBEE_PROFILE_SAN_JUAN_MAX
, ZBEE_MFG_SAN_JUAN
},
368 { ZBEE_PROFILE_TUV_MIN
, ZBEE_PROFILE_TUV_MAX
, ZBEE_MFG_TUV
},
369 { ZBEE_PROFILE_COMPXS_MIN
, ZBEE_PROFILE_COMPXS_MAX
, ZBEE_MFG_COMPXS
},
370 { ZBEE_PROFILE_BM_MIN
, ZBEE_PROFILE_BM_MAX
, ZBEE_MFG_BM
},
371 { ZBEE_PROFILE_AWAREPOINT_MIN
, ZBEE_PROFILE_AWAREPOINT_MAX
, ZBEE_MFG_AWAREPOINT
},
372 { ZBEE_PROFILE_SAN_JUAN_1_MIN
, ZBEE_PROFILE_SAN_JUAN_1_MAX
, ZBEE_MFG_SAN_JUAN
},
373 { ZBEE_PROFILE_ZLL
, ZBEE_PROFILE_ZLL
, "ZLL" },
374 { ZBEE_PROFILE_PHILIPS_MIN
, ZBEE_PROFILE_PHILIPS_MAX
, ZBEE_MFG_PHILIPS
},
375 { ZBEE_PROFILE_LUXOFT_MIN
, ZBEE_PROFILE_LUXOFT_MAX
, ZBEE_MFG_LUXOFT
},
376 { ZBEE_PROFILE_KORWIN_MIN
, ZBEE_PROFILE_KORWIN_MAX
, ZBEE_MFG_KORWIN
},
377 { ZBEE_PROFILE_1_RF_MIN
, ZBEE_PROFILE_1_RF_MAX
, ZBEE_MFG_1_RF
},
378 { ZBEE_PROFILE_STG_MIN
, ZBEE_PROFILE_STG_MAX
, ZBEE_MFG_STG
},
379 { ZBEE_PROFILE_TELEGESIS_MIN
, ZBEE_PROFILE_TELEGESIS_MAX
, ZBEE_MFG_TELEGESIS
},
380 { ZBEE_PROFILE_CIRRONET_1_MIN
, ZBEE_PROFILE_CIRRONET_1_MAX
, ZBEE_MFG_CIRRONET
},
381 { ZBEE_PROFILE_VISIONIC_MIN
, ZBEE_PROFILE_VISIONIC_MAX
, ZBEE_MFG_VISIONIC
},
382 { ZBEE_PROFILE_INSTA_MIN
, ZBEE_PROFILE_INSTA_MAX
, ZBEE_MFG_INSTA
},
383 { ZBEE_PROFILE_ATALUM_MIN
, ZBEE_PROFILE_ATALUM_MAX
, ZBEE_MFG_ATALUM
},
384 { ZBEE_PROFILE_ATMEL_MIN
, ZBEE_PROFILE_ATMEL_MAX
, ZBEE_MFG_ATMEL
},
385 { ZBEE_PROFILE_DEVELCO_MIN
, ZBEE_PROFILE_DEVELCO_MAX
, ZBEE_MFG_DEVELCO
},
386 { ZBEE_PROFILE_HONEYWELL_MIN
, ZBEE_PROFILE_HONEYWELL_MAX
, ZBEE_MFG_HONEYWELL
},
387 { ZBEE_PROFILE_NEC_MIN
, ZBEE_PROFILE_NEC_MAX
, ZBEE_MFG_NEC
},
388 { ZBEE_PROFILE_YAMATAKE_MIN
, ZBEE_PROFILE_YAMATAKE_MAX
, ZBEE_MFG_YAMATAKE
},
389 { ZBEE_PROFILE_TENDRIL_MIN
, ZBEE_PROFILE_TENDRIL_MAX
, ZBEE_MFG_TENDRIL
},
390 { ZBEE_PROFILE_ASSA_MIN
, ZBEE_PROFILE_ASSA_MAX
, ZBEE_MFG_ASSA
},
391 { ZBEE_PROFILE_MAXSTREAM_MIN
, ZBEE_PROFILE_MAXSTREAM_MAX
, ZBEE_MFG_MAXSTREAM
},
392 { ZBEE_PROFILE_XANADU_MIN
, ZBEE_PROFILE_XANADU_MAX
, ZBEE_MFG_XANADU
},
393 { ZBEE_PROFILE_NEUROCOM_MIN
, ZBEE_PROFILE_NEUROCOM_MAX
, ZBEE_MFG_NEUROCOM
},
394 { ZBEE_PROFILE_III_MIN
, ZBEE_PROFILE_III_MAX
, ZBEE_MFG_III
},
395 { ZBEE_PROFILE_VANTAGE_MIN
, ZBEE_PROFILE_VANTAGE_MAX
, ZBEE_MFG_VANTAGE
},
396 { ZBEE_PROFILE_ICONTROL_MIN
, ZBEE_PROFILE_ICONTROL_MAX
, ZBEE_MFG_ICONTROL
},
397 { ZBEE_PROFILE_RAYMARINE_MIN
, ZBEE_PROFILE_RAYMARINE_MAX
, ZBEE_MFG_RAYMARINE
},
398 { ZBEE_PROFILE_RENESAS_MIN
, ZBEE_PROFILE_RENESAS_MAX
, ZBEE_MFG_RENESAS
},
399 { ZBEE_PROFILE_LSR_MIN
, ZBEE_PROFILE_LSR_MAX
, ZBEE_MFG_LSR
},
400 { ZBEE_PROFILE_ONITY_MIN
, ZBEE_PROFILE_ONITY_MAX
, ZBEE_MFG_ONITY
},
401 { ZBEE_PROFILE_MONO_MIN
, ZBEE_PROFILE_MONO_MAX
, ZBEE_MFG_MONO
},
402 { ZBEE_PROFILE_RFT_MIN
, ZBEE_PROFILE_RFT_MAX
, ZBEE_MFG_RFT
},
403 { ZBEE_PROFILE_ITRON_MIN
, ZBEE_PROFILE_ITRON_MAX
, ZBEE_MFG_ITRON
},
404 { ZBEE_PROFILE_TRITECH_MIN
, ZBEE_PROFILE_TRITECH_MAX
, ZBEE_MFG_TRITECH
},
405 { ZBEE_PROFILE_EMBEDIT_MIN
, ZBEE_PROFILE_EMBEDIT_MAX
, ZBEE_MFG_EMBEDIT
},
406 { ZBEE_PROFILE_S3C_MIN
, ZBEE_PROFILE_S3C_MAX
, ZBEE_MFG_S3C
},
407 { ZBEE_PROFILE_SIEMENS_MIN
, ZBEE_PROFILE_SIEMENS_MAX
, ZBEE_MFG_SIEMENS
},
408 { ZBEE_PROFILE_MINDTECH_MIN
, ZBEE_PROFILE_MINDTECH_MAX
, ZBEE_MFG_MINDTECH
},
409 { ZBEE_PROFILE_LGE_MIN
, ZBEE_PROFILE_LGE_MAX
, ZBEE_MFG_LGE
},
410 { ZBEE_PROFILE_MITSUBISHI_MIN
, ZBEE_PROFILE_MITSUBISHI_MAX
, ZBEE_MFG_MITSUBISHI
},
411 { ZBEE_PROFILE_JOHNSON_MIN
, ZBEE_PROFILE_JOHNSON_MAX
, ZBEE_MFG_JOHNSON
},
412 { ZBEE_PROFILE_PRI_MIN
, ZBEE_PROFILE_PRI_MAX
, ZBEE_MFG_PRI
},
413 { ZBEE_PROFILE_KNICK_MIN
, ZBEE_PROFILE_KNICK_MAX
, ZBEE_MFG_KNICK
},
414 { ZBEE_PROFILE_VICONICS_MIN
, ZBEE_PROFILE_VICONICS_MAX
, ZBEE_MFG_VICONICS
},
415 { ZBEE_PROFILE_FLEXIPANEL_MIN
, ZBEE_PROFILE_FLEXIPANEL_MAX
, ZBEE_MFG_FLEXIPANEL
},
416 { ZBEE_PROFILE_TRANE_MIN
, ZBEE_PROFILE_TRANE_MAX
, ZBEE_MFG_TRANE
},
417 { ZBEE_PROFILE_JENNIC_MIN
, ZBEE_PROFILE_JENNIC_MAX
, ZBEE_MFG_JENNIC
},
418 { ZBEE_PROFILE_LIG_MIN
, ZBEE_PROFILE_LIG_MAX
, ZBEE_MFG_LIG
},
419 { ZBEE_PROFILE_ALERTME_MIN
, ZBEE_PROFILE_ALERTME_MAX
, ZBEE_MFG_ALERTME
},
420 { ZBEE_PROFILE_DAINTREE_MIN
, ZBEE_PROFILE_DAINTREE_MAX
, ZBEE_MFG_DAINTREE
},
421 { ZBEE_PROFILE_AIJI_MIN
, ZBEE_PROFILE_AIJI_MAX
, ZBEE_MFG_AIJI
},
422 { ZBEE_PROFILE_TEL_ITALIA_MIN
, ZBEE_PROFILE_TEL_ITALIA_MAX
, ZBEE_MFG_TEL_ITALIA
},
423 { ZBEE_PROFILE_MIKROKRETS_MIN
, ZBEE_PROFILE_MIKROKRETS_MAX
, ZBEE_MFG_MIKROKRETS
},
424 { ZBEE_PROFILE_OKI_MIN
, ZBEE_PROFILE_OKI_MAX
, ZBEE_MFG_OKI
},
425 { ZBEE_PROFILE_NEWPORT_MIN
, ZBEE_PROFILE_NEWPORT_MAX
, ZBEE_MFG_NEWPORT
},
427 { ZBEE_PROFILE_C4_CL
, ZBEE_PROFILE_C4_CL
, ZBEE_MFG_C4
" Cluster Library"},
428 { ZBEE_PROFILE_C4_MIN
, ZBEE_PROFILE_C4_MAX
, ZBEE_MFG_C4
},
430 { ZBEE_PROFILE_STM_MIN
, ZBEE_PROFILE_STM_MAX
, ZBEE_MFG_STM
},
431 { ZBEE_PROFILE_ASN_0_MIN
, ZBEE_PROFILE_ASN_0_MAX
, ZBEE_MFG_ASN
},
432 { ZBEE_PROFILE_DCSI_MIN
, ZBEE_PROFILE_DCSI_MAX
, ZBEE_MFG_DCSI
},
433 { ZBEE_PROFILE_FRANCE_TEL_MIN
, ZBEE_PROFILE_FRANCE_TEL_MAX
, ZBEE_MFG_FRANCE_TEL
},
434 { ZBEE_PROFILE_MUNET_MIN
, ZBEE_PROFILE_MUNET_MAX
, ZBEE_MFG_MUNET
},
435 { ZBEE_PROFILE_AUTANI_MIN
, ZBEE_PROFILE_AUTANI_MAX
, ZBEE_MFG_AUTANI
},
436 { ZBEE_PROFILE_COL_VNET_MIN
, ZBEE_PROFILE_COL_VNET_MAX
, ZBEE_MFG_COL_VNET
},
437 { ZBEE_PROFILE_AEROCOMM_MIN
, ZBEE_PROFILE_AEROCOMM_MAX
, ZBEE_MFG_AEROCOMM
},
438 { ZBEE_PROFILE_SI_LABS_MIN
, ZBEE_PROFILE_SI_LABS_MAX
, ZBEE_MFG_SI_LABS
},
439 { ZBEE_PROFILE_INNCOM_MIN
, ZBEE_PROFILE_INNCOM_MAX
, ZBEE_MFG_INNCOM
},
440 { ZBEE_PROFILE_CANNON_MIN
, ZBEE_PROFILE_CANNON_MAX
, ZBEE_MFG_CANNON
},
441 { ZBEE_PROFILE_SYNAPSE_MIN
, ZBEE_PROFILE_SYNAPSE_MAX
, ZBEE_MFG_SYNAPSE
},
442 { ZBEE_PROFILE_FPS_MIN
, ZBEE_PROFILE_FPS_MAX
, ZBEE_MFG_FPS
},
443 { ZBEE_PROFILE_CLS_MIN
, ZBEE_PROFILE_CLS_MAX
, ZBEE_MFG_CLS
},
444 { ZBEE_PROFILE_CRANE_MIN
, ZBEE_PROFILE_CRANE_MAX
, ZBEE_MFG_CRANE
},
445 { ZBEE_PROFILE_ASN_1_MIN
, ZBEE_PROFILE_ASN_1_MAX
, ZBEE_MFG_ASN
},
446 { ZBEE_PROFILE_MOBILARM_MIN
, ZBEE_PROFILE_MOBILARM_MAX
, ZBEE_MFG_MOBILARM
},
447 { ZBEE_PROFILE_IMONITOR_MIN
, ZBEE_PROFILE_IMONITOR_MAX
, ZBEE_MFG_IMONITOR
},
448 { ZBEE_PROFILE_BARTECH_MIN
, ZBEE_PROFILE_BARTECH_MAX
, ZBEE_MFG_BARTECH
},
449 { ZBEE_PROFILE_MESHNETICS_MIN
, ZBEE_PROFILE_MESHNETICS_MAX
, ZBEE_MFG_MESHNETICS
},
450 { ZBEE_PROFILE_LS_IND_MIN
, ZBEE_PROFILE_LS_IND_MAX
, ZBEE_MFG_LS_IND
},
451 { ZBEE_PROFILE_CASON_MIN
, ZBEE_PROFILE_CASON_MAX
, ZBEE_MFG_CASON
},
452 { ZBEE_PROFILE_WLESS_GLUE_MIN
, ZBEE_PROFILE_WLESS_GLUE_MAX
, ZBEE_MFG_WLESS_GLUE
},
453 { ZBEE_PROFILE_ELSTER_MIN
, ZBEE_PROFILE_ELSTER_MAX
, ZBEE_MFG_ELSTER
},
454 { ZBEE_PROFILE_ONSET_MIN
, ZBEE_PROFILE_ONSET_MAX
, ZBEE_MFG_ONSET
},
455 { ZBEE_PROFILE_RIGA_MIN
, ZBEE_PROFILE_RIGA_MAX
, ZBEE_MFG_RIGA
},
456 { ZBEE_PROFILE_ENERGATE_MIN
, ZBEE_PROFILE_ENERGATE_MAX
, ZBEE_MFG_ENERGATE
},
457 { ZBEE_PROFILE_VANTAGE_1_MIN
, ZBEE_PROFILE_VANTAGE_1_MAX
, ZBEE_MFG_VANTAGE
},
458 { ZBEE_PROFILE_CONMED_MIN
, ZBEE_PROFILE_CONMED_MAX
, ZBEE_MFG_CONMED
},
459 { ZBEE_PROFILE_SMS_TEC_MIN
, ZBEE_PROFILE_SMS_TEC_MAX
, ZBEE_MFG_SMS_TEC
},
460 { ZBEE_PROFILE_POWERMAND_MIN
, ZBEE_PROFILE_POWERMAND_MAX
, ZBEE_MFG_POWERMAND
},
461 { ZBEE_PROFILE_SCHNEIDER_MIN
, ZBEE_PROFILE_SCHNEIDER_MAX
, ZBEE_MFG_SCHNEIDER
},
462 { ZBEE_PROFILE_EATON_MIN
, ZBEE_PROFILE_EATON_MAX
, ZBEE_MFG_EATON
},
463 { ZBEE_PROFILE_TELULAR_MIN
, ZBEE_PROFILE_TELULAR_MAX
, ZBEE_MFG_TELULAR
},
464 { ZBEE_PROFILE_DELPHI_MIN
, ZBEE_PROFILE_DELPHI_MAX
, ZBEE_MFG_DELPHI
},
465 { ZBEE_PROFILE_EPISENSOR_MIN
, ZBEE_PROFILE_EPISENSOR_MAX
, ZBEE_MFG_EPISENSOR
},
466 { ZBEE_PROFILE_LANDIS_GYR_MIN
, ZBEE_PROFILE_LANDIS_GYR_MAX
, ZBEE_MFG_LANDIS_GYR
},
467 { ZBEE_PROFILE_SHURE_MIN
, ZBEE_PROFILE_SHURE_MAX
, ZBEE_MFG_SHURE
},
468 { ZBEE_PROFILE_COMVERGE_MIN
, ZBEE_PROFILE_COMVERGE_MAX
, ZBEE_MFG_COMVERGE
},
469 { ZBEE_PROFILE_KABA_MIN
, ZBEE_PROFILE_KABA_MAX
, ZBEE_MFG_KABA
},
470 { ZBEE_PROFILE_HIDALGO_MIN
, ZBEE_PROFILE_HIDALGO_MAX
, ZBEE_MFG_HIDALGO
},
471 { ZBEE_PROFILE_AIR2APP_MIN
, ZBEE_PROFILE_AIR2APP_MAX
, ZBEE_MFG_AIR2APP
},
472 { ZBEE_PROFILE_AMX_MIN
, ZBEE_PROFILE_AMX_MAX
, ZBEE_MFG_AMX
},
473 { ZBEE_PROFILE_EDMI_MIN
, ZBEE_PROFILE_EDMI_MAX
, ZBEE_MFG_EDMI
},
474 { ZBEE_PROFILE_CYAN_MIN
, ZBEE_PROFILE_CYAN_MAX
, ZBEE_MFG_CYAN
},
475 { ZBEE_PROFILE_SYS_SPA_MIN
, ZBEE_PROFILE_SYS_SPA_MAX
, ZBEE_MFG_SYS_SPA
},
476 { ZBEE_PROFILE_TELIT_MIN
, ZBEE_PROFILE_TELIT_MAX
, ZBEE_MFG_TELIT
},
477 { ZBEE_PROFILE_KAGA_MIN
, ZBEE_PROFILE_KAGA_MAX
, ZBEE_MFG_KAGA
},
478 { ZBEE_PROFILE_4_NOKS_MIN
, ZBEE_PROFILE_4_NOKS_MAX
, ZBEE_MFG_4_NOKS
},
479 { ZBEE_PROFILE_PROFILE_SYS_MIN
, ZBEE_PROFILE_PROFILE_SYS_MAX
, ZBEE_MFG_PROFILE_SYS
},
480 { ZBEE_PROFILE_FREESTYLE_MIN
, ZBEE_PROFILE_FREESTYLE_MAX
, ZBEE_MFG_FREESTYLE
},
481 { ZBEE_PROFILE_REMOTE_MIN
, ZBEE_PROFILE_REMOTE_MAX
, ZBEE_MFG_REMOTE_TECH
},
482 { ZBEE_PROFILE_WAVECOM_MIN
, ZBEE_PROFILE_WAVECOM_MAX
, ZBEE_MFG_WAVECOM
},
483 { ZBEE_PROFILE_ENERGY_OPT_MIN
, ZBEE_PROFILE_ENERGY_OPT_MAX
, ZBEE_MFG_GREEN_ENERGY
},
484 { ZBEE_PROFILE_GE_MIN
, ZBEE_PROFILE_GE_MAX
, ZBEE_MFG_GE
},
485 { ZBEE_PROFILE_MESHWORKS_MIN
, ZBEE_PROFILE_MESHWORKS_MAX
, ZBEE_MFG_MESHWORKS
},
486 { ZBEE_PROFILE_ELLIPS_MIN
, ZBEE_PROFILE_ELLIPS_MAX
, ZBEE_MFG_ELLIPS
},
487 { ZBEE_PROFILE_CEDO_MIN
, ZBEE_PROFILE_CEDO_MAX
, ZBEE_MFG_CEDO
},
488 { ZBEE_PROFILE_A_D_MIN
, ZBEE_PROFILE_A_D_MAX
, ZBEE_MFG_A_AND_D
},
489 { ZBEE_PROFILE_CARRIER_MIN
, ZBEE_PROFILE_CARRIER_MAX
, ZBEE_MFG_CARRIER
},
490 { ZBEE_PROFILE_PASSIVESYS_MIN
, ZBEE_PROFILE_PASSIVESYS_MAX
, ZBEE_MFG_PASSIVE
},
491 { ZBEE_PROFILE_SUNRISE_MIN
, ZBEE_PROFILE_SUNRISE_MAX
, ZBEE_MFG_SUNRISE
},
492 { ZBEE_PROFILE_MEMTEC_MIN
, ZBEE_PROFILE_MEMTEC_MAX
, ZBEE_MFG_MEMTECH
},
493 { ZBEE_PROFILE_BRITISH_GAS_MIN
, ZBEE_PROFILE_BRITISH_GAS_MAX
, ZBEE_MFG_BRITISH_GAS
},
494 { ZBEE_PROFILE_SENTEC_MIN
, ZBEE_PROFILE_SENTEC_MAX
, ZBEE_MFG_SENTEC
},
495 { ZBEE_PROFILE_NAVETAS_MIN
, ZBEE_PROFILE_NAVETAS_MAX
, ZBEE_MFG_NAVETAS
},
496 { ZBEE_PROFILE_ENERNOC_MIN
, ZBEE_PROFILE_ENERNOC_MAX
, ZBEE_MFG_ENERNOC
},
497 { ZBEE_PROFILE_ELTAV_MIN
, ZBEE_PROFILE_ELTAV_MAX
, ZBEE_MFG_ELTAV
},
498 { ZBEE_PROFILE_XSTREAMHD_MIN
, ZBEE_PROFILE_XSTREAMHD_MAX
, ZBEE_MFG_XSTREAMHD
},
499 { ZBEE_PROFILE_OMRON_MIN
, ZBEE_PROFILE_OMRON_MAX
, ZBEE_MFG_OMRON
},
500 { ZBEE_PROFILE_NEC_TOKIN_MIN
, ZBEE_PROFILE_NEC_TOKIN_MAX
, ZBEE_MFG_NEC_TOKIN
},
501 { ZBEE_PROFILE_PEEL_MIN
, ZBEE_PROFILE_PEEL_MAX
, ZBEE_MFG_PEEL
},
502 { ZBEE_PROFILE_ELECTROLUX_MIN
, ZBEE_PROFILE_ELECTROLUX_MAX
, ZBEE_MFG_ELECTROLUX
},
503 { ZBEE_PROFILE_SAMSUNG_MIN
, ZBEE_PROFILE_SAMSUNG_MAX
, ZBEE_MFG_SAMSUNG
},
504 { ZBEE_PROFILE_MAINSTREAM_MIN
, ZBEE_PROFILE_MAINSTREAM_MAX
, ZBEE_MFG_MAINSTREAM
},
505 { ZBEE_PROFILE_DIGI_MIN
, ZBEE_PROFILE_DIGI_MAX
, ZBEE_MFG_DIGI
},
506 { ZBEE_PROFILE_RADIOCRAFTS_MIN
, ZBEE_PROFILE_RADIOCRAFTS_MAX
, ZBEE_MFG_RADIOCRAFTS
},
507 { ZBEE_PROFILE_SCHNEIDER2_MIN
, ZBEE_PROFILE_SCHNEIDER2_MAX
, ZBEE_MFG_SCHNEIDER
},
508 { ZBEE_PROFILE_HUAWEI_MIN
, ZBEE_PROFILE_HUAWEI_MAX
, ZBEE_MFG_HUAWEI
},
509 { ZBEE_PROFILE_BGLOBAL_MIN
, ZBEE_PROFILE_BGLOBAL_MAX
, ZBEE_MFG_BGLOBAL
},
510 { ZBEE_PROFILE_ABB_MIN
, ZBEE_PROFILE_ABB_MAX
, ZBEE_MFG_ABB
},
511 { ZBEE_PROFILE_GENUS_MIN
, ZBEE_PROFILE_GENUS_MAX
, ZBEE_MFG_GENUS
},
512 { ZBEE_PROFILE_UBISYS_MIN
, ZBEE_PROFILE_UBISYS_MAX
, ZBEE_MFG_UBISYS
},
513 { ZBEE_PROFILE_CRESTRON_MIN
, ZBEE_PROFILE_CRESTRON_MAX
, ZBEE_MFG_CRESTRON
},
514 { ZBEE_PROFILE_AAC_TECH_MIN
, ZBEE_PROFILE_AAC_TECH_MAX
, ZBEE_MFG_AAC_TECH
},
515 { ZBEE_PROFILE_STEELCASE_MIN
, ZBEE_PROFILE_STEELCASE_MAX
, ZBEE_MFG_STEELCASE
},
519 /* ZigBee Application Profile ID Abbreviations */
520 static const range_string zbee_aps_apid_abbrs
[] = {
521 { ZBEE_DEVICE_PROFILE
, ZBEE_DEVICE_PROFILE
, "ZDP" },
522 { ZBEE_PROFILE_IPM
, ZBEE_PROFILE_IPM
, "IPM" },
523 { ZBEE_PROFILE_T1
, ZBEE_PROFILE_T1
, "T1" },
524 { ZBEE_PROFILE_HA
, ZBEE_PROFILE_HA
, "HA" },
525 { ZBEE_PROFILE_CBA
, ZBEE_PROFILE_CBA
, "CBA" },
526 { ZBEE_PROFILE_WSN
, ZBEE_PROFILE_WSN
, "WSN" },
527 { ZBEE_PROFILE_TA
, ZBEE_PROFILE_TA
, "TA" },
528 { ZBEE_PROFILE_HC
, ZBEE_PROFILE_HC
, "HC" },
529 { ZBEE_PROFILE_SE
, ZBEE_PROFILE_SE
, "SE" },
530 { ZBEE_PROFILE_RS
, ZBEE_PROFILE_RS
, "RS" },
531 { ZBEE_PROFILE_T2
, ZBEE_PROFILE_T2
, "T2" },
532 { ZBEE_PROFILE_GP
, ZBEE_PROFILE_GP
, "GP" },
533 /* Manufacturer Allocations */
534 { ZBEE_PROFILE_C4_MIN
, ZBEE_PROFILE_C4_MAX
, "C4" },
539 /* ZCL Cluster Names */
540 /* BUGBUG: big enough to hash? */
541 const range_string zbee_aps_cid_names
[] = {
544 { ZBEE_ZCL_CID_BASIC
, ZBEE_ZCL_CID_BASIC
, "Basic"},
545 { ZBEE_ZCL_CID_POWER_CONFIG
, ZBEE_ZCL_CID_POWER_CONFIG
, "Power Configuration"},
546 { ZBEE_ZCL_CID_DEVICE_TEMP_CONFIG
, ZBEE_ZCL_CID_DEVICE_TEMP_CONFIG
, "Device Temperature Configuration"},
547 { ZBEE_ZCL_CID_IDENTIFY
, ZBEE_ZCL_CID_IDENTIFY
, "Identify"},
548 { ZBEE_ZCL_CID_GROUPS
, ZBEE_ZCL_CID_GROUPS
, "Groups"},
549 { ZBEE_ZCL_CID_SCENES
, ZBEE_ZCL_CID_SCENES
, "Scenes"},
550 { ZBEE_ZCL_CID_ON_OFF
, ZBEE_ZCL_CID_ON_OFF
, "On/Off"},
551 { ZBEE_ZCL_CID_ON_OFF_SWITCH_CONFIG
, ZBEE_ZCL_CID_ON_OFF_SWITCH_CONFIG
, "On/Off Switch Configuration"},
552 { ZBEE_ZCL_CID_LEVEL_CONTROL
, ZBEE_ZCL_CID_LEVEL_CONTROL
, "Level Control"},
553 { ZBEE_ZCL_CID_ALARMS
, ZBEE_ZCL_CID_ALARMS
, "Alarms"},
554 { ZBEE_ZCL_CID_TIME
, ZBEE_ZCL_CID_TIME
, "Time"},
555 { ZBEE_ZCL_CID_RSSI_LOCATION
, ZBEE_ZCL_CID_RSSI_LOCATION
, "RSSI Location"},
556 { ZBEE_ZCL_CID_ANALOG_INPUT_BASIC
, ZBEE_ZCL_CID_ANALOG_INPUT_BASIC
, "Analog Input (Basic)"},
557 { ZBEE_ZCL_CID_ANALOG_OUTPUT_BASIC
, ZBEE_ZCL_CID_ANALOG_OUTPUT_BASIC
, "Analog Output (Basic)"},
558 { ZBEE_ZCL_CID_ANALOG_VALUE_BASIC
, ZBEE_ZCL_CID_ANALOG_VALUE_BASIC
, "Analog Value (Basic)"},
559 { ZBEE_ZCL_CID_BINARY_INPUT_BASIC
, ZBEE_ZCL_CID_BINARY_INPUT_BASIC
, "Binary Input (Basic)"},
560 { ZBEE_ZCL_CID_BINARY_OUTPUT_BASIC
, ZBEE_ZCL_CID_BINARY_OUTPUT_BASIC
, "Binary Output (Basic)"},
561 { ZBEE_ZCL_CID_BINARY_VALUE_BASIC
, ZBEE_ZCL_CID_BINARY_VALUE_BASIC
, "Binary Value (Basic)"},
562 { ZBEE_ZCL_CID_MULTISTATE_INPUT_BASIC
, ZBEE_ZCL_CID_MULTISTATE_INPUT_BASIC
, "Multistate Input (Basic)"},
563 { ZBEE_ZCL_CID_MULTISTATE_OUTPUT_BASIC
, ZBEE_ZCL_CID_MULTISTATE_OUTPUT_BASIC
, "Multistate Output (Basic)"},
564 { ZBEE_ZCL_CID_MULTISTATE_VALUE_BASIC
, ZBEE_ZCL_CID_MULTISTATE_VALUE_BASIC
, "Multistate Value (Basic)"},
565 { ZBEE_ZCL_CID_COMMISSIONING
, ZBEE_ZCL_CID_COMMISSIONING
, "Commissioning"},
566 { ZBEE_ZCL_CID_PARTITION
, ZBEE_ZCL_CID_PARTITION
, "Partition"},
567 { ZBEE_ZCL_CID_OTA_UPGRADE
, ZBEE_ZCL_CID_OTA_UPGRADE
, "OTA Upgrade"},
568 { ZBEE_ZCL_CID_POLL_CONTROL
, ZBEE_ZCL_CID_POLL_CONTROL
, "Poll Control"},
569 { ZBEE_ZCL_CID_GP
, ZBEE_ZCL_CID_GP
, "Green Power"},
571 { ZBEE_ZCL_CID_POWER_PROFILE
, ZBEE_ZCL_CID_POWER_PROFILE
, "Power Profile"},
572 { ZBEE_ZCL_CID_APPLIANCE_CONTROL
, ZBEE_ZCL_CID_APPLIANCE_CONTROL
, "Appliance Control"},
575 { ZBEE_ZCL_CID_SHADE_CONFIG
, ZBEE_ZCL_CID_SHADE_CONFIG
, "Shade Configuration"},
576 { ZBEE_ZCL_CID_DOOR_LOCK
, ZBEE_ZCL_CID_DOOR_LOCK
, "Door Lock"},
577 { ZBEE_ZCL_CID_WINDOW_COVERING
, ZBEE_ZCL_CID_WINDOW_COVERING
, "Window Covering"},
580 { ZBEE_ZCL_CID_PUMP_CONFIG_CONTROL
, ZBEE_ZCL_CID_PUMP_CONFIG_CONTROL
, "Pump Configuration Control"},
581 { ZBEE_ZCL_CID_THERMOSTAT
, ZBEE_ZCL_CID_THERMOSTAT
, "Thermostat"},
582 { ZBEE_ZCL_CID_FAN_CONTROL
, ZBEE_ZCL_CID_FAN_CONTROL
, "Fan Control"},
583 { ZBEE_ZCL_CID_DEHUMIDIFICATION_CONTROL
, ZBEE_ZCL_CID_DEHUMIDIFICATION_CONTROL
, "Dehumidification Control"},
584 { ZBEE_ZCL_CID_THERMOSTAT_UI_CONFIG
, ZBEE_ZCL_CID_THERMOSTAT_UI_CONFIG
, "Thermostat User Interface Configuration"},
587 { ZBEE_ZCL_CID_COLOR_CONTROL
, ZBEE_ZCL_CID_COLOR_CONTROL
, "Color Control"},
588 { ZBEE_ZCL_CID_BALLAST_CONFIG
, ZBEE_ZCL_CID_BALLAST_CONFIG
, "Ballast Configuration"},
590 /* Measurement and Sensing */
591 { ZBEE_ZCL_CID_ILLUMINANCE_MEASUREMENT
, ZBEE_ZCL_CID_ILLUMINANCE_MEASUREMENT
, "Illuminance Measurement"},
592 { ZBEE_ZCL_CID_ILLUMINANCE_LEVEL_SENSING
, ZBEE_ZCL_CID_ILLUMINANCE_LEVEL_SENSING
, "Illuminance Level Sensing"},
593 { ZBEE_ZCL_CID_TEMPERATURE_MEASUREMENT
, ZBEE_ZCL_CID_TEMPERATURE_MEASUREMENT
, "Temperature Measurement"},
594 { ZBEE_ZCL_CID_PRESSURE_MEASUREMENT
, ZBEE_ZCL_CID_PRESSURE_MEASUREMENT
, "Pressure Measurement"},
595 { ZBEE_ZCL_CID_FLOW_MEASUREMENT
, ZBEE_ZCL_CID_FLOW_MEASUREMENT
, "Flow Measurement"},
596 { ZBEE_ZCL_CID_REL_HUMIDITY_MEASUREMENT
, ZBEE_ZCL_CID_REL_HUMIDITY_MEASUREMENT
, "Relative Humidity Measurement"},
597 { ZBEE_ZCL_CID_OCCUPANCY_SENSING
, ZBEE_ZCL_CID_OCCUPANCY_SENSING
, "Occupancy Sensing"},
598 { ZBEE_ZCL_CID_ELECTRICAL_MEASUREMENT
, ZBEE_ZCL_CID_ELECTRICAL_MEASUREMENT
, "Electrical Measurement"},
600 /* Security and Safety */
601 { ZBEE_ZCL_CID_IAS_ZONE
, ZBEE_ZCL_CID_IAS_ZONE
, "Intruder Alarm System Zone"},
602 { ZBEE_ZCL_CID_IAS_ACE
, ZBEE_ZCL_CID_IAS_ACE
, "Intruder Alarm System ACE"},
603 { ZBEE_ZCL_CID_IAS_WD
, ZBEE_ZCL_CID_IAS_WD
, "Intruder Alarm System WD"},
605 /* Protocol Interfaces */
606 { ZBEE_ZCL_CID_GENERIC_TUNNEL
, ZBEE_ZCL_CID_GENERIC_TUNNEL
, "BACnet Generic Tunnel"},
607 { ZBEE_ZCL_CID_BACNET_PROTOCOL_TUNNEL
, ZBEE_ZCL_CID_BACNET_PROTOCOL_TUNNEL
, "BACnet Protocol Tunnel"},
608 { ZBEE_ZCL_CID_BACNET_ANALOG_INPUT_REG
, ZBEE_ZCL_CID_BACNET_ANALOG_INPUT_REG
, "BACnet Analog Input (Regular)"},
609 { ZBEE_ZCL_CID_BACNET_ANALOG_INPUT_EXT
, ZBEE_ZCL_CID_BACNET_ANALOG_INPUT_EXT
, "BACnet Analog Input (Extended)"},
610 { ZBEE_ZCL_CID_BACNET_ANALOG_OUTPUT_REG
, ZBEE_ZCL_CID_BACNET_ANALOG_OUTPUT_REG
, "BACnet Analog Output (Regular)"},
611 { ZBEE_ZCL_CID_BACNET_ANALOG_OUTPUT_EXT
, ZBEE_ZCL_CID_BACNET_ANALOG_OUTPUT_EXT
, "BACnet Analog Output (Extended)"},
612 { ZBEE_ZCL_CID_BACNET_ANALOG_VALUE_REG
, ZBEE_ZCL_CID_BACNET_ANALOG_VALUE_REG
, "BACnet Analog Value (Regular)"},
613 { ZBEE_ZCL_CID_BACNET_ANALOG_VALUE_EXT
, ZBEE_ZCL_CID_BACNET_ANALOG_VALUE_EXT
, "BACnet Analog Value (Extended)"},
614 { ZBEE_ZCL_CID_BACNET_BINARY_INPUT_REG
, ZBEE_ZCL_CID_BACNET_BINARY_INPUT_REG
, "BACnet Binary Input (Regular)"},
615 { ZBEE_ZCL_CID_BACNET_BINARY_INPUT_EXT
, ZBEE_ZCL_CID_BACNET_BINARY_INPUT_EXT
, "BACnet Binary Input (Extended)"},
616 { ZBEE_ZCL_CID_BACNET_BINARY_OUTPUT_REG
, ZBEE_ZCL_CID_BACNET_BINARY_OUTPUT_REG
, "BACnet Binary Output (Regular)"},
617 { ZBEE_ZCL_CID_BACNET_BINARY_OUTPUT_EXT
, ZBEE_ZCL_CID_BACNET_BINARY_OUTPUT_EXT
, "BACnet Binary Output (Extended)"},
618 { ZBEE_ZCL_CID_BACNET_BINARY_VALUE_REG
, ZBEE_ZCL_CID_BACNET_BINARY_VALUE_REG
, "BACnet Binary Value (Regular)"},
619 { ZBEE_ZCL_CID_BACNET_BINARY_VALUE_EXT
, ZBEE_ZCL_CID_BACNET_BINARY_VALUE_EXT
, "BACnet Binary Value (Extended)"},
620 { ZBEE_ZCL_CID_BACNET_MULTISTATE_INPUT_REG
, ZBEE_ZCL_CID_BACNET_MULTISTATE_INPUT_REG
, "BACnet Multistage Input (Regular)"},
621 { ZBEE_ZCL_CID_BACNET_MULTISTATE_INPUT_EXT
, ZBEE_ZCL_CID_BACNET_MULTISTATE_INPUT_EXT
, "BACnet Multistage Input (Extended)"},
622 { ZBEE_ZCL_CID_BACNET_MULTISTATE_OUTPUT_REG
, ZBEE_ZCL_CID_BACNET_MULTISTATE_OUTPUT_REG
, "BACnet Multistage Output (Regular)"},
623 { ZBEE_ZCL_CID_BACNET_MULTISTATE_OUTPUT_EXT
, ZBEE_ZCL_CID_BACNET_MULTISTATE_OUTPUT_EXT
, "BACnet Multistage Output (Extended)"},
624 { ZBEE_ZCL_CID_BACNET_MULTISTATE_VALUE_REG
, ZBEE_ZCL_CID_BACNET_MULTISTATE_VALUE_REG
, "BACnet Multistage Value (Regular)"},
625 { ZBEE_ZCL_CID_BACNET_MULTISTATE_VALUE_EXT
, ZBEE_ZCL_CID_BACNET_MULTISTATE_VALUE_EXT
, "BACnet Multistage Value (Extended)"},
627 /* ZCL Cluster IDs - Smart Energy */
628 { ZBEE_ZCL_CID_KEEP_ALIVE
, ZBEE_ZCL_CID_KEEP_ALIVE
, "Keep-Alive"},
629 { ZBEE_ZCL_CID_PRICE
, ZBEE_ZCL_CID_PRICE
, "Price"},
630 { ZBEE_ZCL_CID_DEMAND_RESPONSE_LOAD_CONTROL
, ZBEE_ZCL_CID_DEMAND_RESPONSE_LOAD_CONTROL
, "Demand Response and Load Control"},
631 { ZBEE_ZCL_CID_SIMPLE_METERING
, ZBEE_ZCL_CID_SIMPLE_METERING
, "Simple Metering"},
632 { ZBEE_ZCL_CID_MESSAGE
, ZBEE_ZCL_CID_MESSAGE
, "Message"},
633 { ZBEE_ZCL_CID_TUNNELING
, ZBEE_ZCL_CID_TUNNELING
, "Tunneling"},
634 { ZBEE_ZCL_CID_PRE_PAYMENT
, ZBEE_ZCL_CID_PRE_PAYMENT
, "Pre-Payment"},
635 { ZBEE_ZCL_CID_ENERGY_MANAGEMENT
, ZBEE_ZCL_CID_ENERGY_MANAGEMENT
, "Energy Management"},
636 { ZBEE_ZCL_CID_CALENDAR
, ZBEE_ZCL_CID_CALENDAR
, "Calendar"},
637 { ZBEE_ZCL_CID_DEVICE_MANAGEMENT
, ZBEE_ZCL_CID_DEVICE_MANAGEMENT
, "Device Management"},
638 { ZBEE_ZCL_CID_EVENTS
, ZBEE_ZCL_CID_EVENTS
, "Events"},
639 { ZBEE_ZCL_CID_MDU_PAIRING
, ZBEE_ZCL_CID_MDU_PAIRING
, "MDU Pairing"},
640 { ZBEE_ZCL_CID_SUB_GHZ
, ZBEE_ZCL_CID_SUB_GHZ
, "Sub-Ghz"},
641 { ZBEE_ZCL_CID_DAILY_SCHEDULE
, ZBEE_ZCL_CID_DAILY_SCHEDULE
, "Daily Schedule"},
643 /* ZCL Cluster IDs - Key Establishment */
644 { ZBEE_ZCL_CID_KE
, ZBEE_ZCL_CID_KE
, "Key Establishment"},
646 /* ZCL Cluster IDs - Home Automation */
647 {ZBEE_ZCL_CID_APPLIANCE_IDENTIFICATION
, ZBEE_ZCL_CID_APPLIANCE_IDENTIFICATION
, "Appliance Identification"},
648 {ZBEE_ZCL_CID_METER_IDENTIFICATION
, ZBEE_ZCL_CID_METER_IDENTIFICATION
, "Meter Identification"},
649 {ZBEE_ZCL_CID_APPLIANCE_EVENTS_AND_ALERT
, ZBEE_ZCL_CID_APPLIANCE_EVENTS_AND_ALERT
, "Appliance Events And Alerts"},
650 {ZBEE_ZCL_CID_APPLIANCE_STATISTICS
, ZBEE_ZCL_CID_APPLIANCE_STATISTICS
, "Appliance Statistics"},
652 {ZBEE_ZCL_CID_ZLL
, ZBEE_ZCL_CID_ZLL
, "ZLL Commissioning"},
654 /* ZCL Cluster IDs - Manufacturer Specific */
655 {ZBEE_ZCL_CID_MANUFACTURER_SPECIFIC_MIN
, ZBEE_ZCL_CID_MANUFACTURER_SPECIFIC_MAX
, "Manufacturer Specific"},
659 /* APS Test Profile #2 Cluster Names */
660 static const value_string zbee_aps_t2_cid_names
[] = {
661 { ZBEE_APS_T2_CID_BR
, "Broadcast Request"},
662 { ZBEE_APS_T2_CID_BTADR
, "Broadcast to All Devices Response"},
663 { ZBEE_APS_T2_CID_BTARACR
, "Broadcast to All Routers and Coordinator Response"},
664 { ZBEE_APS_T2_CID_BTARXOWIDR
, "Broadcast to All RXOnWhenIdle Devices Response"},
665 { ZBEE_APS_T2_CID_BTGREQ
, "Buffer Test Group Request"},
666 { ZBEE_APS_T2_CID_BTGRES
, "Buffer Test Group Response"},
667 { ZBEE_APS_T2_CID_BTREQ
, "Buffer Test Request"},
668 { ZBEE_APS_T2_CID_BTRES
, "Buffer Test Response"},
669 { ZBEE_APS_T2_CID_FNDR
, "Freeform No Data Response"},
670 { ZBEE_APS_T2_CID_FREQ
, "Freeform Request"},
671 { ZBEE_APS_T2_CID_FRES
, "Freeform Response"},
672 { ZBEE_APS_T2_CID_PCR
, "Packet Count Response"},
673 { ZBEE_APS_T2_CID_RDREQ
, "Route Discovery Request"},
674 { ZBEE_APS_T2_CID_RDRES
, "Route Discovery Response"},
675 { ZBEE_APS_T2_CID_RESPC
, "Reset Packet Count"},
676 { ZBEE_APS_T2_CID_RETPC
, "Retrieve Packet Count"},
677 { ZBEE_APS_T2_CID_TCP
, "Transmit Counted Packets"},
682 /* APS Test Profile #2 Buffer Test Response Status Names */
683 static const value_string zbee_aps_t2_btres_status_names
[] = {
684 { ZBEE_APS_T2_CID_BTRES_S_SBT
, "Successful Buffer Test"},
685 { ZBEE_APS_T2_CID_BTRES_S_TFOFA
, "Transmission Failure on First Attempt"},
690 /* APS Fragmented Block Acknowledgements */
691 #define ZBEE_APS_FRAG_BLOCK1_ACK 0x01
692 #define ZBEE_APS_FRAG_BLOCK2_ACK 0x02
693 #define ZBEE_APS_FRAG_BLOCK3_ACK 0x04
694 #define ZBEE_APS_FRAG_BLOCK4_ACK 0x08
695 #define ZBEE_APS_FRAG_BLOCK5_ACK 0x10
696 #define ZBEE_APS_FRAG_BLOCK6_ACK 0x20
697 #define ZBEE_APS_FRAG_BLOCK7_ACK 0x40
698 #define ZBEE_APS_FRAG_BLOCK8_ACK 0x80
700 /* calculate the extended counter - top 24 bits of the previous counter,
701 * plus our own; then correct for wrapping */
703 zbee_aps_calculate_extended_counter(uint32_t previous_counter
, uint8_t raw_counter
)
705 uint32_t counter
= (previous_counter
& 0xffffff00) | raw_counter
;
706 if ((counter
+ 0x40) < previous_counter
) {
708 } else if ((previous_counter
+ 0x40) < counter
) {
709 /* we got an out-of-order packet which happened to go backwards over the
716 static struct zbee_aps_node_packet_info
*
717 zbee_aps_node_packet_info(packet_info
*pinfo
,
718 const zbee_nwk_packet
*nwk
, const zbee_nwk_hints_t
*nwk_hints
, const zbee_aps_packet
*packet
)
720 struct zbee_aps_node_packet_info
*node_data_packet
;
722 node_data_packet
= (struct zbee_aps_node_packet_info
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_zbee_aps
, ZBEE_APS_NODE_PROTO_DATA
);
723 if (node_data_packet
== NULL
) {
724 ieee802154_short_addr addr16
;
725 struct zbee_aps_node_info
*node_data
;
729 addr16
.pan
= nwk_hints
->src_pan
;
734 if (packet
->type
!= ZBEE_APS_FCF_ACK
) {
735 addr16
.addr
= nwk
->src
;
738 addr16
.addr
= nwk
->dst
;
740 node_data
= (struct zbee_aps_node_info
*) g_hash_table_lookup(zbee_table_aps_extended_counters
, &addr16
);
741 if (node_data
== NULL
) {
742 node_data
= wmem_new0(wmem_file_scope(), struct zbee_aps_node_info
);
743 node_data
->extended_counter
= 0x100;
744 g_hash_table_insert(zbee_table_aps_extended_counters
, wmem_memdup(wmem_file_scope(), &addr16
, sizeof(addr16
)), node_data
);
747 node_data_packet
= wmem_new(wmem_file_scope(), struct zbee_aps_node_packet_info
);
748 p_add_proto_data(wmem_file_scope(), pinfo
, proto_zbee_aps
, ZBEE_APS_NODE_PROTO_DATA
, node_data_packet
);
750 counter
= zbee_aps_calculate_extended_counter(node_data
->extended_counter
, packet
->counter
);
751 node_data
->extended_counter
= counter
;
752 node_data_packet
->extended_counter
= counter
;
755 return node_data_packet
;
759 *ZigBee Application Support Sublayer dissector for wireshark.
761 *@param tvb pointer to buffer containing raw packet.
762 *@param pinfo pointer to packet information fields
763 *@param tree pointer to data tree Wireshark uses to display packet.
766 dissect_zbee_aps(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
768 tvbuff_t
*payload_tvb
= NULL
;
769 dissector_handle_t profile_handle
= NULL
;
770 dissector_handle_t zcl_handle
= NULL
;
772 proto_tree
*aps_tree
;
773 proto_tree
*field_tree
;
774 proto_item
*proto_root
;
776 zbee_aps_packet packet
;
777 zbee_nwk_packet
*nwk
;
778 zbee_nwk_hints_t
*nwk_hints
;
780 struct zbee_aps_node_packet_info
*node_data_packet
;
785 static int * const frag_ack_flags
[] = {
786 &hf_zbee_aps_block_ack1
,
787 &hf_zbee_aps_block_ack2
,
788 &hf_zbee_aps_block_ack3
,
789 &hf_zbee_aps_block_ack4
,
790 &hf_zbee_aps_block_ack5
,
791 &hf_zbee_aps_block_ack6
,
792 &hf_zbee_aps_block_ack7
,
793 &hf_zbee_aps_block_ack8
,
797 /* Reject the packet if data is NULL */
800 nwk
= (zbee_nwk_packet
*)data
;
803 memset(&packet
, 0, sizeof(zbee_aps_packet
));
805 nwk_hints
= (zbee_nwk_hints_t
*)p_get_proto_data(wmem_file_scope(), pinfo
,
806 proto_get_id_by_filter_name(ZBEE_PROTOABBREV_NWK
), 0);
808 /* Create the protocol tree */
809 proto_root
= proto_tree_add_protocol_format(tree
, proto_zbee_aps
, tvb
, offset
, tvb_captured_length(tvb
), "ZigBee Application Support Layer");
810 aps_tree
= proto_item_add_subtree(proto_root
, ett_zbee_aps
);
812 /* Set the protocol column, if the NWK layer hasn't already done so. */
813 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ZigBee");
816 fcf
= tvb_get_uint8(tvb
, offset
);
817 packet
.type
= zbee_get_bit_field(fcf
, ZBEE_APS_FCF_FRAME_TYPE
);
818 packet
.delivery
= zbee_get_bit_field(fcf
, ZBEE_APS_FCF_DELIVERY_MODE
);
819 packet
.indirect_mode
= zbee_get_bit_field(fcf
, ZBEE_APS_FCF_INDIRECT_MODE
);
820 packet
.ack_format
= zbee_get_bit_field(fcf
, ZBEE_APS_FCF_ACK_FORMAT
);
821 packet
.security
= zbee_get_bit_field(fcf
, ZBEE_APS_FCF_SECURITY
);
822 packet
.ack_req
= zbee_get_bit_field(fcf
, ZBEE_APS_FCF_ACK_REQ
);
823 packet
.ext_header
= zbee_get_bit_field(fcf
, ZBEE_APS_FCF_EXT_HEADER
);
825 /* Display the frame type to the proto root and info column. */
826 proto_item_append_text(proto_root
, " %s", val_to_str_const(packet
.type
, zbee_aps_frame_types
, "Unknown Type"));
828 col_set_str(pinfo
->cinfo
, COL_INFO
, "APS: ");
829 col_append_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(packet
.type
, zbee_aps_frame_types
, "Unknown Frame Type"));
831 /* Display the FCF */
833 /* Create the subtree */
834 field_tree
= proto_tree_add_subtree_format(aps_tree
, tvb
, offset
, 1, ett_zbee_aps_fcf
, NULL
, "Frame Control Field: %s (0x%02x)",
835 val_to_str_const(packet
.type
, zbee_aps_frame_types
, "Unknown"), fcf
);
837 /* Add the frame type and delivery mode. */
838 proto_tree_add_uint(field_tree
, hf_zbee_aps_fcf_frame_type
, tvb
, offset
, 1, fcf
& ZBEE_APS_FCF_FRAME_TYPE
);
839 proto_tree_add_uint(field_tree
, hf_zbee_aps_fcf_delivery
, tvb
, offset
, 1, fcf
& ZBEE_APS_FCF_DELIVERY_MODE
);
841 if (nwk
->version
>= ZBEE_VERSION_2007
) {
842 /* ZigBee 2007 and later uses an ack mode flag. */
843 if (packet
.type
== ZBEE_APS_FCF_ACK
) {
844 proto_tree_add_boolean(field_tree
, hf_zbee_aps_fcf_ack_format
, tvb
, offset
, 1,
845 fcf
& ZBEE_APS_FCF_ACK_FORMAT
);
849 /* ZigBee 2004, uses indirect mode. */
850 if (packet
.delivery
== ZBEE_APS_FCF_INDIRECT
) {
851 proto_tree_add_boolean(field_tree
, hf_zbee_aps_fcf_indirect_mode
, tvb
, offset
, 1,
852 fcf
& ZBEE_APS_FCF_INDIRECT_MODE
);
856 /* Add the rest of the flags */
857 proto_tree_add_boolean(field_tree
, hf_zbee_aps_fcf_security
, tvb
, offset
, 1, fcf
& ZBEE_APS_FCF_SECURITY
);
858 proto_tree_add_boolean(field_tree
, hf_zbee_aps_fcf_ack_req
, tvb
, offset
, 1, fcf
& ZBEE_APS_FCF_ACK_REQ
);
859 proto_tree_add_boolean(field_tree
, hf_zbee_aps_fcf_ext_header
, tvb
, offset
, 1, fcf
& ZBEE_APS_FCF_EXT_HEADER
);
863 /* Check if the endpoint addressing fields are present. */
864 switch (packet
.type
) {
865 case ZBEE_APS_FCF_DATA
:
866 /* Endpoint addressing must exist to some extent on data frames. */
869 case ZBEE_APS_FCF_ACK
:
870 if ((nwk
->version
>= ZBEE_VERSION_2007
) && (packet
.ack_format
)) {
871 /* Command Ack: endpoint addressing does not exist. */
872 goto dissect_zbee_aps_no_endpt
;
876 case ZBEE_APS_FCF_INTERPAN
:
877 packet
.dst_present
= false;
878 packet
.src_present
= false;
882 case ZBEE_APS_FCF_CMD
:
883 /* Endpoint addressing does not exist for these frames. */
884 goto dissect_zbee_aps_no_endpt
;
887 if (packet
.type
!= ZBEE_APS_FCF_INTERPAN
) {
888 /* Determine whether the source and/or destination endpoints are present.
889 * We should only get here for endpoint-addressed data or ack frames.
891 if ((packet
.delivery
== ZBEE_APS_FCF_UNICAST
) || (packet
.delivery
== ZBEE_APS_FCF_BCAST
)) {
892 /* Source and destination endpoints exist. (Although, I strongly
893 * disagree with the presence of the endpoint in broadcast delivery
896 packet
.dst_present
= true;
897 packet
.src_present
= true;
899 else if ((packet
.delivery
== ZBEE_APS_FCF_INDIRECT
) && (nwk
->version
<= ZBEE_VERSION_2004
)) {
900 /* Indirect addressing was removed in ZigBee 2006, basically because it
901 * was a useless, broken feature which only complicated things. Treat
902 * this mode as invalid for ZigBee 2006 and later. When using indirect
903 * addressing, only one of the source and destination endpoints exist,
904 * and is controlled by the setting of indirect_mode.
906 packet
.dst_present
= (!packet
.indirect_mode
);
907 packet
.src_present
= (packet
.indirect_mode
);
909 else if ((packet
.delivery
== ZBEE_APS_FCF_GROUP
) && (nwk
->version
>= ZBEE_VERSION_2007
)) {
910 /* Group addressing was added in ZigBee 2006, and contains only the
911 * source endpoint. (IMO, Broacast deliveries should do the same).
913 packet
.dst_present
= false;
914 packet
.src_present
= true;
917 /* Illegal Delivery Mode. */
918 expert_add_info(pinfo
, proto_root
, &ei_zbee_aps_invalid_delivery_mode
);
919 return tvb_captured_length(tvb
);
923 /* If the destination endpoint is present, get and display it. */
924 if (packet
.dst_present
) {
925 packet
.dst
= tvb_get_uint8(tvb
, offset
);
926 proto_tree_add_uint(aps_tree
, hf_zbee_aps_dst
, tvb
, offset
, 1, packet
.dst
);
927 proto_item_append_text(proto_root
, ", Dst Endpt: %d", packet
.dst
);
930 /* Update the info column. */
931 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Dst Endpt: %d", packet
.dst
);
935 /* If the group address is present, display it. */
936 if (packet
.delivery
== ZBEE_APS_FCF_GROUP
) {
937 packet
.group
= tvb_get_letohs(tvb
, offset
);
938 proto_tree_add_uint(aps_tree
, hf_zbee_aps_group
, tvb
, offset
,2, packet
.group
);
939 proto_item_append_text(proto_root
, ", Group: 0x%04x", packet
.group
);
942 /* Update the info column. */
943 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Group: 0x%04x", packet
.group
);
946 /* Get and display the cluster ID. */
947 if (nwk
->version
>= ZBEE_VERSION_2007
) {
948 /* Cluster ID is 16-bits long in ZigBee 2007 and later. */
949 nwk
->cluster_id
= tvb_get_letohs(tvb
, offset
);
950 switch (tvb_get_letohs(tvb
, offset
+ 2)) {
951 case ZBEE_DEVICE_PROFILE
:
952 proto_tree_add_uint_format(aps_tree
, hf_zbee_aps_zdp_cluster
, tvb
, offset
, 2, nwk
->cluster_id
,
953 "%s (Cluster ID: 0x%04x)",
954 val_to_str_const(nwk
->cluster_id
, zbee_zdp_cluster_names
, "Unknown Device Profile Cluster"),
957 case ZBEE_PROFILE_T2
:
958 proto_tree_add_item(aps_tree
, hf_zbee_aps_t2_cluster
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
959 if (packet
.type
== ZBEE_APS_FCF_DATA
)
961 col_set_str(pinfo
->cinfo
, COL_INFO
,
962 val_to_str_const(nwk
->cluster_id
, zbee_aps_t2_cid_names
, "Unknown T2 cluster"));
966 proto_tree_add_item(aps_tree
, hf_zbee_aps_cluster
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
972 /* Cluster ID is 8-bits long in ZigBee 2004 and earlier. */
973 nwk
->cluster_id
= tvb_get_uint8(tvb
, offset
);
974 proto_tree_add_uint_format_value(aps_tree
, hf_zbee_aps_cluster
, tvb
, offset
,
975 1, nwk
->cluster_id
, "0x%02x", nwk
->cluster_id
);
979 /* Get and display the profile ID. */
980 packet
.profile
= tvb_get_letohs(tvb
, offset
);
981 profile_handle
= dissector_get_uint_handle(zbee_aps_dissector_table
, packet
.profile
);
982 proto_tree_add_uint(aps_tree
, hf_zbee_aps_profile
, tvb
, offset
,2,
984 /* Update the protocol root and info column later, after the source endpoint
985 * so that the source and destination will be back-to-back in the text.
989 /* The source endpoint is present for all cases except indirect /w indirect_mode == false */
990 if (packet
.type
!= ZBEE_APS_FCF_INTERPAN
&&
991 ((packet
.delivery
!= ZBEE_APS_FCF_INDIRECT
) || (!packet
.indirect_mode
))) {
992 packet
.src
= tvb_get_uint8(tvb
, offset
);
993 proto_tree_add_uint(aps_tree
, hf_zbee_aps_src
, tvb
, offset
, 1, packet
.src
);
994 proto_item_append_text(proto_root
, ", Src Endpt: %d", packet
.src
);
997 /* Update the info column. */
998 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Src Endpt: %d", packet
.src
);
1001 /* Display the profile ID now that the source endpoint was listed. */
1002 if (packet
.type
== ZBEE_APS_FCF_DATA
) {
1003 col_append_fstr(pinfo
->cinfo
, COL_PROTOCOL
, " %s",
1004 rval_to_str_const(packet
.profile
, zbee_aps_apid_abbrs
, ""));
1007 /* Jump here if there is no endpoint addressing in this frame. */
1008 dissect_zbee_aps_no_endpt
:
1010 /* Get and display the APS counter. Only present on ZigBee 2007 and later. */
1011 if (nwk
->version
>= ZBEE_VERSION_2007
&& packet
.type
!= ZBEE_APS_FCF_INTERPAN
) {
1012 packet
.counter
= tvb_get_uint8(tvb
, offset
);
1013 proto_tree_add_uint(aps_tree
, hf_zbee_aps_counter
, tvb
, offset
, 1, packet
.counter
);
1017 node_data_packet
= zbee_aps_node_packet_info(pinfo
, nwk
, nwk_hints
, &packet
);
1019 /* Get and display the extended header, if present. */
1020 if (packet
.ext_header
) {
1021 fcf
= tvb_get_uint8(tvb
, offset
);
1022 packet
.fragmentation
= fcf
& ZBEE_APS_EXT_FCF_FRAGMENT
;
1023 /* Create a subtree */
1024 field_tree
= proto_tree_add_subtree_format(aps_tree
, tvb
, offset
, 1, ett_zbee_aps_fcf
, NULL
, "Extended Frame Control Field (0x%02x)", fcf
);
1026 /* Display the fragmentation sub-field. */
1027 proto_tree_add_uint(field_tree
, hf_zbee_aps_fragmentation
, tvb
, offset
, 1, packet
.fragmentation
);
1030 /* If fragmentation is enabled, get and display the block number. */
1031 if (packet
.fragmentation
!= ZBEE_APS_EXT_FCF_FRAGMENT_NONE
) {
1032 packet
.block_number
= tvb_get_uint8(tvb
, offset
);
1033 proto_tree_add_uint(field_tree
, hf_zbee_aps_block_number
, tvb
, offset
, 1, packet
.block_number
);
1037 /* If fragmentation is enabled, and this is an acknowledgement, get and display the ack bitfield. */
1038 if ((packet
.fragmentation
!= ZBEE_APS_EXT_FCF_FRAGMENT_NONE
) && (packet
.type
== ZBEE_APS_FCF_ACK
)) {
1039 proto_tree_add_bitmask(field_tree
, tvb
, offset
, hf_zbee_aps_block_ack
, ett_zbee_aps_frag_ack
, frag_ack_flags
, ENC_NA
);
1044 /* Ensure the fragmentation mode is set off, so that the reassembly handler
1045 * doesn't get called.
1047 packet
.fragmentation
= ZBEE_APS_EXT_FCF_FRAGMENT_NONE
;
1050 /* If a payload is present, and security is enabled, decrypt the payload. */
1051 if ((offset
< tvb_captured_length(tvb
)) && packet
.security
) {
1052 payload_tvb
= dissect_zbee_secure(tvb
, pinfo
, aps_tree
, offset
);
1053 if (payload_tvb
== NULL
) {
1054 /* If Payload_tvb is NULL, then the security dissector cleaned up. */
1055 return tvb_captured_length(tvb
);
1058 /* If the payload exists, create a tvb subset. */
1059 else if (offset
< tvb_captured_length(tvb
)) {
1060 payload_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1063 /* If the payload exists, and the packet is fragmented, attempt reassembly. */
1064 if ((payload_tvb
) && (packet
.fragmentation
!= ZBEE_APS_EXT_FCF_FRAGMENT_NONE
)) {
1067 uint32_t num_blocks
;
1068 fragment_head
*frag_msg
= NULL
;
1071 /* Set the fragmented flag. */
1072 pinfo
->fragmented
= true;
1074 /* The source address (short address and PAN ID) and APS Counter pair form a unique identifier
1075 * for each message (fragmented or not). Hash these together to
1076 * create the message id for the fragmentation handler.
1078 msg_id
= ((nwk
->src
)<<16) + (node_data_packet
->extended_counter
& 0xffff);
1080 msg_id
^= (nwk_hints
->src_pan
)<<16;
1083 /* If this is the first block of a fragmented message, than the block
1084 * number field is the maximum number of blocks in the message. Otherwise
1085 * the block number is the block being sent.
1087 if (packet
.fragmentation
== ZBEE_APS_EXT_FCF_FRAGMENT_FIRST
) {
1088 num_blocks
= packet
.block_number
- 1;
1089 block_num
= 0; /* first packet. */
1092 block_num
= packet
.block_number
;
1096 /* Add this fragment to the reassembly handler. */
1097 frag_msg
= fragment_add_seq_check(&zbee_aps_reassembly_table
,
1098 payload_tvb
, 0, pinfo
, msg_id
, NULL
,
1099 block_num
, tvb_captured_length(payload_tvb
), true);
1101 if (num_blocks
> 0) {
1102 fragment_set_tot_len(&zbee_aps_reassembly_table
, pinfo
, msg_id
, NULL
, num_blocks
);
1105 new_tvb
= process_reassembled_data(payload_tvb
, 0, pinfo
, "Reassembled ZigBee APS" ,
1106 frag_msg
, &zbee_aps_frag_items
, NULL
, aps_tree
);
1109 /* The reassembly handler defragmented the message, and created a new tvbuff. */
1110 payload_tvb
= new_tvb
;
1113 /* The reassembly handler could not defragment the message. */
1114 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (fragment %d)", block_num
);
1115 call_data_dissector(payload_tvb
, pinfo
, tree
);
1116 return tvb_captured_length(tvb
);
1120 /* Handle the packet type. */
1121 switch (packet
.type
) {
1122 case ZBEE_APS_FCF_DATA
:
1123 case ZBEE_APS_FCF_INTERPAN
:
1127 if (nwk
->version
<= ZBEE_VERSION_2004
) {
1129 * In ZigBee 2004, an "application framework" sits between the
1130 * APS and application. Call a subdissector to handle it.
1132 nwk
->private_data
= profile_handle
;
1133 profile_handle
= zbee_apf_handle
;
1135 else if (profile_handle
== NULL
) {
1136 if (payload_tvb
&& (packet
.profile
== ZBEE_PROFILE_T2
)) {
1137 /* Move T2 dissect here: don't want to show T2 contents as
1138 * ZCL mess, broken packets etc */
1139 payload_tvb
= tvb_new_subset_remaining(payload_tvb
, dissect_zbee_t2(payload_tvb
, aps_tree
, nwk
->cluster_id
));
1142 /* Could not locate a profile dissector, but there may
1143 be profile-wide commands so try to dissect them */
1144 zcl_handle
= find_dissector(ZBEE_PROTOABBREV_ZCL
);
1147 call_dissector_with_data(zcl_handle
, payload_tvb
, pinfo
, tree
, nwk
);
1151 call_dissector_with_data(profile_handle
, payload_tvb
, pinfo
, tree
, nwk
);
1152 return tvb_captured_length(tvb
);
1154 case ZBEE_APS_FCF_CMD
:
1156 /* Command packets MUST contain a payload. */
1157 expert_add_info(pinfo
, proto_root
, &ei_zbee_aps_missing_payload
);
1158 return tvb_captured_length(tvb
);
1160 dissect_zbee_aps_cmd(payload_tvb
, pinfo
, aps_tree
, nwk
->version
, data
);
1161 return tvb_captured_length(tvb
);
1163 case ZBEE_APS_FCF_ACK
:
1164 /* Acks should never contain a payload. */
1168 /* Illegal frame type. */
1172 * If we get this far, then no subdissectors have been called, use the data
1173 * dissector to display the leftover bytes, if any.
1177 call_data_dissector(payload_tvb
, pinfo
, tree
);
1180 return tvb_captured_length(tvb
);
1181 } /* dissect_zbee_aps */
1184 *ZigBee APS sub-dissector for APS Command frames
1186 *@param tvb pointer to buffer containing raw packet.
1187 *@param pinfo pointer to packet information fields
1188 *@param tree pointer to data tree Wireshark uses to display packet.
1189 *@param version version of APS
1190 *@param data raw packet private data.
1192 static void dissect_zbee_aps_cmd(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, uint8_t version
, void *data
)
1194 proto_item
*cmd_root
;
1195 proto_tree
*cmd_tree
;
1197 unsigned offset
= 0;
1198 uint8_t cmd_id
= tvb_get_uint8(tvb
, offset
);
1200 /* Create a subtree for the APS Command frame, and add the command ID to it. */
1201 cmd_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, -1, ett_zbee_aps_cmd
, &cmd_root
,
1202 "Command Frame: %s", val_to_str_const(cmd_id
, zbee_aps_cmd_names
, "Unknown"));
1204 /* Add the command ID. */
1205 proto_tree_add_uint(cmd_tree
, hf_zbee_aps_cmd_id
, tvb
, offset
, 1, cmd_id
);
1208 /* Add the command name to the info column. */
1209 col_set_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(cmd_id
, zbee_aps_cmd_names
, "Unknown Command"));
1211 /* Handle the contents of the command frame. */
1213 case ZBEE_APS_CMD_SKKE1
:
1214 case ZBEE_APS_CMD_SKKE2
:
1215 offset
= dissect_zbee_aps_skke_challenge(tvb
, pinfo
, cmd_tree
, offset
);
1218 case ZBEE_APS_CMD_SKKE3
:
1219 case ZBEE_APS_CMD_SKKE4
:
1220 offset
= dissect_zbee_aps_skke_data(tvb
, pinfo
, cmd_tree
, offset
);
1223 case ZBEE_APS_CMD_TRANSPORT_KEY
:
1224 /* Transport Key Command. */
1225 offset
= dissect_zbee_aps_transport_key(tvb
, pinfo
, cmd_tree
, offset
);
1228 case ZBEE_APS_CMD_UPDATE_DEVICE
:
1229 /* Update Device Command. */
1230 offset
= dissect_zbee_aps_update_device(tvb
, pinfo
, cmd_tree
, offset
, version
);
1233 case ZBEE_APS_CMD_REMOVE_DEVICE
:
1234 /* Remove Device. */
1235 offset
= dissect_zbee_aps_remove_device(tvb
, pinfo
, cmd_tree
, offset
);
1238 case ZBEE_APS_CMD_REQUEST_KEY
:
1239 /* Request Key Command. */
1240 offset
= dissect_zbee_aps_request_key(tvb
, pinfo
, cmd_tree
, offset
);
1243 case ZBEE_APS_CMD_SWITCH_KEY
:
1244 /* Switch Key Command. */
1245 offset
= dissect_zbee_aps_switch_key(tvb
, pinfo
, cmd_tree
, offset
);
1248 case ZBEE_APS_CMD_EA_INIT_CHLNG
:
1249 case ZBEE_APS_CMD_EA_RESP_CHLNG
:
1250 /* Entity Authentication Challenge Command. */
1251 offset
= dissect_zbee_aps_auth_challenge(tvb
, pinfo
, cmd_tree
, offset
);
1254 case ZBEE_APS_CMD_EA_INIT_MAC_DATA
:
1255 case ZBEE_APS_CMD_EA_RESP_MAC_DATA
:
1256 /* Entity Authentication Data Command. */
1257 offset
= dissect_zbee_aps_auth_data(tvb
, pinfo
, cmd_tree
, offset
);
1260 case ZBEE_APS_CMD_TUNNEL
:
1261 /* Tunnel Command. */
1262 offset
= dissect_zbee_aps_tunnel(tvb
, pinfo
, cmd_tree
, offset
, data
);
1265 case ZBEE_APS_CMD_VERIFY_KEY
:
1266 /* Verify Key Command. */
1267 offset
= dissect_zbee_aps_verify_key(tvb
, pinfo
, cmd_tree
, offset
);
1270 case ZBEE_APS_CMD_CONFIRM_KEY
:
1271 /* Confirm Key Command. */
1272 offset
= dissect_zbee_aps_confirm_key(tvb
, pinfo
, cmd_tree
, offset
);
1275 case ZBEE_APS_CMD_RELAY_MSG_DOWNSTREAM
:
1276 case ZBEE_APS_CMD_RELAY_MSG_UPSTREAM
:
1283 /* Dissect any TLVs */
1284 offset
= dissect_zbee_tlvs(tvb
, pinfo
, tree
, offset
, data
, ZBEE_TLV_SRC_TYPE_ZBEE_APS
, cmd_id
);
1286 /* Check for any excess bytes. */
1287 if (offset
< tvb_captured_length(tvb
)) {
1288 /* There are leftover bytes! */
1290 tvbuff_t
*leftover_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1292 /* Get the APS Root. */
1293 root
= proto_tree_get_root(tree
);
1295 /* Correct the length of the command tree. */
1296 proto_item_set_len(cmd_root
, offset
);
1298 /* Dump the leftover to the data dissector. */
1299 call_data_dissector(leftover_tvb
, pinfo
, root
);
1301 } /* dissect_zbee_aps_cmd */
1304 *Helper dissector for the SKKE Challenge commands (SKKE1 and
1306 *@param tvb pointer to buffer containing raw packet.
1307 *@param pinfo pointer to packet information fields
1308 *@param tree pointer to the command subtree.
1309 *@param offset into the tvb to begin dissection.
1310 *@return offset after command dissection.
1313 dissect_zbee_aps_skke_challenge(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1315 /* Get and display the initiator address. */
1316 proto_tree_add_item(tree
, hf_zbee_aps_cmd_initiator
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1319 /* Get and display the responder address. */
1320 proto_tree_add_item(tree
, hf_zbee_aps_cmd_responder
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1323 /* Get and display the SKKE data. */
1324 proto_tree_add_item(tree
, hf_zbee_aps_cmd_challenge
, tvb
, offset
, ZBEE_APS_CMD_SKKE_DATA_LENGTH
, ENC_NA
);
1325 offset
+= ZBEE_APS_CMD_SKKE_DATA_LENGTH
;
1329 } /* dissect_zbee_aps_skke_challenge */
1332 *Helper dissector for the SKKE Data commands (SKKE3 and
1334 *@param tvb pointer to buffer containing raw packet.
1335 *@param pinfo pointer to packet information fields
1336 *@param tree pointer to the command subtree.
1337 *@param offset into the tvb to begin dissection.
1338 *@return offset after command dissection.
1341 dissect_zbee_aps_skke_data(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1343 /* Get and display the initiator address. */
1344 proto_tree_add_item(tree
, hf_zbee_aps_cmd_initiator
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1347 /* Get and display the responder address. */
1348 proto_tree_add_item(tree
, hf_zbee_aps_cmd_responder
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1351 /* Get and display the SKKE data. */
1352 proto_tree_add_item(tree
, hf_zbee_aps_cmd_mac
, tvb
, offset
, ZBEE_APS_CMD_SKKE_DATA_LENGTH
, ENC_NA
);
1353 offset
+= ZBEE_APS_CMD_SKKE_DATA_LENGTH
;
1357 } /* dissect_zbee_aps_skke_data */
1360 *Helper dissector for the Transport Key command.
1362 *@param tvb pointer to buffer containing raw packet.
1363 *@param pinfo pointer to packet information fields
1364 *@param tree pointer to the command subtree.
1365 *@param offset into the tvb to begin dissection.
1366 *@return offset after command dissection.
1369 dissect_zbee_aps_transport_key(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1372 uint8_t key
[ZBEE_APS_CMD_KEY_LENGTH
];
1375 /* Get and display the key type. */
1376 key_type
= tvb_get_uint8(tvb
, offset
);
1377 proto_tree_add_uint(tree
, hf_zbee_aps_cmd_key_type
, tvb
, offset
, 1, key_type
);
1380 /* Coincidentally, all the key descriptors start with the key. So
1381 * get and display it.
1383 for (i
=0; i
<ZBEE_APS_CMD_KEY_LENGTH
; i
++) {
1384 key
[i
] = tvb_get_uint8(tvb
, offset
+i
);
1386 proto_tree_add_item(tree
, hf_zbee_aps_cmd_key
, tvb
, offset
, ZBEE_APS_CMD_KEY_LENGTH
, ENC_NA
);
1387 offset
+= ZBEE_APS_CMD_KEY_LENGTH
;
1389 /* Update the key ring for this pan */
1390 zbee_sec_add_key_to_keyring(pinfo
, key
);
1392 /* Parse the rest of the key descriptor. */
1394 case ZBEE_APS_CMD_KEY_STANDARD_NWK
:
1395 case ZBEE_APS_CMD_KEY_HIGH_SEC_NWK
:
1400 /* Get and display the sequence number. */
1401 seqno
= tvb_get_uint8(tvb
, offset
);
1402 proto_tree_add_uint(tree
, hf_zbee_aps_cmd_seqno
, tvb
, offset
, 1, seqno
);
1405 /* Get and display the destination address. */
1406 proto_tree_add_item(tree
, hf_zbee_aps_cmd_dst
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1409 /* Get and display the source address. */
1410 proto_tree_add_item(tree
, hf_zbee_aps_cmd_src
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1415 case ZBEE_APS_CMD_KEY_TC_MASTER
:
1416 case ZBEE_APS_CMD_KEY_TC_LINK
:
1418 /* Trust Center master key. */
1420 /* Get and display the destination address. */
1421 proto_tree_add_item(tree
, hf_zbee_aps_cmd_dst
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1424 /* Get and display the source address. */
1425 proto_tree_add_item(tree
, hf_zbee_aps_cmd_src
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1430 case ZBEE_APS_CMD_KEY_APP_MASTER
:
1431 case ZBEE_APS_CMD_KEY_APP_LINK
:
1433 /* Application master or link key, both have the same format. */
1436 /* get and display the partner address. */
1437 proto_tree_add_item(tree
, hf_zbee_aps_cmd_partner
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1440 /* get and display the initiator flag. */
1441 initiator
= tvb_get_uint8(tvb
, offset
);
1442 proto_tree_add_boolean(tree
, hf_zbee_aps_cmd_initiator_flag
, tvb
, offset
, 1, initiator
);
1453 } /* dissect_zbee_aps_transport_key */
1457 *Helper dissector for the Verify Key Command.
1459 *@param tvb pointer to buffer containing raw packet.
1460 *@param pinfo pointer to packet information fields
1461 *@param tree pointer to the command subtree.
1462 *@param offset into the tvb to begin dissection.
1463 *@return offset after command dissection.
1466 dissect_zbee_aps_verify_key(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1468 /* display the key type. */
1469 proto_tree_add_item(tree
, hf_zbee_aps_cmd_key_type
, tvb
, offset
, 1, ENC_NA
);
1472 /* Get and display the source address. */
1473 proto_tree_add_item(tree
, hf_zbee_aps_cmd_src
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1476 /* This value is the outcome of executing the specialized keyed hash
1477 * function specified in section B.1.4 using a key with the 1-octet string
1478 * 03 as the input string.
1480 proto_tree_add_item(tree
, hf_zbee_aps_cmd_key_hash
, tvb
, offset
, ZBEE_APS_CMD_KEY_LENGTH
, ENC_NA
);
1481 offset
+= ZBEE_APS_CMD_KEY_LENGTH
;
1485 } /* dissect_zbee_aps_verify_key */
1489 *Helper dissector for the Confirm Key command.
1491 *@param tvb pointer to buffer containing raw packet.
1492 *@param pinfo pointer to packet information fields
1493 *@param tree pointer to the command subtree.
1494 *@param offset into the tvb to begin dissection.
1495 *@return offset after command dissection.
1498 dissect_zbee_aps_confirm_key(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1500 /* display status. */
1501 unsigned status
= tvb_get_uint8(tvb
, offset
);
1502 proto_tree_add_item(tree
, hf_zbee_aps_cmd_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1504 /* display the key type. */
1505 proto_tree_add_item(tree
, hf_zbee_aps_cmd_key_type
, tvb
, offset
, 1, ENC_NA
);
1507 proto_tree_add_item(tree
, hf_zbee_aps_cmd_dst
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1510 proto_item_append_text(tree
, ", %s", val_to_str_const(status
, zbee_aps_status_names
, "Unknown Status"));
1511 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s", val_to_str_const(status
, zbee_aps_status_names
, "Unknown Status"));
1514 } /* dissect_zbee_aps_confirm_key */
1517 *Helper dissector for the Update Device command.
1519 *@param tvb pointer to buffer containing raw packet.
1520 *@param pinfo pointer to packet information fields
1521 *@param tree pointer to the command subtree.
1522 *@param offset into the tvb to begin dissection.
1523 *@return offset after command dissection.
1526 dissect_zbee_aps_update_device(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
, uint8_t version
)
1528 /* Get and display the device address. */
1529 proto_tree_add_item(tree
, hf_zbee_aps_cmd_device
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1532 /* Get and display the short address. Only on ZigBee 2006 and later. */
1533 if (version
>= ZBEE_VERSION_2007
) {
1534 proto_tree_add_item(tree
, hf_zbee_aps_cmd_short_addr
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1538 /* Get and display the status. */
1539 proto_tree_add_item(tree
, hf_zbee_aps_cmd_device_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1544 } /* dissect_zbee_aps_update_device */
1547 *Helper dissector for the Remove Device command.
1549 *@param tvb pointer to buffer containing raw packet.
1550 *@param pinfo pointer to packet information fields
1551 *@param tree pointer to the command subtree.
1552 *@param offset into the tvb to begin dissection.
1553 *@return offset after command dissection.
1556 dissect_zbee_aps_remove_device(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1558 /* Get and display the device address. */
1559 proto_tree_add_item(tree
, hf_zbee_aps_cmd_device
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1564 } /* dissect_zbee_aps_remove_device */
1567 *Helper dissector for the Request Key command.
1569 *@param tvb pointer to buffer containing raw packet.
1570 *@param pinfo pointer to packet information fields
1571 *@param tree pointer to the command subtree.
1572 *@param offset into the tvb to begin dissection.
1573 *@return offset after command dissection.
1576 dissect_zbee_aps_request_key(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1580 /* Get and display the key type. */
1581 key_type
= tvb_get_uint8(tvb
, offset
);
1582 proto_tree_add_uint(tree
, hf_zbee_aps_cmd_key_type
, tvb
, offset
, 1, key_type
);
1585 /* Get and display the partner address. Only present on application master key. */
1586 if (key_type
== ZBEE_APS_CMD_KEY_APP_MASTER
) {
1587 proto_tree_add_item(tree
, hf_zbee_aps_cmd_partner
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1593 } /* dissect_zbee_aps_request_key */
1596 *Helper dissector for the Switch Key command.
1598 *@param tvb pointer to buffer containing raw packet.
1599 *@param pinfo pointer to packet information fields
1600 *@param tree pointer to the command subtree.
1601 *@param offset into the tvb to begin dissection.
1602 *@return offset after command dissection.
1605 dissect_zbee_aps_switch_key(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1609 /* Get and display the sequence number. */
1610 seqno
= tvb_get_uint8(tvb
, offset
);
1611 proto_tree_add_uint(tree
, hf_zbee_aps_cmd_seqno
, tvb
, offset
, 1, seqno
);
1616 } /* dissect_zbee_aps_switch_key */
1619 *Helper dissector for the Entity-Authentication Initiator
1621 *@param tvb pointer to buffer containing raw packet.
1622 *@param pinfo pointer to packet information fields
1623 *@param tree pointer to the command subtree.
1624 *@param offset into the tvb to begin dissection.
1625 *@return offset after command dissection.
1628 dissect_zbee_aps_auth_challenge(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1633 /* Get and display the key type. */
1634 key_type
= tvb_get_uint8(tvb
, offset
);
1635 proto_tree_add_uint(tree
, hf_zbee_aps_cmd_ea_key_type
, tvb
, offset
, 1, key_type
);
1638 /* If using the network key, display the key sequence number. */
1639 if (key_type
== ZBEE_APS_CMD_EA_KEY_NWK
) {
1640 key_seqno
= tvb_get_uint8(tvb
, offset
);
1641 proto_tree_add_uint(tree
, hf_zbee_aps_cmd_seqno
, tvb
, offset
, 1, key_seqno
);
1645 /* Get and display the initiator address. */
1646 proto_tree_add_item(tree
, hf_zbee_aps_cmd_initiator
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1649 /* Get and display the responder address. */
1650 proto_tree_add_item(tree
, hf_zbee_aps_cmd_responder
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1653 /* Get and display the challenge. */
1654 proto_tree_add_item(tree
, hf_zbee_aps_cmd_challenge
, tvb
, offset
, ZBEE_APS_CMD_EA_CHALLENGE_LENGTH
, ENC_NA
);
1655 offset
+= ZBEE_APS_CMD_EA_CHALLENGE_LENGTH
;
1659 } /* dissect_zbee_aps_auth_challenge */
1662 *Helper dissector for the Entity-Authentication Initiator
1664 *@param tvb pointer to buffer containing raw packet.
1665 *@param pinfo pointer to packet information fields
1666 *@param tree pointer to the command subtree.
1667 *@param offset into the tvb to begin dissection.
1668 *@return offset after command dissection.
1671 dissect_zbee_aps_auth_data(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, unsigned offset
)
1675 /* Display the MAC. */
1676 proto_tree_add_item(tree
, hf_zbee_aps_cmd_mac
, tvb
, offset
, ZBEE_APS_CMD_EA_MAC_LENGTH
, ENC_NA
);
1677 offset
+= ZBEE_APS_CMD_EA_MAC_LENGTH
;
1679 /* Get and display the data type. */
1680 data_type
= tvb_get_uint8(tvb
, offset
);
1681 /* Note! We're interpreting the DataType field to be the same as
1682 * KeyType field in the challenge frames. So far, this seems
1683 * consistent, although ZigBee appears to have left some holes
1684 * in the definition of the DataType and Data fields (ie: what
1685 * happens when KeyType == Link Key?)
1687 proto_tree_add_uint(tree
, hf_zbee_aps_cmd_ea_key_type
, tvb
, offset
, 1, data_type
);
1690 /* Display the data field. */
1691 proto_tree_add_item(tree
, hf_zbee_aps_cmd_ea_data
, tvb
, offset
, ZBEE_APS_CMD_EA_DATA_LENGTH
, ENC_NA
);
1692 offset
+= ZBEE_APS_CMD_EA_DATA_LENGTH
;
1696 } /* dissect_zbee_aps_auth_data */
1699 *Helper dissector for the Tunnel command.
1701 *@param tvb pointer to buffer containing raw packet.
1702 *@param pinfo pointer to packet information fields
1703 *@param tree pointer to the command subtree.
1704 *@param offset into the tvb to begin dissection.
1705 *@param data raw packet private data.
1706 *@return offset after command dissection.
1709 dissect_zbee_aps_tunnel(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
, void *data
)
1712 tvbuff_t
*tunnel_tvb
;
1714 /* Get and display the destination address. */
1715 proto_tree_add_item(tree
, hf_zbee_aps_cmd_dst
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1718 /* The remainder is a tunneled APS frame. */
1719 tunnel_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1720 root
= proto_tree_get_root(tree
);
1721 call_dissector_with_data(zbee_aps_handle
, tunnel_tvb
, pinfo
, root
, data
);
1722 offset
= tvb_captured_length(tvb
);
1726 } /* dissect_zbee_aps_tunnel */
1730 *ZigBee Application Framework dissector for Wireshark. Note
1732 *@param tvb pointer to buffer containing raw packet.
1733 *@param pinfo pointer to packet information fields
1734 *@param tree pointer to data tree.
1736 static int dissect_zbee_apf(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
1738 proto_tree
*apf_tree
;
1739 proto_item
*proto_root
;
1743 unsigned offset
= 0;
1747 dissector_handle_t app_dissector
= NULL
;
1748 zbee_nwk_packet
*nwk
= (zbee_nwk_packet
*)data
;
1751 app_dissector
= (dissector_handle_t
)(nwk
->private_data
);
1753 /* Create the tree for the application framework. */
1754 proto_root
= proto_tree_add_protocol_format(tree
, proto_zbee_apf
, tvb
, 0,
1755 tvb_captured_length(tvb
), "ZigBee Application Framework");
1756 apf_tree
= proto_item_add_subtree(proto_root
, ett_zbee_apf
);
1758 /* Get the count and type. */
1759 count
= zbee_get_bit_field(tvb_get_uint8(tvb
, offset
), ZBEE_APP_COUNT
);
1760 type
= zbee_get_bit_field(tvb_get_uint8(tvb
, offset
), ZBEE_APP_TYPE
);
1761 proto_tree_add_uint(apf_tree
, hf_zbee_apf_count
, tvb
, offset
, 1, count
);
1762 proto_tree_add_uint(apf_tree
, hf_zbee_apf_type
, tvb
, offset
, 1, type
);
1765 /* Ensure the application dissector exists. */
1766 if (app_dissector
== NULL
) {
1767 /* No dissector for this profile. */
1768 goto dissect_app_end
;
1771 /* Handle the transactions. */
1772 for (i
=0; i
<count
; i
++) {
1775 /* Create a tvb for this transaction. */
1776 length
= zbee_apf_transaction_len(tvb
, offset
, type
);
1777 app_tvb
= tvb_new_subset_length(tvb
, offset
, length
);
1779 /* Call the application dissector. */
1780 call_dissector_with_data(app_dissector
, app_tvb
, pinfo
, tree
, data
);
1782 /* Adjust the offset. */
1787 if (offset
< tvb_captured_length(tvb
)) {
1788 /* There are bytes remaining! */
1789 app_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1790 call_data_dissector(app_tvb
, pinfo
, tree
);
1793 return tvb_captured_length(tvb
);
1794 } /* dissect_zbee_apf */
1797 *ZigBee Test Profile #2 dissector for Wireshark.
1799 *@param tvb pointer to buffer containing raw packet.
1800 *@param tree pointer to the command subtree.
1801 *@param cluster_id ZigBee Test Profile #2 cluster ID.
1804 dissect_zbee_t2(tvbuff_t
*tvb
, proto_tree
*tree
, uint16_t cluster_id
)
1806 unsigned offset
= 0;
1807 uint8_t payload_length
;
1808 proto_tree
*t2_tree
;
1810 t2_tree
= proto_tree_add_subtree(tree
, tvb
, 0, -1, ett_zbee_aps_t2
, NULL
, "ZigBee Test Profile #2");
1812 switch (cluster_id
) {
1813 case ZBEE_APS_T2_CID_BTRES
:
1814 payload_length
= tvb_get_uint8(tvb
, offset
);
1815 proto_tree_add_uint(t2_tree
, hf_zbee_aps_t2_btres_octet_sequence_length_requested
, tvb
, offset
, 1,
1818 proto_tree_add_item(t2_tree
, hf_zbee_aps_t2_btres_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1820 proto_tree_add_item(t2_tree
, hf_zbee_aps_t2_btres_octet_sequence
, tvb
, offset
, payload_length
, ENC_NA
);
1821 offset
+= payload_length
;
1823 case ZBEE_APS_T2_CID_BTREQ
:
1824 payload_length
= tvb_get_uint8(tvb
, offset
);
1825 proto_tree_add_uint(t2_tree
, hf_zbee_aps_t2_btreq_octet_sequence_length
, tvb
, offset
, 1, payload_length
);
1830 } /* dissect_zbee_t2 */
1833 *Peeks into the application framework, and determines the
1835 *@param tvb packet buffer.
1836 *@param offset offset into the buffer.
1837 *@param type message type: KVP or MSG.
1840 zbee_apf_transaction_len(tvbuff_t
*tvb
, unsigned offset
, uint8_t type
)
1842 if (type
== ZBEE_APP_TYPE_KVP
) {
1844 /* | 1 Byte | 1 Byte | 2 Bytes | 0/1 Bytes | Variable |
1845 * | SeqNo | Cmd/Data Type | Attribute | Error Code | Data |
1847 uint8_t kvp_cmd
= zbee_get_bit_field(tvb_get_uint8(tvb
, offset
+1), ZBEE_APP_KVP_CMD
);
1848 uint8_t kvp_type
= zbee_get_bit_field(tvb_get_uint8(tvb
, offset
+1), ZBEE_APP_KVP_TYPE
);
1849 unsigned kvp_len
= ZBEE_APP_KVP_OVERHEAD
;
1851 /* Add the length of the error code, if present. */
1853 case ZBEE_APP_KVP_SET_RESP
:
1854 case ZBEE_APP_KVP_EVENT_RESP
:
1855 /* Error Code Present. */
1857 /* Data Not Present. */
1859 case ZBEE_APP_KVP_GET_RESP
:
1860 /* Error Code Present. */
1864 case ZBEE_APP_KVP_SET
:
1865 case ZBEE_APP_KVP_SET_ACK
:
1866 case ZBEE_APP_KVP_EVENT
:
1867 case ZBEE_APP_KVP_EVENT_ACK
:
1868 /* No Error Code Present. */
1871 case ZBEE_APP_KVP_GET_ACK
:
1873 /* No Error Code Present. */
1874 /* No Data Present. */
1878 /* Add the length of the data. */
1880 case ZBEE_APP_KVP_ABS_TIME
:
1881 case ZBEE_APP_KVP_REL_TIME
:
1884 case ZBEE_APP_KVP_UINT16
:
1885 case ZBEE_APP_KVP_INT16
:
1886 case ZBEE_APP_KVP_FLOAT16
:
1889 case ZBEE_APP_KVP_UINT8
:
1890 case ZBEE_APP_KVP_INT8
:
1893 case ZBEE_APP_KVP_CHAR_STRING
:
1894 case ZBEE_APP_KVP_OCT_STRING
:
1895 /* Variable Length Types, first byte is the length-1 */
1896 kvp_len
+= tvb_get_uint8(tvb
, offset
+kvp_len
)+1;
1898 case ZBEE_APP_KVP_NO_DATA
:
1907 /* | 1 Byte | 1 Byte | Length Bytes |
1908 * | SeqNo | Length | Message |
1910 return (tvb_get_uint8(tvb
, offset
+1) + 2);
1912 } /* zbee_apf_transaction_len */
1915 proto_init_zbee_aps(void)
1917 zbee_table_aps_extended_counters
= g_hash_table_new(ieee802154_short_addr_hash
, ieee802154_short_addr_equal
);
1921 proto_cleanup_zbee_aps(void)
1923 g_hash_table_destroy(zbee_table_aps_extended_counters
);
1926 /* The ZigBee Smart Energy version in enum_val_t for the ZigBee Smart Energy version preferences. */
1927 static const enum_val_t zbee_zcl_protocol_version_enums
[] = {
1928 { "se1.1b", "SE 1.1b", ZBEE_SE_VERSION_1_1B
},
1929 { "se1.2", "SE 1.2", ZBEE_SE_VERSION_1_2
},
1930 { "se1.2a", "SE 1.2a", ZBEE_SE_VERSION_1_2A
},
1931 { "se1.2b", "SE 1.2b", ZBEE_SE_VERSION_1_2B
},
1932 { "se1.4", "SE 1.4", ZBEE_SE_VERSION_1_4
},
1936 int gPREF_zbee_se_protocol_version
= ZBEE_SE_VERSION_1_4
;
1939 dissect_zbee_aps_status_code(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned offset
)
1941 unsigned status
= tvb_get_uint8(tvb
, offset
);
1942 proto_tree_add_item(tree
, hf_zbee_aps_cmd_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1943 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s", val_to_str_const(status
, zbee_aps_status_names
, "Unknown Status"));
1947 *ZigBee APS protocol registration routine.
1950 void proto_register_zbee_aps(void)
1952 static hf_register_info hf
[] = {
1953 { &hf_zbee_aps_fcf_frame_type
,
1954 { "Frame Type", "zbee_aps.type", FT_UINT8
, BASE_HEX
, VALS(zbee_aps_frame_types
), ZBEE_APS_FCF_FRAME_TYPE
,
1957 { &hf_zbee_aps_fcf_delivery
,
1958 { "Delivery Mode", "zbee_aps.delivery", FT_UINT8
, BASE_HEX
, VALS(zbee_aps_delivery_modes
), ZBEE_APS_FCF_DELIVERY_MODE
,
1961 { &hf_zbee_aps_fcf_indirect_mode
,
1962 { "Indirect Address Mode", "zbee_aps.indirect_mode", FT_BOOLEAN
, 8, NULL
, ZBEE_APS_FCF_INDIRECT_MODE
,
1965 { &hf_zbee_aps_fcf_ack_format
,
1966 { "Acknowledgement Format", "zbee_aps.ack_format", FT_BOOLEAN
, 8, NULL
, ZBEE_APS_FCF_ACK_FORMAT
,
1969 { &hf_zbee_aps_fcf_security
,
1970 { "Security", "zbee_aps.security", FT_BOOLEAN
, 8, NULL
, ZBEE_APS_FCF_SECURITY
,
1971 "Whether security operations are performed on the APS payload.", HFILL
}},
1973 { &hf_zbee_aps_fcf_ack_req
,
1974 { "Acknowledgement Request","zbee_aps.ack_req", FT_BOOLEAN
, 8, NULL
, ZBEE_APS_FCF_ACK_REQ
,
1975 "Flag requesting an acknowledgement frame for this packet.", HFILL
}},
1977 { &hf_zbee_aps_fcf_ext_header
,
1978 { "Extended Header", "zbee_aps.ext_header", FT_BOOLEAN
, 8, NULL
, ZBEE_APS_FCF_EXT_HEADER
,
1982 { "Destination Endpoint", "zbee_aps.dst", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1985 { &hf_zbee_aps_group
,
1986 { "Group", "zbee_aps.group", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1989 { &hf_zbee_aps_cluster
,
1990 { "Cluster", "zbee_aps.cluster", FT_UINT16
, BASE_HEX
| BASE_RANGE_STRING
,
1991 RVALS(zbee_aps_cid_names
), 0x0, NULL
, HFILL
}},
1993 { &hf_zbee_aps_profile
,
1994 { "Profile", "zbee_aps.profile", FT_UINT16
, BASE_HEX
| BASE_RANGE_STRING
,
1995 RVALS(zbee_aps_apid_names
), 0x0, NULL
, HFILL
}},
1998 { "Source Endpoint", "zbee_aps.src", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2001 { &hf_zbee_aps_counter
,
2002 { "Counter", "zbee_aps.counter", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2005 { &hf_zbee_aps_fragmentation
,
2006 { "Fragmentation", "zbee_aps.fragmentation", FT_UINT8
, BASE_HEX
, VALS(zbee_aps_fragmentation_modes
), ZBEE_APS_EXT_FCF_FRAGMENT
,
2009 { &hf_zbee_aps_block_number
,
2010 { "Block Number", "zbee_aps.block", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2011 "A block identifier within a fragmented transmission, or the number of expected blocks if the first block.", HFILL
}},
2013 { &hf_zbee_aps_block_ack
,
2014 { "Block Acknowledgements", "zbee_aps.block_acks", FT_UINT8
, BASE_HEX
,
2015 NULL
, 0x0, NULL
, HFILL
}},
2017 { &hf_zbee_aps_block_ack1
,
2018 { "Block 1", "zbee_aps.block1_ack", FT_BOOLEAN
, 8, TFS(&tfs_acknowledged_not_acknowledged
),
2019 ZBEE_APS_FRAG_BLOCK1_ACK
, NULL
, HFILL
}},
2021 { &hf_zbee_aps_block_ack2
,
2022 { "Block 2", "zbee_aps.block2_ack", FT_BOOLEAN
, 8, TFS(&tfs_acknowledged_not_acknowledged
),
2023 ZBEE_APS_FRAG_BLOCK2_ACK
, NULL
, HFILL
}},
2025 { &hf_zbee_aps_block_ack3
,
2026 { "Block 3", "zbee_aps.block3_ack", FT_BOOLEAN
, 8, TFS(&tfs_acknowledged_not_acknowledged
),
2027 ZBEE_APS_FRAG_BLOCK3_ACK
, NULL
, HFILL
}},
2029 { &hf_zbee_aps_block_ack4
,
2030 { "Block 4", "zbee_aps.block4_ack", FT_BOOLEAN
, 8, TFS(&tfs_acknowledged_not_acknowledged
),
2031 ZBEE_APS_FRAG_BLOCK4_ACK
, NULL
, HFILL
}},
2033 { &hf_zbee_aps_block_ack5
,
2034 { "Block 5", "zbee_aps.block5_ack", FT_BOOLEAN
, 8, TFS(&tfs_acknowledged_not_acknowledged
),
2035 ZBEE_APS_FRAG_BLOCK5_ACK
, NULL
, HFILL
}},
2037 { &hf_zbee_aps_block_ack6
,
2038 { "Block 6", "zbee_aps.block6_ack", FT_BOOLEAN
, 8, TFS(&tfs_acknowledged_not_acknowledged
),
2039 ZBEE_APS_FRAG_BLOCK6_ACK
, NULL
, HFILL
}},
2041 { &hf_zbee_aps_block_ack7
,
2042 { "Block 7", "zbee_aps.block7_ack", FT_BOOLEAN
, 8, TFS(&tfs_acknowledged_not_acknowledged
),
2043 ZBEE_APS_FRAG_BLOCK7_ACK
, NULL
, HFILL
}},
2045 { &hf_zbee_aps_block_ack8
,
2046 { "Block 8", "zbee_aps.block8_ack", FT_BOOLEAN
, 8, TFS(&tfs_acknowledged_not_acknowledged
),
2047 ZBEE_APS_FRAG_BLOCK8_ACK
, NULL
, HFILL
}},
2049 { &hf_zbee_aps_cmd_id
,
2050 { "Command Identifier", "zbee_aps.cmd.id", FT_UINT8
, BASE_HEX
, VALS(zbee_aps_cmd_names
), 0x0,
2053 { &hf_zbee_aps_cmd_initiator
,
2054 { "Initiator Address", "zbee_aps.cmd.initiator", FT_EUI64
, BASE_NONE
, NULL
, 0x0,
2055 "The extended address of the device to initiate the SKKE procedure", HFILL
}},
2057 { &hf_zbee_aps_cmd_responder
,
2058 { "Responder Address", "zbee_aps.cmd.responder", FT_EUI64
, BASE_NONE
, NULL
, 0x0,
2059 "The extended address of the device responding to the SKKE procedure", HFILL
}},
2061 { &hf_zbee_aps_cmd_partner
,
2062 { "Partner Address", "zbee_aps.cmd.partner", FT_EUI64
, BASE_NONE
, NULL
, 0x0,
2063 "The partner to use this key with for link-level security.", HFILL
}},
2065 { &hf_zbee_aps_cmd_initiator_flag
,
2066 { "Initiator", "zbee_aps.cmd.init_flag", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2067 "Indicates the destination of the transport-key command requested this key.", HFILL
}},
2069 { &hf_zbee_aps_cmd_device
,
2070 { "Device Address", "zbee_aps.cmd.device", FT_EUI64
, BASE_NONE
, NULL
, 0x0,
2071 "The device whose status is being updated.", HFILL
}},
2073 { &hf_zbee_aps_cmd_challenge
,
2074 { "Challenge", "zbee_aps.cmd.challenge", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2075 "Random challenge value used during SKKE and authentication.", HFILL
}},
2077 { &hf_zbee_aps_cmd_mac
,
2078 { "Message Authentication Code", "zbee_aps.cmd.mac", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2079 "Message authentication values used during SKKE and authentication.", HFILL
}},
2081 { &hf_zbee_aps_cmd_key
,
2082 { "Key", "zbee_aps.cmd.key", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2085 { &hf_zbee_aps_cmd_key_hash
,
2086 { "Key Hash", "zbee_aps.cmd.key_hash", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2089 { &hf_zbee_aps_cmd_key_type
,
2090 { "Key Type", "zbee_aps.cmd.key_type", FT_UINT8
, BASE_HEX
,
2091 VALS(zbee_aps_key_names
), 0x0, NULL
, HFILL
}},
2093 { &hf_zbee_aps_cmd_dst
,
2094 { "Extended Destination", "zbee_aps.cmd.dst", FT_EUI64
, BASE_NONE
, NULL
, 0x0,
2097 { &hf_zbee_aps_cmd_src
,
2098 { "Extended Source", "zbee_aps.cmd.src", FT_EUI64
, BASE_NONE
, NULL
, 0x0,
2101 { &hf_zbee_aps_cmd_seqno
,
2102 { "Sequence Number", "zbee_aps.cmd.seqno", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2103 "The key sequence number associated with the network key.", HFILL
}},
2105 { &hf_zbee_aps_cmd_short_addr
,
2106 { "Device Address", "zbee_aps.cmd.addr", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2107 "The device whose status is being updated.", HFILL
}},
2109 { &hf_zbee_aps_cmd_device_status
,
2110 { "Device Status", "zbee_aps.cmd.update_status", FT_UINT8
, BASE_HEX
,
2111 VALS(zbee_aps_update_status_names
), 0x0,
2112 "Update device status.", HFILL
}},
2114 { &hf_zbee_aps_cmd_status
,
2115 { "Status", "zbee_aps.cmd.status", FT_UINT8
, BASE_HEX
,
2116 VALS(zbee_aps_status_names
), 0x0,
2117 "APS status.", HFILL
}},
2119 { &hf_zbee_aps_cmd_ea_key_type
,
2120 { "Key Type", "zbee_aps.cmd.ea.key_type", FT_UINT8
, BASE_HEX
,
2121 VALS(zbee_aps_ea_key_names
), 0x0,
2124 { &hf_zbee_aps_cmd_ea_data
,
2125 { "Data", "zbee_aps.cmd.ea.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2126 "Additional data used in entity authentication. Typically this will be the outgoing frame counter associated with the key used for entity authentication.", HFILL
}},
2128 { &hf_zbee_aps_fragments
,
2129 { "Message fragments", "zbee_aps.fragments", FT_NONE
, BASE_NONE
, NULL
, 0x0,
2132 { &hf_zbee_aps_fragment
,
2133 { "Message fragment", "zbee_aps.fragment", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2136 { &hf_zbee_aps_fragment_overlap
,
2137 { "Message fragment overlap", "zbee_aps.fragment.overlap", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2140 { &hf_zbee_aps_fragment_overlap_conflicts
,
2141 { "Message fragment overlapping with conflicting data", "zbee_aps.fragment.overlap.conflicts", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2144 { &hf_zbee_aps_fragment_multiple_tails
,
2145 { "Message has multiple tail fragments", "zbee_aps.fragment.multiple_tails", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2148 { &hf_zbee_aps_fragment_too_long_fragment
,
2149 { "Message fragment too long", "zbee_aps.fragment.too_long_fragment", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
2152 { &hf_zbee_aps_fragment_error
,
2153 { "Message defragmentation error", "zbee_aps.fragment.error", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2156 { &hf_zbee_aps_fragment_count
,
2157 { "Message fragment count", "zbee_aps.fragment.count", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2160 { &hf_zbee_aps_reassembled_in
,
2161 { "Reassembled in", "zbee_aps.reassembled.in", FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2164 { &hf_zbee_aps_reassembled_length
,
2165 { "Reassembled ZigBee APS length", "zbee_aps.reassembled.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2168 { &hf_zbee_aps_t2_cluster
,
2169 { "Cluster", "zbee_aps.t2.cluster", FT_UINT16
, BASE_HEX
, VALS(zbee_aps_t2_cid_names
), 0x0, NULL
,
2172 { &hf_zbee_aps_t2_btres_octet_sequence
,
2173 { "Octet Sequence", "zbee_aps.t2.btres.octet_sequence", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2175 { &hf_zbee_aps_t2_btres_octet_sequence_length_requested
,
2176 { "Octet Sequence Length Requested", "zbee_aps.t2.btres.octet_sequence_length_requested", FT_UINT8
,
2177 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
2179 { &hf_zbee_aps_t2_btres_status
,
2180 { "Status", "zbee_aps.t2.btres.status", FT_UINT8
, BASE_HEX
, VALS(zbee_aps_t2_btres_status_names
), 0x0,
2183 { &hf_zbee_aps_t2_btreq_octet_sequence_length
,
2184 { "Octet Sequence Length", "zbee_aps.t2.btreq.octet_sequence_length", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2187 { &hf_zbee_aps_zdp_cluster
,
2188 { "Cluster", "zbee_aps.zdp_cluster", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}}
2191 static hf_register_info hf_apf
[] = {
2192 { &hf_zbee_apf_count
,
2193 { "Count", "zbee_apf.count", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2196 { &hf_zbee_apf_type
,
2197 { "Type", "zbee_apf.type", FT_UINT8
, BASE_HEX
,
2198 VALS(zbee_apf_type_names
), 0x0, NULL
, HFILL
}}
2202 static int *ett
[] = {
2207 &ett_zbee_aps_fragment
,
2208 &ett_zbee_aps_fragments
,
2210 &ett_zbee_aps_frag_ack
2213 static int *ett_apf
[] = {
2217 static ei_register_info ei
[] = {
2218 { &ei_zbee_aps_invalid_delivery_mode
, { "zbee_aps.invalid_delivery_mode", PI_PROTOCOL
, PI_WARN
, "Invalid Delivery Mode", EXPFILL
}},
2219 { &ei_zbee_aps_missing_payload
, { "zbee_aps.missing_payload", PI_MALFORMED
, PI_ERROR
, "Missing Payload", EXPFILL
}},
2222 register_init_routine(proto_init_zbee_aps
);
2223 register_cleanup_routine(proto_cleanup_zbee_aps
);
2225 expert_module_t
* expert_zbee_aps
;
2227 /* Register ZigBee APS protocol with Wireshark. */
2228 proto_zbee_aps
= proto_register_protocol("ZigBee Application Support Layer", "ZigBee APS", ZBEE_PROTOABBREV_APS
);
2229 proto_register_field_array(proto_zbee_aps
, hf
, array_length(hf
));
2230 proto_register_subtree_array(ett
, array_length(ett
));
2231 expert_zbee_aps
= expert_register_protocol(proto_zbee_aps
);
2232 expert_register_field_array(expert_zbee_aps
, ei
, array_length(ei
));
2234 /* Register the APS dissector and subdissector list. */
2235 zbee_aps_dissector_table
= register_dissector_table("zbee.profile", "ZigBee Profile ID", proto_zbee_aps
, FT_UINT16
, BASE_HEX
);
2236 zbee_aps_handle
= register_dissector(ZBEE_PROTOABBREV_APS
, dissect_zbee_aps
, proto_zbee_aps
);
2238 /* Register preferences */
2239 module_t
* zbee_se_prefs
= prefs_register_protocol(proto_zbee_aps
, NULL
);
2241 prefs_register_enum_preference(zbee_se_prefs
, "zbeeseversion", "ZigBee Smart Energy Version",
2242 "Specifies the ZigBee Smart Energy version used when dissecting "
2243 "ZigBee APS messages within the Smart Energy Profile",
2244 &gPREF_zbee_se_protocol_version
, zbee_zcl_protocol_version_enums
, false);
2246 /* Register reassembly table. */
2247 reassembly_table_register(&zbee_aps_reassembly_table
,
2248 &addresses_reassembly_table_functions
);
2250 /* Register the ZigBee Application Framework protocol with Wireshark. */
2251 proto_zbee_apf
= proto_register_protocol("ZigBee Application Framework", "ZigBee APF", "zbee_apf");
2252 proto_register_field_array(proto_zbee_apf
, hf_apf
, array_length(hf_apf
));
2253 proto_register_subtree_array(ett_apf
, array_length(ett_apf
));
2255 /* Register the App dissector. */
2256 zbee_apf_handle
= register_dissector("zbee_apf", dissect_zbee_apf
, proto_zbee_apf
);
2257 } /* proto_register_zbee_aps */
2260 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2265 * indent-tabs-mode: nil
2268 * vi: set shiftwidth=4 tabstop=8 expandtab:
2269 * :indentSize=4:tabSize=8:noTabs=true: