Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-xcp.c
Line
Count
Source
1
/* packet-xcp.c
2
 * Universal Measurement and Calibration (XCP)
3
 * By <lars.voelker@technica-engineering.de>
4
 * Copyright 2023-2025 Dr. Lars Völker
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
 /*
14
  * This is a dissector for the Universal Measurement and Calibration Protocol (XCP) by ASAM.
15
  *
16
  * Due to the nature of the XCP protocol, for each ECU a configuration entry needs to be set
17
  * as XCP does have different encoding per direction but does not state the direction.
18
  * For example and ECU with 192.0.2.85:5555/udp would require something like this:
19
  *   IPv4, 192.0.2.85, UDP, 5555, 1
20
  *
21
  * The protocol defines that it uses 239.255.0.0:5556 for multicast messages but port number
22
  * was not registered with IANA. So a user has to add this manually to UDP/TCP mappings:
23
  *   IPv4, 239.255.0.0, UDP, 5556, 0
24
  *
25
  * Not all messages and use cases are supported. For additional support, a bug should be created
26
  * with an attached trace file for that use case.
27
  *
28
  */
29
30
#include <config.h>
31
32
#include <epan/conversation.h>
33
#include <epan/packet.h>
34
#include <epan/proto_data.h>
35
#include <epan/uat.h>
36
#include <epan/tfs.h>
37
#include <epan/expert.h>
38
39
#include "packet-udp.h"
40
#include "packet-tcp.h"
41
#include "packet-socketcan.h"
42
43
16
#define DATAFILE_XCP_MEMORY_ADDRESSES       "XCP_Addresses"
44
16
#define DATAFILE_XCP_ETH_MAPPING            "XCP_Mapping_UDP_TCP"
45
16
#define DATAFILE_XCP_CAN_MAPPING            "XCP_Mapping_CAN"
46
47
#define XCP_TYPE_UNKNOWN                    0
48
0
#define XCP_TYPE_CAN                        1
49
0
#define XCP_TYPE_ETHERNET                   2
50
#define XCP_TYPE_SXL                        3
51
#define XCP_TYPE_USB                        4
52
#define XCP_TYPE_FLEXRAY                    5
53
54
0
#define XCP_DIR_UNKNOWN                     0
55
0
#define XCP_DIR_M2S                         1
56
0
#define XCP_DIR_S2M                         2
57
58
0
#define XCP_ETH_HDR_LEN                     4
59
60
0
#define XCP_PID_RES                         0xFF
61
#define XCP_PID_ERR                         0xFE
62
#define XCP_PID_EV                          0xFD
63
#define XCP_PID_SERV                        0xFC
64
65
static const value_string pid_type_names_s2m[] = {
66
    {XCP_PID_RES,   "Positive Response"},
67
    {XCP_PID_ERR,   "Error"},
68
    {XCP_PID_EV,    "Event"},
69
    {XCP_PID_SERV,  "Service request"},
70
    {0, NULL}
71
};
72
73
0
#define XCP_CMD_CONNECT                     0xFF
74
0
#define XCP_CMD_DISCONNECT                  0xFE
75
0
#define XCP_CMD_GET_STATUS                  0xFD
76
0
#define XCP_CMD_SYNCH                       0xFC
77
0
#define XCP_CMD_GET_COMM_MODE_INFO          0xFB
78
0
#define XCP_CMD_GET_ID                      0xFA
79
0
#define XCP_CMD_SET_REQUEST                 0xF9
80
0
#define XCP_CMD_GET_SEED                    0xF8
81
0
#define XCP_CMD_UNLOCK                      0xF7
82
0
#define XCP_CMD_SET_MTA                     0xF6
83
0
#define XCP_CMD_UPLOAD                      0xF5
84
0
#define XCP_CMD_SHORT_UPLOAD                0xF4
85
0
#define XCP_CMD_BUILD_CHECKSUM              0xF3
86
0
#define XCP_CMD_TRANSPORT_LAYER_CMD         0xF2
87
#define XCP_CMD_USER_CMD                    0xF1
88
89
0
#define XCP_CMD_DOWNLOAD                    0xF0
90
#define XCP_CMD_DOWNLOAD_NEXT               0xEF
91
0
#define XCP_CMD_DOWNLOAD_MAX                0xEE
92
0
#define XCP_CMD_SHORT_DOWNLOAD              0xED
93
0
#define XCP_CMD_MODIFY_BITS                 0xEC
94
95
0
#define XCP_CMD_SET_CAL_PAGE                0xEB
96
0
#define XCP_CMD_GET_CAL_PAGE                0xEA
97
0
#define XCP_CMD_GET_PAG_PROCESSOR_INFO      0xE9
98
0
#define XCP_CMD_GET_SEGMENT_INFO            0xE8
99
#define XCP_CMD_GET_PAGE_INFO               0xE7
100
0
#define XCP_CMD_SET_SEGMENT_MODE            0xE6
101
#define XCP_CMD_GET_SEGMENT_MODE            0xE5
102
0
#define XCP_CMD_COPY_CAL_PAGE               0xE4
103
104
0
#define XCP_CMD_CLEAR_DAQ_LIST              0xE3
105
0
#define XCP_CMD_SET_DAQ_PTR                 0xE2
106
0
#define XCP_CMD_WRITE_DAQ                   0xE1
107
0
#define XCP_CMD_SET_DAQ_LIST_MODE           0xE0
108
#define XCP_CMD_GET_DAQ_LIST_MODE           0xDF
109
0
#define XCP_CMD_START_STOP_DAQ_LIST         0xDE
110
0
#define XCP_CMD_START_STOP_SYNCH            0xDD
111
0
#define XCP_CMD_GET_DAQ_CLOCK               0xDC
112
0
#define XCP_CMD_READ_DAQ                    0xDB
113
0
#define XCP_CMD_GET_DAQ_PROCESSOR_INFO      0xDA
114
0
#define XCP_CMD_GET_RESOLUTION_INFO         0xD9
115
0
#define XCP_CMD_GET_DAQ_LIST_INFO           0xD8
116
0
#define XCP_CMD_GET_DAQ_EVENT_INFO          0xD7
117
0
#define XCP_CMD_FREE_DAQ                    0xD6
118
0
#define XCP_CMD_ALLOC_DAQ                   0xD5
119
0
#define XCP_CMD_ALLOC_ODT                   0xD4
120
0
#define XCP_CMD_ALLOC_ODT_ENTRY             0xD3
121
122
0
#define XCP_CMD_PROGRAM_START               0xD2
123
0
#define XCP_CMD_PROGRAM_CLEAR               0xD1
124
0
#define XCP_CMD_PROGRAM                     0xD0
125
0
#define XCP_CMD_PROGRAM_RESET               0xCF
126
0
#define XCP_CMD_GET_PGM_PROCESSOR_INFO      0xCE
127
#define XCP_CMD_GET_SECTOR_INFO             0xCD
128
0
#define XCP_CMD_PROGRAM_PREPARE             0xCC
129
0
#define XCP_CMD_PROGRAM_FORMAT              0xCB
130
#define XCP_CMD_PROGRAM_NEXT                0xCA
131
0
#define XCP_CMD_PROGRAM_MAX                 0xC9
132
0
#define XCP_CMD_PROGRAM_VERIFY              0xC8
133
134
0
#define XCP_CMD_WRITE_DAQ_MULTIPLE          0xC7
135
#define XCP_CMD_TIME_CORRELATION_PROPERTIES 0xC6
136
#define XCP_CMD_DTO_CTR_PROPERTIES          0xC5
137
138
/* transport layer commands */
139
0
#define XCP_SUB_CMD_ETH_GET_SLAVE_ID        0xFF
140
#define XCP_SUB_CMD_ETH_GET_SLAVE_ID_EXT    0xFD
141
#define XCP_SUB_CMD_ETH_GET_SLAVE_IP_ADDR   0xFC
142
#define XCP_SUB_CMD_ETH_GET_DAQ_CLC_MCAST   0xFA
143
144
#define XCP_SUB_CMD_CAN_GET_SLAVE_ID        0xFF
145
#define XCP_SUB_CMD_CAN_GET_DAQ_ID          0xFE
146
#define XCP_SUB_CMD_CAN_SET_DAQ_ID          0xFD
147
#define XCP_SUB_CMD_CAN_GET_DAQ_CLC_MCAST   0xFA
148
149
/* two byte commands */
150
0
#define XCP_CMD_2BYTE_FIRST_BYTE            0xC0
151
0
#define XCP_CMD_2BYTE_GET_VERSION           0x00
152
0
#define XCP_CMD_2BYTE_SET_DAQ_PACKED_MODE   0x01
153
#define XCP_CMD_2BYTE_GET_DAQ_PACKED_MODE   0x02
154
0
#define XCP_CMD_2BYTE_XCP_SW_DEBUG          0xFC
155
0
#define XCP_CMD_2BYTE_XCP_POD_COMMANDS      0xFD
156
157
/* SW DEBUG over XCP commands */
158
#define XCP_CMD_SW_DBG_ATTACH               0x00
159
#define XCP_CMD_SW_DBG_GET_VENDOR_INFO      0x01
160
#define XCP_CMD_SW_DBG_GET_MODE_INFO        0x02
161
#define XCP_CMD_SW_DBG_GET_JTAG_ID          0x03
162
#define XCP_CMD_SW_DBG_HALT_AFTER_RESET     0x04
163
#define XCP_CMD_SW_DBG_GET_HWIO_INFO        0x05
164
#define XCP_CMD_SW_DBG_SET_HWIO_EVENT       0x06
165
#define XCP_CMD_SW_DBG_HWIO_CONTROL         0x07
166
#define XCP_CMD_SW_DBG_EXCL_TARGET_ACCESS   0x08
167
#define XCP_CMD_SW_DBG_SEQUENCE_MULTIPLE    0x09
168
#define XCP_CMD_SW_DBG_LLT                  0x0A
169
#define XCP_CMD_SW_DBG_READ_MODIFY_WRITE    0x0B
170
#define XCP_CMD_SW_DBG_WRITE                0x0C
171
#define XCP_CMD_SW_DBG_WRITE_NEXT           0x0D
172
#define XCP_CMD_SW_DBG_WRITE_CAN1           0x0E
173
#define XCP_CMD_SW_DBG_WRITE_CAN2           0x0F
174
#define XCP_CMD_SW_DBG_WRITE_CAN_NEXT       0x10
175
#define XCP_CMD_SW_DBG_READ                 0x11
176
#define XCP_CMD_SW_DBG_READ_CAN1            0x12
177
#define XCP_CMD_SW_DBG_READ_CAN2            0x13
178
#define XCP_CMD_SW_DBG_GET_TRI_DESC_TBL     0x14
179
#define XCP_CMD_SW_DBG_LLBT                 0x15
180
181
/* XCP POD commands */
182
#define XCP_CMD_POD_GET_INFO                0x0001
183
#define XCP_CMD_POD_SET_ACTIVE_CONFIG       0x0002
184
#define XCP_CMD_POD_MANAGE_TRANSFER         0x0003
185
0
#define XCP_CMD_POD_DOWNLOAD                0x0004
186
#define XCP_CMD_POD_UPLOAD                  0x0005
187
0
#define XCP_CMD_POD_GET_STATUS              0x0006
188
189
190
static const value_string cmd_code_names[] = {
191
    {XCP_CMD_CONNECT,                       "Set up Connection with Slave (Connect)"},
192
    {XCP_CMD_DISCONNECT,                    "Disconnect from Slave"},
193
    {XCP_CMD_GET_STATUS,                    "Get Current Session Status from Slave"},
194
    {XCP_CMD_SYNCH,                         "Synchronize Command Execution after Timeout"},
195
    {XCP_CMD_GET_COMM_MODE_INFO,            "Get Communication Mode Info"},
196
    {XCP_CMD_GET_ID,                        "Get Identification from Slave"},
197
    {XCP_CMD_SET_REQUEST,                   "Request to Save to Non-Volatile Memory"},
198
    {XCP_CMD_GET_SEED,                      "Get Seed for Unlocking a Protected Resource"},
199
    {XCP_CMD_UNLOCK,                        "Send Key for Unlocking a Protected Resource (Unlock)"},
200
    {XCP_CMD_SET_MTA,                       "Set Memory Transfer Address in Slave"},
201
    {XCP_CMD_UPLOAD,                        "Upload from Slave to Master"},
202
    {XCP_CMD_SHORT_UPLOAD,                  "Upload from Slave to Master (short version)"},
203
    {XCP_CMD_BUILD_CHECKSUM,                "Build Checksum over Memory Range"},
204
    {XCP_CMD_TRANSPORT_LAYER_CMD,           "Transport Layer Specific Command"},
205
    {XCP_CMD_USER_CMD,                      "User-defined Command"},
206
207
    {XCP_CMD_DOWNLOAD,                      "Download from Master to Slave"},
208
    {XCP_CMD_DOWNLOAD_NEXT,                 "Download from Master to Slave (Block Mode)"},
209
    {XCP_CMD_DOWNLOAD_MAX,                  "Download from Master to Slave (Fixed Size)"},
210
    {XCP_CMD_SHORT_DOWNLOAD,                "Download from Master to Slave (Short Version)"},
211
    {XCP_CMD_MODIFY_BITS,                   "Modify Bits"},
212
213
    {XCP_CMD_SET_CAL_PAGE,                  "Set Calibration Page"},
214
    {XCP_CMD_GET_CAL_PAGE,                  "Get Calibration Page"},
215
    {XCP_CMD_GET_PAG_PROCESSOR_INFO,        "Get General Information on PAG Processor"},
216
    {XCP_CMD_GET_SEGMENT_INFO,              "Get Specific Information for a SEGMENT"},
217
    {XCP_CMD_GET_PAGE_INFO,                 "Get Specific Information for a PAGE"},
218
    {XCP_CMD_SET_SEGMENT_MODE,              "Set Mode for a SEGMENT"},
219
    {XCP_CMD_GET_SEGMENT_MODE,              "Get Mode for a SEGMENT"},
220
    {XCP_CMD_COPY_CAL_PAGE,                 "Copy Page"},
221
222
    {XCP_CMD_CLEAR_DAQ_LIST,                "Clear DAQ List Configuration"},
223
    {XCP_CMD_SET_DAQ_PTR,                   "Set Pointer to ODT Entry"},
224
    {XCP_CMD_WRITE_DAQ,                     "Write Element in ODT Entry"},
225
    {XCP_CMD_SET_DAQ_LIST_MODE,             "Set Mode for DAQ List"},
226
    {XCP_CMD_GET_DAQ_LIST_MODE,             "Get Mode From DAQ List"},
227
    {XCP_CMD_START_STOP_DAQ_LIST,           "Start/Stop/Select DAQ List"},
228
    {XCP_CMD_START_STOP_SYNCH,              "Start/Stop DAQ Lists (Synch)"},
229
    {XCP_CMD_GET_DAQ_CLOCK,                 "Get DAQ Clock From Slave"},
230
    {XCP_CMD_READ_DAQ,                      "Read Element From ODT Entry"},
231
    {XCP_CMD_GET_DAQ_PROCESSOR_INFO,        "Get General Information on DAQ Processor"},
232
    {XCP_CMD_GET_RESOLUTION_INFO,           "Get General Information on DAQ Processing Resolution"},
233
    {XCP_CMD_GET_DAQ_LIST_INFO,             "Get Specific Information for a DAQ List"},
234
    {XCP_CMD_GET_DAQ_EVENT_INFO,            "Get Specific Information for an Event Channel"},
235
    {XCP_CMD_FREE_DAQ,                      "Clear Dynamic DAQ Configuration"},
236
    {XCP_CMD_ALLOC_DAQ,                     "Allocate DAQ Lists"},
237
    {XCP_CMD_ALLOC_ODT,                     "Allocate ODTs to a DAQ List"},
238
    {XCP_CMD_ALLOC_ODT_ENTRY,               "Allocate ODT Entries to an ODT"},
239
240
    {XCP_CMD_PROGRAM_START,                 "Indicate the Beginning of a Programming Sequence"},
241
    {XCP_CMD_PROGRAM_CLEAR,                 "Clear a Part of Non-volatile Memory"},
242
    {XCP_CMD_PROGRAM,                       "Program a Non-volatile Memory"},
243
    {XCP_CMD_PROGRAM_RESET,                 "Indicate the End of a Programming Sequence"},
244
    {XCP_CMD_GET_PGM_PROCESSOR_INFO,        "Get General Information on PGM Processor"},
245
    {XCP_CMD_GET_SECTOR_INFO,               "Get Specific Information for a SECTOR"},
246
    {XCP_CMD_PROGRAM_PREPARE,               "Prepare Non-volatile Memory Programming"},
247
    {XCP_CMD_PROGRAM_FORMAT,                "Set Data Format Before Programming"},
248
    {XCP_CMD_PROGRAM_NEXT,                  "Program a Non-volatile Memory Segment (Block Mode)"},
249
    {XCP_CMD_PROGRAM_MAX,                   "Program a Non-volatile Memory Segment (Fixed Size)"},
250
    {XCP_CMD_PROGRAM_VERIFY,                "Program Verify"},
251
252
    {XCP_CMD_WRITE_DAQ_MULTIPLE,            "Write Multiple Elements in ODT"},
253
    {XCP_CMD_TIME_CORRELATION_PROPERTIES,   "Time Correlation"},
254
    {XCP_CMD_DTO_CTR_PROPERTIES,            "DTO CTR Properties"},
255
256
    {XCP_CMD_2BYTE_FIRST_BYTE,              "2 Byte Command Prefix"},
257
    {0, NULL}
258
};
259
260
static const value_string cmd_code_names_2bytes[] = {
261
    {XCP_CMD_2BYTE_GET_VERSION,             "Get Version Information"},
262
    {XCP_CMD_2BYTE_SET_DAQ_PACKED_MODE,     "Set DAQ List Packet Mode"},
263
    {XCP_CMD_2BYTE_GET_DAQ_PACKED_MODE,     "Get DAQ List Packet Mode"},
264
    {XCP_CMD_2BYTE_XCP_SW_DEBUG,            "Software Debugging over XCP"},
265
    {XCP_CMD_2BYTE_XCP_POD_COMMANDS,        "XCP POD Commands"},
266
    {0, NULL}
267
};
268
269
static const value_string cmd_sw_dbg_names[] = {
270
    {XCP_CMD_SW_DBG_ATTACH,                 "Debugger Attach"},
271
    {XCP_CMD_SW_DBG_GET_VENDOR_INFO,        "Get Vendor Information"},
272
    {XCP_CMD_SW_DBG_GET_MODE_INFO,          "Get Debugging Properties"},
273
    {XCP_CMD_SW_DBG_GET_JTAG_ID,            "Get Target JTAG ID"},
274
    {XCP_CMD_SW_DBG_HALT_AFTER_RESET,       "Halt Target after Reset"},
275
    {XCP_CMD_SW_DBG_GET_HWIO_INFO,          "Get HW-IO Pin Information"},
276
    {XCP_CMD_SW_DBG_SET_HWIO_EVENT,         "HW-IO Event Control"},
277
    {XCP_CMD_SW_DBG_HWIO_CONTROL,           "HW-IO Pin State and Control"},
278
    {XCP_CMD_SW_DBG_EXCL_TARGET_ACCESS,     "Request Exclusive Target Interface Access"},
279
    {XCP_CMD_SW_DBG_SEQUENCE_MULTIPLE,      "Processing of Multiple JPL Debug Sequences"},
280
    {XCP_CMD_SW_DBG_LLT,                    "Low Level Telegram"},
281
    {XCP_CMD_SW_DBG_READ_MODIFY_WRITE,      "Read-Modify-Write"},
282
    {XCP_CMD_SW_DBG_WRITE,                  "Download from Master to Slave"},
283
    {XCP_CMD_SW_DBG_WRITE_NEXT,             "Download from Master to Slave (Block mode)"},
284
    {XCP_CMD_SW_DBG_WRITE_CAN1,             "Download from Master to Slave (CAN – Part 1)"},
285
    {XCP_CMD_SW_DBG_WRITE_CAN2,             "Download from Master to Slave (CAN – Part 2)"},
286
    {XCP_CMD_SW_DBG_WRITE_CAN_NEXT,         "Download from Master to Slave (CAN – Part 3)"},
287
    {XCP_CMD_SW_DBG_READ,                   "Upload from Slave to Master"},
288
    {XCP_CMD_SW_DBG_READ_CAN1,              "Upload from Slave to Master (CAN – Part 1)"},
289
    {XCP_CMD_SW_DBG_READ_CAN2,              "Upload from Slave to Master (CAN – Part 2)"},
290
    {XCP_CMD_SW_DBG_GET_TRI_DESC_TBL,       "Get TRI Parameter from Slave"},
291
    {XCP_CMD_SW_DBG_LLBT,                   "Low Level Byte Telegram"},
292
    {0, NULL}
293
};
294
295
static const value_string cmd_code_mnemonics[] = {
296
    {XCP_CMD_CONNECT,                       "CONNECT"},
297
    {XCP_CMD_DISCONNECT,                    "DISCONNECT"},
298
    {XCP_CMD_GET_STATUS,                    "GET_STATUS"},
299
    {XCP_CMD_SYNCH,                         "SYNCH"},
300
    {XCP_CMD_GET_COMM_MODE_INFO,            "GET_COMM_MODE_INFO"},
301
    {XCP_CMD_GET_ID,                        "GET_ID"},
302
    {XCP_CMD_SET_REQUEST,                   "SET_REQUEST"},
303
    {XCP_CMD_GET_SEED,                      "GET_SEED"},
304
    {XCP_CMD_UNLOCK,                        "UNLOCK"},
305
    {XCP_CMD_SET_MTA,                       "SET_MTA"},
306
    {XCP_CMD_UPLOAD,                        "UPLOAD"},
307
    {XCP_CMD_SHORT_UPLOAD,                  "SHORT_UPLOAD"},
308
    {XCP_CMD_BUILD_CHECKSUM,                "BUILD_CHECKSUM"},
309
    {XCP_CMD_TRANSPORT_LAYER_CMD,           "TRANSPORT_LAYER_CMD"},
310
    {XCP_CMD_USER_CMD,                      "USER_CMD"},
311
312
    {XCP_CMD_DOWNLOAD,                      "DOWNLOAD"},
313
    {XCP_CMD_DOWNLOAD_NEXT,                 "DOWNLOAD_NEXT"},
314
    {XCP_CMD_DOWNLOAD_MAX,                  "DOWNLOAD_MAX"},
315
    {XCP_CMD_SHORT_DOWNLOAD,                "SHORT_DOWNLOAD"},
316
    {XCP_CMD_MODIFY_BITS,                   "MODIFY_BITS"},
317
318
    {XCP_CMD_SET_CAL_PAGE,                  "SET_CAL_PAGE"},
319
    {XCP_CMD_GET_CAL_PAGE,                  "GET_CAL_PAGE"},
320
    {XCP_CMD_GET_PAG_PROCESSOR_INFO,        "GET_PAG_PROCESSOR_INFO"},
321
    {XCP_CMD_GET_SEGMENT_INFO,              "GET_SEGMENT_INFO"},
322
    {XCP_CMD_GET_PAGE_INFO,                 "GET_PAGE_INFO"},
323
    {XCP_CMD_SET_SEGMENT_MODE,              "SET_SEGMENT_MODE"},
324
    {XCP_CMD_GET_SEGMENT_MODE,              "GET_SEGMENT_MODE"},
325
    {XCP_CMD_COPY_CAL_PAGE,                 "COPY_CAL_PAGE"},
326
327
    {XCP_CMD_CLEAR_DAQ_LIST,                "CLEAR_DAQ_LIST"},
328
    {XCP_CMD_SET_DAQ_PTR,                   "SET_DAQ_PTR"},
329
    {XCP_CMD_WRITE_DAQ,                     "WRITE_DAQ"},
330
    {XCP_CMD_SET_DAQ_LIST_MODE,             "SET_DAQ_LIST_MODE"},
331
    {XCP_CMD_GET_DAQ_LIST_MODE,             "GET_DAQ_LIST_MODE"},
332
    {XCP_CMD_START_STOP_DAQ_LIST,           "START_STOP_DAQ_LIST"},
333
    {XCP_CMD_START_STOP_SYNCH,              "START_STOP_SYNCH"},
334
    {XCP_CMD_GET_DAQ_CLOCK,                 "GET_DAQ_CLOCK"},
335
    {XCP_CMD_READ_DAQ,                      "READ_DAQ"},
336
    {XCP_CMD_GET_DAQ_PROCESSOR_INFO,        "GET_DAQ_PROCESSOR_INFO"},
337
    {XCP_CMD_GET_RESOLUTION_INFO,           "GET_DAQ_RESOLUTION_INFO"},
338
    {XCP_CMD_GET_DAQ_LIST_INFO,             "GET_DAQ_LIST_INFO"},
339
    {XCP_CMD_GET_DAQ_EVENT_INFO,            "GET_DAQ_EVENT_INFO"},
340
341
    {XCP_CMD_FREE_DAQ,                      "FREE_DAQ"},
342
    {XCP_CMD_ALLOC_DAQ,                     "ALLOC_DAQ"},
343
    {XCP_CMD_ALLOC_ODT,                     "ALLOC_ODT"},
344
    {XCP_CMD_ALLOC_ODT_ENTRY,               "ALLOC_ODT_ENTRY"},
345
346
    {XCP_CMD_PROGRAM_START,                 "PROGRAM_START"},
347
    {XCP_CMD_PROGRAM_CLEAR,                 "PROGRAM_CLEAR"},
348
    {XCP_CMD_PROGRAM,                       "PROGRAM"},
349
    {XCP_CMD_PROGRAM_RESET,                 "PROGRAM_RESET"},
350
    {XCP_CMD_GET_PGM_PROCESSOR_INFO,        "GET_PGM_PROCESSOR_INFO"},
351
    {XCP_CMD_GET_SECTOR_INFO,               "GET_SECTOR_INFO"},
352
    {XCP_CMD_PROGRAM_PREPARE,               "PROGRAM_PREPARE"},
353
    {XCP_CMD_PROGRAM_FORMAT,                "PROGRAM_FORMAT"},
354
    {XCP_CMD_PROGRAM_NEXT,                  "PROGRAM_NEXT"},
355
    {XCP_CMD_PROGRAM_MAX,                   "PROGRAM_MAX"},
356
    {XCP_CMD_PROGRAM_VERIFY,                "PROGRAM_VERIFY"},
357
358
    {XCP_CMD_WRITE_DAQ_MULTIPLE,            "WRITE_DAQ_MULTIPLE"},
359
    {XCP_CMD_TIME_CORRELATION_PROPERTIES,   "TIME_CORRELATION_PROPERTIES"},
360
    {XCP_CMD_DTO_CTR_PROPERTIES,            "DTO_CTR_PROPERTIESs"},
361
362
    {XCP_CMD_2BYTE_FIRST_BYTE,              "PREFIX_2BYTE_COMMAND"},
363
364
    {0, NULL}
365
};
366
367
static const value_string cmd_code_mnemonics_2bytes[] = {
368
    {XCP_CMD_2BYTE_GET_VERSION,             "GET_VERSION"},
369
    {XCP_CMD_2BYTE_SET_DAQ_PACKED_MODE,     "SET_DAQ_PACKED_MODE"},
370
    {XCP_CMD_2BYTE_GET_DAQ_PACKED_MODE,     "GET_DAQ_PACKED_MODE"},
371
    {XCP_CMD_2BYTE_XCP_SW_DEBUG,            "SW_DBG_OVER_XCP"},
372
    {XCP_CMD_2BYTE_XCP_POD_COMMANDS,        "XCP_POD_COMMAND"},
373
    {0, NULL}
374
};
375
376
static const value_string sub_cmd_code_mnemonics_eth[] = {
377
    {XCP_SUB_CMD_ETH_GET_SLAVE_ID,          "GET_SLAVE_ID"},
378
    {XCP_SUB_CMD_ETH_GET_SLAVE_ID_EXT,      "GET_SLAVE_ID_EXTENDED"},
379
    {XCP_SUB_CMD_ETH_GET_SLAVE_IP_ADDR,     "GET_SLAVE_IP_ADDRESS"},
380
    {XCP_SUB_CMD_ETH_GET_DAQ_CLC_MCAST,     "GET_DAQ_CLOCK_MULTICAST"},
381
    {0, NULL}
382
};
383
384
static const value_string sub_cmd_code_mnemonics_can[] = {
385
    {XCP_SUB_CMD_CAN_GET_SLAVE_ID,          "GET_SLAVE_ID"},
386
    {XCP_SUB_CMD_CAN_GET_DAQ_ID,            "GET_DAQ_ID"},
387
    {XCP_SUB_CMD_CAN_SET_DAQ_ID,            "SET_DAQ_ID"},
388
    {XCP_SUB_CMD_CAN_GET_DAQ_CLC_MCAST,     "GET_DAQ_CLOCK_MULTICAST"},
389
    {0, NULL}
390
};
391
392
static const value_string cmd_sw_dbg_mnemonics[] = {
393
    {XCP_CMD_SW_DBG_ATTACH,                 "DBG_ATTACH"},
394
    {XCP_CMD_SW_DBG_GET_VENDOR_INFO,        "DBG_GET_VENDOR_INFO"},
395
    {XCP_CMD_SW_DBG_GET_MODE_INFO,          "DBG_GET_MODE_INFO"},
396
    {XCP_CMD_SW_DBG_GET_JTAG_ID,            "DBG_GET_JTAG_ID"},
397
    {XCP_CMD_SW_DBG_HALT_AFTER_RESET,       "DBG_HALT_AFTER_RESET"},
398
    {XCP_CMD_SW_DBG_GET_HWIO_INFO,          "DBG_GET_HWIO_INFO"},
399
    {XCP_CMD_SW_DBG_SET_HWIO_EVENT,         "DBG_SET_HWIO_EVENT"},
400
    {XCP_CMD_SW_DBG_HWIO_CONTROL,           "DBG_HWIO_CONTROL"},
401
    {XCP_CMD_SW_DBG_EXCL_TARGET_ACCESS,     "DBG_EXCLUSIVE_TARGET_ACCESS"},
402
    {XCP_CMD_SW_DBG_SEQUENCE_MULTIPLE,      "DBG_SEQUENCE_MULTIPLE"},
403
    {XCP_CMD_SW_DBG_LLT,                    "DBG_LLT"},
404
    {XCP_CMD_SW_DBG_READ_MODIFY_WRITE,      "DBG_READ_MODIFY_WRITE"},
405
    {XCP_CMD_SW_DBG_WRITE,                  "DBG_WRITE"},
406
    {XCP_CMD_SW_DBG_WRITE_NEXT,             "DBG_WRITE_NEXT"},
407
    {XCP_CMD_SW_DBG_WRITE_CAN1,             "DBG_WRITE_CAN1"},
408
    {XCP_CMD_SW_DBG_WRITE_CAN2,             "DBG_WRITE_CAN2"},
409
    {XCP_CMD_SW_DBG_WRITE_CAN_NEXT,         "DBG_WRITE_CAN_NEXT"},
410
    {XCP_CMD_SW_DBG_READ,                   "DBG_READ"},
411
    {XCP_CMD_SW_DBG_READ_CAN1,              "DBG_READ_CAN1"},
412
    {XCP_CMD_SW_DBG_READ_CAN2,              "DBG_READ_CAN2"},
413
    {XCP_CMD_SW_DBG_GET_TRI_DESC_TBL,       "DBG_GET_TRI_DESC_TBL"},
414
    {XCP_CMD_SW_DBG_LLBT,                   "DBG_LLBT"},
415
    {0, NULL}
416
};
417
418
static const value_string cmd_pod_mnemonics[] = {
419
    {XCP_CMD_POD_GET_INFO,                  "POD_GET_INFO"},
420
    {XCP_CMD_POD_SET_ACTIVE_CONFIG,         "POD_SET_ACTIVE_CONFIG"},
421
    {XCP_CMD_POD_MANAGE_TRANSFER,           "POD_MANAGE_TRANSFER"},
422
    {XCP_CMD_POD_DOWNLOAD,                  "POD_DOWNLOAD"},
423
    {XCP_CMD_POD_UPLOAD,                    "POD_UPLOAD"},
424
    {XCP_CMD_POD_GET_STATUS,                "POD_GET_STATUS"},
425
    {0, NULL}
426
};
427
428
static const value_string program_clear_mode_type[] = {
429
    {0, "Absolute Access Mode active"},
430
    {1, "Functional Access Mode active"},
431
    {0, NULL}
432
};
433
434
static const value_string daq_packed_mode_type[] = {
435
    {0, "Data not packed"},
436
    {1, "Element-grouped data packing"},
437
    {2, "Event-grouped data packing"},
438
    {0, NULL}
439
};
440
441
static const value_string daq_packed_timestamp_mode_type[] = {
442
    {0, "Single timestamp of last sample"},
443
    {1, "Single timestamp of first sample"},
444
    {2, "Event-grouped data packing"},
445
    {0, NULL}
446
};
447
448
static const value_string access_mode_type[] = {
449
    {1, "ECU access"},
450
    {2, "XCP access"},
451
    {0, NULL}
452
};
453
454
/* XCP_CMD_SET_DAQ_LIST_MODE */
455
16
#define SET_DAQ_LIST_MODE_PID_OFF           0x20
456
16
#define SET_DAQ_LIST_MODE_TSTAMP            0x10
457
16
#define SET_DAQ_LIST_MODE_DTO_CTR           0x08
458
16
#define SET_DAQ_LIST_MODE_DIR               0x02
459
16
#define SET_DAQ_LIST_MODE_ALT               0x01
460
461
462
/* XCP_CMD_START_STOP_DAQ_LIST */
463
static const value_string start_stop_daq_mode[] = {
464
    {0, "Stop"},
465
    {1, "Start"},
466
    {2, "Select"},
467
    {0, NULL}
468
};
469
470
static const true_false_string xcp_tfs_stim_daq = {
471
    "Stimulation (STIM)",
472
    "Data Acquisition (DAQ)"
473
};
474
475
/* XCP_CMD_START_STOP_SYNCH */
476
static const value_string start_stop_synch_mode[] = {
477
    {0, "Stop All"},
478
    {1, "Start Selected"},
479
    {2, "Stop Selected"},
480
    {3, "Prepare to Start Selected"},
481
    {0, NULL}
482
};
483
484
/* CMD: Connect */
485
static const value_string cmd_connect_mode[] = {
486
    {0,   "Normal"},
487
    {1,   "User-Defined"},
488
    {0, NULL}
489
};
490
491
static const true_false_string xcp_tfs_byte_order = {
492
    "Big Endian / Motorola",
493
    "Little Endian / Intel"
494
};
495
496
static const true_false_string xcp_tfs_protected = {
497
    "Protected with Seed & Key",
498
    "Not Protected with Seed & Key",
499
};
500
501
static const value_string comm_mode_address_granularity[] = {
502
    {0, "BYTE (1 byte)"},
503
    {1, "WORD (2 bytes)"},
504
    {2, "DWORD (4 bytes)"},
505
    {3, "reserved"},
506
    {0, NULL}
507
};
508
509
static const value_string get_id_req_id_type[] = {
510
    {0, "ASCII text"},
511
    {1, "ASAM-MC2 filename without path and extension"},
512
    {2, "ASAM-MC2 filename with path and extension"},
513
    {3, "URL where the ASAM-MC2 file can be found"},
514
    {4, "ASAM-MC2 file to upload"},
515
    {5, "ASAM-MC2 EPK"},
516
    {6, "ASAM-MC2 ECU"},
517
    {7, "ASAM POD SystemID"},
518
    {0, NULL}
519
};
520
521
static const value_string trigger_info_time_of_ts_sampl_type[] = {
522
    {0, "At Protocol Layer Command Processor"},
523
    {1, "Low Jitter, High Priority Interrupt"},
524
    {2, "Physical transmission to XCP master"},
525
    {3, "Physical reception of command"},
526
    {0, NULL}
527
};
528
529
static const value_string trigger_info_trigger_init_type[] = {
530
    {0, "Hardware trigger"},
531
    {1, "Event derived from XCP-independent time sync event"},
532
    {2, "GET_DAQ_CLOCK_MULTICAST"},
533
    {3, "GET_DAQ_CLOCK_MULTICAST via Time Sync Bridge"},
534
    {4, "State Change in Synt/Sync to Grandmaster Clock"},
535
    {5, "Leap second occurred on Grandmaster Clock"},
536
    {6, "Release of ECU reset"},
537
    {7, "Reserved"},
538
    {0, NULL}
539
};
540
541
static const value_string clock_format_type[] = {
542
    {0, "Not part of event payload"},
543
    {1, "DWORD"},
544
    {2, "DLONG/unsigned"},
545
    {3, "reserved"},
546
    {0, NULL}
547
};
548
549
static const true_false_string xcp_tfs_cluster_identifier = {
550
    "Present, when sent as response to TRIGGER_INITIATOR 2 or 3",
551
    "Not Present"
552
};
553
554
static const value_string daq_properties_overload_type[] = {
555
    {0, "No overload indication"},
556
    {1, "Overload indication in the MSB of PID"},
557
    {2, "Overload indication by Event Packet"},
558
    {3, "Not allowed"},
559
    {0, NULL}
560
};
561
562
static const true_false_string xcp_tfs_dynamic_static = {
563
    "Dynamic",
564
    "Static",
565
};
566
567
static const value_string daq_key_byte_id_field_type[] = {
568
    {0, "Absolute ODT number"},
569
    {1, "Relative ODT number, absolute DAQ list number (BYTE)"},
570
    {2, "Relative ODT number, absolute DAQ list number (WORD)"},
571
    {3, "Relative ODT number, absolute DAQ list number (WORD, aligned)"},
572
    {0, NULL}
573
};
574
575
static const value_string daq_key_byte_addr_ext_type[] = {
576
    {0, "Address extension can be different within one and the same ODT"},
577
    {1, "Address extension to be the same for all entries within one ODT"},
578
    {2, "Not allowed"},
579
    {3, "Address extension to be the same for all entries within one DAQ"},
580
    {0, NULL}
581
};
582
583
static const value_string optimization_type[] = {
584
    { 0, "OM_DEFAULT"},
585
    { 1, "OM_ODT_TYPE_16"},
586
    { 2, "OM_ODT_TYPE_32"},
587
    { 3, "OM_ODT_TYPE_64"},
588
    { 4, "OM_ODT_TYPE_ALIGNMENT"},
589
    { 5, "OM_MAX_ENTRY_SIZE"},
590
591
    { 9, "OM_ODT_TYPE_16 (strict)"},
592
    {10, "OM_ODT_TYPE_32 (strict)"},
593
    {11, "OM_ODT_TYPE_64 (strict)"},
594
    {0, NULL}
595
};
596
597
static const value_string daq_event_props_consistency[] = {
598
    {0, "Consistency on IDT level"},
599
    {1, "Consistency on DAQ level"},
600
    {2, "Consistency on Event Channel level"},
601
    {3, "No consistency available"},
602
    {0, NULL}
603
};
604
605
/* shared between XCP_CMD_GET_RESOLUTION_INFO and XCP_CMD_GET_DAQ_EVENT_INFO */
606
static const value_string xcp_time_unit[] = {
607
    {0, "1 ns"},
608
    {1, "10 ns"},
609
    {2, "100 ns"},
610
    {3, "1 µs"},
611
    {4, "10 µs"},
612
    {5, "100 µs"},
613
    {6, "1 ms"},
614
    {7, "10 ms"},
615
    {8, "100 ms"},
616
    {9, "1 s"},
617
    {10, "1 ps"},
618
    {11, "10 ps"},
619
    {12, "100 ps"},
620
    {0, NULL}
621
};
622
623
static const value_string transport_mode_eth_ip_version[] = {
624
    {0, "IPv4"},
625
    {0, NULL}
626
};
627
628
static const value_string get_seed_mode[] = {
629
    {0, "(first part of) seed"},
630
    {1, "remaining part of seed"},
631
    {0, NULL}
632
};
633
634
static const value_string checksum_types[] = {
635
    {0x01, "XCP_ADD_11"},
636
    {0x02, "XCP_ADD_12"},
637
    {0x03, "XCP_ADD_14"},
638
    {0x04, "XCP_ADD_22"},
639
    {0x05, "XCP_ADD_24"},
640
    {0x06, "XCP_ADD_44"},
641
    {0x07, "XCP_CRC_16"},
642
    {0x08, "XCP_CRC_16_CITT"},
643
    {0x09, "XCP_CRC_32"},
644
    {0xff, "XCP_USER_DEFINED"},
645
    {0, NULL}
646
};
647
648
static int proto_xcp;
649
650
static dissector_handle_t xcp_handle_udp;
651
static dissector_handle_t xcp_handle_tcp;
652
static dissector_handle_t xcp_handle_can;
653
654
/* Header fields */
655
static int hf_xcp_header_ethernet;
656
static int hf_xcp_length;
657
static int hf_xcp_counter;
658
659
static int hf_xcp_packet;
660
static int hf_xcp_pid_s2m;
661
static int hf_xcp_cmd_code;
662
static int hf_xcp_cmd_code_level1;
663
664
static int hf_xcp_reserved;
665
static int hf_xcp_unparsed;
666
static int hf_xcp_address;
667
668
static int hf_xcp_session_cfg_id;
669
670
static int hf_xcp_daq_list_number;
671
static int hf_xcp_odt_number;
672
static int hf_xcp_odt_entry_number;
673
static int hf_xcp_event_channel_number;
674
675
static int hf_xcp_logical_data_segment_number;
676
static int hf_xcp_logical_data_page_number;
677
678
static int hf_xcp_num_of_data_elements;
679
static int hf_xcp_address_extension;
680
static int hf_xcp_data_element_1byte;
681
static int hf_xcp_data_element_2bytes;
682
static int hf_xcp_data_element_4bytes;
683
static int hf_xcp_data_element_bytes;
684
685
/* XCP_CMD_CONNECT */
686
static int hf_xcp_conn_mode;
687
static int hf_xcp_conn_resource;
688
static int hf_xcp_conn_resource_dbg;
689
static int hf_xcp_conn_resource_pgm;
690
static int hf_xcp_conn_resource_stim;
691
static int hf_xcp_conn_resource_daq;
692
static int hf_xcp_conn_resource_cal_pag;
693
694
static int hf_xcp_conn_comm_mode_bsc;
695
static int hf_xcp_conn_comm_mode_bsc_optional;
696
static int hf_xcp_conn_comm_mode_bsc_sl_blk_mode;
697
static int hf_xcp_conn_comm_mode_bsc_addr_gran;
698
static int hf_xcp_conn_comm_mode_bsc_byte_order;
699
700
static int hf_xcp_conn_max_cto;
701
static int hf_xcp_conn_max_dto;
702
static int hf_xcp_conn_proto_layer_ver;
703
static int hf_xcp_conn_trans_layer_ver;
704
705
/* XCP_CMD_GET_STATUS */
706
static int hf_xcp_get_st_cur_ses;
707
static int hf_xcp_get_st_cur_ses_resume;
708
static int hf_xcp_get_st_cur_ses_daq_running;
709
static int hf_xcp_get_st_cur_ses_daq_cfg_lost;
710
static int hf_xcp_get_st_cur_ses_clear_daq_req;
711
static int hf_xcp_get_st_cur_ses_store_daq_req;
712
static int hf_xcp_get_st_cur_ses_calpag_cfg_lst;
713
static int hf_xcp_get_st_cur_ses_store_cal_req;
714
715
static int hf_xcp_get_st_cur_res_pro_st;
716
static int hf_xcp_get_st_cur_res_pro_st_dbg;
717
static int hf_xcp_get_st_cur_res_pro_st_pgm;
718
static int hf_xcp_get_st_cur_res_pro_st_stim;
719
static int hf_xcp_get_st_cur_res_pro_st_daq;
720
static int hf_xcp_get_st_cur_res_pro_st_calpag;
721
722
static int hf_xcp_get_st_cur_state_number;
723
724
/* XCP_CMD_GET_COMM_MODE_INFO */
725
static int hf_xcp_comm_mode_res1;
726
static int hf_xcp_comm_mode_opt;
727
static int hf_xcp_comm_mode_opt_interl;
728
static int hf_xcp_comm_mode_opt_mas_blck_mode;
729
static int hf_xcp_comm_mode_res2;
730
static int hf_xcp_comm_mode_max_bs;
731
static int hf_xcp_comm_mode_min_st;
732
static int hf_xcp_comm_mode_queue_size;
733
static int hf_xcp_comm_mode_driver_version;
734
735
/* XCP_CMD_GET_ID */
736
static int hf_xcp_get_id_req_id_type;
737
738
static int hf_xcp_get_id_mode;
739
static int hf_xcp_get_id_mode_compressed_encrypted;
740
static int hf_xcp_get_id_mode_transfer_mode;
741
static int hf_xcp_get_id_res;
742
static int hf_xcp_get_id_length;
743
static int hf_xcp_get_id_id_string;
744
static int hf_xcp_get_id_id_bytes;
745
746
/* XCP_CMD_SET_REQUEST */
747
static int hf_xcp_set_req_md;
748
static int hf_xcp_set_req_md_clr_daq_cfg_lost;
749
static int hf_xcp_set_req_md_clr_cal_pag_cfg_lost;
750
static int hf_xcp_set_req_md_clr_daq_req;
751
static int hf_xcp_set_req_md_str_daq_req_resume;
752
static int hf_xcp_set_req_md_str_daq_req_no_resume;
753
static int hf_xcp_set_req_md_str_cal_req;
754
755
/* GET_SEED */
756
static int hf_xcp_get_seed_mode;
757
static int hf_xcp_get_seed_resource;
758
static int hf_xcp_get_seed_dont_care;
759
760
static int hf_xcp_get_seed_length_of_seed;
761
static int hf_xcp_get_seed_seed;
762
763
/* UNLOCK */
764
static int hf_xcp_unlock_length_of_key;
765
static int hf_xcp_unlock_key;
766
767
/* DTO */
768
static int hf_xcp_data_element_name;
769
770
/* XCP_CMD_BUILD_CHECKSUM */
771
static int hf_xcp_build_chksum_res1;
772
static int hf_xcp_build_chksum_res2;
773
static int hf_xcp_build_chksum_block_size;
774
775
static int hf_xcp_build_chksum_type;
776
static int hf_xcp_build_chksum_res3;
777
static int hf_xcp_build_chksum;
778
779
/* XCP_CMD_TRANSPORT_LAYER */
780
static int hf_xcp_sub_command_eth;
781
static int hf_xcp_sub_command_eth_port;
782
static int hf_xcp_sub_command_eth_ipv4;
783
static int hf_xcp_sub_command_eth_reserved;
784
static int hf_xcp_sub_command_eth_ip_version;
785
786
static int hf_xcp_sub_command_can;
787
788
/* XCP_CMD_SET_CAL_PAGE */
789
static int hf_xcp_set_cal_page_mode;
790
static int hf_xcp_set_cal_page_mode_all;
791
static int hf_xcp_set_cal_page_mode_xcp;
792
static int hf_xcp_set_cal_page_mode_ecu;
793
794
/* XCP_CMD_GET_CAL_PAGE */
795
static int hf_xcp_access_mode;
796
797
/* XCP_CMD_SET_SEGMENT_MODE */
798
static int hf_xcp_set_segment_mode;
799
static int hf_xcp_set_segment_mode_freeze;
800
static int hf_xcp_set_segment_mode_segment;
801
802
/* XCP_CMD_COPY_CAL_PAGE */
803
static int hf_xcp_logical_data_segm_num_src;
804
static int hf_xcp_logical_data_page_num_src;
805
static int hf_xcp_logical_data_segm_num_dst;
806
static int hf_xcp_logical_data_page_num_dst;
807
808
/* XCP_CMD_WRITE_DAQ */
809
static int hf_xcp_bit_offset;
810
static int hf_xcp_size_of_daq_element;
811
812
/* XCP_CMD_SET_DAQ_LIST_MODE */
813
static int hf_xcp_set_daq_list_mode_mode;
814
static int hf_xcp_set_daq_list_mode_mode_pid_off;
815
static int hf_xcp_set_daq_list_mode_mode_timestamp;
816
static int hf_xcp_set_daq_list_mode_mode_dto_ctr;
817
static int hf_xcp_set_daq_list_mode_mode_dir;
818
static int hf_xcp_set_daq_list_mode_mode_alt;
819
static int hf_xcp_transmission_prescaler;
820
static int hf_xcp_daq_list_priority;
821
822
823
/* XCP_CMD_START_STOP_DAQ_LIST */
824
static int hf_xcp_start_stop_daq_mode;
825
826
static int hf_xcp_first_pid;
827
828
829
/* XCP_CMD_START_STOP_SYNCH */
830
static int hf_xcp_start_stop_synch_mode;
831
832
/* XCP_CMD_GET_DAQ_CLOCK */
833
static int hf_xcp_trigger_info;
834
static int hf_xcp_trigger_info_time_of_ts_sampl;
835
static int hf_xcp_trigger_info_trigger_init;
836
static int hf_xcp_payload_fmt;
837
static int hf_xcp_payload_fmt_cluster_ident;
838
static int hf_xcp_payload_fmt_fmt_ecu;
839
static int hf_xcp_payload_fmt_fmt_grandm;
840
static int hf_xcp_payload_fmt_xcp_slv;
841
static int hf_xcp_payload_timestamp_legacy;
842
/* TODO: add optional parameters */
843
844
845
/* XCP_CMD_GET_DAQ_PROCESSOR_INFO */
846
static int hf_xcp_daq_props;
847
static int hf_xcp_daq_props_overload;
848
static int hf_xcp_daq_props_pid_off_supported;
849
static int hf_xcp_daq_props_timestamp_supported;
850
static int hf_xcp_daq_props_bit_stim_supported;
851
static int hf_xcp_daq_props_resume_supported;
852
static int hf_xcp_daq_props_prescaler_supported;
853
static int hf_xcp_daq_props_config_type;
854
855
static int hf_xcp_max_daq;
856
static int hf_xcp_max_event_channel;
857
static int hf_xcp_min_daq;
858
static int hf_xcp_daq_key_byte;
859
static int hf_xcp_daq_key_byte_id_field;
860
static int hf_xcp_daq_key_byte_addr_ext;
861
static int hf_xcp_daq_key_byte_optimization;
862
863
/* XCP_CMD_GET_RESOLUTION_INFO */
864
static int hf_xcp_granularity_odt_entry_size_daq;
865
static int hf_xcp_max_odt_entry_size_daq;
866
static int hf_xcp_granularity_odt_entry_size_stim;
867
static int hf_xcp_max_odt_entry_size_stim;
868
static int hf_xcp_timestamp_mode;
869
static int hf_xcp_timestamp_mode_time_unit;
870
static int hf_xcp_timestamp_mode_timestamp_fixed;
871
static int hf_xcp_timestamp_mode_timestamp_size;
872
static int hf_xcp_timestamp_ticks;
873
874
/* XCP_CMD_GET_DAQ_LIST_INFO */
875
static int hf_xcp_daq_list_properties;
876
static int hf_xcp_daq_list_properties_packed;
877
static int hf_xcp_daq_list_properties_stim;
878
static int hf_xcp_daq_list_properties_daq;
879
static int hf_xcp_daq_list_properties_event_fixed;
880
static int hf_xcp_daq_list_properties_predefined;
881
static int hf_xcp_daq_list_max_odt;
882
static int hf_xcp_daq_list_max_odt_entries;
883
static int hf_xcp_daq_list_fixed_event;
884
885
886
/* XCP_CMD_GET_DAQ_EVENT_INFO */
887
static int hf_xcp_daq_event_properties;
888
static int hf_xcp_daq_event_properties_consistency;
889
static int hf_xcp_daq_event_properties_packed;
890
static int hf_xcp_daq_event_properties_stim;
891
static int hf_xcp_daq_event_properties_daq;
892
893
static int hf_xcp_max_daq_list;
894
static int hf_xcp_event_channel_name_length;
895
static int hf_xcp_event_channel_time_cycle;
896
static int hf_xcp_event_channel_time_unit;
897
static int hf_xcp_event_channel_priority;
898
899
/* XCP_CMD_ALLOC_DAQ */
900
static int hf_xcp_daq_count;
901
902
/* XCP_CMD_ALLOC_ODT */
903
static int hf_xcp_odt_count;
904
905
/* XCP_CMD_ALLOC_ODT_ENTRY */
906
static int hf_xcp_odt_entries_count;
907
908
/* PROGRAM_START */
909
static int hf_xcp_comm_mode_pgm;
910
static int hf_xcp_comm_mode_pgm_slave_block_mode;
911
static int hf_xcp_comm_mode_pgm_interleaved_mode;
912
static int hf_xcp_comm_mode_pgm_master_block_mode;
913
static int hf_xcp_max_cto_pgm;
914
static int hf_xcp_max_bs_pgm;
915
static int hf_xcp_min_st_pgm;
916
static int hf_xcp_queue_size_pgm;
917
918
/* 0xD1 PROGRAM_CLEAR */
919
static int hf_xcp_program_clear_mode;
920
static int hf_xcp_program_clear_range_abs;
921
static int hf_xcp_program_clear_range_fct;
922
static int hf_xcp_program_clear_range_fct_1;
923
static int hf_xcp_program_clear_range_fct_2;
924
static int hf_xcp_program_clear_range_fct_4;
925
926
/* 0xC0 0x0 GET_VERSION */
927
static int hf_xcp_version_proto_major;
928
static int hf_xcp_version_proto_minor;
929
static int hf_xcp_version_transp_layer_major;
930
static int hf_xcp_version_transp_layer_minor;
931
932
/* 0xC0 0x01SET_DAQ_PACKED_MODE */
933
static int hf_xcp_daq_packed_mode;
934
static int hf_xcp_packed_timestamp_mode;
935
static int hf_xcp_packed_timestamp_mode_flags;
936
static int hf_xcp_packed_sample_count;
937
938
/* 0xC0 0xFC SW DEBUG over XCP */
939
static int hf_xcp_debug_command;
940
941
/* 0xC0 0xFD XCP POD */
942
static int hf_xcp_pod_command;
943
944
static int ett_xcp;
945
static int ett_xcp_header;
946
static int ett_xcp_packet;
947
static int ett_xcp_resource_flags;
948
static int ett_xcp_comm_mode_basic_flags;
949
static int ett_xcp_current_session_status_flags;
950
static int ett_xcp_current_res_protec_status;
951
static int ett_xcp_comm_mode_optional;
952
static int ett_xcp_get_id_mode_parameter;
953
static int ett_xcp_set_request_mode;
954
static int ett_xcp_set_cal_page_mode;
955
static int ett_xcp_trigger_info;
956
static int ett_xcp_payload_format;
957
static int ett_xcp_daq_properties;
958
static int ett_xcp_daq_key_byte;
959
static int ett_xcp_timestamp_mode;
960
static int ett_xcp_daq_list_properties;
961
static int ett_xcp_comm_mode_pgm;
962
static int ett_xcp_daq_event_properties;
963
static int ett_xcp_set_segment_mode_mode;
964
static int ett_xcp_set_daq_list_mode_mode;
965
static int ett_xcp_clear_program_range_fct;
966
static int ett_xcp_set_daq_packed_mode_timestamp_mode;
967
static int ett_xcp_element;
968
969
/* expert info items */
970
static expert_field ei_xcp_not_implemented;
971
972
void proto_register_xcp(void);
973
void proto_reg_handoff_xcp(void);
974
975
typedef struct _xcp_odt_entry {
976
    uint32_t                        ecu_id;
977
    uint32_t                        addr_ext;
978
    uint32_t                        address;
979
    char                           *name;
980
981
    uint32_t                        size;
982
} xcp_odt_entry_t;
983
984
typedef struct _xcp_odt {
985
    uint32_t                        odt_number;
986
987
    uint32_t                        pid;
988
989
    uint32_t                        number_of_odt_entries;
990
    wmem_array_t *                  current_odt_entries;
991
} xcp_odt_t;
992
993
typedef struct _xcp_daq {
994
    uint32_t                        daq_number;
995
996
    uint32_t                        number_of_odts;
997
    wmem_array_t *                  current_odts;
998
} xcp_daq_t;
999
1000
0
#define XCP_MESSAGE_CMD_UNKNOWN 0xFFFFFFFF
1001
typedef struct _xcp_message {
1002
    bool                            m2s;
1003
    uint32_t                        cmd;
1004
    uint32_t                        cmd_lvl1;
1005
    uint32_t                        transport_layer_sub_cmd;
1006
    uint32_t                        cmd_sw_debug;
1007
    uint32_t                        cmd_pod;
1008
    uint32_t                        number_of_elements;
1009
    struct _xcp_message             *peer_message;
1010
1011
    uint32_t                        current_daq_list_number;
1012
1013
    uint32_t                        number_of_daqs;
1014
    wmem_array_t *                  current_daqs;
1015
} xcp_message_t;
1016
1017
#define INIT_XCP_MESSAGE_T(X) \
1018
0
    (X)->m2s = true; \
