Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-navitrol.c
Line
Count
Source
1
/* packet-navitrol.c
2
 * Routines for Navitec Systems Navitrol device
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 */
10
11
#include "config.h"
12
13
#include <epan/packet.h>
14
#include <epan/expert.h>
15
#include <epan/unit_strings.h>
16
#include <epan/dissectors/packet-tcp.h>
17
#include <stdlib.h>
18
19
void proto_register_navitrol(void);
20
void proto_reg_handoff_navitrol(void);
21
22
static int proto_navitrol;
23
24
static int hf_navitrol_protocol_version;
25
static int hf_navitrol_message_id;
26
static int hf_navitrol_message_length;
27
static int hf_navitrol_measurement_mode;
28
static int hf_navitrol_ip_address;
29
static int hf_navitrol_port_front;
30
static int hf_navitrol_port_rear;
31
static int hf_navitrol_raw_data_status;
32
static int hf_navitrol_position_x;
33
static int hf_navitrol_position_y;
34
static int hf_navitrol_position_x_double;
35
static int hf_navitrol_position_y_double;
36
static int hf_navitrol_position_heading;
37
static int hf_navitrol_floor;
38
static int hf_navitrol_teaching_command;
39
static int hf_navitrol_error_code;
40
static int hf_navitrol_error_count;
41
static int hf_navitrol_message_number;
42
static int hf_navitrol_cum_s_long;
43
static int hf_navitrol_cum_s_trans;
44
static int hf_navitrol_raw_heading;
45
static int hf_navitrol_timestamp;
46
static int hf_navitrol_position_initialize_status;
47
static int hf_navitrol_position_confidence;
48
static int hf_navitrol_error_description;
49
static int hf_navitrol_saved_log_number;
50
static int hf_navitrol_software_version;
51
static int hf_navitrol_comm_version;
52
static int hf_navitrol_time_set_status;
53
static int hf_navitrol_position_correction_status;
54
static int hf_navitrol_set_time;
55
static int hf_navitrol_vel_long;
56
static int hf_navitrol_vel_trans;
57
static int hf_navitrol_vel_angular;
58
static int hf_navitrol_cum_s_left;
59
static int hf_navitrol_cum_s_right;
60
static int hf_navitrol_driving_enabled;
61
static int hf_navitrol_read_status;
62
static int hf_navitrol_speed_left;
63
static int hf_navitrol_speed_right;
64
static int hf_navitrol_errors_stopping_driving;
65
static int hf_navitrol_start_stop_mode;
66
static int hf_navitrol_clear_log;
67
static int hf_navitrol_log_save_length;
68
static int hf_navitrol_raw_ds;
69
static int hf_navitrol_raw_dh;
70
static int hf_navitrol_position_confidence_float;
71
static int hf_navitrol_floor_changed_status;
72
73
74
static int ett_navitrol;
75
76
static expert_field ei_navitrol_message_id;
77
78
/* Preference for endianness */
79
static int navitrol_endian = ENC_LITTLE_ENDIAN;
80
81
static const enum_val_t navitrol_endian_vals[] = {
82
  { "little_endian", "Little Endian", ENC_LITTLE_ENDIAN},
83
  { "big_endian",  "Big Endian", ENC_BIG_ENDIAN },
84
  { NULL, NULL, 0 }
85
};
86
87
enum navitrol_message_types
88
{
89
  //requests
90
  nav_InitializePosition_v1 = 1,
91
  nav_GetPositionCorrection = 2,
92
  nav_ChangeFloor = 3,
93
  nav_ToggleTeaching_v1 = 4,
94
  nav_ErrorDescriptionRes_v1 = 5,
95
  nav_ErrorDescriptionListReq_v1 = 6,
96
  nav_StartStopClearSaveLog = 7,
97
  nav_ReadEnvironmentFile_v1 = 8,
98
  nav_StartSendRawData = 9,
99
  nav_StopSendRawData = 10,
100
  nav_GetVersion_v1 = 11,
101
  nav_RebootNavitrol_v1 = 12,
102
  nav_SetTime_v1 = 13,
103
  nav_GetPositionCorrectionOdometry = 14,
104
  nav_InitializePosition = 1001,
105
  nav_ToggleTeaching = 1004,
106
  nav_ErrorDescriptionReq = 1005,
107
  nav_ErrorDescriptionListReq = 1006,
108
  nav_SaveLog = 1007,
109
  nav_ReadEnvironmentFile = 1008,
110
  nav_GetVersion = 1011,
111
  nav_RebootNavitrol = 1012,
112
  nav_SetTime = 1013,
113
  nav_PositionCorrectionCumulative = 1014,
114
  nav_PositionCorrectionVelocity = 1015,
115
  nav_OdometerUpdateDifferentialVehicle = 1016,
116
117
  //responses
118
  nav_PositionInitialized_v1 = 101,
119
  nav_PositionCorrection_v1_deprecated = 102,
120
  nav_FloorChanged = 103,
121
  nav_TeachingToggled_v1 = 104,
122
  nav_SendRawDataStarted = 109,
123
  nav_SendRawDataStopped = 110,
124
  nav_PositionCorrection_v1 = 114,
125
  nav_PositionInitialized = 1101,
126
  nav_TeachingToggled = 1104,
127
  nav_ErrorDescriptionRes = 1105,
128
  nav_ErrorDescriptionListRes = 1106,
129
  nav_LogSaved = 1107,
130
  nav_EnvironmentFileRead = 1108,
131
  nav_Version = 1111,
132
  nav_RebootedNavitrol = 1112,
133
  nav_TimeSet = 1113,
134
  nav_PositionCorrection = 1114,
135
  nav_MotorControlDifferentialVehicle = 1116,
136
  nav_Error = 201,
137
};
138
139
static const value_string message_id_vals[] = {
140
  { nav_InitializePosition_v1,  "Initialize position" },
141
  { nav_GetPositionCorrection,  "Get position correction" },
142
  { nav_ChangeFloor,  "Change floor" },
143
  { nav_ToggleTeaching_v1,  "Start/Stop teaching" },
144
  { nav_ErrorDescriptionRes_v1, "Request error description" },
145
  { nav_ErrorDescriptionListReq_v1, "Error description list" },
146
  { nav_StartStopClearSaveLog, "Start/Stop/Clear/Save log" },
147
  { nav_StartSendRawData, "Start sending scanner measurements" },
148
  { nav_StopSendRawData,  "Stop sending scanner measurements" },
149
  { nav_GetVersion_v1,  "Request versions" },
150
  { nav_RebootNavitrol_v1,  "Reboot Navitrol" },
151
  { nav_SetTime_v1, "Set time" },
152
  { nav_GetPositionCorrectionOdometry,  "Get position correction including raw odometry" },
153
  { nav_PositionInitialized_v1, "Initialize position" },
154
  { nav_PositionCorrection_v1_deprecated, "Position correction" },
155
  { nav_FloorChanged, "Floor changed" },
156
  { nav_TeachingToggled_v1, "Teaching started/stopped" },
157
  { nav_SendRawDataStarted, "Scanner measurements started" },
158
  { nav_SendRawDataStopped, "Scanner measurements stopped" },
159
  { nav_PositionCorrection_v1,  "Position correction" },
160
  { nav_Error,  "Error message" },
161
  { nav_InitializePosition, "Initialize position" },
162
  { nav_ToggleTeaching, "Teaching" },
163
  { nav_ErrorDescriptionReq,  "Request error description" },
164
  { nav_ErrorDescriptionListReq,  "Request error description list" },
165
  { nav_SaveLog,  "Save log" },
166
  { nav_ReadEnvironmentFile,  "Read environment file" },
167
  { nav_GetVersion, "Request versions" },
168
  { nav_RebootNavitrol, "Reboot Navitrol" },
169
  { nav_SetTime,  "Set time" },
170
  { nav_PositionCorrectionCumulative, "Get position correction - cumulative" },
171
  { nav_PositionCorrectionVelocity, "Get position correction - velocity" },
172
  { nav_OdometerUpdateDifferentialVehicle, "Odometer update differential vehicle (Navitrol controls the vehicle)" },
173
  { nav_PositionInitialized,  "Position initialized" },
174
  { nav_TeachingToggled,  "Teaching toggled" },
175
  { nav_ErrorDescriptionRes,  "Error description" },
176
  { nav_ErrorDescriptionListRes, "Error description list" },
177
  { nav_LogSaved, "Log saved" },
178
  { nav_EnvironmentFileRead,  "Environment file read" },
179
  { nav_Version,  "Version Info" },
180
  { nav_RebootedNavitrol, "Navitrol rebooted" },
181
  { nav_TimeSet,  "Time set" },
182
  { nav_PositionCorrection, "Position correction" },
183
  { nav_MotorControlDifferentialVehicle,  "Motor control differential vehicle" },
184
185
  { 0,    NULL }
186
};
187
188
static const value_string mesasurement_mode_vals[] = {
189
  { 0, "Off" },
190
  { 1, "Both scanners" },
191
  { 2, "Front scanner" },
192
  { 3, "Rear scanner" },
193
  { 0, NULL }
194
};
195
196
static const value_string status_vals[] = {
197
  { 0, "Failed" },
198
  { 1, "Succeeded" },
199
  { 0, NULL }
200
};
201
202
static const value_string position_correction_status_vals[] = {
203
  { 0, "Failed" },
204
  { 1, "Succeeded" },
205
  { 2, "Teaching" },
206
  { 0, NULL }
207
};
208
209
static const value_string teaching_vals[] = {
210
  { 0, "Invalid" },
211
  { 1, "Start teaching" },
212
  { 2, "Stop teaching" },
213
  { 0, NULL }
214
};
215
216
static const value_string driving_status_vals[] = {
217
  { 0, "Invalid" },
218
  { 1, "Enabled" },
219
  { 2, "Disabled error active" },
220
  { 3, "Disabled manual mode" },
221
  { 4, "Disabled ESTOP" },
222
  { 0, NULL }
223
};
224
225
static const value_string error_driving_vals[] = {
226
  { 0, "No Errors" },
227
  { 1, "Error stopping driving" },
228
  { 0, NULL }
229
};
230
231
static const value_string start_stop_log_mode_vals[] = {
232
  { 0, "Stop logging" },
233
  { 1, "Start/continue logging" },
234
  { 0, NULL }
235
};
236
237
static const value_string clear_log_vals[] = {
238
  { 0, "Do Nothing" },
239
  { 1, "Clear log" },
240
  { 0, NULL }
241
};
242
243
static unsigned
244
get_navitrol_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
245
0
{
246
0
  uint16_t len;
247
248
  /* Get the length of the data from the header. */
249
0
  len = tvb_get_uint32(tvb, offset + 4, navitrol_endian);
250
251
0
  return len;
252
0
}
253
254
static int
255
dissect_navitrol_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
256
0
{
257
0
  proto_tree      *navitrol_tree;
258
0
  proto_item      *ti, *message_item;
259
0
  int       offset = 0;
260
0
  uint32_t      i, message_id, error_count;
261
262
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "navitrol");
263
0
  col_clear(pinfo->cinfo, COL_INFO);
