diff options
Diffstat (limited to 'epan/dissectors/packet-adwin.c')
-rw-r--r-- | epan/dissectors/packet-adwin.c | 1435 |
1 files changed, 1435 insertions, 0 deletions
diff --git a/epan/dissectors/packet-adwin.c b/epan/dissectors/packet-adwin.c new file mode 100644 index 00000000..17104030 --- /dev/null +++ b/epan/dissectors/packet-adwin.c @@ -0,0 +1,1435 @@ +/* packet-adwin.c + * Routines for ADwin protocol dissection + * Copyright 2010, Thomas Boehne <TBoehne[AT]ADwin.de> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +/* includes needed for wireshark */ +#include <epan/packet.h> +#include <epan/prefs.h> +#include <epan/conversation.h> +void proto_reg_handoff_adwin(void); +void proto_register_adwin(void); +static dissector_handle_t adwin_handle; + +#define ADWIN_COMM_PORT 6543 /* Not IANA registered */ + +/* lengths of valid packet structures */ +#define UDPH1_OLD_LENGTH 52 +#define UDPH1_NEW_LENGTH 56 +#define UDPR1_LENGTH 32 +#define UDPH2_LENGTH 412 /* AFAIK: unused */ +#define UDPR2_LENGTH 1008 +#define UDPR3_LENGTH 1408 +#define UDPR4_LENGTH 1416 +#define GetDataSHPacket_LENGTH 1356 +#define GetDataSHRequest_LENGTH 64 + +/* operating systems */ +#define OS_WINDOWS 0x00 +#define OS_LINUX 0x10 +#define OS_JAVA 0x20 +#define OS_DOT_NET 0x40 +#define OS_GENERIC 0x80 +static const value_string osys_mapping[] = { + { OS_WINDOWS, "Windows"}, + { OS_LINUX, "Linux"}, + { OS_JAVA, "Java"}, + { OS_DOT_NET, ".Net"}, + { OS_GENERIC, "Generic TCP/IP Driver"}, + { 0, NULL }, +}; +static value_string_ext osys_mapping_ext = VALUE_STRING_EXT_INIT(osys_mapping); + +/* error codes */ +#define EC_OK 0 +#define EC_TIMEOUT_TO_LINK 1 +#define EC_TIMEOUT_FROM_LINK 2 +#define EC_TIMEOUT_FAST_TO_LINK 3 +#define EC_TIMEOUT_FAST_FROM_LINK 4 +#define EC_TIMEOUT 5 +#define EC_MEMORY_ERROR -100 +#define EC_RETRY_UNKNOWN -41 +#define EC_ALREADY_PROCESSED -40 +#define EC_WRONG_BINARY_FILE -35 +#define EC_INVALID_PACKET_ORDER -33 +#define EC_FIFO_NOT_ENOUGH_DATA -32 +#define EC_DATA_TOO_SMALL -31 +#define EC_WRONG_VERSION -30 +#define EC_WRONG_SIZE -26 +#define EC_PACKET_TOO_LARGE -25 +#define EC_PACKET_ERROR -20 +#define EC_FILE_ERROR -15 +#define EC_TRY_LATER -10 +#define EC_WRONG_PASSWORD -5 +#define EC_UDP_TIMEOUT -1 +static const value_string error_code_mapping[] = { + { EC_OK, "OK"}, + { EC_TIMEOUT_TO_LINK, "Timeout to link"}, + { EC_TIMEOUT_FROM_LINK, "Timeout from link"}, + { EC_TIMEOUT_FAST_TO_LINK, "Timeout fast to link"}, + { EC_TIMEOUT_FAST_FROM_LINK, "Timeout fast from link"}, + { EC_TIMEOUT, "Timeout"}, + { EC_MEMORY_ERROR, "Memory error"}, + { EC_RETRY_UNKNOWN, "Retry unknown"}, + { EC_ALREADY_PROCESSED, "Already processed"}, + { EC_WRONG_BINARY_FILE, "Binary/Processor mismatch"}, + { EC_INVALID_PACKET_ORDER, "Invalid Packet order"}, + { EC_FIFO_NOT_ENOUGH_DATA, "Fifo has not enough data"}, + { EC_DATA_TOO_SMALL, "Data too small"}, + { EC_WRONG_VERSION, "Wrong version"}, + { EC_WRONG_SIZE, "Wrong size"}, + { EC_PACKET_ERROR, "Packet error"}, + { EC_FILE_ERROR, "File error"}, + { EC_TRY_LATER, "Try later"}, + { EC_WRONG_PASSWORD, "Wrong password"}, + { EC_UDP_TIMEOUT, "UDP timeout"}, + { 0, NULL }, +}; +static value_string_ext error_code_mapping_ext = VALUE_STRING_EXT_INIT(error_code_mapping); + +static const value_string data_type_mapping[] = { + { 2, "short / int"}, + { 3, "int"}, + { 4, "long"}, + { 5, "float"}, + { 6, "double"}, + { 20, "variant"}, + { 0, NULL }, +}; +static value_string_ext data_type_mapping_ext = VALUE_STRING_EXT_INIT(data_type_mapping); + +#define I_3PLUS1 0 +#define I_LOAD_BIN_FILE 4 +#define I_GET_DATA 7 +#define I_SET_DATA 8 +#define I_CREATE_DATA 10 +#define I_GET_PAR_ALL 13 +#define I_GET_WORKLOAD 20 +#define I_GET_FIFO 24 +#define I_SET_FIFO 25 +#define I_BOOT 50 +#define I_GET_DATA_TYPE 100 +#define I_GET_DATA_SHIFTED_HANDSHAKE 107 +#define I_SET_DATA_LAST_STATUS 108 +#define I_GET_FIFO_RETRY 124 +#define I_SET_FIFO_RETRY 125 +#define I_GET_DATA_SMALL 207 +#define I_TEST_VERSION 255 +#define I_GET_ARM_VERSION 1000 +#define I_GET_MEMORY 1000000 + +static const value_string instruction_mapping[] = { + { I_3PLUS1, "3+1 instruction" }, + { I_LOAD_BIN_FILE, "Load binary file" }, + { I_GET_DATA, "Get data" }, + { I_SET_DATA, "Set data" }, + { I_CREATE_DATA, "Create data" }, + { I_GET_PAR_ALL, "Get all parameters" }, + { I_GET_WORKLOAD, "Get workload"}, + { I_GET_FIFO, "Get fifo" }, + { I_SET_FIFO, "Set fifo" }, + { I_BOOT, "Boot" }, + { I_GET_DATA_TYPE, "Get data type" }, + { I_GET_DATA_SHIFTED_HANDSHAKE, "Get data (shifted handshake)" }, + { I_SET_DATA_LAST_STATUS, "Get status of last set data" }, + { I_GET_FIFO_RETRY, "Get fifo - retry" }, + { I_SET_FIFO_RETRY, "Set fifo - retry" }, + { I_GET_DATA_SMALL, "Get data (small/fast)" }, + { I_TEST_VERSION, "Get/test version information" }, + { I_GET_ARM_VERSION, "Get ARM-Version" }, + { I_GET_MEMORY, "Get memory DSP" }, + { 0, NULL }, +}; +static value_string_ext instruction_mapping_ext = VALUE_STRING_EXT_INIT(instruction_mapping); + +/* 3+1 instructions */ +#define I_3P1_GET_PAR 1 +#define I_3P1_START 2 +#define I_3P1_STOP 3 +#define I_3P1_GET_MEMORY_INFO 5 +#define I_3P1_SET_PAR 6 +#define I_3P1_CLEAR_DATA 9 +#define I_3P1_GET_DATA_LENGTH 11 +#define I_3P1_GET_DETAILED_MEM_INFO 12 +#define I_3P1_CLEAR_PROCESS 14 +#define I_3P1_ADC 15 +#define I_3P1_DAC 16 +#define I_3P1_GET_DIGIN 17 +#define I_3P1_SET_DIGOUT 18 +#define I_3P1_GET_DIGOUT 19 +#define I_3P1_CLEAR_FIFO 21 +#define I_3P1_GET_FIFO_EMPTY 22 +#define I_3P1_GET_FIFO_COUNT 23 +static const value_string instruction_3plus1_mapping[] = { + { I_3P1_GET_PAR, "Get parameter"}, + { I_3P1_START, "Start process"}, + { I_3P1_STOP, "Stop process"}, + { I_3P1_GET_MEMORY_INFO, "Get memory info"}, + { I_3P1_SET_PAR, "Set parameter"}, + { I_3P1_CLEAR_DATA, "Clear data"}, + { I_3P1_GET_DATA_LENGTH, "Get data length"}, + { I_3P1_GET_DETAILED_MEM_INFO, "Get detailed memory info"}, + { I_3P1_CLEAR_PROCESS, "Clear process"}, + { I_3P1_ADC, "Get ADC value"}, + { I_3P1_DAC, "Set DAC value"}, + { I_3P1_GET_DIGIN, "Get digital in"}, + { I_3P1_SET_DIGOUT, "Set digital out"}, + { I_3P1_GET_DIGOUT, "Get digital out"}, + { I_3P1_CLEAR_FIFO, "Clear fifo"}, + { I_3P1_GET_FIFO_EMPTY, "Get fifo empty"}, + { I_3P1_GET_FIFO_COUNT, "Get fifo full/count"}, + { 0, NULL }, +}; +static value_string_ext instruction_3plus1_mapping_ext = VALUE_STRING_EXT_INIT(instruction_3plus1_mapping); + +static const value_string parameter_mapping[] = { + { 901 , "Status of Process No. 01"}, + { 902 , "Status of Process No. 02"}, + { 903 , "Status of Process No. 03"}, + { 904 , "Status of Process No. 04"}, + { 905 , "Status of Process No. 05"}, + { 906 , "Status of Process No. 06"}, + { 907 , "Status of Process No. 07"}, + { 908 , "Status of Process No. 08"}, + { 909 , "Status of Process No. 09"}, + { 910 , "Status of Process No. 10"}, + { 911 , "GlobalDelay for Process No. 01"}, + { 912 , "GlobalDelay for Process No. 02"}, + { 913 , "GlobalDelay for Process No. 03"}, + { 914 , "GlobalDelay for Process No. 04"}, + { 915 , "GlobalDelay for Process No. 05"}, + { 916 , "GlobalDelay for Process No. 06"}, + { 917 , "GlobalDelay for Process No. 07"}, + { 918 , "GlobalDelay for Process No. 08"}, + { 919 , "GlobalDelay for Process No. 09"}, + { 920 , "GlobalDelay for Process No. 10"}, + { 921 , "GlobalDelay for Process No. 11"}, + { 922 , "GlobalDelay for Process No. 12"}, + { 923 , "GlobalDelay for Process No. 13"}, + { 924 , "GlobalDelay for Process No. 14"}, + { 925 , "GlobalDelay for Process No. 15"}, + { 926 , "GlobalDelay for Process No. 16"}, + { 951 , "Debug Information of Process No. 01"}, + { 952 , "Debug Information of Process No. 02"}, + { 953 , "Debug Information of Process No. 03"}, + { 954 , "Debug Information of Process No. 04"}, + { 955 , "Debug Information of Process No. 05"}, + { 956 , "Debug Information of Process No. 06"}, + { 957 , "Debug Information of Process No. 07"}, + { 958 , "Debug Information of Process No. 08"}, + { 959 , "Debug Information of Process No. 09"}, + { 960 , "Debug Information of Process No. 10"}, + { 961 , "Debug Information of Process No. 11"}, + { 962 , "Debug Information of Process No. 12"}, + { 963 , "Debug Information of Process No. 13"}, + { 964 , "Debug Information of Process No. 14"}, + { 965 , "Debug Information of Process No. 15"}, + { 966 , "Debug Information of Process No. 16"}, + { 1001 , "Parameter No. 01"}, + { 1002 , "Parameter No. 02"}, + { 1003 , "Parameter No. 03"}, + { 1004 , "Parameter No. 04"}, + { 1005 , "Parameter No. 05"}, + { 1006 , "Parameter No. 06"}, + { 1007 , "Parameter No. 07"}, + { 1008 , "Parameter No. 08"}, + { 1009 , "Parameter No. 09"}, + { 1010 , "Parameter No. 10"}, + { 1011 , "Parameter No. 11"}, + { 1012 , "Parameter No. 12"}, + { 1013 , "Parameter No. 13"}, + { 1014 , "Parameter No. 14"}, + { 1015 , "Parameter No. 15"}, + { 1016 , "Parameter No. 16"}, + { 1017 , "Parameter No. 17"}, + { 1018 , "Parameter No. 18"}, + { 1019 , "Parameter No. 19"}, + { 1020 , "Parameter No. 20"}, + { 1021 , "Parameter No. 21"}, + { 1022 , "Parameter No. 22"}, + { 1023 , "Parameter No. 23"}, + { 1024 , "Parameter No. 24"}, + { 1025 , "Parameter No. 25"}, + { 1026 , "Parameter No. 26"}, + { 1027 , "Parameter No. 27"}, + { 1028 , "Parameter No. 28"}, + { 1029 , "Parameter No. 29"}, + { 1030 , "Parameter No. 30"}, + { 1031 , "Parameter No. 31"}, + { 1032 , "Parameter No. 32"}, + { 1033 , "Parameter No. 33"}, + { 1034 , "Parameter No. 34"}, + { 1035 , "Parameter No. 35"}, + { 1036 , "Parameter No. 36"}, + { 1037 , "Parameter No. 37"}, + { 1038 , "Parameter No. 38"}, + { 1039 , "Parameter No. 39"}, + { 1040 , "Parameter No. 40"}, + { 1041 , "Parameter No. 41"}, + { 1042 , "Parameter No. 42"}, + { 1043 , "Parameter No. 43"}, + { 1044 , "Parameter No. 44"}, + { 1045 , "Parameter No. 45"}, + { 1046 , "Parameter No. 46"}, + { 1047 , "Parameter No. 47"}, + { 1048 , "Parameter No. 48"}, + { 1049 , "Parameter No. 49"}, + { 1050 , "Parameter No. 50"}, + { 1051 , "Parameter No. 51"}, + { 1052 , "Parameter No. 52"}, + { 1053 , "Parameter No. 53"}, + { 1054 , "Parameter No. 54"}, + { 1055 , "Parameter No. 55"}, + { 1056 , "Parameter No. 56"}, + { 1057 , "Parameter No. 57"}, + { 1058 , "Parameter No. 58"}, + { 1059 , "Parameter No. 59"}, + { 1060 , "Parameter No. 60"}, + { 1061 , "Parameter No. 61"}, + { 1062 , "Parameter No. 62"}, + { 1063 , "Parameter No. 63"}, + { 1064 , "Parameter No. 64"}, + { 1065 , "Parameter No. 65"}, + { 1066 , "Parameter No. 66"}, + { 1067 , "Parameter No. 67"}, + { 1068 , "Parameter No. 68"}, + { 1069 , "Parameter No. 69"}, + { 1070 , "Parameter No. 70"}, + { 1071 , "Parameter No. 71"}, + { 1072 , "Parameter No. 72"}, + { 1073 , "Parameter No. 73"}, + { 1074 , "Parameter No. 74"}, + { 1075 , "Parameter No. 75"}, + { 1076 , "Parameter No. 76"}, + { 1077 , "Parameter No. 77"}, + { 1078 , "Parameter No. 78"}, + { 1079 , "Parameter No. 79"}, + { 1080 , "Parameter No. 80"}, + { 1101 , "Float-Parameter No. 01"}, + { 1102 , "Float-Parameter No. 02"}, + { 1103 , "Float-Parameter No. 03"}, + { 1104 , "Float-Parameter No. 04"}, + { 1105 , "Float-Parameter No. 05"}, + { 1106 , "Float-Parameter No. 06"}, + { 1107 , "Float-Parameter No. 07"}, + { 1108 , "Float-Parameter No. 08"}, + { 1109 , "Float-Parameter No. 09"}, + { 1110 , "Float-Parameter No. 10"}, + { 1111 , "Float-Parameter No. 11"}, + { 1112 , "Float-Parameter No. 12"}, + { 1113 , "Float-Parameter No. 13"}, + { 1114 , "Float-Parameter No. 14"}, + { 1115 , "Float-Parameter No. 15"}, + { 1116 , "Float-Parameter No. 16"}, + { 1117 , "Float-Parameter No. 17"}, + { 1118 , "Float-Parameter No. 18"}, + { 1119 , "Float-Parameter No. 19"}, + { 1120 , "Float-Parameter No. 20"}, + { 1121 , "Float-Parameter No. 21"}, + { 1122 , "Float-Parameter No. 22"}, + { 1123 , "Float-Parameter No. 23"}, + { 1124 , "Float-Parameter No. 24"}, + { 1125 , "Float-Parameter No. 25"}, + { 1126 , "Float-Parameter No. 26"}, + { 1127 , "Float-Parameter No. 27"}, + { 1128 , "Float-Parameter No. 28"}, + { 1129 , "Float-Parameter No. 29"}, + { 1130 , "Float-Parameter No. 30"}, + { 1131 , "Float-Parameter No. 31"}, + { 1132 , "Float-Parameter No. 32"}, + { 1133 , "Float-Parameter No. 33"}, + { 1134 , "Float-Parameter No. 34"}, + { 1135 , "Float-Parameter No. 35"}, + { 1136 , "Float-Parameter No. 36"}, + { 1137 , "Float-Parameter No. 37"}, + { 1138 , "Float-Parameter No. 38"}, + { 1139 , "Float-Parameter No. 39"}, + { 1140 , "Float-Parameter No. 40"}, + { 1141 , "Float-Parameter No. 41"}, + { 1142 , "Float-Parameter No. 42"}, + { 1143 , "Float-Parameter No. 43"}, + { 1144 , "Float-Parameter No. 44"}, + { 1145 , "Float-Parameter No. 45"}, + { 1146 , "Float-Parameter No. 46"}, + { 1147 , "Float-Parameter No. 47"}, + { 1148 , "Float-Parameter No. 48"}, + { 1149 , "Float-Parameter No. 49"}, + { 1150 , "Float-Parameter No. 50"}, + { 1151 , "Float-Parameter No. 51"}, + { 1152 , "Float-Parameter No. 52"}, + { 1153 , "Float-Parameter No. 53"}, + { 1154 , "Float-Parameter No. 54"}, + { 1155 , "Float-Parameter No. 55"}, + { 1156 , "Float-Parameter No. 56"}, + { 1157 , "Float-Parameter No. 57"}, + { 1158 , "Float-Parameter No. 58"}, + { 1159 , "Float-Parameter No. 59"}, + { 1160 , "Float-Parameter No. 60"}, + { 1161 , "Float-Parameter No. 61"}, + { 1162 , "Float-Parameter No. 62"}, + { 1163 , "Float-Parameter No. 63"}, + { 1164 , "Float-Parameter No. 64"}, + { 1165 , "Float-Parameter No. 65"}, + { 1166 , "Float-Parameter No. 66"}, + { 1167 , "Float-Parameter No. 67"}, + { 1168 , "Float-Parameter No. 68"}, + { 1169 , "Float-Parameter No. 69"}, + { 1170 , "Float-Parameter No. 70"}, + { 1171 , "Float-Parameter No. 71"}, + { 1172 , "Float-Parameter No. 72"}, + { 1173 , "Float-Parameter No. 73"}, + { 1174 , "Float-Parameter No. 74"}, + { 1175 , "Float-Parameter No. 75"}, + { 1176 , "Float-Parameter No. 76"}, + { 1177 , "Float-Parameter No. 77"}, + { 1178 , "Float-Parameter No. 78"}, + { 1179 , "Float-Parameter No. 79"}, + { 1180 , "Float-Parameter No. 80"}, + { 4891 , "Status of Process No. 11"}, + { 4892 , "Status of Process No. 12"}, + { 4893 , "Status of Process No. 13"}, + { 4894 , "Status of Process No. 14"}, + { 4895 , "Status of Process No. 15"}, + { 4896 , "Status of Process No. 16"}, + {10000 , "Start Timing Analyzer"}, + {10001 , "Stop Timing Analyzer"}, + { 0, NULL }, +}; +static value_string_ext parameter_mapping_ext = VALUE_STRING_EXT_INIT(parameter_mapping); + +typedef enum { + APT_UDPH1_old, APT_UDPH1_new, APT_UDPR1, APT_UDPR2, APT_UDPR3, + APT_UDPR4, APT_GDSHP, APT_GDSHR +} adwin_packet_types_t; + +static const value_string packet_type_mapping[] = { + { APT_UDPH1_old, "UDPH1 old"}, + { APT_UDPH1_new, "UDPH1 new"}, + { APT_UDPR1, "UDPR1"}, + { APT_UDPR2, "UDPR2"}, + { APT_UDPR3, "UDPR3"}, + { APT_UDPR4, "UDPR4"}, + { APT_GDSHP, "GDSHP"}, + { APT_GDSHR, "GDSHR"}, + { 0, NULL }, +}; +static value_string_ext packet_type_mapping_ext = VALUE_STRING_EXT_INIT(packet_type_mapping); + +#define SET_PACKET_TYPE(tree, type) \ + proto_tree_add_int(tree, hf_adwin_packet_type, tvb, 0, tvb_captured_length(tvb), type); + + +/* Initialize the protocol and registered fields */ +static int proto_adwin = -1; + +static int global_adwin_dissect_data = 1; + +static int hf_adwin_address = -1; +static int hf_adwin_armVersion = -1; +static int hf_adwin_binfilesize = -1; +static int hf_adwin_blocksize = -1; +static int hf_adwin_count = -1; +static int hf_adwin_complete_packets = -1; +static int hf_adwin_data = -1; +static int hf_adwin_data_int = -1; +static int hf_adwin_data_float = -1; +static int hf_adwin_data_hex = -1; +static int hf_adwin_data_no16 = -1; +static int hf_adwin_data_no32 = -1; +static int hf_adwin_data_packet_index = -1; +static int hf_adwin_data_type = -1; +static int hf_adwin_dll_version = -1; +static int hf_adwin_fifo_no16 = -1; +static int hf_adwin_fifo_no32 = -1; +static int hf_adwin_instruction = -1; +static int hf_adwin_is_range = -1; +static int hf_adwin_i3plus1 = -1; +static int hf_adwin_link_addr = -1; +static int hf_adwin_mem_type = -1; +static int hf_adwin_memsize = -1; +static int hf_adwin_osys = -1; +static int hf_adwin_packet_index = -1; +static int hf_adwin_packet_no = -1; +static int hf_adwin_packet_start = -1; +static int hf_adwin_packet_end = -1; +static int hf_adwin_gdsh_status = -1; +static int hf_adwin_packet_type = -1; +static int hf_adwin_parameter = -1; +static int hf_adwin_password = -1; +static int hf_adwin_process_no = -1; +static int hf_adwin_processor = -1; +static int hf_adwin_response_in = -1; +static int hf_adwin_response_to = -1; +static int hf_adwin_response_time = -1; +static int hf_adwin_retry_packet_index= -1; +static int hf_adwin_request_no = -1; +static int hf_adwin_start_index = -1; +static int hf_adwin_status = -1; +static int hf_adwin_timeout = -1; +static int hf_adwin_unused = -1; +static int hf_adwin_val1 = -1; +static int hf_adwin_val1f = -1; +static int hf_adwin_val2 = -1; +static int hf_adwin_val3 = -1; +static int hf_adwin_val4 = -1; + +/* Initialize the subtree pointers */ +static gint ett_adwin = -1; +static gint ett_adwin_debug = -1; + +/* response/request tracking */ +typedef struct _adwin_transaction_t { + guint32 req_frame; + guint32 rep_frame; + nstime_t req_time; +} adwin_transaction_t; + +/* response/request tracking */ +typedef struct _adwin_conv_info_t { + wmem_map_t *pdus; +} adwin_conv_info_t; + +typedef enum { + ADWIN_REQUEST, + ADWIN_RESPONSE +} adwin_direction_t; + +static void +adwin_request_response_handling(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, guint32 seq_num, adwin_direction_t direction) +{ + conversation_t *conversation; + adwin_conv_info_t *adwin_info; + adwin_transaction_t *adwin_trans; + + /* + * Find or create a conversation for this connection. + */ + conversation = find_or_create_conversation(pinfo); + + /* + * Do we already have a state structure for this conv + */ + adwin_info = (adwin_conv_info_t *)conversation_get_proto_data(conversation, proto_adwin); + if (!adwin_info) { + /* + * No. Attach that information to the conversation, and add + * it to the list of information structures. + */ + adwin_info = wmem_new(wmem_file_scope(), adwin_conv_info_t); + adwin_info->pdus = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); + + conversation_add_proto_data(conversation, proto_adwin, adwin_info); + } + if (!pinfo->fd->visited) { + if (direction == ADWIN_REQUEST) { + /* This is a request */ + adwin_trans = wmem_new(wmem_file_scope(), adwin_transaction_t); + adwin_trans->req_frame = pinfo->num; + adwin_trans->rep_frame = 0; + adwin_trans->req_time = pinfo->abs_ts; + wmem_map_insert(adwin_info->pdus, GUINT_TO_POINTER(seq_num), (void *)adwin_trans); + } else { + adwin_trans = (adwin_transaction_t *)wmem_map_lookup(adwin_info->pdus, GUINT_TO_POINTER(seq_num)); + if (adwin_trans) { + adwin_trans->rep_frame = pinfo->num; + } + } + } else { + adwin_trans = (adwin_transaction_t *)wmem_map_lookup(adwin_info->pdus, GUINT_TO_POINTER(seq_num)); + } + if (!adwin_trans) { + /* create a "fake" adwin_trans structure */ + adwin_trans = wmem_new(pinfo->pool, adwin_transaction_t); + adwin_trans->req_frame = 0; + adwin_trans->rep_frame = 0; + adwin_trans->req_time = pinfo->abs_ts; + } + + /* print state tracking in the tree */ + if (direction == ADWIN_REQUEST) { + /* This is a request */ + if (adwin_trans->rep_frame) { + proto_item *it; + + it = proto_tree_add_uint(adwin_tree, hf_adwin_response_in, + tvb, 0, 0, adwin_trans->rep_frame); + proto_item_set_generated(it); + } + } else { + /* This is a reply */ + if (adwin_trans->req_frame) { + proto_item *it; + nstime_t ns; + + it = proto_tree_add_uint(adwin_tree, hf_adwin_response_to, + tvb, 0, 0, adwin_trans->req_frame); + proto_item_set_generated(it); + + nstime_delta(&ns, &pinfo->abs_ts, &adwin_trans->req_time); + it = proto_tree_add_time(adwin_tree, hf_adwin_response_time, tvb, 0, 0, &ns); + proto_item_set_generated(it); + } + } +} + +static void +dissect_UDPH1_generic(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string, const gchar* packet_name) +{ + guint32 i3plus1code = 0, instructionID, seq_num; + + instructionID = tvb_get_letohl(tvb, 0); + *info_string = wmem_strdup_printf(pinfo->pool, "%s: %s", packet_name, + val_to_str_ext(instructionID, &instruction_mapping_ext, "unknown instruction: %d")); + + if (instructionID == I_3PLUS1) { + gchar *tmp = *info_string; + + i3plus1code = tvb_get_letohl(tvb, 20); + *info_string = wmem_strdup_printf(pinfo->pool, "%s: %s", tmp, val_to_str_ext(i3plus1code, &instruction_3plus1_mapping_ext, "unknown 3+1 code: %d")); + } + + /* Get the transaction identifier */ + seq_num = tvb_get_letohl(tvb, 4); + adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_REQUEST); + + if (! adwin_tree) + return; + + SET_PACKET_TYPE(adwin_tree, APT_UDPH1_old); + + proto_tree_add_item(adwin_tree, hf_adwin_instruction, tvb, 0, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_packet_index, tvb, 4, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_password, tvb, 8, 10, ENC_ASCII); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 18, 2, ENC_NA); + + switch(instructionID) { + case I_3PLUS1: + proto_tree_add_item(adwin_tree, hf_adwin_i3plus1, tvb, 20, 4, ENC_LITTLE_ENDIAN); + switch (i3plus1code) { + case I_3P1_SET_PAR: + proto_tree_add_item(adwin_tree, hf_adwin_parameter, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_val1, tvb, 28, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_val1f, tvb, 28, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 32, 4, ENC_NA); + break; + case I_3P1_GET_PAR: + proto_tree_add_item(adwin_tree, hf_adwin_parameter, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 28, 8, ENC_NA); + break; + case I_3P1_GET_MEMORY_INFO: + case I_3P1_GET_DETAILED_MEM_INFO: + proto_tree_add_item(adwin_tree, hf_adwin_mem_type, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 28, 8, ENC_NA); + break; + case I_3P1_START: + case I_3P1_STOP: + case I_3P1_CLEAR_PROCESS: + proto_tree_add_item(adwin_tree, hf_adwin_process_no, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 28, 8, ENC_NA); + break; + case I_3P1_GET_DATA_LENGTH: + proto_tree_add_item(adwin_tree, hf_adwin_data_no32, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 28, 8, ENC_NA); + break; + case I_3P1_CLEAR_FIFO: + case I_3P1_GET_FIFO_EMPTY: + case I_3P1_GET_FIFO_COUNT: + proto_tree_add_item(adwin_tree, hf_adwin_fifo_no32, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 28, 8, ENC_NA); + break; + default: ; /* should not happen */ + /* illegal values should be displayed properly + by 3plus1_mapping */ + } + break; + case I_BOOT: + proto_tree_add_item(adwin_tree, hf_adwin_memsize, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_blocksize, tvb, 24, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 26, 2, ENC_NA); + proto_tree_add_item(adwin_tree, hf_adwin_processor, tvb, 28, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_binfilesize, tvb, 32, 4, ENC_LITTLE_ENDIAN); + break; + case I_LOAD_BIN_FILE: + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 20, 6, ENC_NA); + proto_tree_add_item(adwin_tree, hf_adwin_blocksize, tvb, 26, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_processor, tvb, 28, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_binfilesize, tvb, 32, 4, ENC_LITTLE_ENDIAN); + break; + case I_GET_WORKLOAD: + proto_tree_add_item(adwin_tree, hf_adwin_instruction, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 24, 12, ENC_NA); + break; + case I_GET_DATA_TYPE: + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 20, 4, ENC_NA); + proto_tree_add_item(adwin_tree, hf_adwin_data_no32, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_start_index, tvb, 28, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 32, 4, ENC_NA); + break; + case I_GET_DATA: + case I_SET_DATA: + proto_tree_add_item(adwin_tree, hf_adwin_data_type, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_data_no16, tvb, 24, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_blocksize, tvb, 26, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_start_index, tvb, 28, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_count, tvb, 32, 4, ENC_LITTLE_ENDIAN); + break; + case I_GET_DATA_SHIFTED_HANDSHAKE: + proto_tree_add_item(adwin_tree, hf_adwin_data_no16, tvb, 20, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_blocksize, tvb, 22, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_start_index, tvb, 24, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_count, tvb, 28, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 32, 4, ENC_NA); + break; + case I_GET_DATA_SMALL: + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 20, 4, ENC_NA); + proto_tree_add_item(adwin_tree, hf_adwin_data_no16, tvb, 24, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 26, 2, ENC_NA); + proto_tree_add_item(adwin_tree, hf_adwin_start_index, tvb, 28, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_count, tvb, 32, 4, ENC_LITTLE_ENDIAN); + break; + case I_GET_PAR_ALL: + proto_tree_add_item(adwin_tree, hf_adwin_start_index, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_count, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 28, 8, ENC_NA); + break; + case I_SET_DATA_LAST_STATUS: + proto_tree_add_item(adwin_tree, hf_adwin_data_packet_index, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 24, 12, ENC_NA); + break; + case I_GET_ARM_VERSION: + proto_tree_add_item(adwin_tree, hf_adwin_armVersion, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 24, 12, ENC_NA); + break; + case I_GET_FIFO: + case I_SET_FIFO: + proto_tree_add_item(adwin_tree, hf_adwin_data_type, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_fifo_no16, tvb, 24, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 26, 6, ENC_NA); + proto_tree_add_item(adwin_tree, hf_adwin_count, tvb, 32, 4, ENC_LITTLE_ENDIAN); + break; + case I_GET_FIFO_RETRY: + case I_SET_FIFO_RETRY: + proto_tree_add_item(adwin_tree, hf_adwin_data_type, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_fifo_no16, tvb, 24, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 26, 2, ENC_NA); + proto_tree_add_item(adwin_tree, hf_adwin_retry_packet_index, tvb, 28, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_count, tvb, 32, 4, ENC_LITTLE_ENDIAN); + break; + case I_TEST_VERSION: + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 20, 16, ENC_NA); + break; + case I_GET_MEMORY: + proto_tree_add_item(adwin_tree, hf_adwin_address, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_count, tvb, 24, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 28, 8, ENC_NA); + break; + default: ; /* should not happen */ + /* illegal values should be displayed properly by + instruction_mapping */ + } + + proto_tree_add_item(adwin_debug_tree, hf_adwin_link_addr, tvb, 36, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_timeout, tvb, 40, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_osys, tvb, 44, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 48, 4, ENC_NA); + +} + + +static void +dissect_UDPH1_old(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string) +{ + dissect_UDPH1_generic(tvb, pinfo, adwin_tree, adwin_debug_tree, info_string, "UDPH1 (old)"); +} + +static void +dissect_UDPH1_new(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree, + gchar** info_string) +{ + gchar* dll_version_s; + gint32 dll_i; + + dissect_UDPH1_generic(tvb, pinfo, adwin_tree, adwin_debug_tree, info_string, "UDPH1 (new)"); + + if (! adwin_tree) + return; + + SET_PACKET_TYPE(adwin_tree, APT_UDPH1_new); + dll_i = tvb_get_letohl(tvb, 52); + dll_version_s = wmem_strdup_printf(pinfo->pool, "%d.%d.%d", + dll_i / 1000000, + (dll_i - dll_i / 1000000 * 1000000) / 1000, + dll_i % 1000); + + proto_tree_add_string(adwin_debug_tree, hf_adwin_dll_version, + tvb, 52, 4, dll_version_s); +} + +static void +dissect_UDPR1(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree, + gchar** info_string) +{ + const gchar *status_string; + guint32 seq_num, status; + + status = tvb_get_letohl(tvb, 0); + status_string = try_val_to_str_ext(status, &error_code_mapping_ext); + if (status_string) { + *info_string = wmem_strdup_printf(pinfo->pool, "UDPR1 Status: %s", status_string); + } else { + *info_string = wmem_strdup_printf(pinfo->pool, "UDPR1 Undefined error code %d", status); + } + + /* Get the transaction identifier */ + seq_num = tvb_get_letohl(tvb, 4); + adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); + + if (! adwin_tree) + return; + + SET_PACKET_TYPE(adwin_tree, APT_UDPR1); + proto_tree_add_item(adwin_tree, hf_adwin_status, tvb, 0, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_packet_index, tvb, 4, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_val1, tvb, 8, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_val1f, tvb, 8, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_val2, tvb, 12, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_val3, tvb, 16, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_val4, tvb, 20, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 24, 8, ENC_NA); +} + +static void +dissect_UDPR2(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree, + gchar** info_string) +{ + const gchar *status_string; + guint32 i, status, seq_num; + + status = tvb_get_letohl(tvb, 0); + status_string = try_val_to_str_ext(status, &error_code_mapping_ext); + if (status_string) { + *info_string = wmem_strdup_printf(pinfo->pool, "UDPR2 Status: %s", status_string); + } else { + *info_string = wmem_strdup_printf(pinfo->pool, "UDPR2 Undefined error code %d", status); + } + + /* Get the transaction identifier */ + seq_num = tvb_get_letohl(tvb, 4); + adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); + + if (! adwin_tree) + return; + + SET_PACKET_TYPE(adwin_tree, APT_UDPR2); + proto_tree_add_item(adwin_tree, hf_adwin_status, tvb, 0, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_packet_index, tvb, 4, 4, ENC_LITTLE_ENDIAN); + + if (! global_adwin_dissect_data) { + call_data_dissector(tvb_new_subset_length(tvb, 8, 250*4), pinfo, adwin_debug_tree); + return; + } + + for (i = 0; i < 250; i++) { + proto_item *item; + guint32 offset = 8 + i * (int)sizeof(guint32); + gint32 value = tvb_get_letohl(tvb, offset); + void * fvalue = &value; + proto_tree_add_none_format(adwin_debug_tree, hf_adwin_data, tvb, offset, 4, + "Data[%3d]: %10d - %10f - 0x%08x", + i, value, *(float*)fvalue, value); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_int, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_float, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_hex, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + } +} + +static void +dissect_UDPR3(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree) +{ + guint32 i, seq_num; + + /* Get the transaction identifier */ + seq_num = tvb_get_letohl(tvb, 0); + adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); + + if (! adwin_tree) + return; + + SET_PACKET_TYPE(adwin_tree, APT_UDPR3); + proto_tree_add_item(adwin_tree, hf_adwin_packet_index, tvb, 0, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_packet_no, tvb, 4, 4, ENC_LITTLE_ENDIAN); + + if (! global_adwin_dissect_data) { + call_data_dissector(tvb_new_subset_length(tvb, 8, 350*4), pinfo, adwin_debug_tree); + return; + } + + for (i = 0; i < 350; i++) { + proto_item *item; + guint32 offset = 8 + i * (int)sizeof(guint32); + gint32 value = tvb_get_letohl(tvb, offset); + void * fvalue = &value; + proto_tree_add_none_format(adwin_debug_tree, hf_adwin_data, tvb, offset, 4, + "Data[%3d]: %10d - %10f - 0x%08x", + i, value, *(float*)fvalue, value); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_int, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_float, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_hex, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + } +} + +static void +dissect_UDPR4(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree, gchar** info_string) +{ + const gchar *status_string; + guint32 data_type, i, status, seq_num; + + status = tvb_get_letohl(tvb, 0); + status_string = try_val_to_str_ext(status, &error_code_mapping_ext); + if (status_string) { + *info_string = wmem_strdup_printf(pinfo->pool, "UDPR4 Status: %s", status_string); + } else { + *info_string = wmem_strdup_printf(pinfo->pool, "UDPR4 Undefined error code %d", status); + } + + /* Get the transaction identifier */ + seq_num = tvb_get_letohl(tvb, 4); + adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); + + if (! adwin_tree) + return; + + SET_PACKET_TYPE(adwin_tree, APT_UDPR4); + proto_tree_add_item(adwin_tree, hf_adwin_status, tvb, 0, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_packet_index, tvb, 4, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_packet_no, tvb, 1408, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_data_type, tvb, 1412, 4, ENC_LITTLE_ENDIAN); + + data_type = tvb_get_letohl(tvb, 1412); + + if (! global_adwin_dissect_data) { + call_data_dissector(tvb_new_subset_length(tvb, 8, 350*4), pinfo, adwin_debug_tree); + return; + } + + for (i = 0; i < 350; i++) { + proto_item *item; + guint32 offset = 8 + i * (int)sizeof(guint32); + gint32 value = tvb_get_letohl(tvb, offset); + void * fvalue = &value; + switch (data_type) { + case 2: + case 3: + case 4: /* some kind of int, usually int/long */ + proto_tree_add_none_format(adwin_debug_tree, hf_adwin_data, tvb, offset, 4, + "Data[%3d]: %10d - 0x%08x", + i, value, value); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_int, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_hex, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + break; + case 5: /* float */ + proto_tree_add_none_format(adwin_debug_tree, hf_adwin_data, tvb, offset, 4, + "Data[%3d]: %10f - 0x%08x", + i, *(float*)fvalue, value); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_float, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_hex, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + break; + default: /* string, double, variant, something funny... */ + proto_tree_add_none_format(adwin_debug_tree, hf_adwin_data, tvb, offset, 4, + "Data[%3d]: 0x%08x", + i, value); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_hex, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + } + } +} + +static void +dissect_GDSHP(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree) +{ + guint32 i, seq_num; + + /* Get the transaction identifier */ + seq_num = tvb_get_ntohl(tvb, 0); + adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); + + if (! adwin_tree) + return; + + SET_PACKET_TYPE(adwin_tree, APT_GDSHP); + proto_tree_add_item(adwin_tree, hf_adwin_packet_index, tvb, 0, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_packet_no, tvb, 4, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_unused, tvb, 8, 4, ENC_NA); + + if (! global_adwin_dissect_data) { + call_data_dissector(tvb_new_subset_length(tvb, 12, 336*4), pinfo, adwin_debug_tree); + return; + } + + for (i = 0; i < 336; i++) { + proto_item *item; + guint32 offset = 12 + i * (int)sizeof(guint32); + gint32 value = tvb_get_letohl(tvb, offset); + void * fvalue = &value; + proto_tree_add_none_format(adwin_debug_tree, hf_adwin_data, tvb, offset, 4, + "Data[%3d]: %10d - %10f - 0x%08x", + i, value, *(float*)fvalue, value); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_int, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_float, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + item = proto_tree_add_item(adwin_debug_tree, hf_adwin_data_hex, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_set_hidden(item); + } +} + +static void +dissect_GDSHR(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *adwin_tree, proto_tree *adwin_debug_tree) +{ + guint32 is_range, packet_start, packet_end, seq_num; + proto_item *ti; + + /* Get the transaction identifier */ + seq_num = tvb_get_ntohl(tvb, 0); + adwin_request_response_handling(tvb, pinfo, adwin_tree, seq_num, ADWIN_RESPONSE); + + if (! adwin_tree) + return; + + SET_PACKET_TYPE(adwin_tree, APT_GDSHR); + proto_tree_add_item(adwin_tree, hf_adwin_packet_index, tvb, 0, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_request_no, tvb, 4, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_tree, hf_adwin_complete_packets, tvb, 8, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_is_range, tvb, 12, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_packet_start, tvb, 16, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(adwin_debug_tree, hf_adwin_packet_end, tvb, 20, 4, ENC_BIG_ENDIAN); + + is_range = tvb_get_ntohl(tvb, 12); + packet_start = tvb_get_ntohl(tvb, 16); + + switch(is_range) { + case 0: + ti = proto_tree_add_uint_format_value(adwin_tree, hf_adwin_gdsh_status, tvb, 12, 4, + is_range, "get single packet no %d", packet_start); + break; + case 1: + packet_end = tvb_get_ntohl(tvb, 20); + ti = proto_tree_add_uint_format_value(adwin_tree, hf_adwin_gdsh_status, tvb, 12, 4, + is_range, "get packets %d - %d", + packet_start, packet_end); + break; + case 2: + ti = proto_tree_add_uint_format_value(adwin_tree, hf_adwin_gdsh_status, tvb, 12, 4, + is_range, "finished"); + break; + default: /* should not happen */ + ti = proto_tree_add_uint_format_value(adwin_tree, hf_adwin_gdsh_status, tvb, 12, 4, + is_range, "unknown code %d", is_range); + } + proto_item_set_len(ti, 12); + proto_tree_add_item(adwin_debug_tree, hf_adwin_unused, tvb, 24, 40, ENC_NA); +} + +/* here we determine which type of packet is sent by looking at its + size. That is safe since the main server application that processes + these packets does it this way, too. + + Depending on the packet type, the appropriate dissector is + called. */ + +static int +dissect_adwin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + proto_item *ti, *ti2; + proto_tree *adwin_tree, *adwin_debug_tree; + gchar *info_string; + guint32 length; + + length = tvb_reported_length(tvb); + + /* First do some heuristics to see if this packet belongs to us */ + if(! (length == UDPH1_OLD_LENGTH + || length == UDPH1_NEW_LENGTH + || length == UDPR1_LENGTH + || length == UDPH2_LENGTH + || length == UDPR2_LENGTH + || length == UDPR3_LENGTH + || length == UDPR4_LENGTH + || length == GetDataSHPacket_LENGTH + || length == GetDataSHRequest_LENGTH)) + return(0); + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ADwin"); + col_clear(pinfo->cinfo, COL_INFO); + + ti = proto_tree_add_item(tree, proto_adwin, tvb, 0, -1, ENC_NA); + adwin_tree = proto_item_add_subtree(ti, ett_adwin); + + ti2 = proto_tree_add_item(adwin_tree, proto_adwin, tvb, 0, -1, ENC_NA); + adwin_debug_tree = proto_item_add_subtree(ti2, ett_adwin_debug); + proto_item_set_text(ti2, "ADwin Debug information"); + + switch (length) { + case UDPH1_OLD_LENGTH: + dissect_UDPH1_old(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string); + break; + case UDPH1_NEW_LENGTH: + dissect_UDPH1_new(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string); + break; + case UDPR1_LENGTH: + dissect_UDPR1(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string); + break; + case UDPH2_LENGTH: /* to the best of my knowledge, this struct + * has never been used publically! */ + /* dissect_UDPH2(tvb, pinfo, adwin_tree, adwin_debug_tree); */ + info_string = wmem_strdup(pinfo->pool, "UDPH2 - UNUSED"); + break; + case UDPR2_LENGTH: + dissect_UDPR2(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string); + break; + case UDPR3_LENGTH: + dissect_UDPR3(tvb, pinfo, adwin_tree, adwin_debug_tree); + info_string = wmem_strdup(pinfo->pool, "UDPR3"); + break; + case UDPR4_LENGTH: + dissect_UDPR4(tvb, pinfo, adwin_tree, adwin_debug_tree, &info_string); + break; + case GetDataSHPacket_LENGTH: + dissect_GDSHP(tvb, pinfo, adwin_tree, adwin_debug_tree); + info_string = wmem_strdup(pinfo->pool, "GDSHP"); + break; + case GetDataSHRequest_LENGTH: + dissect_GDSHR(tvb, pinfo, adwin_tree, adwin_debug_tree); + info_string = wmem_strdup(pinfo->pool, "GDSHR"); + break; + default: + info_string = wmem_strdup_printf(pinfo->pool, "Unknown ADwin packet, length: %d", length); + break; + } + + col_add_str(pinfo->cinfo, COL_INFO, info_string); + + return (tvb_reported_length(tvb)); +} + + +void +proto_reg_handoff_adwin(void) +{ + dissector_add_uint_with_preference("udp.port", ADWIN_COMM_PORT, adwin_handle); +} + +void +proto_register_adwin(void) +{ + static hf_register_info hf[] = { + { &hf_adwin_address, + { "memory address", "adwin.address", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Memory address to read on DSP", HFILL } + }, + { &hf_adwin_armVersion, + { "Get ARM Version", "adwin.armVersion", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_binfilesize, + { "File size", "adwin.binfilesize", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Size of binary file", HFILL } + }, + { &hf_adwin_blocksize, + { "Blocksize", "adwin.blocksize", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Maximum number of unacknowledged packets", HFILL } + }, + { &hf_adwin_complete_packets, + { "Complete packets", "adwin.complete_packets", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Highest sequential package number", HFILL } + }, + { &hf_adwin_count, + { "Count", "adwin.count", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Number of longs", HFILL } + }, + { &hf_adwin_data, + { "Data", "adwin.data", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_data_int, + { "Data element int", "adwin.data_int", + FT_INT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_data_float, + { "Data element float", "adwin.data_float", + FT_FLOAT, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_data_hex, + { "Data element hex", "adwin.data_hex", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_data_no16, + { "Data No. (16bit)", "adwin.data_no16", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_data_no32, + { "Data No. (32bit)", "adwin.data_no32", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_data_type, + { "Data type", "adwin.data_type", + FT_UINT32, BASE_DEC|BASE_EXT_STRING, &data_type_mapping_ext, 0x0, + NULL, HFILL } + }, + { &hf_adwin_data_packet_index, + { "Data packet index", "adwin.data_packet_index", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_dll_version, + { "DLL Version", "adwin.dll_version", + FT_STRINGZ, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_fifo_no16, + { "FiFo No. (16bit)", "adwin.fifo_no", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_fifo_no32, + { "FiFo No. (32bit)", "adwin.fifo_no", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_instruction, + { "Instruction", "adwin.instruction", + FT_UINT32, BASE_DEC|BASE_EXT_STRING, &instruction_mapping_ext, 0x0, + NULL, HFILL } + }, + { &hf_adwin_is_range, + { "packets are a range", "adwin.is_range", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_i3plus1, + { "3+1 Instruction", "adwin.i3plus1", + FT_UINT32, BASE_DEC|BASE_EXT_STRING, &instruction_3plus1_mapping_ext, 0x0, + NULL, HFILL } + }, + { &hf_adwin_link_addr, + { "Link address", "adwin.link_addr", + FT_UINT32, BASE_HEX, NULL, 0x0, + "Link address (TCP/IP Server only)", HFILL } + }, + { &hf_adwin_mem_type, + { "Memory type", "adwin.mem_type", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_memsize, + { "Memory size", "adwin.memsize", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_osys, + { "Operating system", "adwin.osys", + FT_UINT32, BASE_DEC|BASE_EXT_STRING, &osys_mapping_ext, 0x0, + "Operating system / environment", HFILL } + }, + { &hf_adwin_packet_end, + { "End packet", "adwin.packet_end", + FT_UINT32, BASE_DEC, NULL, 0x0, + "GDSH: End Packet", HFILL } + }, + { &hf_adwin_gdsh_status, + { "GDSH status", "adwin.gdsh_status", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_packet_index, + { "Packet index", "adwin.packet_index", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_packet_no, + { "Packet No.", "adwin.packet_no", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_packet_start, + { "Starting packet", "adwin.packet_start", + FT_UINT32, BASE_DEC, NULL, 0x0, + "GDSH: Starting Packet", HFILL } + }, + { &hf_adwin_packet_type, + { "Packet type", "adwin.packet_type", + FT_INT32, BASE_DEC|BASE_EXT_STRING, &packet_type_mapping_ext, 0x0, + NULL, HFILL } + }, + { &hf_adwin_parameter, + { "Parameter", "adwin.parameter", + FT_UINT32, BASE_DEC|BASE_EXT_STRING, ¶meter_mapping_ext, 0x0, + NULL, HFILL } + }, + { &hf_adwin_password, + { "Password", "adwin.password", + FT_STRING, BASE_NONE, NULL, 0x0, + "Password for ADwin system", HFILL } + }, + { &hf_adwin_process_no, + { "Process No.", "adwin.process_no", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_processor, + { "Processor", "adwin.processor", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_response_in, + { "Response In", "adwin.response_in", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "The response to this ADwin request is in this frame", HFILL } + }, + { &hf_adwin_response_to, + { "Request In", "adwin.response_to", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "This is a response to the ADwin request in this frame", HFILL } + }, + { &hf_adwin_response_time, + { "Response time", "adwin.response_time", + FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, + "The time between the Request and the Reply", HFILL } + }, + { &hf_adwin_retry_packet_index, + { "Retry packet index", "adwin.retry_packet_index", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_request_no, + { "Request Number", "adwin.request_no", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Request number index", HFILL } + }, + { &hf_adwin_start_index, + { "Start index", "adwin.start_index", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_status, + { "Status", "adwin.status", + FT_INT32, BASE_DEC|BASE_EXT_STRING, &error_code_mapping_ext, 0x0, + NULL, HFILL } + }, + { &hf_adwin_timeout, + { "Timeout", "adwin.timeout", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Timeout in ms", HFILL } + }, + { &hf_adwin_unused, + { "Unused", "adwin.unused", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_adwin_val1, + { "Value 1 (as int)", "adwin.val1", + FT_INT32, BASE_DEC, NULL, 0x0, + "Generic return value 1 interpreted as integer (correct interpretation depends on request).", HFILL } + }, + { &hf_adwin_val1f, + { "Value 1 (as float)", "adwin.val1f", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Generic return value 1 interpreted as float (correct interpretation depends on request).", HFILL } + }, + { &hf_adwin_val2, + { "Value 2", "adwin.val2", + FT_INT32, BASE_DEC, NULL, 0x0, + "Generic return value 2 (interpretation depends on request).", HFILL } + }, + { &hf_adwin_val3, + { "Value 3", "adwin.val3", + FT_INT32, BASE_DEC, NULL, 0x0, + "Generic return value 3 (interpretation depends on request).", HFILL } + }, + { &hf_adwin_val4, + { "Value 4", "adwin.val4", + FT_INT32, BASE_DEC, NULL, 0x0, + "Generic return value 4 (interpretation depends on request).", HFILL } + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_adwin, + &ett_adwin_debug, + }; + module_t *adwin_module; + + /* Register the protocol name and description */ + proto_adwin = proto_register_protocol("ADwin communication protocol", + "ADwin", "adwin"); + + /* Required function calls to register the header fields and + subtrees used */ + proto_register_field_array(proto_adwin, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + /* Register our configuration options for ADwin */ + adwin_module = prefs_register_protocol(proto_adwin, NULL); + + prefs_register_bool_preference(adwin_module, "dissect_data", + "Dissect Data sections", + "Specify if the Data sections of packets " + "should be dissected or not", + &global_adwin_dissect_data); + + adwin_handle = register_dissector("adwin", dissect_adwin, proto_adwin); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=8 tabstop=8 noexpandtab: + * :indentSize=8:tabSize=8:noTabs=false: + */ |