1019
0
    (X)->cmd = XCP_MESSAGE_CMD_UNKNOWN; \
1020
0
    (X)->cmd_lvl1 = XCP_MESSAGE_CMD_UNKNOWN; \
1021
0
    (X)->transport_layer_sub_cmd = XCP_MESSAGE_CMD_UNKNOWN; \
1022
0
    (X)->cmd_sw_debug = XCP_MESSAGE_CMD_UNKNOWN; \
1023
0
    (X)->cmd_pod = XCP_MESSAGE_CMD_UNKNOWN; \
1024
0
    (X)->number_of_elements = 0; \
1025
0
    (X)->peer_message = NULL; \
1026
0
    (X)->current_daq_list_number = 0xffffffff; \
1027
0
    (X)->number_of_daqs = 0; \
1028
0
    (X)->current_daqs = NULL;
1029
1030
typedef struct _xcp_stream {
1031
    xcp_message_t                  *last_m2s;
1032
    xcp_message_t                  *last_s2m;
1033
    uint32_t                        addr_granularity;
1034
    uint16_t                        ecu_id;
1035
    unsigned int                    endianess;
1036
    bool                            timestamp_extended;
1037
1038
    address                         s_addr;
1039
    uint16_t                        s_port_number;
1040
1041
    uint32_t                        number_of_daqs;
1042
    wmem_array_t *                  current_daqs;
1043
1044
    uint32_t                        current_daq;
1045
    uint32_t                        current_odt;
1046
    uint32_t                        current_odt_entry;
1047
1048
    wmem_map_t                     *pid_map;
1049
1050
} xcp_stream_t;
1051
1052
static uint32_t global_xcp_address_granularity_default = 0;
1053
1054
/* Cannot use wmem_file_scope() but since profile stays the same, this should be ok. */
1055
#define INIT_XCP_STREAM_T(X) \
1056
0
    (X)->last_m2s = NULL; \
1057
0
    (X)->last_s2m = NULL; \
1058
0
    (X)->addr_granularity = (global_xcp_address_granularity_default); \
1059
0
    (X)->ecu_id = 0; \
1060
0
    (X)->endianess = ENC_LITTLE_ENDIAN; \
1061
0
    (X)->timestamp_extended = false; \
1062
0
    clear_address(&((X)->s_addr)); \
1063
0
    (X)->s_port_number = 0; \
1064
0
    (X)->number_of_daqs = 0; \
1065
0
    (X)->current_daqs = NULL; \
1066
0
    (X)->current_daq = 0xFFFFFFFF; \
1067
0
    (X)->current_odt = 0xFFFFFFFF; \
1068
0
    (X)->current_odt_entry = 0xFFFFFFFF; \