264
265
0
  ti = proto_tree_add_item(tree, proto_navitrol, tvb, 0, -1, ENC_NA);
266
0
  navitrol_tree = proto_item_add_subtree(ti, ett_navitrol);
267
268
0
  message_id = tvb_get_uint32(tvb, offset, navitrol_endian);
269
0
  if (message_id & 0xFFFF0000)
270
0
  {
271
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_protocol_version, tvb, offset, 2, navitrol_endian);
272
0
    offset += 2;
273
0
    message_item = proto_tree_add_item(navitrol_tree, hf_navitrol_message_id, tvb, offset, 2, navitrol_endian);
274
0
    offset += 2;
275
0
    message_id = ((message_id >> 16) & 0xFFFF);
276
0
  }
277
0
  else
278
0
  {
279
0
    proto_tree_add_uint(navitrol_tree, hf_navitrol_protocol_version, tvb, offset, 0, 1);
280
0
    message_item = proto_tree_add_item(navitrol_tree, hf_navitrol_message_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
281
0
    offset += 4;
282
0
  }
283
284
0
  col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(message_id, message_id_vals, "Unknown"));
285
286
0
  proto_tree_add_item(navitrol_tree, hf_navitrol_message_length, tvb, offset, 4, navitrol_endian);
287
0
  offset += 4;
