Coverage Report

Created: 2026-06-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-sml.c
Line
Count
Source
1
/* packet-sml.c
2
 * Routines for SML dissection
3
 * Copyright 2013, Alexander Gaertner <gaertner.alex@gmx.de>
4
 *
5
 * Enhancements for SML 1.05 dissection
6
 * Copyright 2022, Uwe Heuert <uwe.heuert@exceeding-solutions.de>
7
 *
8
 * Wireshark - Network traffic analyzer
9
 * By Gerald Combs <gerald@wireshark.org>
10
 * Copyright 1998 Gerald Combs
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
/*
16
SML dissector is based on v1.03 (12.11.2008) specifications of "smart message language" protocol
17
18
Link to specifications: http://www.vde.com/de/fnn/arbeitsgebiete/messwesen/Sym2/infomaterial/seiten/sml-spezifikation.aspx
19
20
Short description of the SML protocol on the SML Wireshark Wiki page:
21
    https://gitlab.com/wireshark/wireshark/-/wikis/SML
22
*/
23
24
#include "config.h"
25
#include <epan/packet.h>
26
#include <epan/prefs.h>
27
#include <epan/crc16-tvb.h>
28
#include <epan/expert.h>
29
30
#include <wsutil/str_util.h>
31
32
0
#define ESC_SEQ_END   UINT64_C(0x1b1b1b1b1a)
33
0
#define ESC_SEQ     0x1b1b1b1b
34
35
0
#define OPEN_REQ    0x0100
36
0
#define OPEN_RES    0x0101
37
0
#define CLOSE_REQ   0x0200
38
0
#define CLOSE_RES   0x0201
39
0
#define PROFILEPACK_REQ   0x0300
40
0
#define PROFILEPACK_RES   0x0301
41
0
#define PROFILELIST_REQ   0x0400
42
0
#define PROFILELIST_RES   0x0401
43
0
#define GETPROCPARAMETER_REQ  0x0500
44
0
#define GETPROCPARAMETER_RES  0x0501
45
0
#define SETPROCPARAMETER_REQ  0x0600
46
0
#define GETLIST_REQ   0x0700
47
0
#define GETLIST_RES   0x0701
48
0
#define ATTENTION   0xFF01
49
50
0
#define PROC_VALUE    0x01
51
0
#define PROC_PERIOD   0x02
52
0
#define PROC_TUPLE    0x03
53
0
#define PROC_TIME   0x04
54
0
#define PROC_LISTENTRY  0x05
55
56
0
#define TIME_SECINDEX       0x01
57
0
#define TIME_TIMESTAMP        0x02
58
0
#define TIME_LOCALTIMESTAMP     0x03
59
60
0
#define LISTTYPE_TIME       0x01
61
0
#define LISTTYPE_TIMESTAMPEDVALUE 0x02
62
0
#define LISTTYPE_COSEMVALUE     0x03
63
64
0
#define COSEMVALUE_SCALER_UNIT    0x01
65
66
0
#define SHORT_LIST    0x70
67
0
#define LONG_LIST   0xF0
68
69
0
#define OPTIONAL    0x01
70
71
0
#define UNSIGNED8   0x62
72
0
#define UNSIGNED16    0x63
73
74
0
#define LIST_6_ELEMENTS   0x76
75
0
#define MSB     0x80
76
77
/* Forward declaration we need below (if using proto_reg_handoff as a prefs callback)*/
78
void proto_register_sml(void);
79
void proto_reg_handoff_sml(void);
80
81
static dissector_handle_t sml_handle;
82
83
/* Initialize the protocol and registered fields */
84
static int proto_sml;
85
86
static int hf_sml_esc;
87
static int hf_sml_version_1;
88
static int hf_sml_groupNo;
89
static int hf_sml_transactionId;
90
static int hf_sml_length;
91
static int hf_sml_datatype;
92
static int hf_sml_abortOnError;
93
static int hf_sml_MessageBody;
94
static int hf_sml_crc16;
95
static int hf_sml_crc16_status;
96
static int hf_sml_endOfSmlMsg;
97
static int hf_sml_end;
98
static int hf_sml_codepage;
99
static int hf_sml_clientId;
100
static int hf_sml_reqFileId;
101
static int hf_sml_serverId;
102
static int hf_sml_username;
103
static int hf_sml_password;
104
static int hf_sml_smlVersion;
105
static int hf_sml_listName;
106
static int hf_sml_globalSignature;
107
static int hf_sml_timetype;
108
static int hf_sml_objName;
109
static int hf_sml_status;
110
static int hf_sml_unit;
111
static int hf_sml_scaler;
112
static int hf_sml_value;
113
static int hf_sml_simplevalue;
114
static int hf_sml_valueSignature;
115
static int hf_sml_listSignature;
116
static int hf_sml_parameterTreePath;
117
static int hf_sml_attribute;
118
static int hf_sml_parameterName;
119
static int hf_sml_procParValue;
120
static int hf_sml_padding;
121
static int hf_sml_secIndex;
122
static int hf_sml_timestamp;
123
static int hf_sml_localOffset;
124
static int hf_sml_seasonTimeOffset;
125
static int hf_sml_attentionNo;
126
static int hf_sml_attentionMsg;
127
static int hf_sml_withRawdata;
128
static int hf_sml_object_list_Entry;
129
static int hf_sml_regPeriod;
130
static int hf_sml_rawdata;
131
static int hf_sml_periodSignature;
132
static int hf_sml_profileSignature;
133
static int hf_sml_signature_mA_R2_R3;
134
static int hf_sml_signature_pA_R1_R4;
135
static int hf_sml_unit_mA;
136
static int hf_sml_scaler_mA;
137
static int hf_sml_value_mA;
138
static int hf_sml_unit_pA;
139
static int hf_sml_scaler_pA;
140
static int hf_sml_value_pA;
141
static int hf_sml_unit_R1;
142
static int hf_sml_scaler_R1;
143
static int hf_sml_value_R1;
144
static int hf_sml_unit_R2;
145
static int hf_sml_scaler_R2;
146
static int hf_sml_value_R2;
147
static int hf_sml_unit_R3;
148
static int hf_sml_scaler_R3;
149
static int hf_sml_value_R3;
150
static int hf_sml_unit_R4;
151
static int hf_sml_scaler_R4;
152
static int hf_sml_value_R4;
153
static int hf_sml_file_marker;
154
static int hf_sml_new_file_marker;
155
static int hf_sml_listtype;
156
static int hf_sml_cosemvalue;
157
158
static const value_string datatype []={
159
  {0x52, "Integer 8"},
160
  {0x53, "Integer 16"},
161
  {0x54, "Integer cropped"},
162
  {0x55, "Integer 32"},
163
  {0x56, "Integer cropped"},
164
  {0x57, "Integer cropped"},
165
  {0x58, "Integer cropped"},
166
  {0x59, "Integer 64"},
167
  {0x62, "Unsigned 8"},
168
  {0x63, "Unsigned 16"},
169
  {0x64, "Unsigned cropped"},
170
  {0x65, "Unsigned 32"},
171
  {0x66, "Unsigned cropped"},
172
  {0x67, "Unsigned cropped"},
173
  {0x68, "Unsigned cropped"},
174
  {0x69, "Unsigned 64"},
175
  {0x42, "Boolean"},
176
  {0x72, "ListType" },
177
  {0, NULL}
178
};
179
180
static const value_string sml_abort[]={
181
  {0x00, "Continue"},
182
  {0x01, "Continue at next group"},
183
  {0x02, "Continue than abort"},
184
  {0xFF, "Abort"},
185
  {0, NULL}
186
};
187
188
static const value_string sml_body[]={
189
  {OPEN_REQ,         "PublicOpen.Req"},
190
  {OPEN_RES,         "PublicOpen.Res"},
191
  {CLOSE_REQ,        "PublicClose.Req"},
192
  {CLOSE_RES,        "PublicClose.Res"},
193
  {PROFILEPACK_REQ,      "GetProfilePack.Req"},
194
  {PROFILEPACK_RES,      "GetProfilePack.Res"},
195
  {PROFILELIST_REQ,      "GetProfileList.Req"},
196
  {PROFILELIST_RES,      "GetProfileList.Res"},
197
  {GETPROCPARAMETER_REQ, "GetProcParameter.Req"},
198
  {GETPROCPARAMETER_RES, "GetProcParameter.Res"},
199
  {SETPROCPARAMETER_REQ, "SetProcParameter.Req"},
200
  {GETLIST_REQ,        "GetList.Req"},
201
  {GETLIST_RES,        "GetList.Res"},
202
  {ATTENTION,        "Attention.Res"},
203
  {0, NULL}
204
};
205
206
static const value_string sml_timetypes[]={
207
  {0x01, "secIndex"},
208
  {0x02, "timestamp"},
209
  {0x03, "localTimestamp" },
210
  {0, NULL}
211
};
212
213
static const value_string procvalues[]={
214
  {PROC_VALUE,  "Value"},
215
  {PROC_PERIOD, "PeriodEntry"},
216
  {PROC_TUPLE,  "TupleEntry"},
217
  {PROC_TIME,   "Time"},
218
  {PROC_LISTENTRY, "ListEntry"},
219
  {0, NULL}
220
};
221
222
static const value_string listtypevalues[] = {
223
  { LISTTYPE_TIME, "smlTime" },
224
  { LISTTYPE_TIMESTAMPEDVALUE, "smlTimestampedValue" },
225
  { LISTTYPE_COSEMVALUE, "smlCosemValue" },
226
  { 0, NULL }
227
};
228
229
static const value_string cosemvaluevalues[] = {
230
  { COSEMVALUE_SCALER_UNIT, "scaler_unit" },
231
  { 0, NULL }
232
};
233
234
static const range_string attentionValues[]={
235
  {0xE000, 0xFCFF, "application specific"},
236
  {0xFD00, 0xFD00, "acknowledged"},
237
  {0xFD01, 0xFD01, "order will be executed later"},
238
  {0xFE00, 0xFE00, "error undefined"},
239
  {0xFE01, 0xFE01, "unknown SML designator"},
240
  {0xFE02, 0xFE02, "User/Password wrong"},
241
  {0xFE03, 0xFE03, "serverId not available"},
242
  {0xFE04, 0xFE04, "reqFileId not available"},
243
  {0xFE05, 0xFE05, "destination attributes cannot be written"},
244
  {0xFE06, 0xFE06, "destination attributes cannot be read"},
245
  {0xFE07, 0xFE07, "communication disturbed"},
246
  {0xFE08, 0xFE08, "rawdata cannot be interpreted"},
247
  {0xFE09, 0xFE09, "value out of range"},
248
  {0xFE0A, 0xFE0A, "order not executed"},
249
  {0xFE0B, 0xFE0B, "checksum failed"},
250
  {0xFE0C, 0xFE0C, "broadcast not supported"},
251
  {0xFE0D, 0xFE0D, "unexpected message"},
252
  {0xFE0E, 0xFE0E, "unknown object in the profile"},
253
  {0xFE0F, 0xFE0F, "datatype not supported"},
254
  {0xFE10, 0xFE10, "optional element not supported"},
255
  {0xFE11, 0xFE11, "no entry in requested profile"},
256
  {0xFE12, 0xFE12, "end limit before begin limit"},
257
  {0xFE13, 0xFE13, "no entry in requested area"},
258
  {0xFE14, 0xFE14, "SML file without close"},
259
  {0xFE15, 0xFE15, "busy, response cannot be sent"},
260
  {0,0, NULL}
261
};
262
263
static const range_string bools[]={
264
  {0x00, 0x00, "false"},
265
  {0x01, 0xFF, "true"},
266
  {0,0, NULL}
267
};
268
269
/* Initialize the subtree pointers */
270
static int ett_sml;
271
static int ett_sml_mainlist;
272
static int ett_sml_version;
273
static int ett_sml_sublist;
274
static int ett_sml_trans;
275
static int ett_sml_group;
276
static int ett_sml_abort;
277
static int ett_sml_body;
278
static int ett_sml_mblist;
279
static int ett_sml_mttree;
280
static int ett_sml_crc16;
281
static int ett_sml_clientId;
282
static int ett_sml_codepage;
283
static int ett_sml_reqFileId;
284
static int ett_sml_serverId;
285
static int ett_sml_username;
286
static int ett_sml_password;
287
static int ett_sml_smlVersion;
288
static int ett_sml_listName;
289
static int ett_sml_globalSignature;
290
static int ett_sml_refTime;
291
static int ett_sml_actSensorTime;
292
static int ett_sml_timetype;
293
static int ett_sml_time;
294
static int ett_sml_valList;
295
static int ett_sml_listEntry;
296
static int ett_sml_objName;
297
static int ett_sml_status;
298
static int ett_sml_valTime;
299
static int ett_sml_unit;
300
static int ett_sml_scaler;
301
static int ett_sml_value;
302
static int ett_sml_simplevalue;
303
static int ett_sml_valueSignature;
304
static int ett_sml_listSignature;
305
static int ett_sml_valtree;
306
static int ett_sml_actGatewayTime;
307
static int ett_sml_treepath;
308
static int ett_sml_parameterTreePath;
309
static int ett_sml_attribute;
310
static int ett_sml_parameterTree;
311
static int ett_sml_parameterName;
312
static int ett_sml_child;
313
static int ett_sml_periodEntry;
314
static int ett_sml_procParValue;
315
static int ett_sml_procParValueTime;
316
static int ett_sml_procParValuetype;
317
static int ett_sml_msgend;
318
static int ett_sml_tuple;
319
static int ett_sml_secIndex;
320
static int ett_sml_timestamp;
321
static int ett_sml_localTimestamp;
322
static int ett_sml_localOffset;
323
static int ett_sml_seasonTimeOffset;
324
static int ett_sml_signature;
325
static int ett_sml_attentionNo;
326
static int ett_sml_attentionMsg;
327
static int ett_sml_withRawdata;
328
static int ett_sml_beginTime;
329
static int ett_sml_endTime;
330
static int ett_sml_object_list;
331
static int ett_sml_object_list_Entry;
332
static int ett_sml_actTime;
333
static int ett_sml_regPeriod;
334
static int ett_sml_rawdata;
335
static int ett_sml_periodSignature;
336
static int ett_sml_period_List_Entry;
337
static int ett_sml_periodList;
338
static int ett_sml_headerList;
339
static int ett_sml_header_List_Entry;
340
static int ett_sml_profileSignature;
341
static int ett_sml_valuelist;
342
static int ett_sml_value_List_Entry;
343
static int ett_sml_signature_mA_R2_R3;
344
static int ett_sml_signature_pA_R1_R4;
345
static int ett_sml_unit_mA;
346
static int ett_sml_scaler_mA;
347
static int ett_sml_value_mA;
348
static int ett_sml_unit_pA;
349
static int ett_sml_scaler_pA;
350
static int ett_sml_value_pA;
351
static int ett_sml_unit_R1;
352
static int ett_sml_scaler_R1;
353
static int ett_sml_value_R1;
354
static int ett_sml_unit_R2;
355
static int ett_sml_scaler_R2;
356
static int ett_sml_value_R2;
357
static int ett_sml_unit_R3;
358
static int ett_sml_scaler_R3;
359
static int ett_sml_value_R3;
360
static int ett_sml_unit_R4;
361
static int ett_sml_scaler_R4;
362
static int ett_sml_value_R4;
363
static int ett_sml_tree_Entry;
364
static int ett_sml_dasDetails;
365
static int ett_sml_attentionDetails;
366
static int ett_sml_listtypetype;
367
static int ett_sml_listtype;
368
static int ett_sml_timestampedvaluetype;
369
static int ett_sml_timestampedvalue;
370
static int ett_sml_cosemvaluetype;
371
static int ett_sml_cosemvalue;
372
static int ett_sml_scaler_unit;
373
374
static expert_field ei_sml_messagetype_unknown;
375
static expert_field ei_sml_procParValue_errror;
376
static expert_field ei_sml_procParValue_invalid;
377
static expert_field ei_sml_segment_needed;
378
static expert_field ei_sml_endOfSmlMsg;
379
static expert_field ei_sml_crc_error;
380
static expert_field ei_sml_tuple_error;
381
static expert_field ei_sml_crc_error_length;
382
static expert_field ei_sml_invalid_count;
383
static expert_field ei_sml_MessageBody;
384
static expert_field ei_sml_esc_error;
385
static expert_field ei_sml_version2_not_supported;
386
static expert_field ei_sml_attentionNo;
387
static expert_field ei_sml_listtype_invalid;
388
static expert_field ei_sml_cosemvalue_invalid;
389
390
/*options*/
391
static bool sml_reassemble = true;
392
static bool sml_crc_enabled;
393
394
/*get number of length octets and calculate how many data octets, it's like BER but not the same! */
395
0
static void get_length(tvbuff_t *tvb, const unsigned *offset, unsigned *data, unsigned *length){
396
0
  unsigned check = 0;
397
0
  unsigned temp_offset = 0;
398
399
0
  temp_offset = *offset;
400
0
  *data = 0;
401
0
  *length = 0;
402
403
0
  check = tvb_get_uint8(tvb, temp_offset);
404
0
  if (check == OPTIONAL){
405
0
    *length = 1;
406
0
  }
407
0
  else if ((check & 0x80) == MSB){
408
0
    while ((check & 0x80) == MSB){
409
0
      check = check & 0x0F;
410
411
0
      *data = *data + check;
412
0
      *data <<= 4;
413
0
      *length+=1;
414
415
0
      temp_offset+=1;
416
0
      check = tvb_get_uint8(tvb, temp_offset);
417
0
    }
418
0
    check = check & 0x0F;
419
420
0
    *data = *data + check;
421
0
    *length+=1;
422
0
    *data = *data - *length;
423
0
  }
424
0
  else{
425
0
    check = check & 0x0F;
426
0
    *length+=1;
427
0
    *data = check - *length;
428
0
  }
429
0
}
430
431
/*often used fields*/
432
static void field_scaler(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length);
433
static void field_unit(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length);
434
static void field_status(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length);
435
static void sml_time_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *SML_time_tree, unsigned *offset);
436
437
0
static void sml_simplevalue(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
438
0
  proto_item *value = NULL;
439
0
  proto_tree *value_tree = NULL;
440
441
0
  get_length(tvb, offset, data, length);
442
0
  value = proto_tree_add_bytes_format(insert_tree, hf_sml_simplevalue, tvb, *offset, *length + *data, NULL, "value %s", (*data == 0) ? ": NOT SET" : "");
443
444
0
  if (tvb_get_uint8(tvb, *offset) != OPTIONAL){
445
0
    value_tree = proto_item_add_subtree(value, ett_sml_simplevalue);
446
0
    if ((tvb_get_uint8(tvb, *offset) & 0x80) == MSB || (tvb_get_uint8(tvb, *offset) & 0xF0) == 0){
447
0
      proto_tree_add_uint(value_tree, hf_sml_length, tvb, *offset, *length, *data);
448
0
      *offset += *length;
449
0
    }
450
0
    else {
451
0
      proto_tree_add_item(value_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
452
0
      *offset += 1;
453
0
    }
454
0
    proto_tree_add_item(value_tree, hf_sml_simplevalue, tvb, *offset, *data, ENC_NA);
455
0
    *offset += *data;
456
0
  }
457
0
  else
458
0
    *offset += 1;
459
0
}
460
461
0
static void sml_timestampedvalue_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *timestampedvalue_tree, unsigned *offset){
462
0
  proto_tree *SML_timestampedvalue_type_tree;
463
0
  proto_tree *SML_time_tree;
464
0
  proto_item *SML_time;
465
0
  unsigned data = 0;
466
0
  unsigned length = 0;
467
468
0
  SML_timestampedvalue_type_tree = proto_tree_add_subtree(timestampedvalue_tree, tvb, *offset, -1, ett_sml_timestampedvaluetype, NULL, "SML_TimestampedValue Type");
469
470
  /*smlTime*/
471
0
  SML_time_tree = proto_tree_add_subtree(SML_timestampedvalue_type_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "smlTime");
472
0
  *offset += 1;
473
0
  sml_time_type(tvb, pinfo, SML_time_tree, offset);
474
0
  proto_item_set_end(SML_time, tvb, *offset);
475
476
  /*status*/
477
0
  field_status(tvb, SML_timestampedvalue_type_tree, offset, &data, &length);
478
479
  /*simpleValue*/
480
0
  sml_simplevalue(tvb, SML_timestampedvalue_type_tree, offset, &data, &length);
481
0
}
482
483
0
static void sml_cosem_scaler_unit_type(tvbuff_t *tvb, proto_tree *cosem_scaler_unit_tree, unsigned *offset){
484
0
  unsigned data, length;
485
486
  /*scaler*/
487
0
  get_length(tvb, offset, &data, &length);
488
0
  field_scaler(tvb, cosem_scaler_unit_tree, offset, &data, &length);
489
490
  /*unit*/
491
0
  get_length(tvb, offset, &data, &length);
492
0
  field_unit(tvb, cosem_scaler_unit_tree, offset, &data, &length);
493
0
}
494
495
0
static void sml_cosemvalue_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *cosemvalue_tree, unsigned *offset){
496
0
  unsigned check = 0;
497
0
  proto_item *SML_cosem_scaler_unit;
498
0
  proto_tree *SML_cosemvalue_type_tree;
499
0
  proto_tree *SML_cosem_scaler_unit_tree;
500
501
0
  SML_cosemvalue_type_tree = proto_tree_add_subtree(cosemvalue_tree, tvb, *offset, -1, ett_sml_cosemvaluetype, NULL, "SML_CosemValue Type");
502
503
0
  proto_tree_add_item(SML_cosemvalue_type_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
504
0
  *offset += 1;
505
0
  proto_tree_add_item(SML_cosemvalue_type_tree, hf_sml_cosemvalue, tvb, *offset, 1, ENC_BIG_ENDIAN);
506
507
0
  check = tvb_get_uint8(tvb, *offset);
508
0
  *offset += 1;
509
510
0
  switch (check) {
511
0
    case COSEMVALUE_SCALER_UNIT:
512
      /*scaler_unit*/
513
0
      SML_cosem_scaler_unit_tree = proto_tree_add_subtree(SML_cosemvalue_type_tree, tvb, *offset, -1, ett_sml_scaler_unit, &SML_cosem_scaler_unit, "CosemScalerUnit");
514
0
      *offset += 1;
515
0
      sml_cosem_scaler_unit_type(tvb, SML_cosem_scaler_unit_tree, offset);
516
0
      break;
517
518
0
    default:
519
0
      expert_add_info(pinfo, SML_cosemvalue_type_tree, &ei_sml_cosemvalue_invalid);
520
0
      break;
521
0
  }
522
0
}
523
524
0
static void sml_listtype_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *listtype_tree, unsigned *offset){
525
0
  unsigned check = 0;
526
0
  proto_tree *SML_listtype_type_tree;
527
0
  proto_item *SML_time;
528
0
  proto_tree *SML_time_tree = NULL;
529
0
  proto_item *SML_timestampedvalue;
530
0
  proto_tree *SML_timestampedvalue_tree = NULL;
531
0
  proto_item *SML_cosemvalue;
532
0
  proto_tree *SML_cosemvalue_tree = NULL;
533
534
0
  SML_listtype_type_tree = proto_tree_add_subtree(listtype_tree, tvb, *offset, -1, ett_sml_listtypetype, NULL, "SML_ListType Type");
535
536
0
  proto_tree_add_item(SML_listtype_type_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
537
0
  *offset += 1;
538
0
  proto_tree_add_item(SML_listtype_type_tree, hf_sml_listtype, tvb, *offset, 1, ENC_BIG_ENDIAN);
539
0
  *offset += 1;
540
541
0
  check = tvb_get_uint8(tvb, *offset);
542
0
  *offset += 1;
543
544
0
  switch (check) {
545
0
    case LISTTYPE_TIME:
546
      /*smlTime*/
547
0
      SML_time_tree = proto_tree_add_subtree(SML_listtype_type_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "Time");
548
0
      *offset += 1;
549
0
      sml_time_type(tvb, pinfo, SML_time_tree, offset);
550
0
      proto_item_set_end(SML_time, tvb, *offset);
551
0
      break;
552
553
0
    case LISTTYPE_TIMESTAMPEDVALUE:
554
      /*smlTimestampedValue*/
555
0
      SML_timestampedvalue_tree = proto_tree_add_subtree(SML_listtype_type_tree, tvb, *offset, -1, ett_sml_timestampedvalue, &SML_timestampedvalue, "TimestampedValue");
556
0
      *offset += 1;
557
0
      sml_timestampedvalue_type(tvb, pinfo, SML_timestampedvalue_tree, offset);
558
0
      proto_item_set_end(SML_timestampedvalue, tvb, *offset);
559
0
      break;
560
561
0
    case LISTTYPE_COSEMVALUE:
562
      /*smlCosemValue*/
563
0
      SML_cosemvalue_tree = proto_tree_add_subtree(SML_listtype_type_tree, tvb, *offset, -1, ett_sml_cosemvalue, &SML_cosemvalue, "CosemValue");
564
0
      *offset += 1;
565
0
      sml_cosemvalue_type(tvb, pinfo, SML_cosemvalue_tree, offset);
566
0
      break;
567
568
0
    default:
569
0
      expert_add_info(pinfo, SML_listtype_type_tree, &ei_sml_listtype_invalid);
570
0
      break;
571
0
  }
572
0
}
573
574
0
static void sml_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
575
0
  proto_item *value = NULL;
576
0
  proto_tree *value_tree = NULL;
577
578
0
  get_length(tvb, offset, data, length);
579
0
  value = proto_tree_add_bytes_format (insert_tree, hf_sml_value, tvb, *offset, *length + *data, NULL,"value %s", (*data == 0)? ": NOT SET" : "");
580
581
0
  if (tvb_get_uint8(tvb, *offset) != OPTIONAL){
582
0
    value_tree = proto_item_add_subtree (value, ett_sml_value);
583
0
    if (tvb_get_uint8(tvb, *offset) == 0x72) {
584
0
      sml_listtype_type(tvb, pinfo, value_tree, offset);
585
0
    }
586
0
    else
587
0
    {
588
0
      if ((tvb_get_uint8(tvb, *offset) & 0x80) == MSB || (tvb_get_uint8(tvb, *offset) & 0xF0) == 0){
589
0
        proto_tree_add_uint(value_tree, hf_sml_length, tvb, *offset, *length, *data);
590
0
        *offset+= *length;
591
0
      }
592
0
      else {
593
0
        proto_tree_add_item (value_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
594
0
        *offset+=1;
595
0
      }
596
0
      proto_tree_add_item (value_tree, hf_sml_value, tvb, *offset, *data, ENC_NA);
597
0
      *offset+= *data;
598
0
    }
599
0
  }
600
0
  else
601
0
    *offset+=1;
602
0
}
603
604
0
static void sml_time_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *SML_time_tree, unsigned *offset){
605
0
  unsigned check = 0;
606
0
  proto_tree *timetype_tree;
607
0
  proto_tree *timevalue_tree;
608
0
  proto_tree *localtimestamptype_tree;
609
0
  unsigned data = 0;
610
0
  unsigned length = 0;
611
612
0
  timetype_tree = proto_tree_add_subtree(SML_time_tree, tvb, *offset, 2, ett_sml_timetype, NULL, "SML-Time Type");
613
614
0
  proto_tree_add_item (timetype_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
615
0
  *offset+=1;
616
0
  proto_tree_add_item (timetype_tree, hf_sml_timetype, tvb, *offset, 1, ENC_BIG_ENDIAN);
617
  //*offset+=1;
618
619
0
  check = tvb_get_uint8(tvb, *offset);
620
0
  *offset += 1;
621
622
0
  switch (check) {
623
0
    case TIME_SECINDEX:
624
      /*secIndex*/
625
0
      get_length(tvb, offset, &data, &length);
626
0
      timevalue_tree = proto_tree_add_subtree(SML_time_tree, tvb, *offset, length + data, ett_sml_secIndex, NULL, "secIndex");
627
0
      proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
628
0
      *offset += 1;
629
0
      proto_tree_add_item(timevalue_tree, hf_sml_secIndex, tvb, *offset, data, ENC_BIG_ENDIAN);
630
0
      *offset += data;
631
632
0
      break;
633
0
    case TIME_TIMESTAMP:
634
      /*timestamp*/
635
0
      get_length(tvb, offset, &data, &length);
636
0
      timevalue_tree = proto_tree_add_subtree(SML_time_tree, tvb, *offset, length + data, ett_sml_timestamp, NULL, "timestamp");
637
0
      proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
638
0
      *offset += 1;
639
0
      proto_tree_add_item(timevalue_tree, hf_sml_timestamp, tvb, *offset, data, ENC_BIG_ENDIAN);
640
0
      *offset += data;
641
642
0
      break;
643
644
0
    case TIME_LOCALTIMESTAMP:
645
      /*localTimestamp*/
646
0
      localtimestamptype_tree = proto_tree_add_subtree(SML_time_tree, tvb, *offset, length + data, ett_sml_localTimestamp, NULL, "localTimestamp");
647
0
      *offset += 1;
648
649
0
      get_length(tvb, offset, &data, &length);
650
0
      timevalue_tree = proto_tree_add_subtree(localtimestamptype_tree, tvb, *offset, length + data, ett_sml_timestamp, NULL, "timestamp");
651
0
      proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
652
0
      *offset += 1;
653
0
      proto_tree_add_item(timevalue_tree, hf_sml_timestamp, tvb, *offset, data, ENC_BIG_ENDIAN);
654
0
      *offset += data;
655
656
0
      get_length(tvb, offset, &data, &length);
657
0
      timevalue_tree = proto_tree_add_subtree(localtimestamptype_tree, tvb, *offset, length + data, ett_sml_localOffset, NULL, "localOffset");
658
0
      proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
659
0
      *offset += 1;
660
0
      proto_tree_add_item(timevalue_tree, hf_sml_localOffset, tvb, *offset, data, ENC_BIG_ENDIAN);
661
0
      *offset += data;
662
663
0
      get_length(tvb, offset, &data, &length);
664
0
      timevalue_tree = proto_tree_add_subtree(localtimestamptype_tree, tvb, *offset, length + data, ett_sml_seasonTimeOffset, NULL, "seasonTimeOffset");
665
0
      proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
666
0
      *offset += 1;
667
0
      proto_tree_add_item(timevalue_tree, hf_sml_seasonTimeOffset, tvb, *offset, data, ENC_BIG_ENDIAN);
668
0
      *offset += data;
669
670
0
      break;
671
672
0
    default:
673
0
      expert_add_info(pinfo, timetype_tree, &ei_sml_listtype_invalid);
674
0
      break;
675
0
  }
676
0
}
677
678
0
static void field_codepage(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
679
0
  proto_item *codepage = NULL;
680
0
  proto_tree *codepage_tree = NULL;
681
682
0
  get_length(tvb, offset, data, length);
683
0
  codepage = proto_tree_add_bytes_format (insert_tree, hf_sml_codepage, tvb, *offset, *length + *data, NULL,"Codepage %s", (*data == 0)? ": NOT SET" : "");
684
685
0
  if (*data > 0) {
686
0
    codepage_tree = proto_item_add_subtree (codepage , ett_sml_codepage);
687
0
    proto_tree_add_uint(codepage_tree, hf_sml_length, tvb, *offset, *length, *data);
688
0
    *offset+= *length;
689
690
0
    proto_tree_add_item (codepage_tree, hf_sml_codepage, tvb, *offset, *data, ENC_NA);
691
0
    *offset+= *data;
692
0
  }
693
0
  else
694
0
    *offset+=1;
695
0
}
696
697
0
static void field_clientId(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
698
0
  proto_item *clientId = NULL;
699
0
  proto_tree *clientId_tree = NULL;
700
701
0
  get_length(tvb, offset, data, length);
702
0
  clientId = proto_tree_add_bytes_format (insert_tree, hf_sml_clientId, tvb, *offset, *length + *data, NULL, "clientID %s", (*data == 0)? ": NOT SET" : "");
703
704
0
  if (*data > 0) {
705
0
    clientId_tree = proto_item_add_subtree (clientId, ett_sml_clientId);
706
0
    proto_tree_add_uint(clientId_tree, hf_sml_length, tvb, *offset, *length, *data);
707
0
    *offset+=*length;
708
0
    proto_tree_add_item (clientId_tree, hf_sml_clientId, tvb, *offset, *data, ENC_NA);
709
0
    *offset+=*data;
710
0
  }
711
0
  else
712
0
    *offset+=1;
713
0
}
714
715
0
static void field_reqFileId(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
716
0
  proto_tree *reqFileId_tree;
717
718
0
  get_length(tvb, offset, data, length);
719
0
  reqFileId_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_reqFileId, NULL, "reqFileId");
720
721
0
  proto_tree_add_uint (reqFileId_tree, hf_sml_length, tvb, *offset, *length, *data);
722
0
  *offset+=*length;
723
0
  proto_tree_add_item (reqFileId_tree, hf_sml_reqFileId, tvb, *offset, *data, ENC_NA);
724
0
  *offset+=*data;
725
0
}
726
727
0
static void field_serverId(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
728
0
  proto_item *serverId = NULL;
729
0
  proto_tree *serverId_tree = NULL;
730
731
  /*Server ID OPTIONAL*/
732
0
  get_length(tvb, offset, data, length);
733
0
  serverId = proto_tree_add_bytes_format (insert_tree,hf_sml_serverId, tvb, *offset, *length + *data, NULL, "Server ID %s", (*data == 0)? ": NOT SET" : "");
734
735
0
  if (*data > 0){
736
0
    serverId_tree = proto_item_add_subtree (serverId , ett_sml_serverId);
737
0
    proto_tree_add_uint (serverId_tree, hf_sml_length, tvb, *offset, *length, *data);
738
0
    *offset+=*length;
739
0
    proto_tree_add_item (serverId_tree, hf_sml_serverId, tvb, *offset, *data, ENC_NA);
740
0
    *offset+=*data;
741
0
  }
742
0
  else
743
0
    *offset+=1;
744
0
}
745
746
0
static void field_username(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
747
0
  proto_item *username = NULL;
748
0
  proto_tree *username_tree = NULL;
749
750
  /*Username OPTIONAL*/
751
0
  get_length(tvb, offset, data, length);
752
0
  username = proto_tree_add_string_format (insert_tree,hf_sml_username, tvb, *offset, *length + *data, NULL, "Username %s", (*data == 0)? ": NOT SET" : "");
753
754
0
  if (*data > 0){
755
0
    username_tree = proto_item_add_subtree (username , ett_sml_username);
756
0
    proto_tree_add_uint (username_tree, hf_sml_length, tvb, *offset, *length, *data);
757
0
    *offset+=*length;
758
0
    proto_tree_add_item (username_tree, hf_sml_username, tvb, *offset, *data, ENC_ASCII | ENC_BIG_ENDIAN);
759
0
    *offset+=*data;
760
0
  }
761
0
  else
762
0
    *offset+=1;
763
0
}
764
765
0
static void field_password(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
766
0
  proto_item *password = NULL;
767
0
  proto_tree *password_tree = NULL;
768
769
  /*Password OPTIONAL*/
770
0
  get_length(tvb, offset, data, length);
771
0
  password = proto_tree_add_string_format (insert_tree,hf_sml_password, tvb, *offset, *length + *data, NULL, "Password %s", (*data == 0)? ": NOT SET" : "");
772
773
0
  if (*data > 0) {
774
0
    password_tree = proto_item_add_subtree (password, ett_sml_password);
775
0
    proto_tree_add_uint (password_tree, hf_sml_length, tvb, *offset, *length, *data);
776
0
    *offset+=*length;
777
0
    proto_tree_add_item (password_tree, hf_sml_password, tvb, *offset, *data, ENC_ASCII | ENC_BIG_ENDIAN);
778
0
    *offset+=*data;
779
0
  }
780
0
  else
781
0
    *offset+=1;
782
0
}
783
784
0
static void field_smlVersion(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
785
0
  proto_item *smlVersion = NULL;
786
0
  proto_tree *smlVersion_tree = NULL;
787
788
  /*sml-Version OPTIONAL*/
789
0
  get_length(tvb, offset, data, length);
790
0
  smlVersion = proto_tree_add_uint_format (insert_tree, hf_sml_smlVersion, tvb, *offset, *length + *data, *length + *data, "SML-Version %s", (*data == 0)? ": Version 1" : "");
791
792
0
  if (*data > 0) {
793
0
    smlVersion_tree = proto_item_add_subtree (smlVersion, ett_sml_smlVersion);
794
0
    proto_tree_add_item (smlVersion_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
795
0
    *offset+=1;
796
797
0
    proto_tree_add_item (smlVersion_tree, hf_sml_smlVersion, tvb, *offset, 1,ENC_BIG_ENDIAN);
798
0
    *offset+=1;
799
0
  }
800
0
  else
801
0
    *offset+=1;
802
0
}
803
804
0
static void field_globalSignature(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
805
0
  proto_item *globalSignature = NULL;
806
0
  proto_tree *globalSignature_tree = NULL;
807
808
  /*Global Signature OPTIONAL*/
809
0
  get_length(tvb, offset, data, length);
810
811
0
  globalSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_globalSignature, tvb, *offset, *length + *data, NULL, "global Signature %s", (*data == 0)? ": NOT SET" : "");
812
813
0
  if (*data > 0){
814
0
    globalSignature_tree = proto_item_add_subtree (globalSignature, ett_sml_globalSignature);
815
0
    proto_tree_add_uint (globalSignature_tree, hf_sml_length, tvb, *offset, *length, *data);
816
0
    *offset+=*length;
817
0
    proto_tree_add_item (globalSignature_tree, hf_sml_globalSignature, tvb, *offset, *data, ENC_NA);
818
0
    *offset+=*data;
819
0
  }
820
0
  else
821
0
    *offset+=1;
822
0
}
823
824
0
static void field_listName(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
825
0
  proto_item *listName = NULL;
826
0
  proto_tree *listName_tree = NULL;
827
828
  /*List Name OPTIONAL*/
829
0
  get_length(tvb, offset, data, length);
830
0
  listName = proto_tree_add_bytes_format (insert_tree,hf_sml_listName, tvb, *offset, *length + *data, NULL, "List Name %s", (*data == 0)? ": NOT SET" : "");
831
832
0
  if (*data > 0) {
833
0
    listName_tree = proto_item_add_subtree (listName, ett_sml_listName);
834
0
    proto_tree_add_uint (listName_tree, hf_sml_length, tvb, *offset, *length, *data);
835
0
    *offset+=*length;
836
0
    proto_tree_add_item (listName_tree, hf_sml_listName, tvb, *offset, *data, ENC_NA);
837
0
    *offset+=*data;
838
0
  }
839
0
  else
840
0
    *offset+=1;
841
0
}
842
843
0
static void field_objName(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
844
0
  proto_tree *objName_tree;
845
846
  /*Objectname*/
847
0
  get_length(tvb, offset, data, length);
848
0
  objName_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_objName, NULL, "Objectname");