1069
0
    (X)->pid_map = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
1070
1071
1072
/*** Configuration ***/
1073
/* Addresses */
1074
typedef struct _xcp_memory_addresses_uat {
1075
    uint32_t                        ecu_id;
1076
    uint32_t                        addr_ext;
1077
    uint32_t                        address;
1078
    char                           *name;
1079
} xcp_memory_addresses_uat_t;
1080
1081
static xcp_memory_addresses_uat_t  *xcp_memory_addresses;
1082
static unsigned                     xcp_memory_addresses_num;
1083
static GHashTable                  *data_xcp_memory_addresses;
1084
1085
1086
/* Ethernet Mapping */
1087
typedef struct _xcp_eth_mapping {
1088
    address                         addr;
1089
    uint8_t                         port_type;
1090
    uint16_t                        port_number;
1091
    uint16_t                        ecu_id;
1092
1093
    xcp_stream_t                   *stream;
1094
} xcp_eth_mapping_t;
1095
1096
typedef struct _xcp_eth_mapping_uat {
1097
    uint8_t                         protocol;
1098
    char                           *ip_address;
1099
    uint8_t                         port_type;
1100
    uint32_t                        port_number;
1101
    uint32_t                        ecu_id;
1102
} xcp_eth_mapping_uat_t;
1103
1104
static xcp_eth_mapping_uat_t       *xcp_uat_eth_mappings;
1105
static uint32_t                     xcp_uat_eth_mapping_num;
1106
static uint32_t                     xcp_uat_eth_mapping_num_current = 0;
1107
static xcp_eth_mapping_t           *xcp_eth_mappings_priv;
1108
static GHashTable                  *data_xcp_eth_mappings = NULL;
1109
1110
0
#define XCP_PROTO_IPV4  1
1111
0
#define XCP_PROTO_IPV6  2
1112
0
#define XCP_PROTO_ANY   3
1113
1114
0
#define XCP_PORT_NONE   0
1115
0
#define XCP_PORT_UDP    1
1116
0
#define XCP_PORT_TCP    2
1117
1118
static const value_string xcp_proto_type_vals[] = {
1119
  { XCP_PROTO_IPV4, "IPv4" },
1120
  { XCP_PROTO_IPV6, "IPv6" },
1121
  { XCP_PROTO_ANY, "ANY" },
1122
  { 0x00, NULL }
1123
};
1124
1125
static const value_string xcp_port_type_vals[] = {
1126
  { XCP_PORT_UDP, "UDP" },
1127
  { XCP_PORT_TCP, "TCP" },
1128
  { 0x00, NULL }
1129
};
1130
1131
1132
/* CAN Mapping */
1133
typedef struct _xcp_can_mapping {
1134
    uint16_t                        bus_id;
1135
    uint32_t                        can_id_m_to_s;
1136
    uint32_t                        can_id_s_to_m;
1137
    uint16_t                        ecu_id;
1138
1139
    xcp_stream_t                   *stream;
1140
} xcp_can_mapping_t;
1141
1142
typedef struct _xcp_can_mapping_uat {
1143
    uint32_t                        bus_id;
1144
    uint32_t                        can_id_m_to_s;
1145
    uint32_t                        can_id_s_to_m;
1146
    uint32_t                        ecu_id;
1147
} xcp_can_mapping_uat_t;
1148
1149
static xcp_can_mapping_uat_t       *xcp_uat_can_mappings;
1150
static uint32_t                     xcp_uat_can_mapping_num;
1151
static uint32_t                     xcp_uat_can_mapping_num_current = 0;
1152
static xcp_can_mapping_t           *xcp_can_mappings_priv = NULL;
1153
static GHashTable                  *data_xcp_can_mappings = NULL;
1154
1155
1156
/* UAT: XCP Memory Addresses */
1157
0
UAT_HEX_CB_DEF(xcp_memory_addresses,        ecu_id,     xcp_memory_addresses_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_memory_addresses_ecu_id_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_memory_addresses_ecu_id_tostr_cb
1158
0
UAT_HEX_CB_DEF(xcp_memory_addresses,        addr_ext,   xcp_memory_addresses_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_memory_addresses_addr_ext_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_memory_addresses_addr_ext_tostr_cb
1159
0
UAT_HEX_CB_DEF(xcp_memory_addresses,        address,    xcp_memory_addresses_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_memory_addresses_address_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_memory_addresses_address_tostr_cb
1160
0
UAT_CSTRING_CB_DEF(xcp_memory_addresses,    name,       xcp_memory_addresses_uat_t)
1161
1162
static uint64_t
1163
0
xcp_memory_address_calc_key(uint16_t ecu_id, uint8_t addr_ext, uint32_t memory_address) {
1164
0
    return ((uint64_t)ecu_id) << 40 | ((uint64_t)addr_ext) << 32 | (uint64_t)memory_address;
1165
0
}
1166
1167
static char *
1168
0
xcp_lookup_memory_address(uint16_t ecu_id, uint8_t addr_ext, uint32_t memory_address) {
1169
0
    uint64_t key = xcp_memory_address_calc_key(ecu_id, addr_ext, memory_address);
1170
1171
0
    if (data_xcp_memory_addresses == NULL) {
1172
0
        return NULL;
1173
0
    }
1174
1175
0
    return (char *)g_hash_table_lookup(data_xcp_memory_addresses, &key);
1176
0
}
1177
1178
static void *
1179
0
copy_xcp_memory_addresses_cb(void *n, const void *o, size_t size _U_) {
1180
0
    xcp_memory_addresses_uat_t        *new_rec = (xcp_memory_addresses_uat_t *)n;
1181
0
    const xcp_memory_addresses_uat_t  *old_rec = (const xcp_memory_addresses_uat_t *)o;
1182
1183
0
    new_rec->ecu_id = old_rec->ecu_id;
1184
0
    new_rec->addr_ext = old_rec->addr_ext;
1185
0
    new_rec->address = old_rec->address;
1186
0
    new_rec->name = g_strdup(old_rec->name);
1187
0
    return new_rec;
1188
0
}
1189
1190
static bool
1191
0
update_xcp_memory_addresses_cb(void *r, char **err) {
1192
0
    xcp_memory_addresses_uat_t *rec = (xcp_memory_addresses_uat_t *)r;
1193
1194
0
    if (rec->name == NULL || rec->name[0] == 0) {
1195
0
        *err = g_strdup("Name cannot be empty");
1196
0
        return false;
1197
0
    }
1198
1199
0
    if ((rec->ecu_id) > 0xfffe) {
1200
0
        *err = g_strdup_printf("We currently only support 16bit ECU-IDs (0x%x) up to 0xfffe", rec->ecu_id);
1201
0
        return false;
1202
0
    }
1203
1204
0
    return true;
1205
0
}
1206
1207
static void
1208
0
free_xcp_memory_addresses_cb(void *r) {
1209
0
    xcp_memory_addresses_uat_t *rec = (xcp_memory_addresses_uat_t *)r;
1210
1211
    /* freeing result of g_strdup */
1212
0
    g_free(rec->name);
1213
0
    rec->name = NULL;
1214
0
}
1215
1216
static void
1217
16
reset_xcp_memory_addresses_cb(void) {
1218
    /* destroy old hash table, if it exists */
1219
16
    if (data_xcp_memory_addresses) {
1220
0
        g_hash_table_destroy(data_xcp_memory_addresses);
1221
0
        data_xcp_memory_addresses = NULL;
1222
0
    }
1223
16
}
1224
1225
static void
1226
16
post_update_xcp_memory_addresses_cb(void) {
1227
16
    reset_xcp_memory_addresses_cb();
1228
1229
    /* create new hash table */
1230
16
    data_xcp_memory_addresses = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, NULL);
1231
1232
16
    for (unsigned i = 0; i < xcp_memory_addresses_num; i++) {
1233
0
        uint64_t *key = g_new(uint64_t, 1);
1234
0
        *key = xcp_memory_address_calc_key((uint16_t)xcp_memory_addresses[i].ecu_id, (uint8_t)xcp_memory_addresses[i].addr_ext, xcp_memory_addresses[i].address);
1235
0
        g_hash_table_insert(data_xcp_memory_addresses, key, xcp_memory_addresses[i].name);
1236
0
    }
1237
16
}
1238
1239
1240
/* UAT: Ethernet Mapping */
1241
0
UAT_VS_DEF(xcp_uat_eth_mappings,            protocol,       xcp_eth_mapping_uat_t, uint8_t, XCP_PROTO_IPV4, "IPv4")
Unexecuted instantiation: packet-xcp.c:xcp_uat_eth_mappings_protocol_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_uat_eth_mappings_protocol_tostr_cb
1242
0
UAT_CSTRING_CB_DEF(xcp_uat_eth_mappings,    ip_address,     xcp_eth_mapping_uat_t)
1243
0
UAT_VS_DEF(xcp_uat_eth_mappings,            port_type,      xcp_eth_mapping_uat_t, uint8_t, XCP_PORT_TCP, "TCP")
Unexecuted instantiation: packet-xcp.c:xcp_uat_eth_mappings_port_type_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_uat_eth_mappings_port_type_tostr_cb
1244
0
UAT_DEC_CB_DEF(xcp_uat_eth_mappings,        port_number,    xcp_eth_mapping_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_uat_eth_mappings_port_number_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_uat_eth_mappings_port_number_tostr_cb
1245
0
UAT_HEX_CB_DEF(xcp_uat_eth_mappings,        ecu_id,         xcp_eth_mapping_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_uat_eth_mappings_ecu_id_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_uat_eth_mappings_ecu_id_tostr_cb
1246
1247
static uint64_t
1248
0
xcp_eth_mapping_calc_key(const address *addr, const uint8_t xcp_port_type, const uint16_t port) {
1249
0
    uint64_t hash = ((uint64_t)xcp_port_type) << 16 | (uint64_t)port;
1250
1251
0
    return add_address_to_hash64(hash, addr);
1252
0
}
1253
1254
static void
1255
16
register_xcp_eth(void) {
1256
16
    uint32_t i;
1257
16
    for (i = 0; i < xcp_uat_eth_mapping_num; i++) {
1258
0
        uint16_t port_number = xcp_uat_eth_mappings[i].port_number;
1259
1260
0
        switch (xcp_uat_eth_mappings[i].port_type) {
1261
0
        case XCP_PORT_UDP:
1262
0
            if (xcp_handle_udp != NULL) {
1263
0
                dissector_add_uint("udp.port", port_number, xcp_handle_udp);
1264
0
            }
1265
0
            break;
1266
0
        case XCP_PORT_TCP:
1267
0
            if (xcp_handle_tcp != NULL) {
1268
0
                dissector_add_uint("tcp.port", port_number, xcp_handle_tcp);
1269
0
            }
1270
0
            break;
1271
0
        }
1272
0
    }
1273
16
}
1274
1275
static void *
1276
0
copy_xcp_eth_mapping_cb(void *n, const void *o, size_t size _U_) {
1277
0
    xcp_eth_mapping_uat_t *new_rec = (xcp_eth_mapping_uat_t *)n;
1278
0
    const xcp_eth_mapping_uat_t *old_rec = (const xcp_eth_mapping_uat_t *)o;
1279
1280
0
    new_rec->protocol = old_rec->protocol;
1281
0
    new_rec->ip_address = g_strdup(old_rec->ip_address);
1282
0
    new_rec->port_type = old_rec->port_type;
1283
0
    new_rec->port_number = old_rec->port_number;
1284
0
    new_rec->ecu_id = old_rec->ecu_id;
1285
1286
0
    return new_rec;
1287
0
}
1288
1289
static bool
1290
0
update_xcp_eth_mapping_cb(void *r, char **err) {
1291
0
    xcp_eth_mapping_uat_t *rec = (xcp_eth_mapping_uat_t *)r;
1292
1293
0
    if ((rec->port_type) != XCP_PROTO_IPV4 && (rec->port_type) != XCP_PROTO_IPV6) {
1294
0
        *err = g_strdup_printf("Invalid Proto Type (0x%d)", rec->protocol);
1295
0
        return false;
1296
0
    }
1297
1298
    /* TODO: check ip_address */
1299
1300
0
    if ((rec->port_type) != XCP_PORT_UDP && (rec->port_type) != XCP_PORT_TCP) {
1301
0
        *err = g_strdup_printf("Invalid Port Type (0x%d)", rec->port_type);
1302
0
        return false;
1303
0
    }
1304
1305
0
    if ((rec->port_number) > 0xffff) {
1306
0
        *err = g_strdup_printf("Invalid Port Number (0x%d)", rec->port_number);
1307
0
        return false;
1308
0
    }
1309
1310
0
    if ((rec->ecu_id) > 0xffff) {
1311
0
        *err = g_strdup_printf("We currently only support 16bit ECU-IDs (0x%x) up to 0xffff", rec->ecu_id);
1312
0
        return false;
1313
0
    }
1314
1315
0
    return true;
1316
0
}
1317
1318
static void
1319
0
free_xcp_eth_mapping_cb(void *r) {
1320
0
    xcp_eth_mapping_uat_t *rec = (xcp_eth_mapping_uat_t *)r;
1321
1322
0
    if (rec != NULL) {
1323
        /* freeing result of g_strdup */
1324
0
        g_free(rec->ip_address);
1325
0
        rec->ip_address = NULL;
1326
0
    }
1327
0
}
1328
1329
static xcp_eth_mapping_t *
1330
0
eth_mapping_uat_entry_to_eth_mapping_entry(uint32_t i) {
1331
0
    xcp_eth_mapping_t *ret = &(xcp_eth_mappings_priv[i]);
1332
1333
0
    clear_address(&(ret->addr));
1334
1335
0
    switch (xcp_uat_eth_mappings[i].protocol) {
1336
0
    case XCP_PROTO_IPV4: {
1337
0
        ws_in4_addr tmp4;
1338
0
        if (ws_inet_pton4(xcp_uat_eth_mappings[i].ip_address, &tmp4)) {
1339
0
            alloc_address_wmem(wmem_epan_scope(), &(ret->addr), AT_IPv4, 4, &tmp4);
1340
0
        }
1341
0
    }
1342
0
        break;
1343
0
    case XCP_PROTO_IPV6: {
1344
0
        ws_in6_addr tmp6;
1345
0
        if (ws_inet_pton6(xcp_uat_eth_mappings[i].ip_address, &tmp6)) {
1346
0
            alloc_address_wmem(wmem_epan_scope(), &(ret->addr), AT_IPv6, sizeof(ws_in6_addr), &tmp6);
1347
0
        }
1348
0
    }
1349
0
        break;
1350
1351
0
    case XCP_PROTO_ANY:
1352
0
        clear_address(&(ret->addr));
1353
0
    }
1354
1355
0
    ret->port_type      = xcp_uat_eth_mappings[i].port_type;
1356
0
    ret->port_number    = (uint16_t)xcp_uat_eth_mappings[i].port_number;
1357
0
    ret->ecu_id         = (uint16_t)xcp_uat_eth_mappings[i].ecu_id;
1358
0
    ret->stream         = NULL;
1359
1360
0
    return ret;
1361
0
}
1362
1363
static void
1364
16
reset_xcp_eth_mapping_cb(void) {
1365
    /* destroy old hash table, if it exists */
1366
16
    if (data_xcp_eth_mappings) {
1367
0
        g_hash_table_destroy(data_xcp_eth_mappings);
1368
0
        data_xcp_eth_mappings = NULL;
1369
0
    }
1370
16
}
1371
1372
static void
1373
16
post_update_xcp_eth_mapping_cb(void) {
1374
    /* destroy the local xcp_uat_eth_mappings array */
1375
16
    if (xcp_eth_mappings_priv != NULL) {
1376
0
        for (uint32_t i = 0; i < xcp_uat_eth_mapping_num_current; i++) {
1377
0
            if (xcp_eth_mappings_priv[i].stream != NULL) {
1378
0
                wmem_free(wmem_epan_scope(), xcp_eth_mappings_priv[i].stream);
1379
0
                xcp_eth_mappings_priv[i].stream = NULL;
1380
0
            }
1381
0
            free_address_wmem(wmem_epan_scope(), &(xcp_eth_mappings_priv[i].addr));
1382
0
        }
1383
1384
0
        wmem_free(wmem_epan_scope(), xcp_eth_mappings_priv);
1385
0
        xcp_eth_mappings_priv = NULL;
1386
0
    }
1387
1388
16
    xcp_eth_mappings_priv = (xcp_eth_mapping_t *)wmem_alloc0_array(wmem_epan_scope(), xcp_eth_mapping_t, xcp_uat_eth_mapping_num);
1389
16
    xcp_uat_eth_mapping_num_current = xcp_uat_eth_mapping_num;
1390
1391
    /* destroy old hash table, if it exists */
1392
16
    reset_xcp_eth_mapping_cb();
1393
1394
    /* we don't need to free the data as long as we don't alloc it first */
1395
16
    data_xcp_eth_mappings = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, NULL);
1396
1397
16
    for (uint32_t i = 0; i < xcp_uat_eth_mapping_num; i++) {
1398
0
        xcp_eth_mapping_t* mapping = eth_mapping_uat_entry_to_eth_mapping_entry(i);
1399
1400
0
        uint64_t* hash = g_new(uint64_t, 1);
1401
0
        *hash = xcp_eth_mapping_calc_key(&(mapping->addr), mapping->port_type, mapping->port_number);
1402
1403
0
        g_hash_table_insert(data_xcp_eth_mappings, hash, mapping);
1404
0
    }
1405
1406
    /* we need to register the CAN-IDs */
1407
16
    register_xcp_eth();
1408
16
}
1409
1410
static xcp_eth_mapping_t *
1411
0
get_eth_mapping(const address *addr, const uint8_t xcp_port_type, const uint16_t port) {
1412
0
    if (data_xcp_eth_mappings == NULL) {
1413
0
        return NULL;
1414
0
    }
1415
1416
0
    uint64_t key = xcp_eth_mapping_calc_key(addr, xcp_port_type, port);
1417
0
    xcp_eth_mapping_t *tmp = g_hash_table_lookup(data_xcp_eth_mappings, &key);
1418
0
    return tmp;
1419
0
}
1420
1421
1422
/* UAT: CAN Mapping */
1423
0
UAT_HEX_CB_DEF(xcp_uat_can_mappings,     bus_id,         xcp_can_mapping_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_uat_can_mappings_bus_id_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_uat_can_mappings_bus_id_tostr_cb
1424
0
UAT_HEX_CB_DEF(xcp_uat_can_mappings,     can_id_m_to_s,  xcp_can_mapping_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_uat_can_mappings_can_id_m_to_s_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_uat_can_mappings_can_id_m_to_s_tostr_cb
1425
0
UAT_HEX_CB_DEF(xcp_uat_can_mappings,     can_id_s_to_m,  xcp_can_mapping_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_uat_can_mappings_can_id_s_to_m_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_uat_can_mappings_can_id_s_to_m_tostr_cb
1426
0
UAT_HEX_CB_DEF(xcp_uat_can_mappings,     ecu_id,         xcp_can_mapping_uat_t)
Unexecuted instantiation: packet-xcp.c:xcp_uat_can_mappings_ecu_id_set_cb
Unexecuted instantiation: packet-xcp.c:xcp_uat_can_mappings_ecu_id_tostr_cb
1427
1428
static void
1429
16
register_xcp_can(void) {
1430
16
    if (xcp_handle_can == NULL) {
1431
0
        return;
1432
0
    }
1433
1434
16
    dissector_delete_all("can.id", xcp_handle_can);
1435
16
    dissector_delete_all("can.extended_id", xcp_handle_can);
1436
1437
    /* CAN: loop over all frame IDs in HT */
1438
16
    if (data_xcp_can_mappings != NULL) {
1439
16
        GList *keys = g_hash_table_get_keys(data_xcp_can_mappings);
1440
1441
16
        GList *tmp;
1442
16
        for (tmp = keys; tmp != NULL; tmp = tmp->next) {
1443
0
            uint32_t id = (uint32_t)(*(uint64_t*)tmp->data);
1444
1445
0
            if ((id & CAN_EFF_FLAG) == CAN_EFF_FLAG) {
1446
0
                dissector_add_uint("can.extended_id", id & CAN_EFF_MASK, xcp_handle_can);
1447
0
            } else {
1448
0
                dissector_add_uint("can.id", id & CAN_SFF_MASK, xcp_handle_can);
1449
0
            }
1450
0
        }
1451
1452
16
        g_list_free(keys);
1453
16
    }
1454
16
}
1455
1456
static void *
1457
0
copy_xcp_can_mapping_cb(void *n, const void *o, size_t size _U_) {
1458
0
    xcp_can_mapping_uat_t *new_rec = (xcp_can_mapping_uat_t *)n;
1459
0
    const xcp_can_mapping_uat_t *old_rec = (const xcp_can_mapping_uat_t *)o;
1460
1461
0
    new_rec->bus_id         = old_rec->bus_id;
1462
0
    new_rec->can_id_m_to_s  = old_rec->can_id_m_to_s;
1463
0
    new_rec->can_id_s_to_m  = old_rec->can_id_s_to_m;
1464
0
    new_rec->ecu_id         = old_rec->ecu_id;
1465
1466
0
    return new_rec;
1467
0
}
1468
1469
static bool
1470
0
update_xcp_can_mapping_cb(void *r, char **err) {
1471
0
    xcp_can_mapping_uat_t *rec = (xcp_can_mapping_uat_t *)r;
1472
1473
0
    if ((rec->ecu_id) > 0xffff) {
1474
0
        *err = g_strdup_printf("We currently only support 16bit ECU-IDs (0x%x) up to 0xffff", rec->ecu_id);
1475
0
        return false;
1476
0
    }
1477
1478
0
    if ((rec->can_id_m_to_s & (CAN_RTR_FLAG | CAN_ERR_FLAG)) != 0) {
1479
0
        *err = g_strdup_printf("We currently do not support CAN IDs with RTR or Error Flag set (CAN_ID: 0x%x M->S)", rec->can_id_m_to_s);
1480
0
        return false;
1481
0
    }
1482
1483
0
    if ((rec->can_id_m_to_s & CAN_EFF_FLAG) == 0 && rec->can_id_m_to_s > CAN_SFF_MASK) {
1484
0
        *err = g_strdup_printf("Standard CAN ID (EFF flag not set) cannot be bigger than 0x7ff (CAN_ID: 0x%x M->S)", rec->can_id_m_to_s);
1485
0
        return false;
1486
0
    }
1487
1488
0
    if ((rec->can_id_s_to_m & (CAN_RTR_FLAG | CAN_ERR_FLAG)) != 0) {
1489
0
        *err = g_strdup_printf("We currently do not support CAN IDs with RTR or Error Flag set (CAN_ID: 0x%x S->M)", rec->can_id_s_to_m);
1490
0
        return false;
1491
0
    }
1492
1493
0
    if ((rec->can_id_s_to_m & CAN_EFF_FLAG) == 0 && rec->can_id_s_to_m > CAN_SFF_MASK) {
1494
0
        *err = g_strdup_printf("Standard CAN ID (EFF flag not set) cannot be bigger than 0x7ff (CAN_ID: 0x%x S->M)", rec->can_id_s_to_m);
1495
0
        return false;
1496
0
    }
1497
1498
0
    return true;
1499
0
}
1500
1501
static xcp_can_mapping_t *
1502
0
can_mapping_uat_entry_to_can_mapping_entry(uint32_t i) {
1503
0
    xcp_can_mapping_t *ret = &(xcp_can_mappings_priv[i]);
1504
1505
0
    ret->bus_id         = xcp_uat_can_mappings[i].bus_id;
1506
0
    ret->can_id_m_to_s  = xcp_uat_can_mappings[i].can_id_m_to_s;
1507
0
    ret->can_id_s_to_m  = xcp_uat_can_mappings[i].can_id_s_to_m;
1508
0
    ret->ecu_id         = (uint16_t)xcp_uat_can_mappings[i].ecu_id;
1509
0
    ret->stream         = NULL;
1510
1511
0
    return ret;
1512
0
}
1513
1514
static void
1515
16
reset_xcp_can_mapping_cb(void) {
1516
    /* destroy hash table, if it exists */
1517
16
    if (data_xcp_can_mappings) {
1518
0
        g_hash_table_destroy(data_xcp_can_mappings);
1519
0
        data_xcp_can_mappings = NULL;
1520
0
    }
1521
16
}
1522
1523
static void
1524
16
post_update_xcp_can_mapping_cb(void) {
1525
16
    uint32_t i;
1526
16
    uint64_t *key;
1527
1528
    /* destroy the local xcp_uat_can_mappings array */
1529
16
    if (xcp_can_mappings_priv != NULL) {
1530
0
        for (i = 0; i < xcp_uat_can_mapping_num_current; i++) {
1531
0
            if (xcp_can_mappings_priv[i].stream != NULL) {
1532
0
                wmem_free(wmem_epan_scope(), xcp_can_mappings_priv[i].stream);
1533
0
            }
1534
0
        }
1535
1536
0
        wmem_free(wmem_epan_scope(), xcp_can_mappings_priv);
1537
0
        xcp_can_mappings_priv = NULL;
1538
0
    }
1539
1540
16
    xcp_can_mappings_priv = (xcp_can_mapping_t *)wmem_alloc0_array(wmem_epan_scope(), xcp_can_mapping_t, xcp_uat_can_mapping_num);
1541
16
    xcp_uat_can_mapping_num_current = xcp_uat_can_mapping_num;
1542
1543
    /* destroy old hash table, if it exists */
1544
16
    reset_xcp_can_mapping_cb();
1545
1546
    /* we don't need to free the data as long as we don't alloc it first */
1547
16
    data_xcp_can_mappings = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, NULL);
1548
1549
16
    for (i = 0; i < xcp_uat_can_mapping_num; i++) {
1550
0
        xcp_can_mapping_t* mapping = can_mapping_uat_entry_to_can_mapping_entry(i);
1551
1552
        /* M -> S */
1553
0
        key = g_new(uint64_t, 1);
1554
0
        *key = xcp_uat_can_mappings[i].can_id_m_to_s | (((uint64_t)xcp_uat_can_mappings[i].bus_id & 0xffff) << 32);
1555
0
        g_hash_table_insert(data_xcp_can_mappings, key, mapping);
1556
1557
        /* S -> M */
1558
0
        key = g_new(uint64_t, 1);
1559
0
        *key = xcp_uat_can_mappings[i].can_id_s_to_m | (((uint64_t)xcp_uat_can_mappings[i].bus_id & 0xffff) << 32);
1560
0
        g_hash_table_insert(data_xcp_can_mappings, key, mapping);
1561
0
    }
1562
1563
    /* we need to register the CAN-IDs */
1564
16
    register_xcp_can();
1565
16
}
1566
1567
static xcp_can_mapping_t *
1568
16
get_can_mapping(uint32_t id, uint16_t bus_id) {
1569
16
    if (data_xcp_can_mappings == NULL) {
1570
0
        return NULL;
1571
0
    }
1572
1573
    /* key is Bus ID, EFF Flag, CAN-ID */
1574
16
    uint64_t key = ((uint64_t)id & (CAN_EFF_MASK | CAN_EFF_FLAG)) | ((uint64_t)bus_id << 32);
1575
16
    xcp_can_mapping_t *tmp = (xcp_can_mapping_t *)g_hash_table_lookup(data_xcp_can_mappings, &key);
1576
1577
16
    if (tmp == NULL) {
1578
        /* try again without Bus ID set */
1579
16
        key = id & (CAN_EFF_MASK | CAN_EFF_FLAG);
1580
16
        tmp = (xcp_can_mapping_t *)g_hash_table_lookup(data_xcp_can_mappings, &key);
1581
16
    }
1582
1583
16
    return tmp;
1584
16
}
1585
1586
/*** State ***/
1587
1588
static xcp_daq_t *
1589
0
get_daq_from_message(xcp_message_t *message, uint32_t i) {
1590
0
    if (message == NULL || message->current_daqs == NULL || i >= message->number_of_daqs || i >= wmem_array_get_count(message->current_daqs)) {
1591
0
        return NULL;
1592
0
    }
1593
1594
0
    return (xcp_daq_t *)wmem_array_index(message->current_daqs, i);
1595
0
}
1596
1597
static xcp_odt_t *
1598
0
get_odt_from_message(xcp_message_t *message, uint32_t daq_number, uint32_t i) {
1599
0
    xcp_daq_t *daq = get_daq_from_message(message, daq_number);
1600
1601
0
    if (daq == NULL || daq->current_odts == NULL || i >= daq->number_of_odts || i >= wmem_array_get_count(daq->current_odts)) {
1602
0
        return NULL;
1603
0
    }
1604
1605
0
    return (xcp_odt_t *)wmem_array_index(daq->current_odts, i);
1606
0
}
1607
1608
static xcp_odt_entry_t *
1609
0
get_odt_entry_from_message(xcp_message_t *message, uint32_t daq_number, uint32_t odt_number, uint32_t i) {
1610
0
    xcp_odt_t *odt = get_odt_from_message(message, daq_number, odt_number);
1611
1612
0
    if (odt == NULL || odt->current_odt_entries == NULL || i >= odt->number_of_odt_entries || i >= wmem_array_get_count(odt->current_odt_entries)) {
1613
0
        return NULL;
1614
0
    }
1615
1616
0
    return (xcp_odt_entry_t *)wmem_array_index(odt->current_odt_entries, i);
1617
0
}
1618
1619
1620
/*** Dissector ***/
1621
static int
1622
0
dissect_transport_layer_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset_orig, int max_length _U_, bool m2s, uint32_t xcp_type, xcp_message_t *message, xcp_stream_t *stream _U_) {
1623
0
    uint32_t    offset = offset_orig;
1624
0
    uint32_t    subcmd;
1625
0
    const char *tmp_name;
1626
1627
0
    if (m2s) {
1628
0
        switch (xcp_type) {
1629
0
        case XCP_TYPE_ETHERNET:
1630
            /* All multi-byte parameters are ENC_LITTLE_ENDIAN */
1631
0
            proto_tree_add_item_ret_uint(tree, hf_xcp_sub_command_eth, tvb, offset, 1, ENC_NA, &subcmd);
1632
0
            message->transport_layer_sub_cmd = subcmd;
1633
0
            offset += 1;
1634
1635
0
            tmp_name = try_val_to_str(subcmd, sub_cmd_code_mnemonics_eth);
1636
0
            if (tmp_name != NULL) {
1637
0
                col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", tmp_name);
1638
0
            }
1639
1640
0
            switch (message->transport_layer_sub_cmd) {
1641
0
            case XCP_SUB_CMD_ETH_GET_SLAVE_ID: {
1642
0
                uint32_t ip_version = tvb_get_uint8(tvb, offset + 18);
1643
1644
0
                proto_tree_add_item(tree, hf_xcp_sub_command_eth_port, tvb, offset, 2, ENC_LITTLE_ENDIAN); // ENC_LITTLE_ENDIAN ok
1645
0
                offset += 2;
1646
1647
0
                switch (ip_version) {
1648
0
                case 0:
1649
                    /* TODO: is this actually encoded in big-endian order? */
1650
0
                    proto_tree_add_item(tree, hf_xcp_sub_command_eth_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
1651
0
                    offset += 4;
1652
1653
                    /* TODO: we need to register the address and since the answer will be sent there... */
1654
                    /* This is a bit unclear in the standard and requires example traces. */
1655
1656
0
                    proto_tree_add_item(tree, hf_xcp_sub_command_eth_reserved, tvb, offset, 12, ENC_NA);
1657
0
                    offset += 12;
1658
1659
0
                    proto_tree_add_item(tree, hf_xcp_sub_command_eth_ip_version, tvb, offset, 1, ENC_NA);
1660
0
                    offset += 1;
1661
0
                }
1662
1663
0
            }
1664
0
                break;
1665
            //case XCP_SUB_CMD_ETH_GET_SLAVE_ID_EXT:
1666
            //    /* TODO */
1667
            //    break;
1668
            //case XCP_SUB_CMD_ETH_GET_SLAVE_IP_ADDR:
1669
            //    /* TODO */
1670
            //    break;
1671
            //case XCP_SUB_CMD_ETH_GET_DAQ_CLC_MCAST:
1672
            //    /* TODO */
1673
            //    break;
1674
0
            }
1675
0
            break;
1676
1677
0
        case XCP_TYPE_CAN:
1678
0
            proto_tree_add_item_ret_uint(tree, hf_xcp_sub_command_can, tvb, offset, 1, ENC_NA, &subcmd);
1679
0
            message->transport_layer_sub_cmd = subcmd;
1680
            //offset += 1;
1681
1682
            //switch (message->transport_layer_sub_cmd) {
1683
            //case XCP_SUB_CMD_CAN_GET_SLAVE_ID:
1684
            //    /* TODO */
1685
            //    break;
1686
            //case XCP_SUB_CMD_CAN_GET_DAQ_ID:
1687
            //    /* TODO */
1688
            //    break;
1689
            //case XCP_SUB_CMD_CAN_SET_DAQ_ID:
1690
            //    /* TODO */
1691
            //    break;
1692
            //case XCP_SUB_CMD_CAN_GET_DAQ_CLC_MCAST:
1693
            //    /* TODO */
1694
            //    break;
1695
            //}
1696
0
            break;
1697
1698
0
        default:
1699
0
            proto_tree_add_expert_remaining(tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
1700
0
            col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
1701
0
            break;
1702
0
        }
1703
0
    } else {
1704
0
        if (message->peer_message != NULL) {
1705
0
            switch (xcp_type) {
1706
0
            case XCP_TYPE_ETHERNET:
1707
                //switch (message->transport_layer_sub_cmd) {
1708
                //case XCP_SUB_CMD_ETH_GET_SLAVE_ID:
1709
                //    /* TODO */
1710
                //    break;
1711
                //case XCP_SUB_CMD_ETH_GET_SLAVE_ID_EXT:
1712
                //    /* TODO */
1713
                //    break;
1714
                //case XCP_SUB_CMD_ETH_GET_SLAVE_IP_ADDR:
1715
                //    /* TODO */
1716
                //    break;
1717
                //case XCP_SUB_CMD_ETH_GET_DAQ_CLC_MCAST:
1718
                //    /* TODO */
1719
                //    break;
1720
                //}
1721
0
                break;
1722
0
            case XCP_TYPE_CAN:
1723
                //switch (message->transport_layer_sub_cmd) {
1724
                //case XCP_SUB_CMD_CAN_GET_SLAVE_ID:
1725
                //    /* TODO */
1726
                //    break;
1727
                //case XCP_SUB_CMD_CAN_GET_DAQ_ID:
1728
                //    /* TODO */
1729
                //    break;
1730
                //case XCP_SUB_CMD_CAN_SET_DAQ_ID:
1731
                //    /* TODO */
1732
                //    break;
1733
                //case XCP_SUB_CMD_CAN_GET_DAQ_CLC_MCAST:
1734
                //    /* TODO */
1735
                //    break;
1736
                //}
1737
0
                break;
1738
1739
0
            default:
1740
0
                proto_tree_add_expert_remaining(tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
1741
0
                col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
1742
0
                break;
1743
0
            }
1744
0
        }
1745
0
    }
1746
1747
0
    return offset - offset_orig;
1748
0
}
1749
1750
static int
1751
0
dissect_sw_debug_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset_orig, int max_length _U_, bool m2s, uint32_t xcp_type _U_, xcp_message_t *message, xcp_stream_t *stream _U_) {
1752
0
    uint32_t offset = offset_orig;
1753
1754
0
    if (m2s) {
1755
0
        uint32_t cmd;
1756
0
        proto_tree_add_item_ret_uint(tree, hf_xcp_debug_command, tvb, offset, 1, ENC_NA, &cmd);
1757
0
        message->cmd_sw_debug = cmd;
1758
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str(pinfo->pool, cmd, cmd_sw_dbg_mnemonics, "Unknown Software Debug Command (0x%02x)"));
1759
0
        offset += 1;
1760
1761
        /* TODO */
1762
0
        proto_tree_add_expert_remaining(tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
1763
0
        col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
1764
0
        offset += tvb_captured_length_remaining(tvb, offset);
1765
1766
0
    } else {
1767
1768
        /* TODO */
1769
0
        proto_tree_add_expert_remaining(tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
1770
0
        col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
1771
0
        offset += tvb_captured_length_remaining(tvb, offset);
1772
0
    }
1773
1774
0
    return offset - offset_orig;
1775
0
}
1776
1777
static int
1778
0
dissect_pod_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset_orig, int max_length _U_, bool m2s, uint32_t xcp_type _U_, xcp_message_t *message, xcp_stream_t *stream) {
1779
0
    if (stream == NULL || message == NULL) {
1780
        /* should never happen */
1781
0
        ws_assert_not_reached();
1782
0
        return 0;
1783
0
    }
1784
1785
0
    uint32_t offset = offset_orig;
1786
1787
0
    if (m2s) {
1788
0
        uint32_t cmd;
1789
0
        proto_tree_add_item_ret_uint(tree, hf_xcp_pod_command, tvb, offset, 2, stream->endianess, &cmd);
1790
0
        message->cmd_pod = cmd;
1791
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str(pinfo->pool, cmd, cmd_pod_mnemonics, "Unknown POD Command (0x%04x)"));
1792
0
        offset += 1;
1793
1794
0
        switch (message->cmd_pod) {
1795
        //case XCP_CMD_POD_GET_INFO:
1796
        //    /* TODO */
1797
        //    break;
1798
1799
        //case XCP_CMD_POD_SET_ACTIVE_CONFIG:
1800
        //    /* TODO */
1801
        //    break;
1802
1803
        //case XCP_CMD_POD_MANAGE_TRANSFER:
1804
        //    /* TODO */
1805
        //    break;
1806
1807
        //case XCP_CMD_POD_DOWNLOAD:
1808
        //    /* TODO */
1809
        //    break;
1810
1811
        //case XCP_CMD_POD_UPLOAD:
1812
        //    /* TODO */
1813
        //    break;
1814
1815
0
        case XCP_CMD_POD_GET_STATUS:
1816
            /* No Parameters */
1817
0
            break;
1818
1819
0
        default:
1820
0
            proto_tree_add_expert_remaining(tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
1821
0
            col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
1822
0
            offset += tvb_captured_length_remaining(tvb, offset);
1823
0
        }
1824
1825
0
    } else {
1826
0
        switch (message->cmd_pod) {
1827
        //case XCP_CMD_POD_GET_INFO:
1828
        //    /* TODO */
1829
        //    break;
1830
1831
        //case XCP_CMD_POD_SET_ACTIVE_CONFIG:
1832
        //    /* TODO */
1833
        //    break;
1834
1835
        //case XCP_CMD_POD_MANAGE_TRANSFER:
1836
        //    /* TODO */
1837
        //    break;
1838
1839
0
        case XCP_CMD_POD_DOWNLOAD:
1840
            /* No Parameters */
1841
0
            break;
1842
1843
        //case XCP_CMD_POD_UPLOAD:
1844
        //    /* TODO */
1845
        //    break;
1846
1847
        //case XCP_CMD_POD_GET_STATUS:
1848
        //    /* TODO */
1849
        //    break;
1850
1851
0
        default:
1852
0
            proto_tree_add_expert_remaining(tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
1853
0
            col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
1854
0
            offset += tvb_captured_length_remaining(tvb, offset);
1855
0
        }
1856
0
    }
1857
1858
0
    return offset - offset_orig;
1859
0
}
1860
1861
static int
1862
0
dissect_xcp_m2s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset_orig, int max_length, uint32_t xcp_type, xcp_message_t *message, xcp_stream_t *stream) {
1863
0
    if (stream == NULL || message == NULL) {
1864
        /* should never happen */
1865
0
        ws_assert_not_reached();
1866
0
        return 0;
1867
0
    }
1868
1869
0
    uint32_t offset = offset_orig;
1870
0
    proto_item *ti_root = NULL;
1871
0
    proto_tree *xcp_tree = NULL;
1872
1873
0
    ti_root = proto_tree_add_item(tree, hf_xcp_packet, tvb, offset, max_length, ENC_NA);
1874
0
    xcp_tree = proto_item_add_subtree(ti_root, ett_xcp_packet);
1875
1876
0
    uint32_t cmd;
1877
0
    uint32_t cmd_lvl1 = XCP_MESSAGE_CMD_UNKNOWN;
1878
1879
0
    proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_cmd_code, tvb, offset, 1, ENC_NA, &cmd);
1880
0
    offset += 1;
1881
1882
0
    if (cmd != XCP_CMD_2BYTE_FIRST_BYTE) {
1883
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "XCP M->S: %s", val_to_str(pinfo->pool, cmd, cmd_code_mnemonics, "Unknown Command Code (0x%02x)"));
1884
0
    } else {
1885
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_cmd_code_level1, tvb, offset, 1, ENC_NA, &cmd_lvl1);
1886
0
        offset += 1;
1887
1888
0
        if (cmd_lvl1 == XCP_CMD_2BYTE_XCP_POD_COMMANDS || cmd_lvl1 == XCP_CMD_2BYTE_XCP_SW_DEBUG) {
1889
0
            col_set_str(pinfo->cinfo, COL_INFO, "XCP M->S:");
1890
0
        } else {
1891
0
            col_add_fstr(pinfo->cinfo, COL_INFO, "XCP M->S: %s", val_to_str(pinfo->pool, cmd_lvl1, cmd_code_mnemonics_2bytes, "Unknown Command Code (0xC0 0x%02x)"));
1892
0
        }
1893
0
    }
1894
1895
    /* setting up the meta data*/
1896
0
    if (!(pinfo->fd->visited)) {
1897
0
        stream->last_m2s = message;
1898
0
        message->number_of_daqs = stream->number_of_daqs;
1899
0
        message->current_daqs = stream->current_daqs;
1900
1901
0
        message->peer_message   = NULL;
1902
0
        message->m2s            = true;
1903
0
        message->cmd            = cmd;
1904
0
        message->cmd_lvl1       = cmd_lvl1;
1905
0
    }
1906
1907
0
    switch (cmd) {
1908
0
    case XCP_CMD_CONNECT:
1909
0
        proto_tree_add_item(xcp_tree, hf_xcp_conn_mode, tvb, offset, 1, ENC_NA);
1910
0
        offset += 1;
1911
0
        break;
1912
1913
0
    case XCP_CMD_DISCONNECT:
1914
        /* No Parameters */
1915
0
        break;
1916
1917
0
    case XCP_CMD_GET_STATUS:
1918
        /* No Parameters */
1919
0
        break;
1920
1921
0
    case XCP_CMD_SYNCH:
1922
        /* No Parameters */
1923
0
        break;
1924
1925
0
    case XCP_CMD_GET_COMM_MODE_INFO:
1926
        /* No Parameters */
1927
0
        break;
1928
1929
0
    case XCP_CMD_GET_ID:
1930
0
        proto_tree_add_item(xcp_tree, hf_xcp_get_id_req_id_type, tvb, offset, 1, ENC_NA);
1931
0
        offset += 1;
1932
0
        break;
1933
1934
0
    case XCP_CMD_SET_REQUEST: {
1935
0
        static int * const set_request_mode_flags[] = {
1936
0
            &hf_xcp_set_req_md_clr_daq_cfg_lost,
1937
0
            &hf_xcp_set_req_md_clr_cal_pag_cfg_lost,
1938
0
            &hf_xcp_set_req_md_clr_daq_req,
1939
0
            &hf_xcp_set_req_md_str_daq_req_resume,
1940
0
            &hf_xcp_set_req_md_str_daq_req_no_resume,
1941
0
            &hf_xcp_set_req_md_str_cal_req,
1942
0
            NULL
1943
0
        };
1944
1945
0
        proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_set_req_md, ett_xcp_set_request_mode, set_request_mode_flags, ENC_NA);
1946
0
        offset += 1;
1947
1948
0
        proto_tree_add_item(xcp_tree, hf_xcp_session_cfg_id, tvb, offset, 2, stream->endianess);
1949
0
        offset += 2;
1950
0
    }
1951
0
        break;
1952
1953
0
    case XCP_CMD_GET_SEED: {
1954
0
        uint32_t seed_mode;
1955
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_get_seed_mode, tvb, offset, 1, ENC_NA, &seed_mode);
1956
0
        offset += 1;
1957
1958
0
        if (seed_mode == 0) {
1959
0
            proto_tree_add_item(xcp_tree, hf_xcp_get_seed_resource, tvb, offset, 1, ENC_NA);
1960
0
        } else {
1961
0
            proto_tree_add_item(xcp_tree, hf_xcp_get_seed_dont_care, tvb, offset, 1, ENC_NA);
1962
0
        }
1963
0
        offset += 1;
1964
0
    }
1965
0
        break;
1966
1967
0
    case XCP_CMD_UNLOCK: {
1968
0
        proto_tree_add_item(xcp_tree, hf_xcp_unlock_length_of_key, tvb, offset, 1, ENC_NA);
1969
0
        offset += 1;
1970
1971
0
        uint32_t key_length = max_length - (offset - offset_orig);
1972
0
        proto_tree_add_item(xcp_tree, hf_xcp_unlock_key, tvb, offset, key_length, ENC_NA);
1973
0
        offset += key_length;
1974
0
    }
1975
0
        break;
1976
1977
0
    case XCP_CMD_SET_MTA: {
1978
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
1979
0
        offset += 1;
1980
1981
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
1982
0
        offset += 1;
1983
1984
0
        uint32_t address_extension;
1985
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_address_extension, tvb, offset, 1, ENC_NA, &address_extension);
1986
0
        offset += 1;
1987
1988
0
        uint32_t memory_address;
1989
0
        proto_item *ti = proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_address, tvb, offset, 4, stream->endianess, &memory_address);
1990
0
        offset += 4;
1991
1992
0
        char *name_string = xcp_lookup_memory_address(stream->ecu_id, (uint8_t)address_extension, memory_address);
1993
0
        if (name_string != NULL) {
1994
0
            proto_item_append_text(ti, " (%s)", name_string);
1995
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x%04x %s", address_extension, memory_address, name_string);
1996
0
        } else {
1997
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x%04x", address_extension, memory_address);
1998
0
        }
1999
0
    }
2000
0
        break;
2001
2002
0
    case XCP_CMD_UPLOAD:
2003
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_num_of_data_elements, tvb, offset, 1, ENC_NA, &(message->number_of_elements));
2004
0
        offset += 1;