288
289
0
  switch (message_id)
290
0
  {
291
0
  case nav_InitializePosition_v1: //Initialize position v1
292
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
293
0
    offset += 8;
294
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
295
0
    offset += 8;
296
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, ENC_LITTLE_ENDIAN);
297
0
    offset += 4;
298
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
299
    /* offset += 4; */
300
0
    break;
301
302
0
  case nav_GetPositionCorrection: //Get position correction v1
303
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_message_number, tvb, offset, 4, ENC_LITTLE_ENDIAN);
304
0
    offset += 4;
305
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
306
0
    offset += 8;
307
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
308
0
    offset += 8;
309
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, ENC_LITTLE_ENDIAN);
310
0
    offset += 4;
311
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
312
    /* offset += 4; */
313
0
    break;
314
315
0
  case nav_GetPositionCorrectionOdometry: //Get position correction with raw odometry v1
316
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_message_number, tvb, offset, 4, ENC_LITTLE_ENDIAN);
317
0
    offset += 4;
318
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
319
0
    offset += 8;
320
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
321
0
    offset += 8;
322
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, ENC_LITTLE_ENDIAN);
323
0
    offset += 4;
324
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
325
0
    offset += 4;
326
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_raw_ds, tvb, offset, 4, ENC_LITTLE_ENDIAN);
327
0
    offset += 4;
328
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_raw_dh, tvb, offset, 4, ENC_LITTLE_ENDIAN);
329
    /* offset += 4; */
330
0
    break;
331
332
0
  case nav_ChangeFloor:   //Change floor v1
333
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
334
    /* offset += 4; */
335
0
    break;
336
337
0
  case nav_FloorChanged:    //Floor changed v1
338
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor_changed_status, tvb, offset, 1, ENC_NA);
339
0
    offset += 1;
340
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
341
    /* offset += 4; */
342
0
    break;
343
344
0
  case nav_StartStopClearSaveLog:
345
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_start_stop_mode, tvb, offset, 1, ENC_NA);
346
0
    offset += 1;
347
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_clear_log, tvb, offset, 1, ENC_NA);
348
0
    offset += 1;
349
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_log_save_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
350
    /* offset += 4; */
351
0
    break;