849
850
0
  proto_tree_add_uint (objName_tree, hf_sml_length, tvb, *offset, *length, *data);
851
0
  *offset+=*length;
852
0
  proto_tree_add_item (objName_tree, hf_sml_objName, tvb, *offset, *data, ENC_NA);
853
0
  *offset+=*data;
854
0
}
855
856
0
static void field_status(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
857
0
  proto_tree *status_tree = NULL;
858
859
0
  get_length(tvb, offset, data, length);
860
0
  status_tree = proto_tree_add_subtree_format(insert_tree, tvb, *offset, *length + *data,
861
0
            ett_sml_status, NULL, "status %s", (*data == 0)? ": NOT SET" : "");
862
863
0
  if (*data > 0){
864
0
    proto_tree_add_item (status_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
865
0
    *offset+=1;
866
0
    proto_tree_add_item (status_tree, hf_sml_status, tvb, *offset, *data, ENC_BIG_ENDIAN);
867
0
    *offset+= *data;
868
0
  }
869
0
  else
870
0
    *offset+=1;
871
0
}
872
873
0
static void field_unit(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
874
0
  proto_item *unit = NULL;
875
0
  proto_tree *unit_tree = NULL;
876
877
  /*unit OPTIONAL*/
878
0
  get_length(tvb, offset, data, length);
879
0
  unit = proto_tree_add_uint_format (insert_tree, hf_sml_unit, tvb, *offset, *length + *data, *length + *data, "Unit %s", (*data == 0)? ": NOT SET" : "");
880
0
  if (*data > 0) {
881
0
    unit_tree = proto_item_add_subtree (unit, ett_sml_unit);
882
0
    proto_tree_add_item (unit_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
883
0
    *offset+=1;
884
0
    proto_tree_add_item(unit_tree, hf_sml_unit, tvb, *offset, 1, ENC_BIG_ENDIAN);
885
0
    *offset+=1;
886
0
  }
887
0
  else
888
0
    *offset+=1;
889
0
}
890
891
0
static void field_scaler(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
892
0
  proto_item *scaler = NULL;
893
0
  proto_tree *scaler_tree = NULL;
894
895
  /*Scaler OPTIONAL*/
896
0
  get_length(tvb, offset, data, length);
897
0
  scaler = proto_tree_add_uint_format (insert_tree, hf_sml_scaler, tvb, *offset, *length + *data, *length + *data, "Scaler %s", (*data == 0)? ": NOT SET" : "");
898
899
0
  if (*data > 0){
900
0
    scaler_tree = proto_item_add_subtree (scaler, ett_sml_scaler);
901
0
    proto_tree_add_item (scaler_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
902
0
    *offset+=1;
903
0
    proto_tree_add_item(scaler_tree, hf_sml_scaler, tvb, *offset, 1, ENC_BIG_ENDIAN);
904
0
    *offset+=1;
905
0
  }
906
0
  else
907
0
    *offset+=1;
908
0
}
909
910
0
static void field_valueSignature(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
911
0
  proto_item *valueSignature = NULL;
912
0
  proto_tree *valueSignature_tree = NULL;
913
914
  /*value Signature*/
915
0
  get_length(tvb, offset, data, length);
916
0
  valueSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_valueSignature, tvb, *offset, *length + *data, NULL, "ValueSignature %s", (*data == 0)? ": NOT SET" : "");
917
918
0
  if (*data > 0){
919
0
    valueSignature_tree = proto_item_add_subtree (valueSignature, ett_sml_valueSignature);
920
0
    proto_tree_add_uint (valueSignature_tree, hf_sml_length, tvb, *offset, *length, *data);
921
0
    *offset+=*length;
922
0
    proto_tree_add_item (valueSignature_tree, hf_sml_valueSignature, tvb, *offset, *data, ENC_NA);
923
0
    *offset+=*data;
924
0
  }
925
0
  else
926
0
    *offset+=1;
927
0
}
928
929
0
static void field_parameterTreePath(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
930
0
  proto_item *parameterTreePath = NULL;
931
0
  proto_tree *parameterTreePath_tree = NULL;
932
933
  /*parameterTreePath*/
934
0
  get_length(tvb, offset, data, length);
935
0
  parameterTreePath = proto_tree_add_bytes_format (insert_tree, hf_sml_parameterTreePath, tvb, *offset, *length + *data, NULL, "path_Entry %s", (*data == 0)? ": NOT SET" : "");
936
937
0
  parameterTreePath_tree = proto_item_add_subtree (parameterTreePath, ett_sml_parameterTreePath);
938
0
  proto_tree_add_uint (parameterTreePath_tree, hf_sml_length, tvb, *offset, *length, *data);
939
0
  *offset+=*length;
940
0
  proto_tree_add_item (parameterTreePath_tree, hf_sml_parameterTreePath, tvb, *offset, *data, ENC_NA);
941
0
  *offset+=*data;
942
0
}
943
944
0
static void field_ObjReqEntry(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
945
0
  proto_tree *object_list_Entry_tree;
946
947
  /*parameterTreePath*/
948
0
  get_length(tvb, offset, data, length);
949
0
  object_list_Entry_tree = proto_tree_add_subtree(insert_tree, tvb ,*offset, *length + *data, ett_sml_object_list_Entry, NULL, "object_list_Entry");
950
0
  proto_tree_add_uint (object_list_Entry_tree, hf_sml_length, tvb, *offset, *length, *data);
951
0
  *offset+=*length;
952
0
  proto_tree_add_item (object_list_Entry_tree, hf_sml_object_list_Entry, tvb, *offset, *data, ENC_NA);
953
0
  *offset+=*data;
954
0
}
955
956
0
static void field_regPeriod(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
957
0
  proto_tree *regPeriod_tree;
958
959
0
  get_length(tvb, offset, data, length);
960
0
  regPeriod_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_regPeriod, NULL, "regPeriod");
961
962
0
  proto_tree_add_item (regPeriod_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
963
0
  *offset+=1;
964
0
  proto_tree_add_item (regPeriod_tree, hf_sml_regPeriod, tvb, *offset, *data, ENC_BIG_ENDIAN);
965
0
  *offset+=*data;
966
0
}
967
968
0
static void field_rawdata(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
969
0
  proto_item *rawdata = NULL;
970
0
  proto_tree *rawdata_tree = NULL;
971
972
  /*rawdata*/
973
0
  get_length(tvb, offset, data, length);
974
0
  rawdata = proto_tree_add_bytes_format (insert_tree, hf_sml_rawdata, tvb, *offset, *length + *data, NULL, "rawdata %s", (*data == 0)? ": NOT SET" : "");
975
976
0
  if (*data > 0){
977
0
    rawdata_tree = proto_item_add_subtree (rawdata, ett_sml_rawdata);
978
0
    proto_tree_add_uint (rawdata_tree, hf_sml_length, tvb, *offset, *length, *data);
979
0
    *offset+=*length;
980
0
    proto_tree_add_item (rawdata_tree, hf_sml_rawdata, tvb, *offset, *data, ENC_NA);
981
0
    *offset+=*data;
982
0
  }
983
0
  else
984
0
    *offset+=1;
985
0
}
986
987
0
static void field_periodSignature(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
988
0
  proto_item *periodSignature = NULL;
989
0
  proto_tree *periodSignature_tree = NULL;
990
991
  /*periodSignature*/
992
0
  get_length(tvb, offset, data, length);
993
0
  periodSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_periodSignature, tvb, *offset, *length + *data, NULL,"periodSignature %s", (*data == 0)? ": NOT SET" : "");
994
995
0
  if (*data > 0){
996
0
    periodSignature_tree = proto_item_add_subtree (periodSignature, ett_sml_periodSignature);
997
0
    proto_tree_add_uint (periodSignature_tree, hf_sml_length, tvb, *offset, *length, *data);
998
0
    *offset+=*length;
999
0
    proto_tree_add_item (periodSignature_tree, hf_sml_periodSignature, tvb, *offset, *data, ENC_NA);
1000
0
    *offset+=*data;
1001
0
  }
1002
0
  else
1003
0
    *offset+=1;
1004
0
}
1005
/*
1006
static void field_actTime(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
1007
  proto_tree *actTime_tree;
1008
1009
  get_length(tvb, offset, data, length);
1010
  actTime_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_actTime, NULL, "actTime");
1011
  proto_tree_add_item (actTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1012
  *offset+=1;
1013
  proto_tree_add_item(actTime_tree, hf_sml_actTime, tvb, *offset, *data, ENC_BIG_ENDIAN);
1014
  *offset+=*data;
1015
}
1016
1017
static void field_valTime(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
1018
  proto_tree *valTime_tree;
1019
1020
  get_length(tvb, offset, data, length);
1021
  valTime_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_valTime, NULL, "valTime");
1022
  proto_tree_add_item (valTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1023
  *offset+=1;
1024
  proto_tree_add_item(valTime_tree, hf_sml_valTime, tvb, *offset, *data, ENC_BIG_ENDIAN);
1025
  *offset+=*data;
1026
}
1027
*/
1028
0
static void TupleEntryTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *procParValue_tree, unsigned *offset){
1029
0
  proto_item *SML_time;
1030
0
  proto_item *TupleEntry;
1031
1032
0
  proto_tree *TupleEntry_list = NULL;
1033
0
  proto_tree *SML_time_tree = NULL;
1034
  //proto_tree *secIndex_tree = NULL;
1035
0
  proto_tree *unit_pA_tree = NULL;
1036
0
  proto_tree *scaler_pA_tree = NULL;
1037
0
  proto_tree *value_pA_tree = NULL;
1038
0
  proto_tree *unit_mA_tree = NULL;
1039
0
  proto_tree *scaler_mA_tree = NULL;
1040
0
  proto_tree *value_mA_tree = NULL;
1041
0
  proto_tree *unit_R1_tree = NULL;
1042
0
  proto_tree *scaler_R1_tree = NULL;
1043
0
  proto_tree *value_R1_tree = NULL;
1044
0
  proto_tree *unit_R2_tree = NULL;
1045
0
  proto_tree *scaler_R2_tree = NULL;
1046
0
  proto_tree *value_R2_tree = NULL;
1047
0
  proto_tree *unit_R3_tree = NULL;
1048
0
  proto_tree *scaler_R3_tree = NULL;
1049
0
  proto_tree *value_R3_tree = NULL;
1050
0
  proto_tree *unit_R4_tree = NULL;
1051
0
  proto_tree *scaler_R4_tree = NULL;
1052
0
  proto_tree *value_R4_tree = NULL;
1053
0
  proto_tree *signature_pA_R1_R4_tree = NULL;
1054
0
  proto_tree *signature_mA_R2_R3_tree = NULL;
1055
1056
0
  unsigned data = 0;
1057
0
  unsigned length = 0;
1058
1059
  /*Tuple_List*/
1060
0
  TupleEntry_list = proto_tree_add_subtree(procParValue_tree, tvb, *offset, -1, ett_sml_tuple, &TupleEntry, "TupleEntry");
1061
0
  get_length(tvb, offset, &data, &length);
1062
0
  *offset+=length;
1063
1064
  /*Server Id*/
1065
0
  field_serverId(tvb, TupleEntry_list, offset, &data, &length);
1066
1067
  /*secindex*/
1068
0
  SML_time_tree = proto_tree_add_subtree(procParValue_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "secIndex");
1069
0
  *offset+=1;
1070
0
  sml_time_type(tvb, pinfo, SML_time_tree, offset);
1071
0
  proto_item_set_end(SML_time, tvb, *offset);
1072
1073
  /*Sml Status OPTIONAL*/
1074
0
  field_status(tvb, TupleEntry_list, offset, &data, &length);
1075
1076
  /*unit_pA*/
1077
0
  unit_pA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_pA, NULL, "unit_pA");