2005
0
        break;
2006
2007
0
    case XCP_CMD_SHORT_UPLOAD: {
2008
0
        uint32_t number_of_elements;
2009
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_num_of_data_elements, tvb, offset, 1, ENC_NA, &number_of_elements);
2010
0
        message->number_of_elements = number_of_elements;
2011
0
        offset += 1;
2012
2013
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2014
0
        offset += 1;
2015
2016
0
        uint32_t address_extension;
2017
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_address_extension, tvb, offset, 1, ENC_NA, &address_extension);
2018
0
        offset += 1;
2019
2020
0
        uint32_t memory_address;
2021
0
        proto_item *ti = proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_address, tvb, offset, 4, stream->endianess, &memory_address);
2022
0
        offset += 4;
2023
2024
0
        char *name_string = xcp_lookup_memory_address(stream->ecu_id, (uint8_t)address_extension, memory_address);
2025
0
        if (name_string != NULL) {
2026
0
            proto_item_append_text(ti, " (%s)", name_string);
2027
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x%04x [%d] %s", address_extension, memory_address, number_of_elements, name_string);
2028
0
        } else {
2029
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x%04x [%d]", address_extension, memory_address, number_of_elements);
2030
0
        }
2031
2032
0
    }
2033
0
        break;
2034
2035
0
    case XCP_CMD_BUILD_CHECKSUM: {
2036
0
        proto_tree_add_item(xcp_tree, hf_xcp_build_chksum_res1, tvb, offset, 1, ENC_NA);
2037
0
        offset += 1;
2038
2039
0
        proto_tree_add_item(xcp_tree, hf_xcp_build_chksum_res2, tvb, offset, 2, stream->endianess);
2040
0
        offset += 2;
2041
2042
0
        uint32_t block_size;
2043
0
        proto_item *ti = proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_build_chksum_block_size, tvb, offset, 4, stream->endianess, &block_size);
2044
0
        proto_item_append_text(ti, " (%d)", stream->addr_granularity * block_size);
2045
0
        offset += 4;
2046
0
    }
2047
0
        break;
2048
2049
0
    case XCP_CMD_TRANSPORT_LAYER_CMD:
2050
0
        offset += dissect_transport_layer_cmd(tvb, pinfo, xcp_tree, offset, max_length, true, xcp_type, message, stream);
2051
0
        break;
2052
2053
    //case XCP_CMD_USER_CMD:
2054
    //    /* TODO */
2055
    //    break;
2056
2057
2058
0
    case XCP_CMD_DOWNLOAD: {
2059
0
        uint32_t number_of_elements;
2060
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_num_of_data_elements, tvb, offset, 1, ENC_NA, &number_of_elements);
2061
0
        message->number_of_elements = number_of_elements;
2062
0
        offset += 1;
2063
2064
0
        uint32_t i;
2065
0
        uint32_t tmp;
2066
0
        if (stream->addr_granularity == 1) {
2067
0
            for (i = 0; i < number_of_elements; i++) {
2068
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_1byte, tvb, offset, 1, ENC_NA, &tmp);
2069
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tmp);
2070
0
                offset += 1;
2071
0
            }
2072
0
        } else if (stream->addr_granularity == 2) {
2073
0
            for (i = 0; i < number_of_elements; i++) {
2074
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_2bytes, tvb, offset, 2, stream->endianess, &tmp);
2075
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", tmp);
2076
0
                offset += 2;
2077
0
            }
2078
0
        } else if (stream->addr_granularity == 4) {
2079
0
            proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2080
0
            proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2081
0
            offset += 2;
2082
2083
0
            for (i = 0; i < number_of_elements; i++) {
2084
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_4bytes, tvb, offset, 4, stream->endianess, &tmp);
2085
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%08x", tmp);
2086
0
                offset += 4;
2087
0
            }
2088
0
        }
2089
2090
0
    }
2091
0
        break;
2092
2093
    //case XCP_CMD_DOWNLOAD_NEXT:
2094
    //    /* TODO */
2095
    //    break;
2096
2097
    //case XCP_CMD_DOWNLOAD_MAX:
2098
    //    /* TODO */
2099
    //    break;
2100
2101
0
    case XCP_CMD_SHORT_DOWNLOAD: {
2102
0
        uint32_t number_of_elements;
2103
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_num_of_data_elements, tvb, offset, 1, ENC_NA, &number_of_elements);
2104
0
        message->number_of_elements = number_of_elements;
2105
0
        offset += 1;
2106
2107
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2108
0
        offset += 1;
2109
2110
0
        uint32_t address_extension;
2111
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_address_extension, tvb, offset, 1, ENC_NA, &address_extension);
2112
0
        offset += 1;
2113
2114
0
        uint32_t memory_address;
2115
0
        proto_item *ti = proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_address, tvb, offset, 4, stream->endianess, &memory_address);
2116
0
        offset += 4;
2117
2118
0
        char *name_string = xcp_lookup_memory_address(stream->ecu_id, (uint8_t)address_extension, memory_address);
2119
0
        if (name_string != NULL) {
2120
0
            proto_item_append_text(ti, " (%s)", name_string);
2121
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x%04x [%d] %s", address_extension, memory_address, number_of_elements, name_string);
2122
0
        } else {
2123
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x%04x [%d]", address_extension, memory_address, number_of_elements);
2124
0
        }
2125
2126
0
        uint32_t i;
2127
0
        uint32_t tmp;
2128
2129
0
        if (stream->addr_granularity == 1) {
2130
0
            for (i = 0; i < number_of_elements; i++) {
2131
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_1byte, tvb, offset, 1, ENC_NA, &tmp);
2132
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tmp);
2133
0
                offset += 1;
2134
0
            }
2135
0
        } else if (stream->addr_granularity == 2) {
2136
0
            for (i = 0; i < number_of_elements; i++) {
2137
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_2bytes, tvb, offset, 2, stream->endianess, &tmp);
2138
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", tmp);
2139
0
                offset += 2;
2140
0
            }
2141
0
        } else if (stream->addr_granularity == 4) {
2142
0
            for (i = 0; i < number_of_elements; i++) {
2143
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_4bytes, tvb, offset, 4, stream->endianess, &tmp);
2144
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%08x", tmp);
2145
0
                offset += 4;
2146
0
            }
2147
0
        }
2148
2149
0
    }
2150
0
        break;
2151
2152
    //case XCP_CMD_MODIFY_BITS:
2153
    //    /* TODO */
2154
    //    break;
2155
2156
2157
0
    case XCP_CMD_SET_CAL_PAGE: {
2158
0
        static int * const set_cal_page_mode[] = {
2159
0
            &hf_xcp_set_cal_page_mode_all,
2160
0
            &hf_xcp_set_cal_page_mode_xcp,
2161
0
            &hf_xcp_set_cal_page_mode_ecu,
2162
0
            NULL
2163
0
        };
2164
2165
0
        proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_set_cal_page_mode, ett_xcp_set_cal_page_mode, set_cal_page_mode, ENC_NA);
2166
0
        offset += 1;
2167
2168
0
        uint32_t segment_number;
2169
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_logical_data_segment_number, tvb, offset, 1, ENC_NA, &segment_number);
2170
0
        offset += 1;
2171
2172
0
        uint32_t page_number;
2173
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_logical_data_page_number, tvb, offset, 1, ENC_NA, &page_number);
2174
0
        offset += 1;
2175
2176
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": SEGMENT:%d PAGE:%d", segment_number, page_number);
2177
0
    }
2178
0
        break;
2179
2180
0
    case XCP_CMD_GET_CAL_PAGE: {
2181
0
        proto_tree_add_item(xcp_tree, hf_xcp_access_mode, tvb, offset, 1, ENC_NA);
2182
0
        offset += 1;
2183
2184
0
        uint32_t segment_number;
2185
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_logical_data_segment_number, tvb, offset, 1, ENC_NA, &segment_number);
2186
0
        offset += 1;
2187
2188
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": SEGMENT:%d", segment_number);
2189
0
    }
2190
0
        break;
2191
2192
0
    case XCP_CMD_GET_PAG_PROCESSOR_INFO:
2193
        /* No Parameters */
2194
0
        break;
2195
2196
    //case XCP_CMD_GET_SEGMENT_INFO:
2197
    //    /* TODO */
2198
    //    break;
2199
2200
    //case XCP_CMD_GET_PAGE_INFO:
2201
    //    /* TODO */
2202
    //    break;
2203
2204
0
    case XCP_CMD_SET_SEGMENT_MODE: {
2205
0
        static int* const set_segment_mode_mode_flags[] = {
2206
0
            &hf_xcp_set_segment_mode_freeze,
2207
0
            NULL
2208
0
        };
2209
2210
0
        uint64_t freeze;
2211
0
        proto_tree_add_bitmask_ret_uint64(xcp_tree, tvb, offset, hf_xcp_set_segment_mode, ett_xcp_set_segment_mode_mode, set_segment_mode_mode_flags, ENC_NA, &freeze);
2212
0
        offset += 1;
2213
2214
0
        uint32_t segment_number;
2215
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_set_segment_mode_segment, tvb, offset, 1, ENC_NA, &segment_number);
2216
0
        offset += 1;
2217
2218
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": Freeze %s for SEGMENT:%d", (freeze == 1 ? "Enabled" : "Disabled"), segment_number);
2219
0
    }
2220
0
        break;
2221
2222
    //case XCP_CMD_GET_SEGMENT_MODE:
2223
    //    /* TODO */
2224
    //    break;
2225
2226
0
    case XCP_CMD_COPY_CAL_PAGE:
2227
0
        proto_tree_add_item(xcp_tree, hf_xcp_logical_data_segm_num_src, tvb, offset, 1, ENC_NA);
2228
0
        offset += 1;
2229
2230
0
        proto_tree_add_item(xcp_tree, hf_xcp_logical_data_page_num_src, tvb, offset, 1, ENC_NA);
2231
0
        offset += 1;
2232
2233
0
        proto_tree_add_item(xcp_tree, hf_xcp_logical_data_segm_num_dst, tvb, offset, 1, ENC_NA);
2234
0
        offset += 1;
2235
2236
0
        proto_tree_add_item(xcp_tree, hf_xcp_logical_data_page_num_dst, tvb, offset, 1, ENC_NA);
2237
0
        offset += 1;
2238
2239
0
        break;
2240
2241
2242
0
    case XCP_CMD_CLEAR_DAQ_LIST: {
2243
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2244
0
        offset += 1;
2245
2246
0
        uint32_t daq_list_number;
2247
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_number, tvb, offset, 2, stream->endianess, &daq_list_number);
2248
0
        offset += 2;
2249
2250
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": DAQ_LIST:%d", daq_list_number);
2251
0
    }
2252
0
        break;
2253
2254
0
    case XCP_CMD_SET_DAQ_PTR: {
2255
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2256
0
        offset += 1;
2257
2258
0
        uint32_t daq_list_number;
2259
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_number, tvb, offset, 2, stream->endianess, &daq_list_number);
2260
0
        offset += 2;
2261
2262
0
        uint32_t odt_number;
2263
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_odt_number, tvb, offset, 1, ENC_NA, &odt_number);
2264
0
        offset += 1;
2265
2266
0
        uint32_t odt_entry_number;
2267
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_odt_entry_number, tvb, offset, 1, ENC_NA, &odt_entry_number);
2268
0
        offset += 1;
2269
2270
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": DAQ_LIST:%d ODT:%d ODT_ENTRY:%d", daq_list_number, odt_number, odt_entry_number);
2271
2272
0
        stream->current_daq = daq_list_number;
2273
0
        stream->current_odt = odt_number;
2274
0
        stream->current_odt_entry = odt_entry_number;
2275
0
    }
2276
0
        break;
2277
2278
0
    case XCP_CMD_WRITE_DAQ: {
2279
0
        uint32_t bit_offset;
2280
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_bit_offset, tvb, offset, 1, ENC_NA, &bit_offset);
2281
0
        offset += 1;
2282
2283
0
        uint32_t size_of_daq_element;
2284
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_size_of_daq_element, tvb, offset, 1, ENC_NA, &size_of_daq_element);
2285
0
        offset += 1;
2286
2287
0
        if (bit_offset == 0xff) {
2288
            /* bit offset can be ignored */
2289
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": SIZE_OF_DAQ_ELEMENT:%d", size_of_daq_element);
2290
0
        } else {
2291
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": BIT_OFFSET:%d SIZE_OF_DAQ_ELEMENT:%d", bit_offset, size_of_daq_element);
2292
0
        }
2293
2294
0
        uint32_t address_extension;
2295
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_address_extension, tvb, offset, 1, ENC_NA, &address_extension);
2296
0
        offset += 1;
2297
2298
0
        uint32_t memory_address;
2299
0
        proto_item *ti = proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_address, tvb, offset, 4, stream->endianess, &memory_address);
2300
0
        offset += 4;
2301
2302
0
        char *name_string = xcp_lookup_memory_address(stream->ecu_id, (uint8_t)address_extension, memory_address);
2303
0
        if (name_string != NULL) {
2304
0
            proto_item_append_text(ti, " (%s)", name_string);
2305
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x%04x %s", address_extension, memory_address, name_string);
2306
0
        } else {
2307
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x%04x", address_extension, memory_address);
2308
0
        }
2309
2310
0
        xcp_odt_entry_t *odt_entry = get_odt_entry_from_message(message, stream->current_daq, stream->current_odt, stream->current_odt_entry);