352
353
0
  case nav_StartSendRawData:  //Start sending scanner measurements v1
354
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_measurement_mode, tvb, offset, 1, ENC_NA);
355
0
    offset += 1;
356
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN);
357
0
    offset += 4;
358
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_port_front, tvb, offset, 4, ENC_LITTLE_ENDIAN);
359
0
    offset += 4;
360
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_port_rear, tvb, offset, 4, ENC_LITTLE_ENDIAN);
361
    /* offset += 4; */
362
0
    break;
363
364
0
  case nav_SendRawDataStarted:  //Scanner measurement sending started v1
365
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_raw_data_status, tvb, offset, 1, ENC_NA);
366
    /* offset += 1; */
367
0
    break;
368
369
0
  case nav_InitializePosition:  //Initialize position v3
370
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x, tvb, offset, 4, navitrol_endian);
371
0
    offset += 4;
372
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y, tvb, offset, 4, navitrol_endian);
373
0
    offset += 4;
374
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, navitrol_endian);
375
0
    offset += 4;
376
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, navitrol_endian);
377
    /* offset += 4; */
378
0
    break;
379
380
0
  case nav_ToggleTeaching_v1: //Start/Stop teaching v1
381
0
  case nav_ToggleTeaching:  //Start/Stop teaching v3
382
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_teaching_command, tvb, offset, 2, navitrol_endian);
383
    /* offset += 2; */
384
0
    break;
385
386
0
  case nav_ErrorDescriptionRes_v1: //Request error description v1
387
0
  case nav_ErrorDescriptionReq: //Request error description v3
388
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_error_code, tvb, offset, 4, navitrol_endian);
389
    /* offset += 4; */
390
0
    break;
391
392
0
  case nav_SetTime_v1:  //Set time v1
393
0
    {
394
0
      int start_offset = offset;
395
0
      struct tm tm_set_time;
396
0
      time_t set_time_seconds;
397
0
      nstime_t ns_set_time;
398
399
0
      tm_set_time.tm_sec = tvb_get_uint8(tvb, offset);
400
0
      offset += 1;
401
0
      tm_set_time.tm_min = tvb_get_uint8(tvb, offset);
402
0
      offset += 1;
403
0
      tm_set_time.tm_hour = tvb_get_uint8(tvb, offset);
404
0
      offset += 1;
405
0
      tm_set_time.tm_mday = tvb_get_uint8(tvb, offset);
406
0
      offset += 1;
407
0
      tm_set_time.tm_mon = tvb_get_uint8(tvb, offset);
408
0
      offset += 1;
409
0
      tm_set_time.tm_year = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN)-1900;
410
0
      tm_set_time.tm_isdst = -1;
411
      /* offset += 4; */
412
413
0
      set_time_seconds = mktime(&tm_set_time);
414
0
      ns_set_time.secs = set_time_seconds;
415
0
      ns_set_time.nsecs = 0;
416
0
      proto_tree_add_time(navitrol_tree, hf_navitrol_set_time, tvb, start_offset,
417
0
        9, &ns_set_time);
418
419
0
    }
420
0
    break;
421
422
0
  case nav_SetTime: //Set time v3
423
0
    {
424
0
      int start_offset = offset;
425
0
      struct tm tm_set_time;
426
0
      time_t set_time_seconds;
427
0
      nstime_t ns_set_time;
428
429
0
      tm_set_time.tm_year = tvb_get_uint32(tvb, offset, navitrol_endian)-1900;
430
0
      offset += 4;
431
0
      tm_set_time.tm_mon = tvb_get_uint16(tvb, offset, navitrol_endian);
432
0
      offset += 2;
433
0
      tm_set_time.tm_mday = tvb_get_uint16(tvb, offset, navitrol_endian);
434
0
      offset += 2;
435
0
      tm_set_time.tm_hour = tvb_get_uint16(tvb, offset, navitrol_endian);
436
0
      offset += 2;
437
0
      tm_set_time.tm_min = tvb_get_uint16(tvb, offset, navitrol_endian);
438
0
      offset += 2;
439
0
      tm_set_time.tm_sec = tvb_get_uint16(tvb, offset, navitrol_endian);
440
      /* offset += 2; */
441
0
      tm_set_time.tm_isdst = -1;
442
443
0
      set_time_seconds = mktime(&tm_set_time);
444
0
      ns_set_time.secs = set_time_seconds;
445
0
      ns_set_time.nsecs = 0;
446
0
      proto_tree_add_time(navitrol_tree, hf_navitrol_set_time, tvb, start_offset,
447
0
        14, &ns_set_time);
448
449
0
    }
450
0
    break;
451
452
0
  case nav_PositionCorrection_v1:
453
0
  case nav_PositionCorrection_v1_deprecated:
454
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_message_number, tvb, offset, 4, ENC_LITTLE_ENDIAN);
455
0
    offset += 4;
456
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_correction_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
457
0
    offset += 1;
458
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
459
0
    offset += 8;
460
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
461
0
    offset += 8;
