2 * RDM (Remote Device Management) packet disassembly.
6 * This dissector is written by
8 * Shaun Jackman <sjackman@gmail.com>
9 * Copyright 2006 Pathway Connectivity
11 * Erwin Rol <erwin@erwinrol.com>
12 * Copyright 2003 Erwin Rol
14 * Wireshark - Network traffic analyzer
15 * Gerald Combs <gerald@wireshark.org>
16 * Copyright 1999 Gerald Combs
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin Street, Fifth Floor
31 * Boston, MA 02110-1301, USA.
34 * ANSI E1.20-2006, Entertainment Technology
35 * Remote Device Management over USITT DMX512, describes a method of
36 * bi-directional communications over a USITT DMX512/1990 data link
37 * between an entertainment lighting controller and one or more
38 * remotely controlled lighting devices. The protocol also is intended
39 * to work with the ANSI E1.11-2004 control protocol. It allows
40 * discovery of devices on a DMX512/E1.11 network and the remote
41 * setting of DMX starting addresses, as well as status and fault
42 * reporting back to the control console.
50 #include <epan/packet.h>
52 static int proto_rdm = -1;
54 static int hf_rdm_start_code = -1;
55 static int hf_rdm_sub_start_code = -1;
56 static int hf_rdm_message_length = -1;
57 static int hf_rdm_dest_uid = -1;
58 static int hf_rdm_src_uid = -1;
59 static int hf_rdm_transaction_number = -1;
60 static int hf_rdm_response_type = -1;
61 static int hf_rdm_message_count = -1;
62 static int hf_rdm_sub_device = -1;
63 static int hf_rdm_command_class = -1;
64 static int hf_rdm_parameter_id = -1;
65 static int hf_rdm_parameter_data_length = -1;
66 static int hf_rdm_parameter_data = -1;
67 static int hf_rdm_intron = -1;
68 static int hf_rdm_checksum = -1;
69 static int hf_rdm_trailer = -1;
71 static int ett_rdm = -1;
74 rdm_checksum(tvbuff_t *tvb, unsigned length)
78 for (i = 0; i < length; i++)
79 sum += tvb_get_guint8(tvb, i);
84 dissect_rdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
86 if (check_col(pinfo->cinfo, COL_PROTOCOL))
87 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDM");
88 if (check_col(pinfo->cinfo, COL_INFO))
89 col_clear(pinfo->cinfo, COL_INFO);
92 unsigned message_length, checksum, checksum_shouldbe,
93 parameter_data_length, offset = 0;
96 proto_tree *ti = proto_tree_add_item(tree, proto_rdm, tvb,
98 proto_tree *rdm_tree = proto_item_add_subtree(ti, ett_rdm);
100 proto_tree_add_item(rdm_tree, hf_rdm_start_code, tvb,
104 proto_tree_add_item(rdm_tree, hf_rdm_sub_start_code, tvb,
108 message_length = tvb_get_guint8(tvb, offset);
109 proto_tree_add_item(rdm_tree, hf_rdm_message_length, tvb,
113 proto_tree_add_item(rdm_tree, hf_rdm_dest_uid, tvb,
117 proto_tree_add_item(rdm_tree, hf_rdm_src_uid, tvb,
121 proto_tree_add_item(rdm_tree, hf_rdm_transaction_number, tvb,
125 proto_tree_add_item(rdm_tree, hf_rdm_response_type, tvb,
129 proto_tree_add_item(rdm_tree, hf_rdm_message_count, tvb,
133 proto_tree_add_item(rdm_tree, hf_rdm_sub_device, tvb,
137 proto_tree_add_item(rdm_tree, hf_rdm_command_class, tvb,
141 proto_tree_add_item(rdm_tree, hf_rdm_parameter_id, tvb,
145 parameter_data_length = tvb_get_guint8(tvb, offset);
146 proto_tree_add_item(rdm_tree, hf_rdm_parameter_data_length, tvb,
150 if (parameter_data_length > 0) {
151 proto_tree_add_item(rdm_tree, hf_rdm_parameter_data, tvb,
152 offset, parameter_data_length, FALSE);
153 offset += parameter_data_length;
156 if (offset < message_length) {
157 proto_tree_add_item(rdm_tree, hf_rdm_intron, tvb,
158 offset, message_length - offset, FALSE);
159 offset = message_length;
162 checksum_shouldbe = rdm_checksum(tvb, offset);
163 checksum = tvb_get_ntohs(tvb, offset);
164 item = proto_tree_add_item(rdm_tree, hf_rdm_checksum, tvb,
166 proto_item_append_text(item, checksum == checksum_shouldbe
168 : " [incorrect, should be 0x%04x]", checksum_shouldbe);
171 if (offset < tvb_length(tvb))
172 proto_tree_add_item(rdm_tree, hf_rdm_trailer, tvb,
178 proto_register_rdm(void)
180 static hf_register_info hf[] = {
181 { &hf_rdm_start_code,
182 { "Start code", "rdm.sc",
183 FT_UINT8, BASE_HEX, NULL, 0x0,
186 { &hf_rdm_sub_start_code,
187 { "Sub-start code", "rdm.ssc",
188 FT_UINT8, BASE_HEX, NULL, 0x0,
191 { &hf_rdm_message_length,
192 { "Message length", "rdm.len",
193 FT_UINT8, BASE_DEC, NULL, 0x0,
197 { "Destination UID", "rdm.dst",
198 FT_BYTES, BASE_HEX, NULL, 0x0,
202 { "Source UID", "rdm.src",
203 FT_BYTES, BASE_HEX, NULL, 0x0,
206 { &hf_rdm_transaction_number,
207 { "Transaction number", "rdm.tn",
208 FT_UINT8, BASE_DEC, NULL, 0x0,
211 { &hf_rdm_response_type,
212 { "Response type", "rdm.rt",
213 FT_UINT8, BASE_HEX, NULL, 0x0,
216 { &hf_rdm_message_count,
217 { "Message count", "rdm.mc",
218 FT_UINT8, BASE_DEC, NULL, 0x0,
221 { &hf_rdm_sub_device,
222 { "Sub-device", "rdm.sd",
223 FT_UINT16, BASE_DEC, NULL, 0x0,
226 { &hf_rdm_command_class,
227 { "Command class", "rdm.cc",
228 FT_UINT8, BASE_HEX, NULL, 0x0,
231 { &hf_rdm_parameter_id,
232 { "Parameter ID", "rdm.pid",
233 FT_UINT16, BASE_HEX, NULL, 0x0,
236 { &hf_rdm_parameter_data_length,
237 { "Parameter data length", "rdm.pdl",
238 FT_UINT8, BASE_DEC, NULL, 0x0,
241 { &hf_rdm_parameter_data,
242 { "Parameter data", "rdm.pd",
243 FT_BYTES, BASE_HEX, NULL, 0x0,
247 { "Intron", "rdm.intron",
248 FT_BYTES, BASE_HEX, NULL, 0x0,
252 { "Checksum", "rdm.checksum",
253 FT_UINT16, BASE_HEX, NULL, 0x0,
257 { "Trailer", "rdm.trailer",
258 FT_BYTES, BASE_HEX, NULL, 0x0,
262 static gint *ett[] = {
266 proto_rdm = proto_register_protocol("Remote Device Management",
268 proto_register_field_array(proto_rdm, hf, array_length(hf));
269 proto_register_subtree_array(ett, array_length(ett));
270 register_dissector("rdm", dissect_rdm, proto_rdm);
274 proto_reg_handoff_rdm(void)