2311
0
        if (odt_entry != NULL) {
2312
0
            odt_entry->ecu_id = stream->ecu_id;
2313
0
            odt_entry->addr_ext = address_extension;
2314
0
            odt_entry->address = memory_address;
2315
0
            odt_entry->name = name_string == false ? NULL : wmem_strdup(wmem_file_scope(), name_string);
2316
0
            odt_entry->size = size_of_daq_element;
2317
0
        }
2318
2319
0
        stream->current_odt_entry += 1;
2320
0
    }
2321
0
        break;
2322
2323
0
    case XCP_CMD_SET_DAQ_LIST_MODE: {
2324
0
        static int * const set_daq_list_mode_mode_flags[] = {
2325
0
            &hf_xcp_set_daq_list_mode_mode_pid_off,
2326
0
            &hf_xcp_set_daq_list_mode_mode_timestamp,
2327
0
            &hf_xcp_set_daq_list_mode_mode_dto_ctr,
2328
0
            &hf_xcp_set_daq_list_mode_mode_dir,
2329
0
            &hf_xcp_set_daq_list_mode_mode_alt,
2330
0
            NULL
2331
0
        };
2332
2333
0
        uint64_t mode;
2334
0
        proto_tree_add_bitmask_ret_uint64(xcp_tree, tvb, offset, hf_xcp_set_daq_list_mode_mode, ett_xcp_set_daq_list_mode_mode, set_daq_list_mode_mode_flags, ENC_NA, &mode);
2335
0
        offset += 1;
2336
2337
0
        uint32_t daq_list_number;
2338
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_number, tvb, offset, 2, stream->endianess, &daq_list_number);
2339
0
        offset += 2;
2340
2341
0
        uint32_t channel_number;
2342
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_event_channel_number, tvb, offset, 2, stream->endianess, &channel_number);
2343
0
        offset += 2;
2344
2345
0
        uint32_t prescaler;
2346
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_transmission_prescaler, tvb, offset, 1, ENC_NA, &prescaler);
2347
0
        offset += 1;
2348
2349
0
        uint32_t priority;
2350
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_priority, tvb, offset, 1, ENC_NA, &priority);
2351
0
        offset += 1;
2352
2353
0
        col_append_str(pinfo->cinfo, COL_INFO, ": ");
2354
0
        if ((mode & SET_DAQ_LIST_MODE_PID_OFF) == SET_DAQ_LIST_MODE_PID_OFF) {
2355
0
            col_append_str(pinfo->cinfo, COL_INFO, "PID:OFF ");
2356
0
        } else {
2357
0
            col_append_str(pinfo->cinfo, COL_INFO, "PID:ON ");
2358
0
        }
2359
2360
0
        if ((mode & SET_DAQ_LIST_MODE_TSTAMP) == SET_DAQ_LIST_MODE_TSTAMP) {
2361
0
            col_append_str(pinfo->cinfo, COL_INFO, "TSTAMP:ON ");
2362
0
        } else {
2363
0
            col_append_str(pinfo->cinfo, COL_INFO, "TSTAMP:OFF ");
2364
0
        }
2365
2366
0
        if ((mode & SET_DAQ_LIST_MODE_DTO_CTR) == SET_DAQ_LIST_MODE_DTO_CTR) {
2367
0
            col_append_str(pinfo->cinfo, COL_INFO, "DTO_CTR:ON ");
2368
0
        } else {
2369
0
            col_append_str(pinfo->cinfo, COL_INFO, "DTO_CTR:OFF ");
2370
0
        }
2371
2372
0
        if ((mode & SET_DAQ_LIST_MODE_DIR) == SET_DAQ_LIST_MODE_DIR) {
2373
0
            col_append_str(pinfo->cinfo, COL_INFO, "STIM ");
2374
0
        } else {
2375
0
            col_append_str(pinfo->cinfo, COL_INFO, "DAQ ");
2376
0
        }
2377
2378
0
        if ((mode & SET_DAQ_LIST_MODE_ALT) == SET_DAQ_LIST_MODE_ALT) {
2379
0
            col_append_str(pinfo->cinfo, COL_INFO, "ALT:ON ");
2380
0
        } else {
2381
0
            col_append_str(pinfo->cinfo, COL_INFO, "ALT:OFF ");
2382
0
        }
2383
2384
0
        col_append_fstr(pinfo->cinfo, COL_INFO, "DAQ_LIST:%d EVENT_CHANNEL:%d PRESCALER:%d PRIO:%d", daq_list_number, channel_number, prescaler, priority);
2385
2386
        /* TODO: This information affects the DTO format, so we need to store it for the connection. */
2387
0
    }
2388
0
        break;
2389
2390
    //case XCP_CMD_GET_DAQ_LIST_MODE:
2391
    //    /* TODO */
2392
    //    break;
2393
2394
0
    case XCP_CMD_START_STOP_DAQ_LIST: {
2395
0
        uint32_t start_stop_mode;
2396
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_start_stop_daq_mode, tvb, offset, 1, ENC_NA, &start_stop_mode);
2397
0
        offset += 1;
2398
2399
0
        uint32_t daq_list_number;
2400
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_number, tvb, offset, 2, stream->endianess, &daq_list_number);
2401
0
        offset += 2;
2402
2403
0
        const char *tmp = try_val_to_str(start_stop_mode, start_stop_daq_mode);
2404
0
        if (tmp != NULL) {
2405
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s DAQ_LIST:%d", tmp, daq_list_number);
2406
0
        }
2407
2408
0
        message->current_daq_list_number = daq_list_number;
2409
0
    }
2410
0
    break;
2411
2412
0
    case XCP_CMD_START_STOP_SYNCH: {
2413
0
        uint32_t start_stop_mode;
2414
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_start_stop_synch_mode, tvb, offset, 1, ENC_NA, &start_stop_mode);
2415
0
        offset += 1;
2416
2417
0
        const char *tmp = try_val_to_str(start_stop_mode, start_stop_synch_mode);
2418
0
        if (tmp != NULL) {
2419
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", tmp);
2420
0
        }
2421
2422
0
    }
2423
0
        break;
2424
2425
0
    case XCP_CMD_GET_DAQ_CLOCK:
2426
        /* No Parameters */
2427
0
        break;
2428
2429
0
    case XCP_CMD_READ_DAQ:
2430
        /* No Parameters */
2431
0
        break;
2432
2433
0
    case XCP_CMD_GET_DAQ_PROCESSOR_INFO:
2434
        /* No Parameters */
2435
0
        break;
2436
2437
0
    case XCP_CMD_GET_RESOLUTION_INFO:
2438
        /* No Parameters */
2439
0
        break;
2440
2441
0
    case XCP_CMD_GET_DAQ_LIST_INFO: {
2442
0
        uint32_t daq_list_number;
2443
2444
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2445
0
        offset += 1;
2446
2447
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_number, tvb, offset, 2, stream->endianess, &daq_list_number);
2448
0
        offset += 2;
2449
2450
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": DAQ_LIST:%d", daq_list_number);
2451
0
    }
2452
0
        break;
2453
2454
0
    case XCP_CMD_GET_DAQ_EVENT_INFO: {
2455
0
        uint32_t channel_number;
2456
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2457
0
        offset += 1;
2458
2459
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_event_channel_number, tvb, offset, 2, stream->endianess, &channel_number);
2460
0
        offset += 2;
2461
2462
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": CHANNEL_NUMBER:%d", channel_number);
2463
0
    }
2464
0
        break;
2465
2466
0
    case XCP_CMD_FREE_DAQ:
2467
        /* No Parameters */
2468
2469
0
        stream->number_of_daqs = 0;
2470
0
        message->number_of_daqs = 0;
2471
0
        break;
2472
2473
0
    case XCP_CMD_ALLOC_DAQ: {
2474
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2475
0
        offset += 1;
2476
2477
0
        uint32_t daq_count;
2478
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_count, tvb, offset, 2, stream->endianess, &daq_count);
2479
0
        offset += 2;
2480
2481
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": DAQ_COUNT:%d", daq_count);
2482
2483
0
        stream->number_of_daqs = daq_count;
2484
0
        message->number_of_daqs = daq_count;
2485
2486
0
        stream->current_daqs = wmem_array_new(wmem_file_scope(), sizeof(xcp_daq_t));
2487
0
        message->current_daqs = stream->current_daqs;
2488
2489
0
        uint32_t i;
2490
0
        for (i = 0; i < daq_count; i++) {
2491
0
            xcp_daq_t tmp;
2492
0
            tmp.daq_number = i;
2493
0
            tmp.number_of_odts = 0;
2494
0
            tmp.current_odts = NULL;
2495
0
            wmem_array_append(message->current_daqs, &tmp, 1);
2496
0
        }
2497
2498
0
    }
2499
0
        break;
2500
2501
0
    case XCP_CMD_ALLOC_ODT: {
2502
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2503
0
        offset += 1;
2504
2505
0
        uint32_t daq_list_number;
2506
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_number, tvb, offset, 2, stream->endianess, &daq_list_number);
2507
0
        offset += 2;
2508
2509
0
        uint32_t odt_count;
2510
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_odt_count, tvb, offset, 1, ENC_NA, &odt_count);
2511
0
        offset += 1;
2512
2513
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": DAQ_LIST:%d ODT_COUNT:%d", daq_list_number, odt_count);
2514
2515
0
        xcp_daq_t *daq = get_daq_from_message(message, daq_list_number);
2516
0
        if (daq != NULL) {
2517
0
            if (odt_count > 0) {
2518
0
                daq->number_of_odts = odt_count;
2519
0
                daq->current_odts = wmem_array_new(wmem_file_scope(), sizeof(xcp_odt_t));
2520
2521
0
                uint32_t i;
2522
0
                for (i = 0; i < odt_count; i++) {
2523
0
                    xcp_odt_t tmp;
2524
0
                    tmp.odt_number = i;
2525
0
                    tmp.pid = 0xffffffff;
2526
0
                    tmp.number_of_odt_entries = 0;
2527
0
                    tmp.current_odt_entries = NULL;
2528
2529
0
                    wmem_array_append(daq->current_odts, &tmp, 1);
2530
0
                }
2531
0
            }
2532
0
        }
2533
0
    }
2534
0
        break;
2535
2536
0
    case XCP_CMD_ALLOC_ODT_ENTRY: {
2537
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2538
0
        offset += 1;
2539
2540
0
        uint32_t daq_list_number;
2541
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_number, tvb, offset, 2, stream->endianess, &daq_list_number);
2542
0
        offset += 2;
2543
2544
0
        uint32_t odt_number;
2545
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_odt_number, tvb, offset, 1, ENC_NA, &odt_number);
2546
0
        offset += 1;
2547
2548
0
        uint32_t odt_entries_count;
2549
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_odt_entries_count, tvb, offset, 1, ENC_NA, &odt_entries_count);
2550
0
        offset += 1;
2551
2552
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ": DAQ_LIST:%d ODT:%d ODT_ENTRIES_COUNT:%d", daq_list_number, odt_number, odt_entries_count);
2553
2554
0
        xcp_odt_t *odt = get_odt_from_message(message, daq_list_number, odt_number);
2555
0
        if (odt != NULL) {
2556
0
            if (odt_entries_count > 0) {
2557
0
                odt->number_of_odt_entries = odt_entries_count;
2558
0
                odt->current_odt_entries = wmem_array_new(wmem_file_scope(), sizeof(xcp_odt_entry_t));
2559
2560
0
                uint32_t i;
2561
0
                for (i = 0; i < odt_entries_count; i++) {
2562
0
                    xcp_odt_entry_t odt_entry;
2563
0
                    odt_entry.ecu_id = stream->ecu_id;
2564
0
                    odt_entry.addr_ext = 0;
2565
0
                    odt_entry.address = 0;
2566
0
                    odt_entry.name = NULL;
2567
0
                    wmem_array_append(odt->current_odt_entries, &odt_entry, 1);
2568
0
                }
2569
0
            }
2570
0
        }
2571
0
    }
2572
0
        break;
2573
2574
2575
0
    case XCP_CMD_PROGRAM_START:
2576
        /* No Parameters */
2577
0
        break;
2578
2579
0
    case XCP_CMD_PROGRAM_CLEAR: {
2580
0
        static int * const program_clear_range_fct_flags[] = {
2581
0
            &hf_xcp_program_clear_range_fct_4,
2582
0
            &hf_xcp_program_clear_range_fct_2,
2583
0
            &hf_xcp_program_clear_range_fct_1,
2584
0
            NULL
2585
0
        };
2586
2587
0
        uint32_t clear_mode;
2588
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_program_clear_mode, tvb, offset, 1, ENC_NA, &clear_mode);
2589
0
        offset += 1;
2590
2591
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2592
0
        offset += 1;
2593
2594
0
        proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2595
0
        offset += 1;
2596
2597
0
        uint32_t clear_range_abs;
2598
0
        uint64_t clear_range_fct;
2599
0
        switch (clear_mode) {
2600
0
        case 0x00:
2601
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_program_clear_range_abs, tvb, offset, 4, stream->endianess, &clear_range_abs);
2602
0
            offset += 4;
2603
2604
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": Clear Absolute 0x%08x", clear_range_abs);
2605
0
            break;
2606
0
        case 0x01:
2607
0
            proto_tree_add_bitmask_ret_uint64(xcp_tree, tvb, offset, hf_xcp_program_clear_range_fct, ett_xcp_set_daq_list_mode_mode, program_clear_range_fct_flags, stream->endianess, &clear_range_fct);
2608
0
            offset += 4;
2609
2610
0
            col_append_str(pinfo->cinfo, COL_INFO, ": Clear Functional:");
2611
0
            if ((clear_range_fct & 0x00000001) == 0x00000001) {
2612
0
                col_append_str(pinfo->cinfo, COL_INFO, "  Calibration area(s)");
2613
0
            }
2614
0
            if ((clear_range_fct & 0x00000002) == 0x00000002) {
2615
0
                col_append_str(pinfo->cinfo, COL_INFO, "  Code area(s)");
2616
0
            }
2617
0
            if ((clear_range_fct & 0x00000004) == 0x00000004) {
2618
0
                col_append_str(pinfo->cinfo, COL_INFO, "  NVRAM area(s)");
2619
0
            }
2620
0
            break;
2621
0
        }
2622
0
    }
2623
0
        break;
2624
2625
0
    case XCP_CMD_PROGRAM: {
2626
0
        uint32_t number_of_elements;
2627
0
        proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_num_of_data_elements, tvb, offset, 1, ENC_NA, &number_of_elements);
2628
0
        message->number_of_elements = number_of_elements;
2629
0
        offset += 1;
2630
2631
0
        uint32_t i;
2632
0
        uint32_t tmp;
2633
0
        if (stream->addr_granularity == 1) {
2634
0
            for (i = 0; i < number_of_elements; i++) {
2635
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_1byte, tvb, offset, 1, ENC_NA, &tmp);
2636
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tmp);
2637
0
                offset += 1;
2638
0
            }
2639
0
        } else if (stream->addr_granularity == 2) {
2640
0
            for (i = 0; i < number_of_elements; i++) {
2641
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_2bytes, tvb, offset, 2, stream->endianess, &tmp);
2642
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", tmp);
2643
0
                offset += 2;
2644
0
            }
2645
0
        } else if (stream->addr_granularity == 4) {
2646
0
            proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2647
0
            proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
2648
0
            offset += 2;
2649
2650
0
            for (i = 0; i < number_of_elements; i++) {
2651
0
                proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_4bytes, tvb, offset, 4, stream->endianess, &tmp);
2652
0
                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%08x", tmp);
2653
0
                offset += 4;
2654
0
            }
2655
0
        }
2656
0
    }
2657
0
        break;
2658
2659
0
    case XCP_CMD_PROGRAM_RESET:
2660
        /* No Parameters */
2661
0
        break;
2662
2663
0
    case XCP_CMD_GET_PGM_PROCESSOR_INFO:
2664
        /* No Parameters */
2665
0
        break;
2666
2667
    //case XCP_CMD_GET_SECTOR_INFO:
2668
    //    /* TODO */
2669
    //    break;
2670
2671
    //case XCP_CMD_PROGRAM_PREPARE:
2672
    //    /* TODO */
2673
    //    break;
2674
2675
    //case XCP_CMD_PROGRAM_FORMAT:
2676
    //    /* TODO */
2677
    //    break;
2678
2679
    //case XCP_CMD_PROGRAM_NEXT:
2680
    //    /* TODO */
2681
    //    break;
2682
2683
    //case XCP_CMD_PROGRAM_MAX:
2684
    //    /* TODO */
2685
    //    break;
2686
2687
    //case XCP_CMD_PROGRAM_VERIFY:
2688
    //    /* TODO */
2689
    //    break;
2690
2691
    //case XCP_CMD_WRITE_DAQ_MULTIPLE:
2692
    //    /* TODO */
2693
    //    break;
2694
2695
    //case XCP_CMD_TIME_CORRELATION_PROPERTIES:
2696
    //    /* TODO */
2697
    //    break;
2698
2699
    //case XCP_CMD_DTO_CTR_PROPERTIES:
2700
    //    /* TODO */
2701
    //    break;
2702
2703
2704
0
    case XCP_CMD_2BYTE_FIRST_BYTE:
2705
0
        switch (cmd_lvl1) {
2706
0
        case XCP_CMD_2BYTE_GET_VERSION:
2707
            /* No Parameters */
2708
0
            break;
2709
2710
0
        case XCP_CMD_2BYTE_SET_DAQ_PACKED_MODE: {
2711
0
            static int * const set_daq_packed_timestamp_mode[] = {
2712
0
                &hf_xcp_packed_timestamp_mode_flags,
2713
0
                NULL
2714
0
            };
2715
2716
0
            uint32_t daq_list_number;
2717
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_daq_list_number, tvb, offset, 2, stream->endianess, &daq_list_number);
2718
0
            offset += 2;
2719
2720
0
            proto_tree_add_item(xcp_tree, hf_xcp_daq_packed_mode, tvb, offset, 1, ENC_NA);
2721
0
            offset += 1;
2722
2723
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_packed_timestamp_mode, ett_xcp_set_daq_packed_mode_timestamp_mode, set_daq_packed_timestamp_mode, ENC_NA);
2724
0
            offset += 1;
2725
2726
0
            uint32_t sample_count;
2727
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_packed_sample_count, tvb, offset, 2, stream->endianess, &sample_count);
2728
0
            offset += 2;
2729
2730
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": DAQ_LIST:%d SAMPLE_COUNT:%d", daq_list_number, sample_count);
2731
0
        }
2732
0
            break;
2733
2734
        //case XCP_CMD_2BYTE_GET_DAQ_PACKED_MODE:
2735
        //    /* TODO */
2736
        //    break;
2737
2738
0
        case XCP_CMD_2BYTE_XCP_SW_DEBUG:
2739
0
            offset += dissect_sw_debug_cmd(tvb, pinfo, xcp_tree, offset, tvb_captured_length_remaining(tvb, offset), true, xcp_type, message, stream);
2740
0
            break;
2741
2742
0
        case XCP_CMD_2BYTE_XCP_POD_COMMANDS:
2743
0
            offset += dissect_pod_cmd(tvb, pinfo, xcp_tree, offset, tvb_captured_length_remaining(tvb, offset), true, xcp_type, message, stream);
2744
0
            break;
2745
2746
0
        default:
2747
0
            proto_tree_add_expert_remaining(xcp_tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
2748
0
            col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
2749
0
        }
2750
0
        break;
2751
2752
0
    default:
2753
0
        proto_tree_add_expert_remaining(xcp_tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
2754
0
        col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
2755
0
    }
2756
2757
0
    int unparsed_length = tvb_captured_length_remaining(tvb, offset);
2758
0
    if (unparsed_length > 0) {
2759
0
        proto_tree_add_item(xcp_tree, hf_xcp_unparsed, tvb, offset, unparsed_length, ENC_NA);
2760
0
        offset += tvb_captured_length_remaining(tvb, offset);
2761
0
    }
2762
2763
0
    return offset - offset_orig;
2764
0
}
2765
2766
static int
2767
0
dissect_xcp_s2m(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset_orig, int max_length, uint32_t xcp_type, xcp_message_t *message, xcp_stream_t *stream) {
2768
0
    if (stream == NULL || message == NULL) {
2769
        /* should never happen */
2770
0
        ws_assert_not_reached();
2771
0
        return 0;
2772
0
    }
2773
2774
0
    uint32_t offset = offset_orig;
2775
0
    proto_item *ti_root = NULL;
2776
0
    proto_tree *xcp_tree = NULL;
2777
2778
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "XCP");
2779
0
    col_clear(pinfo->cinfo, COL_INFO);
2780
2781
0
    ti_root = proto_tree_add_item(tree, hf_xcp_packet, tvb, offset, max_length, ENC_NA);
2782
0
    xcp_tree = proto_item_add_subtree(ti_root, ett_xcp_packet);
2783
2784
    /* setting up the meta data*/
2785
0
    if (!(pinfo->fd->visited)) {
2786
2787
0
        stream->last_s2m = message;
2788
2789
0
        if (stream->last_m2s != NULL) {
2790
0
            message->peer_message = stream->last_m2s;
2791
0
            stream->last_m2s->peer_message = message;
2792
0
        }
2793
2794
0
        message->number_of_daqs = stream->number_of_daqs;
2795
0
        message->current_daqs = stream->current_daqs;
2796
2797
0
        message->m2s = false;
2798
0
    }
2799
2800
0
    uint32_t pid = 0;
2801
0
    proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_pid_s2m, tvb, offset, 1, ENC_NA, &pid);
2802
0
    offset += 1;
2803
2804
0
    if (pid == XCP_PID_RES) {
2805
2806
0
        if (message != NULL && message->peer_message != NULL && message->peer_message->cmd != XCP_MESSAGE_CMD_UNKNOWN) {
2807
0
            message->cmd = message->peer_message->cmd;
2808
0
            message->cmd_lvl1 = message->peer_message->cmd_lvl1;
2809
0
            message->cmd_sw_debug = message->peer_message->cmd_sw_debug;
2810
0
            message->cmd_pod = message->peer_message->cmd_pod;
2811
0
            message->transport_layer_sub_cmd = message->peer_message->transport_layer_sub_cmd;
2812
2813
0
            if (message->cmd != XCP_CMD_2BYTE_FIRST_BYTE) {
2814
0
                col_append_fstr(pinfo->cinfo, COL_INFO, "XCP S->M: %s RES", val_to_str(pinfo->pool, message->cmd, cmd_code_mnemonics, "Unknown Command Code 0x%02x"));
2815
0
            } else {
2816
0
                switch (message->cmd_lvl1) {
2817
0
                case XCP_CMD_2BYTE_XCP_SW_DEBUG:
2818
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, "XCP S->M: %s RES", val_to_str(pinfo->pool, message->cmd_sw_debug, cmd_sw_dbg_mnemonics, "Unknown Command Code 0xC0 0xFC 0x%02x"));
2819
0
                    break;
2820
2821
0
                case XCP_CMD_2BYTE_XCP_POD_COMMANDS:
2822
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, "XCP S->M: %s RES", val_to_str(pinfo->pool, message->cmd_pod, cmd_pod_mnemonics, "Unknown Command Code 0xC0 0xFD 0x%04x"));
2823
0
                    break;
2824
2825
0
                default:
2826
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, "XCP S->M: %s RES", val_to_str(pinfo->pool, message->cmd_lvl1, cmd_code_mnemonics_2bytes, "Unknown Command Code 0xC0 0x%02x"));
2827
0
                    break;
2828
0
                }
2829
0
            }
2830
0
        }
2831
2832
0
        switch (message->cmd) {
2833
0
        case XCP_CMD_CONNECT: {
2834
0
            static int * const resource_flags[] = {
2835
0
                &hf_xcp_conn_resource_dbg,
2836
0
                &hf_xcp_conn_resource_pgm,
2837
0
                &hf_xcp_conn_resource_stim,
2838
0
                &hf_xcp_conn_resource_daq,
2839
0
                &hf_xcp_conn_resource_cal_pag,
2840
0
                NULL
2841
0
            };
2842
2843
0
            static int * const comm_mode_basic_flags[] = {
2844
0
                &hf_xcp_conn_comm_mode_bsc_optional,
2845
0
                &hf_xcp_conn_comm_mode_bsc_sl_blk_mode,
2846
0
                &hf_xcp_conn_comm_mode_bsc_addr_gran,
2847
0
                &hf_xcp_conn_comm_mode_bsc_byte_order,
2848
0
                NULL
2849
0
            };
2850
2851
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_conn_resource, ett_xcp_resource_flags, resource_flags, ENC_NA);
2852
0
            offset += 1;
2853
2854
0
            if (!pinfo->fd->visited) {
2855
0
                uint8_t address_granularity = (tvb_get_uint8(tvb, offset) & 0x06) >> 1;
2856
0
                switch (address_granularity) {
2857
0
                case 0:
2858
0
                    stream->addr_granularity = 1;
2859
0
                    break;
2860
0
                case 1:
2861
0
                    stream->addr_granularity = 2;
2862
0
                    break;
2863
0
                case 2:
2864
0
                    stream->addr_granularity = 4;
2865
0
                    break;
2866
0
                default:
2867
0
                    stream->addr_granularity = 0;
2868
0
                    break;
2869
0
                }
2870
0
            }
2871
2872
0
            uint64_t comm_mode_basic;
2873
0
            proto_tree_add_bitmask_ret_uint64(xcp_tree, tvb, offset, hf_xcp_conn_comm_mode_bsc, ett_xcp_comm_mode_basic_flags, comm_mode_basic_flags, ENC_NA, &comm_mode_basic);
2874
0
            stream->endianess = ((comm_mode_basic & 0x01) == 0x01) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN;
2875
0
            offset += 1;
2876
2877
0
            proto_tree_add_item(xcp_tree, hf_xcp_conn_max_cto, tvb, offset, 1, ENC_NA);
2878
0
            offset += 1;
2879
2880
0
            proto_tree_add_item(xcp_tree, hf_xcp_conn_max_dto, tvb, offset, 2, stream->endianess);
2881
0
            offset += 2;
2882
2883
0
            proto_tree_add_item(xcp_tree, hf_xcp_conn_proto_layer_ver, tvb, offset, 1, ENC_NA);
2884
0
            offset += 1;
2885
2886
0
            proto_tree_add_item(xcp_tree, hf_xcp_conn_trans_layer_ver, tvb, offset, 1, ENC_NA);
2887
0
            offset += 1;
2888
0
        }
2889
0
            break;
2890
2891
0
        case XCP_CMD_DISCONNECT:
2892
            /* No Parameters */
2893
0
            break;
2894
2895
0
        case XCP_CMD_GET_STATUS: {
2896
0
            static int * const current_session_status_flags[] = {
2897
0
                &hf_xcp_get_st_cur_ses_resume,
2898
0
                &hf_xcp_get_st_cur_ses_daq_running,
2899
0
                &hf_xcp_get_st_cur_ses_daq_cfg_lost,
2900
0
                &hf_xcp_get_st_cur_ses_clear_daq_req,
2901
0
                &hf_xcp_get_st_cur_ses_store_daq_req,
2902
0
                &hf_xcp_get_st_cur_ses_calpag_cfg_lst,
2903
0
                &hf_xcp_get_st_cur_ses_store_cal_req,
2904
0
                NULL
2905
0
            };
2906
2907
0
            static int * const current_protection_status_flags[] = {
2908
0
                &hf_xcp_get_st_cur_res_pro_st_dbg,
2909
0
                &hf_xcp_get_st_cur_res_pro_st_pgm,
2910
0
                &hf_xcp_get_st_cur_res_pro_st_stim,
2911
0
                &hf_xcp_get_st_cur_res_pro_st_daq,
2912
0
                &hf_xcp_get_st_cur_res_pro_st_calpag,
2913
0
                NULL
2914
0
            };
2915
2916
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_get_st_cur_ses, ett_xcp_current_session_status_flags, current_session_status_flags, ENC_NA);
2917
0
            offset += 1;
2918
2919
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_get_st_cur_res_pro_st, ett_xcp_current_res_protec_status, current_protection_status_flags, ENC_NA);
2920
0
            offset += 1;
2921
2922
0
            proto_tree_add_item(xcp_tree, hf_xcp_get_st_cur_state_number, tvb, offset, 1, ENC_NA);
2923
0
            offset += 1;
2924
2925
0
            proto_tree_add_item(xcp_tree, hf_xcp_session_cfg_id, tvb, offset, 2, stream->endianess);
2926
0
            offset += 2;
2927
0
        }
2928
0
            break;
2929
2930
0
        case XCP_CMD_SYNCH:
2931
            /* No Parameters */
2932
0
            break;
2933
2934
0
        case XCP_CMD_GET_COMM_MODE_INFO: {
2935
0
            static int * const comm_mode_optional_flags[] = {
2936
0
                &hf_xcp_comm_mode_opt_interl,
2937
0
                &hf_xcp_comm_mode_opt_mas_blck_mode,
2938
0
                NULL
2939
0
            };
2940
2941
0
            proto_tree_add_item(xcp_tree, hf_xcp_comm_mode_res1, tvb, offset, 1, ENC_NA);
2942
0
            offset += 1;
2943
2944
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_comm_mode_opt, ett_xcp_comm_mode_optional, comm_mode_optional_flags, ENC_NA);
2945
0
            offset += 1;
2946
2947
0
            proto_tree_add_item(xcp_tree, hf_xcp_comm_mode_res2, tvb, offset, 1, ENC_NA);
2948
0
            offset += 1;
2949
2950
0
            proto_tree_add_item(xcp_tree, hf_xcp_comm_mode_max_bs, tvb, offset, 1, ENC_NA);
2951
0
            offset += 1;
2952
2953
0
            proto_tree_add_item(xcp_tree, hf_xcp_comm_mode_min_st, tvb, offset, 1, ENC_NA);
2954
0
            offset += 1;
2955
2956
0
            proto_tree_add_item(xcp_tree, hf_xcp_comm_mode_queue_size, tvb, offset, 1, ENC_NA);