462
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, ENC_LITTLE_ENDIAN);
463
0
    offset += 4;
464
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
465
0
    offset += 4;
466
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_confidence_float, tvb, offset, 4, ENC_LITTLE_ENDIAN);
467
    /* offset += 4; */
468
0
    break;
469
470
0
  case nav_PositionCorrectionCumulative:  //Get position correction - cumulative v3
471
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_message_number, tvb, offset, 4, navitrol_endian);
472
0
    offset += 4;
473
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x, tvb, offset, 4, navitrol_endian);
474
0
    offset += 4;
475
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y, tvb, offset, 4, navitrol_endian);
476
0
    offset += 4;
477
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, navitrol_endian);
478
0
    offset += 4;
479
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, navitrol_endian);
480
0
    offset += 4;
481
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_cum_s_long, tvb, offset, 4, navitrol_endian);
482
0
    offset += 4;
483
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_cum_s_trans, tvb, offset, 4, navitrol_endian);
484
0
    offset += 4;
485
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_raw_heading, tvb, offset, 4, navitrol_endian);
486
0
    offset += 4;
487
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_timestamp, tvb, offset, 4, navitrol_endian);
488
    /* offset += 4; */
489
0
    break;
490
491
0
  case nav_PositionCorrectionVelocity:  //Get position correction - velocity v3
492
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_message_number, tvb, offset, 4, navitrol_endian);
493
0
    offset += 4;
494
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x, tvb, offset, 4, navitrol_endian);
495
0
    offset += 4;
496
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y, tvb, offset, 4, navitrol_endian);
497
0
    offset += 4;
498
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, navitrol_endian);
499
0
    offset += 4;
500
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, navitrol_endian);
501
0
    offset += 4;
502
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_vel_long, tvb, offset, 4, navitrol_endian);
503
0
    offset += 4;
504
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_vel_trans, tvb, offset, 4, navitrol_endian);
505
0
    offset += 4;
506
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_vel_angular, tvb, offset, 4, navitrol_endian);
507
0
    offset += 4;
508
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_timestamp, tvb, offset, 4, navitrol_endian);
509
    /* offset += 4; */
510
0
    break;
511
512
0
  case nav_OdometerUpdateDifferentialVehicle:
513
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_message_number, tvb, offset, 4, navitrol_endian);
514
0
    offset += 4;
515
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_cum_s_left, tvb, offset, 4, navitrol_endian);
516
0
    offset += 4;
517
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_cum_s_right, tvb, offset, 4, navitrol_endian);
518
0
    offset += 4;
519
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_driving_enabled, tvb, offset, 2, navitrol_endian);
520
0
    offset += 2;
521
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_timestamp, tvb, offset, 4, navitrol_endian);
522
    /* offset += 4; */
523
0
    break;
524
525
0
  case nav_PositionInitialized_v1: //Position Initialized v1
526
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_initialize_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
527
0
    offset += 1;
528
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
529
0
    offset += 8;
530
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y_double, tvb, offset, 8, ENC_LITTLE_ENDIAN);
531
0
    offset += 8;
532
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, ENC_LITTLE_ENDIAN);
533
0
    offset += 4;
534
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, ENC_LITTLE_ENDIAN);
535
0
    offset += 4;
536
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_confidence_float, tvb, offset, 4, ENC_LITTLE_ENDIAN);
537
    /* offset += 4; */
538
0
    break;
539
540
0
  case nav_PositionInitialized: //Position Initialized v3
541
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x, tvb, offset, 4, navitrol_endian);
542
0
    offset += 4;
543
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y, tvb, offset, 4, navitrol_endian);
544
0
    offset += 4;
545
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, navitrol_endian);
546
0
    offset += 4;
547
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, navitrol_endian);
548
0
    offset += 4;
549
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_initialize_status, tvb, offset, 2, navitrol_endian);
550
0
    offset += 2;
551
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_confidence, tvb, offset, 2, navitrol_endian);
552
    /* offset += 2; */
553
0
    break;
554
555
0
  case nav_TeachingToggled_v1:  //Teaching response v1
556
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_teaching_command, tvb, offset, 1, navitrol_endian);
557
    /* offset += 1; */
558
0
    break;
559
560
0
  case nav_TeachingToggled: //Teaching response v3
561
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_teaching_command, tvb, offset, 2, navitrol_endian);
562
    /* offset += 2; */
563
0
    break;
564
565
0
  case nav_ErrorDescriptionRes: // Error description response v3
566
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_error_code, tvb, offset, 4, navitrol_endian);
567
0
    offset += 4;
568
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_error_description, tvb, offset, 200, ENC_ASCII);
569
    /* offset += 200; */
570
0
    break;
571
572
0
  case nav_ErrorDescriptionListRes:  // Error description response v3
573
0
    proto_tree_add_item_ret_uint(navitrol_tree, hf_navitrol_error_count, tvb, offset, 4, navitrol_endian, &error_count);
