Fixup: tvb_get_string(z) -> tvb_get_string(z)_enc
[metze/wireshark/wip.git] / epan / dissectors / packet-sysex.c
1 /* packet-sysex.c
2  *
3  * MIDI SysEx dissector
4  * Tomasz Mon 2012
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21
22 #include "config.h"
23
24 #include <glib.h>
25 #include <epan/conversation.h>
26 #include <epan/wmem/wmem.h>
27 #include <epan/expert.h>
28 #include <epan/packet.h>
29 #include <epan/reassemble.h>
30 #include <epan/tfs.h>
31
32 void proto_register_sysex(void);
33 void proto_reg_handoff_sysex(void);
34
35 /* protocols and header fields */
36 static int proto_sysex = -1;
37 static int hf_sysex_message_start = -1;
38 static int hf_sysex_manufacturer_id = -1;
39 static int hf_sysex_three_byte_manufacturer_id = -1;
40 static int hf_sysex_device_id = -1;
41 static int hf_sysex_message_eox = -1;
42
43 static int hf_digitech_family_id = -1;
44 static int hf_digitech_rp_product_id = -1;
45 static int hf_digitech_unknown_product_id = -1;
46 static int hf_digitech_procedure_id = -1;
47
48 static int hf_digitech_desired_device_id = -1;
49 static int hf_digitech_desired_family_id = -1;
50 static int hf_digitech_desired_product_id = -1;
51 static int hf_digitech_device_id = -1;
52 static int hf_digitech_os_mode = -1;
53
54 static int hf_digitech_preset_bank = -1;
55 static int hf_digitech_preset_index = -1;
56 static int hf_digitech_preset_count = -1;
57 static int hf_digitech_preset_name = -1;
58 static int hf_digitech_preset_modified = -1;
59
60 static int hf_digitech_message_count = -1;
61
62 static int hf_digitech_parameter_count = -1;
63 static int hf_digitech_parameter_id = -1;
64 static int hf_digitech_parameter_id_global = -1;
65 static int hf_digitech_parameter_id_pickup = -1;
66 static int hf_digitech_parameter_id_wah = -1;
67 static int hf_digitech_parameter_id_compressor = -1;
68 static int hf_digitech_parameter_id_gnx3k_whammy = -1;
69 static int hf_digitech_parameter_id_distortion = -1;
70 static int hf_digitech_parameter_id_amp_channel = -1;
71 static int hf_digitech_parameter_id_amp = -1;
72 static int hf_digitech_parameter_id_amp_cabinet = -1;
73 static int hf_digitech_parameter_id_amp_b = -1;
74 static int hf_digitech_parameter_id_amp_cabinet_b = -1;
75 static int hf_digitech_parameter_id_noisegate = -1;
76 static int hf_digitech_parameter_id_volume_pre_fx = -1;
77 static int hf_digitech_parameter_id_chorusfx = -1;
78 static int hf_digitech_parameter_id_delay = -1;
79 static int hf_digitech_parameter_id_reverb = -1;
80 static int hf_digitech_parameter_id_volume_post_fx = -1;
81 static int hf_digitech_parameter_id_preset = -1;
82 static int hf_digitech_parameter_id_wah_min_max = -1;
83 static int hf_digitech_parameter_id_equalizer = -1;
84 static int hf_digitech_parameter_id_equalizer_b = -1;
85 static int hf_digitech_parameter_id_amp_loop = -1;
86
87 static int hf_digitech_parameter_position = -1;
88 static int hf_digitech_parameter_data = -1;
89 static int hf_digitech_parameter_data_count = -1;
90 static int hf_digitech_parameter_data_two_byte_count = -1;
91 static int hf_digitech_parameter_multibyte_data = -1;
92
93 static int hf_digitech_ack_request_proc_id = -1;
94 static int hf_digitech_nack_request_proc_id = -1;
95
96 static int hf_digitech_checksum = -1;
97
98 static gint ett_sysex = -1;
99
100 static expert_field ei_sysex_message_start_byte = EI_INIT;
101 static expert_field ei_digitech_checksum_bad = EI_INIT;
102 static expert_field ei_sysex_message_end_byte = EI_INIT;
103 static expert_field ei_sysex_undecoded = EI_INIT;
104
105 #define SYSEX_MANUFACTURER_DOD 0x000010
106
107 static const value_string sysex_three_byte_manufacturer_id[] = {
108     {SYSEX_MANUFACTURER_DOD, "DOD Electronics Corp."},
109     {0, NULL}
110 };
111
112 typedef struct _digitech_conv_data_t {
113     gint protocol_version;
114 } digitech_conv_data_t;
115
116 #define DIGITECH_FAMILY_X_FLOOR  0x5C
117 #define DIGITECH_FAMILY_JAMMAN   0x5D
118 #define DIGITECH_FAMILY_RP       0x5E
119 #define DIGITECH_FAMILY_RACK     0x5F
120 #define DIGITECH_FAMILY_VOCALIST 0x60
121
122 static const value_string digitech_family_id[] = {
123     {DIGITECH_FAMILY_X_FLOOR,  "\"X\" Floor Guitar Processor"},
124     {DIGITECH_FAMILY_JAMMAN,   "JamMan"},
125     {DIGITECH_FAMILY_RP,       "RP series"},
126     {DIGITECH_FAMILY_RACK,     "Rack"},
127     {DIGITECH_FAMILY_VOCALIST, "Vocalist"},
128     {0x7F, "All"},
129     {0, NULL}
130 };
131
132 static const value_string digitech_rp_product_id[] = {
133     {0x01, "RP150"},
134     {0x02, "RP250"},
135     {0x03, "RP350"},
136     {0x04, "RP370"},
137     {0x05, "RP500"},
138     {0x06, "RP1000"},
139     {0x07, "RP155"},
140     {0x08, "RP255"},
141     {0x09, "RP355"},
142     {0, NULL}
143 };
144
145 typedef enum _digitech_procedure_id {
146     DIGITECH_PROCEDURE_REQUEST_WHO_AM_I = 0x01,
147     DIGITECH_PROCEDURE_RECEIVE_WHO_AM_I = 0x02,
148
149     DIGITECH_PROCEDURE_REQUEST_DEVICE_CONFIGURATION = 0x08,
150     DIGITECH_PROCEDURE_RECEIVE_DEVICE_CONFIGURATION = 0x09,
151
152     DIGITECH_PROCEDURE_REQUEST_GLOBAL_PARAMETERS = 0x10,
153     DIGITECH_PROCEDURE_RECEIVE_GLOBAL_PARAMETERS = 0x11,
154
155     DIGITECH_PROCEDURE_REQUEST_BULK_DUMP = 0x18,
156     DIGITECH_PROCEDURE_RECEIVE_BULK_DUMP_START = 0x19,
157     DIGITECH_PROCEDURE_RECEIVE_BULK_DUMP_END = 0x1B,
158
159     DIGITECH_PROCEDURE_RECEIVE_USER_PRESET_INDEX_TABLE = 0x20,
160
161     DIGITECH_PROCEDURE_REQUEST_PRESET_NAMES = 0x21,
162     DIGITECH_PROCEDURE_RECEIVE_PRESET_NAMES = 0x22,
163
164     DIGITECH_PROCEDURE_REQUEST_PRESET_NAME = 0x28,
165     DIGITECH_PROCEDURE_RECEIVE_PRESET_NAME = 0x29,
166
167     DIGITECH_PROCEDURE_REQUEST_PRESET = 0x2A,
168     DIGITECH_PROCEDURE_RECEIVE_PRESET_START = 0x2B,
169     DIGITECH_PROCEDURE_RECEIVE_PRESET_END = 0x2C,
170     DIGITECH_PROCEDURE_RECEIVE_PRESET_PARAMETERS = 0x2D,
171
172     DIGITECH_PROCEDURE_LOAD_EDIT_BUFFER_PRESET = 0x38, /* version 0 only
173                                        use move preset in later versions */
174
175     DIGITECH_PROCEDURE_MOVE_PRESET = 0x39,
176
177     DIGITECH_PROCEDURE_REQUEST_MODIFIER_LINKABLE_LIST = 0x3A,
178     DIGITECH_PROCEDURE_RECEIVE_MODIFIER_LINKABLE_LIST = 0x3B,
179
180     DIGITECH_PROCEDURE_REQUEST_PARAMETER_VALUE = 0x40,
181     DIGITECH_PROCEDURE_RECEIVE_PARAMETER_VALUE = 0x41,
182
183     /* version 1 and later */
184     DIGITECH_PROCEDURE_REQUEST_OBJECT_NAMES = 0x50,
185     DIGITECH_PROCEDURE_RECEIVE_OBJECT_NAMES = 0x51,
186     DIGITECH_PROCEDURE_REQUEST_OBJECT_NAME = 0x52,
187     DIGITECH_PROCEDURE_RECEIVE_OBJECT_NAME = 0x53,
188     DIGITECH_PROCEDURE_REQUEST_OBJECT = 0x54,
189     DIGITECH_PROCEDURE_RECEIVE_OBJECT = 0x55,
190     DIGITECH_PROCEDURE_MOVE_OBJECT = 0x56,
191     DIGITECH_PROCEDURE_DELETE_OBJECT = 0x57,
192     DIGITECH_PROCEDURE_REQUEST_TABLE = 0x5A,
193     DIGITECH_PROCEDURE_RECEIVE_TABLE = 0x5B,
194
195     DIGITECH_PROCEDURE_RECEIVE_DEVICE_NOTIFICATION = 0x70,
196
197     DIGITECH_PROCEDURE_START_OS_DOWNLOAD = 0x71,
198     DIGITECH_PROCEDURE_RESTART_DEVICE = 0x72,
199     DIGITECH_PROCEDURE_REQUEST_DEBUG_DATA = 0x73,
200     DIGITECH_PROCEDURE_RECEIVE_DEBUG_DATA = 0x74,
201
202     DIGITECH_PROCEDURE_ACK = 0x7E,
203     DIGITECH_PROCEDURE_NACK = 0x7F
204 } digitech_procedure_id;
205
206 static const value_string digitech_procedures[] = {
207     {DIGITECH_PROCEDURE_REQUEST_WHO_AM_I, "Request WhoAmI"},
208     {DIGITECH_PROCEDURE_RECEIVE_WHO_AM_I, "Receive WhoAmI"},
209     {DIGITECH_PROCEDURE_REQUEST_DEVICE_CONFIGURATION, "Request Device Configuration"},
210     {DIGITECH_PROCEDURE_RECEIVE_DEVICE_CONFIGURATION, "Receive Device Configuration"},
211     {DIGITECH_PROCEDURE_REQUEST_GLOBAL_PARAMETERS, "Request Global Parameters"},
212     {DIGITECH_PROCEDURE_RECEIVE_GLOBAL_PARAMETERS, "Receive Global Parameters"},
213     {DIGITECH_PROCEDURE_REQUEST_BULK_DUMP, "Request Bulk Dump"},
214     {DIGITECH_PROCEDURE_RECEIVE_BULK_DUMP_START, "Receive Bulk Dump Start"},
215     {DIGITECH_PROCEDURE_RECEIVE_BULK_DUMP_END, "Receive Bulk Dump End"},
216     {DIGITECH_PROCEDURE_RECEIVE_USER_PRESET_INDEX_TABLE, "Receive User Preset Index Table"},
217     {DIGITECH_PROCEDURE_REQUEST_PRESET_NAMES, "Request Preset Names"},
218     {DIGITECH_PROCEDURE_RECEIVE_PRESET_NAMES, "Receive Preset Names"},
219     {DIGITECH_PROCEDURE_REQUEST_PRESET_NAME, "Request Preset Name"},
220     {DIGITECH_PROCEDURE_RECEIVE_PRESET_NAME, "Receive Preset Name"},
221     {DIGITECH_PROCEDURE_REQUEST_PRESET, "Request Preset"},
222     {DIGITECH_PROCEDURE_RECEIVE_PRESET_START, "Receive Preset Start"},
223     {DIGITECH_PROCEDURE_RECEIVE_PRESET_END, "Receive Preset End"},
224     {DIGITECH_PROCEDURE_RECEIVE_PRESET_PARAMETERS, "Receive Preset Parameters"},
225     {DIGITECH_PROCEDURE_LOAD_EDIT_BUFFER_PRESET, "Load Edit Buffer Preset"},
226     {DIGITECH_PROCEDURE_MOVE_PRESET, "Move Preset"},
227     {DIGITECH_PROCEDURE_REQUEST_MODIFIER_LINKABLE_LIST, "Request Modifier-Linkable List"},
228     {DIGITECH_PROCEDURE_RECEIVE_MODIFIER_LINKABLE_LIST, "Receive Modifier-Linkable List"},
229     {DIGITECH_PROCEDURE_REQUEST_PARAMETER_VALUE, "Request Parameter Value"},
230     {DIGITECH_PROCEDURE_RECEIVE_PARAMETER_VALUE, "Receive Parameter Value"},
231     {DIGITECH_PROCEDURE_REQUEST_OBJECT_NAMES, "Request Object Names"},
232     {DIGITECH_PROCEDURE_RECEIVE_OBJECT_NAMES, "Receive Object Names"},
233     {DIGITECH_PROCEDURE_REQUEST_OBJECT_NAME, "Request Object Name"},
234     {DIGITECH_PROCEDURE_RECEIVE_OBJECT_NAME, "Receive Object Name"},
235     {DIGITECH_PROCEDURE_REQUEST_OBJECT, "Request Object"},
236     {DIGITECH_PROCEDURE_RECEIVE_OBJECT, "Receive Object"},
237     {DIGITECH_PROCEDURE_MOVE_OBJECT, "Move Object"},
238     {DIGITECH_PROCEDURE_DELETE_OBJECT, "Delete Object"},
239     {DIGITECH_PROCEDURE_REQUEST_TABLE, "Request Table"},
240     {DIGITECH_PROCEDURE_RECEIVE_TABLE, "Receive Table"},
241     {DIGITECH_PROCEDURE_RECEIVE_DEVICE_NOTIFICATION, "Receive Device Notification"},
242     {DIGITECH_PROCEDURE_START_OS_DOWNLOAD, "Start OS Download"},
243     {DIGITECH_PROCEDURE_RESTART_DEVICE, "Restart Device"},
244     {DIGITECH_PROCEDURE_REQUEST_DEBUG_DATA, "Request Debug Data"},
245     {DIGITECH_PROCEDURE_RECEIVE_DEBUG_DATA, "Receive Debug Data"},
246     {DIGITECH_PROCEDURE_ACK, "ACK"},
247     {DIGITECH_PROCEDURE_NACK, "NACK"},
248     {0, NULL}
249 };
250 static value_string_ext digitech_procedures_ext =
251     VALUE_STRING_EXT_INIT(digitech_procedures);
252
253 static const value_string digitech_os_modes[] = {
254     {0, "Normal"},
255     {1, "Flash update"},
256     {0, NULL}
257 };
258
259 static const value_string digitech_preset_banks[] = {
260     {0, "Factory (fixed) bank"},
261     {1, "User bank"},
262     {2, "Artist bank"},
263     {3, "Media card (CF or other)"},
264     {4, "Current preset edit buffer"},
265     {5, "Second factory bank"},
266     {6, "External preset"},
267     {0, NULL}
268 };
269
270 static const value_string digitech_parameter_ids_global[] = {
271     {12361, "Amp/Cab Bypass On/Off"},
272     {12298, "GUI Mode On/Off"},
273     {0, NULL}
274 };
275
276 static const value_string digitech_parameter_ids_pickup[] = {
277     {65, "Pickup On/Off"},
278     {0, NULL}
279 };
280
281 static const value_string digitech_parameter_ids_wah[] = {
282     {129, "Wah On/Off"},
283     {133, "Wah Level"},
284     {0, NULL}
285 };
286
287 static const value_string digitech_parameter_ids_compressor[] = {
288     {193, "Compressor On/Off"},
289     {194, "Compressor Attack"},
290     {195, "Compressor Ratio"},
291     {200, "Compressor Threshold"},
292     {201, "Compressor Gain"},
293     {208, "Compressor Sustain"},
294     {209, "Compressor Tone"},
295     {210, "Compressor Level"},
296     {211, "Compressor Attack"},
297     {212, "Compressor Output"},
298     {213, "Compressor Sensitivity"},
299     {0, NULL}
300 };
301
302 static const value_string digitech_parameter_ids_gnx3k_whammy[] = {
303     {769, "Whammy/IPS On/Off"},
304     {1667, "Whammy/IPS Detune Level"},
305     {1670, "Whammy/IPS Detune Shift Amount"},
306     {1731, "Whammy/IPS Pitch Shift Level"},
307     {1732, "Whammy/IPS Pitch Shift Shift Amount"},
308     {1795, "Whammy/IPS Whammy Pedal"},
309     {1796, "Whammy/IPS Whammy Mix"},
310     {1797, "Whammy/IPS Whammy Shift Amount"},
311     {2754, "Whammy/IPS IPS Shift Amount"},
312     {2755, "Whammy/IPS IPS Scale"},
313     {2756, "Whammy/IPS IPS Key"},
314     {2757, "Whammy/IPS IPS Level"},
315     {2818, "Whammy/IPS Talker Mic Level"},
316     {0, NULL}
317 };
318 static value_string_ext digitech_parameter_ids_gnx3k_whammy_ext =
319     VALUE_STRING_EXT_INIT(digitech_parameter_ids_gnx3k_whammy);
320
321 static const value_string digitech_parameter_ids_distortion[] = {
322     {2433, "Distortion On/Off"},
323     {2434, "Distortion Screamer Drive"},
324     {2435, "Distortion Screamer Tone"},
325     {2436, "Distortion Screamer Level"},
326     {2437, "Distortion Rodent Dist"},
327     {2438, "Distortion Rodent Filter"},
328     {2439, "Distortion Rodent Level"},
329     {2440, "Distortion DS Gain"},
330     {2441, "Distortion DS Tone"},
331     {2442, "Distortion DS Level"},
332     {2443, "Distortion DOD250 Gain"},
333     {2444, "Distortion DOD250 Level"},
334     {2445, "Distortion Big MP Sustain"},
335     {2446, "Distortion Big MP Tone"},
336     {2447, "Distortion Big MP Volume"},
337     {2448, "Distortion GuyOD Drive"},
338     {2449, "Distortion GuyOD Level"},
339     {2450, "Distortion Sparkdrive Gain"},
340     {2451, "Distortion Sparkdrive Tone"},
341     {2452, "Distortion Sparkdrive Clean"},
342     {2453, "Distortion Sparkdrive Volume"},
343     {2454, "Distortion Grunge Grunge"},
344     {2455, "Distortion Grunge Butt"},
345     {2456, "Distortion Grunge Face"},
346     {2457, "Distortion Grunge Loud"},
347     {2458, "Distortion Fuzzy Fuzz"},
348     {2459, "Distortion Fuzzy Volume"},
349     {2460, "Distortion Zone Gain"},
350     {2461, "Distortion Zone Mid freq"},
351     {2462, "Distortion Zone Mid level"},
352     {2463, "Distortion Zone Low"},
353     {2464, "Distortion Zone High"},
354     {2465, "Distortion Zone Level"},
355     {2466, "Distortion 8tavia Drive"},
356     {2467, "Distortion 8tavia Volume"},
357     {2468, "Distortion MX Dist"},
358     {2469, "Distortion MX Output"},
359     {2470, "Distortion Gonk Suck"},
360     {2471, "Distortion Gonk Smear"},
361     {2472, "Distortion Gonk Heave"},
362     {2473, "Distortion 808 Overdrive"},
363     {2474, "Distortion 808 Tone"},
364     {2475, "Distortion 808 Level"},
365     {2476, "Distortion Death Mid"},
366     {2477, "Distortion Death Low"},
367     {2478, "Distortion Death Level"},
368     {2479, "Distortion Death High"},
369     {2480, "Distortion Gonk Gonk"},
370     {2481, "Distortion Fuzzlator Fuzz"},
371     {2482, "Distortion Fuzzlator Tone"},
372     {2483, "Distortion Fuzzlator LooseTight"},
373     {2484, "Distortion Fuzzlator Volume"},
374     {2485, "Distortion Classic Fuzz Fuzz"},
375     {2486, "Distortion Classic Fuzz Tone"},
376     {2487, "Distortion Classic Fuzz Volume"},
377     {2488, "Distortion Redline Gain"},
378     {2489, "Distortion Redline Low"},
379     {2490, "Distortion Redline High"},
380     {2491, "Distortion Redline Level"},
381     {2492, "Distortion OC Drive Drive"},
382     {2493, "Distortion OC Drive HP/LP"},
383     {2494, "Distortion OC Drive Tone"},
384     {2495, "Distortion OC Drive Level"},
385     {2562, "Distortion TS Mod Drive"},
386     {2563, "Distortion TS Mod Level"},
387     {2564, "Distortion TS Mod Tone"},
388     {2565, "Distortion SD Overdrive Drive"},
389     {2566, "Distortion SD Overdrive Tone"},
390     {2567, "Distortion SD Overdrive Level"},
391     {2568, "Distortion OD Overdrive Overdrive"},
392     {2569, "Distortion OD Overdrive Level"},
393     {2570, "Distortion Amp Driver Gain"},
394     {2571, "Distortion Amp Driver Mid Boost"},
395     {2572, "Distortion Amp Driver Level"},
396     {0, NULL}
397 };
398 static value_string_ext digitech_parameter_ids_distortion_ext =
399     VALUE_STRING_EXT_INIT(digitech_parameter_ids_distortion);
400
401 static const value_string digitech_parameter_ids_amp_channel[] = {
402     {260, "Amp Channel Amp Channel"},
403     {261, "Amp Channel Warp"},
404     {262, "Amp Channel Amp Warp"},
405     {263, "Amp Channel Cabinet Warp"},
406     {0, NULL}
407 };
408
409 static const value_string digitech_parameter_ids_amp[] = {
410     {265, "Amplifier On/Off"},
411     {2497, "Amplifier Gain"},
412     {2498, "Amplifier Level"},
413     {2499, "Channel 1 Bass Freq"},
414     {2500, "Channel 1 Bass Level"},
415     {2501, "Channel 1 Mid Freq"},
416     {2502, "Channel 1 Mid Level"},
417     {2503, "Channel 1 Treb Freq"},
418     {2504, "Channel 1 Treb Level"},
419     {2505, "EQ Enable On/Off"},
420     {2506, "Channel 1 Presence"},
421     {2507, "Amplifier Bass"},
422     {2508, "Amplifier Mid"},
423     {2509, "Amplifier Treble"},
424     {0, NULL}
425 };
426 static value_string_ext digitech_parameter_ids_amp_ext =
427     VALUE_STRING_EXT_INIT(digitech_parameter_ids_amp);
428
429 static const value_string digitech_parameter_ids_amp_cabinet[] = {
430     {2561, "Channel 1 Tuning"},
431     {0, NULL}
432 };
433
434 static const value_string digitech_parameter_ids_amp_b[] = {
435     {265, "Amplifier B On/Off"},
436     {2497, "Amplifier B Gain"},
437     {2498, "Amplifier B Level"},
438     {2499, "Channel 2 Bass Freq"},
439     {2500, "Channel 2 Bass Level"},
440     {2501, "Channel 2 Mid Freq"},
441     {2502, "Channel 2 Mid Level"},
442     {2503, "Channel 2 Treb Freq"},
443     {2504, "Channel 2 Treb Level"},
444     {2505, "EQ Enable On/Off"},
445     {2506, "Channel 2 Presence"},
446     {0, NULL}
447 };
448
449 static const value_string digitech_parameter_ids_amp_cabinet_b[] = {
450     {2561, "Channel 2 Tuning"},
451     {0, NULL}
452 };
453
454 static const value_string digitech_parameter_ids_noisegate[] = {
455     {705, "Noisegate On/Off"},
456     {706, "Noisegate Attack"},
457     {710, "Noisegate Threshold"},
458     {711, "Noisegate Sens"},
459     {712, "Noisegate Attack"},
460     {713, "Noisegate Release"},
461     {714, "Noisegate Attn"},
462     {0, NULL}
463 };
464
465 static const value_string digitech_parameter_ids_volume_pre_fx[] = {
466     {2626, "Pickup Volume Pre FX"},
467     {0, NULL}
468 };
469
470 static const value_string digitech_parameter_ids_chorusfx[] = {
471     {769, "Chorus/FX On/Off"},
472     {836, "Chorus/FX Chorus Level"},
473     {837, "Chorus/FX Chorus Speed"},
474     {838, "Chorus/FX CE/Dual/Multi Chorus Depth"},
475     {839, "Chorus/FX Chorus Predelay"},
476     {840, "Chorus/FX Dual/Multi Chorus Wave"},
477     {841, "Chorus/FX Chorus Balance"},
478     {848, "Chorus/FX Chorus Width"},
479     {849, "Chorus/FX Chorus Intensity"},
480     {850, "Chorus/FX Small Clone Rate"},
481     {901, "Chorus/FX Flanger Level/Mix"},
482     {902, "Chorus/FX Flanger Speed"},
483     {903, "Chorus/FX Flanger Depth"},
484     {904, "Chorus/FX Flanger Regen"},
485     {905, "Chorus/FX Flanger Waveform"},
486     {906, "Chorus/FX Flanger Balance"},
487     {914, "Chorus/FX Flanger Width"},
488     {916, "Chorus/FX Flanger Color"},
489     {917, "Chorus/FX Flanger Manual"},
490     {918, "Chorus/FX Flanger Rate"},
491     {919, "Chorus/FX Flanger Range"},
492     {920, "Chorus/FX Flanger Enhance"},
493     {921, "Chorus/FX Flanger Harmonics"},
494     {922, "Chorus/FX Filter Flanger Frequency"},
495     {962, "Chorus/FX Phaser Speed"},
496     {963, "Chorus/FX Phaser Depth"},
497     {965, "Chorus/FX Phaser Level"},
498     {966, "Chorus/FX Phaser Regen"},
499     {967, "Chorus/FX Phaser Waveform"},
500     {968, "Chorus/FX Phaser Balance"},
501     {976, "Chorus/FX MX Phaser Intensity"},
502     {977, "Chorus/FX EH Phaser Color"},
503     {979, "Chorus/FX EH Phaser Rate"},
504     {1028, "Chorus/FX Triggered Flanger Lfo Start"},
505     {1029, "Chorus/FX Triggered Flanger/Phaser Mix"},
506     {1030, "Chorus/FX Triggered Flanger Speed"},
507     {1031, "Chorus/FX Triggered Flanger Sens"},
508     {1032, "Chorus/FX Triggered Flanger Level"},
509     {1092, "Chorus/FX Triggered Phaser Lfo Start"},
510     {1094, "Chorus/FX Triggered Phaser Speed"},
511     {1095, "Chorus/FX Triggered Phaser Sens"},
512     {1096, "Chorus/FX Triggered Phaser Level"},
513     {1155, "Chorus/FX Tremolo Depth"},
514     {1156, "Chorus/FX Tremolo Speed"},
515     {1157, "Chorus/FX Tremolo Wave"},
516     {1219, "Chorus/FX Panner Depth"},
517     {1220, "Chorus/FX Panner Speed"},
518     {1221, "Chorus/FX Panner Wave"},
519     {1284, "Chorus/FX Vibrato Speed"},
520     {1285, "Chorus/FX Vibrato Depth"},
521     {1286, "Chorus/FX Vibrato Waveform"},
522     {1314, "Chorus/FX Vibropan Speed"},
523     {1315, "Chorus/FX Vibropan Depth"},
524     {1316, "Chorus/FX Vibropan Vibra"},
525     {1317, "Chorus/FX Vibropan Wave"},
526     {1346, "Chorus/FX Rotary Speed"},
527     {1348, "Chorus/FX Rotary Intensity"},
528     {1349, "Chorus/FX Rotary Mix"},
529     {1350, "Chorus/FX Rotary Doppler"},
530     {1351, "Chorus/FX Rotary Crossover"},
531     {1352, "Chorus/FX Rotary Balance"},
532     {1410, "Chorus/FX YaYa Pedal"},
533     {1412, "Chorus/FX YaYa Range"},
534     {1413, "Chorus/FX YaYa Mix"},
535     {1414, "Chorus/FX YaYa Depth"},
536     {1416, "Chorus/FX YaYa Balance"},
537     {1417, "Chorus/FX YaYa Intensity"},
538     {1418, "Chorus/FX YaYa Range"},
539     {1476, "Chorus/FX AutoYa Range"},
540     {1477, "Chorus/FX AutoYa Mix"},
541     {1478, "Chorus/FX AutoYa Speed"},
542     {1479, "Chorus/FX AutoYa Depth"},
543     {1481, "Chorus/FX AutoYa Balance"},
544     {1482, "Chorus/FX AutoYa Intensity"},
545     {1483, "Chorus/FX AutoYa Range"},
546     {1540, "Chorus/FX Synthtalk Vox"},
547     {1542, "Chorus/FX Synthtalk Attack"},
548     {1543, "Chorus/FX Synthtalk Release"},
549     {1544, "Chorus/FX Synthtalk Sens"},
550     {1545, "Chorus/FX Synthtalk Balance"},
551     {1604, "Chorus/FX Envelope Mix"},
552     {1605, "Chorus/FX Envelope/FX25 Range"},
553     {1606, "Chorus/FX Envelope/FX25 Sensitivity"},
554     {1607, "Chorus/FX Envelope Balance"},
555     {1608, "Chorus/FX FX25 Blend"},
556     {1667, "Chorus/FX Detune Level"},
557     {1668, "Chorus/FX Detune Amount"},
558     {1669, "Chorus/FX Detune Balance"},
559     {1730, "Chorus/FX Pitch Shift Amount"},
560     {1731, "Chorus/FX Pitch Level"},
561     {1733, "Chorus/FX Pitch Balance"},
562     {1745, "Chorus/FX Pitch Shift Mix"},
563     {1746, "Chorus/FX Octaver Octave 1"},
564     {1747, "Chorus/FX Octaver Octave 2"},
565     {1748, "Chorus/FX Octaver Dry Level"},
566     {1795, "Chorus/FX Whammy Pedal"},
567     {1796, "Chorus/FX Whammy Mix"},
568     {1797, "Chorus/FX Whammy Amount"},
569     {2754, "Chorus/FX IPS/Harmony Pitch Shift"},
570     {2755, "Chorus/FX IPS/Harmony Pitch Scale"},
571     {2756, "Chorus/FX IPS/Harmony Pitch Key"},
572     {2757, "Chorus/FX IPS/Harmony Pitch Level"},
573     {2882, "Chorus/FX Unovibe Chorus/Vibrato"},
574     {2883, "Chorus/FX Unovibe Intensity"},
575     {2884, "Chorus/FX Unovibe Pedal Speed"},
576     {2885, "Chorus/FX Unovibe Volume"},
577     {3010, "Chorus/FX Step Filter Speed"},
578     {3011, "Chorus/FX Step Filter Intensity"},
579     {3012, "Chorus/FX Sample/Hold Speed"},
580     {3013, "Chorus/FX Sample/Hold Intensity"},
581     {0, NULL}
582 };
583 static value_string_ext digitech_parameter_ids_chorusfx_ext =
584     VALUE_STRING_EXT_INIT(digitech_parameter_ids_chorusfx);
585
586 static const value_string digitech_parameter_ids_delay[] = {
587     {1857, "Delay On/Off"},
588     {1860, "Delay Level"},
589     {1862, "Delay Time"},
590     {1863, "Delay Repeats"},
591     {1864, "Delay Thresh"},
592     {1865, "Delay Atten"},
593     {1866, "Delay Balance"},
594     {1867, "Delay Spread"},
595     {1868, "Delay Tap Time"},
596     {1873, "Delay Depth"},
597     {1874, "Delay Repeats"},
598     {1888, "Delay Time"},
599     {1889, "Delay Ducker thresh"},
600     {1890, "Delay Ducker level"},
601     {1891, "Delay Tape Wow"},
602     {1892, "Delay Tape Flutter"},
603     {1893, "Delay Echo Plex Volume"},
604     {1894, "Delay DM Repeat Rate"},
605     {1895, "Delay DM Echo"},
606     {1896, "Delay DM Intensity"},
607     {1897, "Delay Echo Plex Time"},
608     {1898, "Delay DM Delay Repeat Rate"},
609     {1899, "Delay Echo Plex Time"},
610     {1900, "Delay Tap Time"},
611     {1901, "Delay Reverse Time"},
612     {1902, "Delay Reverse Mix"},
613     {1905, "Delay 2-tap Ratio"},
614     {0, NULL}
615 };
616 static value_string_ext digitech_parameter_ids_delay_ext =
617     VALUE_STRING_EXT_INIT(digitech_parameter_ids_delay);
618
619 static const value_string digitech_parameter_ids_reverb[] = {
620     {1921, "Reverb On/Off"},
621     {1922, "Reverb Predelay"},
622     {1924, "Reverb Damping"},
623     {1925, "Reverb Level"},
624     {1927, "Reverb Decay"},
625     {1928, "Reverb Balance"},
626     {1933, "Reverb Liveliness"},
627     {9, NULL}
628 };
629
630 static const value_string digitech_parameter_ids_volume_post_fx[] = {
631     {2626, "Pickup Volume Post FX"},
632     {0, NULL}
633 };
634
635 static const value_string digitech_parameter_ids_preset[] = {
636     {2626, "Pickup Preset Level"},
637     {0, NULL}
638 };
639
640 static const value_string digitech_parameter_ids_wah_min_max[] = {
641     {8195, "Wah Min"},
642     {8196, "Wah Max"},
643     {0, NULL}
644 };
645
646 static const value_string digitech_parameter_ids_equalizer[] = {
647     {3203, "Equalizer Bass"},
648     {3204, "Equalizer Mid"},
649     {3205, "Equalizer Treble"},
650     {3206, "Equalizer Mid Hz"},
651     {3207, "Equalizer Presence"},
652     {3211, "Equalizer Treb Hz"},
653     {3212, "Equalizer On/Off"},
654     {3213, "Equalizer Low Freq"},
655     {3215, "Equalizer High Freq"},
656     {3216, "Equalizer Low Bandwidth"},
657     {3217, "Equalizer Mid Bandwidth"},
658     {3218, "Equalizer High Bandwidth"},
659     {0, NULL}
660 };
661
662 static const value_string digitech_parameter_ids_equalizer_b[] = {
663     {3203, "Equalizer B Bass"},
664     {3204, "Equalizer B Mid"},
665     {3205, "Equalizer B Treble"},
666     {3206, "Equalizer B Mid Hz"},
667     {3207, "Equalizer B Presence"},
668     {3211, "Equalizer B Treb Hz"},
669     {3212, "Equalizer B On/Off"},
670     {0, NULL}
671 };
672
673 static const value_string digitech_parameter_ids_amp_loop[] = {
674     {3649, "Amp Loop On/Off"},
675     {0, NULL}
676 };
677
678 #define DIGITECH_POSITION_GLOBAL 0
679 #define DIGITECH_POSITION_PICKUP 2
680 #define DIGITECH_POSITION_WAH 3
681 #define DIGITECH_POSITION_COMPRESSOR 4
682 #define DIGITECH_POSITION_GNX3K_WHAMMY 5
683 #define DIGITECH_POSITION_DISTORTION 6
684 #define DIGITECH_POSITION_AMP_CHANNEL 7
685 #define DIGITECH_POSITION_AMP 8
686 #define DIGITECH_POSITION_AMP_CABINET 9
687 #define DIGITECH_POSITION_AMP_B 10
688 #define DIGITECH_POSITION_AMP_CABINET_B 11
689 #define DIGITECH_POSITION_NOISEGATE 12
690 #define DIGITECH_POSITION_VOLUME_PRE_FX 13
691 #define DIGITECH_POSITION_CHORUS_FX 14
692 #define DIGITECH_POSITION_DELAY 15
693 #define DIGITECH_POSITION_REVERB 16
694 #define DIGITECH_POSITION_VOLUME_POST_FX 17
695 #define DIGITECH_POSITION_PRESET 18
696 #define DIGITECH_POSITION_EXPRESSION 19
697 #define DIGITECH_POSITION_WAH_MIN_MAX 20
698 #define DIGITECH_POSITION_V_SWITCH_ASSIGN 21
699 #define DIGITECH_POSITION_LFO_1 22
700 #define DIGITECH_POSITION_LFO_2 23
701 #define DIGITECH_POSITION_EQUALIZER 24
702 #define DIGITECH_POSITION_EQUALIZER_B 25
703 #define DIGITECH_POSITION_LIBRARY 26
704 #define DIGITECH_POSITION_AMP_LOOP 33
705 #define DIGITECH_POSITION_WAH_PEDAL 132
706
707 static const value_string digitech_parameter_positions[] = {
708     {DIGITECH_POSITION_GLOBAL,          "Global"},
709     {DIGITECH_POSITION_PICKUP,          "Pickup"},
710     {DIGITECH_POSITION_WAH,             "Wah"},
711     {DIGITECH_POSITION_COMPRESSOR,      "Compressor"},
712     {DIGITECH_POSITION_GNX3K_WHAMMY,    "GNX3K Whammy"},
713     {DIGITECH_POSITION_DISTORTION,      "Distortion"},
714     {DIGITECH_POSITION_AMP_CHANNEL,     "Amp Channel"},
715     {DIGITECH_POSITION_AMP,             "Amp"},
716     {DIGITECH_POSITION_AMP_CABINET,     "Amp Cabinet"},
717     {DIGITECH_POSITION_AMP_B,           "Amp B"},
718     {DIGITECH_POSITION_AMP_CABINET_B,   "Amp Cabinet B"},
719     {DIGITECH_POSITION_NOISEGATE,       "Noisegate"},
720     {DIGITECH_POSITION_VOLUME_PRE_FX,   "Volume Pre Fx"},
721     {DIGITECH_POSITION_CHORUS_FX,       "Chorus/FX"},
722     {DIGITECH_POSITION_DELAY,           "Delay"},
723     {DIGITECH_POSITION_REVERB,          "Reverb"},
724     {DIGITECH_POSITION_VOLUME_POST_FX,  "Volume Post Fx"},
725     {DIGITECH_POSITION_PRESET,          "Preset"},
726     {DIGITECH_POSITION_EXPRESSION,      "Expression"},
727     {DIGITECH_POSITION_WAH_MIN_MAX,     "Wah Min-Max"},
728     {DIGITECH_POSITION_V_SWITCH_ASSIGN, "V-Switch Assign"},
729     {DIGITECH_POSITION_LFO_1,           "LFO 1"},
730     {DIGITECH_POSITION_LFO_2,           "LFO 2"},
731     {DIGITECH_POSITION_EQUALIZER,       "Equalizer"},
732     {DIGITECH_POSITION_EQUALIZER_B,     "Equalizer B"},
733     {DIGITECH_POSITION_LIBRARY,         "Library"},
734     {DIGITECH_POSITION_AMP_LOOP,        "Amp Loop"},
735     {DIGITECH_POSITION_WAH_PEDAL,       "Wah Pedal"},
736     {0, NULL}
737 };
738 static value_string_ext digitech_parameter_positions_ext =
739     VALUE_STRING_EXT_INIT(digitech_parameter_positions);
740
741 static tvbuff_t *
742 unpack_digitech_message(tvbuff_t *tvb, gint offset)
743 {
744     tvbuff_t *next_tvb;
745     gint length = tvb_length(tvb);
746     gint data_len = length - offset - 2;
747     const guint8* data_ptr;
748     gint remaining = data_len;
749     guchar* unpacked;
750     guchar* unpacked_ptr;
751     gint unpacked_size;
752     guint8 msb;
753     gint i;
754
755     unpacked_size = data_len - (data_len / 8);
756     if (data_len % 8)
757     {
758         unpacked_size--;
759     }
760
761     data_ptr = tvb_get_ptr(tvb, offset, data_len);
762     unpacked = (guchar*)g_malloc(unpacked_size);
763     unpacked_ptr = unpacked;
764
765     while (remaining > 0)
766     {
767         msb = *data_ptr++;
768         remaining--;
769
770         for (i = 0; (i < 7) && (remaining > 0); ++i, --remaining)
771         {
772             *unpacked_ptr = *data_ptr | ((msb << (i + 1)) & 0x80);
773             unpacked_ptr++;
774             data_ptr++;
775         }
776     }
777
778     /* Create new tvb with unpacked data */
779     next_tvb = tvb_new_child_real_data(tvb, unpacked, unpacked_size, unpacked_size);
780     tvb_set_free_cb(next_tvb, g_free);
781
782     return next_tvb;
783 }
784
785 static int
786 get_digitech_hf_parameter_id_by_position(guint8 position)
787 {
788     int hf_parameter = hf_digitech_parameter_id;
789
790     switch (position)
791     {
792         case DIGITECH_POSITION_GLOBAL:
793             hf_parameter = hf_digitech_parameter_id_global;
794             break;
795         case DIGITECH_POSITION_PICKUP:
796             hf_parameter = hf_digitech_parameter_id_pickup;
797             break;
798         case DIGITECH_POSITION_WAH:
799             hf_parameter = hf_digitech_parameter_id_wah;
800             break;
801         case DIGITECH_POSITION_COMPRESSOR:
802             hf_parameter = hf_digitech_parameter_id_compressor;
803             break;
804         case DIGITECH_POSITION_GNX3K_WHAMMY:
805             hf_parameter = hf_digitech_parameter_id_gnx3k_whammy;
806             break;
807         case DIGITECH_POSITION_DISTORTION:
808             hf_parameter = hf_digitech_parameter_id_distortion;
809             break;
810         case DIGITECH_POSITION_AMP_CHANNEL:
811             hf_parameter = hf_digitech_parameter_id_amp_channel;
812             break;
813         case DIGITECH_POSITION_AMP:
814             hf_parameter = hf_digitech_parameter_id_amp;
815             break;
816         case DIGITECH_POSITION_AMP_CABINET:
817             hf_parameter = hf_digitech_parameter_id_amp_cabinet;
818             break;
819         case DIGITECH_POSITION_AMP_B:
820             hf_parameter = hf_digitech_parameter_id_amp_b;
821             break;
822         case DIGITECH_POSITION_AMP_CABINET_B:
823             hf_parameter = hf_digitech_parameter_id_amp_cabinet_b;
824             break;
825         case DIGITECH_POSITION_NOISEGATE:
826             hf_parameter = hf_digitech_parameter_id_noisegate;
827             break;
828         case DIGITECH_POSITION_VOLUME_PRE_FX:
829             hf_parameter = hf_digitech_parameter_id_volume_pre_fx;
830             break;
831         case DIGITECH_POSITION_CHORUS_FX:
832             hf_parameter = hf_digitech_parameter_id_chorusfx;
833             break;
834         case DIGITECH_POSITION_DELAY:
835             hf_parameter = hf_digitech_parameter_id_delay;
836             break;
837         case DIGITECH_POSITION_REVERB:
838             hf_parameter = hf_digitech_parameter_id_reverb;
839             break;
840         case DIGITECH_POSITION_VOLUME_POST_FX:
841             hf_parameter = hf_digitech_parameter_id_volume_post_fx;
842             break;
843         case DIGITECH_POSITION_PRESET:
844             hf_parameter = hf_digitech_parameter_id_preset;
845             break;
846         case DIGITECH_POSITION_WAH_MIN_MAX:
847             hf_parameter = hf_digitech_parameter_id_wah_min_max;
848             break;
849         case DIGITECH_POSITION_EQUALIZER:
850             hf_parameter = hf_digitech_parameter_id_equalizer;
851             break;
852         case DIGITECH_POSITION_EQUALIZER_B:
853             hf_parameter = hf_digitech_parameter_id_equalizer_b;
854             break;
855         case DIGITECH_POSITION_AMP_LOOP:
856             hf_parameter = hf_digitech_parameter_id_amp_loop;
857             break;
858
859         case DIGITECH_POSITION_EXPRESSION:
860         case DIGITECH_POSITION_V_SWITCH_ASSIGN:
861         case DIGITECH_POSITION_LFO_1:
862         case DIGITECH_POSITION_LFO_2:
863         case DIGITECH_POSITION_LIBRARY:
864         case DIGITECH_POSITION_WAH_PEDAL:
865             /* TODO */
866         default:
867             break;
868     }
869
870     return hf_parameter;
871 }
872
873 /* Dissects DigiTech parameter starting at data_offset.
874  * Returns new data_offset.
875  */
876 static gint
877 dissect_digitech_parameter(tvbuff_t *data_tvb, proto_tree *tree,
878                            digitech_conv_data_t *conv_data, gint data_offset)
879 {
880     guint8 digitech_helper;
881     int hf_parameter = hf_digitech_parameter_id;
882
883     /* Version 1 and later specify parameter position */
884     if (conv_data->protocol_version >= 1)
885     {
886         digitech_helper = tvb_get_guint8(data_tvb, data_offset+2);
887         hf_parameter = get_digitech_hf_parameter_id_by_position(digitech_helper);
888     }
889
890     proto_tree_add_item(tree, hf_parameter, data_tvb, data_offset, 2, ENC_BIG_ENDIAN);
891     data_offset += 2;
892
893     /* Add (optional) position to tree */
894     if (conv_data->protocol_version >= 1)
895     {
896         proto_tree_add_item(tree, hf_digitech_parameter_position, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
897         data_offset++;
898     }
899
900     digitech_helper = tvb_get_guint8(data_tvb, data_offset);
901     /* Values 0-127 fit in one byte */
902     if (digitech_helper < 0x80)
903     {
904         proto_tree_add_item(tree, hf_digitech_parameter_data, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
905         data_offset++;
906     }
907     else /* digitech_helper >= 0x80 */
908     {
909         guint16 data_count;
910
911         /* Single byte data count */
912         if (digitech_helper > 0x80)
913         {
914             data_count = (guint16)(digitech_helper & ~0x80);
915             proto_tree_add_uint(tree, hf_digitech_parameter_data_count, data_tvb,
916                                 data_offset, 1, (guint32)data_count);
917             data_offset++;
918         }
919         /* Two-byte data count */
920         else /* digitech_helper == 0x80 */
921         {
922             data_count = (guint16)tvb_get_ntohs(data_tvb, data_offset+1);
923             proto_tree_add_uint(tree, hf_digitech_parameter_data_two_byte_count, data_tvb,
924                                 data_offset, 3, (guint32)data_count);
925             data_offset += 3;
926         }
927
928         proto_tree_add_item(tree, hf_digitech_parameter_multibyte_data, data_tvb,
929                             data_offset, (gint)data_count, ENC_NA);
930         data_offset += data_count;
931     }
932
933     return data_offset;
934 }
935
936 static int
937 get_digitech_hf_product_by_family(guint8 family)
938 {
939     int hf_product = hf_digitech_unknown_product_id;
940
941     switch (family)
942     {
943         case DIGITECH_FAMILY_RP:
944             hf_product = hf_digitech_rp_product_id;
945             break;
946         default:
947             break;
948     }
949
950     return hf_product;
951 }
952
953 static void
954 dissect_digitech_procedure(guint8 procedure, const gint offset,
955                            tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
956 {
957     tvbuff_t *data_tvb;
958     gint data_offset;
959     gint data_len;
960     guint8 *tmp_string;
961     guint str_size;
962     guint16 count;
963     guint8 digitech_helper;
964     conversation_t *conversation;
965     digitech_conv_data_t *conv_data;
966
967     conversation = find_or_create_conversation(pinfo);
968     conv_data = (digitech_conv_data_t *)conversation_get_proto_data(conversation, proto_sysex);
969
970     if (conv_data == NULL)
971     {
972         conv_data = wmem_new(wmem_file_scope(), digitech_conv_data_t);
973         conv_data->protocol_version = 1; /* Default to version 1 */
974     }
975
976     /* Procedure data starts at offset and ends two bytes before end
977      * of System Exclusive packet (one byte is checksum, the other one
978      * is EOX)
979      */
980     if (tvb_length(tvb) - offset < 2)
981     {
982         /* There is no DigiTech procedure data, do not attempt further
983          * dissection */
984         return;
985     }
986
987     data_tvb = unpack_digitech_message(tvb, offset);
988     add_new_data_source(pinfo, data_tvb, "Unpacked Procedure Data");
989
990     data_offset = 0;
991     data_len = tvb_length(data_tvb);
992
993     switch (procedure)
994     {
995         case DIGITECH_PROCEDURE_REQUEST_WHO_AM_I:
996             proto_tree_add_item(tree, hf_digitech_desired_device_id, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
997             data_offset++;
998             proto_tree_add_item(tree, hf_digitech_desired_family_id, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
999             data_offset++;
1000             proto_tree_add_item(tree, hf_digitech_desired_product_id, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1001             data_offset++;
1002             break;
1003         case DIGITECH_PROCEDURE_RECEIVE_WHO_AM_I:
1004             proto_tree_add_item(tree, hf_digitech_device_id, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1005             data_offset++;
1006
1007             digitech_helper = tvb_get_guint8(data_tvb, data_offset);
1008             proto_tree_add_item(tree, hf_digitech_family_id, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1009             data_offset++;
1010
1011             proto_tree_add_item(tree, get_digitech_hf_product_by_family(digitech_helper),
1012                                 data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1013             data_offset++;
1014
1015             if (data_len == 3)
1016             {
1017                 /* Version 0, everything already decoded */
1018                 conv_data->protocol_version = 0;
1019             }
1020             else if (data_len == 4)
1021             {
1022                 /* Version 1 and later */
1023                 conv_data->protocol_version = 1;
1024
1025                 proto_tree_add_item(tree, hf_digitech_os_mode, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1026                 data_offset++;
1027             }
1028             break;
1029         case DIGITECH_PROCEDURE_REQUEST_PRESET_NAMES:
1030             proto_tree_add_item(tree, hf_digitech_preset_bank, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1031             data_offset++;
1032
1033             break;
1034         case DIGITECH_PROCEDURE_RECEIVE_PRESET_NAMES:
1035             proto_tree_add_item(tree, hf_digitech_preset_bank, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1036             data_offset++;
1037
1038             count = (guint16)tvb_get_guint8(data_tvb, data_offset);
1039             proto_tree_add_item(tree, hf_digitech_preset_count, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1040             data_offset++;
1041
1042             while ((count > 0) && (str_size = tvb_strsize(data_tvb, data_offset)))
1043             {
1044                 tmp_string = tvb_get_string_enc(wmem_packet_scope(), data_tvb, data_offset, str_size - 1, ENC_ASCII);
1045                 proto_tree_add_string(tree, hf_digitech_preset_name, data_tvb, data_offset, str_size, tmp_string);
1046                 data_offset += (gint)str_size;
1047                 count--;
1048             }
1049             break;
1050         case DIGITECH_PROCEDURE_REQUEST_PRESET:
1051             proto_tree_add_item(tree, hf_digitech_preset_bank, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1052             data_offset++;
1053
1054             proto_tree_add_item(tree, hf_digitech_preset_index, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1055             data_offset++;
1056             break;
1057         case DIGITECH_PROCEDURE_RECEIVE_PRESET_START:
1058             /* Preset bank */
1059             proto_tree_add_item(tree, hf_digitech_preset_bank, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1060             data_offset++;
1061
1062             /* Preset index */
1063             proto_tree_add_item(tree, hf_digitech_preset_index, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1064             data_offset++;
1065
1066             /* Preset name (NULL-terminated) */
1067             str_size = tvb_strsize(data_tvb, data_offset);
1068             tmp_string = tvb_get_string_enc(wmem_packet_scope(), data_tvb, data_offset, str_size - 1, ENC_ASCII);
1069             proto_tree_add_string(tree, hf_digitech_preset_name, data_tvb, data_offset, str_size, tmp_string);
1070             data_offset += (gint)str_size;
1071
1072             /* Preset modified (0 = unmodified, !0 = modified) */
1073             proto_tree_add_item(tree, hf_digitech_preset_modified, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1074             data_offset++;
1075
1076             /* Message Count */
1077             proto_tree_add_item(tree, hf_digitech_message_count, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1078             data_offset++;
1079             break;
1080         case DIGITECH_PROCEDURE_RECEIVE_PRESET_PARAMETERS:
1081             count = tvb_get_ntohs(data_tvb, data_offset);
1082             proto_tree_add_item(tree, hf_digitech_parameter_count, data_tvb, data_offset, 2, ENC_BIG_ENDIAN);
1083             data_offset += 2;
1084             while (count > 0)
1085             {
1086                 data_offset = dissect_digitech_parameter(data_tvb, tree, conv_data, data_offset);
1087                 count--;
1088             }
1089             break;
1090         case DIGITECH_PROCEDURE_RECEIVE_PARAMETER_VALUE:
1091             data_offset = dissect_digitech_parameter(data_tvb, tree, conv_data, data_offset);
1092             break;
1093         case DIGITECH_PROCEDURE_ACK:
1094             proto_tree_add_item(tree, hf_digitech_ack_request_proc_id, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1095             data_offset++;
1096             break;
1097         case DIGITECH_PROCEDURE_NACK:
1098             proto_tree_add_item(tree, hf_digitech_nack_request_proc_id, data_tvb, data_offset, 1, ENC_BIG_ENDIAN);
1099             data_offset++;
1100             break;
1101         default:
1102             break;
1103     }
1104
1105     if (data_offset < data_len)
1106     {
1107         proto_tree_add_expert(tree, pinfo, &ei_sysex_undecoded,
1108                                   data_tvb, data_offset, data_len - data_offset);
1109     }
1110 }
1111
1112 /* dissector for System Exclusive MIDI data */
1113 static void
1114 dissect_sysex_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
1115 {
1116     guint8 sysex_helper;
1117     gint data_len;
1118     proto_item *item;
1119
1120     col_set_str(pinfo->cinfo, COL_PROTOCOL, "SYSEX");
1121     col_set_str(pinfo->cinfo, COL_INFO, "MIDI System Exclusive Command");
1122
1123     data_len = tvb_length(tvb);
1124
1125     if (parent_tree)
1126     {
1127         proto_item *ti = NULL;
1128         proto_tree *tree = NULL;
1129         gint offset = 0;
1130         guint8 manufacturer_id;
1131         guint32 three_byte_manufacturer_id = 0xFFFFFF;
1132         guint8 procedure_id;
1133
1134         ti = proto_tree_add_protocol_format(parent_tree, proto_sysex, tvb, 0, -1, "MIDI System Exclusive Command");
1135         tree = proto_item_add_subtree(ti, ett_sysex);
1136
1137         /* Check start byte (System Exclusive - 0xF0) */
1138         sysex_helper = tvb_get_guint8(tvb, 0);
1139         item = proto_tree_add_item(tree, hf_sysex_message_start, tvb, offset, 1, ENC_BIG_ENDIAN);
1140         if (sysex_helper != 0xF0)
1141         {
1142             expert_add_info(pinfo, item, &ei_sysex_message_start_byte);
1143         }
1144
1145         offset++;
1146
1147         manufacturer_id = tvb_get_guint8(tvb, offset);
1148         /* Three-byte manufacturer ID starts with 00 */
1149         if (manufacturer_id == 0)
1150         {
1151             three_byte_manufacturer_id = tvb_get_ntoh24(tvb, offset);
1152             proto_tree_add_item(tree, hf_sysex_three_byte_manufacturer_id, tvb, offset, 3, ENC_BIG_ENDIAN);
1153             offset += 3;
1154         }
1155         /* One-byte manufacturer ID */
1156         else
1157         {
1158             proto_tree_add_item(tree, hf_sysex_manufacturer_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1159             offset++;
1160         }
1161
1162         proto_tree_add_item(tree, hf_sysex_device_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1163         offset++;
1164
1165         /* Following data is menufacturer-specific */
1166         switch (three_byte_manufacturer_id)
1167         {
1168             case SYSEX_MANUFACTURER_DOD:
1169             {
1170                 guint8 digitech_helper;
1171                 const guint8 *data_ptr;
1172                 int len;
1173                 int i;
1174
1175                 digitech_helper = tvb_get_guint8(tvb, offset);
1176                 proto_tree_add_item(tree, hf_digitech_family_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1177                 offset++;
1178
1179                 proto_tree_add_item(tree, get_digitech_hf_product_by_family(digitech_helper),
1180                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1181                 offset++;
1182
1183                 procedure_id = tvb_get_guint8(tvb, offset);
1184                 proto_tree_add_item(tree, hf_digitech_procedure_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1185                 offset++;
1186
1187                 dissect_digitech_procedure(procedure_id, offset, tvb, pinfo, tree);
1188
1189                 len = tvb_length(tvb) - 2;
1190                 offset = len; /* Penultimate byte is checksum */
1191                 data_ptr = tvb_get_ptr(tvb, 1, len);
1192                 /* Calculate checksum */
1193                 for (i = 0, digitech_helper = 0; i < len; ++i)
1194                 {
1195                     digitech_helper ^= *data_ptr++;
1196                 }
1197
1198                 item = proto_tree_add_item(tree, hf_digitech_checksum, tvb, offset, 1, ENC_BIG_ENDIAN);
1199                 if (digitech_helper == 0)
1200                 {
1201                     proto_item_append_text(item, " (correct)");
1202                 }
1203                 else
1204                 {
1205                     proto_item_append_text(item, " (NOT correct)");
1206                     expert_add_info(pinfo, item, &ei_digitech_checksum_bad);
1207                 }
1208                 offset++;
1209                 break;
1210             }
1211             default:
1212                 break;
1213         }
1214
1215         if (offset < data_len - 1)
1216         {
1217             proto_tree_add_expert(tree, pinfo, &ei_sysex_undecoded,
1218                                       tvb, offset, data_len - offset - 1);
1219         }
1220
1221         /* Check end byte (EOX - 0xF7) */
1222         sysex_helper = tvb_get_guint8(tvb, data_len - 1);
1223         item = proto_tree_add_item(tree, hf_sysex_message_eox, tvb, data_len - 1, 1, ENC_BIG_ENDIAN);
1224         if (sysex_helper != 0xF7)
1225         {
1226             expert_add_info(pinfo, item, &ei_sysex_message_end_byte);
1227         }
1228     }
1229 }
1230
1231 void
1232 proto_register_sysex(void)
1233 {
1234     static hf_register_info hf[] = {
1235         { &hf_sysex_message_start,
1236             { "SysEx message start", "sysex.start", FT_UINT8, BASE_HEX,
1237               NULL, 0, "System Exclusive Message start (0xF0)", HFILL }},
1238         { &hf_sysex_manufacturer_id,
1239             { "Manufacturer ID", "sysex.manufacturer_id", FT_UINT8, BASE_HEX,
1240               NULL, 0, NULL, HFILL }},
1241         { &hf_sysex_three_byte_manufacturer_id,
1242             { "Manufacturer ID", "sysex.manufacturer_id", FT_UINT24, BASE_HEX,
1243               VALS(sysex_three_byte_manufacturer_id), 0, NULL, HFILL }},
1244         { &hf_sysex_device_id,
1245             { "Device ID", "sysex.device_id", FT_UINT8, BASE_HEX,
1246               NULL, 0, NULL, HFILL }},
1247         { &hf_sysex_message_eox,
1248             { "EOX", "sysex.eox", FT_UINT8, BASE_HEX,
1249               NULL, 0, "System Exclusive Message end (0xF7)", HFILL}},
1250
1251         /* DigiTech manufacturer-specific fields */
1252         { &hf_digitech_family_id,
1253             { "Family ID", "sysex.digitech.family_id", FT_UINT8, BASE_HEX,
1254               VALS(digitech_family_id), 0, NULL, HFILL }},
1255         { &hf_digitech_unknown_product_id,
1256             { "Product ID", "sysex.digitech.product_id", FT_UINT8, BASE_HEX,
1257               NULL, 0, NULL, HFILL }},
1258         { &hf_digitech_rp_product_id,
1259             { "Product ID", "sysex.digitech.product_id", FT_UINT8, BASE_HEX,
1260               VALS(digitech_rp_product_id), 0, NULL, HFILL }},
1261         { &hf_digitech_procedure_id,
1262             { "Procedure ID", "sysex.digitech.procedure_id", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
1263               &digitech_procedures_ext, 0, NULL, HFILL }},
1264
1265         { &hf_digitech_desired_device_id,
1266             { "Desired Device ID", "sysex.digitech.desired_device_id", FT_UINT8, BASE_HEX,
1267               NULL, 0, NULL, HFILL }},
1268         { &hf_digitech_desired_family_id,
1269             { "Desired Family ID", "sysex.digitech.desired_family_id", FT_UINT8, BASE_HEX,
1270               NULL, 0, NULL, HFILL }},
1271         { &hf_digitech_desired_product_id,
1272             { "Desired Product ID", "sysex.digitech.desired_product_id", FT_UINT8, BASE_HEX,
1273               NULL, 0, NULL, HFILL }},
1274         { &hf_digitech_device_id,
1275             { "Device ID", "sysex.digitech.device_id", FT_UINT8, BASE_HEX,
1276               NULL, 0, NULL, HFILL }},
1277         { &hf_digitech_os_mode,
1278             { "OS Mode", "sysex.digitech.os_mode", FT_UINT8, BASE_HEX,
1279               VALS(digitech_os_modes), 0, "DigiTech OS Mode", HFILL }},
1280
1281         { &hf_digitech_preset_bank,
1282             { "Preset Bank", "sysex.digitech.preset_bank", FT_UINT8, BASE_HEX,
1283               VALS(digitech_preset_banks), 0, NULL, HFILL }},
1284         { &hf_digitech_preset_index,
1285             { "Preset Index", "sysex.digitech.preset_index", FT_UINT8, BASE_HEX,
1286               NULL, 0, NULL, HFILL }},
1287         { &hf_digitech_preset_count,
1288             { "Preset Count", "sysex.digitech.preset_count", FT_UINT8, BASE_DEC,
1289               NULL, 0, NULL, HFILL }},
1290         { &hf_digitech_preset_name,
1291             { "Preset Name", "sysex.digitech.preset_name", FT_STRING, BASE_NONE,
1292               NULL, 0, NULL, HFILL }},
1293         { &hf_digitech_preset_modified,
1294             { "Preset Modified", "sysex.digitech.preset_modified", FT_BOOLEAN, BASE_NONE,
1295               TFS(&tfs_yes_no), 0, "Modified flag (0 = unmodified)", HFILL }},
1296
1297         { &hf_digitech_message_count,
1298             { "Messages to follow", "sysex.digitech.message_count", FT_UINT8, BASE_DEC,
1299               NULL, 0, "Number of messages to follow", HFILL }},
1300
1301         { &hf_digitech_parameter_count,
1302             { "Parameter Count", "sysex.digitech.parameter_count", FT_UINT16, BASE_DEC,
1303               NULL, 0, NULL, HFILL }},
1304
1305         { &hf_digitech_parameter_id,
1306             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1307               NULL, 0, NULL, HFILL }},
1308         { &hf_digitech_parameter_id_global,
1309             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1310               VALS(digitech_parameter_ids_global), 0, NULL, HFILL }},
1311         { &hf_digitech_parameter_id_pickup,
1312             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1313               VALS(digitech_parameter_ids_pickup), 0, NULL, HFILL }},
1314         { &hf_digitech_parameter_id_wah,
1315             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1316               VALS(digitech_parameter_ids_wah), 0, NULL, HFILL }},
1317         { &hf_digitech_parameter_id_compressor,
1318             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1319               VALS(digitech_parameter_ids_compressor), 0, NULL, HFILL }},
1320         { &hf_digitech_parameter_id_gnx3k_whammy,
1321             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
1322               &digitech_parameter_ids_gnx3k_whammy_ext, 0, NULL, HFILL }},
1323         { &hf_digitech_parameter_id_distortion,
1324             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
1325               &digitech_parameter_ids_distortion_ext, 0, NULL, HFILL }},
1326         { &hf_digitech_parameter_id_amp_channel,
1327             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1328               VALS(digitech_parameter_ids_amp_channel), 0, NULL, HFILL }},
1329         { &hf_digitech_parameter_id_amp,
1330             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
1331               &digitech_parameter_ids_amp_ext, 0, NULL, HFILL }},
1332         { &hf_digitech_parameter_id_amp_cabinet,
1333             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1334               VALS(digitech_parameter_ids_amp_cabinet), 0, NULL, HFILL }},
1335         { &hf_digitech_parameter_id_amp_b,
1336             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1337               VALS(digitech_parameter_ids_amp_b), 0, NULL, HFILL }},
1338         { &hf_digitech_parameter_id_amp_cabinet_b,
1339             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1340               VALS(digitech_parameter_ids_amp_cabinet_b), 0, NULL, HFILL }},
1341         { &hf_digitech_parameter_id_noisegate,
1342             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1343               VALS(digitech_parameter_ids_noisegate), 0, NULL, HFILL }},
1344         { &hf_digitech_parameter_id_volume_pre_fx,
1345             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1346               VALS(digitech_parameter_ids_volume_pre_fx), 0, NULL, HFILL }},
1347         { &hf_digitech_parameter_id_chorusfx,
1348             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
1349               &digitech_parameter_ids_chorusfx_ext, 0, NULL, HFILL }},
1350         { &hf_digitech_parameter_id_delay,
1351             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
1352               &digitech_parameter_ids_delay_ext, 0, NULL, HFILL }},
1353         { &hf_digitech_parameter_id_reverb,
1354             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1355               VALS(digitech_parameter_ids_reverb), 0, NULL, HFILL }},
1356         { &hf_digitech_parameter_id_volume_post_fx,
1357             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1358               VALS(digitech_parameter_ids_volume_post_fx), 0, NULL, HFILL }},
1359         { &hf_digitech_parameter_id_preset,
1360             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1361               VALS(digitech_parameter_ids_preset), 0, NULL, HFILL }},
1362         { &hf_digitech_parameter_id_wah_min_max,
1363             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1364               VALS(digitech_parameter_ids_wah_min_max), 0, NULL, HFILL }},
1365         { &hf_digitech_parameter_id_equalizer,
1366             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1367               VALS(digitech_parameter_ids_equalizer), 0, NULL, HFILL }},
1368         { &hf_digitech_parameter_id_equalizer_b,
1369             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1370               VALS(digitech_parameter_ids_equalizer_b), 0, NULL, HFILL }},
1371         { &hf_digitech_parameter_id_amp_loop,
1372             { "Parameter ID", "sysex.digitech.parameter_id", FT_UINT16, BASE_DEC,
1373               VALS(digitech_parameter_ids_amp_loop), 0, NULL, HFILL }},
1374
1375
1376         { &hf_digitech_parameter_position,
1377             { "Parameter position", "sysex.digitech.parameter_position", FT_UINT8, BASE_DEC | BASE_EXT_STRING,
1378               &digitech_parameter_positions_ext, 0, NULL, HFILL }},
1379         { &hf_digitech_parameter_data,
1380             { "Parameter data", "sysex.digitech.parameter_data", FT_UINT8, BASE_DEC,
1381               NULL, 0, NULL, HFILL }},
1382         { &hf_digitech_parameter_data_count,
1383             { "Parameter value count", "sysex.digitech.parameter_data_count", FT_UINT8, BASE_DEC,
1384               NULL, 0, NULL, HFILL }},
1385         { &hf_digitech_parameter_data_two_byte_count,
1386             { "Parameter data count", "sysex.digitech.parameter_data_count", FT_UINT24, BASE_DEC,
1387               NULL, 0, NULL, HFILL }},
1388         { &hf_digitech_parameter_multibyte_data,
1389             { "Parameter data", "sysex.digitech.parameter_data", FT_BYTES, BASE_NONE,
1390               NULL, 0, NULL, HFILL }},
1391
1392         { &hf_digitech_ack_request_proc_id,
1393             { "Requesting Procedure ID", "sysex.digitech.ack.procedure_id", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
1394               &digitech_procedures_ext, 0, "Procedure ID of the request being ACKed", HFILL }},
1395         { &hf_digitech_nack_request_proc_id,
1396             { "Requesting Procedure ID", "sysex.digitech.ack.procedure_id", FT_UINT8, BASE_HEX | BASE_EXT_STRING,
1397               &digitech_procedures_ext, 0, "Procedure ID of the request being NACKed", HFILL }},
1398
1399         { &hf_digitech_checksum,
1400             { "Checksum", "sysex.digitech.checksum", FT_UINT8, BASE_HEX,
1401               NULL, 0, NULL, HFILL }},
1402     };
1403
1404     static gint *sysex_subtrees[] = {
1405         &ett_sysex
1406     };
1407
1408     static ei_register_info ei[] = {
1409         { &ei_sysex_message_start_byte, { "sysex.message_start_byte", PI_PROTOCOL, PI_WARN, "SYSEX Error: Wrong start byte", EXPFILL }},
1410         { &ei_digitech_checksum_bad, { "sysex.digitech.checksum_bad", PI_CHECKSUM, PI_WARN, "ARP packet storm detected", EXPFILL }},
1411         { &ei_sysex_message_end_byte, { "sysex.message_end_byte", PI_PROTOCOL, PI_WARN, "SYSEX Error: Wrong end byte", EXPFILL }},
1412         { &ei_sysex_undecoded, { "sysex.undecoded", PI_UNDECODED, PI_WARN, "Not dissected yet (report to wireshark.org)", EXPFILL }},
1413     };
1414
1415     expert_module_t* expert_sysex;
1416
1417     proto_sysex = proto_register_protocol("MIDI System Exclusive", "SYSEX", "sysex");
1418     proto_register_field_array(proto_sysex, hf, array_length(hf));
1419     proto_register_subtree_array(sysex_subtrees, array_length(sysex_subtrees));
1420     expert_sysex = expert_register_protocol(proto_sysex);
1421     expert_register_field_array(expert_sysex, ei, array_length(ei));
1422
1423     register_dissector("sysex", dissect_sysex_command, proto_sysex);
1424 }
1425
1426 void
1427 proto_reg_handoff_sysex(void)
1428 {
1429 }
1430
1431 /*
1432  * Editor modelines
1433  *
1434  * Local Variables:
1435  * c-basic-offset: 4
1436  * tab-width: 8
1437  * indent-tabs-mode: nil
1438  * End:
1439  *
1440  * ex: set shiftwidth=4 tabstop=8 expandtab:
1441  * :indentSize=4:tabSize=8:noTabs=true:
1442  */