2957
0
            offset += 1;
2958
2959
0
            proto_tree_add_item(xcp_tree, hf_xcp_comm_mode_driver_version, tvb, offset, 1, ENC_NA);
2960
0
            offset += 1;
2961
0
        }
2962
0
            break;
2963
2964
0
        case XCP_CMD_GET_ID: {
2965
0
            static int * const get_id_mode_parameter[] = {
2966
0
                &hf_xcp_get_id_mode_compressed_encrypted,
2967
0
                &hf_xcp_get_id_mode_transfer_mode,
2968
0
                NULL
2969
0
            };
2970
2971
0
            uint64_t mode_bits;
2972
0
            proto_tree_add_bitmask_ret_uint64(xcp_tree, tvb, offset, hf_xcp_get_id_mode, ett_xcp_get_id_mode_parameter, get_id_mode_parameter, ENC_NA, &mode_bits);
2973
0
            bool mode_comp_enc = (mode_bits & 0x0000000000000002) == 0x0000000000000002;
2974
0
            bool mode_transfer = (mode_bits & 0x0000000000000001) == 0x0000000000000001;
2975
0
            offset += 1;
2976
2977
0
            proto_tree_add_item(xcp_tree, hf_xcp_get_id_res, tvb, offset, 2, stream->endianess);
2978
0
            offset += 2;
2979
2980
0
            uint32_t length;
2981
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_get_id_length, tvb, offset, 4, stream->endianess, &length);
2982
0
            offset += 4;
2983
2984
0
            if (mode_transfer) {
2985
0
                if (!mode_comp_enc) {
2986
0
                    proto_tree_add_item(xcp_tree, hf_xcp_get_id_id_string, tvb, offset, length, ENC_ASCII);
2987
0
                    offset += length;
2988
0
                } else {
2989
0
                    proto_tree_add_item(xcp_tree, hf_xcp_get_id_id_bytes, tvb, offset, length, ENC_NA);
2990
0
                    offset += length;
2991
0
                }
2992
0
            }
2993
0
        }
2994
0
            break;
2995
2996
0
        case XCP_CMD_SET_REQUEST:
2997
            /* No Parameters */
2998
0
            break;
2999
3000
0
        case XCP_CMD_GET_SEED: {
3001
0
            proto_tree_add_item(xcp_tree, hf_xcp_get_seed_length_of_seed, tvb, offset, 1, ENC_NA);
3002
0
            offset += 1;
3003
3004
0
            uint32_t seed_length = max_length - (offset - offset_orig);
3005
0
            proto_tree_add_item(xcp_tree, hf_xcp_get_seed_seed, tvb, offset, seed_length, ENC_NA);
3006
0
            offset += seed_length;
3007
0
        }
3008
0
            break;
3009
3010
0
        case XCP_CMD_UNLOCK: {
3011
0
            static int * const current_protection_status_flags[] = {
3012
0
                &hf_xcp_get_st_cur_res_pro_st_dbg,
3013
0
                &hf_xcp_get_st_cur_res_pro_st_pgm,
3014
0
                &hf_xcp_get_st_cur_res_pro_st_stim,
3015
0
                &hf_xcp_get_st_cur_res_pro_st_daq,
3016
0
                &hf_xcp_get_st_cur_res_pro_st_calpag,
3017
0
                NULL
3018
0
            };
3019
3020
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_get_st_cur_res_pro_st, ett_xcp_current_res_protec_status, current_protection_status_flags, ENC_NA);
3021
0
            offset += 1;
3022
0
        }
3023
0
            break;
3024
3025
0
        case XCP_CMD_SET_MTA:
3026
            /* No Parameters */
3027
0
            break;
3028
3029
0
        case XCP_CMD_UPLOAD:
3030
            /* fall through */
3031
0
        case XCP_CMD_SHORT_UPLOAD: {
3032
0
            uint32_t i;
3033
0
            uint32_t tmp;
3034
3035
0
            if (message->peer_message == NULL) {
3036
                /* this should never happen */
3037
0
                ws_assert_not_reached();
3038
0
                return offset - offset_orig;
3039
0
            }
3040
3041
0
            if (stream->addr_granularity == 1) {
3042
0
                for (i = 0; i < message->peer_message->number_of_elements; i++) {
3043
0
                    proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_1byte, tvb, offset, 1, ENC_NA, &tmp);
3044
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tmp);
3045
0
                    offset += 1;
3046
0
                }
3047
0
            } else if (stream->addr_granularity == 2) {
3048
0
                proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
3049
0
                offset += 1;
3050
0
                for (i = 0; i < message->peer_message->number_of_elements; i++) {
3051
0
                    proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_2bytes, tvb, offset, 2, stream->endianess, &tmp);
3052
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", tmp);
3053
0
                    offset += 2;
3054
0
                }
3055
0
            } else if (stream->addr_granularity == 4) {
3056
0
                proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
3057
0
                proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset + 1, 1, ENC_NA);
3058
0
                proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset + 2, 1, ENC_NA);
3059
0
                offset += 3;
3060
3061
0
                for (i = 0; i < message->peer_message->number_of_elements; i++) {
3062
0
                    proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_data_element_4bytes, tvb, offset, 4, stream->endianess, &tmp);
3063
0
                    col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%08x", tmp);
3064
0
                    offset += 4;
3065
0
                }
3066
0
            }
3067
0
        }
3068
0
            break;
3069
3070
0
        case XCP_CMD_BUILD_CHECKSUM:
3071
0
            proto_tree_add_item(xcp_tree, hf_xcp_build_chksum_type, tvb, offset, 1, ENC_NA);
3072
0
            offset += 1;
3073
3074
0
            proto_tree_add_item(xcp_tree, hf_xcp_build_chksum_res3, tvb, offset, 2, stream->endianess);
3075
0
            offset += 2;
3076
3077
0
            proto_tree_add_item(xcp_tree, hf_xcp_build_chksum, tvb, offset, 4, stream->endianess);
3078
0
            offset += 4;
3079
3080
0
            break;
3081
3082
0
        case XCP_CMD_TRANSPORT_LAYER_CMD:
3083
0
            offset += dissect_transport_layer_cmd(tvb, pinfo, xcp_tree, offset, max_length, false, xcp_type, message, stream);
3084
0
            break;
3085
3086
        //case XCP_CMD_USER_CMD:
3087
        //    /* TODO */
3088
        //    break;
3089
3090
3091
0
        case XCP_CMD_DOWNLOAD:
3092
            /* No Parameters */
3093
0
            break;
3094
3095
        //case XCP_CMD_DOWNLOAD_NEXT:
3096
        //    /* TODO */
3097
        //    break;
3098
3099
0
        case XCP_CMD_DOWNLOAD_MAX:
3100
            /* No Parameters */
3101
0
            break;
3102
3103
0
        case XCP_CMD_SHORT_DOWNLOAD:
3104
            /* No Parameters */
3105
0
            break;
3106
3107
0
        case XCP_CMD_MODIFY_BITS:
3108
            /* No Parameters */
3109
0
            break;
3110
3111
3112
0
        case XCP_CMD_SET_CAL_PAGE:
3113
            /* No Parameters */
3114
0
            break;
3115
3116
0
        case XCP_CMD_GET_CAL_PAGE: {
3117
0
            proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
3118
0
            offset += 1;
3119
3120
0
            proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
3121
0
            offset += 1;
3122
3123
0
            uint32_t page_number;
3124
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_logical_data_page_number, tvb, offset, 1, ENC_NA, &page_number);
3125
0
            offset += 1;
3126
3127
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": PAGE:%d", page_number);
3128
0
        }
3129
0
            break;
3130
3131
        //case XCP_CMD_GET_PAG_PROCESSOR_INFO:
3132
        //    /* TODO */
3133
        //    break;
3134
3135
0
        case XCP_CMD_GET_SEGMENT_INFO:
3136
            /* No Parameters */
3137
0
            break;
3138
3139
        //case XCP_CMD_GET_PAGE_INFO:
3140
        //    /* TODO */
3141
        //    break;
3142
3143
0
        case XCP_CMD_SET_SEGMENT_MODE:
3144
            /* No Parameters */
3145
0
            break;
3146
3147
        //case XCP_CMD_GET_SEGMENT_MODE:
3148
        //    /* TODO */
3149
        //    break;
3150
3151
0
        case XCP_CMD_COPY_CAL_PAGE:
3152
            /* No Parameters */
3153
0
            break;
3154
3155
3156
0
        case XCP_CMD_CLEAR_DAQ_LIST:
3157
            /* No Parameters */
3158
0
            break;
3159
3160
0
        case XCP_CMD_SET_DAQ_PTR:
3161
            /* No Parameters */
3162
0
            break;
3163
3164
0
        case XCP_CMD_WRITE_DAQ:
3165
            /* No Parameters */
3166
0
            break;
3167
3168
0
        case XCP_CMD_SET_DAQ_LIST_MODE:
3169
            /* No Parameters */
3170
0
            break;
3171
3172
            //case XCP_CMD_GET_DAQ_LIST_MODE:
3173
            //    /* TODO */
3174
            //    break;
3175
3176
0
        case XCP_CMD_START_STOP_DAQ_LIST: {
3177
0
            uint32_t odt_pid;
3178
0
            proto_tree_add_item_ret_uint(tree, hf_xcp_first_pid, tvb, offset, 1, ENC_NA, &odt_pid);
3179
0
            offset += 1;
3180
3181
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": PID:0x%02x", odt_pid);
3182
3183
0
            if (message != NULL && message->peer_message != NULL) {
3184
0
                xcp_daq_t *daq = get_daq_from_message(message, message->peer_message->current_daq_list_number);
3185
3186
0
                if (daq != NULL && daq->current_odts != NULL && daq->number_of_odts <= wmem_array_get_count(daq->current_odts)) {
3187
0
                    xcp_odt_t *odt;
3188
3189
0
                    uint32_t i;
3190
0
                    for (i = 0; i < daq->number_of_odts; i++) {
3191
0
                        odt = (xcp_odt_t *)wmem_array_index(daq->current_odts, i);
3192
0
                        odt->pid = odt_pid + i;
3193
3194
0
                        wmem_map_insert(stream->pid_map, GUINT_TO_POINTER(odt_pid + i), (void *)odt);
3195
0
                    }
3196
0
                }
3197
0
            }
3198
0
        }
3199
0
            break;
3200
3201
0
        case XCP_CMD_START_STOP_SYNCH:
3202
            /* No Parameters */
3203
0
            break;
3204
3205
0
        case XCP_CMD_GET_DAQ_CLOCK: {
3206
0
            static int * const trigger_info[] = {
3207
0
                &hf_xcp_trigger_info_time_of_ts_sampl,
3208
0
                &hf_xcp_trigger_info_trigger_init,
3209
0
                NULL
3210
0
            };
3211
3212
0
            static int * const payload_format[] = {
3213
0
                &hf_xcp_payload_fmt_cluster_ident,
3214
0
                &hf_xcp_payload_fmt_fmt_ecu,
3215
0
                &hf_xcp_payload_fmt_fmt_grandm,
3216
0
                &hf_xcp_payload_fmt_xcp_slv,
3217
0
                NULL
3218
0
            };
3219
3220
0
            proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
3221
0
            offset += 1;
3222
3223
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_trigger_info, ett_xcp_trigger_info, trigger_info, ENC_NA);
3224
0
            offset += 1;
3225
3226
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_payload_fmt, ett_xcp_payload_format, payload_format, ENC_NA);
3227
0
            offset += 1;
3228
3229
            /*
3230
             * How to know format? After TIME_SYNCHRONIZATION_PROPERTIES with fmt > 1 was called,
3231
             *
3232
             * we switch to Extended Format! Except if MAX_CTO = 8.
3233
             * Maybe the standard means TIME_CORRELATION_PROPERTIES???
3234
             */
3235
0
            if (stream->timestamp_extended) {
3236
0
                proto_tree_add_expert_remaining(tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
3237
                /* TODO */
3238
0
            } else {
3239
0
                proto_tree_add_item(xcp_tree, hf_xcp_payload_timestamp_legacy, tvb, offset, 4, stream->endianess);
3240
0
                offset += 4;
3241
0
            }
3242
0
        }
3243
0
            break;
3244
3245
        //case XCP_CMD_READ_DAQ:
3246
        //    /* TODO */
3247
        //    break;
3248
3249
0
        case XCP_CMD_GET_DAQ_PROCESSOR_INFO: {
3250
0
            static int * const daq_properties_flags[] = {
3251
0
                &hf_xcp_daq_props_overload,
3252
0
                &hf_xcp_daq_props_pid_off_supported,
3253
0
                &hf_xcp_daq_props_timestamp_supported,
3254
0
                &hf_xcp_daq_props_bit_stim_supported,
3255
0
                &hf_xcp_daq_props_resume_supported,
3256
0
                &hf_xcp_daq_props_prescaler_supported,
3257
0
                &hf_xcp_daq_props_config_type,
3258
0
                NULL
3259
0
            };
3260
3261
0
            static int * const daq_key_byte[] = {
3262
0
                &hf_xcp_daq_key_byte_id_field,
3263
0
                &hf_xcp_daq_key_byte_addr_ext,
3264
0
                &hf_xcp_daq_key_byte_optimization,
3265
0
                NULL
3266
0
            };
3267
3268
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_daq_props, ett_xcp_daq_properties, daq_properties_flags, ENC_NA);
3269
0
            offset += 1;
3270
3271
0
            proto_tree_add_item(xcp_tree, hf_xcp_max_daq, tvb, offset, 2, stream->endianess);
3272
0
            offset += 2;
3273
3274
0
            proto_tree_add_item(xcp_tree, hf_xcp_max_event_channel, tvb, offset, 2, stream->endianess);
3275
0
            offset += 2;
3276
3277
0
            proto_tree_add_item(xcp_tree, hf_xcp_min_daq, tvb, offset, 1, ENC_NA);
3278
0
            offset += 1;
3279
3280
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_daq_key_byte, ett_xcp_daq_key_byte, daq_key_byte, ENC_NA);
3281
0
            offset += 1;
3282
0
        }
3283
0
            break;
3284
3285
0
        case XCP_CMD_GET_RESOLUTION_INFO: {
3286
0
            static int * const timestamp_mode_flags[] = {
3287
0
                &hf_xcp_timestamp_mode_time_unit,
3288
0
                &hf_xcp_timestamp_mode_timestamp_fixed,
3289
0
                &hf_xcp_timestamp_mode_timestamp_size,
3290
0
                NULL
3291
0
            };
3292
3293
0
            proto_tree_add_item(xcp_tree, hf_xcp_granularity_odt_entry_size_daq, tvb, offset, 1, ENC_NA);
3294
0
            offset += 1;
3295
3296
0
            proto_tree_add_item(xcp_tree, hf_xcp_max_odt_entry_size_daq, tvb, offset, 1, ENC_NA);
3297
0
            offset += 1;
3298
3299
0
            proto_tree_add_item(xcp_tree, hf_xcp_granularity_odt_entry_size_stim, tvb, offset, 1, ENC_NA);
3300
0
            offset += 1;
3301
3302
0
            proto_tree_add_item(xcp_tree, hf_xcp_max_odt_entry_size_stim, tvb, offset, 1, ENC_NA);
3303
0
            offset += 1;
3304
3305
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_timestamp_mode, ett_xcp_timestamp_mode, timestamp_mode_flags, ENC_NA);
3306
0
            offset += 1;
3307
3308
0
            proto_tree_add_item(xcp_tree, hf_xcp_timestamp_ticks, tvb, offset, 2, stream->endianess);
3309
0
            offset += 2;
3310
0
        }
3311
0
            break;
3312
3313
0
        case XCP_CMD_GET_DAQ_LIST_INFO: {
3314
0
            static int * const daq_list_properties_flags[] = {
3315
0
                &hf_xcp_daq_list_properties_packed,
3316
0
                &hf_xcp_daq_list_properties_stim,
3317
0
                &hf_xcp_daq_list_properties_daq,
3318
0
                &hf_xcp_daq_list_properties_event_fixed,
3319
0
                &hf_xcp_daq_list_properties_predefined,
3320
0
                NULL
3321
0
            };
3322
3323
0
            uint64_t flags;
3324
0
            proto_tree_add_bitmask_ret_uint64(xcp_tree, tvb, offset, hf_xcp_daq_list_properties, ett_xcp_daq_list_properties, daq_list_properties_flags, ENC_NA, &flags);
3325
0
            offset += 1;
3326
3327
0
            proto_tree_add_item(xcp_tree, hf_xcp_daq_list_max_odt, tvb, offset, 1, ENC_NA);
3328
0
            offset += 1;
3329
3330
0
            proto_tree_add_item(xcp_tree, hf_xcp_daq_list_max_odt_entries, tvb, offset, 1, ENC_NA);
3331
0
            offset += 1;
3332
3333
            /* The XCP standard is inconsistent about this! Parameter is always present but examples in the standard do not have it!? */
3334
0
            if ((flags & 0x02) == 0x02) {
3335
0
                proto_tree_add_item(xcp_tree, hf_xcp_daq_list_fixed_event, tvb, offset, 2, stream->endianess);
3336
0
                offset += 2;
3337
0
            }
3338
0
        }
3339
0
            break;
3340
3341
0
        case XCP_CMD_GET_DAQ_EVENT_INFO: {
3342
0
            static int * const daq_event_properties_flags[] = {
3343
0
                &hf_xcp_daq_event_properties_consistency,
3344
0
                &hf_xcp_daq_event_properties_packed,
3345
0
                &hf_xcp_daq_event_properties_stim,
3346
0
                &hf_xcp_daq_event_properties_daq,
3347
0
                NULL
3348
0
            };
3349
3350
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_daq_event_properties, ett_xcp_daq_event_properties, daq_event_properties_flags, ENC_NA);
3351
0
            offset += 1;
3352
3353
0
            proto_tree_add_item(xcp_tree, hf_xcp_max_daq_list, tvb, offset, 1, ENC_NA);
3354
0
            offset += 1;
3355
3356
0
            proto_tree_add_item(xcp_tree, hf_xcp_event_channel_name_length, tvb, offset, 1, ENC_NA);
3357
0
            offset += 1;
3358
3359
0
            proto_tree_add_item(xcp_tree, hf_xcp_event_channel_time_cycle, tvb, offset, 1, ENC_NA);
3360
0
            offset += 1;
3361
3362
0
            proto_tree_add_item(xcp_tree, hf_xcp_event_channel_time_unit, tvb, offset, 1, ENC_NA);
3363
0
            offset += 1;
3364
3365
0
            proto_tree_add_item(xcp_tree, hf_xcp_event_channel_priority, tvb, offset, 1, ENC_NA);
3366
0
            offset += 1;
3367
0
        }
3368
0
            break;
3369
3370
0
        case XCP_CMD_FREE_DAQ:
3371
            /* No Parameters */
3372
0
            break;
3373
3374
0
        case XCP_CMD_ALLOC_DAQ:
3375
            /* No Parameters */
3376
0
            break;
3377
3378
0
        case XCP_CMD_ALLOC_ODT:
3379
            /* No Parameters */
3380
0
            break;
3381
3382
0
        case XCP_CMD_ALLOC_ODT_ENTRY:
3383
            /* No Parameters */
3384
0
            break;
3385
3386
3387
0
        case XCP_CMD_PROGRAM_START: {
3388
0
            static int * const comm_mode_pgm[] = {
3389
0
                &hf_xcp_comm_mode_pgm_slave_block_mode,
3390
0
                &hf_xcp_comm_mode_pgm_interleaved_mode,
3391
0
                &hf_xcp_comm_mode_pgm_master_block_mode,
3392
0
                NULL
3393
0
            };
3394
3395
0
            proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
3396
0
            offset += 1;
3397
3398
0
            proto_tree_add_bitmask(xcp_tree, tvb, offset, hf_xcp_comm_mode_pgm, ett_xcp_comm_mode_pgm, comm_mode_pgm, ENC_NA);
3399
0
            offset += 1;
3400
3401
0
            uint32_t max_cto;
3402
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_max_cto_pgm, tvb, offset, 1, ENC_NA, &max_cto);
3403
0
            offset += 1;
3404
3405
0
            uint32_t max_bs;
3406
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_max_bs_pgm, tvb, offset, 1, ENC_NA, &max_bs);
3407
0
            offset += 1;
3408
3409
0
            uint32_t min_st;
3410
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_min_st_pgm, tvb, offset, 1, ENC_NA, &min_st);
3411
0
            offset += 1;
3412
3413
0
            uint32_t queue_size;
3414
0
            proto_tree_add_item_ret_uint(xcp_tree, hf_xcp_queue_size_pgm, tvb, offset, 1, ENC_NA, &queue_size);
3415
0
            offset += 1;
3416
3417
0
            col_append_fstr(pinfo->cinfo, COL_INFO, ": MAX_CTO:%d MAX_BS:%d MIN_ST:%d QUEUE_SIZE:%d", max_cto, max_bs, min_st, queue_size);
3418
0
        }
3419
0
            break;
3420
3421
0
        case XCP_CMD_PROGRAM_CLEAR:
3422
            /* No Parameters */
3423
0
            break;
3424
3425
0
        case XCP_CMD_PROGRAM:
3426
            /* No Parameters */
3427
0
            break;
3428
3429
0
        case XCP_CMD_PROGRAM_RESET:
3430
            /* No Parameters */
3431
0
            break;
3432
3433
        //case XCP_CMD_GET_PGM_PROCESSOR_INFO:
3434
        //    /* TODO */
3435
        //    break;
3436
3437
        //case XCP_CMD_GET_SECTOR_INFO:
3438
        //    /* TODO */
3439
        //    break;
3440
3441
0
        case XCP_CMD_PROGRAM_PREPARE:
3442
            /* No Parameters */
3443
0
            break;
3444
3445
0
        case XCP_CMD_PROGRAM_FORMAT:
3446
            /* No Parameters */
3447
0
            break;
3448
3449
        //case XCP_CMD_PROGRAM_NEXT:
3450
        //    /* TODO */
3451
        //    break;
3452
3453
0
        case XCP_CMD_PROGRAM_MAX:
3454
            /* No Parameters */
3455
0
            break;
3456
3457
0
        case XCP_CMD_PROGRAM_VERIFY:
3458
            /* No Parameters */
3459
0
            break;
3460
3461
3462
0
        case XCP_CMD_WRITE_DAQ_MULTIPLE:
3463
            /* No Parameters */
3464
0
            break;
3465
3466
        //case XCP_CMD_TIME_CORRELATION_PROPERTIES:
3467
        //    /* No Parameters ??? Examples says timestamps... */
3468
        //    break;
3469
3470
        //case XCP_CMD_DTO_CTR_PROPERTIES:
3471
        //    /* TODO */
3472
        //    break;
3473
3474
3475
0
        case XCP_CMD_2BYTE_FIRST_BYTE:
3476
0
            switch (message->cmd_lvl1) {
3477
0
                case XCP_CMD_2BYTE_GET_VERSION:
3478
0
                    proto_tree_add_item(xcp_tree, hf_xcp_reserved, tvb, offset, 1, ENC_NA);
3479
0
                    offset += 1;
3480
3481
0
                    proto_tree_add_item(xcp_tree, hf_xcp_version_proto_major, tvb, offset, 1, ENC_NA);
3482
0
                    offset += 1;
3483
3484
0
                    proto_tree_add_item(xcp_tree, hf_xcp_version_proto_minor, tvb, offset, 1, ENC_NA);
3485
0
                    offset += 1;
3486
3487
0
                    proto_tree_add_item(xcp_tree, hf_xcp_version_transp_layer_major, tvb, offset, 1, ENC_NA);
3488
0
                    offset += 1;
3489
3490
0
                    proto_tree_add_item(xcp_tree, hf_xcp_version_transp_layer_minor, tvb, offset, 1, ENC_NA);
3491
0
                    offset += 1;
3492
0
                    break;
3493
3494
0
                case XCP_CMD_2BYTE_SET_DAQ_PACKED_MODE: {
3495
                    /* No parameter */
3496
0
                }
3497
0
                    break;
3498
3499
                //case XCP_CMD_2BYTE_GET_DAQ_PACKED_MODE:
3500
                //    /* TODO */
3501
                //    break;
3502
3503
0
            case XCP_CMD_2BYTE_XCP_SW_DEBUG:
3504
0
                offset += dissect_sw_debug_cmd(tvb, pinfo, xcp_tree, offset, tvb_captured_length_remaining(tvb, offset), false, xcp_type, message, stream);
3505
0
                break;
3506
3507
0
            case XCP_CMD_2BYTE_XCP_POD_COMMANDS:
3508
0
                offset += dissect_pod_cmd(tvb, pinfo, xcp_tree, offset, tvb_captured_length_remaining(tvb, offset), false, xcp_type, message, stream);
3509
0
                break;
3510
3511
0
            default:
3512
0
                proto_tree_add_expert_remaining(xcp_tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
3513
0
                col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
3514
0
            }
3515
3516
0
            break;
3517
3518
0
        default:
3519
0
            proto_tree_add_expert_remaining(xcp_tree, pinfo, &ei_xcp_not_implemented, tvb, offset);
3520
0
            col_append_str(pinfo->cinfo, COL_INFO, "   *** NOT IMPLEMENTED YET ***");
3521
0
        }
3522
0
    } else if (stream->pid_map != NULL && wmem_map_contains(stream->pid_map, GUINT_TO_POINTER(pid))) {
3523
0
        xcp_odt_t *odt = (xcp_odt_t *)wmem_map_lookup(stream->pid_map, GUINT_TO_POINTER(pid));
3524
3525
0
        if (odt != NULL && odt->current_odt_entries != NULL && odt->number_of_odt_entries <= wmem_array_get_count(odt->current_odt_entries)) {
3526
0
            col_append_str(pinfo->cinfo, COL_INFO, "XCP S->M: DAQ:");
3527
3528
            // TODO: create header based on SEQ_DAQ_LIST_MODE!
3529
3530
0
            proto_item *ti;
3531
0
            proto_tree *element_tree;
3532
3533
0
            uint32_t i;
3534
0
            uint32_t j;
3535
0
            uint32_t tmp;
3536
0
            for (i = 0; i < odt->number_of_odt_entries; i++) {
3537
0
                xcp_odt_entry_t *odt_entry = wmem_array_index(odt->current_odt_entries, i);
3538
3539
0
                if (odt_entry != NULL) {
3540
0
                    if (odt_entry->name != NULL) {
3541
0
                        col_append_fstr(pinfo->cinfo, COL_INFO, " %s:", odt_entry->name);
3542
0
                    } else {
3543
0
                        col_append_fstr(pinfo->cinfo, COL_INFO, " Param %d:", i);
3544
0
                    }
3545
3546
0
                    int element_length = stream->addr_granularity * odt_entry->size;
3547
0
                    ti = proto_tree_add_item(xcp_tree, hf_xcp_data_element_bytes, tvb, offset, element_length, ENC_NA);
3548
0
                    element_tree = proto_item_add_subtree(ti, ett_xcp_element);
3549
0
                    if (odt_entry->name != NULL) {
3550
0
                        proto_tree_add_string(element_tree, hf_xcp_data_element_name, tvb, offset, element_length, odt_entry->name);
3551
0
                    } else {
3552
0
                        proto_tree_add_string(element_tree, hf_xcp_data_element_name, tvb, offset, element_length, wmem_strdup_printf(wmem_file_scope(), "Param %d", i));
3553
0
                    }
3554
3555
0
                    switch (element_length) {
3556
0
                    case 1:
3557
0
                        proto_tree_add_item_ret_uint(element_tree, hf_xcp_data_element_1byte, tvb, offset, 1, ENC_NA, &tmp);
3558
0
                        col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tmp);
3559
0
                        offset += 1;
3560
0
                        break;
3561
0
                    case 2:
3562
0
                        proto_tree_add_item_ret_uint(element_tree, hf_xcp_data_element_2bytes, tvb, offset, 2, stream->endianess, &tmp);
3563
0
                        col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%04x", tmp);
3564
0
                        offset += 2;
3565
0
                        break;
3566
0
                    case 4:
3567
0
                        proto_tree_add_item_ret_uint(element_tree, hf_xcp_data_element_4bytes, tvb, offset, 4, stream->endianess, &tmp);
3568
0
                        col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%08x", tmp);
3569
0
                        offset += 4;
3570
0
                        break;
3571
0
                    default: {
3572
0
                        for (j = 0; j < odt_entry->size; j++) {
3573
0
                            switch (stream->addr_granularity) {
3574
0
                            case 1:
3575
0
                                proto_tree_add_item_ret_uint(element_tree, hf_xcp_data_element_1byte, tvb, offset, 1, ENC_NA, &tmp);
3576
0
                                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tmp);
3577
0
                                offset += 1;
3578
0
                                break;
3579
0
                            case 2:
3580
0
                                proto_tree_add_item_ret_uint(element_tree, hf_xcp_data_element_2bytes, tvb, offset, 2, stream->endianess, &tmp);
3581
0
                                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tmp);
3582
0
                                offset += 2;
3583
0
                                break;
3584
0
                            case 4:
3585
0
                                proto_tree_add_item_ret_uint(element_tree, hf_xcp_data_element_4bytes, tvb, offset, 4, stream->endianess, &tmp);
3586
0
                                col_append_fstr(pinfo->cinfo, COL_INFO, " 0x%02x", tmp);
3587
0
                                offset += 4;
3588
0
                                break;
3589
0
                            }
3590
0
                        }
3591
0
                    }
3592
0
                        break;
3593
0
                    }
3594
0
                }
3595
0
            }
3596
0
        }
3597
0
    } else {
3598
0
        col_append_fstr(pinfo->cinfo, COL_INFO, "XCP S->M: PID: %s", val_to_str(pinfo->pool, pid, pid_type_names_s2m, "Unknown PID 0x%02x"));
3599
0
    }