574
0
    offset += 4;
575
0
    for (i = 0; i < error_count; i++)
576
0
    {
577
0
      proto_tree_add_item(navitrol_tree, hf_navitrol_error_code, tvb, offset, 4, navitrol_endian);
578
0
      offset += 4;
579
0
    }
580
0
    for (i = 0; i < error_count; i++)
581
0
    {
582
0
      proto_tree_add_item(navitrol_tree, hf_navitrol_error_description, tvb, offset, 200, ENC_ASCII);
583
0
      offset += 200;
584
0
    }
585
0
    break;
586
587
0
  case nav_LogSaved:      //Log saved v3
588
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_saved_log_number, tvb, offset, 4, navitrol_endian);
589
    /* offset += 4; */
590
0
    break;
591
592
0
  case nav_EnvironmentFileRead: //Environment file read v3
593
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_read_status, tvb, offset, 2, navitrol_endian);
594
    /* offset += 2; */
595
0
    break;
596
597
0
  case nav_Version:     //Version information v3
598
0
  {
599
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_software_version, tvb, offset, 4, navitrol_endian);
600
0
    offset += 4;
601
0
    uint32_t version = tvb_get_uint32(tvb, offset, navitrol_endian) / 10000;
602
0
    proto_tree_add_uint(navitrol_tree, hf_navitrol_comm_version, tvb, offset, 4, version);
603
    /* offset += 4; */
604
0
    break;
605
0
  }
606
607
0
  case nav_TimeSet:   //Time set v3
608
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_time_set_status, tvb, offset, 2, navitrol_endian);
609
    /* offset += 2; */
610
0
    break;
611
612
0
  case nav_PositionCorrection:  //Position correction v3
613
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_message_number, tvb, offset, 4, navitrol_endian);
614
0
    offset += 4;
615
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_x, tvb, offset, 4, navitrol_endian);
616
0
    offset += 4;
617
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_y, tvb, offset, 4, navitrol_endian);
618
0
    offset += 4;
619
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_heading, tvb, offset, 4, navitrol_endian);
620
0
    offset += 4;
621
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_floor, tvb, offset, 4, navitrol_endian);
622
0
    offset += 4;
623
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_correction_status, tvb, offset, 2, navitrol_endian);
624
0
    offset += 2;
625
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_position_confidence, tvb, offset, 2, navitrol_endian);
626
    /* offset += 2; */
627
0
    break;
628
629
0
  case nav_MotorControlDifferentialVehicle: //Motor control differential vehicle v3
630
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_message_number, tvb, offset, 4, navitrol_endian);
631
0
    offset += 4;
632
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_speed_left, tvb, offset, 4, navitrol_endian);
633
0
    offset += 4;
634
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_speed_right, tvb, offset, 4, navitrol_endian);
635
0
    offset += 4;
636
0
    proto_tree_add_item(navitrol_tree, hf_navitrol_errors_stopping_driving, tvb, offset, 2, navitrol_endian);
637
    /* offset += 2; */
638
0
    break;
639
640
0
  case nav_Error:   //Error message
641
0
    proto_tree_add_item_ret_uint(navitrol_tree, hf_navitrol_error_count, tvb, offset, 4, navitrol_endian, &error_count);
642
0
    offset += 4;
643
0
    for (i = 0; i < error_count; i++)
644
0
    {
645
0
      proto_tree_add_item(navitrol_tree, hf_navitrol_error_code, tvb, offset, 4, navitrol_endian);
646
0
      offset += 4;
647
0
    }
648
0
    break;
649
650
  //Commands that have no data
651
0
  case nav_ErrorDescriptionListReq:
652
0
  case nav_ErrorDescriptionListReq_v1:
653
0
  case nav_ReadEnvironmentFile:
654
0
  case nav_ReadEnvironmentFile_v1:
655
0
  case nav_RebootedNavitrol:
656
0
  case nav_StopSendRawData:
657
0
  case nav_SendRawDataStopped:
658
0
  case nav_SaveLog:
659
0
  case nav_GetVersion:
660
0
  case nav_GetVersion_v1:
661
0
  case nav_RebootNavitrol:
662
0
  case nav_RebootNavitrol_v1:
663
0
    break;
664
0
  default:
665
0
    expert_add_info(pinfo, message_item, &ei_navitrol_message_id);
666
0
    break;
667
0
  }
668
669
0
  return tvb_captured_length(tvb);
