diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index bf0591260c..0eb75ba671 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -519,6 +519,11 @@ set(DISSECTOR_SRC dissectors/packet-dlm3.c dissectors/packet-dlsw.c dissectors/packet-dmp.c + dissectors/packet-dmx.c + dissectors/packet-dmx-chan.c + dissectors/packet-dmx-test.c + dissectors/packet-dmx-text.c + dissectors/packet-dmx-sip.c dissectors/packet-dnp.c dissectors/packet-dns.c dissectors/packet-dplay.c diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index 1578e891f9..4d9bd1510e 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -439,6 +439,11 @@ DISSECTOR_SRC = \ packet-dlm3.c \ packet-dlsw.c \ packet-dmp.c \ + packet-dmx.c \ + packet-dmx-chan.c \ + packet-dmx-test.c \ + packet-dmx-text.c \ + packet-dmx-sip.c \ packet-dnp.c \ packet-dns.c \ packet-dplay.c \ diff --git a/epan/dissectors/packet-artnet.c b/epan/dissectors/packet-artnet.c index f6f3c42f4e..8fe4d9494d 100644 --- a/epan/dissectors/packet-artnet.c +++ b/epan/dissectors/packet-artnet.c @@ -3,7 +3,7 @@ * * $Id$ * - * Copyright (c) 2003 by Erwin Rol + * Copyright (c) 2003, 2011 by Erwin Rol * * Wireshark - Network traffic analyzer * By Gerald Combs @@ -68,51 +68,86 @@ #define ARTNET_VIDEO_PALETTE_LENGTH 55 #define ARTNET_VIDEO_DATA_LENGTH 8 - #define ARTNET_OP_POLL 0x2000 #define ARTNET_OP_POLL_REPLY 0x2100 -#define ARTNET_OP_POLL_SERVER_REPLY 0x2200 +#define ARTNET_OP_POLL_FP_REPLY 0x2200 +#define ARTNET_OP_DIAG_DATA 0x2300 +#define ARTNET_OP_COMMAND 0x2400 + #define ARTNET_OP_OUTPUT 0x5000 + #define ARTNET_OP_ADDRESS 0x6000 + #define ARTNET_OP_INPUT 0x7000 -#define ARTNET_OP_VIDEO_SETUP 0xa010 -#define ARTNET_OP_VIDEO_PALETTE 0xa020 -#define ARTNET_OP_VIDEO_DATA 0xa040 #define ARTNET_OP_TOD_REQUEST 0x8000 #define ARTNET_OP_TOD_DATA 0x8100 #define ARTNET_OP_TOD_CONTROL 0x8200 #define ARTNET_OP_RDM 0x8300 +#define ARTNET_OP_RDM_SUB 0x8400 + +#define ARTNET_OP_MEDIA 0x9000 +#define ARTNET_OP_MEDIA_PATCH 0x9100 +#define ARTNET_OP_MEDIA_CONTROL 0x9200 +#define ARTNET_OP_MEDIA_CONTRL_REPLY 0x9300 +#define ARTNET_OP_TIME_CODE 0x9700 +#define ARTNET_OP_TIME_SYNC 0x9800 +#define ARTNET_OP_TRIGGER 0x9900 + +#define ARTNET_OP_DIRECTORY 0x9a00 +#define ARTNET_OP_DIRECTORY_REPLY 0x9b00 + +#define ARTNET_OP_VIDEO_SETUP 0xa010 +#define ARTNET_OP_VIDEO_PALETTE 0xa020 +#define ARTNET_OP_VIDEO_DATA 0xa040 #define ARTNET_OP_MAC_MASTER 0xf000 #define ARTNET_OP_MAC_SLAVE 0xf100 #define ARTNET_OP_FIRMWARE_MASTER 0xf200 #define ARTNET_OP_FIRMWARE_REPLY 0xf300 +#define ARTNET_OP_FILE_TN_MASTER 0xf400 +#define ARTNET_OP_FILE_FN_MASTER 0xf500 +#define ARTNET_OP_FILE_FN_REPLY 0xf600 #define ARTNET_OP_IP_PROG 0xf800 #define ARTNET_OP_IP_PROG_REPLY 0xf900 static const value_string artnet_opcode_vals[] = { - { ARTNET_OP_POLL, "ArtPoll packet" }, - { ARTNET_OP_POLL_REPLY, "ArtPollReply packet" }, - { ARTNET_OP_POLL_SERVER_REPLY, "ArtPollServerReply packet" }, - { ARTNET_OP_OUTPUT, "ArtDMX data packet" }, - { ARTNET_OP_ADDRESS, "ArtAddress packet" }, - { ARTNET_OP_INPUT, "ArtInput packet" }, - { ARTNET_OP_VIDEO_SETUP, "ArtVideoSetup packet" }, - { ARTNET_OP_VIDEO_PALETTE, "ArtVideoPalette packet" }, - { ARTNET_OP_VIDEO_DATA, "ArtVideoData packet" }, - { ARTNET_OP_TOD_REQUEST, "ArtTodRequest packet" }, - { ARTNET_OP_TOD_DATA, "ArtTodData packet" }, - { ARTNET_OP_TOD_CONTROL, "ArtTodControl packet" }, - { ARTNET_OP_RDM, "ArtRdm packet" }, - { ARTNET_OP_MAC_MASTER, "ArtMacMaster packet" }, - { ARTNET_OP_MAC_SLAVE, "ArtMacSlave packet" }, - { ARTNET_OP_FIRMWARE_MASTER, "ArtFirmwareMaster packet" }, - { ARTNET_OP_FIRMWARE_REPLY, "ArtFirmwareReply packet" }, - { ARTNET_OP_IP_PROG, "ArtIpProg packet" }, - { ARTNET_OP_IP_PROG_REPLY, "ArtIpProgReply packet" }, - { 0, NULL } + { ARTNET_OP_POLL, "ArtPoll" }, + { ARTNET_OP_POLL_REPLY, "ArtPollReply" }, + { ARTNET_OP_POLL_FP_REPLY, "ArtPollFpReply" }, + { ARTNET_OP_DIAG_DATA, "ArtDiagData" }, + { ARTNET_OP_COMMAND, "ArtCommand" }, + { ARTNET_OP_OUTPUT, "ArtDMX" }, + { ARTNET_OP_ADDRESS, "ArtAddress" }, + { ARTNET_OP_INPUT, "ArtInput" }, + { ARTNET_OP_TOD_REQUEST, "ArtTodRequest" }, + { ARTNET_OP_TOD_DATA, "ArtTodData" }, + { ARTNET_OP_TOD_CONTROL, "ArtTodControl" }, + { ARTNET_OP_RDM, "ArtRdm" }, + { ARTNET_OP_RDM_SUB, "ArtRdmSub" }, + { ARTNET_OP_MEDIA, "ArtMedia" }, + { ARTNET_OP_MEDIA_PATCH, "ArtMediaPatch" }, + { ARTNET_OP_MEDIA_CONTROL, "ArtMediaControl" }, + { ARTNET_OP_MEDIA_CONTRL_REPLY, "ArtMediaContrlReply" }, + { ARTNET_OP_TIME_CODE, "ArtTimeCode" }, + { ARTNET_OP_TIME_SYNC, "ArtTimeSync" }, + { ARTNET_OP_TRIGGER, "ArtTrigger" }, + { ARTNET_OP_DIRECTORY, "ArtDirectory" }, + { ARTNET_OP_DIRECTORY_REPLY, "ArtDirectoryReply" }, + { ARTNET_OP_VIDEO_SETUP, "ArtVideoSetup" }, + { ARTNET_OP_VIDEO_PALETTE, "ArtVideoPalette" }, + { ARTNET_OP_VIDEO_DATA, "ArtVideoData" }, + { ARTNET_OP_MAC_MASTER, "ArtMacMaster" }, + { ARTNET_OP_MAC_SLAVE, "ArtMacSlave" }, + { ARTNET_OP_FIRMWARE_MASTER, "ArtFirmwareMaster" }, + { ARTNET_OP_FIRMWARE_REPLY, "ArtFirmwareReply" }, + { ARTNET_OP_FILE_TN_MASTER, "ArtfileTnMaster" }, + { ARTNET_OP_FILE_FN_MASTER, "ArtfileFnMaster" }, + { ARTNET_OP_FILE_FN_REPLY, "ArtfileFnReply" }, + { ARTNET_OP_IP_PROG, "ArtIpProg" }, + { ARTNET_OP_IP_PROG_REPLY, "ArtIpProgReply" }, + { 0, NULL } }; static const value_string artnet_oem_code_vals[] = { @@ -280,6 +315,35 @@ static const value_string artnet_rdm_command_vals[] = { { 0, NULL } }; + +#define ARTNET_CC_DISCOVERY_COMMAND 0x10 +#define ARTNET_CC_DISCOVERY_COMMAND_RESPONSE 0x11 +#define ARTNET_CC_GET_COMMAND 0x20 +#define ARTNET_CC_GET_COMMAND_RESPONSE 0x21 +#define ARTNET_CC_SET_COMMAND 0x30 +#define ARTNET_CC_SET_COMMAND_RESPONSE 0x31 + +static const value_string artnet_cc_vals[] = { + { ARTNET_CC_DISCOVERY_COMMAND, "Discovery Command" }, + { ARTNET_CC_DISCOVERY_COMMAND_RESPONSE, "Discovery Command Response" }, + { ARTNET_CC_GET_COMMAND, "Get Command" }, + { ARTNET_CC_GET_COMMAND_RESPONSE, "Get Command Response" }, + { ARTNET_CC_SET_COMMAND, "Set Command" }, + { ARTNET_CC_SET_COMMAND_RESPONSE, "Set Command Response" }, + { 0, NULL }, +}; + +#define ARTNET_FILE_TYPE_FIRST 0x00 +#define ARTNET_FILE_TYPE_NORM 0x01 +#define ARTNET_FILE_TYPE_LAST 0x02 + +static const value_string artnet_file_type_vals[] = { + { ARTNET_FILE_TYPE_FIRST, "First file packet" } , + { ARTNET_FILE_TYPE_NORM, "File packet" } , + { ARTNET_FILE_TYPE_LAST, "Final file packet" } , + { 0, NULL }, +}; + void proto_reg_handoff_artnet(void); /* Define the artnet proto */ @@ -289,6 +353,7 @@ static int proto_artnet = -1; /* general */ static int hf_artnet_filler = -1; static int hf_artnet_spare = -1; +static int hf_artnet_excess_bytes = -1; /* Header */ static int hf_artnet_header = -1; @@ -354,9 +419,6 @@ static int hf_artnet_output_sequence = -1; static int hf_artnet_output_physical = -1; static int hf_artnet_output_universe = -1; static int hf_artnet_output_length = -1; -static int hf_artnet_output_data = -1; -static int hf_artnet_output_dmx_data = -1; -static int hf_artnet_output_data_filter = -1; /* ArtAddress */ static int hf_artnet_address = -1; @@ -419,8 +481,8 @@ static int hf_artnet_video_data_len_x = -1; static int hf_artnet_video_data_len_y = -1; static int hf_artnet_video_data_data = -1; -/* ArtPollServerReply */ -static int hf_artnet_poll_server_reply = -1; +/* ArtPollFpReply */ +static int hf_artnet_poll_fp_reply = -1; /* ArtTodRequest */ static int hf_artnet_tod_request = -1; @@ -447,6 +509,19 @@ static int hf_artnet_tod_control_address = -1; static int hf_artnet_rdm = -1; static int hf_artnet_rdm_command = -1; static int hf_artnet_rdm_address = -1; +static int hf_artnet_rdm_sc = -1; + +static int hf_artnet_rdm_rdmver = -1; +static int hf_artnet_rdm_net = -1; + +/* ArtRdmSub */ +static int hf_artnet_rdm_sub = -1; +static int hf_artnet_rdm_sub_uid = -1; +static int hf_artnet_rdm_sub_command_class = -1; +static int hf_artnet_rdm_sub_pid = -1; +static int hf_artnet_rdm_sub_sub_device = -1; +static int hf_artnet_rdm_sub_sub_count = -1; +static int hf_artnet_rdm_sub_data = -1; /* ArtIpProg */ static int hf_artnet_ip_prog = -1; @@ -467,21 +542,84 @@ static int hf_artnet_ip_prog_reply_ip = -1; static int hf_artnet_ip_prog_reply_sm = -1; static int hf_artnet_ip_prog_reply_port = -1; +/* ArtDiagData */ +static int hf_artnet_diag_data = -1; +static int hf_artnet_diag_data_priority = -1; +static int hf_artnet_diag_data_index = -1; +static int hf_artnet_diag_data_length = -1; +static int hf_artnet_diag_data_data = -1; + +/* ArtCommand */ +static int hf_artnet_command = -1; + +/* ArtMedia */ +static int hf_artnet_media = -1; + +/* ArtMediaPatch */ +static int hf_artnet_media_patch = -1; + +/* ArtMediaControl */ +static int hf_artnet_media_control = -1; + +/* ArtMediaControlReply */ +static int hf_artnet_media_control_reply = -1; + +/* ArtTimeCode */ +static int hf_artnet_time_code = -1; + +/* ArtTimeSync */ +static int hf_artnet_time_sync = -1; + +/* ArtTrigger */ +static int hf_artnet_trigger = -1; + +/* ArtDirectory */ +static int hf_artnet_directory = -1; +static int hf_artnet_directory_filler = -1; +static int hf_artnet_directory_cmd = -1; +static int hf_artnet_directory_file = -1; + +/* ArtDirectoryReply */ +static int hf_artnet_directory_reply = -1; +static int hf_artnet_directory_reply_filler = -1; +static int hf_artnet_directory_reply_flags = -1; +static int hf_artnet_directory_reply_file = -1; +static int hf_artnet_directory_reply_name = -1; +static int hf_artnet_directory_reply_desc = -1; +static int hf_artnet_directory_reply_length = -1; +static int hf_artnet_directory_reply_data = -1; + +/* ArtMacMaster */ +static int hf_artnet_mac_master = -1; + +/* ArtMacSlave */ +static int hf_artnet_mac_slave = -1; + +/* ArtFileTnMaster */ +static int hf_artnet_file_tn_master = -1; +static int hf_artnet_file_tn_master_filler = -1; +static int hf_artnet_file_tn_master_type = -1; +static int hf_artnet_file_tn_master_block_id = -1; +static int hf_artnet_file_tn_master_length = -1; +static int hf_artnet_file_tn_master_name = -1; +static int hf_artnet_file_tn_master_checksum = -1; +static int hf_artnet_file_tn_master_spare = -1; +static int hf_artnet_file_tn_master_data = -1; + + +/* ArtFileFnMaster */ +static int hf_artnet_file_fn_master = -1; + +/* ArtFileFnReply */ +static int hf_artnet_file_fn_reply = -1; + + /* Define the tree for artnet */ static int ett_artnet = -1; -/* - * Here are the global variables associated with the preferences - * for artnet - */ - -static guint global_udp_port_artnet = UDP_PORT_ARTNET; -static gint global_disp_chan_val_type = 0; -static gint global_disp_col_count = 16; -static gint global_disp_chan_nr_type = 0; - /* A static handle for the rdm dissector */ static dissector_handle_t rdm_handle; +static dissector_handle_t dmx_chan_handle; static guint dissect_artnet_poll(tvbuff_t *tvb, guint offset, proto_tree *tree) @@ -747,23 +885,12 @@ dissect_artnet_poll_reply(tvbuff_t *tvb, guint offset, proto_tree *tree) } static guint -dissect_artnet_output(tvbuff_t *tvb, guint offset, proto_tree *tree) +dissect_artnet_output(tvbuff_t *tvb, guint offset, proto_tree *tree, packet_info *pinfo, proto_tree* base_tree) { - proto_tree *hi,*si; - proto_item *item; - guint16 length,r,c,row_count; - guint8 v; - static char string[255]; - char* ptr; - const char* chan_format[] = { - "%2u ", - "%02x ", - "%3u " - }; - const char* string_format[] = { - "%03x: %s", - "%3u: %s" - }; + tvbuff_t *next_tvb = NULL; + guint16 length; + guint size; + gboolean save_info; proto_tree_add_item(tree, hf_artnet_output_sequence, tvb, offset, 1, ENC_BIG_ENDIAN); @@ -782,56 +909,19 @@ dissect_artnet_output(tvbuff_t *tvb, guint offset, proto_tree *tree) offset, 2, length); offset += 2; - hi = proto_tree_add_item(tree, - hf_artnet_output_data, - tvb, - offset, - length, - ENC_NA); + size = tvb_reported_length_remaining(tvb, offset); - si = proto_item_add_subtree(hi, ett_artnet); + save_info=col_get_writable(pinfo->cinfo); + col_set_writable(pinfo->cinfo, ENC_BIG_ENDIAN); - row_count = (length/global_disp_col_count) + ((length%global_disp_col_count) == 0 ? 0 : 1); - ptr = string; - /* XX: In theory the g_snprintf statements below could store '\0' bytes off the end of the */ - /* 'string' buffer'. This is so since g_snprint returns the number of characters which */ - /* "would have been written" (whether or not there was room) and since ptr is always */ - /* incremented by this amount. In practice the string buffer is large enough such that the */ - /* string buffer size is not exceeded even with the maximum number of columns which might */ - /* be displayed. */ - /* ToDo: consider recoding slightly ... */ - for (r=0; r < row_count;r++) { - for (c=0;(c < global_disp_col_count) && (((r*global_disp_col_count)+c) < length);c++) { - if ((global_disp_col_count > 1) && (c % (global_disp_col_count/2)) == 0) { - ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), " "); - } + if (!next_tvb) + next_tvb = tvb_new_subset(tvb, offset, length, length); - v = tvb_get_guint8(tvb, (offset+(r*global_disp_col_count)+c)); - if (global_disp_chan_val_type == 0) { - v = (v * 100) / 255; - if (v == 100) { - ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), "FL "); - } else { - ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), chan_format[global_disp_chan_val_type], v); - } - } else { - ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), chan_format[global_disp_chan_val_type], v); - } - } + call_dissector(dmx_chan_handle, next_tvb, pinfo, base_tree); - proto_tree_add_none_format(si,hf_artnet_output_dmx_data, tvb, - offset+(r*global_disp_col_count), c, - string_format[global_disp_chan_nr_type], (r*global_disp_col_count)+1, string); - ptr = string; - } + col_set_writable(pinfo->cinfo, save_info); - /* Add the real type hidden */ - item = proto_tree_add_item(si, hf_artnet_output_data_filter, tvb, - offset, length, ENC_NA ); - PROTO_ITEM_SET_HIDDEN(item); - offset += length; - - return offset; + return offset + size; } static guint @@ -1230,19 +1320,40 @@ dissect_artnet_tod_control(tvbuff_t *tvb, guint offset, proto_tree *tree) } static guint -dissect_artnet_rdm(tvbuff_t *tvb, guint offset, proto_tree *tree, packet_info *pinfo) +dissect_artnet_rdm(tvbuff_t *tvb, guint offset, proto_tree *tree, packet_info *pinfo, proto_tree *base_tree) { + guint8 rdmver; + guint8 sc; guint size; gboolean save_info; tvbuff_t *next_tvb = NULL; - proto_tree_add_item(tree, hf_artnet_filler, tvb, - offset, 2, ENC_NA); - offset += 2; + rdmver = tvb_get_guint8(tvb, offset); + if (rdmver == 0x00) { + proto_tree_add_item(tree, hf_artnet_filler, tvb, + offset, 2, ENC_NA); + offset += 2; - proto_tree_add_item(tree, hf_artnet_spare, tvb, - offset, 8, ENC_NA); - offset += 8; + proto_tree_add_item(tree, hf_artnet_spare, tvb, + offset, 8, ENC_NA); + offset += 8; + } else { + proto_tree_add_item(tree, hf_artnet_rdm_rdmver, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_artnet_filler, tvb, + offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_artnet_spare, tvb, + offset, 7, ENC_NA); + offset += 7; + + proto_tree_add_item(tree, hf_artnet_rdm_net, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + } proto_tree_add_item(tree, hf_artnet_rdm_command, tvb, offset, 1, ENC_BIG_ENDIAN); @@ -1251,7 +1362,17 @@ dissect_artnet_rdm(tvbuff_t *tvb, guint offset, proto_tree *tree, packet_info * proto_tree_add_item(tree, hf_artnet_rdm_address, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; + + // check for old version that included the 0xCC startcode + // The 0xCC will never be the first byte of the RDM packet + sc = tvb_get_guint8(tvb, offset); + if (sc == 0xCC) { + proto_tree_add_item(tree, hf_artnet_rdm_sc, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + } + size = tvb_reported_length_remaining(tvb, offset); save_info=col_get_writable(pinfo->cinfo); @@ -1260,15 +1381,79 @@ dissect_artnet_rdm(tvbuff_t *tvb, guint offset, proto_tree *tree, packet_info * if (!next_tvb) next_tvb = tvb_new_subset_remaining(tvb, offset); - call_dissector(rdm_handle, next_tvb, pinfo, tree); + call_dissector(rdm_handle, next_tvb, pinfo, base_tree); col_set_writable(pinfo->cinfo, save_info); - size = tvb_reported_length_remaining(tvb, offset) - size; - return offset + size; } + +static guint +dissect_artnet_rdm_sub(tvbuff_t *tvb, guint offset, proto_tree *tree, packet_info *pinfo _U_) +{ + guint8 cc; + guint16 sc; + gint size; + + proto_tree_add_item(tree, hf_artnet_rdm_rdmver, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_artnet_filler, tvb, + offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_artnet_rdm_sub_uid, tvb, + offset, 6, ENC_NA); + offset += 6; + + proto_tree_add_item(tree, hf_artnet_spare, tvb, + offset, 1, ENC_NA); + offset += 1; + + cc = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tree, hf_artnet_rdm_sub_command_class, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + proto_tree_add_item(tree, hf_artnet_rdm_sub_pid, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_artnet_rdm_sub_sub_device, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + sc = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tree, hf_artnet_rdm_sub_sub_count, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_artnet_spare, tvb, + offset, 4, ENC_NA); + offset += 4; + + switch(cc) { + case ARTNET_CC_SET_COMMAND: + case ARTNET_CC_GET_COMMAND_RESPONSE: + size = tvb_reported_length_remaining(tvb, offset); + proto_tree_add_item(tree, hf_artnet_rdm_sub_data, tvb, + offset, size, ENC_NA); + offset += size; + break; + + case ARTNET_CC_DISCOVERY_COMMAND: + case ARTNET_CC_DISCOVERY_COMMAND_RESPONSE: + case ARTNET_CC_GET_COMMAND: + case ARTNET_CC_SET_COMMAND_RESPONSE: + default: + break; + } + + return offset; +} + static guint dissect_artnet_ip_prog(tvbuff_t *tvb, guint offset, proto_tree *tree) { guint8 command; @@ -1342,16 +1527,218 @@ dissect_artnet_ip_prog_reply(tvbuff_t *tvb, guint offset, proto_tree *tree) } static guint -dissect_artnet_poll_server_reply(tvbuff_t *tvb, guint offset, proto_tree *tree) +dissect_artnet_poll_fp_reply(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) { - /* no spec released for this packet at the moment */ + return offset; +} + + +/* ArtDiagData */ +static guint +dissect_artnet_diag_data(tvbuff_t *tvb, guint offset, proto_tree *tree) +{ + guint16 length; + proto_tree_add_item(tree, hf_artnet_filler, tvb, - offset, 182, ENC_NA); - offset += 182; + offset, 1, ENC_NA); + offset++; + + proto_tree_add_item(tree, hf_artnet_diag_data_priority, tvb, + offset, 1, ENC_NA); + offset++; + + proto_tree_add_item(tree, hf_artnet_diag_data_index, tvb, + offset, 2, ENC_NA); + offset += 2; + + length = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tree, hf_artnet_diag_data_length, tvb, + offset, 2, ENC_NA); + offset+=2; + + proto_tree_add_item(tree, hf_artnet_diag_data_data, tvb, + offset, length, ENC_NA); + offset += length; return offset; } +/* ArtCommand */ +static guint +dissect_artnet_command(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtMedia */ +static guint +dissect_artnet_media(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtMediaPatch */ +static guint +dissect_artnet_media_patch(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtMediaControl */ +static guint +dissect_artnet_media_control(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtMediaControlReply */ +static guint +dissect_artnet_media_control_reply(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtTimeCode */ +static guint +dissect_artnet_time_code(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtTimeSync */ +static guint +dissect_artnet_time_sync(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtTrigger */ +static guint +dissect_artnet_trigger(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtDirectory */ +static guint +dissect_artnet_directory(tvbuff_t *tvb, guint offset, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_artnet_directory_filler, tvb, + offset, 2, ENC_NA); + offset += 2; + + proto_tree_add_item(tree, hf_artnet_directory_cmd, tvb, + offset, 1, ENC_NA); + offset++; + + proto_tree_add_item(tree, hf_artnet_directory_file, tvb, + offset, 2, ENC_NA); + offset += 2; + + return offset; +} + +/* ArtDirectoryReply */ +static guint +dissect_artnet_directory_reply(tvbuff_t *tvb, guint offset, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_artnet_directory_reply_filler, tvb, + offset, 2, ENC_NA); + offset += 2; + + proto_tree_add_item(tree, hf_artnet_directory_reply_flags, tvb, + offset, 1, ENC_NA); + offset++; + + proto_tree_add_item(tree, hf_artnet_directory_reply_file, tvb, + offset, 2, ENC_NA); + offset += 2; + + proto_tree_add_item(tree, hf_artnet_directory_reply_name, tvb, + offset, 16, ENC_NA); + offset += 16; + + proto_tree_add_item(tree, hf_artnet_directory_reply_desc, tvb, + offset, 64, ENC_NA); + offset += 64; + + proto_tree_add_item(tree, hf_artnet_directory_reply_length, tvb, + offset, 8, ENC_NA); + offset += 8; + + proto_tree_add_item(tree, hf_artnet_directory_reply_data, tvb, + offset, 64, ENC_NA); + offset += 64; + + return offset; +} + +/* ArtMacMaster */ +static guint +dissect_artnet_mac_master(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtMacSlave */ +static guint +dissect_artnet_mac_slave(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtFileTnMaster */ +static guint +dissect_artnet_file_tn_master(tvbuff_t *tvb, guint offset, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_artnet_file_tn_master_filler, tvb, + offset, 2, ENC_NA); + offset += 2; + + proto_tree_add_item(tree, hf_artnet_file_tn_master_type, tvb, + offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_artnet_file_tn_master_block_id, tvb, + offset, 1, ENC_NA); + offset += 1; + + proto_tree_add_item(tree, hf_artnet_file_tn_master_length, tvb, + offset, 4, ENC_NA); + offset += 4; + + proto_tree_add_item(tree, hf_artnet_file_tn_master_name, tvb, + offset, 14, ENC_NA); + offset += 14; + + proto_tree_add_item(tree, hf_artnet_file_tn_master_checksum, tvb, + offset, 2, ENC_NA); + offset += 2; + + proto_tree_add_item(tree, hf_artnet_file_tn_master_spare, tvb, + offset, 4, ENC_NA); + offset += 4; + + proto_tree_add_item(tree, hf_artnet_file_tn_master_data, tvb, + offset, 512, ENC_NA); + offset += 512; + + return offset; +} + +/* ArtFileFnMaster */ +static guint +dissect_artnet_file_fn_master(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} + +/* ArtFileFnReply */ +static guint +dissect_artnet_file_fn_reply(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_) +{ + return offset; +} static void dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -1366,6 +1753,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Clear out stuff in the info column */ col_clear(pinfo->cinfo, COL_INFO); + if (tree) { ti = proto_tree_add_item(tree, proto_artnet, tvb, offset, -1, ENC_NA); artnet_tree = proto_item_add_subtree(ti, ett_artnet); @@ -1390,16 +1778,18 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { opcode = tvb_get_letohs(tvb, offset); /* set the info column */ - col_add_fstr(pinfo->cinfo, COL_INFO, "%s", - val_to_str(opcode, artnet_opcode_vals, "Unknown (0x%04x)")); + col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%04x)", + val_to_str(opcode, artnet_opcode_vals, "Unknown"), opcode); if( tree ){ proto_tree_add_uint(artnet_header_tree, hf_artnet_header_opcode, tvb, offset, 2, opcode); + + proto_item_append_text(ti, ", Opcode: %s (0x%04x)", val_to_str(opcode, artnet_opcode_vals, "Unknown"), opcode); } offset += 2; - if( opcode != ARTNET_OP_POLL_REPLY && opcode != ARTNET_OP_POLL_SERVER_REPLY ) { + if( opcode != ARTNET_OP_POLL_REPLY && opcode != ARTNET_OP_POLL_FP_REPLY ) { if( tree ){ proto_tree_add_item(artnet_header_tree, hf_artnet_header_protver, tvb, offset, 2, ENC_BIG_ENDIAN); @@ -1410,13 +1800,14 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { } switch( opcode ) { + case ARTNET_OP_POLL: if (tree) { hi = proto_tree_add_item(artnet_tree, hf_artnet_poll, tvb, offset, - ARTNET_POLL_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1425,6 +1816,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; } break; @@ -1434,7 +1826,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hf_artnet_poll_reply, tvb, offset, - ARTNET_POLL_REPLY_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1443,6 +1835,61 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; + } + break; + + case ARTNET_OP_POLL_FP_REPLY: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_poll_fp_reply, + tvb, + offset, + 0, + ENC_NA ); + si = proto_item_add_subtree(hi, ett_artnet ); + + size = dissect_artnet_poll_fp_reply( tvb, offset, si ); + size -= offset; + + proto_item_set_len(si, size ); + offset += size; + } + break; + + case ARTNET_OP_DIAG_DATA: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_diag_data, + tvb, + offset, + 0, + ENC_NA ); + si = proto_item_add_subtree(hi, ett_artnet ); + + size = dissect_artnet_diag_data( tvb, offset, si ); + size -= offset; + + proto_item_set_len(si, size ); + offset += size; + } + break; + + case ARTNET_OP_COMMAND: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_command, + tvb, + offset, + 0, + ENC_NA ); + si = proto_item_add_subtree(hi, ett_artnet ); + + size = dissect_artnet_command( tvb, offset, si ); + size -= offset; + + proto_item_set_len(si, size ); + offset += size; } break; @@ -1452,25 +1899,26 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hf_artnet_output, tvb, offset, - ARTNET_OUTPUT_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); - size = dissect_artnet_output( tvb, offset, si ); + size = dissect_artnet_output( tvb, offset, si, pinfo, tree); size -= offset; - - proto_item_set_len(si, size); + proto_item_set_len(si, size ); + offset += size; } break; + case ARTNET_OP_ADDRESS: if (tree) { hi = proto_tree_add_item(artnet_tree, hf_artnet_address, tvb, offset, - ARTNET_POLL_REPLY_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1479,6 +1927,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; } break; @@ -1488,7 +1937,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hf_artnet_input, tvb, offset, - ARTNET_INPUT_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1497,16 +1946,272 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; } break; + case ARTNET_OP_TOD_REQUEST: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_tod_request, + tvb, + offset, + 0, + ENC_NA); + + si = proto_item_add_subtree(hi, ett_artnet); + + size = dissect_artnet_tod_request( tvb, offset, si ); + size -= offset; + + proto_item_set_len(si, size); + offset += size; + } + break; + + case ARTNET_OP_TOD_DATA: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_tod_data, + tvb, + offset, + 0, + ENC_NA); + + si = proto_item_add_subtree(hi, ett_artnet ); + + size = dissect_artnet_tod_data( tvb, offset, si ); + size -= offset; + + proto_item_set_len(si, size ); + offset += size; + } + break; + + case ARTNET_OP_TOD_CONTROL: + if (tree){ + hi = proto_tree_add_item(artnet_tree, + hf_artnet_tod_control, + tvb, + offset, + 0, + ENC_NA ); + si = proto_item_add_subtree(hi, ett_artnet ); + + size = dissect_artnet_tod_control( tvb, offset, si ); + size -= offset; + + proto_item_set_len(si, size ); + offset += size; + } + break; + + case ARTNET_OP_RDM: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_rdm, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_rdm( tvb, offset, si, pinfo, tree); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_RDM_SUB: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_rdm_sub, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_rdm_sub( tvb, offset, si, pinfo ); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_MEDIA: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_media, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_media( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_MEDIA_PATCH: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_media_patch, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_media_patch( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_MEDIA_CONTROL: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_media_control, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_media_control( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_MEDIA_CONTRL_REPLY: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_media_control_reply, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_media_control_reply( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_TIME_CODE: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_time_code, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_time_code( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_TIME_SYNC: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_time_sync, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_time_sync( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_TRIGGER: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_trigger, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_trigger( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_DIRECTORY: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_directory, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_directory( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_DIRECTORY_REPLY: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_directory_reply, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi,ett_artnet); + + size = dissect_artnet_directory_reply( tvb, offset, si); + size -= offset; + + proto_item_set_len( si, size ); + offset += size; + } + break; + + case ARTNET_OP_VIDEO_SETUP: if (tree) { hi = proto_tree_add_item(artnet_tree, hf_artnet_input, tvb, offset, - ARTNET_VIDEO_SETUP_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1515,6 +2220,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; } break; @@ -1524,7 +2230,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hf_artnet_input, tvb, offset, - ARTNET_VIDEO_PALETTE_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1533,6 +2239,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; } break; @@ -1542,7 +2249,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hf_artnet_input, tvb, offset, - ARTNET_VIDEO_DATA_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1551,6 +2258,45 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; + } + break; + + case ARTNET_OP_MAC_MASTER: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_mac_master, + tvb, + offset, + 0, + ENC_NA); + + si = proto_item_add_subtree(hi, ett_artnet); + + size = dissect_artnet_mac_master( tvb, offset, si ); + size -= offset; + + proto_item_set_len(si, size); + offset += size; + } + break; + + case ARTNET_OP_MAC_SLAVE: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_mac_slave, + tvb, + offset, + 0, + ENC_NA); + + si = proto_item_add_subtree(hi, ett_artnet); + + size = dissect_artnet_mac_slave( tvb, offset, si ); + size -= offset; + + proto_item_set_len(si, size); + offset += size; } break; @@ -1560,7 +2306,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hf_artnet_firmware_master, tvb, offset, - ARTNET_FIRMWARE_MASTER_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1569,6 +2315,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; } break; @@ -1578,7 +2325,7 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hf_artnet_firmware_reply, tvb, offset, - ARTNET_FIRMWARE_REPLY_LENGTH, + 0, ENC_NA); si = proto_item_add_subtree(hi, ett_artnet); @@ -1587,138 +2334,116 @@ dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { size -= offset; proto_item_set_len(si, size); + offset += size; } break; - case ARTNET_OP_TOD_REQUEST: + case ARTNET_OP_FILE_TN_MASTER: if (tree) { hi = proto_tree_add_item(artnet_tree, - hf_artnet_tod_request, - tvb, - offset, - 0, - ENC_NA); + hf_artnet_file_tn_master, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi, ett_artnet ); - si = proto_item_add_subtree(hi, ett_artnet); + size = dissect_artnet_file_tn_master( tvb, offset, si); + size -= offset; - size = dissect_artnet_tod_request( tvb, offset, si ); - size -= offset; - - proto_item_set_len(si, size); + proto_item_set_len(si, size ); + offset += size; } break; - case ARTNET_OP_TOD_DATA: + case ARTNET_OP_FILE_FN_MASTER: if (tree) { hi = proto_tree_add_item(artnet_tree, - hf_artnet_tod_data, - tvb, - offset, - 0, - ENC_NA); + hf_artnet_file_fn_master, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi, ett_artnet ); - si = proto_item_add_subtree(hi, ett_artnet ); + size = dissect_artnet_file_fn_master( tvb, offset, si); + size -= offset; - size = dissect_artnet_tod_data( tvb, offset, si ); - size -= offset; - - proto_item_set_len(si, size ); + proto_item_set_len(si, size ); + offset += size; } break; - case ARTNET_OP_TOD_CONTROL: - if (tree){ - hi = proto_tree_add_item(artnet_tree, - hf_artnet_tod_control, - tvb, - offset, - 0, - ENC_NA ); - si = proto_item_add_subtree(hi, ett_artnet ); + case ARTNET_OP_FILE_FN_REPLY: + if (tree) { + hi = proto_tree_add_item(artnet_tree, + hf_artnet_file_fn_reply, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi, ett_artnet ); - size = dissect_artnet_tod_control( tvb, offset, si ); - size -= offset; + size = dissect_artnet_file_fn_reply( tvb, offset, si); + size -= offset; - proto_item_set_len(si, size ); + proto_item_set_len(si, size ); + offset += size; } break; - case ARTNET_OP_RDM: - hi = proto_tree_add_item(artnet_tree, - hf_artnet_rdm, - tvb, - offset, - 0, - ENC_NA); - si = proto_item_add_subtree(hi,ett_artnet); - - size = dissect_artnet_rdm( tvb, offset, si, pinfo ); - size -= offset; - - proto_item_set_len( si, size ); - break; - case ARTNET_OP_IP_PROG: if (tree) { hi = proto_tree_add_item(artnet_tree, - hf_artnet_ip_prog, - tvb, - offset, - 0, - ENC_NA); - si = proto_item_add_subtree(hi, ett_artnet ); + hf_artnet_ip_prog, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi, ett_artnet ); - size = dissect_artnet_ip_prog( tvb, offset, si); - size -= offset; + size = dissect_artnet_ip_prog( tvb, offset, si); + size -= offset; - proto_item_set_len(si, size ); + proto_item_set_len(si, size ); + offset += size; } break; case ARTNET_OP_IP_PROG_REPLY: if (tree) { hi = proto_tree_add_item(artnet_tree, - hf_artnet_ip_prog_reply, - tvb, - offset, - 0, - ENC_NA); - si = proto_item_add_subtree(hi, ett_artnet ); + hf_artnet_ip_prog_reply, + tvb, + offset, + 0, + ENC_NA); + si = proto_item_add_subtree(hi, ett_artnet ); - size = dissect_artnet_ip_prog_reply( tvb, offset, si ); - size -= offset; + size = dissect_artnet_ip_prog_reply( tvb, offset, si ); + size -= offset; - proto_item_set_len(si, size ); + proto_item_set_len(si, size ); + offset += size; } break; - case ARTNET_OP_POLL_SERVER_REPLY: - if (tree) { - hi = proto_tree_add_item(artnet_tree, - hf_artnet_poll_server_reply, - tvb, - offset, - 0, - ENC_NA ); - si = proto_item_add_subtree(hi, ett_artnet ); - - size = dissect_artnet_poll_server_reply( tvb, offset, si ); - size -= offset; - - proto_item_set_len(si, size ); - } - break; default: if (tree) { proto_tree_add_text(artnet_tree, tvb, offset, -1, "Data (%d bytes)", tvb_reported_length_remaining(tvb, offset)); + offset += tvb_reported_length_remaining(tvb, offset); } break; } - - + if (tree) { + if (tvb_reported_length_remaining(tvb, offset) > 0) { + proto_tree_add_item(artnet_tree, hf_artnet_excess_bytes, tvb, + offset, tvb_reported_length_remaining(tvb, offset), ENC_NA); + } + } } void @@ -1726,6 +2451,11 @@ proto_register_artnet(void) { static hf_register_info hf[] = { /* General */ + { &hf_artnet_excess_bytes, + { "Excess Bytes", + "artnet.excess_bytes", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, { &hf_artnet_filler, { "filler", @@ -1740,7 +2470,6 @@ proto_register_artnet(void) { NULL, HFILL }}, /* header */ - { &hf_artnet_header, { "Descriptor Header", "artnet.header", @@ -2089,24 +2818,6 @@ proto_register_artnet(void) { FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, - { &hf_artnet_output_data, - { "DMX data", - "artnet.output.data", - FT_NONE, BASE_NONE, NULL, 0x0, - NULL, HFILL }}, - - { &hf_artnet_output_data_filter, - { "DMX data filter", - "artnet.output.data_filter", - FT_BYTES, BASE_NONE, NULL, 0x0, - NULL, HFILL }}, - - { &hf_artnet_output_dmx_data, - { "DMX data", - "artnet.output.dmx_data", - FT_NONE, BASE_NONE, NULL, 0x0, - NULL, HFILL }}, - /* ArtAddress */ { &hf_artnet_address, @@ -2514,6 +3225,67 @@ proto_register_artnet(void) { "artnet.rdm.address", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + + { &hf_artnet_rdm_sc, + { "Startcode", + "artnet.rdm.sc", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_rdm_rdmver, + { "RDM Version", + "artnet.rdm.rdmver", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_rdm_net, + { "Address High", + "artnet.rdm.net", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + /* ArtRdmSub */ + { &hf_artnet_rdm_sub, + { "ArtRdmSub packet", + "artnet.rdm_sub", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtRdmSub packet", HFILL }}, + + { &hf_artnet_rdm_sub_uid, + { "UID", + "artnet.rdm_sub.uid", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_rdm_sub_command_class, + { "Command Class", + "artnet.rdm_sub.command_class", + FT_UINT8, BASE_HEX, VALS(artnet_cc_vals), 0x0, + NULL, HFILL }}, + + { &hf_artnet_rdm_sub_pid, + { "Parameter ID", + "artnet.rdm_sub.param_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_rdm_sub_sub_device, + { "Sub Device", + "artnet.rdm_sub.sub_device", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_rdm_sub_sub_count, + { "Sub Count", + "artnet.rdm_sub.sub_count", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_rdm_sub_data, + { "Data", + "artnet.rdm_sub.data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, /* ArtIpProg */ { &hf_artnet_ip_prog, @@ -2608,11 +3380,255 @@ proto_register_artnet(void) { NULL, HFILL }}, /* ArtPollServerReply */ - { &hf_artnet_poll_server_reply, - { "ArtPollServerReply packet", - "artnet.poll_server_reply", - FT_NONE, BASE_NONE, NULL, 0, - "Art-Net ArtPollServerReply packet", HFILL }} + { &hf_artnet_poll_fp_reply, + { "ArtPollFpReply packet", + "artnet.poll_fp_reply", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtPollFpReply packet", HFILL }}, + + /* ArtDiagData */ + { &hf_artnet_diag_data, + { "ArtDiagData packet", + "artnet.diag_data", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtDiagData packet", HFILL }}, + + { &hf_artnet_diag_data_priority, + { "Priotity", + "artnet.diag_data.priority", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_diag_data_index, + { "Index", + "artnet.diag_data.index", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_diag_data_length, + { "Length", + "artnet.diag_data.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_diag_data_data, + { "Data", + "artnet.diag_data.data", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + /* ArtCommand */ + { &hf_artnet_command, + { "ArtCommand packet", + "artnet.command", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtCommand packet", HFILL }}, + + /* ArtMedia */ + { &hf_artnet_media, + { "ArtMedia packet", + "artnet.media", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtMedia packet", HFILL }}, + + /* ArtMediaPatch */ + { &hf_artnet_media_patch, + { "ArtMediaPatch packet", + "artnet.media_patch", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtMediaPatch packet", HFILL }}, + + /* ArtMediaControl */ + { &hf_artnet_media_control, + { "ArtMediaControl packet", + "artnet.media_control", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtMediaControl packet", HFILL }}, + + /* ArtMediaControlReply */ + { &hf_artnet_media_control_reply, + { "ArtMediaControlReply packet", + "artnet.media_control_reply", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtMediaControlReply packet", HFILL }}, + + /* ArtTimeCode */ + { &hf_artnet_time_code, + { "ArtTimeCode packet", + "artnet.time_code", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtTimeCode packet", HFILL }}, + + /* ArtTimeSync */ + { &hf_artnet_time_sync, + { "ArtTimeSync packet", + "artnet.time_sync", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtTimeSync packet", HFILL }}, + + /* ArtTrigger */ + { &hf_artnet_trigger, + { "ArtTrigger packet", + "artnet.trigger", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtTrigger packet", HFILL }}, + + /* ArtDirectory */ + { &hf_artnet_directory, + { "ArtDirectory packet", + "artnet.directory", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtDirectory packet", HFILL }}, + + { &hf_artnet_directory_filler, + { "Filler", + "artnet.directory.filler", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_directory_cmd, + { "Command", + "artnet.directory.cmd", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_directory_file, + { "File Nr.", + "artnet.directory.file", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + /* ArtDirectoryReply */ + { &hf_artnet_directory_reply, + { "ArtDirectoryReply packet", + "artnet.directory_reply", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtDirectoryReply packet", HFILL }}, + + { &hf_artnet_directory_reply_filler, + { "Filler", + "artnet.directory_reply.filler", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_directory_reply_flags, + { "Flags", + "artnet.directory_reply.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_directory_reply_file, + { "File", + "artnet.directory_reply.file", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_directory_reply_name, + { "Name", + "artnet.directory_reply.name", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_directory_reply_desc, + { "Description", + "artnet.directory_reply.desc", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_directory_reply_length, + { "Lenght", + "artnet.directory_reply.length", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_directory_reply_data, + { "Data", + "artnet.directory_reply.data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + /* ArtMacMaster */ + { &hf_artnet_mac_master, + { "ArtMacMaster packet", + "artnet.mac_master", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtMacMaster packet", HFILL }}, + + /* ArtMacSlave */ + { &hf_artnet_mac_slave, + { "ArtMacSlave packet", + "artnet.mac_slave", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtMacSlave packet", HFILL }}, + + /* ArtFileTnMaster */ + { &hf_artnet_file_tn_master, + { "ArtFileTnMaster packet", + "artnet.file_tn_master", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtFileTnMaster packet", HFILL }}, + + { &hf_artnet_file_tn_master_filler, + { "Filler", + "artnet.file_tn_master.filler", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_file_tn_master_type, + { "Type", + "artnet.file_tn_master.type", + FT_UINT8, BASE_HEX, VALS(artnet_file_type_vals), 0x0, + NULL, HFILL }}, + + { &hf_artnet_file_tn_master_block_id, + { "Block ID", + "artnet.file_tn_master.block_id", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_file_tn_master_length, + { "Length", + "artnet.file_tn_master.length", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_file_tn_master_name, + { "Name", + "artnet.file_tn_master.name", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_file_tn_master_checksum, + { "Checksum", + "artnet.file_tn_master.checksum", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_file_tn_master_spare, + { "Spare", + "artnet.file_tn_master.spare", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_artnet_file_tn_master_data, + { "Data", + "artnet.file_tn_master.data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + /* ArtFileFnMaster */ + { &hf_artnet_file_fn_master, + { "ArtFileFnMaster packet", + "artnet.file_fn_master", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtFileFnMaster packet", HFILL }}, + + /* ArtFileFnReply */ + { &hf_artnet_file_fn_reply, + { "ArtFileFnReply packet", + "artnet.file_fn_reply", + FT_NONE, BASE_NONE, NULL, 0, + "Art-Net ArtFileFnReply packet", HFILL }} }; @@ -2620,80 +3636,47 @@ proto_register_artnet(void) { &ett_artnet, }; - module_t *artnet_module; - - static enum_val_t disp_chan_val_types[] = { - { "pro", "Percent", 0 }, - { "hex", "Hexadecimal", 1 }, - { "dec", "Decimal", 2 }, - { NULL, NULL, 0 } - }; - - static enum_val_t disp_chan_nr_types[] = { - { "hex", "Hexadecimal", 0 }, - { "dec", "Decimal", 1 }, - { NULL, NULL, 0 } - }; - - static enum_val_t col_count[] = { - { "6", "6", 6 }, - { "10", "10", 10 }, - { "12", "12", 12 }, - { "16", "16", 16 }, - { "24", "24", 24 }, - { NULL, NULL, 0 } - }; - proto_artnet = proto_register_protocol("Art-Net", "ARTNET","artnet"); proto_register_field_array(proto_artnet,hf,array_length(hf)); proto_register_subtree_array(ett,array_length(ett)); - - artnet_module = prefs_register_protocol(proto_artnet, - proto_reg_handoff_artnet); - prefs_register_uint_preference(artnet_module, "udp_port", - "UDP Port", - "The UDP port on which " - "Art-Net " - "packets will be sent", - 10,&global_udp_port_artnet); - - prefs_register_enum_preference(artnet_module, "dmx_disp_chan_val_type", - "DMX Display channel value type", - "The way DMX values are displayed", - &global_disp_chan_val_type, - disp_chan_val_types, ENC_BIG_ENDIAN); - - prefs_register_enum_preference(artnet_module, "dmx_disp_chan_nr_type", - "DMX Display channel nr. type", - "The way DMX channel numbers are displayed", - &global_disp_chan_nr_type, - disp_chan_nr_types, ENC_BIG_ENDIAN); - - prefs_register_enum_preference(artnet_module, "dmx_disp_col_count", - "DMX Display Column Count", - "The number of columns for the DMX display", - &global_disp_col_count, - col_count, ENC_BIG_ENDIAN); } +/* Heuristic dissector */ +static gboolean +dissect_artnet_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + static const char artnet_packet_id[] = "Art-Net\0"; + + /* check if we atleast have the 8 byte header */ + if (tvb_length(tvb) < sizeof(artnet_packet_id)) + return FALSE; + + /* Check the 8 byte header */ + if (tvb_memeql(tvb, 0, artnet_packet_id, sizeof(artnet_packet_id) - 1) != 0) + return FALSE; + + /* if the header matches, dissect it */ + dissect_artnet(tvb, pinfo, tree); + + return TRUE; +} + + /* The registration hand-off routing */ void proto_reg_handoff_artnet(void) { static gboolean artnet_initialized = FALSE; static dissector_handle_t artnet_handle; - static guint udp_port_artnet; - + if(!artnet_initialized) { - artnet_handle = create_dissector_handle(dissect_artnet,proto_artnet); + artnet_handle = create_dissector_handle(dissect_artnet,proto_artnet); + dissector_add_handle("udp.port", artnet_handle); rdm_handle = find_dissector("rdm"); + dmx_chan_handle = find_dissector("dmx-chan"); artnet_initialized = TRUE; - } else { - dissector_delete_uint("udp.port",udp_port_artnet,artnet_handle); } - udp_port_artnet = global_udp_port_artnet; - - dissector_add_uint("udp.port",global_udp_port_artnet,artnet_handle); + heur_dissector_add("udp", dissect_artnet_heur, proto_artnet); } diff --git a/epan/dissectors/packet-dmx-chan.c b/epan/dissectors/packet-dmx-chan.c new file mode 100644 index 0000000000..fc6ee8f243 --- /dev/null +++ b/epan/dissectors/packet-dmx-chan.c @@ -0,0 +1,216 @@ +/* packet-dmx-chan.c + * DMX Channel Data packet disassembly. + * + * $Id: $ + * + * This dissector is written by + * + * Erwin Rol + * Copyright 2011 Erwin Rol + * + * Wireshark - Network traffic analyzer + * Gerald Combs + * Copyright 1999 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +/* + * This dissector is based on; + * American National Standard E1.11 - 2004 + * Entertainment Technology USITT DMX512-A + * Asynchronous Serial Digital Data Transmission Standard + * for Controlling Lighting Equipment and Accessories + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +void proto_reg_handoff_dmx_chan(void); + +static int proto_dmx_chan = -1; + +static int hf_dmx_chan_output_dmx_data = -1; +static int hf_dmx_chan_output_data_filter = -1; + +static int ett_dmx_chan = -1; + +/* + * Here are the global variables associated with the preferences for DMX + */ +static gint global_disp_chan_val_type = 0; +static gint global_disp_col_count = 16; +static gint global_disp_chan_nr_type = 0; + +static void +dissect_dmx_chan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "DMX Channels"); + col_clear(pinfo->cinfo, COL_INFO); + + if (tree != NULL) { + const char* chan_format[] = { + "%2u%% ", + "0x%02x ", + "%3u " + }; + const char* string_format[] = { + "0x%03x: %s", + "%3u: %s" + }; + static char string[255]; + proto_item *item; + guint16 length,r,c,row_count; + guint8 v; + char* ptr; + unsigned offset = 0; + + proto_tree *ti = proto_tree_add_item(tree, proto_dmx_chan, tvb, + offset, -1, FALSE); + proto_tree *dmx_chan_tree = proto_item_add_subtree(ti, ett_dmx_chan); + + length = tvb_reported_length_remaining(tvb, offset); + + row_count = (length / global_disp_col_count) + ((length % global_disp_col_count) == 0 ? 0 : 1); + ptr = string; + /* XX: In theory the g_snprintf statements below could store '\0' bytes off the end of the */ + /* 'string' buffer'. This is so since g_snprint returns the number of characters which */ + /* "would have been written" (whether or not there was room) and since ptr is always */ + /* incremented by this amount. In practice the string buffer is large enough such that the */ + /* string buffer size is not exceeded even with the maximum number of columns which might */ + /* be displayed. */ + /* ToDo: consider recoding slightly ... */ + for (r = 0; r < row_count;r++) { + for (c = 0;(c < global_disp_col_count) && (((r * global_disp_col_count) + c) < length);c++) { + if ((c % (global_disp_col_count / 2)) == 0) { + ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), " "); + } + + v = tvb_get_guint8(tvb, (offset + (r * global_disp_col_count) + c)); + if (global_disp_chan_val_type == 0) { + v = (v * 100) / 255; + if (v == 100) { + ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), "FL "); + } else { + ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), + chan_format[global_disp_chan_val_type], v); + } + } else { + ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), + chan_format[global_disp_chan_val_type], v); + } + } + + proto_tree_add_none_format(dmx_chan_tree, hf_dmx_chan_output_dmx_data, tvb, + offset+(r * global_disp_col_count), c, + string_format[global_disp_chan_nr_type], + (r * global_disp_col_count) + 1, string); + ptr = string; + } + + /* Add the real type hidden */ + item = proto_tree_add_item(dmx_chan_tree, hf_dmx_chan_output_data_filter, tvb, + offset, length, ENC_NA ); + PROTO_ITEM_SET_HIDDEN(item); + offset += length; + } +} + +void +proto_register_dmx_chan(void) +{ + static hf_register_info hf[] = { + { &hf_dmx_chan_output_data_filter, + { "DMX data filter", + "dmx_chan.data_filter", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_chan_output_dmx_data, + { "DMX data", + "dmx_chan.dmx_data", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + }; + + static gint *ett[] = { + &ett_dmx_chan + }; + + module_t *dmx_chan_module; + + static enum_val_t disp_chan_val_types[] = { + { "pro", "Percent", 0 }, + { "hex", "Hexadecimal", 1 }, + { "dec", "Decimal", 2 }, + { NULL, NULL, 0 } + }; + + static enum_val_t disp_chan_nr_types[] = { + { "hex", "Hexadecimal", 0 }, + { "dec", "Decimal", 1 }, + { NULL, NULL, 0 } + }; + + static enum_val_t col_count[] = { + { "6", "6", 6 }, + { "10", "10", 10 }, + { "12", "12", 12 }, + { "16", "16", 16 }, + { "24", "24", 24 }, + { NULL, NULL, 0 } + }; + + proto_dmx_chan = proto_register_protocol("DMX Channels","DMX Channels", "dmx-chan"); + proto_register_field_array(proto_dmx_chan, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("dmx-chan", dissect_dmx_chan, proto_dmx_chan); + + dmx_chan_module = prefs_register_protocol(proto_dmx_chan, NULL); + + prefs_register_enum_preference(dmx_chan_module, "dmx_disp_chan_val_type", + "DMX Display channel value type", + "The way DMX values are displayed", + &global_disp_chan_val_type, + disp_chan_val_types, ENC_BIG_ENDIAN); + + prefs_register_enum_preference(dmx_chan_module, "dmx_disp_chan_nr_type", + "DMX Display channel nr. type", + "The way DMX channel numbers are displayed", + &global_disp_chan_nr_type, + disp_chan_nr_types, ENC_BIG_ENDIAN); + + prefs_register_enum_preference(dmx_chan_module, "dmx_disp_col_count", + "DMX Display Column Count", + "The number of columns for the DMX display", + &global_disp_col_count, + col_count, ENC_BIG_ENDIAN); +} + +void +proto_reg_handoff_dmx_chan(void) +{ +} diff --git a/epan/dissectors/packet-dmx-sip.c b/epan/dissectors/packet-dmx-sip.c new file mode 100644 index 0000000000..7620bd76a5 --- /dev/null +++ b/epan/dissectors/packet-dmx-sip.c @@ -0,0 +1,320 @@ +/* packet-dmx-sip.c + * DMX SIP packet disassembly. + * + * $Id: $ + * + * This dissector is written by + * + * Erwin Rol + * Copyright 2011 Erwin Rol + * + * Wireshark - Network traffic analyzer + * Gerald Combs + * Copyright 1999 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +/* + * This dissector is based on; + * American National Standard E1.11 - 2004 + * Entertainment Technology USITT DMX512-A + * Asynchronous Serial Digital Data Transmission Standard + * for Controlling Lighting Equipment and Accessories + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DMX_SC_SIP 0xCF + +void proto_reg_handoff_dmx_sip(void); + +static int proto_dmx_sip = -1; + +static int hf_dmx_sip_byte_count = -1; +static int hf_dmx_sip_control_bit_field = -1; +static int hf_dmx_sip_prev_packet_checksum = -1; +static int hf_dmx_sip_seq_nr = -1; +static int hf_dmx_sip_dmx_universe_nr = -1; +static int hf_dmx_sip_dmx_proc_level = -1; +static int hf_dmx_sip_dmx_software_version = -1; +static int hf_dmx_sip_dmx_packet_len = -1; +static int hf_dmx_sip_dmx_nr_packets = -1; +static int hf_dmx_sip_orig_dev_id = -1; +static int hf_dmx_sip_sec_dev_id = -1; +static int hf_dmx_sip_third_dev_id = -1; +static int hf_dmx_sip_fourth_dev_id = -1; +static int hf_dmx_sip_fifth_dev_id = -1; +static int hf_dmx_sip_reserved = -1; +static int hf_dmx_sip_checksum = -1; +static int hf_dmx_sip_checksum_good = -1; +static int hf_dmx_sip_checksum_bad = -1; +static int hf_dmx_sip_trailer = -1; + +static int ett_dmx_sip = -1; + +static guint8 +dmx_sip_checksum(tvbuff_t *tvb, unsigned length) +{ + guint8 sum = DMX_SC_SIP; + unsigned i; + for (i = 0; i < length; i++) + sum += tvb_get_guint8(tvb, i); + return sum; +} + +static void +dissect_dmx_sip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "DMX SIP"); + col_clear(pinfo->cinfo, COL_INFO); + + if (tree != NULL) { + unsigned offset = 0; + unsigned byte_count; + unsigned checksum, checksum_shouldbe; + proto_item *item; + proto_tree *checksum_tree; + + proto_tree *ti = proto_tree_add_item(tree, proto_dmx_sip, tvb, + offset, -1, FALSE); + proto_tree *dmx_sip_tree = proto_item_add_subtree(ti, ett_dmx_sip); + + + byte_count = tvb_get_guint8(tvb, offset); + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_byte_count, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_control_bit_field, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_prev_packet_checksum, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_seq_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_universe_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_proc_level, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_software_version, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_packet_len, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_dmx_nr_packets, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_orig_dev_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_sec_dev_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_third_dev_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_fourth_dev_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_fifth_dev_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + if (offset < byte_count) { + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_reserved, tvb, + offset, byte_count - offset, ENC_BIG_ENDIAN); + offset += (byte_count - offset); + } + + dmx_sip_checksum(tvb, offset); + + checksum_shouldbe = dmx_sip_checksum(tvb, offset); + checksum = tvb_get_guint8(tvb, offset); + item = proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_checksum, tvb, + offset, 1, ENC_BIG_ENDIAN); + if (checksum == checksum_shouldbe) { + proto_item_append_text(item, " [correct]"); + + checksum_tree = proto_item_add_subtree(item, ett_dmx_sip); + item = proto_tree_add_boolean(checksum_tree, hf_dmx_sip_checksum_good, tvb, + offset, 1, TRUE); + PROTO_ITEM_SET_GENERATED(item); + item = proto_tree_add_boolean(checksum_tree, hf_dmx_sip_checksum_bad, tvb, + offset, 1, FALSE); + PROTO_ITEM_SET_GENERATED(item); + } else { + proto_item_append_text(item, " [incorrect, should be 0x%02x]", checksum_shouldbe); + + checksum_tree = proto_item_add_subtree(item, ett_dmx_sip); + item = proto_tree_add_boolean(checksum_tree, hf_dmx_sip_checksum_good, tvb, + offset, 1, FALSE); + PROTO_ITEM_SET_GENERATED(item); + item = proto_tree_add_boolean(checksum_tree, hf_dmx_sip_checksum_bad, tvb, + offset, 1, TRUE); + PROTO_ITEM_SET_GENERATED(item); + } + + offset += 1; + + if (offset < tvb_length(tvb)) + proto_tree_add_item(dmx_sip_tree, hf_dmx_sip_trailer, tvb, + offset, -1, ENC_NA); + } +} + +void +proto_register_dmx_sip(void) +{ + static hf_register_info hf[] = { + { &hf_dmx_sip_byte_count, + { "Byte Count", "dmx_sip.byte_count", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_control_bit_field, + { "Control Bit Field", "dmx_sip.control_bit_field", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_prev_packet_checksum, + { "Checksum of prev. packet", "dmx_sip.prev_packet_checksum", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_seq_nr, + { "SIP sequence nr.", "dmx_sip.seq_nr", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_dmx_universe_nr, + { "DMX512 universe nr.", "dmx_sip.dmx_universe_nr", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_dmx_proc_level, + { "DMX512 processing level", "dmx_sip.dmx_proc_level", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_dmx_software_version, + { "Software Version", "dmx_sip.dmx_software_version", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_dmx_packet_len, + { "Standard Packet Len", "dmx_sip.dmx_packet_len", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_dmx_nr_packets, + { "Number of Packets", "dmx_sip.dmx_nr_packets", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_orig_dev_id, + { "1st Device's ID", "dmx_sip.orig_dev_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_sec_dev_id, + { "2nd Device's ID", "dmx_sip.sec_dev_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_third_dev_id, + { "3rd Device's ID", "dmx_sip.third_dev_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_fourth_dev_id, + { "4th Device's ID", "dmx_sip.fourth_dev_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_fifth_dev_id, + { "5th Device's ID", "dmx_sip.fifth_dev_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_reserved, + { "Reserved", "dmx_sip.reserved", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_checksum, + { "Checksum", "dmx_sip.checksum", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_sip_checksum_good, + { "Good Checksum", "dmx_sip.checksum_good", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "True: checksum matches packet content; False: doesn't match content", HFILL }}, + + { &hf_dmx_sip_checksum_bad, + { "Bad Checksum", "dmx_sip.checksum_bad", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "True: checksum doesn't match packet content; False: matches content", HFILL }}, + + { &hf_dmx_sip_trailer, + { "Trailer", "dmx_sip.trailer", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + }; + + static gint *ett[] = { + &ett_dmx_sip + }; + + proto_dmx_sip = proto_register_protocol("DMX SIP", "DMX SIP", "dmx-sip"); + proto_register_field_array(proto_dmx_sip, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("dmx-sip", dissect_dmx_sip, proto_dmx_sip); +} + +void +proto_reg_handoff_dmx_sip(void) +{ +} diff --git a/epan/dissectors/packet-dmx-test.c b/epan/dissectors/packet-dmx-test.c new file mode 100644 index 0000000000..2161f281a9 --- /dev/null +++ b/epan/dissectors/packet-dmx-test.c @@ -0,0 +1,158 @@ +/* packet-dmx-test.c + * DMX Test packet disassembly. + * + * $Id: $ + * + * This dissector is written by + * + * Erwin Rol + * Copyright 2011 Erwin Rol + * + * Wireshark - Network traffic analyzer + * Gerald Combs + * Copyright 1999 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +/* + * This dissector is based on; + * American National Standard E1.11 - 2004 + * Entertainment Technology USITT DMX512-A + * Asynchronous Serial Digital Data Transmission Standard + * for Controlling Lighting Equipment and Accessories + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DMX_TEST_PACKET_SIZE 512 +#define DMX_TEST_VALUE 0x55 + +void proto_reg_handoff_dmx_test(void); + +static int proto_dmx_test = -1; + +static int hf_dmx_test_data = -1; +static int hf_dmx_test_data_good = -1; +static int hf_dmx_test_data_bad = -1; + +static int ett_dmx_test = -1; + +static void +dissect_dmx_test(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "DMX Test Frame"); + col_clear(pinfo->cinfo, COL_INFO); + + if (tree != NULL) { + unsigned offset = 0; + unsigned size, i, test_data_is_ok; + proto_tree* test_data_tree; + proto_item *item; + + proto_tree *ti = proto_tree_add_item(tree, proto_dmx_test, tvb, + offset, -1, FALSE); + proto_tree *dmx_test_tree = proto_item_add_subtree(ti, ett_dmx_test); + + size = tvb_reported_length_remaining(tvb, offset); + + item = proto_tree_add_item(dmx_test_tree, hf_dmx_test_data, tvb, + offset, size, ENC_BIG_ENDIAN); + offset += size; + + if (size == DMX_TEST_PACKET_SIZE) { + test_data_is_ok = TRUE; + for (i = 0; i < DMX_TEST_PACKET_SIZE; i++) { + if (tvb_get_guint8(tvb, i) != DMX_TEST_VALUE) { + test_data_is_ok = FALSE; + break; + } + } + } else { + test_data_is_ok = FALSE; + } + + if (test_data_is_ok) { + proto_item_append_text(ti, ", Data correct"); + proto_item_append_text(item, " [correct]"); + + test_data_tree = proto_item_add_subtree(item, ett_dmx_test); + item = proto_tree_add_boolean(test_data_tree, hf_dmx_test_data_good, tvb, + offset, size, TRUE); + PROTO_ITEM_SET_GENERATED(item); + item = proto_tree_add_boolean(test_data_tree, hf_dmx_test_data_bad, tvb, + offset, size, FALSE); + PROTO_ITEM_SET_GENERATED(item); + } else { + proto_item_append_text(ti, ", Data incorrect"); + proto_item_append_text(item, " [incorrect]"); + + test_data_tree = proto_item_add_subtree(item, ett_dmx_test); + item = proto_tree_add_boolean(test_data_tree, hf_dmx_test_data_good, tvb, + offset, size, FALSE); + PROTO_ITEM_SET_GENERATED(item); + item = proto_tree_add_boolean(test_data_tree, hf_dmx_test_data_bad, tvb, + offset, size, TRUE); + PROTO_ITEM_SET_GENERATED(item); + } + } +} + +void +proto_register_dmx_test(void) +{ + static hf_register_info hf[] = { + { &hf_dmx_test_data, + { "Test Data", "dmx_test.data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_dmx_test_data_good, + { "Data Good", "dmx_test.data_good", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "True: test data is correct; False: test data is incorrect", HFILL }}, + + { &hf_dmx_test_data_bad, + { "Data Bad", "dmx_test.data_bad", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "True: test data is incorrect; False: test data is correct", HFILL }}, + }; + + static gint *ett[] = { + &ett_dmx_test + }; + + proto_dmx_test = proto_register_protocol("DMX Test Frame", "DMX Test Frame", "dmx-test"); + proto_register_field_array(proto_dmx_test, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("dmx-test", dissect_dmx_test, proto_dmx_test); +} + +void +proto_reg_handoff_dmx_test(void) +{ +} diff --git a/epan/dissectors/packet-dmx-text.c b/epan/dissectors/packet-dmx-text.c new file mode 100644 index 0000000000..61d179465a --- /dev/null +++ b/epan/dissectors/packet-dmx-text.c @@ -0,0 +1,126 @@ +/* packet-dmx-text.c + * DMX Text packet disassembly. + * + * $Id: $ + * + * This dissector is written by + * + * Erwin Rol + * Copyright 2011 Erwin Rol + * + * Wireshark - Network traffic analyzer + * Gerald Combs + * Copyright 1999 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +/* + * This dissector is based on; + * American National Standard E1.11 - 2004 + * Entertainment Technology USITT DMX512-A + * Asynchronous Serial Digital Data Transmission Standard + * for Controlling Lighting Equipment and Accessories + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +void proto_reg_handoff_dmx_text(void); + +static int proto_dmx_text = -1; + +static int hf_dmx_text_page_nr = -1; +static int hf_dmx_text_line_len = -1; +static int hf_dmx_text_string = -1; + +static int ett_dmx_text = -1; + +static void +dissect_dmx_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "DMX Text"); + col_clear(pinfo->cinfo, COL_INFO); + + if (tree != NULL) { + unsigned offset = 0; + unsigned size; + + proto_tree *ti = proto_tree_add_item(tree, proto_dmx_text, tvb, + offset, -1, FALSE); + proto_tree *dmx_text_tree = proto_item_add_subtree(ti, ett_dmx_text); + + proto_tree_add_item(dmx_text_tree, hf_dmx_text_page_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(dmx_text_tree, hf_dmx_text_line_len, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + size = tvb_reported_length_remaining(tvb, offset); + + proto_tree_add_item(dmx_text_tree, hf_dmx_text_string, tvb, + offset, size, ENC_BIG_ENDIAN); + offset += size; + } +} + +void +proto_register_dmx_text(void) +{ + static hf_register_info hf[] = { + { &hf_dmx_text_page_nr, + { "Page Number", + "dmx_text.page_nr", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_dmx_text_line_len, + { "Line Length", + "dmx_text.line_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_dmx_text_string, + { "Text String", + "dmx_text.string", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + }; + + static gint *ett[] = { + &ett_dmx_text + }; + + proto_dmx_text = proto_register_protocol("DMX Text Frame", "DMX Text Frame", "dmx-text"); + proto_register_field_array(proto_dmx_text, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("dmx-text", dissect_dmx_text, proto_dmx_text); +} + +void +proto_reg_handoff_dmx_text(void) +{ +} diff --git a/epan/dissectors/packet-dmx.c b/epan/dissectors/packet-dmx.c new file mode 100644 index 0000000000..f3e67cdbb6 --- /dev/null +++ b/epan/dissectors/packet-dmx.c @@ -0,0 +1,169 @@ +/* packet-dmx.c + * DMX packet disassembly. + * + * $Id: $ + * + * This dissector is written by + * + * Erwin Rol + * Copyright 2012 Erwin Rol + * + * Wireshark - Network traffic analyzer + * Gerald Combs + * Copyright 1999 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + +/* + * This dissector is based on; + * American National Standard E1.11 - 2004 + * Entertainment Technology USITT DMX512-A + * Asynchronous Serial Digital Data Transmission Standard + * for Controlling Lighting Equipment and Accessories + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DMX_SC_DMX 0x00 +#define DMX_SC_TEXT 0x17 +#define DMX_SC_TEST 0x55 +#define DMX_SC_RDM 0xCC +#define DMX_SC_SIP 0xCF + +static const value_string dmx_sc_vals[] = { + { DMX_SC_DMX, "DMX" }, + { DMX_SC_TEXT, "Text" }, + { DMX_SC_TEST, "Test" }, + { DMX_SC_RDM, "RDM" }, + { DMX_SC_SIP, "SIP" }, + { 0, NULL }, +}; + +void proto_reg_handoff_dmx(void); + +static int proto_dmx = -1; + +static int hf_dmx_start_code = -1; +static int hf_dmx_frame_data = -1; + +static int ett_dmx = -1; + +static dissector_handle_t rdm_handle; +static dissector_handle_t dmx_chan_handle; +static dissector_handle_t dmx_test_handle; +static dissector_handle_t dmx_text_handle; +static dissector_handle_t dmx_sip_handle; + + +static void +dissect_dmx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + tvbuff_t *next_tvb = NULL; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "DMX"); + col_clear(pinfo->cinfo, COL_INFO); + + if (tree != NULL) { + unsigned offset = 0; + guint8 start_code; + + start_code = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tree, hf_dmx_start_code, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + switch (start_code) { + case DMX_SC_DMX: + next_tvb = tvb_new_subset_remaining(tvb, offset); + call_dissector(dmx_chan_handle, next_tvb, pinfo, tree); + break; + case DMX_SC_TEXT: + next_tvb = tvb_new_subset_remaining(tvb, offset); + call_dissector(dmx_text_handle, next_tvb, pinfo, tree); + break; + case DMX_SC_TEST: + next_tvb = tvb_new_subset_remaining(tvb, offset); + call_dissector(dmx_test_handle, next_tvb, pinfo, tree); + break; + case DMX_SC_RDM: + next_tvb = tvb_new_subset_remaining(tvb, offset); + call_dissector(rdm_handle, next_tvb, pinfo, tree); + break; + case DMX_SC_SIP: + next_tvb = tvb_new_subset_remaining(tvb, offset); + call_dissector(dmx_sip_handle, next_tvb, pinfo, tree); + break; + default: + if (offset < tvb_length(tvb)) + proto_tree_add_item(tree, hf_dmx_frame_data, tvb, + offset, -1, ENC_NA); + break; + } + } +} + +void +proto_register_dmx(void) +{ + static hf_register_info hf[] = { + { &hf_dmx_start_code, + { "Start Code", "dmx.start_code", + FT_UINT8, BASE_HEX, VALS(dmx_sc_vals), 0x0, + NULL, HFILL }}, + { &hf_dmx_frame_data, + { "Frame Data", "dmx.frame_data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + }; + + static gint *ett[] = { + &ett_dmx + }; + + proto_dmx = proto_register_protocol("DMX", "DMX", "dmx"); + proto_register_field_array(proto_dmx, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_dmx(void) +{ + static gboolean dmx_initialized = FALSE; + static dissector_handle_t dmx_handle; + + if (!dmx_initialized) { + dmx_handle = create_dissector_handle(dissect_dmx, proto_dmx); + rdm_handle = find_dissector("rdm"); + dmx_test_handle = find_dissector("dmx-chan"); + dmx_test_handle = find_dissector("dmx-test"); + dmx_text_handle = find_dissector("dmx-text"); + dmx_sip_handle = find_dissector("dmx-sip"); + dmx_initialized = TRUE; + } +} diff --git a/epan/dissectors/packet-rdm.c b/epan/dissectors/packet-rdm.c index 6d698d2da5..d6e7404135 100644 --- a/epan/dissectors/packet-rdm.c +++ b/epan/dissectors/packet-rdm.c @@ -4,13 +4,13 @@ * $Id$ * * This dissector is written by + * + * Erwin Rol + * Copyright 2003, 2011, 2012 Erwin Rol * * Shaun Jackman * Copyright 2006 Pathway Connectivity * - * Erwin Rol - * Copyright 2003 Erwin Rol - * * Wireshark - Network traffic analyzer * Gerald Combs * Copyright 1999 Gerald Combs @@ -49,37 +49,1995 @@ #include #include +#define RDM_SC_RDM 0xCC +#define RDM_SC_SUB_MESSAGE 0x01 + +#define RDM_CC_DISCOVERY_COMMAND 0x10 +#define RDM_CC_DISCOVERY_COMMAND_RESPONSE 0x11 +#define RDM_CC_GET_COMMAND 0x20 +#define RDM_CC_GET_COMMAND_RESPONSE 0x21 +#define RDM_CC_SET_COMMAND 0x30 +#define RDM_CC_SET_COMMAND_RESPONSE 0x31 + +static const value_string rdm_cc_vals[] = { + { RDM_CC_DISCOVERY_COMMAND, "Discovery Command" }, + { RDM_CC_DISCOVERY_COMMAND_RESPONSE, "Discovery Command Response" }, + { RDM_CC_GET_COMMAND, "Get Command" }, + { RDM_CC_GET_COMMAND_RESPONSE, "Get Command Response" }, + { RDM_CC_SET_COMMAND, "Set Command" }, + { RDM_CC_SET_COMMAND_RESPONSE, "Set Command Response" }, + { 0, NULL }, +}; + +#define RDM_RESPONSE_TYPE_ACK 0x00 +#define RDM_RESPONSE_TYPE_ACK_TIMER 0x01 +#define RDM_RESPONSE_TYPE_NACK_REASON 0x02 +#define RDM_RESPONSE_TYPE_ACK_OVERFLOW 0x03 + +static const value_string rdm_rt_vals[] = { + { RDM_RESPONSE_TYPE_ACK, "Ack" }, + { RDM_RESPONSE_TYPE_ACK_TIMER, "Ack Timer" }, + { RDM_RESPONSE_TYPE_NACK_REASON, "Nack Reason" }, + { RDM_RESPONSE_TYPE_ACK_OVERFLOW, "Ack Overflow" }, + { 0, NULL }, +}; + +#define RDM_PARAM_ID_DISC_UNIQUE_BRANCH 0x0001 +#define RDM_PARAM_ID_DISC_MUTE 0x0002 +#define RDM_PARAM_ID_DISC_UN_MUTE 0x0003 +#define RDM_PARAM_ID_PROXIED_DEVICES 0x0010 +#define RDM_PARAM_ID_PROXIED_DEVICE_COUNT 0x0011 +#define RDM_PARAM_ID_COMMS_STATUS 0x0015 +#define RDM_PARAM_ID_QUEUED_MESSAGE 0x0020 +#define RDM_PARAM_ID_STATUS_MESSAGES 0x0030 +#define RDM_PARAM_ID_STATUS_ID_DESCRIPTION 0x0031 +#define RDM_PARAM_ID_CLEAR_STATUS_ID 0x0032 +#define RDM_PARAM_ID_SUB_DEVICE_STATUS_REPORT_THRESHOLD 0x0033 +#define RDM_PARAM_ID_SUPPORTED_PARAMETERS 0x0050 +#define RDM_PARAM_ID_PARAMETER_DESCRIPTION 0x0051 +#define RDM_PARAM_ID_DEVICE_INFO 0x0060 +#define RDM_PARAM_ID_PRODUCT_DETAIL_ID_LIST 0x0070 +#define RDM_PARAM_ID_DEVICE_MODEL_DESCRIPTION 0x0080 +#define RDM_PARAM_ID_MANUFACTURER_LABEL 0x0081 +#define RDM_PARAM_ID_DEVICE_LABEL 0x0082 +#define RDM_PARAM_ID_FACTORY_DEFAULTS 0x0090 +#define RDM_PARAM_ID_LANGUAGE_CAPABILITIES 0x00A0 +#define RDM_PARAM_ID_LANGUAGE 0x00B0 +#define RDM_PARAM_ID_SOFTWARE_VERSION_LABEL 0x00C0 +#define RDM_PARAM_ID_BOOT_SOFTWARE_VERSION_ID 0x00C1 +#define RDM_PARAM_ID_BOOT_SOFTWARE_VERSION_LABEL 0x00C2 +#define RDM_PARAM_ID_DMX_PERSONALITY 0x00E0 +#define RDM_PARAM_ID_DMX_PERSONALITY_DESCRIPTION 0x00E1 +#define RDM_PARAM_ID_DMX_START_ADDRESS 0x00F0 +#define RDM_PARAM_ID_SLOT_INFO 0x0120 +#define RDM_PARAM_ID_SLOT_DESCRIPTION 0x0121 +#define RDM_PARAM_ID_DEFAULT_SLOT_VALUE 0x0122 +#define RDM_PARAM_ID_SENSOR_DEFINITION 0x0200 +#define RDM_PARAM_ID_SENSOR_VALUE 0x0201 +#define RDM_PARAM_ID_RECORD_SENSORS 0x0202 +#define RDM_PARAM_ID_DEVICE_HOURS 0x0400 +#define RDM_PARAM_ID_LAMP_HOURS 0x0401 +#define RDM_PARAM_ID_LAMP_STRIKES 0x0402 +#define RDM_PARAM_ID_LAMP_STATE 0x0403 +#define RDM_PARAM_ID_LAMP_ON_MODE 0x0404 +#define RDM_PARAM_ID_DEVICE_POWER_CYCLES 0x0405 +#define RDM_PARAM_ID_DISPLAY_INVERT 0x0500 +#define RDM_PARAM_ID_DISPLAY_LEVEL 0x0501 +#define RDM_PARAM_ID_PAN_INVERT 0x0600 +#define RDM_PARAM_ID_TILT_INVERT 0x0601 +#define RDM_PARAM_ID_PAN_TILT_SWAP 0x0602 +#define RDM_PARAM_ID_REAL_TIME_CLOCK 0x0603 +#define RDM_PARAM_ID_IDENTIFY_DEVICE 0x1000 +#define RDM_PARAM_ID_RESET_DEVICE 0x1001 +#define RDM_PARAM_ID_POWER_STATE 0x1010 +#define RDM_PARAM_ID_PERFORM_SELFTEST 0x1020 +#define RDM_PARAM_ID_SELF_TEST_DESCRIPTION 0x1021 +#define RDM_PARAM_ID_CAPTURE_PRESET 0x1030 +#define RDM_PARAM_ID_PRESET_PLAYBACK 0x1031 + +static const value_string rdm_param_id_vals[] = { + { RDM_PARAM_ID_DISC_UNIQUE_BRANCH, "DISC_UNIQUE_BRANCH" }, + { RDM_PARAM_ID_DISC_MUTE, "DISC_MUTE" }, + { RDM_PARAM_ID_DISC_UN_MUTE, "DISC_UN_MUTE" }, + { RDM_PARAM_ID_PROXIED_DEVICES, "PROXIED_DEVICES" }, + { RDM_PARAM_ID_PROXIED_DEVICE_COUNT, "PROXIED_DEVICE_COUNT" }, + { RDM_PARAM_ID_COMMS_STATUS, "COMMS_STATUS" }, + { RDM_PARAM_ID_QUEUED_MESSAGE, "QUEUED_MESSAGE" }, + { RDM_PARAM_ID_STATUS_MESSAGES, "STATUS_MESSAGES" }, + { RDM_PARAM_ID_STATUS_ID_DESCRIPTION, "STATUS_ID_DESCRIPTION" }, + { RDM_PARAM_ID_CLEAR_STATUS_ID, "CLEAR_STATUS_ID" }, + { RDM_PARAM_ID_SUB_DEVICE_STATUS_REPORT_THRESHOLD, "DEVICE_STATUS_REPORT_THRESHOLD" }, + { RDM_PARAM_ID_SUPPORTED_PARAMETERS, "SUPPORTED_PARAMETERS" }, + { RDM_PARAM_ID_PARAMETER_DESCRIPTION, "PARAMETER_DESCRIPTION" }, + { RDM_PARAM_ID_DEVICE_INFO, "DEVICE_INFO" }, + { RDM_PARAM_ID_PRODUCT_DETAIL_ID_LIST, "PRODUCT_DETAIL_ID_LIST" }, + { RDM_PARAM_ID_DEVICE_MODEL_DESCRIPTION, "DEVICE_MODEL_DESCRIPTION" }, + { RDM_PARAM_ID_MANUFACTURER_LABEL, "MANUFACTURER_LABEL" }, + { RDM_PARAM_ID_DEVICE_LABEL, "DEVICE_LABEL" }, + { RDM_PARAM_ID_FACTORY_DEFAULTS, "FACTORY_DEFAULTS" }, + { RDM_PARAM_ID_LANGUAGE_CAPABILITIES, "LANGUAGE_CAPABILITIES" }, + { RDM_PARAM_ID_LANGUAGE, "LANGUAGE" }, + { RDM_PARAM_ID_SOFTWARE_VERSION_LABEL, "SOFTWARE_VERSION_LABEL" }, + { RDM_PARAM_ID_BOOT_SOFTWARE_VERSION_ID, "BOOT_SOFTWARE_VERSION_ID" }, + { RDM_PARAM_ID_BOOT_SOFTWARE_VERSION_LABEL, "BOOT_SOFTWARE_VERSION_LABEL" }, + { RDM_PARAM_ID_DMX_PERSONALITY, "DMX_PERSONALITY" }, + { RDM_PARAM_ID_DMX_PERSONALITY_DESCRIPTION, "DMX_PERSONALITY_DESCRIPTION" }, + { RDM_PARAM_ID_DMX_START_ADDRESS, "DMX_START_ADDRESS" }, + { RDM_PARAM_ID_SLOT_INFO, "SLOT_INFO" }, + { RDM_PARAM_ID_SLOT_DESCRIPTION, "SLOT_DESCRIPTION" }, + { RDM_PARAM_ID_DEFAULT_SLOT_VALUE, "DEFAULT_SLOT_VALUE" }, + { RDM_PARAM_ID_SENSOR_DEFINITION, "SENSOR_DEFINITION" }, + { RDM_PARAM_ID_SENSOR_VALUE, "SENSOR_VALUE" }, + { RDM_PARAM_ID_RECORD_SENSORS, "RECORD_SENSORS" }, + { RDM_PARAM_ID_DEVICE_HOURS, "DEVICE_HOURS" }, + { RDM_PARAM_ID_LAMP_HOURS, "LAMP_HOURS" }, + { RDM_PARAM_ID_LAMP_STRIKES, "LAMP_STRIKES" }, + { RDM_PARAM_ID_LAMP_STATE, "LAMP_STATE" }, + { RDM_PARAM_ID_LAMP_ON_MODE, "LAMP_ON_MODE" }, + { RDM_PARAM_ID_DEVICE_POWER_CYCLES, "DEVICE_POWER_CYCLES" }, + { RDM_PARAM_ID_DISPLAY_INVERT, "DISPLAY_INVERT" }, + { RDM_PARAM_ID_DISPLAY_LEVEL, "DISPLAY_LEVEL" }, + { RDM_PARAM_ID_PAN_INVERT, "PAN_INVERT" }, + { RDM_PARAM_ID_TILT_INVERT, "TILT_INVERT" }, + { RDM_PARAM_ID_PAN_TILT_SWAP, "PAN_TILT_SWAP" }, + { RDM_PARAM_ID_REAL_TIME_CLOCK, "REAL_TIME_CLOCK" }, + { RDM_PARAM_ID_IDENTIFY_DEVICE, "IDENTIFY_DEVICE" }, + { RDM_PARAM_ID_RESET_DEVICE, "RESET_DEVICE" }, + { RDM_PARAM_ID_POWER_STATE, "POWER_STATE" }, + { RDM_PARAM_ID_PERFORM_SELFTEST, "PERFORM_SELFTEST" }, + { RDM_PARAM_ID_SELF_TEST_DESCRIPTION, "SELF_TEST_DESCRIPTION" }, + { RDM_PARAM_ID_CAPTURE_PRESET, "CAPTURE_PRESET" }, + { RDM_PARAM_ID_PRESET_PLAYBACK, "PRESET_PLAYBACK" }, + { 0, NULL }, +}; + + +#define RDM_STATUS_NONE 0x00 +#define RMD_STATUS_GET_LAST_MESSAGE 0x01 +#define RDM_STATUS_ADVISORY 0x02 +#define RDM_STATUS_WARNING 0x03 +#define RDM_STATUS_ERROR 0x04 + +static const value_string rdm_status_vals[] = { + { RDM_STATUS_NONE, "None" }, + { RMD_STATUS_GET_LAST_MESSAGE, "Get Last Message" }, + { RDM_STATUS_ADVISORY, "Advisory" }, + { RDM_STATUS_WARNING, "Warning" }, + { RDM_STATUS_ERROR, "Error" }, + { 0, NULL }, +}; + +#define RDM_PREFIX_NONE 0x00 +#define RDM_PREFIX_DECI 0x01 +#define RDM_PREFIX_CENTI 0x02 +#define RDM_PREFIX_MILLI 0x03 +#define RDM_PREFIX_MICRO 0x04 +#define RDM_PREFIX_NANO 0x05 +#define RDM_PREFIX_PICO 0x06 +#define RDM_PREFIX_FEMPTO 0x07 +#define RDM_PREFIX_ATTO 0x08 +#define RDM_PREFIX_ZEPTO 0x09 +#define RDM_PREFIX_YOCTO 0x0A +#define RDM_PREFIX_DECA 0x11 +#define RDM_PREFIX_HECTO 0x12 +#define RDM_PREFIX_KILO 0x13 +#define RDM_PREFIX_MEGA 0x14 +#define RDM_PREFIX_GIGA 0x15 +#define RDM_PREFIX_TERRA 0x16 +#define RDM_PREFIX_PETA 0x17 +#define RDM_PREFIX_EXA 0x18 +#define RDM_PREFIX_ZETTA 0x19 +#define RDM_PREFIX_YOTTA 0x1A + +static const value_string rdm_prefix_vals[] = { + { RDM_PREFIX_NONE, "NONE (x1)" }, + { RDM_PREFIX_DECI, "deci (x10^-1)" }, + { RDM_PREFIX_CENTI, "centi (x10^-2)" }, + { RDM_PREFIX_MILLI, "milli (x10^-3)" }, + { RDM_PREFIX_MICRO, "micro (x10^-6)" }, + { RDM_PREFIX_NANO, "nano (x10^-9)" }, + { RDM_PREFIX_PICO, "pico (x10^-12)" }, + { RDM_PREFIX_FEMPTO, "fempto (x10^-15)" }, + { RDM_PREFIX_ATTO, "atto (x10^-18)" }, + { RDM_PREFIX_ZEPTO, "zepto (x10^-21)" }, + { RDM_PREFIX_YOCTO, "yocto (x10^-24)" }, + { RDM_PREFIX_DECA, "deca (x10^1)" }, + { RDM_PREFIX_HECTO, "hecto (x10^2)" }, + { RDM_PREFIX_KILO, "kilo (x10^3)" }, + { RDM_PREFIX_MEGA, "mega (x10^6)" }, + { RDM_PREFIX_GIGA, "giga (x10^9)" }, + { RDM_PREFIX_TERRA, "terra (x10^12)" }, + { RDM_PREFIX_PETA, "peta (x10^15)" }, + { RDM_PREFIX_EXA, "exa (x10^18)" }, + { RDM_PREFIX_ZETTA, "zetta (x10^21)" }, + { RDM_PREFIX_YOTTA, "yotta (x10^24)" }, + { 0, NULL }, +}; + +#define RDM_UNITS_NONE 0x00 +#define RDM_UNITS_CENTIGRADE 0x01 +#define RDM_UNITS_VOLTS_DC 0x02 +#define RDM_UNITS_VOLTS_AC_PEAK 0x03 +#define RDM_UNITS_VOLTS_AC_RMS 0x04 +#define RDM_UNITS_AMPERE_DC 0x05 +#define RDM_UNITS_AMPERE_AC_PEAK 0x06 +#define RDM_UNITS_AMPERE_AC_RMS 0x07 +#define RDM_UNITS_HERTZ 0x08 +#define RDM_UNITS_OHM 0x09 +#define RDM_UNITS_WATT 0x0A +#define RDM_UNITS_KILOGRAM 0x0B +#define RDM_UNITS_METERS 0x0C +#define RDM_UNITS_METERS_SQUARED 0x0D +#define RDM_UNITS_METERS_CUBED 0x0E +#define RDM_UNITS_KILOGRAMMES_PER_METER_CUBED 0x0F +#define RDM_UNITS_METERS_PER_SECOND 0x10 +#define RDM_UNITS_METERS_PER_SECOND_SQUARED 0x11 +#define RDM_UNITS_NEWTON 0x12 +#define RDM_UNITS_JOULE 0x13 +#define RDM_UNITS_PASCAL 0x14 +#define RDM_UNITS_SECOND 0x15 +#define RDM_UNITS_DEGREE 0x16 +#define RDM_UNITS_STERADIAN 0x17 +#define RDM_UNITS_CANDELA 0x18 +#define RDM_UNITS_LUMEN 0x19 +#define RDM_UNITS_LUX 0x1A +#define RDM_UNITS_IRE 0x1B +#define RDM_UNITS_BYTE 0x1C + +static const value_string rdm_unit_vals[] = { + { RDM_UNITS_NONE, "NONE" }, + { RDM_UNITS_CENTIGRADE, "Centigrade" }, + { RDM_UNITS_VOLTS_DC, "Volts DC" }, + { RDM_UNITS_VOLTS_AC_PEAK, "Volts AC Peak" }, + { RDM_UNITS_VOLTS_AC_RMS, "Volts AC RMS" }, + { RDM_UNITS_AMPERE_DC, "Ampere DC" }, + { RDM_UNITS_AMPERE_AC_PEAK, "Ampere AC Peak" }, + { RDM_UNITS_AMPERE_AC_RMS, "Ampere AC RMS" }, + { RDM_UNITS_HERTZ, "Hertz" }, + { RDM_UNITS_OHM, "Ohm" }, + { RDM_UNITS_WATT, "Watt" }, + { RDM_UNITS_KILOGRAM, "Kilogram" }, + { RDM_UNITS_METERS, "Meters" }, + { RDM_UNITS_METERS_SQUARED, "Meters Squared" }, + { RDM_UNITS_METERS_CUBED, "Meters Cubed" }, + { RDM_UNITS_KILOGRAMMES_PER_METER_CUBED, "Kilogrammes per Meter Cubed" }, + { RDM_UNITS_METERS_PER_SECOND, "Meters per Second" }, + { RDM_UNITS_METERS_PER_SECOND_SQUARED, "Meters per Second Squared" }, + { RDM_UNITS_NEWTON, "Newton" }, + { RDM_UNITS_JOULE, "Joule" }, + { RDM_UNITS_PASCAL, "Pascal" }, + { RDM_UNITS_SECOND, "Second" }, + { RDM_UNITS_DEGREE, "Degree" }, + { RDM_UNITS_STERADIAN, "Steradian" }, + { RDM_UNITS_CANDELA, "Candela" }, + { RDM_UNITS_LUMEN, "Lumen" }, + { RDM_UNITS_LUX, "Lux" }, + { RDM_UNITS_IRE, "Ire" }, + { RDM_UNITS_BYTE, "Byte" }, + { 0, NULL }, +}; + +#define RDM_SENS_TEMPERATURE 0x00 +#define RDM_SENS_VOLTAGE 0x01 +#define RDM_SENS_CURRENT 0x02 +#define RDM_SENS_FREQUENCY 0x03 +#define RDM_SENS_RESISTANCE 0x04 +#define RDM_SENS_POWER 0x05 +#define RDM_SENS_MASS 0x06 +#define RDM_SENS_LENGTH 0x07 +#define RDM_SENS_AREA 0x08 +#define RDM_SENS_VOLUME 0x09 +#define RDM_SENS_DENSITY 0x0A +#define RDM_SENS_VELOCITY 0x0B +#define RDM_SENS_ACCELERATION 0x0C +#define RDM_SENS_FORCE 0x0D +#define RDM_SENS_ENERGY 0x0E +#define RDM_SENS_PRESSURE 0x0F +#define RDM_SENS_TIME 0x10 +#define RDM_SENS_ANGLE 0x11 +#define RDM_SENS_POSITION_X 0x12 +#define RDM_SENS_POSITION_Y 0x13 +#define RDM_SENS_POSITION_Z 0x14 +#define RDM_SENS_ANGULAR_VELOCITY 0x15 +#define RDM_SENS_LUMINOUS_INTENSITY 0x16 +#define RDM_SENS_LUMINOUS_FLUX 0x17 +#define RDM_SENS_ILLUMINANCE 0x18 +#define RDM_SENS_CHROMINANCE_RED 0x19 +#define RDM_SENS_CHROMINANCE_GREEN 0x1A +#define RDM_SENS_CHROMINANCE_BLUE 0x1B +#define RDM_SENS_CONTACTS 0x1C +#define RDM_SENS_MEMORY 0x1D +#define RDM_SENS_ITEMS 0x1E +#define RDM_SENS_HUMIDITY 0x1F +#define RDM_SENS_COUNTER_16BIT 0x20 +#define RDM_SENS_OTHER 0x7F + +static const value_string rdm_sensor_type_vals[] = { + { RDM_SENS_TEMPERATURE, "Temperature" }, + { RDM_SENS_VOLTAGE, "Voltage" }, + { RDM_SENS_CURRENT, "Current" }, + { RDM_SENS_FREQUENCY, "Frequency" }, + { RDM_SENS_RESISTANCE, "Resistance" }, + { RDM_SENS_POWER, "Power" }, + { RDM_SENS_MASS, "Mass" }, + { RDM_SENS_LENGTH, "Lenght" }, + { RDM_SENS_AREA, "Area" }, + { RDM_SENS_VOLUME, "Volume" }, + { RDM_SENS_DENSITY, "Density" }, + { RDM_SENS_VELOCITY, "Velocity" }, + { RDM_SENS_ACCELERATION, "Acceleration" }, + { RDM_SENS_FORCE, "Force" }, + { RDM_SENS_ENERGY, "Energy" }, + { RDM_SENS_PRESSURE, "Pressure" }, + { RDM_SENS_TIME, "Time" }, + { RDM_SENS_ANGLE, "Angle" }, + { RDM_SENS_POSITION_X, "Position X" }, + { RDM_SENS_POSITION_Y, "Position Y" }, + { RDM_SENS_POSITION_Z, "Position Z" }, + { RDM_SENS_ANGULAR_VELOCITY, "Angular Velocity" }, + { RDM_SENS_LUMINOUS_INTENSITY, "Luminous Intensity" }, + { RDM_SENS_LUMINOUS_FLUX, "Luminous Flux" }, + { RDM_SENS_ILLUMINANCE, "Illuminance" }, + { RDM_SENS_CHROMINANCE_RED, "Chrominance Red" }, + { RDM_SENS_CHROMINANCE_GREEN, "Chrominance Green" }, + { RDM_SENS_CHROMINANCE_BLUE, "Chrominance Blue" }, + { RDM_SENS_CONTACTS, "Contacts" }, + { RDM_SENS_MEMORY, "Memory" }, + { RDM_SENS_ITEMS, "Items" }, + { RDM_SENS_HUMIDITY, "Humidity" }, + { RDM_SENS_COUNTER_16BIT, "Counter 16bit" }, + { RDM_SENS_OTHER, "Other" }, + { 0, NULL} , +}; + +#define RDM_PRODUCT_CATEGORY_NOT_DECLARED 0x0000 +#define RDM_PRODUCT_CATEGORY_FIXTURE 0x0100 +#define RDM_PRODUCT_CATEGORY_FIXTURE_FIXED 0x0101 +#define RDM_PRODUCT_CATEGORY_FIXTURE_MOVING_YOKE 0x0102 +#define RDM_PRODUCT_CATEGORY_FIXTURE_MOVING_MIRROR 0x0103 +#define RDM_PRODUCT_CATEGORY_FIXTURE_OTHER 0x01FF +#define RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY 0x0200 +#define RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_COLOR 0x0201 +#define RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_YOKE 0x0202 +#define RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_MIRROR 0x0203 +#define RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_EFFECT 0x0204 +#define RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_BEAM 0x0205 +#define RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_OTHER 0x02FF +#define RDM_PRODUCT_CATEGORY_PROJECTOR 0x0300 +#define RDM_PRODUCT_CATEGORY_PROJECTOR_FIXED 0x0301 +#define RDM_PRODUCT_CATEGORY_PROJECTOR_MOVING_YOKE 0x0302 +#define RDM_PRODUCT_CATEGORY_PROJECTOR_MOVING_MIRROR 0x0303 +#define RDM_PRODUCT_CATEGORY_PROJECTOR_OTHER 0x03FF +#define RDM_PRODUCT_CATEGORY_ATMOSPHERIC 0x0400 +#define RDM_PRODUCT_CATEGORY_ATMOSPHERIC_EFFECT 0x0401 +#define RDM_PRODUCT_CATEGORY_ATMOSPHERIC_PYRO 0x0402 +#define RDM_PRODUCT_CATEGORY_ATMOSPHERIC_OTHER 0x04FF +#define RDM_PRODUCT_CATEGORY_DIMMER 0x0500 +#define RDM_PRODUCT_CATEGORY_DIMMER_AC_INCANDESCENT 0x0501 +#define RDM_PRODUCT_CATEGORY_DIMMER_AC_FLUORESCENT 0x0502 +#define RDM_PRODUCT_CATEGORY_DIMMER_AC_COLDCATHODE 0x0503 +#define RDM_PRODUCT_CATEGORY_DIMMER_AC_NONDIM 0x0504 +#define RDM_PRODUCT_CATEGORY_DIMMER_AC_ELV 0x0505 +#define RDM_PRODUCT_CATEGORY_DIMMER_AC_OTHER 0x0506 +#define RDM_PRODUCT_CATEGORY_DIMMER_DC_LEVEL 0x0507 +#define RDM_PRODUCT_CATEGORY_DIMMER_DC_PWM 0x0508 +#define RDM_PRODUCT_CATEGORY_DIMMER_CS_LED 0x0509 +#define RDM_PRODUCT_CATEGORY_DIMMER_OTHER 0x05FF +#define RDM_PRODUCT_CATEGORY_POWER 0x0600 +#define RDM_PRODUCT_CATEGORY_POWER_CONTROL 0x0601 +#define RDM_PRODUCT_CATEGORY_POWER_SOURCE 0x0602 +#define RDM_PRODUCT_CATEGORY_POWER_OTHER 0x06FF +#define RDM_PRODUCT_CATEGORY_SCENIC 0x0700 +#define RDM_PRODUCT_CATEGORY_SCENIC_DRIVE 0x0701 +#define RDM_PRODUCT_CATEGORY_SCENIC_OTHER 0x07FF +#define RDM_PRODUCT_CATEGORY_DATA 0x0800 +#define RDM_PRODUCT_CATEGORY_DATA_DISTRIBUTION 0x0801 +#define RDM_PRODUCT_CATEGORY_DATA_CONVERSION 0x0802 +#define RDM_PRODUCT_CATEGORY_DATA_OTHER 0x08FF +#define RDM_PRODUCT_CATEGORY_AV 0x0900 +#define RDM_PRODUCT_CATEGORY_AV_AUDIO 0x0901 +#define RDM_PRODUCT_CATEGORY_AV_VIDEO 0x0902 +#define RDM_PRODUCT_CATEGORY_AV_OTHER 0x09FF +#define RDM_PRODUCT_CATEGORY_MONITOR 0x0A00 +#define RDM_PRODUCT_CATEGORY_MONITOR_ACLINEPOWER 0x0A01 +#define RDM_PRODUCT_CATEGORY_MONITOR_DCPOWER 0x0A02 +#define RDM_PRODUCT_CATEGORY_MONITOR_ENVIRONMENTAL 0x0A03 +#define RDM_PRODUCT_CATEGORY_MONITOR_OTHER 0x0AFF +#define RDM_PRODUCT_CATEGORY_CONTROL 0x7000 +#define RDM_PRODUCT_CATEGORY_CONTROL_CONTROLLER 0x7001 +#define RDM_PRODUCT_CATEGORY_CONTROL_BACKUPDEVICE 0x7002 +#define RDM_PRODUCT_CATEGORY_CONTROL_OTHER 0x70FF +#define RDM_PRODUCT_CATEGORY_TEST 0x7100 +#define RDM_PRODUCT_CATEGORY_TEST_EQUIPMENT 0x7101 +#define RDM_PRODUCT_CATEGORY_TEST_EQUIPMENT_OTHER 0x71FF +#define RDM_PRODUCT_CATEGORY_OTHER 0x7FFF + +static const value_string rdm_product_cat_vals[] = { + { RDM_PRODUCT_CATEGORY_NOT_DECLARED, "Not Declared" }, + { RDM_PRODUCT_CATEGORY_FIXTURE, "Fixture" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_FIXED, "Fixture Fixed" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_MOVING_YOKE, "Fixture Moving Yoke" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_MOVING_MIRROR, "Fixture Moving Mirror" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_OTHER, "Fixture Other" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY, "Fixture Accessory" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_COLOR, "Fixture Accessory Color" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_YOKE, "Fixture Accessory Yoke" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_MIRROR,"Fixture Accessory Mirror" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_EFFECT,"Fixture Accessory Effect" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_BEAM, "Fixture Accessory Beam" }, + { RDM_PRODUCT_CATEGORY_FIXTURE_ACCESSORY_OTHER, "Fixture Accessory Other" }, + { RDM_PRODUCT_CATEGORY_PROJECTOR, "Projector" }, + { RDM_PRODUCT_CATEGORY_PROJECTOR_FIXED, "Projector Fixed" }, + { RDM_PRODUCT_CATEGORY_PROJECTOR_MOVING_YOKE, "Projector Moving Yoke" }, + { RDM_PRODUCT_CATEGORY_PROJECTOR_MOVING_MIRROR, "Projector Moving Mirror" }, + { RDM_PRODUCT_CATEGORY_PROJECTOR_OTHER, "Projector Other" }, + { RDM_PRODUCT_CATEGORY_ATMOSPHERIC, "Atmospheric" }, + { RDM_PRODUCT_CATEGORY_ATMOSPHERIC_EFFECT, "Atmospheric Effect" }, + { RDM_PRODUCT_CATEGORY_ATMOSPHERIC_PYRO, "Atmospheric Pyro" }, + { RDM_PRODUCT_CATEGORY_ATMOSPHERIC_OTHER, "Atmospheric Other" }, + { RDM_PRODUCT_CATEGORY_DIMMER, "Dimmer" }, + { RDM_PRODUCT_CATEGORY_DIMMER_AC_INCANDESCENT, "Dimmer AC Incandescent" }, + { RDM_PRODUCT_CATEGORY_DIMMER_AC_FLUORESCENT, "Dimmer AC Fluorescent" }, + { RDM_PRODUCT_CATEGORY_DIMMER_AC_COLDCATHODE, "Dimmer AC Coldcathode" }, + { RDM_PRODUCT_CATEGORY_DIMMER_AC_NONDIM, "Dimmer AC Nondim" }, + { RDM_PRODUCT_CATEGORY_DIMMER_AC_ELV, "Dimmer AC ELV" }, + { RDM_PRODUCT_CATEGORY_DIMMER_AC_OTHER, "Dimmer AC Other" }, + { RDM_PRODUCT_CATEGORY_DIMMER_DC_LEVEL, "Dimmer DC Level" }, + { RDM_PRODUCT_CATEGORY_DIMMER_DC_PWM, "Dimmer DC PWM" }, + { RDM_PRODUCT_CATEGORY_DIMMER_CS_LED, "Dimmer CS LED" }, + { RDM_PRODUCT_CATEGORY_DIMMER_OTHER, "Dimmer Other" }, + { RDM_PRODUCT_CATEGORY_POWER, "Power" }, + { RDM_PRODUCT_CATEGORY_POWER_CONTROL, "Power Control" }, + { RDM_PRODUCT_CATEGORY_POWER_SOURCE, "Power Source" }, + { RDM_PRODUCT_CATEGORY_POWER_OTHER, "Power Other" }, + { RDM_PRODUCT_CATEGORY_SCENIC, "Scenic" }, + { RDM_PRODUCT_CATEGORY_SCENIC_DRIVE, "Scenic Drive" }, + { RDM_PRODUCT_CATEGORY_SCENIC_OTHER, "Scenic Other" }, + { RDM_PRODUCT_CATEGORY_DATA, "Data" }, + { RDM_PRODUCT_CATEGORY_DATA_DISTRIBUTION, "Data Distribution" }, + { RDM_PRODUCT_CATEGORY_DATA_CONVERSION, "Data Conversion" }, + { RDM_PRODUCT_CATEGORY_DATA_OTHER, "Data Other" }, + { RDM_PRODUCT_CATEGORY_AV, "AV" }, + { RDM_PRODUCT_CATEGORY_AV_AUDIO, "AV Audio" }, + { RDM_PRODUCT_CATEGORY_AV_VIDEO, "AV Video" }, + { RDM_PRODUCT_CATEGORY_AV_OTHER, "AV Other" }, + { RDM_PRODUCT_CATEGORY_MONITOR, "Monitor" }, + { RDM_PRODUCT_CATEGORY_MONITOR_ACLINEPOWER, "Monitor AC Line Power" }, + { RDM_PRODUCT_CATEGORY_MONITOR_DCPOWER, "Monitor DC Power" }, + { RDM_PRODUCT_CATEGORY_MONITOR_ENVIRONMENTAL, "Monitor Environmental" }, + { RDM_PRODUCT_CATEGORY_MONITOR_OTHER, "Monitor Other" }, + { RDM_PRODUCT_CATEGORY_CONTROL, "Control" }, + { RDM_PRODUCT_CATEGORY_CONTROL_CONTROLLER, "Control Controller" }, + { RDM_PRODUCT_CATEGORY_CONTROL_BACKUPDEVICE, "Control Backup Device" }, + { RDM_PRODUCT_CATEGORY_CONTROL_OTHER, "Control Other" }, + { RDM_PRODUCT_CATEGORY_TEST, "Test" }, + { RDM_PRODUCT_CATEGORY_TEST_EQUIPMENT, "Test Equipment" }, + { RDM_PRODUCT_CATEGORY_TEST_EQUIPMENT_OTHER, "Test Equipment Other" }, + { RDM_PRODUCT_CATEGORY_OTHER, "Other" }, + { 0, NULL }, +}; + static int proto_rdm = -1; -static int hf_rdm_start_code = -1; static int hf_rdm_sub_start_code = -1; static int hf_rdm_message_length = -1; static int hf_rdm_dest_uid = -1; static int hf_rdm_src_uid = -1; static int hf_rdm_transaction_number = -1; +static int hf_rdm_port_id = -1; static int hf_rdm_response_type = -1; static int hf_rdm_message_count = -1; static int hf_rdm_sub_device = -1; +static int hf_rdm_mdb = -1; static int hf_rdm_command_class = -1; static int hf_rdm_parameter_id = -1; static int hf_rdm_parameter_data_length = -1; static int hf_rdm_parameter_data = -1; +static int hf_rdm_parameter_data_raw = -1; static int hf_rdm_intron = -1; static int hf_rdm_checksum = -1; +static int hf_rdm_checksum_good = -1; +static int hf_rdm_checksum_bad = -1; static int hf_rdm_trailer = -1; +static int hf_rdm_pd_device_label = -1; + +static int hf_rdm_pd_manu_label = -1; + +static int hf_rdm_pd_dmx_start_address = -1; + +static int hf_rdm_pd_queued_message_status = -1; + +static int hf_rdm_pd_sensor_nr = -1; +static int hf_rdm_pd_sensor_type = -1; +static int hf_rdm_pd_sensor_unit = -1; +static int hf_rdm_pd_sensor_prefix = -1; +static int hf_rdm_pd_sensor_value_pres = -1; +static int hf_rdm_pd_sensor_value_low = -1; +static int hf_rdm_pd_sensor_value_high = -1; +static int hf_rdm_pd_sensor_value_rec = -1; + +static int hf_rdm_pd_sensor_range_min_value = -1; +static int hf_rdm_pd_sensor_range_max_value = -1; +static int hf_rdm_pd_sensor_normal_min_value = -1; +static int hf_rdm_pd_sensor_normal_max_value = -1; +static int hf_rdm_pd_sensor_recorded_value_support = -1; +static int hf_rdm_pd_sensor_description = -1; + +static int hf_rdm_pd_device_hours = -1; +static int hf_rdm_pd_lamp_hours = -1; +static int hf_rdm_pd_lamp_strikes = -1; + + +static int hf_rdm_pd_proto_vers = -1; +static int hf_rdm_pd_device_model_id = -1; +static int hf_rdm_pd_product_cat = -1; +static int hf_rdm_pd_software_vers_id = -1; +static int hf_rdm_pd_dmx_footprint = -1; +static int hf_rdm_pd_dmx_pers_current = -1; +static int hf_rdm_pd_dmx_pers_total = -1; +static int hf_rdm_pd_sub_device_count = -1; +static int hf_rdm_pd_sensor_count = -1; + +static int hf_rdm_pd_device_model_description = -1; + +static int hf_rdm_pd_disc_unique_branch_lb_uid = -1; +static int hf_rdm_pd_disc_unique_branch_ub_uid = -1; +static int hf_rdm_pd_disc_mute_control_field = -1; +static int hf_rdm_pd_disc_mute_binding_uid = -1; +static int hf_rdm_pd_disc_unmute_control_field = -1; +static int hf_rdm_pd_disc_unmute_binding_uid = -1; +static int hf_rdm_pd_proxied_devices_uid = -1; +static int hf_rdm_pd_proxied_device_count = -1; +static int hf_rdm_pd_proxied_device_list_change = -1; +static int hf_rdm_pd_real_time_clock_year = -1; +static int hf_rdm_pd_real_time_clock_month = -1; +static int hf_rdm_pd_real_time_clock_day = -1; +static int hf_rdm_pd_real_time_clock_hour = -1; +static int hf_rdm_pd_real_time_clock_minute = -1; +static int hf_rdm_pd_real_time_clock_second = -1; +static int hf_rdm_pd_lamp_state = -1; +static int hf_rdm_pd_lamp_on_mode = -1; +static int hf_rdm_pd_device_power_cycles = -1; +static int hf_rdm_pd_display_invert = -1; +static int hf_rdm_pd_display_level = -1; +static int hf_rdm_pd_pan_invert = -1; +static int hf_rdm_pd_tilt_invert = -1; +static int hf_rdm_pd_tilt_swap = -1; +static int hf_rdm_pd_selftest_nr = -1; +static int hf_rdm_pd_selftest_state = -1; +static int hf_rdm_pd_selftest_description = -1; +static int hf_rdm_pd_language_code = -1; +static int hf_rdm_pd_identify_device = -1; +static int hf_rdm_pd_identify_device_state = -1; +static int hf_rdm_pd_reset_device = -1; +static int hf_rdm_pd_power_state = -1; +static int hf_rdm_pd_capture_preset_scene_nr = -1; +static int hf_rdm_pd_capture_preset_up_fade_time = -1; +static int hf_rdm_pd_capture_preset_down_fade_time = -1; +static int hf_rdm_pd_capture_preset_wait_time = -1; +static int hf_rdm_pd_preset_playback_mode = -1; +static int hf_rdm_pd_preset_playback_level = -1; +static int hf_rdm_pd_parameter_id = -1; +static int hf_rdm_pd_parameter_pdl_size = -1; +static int hf_rdm_pd_parameter_data_type = -1; +static int hf_rdm_pd_parameter_cmd_class = -1; +static int hf_rdm_pd_parameter_type = -1; +static int hf_rdm_pd_parameter_unit = -1; +static int hf_rdm_pd_parameter_prefix = -1; +static int hf_rdm_pd_parameter_min_value = -1; +static int hf_rdm_pd_parameter_max_value = -1; +static int hf_rdm_pd_parameter_default_value = -1; +static int hf_rdm_pd_parameter_description = -1; +static int hf_rdm_pd_software_version_label = -1; +static int hf_rdm_pd_boot_software_version_id = -1; +static int hf_rdm_pd_boot_software_version_label = -1; +static int hf_rdm_pd_comms_status_short_msg = -1; +static int hf_rdm_pd_comms_status_len_mismatch = -1; +static int hf_rdm_pd_comms_status_csum_fail = -1; +static int hf_rdm_pd_status_messages_type = -1; +static int hf_rdm_pd_status_messages_sub_device_id = -1; +static int hf_rdm_pd_status_messages_id = -1; +static int hf_rdm_pd_status_messages_data_value_1 = -1; +static int hf_rdm_pd_status_messages_data_value_2 = -1; +static int hf_rdm_pd_status_id = -1; +static int hf_rdm_pd_status_id_description = -1; +static int hf_rdm_pd_sub_device_status_report_threshold_status_type = -1; +static int hf_rdm_pd_product_detail_id_list = -1; +static int hf_rdm_pd_factory_defaults = -1; +static int hf_rdm_pd_dmx_pers_nr = -1; +static int hf_rdm_pd_dmx_pers_count = -1; +static int hf_rdm_pd_dmx_pers_description = -1; +static int hf_rdm_pd_dmx_pers_slots = -1; +static int hf_rdm_pd_dmx_pers_text = -1; +static int hf_rdm_pd_slot_offset = -1; +static int hf_rdm_pd_slot_type = -1; +static int hf_rdm_pd_slot_label_id = -1; +static int hf_rdm_pd_slot_nr = -1; +static int hf_rdm_pd_slot_description = -1; +static int hf_rdm_pd_slot_value = -1; +static int hf_rdm_pd_rec_value_support = -1; + + static int ett_rdm = -1; static guint16 rdm_checksum(tvbuff_t *tvb, unsigned length) { - guint16 sum = 0; + guint16 sum = RDM_SC_RDM; unsigned i; for (i = 0; i < length; i++) sum += tvb_get_guint8(tvb, i); return sum; } +static guint +dissect_rdm_pd_queued_message(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_queued_message_status, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_dmx_start_address(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_dmx_start_address, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_device_info(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_proto_vers, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_device_model_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_product_cat, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_software_vers_id, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset+=4; + + proto_tree_add_item(tree, hf_rdm_pd_dmx_footprint, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_current, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_total, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_rdm_pd_dmx_start_address, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_sub_device_count, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_count, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + break; + } + + return offset; +} + + +static guint +dissect_rdm_pd_device_model_description(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_device_model_description, tvb, + offset, len, ENC_BIG_ENDIAN); + offset+=len; + break; + } + + return offset; +} + + +static guint +dissect_rdm_pd_device_label(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_device_label, tvb, + offset, len, ENC_BIG_ENDIAN); + offset+=len; + break; + } + + return offset; +} + + +static guint +dissect_rdm_pd_device_hours(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_device_hours, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset+=4; + break; + } + + return offset; +} + + +static guint +dissect_rdm_pd_lamp_hours(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_lamp_hours, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset+=4; + break; + } + + return offset; +} + + +static guint +dissect_rdm_pd_lamp_strikes(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_lamp_strikes, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset+=4; + break; + } + + return offset; +} + + +static guint +dissect_rdm_pd_sensor_definition(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_sensor_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_sensor_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_unit, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_prefix, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_range_min_value, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_range_max_value, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_normal_min_value, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_normal_max_value, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_recorded_value_support, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_rdm_pd_sensor_description, tvb, + offset, len - 13, ENC_BIG_ENDIAN); + offset += (len - 13); + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_sensor_value(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + case RDM_CC_SET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_sensor_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + case RDM_CC_SET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_sensor_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + proto_tree_add_item(tree, hf_rdm_pd_sensor_value_pres, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + + if (len == 7 || len == 9) { + proto_tree_add_item(tree, hf_rdm_pd_sensor_value_low, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + proto_tree_add_item(tree, hf_rdm_pd_sensor_value_high, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + } + + if (len == 5 || len == 9) { + proto_tree_add_item(tree, hf_rdm_pd_sensor_value_rec, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset+=2; + } + + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_manufacturer_label(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_manu_label, tvb, + offset, len, ENC_BIG_ENDIAN); + offset+=len; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_disc_unique_branch(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_DISCOVERY_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_disc_unique_branch_lb_uid, tvb, + offset, 6, ENC_NA); + offset += 6; + + proto_tree_add_item(tree, hf_rdm_pd_disc_unique_branch_ub_uid, tvb, + offset, 6, ENC_NA); + offset += 6; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_disc_mute(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_DISCOVERY_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_disc_mute_control_field, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + if (len > 2) { + proto_tree_add_item(tree, hf_rdm_pd_disc_mute_binding_uid, tvb, + offset, 6, ENC_NA); + offset += 6; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_disc_un_mute(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_DISCOVERY_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_disc_unmute_control_field, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + if (len > 2) { + proto_tree_add_item(tree, hf_rdm_pd_disc_unmute_binding_uid, tvb, + offset, 6, ENC_NA); + offset += 6; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_proxied_devices(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + while (len >= 6) { + proto_tree_add_item(tree, hf_rdm_pd_proxied_devices_uid, tvb, + offset, 6, ENC_NA); + offset += 6; + len -= 6; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_proxied_device_count(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_proxied_device_count, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_proxied_device_list_change, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_comms_status(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_comms_status_short_msg, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_comms_status_len_mismatch, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_comms_status_csum_fail, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_status_messages(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_status_messages_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + while (len >= 9) { + proto_tree_add_item(tree, hf_rdm_pd_status_messages_sub_device_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + proto_tree_add_item(tree, hf_rdm_pd_status_messages_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + len -= 1; + proto_tree_add_item(tree, hf_rdm_pd_status_messages_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + proto_tree_add_item(tree, hf_rdm_pd_status_messages_data_value_1, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + proto_tree_add_item(tree, hf_rdm_pd_status_messages_data_value_2, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_status_id_description(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_status_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_status_id_description, tvb, + offset, len, ENC_BIG_ENDIAN); + offset += len; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_clear_status_id(tvbuff_t *tvb _U_, guint offset, proto_tree *tree _U_, guint8 cc _U_, guint8 len _U_) +{ + return offset; +} + +static guint +dissect_rdm_pd_sub_device_status_report_threshold(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_sub_device_status_report_threshold_status_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_supported_parameters(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + while (len >= 2) { + proto_tree_add_item(tree, hf_rdm_pd_parameter_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_parameter_description(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_parameter_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_parameter_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_parameter_pdl_size, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_parameter_data_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_parameter_cmd_class, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_parameter_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_parameter_unit, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_parameter_prefix, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_parameter_min_value, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_rdm_pd_parameter_max_value, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_rdm_pd_parameter_default_value, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_rdm_pd_parameter_description, tvb, + offset, len - 0x14, ENC_BIG_ENDIAN); + offset += (len - 0x14); + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_product_detail_id_list(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + while (len >= 2) { + proto_tree_add_item(tree, hf_rdm_pd_product_detail_id_list, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_factory_defaults(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_factory_defaults, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_language_capabilities(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + while (len >= 2) { + proto_tree_add_item(tree, hf_rdm_pd_language_code, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_language(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_language_code, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_software_version_label(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_software_version_label, tvb, + offset, len, ENC_BIG_ENDIAN); + offset += len; + + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_boot_software_version_id(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_boot_software_version_id, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset += 4; + + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_boot_software_version_label(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_boot_software_version_label, tvb, + offset, len, ENC_BIG_ENDIAN); + offset += len; + + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_dmx_personality(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_current, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_count, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_dmx_personality_description(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_description, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_description, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_slots, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_dmx_pers_text, tvb, + offset, (len - 3), ENC_BIG_ENDIAN); + offset += (len - 3); + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_slot_info(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + while (len >= 5) { + proto_tree_add_item(tree, hf_rdm_pd_slot_offset, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + proto_tree_add_item(tree, hf_rdm_pd_slot_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + len -= 1; + proto_tree_add_item(tree, hf_rdm_pd_slot_label_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_slot_description(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_slot_nr, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_slot_nr, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_slot_description, tvb, + offset, (len - 2), ENC_BIG_ENDIAN); + offset += (len - 2); + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_slot_value(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND_RESPONSE: + while (len >= 3) { + proto_tree_add_item(tree, hf_rdm_pd_slot_offset, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + len -= 2; + proto_tree_add_item(tree, hf_rdm_pd_slot_value, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + len -= 1; + } + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_record_sensors(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_sensor_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_sensor_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_sensor_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_sensor_unit, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_sensor_prefix, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_sensor_range_min_value, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_sensor_range_max_value, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_sensor_normal_min_value, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_sensor_normal_max_value, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_rec_value_support, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_sensor_description, tvb, + offset, (len - 13), ENC_BIG_ENDIAN); + offset += (len - 13); + + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_lamp_state(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_lamp_state, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_lamp_on_mode(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_lamp_on_mode, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_device_power_cycles(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_device_power_cycles, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset +=4; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_display_invert(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_display_invert, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_display_level(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_display_level, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_pan_invert(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_pan_invert, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_tilt_invert(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_tilt_invert, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_pan_tilt_swap(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_tilt_swap, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_real_time_clock(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_real_time_clock_year, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_real_time_clock_month, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_real_time_clock_day, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_real_time_clock_hour, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_real_time_clock_minute, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_real_time_clock_second, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_identify_device(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_identify_device, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_identify_device_state, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_reset_device(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_reset_device, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_power_state(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_power_state, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_perform_selftest(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_selftest_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_selftest_state, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_self_test_description(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len) +{ + switch(cc) { + case RDM_CC_GET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_selftest_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_selftest_nr, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_rdm_pd_selftest_description, tvb, + offset, (len - 1), ENC_BIG_ENDIAN); + offset += (len - 1); + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_capture_preset(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + proto_tree_add_item(tree, hf_rdm_pd_capture_preset_scene_nr, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_capture_preset_up_fade_time, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_capture_preset_down_fade_time, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_capture_preset_wait_time, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + break; + } + + return offset; +} + +static guint +dissect_rdm_pd_preset_playback(tvbuff_t *tvb, guint offset, proto_tree *tree, guint8 cc, guint8 len _U_) +{ + switch(cc) { + case RDM_CC_SET_COMMAND: + case RDM_CC_GET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_pd_preset_playback_mode, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(tree, hf_rdm_pd_preset_playback_level, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + break; + } + + return offset; +} + +static guint +dissect_rdm_mdb(tvbuff_t *tvb, guint offset, proto_tree *tree) +{ + guint8 cc; + guint16 param_id; + guint8 parameter_data_length; + proto_tree *hi,*si, *mdb_tree; + + cc = tvb_get_guint8(tvb, offset + 4); + + switch (cc) { + case RDM_CC_DISCOVERY_COMMAND: + case RDM_CC_GET_COMMAND: + case RDM_CC_SET_COMMAND: + proto_tree_add_item(tree, hf_rdm_port_id, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + break; + + case RDM_CC_DISCOVERY_COMMAND_RESPONSE: + case RDM_CC_GET_COMMAND_RESPONSE: + case RDM_CC_SET_COMMAND_RESPONSE: + proto_tree_add_item(tree, hf_rdm_response_type, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + break; + } + + proto_tree_add_item(tree, hf_rdm_message_count, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + proto_tree_add_item(tree, hf_rdm_sub_device, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + hi = proto_tree_add_item(tree, hf_rdm_mdb, tvb, + offset, -1, ENC_BIG_ENDIAN); + mdb_tree = proto_item_add_subtree(hi,ett_rdm); + + + proto_tree_add_item(mdb_tree, hf_rdm_command_class, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + + param_id = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(mdb_tree, hf_rdm_parameter_id, tvb, + offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + parameter_data_length = tvb_get_guint8(tvb, offset); + proto_tree_add_item(mdb_tree, hf_rdm_parameter_data_length, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset++; + proto_item_set_len( mdb_tree, parameter_data_length + 4); + + if (parameter_data_length > 0) { + hi = proto_tree_add_item(mdb_tree, hf_rdm_parameter_data, tvb, + offset, parameter_data_length, ENC_BIG_ENDIAN); + si = proto_item_add_subtree(hi,ett_rdm); + + switch(param_id) { + case RDM_PARAM_ID_SENSOR_VALUE: + offset = dissect_rdm_pd_sensor_value(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_QUEUED_MESSAGE: + offset = dissect_rdm_pd_queued_message(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DMX_START_ADDRESS: + offset = dissect_rdm_pd_dmx_start_address(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DEVICE_INFO: + offset = dissect_rdm_pd_device_info(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DEVICE_MODEL_DESCRIPTION: + offset = dissect_rdm_pd_device_model_description(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DEVICE_LABEL: + offset = dissect_rdm_pd_device_label(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DEVICE_HOURS: + offset = dissect_rdm_pd_device_hours(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_LAMP_HOURS: + offset = dissect_rdm_pd_lamp_hours(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_LAMP_STRIKES: + offset = dissect_rdm_pd_lamp_strikes(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_SENSOR_DEFINITION: + offset = dissect_rdm_pd_sensor_definition(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_MANUFACTURER_LABEL: + offset = dissect_rdm_pd_manufacturer_label(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DISC_UNIQUE_BRANCH: + offset = dissect_rdm_pd_disc_unique_branch(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DISC_MUTE: + offset = dissect_rdm_pd_disc_mute(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DISC_UN_MUTE: + offset = dissect_rdm_pd_disc_un_mute(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_PROXIED_DEVICES: + offset = dissect_rdm_pd_proxied_devices(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_PROXIED_DEVICE_COUNT: + offset = dissect_rdm_pd_proxied_device_count(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_COMMS_STATUS: + offset = dissect_rdm_pd_comms_status(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_STATUS_MESSAGES: + offset = dissect_rdm_pd_status_messages(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_STATUS_ID_DESCRIPTION: + offset = dissect_rdm_pd_status_id_description(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_CLEAR_STATUS_ID: + offset = dissect_rdm_pd_clear_status_id(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_SUB_DEVICE_STATUS_REPORT_THRESHOLD: + offset = dissect_rdm_pd_sub_device_status_report_threshold(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_SUPPORTED_PARAMETERS: + offset = dissect_rdm_pd_supported_parameters(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_PARAMETER_DESCRIPTION: + offset = dissect_rdm_pd_parameter_description(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_PRODUCT_DETAIL_ID_LIST: + offset = dissect_rdm_pd_product_detail_id_list(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_FACTORY_DEFAULTS: + offset = dissect_rdm_pd_factory_defaults(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_LANGUAGE_CAPABILITIES: + offset = dissect_rdm_pd_language_capabilities(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_LANGUAGE: + offset = dissect_rdm_pd_language(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_SOFTWARE_VERSION_LABEL: + offset = dissect_rdm_pd_software_version_label(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_BOOT_SOFTWARE_VERSION_ID: + offset = dissect_rdm_pd_boot_software_version_id(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_BOOT_SOFTWARE_VERSION_LABEL: + offset = dissect_rdm_pd_boot_software_version_label(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DMX_PERSONALITY: + offset = dissect_rdm_pd_dmx_personality(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DMX_PERSONALITY_DESCRIPTION: + offset = dissect_rdm_pd_dmx_personality_description(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_SLOT_INFO: + offset = dissect_rdm_pd_slot_info(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_SLOT_DESCRIPTION: + offset = dissect_rdm_pd_slot_description(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DEFAULT_SLOT_VALUE: + offset = dissect_rdm_pd_slot_value(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_RECORD_SENSORS: + offset = dissect_rdm_pd_record_sensors(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_LAMP_STATE: + offset = dissect_rdm_pd_lamp_state(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_LAMP_ON_MODE: + offset = dissect_rdm_pd_lamp_on_mode(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DEVICE_POWER_CYCLES: + offset = dissect_rdm_pd_device_power_cycles(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DISPLAY_INVERT: + offset = dissect_rdm_pd_display_invert(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_DISPLAY_LEVEL: + offset = dissect_rdm_pd_display_level(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_PAN_INVERT: + offset = dissect_rdm_pd_pan_invert(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_TILT_INVERT: + offset = dissect_rdm_pd_tilt_invert(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_PAN_TILT_SWAP: + offset = dissect_rdm_pd_pan_tilt_swap(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_REAL_TIME_CLOCK: + offset = dissect_rdm_pd_real_time_clock(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_IDENTIFY_DEVICE: + offset = dissect_rdm_pd_identify_device(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_RESET_DEVICE: + offset = dissect_rdm_pd_reset_device(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_POWER_STATE: + offset = dissect_rdm_pd_power_state(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_PERFORM_SELFTEST: + offset = dissect_rdm_pd_perform_selftest(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_SELF_TEST_DESCRIPTION: + offset = dissect_rdm_pd_self_test_description(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_CAPTURE_PRESET: + offset = dissect_rdm_pd_capture_preset(tvb, offset, si, cc, parameter_data_length); + break; + + case RDM_PARAM_ID_PRESET_PLAYBACK: + offset = dissect_rdm_pd_preset_playback(tvb, offset, si, cc, parameter_data_length); + break; + + default: + proto_tree_add_item(si, hf_rdm_parameter_data_raw, tvb, + offset, parameter_data_length, ENC_NA); + offset += parameter_data_length; + break; + } + } + + return offset; +} + static void dissect_rdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -87,18 +2045,17 @@ dissect_rdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) col_clear(pinfo->cinfo, COL_INFO); if (tree != NULL) { - unsigned message_length, checksum, checksum_shouldbe, - parameter_data_length, offset = 0; + gint padding_size; + guint16 man_id; + guint32 dev_id; + unsigned message_length, checksum, checksum_shouldbe, offset = 0; proto_item *item; + proto_tree *checksum_tree; proto_tree *ti = proto_tree_add_item(tree, proto_rdm, tvb, offset, -1, ENC_NA); proto_tree *rdm_tree = proto_item_add_subtree(ti, ett_rdm); - proto_tree_add_item(rdm_tree, hf_rdm_start_code, tvb, - offset, 1, ENC_BIG_ENDIAN); - offset++; - proto_tree_add_item(rdm_tree, hf_rdm_sub_start_code, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; @@ -108,10 +2065,17 @@ dissect_rdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) offset, 1, ENC_BIG_ENDIAN); offset++; + man_id = tvb_get_ntohs(tvb, offset); + dev_id = tvb_get_ntohl(tvb, offset + 2); + proto_item_append_text(ti, ", Dst UID: %04x:%08x", man_id, dev_id); proto_tree_add_item(rdm_tree, hf_rdm_dest_uid, tvb, offset, 6, ENC_NA); offset += 6; + + man_id = tvb_get_ntohs(tvb, offset); + dev_id = tvb_get_ntohl(tvb, offset + 2); + proto_item_append_text(ti, ", Src UID: %04x:%08x", man_id, dev_id); proto_tree_add_item(rdm_tree, hf_rdm_src_uid, tvb, offset, 6, ENC_NA); offset += 6; @@ -120,41 +2084,13 @@ dissect_rdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) offset, 1, ENC_BIG_ENDIAN); offset++; - proto_tree_add_item(rdm_tree, hf_rdm_response_type, tvb, - offset, 1, ENC_BIG_ENDIAN); - offset++; + offset = dissect_rdm_mdb(tvb, offset, rdm_tree); - proto_tree_add_item(rdm_tree, hf_rdm_message_count, tvb, - offset, 1, ENC_BIG_ENDIAN); - offset++; - - proto_tree_add_item(rdm_tree, hf_rdm_sub_device, tvb, - offset, 2, ENC_BIG_ENDIAN); - offset += 2; - - proto_tree_add_item(rdm_tree, hf_rdm_command_class, tvb, - offset, 1, ENC_BIG_ENDIAN); - offset++; - - proto_tree_add_item(rdm_tree, hf_rdm_parameter_id, tvb, - offset, 2, ENC_BIG_ENDIAN); - offset += 2; - - parameter_data_length = tvb_get_guint8(tvb, offset); - proto_tree_add_item(rdm_tree, hf_rdm_parameter_data_length, tvb, - offset, 1, ENC_BIG_ENDIAN); - offset++; - - if (parameter_data_length > 0) { - proto_tree_add_item(rdm_tree, hf_rdm_parameter_data, tvb, - offset, parameter_data_length, ENC_NA); - offset += parameter_data_length; - } - - if (offset < message_length) { + padding_size = offset - (message_length - 1); + if (padding_size > 0) { proto_tree_add_item(rdm_tree, hf_rdm_intron, tvb, - offset, message_length - offset, ENC_NA); - offset = message_length; + offset, padding_size, ENC_NA); + offset += padding_size; } checksum_shouldbe = rdm_checksum(tvb, offset); @@ -162,10 +2098,27 @@ dissect_rdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) item = proto_tree_add_item(rdm_tree, hf_rdm_checksum, tvb, offset, 2, ENC_BIG_ENDIAN); if (checksum == checksum_shouldbe) { - proto_item_append_text(item, " [correct]"); + proto_item_append_text(item, " [correct]"); + + checksum_tree = proto_item_add_subtree(item, ett_rdm); + item = proto_tree_add_boolean(checksum_tree, hf_rdm_checksum_good, tvb, + offset, 2, TRUE); + PROTO_ITEM_SET_GENERATED(item); + item = proto_tree_add_boolean(checksum_tree, hf_rdm_checksum_bad, tvb, + offset, 2, FALSE); + PROTO_ITEM_SET_GENERATED(item); } else { - proto_item_append_text(item, " [incorrect, should be 0x%04x]", checksum_shouldbe); + proto_item_append_text(item, " [incorrect, should be 0x%04x]", checksum_shouldbe); + + checksum_tree = proto_item_add_subtree(item, ett_rdm); + item = proto_tree_add_boolean(checksum_tree, hf_rdm_checksum_good, tvb, + offset, 2, FALSE); + PROTO_ITEM_SET_GENERATED(item); + item = proto_tree_add_boolean(checksum_tree, hf_rdm_checksum_bad, tvb, + offset, 2, TRUE); + PROTO_ITEM_SET_GENERATED(item); } + offset += 2; if (offset < tvb_length(tvb)) @@ -178,11 +2131,6 @@ void proto_register_rdm(void) { static hf_register_info hf[] = { - { &hf_rdm_start_code, - { "Start code", "rdm.sc", - FT_UINT8, BASE_HEX, NULL, 0x0, - NULL, HFILL }}, - { &hf_rdm_sub_start_code, { "Sub-start code", "rdm.ssc", FT_UINT8, BASE_HEX, NULL, 0x0, @@ -208,9 +2156,14 @@ proto_register_rdm(void) FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_rdm_port_id, + { "Port ID", "rdm.port_id", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + { &hf_rdm_response_type, { "Response type", "rdm.rt", - FT_UINT8, BASE_HEX, NULL, 0x0, + FT_UINT8, BASE_HEX, VALS(rdm_rt_vals), 0x0, NULL, HFILL }}, { &hf_rdm_message_count, @@ -223,14 +2176,19 @@ proto_register_rdm(void) FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_rdm_mdb, + { "Message Data Block", "rdm.mdb", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_rdm_command_class, { "Command class", "rdm.cc", - FT_UINT8, BASE_HEX, NULL, 0x0, + FT_UINT8, BASE_HEX, VALS(rdm_cc_vals), 0x0, NULL, HFILL }}, { &hf_rdm_parameter_id, { "Parameter ID", "rdm.pid", - FT_UINT16, BASE_HEX, NULL, 0x0, + FT_UINT16, BASE_HEX, VALS(rdm_param_id_vals), 0x0, NULL, HFILL }}, { &hf_rdm_parameter_data_length, @@ -240,6 +2198,11 @@ proto_register_rdm(void) { &hf_rdm_parameter_data, { "Parameter data", "rdm.pd", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_parameter_data_raw, + { "Raw Data", "rdm.pd.raw", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, @@ -253,9 +2216,555 @@ proto_register_rdm(void) FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + { &hf_rdm_checksum_good, + { "Good Checksum", "rdm.checksum_good", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "True: checksum matches packet content; False: doesn't match content", HFILL }}, + + { &hf_rdm_checksum_bad, + { "Bad Checksum", "rdm.checksum_bad", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "True: checksum doesn't match packet content; False: matches content", HFILL }}, + { &hf_rdm_trailer, { "Trailer", "rdm.trailer", FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_queued_message_status, + { "Status", "rdm.pd.queued_message.status", + FT_UINT8, BASE_HEX, VALS(rdm_status_vals), 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_nr, + { "Sensor Nr.", "rdm.pd.sensor.nr", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_value_pres, + { "Sensor Present Value", "rdm.pd.sensor.value.present", + FT_INT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_value_low, + { "Sensor Lowest Value", "rdm.pd.sensor.value.lowest", + FT_INT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_value_high, + { "Sensor Highest Value", "rdm.pd.sensor.value.highest", + FT_INT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_value_rec, + { "Sensor Recorded Value", "rdm.pd.sensor.value.recorded", + FT_INT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_range_min_value, + { "Sensor Range Min. Value", "rdm.pd.sensor.range.min_value", + FT_INT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_range_max_value, + { "Sensor Range Max. Value", "rdm.pd.sensor.range.max_value", + FT_INT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_normal_min_value, + { "Sensor Normal Min. Value", "rdm.pd.sensor.normal.min_value", + FT_INT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_normal_max_value, + { "Sensor Normal Max. Value", "rdm.pd.sensor.normal.max_value", + FT_INT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_recorded_value_support, + { "Sensor Recorded Value Support", "rdm.pd.sensor.recorded_value_support", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_type, + { "Sensor Type", "rdm.pd.sensor_type", + FT_UINT8, BASE_HEX, VALS(rdm_sensor_type_vals), 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_unit, + { "Sensor Unit", "rdm.pd.sensor_unit", + FT_UINT8, BASE_HEX, VALS(rdm_unit_vals), 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_prefix, + { "Sensor Prefix", "rdm.pd.sensor_prefix", + FT_UINT8, BASE_HEX, VALS(rdm_prefix_vals), 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_description, + { "Sensor Description", "rdm.pd.sensor.description", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_manu_label, + { "Manufacturur Label", "rdm.pd.manu_label", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + + { &hf_rdm_pd_device_label, + { "Device Label", "rdm.pd.device_label", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_start_address, + { "DMX Start Address", "rdm.pd.dmx_start_address", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_device_hours, + { "Device Hours", "rdm.pd.device_hours", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_lamp_hours, + { "Lamp Hours", "rdm.pd.lamp_hours", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_lamp_strikes, + { "Lamp Strikes", "rdm.pd.lamp_strikes", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_proto_vers, + { "RDM Protocol Version", "rdm.pd.proto_vers", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_device_model_id, + { "Device Model ID", "rdm.pd.device_model_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_product_cat, + { "Product Category", "rdm.pd.product_cat", + FT_UINT16, BASE_HEX, VALS(rdm_product_cat_vals), 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_software_vers_id, + { "Software Version ID", "rdm.pd.software_version_id", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_footprint, + { "DMX Footprint", "rdm.pd.dmx_footprint", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_pers_current, + { "Current DMX Personallity", "rdm.pd.dmx_pers_current", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_pers_total, + { "Total nr. DMX Personallities", "rdm.pd.dmx_pers_total", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sub_device_count, + { "Sub-Device Count", "rdm.pd.sub_device_count", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sensor_count, + { "Sensor Count", "rdm.pd.sensor_count", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_device_model_description, + { "Device Model Description", "rdm.pd.device_model_description", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_disc_unique_branch_lb_uid, + { "Lower Bound UID", "rdm.pd.disc_unique_branch.lb_uid", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_disc_unique_branch_ub_uid, + { "Upper Bound UID", "rdm.pd.disc_unique_branch.ub_uid", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_disc_mute_control_field, + { "Control Field", "rdm.pd.disc_mute.control_field", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_disc_mute_binding_uid, + { "Binding UID", "rdm.pd.disc_mute.binding_uid", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_disc_unmute_control_field, + { "Control Field", "rdm.pd.disc_unmute.control_field", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_disc_unmute_binding_uid, + { "Binding UID", "rdm.pd.disc_unmute.binding_uid", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_proxied_devices_uid, + { "UID", "rdm.pd.proxied_devices.uid", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_proxied_device_count, + { "Device Count", "rdm.pd.device_count", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_proxied_device_list_change, + { "List Change", "rdm.pd.list_change", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_real_time_clock_year, + { "Year", "rdm.pd.real_time_clock.year", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_real_time_clock_month, + { "Month", "rdm.pd.real_time_clock.month", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_real_time_clock_day, + { "Day", "rdm.pd.real_time_clock.day", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_real_time_clock_hour, + { "Hour", "rdm.pd.real_time_clock.hour", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_real_time_clock_minute, + { "Minute", "rdm.pd.real_time_clock.minute", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_real_time_clock_second, + { "Second", "rdm.pd.real_time_clock.second", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_lamp_state, + { "Lamp State", "rdm.pd.lamp_state", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_lamp_on_mode, + { "Lamp On Mode", "rdm.pd.lamp_on_mode", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_device_power_cycles, + { "Device Power Cycles", "rdm.pd.device_power_cycles", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_display_invert, + { "Display Invert", "rdm.pd.display_invert", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_display_level, + { "Display Level", "rdm.pd.display_level", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_pan_invert, + { "Pan Invert", "rdm.pd.pan_invert", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_tilt_invert, + { "Tilt Invert", "rdm.pd.tilt_invert", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_tilt_swap, + { "Tilt Swap", "rdm.pd.tilt_swap", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_selftest_nr, + { "Selftest Nr.", "rdm.pd.selftest.nr", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_selftest_state, + { "Selftest State", "rdm.pd.selftest.state", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_selftest_description, + { "Selftest Description", "rdm.pd.selftest.description", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_language_code, + { "Language Code", "rdm.pd.language_code", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_identify_device, + { "Identify Device", "rdm.pd.identify_device", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_identify_device_state, + { "Identify Device State", "rdm.pd.identify_device.state", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_reset_device, + { "Reset Device", "rdm.pd.reset_device", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_power_state, + { "Power State", "rdm.pd.power_state", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_capture_preset_scene_nr, + { "Scene Nr.", "rdm.pd.capture_preset.scene_nr", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_capture_preset_up_fade_time, + { "Up Fade Time", "rdm.pd.capture_preset.up_fade_time", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_capture_preset_down_fade_time, + { "Down Fade Time", "rdm.pd.capture_preset.down_fade_time", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_capture_preset_wait_time, + { "Wait Time", "rdm.pd.capture_preset.wait_time", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_preset_playback_mode, + { "Mode", "rdm.pd.preset_playback.mode", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_preset_playback_level, + { "Level", "rdm.pd.preset_playback.level", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_id, + { "ID", "rdm.pd.parameter.id", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_pdl_size, + { "PDL Size", "rdm.pd.parameter.pdl_size", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_data_type, + { "Data Type", "rdm.pd.parameter.data_type", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_cmd_class, + { "Command Class", "rdm.pd.parameter.cmd_class", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_type, + { "Type", "rdm.pd.parameter.type", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_unit, + { "Unit", "rdm.pd.parameter.unit", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_prefix, + { "Prefix", "rdm.pd.parameter.prefix", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_min_value, + { "Min. Value", "rdm.pd.parameter.min_value", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_max_value, + { "Max. Value", "rdm.pd.parameter.max_value", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_default_value, + { "Delauft Value", "rdm.pd.parameter.default_value", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_parameter_description, + { "Description", "rdm.pd.parameter.description", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_software_version_label, + { "Version Label", "rdm.pd.software_version.label", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_boot_software_version_id, + { "Version ID", "rdm.pd.boot_software_version.id", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_boot_software_version_label, + { "Version Label", "rdm.pd.boot_software_version.label", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_comms_status_short_msg, + { "Short Msg", "rdm.pd.comms_status.short_msg", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_comms_status_len_mismatch, + { "Len Mismatch", "rdm.pd.comms_status.len_mismatch", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_comms_status_csum_fail, + { "Checksum Fail", "rdm.pd.comms_status.csum_fail", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_status_messages_type, + { "Type", "rdm.pd.status_messages.type", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_status_messages_sub_device_id, + { "Sub. Device ID", "rdm.pd.status_messages.sub_devices_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_status_messages_id, + { "ID", "rdm.pd.status_messages.id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_status_messages_data_value_1, + { "Data Value 1", "rdm.pd.status_messages.data_value_1", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_status_messages_data_value_2, + { "Data Value 2", "rdm.pd.status_messages.data_value_2", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_status_id, + { "ID", "rdm.pd.status_id", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_status_id_description, + { "Description", "rdm.pd.status_id.description", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_sub_device_status_report_threshold_status_type, + { "Status Type", "rdm.pd.sub_device_status_report_threshold.status_type", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_product_detail_id_list, + { "Sensor Count", "rdm.pd.product_detail_id_list", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_factory_defaults, + { "Factory Defaults", "rdm.pd.factory_defaults", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_pers_nr, + { "DMX Pers. Nr.", "rdm.pd.dmx_pers.nr", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_pers_count, + { "DMX Pers. Count", "rdm.pd.dmx_pers.count", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_pers_description, + { "DMX Pers. Description", "rdm.pd.dmx_pers.description", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_pers_slots, + { "DMX Pers. Slots", "rdm.pd.dmx_pers.slots", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_dmx_pers_text, + { "DMX Pers. Text", "rdm.pd.dmx_pers.text", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_slot_offset, + { "Slot Offset", "rdm.pd.slot_offset", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_slot_type, + { "Slot Type", "rdm.pd.slot_type", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_slot_label_id, + { "Slot Label ID", "rdm.pd.slot_label_id", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_slot_nr, + { "Slot Nr.", "rdm.pd.slot_nr", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_slot_description, + { "Slot Description", "rdm.pd.slot_description", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_slot_value, + { "Slot Value", "rdm.pd.slot_value", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_rdm_pd_rec_value_support, + { "Rec. Value Support", "rdm.pd.rec_value_support", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }} };