1078
0
  proto_tree_add_item (unit_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1079
0
  *offset+=1;
1080
0
  proto_tree_add_item (unit_pA_tree, hf_sml_unit_pA, tvb, *offset, 1, ENC_BIG_ENDIAN);
1081
0
  *offset+=1;
1082
1083
  /*scaler_pA*/
1084
0
  scaler_pA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_pA, NULL, "scaler_pA");
1085
0
  proto_tree_add_item (scaler_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1086
0
  *offset+=1;
1087
0
  proto_tree_add_item (scaler_pA_tree, hf_sml_scaler_pA, tvb, *offset, 1, ENC_BIG_ENDIAN);
1088
0
  *offset+=1;
1089
1090
  /*value_pA*/
1091
0
  get_length(tvb, offset, &data, &length);
1092
0
  value_pA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_pA, NULL, "value_pA");
1093
0
  proto_tree_add_item (value_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1094
0
  *offset+=1;
1095
0
  proto_tree_add_item (value_pA_tree, hf_sml_value_pA, tvb, *offset, data, ENC_BIG_ENDIAN);
1096
0
  *offset+=data;
1097
1098
  /*unit_R1*/
1099
0
  unit_R1_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_R1, NULL, "unit_R1");
1100
0
  proto_tree_add_item (unit_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1101
0
  *offset+=1;
1102
0
  proto_tree_add_item (unit_R1_tree, hf_sml_unit_R1, tvb, *offset, 1, ENC_BIG_ENDIAN);
1103
0
  *offset+=1;
1104
1105
  /*scaler_R1*/
1106
0
  scaler_R1_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 1, ett_sml_scaler_R1, NULL, "scaler_R1");
1107
0
  proto_tree_add_item (scaler_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1108
0
  *offset+=1;
1109
0
  proto_tree_add_item (scaler_R1_tree, hf_sml_scaler_R1, tvb, *offset, 1, ENC_BIG_ENDIAN);
1110
0
  *offset+=1;
1111
1112
  /*value_R1*/
1113
0
  get_length(tvb, offset, &data, &length);
1114
0
  value_R1_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_R1, NULL, "value_R1");
1115
0
  proto_tree_add_item (value_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1116
0
  *offset+=1;
1117
0
  proto_tree_add_item (value_R1_tree, hf_sml_value_R1, tvb, *offset, data, ENC_BIG_ENDIAN);
1118
0
  *offset+=data;
1119
1120
  /*unit_R4*/
1121
0
  unit_R4_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_R4, NULL, "unit_R4");
1122
0
  proto_tree_add_item (unit_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1123
0
  *offset+=1;
1124
0
  proto_tree_add_item (unit_R4_tree, hf_sml_unit_R4, tvb, *offset, 1, ENC_BIG_ENDIAN);
1125
0
  *offset+=1;
1126
1127
  /*scaler_R4*/
1128
0
  scaler_R4_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_R4, NULL, "scaler_R4");
1129
0
  proto_tree_add_item (scaler_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1130
0
  *offset+=1;
1131
0
  proto_tree_add_item (scaler_R4_tree, hf_sml_scaler_R4, tvb, *offset, 1, ENC_BIG_ENDIAN);
1132
0
  *offset+=1;
1133
1134
  /*value_R4*/
1135
0
  get_length(tvb, offset, &data, &length);
1136
0
  value_R4_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_R4, NULL, "value_R4");
1137
0
  proto_tree_add_item (value_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1138
0
  *offset+=1;
1139
0
  proto_tree_add_item (value_R4_tree, hf_sml_value_R4, tvb, *offset, data, ENC_BIG_ENDIAN);
1140
0
  *offset+=data;
1141
1142
  /*signature_pA_R1_R4*/
1143
0
  get_length(tvb, offset, &data, &length);
1144
0
  signature_pA_R1_R4_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_signature_pA_R1_R4, NULL, "signature_pa_R1_R4");