670
0
}
671
672
static int
673
dissect_navitrol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
674
0
{
675
0
  tcp_dissect_pdus(tvb, pinfo, tree, true, 8, get_navitrol_pdu_len, dissect_navitrol_pdu, data);
676
0
  return tvb_captured_length(tvb);
677
0
}
678
679
static void
680
navitrol_software_version( char *result, uint32_t version )
681
0
{
682
0
  uint32_t release_version, minor_version, branch_version;
683
684
0
  release_version = version / 10000;
685
0
  version %= 10000;
686
0
  minor_version = version / 100;
687
0
  branch_version = version % 100;
688
689
0
  snprintf( result, ITEM_LABEL_LENGTH, "%u.%02u.%02u", release_version, minor_version, branch_version);
690
0
}
691
692
void
693
proto_register_navitrol(void)
694
16
{
695
16
  module_t *navitrol_module;
696
16
  expert_module_t* expert_navitrol;
697
698
16
  static hf_register_info hf[] = {
699
16
    { &hf_navitrol_protocol_version,
700
16
      { "Protocol version", "navitrol.protocol_version", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
701
16
    { &hf_navitrol_message_id,
702
16
      { "Message ID", "navitrol.message_id", FT_UINT32, BASE_DEC, VALS(message_id_vals), 0x0, NULL, HFILL } },
703
16
    { &hf_navitrol_message_length,
704
16
      { "Message length", "navitrol.message_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
705
16
    { &hf_navitrol_measurement_mode,
706
16
      { "Measurement sending mode", "navitrol.measurement_mode", FT_UINT8, BASE_DEC, VALS(mesasurement_mode_vals), 0x0, NULL, HFILL } },
707
16
    { &hf_navitrol_ip_address,
708
16
      { "IP Address", "navitrol.ip_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
709
16
    { &hf_navitrol_port_front,
710
16
      { "Front port", "navitrol.port_front", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
711
16
    { &hf_navitrol_port_rear,
712
16
      { "Rear port", "navitrol.port_rear", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
713
16
    { &hf_navitrol_raw_data_status,
714
16
      { "Status", "navitrol.raw_data_status", FT_UINT8, BASE_DEC, VALS(status_vals), 0x0, NULL, HFILL } },
715
16
    { &hf_navitrol_position_x,
716
16
      { "X", "navitrol.position_x", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
717
16
    { &hf_navitrol_position_y,
718
16
      { "Y", "navitrol.position_y", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
719
16
    { &hf_navitrol_position_x_double,
720
16
      { "X", "navitrol.position_x.double", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
721
16
    { &hf_navitrol_position_y_double,
722
16
      { "Y", "navitrol.position_y.double", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
723
16
    { &hf_navitrol_position_heading,
724
16
      { "Heading", "navitrol.position_heading", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
725
16
    { &hf_navitrol_floor,
726
16
      { "Floor", "navitrol.floor", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
727
16
    { &hf_navitrol_cum_s_long,
728
16
      { "Cumulative raw odometer distance heading", "navitrol.cum_s_long", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
729
16
    { &hf_navitrol_cum_s_trans,
730
16
      { "Cumulative raw odometer distance transversal", "navitrol.cum_s_trans", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
731
16
    { &hf_navitrol_teaching_command,
732
16
      { "Command", "navitrol.teaching_command", FT_UINT16, BASE_DEC, VALS(teaching_vals), 0x0, NULL, HFILL } },
733
16
    { &hf_navitrol_error_code,
734
16
      { "Error code", "navitrol.error_code", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
735
16
    { &hf_navitrol_error_count,
736
16
      { "Error count", "navitrol.error_count", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
737
16
    { &hf_navitrol_message_number,
738
16
      { "Message number", "navitrol.message_number", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
739
16
    { &hf_navitrol_raw_heading,
740
16
      { "Raw heading", "navitrol.raw_heading", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
741
16
    { &hf_navitrol_timestamp,
742
16
      { "Timestamp", "navitrol.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
743
16
    { &hf_navitrol_position_initialize_status,
744
16
      { "Position initialize status", "navitrol.position_initialize_status", FT_UINT16, BASE_DEC, VALS(status_vals), 0x0, NULL, HFILL } },
745
16
    { &hf_navitrol_position_confidence,
746
16
      { "Position confidence", "navitrol.position_confidence", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL } },
747
16
    { &hf_navitrol_position_confidence_float,
748
16
      { "Position confidence", "navitrol.position_confidence_f", FT_FLOAT, BASE_NONE|BASE_UNIT_STRING, UNS(&units_percent), 0x0, NULL, HFILL } },
749
16
    { &hf_navitrol_error_description,
750
16
      { "Error description", "navitrol.error_description", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
751
16
    { &hf_navitrol_saved_log_number,
752
16
      { "Saved log number", "navitrol.saved_log_number", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
753
16
    { &hf_navitrol_software_version,
754
16
      { "Software version", "navitrol.software_version", FT_UINT32, BASE_CUSTOM, CF_FUNC(navitrol_software_version), 0x0, NULL, HFILL } },
755
16
    { &hf_navitrol_comm_version,
756
16
      { "Communication protocol version", "navitrol.comm_version", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
757
16
    { &hf_navitrol_time_set_status,
758
16
      { "Time set status", "navitrol.time_set_status", FT_UINT16, BASE_DEC, VALS(status_vals), 0x0, NULL, HFILL } },
759
16
    { &hf_navitrol_position_correction_status,
760
16
      { "Position correction status", "navitrol.position_correction_status", FT_UINT16, BASE_DEC, VALS(position_correction_status_vals), 0x0, NULL, HFILL } },
761
16
    { &hf_navitrol_set_time,
762
16
      { "Set time", "navitrol.set_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
763
16
    { &hf_navitrol_vel_long,
764
16
      { "Raw dead reckoning velocity heading", "navitrol.vel_long", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
765
16
    { &hf_navitrol_vel_trans,
766
16
      { "Raw dead reckoning velocity transversal", "navitrol.vel_trans", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
767
16
    { &hf_navitrol_vel_angular,
768
16
      { "Raw dead reckoning angular velocity", "navitrol.vel_angular", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
769
16
    { &hf_navitrol_cum_s_left,
770
16
      { "Cumulative raw odometer left wheel (in 0.1 millimeters)", "navitrol.cum_s_left", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
771
16
    { &hf_navitrol_cum_s_right,
772
16
      { "Cumulative raw odometer right wheel (in 0.1 millimeters)", "navitrol.cum_s_right", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
773
16
    { &hf_navitrol_driving_enabled,
774
16
      { "Driving enabled", "navitrol.driving_enabled", FT_UINT16, BASE_DEC, VALS(driving_status_vals), 0x0, NULL, HFILL } },
775
16
    { &hf_navitrol_read_status,
776
16
      { "Read status", "navitrol.read_status", FT_UINT16, BASE_DEC, VALS(status_vals), 0x0, NULL, HFILL } },
777
16
    { &hf_navitrol_speed_left,
778
16
      { "Speed left", "navitrol.speed_left", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
779
16
    { &hf_navitrol_speed_right,
780
16
      { "Speed right", "navitrol.speed_right", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
781
16
    { &hf_navitrol_errors_stopping_driving,
782
16
      { "Errors stopping driving", "navitrol.errors_stopping_driving", FT_UINT16, BASE_DEC, VALS(error_driving_vals), 0x0, NULL, HFILL } },
783
16
    { &hf_navitrol_start_stop_mode,
784
16
      { "Start/stop mode", "navitrol.start_stop_mode", FT_UINT8, BASE_DEC, VALS(start_stop_log_mode_vals), 0x0, NULL, HFILL } },
785
16
    { &hf_navitrol_clear_log,
786
16
      { "Clear log", "navitrol.clear_log", FT_UINT8, BASE_DEC, VALS(clear_log_vals), 0x0, NULL, HFILL } },
787
16
    { &hf_navitrol_log_save_length,
788
16
      { "Length of log to save to file", "navitrol.log_save_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
789
16
    { &hf_navitrol_raw_ds,
790
16
      { "RawDs", "navitrol.raw_ds", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
791
16
    { &hf_navitrol_raw_dh,
792
16
      { "RawDh", "navitrol.raw_dh", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } },
793
16
    { &hf_navitrol_floor_changed_status,
794
16
      { "Floor changed status", "navitrol.floor_changed_status", FT_UINT8, BASE_DEC, VALS(status_vals), 0x0, NULL, HFILL } },
795
16
  };
796
797
16
  static int *ett[] = {
798
16
    &ett_navitrol,
799
16
  };
800
801
16
  static ei_register_info ei[] = {
802
16
    { &ei_navitrol_message_id, { "navitrol.message_id.unknown", PI_PROTOCOL, PI_WARN, "Unknown message ID", EXPFILL }},
803
16
  };
804
805
16
  proto_navitrol = proto_register_protocol("Navitec Systems Navitrol", "Navitrol", "navitrol");
806
16
  proto_register_field_array(proto_navitrol, hf, array_length(hf));
807
16
  proto_register_subtree_array(ett, array_length(ett));
808
16
  expert_navitrol = expert_register_protocol(proto_navitrol);
809
16
  expert_register_field_array(expert_navitrol, ei, array_length(ei));
810
811
16
  navitrol_module = prefs_register_protocol(proto_navitrol, NULL);
812
813
16
  prefs_register_enum_preference(navitrol_module, "endian",
814
16
    "Endianness of protocol",
815
16
    "Endianness applied to protocol fields",
816
16
    &navitrol_endian,
817
16
    navitrol_endian_vals,
818
16
    false);
819
820
16
}
821
822
void
823
proto_reg_handoff_navitrol(void)
824
16
{
825
16
  dissector_handle_t navitrol_handle;
826
827
16
  navitrol_handle = create_dissector_handle(dissect_navitrol, proto_navitrol);
828
16
  dissector_add_for_decode_as("tcp.port", navitrol_handle);
829
16
}
830
831
/*
832
 * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
833
 *
834
 * Local variables:
835
 * c-basic-offset: 4
836
 * tab-width: 8
837
 * indent-tabs-mode: t
838
 * End:
839
 *
840
 * vi: set shiftwidth=4 tabstop=8 expandtab:
841
 * :indentSize=4:tabSize=8:noTabs=false:
842
 */