3600
3601
0
    int unparsed_length = tvb_captured_length_remaining(tvb, offset);
3602
0
    if (unparsed_length > 0) {
3603
0
        proto_tree_add_item(xcp_tree, hf_xcp_unparsed, tvb, offset, unparsed_length, ENC_NA);
3604
0
        offset += tvb_captured_length_remaining(tvb, offset);
3605
0
    }
3606
3607
0
    return offset - offset_orig;
3608
0
}
3609
3610
static int
3611
0
dissect_xcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, xcp_stream_t *stream, uint32_t xcp_type, uint32_t xcp_direction) {
3612
0
    proto_item *ti = NULL;
3613
0
    proto_item *ti_root = NULL;
3614
0
    proto_tree *xcp_tree = NULL;
3615
3616
0
    uint32_t offset = 0;
3617
0
    int max_length = -1;
3618
3619
0
    xcp_message_t *message_info;
3620
3621
0
    col_clear(pinfo->cinfo, COL_INFO);
3622
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "XCP");
3623
3624
0
    message_info = (xcp_message_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_xcp, 0);
3625
0
    if (!message_info) {
3626
0
        message_info = wmem_new0(wmem_file_scope(), xcp_message_t);
3627
0
        INIT_XCP_MESSAGE_T(message_info);
3628
0
        p_add_proto_data(wmem_file_scope(), pinfo, proto_xcp, 0, message_info);
3629
0
    }
3630
3631
0
    ti_root = proto_tree_add_item(tree, proto_xcp, tvb, 0, -1, ENC_NA);
3632
0
    xcp_tree = proto_item_add_subtree(ti_root, ett_xcp);
3633
3634
0
    if (!proto_field_is_referenced(tree, proto_xcp)) {
3635
0
        xcp_tree = NULL;
3636
0
    }
3637
3638
0
    switch (xcp_type) {
3639
0
    case XCP_TYPE_ETHERNET: {
3640
        /* Ethernet has an additional header that needs to be parsed first. */
3641
        /* Multi-byte parameters in this header are always ENC_LITTLE_ENDIAN */
3642
0
        proto_tree *xcp_header_tree = NULL;
3643
3644
0
        ti = proto_tree_add_item(xcp_tree, hf_xcp_header_ethernet, tvb, offset, 4, ENC_NA);
3645
0
        xcp_header_tree = proto_item_add_subtree(ti, ett_xcp_header);
3646
3647
0
        uint32_t tmp = 0;
3648
0
        proto_tree_add_item_ret_uint(xcp_header_tree, hf_xcp_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &tmp); // ENC_LITTLE_ENDIAN ok
3649
0
        offset += 2;
3650
3651
        /* cast ok, since tmp can only have uint16 values */
3652
0
        max_length = (int)tmp;
3653
3654
0
        proto_tree_add_item(xcp_header_tree, hf_xcp_counter, tvb, offset, 2, ENC_LITTLE_ENDIAN); // ENC_LITTLE_ENDIAN ok
3655
0
        offset += 2;
3656
3657
0
        break;
3658
0
        }
3659
3660
0
    case XCP_TYPE_CAN:
3661
        /* nothing to do */
3662
0
        break;
3663
0
    }
3664
3665
    /* The XCP packet do not say which direction they are going. If we cannot determine the direction, we show both. */
3666
0
    uint32_t size_m2s = 0;
3667
0
    uint32_t size_s2m = 0;
3668
3669
0
    if (xcp_direction == XCP_DIR_M2S || xcp_direction == XCP_DIR_UNKNOWN) {
3670
0
        size_m2s = dissect_xcp_m2s(tvb, pinfo, xcp_tree, offset, max_length, xcp_type, message_info, stream);
3671
0
    }
3672
3673
0
    if (xcp_direction == XCP_DIR_S2M || xcp_direction == XCP_DIR_UNKNOWN) {
3674
0
        offset += dissect_xcp_s2m(tvb, pinfo, xcp_tree, offset, max_length, xcp_type, message_info, stream);
3675
0
    }
3676
3677
0
    return offset + MAX(size_m2s, size_s2m);
3678
0
}
3679
3680
static int
3681
54
dissect_xcp_can(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
3682
54
    struct can_info *can_info = (struct can_info *)data;
3683
54
    DISSECTOR_ASSERT(can_info);
3684
3685
54
    if (can_info->id & (CAN_ERR_FLAG | CAN_RTR_FLAG)) {
3686
        /* Error and RTR frames are not for us. */
3687
38
        return 0;
3688
38
    }
3689
3690
16
    xcp_can_mapping_t *can_mapping = get_can_mapping(can_info->id, can_info->bus_id);
3691
16
    if (can_mapping == NULL) {
3692
16
        return 0;
3693
16
    }
3694
3695
0
    if (can_mapping->stream == NULL) {
3696
0
        can_mapping->stream = wmem_alloc0(wmem_epan_scope(), sizeof(xcp_stream_t));
3697
3698
0
        INIT_XCP_STREAM_T(can_mapping->stream)
3699
0
        can_mapping->stream->ecu_id = can_mapping->ecu_id;
3700
0
    }
3701
3702
0
    uint32_t xcp_dir = XCP_DIR_UNKNOWN;
3703
0
    if (can_info->id == can_mapping->can_id_m_to_s) {
3704
0
        xcp_dir = XCP_DIR_M2S;
3705
0
    } else if (can_info->id == can_mapping->can_id_s_to_m) {
3706
0
        xcp_dir = XCP_DIR_S2M;
3707
0
    }
3708
3709
0
    return dissect_xcp(tvb, pinfo, tree, can_mapping->stream, XCP_TYPE_CAN, xcp_dir);
3710
16
}
3711
3712
static bool
3713
54
dissect_xcp_can_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
3714
54
    return dissect_xcp_can(tvb, pinfo, tree, data) != 0;
3715
54
}
3716
3717
static uint32_t
3718
0
xcp_ptype_to_port_type(packet_info *pinfo) {
3719
0
    uint8_t xcp_port_type = XCP_PORT_NONE;
3720
3721
0
    switch (pinfo->ptype) {
3722
0
    case PT_UDP:
3723
0
        xcp_port_type = XCP_PORT_UDP;
3724
0
        break;
3725
0
    case PT_TCP:
3726
0
        xcp_port_type = XCP_PORT_TCP;
3727
0
        break;
3728
0
    default:
3729
        /* this should never happen */
3730
0
        ws_assert_not_reached();
3731
0
    }
3732
3733
0
    return xcp_port_type;
3734
0
}
3735
3736
static uint32_t
3737
0
xcp_stream_direction(packet_info *pinfo, xcp_stream_t *stream) {
3738
0
    if (pinfo == NULL || stream == NULL) {
3739
0
        return XCP_DIR_UNKNOWN;
3740
0
    }
3741
3742
0
    if (pinfo->destport == stream->s_port_number && addresses_equal(&(pinfo->net_dst), &(stream->s_addr))) {
3743
0
        return XCP_DIR_M2S;
3744
0
    }
3745
3746
0
    if (pinfo->srcport == stream->s_port_number && addresses_equal(&(pinfo->net_src), &(stream->s_addr))) {
3747
0
        return XCP_DIR_S2M;
3748
0
    }
3749
3750
0
    return XCP_DIR_UNKNOWN;
3751
0
}
3752
3753
static int
3754
0
dissect_xcp_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
3755
0
    conversation_t *conv = find_conversation_pinfo(pinfo, 0);
3756
3757
0
    xcp_stream_t *stream = NULL;
3758
0
    if (conv != NULL) {
3759
0
        stream = (xcp_stream_t *)conversation_get_proto_data(conv, proto_xcp);
3760
3761
0
        if (stream != NULL) {
3762
0
            return dissect_xcp(tvb, pinfo, tree, stream, XCP_TYPE_ETHERNET, xcp_stream_direction(pinfo, stream));
3763
0
        }
3764
0
    }
3765
3766
    /* we need to create the stream data first */
3767
3768
0
    uint8_t xcp_port_type = xcp_ptype_to_port_type(pinfo);
3769
0
    if (xcp_port_type == XCP_PORT_NONE) {
3770
0
        return 0;
3771
0
    }
3772
3773
0
    uint32_t direction = XCP_DIR_UNKNOWN;
3774
3775
0
    xcp_eth_mapping_t *mapping = get_eth_mapping(&(pinfo->net_dst), xcp_port_type, pinfo->destport);
3776
0
    if (mapping != NULL) {
3777
0
        direction = XCP_DIR_M2S;
3778
0
    } else {
3779
0
        mapping = get_eth_mapping(&(pinfo->net_src), xcp_port_type, pinfo->srcport);
3780
0
        if (mapping != NULL) {
3781
0
            direction = XCP_DIR_S2M;
3782
0
        }
3783
0
    }
3784
3785
0
    if (mapping == NULL) {
3786
        /* let us try the 'don't care' address */
3787
0
        address any;
3788
0
        clear_address(&any);
3789
3790
0
        mapping = get_eth_mapping(&any, xcp_port_type, pinfo->destport);
3791
0
        if (mapping != NULL) {
3792
0
            direction = XCP_DIR_M2S;
3793
0
        } else {
3794
0
            mapping = get_eth_mapping(&any, xcp_port_type, pinfo->srcport);
3795
0
            if (mapping != NULL) {
3796
0
                direction = XCP_DIR_S2M;
3797
0
            }
3798
0
        }
3799
0
    }
3800
3801
0
    if (mapping == NULL) {
3802
0
        return 0;
3803
0
    }
3804
3805
0
    if (mapping->stream == NULL) {
3806
0
        mapping->stream = wmem_alloc0(wmem_epan_scope(), sizeof(xcp_stream_t));
3807
0
        INIT_XCP_STREAM_T(mapping->stream)
3808
0
        mapping->stream->ecu_id = mapping->ecu_id;
3809
3810
0
        if (direction == XCP_DIR_M2S) {
3811
0
            copy_address(&(mapping->stream->s_addr), &(pinfo->net_dst));
3812
0
            mapping->stream->s_port_number = pinfo->destport;
3813
0
        } else {
3814
0
            copy_address(&(mapping->stream->s_addr), &(pinfo->net_src));
3815
0
            mapping->stream->s_port_number = pinfo->srcport;
3816
0
        }
3817
0
    }
3818
3819
0
    return dissect_xcp(tvb, pinfo, tree, mapping->stream, XCP_TYPE_ETHERNET, direction);
3820
0
}
3821
3822
static uint32_t
3823
0
get_xcp_eth_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) {
3824
    /* Always ENC_LITTLE_ENDIAN */
3825
0
    uint32_t ret = XCP_ETH_HDR_LEN + (uint32_t)tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN); // ENC_LITTLE_ENDIAN ok
3826
0
    return ret;
3827
0
}
3828
3829
static int
3830
0
dissect_xcp_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
3831
0
    return udp_dissect_pdus(tvb, pinfo, tree, XCP_ETH_HDR_LEN, NULL, get_xcp_eth_len, dissect_xcp_eth, data);
3832
0
}
3833
3834
static int
3835
0
dissect_xcp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
3836
0
     tcp_dissect_pdus(tvb, pinfo, tree, true, XCP_ETH_HDR_LEN, get_xcp_eth_len, dissect_xcp_eth, data);
3837
0
     return tvb_captured_length(tvb);