1145
0
  proto_tree_add_uint (signature_pA_R1_R4_tree, hf_sml_length, tvb, *offset, length, data);
1146
0
  *offset+=length;
1147
0
  proto_tree_add_item (signature_pA_R1_R4_tree, hf_sml_signature_pA_R1_R4, tvb, *offset, data, ENC_NA);
1148
0
  *offset+=data;
1149
1150
  /*unit_mA*/
1151
0
  unit_mA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_mA, NULL, "unit_mA");
1152
0
  proto_tree_add_item (unit_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1153
0
  *offset+=1;
1154
0
  proto_tree_add_item (unit_mA_tree, hf_sml_unit_mA, tvb, *offset, 1, ENC_BIG_ENDIAN);
1155
0
  *offset+=1;
1156
1157
  /*scaler_mA*/
1158
0
  scaler_mA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_mA, NULL, "scaler_mA");
1159
0
  proto_tree_add_item (scaler_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1160
0
  *offset+=1;
1161
0
  proto_tree_add_item (scaler_mA_tree, hf_sml_scaler_mA, tvb, *offset, 1, ENC_BIG_ENDIAN);
1162
0
  *offset+=1;
1163
1164
  /*value_mA*/
1165
0
  get_length(tvb, offset, &data, &length);
1166
0
  value_mA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_mA, NULL, "value_mA");
1167
0
  proto_tree_add_item (value_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1168
0
  *offset+=1;
1169
0
  proto_tree_add_item (value_mA_tree, hf_sml_value_mA, tvb, *offset, data, ENC_BIG_ENDIAN);
1170
0
  *offset+=data;
1171
1172
  /*unit_R2*/
1173
0
  unit_R2_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_R2, NULL, "unit_R2");
1174
0
  proto_tree_add_item (unit_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1175
0
  *offset+=1;
1176
0
  proto_tree_add_item (unit_R2_tree, hf_sml_unit_R2, tvb, *offset, 1, ENC_BIG_ENDIAN);
1177
0
  *offset+=1;
1178
1179
  /*scaler_R2*/
1180
0
  scaler_R2_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_R2, NULL, "scaler_R2");
1181
0
  proto_tree_add_item (scaler_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1182
0
  *offset+=1;
1183
0
  proto_tree_add_item (scaler_R2_tree, hf_sml_scaler_R2, tvb, *offset, 1, ENC_BIG_ENDIAN);
1184
0
  *offset+=1;
1185
1186
  /*value_R2*/
1187
0
  get_length(tvb, offset, &data, &length);
1188
0
  value_R2_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_R2, NULL, "value_R2");
1189
0
  proto_tree_add_item (value_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1190
0
  *offset+=1;
1191
0
  proto_tree_add_item (value_R2_tree, hf_sml_value_R2, tvb, *offset, data, ENC_BIG_ENDIAN);
1192
0
  *offset+=data;
1193
1194
  /*unit_R3*/
1195
0
  unit_R3_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_R3, NULL, "unit_R3");
1196
0
  proto_tree_add_item (unit_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1197
0
  *offset+=1;
1198
0
  proto_tree_add_item (unit_R3_tree, hf_sml_unit_R3, tvb, *offset, 1, ENC_BIG_ENDIAN);
1199
0
  *offset+=1;
1200
1201
  /*scaler_R3*/
1202
0
  scaler_R3_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_R3, NULL, "scaler_R3");
1203
0
  proto_tree_add_item (scaler_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1204
0
  *offset+=1;
1205
0
  proto_tree_add_item (scaler_R3_tree, hf_sml_scaler_R3, tvb, *offset, 1, ENC_BIG_ENDIAN);
1206
0
  *offset+=1;
1207
1208
  /*value_R3*/
1209
0
  get_length(tvb, offset, &data, &length);
1210
0
  value_R3_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_R3, NULL, "value_R3");
1211
0
  proto_tree_add_item (value_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1212
0
  *offset+=1;
1213
0
  proto_tree_add_item (value_R3_tree, hf_sml_value_R3, tvb, *offset, data, ENC_BIG_ENDIAN);
1214
0
  *offset+=data;
1215
1216
  /*signature_mA_R2_R3*/
1217
0
  get_length(tvb, offset, &data, &length);
1218
0
  signature_mA_R2_R3_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_signature_mA_R2_R3, NULL, "signature_mA_R2_R3");
1219
0
  proto_tree_add_uint (signature_mA_R2_R3_tree, hf_sml_length, tvb, *offset, length, data);
1220
0
  *offset+=length;
1221
0
  proto_tree_add_item (signature_mA_R2_R3_tree, hf_sml_signature_mA_R2_R3, tvb, *offset, data, ENC_NA);
1222
0
  *offset+=data;
1223
1224
0
  proto_item_set_end(TupleEntry, tvb, *offset);
1225
0
}
1226
1227
// NOLINTNEXTLINE(misc-no-recursion)
1228
0
static void child_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
1229
0
  proto_item *parameterName;
1230
0
  proto_item *procParValue;
1231
0
  proto_item *child;
1232
0
  proto_item *periodEntry;
1233
0
  proto_item *SML_time;
1234
0
  proto_item *listEntry;
1235
0
  proto_item *tree_Entry;
1236
1237
0
  proto_tree *parameterName_tree = NULL;
1238
0
  proto_tree *procParValue_tree = NULL;
1239
0
  proto_tree *procParValuetype_tree = NULL;
1240
0
  proto_tree *periodEntry_tree = NULL;
1241
0
  proto_tree *SML_time_tree = NULL;
1242
0
  proto_tree *listEntry_tree = NULL;
1243
  //proto_tree *procParValueTime_tree = NULL;
1244
0
  proto_tree *child_list = NULL;
1245
0
  proto_tree *tree_Entry_list = NULL;
1246
1247
0
  unsigned i = 0;
1248
0
  unsigned repeat = 0;
1249
0
  unsigned check = 0;
1250
1251
  /*parameterName*/
1252
0
  get_length(tvb, offset, data, length);
1253
0
  parameterName_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_parameterName, &parameterName, "parameterName");
1254
0
  proto_tree_add_uint (parameterName_tree, hf_sml_length, tvb, *offset, *length, *data);
1255
0
  *offset+=*length;
1256
0
  proto_tree_add_item (parameterName_tree, hf_sml_parameterName, tvb, *offset, *data, ENC_NA);
1257
0
  *offset+=*data;
1258
1259
  /*procParValue OPTIONAL*/
1260
0
  check = tvb_get_uint8(tvb, *offset);
1261
1262
0
  if (check == OPTIONAL){
1263
0
    procParValue = proto_tree_add_item(insert_tree, hf_sml_procParValue, tvb, *offset, 1, ENC_BIG_ENDIAN);
1264
0
    proto_item_append_text(procParValue, ": NOT SET");
1265
0
    *offset+=1;
1266
0
  }
1267
0
  else if (check == 0x72){
1268
0
    get_length(tvb, offset, data, length);
1269
0
    procParValue_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, -1, ett_sml_procParValue, &procParValue, "ProcParValue");
1270
0
    *offset+=1;
1271
1272
    /*procParValue CHOOSE*/
1273
0
    procParValuetype_tree = proto_tree_add_subtree(procParValue_tree, tvb, *offset, 2, ett_sml_procParValuetype, NULL, "ProcParValueType");
1274
0
    proto_tree_add_item (procParValuetype_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1275
0
    *offset+=1;
1276
0
    check = tvb_get_uint8(tvb, *offset);
1277
0
    proto_tree_add_item (procParValuetype_tree, hf_sml_procParValue, tvb, *offset, 1 ,ENC_BIG_ENDIAN);
1278
0
    *offset+=1;
1279
1280
0
    switch (check) {
1281
0
      case PROC_VALUE:
1282
        /*value*/
1283
0
        sml_value(tvb, pinfo, procParValue_tree, offset, data, length);
1284
0
        break;
1285
1286
0
      case PROC_PERIOD:
1287
        /*period*/
1288
0
        get_length(tvb, offset, data, length);
1289
0
        periodEntry_tree = proto_tree_add_subtree_format(procParValue_tree, tvb, *offset, -1, ett_sml_periodEntry, &periodEntry,
1290
0
                    "PeriodEntry List with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1291
0
        *offset+=*length;
1292
1293
        /*objName*/
1294
0
        field_objName(tvb, periodEntry_tree, offset, data, length);
1295
1296
        /*unit OPTIONAL*/
1297
0
        field_unit(tvb, periodEntry_tree, offset, data, length);
1298
1299
        /*scaler OPTIONAL*/
1300
0
        field_scaler(tvb, periodEntry_tree, offset, data, length);
1301
1302
        /*value*/
1303
0
        sml_value(tvb, pinfo, periodEntry_tree, offset, data, length);
1304
1305
        /*value Signature*/
1306
0
        field_valueSignature(tvb, periodEntry_tree, offset, data, length);
1307
1308
0
        proto_item_set_end(periodEntry, tvb, *offset);
1309
0
        break;
1310
1311
0
      case PROC_TUPLE:
1312
        /*TupleEntry*/
1313
0
        if (tvb_get_uint8(tvb, *offset) == 0xF1 && tvb_get_uint8(tvb, *offset+1) == 0x07){
1314
0
          TupleEntryTree(tvb, pinfo, procParValue_tree, offset);
1315
0
        }
1316
0
        else {
1317
0
          expert_add_info(pinfo, NULL, &ei_sml_tuple_error);
1318
0
          return;
1319
0
        }
1320
0
        break;
1321
1322
0
      case PROC_TIME:
1323
0
        SML_time_tree = proto_tree_add_subtree(procParValue_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "Time");
1324
0
        *offset+=1;
1325
0
        sml_time_type(tvb, pinfo, SML_time_tree, offset);
1326
0
        proto_item_set_end(SML_time, tvb, *offset);
1327
0
        break;
1328
1329
0
      case PROC_LISTENTRY:
1330
        /*listEntry*/
1331
0
        get_length(tvb, offset, data, length);
1332
0
        listEntry_tree = proto_tree_add_subtree_format(procParValue_tree, tvb, *offset, -1, ett_sml_listEntry, &listEntry,
1333
0
          "ListEntry List with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1334
0
        *offset += *length;
1335
1336
        /*objName*/
1337
0
        field_objName(tvb, listEntry_tree, offset, data, length);
1338
1339
        /*status OPTIONAL*/
1340
0
        field_status(tvb, listEntry_tree, offset, data, length);
1341
1342
        /*valTime OPTIONAL*/
1343
0
        SML_time_tree = proto_tree_add_subtree(listEntry_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "Time");
1344
0
        *offset += 1;
1345
0
        sml_time_type(tvb, pinfo, SML_time_tree, offset);
1346
0
        proto_item_set_end(SML_time, tvb, *offset);
1347
1348
        /*unit OPTIONAL*/
1349
0
        field_unit(tvb, listEntry_tree, offset, data, length);
1350
1351
        /*scaler OPTIONAL*/
1352
0
        field_scaler(tvb, listEntry_tree, offset, data, length);
1353
1354
        /*value*/
1355
0
        sml_value(tvb, pinfo, listEntry_tree, offset, data, length);
1356
1357
        /*valueSignature OPTIONAL*/
1358
0
        field_valueSignature(tvb, listEntry_tree, offset, data, length);
1359
1360
0
        proto_item_set_end(listEntry, tvb, *offset);
1361
0
        break;
1362
1363
0
      default:
1364
0
        expert_add_info(pinfo, procParValue, &ei_sml_procParValue_invalid);
1365
0
        break;
1366
0
    }
1367
0
    proto_item_set_end(procParValue, tvb, *offset);
1368
0
  }
1369
0
  else {
1370
0
    expert_add_info(pinfo, NULL, &ei_sml_procParValue_errror);
1371
0
    return;
1372
0
  }
1373
1374
  /*child list OPTIONAL*/
1375
0
  check = tvb_get_uint8(tvb, *offset);
1376
1377
0
  child_list = proto_tree_add_subtree(insert_tree, tvb, *offset, -1, ett_sml_child, &child, "Child List");
1378
0
  if (check == OPTIONAL){
1379
0
    proto_item_append_text(child, ": NOT SET");
1380
0
    proto_item_set_len(child, 1);
1381
0
    *offset+=1;
1382
0
  }
1383
0
  else if ((check & 0x0F) != 0){
1384
0
    if (check == 0x71){
1385
0
      get_length(tvb, offset, data, length);
1386
0
      proto_item_append_text(child, "with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1387
0
      *offset+=1;
1388
1389
0
      tree_Entry_list = proto_tree_add_subtree(child_list, tvb, *offset, -1, ett_sml_tree_Entry, &tree_Entry, "tree_Entry");
1390
0
      *offset+=1;
1391
1392
0
      increment_dissection_depth(pinfo);
1393
0
      child_tree(tvb, pinfo,tree_Entry_list, offset, data, length);
1394
0
      decrement_dissection_depth(pinfo);
1395
1396
0
      proto_item_set_end(tree_Entry, tvb, *offset);
1397
0
      proto_item_set_end(child, tvb, *offset);
1398
0
    }
1399
0
    else if ((check & 0xF0) == SHORT_LIST || (check & 0xF0) == LONG_LIST){
1400
0
      get_length(tvb, offset, data, length);
1401
0
      repeat = *length + *data;
1402
0
      proto_item_append_text(child, "with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1403
0
      if (repeat <= 0){
1404
0
        expert_add_info_format(pinfo, child, &ei_sml_invalid_count, "invalid loop count");
1405
0
        return;
1406
0
      }
1407
0
      *offset+=*length;
1408
1409
0
      for(i =0 ; i < repeat; i++){
1410
0
        tree_Entry_list = proto_tree_add_subtree(child_list, tvb, *offset, -1, ett_sml_tree_Entry, &tree_Entry, "tree_Entry");
1411
1412
0
        if (tvb_get_uint8(tvb, *offset) != 0x73){
1413
0
          expert_add_info_format(pinfo, tree_Entry, &ei_sml_invalid_count, "invalid count of elements in tree_Entry");
1414
0
          return;
1415
0
        }
1416
0
        *offset+=1;
1417
1418
0
        increment_dissection_depth(pinfo);
1419
0
        child_tree(tvb, pinfo, tree_Entry_list, offset, data, length);
1420
0
        decrement_dissection_depth(pinfo);
1421
0
        proto_item_set_end(tree_Entry, tvb, *offset);
1422
0
      }
1423
0
      proto_item_set_end(child, tvb, *offset);
1424
0
    }
1425
0
  }
1426
0
  else {
1427
0
    expert_add_info_format(pinfo, child, &ei_sml_invalid_count, "invalid count of elements in child List");
1428
0
  }
1429
0
}
1430
1431
/*messagetypes*/
1432
0
static void decode_PublicOpenReq (tvbuff_t *tvb, proto_tree *messagebodytree_list, unsigned *offset){
1433
0
  unsigned data = 0;
1434
0
  unsigned length = 0;
1435
1436
  /*Codepage OPTIONAL*/
1437
0
  field_codepage (tvb, messagebodytree_list, offset, &data, &length);
1438
1439
  /*clientID*/
1440
0
  field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1441
1442
  /*reqFileId*/
1443
0
  field_reqFileId (tvb, messagebodytree_list, offset, &data, &length);
1444
1445
  /*ServerID*/
1446
0
  field_serverId(tvb,messagebodytree_list, offset, &data, &length);
1447
1448
  /*user*/
1449
0
  field_username(tvb,messagebodytree_list, offset, &data, &length);
1450
1451
  /*password*/
1452
0
  field_password(tvb,messagebodytree_list, offset, &data, &length);
1453
1454
  /*sml-Version OPTIONAL*/
1455
0
  field_smlVersion(tvb,messagebodytree_list, offset, &data, &length);
1456
0
}
1457
1458
0
static void decode_PublicOpenRes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1459
0
  proto_item *SML_time = NULL;
1460
1461
  //proto_tree *refTime_tree = NULL;
1462
0
  proto_tree *SML_time_tree = NULL;
1463
1464
0
  unsigned data = 0;
1465
0
  unsigned length = 0;
1466
1467
  /*Codepage OPTIONAL*/
1468
0
  field_codepage (tvb, messagebodytree_list, offset, &data, &length);
1469
1470
  /*clientID OPTIONAL*/
1471
0
  field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1472
1473
  /*reqFileId*/
1474
0
  field_reqFileId (tvb, messagebodytree_list, offset, &data, &length);
1475
1476
  /*ServerID*/
1477
0
  field_serverId(tvb,messagebodytree_list,offset, &data, &length);
1478
1479
  /*RefTime Optional*/
1480
0
  get_length(tvb, offset, &data, &length);
1481
1482
0
  SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "refTime");
1483
0
  if (data == 0){
1484
0
    proto_item_append_text(SML_time, ": NOT SET");
1485
0
    proto_item_set_len(SML_time, length + data);
1486
0
    *offset+=1;
1487
0
  }
1488
0
  else{
1489
    /*SML TIME*/
1490
0
    *offset+=1;
1491
0
    sml_time_type(tvb, pinfo, SML_time_tree, offset);
1492
0
    proto_item_set_end(SML_time,tvb,*offset);
1493
0
  }
1494
  /*sml-Version OPTIONAL*/
1495
0
  field_smlVersion(tvb, messagebodytree_list, offset, &data, &length);
1496
0
}
1497
1498
0
static bool decode_GetProfile_List_Pack_Req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1499
0
  proto_item *withRawdata = NULL;
1500
0
  proto_item *SML_time = NULL;
1501
0
  proto_item *treepath = NULL;
1502
0
  proto_item *object_list = NULL;
1503
0
  proto_item *dasDetails = NULL;
1504
1505
0
  proto_tree *withRawdata_tree = NULL;
1506
0
  proto_tree *SML_time_tree = NULL;
1507
  //proto_tree *beginTime_tree = NULL;
1508
0
  proto_tree *treepath_list = NULL;
1509
0
  proto_tree *object_list_list = NULL;
1510
  //proto_tree *endTime_tree = NULL;
1511
0
  proto_tree *dasDetails_list = NULL;
1512
1513
0
  unsigned i = 0;
1514
0
  unsigned repeat = 0;
1515
0
  unsigned check = 0;
1516
0
  unsigned data = 0;
1517
0
  unsigned length = 0;
1518
1519
  /*ServerID*/
1520
0
  field_serverId(tvb,messagebodytree_list, offset, &data, &length);
1521
1522
  /*user*/
1523
0
  field_username(tvb,messagebodytree_list, offset, &data, &length);
1524
1525
  /*password*/
1526
0
  field_password(tvb,messagebodytree_list, offset, &data, &length);
1527
1528
  /*withRawdata OPTIONAL*/
1529
0
  get_length(tvb, offset, &data, &length);
1530
0
  withRawdata = proto_tree_add_uint_format (messagebodytree_list, hf_sml_withRawdata, tvb, *offset, data+length, data+length, "withRawdata %s", (data == 0)? ": NOT SET" : "");
1531
1532
0
  if (data > 0) {
1533
0
    withRawdata_tree = proto_item_add_subtree (withRawdata, ett_sml_withRawdata);
1534
0
    proto_tree_add_item (withRawdata_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1535
0
    *offset+=1;
1536
0
    proto_tree_add_item (withRawdata_tree, hf_sml_withRawdata, tvb, *offset, 1, ENC_BIG_ENDIAN);
1537
0
    *offset+=1;
1538
0
  }
1539
0
  else
1540
0
    *offset+=1;
1541
1542
  /*beginTime OPTIONAL*/
1543
0
  get_length(tvb, offset, &data, &length);
1544
1545
0
  SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "beginTime");
1546
0
  if (data == 0){
1547
0
    proto_item_append_text(SML_time, ": NOT SET");
1548
0
    proto_item_set_len(SML_time, length + data);
1549
0
    *offset+=1;
1550
0
  }
1551
0
  else {
1552
    /*SML TIME*/
1553
0
    *offset+=1;
1554
0
    sml_time_type(tvb, pinfo, SML_time_tree, offset);
1555
0
    proto_item_set_end(SML_time,tvb,*offset);
1556
0
  }
1557
1558
  /*endTime OPTIONAL*/
1559
0
  get_length(tvb, offset, &data, &length);
1560
1561
0
  SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "endTime");
1562
0
  if (data == 0){
1563
0
    proto_item_append_text(SML_time, ": NOT SET");
1564
0
    proto_item_set_len(SML_time, length + data);
1565
0
    *offset+=1;
1566
0
  }
1567
0
  else {
1568
    /*SML TIME*/
1569
0
    *offset+=1;
1570
0
    sml_time_type(tvb, pinfo, SML_time_tree, offset);
1571
0
    proto_item_set_end(SML_time,tvb,*offset);
1572
0
  }
1573
1574
  /*Treepath List*/
1575
0
  get_length(tvb, offset, &data, &length);
1576
0
  repeat = (data+length);
1577
0
  treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
1578
0
          "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1579
1580
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1581
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in Treepath");
1582
0
    return true;
1583
0
  }
1584
0
  else if (repeat <= 0){
1585
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1586
0
    return true;
1587
0
  }
1588
0
  *offset+=length;
1589
1590
0
  for (i=0; i< repeat; i++) {
1591
0
    field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1592
0
  }
1593
0
  proto_item_set_end(treepath, tvb, *offset);
1594
1595
  /*object_list*/
1596
0
  object_list_list = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_object_list, &object_list, "object_List");
1597
0
  if (tvb_get_uint8(tvb,*offset) == OPTIONAL){
1598
0
    proto_item_append_text(object_list, ": NOT SET");
1599
0
    proto_item_set_len(object_list, 1);
1600
0
    *offset+=1;
1601
0
  }
1602
0
  else{
1603
0
    get_length(tvb, offset, &data, &length);
1604
0
    repeat = (data+length);
1605
0
    proto_item_append_text(object_list, " with %d %s", length+data, plurality(length+data, "element", "elements"));
1606
1607
0
    if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1608
0
      expert_add_info_format(pinfo, object_list, &ei_sml_invalid_count, "invalid count of elements in object_List");
1609
0
      return true;
1610
0
    }
1611
0
    else if (repeat <= 0){
1612
0
      expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1613
0
      return true;
1614
0
    }
1615
1616
0
    *offset+=length;
1617
1618
0
    for (i=0; i< repeat; i++) {
1619
0
      field_ObjReqEntry(tvb, object_list_list, offset, &data, &length);
1620
0
    }
1621
0
    proto_item_set_end(object_list, tvb, *offset);
1622
0
  }
1623
1624
  /*dasDetails*/
1625
0
  check = tvb_get_uint8(tvb,*offset);
1626
1627
0
  dasDetails_list = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_dasDetails, &dasDetails, "dasDetails");
1628
0
  if (check == OPTIONAL){
1629
0
    proto_item_append_text(dasDetails, ": NOT SET");
1630
0
    proto_item_set_len(dasDetails, 1);
1631
0
    *offset+=1;
1632
0
  }
1633
0
  else if ((check & 0xF0) == LONG_LIST || (check & 0xF0) == SHORT_LIST){
1634
0
    get_length(tvb, offset, &data, &length);
1635
0
    proto_item_append_text(dasDetails, " with %d %s", length+data, plurality(length+data, "element", "elements"));
1636
0
    *offset+=length;
1637
1638
0
    child_tree(tvb, pinfo, dasDetails_list, offset, &data, &length);
1639
0
    proto_item_set_end(dasDetails, tvb, *offset);
1640
0
  }
1641
0
  else {
1642
0
    expert_add_info_format(pinfo, dasDetails, &ei_sml_invalid_count, "invalid count of elements in dasDetails");
1643
0
    return true;
1644
0
  }
1645
0
  return false;
1646
0
}
1647
1648
0
static bool decode_GetProfilePackRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1649
0
  proto_item *SML_time = NULL;
1650
0
  proto_item *treepath = NULL;
1651
0
  proto_item *periodList = NULL;
1652
0
  proto_item *period_List_Entry = NULL;
1653
0
  proto_item *headerList = NULL;
1654
0
  proto_item *header_List_Entry = NULL;
1655
0
  proto_item *profileSignature = NULL;
1656
0
  proto_item *valuelist = NULL;
1657
0
  proto_item *value_List_Entry = NULL;
1658
1659
0
  proto_tree *SML_time_tree = NULL;
1660
0
  proto_tree *treepath_list = NULL;
1661
0
  proto_tree *periodList_list = NULL;
1662
0
  proto_tree *period_List_Entry_list = NULL;
1663
0
  proto_tree *headerList_subtree = NULL;
1664
0
  proto_tree *header_List_Entry_list = NULL;
1665
0
  proto_tree *profileSignature_tree = NULL;
1666
0
  proto_tree *valuelist_list = NULL;
1667
0
  proto_tree *value_List_Entry_list = NULL;
1668
1669
0
  unsigned i = 0;
1670
0
  unsigned d = 0;
1671
0
  unsigned repeat = 0;
1672
0
  unsigned repeat2= 0;
1673
0
  unsigned data = 0;
1674
0
  unsigned length = 0;
1675
1676
  /*ServerID*/
1677
0
  field_serverId(tvb, messagebodytree_list, offset, &data, &length);
1678
1679
  /*actTime*/
1680
0
  get_length(tvb, offset, &data, &length);
1681
0
  SML_time_tree = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time,
1682
0
        "actTime List with %d %s", length+data, plurality(length+data, "element", "elements"));
1683
0
  *offset+=1;
1684
0
  sml_time_type(tvb, pinfo, SML_time_tree, offset);
1685
0
  proto_item_set_end(SML_time,tvb,*offset);
1686
1687
  /*regPeriod*/
1688
0
  field_regPeriod(tvb, messagebodytree_list, offset, &data, &length);
1689
1690
  /*Treepath List*/
1691
0
  get_length(tvb, offset, &data, &length);
1692
0
  repeat = (data+length);
1693
0
  treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
1694
0
          "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1695
1696
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1697
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in Treepath");
1698
0
    return true;
1699
0
  }
1700
0
  else if (repeat <= 0){
1701
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1702
0
    return true;
1703
0
  }
1704
1705
0
  *offset+=length;
1706
1707
0
  for (i=0; i< repeat; i++) {
1708
0
    field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1709
0
  }
1710
0
  proto_item_set_end(treepath, tvb, *offset);
1711
1712
  /*headerList*/
1713
0
  get_length(tvb, offset, &data, &length);
1714
0
  repeat = (data+length);
1715
0
  headerList_subtree = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_headerList, &headerList,
1716
0
              "header_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1717
1718
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1719
0
    expert_add_info_format(pinfo, headerList, &ei_sml_invalid_count, "invalid count of elements in headerlist");
1720
0
    return true;
1721
0
  }
1722
0
  else if (repeat <= 0){
1723
0
    expert_add_info_format(pinfo, headerList, &ei_sml_invalid_count, "invalid loop count");
1724
0
    return true;
1725
0
  }
1726
1727
0
  *offset+=length;
1728
1729
0
  for (i=0; i< repeat; i++) {
1730
0
    get_length(tvb, offset, &data, &length);
1731
0
    header_List_Entry_list = proto_tree_add_subtree_format(headerList_subtree, tvb, *offset, -1, ett_sml_header_List_Entry, &header_List_Entry,
1732
0
                "header_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1733
0
    *offset+=1;
1734
1735
    /*objname*/
1736
0
    field_objName(tvb, header_List_Entry_list, offset, &data, &length);
1737
1738
    /*unit*/
1739
0
    field_unit(tvb, header_List_Entry_list, offset, &data, &length);
1740
1741
    /*scaler*/
1742
0
    field_scaler(tvb, header_List_Entry_list, offset, &data, &length);
1743
1744
0
    proto_item_set_end(header_List_Entry, tvb, *offset);
1745
0
  }
1746
0
  proto_item_set_end(headerList, tvb, *offset);
1747
1748
  /*period List*/
1749
0
  get_length(tvb, offset, &data, &length);
1750
0
  repeat = (data+length);
1751
0
  periodList_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_periodList, &periodList,
1752
0
        "period_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1753
1754
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1755
0
    expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid count of elements in periodList");
1756
0
    return true;
1757
0
  }
1758
0
  else if (repeat <= 0){
1759
0
    expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid loop count");
1760
0
    return true;
1761
0
  }
1762
1763
0
  *offset+=length;
1764
1765
0
  for (i=0; i< repeat; i++) {
1766
0
    get_length(tvb, offset, &data, &length);
1767
0
    period_List_Entry_list = proto_tree_add_subtree_format(periodList_list, tvb, *offset, -1, ett_sml_period_List_Entry, &period_List_Entry,
1768
0
            "period_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1769
0
    *offset+=1;
1770
1771
    /*valTime*/
1772
0
    get_length(tvb, offset, &data, &length);
1773
0
    SML_time_tree = proto_tree_add_subtree(period_List_Entry, tvb, *offset, -1, ett_sml_time, &SML_time, "valTime");
1774
0
    *offset+=1;
1775
0
    sml_time_type(tvb, pinfo, SML_time_tree, offset);
1776
0
    proto_item_set_end(SML_time,tvb, *offset);
1777
1778
    /*status*/
1779
0
    field_status(tvb, period_List_Entry_list, offset, &data, &length);
1780
1781
    /*value List*/
1782
0
    get_length(tvb, offset, &data, &length);
1783
0
    repeat2 = data + length;
1784
0
    valuelist_list = proto_tree_add_subtree_format(period_List_Entry_list, tvb, *offset, -1, ett_sml_valuelist, &valuelist,
1785
0
                     "period_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1786
1787
0
    if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1788
0
      expert_add_info_format(pinfo, valuelist, &ei_sml_invalid_count, "invalid count of elements in valueList");
1789
0
      return true;
1790
0
    }
1791
0
    else if (repeat2 <= 0){
1792
0
      expert_add_info_format(pinfo, valuelist, &ei_sml_invalid_count, "invalid loop count");
1793
0
      return true;
1794
0
    }
1795
1796
0
    *offset+=length;
1797
1798
0
    for (d=0; d< repeat2; d++) {
1799
0
      get_length(tvb, offset, &data, &length);
1800
0
      value_List_Entry_list = proto_tree_add_subtree_format(valuelist_list, tvb, *offset, -1, ett_sml_value_List_Entry, NULL,
1801
0
                  "value_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1802
0
      *offset+=1;
1803
1804
      /*value*/
1805
0
      sml_value(tvb, pinfo, value_List_Entry_list, offset, &data, &length);
1806
1807
      /*value Signature*/
1808
0
      field_valueSignature(tvb, value_List_Entry_list, offset, &data, &length);
1809
1810
0
      proto_item_set_end(value_List_Entry, tvb, *offset);
1811
0
    }
1812
0
    proto_item_set_end(valuelist, tvb, *offset);
1813
1814
    /*period Signature*/
1815
0
    field_periodSignature(tvb, period_List_Entry_list, offset, &data, &length);
1816
1817
0
    proto_item_set_end(period_List_Entry, tvb, *offset);
1818
0
  }
1819
0
  proto_item_set_end(periodList,tvb, *offset);
1820
1821
  /*rawdata*/
1822
0
  field_rawdata(tvb, messagebodytree_list, offset, &data, &length);
1823
1824
  /*profile Signature*/
1825
0
  get_length(tvb, offset, &data, &length);
1826
0
  profileSignature = proto_tree_add_bytes_format (messagebodytree_list, hf_sml_profileSignature, tvb, *offset, length+data, NULL, "profileSignature %s", (data == 0)? ": NOT SET" : "");
1827
1828
0
  if (data > 0){
1829
0
    profileSignature_tree = proto_item_add_subtree (profileSignature, ett_sml_profileSignature);
1830
0
    proto_tree_add_uint (profileSignature_tree, hf_sml_length, tvb, *offset, length, data);
1831
0
    *offset+=length;
1832
0
    proto_tree_add_item (profileSignature_tree, hf_sml_profileSignature, tvb, *offset, data, ENC_NA);
1833
0
    *offset+=data;
1834
0
  }
1835
0
  else
1836
0
    *offset+=1;
1837
1838
0
  return false;
1839
0
}
1840
1841
0
static bool decode_GetProfileListRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1842
0
  proto_item *SML_time = NULL;
1843
0
  proto_item *treepath = NULL;
1844
0
  proto_item *periodList = NULL;
1845
0
  proto_item *periodList_Entry = NULL;
1846
1847
0
  proto_tree *SML_time_tree = NULL;
1848
0
  proto_tree *treepath_list = NULL;
1849
0
  proto_tree *periodList_list = NULL;
1850
0
  proto_tree *periodList_Entry_list = NULL;
1851
1852
0
  unsigned i = 0;
1853
0
  unsigned repeat = 0;
1854
0
  unsigned data = 0;
1855
0
  unsigned length = 0;
1856
1857
  /*ServerID*/
1858
0
  field_serverId(tvb, messagebodytree_list, offset, &data, &length);
1859
1860
  /*actTime*/
1861
0
  get_length(tvb, offset, &data, &length);
1862
0
  SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "actTime");
1863
0
  *offset+=1;
1864
0
  sml_time_type(tvb, pinfo, SML_time_tree, offset);
1865
0
  proto_item_set_end(SML_time,tvb, *offset);
1866
1867
  /*regPeriod*/
1868
0
  field_regPeriod(tvb, messagebodytree_list, offset, &data, &length);
1869
1870
  /*Treepath List*/
1871
0
  get_length(tvb, offset, &data, &length);
1872
0
  repeat = (data+length);
1873
0
  treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
1874
0
        "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1875
1876
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1877
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in parameterTreePath");
1878
0
    return true;
1879
0
  }
1880
0
  else if (repeat <= 0){
1881
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1882
0
    return true;
1883
0
  }
1884
1885
0
  *offset+=length;
1886
1887
0
  for (i=0; i< repeat; i++) {
1888
0
    field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1889
0
  }
1890
0
  proto_item_set_end(treepath, tvb,*offset);
1891
1892
  /*valTime Optional*/
1893
0
  get_length(tvb, offset, &data, &length);
1894
1895
0
  SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "valTime");
1896
0
  if (data == 0){
1897
0
    proto_item_append_text(SML_time, ": NOT SET");
1898
0
    proto_item_set_len(SML_time, length + data);
1899
0
    *offset+=1;
1900
0
  }
1901
0
  else {
1902
    /*SML TIME*/
1903
0
    *offset+=1;
1904
0
    sml_time_type(tvb, pinfo, SML_time_tree, offset);
1905
0
    proto_item_set_end(SML_time,tvb,*offset);
1906
0
  }
1907
1908
  /*Status*/
1909
0
  field_status(tvb, messagebodytree_list, offset, &data, &length);
1910
1911
  /*period-List*/
1912
0
  get_length(tvb, offset, &data, &length);
1913
0
  repeat = (data+length);
1914
0
  periodList_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_periodList, &periodList,
1915
0
          "period-List with %d %s", length+data, plurality(length+data, "element", "elements"));
1916
1917
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1918
0
    expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid count of elements in periodList");
1919
0
    return true;
1920
0
  }
1921
0
  else if (repeat <= 0){
1922
0
    expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid loop count");
1923
0
    return true;
1924
0
  }
1925
1926
0
  *offset+=length;
1927
1928
0
  for (i=0; i< repeat; i++) {
1929
0
    get_length(tvb, offset, &data, &length);
1930
0
    periodList_Entry_list = proto_tree_add_subtree(periodList_list, tvb, *offset, -1, ett_sml_period_List_Entry, &periodList_Entry, "PeriodEntry");
1931
0
    *offset+=1;
1932
1933
    /*ObjName*/
1934
0
    field_objName(tvb, periodList_Entry_list, offset, &data, &length);
1935
1936
    /*Unit*/
1937
0
    field_unit(tvb, periodList_Entry_list, offset, &data, &length);
1938
1939
    /*scaler*/
1940
0
    field_scaler(tvb, periodList_Entry_list, offset, &data, &length);
1941
1942
    /*value*/
1943
0
    sml_value(tvb, pinfo, periodList_Entry_list, offset, &data, &length);
1944
1945
    /*value*/
1946
0
    field_valueSignature(tvb, periodList_Entry_list, offset, &data, &length);
1947
1948
0
    proto_item_set_end(periodList_Entry, tvb, *offset);
1949
0
  }