3838
0
}
3839
3840
static void
3841
0
check_config(void) {
3842
    /* only 0, 1, 2, 4 allowed */
3843
0
    if (global_xcp_address_granularity_default != 0 && global_xcp_address_granularity_default != 1 &&
3844
0
        global_xcp_address_granularity_default != 2 && global_xcp_address_granularity_default != 4) {
3845
0
        global_xcp_address_granularity_default = 0;
3846
0
    }
3847
0
}
3848
3849
void
3850
16
proto_register_xcp(void) {
3851
16
    module_t *xcp_module = NULL;
3852
16
    expert_module_t* expert_module_xcp;
3853
3854
    /* UATs */
3855
16
    uat_t *xcp_addresses_uat;
3856
16
    uat_t *xcp_eth_mapping_uat;
3857
16
    uat_t *xcp_can_mapping_uat;
3858
3859
16
    static hf_register_info hf[] = {
3860
16
        { &hf_xcp_header_ethernet,                  { "XCP Header", "xcp.header_eth", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3861
16
        { &hf_xcp_length,                           { "Length", "xcp.header_eth.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3862
16
        { &hf_xcp_counter,                          { "Counter", "xcp.header_eth.counter", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3863
3864
16
        { &hf_xcp_packet,                           { "XCP Packet", "xcp.packet", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3865
16
        { &hf_xcp_pid_s2m,                          { "Packet Identifier (S2M)", "xcp.packet.pid_s2m", FT_UINT8, BASE_HEX, VALS(pid_type_names_s2m), 0x0, NULL, HFILL }},
3866
16
        { &hf_xcp_cmd_code,                         { "Command Code", "xcp.packet.command_code", FT_UINT8, BASE_HEX, VALS(cmd_code_names), 0x0, NULL, HFILL }},
3867
16
        { &hf_xcp_cmd_code_level1,                  { "Level 1 Command Code", "xcp.packet.command_code_level1", FT_UINT8, BASE_HEX, VALS(cmd_code_names_2bytes), 0x0, NULL, HFILL }},
3868
3869
16
        { &hf_xcp_reserved,                         { "Reserved", "xcp.packet.reserved", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3870
16
        { &hf_xcp_unparsed,                         { "Unparsed", "xcp.packet.unparsed", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3871
16
        { &hf_xcp_address,                          { "Address", "xcp.packet.address", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3872
3873
16
        { &hf_xcp_session_cfg_id,                   { "Session Configuration ID", "xcp.packet.session_configuration_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3874
3875
16
        { &hf_xcp_daq_list_number,                  { "DAQ List Number", "xcp.packet.daq_list_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3876
16
        { &hf_xcp_odt_number,                       { "ODT Number", "xcp.packet.odt_number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3877
16
        { &hf_xcp_odt_entry_number,                 { "ODT Entry Number", "xcp.packet.odt_entry_number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3878
16
        { &hf_xcp_event_channel_number,             { "Event Channel Number", "xcp.packet.event_channel_number", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3879
3880
16
        { &hf_xcp_logical_data_segment_number,      { "Logical Data Segment Number", "xcp.packet.logical_data_segment_number", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3881
16
        { &hf_xcp_logical_data_page_number,         { "Logical Data Page Number", "xcp.packet.logical_data_page_number", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3882
3883
16
        { &hf_xcp_num_of_data_elements,             { "Number of Data Elements", "xcp.packet.number_of_data_elements", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3884
16
        { &hf_xcp_address_extension,                { "Address Extension", "xcp.packet.address_extension", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3885
16
        { &hf_xcp_data_element_1byte,               { "Data Element (1 Byte)", "xcp.packet.data_element_1byte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3886
16
        { &hf_xcp_data_element_2bytes,              { "Data Element (2 Bytes)", "xcp.packet.data_element_2bytes", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3887
16
        { &hf_xcp_data_element_4bytes,              { "Data Element (4 Bytes)", "xcp.packet.data_element_4bytes", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3888
16
        { &hf_xcp_data_element_bytes,               { "Data Element", "xcp.packet.data_element", FT_BYTES, BASE_NONE | SEP_SPACE, NULL, 0x0, NULL, HFILL } },
3889
3890
        /* 0xFF XCP_CMD_CONNECT */
3891
16
        { &hf_xcp_conn_mode,                        { "Mode", "xcp.packet.connect_mode", FT_UINT8, BASE_HEX, VALS(cmd_connect_mode), 0x0, NULL, HFILL }},
3892
16
        { &hf_xcp_conn_resource,                    { "Resource", "xcp.packet.resource", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3893
16
        { &hf_xcp_conn_resource_dbg,                { "Software Debugging", "xcp.packet.resource.dbg", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x20, NULL, HFILL }},
3894
16
        { &hf_xcp_conn_resource_pgm,                { "Programming", "xcp.packet.resource.pgm", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x10, NULL, HFILL }},
3895
16
        { &hf_xcp_conn_resource_stim,               { "Stimulation", "xcp.packet.resource.stim", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x08, NULL, HFILL }},
3896
16
        { &hf_xcp_conn_resource_daq,                { "DAQ lists", "xcp.packet.resource.daq", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x04, NULL, HFILL }},
3897
16
        { &hf_xcp_conn_resource_cal_pag,            { "Calibration and Paging", "xcp.packet.resource.cal_pag", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x01, NULL, HFILL }},
3898
3899
16
        { &hf_xcp_conn_comm_mode_bsc,               { "Communication Mode Basic", "xcp.packet.comm_mode_basic", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3900
16
        { &hf_xcp_conn_comm_mode_bsc_optional,      { "Optional", "xcp.packet.comm_mode_basic.optional", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
3901
16
        { &hf_xcp_conn_comm_mode_bsc_sl_blk_mode,   { "Slave Block Mode", "xcp.packet.comm_mode_basic.slave_block_mode", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x40, NULL, HFILL }},
3902
16
        { &hf_xcp_conn_comm_mode_bsc_addr_gran,     { "Address Granularity", "xcp.packet.comm_mode_basic.address_granularity", FT_UINT8, BASE_HEX, VALS(comm_mode_address_granularity), 0x06, NULL, HFILL }},
3903
16
        { &hf_xcp_conn_comm_mode_bsc_byte_order,    { "Byte Order", "xcp.packet.comm_mode_basic.byte_order", FT_BOOLEAN, 8, TFS(&xcp_tfs_byte_order), 0x01, NULL, HFILL }},
3904
3905
16
        { &hf_xcp_conn_max_cto,                     { "Max CTO", "xcp.packet.max_cto", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3906
16
        { &hf_xcp_conn_max_dto,                     { "Max DTO", "xcp.packet.max_dto", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3907
16
        { &hf_xcp_conn_proto_layer_ver,             { "Protocol Layer Version", "xcp.packet.proto_layer_version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3908
16
        { &hf_xcp_conn_trans_layer_ver,             { "Transport Layer Version", "xcp.packet.transport_layer_version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3909
3910
        /* 0xFD XCP_CMD_GET_STATUS */
3911
16
        { &hf_xcp_get_st_cur_ses,                   { "Current Session Status", "xcp.packet.current_session_status", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3912
16
        { &hf_xcp_get_st_cur_ses_resume,            { "Resume Mode", "xcp.packet.current_session_status.resume", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
3913
16
        { &hf_xcp_get_st_cur_ses_daq_running,       { "DAQ Running", "xcp.packet.current_session_status.daq_running", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
3914
16
        { &hf_xcp_get_st_cur_ses_daq_cfg_lost,      { "Configuration of resource DAQ", "xcp.packet.current_session_status.daq_cfg_lost", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
3915
16
        { &hf_xcp_get_st_cur_ses_clear_daq_req,     { "Request to clear DAQ configuration", "xcp.packet.current_session_status.clear_daq_req", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
3916
16
        { &hf_xcp_get_st_cur_ses_store_daq_req,     { "Request to store DAQ list", "xcp.packet.current_session_status.store_daq_req", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
3917
16
        { &hf_xcp_get_st_cur_ses_calpag_cfg_lst,    { "Configuration of resource CAL and PAG", "xcp.packet.current_session_status.cal_pag_cfg_lost", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
3918
16
        { &hf_xcp_get_st_cur_ses_store_cal_req,     { "Request to store calibration data", "xcp.packet.current_session_status.store_cal_req", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
3919
3920
16
        { &hf_xcp_get_st_cur_res_pro_st,            { "Current Resource Protection Status", "xcp.packet.current_protection_status", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3921
16
        { &hf_xcp_get_st_cur_res_pro_st_dbg,        { "Software Debugging Commands", "xcp.packet.current_protection_status.dbg", FT_BOOLEAN, 8, TFS(&xcp_tfs_protected), 0x20, NULL, HFILL }},
3922
16
        { &hf_xcp_get_st_cur_res_pro_st_pgm,        { "Programming Commands", "xcp.packet.current_protection_status.pgm", FT_BOOLEAN, 8, TFS(&xcp_tfs_protected), 0x10, NULL, HFILL }},
3923
16
        { &hf_xcp_get_st_cur_res_pro_st_stim,       { "DAQ List Commands (STIM)", "xcp.packet.current_protection_status.stim", FT_BOOLEAN, 8, TFS(&xcp_tfs_protected), 0x08, NULL, HFILL }},
3924
16
        { &hf_xcp_get_st_cur_res_pro_st_daq,        { "DAQ List Commands (DAQ)", "xcp.packet.current_protection_status.daq", FT_BOOLEAN, 8, TFS(&xcp_tfs_protected), 0x04, NULL, HFILL }},
3925
16
        { &hf_xcp_get_st_cur_res_pro_st_calpag,     { "Calibration/Paging Commands", "xcp.packet.current_protection_status.cal_pag", FT_BOOLEAN, 8, TFS(&xcp_tfs_protected), 0x01, NULL, HFILL }},
3926
3927
16
        { &hf_xcp_get_st_cur_state_number,          { "State Number", "xcp.packet.current_state_number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3928
3929
        /* 0xFB XCP_CMD_GET_COMM_MODE_INFO */
3930
16
        { &hf_xcp_comm_mode_res1,                   { "Reserved", "xcp.packet.comm_mode_res1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3931
16
        { &hf_xcp_comm_mode_opt,                    { "Comm Mode Optional", "xcp.packet.comm_mode_opt", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3932
16
        { &hf_xcp_comm_mode_opt_interl,             { "Interleaved Mode", "xcp.packet.comm_mode_opt.interleaved", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x2, NULL, HFILL }},
3933
16
        { &hf_xcp_comm_mode_opt_mas_blck_mode,      { "Master Block Mode", "xcp.packet.comm_mode_opt.master_block_mode", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x1, NULL, HFILL } },
3934
16
        { &hf_xcp_comm_mode_res2,                   { "Reserved", "xcp.packet.comm_mode_res2", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3935
16
        { &hf_xcp_comm_mode_max_bs,                 { "Max BS", "xcp.packet.max_bs", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3936
16
        { &hf_xcp_comm_mode_min_st,                 { "Min ST", "xcp.packet.min_st", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3937
16
        { &hf_xcp_comm_mode_queue_size,             { "Queue Size", "xcp.packet.queue_size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3938
16
        { &hf_xcp_comm_mode_driver_version,         { "XCP Driver Version Number", "xcp.packet.driver_version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3939
3940
        /* 0xFA XCP_CMD_GET_ID */
3941
16
        { &hf_xcp_get_id_req_id_type,               { "Req ID Type", "xcp.packet.get_id_req_id_type", FT_UINT8, BASE_HEX, VALS(get_id_req_id_type), 0x0, NULL, HFILL } },
3942
3943
16
        { &hf_xcp_get_id_mode,                      { "Mode", "xcp.packet.get_id_mode", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3944
16
        { &hf_xcp_get_id_mode_compressed_encrypted, { "Compressed/Encrypted", "xcp.packet.get_id_mode.compressed_encrypted", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL } },
3945
16
        { &hf_xcp_get_id_mode_transfer_mode,        { "Transfer Mode", "xcp.packet.get_id_mode.transfer_mode", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } },
3946
16
        { &hf_xcp_get_id_res,                       { "Reserved", "xcp.packet.get_id_res", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3947
16
        { &hf_xcp_get_id_length,                    { "Length", "xcp.packet.get_id_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3948
16
        { &hf_xcp_get_id_id_string,                 { "Identification", "xcp.packet.get_id_id_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3949
16
        { &hf_xcp_get_id_id_bytes,                  { "Identification", "xcp.packet.get_id_id_bytes", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3950
3951
        /* 0xF9 XCP_CMD_SET_REQUEST */
3952
16
        { &hf_xcp_set_req_md,                       { "Mode", "xcp.packet.set_request_mode", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3953
16
        { &hf_xcp_set_req_md_clr_daq_cfg_lost,      { "Clear DAQ Config Lost", "xcp.packet.set_request_mode.clear_daq_cfg_lost", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL } },
3954
16
        { &hf_xcp_set_req_md_clr_cal_pag_cfg_lost,  { "Clear CAL/PAG Config Lost", "xcp.packet.set_request_mode.clear_cal_pag_cfg_lost", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL } },
3955
16
        { &hf_xcp_set_req_md_clr_daq_req,           { "Clear DAQ Request", "xcp.packet.set_request_mode.clear_daq_req", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL } },
3956
16
        { &hf_xcp_set_req_md_str_daq_req_resume,    { "Store DAQ Request Resume", "xcp.packet.set_request_mode.store_daq_req_resume", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL } },
3957
16
        { &hf_xcp_set_req_md_str_daq_req_no_resume, { "Store DAQ Request No Resume", "xcp.packet.set_request_mode.store_daq_req_no_resume", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL } },
3958
16
        { &hf_xcp_set_req_md_str_cal_req,           { "Store CAL Request", "xcp.packet.set_request_mode.store_cal_request", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } },
3959
3960
        /* 0xF8 GET_SEED */
3961
16
        { &hf_xcp_get_seed_mode,                    { "Mode", "xcp.packet.get_seed.mode", FT_UINT8, BASE_HEX, VALS(get_seed_mode), 0x0, NULL, HFILL } },
3962
16
        { &hf_xcp_get_seed_resource,                { "Resource", "xcp.packet.get_seed.resource", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3963
16
        { &hf_xcp_get_seed_dont_care,               { "Don't Care", "xcp.packet.get_seed.dont_care", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3964
3965
16
        { &hf_xcp_get_seed_length_of_seed,          { "Length of seed", "xcp.packet.get_seed.length_of_seed", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3966
16
        { &hf_xcp_get_seed_seed,                    { "Seed", "xcp.packet.get_seed.seed", FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, NULL, HFILL } },
3967
3968
        /* 0xF7 UNLOCK */
3969
16
        { &hf_xcp_unlock_length_of_key,             { "(remaining) Length of key in bytes", "xcp.packet.unlock.length_of_key", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3970
16
        { &hf_xcp_unlock_key,                       { "Key", "xcp.packet.unlock.key", FT_BYTES, BASE_NONE|SEP_SPACE, NULL, 0x0, NULL, HFILL } },
3971
3972
        /* DTO */
3973
16
        { &hf_xcp_data_element_name,                { "Name", "xcp.packet.data_element.name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3974
3975
        /* 0xF3 XCP_CMD_BUILD_CHECKSUM */
3976
16
        { &hf_xcp_build_chksum_res1,                { "Reserved", "xcp.packet.build_checksum.reserved1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3977
16
        { &hf_xcp_build_chksum_res2,                { "Reserved", "xcp.packet.build_checksum.reserved2", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3978
16
        { &hf_xcp_build_chksum_block_size,          { "Block size [AG]", "xcp.packet.build_checksum.block_size", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3979
3980
16
        { &hf_xcp_build_chksum_type,                { "Checksum type", "xcp.packet.build_checksum.checksum_type", FT_UINT8, BASE_HEX, VALS(checksum_types), 0x0, NULL, HFILL } },
3981
16
        { &hf_xcp_build_chksum_res3,                { "Reserved", "xcp.packet.build_checksum.reserved3", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3982
16
        { &hf_xcp_build_chksum,                     { "Checksum", "xcp.packet.build_checksum.checksum", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3983
3984
        /* 0xF2 XCP_CMD_TRANSPORT_LAYER_CMD */
3985
16
        { &hf_xcp_sub_command_eth,                  { "Sub Command Code", "xcp.packet.sub_command_eth", FT_UINT8, BASE_HEX, VALS(sub_cmd_code_mnemonics_eth), 0x0, NULL, HFILL } },
3986
16
        { &hf_xcp_sub_command_eth_port,             { "Port", "xcp.packet.sub_command_eth.port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3987
16
        { &hf_xcp_sub_command_eth_ipv4,             { "IP", "xcp.packet.sub_command_eth.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3988
16
        { &hf_xcp_sub_command_eth_reserved,         { "Reserved", "xcp.packet.sub_command_eth.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3989
16
        { &hf_xcp_sub_command_eth_ip_version,       { "IP Version", "xcp.packet.sub_command_eth.ip_version", FT_UINT8, BASE_HEX, VALS(transport_mode_eth_ip_version), 0x0, NULL, HFILL } },
3990
3991
16
        { &hf_xcp_sub_command_can,                  { "Sub Command Code", "xcp.packet.sub_command_eth", FT_UINT8, BASE_HEX, VALS(sub_cmd_code_mnemonics_can), 0x0, NULL, HFILL } },
3992
3993
        /* 0xEB XCP_CMD_SET_CAL_PAGE */
3994
16
        { &hf_xcp_set_cal_page_mode,                { "Mode", "xcp.packet.set_cal_page_mode", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3995
16
        { &hf_xcp_set_cal_page_mode_all,            { "All", "xcp.packet.set_cal_page_mode.all", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL } },
3996
16
        { &hf_xcp_set_cal_page_mode_xcp,            { "XCP", "xcp.packet.set_cal_page_mode.xcp", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL } },
3997
16
        { &hf_xcp_set_cal_page_mode_ecu,            { "ECU", "xcp.packet.set_cal_page_mode.ecu", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } },
3998
3999
        /* 0xEA XCP_CMD_GET_CAL_PAGE */
4000
16
        { &hf_xcp_access_mode,                      { "Access Mode", "xcp.packet.access_mode", FT_UINT8, BASE_HEX, VALS(access_mode_type), 0x0, NULL, HFILL } },
4001
4002
        /* 0xE6 XCP_CMD_SET_SEGMENT_MODE */
4003
16
        { &hf_xcp_set_segment_mode,                 { "Mode", "xcp.packet.set_segment_mode.mode", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4004
16
        { &hf_xcp_set_segment_mode_freeze,          { "Freeze", "xcp.packet.set_segment_mode.freeze", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } },
4005
16
        { &hf_xcp_set_segment_mode_segment,         { "Segment number", "xcp.packet.set_segment_mode.segment", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4006
4007
        /* 0xE4 XCP_CMD_COPY_CAL_PAGE */
4008
16
        { &hf_xcp_logical_data_segm_num_src,        { "Local data segment number source", "xcp.packet.copy_cal_page.local_data_segm_num_src", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4009
16
        { &hf_xcp_logical_data_page_num_src,        { "Local data page number source", "xcp.packet.copy_cal_page.local_data_page_num_src", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4010
16
        { &hf_xcp_logical_data_segm_num_dst,        { "Local data segment number source", "xcp.packet.copy_cal_page.local_data_segm_num_dst", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4011
16
        { &hf_xcp_logical_data_page_num_dst,        { "Local data page number source", "xcp.packet.copy_cal_page.local_data_page_num_dst", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4012
4013
        /* 0xE1 XCP_CMD_WRITE_DAQ */
4014
16
        { &hf_xcp_bit_offset,                       { "Bit Offset", "xcp.packet.bit_offset", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4015
16
        { &hf_xcp_size_of_daq_element,              { "Size of DAQ Element", "xcp.packet.size_of_daq_element", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4016
4017
        /* 0xE0 XCP_CMD_SET_DAQ_LIST_MODE */
4018
16
        { &hf_xcp_set_daq_list_mode_mode,           { "Mode", "xcp.packet.set_daq_list_mode_mode", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4019
16
        { &hf_xcp_set_daq_list_mode_mode_pid_off,   { "PID off", "xcp.packet.get_id_mode.transfer_mode.pid_off", FT_BOOLEAN, 8, NULL, SET_DAQ_LIST_MODE_PID_OFF, NULL, HFILL } },
4020
16
        { &hf_xcp_set_daq_list_mode_mode_timestamp, { "Timestamp", "xcp.packet.get_id_mode.transfer_mode.timestamp", FT_BOOLEAN, 8, NULL, SET_DAQ_LIST_MODE_TSTAMP, NULL, HFILL } },
4021
16
        { &hf_xcp_set_daq_list_mode_mode_dto_ctr,   { "DTO CTR", "xcp.packet.get_id_mode.transfer_mode.dto_ctr", FT_BOOLEAN, 8, NULL, SET_DAQ_LIST_MODE_DTO_CTR, NULL, HFILL } },
4022
16
        { &hf_xcp_set_daq_list_mode_mode_dir,       { "Direction", "xcp.packet.get_id_mode.transfer_mode.direction", FT_BOOLEAN, 8, TFS(&xcp_tfs_stim_daq), SET_DAQ_LIST_MODE_DIR, NULL, HFILL } },
4023
16
        { &hf_xcp_set_daq_list_mode_mode_alt,       { "Alternating Display Mode", "xcp.packet.get_id_mode.transfer_mode.alternating", FT_BOOLEAN, 8, NULL, SET_DAQ_LIST_MODE_ALT, NULL, HFILL } },
4024
16
        { &hf_xcp_transmission_prescaler,           { "Transmission Prescaler", "xcp.packet.transmission_prescaler", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4025
16
        { &hf_xcp_daq_list_priority,                { "DAQ List Priority", "xcp.packet.daq_list_priority", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4026
4027
        /* 0xDE XCP_CMD_START_STOP_DAQ_LIST */
4028
16
        { &hf_xcp_start_stop_daq_mode,              { "Mode", "xcp.packet.start_stop_daq_mode", FT_UINT8, BASE_HEX, VALS(start_stop_daq_mode), 0x0, NULL, HFILL } },
4029
4030
16
        { &hf_xcp_first_pid,                        { "First PID", "xcp.packet.first_pid", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4031
4032
        /* 0xDD XCP_CMD_START_STOP_SYNCH */
4033
16
        { &hf_xcp_start_stop_synch_mode,            { "Mode", "xcp.packet.start_stop_synch_mode", FT_UINT8, BASE_HEX, VALS(start_stop_synch_mode), 0x0, NULL, HFILL } },
4034
4035
        /* 0xDC XCP_CMD_GET_DAQ_CLOCK */
4036
16
        { &hf_xcp_trigger_info,                     { "Trigger Info", "xcp.packet.trigger_info", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4037
16
        { &hf_xcp_trigger_info_time_of_ts_sampl,    { "Time of Timestamp Sampling", "xcp.packet.trigger_info.time_of_timestamp_sample", FT_UINT8, BASE_DEC, VALS(trigger_info_time_of_ts_sampl_type), 0x18, NULL, HFILL } },
4038
16
        { &hf_xcp_trigger_info_trigger_init,        { "Trigger Initiator", "xcp.packet.trigger_info.trigger_initiator", FT_UINT8, BASE_DEC, VALS(trigger_info_trigger_init_type), 0x07, NULL, HFILL } },
4039
16
        { &hf_xcp_payload_fmt,                      { "Payload Format", "xcp.packet.payload_format", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4040
16
        { &hf_xcp_payload_fmt_cluster_ident,        { "Cluster Identifier", "xcp.packet.payload_fmt.cluster_ident_and_counter", FT_BOOLEAN, 8, TFS(&xcp_tfs_cluster_identifier), 0x40, NULL, HFILL } },
4041
16
        { &hf_xcp_payload_fmt_fmt_ecu,              { "Format ECU Clock", "xcp.packet.payload_fmt.format_ecu_clock", FT_UINT8, BASE_DEC, VALS(clock_format_type), 0x30, NULL, HFILL } },
4042
16
        { &hf_xcp_payload_fmt_fmt_grandm,           { "Format Grandmaster Clock", "xcp.packet.payload_fmt.format_grandmaster_clock", FT_UINT8, BASE_DEC, VALS(clock_format_type), 0x0c, NULL, HFILL } },
4043
16
        { &hf_xcp_payload_fmt_xcp_slv,              { "Format XCP Slave Clock", "xcp.packet.payload_fmt.format_xcp_slave_clock", FT_UINT8, BASE_DEC, VALS(clock_format_type), 0x03, NULL, HFILL } },
4044
16
        { &hf_xcp_payload_timestamp_legacy,         { "Timestamp (legacy)", "xcp.packet.payload_fmt.timestamp_legacy", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4045
4046
        /* 0xDA XCP_CMD_GET_DAQ_PROCESSOR_INFO */
4047
16
        { &hf_xcp_daq_props,                        { "General properties of DAQ lists", "xcp.packet.daq_properties", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4048
16
        { &hf_xcp_daq_props_overload,               { "Overload", "xcp.packet.daq_properties_overload", FT_UINT8, BASE_HEX, VALS(daq_properties_overload_type), 0xC0, NULL, HFILL } },
4049
16
        { &hf_xcp_daq_props_pid_off_supported,      { "PID off", "xcp.packet.daq_properties_pid_off_supported", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x20, NULL, HFILL } },
4050
16
        { &hf_xcp_daq_props_timestamp_supported,    { "Timestamped mode", "xcp.packet.daq_properties_timestamp_supported", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x10, NULL, HFILL } },
4051
16
        { &hf_xcp_daq_props_bit_stim_supported,     { "Bitwise data stimulation", "xcp.packet.daq_properties_bit_stim_supported", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x08, NULL, HFILL } },
4052
16
        { &hf_xcp_daq_props_resume_supported,       { "DAQ list resume mode", "xcp.packet.daq_properties_resume_supported", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x04, NULL, HFILL } },
4053
16
        { &hf_xcp_daq_props_prescaler_supported,    { "Prescaler", "xcp.packet.daq_properties_prescaler_supported", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x02, NULL, HFILL } },
4054
16
        { &hf_xcp_daq_props_config_type,            { "DAQ list configuration", "xcp.packet.daq_config_type", FT_BOOLEAN, 8, TFS(&xcp_tfs_dynamic_static), 0x01, NULL, HFILL } },
4055
4056
16
        { &hf_xcp_max_daq,                          { "Total number of available DAQ lists", "xcp.packet.max_daq", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4057
16
        { &hf_xcp_max_event_channel,                { "Total number of available event channels", "xcp.packet.max_event_channel", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4058
16
        { &hf_xcp_min_daq,                          { "Total number of predefined DAQ lists", "xcp.packet.min_daq", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4059
4060
16
        { &hf_xcp_daq_key_byte,                     { "DAQ key byte", "xcp.packet.daq_key_byte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4061
16
        { &hf_xcp_daq_key_byte_id_field,            { "Identification Field", "xcp.packet.daq_key_byte_id_field", FT_UINT8, BASE_HEX, VALS(daq_key_byte_id_field_type), 0xC0, NULL, HFILL } },
4062
16
        { &hf_xcp_daq_key_byte_addr_ext,            { "Address Extension", "xcp.packet.daq_key_byte_address_extension", FT_UINT8, BASE_HEX, VALS(daq_key_byte_addr_ext_type), 0x30, NULL, HFILL } },
4063
16
        { &hf_xcp_daq_key_byte_optimization,        { "Optimization", "xcp.packet.daq_key_optimization", FT_UINT8, BASE_HEX, VALS(optimization_type), 0x0F, NULL, HFILL } },
4064
4065
        /* 0xD9 XCP_CMD_GET_RESOLUTION_INFO */
4066
16
        { &hf_xcp_granularity_odt_entry_size_daq,   { "Granularity for size of ODT entry (DAQ direction)", "xcp.packet.granularity_odt_entry_size_daq", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4067
16
        { &hf_xcp_max_odt_entry_size_daq,           { "Maximum size of ODT entry (DAQ direction)", "xcp.packet.max_odt_entry_size_daq", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4068
16
        { &hf_xcp_granularity_odt_entry_size_stim,  { "Granularity for size of ODT entry (STIM direction)", "xcp.packet.granularity_odt_entry_size_stim", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4069
16
        { &hf_xcp_max_odt_entry_size_stim,          { "Maximum size of ODT entry (STIM direction)", "xcp.packet.max_odt_entry_size_stim", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4070
16
        { &hf_xcp_timestamp_mode,                   { "Timestamp unit and size", "xcp.packet.timestamp_mode", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4071
16
        { &hf_xcp_timestamp_mode_time_unit,         { "Timestamp Unit", "xcp.packet.timestamp_mode_unit", FT_UINT8, BASE_HEX, VALS(xcp_time_unit), 0xf0, NULL, HFILL } },
4072
16
        { &hf_xcp_timestamp_mode_timestamp_fixed,   { "Timestamp Fixed", "xcp.packet.timestamp_mode_timestamp_fixed", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL } },
4073
16
        { &hf_xcp_timestamp_mode_timestamp_size,    { "Timestamp Size", "xcp.packet.timestamp_size", FT_UINT8, BASE_DEC, NULL, 0x07, NULL, HFILL } },
4074
16
        { &hf_xcp_timestamp_ticks,                  { "Timestamp tickets per unit", "xcp.packet.timestamp_ticks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4075
4076
        /* 0xD8 XCP_CMD_GET_DAQ_LIST_INFO */
4077
16
        { &hf_xcp_daq_list_properties,              { "DAQ List Properties", "xcp.packet.daq_list_properties", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4078
16
        { &hf_xcp_daq_list_properties_packed,       { "Packed", "xcp.packet.daq_list_properties_packed", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x10, NULL, HFILL } },
4079
16
        { &hf_xcp_daq_list_properties_stim,         { "STIM", "xcp.packet.daq_list_properties_stim", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x08, NULL, HFILL } },
4080
16
        { &hf_xcp_daq_list_properties_daq,          { "DAQ", "xcp.packet.daq_list_properties_daq", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x04, NULL, HFILL } },
4081
16
        { &hf_xcp_daq_list_properties_event_fixed,  { "Event Channel Fixed", "xcp.packet.daq_list_properties_event_fixed", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL } },
4082
16
        { &hf_xcp_daq_list_properties_predefined,   { "Predefined", "xcp.packet.daq_list_properties_predefined", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } },
4083
16
        { &hf_xcp_daq_list_max_odt,                 { "Max ODT", "xcp.packet.max_odt", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4084
16
        { &hf_xcp_daq_list_max_odt_entries,         { "Max ODT Entries", "xcp.packet.max_odt_entries", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4085
16
        { &hf_xcp_daq_list_fixed_event,             { "Fixed Event Channel", "xcp.packet.fixed_event", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4086
4087
        /* 0xD7 XCP_CMD_GET_DAQ_EVENT_INFO */
4088
16
        { &hf_xcp_daq_event_properties,             { "DAQ Event Properties", "xcp.packet.daq_event_properties", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4089
16
        { &hf_xcp_daq_event_properties_consistency, { "Consistency", "xcp.packet.daq_event_properties_consistency", FT_UINT8, BASE_HEX, VALS(daq_event_props_consistency), 0xc0, NULL, HFILL } },
4090
16
        { &hf_xcp_daq_event_properties_packed,      { "Packed", "xcp.packet.daq_event_properties_packed", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x10, NULL, HFILL } },
4091
16
        { &hf_xcp_daq_event_properties_stim,        { "STIM", "xcp.packet.daq_event_properties_stim", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x08, NULL, HFILL } },
4092
16
        { &hf_xcp_daq_event_properties_daq,         { "DAQ", "xcp.packet.daq_event_properties_daq", FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x04, NULL, HFILL } },
4093
4094
16
        { &hf_xcp_max_daq_list,                     { "Maximum Number of DAQ Lists for this even channel", "xcp.packet.max_daq_list", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4095
16
        { &hf_xcp_event_channel_name_length,        { "Event Channel Name Length", "xcp.packet.event_channel_name_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4096
16
        { &hf_xcp_event_channel_time_cycle,         { "Event Channel Time Cycle", "xcp.packet.event_channel_time_cycle", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4097
16
        { &hf_xcp_event_channel_time_unit,          { "Event Channel Time Unit", "xcp.packet.event_channel_time_unit", FT_UINT8, BASE_DEC, VALS(xcp_time_unit), 0x0, NULL, HFILL } },
4098
16
        { &hf_xcp_event_channel_priority,           { "Event Channel Priority", "xcp.packet.event_channel_priority", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4099
4100
        /* 0xD5 XCP_CMD_ALLOC_DAQ */
4101
16
        { &hf_xcp_daq_count,                        { "DAQ Count", "xcp.packet.daq_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4102
4103
        /* 0xD4 XCP_CMD_ALLOC_ODT */
4104
16
        { &hf_xcp_odt_count,                        { "ODT Counter", "xcp.packet.odt_count", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4105
4106
        /* 0xD3 XCP_CMD_ALLOC_ODT_ENTRY */
4107
16
        { &hf_xcp_odt_entries_count,                { "ODT Entries Count", "xcp.packet.odt_entries_count", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4108
4109
        /* 0xD2 PROGRAM_START */
4110
16
        { &hf_xcp_comm_mode_pgm,                    { "Comm Mode PGM", "xcp.packet.comm_mode_pgm", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4111
16
        { &hf_xcp_comm_mode_pgm_slave_block_mode,   { "Slave Block Mode", "xcp.packet.comm_mode_pgm.slave_block_mode", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x40, NULL, HFILL } },
4112
16
        { &hf_xcp_comm_mode_pgm_interleaved_mode,   { "Interleaved Mode", "xcp.packet.comm_mode_pgm.interleaved", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x02, NULL, HFILL } },
4113
16
        { &hf_xcp_comm_mode_pgm_master_block_mode,  { "Master Block Mode", "xcp.packet.comm_mode_pgm.master_block_mode", FT_BOOLEAN, 8, TFS(&tfs_available_not_available), 0x01, NULL, HFILL } },
4114
16
        { &hf_xcp_max_cto_pgm,                      { "Max DTO", "xcp.packet.max_dto_pgm", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4115
16
        { &hf_xcp_max_bs_pgm,                       { "Max BS", "xcp.packet.max_bs_pgm", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4116
16
        { &hf_xcp_min_st_pgm,                       { "Min ST", "xcp.packet.min_st_pgm", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4117
16
        { &hf_xcp_queue_size_pgm,                   { "Queue Size", "xcp.packet.queue_size_pgm", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4118
4119
        /* 0xD1 PROGRAM_CLEAR */
4120
16
        { &hf_xcp_program_clear_mode,               { "Mode", "xcp.packet.program_clear_mode", FT_UINT8, BASE_HEX, VALS(program_clear_mode_type), 0x0, NULL, HFILL } },
4121
16
        { &hf_xcp_program_clear_range_abs,          { "Clear Range", "xcp.packet.clear_range_abs", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4122
16
        { &hf_xcp_program_clear_range_fct,          { "Clear Range", "xcp.packet.clear_range_fct", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4123
16
        { &hf_xcp_program_clear_range_fct_1,        { "Clear All Calibration Data Area(s)", "xcp.packet.clear_range_fct.clear_all_calibration_data", FT_BOOLEAN, 32, NULL, 0x00000001, NULL, HFILL } },
4124
16
        { &hf_xcp_program_clear_range_fct_2,        { "Clear All Code Area(s)", "xcp.packet.clear_range_fct.clear_all_code_areas", FT_BOOLEAN, 32, NULL, 0x00000002, NULL, HFILL } },
4125
16
        { &hf_xcp_program_clear_range_fct_4,        { "Clear All NVRAM area(s)", "xcp.packet.clear_range_fct.clear_all_nvram_areas", FT_BOOLEAN, 32, NULL, 0x00000004, NULL, HFILL } },
4126
4127
4128
        /* 2BYTE COMMANDS */
4129
        /* 0xC0 0x00 GET_VERSION */
4130
16
        { &hf_xcp_version_proto_major,              { "Major version of protocol layer", "xcp.packet.version_proto_major", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4131
16
        { &hf_xcp_version_proto_minor,              { "Minor version of protocol layer", "xcp.packet.version_proto_minor", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4132
16
        { &hf_xcp_version_transp_layer_major,       { "Major version of active transport layer", "xcp.packet.version_transport_layer_major", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4133
16
        { &hf_xcp_version_transp_layer_minor,       { "Minor version of active transport layer", "xcp.packet.version_transport_layer_minor", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4134
4135
        /* 0xC0 0x01 SET_DAQ_PACKED_MODE */
4136
16
        { &hf_xcp_daq_packed_mode,                  { "DAQ Packed Mode", "xcp.packet.daq_packed_mode", FT_UINT8, BASE_HEX, VALS(daq_packed_mode_type), 0x0, NULL, HFILL } },
4137
16
        { &hf_xcp_packed_timestamp_mode,            { "Timestamp Mode", "xcp.packet.daq_packed_timestamp_mode", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
4138
16
        { &hf_xcp_packed_timestamp_mode_flags,      { "Timestamp Modes", "xcp.packet.daq_packed_timestamp_modes", FT_UINT8, BASE_HEX, VALS(daq_packed_timestamp_mode_type), 0x03, NULL, HFILL } },
4139
16
        { &hf_xcp_packed_sample_count,              { "Sample Count", "xcp.packet.daq_packet_sample_count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
4140
4141
4142
        /* 0xC0 0xFC SW DEBUG over XCP */
4143
16
        { &hf_xcp_debug_command,                    { "Command Code", "xcp.packet.sw_debug.command_code", FT_UINT8, BASE_HEX, VALS(cmd_sw_dbg_names), 0x0, NULL, HFILL } },
4144
4145
        /* 0xC0 0xFD XCP POD */
4146
16
        { &hf_xcp_pod_command,                      { "POD Command", "xcp.packet.pod.command_code", FT_UINT16, BASE_HEX, VALS(cmd_pod_mnemonics), 0x0, NULL, HFILL } },
4147
16
    };
4148
4149
16
    static int *ett[] = {
4150
16
        &ett_xcp,
4151
16
        &ett_xcp_header,
4152
16
        &ett_xcp_packet,
4153
16
        &ett_xcp_resource_flags,
4154
16
        &ett_xcp_comm_mode_basic_flags,
4155
16
        &ett_xcp_current_session_status_flags,
4156
16
        &ett_xcp_current_res_protec_status,
4157
16
        &ett_xcp_comm_mode_optional,
4158
16
        &ett_xcp_get_id_mode_parameter,
4159
16
        &ett_xcp_set_request_mode,
4160
16
        &ett_xcp_set_cal_page_mode,
4161
16
        &ett_xcp_trigger_info,
4162
16
        &ett_xcp_payload_format,
4163
16
        &ett_xcp_daq_properties,
4164
16
        &ett_xcp_daq_key_byte,
4165
16
        &ett_xcp_timestamp_mode,
4166
16
        &ett_xcp_daq_list_properties,
4167
16
        &ett_xcp_daq_event_properties,
4168
16
        &ett_xcp_comm_mode_pgm,
4169
16
        &ett_xcp_set_segment_mode_mode,
4170
16
        &ett_xcp_set_daq_list_mode_mode,
4171
16
        &ett_xcp_clear_program_range_fct,
4172
16
        &ett_xcp_set_daq_packed_mode_timestamp_mode,
4173
16
        &ett_xcp_element,
4174
16
    };
4175
4176
16
    static ei_register_info ei[] = {
4177
16
        { &ei_xcp_not_implemented,{ "xcp.not_implemented", PI_UNDECODED, PI_WARN, "Not implemented yet. Please consider creating a ticket and attaching an example trace.", EXPFILL } },
4178
16
    };
4179
4180
16
    proto_xcp = proto_register_protocol("Universal Measurement and Calibration Protocol (XCP)", "XCP", "xcp");
4181
4182
16
    xcp_handle_udp = register_dissector("xcp_udp", dissect_xcp_udp, proto_xcp);
4183
16
    xcp_handle_tcp = register_dissector("xcp_tcp", dissect_xcp_tcp, proto_xcp);
4184
4185
16
    proto_register_field_array(proto_xcp, hf, array_length(hf));
4186
16
    proto_register_subtree_array(ett, array_length(ett));
4187
16
    expert_module_xcp = expert_register_protocol(proto_xcp);
4188
16
    expert_register_field_array(expert_module_xcp, ei, array_length(ei));
4189
4190
16
    xcp_module = prefs_register_protocol(proto_xcp, &check_config);
4191
4192
16
    prefs_register_uint_preference(xcp_module, "address_granularity_default", "Address Granularity Default Value (0, 1, 2, 4)",
4193
16
                                   "The value for Address Granularity used, if not known.", 10, &global_xcp_address_granularity_default);
4194
4195
    /* UATs */
4196
16
    static uat_field_t xcp_memory_addresses_fields[] = {
4197
16
        UAT_FLD_HEX(xcp_memory_addresses,     ecu_id,   "ECU ID",               "ECU ID (16bit hex without leading 0x, 0x0000..0xfffe)"),
4198
16
        UAT_FLD_HEX(xcp_memory_addresses,     addr_ext, "Address Extension",    "The memory address extension byte (8bit hex without leading 0x)"),
4199
16
        UAT_FLD_HEX(xcp_memory_addresses,     address,  "Address",              "The memory address (32bit hex without leading 0x)"),
4200
16
        UAT_FLD_CSTRING(xcp_memory_addresses, name,     "Name",                 "The name for the memory address"),
4201
16
    UAT_END_FIELDS
4202
16
    };
4203
4204
16
    xcp_addresses_uat = uat_new("Memory Addresses",
4205
16
        sizeof(xcp_memory_addresses_uat_t),         /* record size           */
4206
16
        DATAFILE_XCP_MEMORY_ADDRESSES,              /* filename              */
4207
16
        true,                                       /* from profile          */
4208
16
        (void **)&xcp_memory_addresses,             /* data_ptr              */
4209
16
        &xcp_memory_addresses_num,                  /* numitems_ptr          */
4210
16
        UAT_AFFECTS_DISSECTION,                     /* but not fields        */
4211
16
        NULL,                                       /* help                  */
4212
16
        copy_xcp_memory_addresses_cb,               /* copy callback         */
4213
16
        update_xcp_memory_addresses_cb,             /* update callback       */
4214
16
        free_xcp_memory_addresses_cb,               /* free callback         */
4215
16
        post_update_xcp_memory_addresses_cb,        /* post update callback  */
4216
16
        reset_xcp_memory_addresses_cb,              /* reset callback        */
4217
16
        xcp_memory_addresses_fields                 /* UAT field definitions */
4218
16
    );
4219
4220
16
    prefs_register_uat_preference(xcp_module, "addresses", "Memory Addresses",
4221
16
        "A table to define names of memory addresses", xcp_addresses_uat);
4222
4223
4224
    /* UAT for UDP/TCP communication */
4225
16
    static uat_field_t xcp_eth_mapping_fields[] = {
4226
16
        UAT_FLD_VS(xcp_uat_eth_mappings,        protocol,       "IPv4/IPv6",        xcp_proto_type_vals,    "IPv4 or IPv6 or ANY"),
4227
16
        UAT_FLD_CSTRING(xcp_uat_eth_mappings,   ip_address,     "IP Address ECU",   "IP Address"),
4228
16
        UAT_FLD_VS(xcp_uat_eth_mappings,        port_type,      "UDP/TCP",          xcp_port_type_vals,     "TCP or UDP"),
4229
16
        UAT_FLD_DEC(xcp_uat_eth_mappings,       port_number,    "Port Number ECU",  "Port Number"),
4230
16
        UAT_FLD_HEX(xcp_uat_eth_mappings,       ecu_id,         "ECU ID",           "ECU ID (16bit hex without leading 0x, 0x0000..0xfffe, 0xffff for multicast)"),
4231
16
        UAT_END_FIELDS
4232
16
    };
4233
4234
16
    xcp_eth_mapping_uat = uat_new("UDP/TCP",
4235
16
        sizeof(xcp_eth_mapping_uat_t),              /* record size           */
4236
16
        DATAFILE_XCP_ETH_MAPPING,                   /* filename              */
4237
16
        true,                                       /* from profile          */
4238
16
        (void **)&xcp_uat_eth_mappings,             /* data_ptr              */
4239
16
        &xcp_uat_eth_mapping_num,                   /* numitems_ptr          */
4240
16
        UAT_AFFECTS_DISSECTION,                     /* but not fields        */
4241
16
        NULL,                                       /* help                  */
4242
16
        copy_xcp_eth_mapping_cb,                    /* copy callback         */
4243
16
        update_xcp_eth_mapping_cb,                  /* update callback       */
4244
16
        free_xcp_eth_mapping_cb,                    /* free callback         */
4245
16
        post_update_xcp_eth_mapping_cb,             /* post update callback  */
4246
16
        reset_xcp_eth_mapping_cb,                   /* reset callback        */
4247
16
        xcp_eth_mapping_fields                      /* UAT field definitions */
4248
16
    );
4249
4250
16
    prefs_register_uat_preference(xcp_module, "eth_mappings", "UDP/TCP Mappings",
4251
16
        "A table to map UDP and TCP packets to XCP", xcp_eth_mapping_uat);
4252
4253
4254
    /* add UAT for CAN */
4255
16
    static uat_field_t xcp_can_mapping_fields[] = {
4256
16
        UAT_FLD_HEX(xcp_uat_can_mappings, bus_id,        "Bus ID",       "Bus ID on which frame was recorded with 0=any (16bit hex without leading 0x)"),
4257
16
        UAT_FLD_HEX(xcp_uat_can_mappings, can_id_m_to_s, "CAN ID M->S",  "CAN ID M->S (32bit hex without leading 0x, highest bit 1 for extended, 0 for standard ID)"),
4258
16
        UAT_FLD_HEX(xcp_uat_can_mappings, can_id_s_to_m, "CAN ID S->M",  "CAN ID S->M (32bit hex without leading 0x, highest bit 1 for extended, 0 for standard ID)"),
4259
16
        UAT_FLD_HEX(xcp_uat_can_mappings, ecu_id,        "ECU ID",       "ECU ID (16bit hex without leading 0x, 0x0000..0xfffe, 0xffff to all)"),
4260
16
        UAT_END_FIELDS
4261
16
    };
4262
4263
16
    xcp_can_mapping_uat = uat_new("CAN",
4264
16
        sizeof(xcp_can_mapping_uat_t),              /* record size           */
4265
16
        DATAFILE_XCP_CAN_MAPPING,                   /* filename              */
4266
16
        true,                                       /* from profile          */
4267
16
        (void **)&xcp_uat_can_mappings,             /* data_ptr              */
4268
16
        &xcp_uat_can_mapping_num,                   /* numitems_ptr          */
4269
16
        UAT_AFFECTS_DISSECTION,                     /* but not fields        */
4270
16
        NULL,                                       /* help                  */
4271
16
        copy_xcp_can_mapping_cb,                    /* copy callback         */
4272
16
        update_xcp_can_mapping_cb,                  /* update callback       */
4273
16
        NULL,                                       /* free callback         */
4274
16
        post_update_xcp_can_mapping_cb,             /* post update callback  */
4275
16
        reset_xcp_can_mapping_cb,                   /* reset callback        */
4276
16
        xcp_can_mapping_fields                      /* UAT field definitions */
4277
16
    );
4278
4279
16
    prefs_register_uat_preference(xcp_module, "can_mappings", "CAN Mappings",
4280
16
        "A table to map CAN payloads to XCP", xcp_can_mapping_uat);
4281
4282
16
}
4283
4284
void
4285
16
proto_reg_handoff_xcp(void) {
4286
16
    static bool initialized = false;
4287
4288
16
    if (!initialized) {
4289
16
        xcp_handle_can = register_dissector("xcp_over_can", dissect_xcp_can, proto_xcp);
4290
16
        dissector_add_for_decode_as("can.subdissector", xcp_handle_can);
4291
16
        heur_dissector_add("can", dissect_xcp_can_heur, "XCP over CAN", "xcp_can_heur", proto_xcp, HEURISTIC_ENABLE);
4292
4293
        initialized = true;
4294
16
    }
4295
16
}
4296
4297
 /*
4298
  * Editor modelines
4299
  *
4300
  * Local Variables:
4301
  * c-basic-offset: 4
4302
  * tab-width: 8
4303
  * indent-tabs-mode: nil
4304
  * End:
4305
  *
4306
  * ex: set shiftwidth=4 tabstop=8 expandtab:
4307
  * :indentSize=4:tabSize=8:noTabs=true:
4308
  */