1950
0
  proto_item_set_end(periodList, tvb, *offset);
1951
1952
  /*rawdata*/
1953
0
  field_rawdata(tvb, messagebodytree_list, offset, &data, &length);
1954
1955
  /*period Signature*/
1956
0
  field_periodSignature(tvb, messagebodytree_list, offset, &data, &length);
1957
1958
0
  return false;
1959
0
}
1960
1961
0
static void decode_GetListReq (tvbuff_t *tvb, proto_tree *messagebodytree_list, unsigned *offset){
1962
0
  unsigned data = 0;
1963
0
  unsigned length = 0;
1964
1965
  /*clientID*/
1966
0
  field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1967
1968
  /*ServerID*/
1969
0
  field_serverId(tvb,messagebodytree_list,offset, &data, &length);
1970
1971
  /*user*/
1972
0
  field_username(tvb,messagebodytree_list,offset, &data, &length);
1973
1974
  /*password*/
1975
0
  field_password(tvb,messagebodytree_list,offset, &data, &length);
1976
1977
  /*listName*/
1978
0
  field_listName(tvb,messagebodytree_list,offset, &data, &length);
1979
0
}
1980
1981
0
static bool decode_GetListRes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1982
0
  proto_item *valList = NULL;
1983
0
  proto_item *listSignature = NULL;
1984
0
  proto_item *valtree = NULL;
1985
0
  proto_item *SML_time;
1986
1987
  //proto_tree *actSensorTime_tree = NULL;
1988
0
  proto_tree *valList_list = NULL;
1989
0
  proto_tree *listSignature_tree = NULL;
1990
0
  proto_tree *valtree_list = NULL;
1991
  //proto_tree *actGatewayTime_tree = NULL;
1992
0
  proto_tree *SML_time_tree = NULL;
1993
1994
0
  unsigned repeat = 0;
1995
0
  unsigned i = 0;
1996
0
  unsigned data = 0;
1997
0
  unsigned length = 0;
1998
1999
  /*clientID OPTIONAL*/
2000
0
  field_clientId (tvb, messagebodytree_list, offset, &data, &length);
2001
2002
  /*ServerID*/
2003
0
  field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2004
2005
  /*listName*/
2006
0
  field_listName(tvb, messagebodytree_list, offset, &data, &length);
2007
2008
  /*actSensorTime OPTIONAL*/
2009
0
  get_length(tvb, offset, &data, &length);
2010
2011
0
  SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "actSensorTime");
2012
0
  if (data == 0){
2013
0
    proto_item_append_text(SML_time, ": NOT SET");
2014
0
    proto_item_set_len(SML_time, length + data);
2015
0
    *offset+=1;
2016
0
  }
2017
0
  else {
2018
    /*SML TIME*/
2019
0
    *offset+=1;
2020
0
    sml_time_type(tvb, pinfo, SML_time_tree, offset);
2021
0
    proto_item_set_end(SML_time,tvb,*offset);
2022
0
  }
2023
2024
  /*valList*/
2025
0
  get_length(tvb, offset, &data, &length);
2026
0
  repeat = (length + data);
2027
0
  valtree_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_valtree, &valtree,
2028
0
            "valList with %d %s", length+data, plurality(length+data, "element", "elements"));
2029
2030
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2031
0
    expert_add_info_format(pinfo, valtree, &ei_sml_invalid_count, "invalid count of elements in valList");
2032
0
    return true;
2033
0
  }
2034
0
  else if (repeat <= 0){
2035
0
    expert_add_info_format(pinfo, valtree, &ei_sml_invalid_count, "invalid loop count");
2036
0
    return true;
2037
0
  }
2038
2039
0
  *offset+=length;
2040
2041
0
  for (i=0; i < repeat; i++){
2042
0
    get_length(tvb, offset, &data, &length);
2043
0
    valList_list = proto_tree_add_subtree(valtree_list, tvb, *offset, -1, ett_sml_valList, &valList, "valListEntry");
2044
0
    *offset+=length;
2045
2046
    /*objName*/
2047
0
    field_objName(tvb, valList_list, offset, &data, &length);
2048
2049
    /*Sml Status OPTIONAL*/
2050
0
    field_status(tvb, valList_list, offset, &data, &length);
2051
2052
    /*valTime OPTIONAL*/
2053
0
    get_length(tvb, offset, &data, &length);
2054
2055
0
    SML_time_tree = proto_tree_add_subtree(valList_list, tvb, *offset, -1, ett_sml_time, &SML_time, "valTime");
2056
0
    if (data == 0){
2057
0
      proto_item_append_text(SML_time, ": NOT SET");
2058
0
      proto_item_set_len(SML_time, length + data);
2059
0
      *offset+=1;
2060
0
    }
2061
0
    else {
2062
      /*SML TIME*/
2063
0
      *offset+=1;
2064
0
      sml_time_type(tvb, pinfo, SML_time_tree, offset);
2065
0
      proto_item_set_end(SML_time, tvb, *offset);
2066
0
    }
2067
2068
    /*unit OPTIONAL*/
2069
0
    field_unit(tvb, valList_list, offset, &data, &length);
2070
2071
    /*Scaler OPTIONAL*/
2072
0
    field_scaler(tvb, valList_list, offset, &data, &length);
2073
2074
    /*value*/
2075
0
    sml_value(tvb, pinfo, valList_list, offset, &data, &length);
2076
2077
    /*value Signature*/
2078
0
    field_valueSignature(tvb, valList_list, offset, &data, &length);
2079
2080
0
    proto_item_set_end(valList, tvb, *offset);
2081
0
  }
2082
0
  proto_item_set_end(valtree, tvb, *offset);
2083
2084
  /*List Signature OPTIONAL*/
2085
0
  get_length(tvb, offset, &data, &length);
2086
0
  listSignature = proto_tree_add_bytes_format (messagebodytree_list, hf_sml_listSignature, tvb, *offset, length+data, NULL, "ListSignature %s", (data == 0)? ": NOT SET" : "");
2087
2088
0
  if (data > 0){
2089
0
    listSignature_tree = proto_item_add_subtree (listSignature, ett_sml_listSignature);
2090
0
    proto_tree_add_uint (listSignature_tree, hf_sml_length, tvb, *offset, length, data);
2091
0
    *offset+=length;
2092
0
    proto_tree_add_item (listSignature_tree, hf_sml_listSignature, tvb, *offset, data, ENC_NA);
2093
0
    *offset+=data;
2094
0
  }
2095
0
  else
2096
0
    *offset+=1;
2097
2098
  /*actGatewayTime OPTIONAL*/
2099
0
  get_length(tvb, offset, &data, &length);
2100
2101
0
  SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "actGatewayTime");
2102
0
  if (data == 0){
2103
0
    proto_item_append_text(SML_time, ": NOT SET");
2104
0
    proto_item_set_len(SML_time, length + data);
2105
0
    *offset+=1;
2106
0
  }
2107
0
  else{
2108
    /*SML TIME*/
2109
0
    *offset+=1;
2110
0
    sml_time_type(tvb, pinfo, SML_time_tree, offset);
2111
0
    proto_item_set_end(SML_time,tvb,*offset);
2112
0
  }
2113
0
  return false;
2114
0
}
2115
2116
0
static bool decode_GetProcParameterReq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
2117
0
  proto_item *treepath = NULL;
2118
0
  proto_item *attribute = NULL;
2119
2120
0
  proto_tree *treepath_list = NULL;
2121
0
  proto_tree *attribute_tree = NULL;
2122
2123
0
  unsigned i = 0;
2124
0
  unsigned repeat = 0;
2125
0
  unsigned data = 0;
2126
0
  unsigned length = 0;
2127
2128
  /*ServerID*/
2129
0
  field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2130
2131
  /*user*/
2132
0
  field_username(tvb, messagebodytree_list, offset, &data, &length);
2133
2134
  /*password*/
2135
0
  field_password(tvb, messagebodytree_list, offset, &data, &length);
2136
2137
  /*Treepath List*/
2138
0
  get_length(tvb, offset, &data, &length);
2139
0
  repeat = data+length;
2140
0
  treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
2141
0
          "ParameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2142
2143
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2144
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2145
0
    return true;
2146
0
  }
2147
0
  else if (repeat <= 0){
2148
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2149
0
    return true;
2150
0
  }
2151
2152
0
  *offset+=length;
2153
2154
0
  for (i=0; i< repeat; i++) {
2155
0
    field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2156
0
  }
2157
0
  proto_item_set_end(treepath, tvb, *offset);
2158
2159
  /*attribute*/
2160
0
  get_length(tvb, offset, &data, &length);
2161
0
  attribute = proto_tree_add_bytes_format (messagebodytree_list,hf_sml_attribute, tvb, *offset, length+data, NULL, "attribute %s", (data == 0)? ": NOT SET" : "");
2162
2163
0
  if (data > 0) {
2164
0
    attribute_tree = proto_item_add_subtree (attribute, ett_sml_attribute);
2165
0
    proto_tree_add_uint (attribute_tree, hf_sml_length, tvb, *offset, length, data);
2166
0
    *offset+=length;
2167
0
    proto_tree_add_item (attribute_tree, hf_sml_attribute, tvb, *offset, data, ENC_NA);
2168
0
    *offset+=data;
2169
0
  }
2170
0
  else
2171
0
    *offset+=1;
2172
2173
0
  return false;
2174
0
}
2175
2176
0
static bool decode_GetProcParameterRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
2177
0
  proto_item *treepath = NULL;
2178
0
  proto_item *parameterTree =NULL;
2179
2180
0
  proto_tree *treepath_list = NULL;
2181
0
  proto_tree *parameterTree_list = NULL;
2182
2183
0
  unsigned i = 0;
2184
0
  unsigned repeat = 0;
2185
0
  unsigned data = 0;
2186
0
  unsigned length = 0;
2187
2188
  /*ServerID*/
2189
0
  field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2190
2191
  /*Treepath List*/
2192
0
  get_length(tvb, offset, &data, &length);
2193
0
  repeat = (data+length);
2194
0
  treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
2195
0
          "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2196
2197
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2198
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2199
0
    return true;
2200
0
  }
2201
0
  else if (repeat <= 0){
2202
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2203
0
    return true;
2204
0
  }
2205
2206
0
  *offset+=length;
2207
2208
0
  for (i=0; i< repeat; i++) {
2209
0
    field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2210
0
  }
2211
0
  proto_item_set_end(treepath, tvb, *offset);
2212
2213
  /*parameterTree*/
2214
0
  get_length(tvb, offset, &data, &length);
2215
0
  parameterTree_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_parameterTree, &parameterTree,
2216
0
        "parameterTree with %d %s", length+data, plurality(length+data, "element", "elements"));
2217
2218
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2219
0
    expert_add_info_format(pinfo, parameterTree, &ei_sml_invalid_count, "invalid count of elements in parameterTree");
2220
0
    return true;
2221
0
  }
2222
2223
0
  *offset+=length;
2224
2225
0
  child_tree(tvb, pinfo,parameterTree_list, offset, &data, &length);
2226
0
  proto_item_set_end(parameterTree, tvb, *offset);
2227
2228
0
  return false;
2229
0
}
2230
2231
0
static bool decode_SetProcParameterReq(tvbuff_t *tvb, packet_info *pinfo,proto_tree *messagebodytree_list, unsigned *offset){
2232
0
  proto_item *treepath = NULL;
2233
0
  proto_item *parameterTree = NULL;
2234
2235
0
  proto_tree *treepath_list = NULL;
2236
0
  proto_tree *parameterTree_list = NULL;
2237
2238
0
  unsigned i = 0;
2239
0
  unsigned repeat = 0;
2240
0
  unsigned data = 0;
2241
0
  unsigned length = 0;
2242
2243
  /*ServerID*/
2244
0
  field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2245
2246
  /*user*/
2247
0
  field_username(tvb, messagebodytree_list, offset, &data, &length);
2248
2249
  /*password*/
2250
0
  field_password(tvb, messagebodytree_list, offset, &data, &length);
2251
2252
  /*Treepath List*/
2253
0
  get_length(tvb, offset, &data, &length);
2254
0
  repeat = (data+length);
2255
0
  treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
2256
0
          "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2257
2258
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2259
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2260
0
    return true;
2261
0
  }
2262
0
  else if (repeat <= 0){
2263
0
    expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2264
0
    return true;
2265
0
  }
2266
2267
0
  *offset+=length;
2268
2269
0
  for (i=0; i< repeat; i++) {
2270
0
    field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2271
0
  }
2272
0
  proto_item_set_end(treepath, tvb, *offset);
2273
2274
  /*parameterTree*/
2275
0
  get_length(tvb, offset, &data, &length);
2276
0
  parameterTree_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_parameterTree, &parameterTree,
2277
0
        "parameterTree with %d %s", length+data, plurality(length+data, "element", "elements"));
2278
2279
0
  if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2280
0
    expert_add_info_format(pinfo, parameterTree, &ei_sml_invalid_count, "invalid count of elements in parameterTree");
2281
0
    return true;
2282
0
  }
2283
2284
0
  *offset+=length;
2285
2286
0
  child_tree(tvb, pinfo,parameterTree_list, offset, &data, &length);
2287
0
  proto_item_set_end(parameterTree, tvb, *offset);
2288
2289
0
  return false;
2290
0
}
2291
2292
0
static bool decode_AttentionRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
2293
0
  proto_item *attentionMsg = NULL;
2294
0
  proto_item *attentionDetails = NULL;
2295
2296
0
  proto_tree *attentionNo_tree = NULL;
2297
0
  proto_tree *attentionMsg_tree = NULL;
2298
0
  proto_tree *attentionDetails_list = NULL;
2299
0
    proto_item *attentionNo_item;
2300
2301
0
  unsigned data = 0;
2302
0
  unsigned length = 0;
2303
2304
  /*ServerID*/
2305
0
  field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2306
2307
  /*attention NO*/
2308
0
  get_length(tvb, offset, &data, &length);
2309
0
  attentionNo_tree = proto_tree_add_subtree(messagebodytree_list, tvb ,*offset, length+data, ett_sml_attentionNo, &attentionNo_item, "attentionNo");
2310
0
  proto_tree_add_uint (attentionNo_tree, hf_sml_length, tvb, *offset, length, data);
2311
0
  *offset+=length;
2312
2313
0
  if (data == 6){
2314
0
    *offset+=4;
2315
0
    proto_tree_add_item (attentionNo_tree, hf_sml_attentionNo, tvb, *offset, 2, ENC_BIG_ENDIAN);
2316
0
    *offset+=2;
2317
0
  }
2318
0
  else {
2319
0
    expert_add_info(pinfo, attentionNo_item, &ei_sml_attentionNo);
2320
0
    *offset+=data;
2321
0
  }
2322
2323
  /*attention Msg*/
2324
0
  get_length(tvb, offset, &data, &length);
2325
0
  attentionMsg = proto_tree_add_string_format (messagebodytree_list, hf_sml_attentionMsg, tvb, *offset, length+data, NULL, "attentionMsg %s", (data == 0)? ": NOT SET" : "");
2326
2327
0
  if (data > 0){
2328
0
    attentionMsg_tree = proto_item_add_subtree (attentionMsg, ett_sml_attentionMsg);
2329
0
    proto_tree_add_uint (attentionMsg_tree, hf_sml_length, tvb, *offset, length, data);
2330
0
    *offset+=length;
2331
0
    proto_tree_add_item (attentionMsg_tree, hf_sml_attentionMsg, tvb, *offset, data, ENC_ASCII | ENC_BIG_ENDIAN);
2332
0
    *offset+=data;
2333
0
  }
2334
0
  else
2335
0
    *offset+=1;
2336
2337
  /*attentiondetails*/
2338
0
  attentionDetails_list = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_attentionDetails, &attentionDetails, "attentionDetails");
2339
0
  if (tvb_get_uint8(tvb,*offset) == OPTIONAL){
2340
0
    proto_item_append_text(attentionDetails, ": NOT SET");
2341
0
    proto_item_set_len(attentionDetails, 1);
2342
0
    *offset+=1;
2343
0
  }
2344
0
  else{
2345
0
    get_length(tvb, offset, &data, &length);
2346
0
    proto_item_append_text(attentionDetails, " with %d %s", length+data, plurality(length+data, "element", "elements"));
2347
2348
0
    if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2349
0
      expert_add_info_format(pinfo, attentionDetails, &ei_sml_invalid_count, "invalid count of elements in attentionDetails");
2350
0
      return true;
2351
0
    }
2352
2353
0
    *offset+=length;
2354
2355
0
    child_tree(tvb, pinfo,attentionDetails_list, offset, &data, &length);
2356
0
    proto_item_set_end(attentionDetails, tvb, *offset);
2357
0
  }
2358
2359
0
  return false;
2360
0
}
2361
2362
/*dissect SML-File*/
2363
0
static void dissect_sml_file(tvbuff_t *tvb, packet_info *pinfo, unsigned *offset, proto_tree *sml_tree){
2364
0
  proto_item *file = NULL;
2365
0
  proto_item *mainlist;
2366
0
  proto_item *sublist;
2367
0
  proto_item *messagebody;
2368
0
  proto_item *crc16;
2369
0
  proto_item *messagebodytree;
2370
0
  proto_item *msgend;
2371
2372
0
  proto_tree *mainlist_list = NULL;
2373
0
  proto_tree *trans_tree = NULL;
2374
0
  proto_tree *groupNo_tree = NULL;
2375
0
  proto_tree *abortOnError_tree = NULL;
2376
0
  proto_tree *sublist_list = NULL;
2377
0
  proto_tree *messagebody_tree = NULL;
2378
0
  proto_tree *crc16_tree = NULL;
2379
0
  proto_tree *messagebodytree_list = NULL;
2380
0
  proto_tree *msgend_tree = NULL;
2381
2382
0
  uint16_t messagebody_switch = 0;
2383
0
  uint16_t crc_check = 0;
2384
0
  uint16_t crc_ref = 0;
2385
0
  unsigned check = 0;
2386
2387
0
  unsigned available = 0;
2388
0
  unsigned crc_msg_len = 0;
2389
0
  unsigned crc_file_len = 0;
2390
0
  unsigned data = 0;
2391
0
  unsigned length = 0;
2392
2393
0
  bool msg_error = false;
2394
0
  bool close1 = false;
2395
0
  bool close2 = false;
2396
0
  int end_offset = 0;
2397
2398
0
  unsigned start_offset;
2399
0
  start_offset = *offset;
2400
2401
0
  end_offset = tvb_reported_length_remaining(tvb, *offset);
2402
0
  if (end_offset <= 0){
2403
0
    return;
2404
0
  }
2405
2406
0
  if (tvb_get_ntoh40(tvb, end_offset-8) != ESC_SEQ_END && pinfo->can_desegment){
2407
0
    if (tvb_get_uint8(tvb, end_offset-1) != 0){
2408
0
      pinfo->desegment_offset = start_offset;
2409
0
      pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2410
0
      return;
2411
0
    }
2412
0
    else if (tvb_get_uint8(tvb, end_offset-4) != UNSIGNED16 && tvb_get_uint8(tvb, end_offset-3) != UNSIGNED8){
2413
0
      pinfo->desegment_offset = start_offset;
2414
0
      pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2415
0
      return;
2416
0
    }
2417
0
  }
2418
0
  else if (!pinfo->can_desegment){
2419
0
    expert_add_info(pinfo, NULL, &ei_sml_segment_needed);
2420
0
  }
2421
2422
0
  while(!close1 && !close2){
2423
0
    if (sml_reassemble){
2424
0
      file = proto_tree_add_item(sml_tree, hf_sml_file_marker, tvb, *offset, -1, ENC_NA);
2425
0
    }
2426
2427
    /*check if escape*/
2428
0
    if (tvb_get_ntohl(tvb, *offset) == ESC_SEQ){
2429
0
      crc_file_len = *offset;
2430
      /*Escape Start*/
2431
0
      proto_tree_add_item (sml_tree, hf_sml_esc, tvb, *offset, 4, ENC_BIG_ENDIAN);
2432
0
      *offset+=4;
2433
2434
      /*Version*/
2435
0
      if (tvb_get_uint8(tvb, *offset) == 0x01){
2436
0
        proto_tree_add_item (sml_tree, hf_sml_version_1, tvb, *offset, 4, ENC_BIG_ENDIAN);
2437
0
        *offset+=4;
2438
0
      }
2439
0
      else{
2440
0
        proto_tree_add_expert(sml_tree, pinfo, &ei_sml_version2_not_supported, tvb, *offset, -1);
2441
0
        return;
2442
0
      }
2443
0
    }
2444
2445
0
    while (!close1){
2446
0
      crc_msg_len = *offset;
2447
2448
      /*List*/
2449
0
      get_length(tvb, offset, &data, &length);
2450
0
      mainlist_list = proto_tree_add_subtree_format(sml_tree, tvb, *offset, -1, ett_sml_mainlist, &mainlist, "List with %d %s",
2451
0
                      length+data, plurality(length+data, "element", "elements"));
2452
2453
0
      if (tvb_get_uint8(tvb, *offset) != LIST_6_ELEMENTS) {
2454
0
        expert_add_info_format(pinfo, mainlist, &ei_sml_invalid_count, "invalid count of elements");
2455
0
        return;
2456
0
      }
2457
0
      *offset+=1;
2458
2459
      /*Transaction ID*/
2460
0
      get_length(tvb, offset, &data, &length);
2461
0
      trans_tree = proto_tree_add_subtree_format(mainlist_list, tvb, *offset, length + data, ett_sml_trans, NULL, "Transaction ID");
2462
0
      proto_tree_add_uint (trans_tree, hf_sml_length, tvb, *offset, length, data);
2463
0
      *offset+=length;
2464
0
      proto_tree_add_item (trans_tree, hf_sml_transactionId, tvb, *offset, data, ENC_NA);
2465
0
      *offset+=data;
2466
2467
      /*Group No*/
2468
0
      groupNo_tree = proto_tree_add_subtree(mainlist_list, tvb, *offset, 2, ett_sml_group, NULL, "Group No");
2469
0
      proto_tree_add_item (groupNo_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
2470
0
      *offset+=1;
2471
0
      proto_tree_add_item (groupNo_tree, hf_sml_groupNo, tvb, *offset, 1, ENC_BIG_ENDIAN);
2472
0
      *offset+=1;
2473
2474
      /*abort on Error*/
2475
0
      abortOnError_tree = proto_tree_add_subtree(mainlist_list, tvb, *offset, 2, ett_sml_abort, NULL, "Abort on Error");
2476
0
      proto_tree_add_item(abortOnError_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
2477
0
      *offset+=1;
2478
0
      proto_tree_add_item(abortOnError_tree, hf_sml_abortOnError, tvb, *offset, 1, ENC_BIG_ENDIAN);
2479
0
      *offset+=1;
2480
2481
      /*Sub List*/
2482
0
      sublist_list = proto_tree_add_subtree(mainlist_list, tvb, *offset, -1, ett_sml_sublist, &sublist, "MessageBody");
2483
0
      *offset+=1;
2484
2485
      /*Zero Cutting Check*/
2486
0
      get_length(tvb, offset, &data, &length);
2487
0
      messagebody_tree = proto_tree_add_subtree(sublist_list, tvb, *offset, length + data, ett_sml_mttree, &messagebody, "Messagetype");
2488
0
      proto_tree_add_item (messagebody_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
2489
0
      *offset+=1;
2490
2491
0
      if (data == 4){
2492
0
        *offset+=2;
2493
0
      }
2494
0
      else if (data !=2){
2495
0
        expert_add_info(pinfo, messagebody, &ei_sml_messagetype_unknown);
2496
0
        return;
2497
0
      }
2498
2499
0
      messagebody_switch = tvb_get_ntohs(tvb, *offset);
2500
0
      proto_tree_add_item (messagebody_tree, hf_sml_MessageBody, tvb, *offset, 2, ENC_BIG_ENDIAN);
2501
0
      *offset+=2;
2502
2503
      /*MessageBody List*/
2504
0
      get_length(tvb, offset, &data, &length);
2505
0
      messagebodytree_list = proto_tree_add_subtree_format(sublist_list, tvb, *offset, -1, ett_sml_mblist, &messagebodytree,
2506
0
                        "List with %d %s", length+data, plurality(length+data, "element", "elements"));
2507
0
      *offset+=length;
2508
2509
0
      switch (messagebody_switch){
2510
0
        case OPEN_REQ:
2511
0
          col_append_str (pinfo->cinfo, COL_INFO, "OpenReq; ");
2512
0
          proto_item_append_text(mainlist, " [Open Request]");
2513
0
          decode_PublicOpenReq(tvb, messagebodytree_list, offset);
2514
0
          break;
2515
0
        case OPEN_RES:
2516
0
          col_append_str (pinfo->cinfo, COL_INFO, "OpenRes; ");
2517
0
          proto_item_append_text(mainlist, " [Open Response]");
2518
0
          decode_PublicOpenRes(tvb, pinfo, messagebodytree_list, offset);
2519
0
          break;
2520
0
        case CLOSE_REQ:
2521
0
          col_append_str (pinfo->cinfo, COL_INFO, "CloseReq; ");
2522
0
          proto_item_append_text(mainlist, " [Close Request]");
2523
0
          field_globalSignature(tvb, messagebodytree_list, offset, &data, &length);
2524
0
          break;
2525
0
        case CLOSE_RES:
2526
0
          col_append_str (pinfo->cinfo, COL_INFO, "CloseRes; ");
2527
0
          proto_item_append_text(mainlist, " [Close Response]");
2528
0
          field_globalSignature(tvb, messagebodytree_list, offset, &data, &length);
2529
0
          break;
2530
0
        case PROFILEPACK_REQ:
2531
0
          col_append_str (pinfo->cinfo, COL_INFO, "GetProfilePackReq; ");
2532
0
          proto_item_append_text(mainlist, " [GetProfilePack Request]");
2533
0
          msg_error = decode_GetProfile_List_Pack_Req(tvb, pinfo,messagebodytree_list, offset);
2534
0
          break;
2535
0
        case PROFILEPACK_RES:
2536
0
          col_append_str (pinfo->cinfo, COL_INFO, "GetProfilePackRes; ");
2537
0
          proto_item_append_text(mainlist, " [GetProfilePack Response]");
2538
0
          msg_error = decode_GetProfilePackRes(tvb, pinfo,messagebodytree_list, offset);
2539
0
          break;
2540
0
        case PROFILELIST_REQ:
2541
0
          col_append_str (pinfo->cinfo, COL_INFO, "GetProfileListReq; ");
2542
0
          proto_item_append_text(mainlist, " [GetProfileList Request]");
2543
0
          msg_error = decode_GetProfile_List_Pack_Req(tvb, pinfo,messagebodytree_list, offset);
2544
0
          break;
2545
0
        case PROFILELIST_RES:
2546
0
          col_append_str (pinfo->cinfo, COL_INFO, "GetProfileListRes; ");
2547
0
          proto_item_append_text(mainlist, " [GetProfileList Response]");
2548
0
          msg_error = decode_GetProfileListRes(tvb, pinfo,messagebodytree_list, offset);
2549
0
          break;
2550
0
        case GETPROCPARAMETER_REQ:
2551
0
          col_append_str (pinfo->cinfo, COL_INFO, "GetProcParameterReq; ");
2552
0
          proto_item_append_text(mainlist, " [GetProcParameter Request]");
2553
0
          msg_error =  decode_GetProcParameterReq(tvb, pinfo,messagebodytree_list, offset);
2554
0
          break;
2555
0
        case GETPROCPARAMETER_RES:
2556
0
          col_append_str (pinfo->cinfo, COL_INFO, "GetProcParameterRes; ");
2557
0
          proto_item_append_text(mainlist, " [GetProcParameter Response]");
2558
0
          msg_error =  decode_GetProcParameterRes(tvb, pinfo,messagebodytree_list, offset);
2559
0
          break;
2560
0
        case SETPROCPARAMETER_REQ:
2561
0
          col_append_str (pinfo->cinfo, COL_INFO, "SetProcParameterReq; ");
2562
0
          proto_item_append_text(mainlist, " [SetProcParameter Request]");
2563
0
          msg_error =  decode_SetProcParameterReq(tvb, pinfo,messagebodytree_list, offset);
2564
0
          break;
2565
0
        case GETLIST_REQ:
2566
0
          col_append_str (pinfo->cinfo, COL_INFO, "GetListReq; ");
2567
0
          proto_item_append_text(mainlist, " [GetList Request]");
2568
0
          decode_GetListReq(tvb, messagebodytree_list, offset);
2569
0
          break;
2570
0
        case GETLIST_RES:
2571
0
          col_append_str (pinfo->cinfo, COL_INFO, "GetListRes; ");
2572
0
          proto_item_append_text(mainlist, " [GetList Response]");
2573
0
          msg_error =  decode_GetListRes(tvb, pinfo,messagebodytree_list, offset);
2574
0
          break;
2575
0
        case ATTENTION:
2576
0
          col_append_str (pinfo->cinfo, COL_INFO, "AttentionRes; ");
2577
0
          proto_item_append_text(mainlist, " [Attention Response]");
2578
0
          msg_error =  decode_AttentionRes(tvb, pinfo,messagebodytree_list, offset);
2579
0
          break;
2580
0
        default :
2581
0
          expert_add_info(pinfo, messagebodytree, &ei_sml_messagetype_unknown);
2582
0
          return;
2583
0
      }
2584
2585
0
      if (msg_error){
2586
0
        expert_add_info(pinfo, messagebodytree, &ei_sml_MessageBody);
2587
0
        return;
2588
0
      }
2589
2590
0
      proto_item_set_end(messagebodytree, tvb, *offset);
2591
0
      proto_item_set_end(sublist, tvb, *offset);
2592
2593
      /* CRC 16*/
2594
0
      get_length(tvb, offset, &data, &length);
2595
0
      crc16_tree = proto_tree_add_subtree(mainlist_list, tvb, *offset, data + length, ett_sml_crc16, &crc16, "CRC");
2596
2597
0
      if(tvb_get_uint8(tvb, *offset) != UNSIGNED8 && tvb_get_uint8(tvb, *offset) != UNSIGNED16){
2598
0
        expert_add_info(pinfo, crc16, &ei_sml_crc_error_length);
2599
0
        return;
2600
0
      }
2601
2602
0
      proto_tree_add_item (crc16_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
2603
0
      *offset+=1;
2604
2605
0
      if (sml_crc_enabled) {
2606
0
        crc_msg_len = (*offset - crc_msg_len - 1);
2607
0
        crc_check = crc16_ccitt_tvb_offset(tvb, (*offset - crc_msg_len - 1), crc_msg_len);
2608
2609
0
        if (data == 1){
2610
0
          crc_ref = crc_ref & 0xFF00;
2611
0
        }
2612
2613
0
        proto_tree_add_checksum(crc16_tree, tvb, *offset, hf_sml_crc16, hf_sml_crc16_status, &ei_sml_crc_error, pinfo, crc_check,
2614
0
                  ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
2615
0
      }
2616
0
      else {
2617
0
        proto_tree_add_checksum(crc16_tree, tvb, *offset, hf_sml_crc16, hf_sml_crc16_status, &ei_sml_crc_error, pinfo, 0,
2618
0
                  ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
2619
0
      }
2620
0
      *offset+=data;
2621
2622
      /*Message END*/
2623
0
      if (tvb_get_uint8 (tvb, *offset) == 0){
2624
0
        proto_tree_add_item (mainlist_list, hf_sml_endOfSmlMsg, tvb, *offset, 1, ENC_BIG_ENDIAN);
2625
0
        *offset+=1;
2626
0
      }
2627
0
      else {
2628
0
        expert_add_info(pinfo, NULL, &ei_sml_endOfSmlMsg);
2629
0
        return;
2630
0
      }
2631
2632
0
      proto_item_set_end(mainlist, tvb, *offset);
2633
2634
0
      if (tvb_reported_length_remaining(tvb, *offset) > 0){
2635
0
        check = tvb_get_uint8(tvb, *offset);
2636
2637
0
        if (check == LIST_6_ELEMENTS){
2638
0
          close1 = false;
2639
0
        }
2640
0
        else if (check == 0x1b || check == 0){
2641
0
          close1 = true;
2642
0
        }
2643
0
      }
2644
0
      else if (sml_reassemble && pinfo->can_desegment){
2645
0
        pinfo->desegment_offset = start_offset;
2646
0
        pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2647
0
        return;
2648
0
      }
2649
0
      else
2650
0
        return;
2651
0
    }
2652
2653
    /*Padding*/
2654
0
    if (check == 0){
2655
0
      length = 1;
2656
0
      *offset+=1;
2657
2658
0
      while (tvb_get_uint8(tvb, *offset) == 0){
2659
0
        length++;
2660
0
        *offset+=1;
2661
0
      }
2662
0
      *offset-=length;
2663
2664
0
      proto_tree_add_item (sml_tree, hf_sml_padding, tvb, *offset, length, ENC_NA);
2665
0
      *offset+=length;
2666
0
    }
2667
2668
    /*Escape End*/
2669
0
    if(tvb_get_ntoh40(tvb, *offset) != ESC_SEQ_END){
2670
0
      expert_add_info(pinfo, NULL, &ei_sml_esc_error);
2671
0
      return;
2672
0
    }
2673
0
    proto_tree_add_item (sml_tree, hf_sml_esc, tvb, *offset, 4, ENC_BIG_ENDIAN);
2674
0
    *offset+=4;
2675
2676
    /*MSG END*/
2677
0
    msgend = proto_tree_add_item (sml_tree, hf_sml_end, tvb, *offset, 4, ENC_BIG_ENDIAN);
2678
0
    msgend_tree = proto_item_add_subtree (msgend, ett_sml_msgend);
2679
0
    *offset+=1;
2680
0
    proto_tree_add_item (msgend_tree, hf_sml_padding, tvb, *offset, 1, ENC_NA);
2681
0
    *offset+=1;
2682
2683
0
    if (sml_crc_enabled && sml_reassemble){
2684
0
      crc_file_len = *offset - crc_file_len;
2685
0
      crc_check = crc16_ccitt_tvb_offset(tvb,*offset-crc_file_len, crc_file_len);
2686
2687
0
      proto_tree_add_checksum(msgend_tree, tvb, *offset, hf_sml_crc16, hf_sml_crc16_status, &ei_sml_crc_error, pinfo, crc_check,
2688
0
                  ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
2689
0
    }
2690
0
    else {
2691
0
      proto_tree_add_checksum(msgend_tree, tvb, *offset, hf_sml_crc16, hf_sml_crc16_status, &ei_sml_crc_error, pinfo, crc_check,
2692
0
                  ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
2693
0
    }
2694
0
    *offset+=2;
2695
2696
0
    available = tvb_reported_length_remaining(tvb, *offset);
2697
0
    if (available <= 0){
2698
0
      close2 = true;
2699
0
    }
2700
0
    else {
2701
0
      if (sml_reassemble){
2702
0
        proto_item_set_end(file, tvb, *offset);
2703
0
      }
2704
0
      else {
2705
0
        proto_tree_add_item(sml_tree, hf_sml_new_file_marker, tvb, *offset, 0, ENC_NA);
2706
0
      }
2707
0
      close1 = false;
2708
0
    }
2709
0
  }
2710
0
}
2711
2712
/* main */
2713
0
static int dissect_sml (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
2714
0
  proto_item *sml_item;
2715
0
  proto_tree *sml_tree;
2716
2717
0
  unsigned offset = 0;
2718
2719
  /*Check if not SML*/
2720
0
  if (tvb_get_ntohl(tvb, offset) != ESC_SEQ && tvb_get_uint8(tvb, offset) != LIST_6_ELEMENTS){
2721
0
    return 0;
2722
0
  }
2723
2724
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "SML");
2725
0
  col_clear(pinfo->cinfo,COL_INFO);
2726
2727
  /* create display subtree for the protocol */
2728
0
  sml_item = proto_tree_add_item(tree, proto_sml, tvb, 0, -1, ENC_NA);
2729
0
  sml_tree = proto_item_add_subtree(sml_item, ett_sml);
2730
0
  dissect_sml_file(tvb, pinfo, &offset, sml_tree);
2731
0
  return tvb_captured_length(tvb);
2732
0
}
2733
2734
static void
2735
sml_fmt_length( char *result, uint32_t length )
2736
0
{
2737
0
   snprintf( result, ITEM_LABEL_LENGTH, "%d %s", length, plurality(length, "octet", "octets"));
2738
0
}
2739
2740
14
void proto_register_sml (void) {
2741
14
  module_t *sml_module;
2742
14
  expert_module_t* expert_sml;
2743
2744
14
  static hf_register_info hf[] = {
2745
14
    { &hf_sml_esc,
2746
14
      { "Escape", "sml.esc", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2747
14
    { &hf_sml_version_1,
2748
14
      { "Version 1", "sml.version_1", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2749
14
    { &hf_sml_smlVersion,
2750
14
      { "SML Version", "sml.version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2751
14
    { &hf_sml_crc16,
2752
14
      { "CRC16", "sml.crc", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2753
14
    { &hf_sml_crc16_status,
2754
14
      { "CRC16 Status", "sml.crc.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0, NULL, HFILL }},
2755
14
    { &hf_sml_endOfSmlMsg,
2756
14
      { "End of SML Msg", "sml.end", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2757
14
    { &hf_sml_transactionId,
2758
14
      { "Transaction ID", "sml.transactionid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2759
14
    { &hf_sml_length,
2760
14
      { "Length", "sml.length", FT_UINT32, BASE_CUSTOM, CF_FUNC(sml_fmt_length), 0x0, NULL, HFILL }},
2761
14
    { &hf_sml_groupNo,
2762
14
      { "GroupNo", "sml.groupno", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2763
14
    { &hf_sml_datatype,
2764
14
      { "Datatype", "sml.datatype", FT_UINT8, BASE_HEX, VALS (datatype), 0x0, NULL, HFILL }},
2765
14
    { &hf_sml_abortOnError,
2766
14
      { "Abort On Error", "sml.abort", FT_UINT8, BASE_HEX, VALS (sml_abort), 0x0, NULL, HFILL }},
2767
14
    { &hf_sml_MessageBody,
2768
14
      { "Messagebody", "sml.messagebody", FT_UINT16, BASE_HEX, VALS (sml_body), 0x0, NULL, HFILL }},
2769
14
    { &hf_sml_end,
2770
14
      { "End of Msg", "sml.end", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2771
14
    { &hf_sml_codepage,
2772
14
      { "Codepage", "sml.codepage", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2773
14
    { &hf_sml_clientId,
2774
14
      { "Client ID", "sml.clientid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2775
14
    { &hf_sml_reqFileId,
2776
14
      { "reqFile ID", "sml.reqfileid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2777
14
    { &hf_sml_serverId,
2778
14
      { "server ID", "sml.serverid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2779
14
    { &hf_sml_username,
2780
14
      { "Username", "sml.username", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2781
14
    { &hf_sml_password,
2782
14
      { "Password", "sml.password", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2783
14
    { &hf_sml_listName,
2784
14
      { "List Name", "sml.listname", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2785
14
    { &hf_sml_globalSignature,
2786
14
      { "Global Signature", "sml.globalsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2787
14
    { &hf_sml_timetype,
2788
14
      { "Time type", "sml.timetype", FT_UINT8, BASE_HEX, VALS (sml_timetypes), 0x0, NULL, HFILL }},
2789
14
    { &hf_sml_objName,
2790
14
      { "objName", "sml.objname", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2791
14
    { &hf_sml_status,
2792
14
      { "Status", "sml.status", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2793
14
    { &hf_sml_unit,
2794
14
      { "unit", "sml.unit", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2795
14
    { &hf_sml_scaler,
2796
14
      { "scaler", "sml.scaler", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2797
14
    { &hf_sml_value,
2798
14
      { "value", "sml.value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2799
14
    { &hf_sml_simplevalue,
2800
14
      { "simplevalue", "sml.simplevalue", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2801
14
    { &hf_sml_valueSignature,
2802
14
      { "ValueSignature", "sml.valuesignature", FT_BYTES, BASE_NONE, NULL, 0x0,NULL, HFILL }},
2803
14
    { &hf_sml_listSignature,
2804
14
      { "ListSignature", "sml.listsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2805
14
    { &hf_sml_parameterTreePath,
2806
14
      { "path_Entry", "sml.parametertreepath", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2807
14
    { &hf_sml_attribute,
2808
14
      { "attribute", "sml.attribute", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2809
14
    { &hf_sml_parameterName,
2810
14
      { "parameterName", "sml.parametername", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2811
14
    { &hf_sml_procParValue,
2812
14
      { "procParValue", "sml.procparvalue", FT_UINT8, BASE_HEX, VALS(procvalues), 0x0, NULL, HFILL }},
2813
14
    { &hf_sml_padding,
2814
14
      { "Padding", "sml.padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2815
14
    { &hf_sml_secIndex,
2816
14
      { "secIndex", "sml.secindex", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2817
14
    { &hf_sml_timestamp,
2818
14
      { "timestamp", "sml.timestamp", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2819
14
    { &hf_sml_localOffset,
2820
14
      { "localOffset", "sml.localOffset", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2821
14
    { &hf_sml_seasonTimeOffset,
2822
14
      { "seasonTimeOffset", "sml.seasonTimeOffset", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2823
14
    { &hf_sml_attentionNo,
2824
14
      { "attentionNo", "sml.attentionno", FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(attentionValues), 0x0, NULL, HFILL }},
2825
14
    { &hf_sml_attentionMsg,
2826
14
      { "attentionMsg", "sml.attentionmsg", FT_STRING, BASE_NONE, NULL, 0x0 , NULL, HFILL }},
2827
14
    { &hf_sml_withRawdata,
2828
14
      { "withRawdata", "sml.withrawdata", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(bools), 0x0 , NULL, HFILL }},
2829
14
    { &hf_sml_object_list_Entry,
2830
14
      { "object_list_Entry", "sml.objectentry", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2831
14
    { &hf_sml_regPeriod,
2832
14
      { "regPeriod", "sml.regperiod", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2833
14
    { &hf_sml_rawdata,
2834
14
      { "rawdata", "sml.rawdata", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2835
14
    { &hf_sml_periodSignature,
2836
14
      { "periodSignature", "sml.periodsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2837
14
    { &hf_sml_profileSignature,
2838
14
      { "profileSignature", "sml.profilesignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2839
14
    { &hf_sml_signature_mA_R2_R3,
2840
14
      { "signature_mA_R2_R3", "sml.signaturema", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2841
14
    { &hf_sml_signature_pA_R1_R4,
2842
14
      { "signature_pA_R1_R4", "sml.signaturepa", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2843
14
    { &hf_sml_unit_mA,
2844
14
      { "unit_mA", "sml.unitmA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2845
14
    { &hf_sml_unit_pA,
2846
14
      { "unit_pA", "sml.unitpA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2847
14
    { &hf_sml_unit_R1,
2848
14
      { "unit_R1", "sml.unitR1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2849
14
    { &hf_sml_unit_R2,
2850
14
      { "unit_R2", "sml.unitR2", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2851
14
    { &hf_sml_unit_R3,
2852
14
      { "unit_R3", "sml.unitR3", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2853
14
    { &hf_sml_unit_R4,
2854
14
      { "unit_R4", "sml.unitR4", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2855
14
    { &hf_sml_scaler_mA,
2856
14
      { "scaler_mA", "sml.scalermA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2857
14
    { &hf_sml_scaler_pA,
2858
14
      { "scaler_pA", "sml.scalerpA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2859
14
    { &hf_sml_scaler_R1,
2860
14
      { "scaler_R1", "sml.scalerR1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2861
14
    { &hf_sml_scaler_R2,
2862
14
      { "scaler_R2", "sml.scalerR2", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2863
14
    { &hf_sml_scaler_R3,
2864
14
      { "scaler_R3", "sml.scalerR3", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2865
14
    { &hf_sml_scaler_R4,
2866
14
      { "scaler_R4", "sml.scalerR4", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2867
14
    { &hf_sml_value_mA,
2868
14
      { "value_mA", "sml.valuemA", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2869
14
    { &hf_sml_value_pA,
2870
14
      { "value_pA", "sml.valuepA", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2871
14
    { &hf_sml_value_R1,
2872
14
      { "value_R1", "sml.valueR1", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2873
14
    { &hf_sml_value_R2,
2874
14
      { "value_R2", "sml.valueR2", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2875
14
    { &hf_sml_value_R3,
2876
14
      { "value_R3", "sml.valueR3", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2877
14
    { &hf_sml_value_R4,
2878
14
      { "value_R4", "sml.valueR4", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2879
14
    { &hf_sml_file_marker,
2880
14
      { "---SML-File---", "sml.file_marker", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2881
14
    { &hf_sml_new_file_marker,
2882
14
      { "---New SML File---", "sml.new_file_marker", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2883
14
    { &hf_sml_listtype,
2884
14
      { "listType", "sml.listtype", FT_UINT8, BASE_HEX, VALS(listtypevalues), 0x0, NULL, HFILL }},
2885
14
    { &hf_sml_cosemvalue,
2886
14
      { "cosemvalue", "sml.cosemvalue", FT_UINT8, BASE_HEX, VALS(cosemvaluevalues), 0x0, NULL, HFILL } },
2887
14
  };
2888
2889
  /* Setup protocol subtree array */
2890
14
  static int *ett[] = {
2891
14
    &ett_sml,
2892
14
    &ett_sml_mainlist,
2893
14
    &ett_sml_version,
2894
14
    &ett_sml_sublist,
2895
14
    &ett_sml_trans,
2896
14
    &ett_sml_group,
2897
14
    &ett_sml_abort,
2898
14
    &ett_sml_body,
2899
14
    &ett_sml_mblist,
2900
14
    &ett_sml_mttree,
2901
14
    &ett_sml_clientId,
2902
14
    &ett_sml_codepage,
2903
14
    &ett_sml_reqFileId,
2904
14
    &ett_sml_serverId,
2905
14
    &ett_sml_username,
2906
14
    &ett_sml_password,
2907
14
    &ett_sml_smlVersion,
2908
14
    &ett_sml_crc16,
2909
14
    &ett_sml_listName,
2910
14
    &ett_sml_globalSignature,
2911
14
    &ett_sml_refTime,
2912
14
    &ett_sml_actSensorTime,
2913
14
    &ett_sml_timetype,
2914
14
    &ett_sml_time,
2915
14
    &ett_sml_valList,
2916
14
    &ett_sml_objName,
2917
14
    &ett_sml_listEntry,
2918
14
    &ett_sml_status,
2919
14
    &ett_sml_valTime,
2920
14
    &ett_sml_unit,
2921
14
    &ett_sml_scaler,
2922
14
    &ett_sml_value,
2923
14
    &ett_sml_simplevalue,
2924
14
    &ett_sml_valueSignature,
2925
14
    &ett_sml_valtree,
2926
14
    &ett_sml_listSignature,
2927
14
    &ett_sml_actGatewayTime,
2928
14
    &ett_sml_treepath,
2929
14
    &ett_sml_parameterTreePath,
2930
14
    &ett_sml_attribute,
2931
14
    &ett_sml_parameterTree,
2932
14
    &ett_sml_parameterName,
2933
14
    &ett_sml_child,
2934
14
    &ett_sml_periodEntry,
2935
14
    &ett_sml_procParValueTime,
2936
14
    &ett_sml_procParValuetype,
2937
14
    &ett_sml_procParValue,
2938
14
    &ett_sml_msgend,
2939
14
    &ett_sml_tuple,
2940
14
    &ett_sml_secIndex,
2941
14
    &ett_sml_timestamp,
2942
14
    &ett_sml_localTimestamp,
2943
14
    &ett_sml_localOffset,
2944
14
    &ett_sml_seasonTimeOffset,
2945
14
    &ett_sml_signature,
2946
14
    &ett_sml_attentionNo,
2947
14
    &ett_sml_attentionMsg,
2948
14
    &ett_sml_withRawdata,
2949
14
    &ett_sml_beginTime,
2950
14
    &ett_sml_endTime,
2951
14
    &ett_sml_object_list,
2952
14
    &ett_sml_object_list_Entry,
2953
14
    &ett_sml_actTime,
2954
14
    &ett_sml_regPeriod,
2955
14
    &ett_sml_rawdata,
2956
14
    &ett_sml_periodSignature,
2957
14
    &ett_sml_period_List_Entry,
2958
14
    &ett_sml_periodList,
2959
14
    &ett_sml_header_List_Entry,
2960
14
    &ett_sml_profileSignature,
2961
14
    &ett_sml_valuelist,
2962
14
    &ett_sml_headerList,
2963
14
    &ett_sml_value_List_Entry,
2964
14
    &ett_sml_signature_mA_R2_R3,
2965
14
    &ett_sml_signature_pA_R1_R4,
2966
14
    &ett_sml_unit_mA,
2967
14
    &ett_sml_scaler_mA,
2968
14
    &ett_sml_value_mA,
2969
14
    &ett_sml_unit_pA,
2970
14
    &ett_sml_scaler_pA,
2971
14
    &ett_sml_value_pA,
2972
14
    &ett_sml_unit_R1,
2973
14
    &ett_sml_scaler_R1,
2974
14
    &ett_sml_value_R1,
2975
14
    &ett_sml_unit_R2,
2976
14
    &ett_sml_scaler_R2,
2977
14
    &ett_sml_value_R2,
2978
14
    &ett_sml_unit_R3,
2979
14
    &ett_sml_scaler_R3,
2980
14
    &ett_sml_value_R3,
2981
14
    &ett_sml_unit_R4,
2982
14
    &ett_sml_scaler_R4,
2983
14
    &ett_sml_value_R4,
2984
14
    &ett_sml_tree_Entry,
2985
14
    &ett_sml_dasDetails,
2986
14
    &ett_sml_attentionDetails,
2987
14
    &ett_sml_listtypetype,
2988
14
    &ett_sml_listtype,
2989
14
    &ett_sml_timestampedvaluetype,
2990
14
    &ett_sml_timestampedvalue,
2991
14
    &ett_sml_cosemvaluetype,
2992
14
    &ett_sml_cosemvalue,
2993
14
    &ett_sml_scaler_unit
2994
14
  };
2995
2996
14
  static ei_register_info ei[] = {
2997
14
    { &ei_sml_tuple_error, { "sml.tuple_error_", PI_PROTOCOL, PI_ERROR, "error in Tuple", EXPFILL }},
2998
14
    { &ei_sml_procParValue_invalid, { "sml.procparvalue.invalid", PI_PROTOCOL, PI_WARN, "invalid procParValue", EXPFILL }},
2999
14
    { &ei_sml_procParValue_errror, { "sml.procparvalue.error", PI_PROTOCOL, PI_ERROR, "error in procParValue", EXPFILL }},
3000
14
    { &ei_sml_invalid_count, { "sml.invalid_count", PI_PROTOCOL, PI_ERROR, "invalid loop count", EXPFILL }},
3001
14
    { &ei_sml_segment_needed, { "sml.segment_needed", PI_REASSEMBLE, PI_NOTE, "probably segment needed", EXPFILL }},
3002
14
    { &ei_sml_messagetype_unknown, { "sml.messagetype.unknown", PI_PROTOCOL, PI_ERROR, "unknown Messagetype", EXPFILL }},
3003
14
    { &ei_sml_MessageBody, { "sml.messagebody.error", PI_PROTOCOL, PI_ERROR, "Error in MessageBody", EXPFILL }},
3004
14
    { &ei_sml_crc_error_length, { "sml.crc.length_error", PI_PROTOCOL, PI_ERROR, "CRC length error", EXPFILL }},
3005
14
    { &ei_sml_crc_error, { "sml.crc.error", PI_CHECKSUM, PI_WARN, "CRC error", EXPFILL }},
3006
14
    { &ei_sml_endOfSmlMsg, { "sml.end.not_zero", PI_PROTOCOL, PI_ERROR, "MsgEnd not 0x00", EXPFILL }},
3007
14
    { &ei_sml_esc_error, { "sml.esc.error", PI_PROTOCOL, PI_ERROR, "escapesequence error", EXPFILL }},
3008
14
    { &ei_sml_version2_not_supported, { "sml.version2_not_supported", PI_UNDECODED, PI_WARN, "SML Version 2 not supported", EXPFILL }},
3009
14
    { &ei_sml_attentionNo, { "sml.attentionno.unknown", PI_PROTOCOL, PI_WARN, "unknown attentionNo", EXPFILL }},
3010
14
    { &ei_sml_listtype_invalid, { "sml.listtype.invalid", PI_PROTOCOL, PI_WARN, "invalid listtype", EXPFILL } },
3011
14
    { &ei_sml_cosemvalue_invalid, { "sml.cosemvalue.invalid", PI_PROTOCOL, PI_WARN, "invalid cosemvalue", EXPFILL } },
3012
14
  };
3013
3014
14
  proto_sml = proto_register_protocol("Smart Message Language","SML", "sml");
3015
14
  sml_handle = register_dissector("sml", dissect_sml, proto_sml);
3016
3017
14
  sml_module = prefs_register_protocol(proto_sml, NULL);
3018
3019
14
  prefs_register_bool_preference (sml_module, "reassemble", "Enable reassemble", "Enable reassembling (default is enabled)", &sml_reassemble);
3020
14
  prefs_register_bool_preference (sml_module, "crc", "Enable crc calculation", "Enable crc (default is disabled)", &sml_crc_enabled);
3021
3022
14
  proto_register_field_array(proto_sml, hf, array_length(hf));
3023
14
  proto_register_subtree_array(ett, array_length(ett));
3024
14
  expert_sml = expert_register_protocol(proto_sml);
3025
14
  expert_register_field_array(expert_sml, ei, array_length(ei));
3026
14
}
3027
3028
14
void proto_reg_handoff_sml(void) {
3029
14
  dissector_add_for_decode_as_with_preference("tcp.port", sml_handle);
3030
14
  dissector_add_for_decode_as_with_preference("udp.port", sml_handle);
3031
14
}
3032
3033
/*
3034
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3035
 *
3036
 * Local variables:
3037
 * c-basic-offset: 8
3038
 * tab-width: 8
3039
 * indent-tabs-mode: t
3040
 * End:
3041
 *
3042
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3043
 * :indentSize=8:tabSize=8:noTabs=false:
3044
 */