Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-sml.c
blobf2cb82cc4facd8def54a297e425142c93189823a
1 /* packet-sml.c
2 * Routines for SML dissection
3 * Copyright 2013, Alexander Gaertner <gaertner.alex@gmx.de>
5 * Enhancements for SML 1.05 dissection
6 * Copyright 2022, Uwe Heuert <uwe.heuert@exceeding-solutions.de>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
16 SML dissector is based on v1.03 (12.11.2008) specifications of "smart message language" protocol
18 Link to specifications: http://www.vde.com/de/fnn/arbeitsgebiete/messwesen/Sym2/infomaterial/seiten/sml-spezifikation.aspx
20 Short description of the SML protocol on the SML Wireshark Wiki page:
21 https://gitlab.com/wireshark/wireshark/-/wikis/SML
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>
30 #include <wsutil/str_util.h>
32 #define ESC_SEQ_END UINT64_C(0x1b1b1b1b1a)
33 #define ESC_SEQ 0x1b1b1b1b
35 #define OPEN_REQ 0x0100
36 #define OPEN_RES 0x0101
37 #define CLOSE_REQ 0x0200
38 #define CLOSE_RES 0x0201
39 #define PROFILEPACK_REQ 0x0300
40 #define PROFILEPACK_RES 0x0301
41 #define PROFILELIST_REQ 0x0400
42 #define PROFILELIST_RES 0x0401
43 #define GETPROCPARAMETER_REQ 0x0500
44 #define GETPROCPARAMETER_RES 0x0501
45 #define SETPROCPARAMETER_REQ 0x0600
46 #define GETLIST_REQ 0x0700
47 #define GETLIST_RES 0x0701
48 #define ATTENTION 0xFF01
50 #define PROC_VALUE 0x01
51 #define PROC_PERIOD 0x02
52 #define PROC_TUPLE 0x03
53 #define PROC_TIME 0x04
54 #define PROC_LISTENTRY 0x05
56 #define TIME_SECINDEX 0x01
57 #define TIME_TIMESTAMP 0x02
58 #define TIME_LOCALTIMESTAMP 0x03
60 #define LISTTYPE_TIME 0x01
61 #define LISTTYPE_TIMESTAMPEDVALUE 0x02
62 #define LISTTYPE_COSEMVALUE 0x03
64 #define COSEMVALUE_SCALER_UNIT 0x01
66 #define SHORT_LIST 0x70
67 #define LONG_LIST 0xF0
69 #define OPTIONAL 0x01
71 #define UNSIGNED8 0x62
72 #define UNSIGNED16 0x63
74 #define LIST_6_ELEMENTS 0x76
75 #define MSB 0x80
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);
81 static dissector_handle_t sml_handle;
83 /* Initialize the protocol and registered fields */
84 static int proto_sml;
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;
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}
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}
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}
206 static const value_string sml_timetypes[]={
207 {0x01, "secIndex"},
208 {0x02, "timestamp"},
209 {0x03, "localTimestamp" },
210 {0, NULL}
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}
222 static const value_string listtypevalues[] = {
223 { LISTTYPE_TIME, "smlTime" },
224 { LISTTYPE_TIMESTAMPEDVALUE, "smlTimestampedValue" },
225 { LISTTYPE_COSEMVALUE, "smlCosemValue" },
226 { 0, NULL }
229 static const value_string cosemvaluevalues[] = {
230 { COSEMVALUE_SCALER_UNIT, "scaler_unit" },
231 { 0, NULL }
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}
263 static const range_string bools[]={
264 {0x00, 0x00, "false"},
265 {0x01, 0xFF, "true"},
266 {0,0, NULL}
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;
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;
390 /*options*/
391 static bool sml_reassemble = true;
392 static bool sml_crc_enabled;
394 /*get number of length octets and calculate how many data octets, it's like BER but not the same! */
395 static void get_length(tvbuff_t *tvb, unsigned *offset, unsigned *data, unsigned *length){
396 unsigned check = 0;
397 unsigned temp_offset = 0;
399 temp_offset = *offset;
400 *data = 0;
401 *length = 0;
403 check = tvb_get_uint8(tvb, temp_offset);
404 if (check == OPTIONAL){
405 *length = 1;
407 else if ((check & 0x80) == MSB){
408 while ((check & 0x80) == MSB){
409 check = check & 0x0F;
411 *data = *data + check;
412 *data <<= 4;
413 *length+=1;
415 temp_offset+=1;
416 check = tvb_get_uint8(tvb, temp_offset);
418 check = check & 0x0F;
420 *data = *data + check;
421 *length+=1;
422 *data = *data - *length;
424 else{
425 check = check & 0x0F;
426 *length+=1;
427 *data = check - *length;
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);
437 static void sml_simplevalue(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
438 proto_item *value = NULL;
439 proto_tree *value_tree = NULL;
441 get_length(tvb, offset, data, length);
442 value = proto_tree_add_bytes_format(insert_tree, hf_sml_simplevalue, tvb, *offset, *length + *data, NULL, "value %s", (*data == 0) ? ": NOT SET" : "");
444 if (tvb_get_uint8(tvb, *offset) != OPTIONAL){
445 value_tree = proto_item_add_subtree(value, ett_sml_simplevalue);
446 if ((tvb_get_uint8(tvb, *offset) & 0x80) == MSB || (tvb_get_uint8(tvb, *offset) & 0xF0) == 0){
447 proto_tree_add_uint(value_tree, hf_sml_length, tvb, *offset, *length, *data);
448 *offset += *length;
450 else {
451 proto_tree_add_item(value_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
452 *offset += 1;
454 proto_tree_add_item(value_tree, hf_sml_simplevalue, tvb, *offset, *data, ENC_NA);
455 *offset += *data;
457 else
458 *offset += 1;
461 static void sml_timestampedvalue_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *timestampedvalue_tree, unsigned *offset){
462 proto_tree *SML_timestampedvalue_type_tree;
463 proto_tree *SML_time_tree;
464 proto_item *SML_time;
465 unsigned data = 0;
466 unsigned length = 0;
468 SML_timestampedvalue_type_tree = proto_tree_add_subtree(timestampedvalue_tree, tvb, *offset, -1, ett_sml_timestampedvaluetype, NULL, "SML_TimestampedValue Type");
470 /*smlTime*/
471 SML_time_tree = proto_tree_add_subtree(SML_timestampedvalue_type_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "smlTime");
472 *offset += 1;
473 sml_time_type(tvb, pinfo, SML_time_tree, offset);
474 proto_item_set_end(SML_time, tvb, *offset);
476 /*status*/
477 field_status(tvb, SML_timestampedvalue_type_tree, offset, &data, &length);
479 /*simpleValue*/
480 sml_simplevalue(tvb, SML_timestampedvalue_type_tree, offset, &data, &length);
483 static void sml_cosem_scaler_unit_type(tvbuff_t *tvb, proto_tree *cosem_scaler_unit_tree, unsigned *offset){
484 unsigned data, length;
486 /*scaler*/
487 get_length(tvb, offset, &data, &length);
488 field_scaler(tvb, cosem_scaler_unit_tree, offset, &data, &length);
490 /*unit*/
491 get_length(tvb, offset, &data, &length);
492 field_unit(tvb, cosem_scaler_unit_tree, offset, &data, &length);
495 static void sml_cosemvalue_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *cosemvalue_tree, unsigned *offset){
496 unsigned check = 0;
497 proto_item *SML_cosem_scaler_unit;
498 proto_tree *SML_cosemvalue_type_tree;
499 proto_tree *SML_cosem_scaler_unit_tree;
501 SML_cosemvalue_type_tree = proto_tree_add_subtree(cosemvalue_tree, tvb, *offset, -1, ett_sml_cosemvaluetype, NULL, "SML_CosemValue Type");
503 proto_tree_add_item(SML_cosemvalue_type_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
504 *offset += 1;
505 proto_tree_add_item(SML_cosemvalue_type_tree, hf_sml_cosemvalue, tvb, *offset, 1, ENC_BIG_ENDIAN);
507 check = tvb_get_uint8(tvb, *offset);
508 *offset += 1;
510 switch (check) {
511 case COSEMVALUE_SCALER_UNIT:
512 /*scaler_unit*/
513 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 *offset += 1;
515 sml_cosem_scaler_unit_type(tvb, SML_cosem_scaler_unit_tree, offset);
516 break;
518 default:
519 expert_add_info(pinfo, SML_cosemvalue_type_tree, &ei_sml_cosemvalue_invalid);
520 break;
524 static void sml_listtype_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *listtype_tree, unsigned *offset){
525 unsigned check = 0;
526 proto_tree *SML_listtype_type_tree;
527 proto_item *SML_time;
528 proto_tree *SML_time_tree = NULL;
529 proto_item *SML_timestampedvalue;
530 proto_tree *SML_timestampedvalue_tree = NULL;
531 proto_item *SML_cosemvalue;
532 proto_tree *SML_cosemvalue_tree = NULL;
534 SML_listtype_type_tree = proto_tree_add_subtree(listtype_tree, tvb, *offset, -1, ett_sml_listtypetype, NULL, "SML_ListType Type");
536 proto_tree_add_item(SML_listtype_type_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
537 *offset += 1;
538 proto_tree_add_item(SML_listtype_type_tree, hf_sml_listtype, tvb, *offset, 1, ENC_BIG_ENDIAN);
539 *offset += 1;
541 check = tvb_get_uint8(tvb, *offset);
542 *offset += 1;
544 switch (check) {
545 case LISTTYPE_TIME:
546 /*smlTime*/
547 SML_time_tree = proto_tree_add_subtree(SML_listtype_type_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "Time");
548 *offset += 1;
549 sml_time_type(tvb, pinfo, SML_time_tree, offset);
550 proto_item_set_end(SML_time, tvb, *offset);
551 break;
553 case LISTTYPE_TIMESTAMPEDVALUE:
554 /*smlTimestampedValue*/
555 SML_timestampedvalue_tree = proto_tree_add_subtree(SML_listtype_type_tree, tvb, *offset, -1, ett_sml_timestampedvalue, &SML_timestampedvalue, "TimestampedValue");
556 *offset += 1;
557 sml_timestampedvalue_type(tvb, pinfo, SML_timestampedvalue_tree, offset);
558 proto_item_set_end(SML_timestampedvalue, tvb, *offset);
559 break;
561 case LISTTYPE_COSEMVALUE:
562 /*smlCosemValue*/
563 SML_cosemvalue_tree = proto_tree_add_subtree(SML_listtype_type_tree, tvb, *offset, -1, ett_sml_cosemvalue, &SML_cosemvalue, "CosemValue");
564 *offset += 1;
565 sml_cosemvalue_type(tvb, pinfo, SML_cosemvalue_tree, offset);
566 break;
568 default:
569 expert_add_info(pinfo, SML_listtype_type_tree, &ei_sml_listtype_invalid);
570 break;
574 static void sml_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
575 proto_item *value = NULL;
576 proto_tree *value_tree = NULL;
578 get_length(tvb, offset, data, length);
579 value = proto_tree_add_bytes_format (insert_tree, hf_sml_value, tvb, *offset, *length + *data, NULL,"value %s", (*data == 0)? ": NOT SET" : "");
581 if (tvb_get_uint8(tvb, *offset) != OPTIONAL){
582 value_tree = proto_item_add_subtree (value, ett_sml_value);
583 if (tvb_get_uint8(tvb, *offset) == 0x72) {
584 sml_listtype_type(tvb, pinfo, value_tree, offset);
586 else
588 if ((tvb_get_uint8(tvb, *offset) & 0x80) == MSB || (tvb_get_uint8(tvb, *offset) & 0xF0) == 0){
589 proto_tree_add_uint(value_tree, hf_sml_length, tvb, *offset, *length, *data);
590 *offset+= *length;
592 else {
593 proto_tree_add_item (value_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
594 *offset+=1;
596 proto_tree_add_item (value_tree, hf_sml_value, tvb, *offset, *data, ENC_NA);
597 *offset+= *data;
600 else
601 *offset+=1;
604 static void sml_time_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *SML_time_tree, unsigned *offset){
605 unsigned check = 0;
606 proto_tree *timetype_tree;
607 proto_tree *timevalue_tree;
608 proto_tree *localtimestamptype_tree;
609 unsigned data = 0;
610 unsigned length = 0;
612 timetype_tree = proto_tree_add_subtree(SML_time_tree, tvb, *offset, 2, ett_sml_timetype, NULL, "SML-Time Type");
614 proto_tree_add_item (timetype_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
615 *offset+=1;
616 proto_tree_add_item (timetype_tree, hf_sml_timetype, tvb, *offset, 1, ENC_BIG_ENDIAN);
617 //*offset+=1;
619 check = tvb_get_uint8(tvb, *offset);
620 *offset += 1;
622 switch (check) {
623 case TIME_SECINDEX:
624 /*secIndex*/
625 get_length(tvb, offset, &data, &length);
626 timevalue_tree = proto_tree_add_subtree(SML_time_tree, tvb, *offset, length + data, ett_sml_secIndex, NULL, "secIndex");
627 proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
628 *offset += 1;
629 proto_tree_add_item(timevalue_tree, hf_sml_secIndex, tvb, *offset, data, ENC_BIG_ENDIAN);
630 *offset += data;
632 break;
633 case TIME_TIMESTAMP:
634 /*timestamp*/
635 get_length(tvb, offset, &data, &length);
636 timevalue_tree = proto_tree_add_subtree(SML_time_tree, tvb, *offset, length + data, ett_sml_timestamp, NULL, "timestamp");
637 proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
638 *offset += 1;
639 proto_tree_add_item(timevalue_tree, hf_sml_timestamp, tvb, *offset, data, ENC_BIG_ENDIAN);
640 *offset += data;
642 break;
644 case TIME_LOCALTIMESTAMP:
645 /*localTimestamp*/
646 localtimestamptype_tree = proto_tree_add_subtree(SML_time_tree, tvb, *offset, length + data, ett_sml_localTimestamp, NULL, "localTimestamp");
647 *offset += 1;
649 get_length(tvb, offset, &data, &length);
650 timevalue_tree = proto_tree_add_subtree(localtimestamptype_tree, tvb, *offset, length + data, ett_sml_timestamp, NULL, "timestamp");
651 proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
652 *offset += 1;
653 proto_tree_add_item(timevalue_tree, hf_sml_timestamp, tvb, *offset, data, ENC_BIG_ENDIAN);
654 *offset += data;
656 get_length(tvb, offset, &data, &length);
657 timevalue_tree = proto_tree_add_subtree(localtimestamptype_tree, tvb, *offset, length + data, ett_sml_localOffset, NULL, "localOffset");
658 proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
659 *offset += 1;
660 proto_tree_add_item(timevalue_tree, hf_sml_localOffset, tvb, *offset, data, ENC_BIG_ENDIAN);
661 *offset += data;
663 get_length(tvb, offset, &data, &length);
664 timevalue_tree = proto_tree_add_subtree(localtimestamptype_tree, tvb, *offset, length + data, ett_sml_seasonTimeOffset, NULL, "seasonTimeOffset");
665 proto_tree_add_item(timevalue_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
666 *offset += 1;
667 proto_tree_add_item(timevalue_tree, hf_sml_seasonTimeOffset, tvb, *offset, data, ENC_BIG_ENDIAN);
668 *offset += data;
670 break;
672 default:
673 expert_add_info(pinfo, timetype_tree, &ei_sml_listtype_invalid);
674 break;
678 static void field_codepage(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
679 proto_item *codepage = NULL;
680 proto_tree *codepage_tree = NULL;
682 get_length(tvb, offset, data, length);
683 codepage = proto_tree_add_bytes_format (insert_tree, hf_sml_codepage, tvb, *offset, *length + *data, NULL,"Codepage %s", (*data == 0)? ": NOT SET" : "");
685 if (*data > 0) {
686 codepage_tree = proto_item_add_subtree (codepage , ett_sml_codepage);
687 proto_tree_add_uint(codepage_tree, hf_sml_length, tvb, *offset, *length, *data);
688 *offset+= *length;
690 proto_tree_add_item (codepage_tree, hf_sml_codepage, tvb, *offset, *data, ENC_NA);
691 *offset+= *data;
693 else
694 *offset+=1;
697 static void field_clientId(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
698 proto_item *clientId = NULL;
699 proto_tree *clientId_tree = NULL;
701 get_length(tvb, offset, data, length);
702 clientId = proto_tree_add_bytes_format (insert_tree, hf_sml_clientId, tvb, *offset, *length + *data, NULL, "clientID %s", (*data == 0)? ": NOT SET" : "");
704 if (*data > 0) {
705 clientId_tree = proto_item_add_subtree (clientId, ett_sml_clientId);
706 proto_tree_add_uint(clientId_tree, hf_sml_length, tvb, *offset, *length, *data);
707 *offset+=*length;
708 proto_tree_add_item (clientId_tree, hf_sml_clientId, tvb, *offset, *data, ENC_NA);
709 *offset+=*data;
711 else
712 *offset+=1;
715 static void field_reqFileId(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
716 proto_tree *reqFileId_tree;
718 get_length(tvb, offset, data, length);
719 reqFileId_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_reqFileId, NULL, "reqFileId");
721 proto_tree_add_uint (reqFileId_tree, hf_sml_length, tvb, *offset, *length, *data);
722 *offset+=*length;
723 proto_tree_add_item (reqFileId_tree, hf_sml_reqFileId, tvb, *offset, *data, ENC_NA);
724 *offset+=*data;
727 static void field_serverId(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
728 proto_item *serverId = NULL;
729 proto_tree *serverId_tree = NULL;
731 /*Server ID OPTIONAL*/
732 get_length(tvb, offset, data, length);
733 serverId = proto_tree_add_bytes_format (insert_tree,hf_sml_serverId, tvb, *offset, *length + *data, NULL, "Server ID %s", (*data == 0)? ": NOT SET" : "");
735 if (*data > 0){
736 serverId_tree = proto_item_add_subtree (serverId , ett_sml_serverId);
737 proto_tree_add_uint (serverId_tree, hf_sml_length, tvb, *offset, *length, *data);
738 *offset+=*length;
739 proto_tree_add_item (serverId_tree, hf_sml_serverId, tvb, *offset, *data, ENC_NA);
740 *offset+=*data;
742 else
743 *offset+=1;
746 static void field_username(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
747 proto_item *username = NULL;
748 proto_tree *username_tree = NULL;
750 /*Username OPTIONAL*/
751 get_length(tvb, offset, data, length);
752 username = proto_tree_add_string_format (insert_tree,hf_sml_username, tvb, *offset, *length + *data, NULL, "Username %s", (*data == 0)? ": NOT SET" : "");
754 if (*data > 0){
755 username_tree = proto_item_add_subtree (username , ett_sml_username);
756 proto_tree_add_uint (username_tree, hf_sml_length, tvb, *offset, *length, *data);
757 *offset+=*length;
758 proto_tree_add_item (username_tree, hf_sml_username, tvb, *offset, *data, ENC_ASCII | ENC_BIG_ENDIAN);
759 *offset+=*data;
761 else
762 *offset+=1;
765 static void field_password(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
766 proto_item *password = NULL;
767 proto_tree *password_tree = NULL;
769 /*Password OPTIONAL*/
770 get_length(tvb, offset, data, length);
771 password = proto_tree_add_string_format (insert_tree,hf_sml_password, tvb, *offset, *length + *data, NULL, "Password %s", (*data == 0)? ": NOT SET" : "");
773 if (*data > 0) {
774 password_tree = proto_item_add_subtree (password, ett_sml_password);
775 proto_tree_add_uint (password_tree, hf_sml_length, tvb, *offset, *length, *data);
776 *offset+=*length;
777 proto_tree_add_item (password_tree, hf_sml_password, tvb, *offset, *data, ENC_ASCII | ENC_BIG_ENDIAN);
778 *offset+=*data;
780 else
781 *offset+=1;
784 static void field_smlVersion(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
785 proto_item *smlVersion = NULL;
786 proto_tree *smlVersion_tree = NULL;
788 /*sml-Version OPTIONAL*/
789 get_length(tvb, offset, data, length);
790 smlVersion = proto_tree_add_uint_format (insert_tree, hf_sml_smlVersion, tvb, *offset, *length + *data, *length + *data, "SML-Version %s", (*data == 0)? ": Version 1" : "");
792 if (*data > 0) {
793 smlVersion_tree = proto_item_add_subtree (smlVersion, ett_sml_smlVersion);
794 proto_tree_add_item (smlVersion_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
795 *offset+=1;
797 proto_tree_add_item (smlVersion_tree, hf_sml_smlVersion, tvb, *offset, 1,ENC_BIG_ENDIAN);
798 *offset+=1;
800 else
801 *offset+=1;
804 static void field_globalSignature(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
805 proto_item *globalSignature = NULL;
806 proto_tree *globalSignature_tree = NULL;
808 /*Global Signature OPTIONAL*/
809 get_length(tvb, offset, data, length);
811 globalSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_globalSignature, tvb, *offset, *length + *data, NULL, "global Signature %s", (*data == 0)? ": NOT SET" : "");
813 if (*data > 0){
814 globalSignature_tree = proto_item_add_subtree (globalSignature, ett_sml_globalSignature);
815 proto_tree_add_uint (globalSignature_tree, hf_sml_length, tvb, *offset, *length, *data);
816 *offset+=*length;
817 proto_tree_add_item (globalSignature_tree, hf_sml_globalSignature, tvb, *offset, *data, ENC_NA);
818 *offset+=*data;
820 else
821 *offset+=1;
824 static void field_listName(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
825 proto_item *listName = NULL;
826 proto_tree *listName_tree = NULL;
828 /*List Name OPTIONAL*/
829 get_length(tvb, offset, data, length);
830 listName = proto_tree_add_bytes_format (insert_tree,hf_sml_listName, tvb, *offset, *length + *data, NULL, "List Name %s", (*data == 0)? ": NOT SET" : "");
832 if (*data > 0) {
833 listName_tree = proto_item_add_subtree (listName, ett_sml_listName);
834 proto_tree_add_uint (listName_tree, hf_sml_length, tvb, *offset, *length, *data);
835 *offset+=*length;
836 proto_tree_add_item (listName_tree, hf_sml_listName, tvb, *offset, *data, ENC_NA);
837 *offset+=*data;
839 else
840 *offset+=1;
843 static void field_objName(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
844 proto_tree *objName_tree;
846 /*Objectname*/
847 get_length(tvb, offset, data, length);
848 objName_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_objName, NULL, "Objectname");
850 proto_tree_add_uint (objName_tree, hf_sml_length, tvb, *offset, *length, *data);
851 *offset+=*length;
852 proto_tree_add_item (objName_tree, hf_sml_objName, tvb, *offset, *data, ENC_NA);
853 *offset+=*data;
856 static void field_status(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
857 proto_tree *status_tree = NULL;
859 get_length(tvb, offset, data, length);
860 status_tree = proto_tree_add_subtree_format(insert_tree, tvb, *offset, *length + *data,
861 ett_sml_status, NULL, "status %s", (*data == 0)? ": NOT SET" : "");
863 if (*data > 0){
864 proto_tree_add_item (status_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
865 *offset+=1;
866 proto_tree_add_item (status_tree, hf_sml_status, tvb, *offset, *data, ENC_BIG_ENDIAN);
867 *offset+= *data;
869 else
870 *offset+=1;
873 static void field_unit(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
874 proto_item *unit = NULL;
875 proto_tree *unit_tree = NULL;
877 /*unit OPTIONAL*/
878 get_length(tvb, offset, data, length);
879 unit = proto_tree_add_uint_format (insert_tree, hf_sml_unit, tvb, *offset, *length + *data, *length + *data, "Unit %s", (*data == 0)? ": NOT SET" : "");
880 if (*data > 0) {
881 unit_tree = proto_item_add_subtree (unit, ett_sml_unit);
882 proto_tree_add_item (unit_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
883 *offset+=1;
884 proto_tree_add_item(unit_tree, hf_sml_unit, tvb, *offset, 1, ENC_BIG_ENDIAN);
885 *offset+=1;
887 else
888 *offset+=1;
891 static void field_scaler(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
892 proto_item *scaler = NULL;
893 proto_tree *scaler_tree = NULL;
895 /*Scaler OPTIONAL*/
896 get_length(tvb, offset, data, length);
897 scaler = proto_tree_add_uint_format (insert_tree, hf_sml_scaler, tvb, *offset, *length + *data, *length + *data, "Scaler %s", (*data == 0)? ": NOT SET" : "");
899 if (*data > 0){
900 scaler_tree = proto_item_add_subtree (scaler, ett_sml_scaler);
901 proto_tree_add_item (scaler_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
902 *offset+=1;
903 proto_tree_add_item(scaler_tree, hf_sml_scaler, tvb, *offset, 1, ENC_BIG_ENDIAN);
904 *offset+=1;
906 else
907 *offset+=1;
910 static void field_valueSignature(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
911 proto_item *valueSignature = NULL;
912 proto_tree *valueSignature_tree = NULL;
914 /*value Signature*/
915 get_length(tvb, offset, data, length);
916 valueSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_valueSignature, tvb, *offset, *length + *data, NULL, "ValueSignature %s", (*data == 0)? ": NOT SET" : "");
918 if (*data > 0){
919 valueSignature_tree = proto_item_add_subtree (valueSignature, ett_sml_valueSignature);
920 proto_tree_add_uint (valueSignature_tree, hf_sml_length, tvb, *offset, *length, *data);
921 *offset+=*length;
922 proto_tree_add_item (valueSignature_tree, hf_sml_valueSignature, tvb, *offset, *data, ENC_NA);
923 *offset+=*data;
925 else
926 *offset+=1;
929 static void field_parameterTreePath(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
930 proto_item *parameterTreePath = NULL;
931 proto_tree *parameterTreePath_tree = NULL;
933 /*parameterTreePath*/
934 get_length(tvb, offset, data, length);
935 parameterTreePath = proto_tree_add_bytes_format (insert_tree, hf_sml_parameterTreePath, tvb, *offset, *length + *data, NULL, "path_Entry %s", (*data == 0)? ": NOT SET" : "");
937 parameterTreePath_tree = proto_item_add_subtree (parameterTreePath, ett_sml_parameterTreePath);
938 proto_tree_add_uint (parameterTreePath_tree, hf_sml_length, tvb, *offset, *length, *data);
939 *offset+=*length;
940 proto_tree_add_item (parameterTreePath_tree, hf_sml_parameterTreePath, tvb, *offset, *data, ENC_NA);
941 *offset+=*data;
944 static void field_ObjReqEntry(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
945 proto_tree *object_list_Entry_tree;
947 /*parameterTreePath*/
948 get_length(tvb, offset, data, length);
949 object_list_Entry_tree = proto_tree_add_subtree(insert_tree, tvb ,*offset, *length + *data, ett_sml_object_list_Entry, NULL, "object_list_Entry");
950 proto_tree_add_uint (object_list_Entry_tree, hf_sml_length, tvb, *offset, *length, *data);
951 *offset+=*length;
952 proto_tree_add_item (object_list_Entry_tree, hf_sml_object_list_Entry, tvb, *offset, *data, ENC_NA);
953 *offset+=*data;
956 static void field_regPeriod(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
957 proto_tree *regPeriod_tree;
959 get_length(tvb, offset, data, length);
960 regPeriod_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_regPeriod, NULL, "regPeriod");
962 proto_tree_add_item (regPeriod_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
963 *offset+=1;
964 proto_tree_add_item (regPeriod_tree, hf_sml_regPeriod, tvb, *offset, *data, ENC_BIG_ENDIAN);
965 *offset+=*data;
968 static void field_rawdata(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
969 proto_item *rawdata = NULL;
970 proto_tree *rawdata_tree = NULL;
972 /*rawdata*/
973 get_length(tvb, offset, data, length);
974 rawdata = proto_tree_add_bytes_format (insert_tree, hf_sml_rawdata, tvb, *offset, *length + *data, NULL, "rawdata %s", (*data == 0)? ": NOT SET" : "");
976 if (*data > 0){
977 rawdata_tree = proto_item_add_subtree (rawdata, ett_sml_rawdata);
978 proto_tree_add_uint (rawdata_tree, hf_sml_length, tvb, *offset, *length, *data);
979 *offset+=*length;
980 proto_tree_add_item (rawdata_tree, hf_sml_rawdata, tvb, *offset, *data, ENC_NA);
981 *offset+=*data;
983 else
984 *offset+=1;
987 static void field_periodSignature(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
988 proto_item *periodSignature = NULL;
989 proto_tree *periodSignature_tree = NULL;
991 /*periodSignature*/
992 get_length(tvb, offset, data, length);
993 periodSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_periodSignature, tvb, *offset, *length + *data, NULL,"periodSignature %s", (*data == 0)? ": NOT SET" : "");
995 if (*data > 0){
996 periodSignature_tree = proto_item_add_subtree (periodSignature, ett_sml_periodSignature);
997 proto_tree_add_uint (periodSignature_tree, hf_sml_length, tvb, *offset, *length, *data);
998 *offset+=*length;
999 proto_tree_add_item (periodSignature_tree, hf_sml_periodSignature, tvb, *offset, *data, ENC_NA);
1000 *offset+=*data;
1002 else
1003 *offset+=1;
1006 static void field_actTime(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
1007 proto_tree *actTime_tree;
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;
1017 static void field_valTime(tvbuff_t *tvb, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
1018 proto_tree *valTime_tree;
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;
1028 static void TupleEntryTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *procParValue_tree, unsigned *offset){
1029 proto_item *SML_time;
1030 proto_item *TupleEntry;
1032 proto_tree *TupleEntry_list = NULL;
1033 proto_tree *SML_time_tree = NULL;
1034 //proto_tree *secIndex_tree = NULL;
1035 proto_tree *unit_pA_tree = NULL;
1036 proto_tree *scaler_pA_tree = NULL;
1037 proto_tree *value_pA_tree = NULL;
1038 proto_tree *unit_mA_tree = NULL;
1039 proto_tree *scaler_mA_tree = NULL;
1040 proto_tree *value_mA_tree = NULL;
1041 proto_tree *unit_R1_tree = NULL;
1042 proto_tree *scaler_R1_tree = NULL;
1043 proto_tree *value_R1_tree = NULL;
1044 proto_tree *unit_R2_tree = NULL;
1045 proto_tree *scaler_R2_tree = NULL;
1046 proto_tree *value_R2_tree = NULL;
1047 proto_tree *unit_R3_tree = NULL;
1048 proto_tree *scaler_R3_tree = NULL;
1049 proto_tree *value_R3_tree = NULL;
1050 proto_tree *unit_R4_tree = NULL;
1051 proto_tree *scaler_R4_tree = NULL;
1052 proto_tree *value_R4_tree = NULL;
1053 proto_tree *signature_pA_R1_R4_tree = NULL;
1054 proto_tree *signature_mA_R2_R3_tree = NULL;
1056 unsigned data = 0;
1057 unsigned length = 0;
1059 /*Tuple_List*/
1060 TupleEntry_list = proto_tree_add_subtree(procParValue_tree, tvb, *offset, -1, ett_sml_tuple, &TupleEntry, "TupleEntry");
1061 get_length(tvb, offset, &data, &length);
1062 *offset+=length;
1064 /*Server Id*/
1065 field_serverId(tvb, TupleEntry_list, offset, &data, &length);
1067 /*secindex*/
1068 SML_time_tree = proto_tree_add_subtree(procParValue_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "secIndex");
1069 *offset+=1;
1070 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1071 proto_item_set_end(SML_time, tvb, *offset);
1073 /*Sml Status OPTIONAL*/
1074 field_status(tvb, TupleEntry_list, offset, &data, &length);
1076 /*unit_pA*/
1077 unit_pA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_pA, NULL, "unit_pA");
1078 proto_tree_add_item (unit_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1079 *offset+=1;
1080 proto_tree_add_item (unit_pA_tree, hf_sml_unit_pA, tvb, *offset, 1, ENC_BIG_ENDIAN);
1081 *offset+=1;
1083 /*scaler_pA*/
1084 scaler_pA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_pA, NULL, "scaler_pA");
1085 proto_tree_add_item (scaler_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1086 *offset+=1;
1087 proto_tree_add_item (scaler_pA_tree, hf_sml_scaler_pA, tvb, *offset, 1, ENC_BIG_ENDIAN);
1088 *offset+=1;
1090 /*value_pA*/
1091 get_length(tvb, offset, &data, &length);
1092 value_pA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_pA, NULL, "value_pA");
1093 proto_tree_add_item (value_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1094 *offset+=1;
1095 proto_tree_add_item (value_pA_tree, hf_sml_value_pA, tvb, *offset, data, ENC_BIG_ENDIAN);
1096 *offset+=data;
1098 /*unit_R1*/
1099 unit_R1_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_R1, NULL, "unit_R1");
1100 proto_tree_add_item (unit_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1101 *offset+=1;
1102 proto_tree_add_item (unit_R1_tree, hf_sml_unit_R1, tvb, *offset, 1, ENC_BIG_ENDIAN);
1103 *offset+=1;
1105 /*scaler_R1*/
1106 scaler_R1_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 1, ett_sml_scaler_R1, NULL, "scaler_R1");
1107 proto_tree_add_item (scaler_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1108 *offset+=1;
1109 proto_tree_add_item (scaler_R1_tree, hf_sml_scaler_R1, tvb, *offset, 1, ENC_BIG_ENDIAN);
1110 *offset+=1;
1112 /*value_R1*/
1113 get_length(tvb, offset, &data, &length);
1114 value_R1_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_R1, NULL, "value_R1");
1115 proto_tree_add_item (value_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1116 *offset+=1;
1117 proto_tree_add_item (value_R1_tree, hf_sml_value_R1, tvb, *offset, data, ENC_BIG_ENDIAN);
1118 *offset+=data;
1120 /*unit_R4*/
1121 unit_R4_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_R4, NULL, "unit_R4");
1122 proto_tree_add_item (unit_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1123 *offset+=1;
1124 proto_tree_add_item (unit_R4_tree, hf_sml_unit_R4, tvb, *offset, 1, ENC_BIG_ENDIAN);
1125 *offset+=1;
1127 /*scaler_R4*/
1128 scaler_R4_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_R4, NULL, "scaler_R4");
1129 proto_tree_add_item (scaler_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1130 *offset+=1;
1131 proto_tree_add_item (scaler_R4_tree, hf_sml_scaler_R4, tvb, *offset, 1, ENC_BIG_ENDIAN);
1132 *offset+=1;
1134 /*value_R4*/
1135 get_length(tvb, offset, &data, &length);
1136 value_R4_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_R4, NULL, "value_R4");
1137 proto_tree_add_item (value_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1138 *offset+=1;
1139 proto_tree_add_item (value_R4_tree, hf_sml_value_R4, tvb, *offset, data, ENC_BIG_ENDIAN);
1140 *offset+=data;
1142 /*signature_pA_R1_R4*/
1143 get_length(tvb, offset, &data, &length);
1144 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 proto_tree_add_uint (signature_pA_R1_R4_tree, hf_sml_length, tvb, *offset, length, data);
1146 *offset+=length;
1147 proto_tree_add_item (signature_pA_R1_R4_tree, hf_sml_signature_pA_R1_R4, tvb, *offset, data, ENC_NA);
1148 *offset+=data;
1150 /*unit_mA*/
1151 unit_mA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_mA, NULL, "unit_mA");
1152 proto_tree_add_item (unit_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1153 *offset+=1;
1154 proto_tree_add_item (unit_mA_tree, hf_sml_unit_mA, tvb, *offset, 1, ENC_BIG_ENDIAN);
1155 *offset+=1;
1157 /*scaler_mA*/
1158 scaler_mA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_mA, NULL, "scaler_mA");
1159 proto_tree_add_item (scaler_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1160 *offset+=1;
1161 proto_tree_add_item (scaler_mA_tree, hf_sml_scaler_mA, tvb, *offset, 1, ENC_BIG_ENDIAN);
1162 *offset+=1;
1164 /*value_mA*/
1165 get_length(tvb, offset, &data, &length);
1166 value_mA_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_mA, NULL, "value_mA");
1167 proto_tree_add_item (value_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1168 *offset+=1;
1169 proto_tree_add_item (value_mA_tree, hf_sml_value_mA, tvb, *offset, data, ENC_BIG_ENDIAN);
1170 *offset+=data;
1172 /*unit_R2*/
1173 unit_R2_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_R2, NULL, "unit_R2");
1174 proto_tree_add_item (unit_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1175 *offset+=1;
1176 proto_tree_add_item (unit_R2_tree, hf_sml_unit_R2, tvb, *offset, 1, ENC_BIG_ENDIAN);
1177 *offset+=1;
1179 /*scaler_R2*/
1180 scaler_R2_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_R2, NULL, "scaler_R2");
1181 proto_tree_add_item (scaler_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1182 *offset+=1;
1183 proto_tree_add_item (scaler_R2_tree, hf_sml_scaler_R2, tvb, *offset, 1, ENC_BIG_ENDIAN);
1184 *offset+=1;
1186 /*value_R2*/
1187 get_length(tvb, offset, &data, &length);
1188 value_R2_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_R2, NULL, "value_R2");
1189 proto_tree_add_item (value_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1190 *offset+=1;
1191 proto_tree_add_item (value_R2_tree, hf_sml_value_R2, tvb, *offset, data, ENC_BIG_ENDIAN);
1192 *offset+=data;
1194 /*unit_R3*/
1195 unit_R3_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_unit_R3, NULL, "unit_R3");
1196 proto_tree_add_item (unit_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1197 *offset+=1;
1198 proto_tree_add_item (unit_R3_tree, hf_sml_unit_R3, tvb, *offset, 1, ENC_BIG_ENDIAN);
1199 *offset+=1;
1201 /*scaler_R3*/
1202 scaler_R3_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, 2, ett_sml_scaler_R3, NULL, "scaler_R3");
1203 proto_tree_add_item (scaler_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1204 *offset+=1;
1205 proto_tree_add_item (scaler_R3_tree, hf_sml_scaler_R3, tvb, *offset, 1, ENC_BIG_ENDIAN);
1206 *offset+=1;
1208 /*value_R3*/
1209 get_length(tvb, offset, &data, &length);
1210 value_R3_tree = proto_tree_add_subtree(TupleEntry_list, tvb, *offset, length+data, ett_sml_value_R3, NULL, "value_R3");
1211 proto_tree_add_item (value_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1212 *offset+=1;
1213 proto_tree_add_item (value_R3_tree, hf_sml_value_R3, tvb, *offset, data, ENC_BIG_ENDIAN);
1214 *offset+=data;
1216 /*signature_mA_R2_R3*/
1217 get_length(tvb, offset, &data, &length);
1218 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 proto_tree_add_uint (signature_mA_R2_R3_tree, hf_sml_length, tvb, *offset, length, data);
1220 *offset+=length;
1221 proto_tree_add_item (signature_mA_R2_R3_tree, hf_sml_signature_mA_R2_R3, tvb, *offset, data, ENC_NA);
1222 *offset+=data;
1224 proto_item_set_end(TupleEntry, tvb, *offset);
1227 // NOLINTNEXTLINE(misc-no-recursion)
1228 static void child_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *insert_tree, unsigned *offset, unsigned *data, unsigned *length){
1229 proto_item *parameterName;
1230 proto_item *procParValue;
1231 proto_item *child;
1232 proto_item *periodEntry;
1233 proto_item *SML_time;
1234 proto_item *listEntry;
1235 proto_item *tree_Entry;
1237 proto_tree *parameterName_tree = NULL;
1238 proto_tree *procParValue_tree = NULL;
1239 proto_tree *procParValuetype_tree = NULL;
1240 proto_tree *periodEntry_tree = NULL;
1241 proto_tree *SML_time_tree = NULL;
1242 proto_tree *listEntry_tree = NULL;
1243 //proto_tree *procParValueTime_tree = NULL;
1244 proto_tree *child_list = NULL;
1245 proto_tree *tree_Entry_list = NULL;
1247 unsigned i = 0;
1248 unsigned repeat = 0;
1249 unsigned check = 0;
1251 /*parameterName*/
1252 get_length(tvb, offset, data, length);
1253 parameterName_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, *length + *data, ett_sml_parameterName, &parameterName, "parameterName");
1254 proto_tree_add_uint (parameterName_tree, hf_sml_length, tvb, *offset, *length, *data);
1255 *offset+=*length;
1256 proto_tree_add_item (parameterName_tree, hf_sml_parameterName, tvb, *offset, *data, ENC_NA);
1257 *offset+=*data;
1259 /*procParValue OPTIONAL*/
1260 check = tvb_get_uint8(tvb, *offset);
1262 if (check == OPTIONAL){
1263 procParValue = proto_tree_add_item(insert_tree, hf_sml_procParValue, tvb, *offset, 1, ENC_BIG_ENDIAN);
1264 proto_item_append_text(procParValue, ": NOT SET");
1265 *offset+=1;
1267 else if (check == 0x72){
1268 get_length(tvb, offset, data, length);
1269 procParValue_tree = proto_tree_add_subtree(insert_tree, tvb, *offset, -1, ett_sml_procParValue, &procParValue, "ProcParValue");
1270 *offset+=1;
1272 /*procParValue CHOOSE*/
1273 procParValuetype_tree = proto_tree_add_subtree(procParValue_tree, tvb, *offset, 2, ett_sml_procParValuetype, NULL, "ProcParValueType");
1274 proto_tree_add_item (procParValuetype_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1275 *offset+=1;
1276 check = tvb_get_uint8(tvb, *offset);
1277 proto_tree_add_item (procParValuetype_tree, hf_sml_procParValue, tvb, *offset, 1 ,ENC_BIG_ENDIAN);
1278 *offset+=1;
1280 switch (check) {
1281 case PROC_VALUE:
1282 /*value*/
1283 sml_value(tvb, pinfo, procParValue_tree, offset, data, length);
1284 break;
1286 case PROC_PERIOD:
1287 /*period*/
1288 get_length(tvb, offset, data, length);
1289 periodEntry_tree = proto_tree_add_subtree_format(procParValue_tree, tvb, *offset, -1, ett_sml_periodEntry, &periodEntry,
1290 "PeriodEntry List with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1291 *offset+=*length;
1293 /*objName*/
1294 field_objName(tvb, periodEntry_tree, offset, data, length);
1296 /*unit OPTIONAL*/
1297 field_unit(tvb, periodEntry_tree, offset, data, length);
1299 /*scaler OPTIONAL*/
1300 field_scaler(tvb, periodEntry_tree, offset, data, length);
1302 /*value*/
1303 sml_value(tvb, pinfo, periodEntry_tree, offset, data, length);
1305 /*value Signature*/
1306 field_valueSignature(tvb, periodEntry_tree, offset, data, length);
1308 proto_item_set_end(periodEntry, tvb, *offset);
1309 break;
1311 case PROC_TUPLE:
1312 /*TupleEntry*/
1313 if (tvb_get_uint8(tvb, *offset) == 0xF1 && tvb_get_uint8(tvb, *offset+1) == 0x07){
1314 TupleEntryTree(tvb, pinfo, procParValue_tree, offset);
1316 else {
1317 expert_add_info(pinfo, NULL, &ei_sml_tuple_error);
1318 return;
1320 break;
1322 case PROC_TIME:
1323 SML_time_tree = proto_tree_add_subtree(procParValue_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "Time");
1324 *offset+=1;
1325 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1326 proto_item_set_end(SML_time, tvb, *offset);
1327 break;
1329 case PROC_LISTENTRY:
1330 /*listEntry*/
1331 get_length(tvb, offset, data, length);
1332 listEntry_tree = proto_tree_add_subtree_format(procParValue_tree, tvb, *offset, -1, ett_sml_listEntry, &listEntry,
1333 "ListEntry List with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1334 *offset += *length;
1336 /*objName*/
1337 field_objName(tvb, listEntry_tree, offset, data, length);
1339 /*status OPTIONAL*/
1340 field_status(tvb, listEntry_tree, offset, data, length);
1342 /*valTime OPTIONAL*/
1343 SML_time_tree = proto_tree_add_subtree(listEntry_tree, tvb, *offset, -1, ett_sml_time, &SML_time, "Time");
1344 *offset += 1;
1345 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1346 proto_item_set_end(SML_time, tvb, *offset);
1348 /*unit OPTIONAL*/
1349 field_unit(tvb, listEntry_tree, offset, data, length);
1351 /*scaler OPTIONAL*/
1352 field_scaler(tvb, listEntry_tree, offset, data, length);
1354 /*value*/
1355 sml_value(tvb, pinfo, listEntry_tree, offset, data, length);
1357 /*valueSignature OPTIONAL*/
1358 field_valueSignature(tvb, listEntry_tree, offset, data, length);
1360 proto_item_set_end(listEntry, tvb, *offset);
1361 break;
1363 default:
1364 expert_add_info(pinfo, procParValue, &ei_sml_procParValue_invalid);
1365 break;
1367 proto_item_set_end(procParValue, tvb, *offset);
1369 else {
1370 expert_add_info(pinfo, NULL, &ei_sml_procParValue_errror);
1371 return;
1374 /*child list OPTIONAL*/
1375 check = tvb_get_uint8(tvb, *offset);
1377 child_list = proto_tree_add_subtree(insert_tree, tvb, *offset, -1, ett_sml_child, &child, "Child List");
1378 if (check == OPTIONAL){
1379 proto_item_append_text(child, ": NOT SET");
1380 proto_item_set_len(child, 1);
1381 *offset+=1;
1383 else if ((check & 0x0F) != 0){
1384 if (check == 0x71){
1385 get_length(tvb, offset, data, length);
1386 proto_item_append_text(child, "with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1387 *offset+=1;
1389 tree_Entry_list = proto_tree_add_subtree(child_list, tvb, *offset, -1, ett_sml_tree_Entry, &tree_Entry, "tree_Entry");
1390 *offset+=1;
1392 increment_dissection_depth(pinfo);
1393 child_tree(tvb, pinfo,tree_Entry_list, offset, data, length);
1394 decrement_dissection_depth(pinfo);
1396 proto_item_set_end(tree_Entry, tvb, *offset);
1397 proto_item_set_end(child, tvb, *offset);
1399 else if ((check & 0xF0) == SHORT_LIST || (check & 0xF0) == LONG_LIST){
1400 get_length(tvb, offset, data, length);
1401 repeat = *length + *data;
1402 proto_item_append_text(child, "with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1403 if (repeat <= 0){
1404 expert_add_info_format(pinfo, child, &ei_sml_invalid_count, "invalid loop count");
1405 return;
1407 *offset+=*length;
1409 for(i =0 ; i < repeat; i++){
1410 tree_Entry_list = proto_tree_add_subtree(child_list, tvb, *offset, -1, ett_sml_tree_Entry, &tree_Entry, "tree_Entry");
1412 if (tvb_get_uint8(tvb, *offset) != 0x73){
1413 expert_add_info_format(pinfo, tree_Entry, &ei_sml_invalid_count, "invalid count of elements in tree_Entry");
1414 return;
1416 *offset+=1;
1418 increment_dissection_depth(pinfo);
1419 child_tree(tvb, pinfo, tree_Entry_list, offset, data, length);
1420 decrement_dissection_depth(pinfo);
1421 proto_item_set_end(tree_Entry, tvb, *offset);
1423 proto_item_set_end(child, tvb, *offset);
1426 else {
1427 expert_add_info_format(pinfo, child, &ei_sml_invalid_count, "invalid count of elements in child List");
1431 /*messagetypes*/
1432 static void decode_PublicOpenReq (tvbuff_t *tvb, proto_tree *messagebodytree_list, unsigned *offset){
1433 unsigned data = 0;
1434 unsigned length = 0;
1436 /*Codepage OPTIONAL*/
1437 field_codepage (tvb, messagebodytree_list, offset, &data, &length);
1439 /*clientID*/
1440 field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1442 /*reqFileId*/
1443 field_reqFileId (tvb, messagebodytree_list, offset, &data, &length);
1445 /*ServerID*/
1446 field_serverId(tvb,messagebodytree_list, offset, &data, &length);
1448 /*user*/
1449 field_username(tvb,messagebodytree_list, offset, &data, &length);
1451 /*password*/
1452 field_password(tvb,messagebodytree_list, offset, &data, &length);
1454 /*sml-Version OPTIONAL*/
1455 field_smlVersion(tvb,messagebodytree_list, offset, &data, &length);
1458 static void decode_PublicOpenRes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1459 proto_item *SML_time = NULL;
1461 //proto_tree *refTime_tree = NULL;
1462 proto_tree *SML_time_tree = NULL;
1464 unsigned data = 0;
1465 unsigned length = 0;
1467 /*Codepage OPTIONAL*/
1468 field_codepage (tvb, messagebodytree_list, offset, &data, &length);
1470 /*clientID OPTIONAL*/
1471 field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1473 /*reqFileId*/
1474 field_reqFileId (tvb, messagebodytree_list, offset, &data, &length);
1476 /*ServerID*/
1477 field_serverId(tvb,messagebodytree_list,offset, &data, &length);
1479 /*RefTime Optional*/
1480 get_length(tvb, offset, &data, &length);
1482 SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "refTime");
1483 if (data == 0){
1484 proto_item_append_text(SML_time, ": NOT SET");
1485 proto_item_set_len(SML_time, length + data);
1486 *offset+=1;
1488 else{
1489 /*SML TIME*/
1490 *offset+=1;
1491 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1492 proto_item_set_end(SML_time,tvb,*offset);
1494 /*sml-Version OPTIONAL*/
1495 field_smlVersion(tvb, messagebodytree_list, offset, &data, &length);
1498 static bool decode_GetProfile_List_Pack_Req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1499 proto_item *withRawdata = NULL;
1500 proto_item *SML_time = NULL;
1501 proto_item *treepath = NULL;
1502 proto_item *object_list = NULL;
1503 proto_item *dasDetails = NULL;
1505 proto_tree *withRawdata_tree = NULL;
1506 proto_tree *SML_time_tree = NULL;
1507 //proto_tree *beginTime_tree = NULL;
1508 proto_tree *treepath_list = NULL;
1509 proto_tree *object_list_list = NULL;
1510 //proto_tree *endTime_tree = NULL;
1511 proto_tree *dasDetails_list = NULL;
1513 unsigned i = 0;
1514 unsigned repeat = 0;
1515 unsigned check = 0;
1516 unsigned data = 0;
1517 unsigned length = 0;
1519 /*ServerID*/
1520 field_serverId(tvb,messagebodytree_list, offset, &data, &length);
1522 /*user*/
1523 field_username(tvb,messagebodytree_list, offset, &data, &length);
1525 /*password*/
1526 field_password(tvb,messagebodytree_list, offset, &data, &length);
1528 /*withRawdata OPTIONAL*/
1529 get_length(tvb, offset, &data, &length);
1530 withRawdata = proto_tree_add_uint_format (messagebodytree_list, hf_sml_withRawdata, tvb, *offset, data+length, data+length, "withRawdata %s", (data == 0)? ": NOT SET" : "");
1532 if (data > 0) {
1533 withRawdata_tree = proto_item_add_subtree (withRawdata, ett_sml_withRawdata);
1534 proto_tree_add_item (withRawdata_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
1535 *offset+=1;
1536 proto_tree_add_item (withRawdata_tree, hf_sml_withRawdata, tvb, *offset, 1, ENC_BIG_ENDIAN);
1537 *offset+=1;
1539 else
1540 *offset+=1;
1542 /*beginTime OPTIONAL*/
1543 get_length(tvb, offset, &data, &length);
1545 SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "beginTime");
1546 if (data == 0){
1547 proto_item_append_text(SML_time, ": NOT SET");
1548 proto_item_set_len(SML_time, length + data);
1549 *offset+=1;
1551 else {
1552 /*SML TIME*/
1553 *offset+=1;
1554 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1555 proto_item_set_end(SML_time,tvb,*offset);
1558 /*endTime OPTIONAL*/
1559 get_length(tvb, offset, &data, &length);
1561 SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "endTime");
1562 if (data == 0){
1563 proto_item_append_text(SML_time, ": NOT SET");
1564 proto_item_set_len(SML_time, length + data);
1565 *offset+=1;
1567 else {
1568 /*SML TIME*/
1569 *offset+=1;
1570 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1571 proto_item_set_end(SML_time,tvb,*offset);
1574 /*Treepath List*/
1575 get_length(tvb, offset, &data, &length);
1576 repeat = (data+length);
1577 treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
1578 "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1580 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1581 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in Treepath");
1582 return true;
1584 else if (repeat <= 0){
1585 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1586 return true;
1588 *offset+=length;
1590 for (i=0; i< repeat; i++) {
1591 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1593 proto_item_set_end(treepath, tvb, *offset);
1595 /*object_list*/
1596 object_list_list = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_object_list, &object_list, "object_List");
1597 if (tvb_get_uint8(tvb,*offset) == OPTIONAL){
1598 proto_item_append_text(object_list, ": NOT SET");
1599 proto_item_set_len(object_list, 1);
1600 *offset+=1;
1602 else{
1603 get_length(tvb, offset, &data, &length);
1604 repeat = (data+length);
1605 proto_item_append_text(object_list, " with %d %s", length+data, plurality(length+data, "element", "elements"));
1607 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1608 expert_add_info_format(pinfo, object_list, &ei_sml_invalid_count, "invalid count of elements in object_List");
1609 return true;
1611 else if (repeat <= 0){
1612 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1613 return true;
1616 *offset+=length;
1618 for (i=0; i< repeat; i++) {
1619 field_ObjReqEntry(tvb, object_list_list, offset, &data, &length);
1621 proto_item_set_end(object_list, tvb, *offset);
1624 /*dasDetails*/
1625 check = tvb_get_uint8(tvb,*offset);
1627 dasDetails_list = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_dasDetails, &dasDetails, "dasDetails");
1628 if (check == OPTIONAL){
1629 proto_item_append_text(dasDetails, ": NOT SET");
1630 proto_item_set_len(dasDetails, 1);
1631 *offset+=1;
1633 else if ((check & 0xF0) == LONG_LIST || (check & 0xF0) == SHORT_LIST){
1634 get_length(tvb, offset, &data, &length);
1635 proto_item_append_text(dasDetails, " with %d %s", length+data, plurality(length+data, "element", "elements"));
1636 *offset+=length;
1638 child_tree(tvb, pinfo, dasDetails_list, offset, &data, &length);
1639 proto_item_set_end(dasDetails, tvb, *offset);
1641 else {
1642 expert_add_info_format(pinfo, dasDetails, &ei_sml_invalid_count, "invalid count of elements in dasDetails");
1643 return true;
1645 return false;
1648 static bool decode_GetProfilePackRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1649 proto_item *SML_time = NULL;
1650 proto_item *treepath = NULL;
1651 proto_item *periodList = NULL;
1652 proto_item *period_List_Entry = NULL;
1653 proto_item *headerList = NULL;
1654 proto_item *header_List_Entry = NULL;
1655 proto_item *profileSignature = NULL;
1656 proto_item *valuelist = NULL;
1657 proto_item *value_List_Entry = NULL;
1659 proto_tree *SML_time_tree = NULL;
1660 proto_tree *treepath_list = NULL;
1661 proto_tree *periodList_list = NULL;
1662 proto_tree *period_List_Entry_list = NULL;
1663 proto_tree *headerList_subtree = NULL;
1664 proto_tree *header_List_Entry_list = NULL;
1665 proto_tree *profileSignature_tree = NULL;
1666 proto_tree *valuelist_list = NULL;
1667 proto_tree *value_List_Entry_list = NULL;
1669 unsigned i = 0;
1670 unsigned d = 0;
1671 unsigned repeat = 0;
1672 unsigned repeat2= 0;
1673 unsigned data = 0;
1674 unsigned length = 0;
1676 /*ServerID*/
1677 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
1679 /*actTime*/
1680 get_length(tvb, offset, &data, &length);
1681 SML_time_tree = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time,
1682 "actTime List with %d %s", length+data, plurality(length+data, "element", "elements"));
1683 *offset+=1;
1684 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1685 proto_item_set_end(SML_time,tvb,*offset);
1687 /*regPeriod*/
1688 field_regPeriod(tvb, messagebodytree_list, offset, &data, &length);
1690 /*Treepath List*/
1691 get_length(tvb, offset, &data, &length);
1692 repeat = (data+length);
1693 treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
1694 "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1696 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1697 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in Treepath");
1698 return true;
1700 else if (repeat <= 0){
1701 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1702 return true;
1705 *offset+=length;
1707 for (i=0; i< repeat; i++) {
1708 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1710 proto_item_set_end(treepath, tvb, *offset);
1712 /*headerList*/
1713 get_length(tvb, offset, &data, &length);
1714 repeat = (data+length);
1715 headerList_subtree = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_headerList, &headerList,
1716 "header_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1718 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1719 expert_add_info_format(pinfo, headerList, &ei_sml_invalid_count, "invalid count of elements in headerlist");
1720 return true;
1722 else if (repeat <= 0){
1723 expert_add_info_format(pinfo, headerList, &ei_sml_invalid_count, "invalid loop count");
1724 return true;
1727 *offset+=length;
1729 for (i=0; i< repeat; i++) {
1730 get_length(tvb, offset, &data, &length);
1731 header_List_Entry_list = proto_tree_add_subtree_format(headerList_subtree, tvb, *offset, -1, ett_sml_header_List_Entry, &header_List_Entry,
1732 "header_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1733 *offset+=1;
1735 /*objname*/
1736 field_objName(tvb, header_List_Entry_list, offset, &data, &length);
1738 /*unit*/
1739 field_unit(tvb, header_List_Entry_list, offset, &data, &length);
1741 /*scaler*/
1742 field_scaler(tvb, header_List_Entry_list, offset, &data, &length);
1744 proto_item_set_end(header_List_Entry, tvb, *offset);
1746 proto_item_set_end(headerList, tvb, *offset);
1748 /*period List*/
1749 get_length(tvb, offset, &data, &length);
1750 repeat = (data+length);
1751 periodList_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_periodList, &periodList,
1752 "period_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1754 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1755 expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid count of elements in periodList");
1756 return true;
1758 else if (repeat <= 0){
1759 expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid loop count");
1760 return true;
1763 *offset+=length;
1765 for (i=0; i< repeat; i++) {
1766 get_length(tvb, offset, &data, &length);
1767 period_List_Entry_list = proto_tree_add_subtree_format(periodList_list, tvb, *offset, -1, ett_sml_period_List_Entry, &period_List_Entry,
1768 "period_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1769 *offset+=1;
1771 /*valTime*/
1772 get_length(tvb, offset, &data, &length);
1773 SML_time_tree = proto_tree_add_subtree(period_List_Entry, tvb, *offset, -1, ett_sml_time, &SML_time, "valTime");
1774 *offset+=1;
1775 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1776 proto_item_set_end(SML_time,tvb, *offset);
1778 /*status*/
1779 field_status(tvb, period_List_Entry_list, offset, &data, &length);
1781 /*value List*/
1782 get_length(tvb, offset, &data, &length);
1783 repeat2 = data + length;
1784 valuelist_list = proto_tree_add_subtree_format(period_List_Entry_list, tvb, *offset, -1, ett_sml_valuelist, &valuelist,
1785 "period_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1787 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1788 expert_add_info_format(pinfo, valuelist, &ei_sml_invalid_count, "invalid count of elements in valueList");
1789 return true;
1791 else if (repeat2 <= 0){
1792 expert_add_info_format(pinfo, valuelist, &ei_sml_invalid_count, "invalid loop count");
1793 return true;
1796 *offset+=length;
1798 for (d=0; d< repeat2; d++) {
1799 get_length(tvb, offset, &data, &length);
1800 value_List_Entry_list = proto_tree_add_subtree_format(valuelist_list, tvb, *offset, -1, ett_sml_value_List_Entry, NULL,
1801 "value_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1802 *offset+=1;
1804 /*value*/
1805 sml_value(tvb, pinfo, value_List_Entry_list, offset, &data, &length);
1807 /*value Signature*/
1808 field_valueSignature(tvb, value_List_Entry_list, offset, &data, &length);
1810 proto_item_set_end(value_List_Entry, tvb, *offset);
1812 proto_item_set_end(valuelist, tvb, *offset);
1814 /*period Signature*/
1815 field_periodSignature(tvb, period_List_Entry_list, offset, &data, &length);
1817 proto_item_set_end(period_List_Entry, tvb, *offset);
1819 proto_item_set_end(periodList,tvb, *offset);
1821 /*rawdata*/
1822 field_rawdata(tvb, messagebodytree_list, offset, &data, &length);
1824 /*profile Signature*/
1825 get_length(tvb, offset, &data, &length);
1826 profileSignature = proto_tree_add_bytes_format (messagebodytree_list, hf_sml_profileSignature, tvb, *offset, length+data, NULL, "profileSignature %s", (data == 0)? ": NOT SET" : "");
1828 if (data > 0){
1829 profileSignature_tree = proto_item_add_subtree (profileSignature, ett_sml_profileSignature);
1830 proto_tree_add_uint (profileSignature_tree, hf_sml_length, tvb, *offset, length, data);
1831 *offset+=length;
1832 proto_tree_add_item (profileSignature_tree, hf_sml_profileSignature, tvb, *offset, data, ENC_NA);
1833 *offset+=data;
1835 else
1836 *offset+=1;
1838 return false;
1841 static bool decode_GetProfileListRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1842 proto_item *SML_time = NULL;
1843 proto_item *treepath = NULL;
1844 proto_item *periodList = NULL;
1845 proto_item *periodList_Entry = NULL;
1847 proto_tree *SML_time_tree = NULL;
1848 proto_tree *treepath_list = NULL;
1849 proto_tree *periodList_list = NULL;
1850 proto_tree *periodList_Entry_list = NULL;
1852 unsigned i = 0;
1853 unsigned repeat = 0;
1854 unsigned data = 0;
1855 unsigned length = 0;
1857 /*ServerID*/
1858 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
1860 /*actTime*/
1861 get_length(tvb, offset, &data, &length);
1862 SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "actTime");
1863 *offset+=1;
1864 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1865 proto_item_set_end(SML_time,tvb, *offset);
1867 /*regPeriod*/
1868 field_regPeriod(tvb, messagebodytree_list, offset, &data, &length);
1870 /*Treepath List*/
1871 get_length(tvb, offset, &data, &length);
1872 repeat = (data+length);
1873 treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
1874 "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1876 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1877 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in parameterTreePath");
1878 return true;
1880 else if (repeat <= 0){
1881 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1882 return true;
1885 *offset+=length;
1887 for (i=0; i< repeat; i++) {
1888 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1890 proto_item_set_end(treepath, tvb,*offset);
1892 /*valTime Optional*/
1893 get_length(tvb, offset, &data, &length);
1895 SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "valTime");
1896 if (data == 0){
1897 proto_item_append_text(SML_time, ": NOT SET");
1898 proto_item_set_len(SML_time, length + data);
1899 *offset+=1;
1901 else {
1902 /*SML TIME*/
1903 *offset+=1;
1904 sml_time_type(tvb, pinfo, SML_time_tree, offset);
1905 proto_item_set_end(SML_time,tvb,*offset);
1908 /*Status*/
1909 field_status(tvb, messagebodytree_list, offset, &data, &length);
1911 /*period-List*/
1912 get_length(tvb, offset, &data, &length);
1913 repeat = (data+length);
1914 periodList_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_periodList, &periodList,
1915 "period-List with %d %s", length+data, plurality(length+data, "element", "elements"));
1917 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1918 expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid count of elements in periodList");
1919 return true;
1921 else if (repeat <= 0){
1922 expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid loop count");
1923 return true;
1926 *offset+=length;
1928 for (i=0; i< repeat; i++) {
1929 get_length(tvb, offset, &data, &length);
1930 periodList_Entry_list = proto_tree_add_subtree(periodList_list, tvb, *offset, -1, ett_sml_period_List_Entry, &periodList_Entry, "PeriodEntry");
1931 *offset+=1;
1933 /*ObjName*/
1934 field_objName(tvb, periodList_Entry_list, offset, &data, &length);
1936 /*Unit*/
1937 field_unit(tvb, periodList_Entry_list, offset, &data, &length);
1939 /*scaler*/
1940 field_scaler(tvb, periodList_Entry_list, offset, &data, &length);
1942 /*value*/
1943 sml_value(tvb, pinfo, periodList_Entry_list, offset, &data, &length);
1945 /*value*/
1946 field_valueSignature(tvb, periodList_Entry_list, offset, &data, &length);
1948 proto_item_set_end(periodList_Entry, tvb, *offset);
1950 proto_item_set_end(periodList, tvb, *offset);
1952 /*rawdata*/
1953 field_rawdata(tvb, messagebodytree_list, offset, &data, &length);
1955 /*period Signature*/
1956 field_periodSignature(tvb, messagebodytree_list, offset, &data, &length);
1958 return false;
1961 static void decode_GetListReq (tvbuff_t *tvb, proto_tree *messagebodytree_list, unsigned *offset){
1962 unsigned data = 0;
1963 unsigned length = 0;
1965 /*clientID*/
1966 field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1968 /*ServerID*/
1969 field_serverId(tvb,messagebodytree_list,offset, &data, &length);
1971 /*user*/
1972 field_username(tvb,messagebodytree_list,offset, &data, &length);
1974 /*password*/
1975 field_password(tvb,messagebodytree_list,offset, &data, &length);
1977 /*listName*/
1978 field_listName(tvb,messagebodytree_list,offset, &data, &length);
1981 static bool decode_GetListRes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
1982 proto_item *valList = NULL;
1983 proto_item *listSignature = NULL;
1984 proto_item *valtree = NULL;
1985 proto_item *SML_time;
1987 //proto_tree *actSensorTime_tree = NULL;
1988 proto_tree *valList_list = NULL;
1989 proto_tree *listSignature_tree = NULL;
1990 proto_tree *valtree_list = NULL;
1991 //proto_tree *actGatewayTime_tree = NULL;
1992 proto_tree *SML_time_tree = NULL;
1994 unsigned repeat = 0;
1995 unsigned i = 0;
1996 unsigned data = 0;
1997 unsigned length = 0;
1999 /*clientID OPTIONAL*/
2000 field_clientId (tvb, messagebodytree_list, offset, &data, &length);
2002 /*ServerID*/
2003 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2005 /*listName*/
2006 field_listName(tvb, messagebodytree_list, offset, &data, &length);
2008 /*actSensorTime OPTIONAL*/
2009 get_length(tvb, offset, &data, &length);
2011 SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "actSensorTime");
2012 if (data == 0){
2013 proto_item_append_text(SML_time, ": NOT SET");
2014 proto_item_set_len(SML_time, length + data);
2015 *offset+=1;
2017 else {
2018 /*SML TIME*/
2019 *offset+=1;
2020 sml_time_type(tvb, pinfo, SML_time_tree, offset);
2021 proto_item_set_end(SML_time,tvb,*offset);
2024 /*valList*/
2025 get_length(tvb, offset, &data, &length);
2026 repeat = (length + data);
2027 valtree_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_valtree, &valtree,
2028 "valList with %d %s", length+data, plurality(length+data, "element", "elements"));
2030 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2031 expert_add_info_format(pinfo, valtree, &ei_sml_invalid_count, "invalid count of elements in valList");
2032 return true;
2034 else if (repeat <= 0){
2035 expert_add_info_format(pinfo, valtree, &ei_sml_invalid_count, "invalid loop count");
2036 return true;
2039 *offset+=length;
2041 for (i=0; i < repeat; i++){
2042 get_length(tvb, offset, &data, &length);
2043 valList_list = proto_tree_add_subtree(valtree_list, tvb, *offset, -1, ett_sml_valList, &valList, "valListEntry");
2044 *offset+=length;
2046 /*objName*/
2047 field_objName(tvb, valList_list, offset, &data, &length);
2049 /*Sml Status OPTIONAL*/
2050 field_status(tvb, valList_list, offset, &data, &length);
2052 /*valTime OPTIONAL*/
2053 get_length(tvb, offset, &data, &length);
2055 SML_time_tree = proto_tree_add_subtree(valList_list, tvb, *offset, -1, ett_sml_time, &SML_time, "valTime");
2056 if (data == 0){
2057 proto_item_append_text(SML_time, ": NOT SET");
2058 proto_item_set_len(SML_time, length + data);
2059 *offset+=1;
2061 else {
2062 /*SML TIME*/
2063 *offset+=1;
2064 sml_time_type(tvb, pinfo, SML_time_tree, offset);
2065 proto_item_set_end(SML_time, tvb, *offset);
2068 /*unit OPTIONAL*/
2069 field_unit(tvb, valList_list, offset, &data, &length);
2071 /*Scaler OPTIONAL*/
2072 field_scaler(tvb, valList_list, offset, &data, &length);
2074 /*value*/
2075 sml_value(tvb, pinfo, valList_list, offset, &data, &length);
2077 /*value Signature*/
2078 field_valueSignature(tvb, valList_list, offset, &data, &length);
2080 proto_item_set_end(valList, tvb, *offset);
2082 proto_item_set_end(valtree, tvb, *offset);
2084 /*List Signature OPTIONAL*/
2085 get_length(tvb, offset, &data, &length);
2086 listSignature = proto_tree_add_bytes_format (messagebodytree_list, hf_sml_listSignature, tvb, *offset, length+data, NULL, "ListSignature %s", (data == 0)? ": NOT SET" : "");
2088 if (data > 0){
2089 listSignature_tree = proto_item_add_subtree (listSignature, ett_sml_listSignature);
2090 proto_tree_add_uint (listSignature_tree, hf_sml_length, tvb, *offset, length, data);
2091 *offset+=length;
2092 proto_tree_add_item (listSignature_tree, hf_sml_listSignature, tvb, *offset, data, ENC_NA);
2093 *offset+=data;
2095 else
2096 *offset+=1;
2098 /*actGatewayTime OPTIONAL*/
2099 get_length(tvb, offset, &data, &length);
2101 SML_time_tree = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_time, &SML_time, "actGatewayTime");
2102 if (data == 0){
2103 proto_item_append_text(SML_time, ": NOT SET");
2104 proto_item_set_len(SML_time, length + data);
2105 *offset+=1;
2107 else{
2108 /*SML TIME*/
2109 *offset+=1;
2110 sml_time_type(tvb, pinfo, SML_time_tree, offset);
2111 proto_item_set_end(SML_time,tvb,*offset);
2113 return false;
2116 static bool decode_GetProcParameterReq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
2117 proto_item *treepath = NULL;
2118 proto_item *attribute = NULL;
2120 proto_tree *treepath_list = NULL;
2121 proto_tree *attribute_tree = NULL;
2123 unsigned i = 0;
2124 unsigned repeat = 0;
2125 unsigned data = 0;
2126 unsigned length = 0;
2128 /*ServerID*/
2129 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2131 /*user*/
2132 field_username(tvb, messagebodytree_list, offset, &data, &length);
2134 /*password*/
2135 field_password(tvb, messagebodytree_list, offset, &data, &length);
2137 /*Treepath List*/
2138 get_length(tvb, offset, &data, &length);
2139 repeat = data+length;
2140 treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
2141 "ParameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2143 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2144 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2145 return true;
2147 else if (repeat <= 0){
2148 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2149 return true;
2152 *offset+=length;
2154 for (i=0; i< repeat; i++) {
2155 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2157 proto_item_set_end(treepath, tvb, *offset);
2159 /*attribute*/
2160 get_length(tvb, offset, &data, &length);
2161 attribute = proto_tree_add_bytes_format (messagebodytree_list,hf_sml_attribute, tvb, *offset, length+data, NULL, "attribute %s", (data == 0)? ": NOT SET" : "");
2163 if (data > 0) {
2164 attribute_tree = proto_item_add_subtree (attribute, ett_sml_attribute);
2165 proto_tree_add_uint (attribute_tree, hf_sml_length, tvb, *offset, length, data);
2166 *offset+=length;
2167 proto_tree_add_item (attribute_tree, hf_sml_attribute, tvb, *offset, data, ENC_NA);
2168 *offset+=data;
2170 else
2171 *offset+=1;
2173 return false;
2176 static bool decode_GetProcParameterRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
2177 proto_item *treepath = NULL;
2178 proto_item *parameterTree =NULL;
2180 proto_tree *treepath_list = NULL;
2181 proto_tree *parameterTree_list = NULL;
2183 unsigned i = 0;
2184 unsigned repeat = 0;
2185 unsigned data = 0;
2186 unsigned length = 0;
2188 /*ServerID*/
2189 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2191 /*Treepath List*/
2192 get_length(tvb, offset, &data, &length);
2193 repeat = (data+length);
2194 treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
2195 "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2197 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2198 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2199 return true;
2201 else if (repeat <= 0){
2202 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2203 return true;
2206 *offset+=length;
2208 for (i=0; i< repeat; i++) {
2209 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2211 proto_item_set_end(treepath, tvb, *offset);
2213 /*parameterTree*/
2214 get_length(tvb, offset, &data, &length);
2215 parameterTree_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_parameterTree, &parameterTree,
2216 "parameterTree with %d %s", length+data, plurality(length+data, "element", "elements"));
2218 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2219 expert_add_info_format(pinfo, parameterTree, &ei_sml_invalid_count, "invalid count of elements in parameterTree");
2220 return true;
2223 *offset+=length;
2225 child_tree(tvb, pinfo,parameterTree_list, offset, &data, &length);
2226 proto_item_set_end(parameterTree, tvb, *offset);
2228 return false;
2231 static bool decode_SetProcParameterReq(tvbuff_t *tvb, packet_info *pinfo,proto_tree *messagebodytree_list, unsigned *offset){
2232 proto_item *treepath = NULL;
2233 proto_item *parameterTree = NULL;
2235 proto_tree *treepath_list = NULL;
2236 proto_tree *parameterTree_list = NULL;
2238 unsigned i = 0;
2239 unsigned repeat = 0;
2240 unsigned data = 0;
2241 unsigned length = 0;
2243 /*ServerID*/
2244 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2246 /*user*/
2247 field_username(tvb, messagebodytree_list, offset, &data, &length);
2249 /*password*/
2250 field_password(tvb, messagebodytree_list, offset, &data, &length);
2252 /*Treepath List*/
2253 get_length(tvb, offset, &data, &length);
2254 repeat = (data+length);
2255 treepath_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_treepath, &treepath,
2256 "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2258 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2259 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2260 return true;
2262 else if (repeat <= 0){
2263 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2264 return true;
2267 *offset+=length;
2269 for (i=0; i< repeat; i++) {
2270 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2272 proto_item_set_end(treepath, tvb, *offset);
2274 /*parameterTree*/
2275 get_length(tvb, offset, &data, &length);
2276 parameterTree_list = proto_tree_add_subtree_format(messagebodytree_list, tvb, *offset, -1, ett_sml_parameterTree, &parameterTree,
2277 "parameterTree with %d %s", length+data, plurality(length+data, "element", "elements"));
2279 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2280 expert_add_info_format(pinfo, parameterTree, &ei_sml_invalid_count, "invalid count of elements in parameterTree");
2281 return true;
2284 *offset+=length;
2286 child_tree(tvb, pinfo,parameterTree_list, offset, &data, &length);
2287 proto_item_set_end(parameterTree, tvb, *offset);
2289 return false;
2292 static bool decode_AttentionRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, unsigned *offset){
2293 proto_item *attentionMsg = NULL;
2294 proto_item *attentionDetails = NULL;
2296 proto_tree *attentionNo_tree = NULL;
2297 proto_tree *attentionMsg_tree = NULL;
2298 proto_tree *attentionDetails_list = NULL;
2299 proto_item *attentionNo_item;
2301 unsigned data = 0;
2302 unsigned length = 0;
2304 /*ServerID*/
2305 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2307 /*attention NO*/
2308 get_length(tvb, offset, &data, &length);
2309 attentionNo_tree = proto_tree_add_subtree(messagebodytree_list, tvb ,*offset, length+data, ett_sml_attentionNo, &attentionNo_item, "attentionNo");
2310 proto_tree_add_uint (attentionNo_tree, hf_sml_length, tvb, *offset, length, data);
2311 *offset+=length;
2313 if (data == 6){
2314 *offset+=4;
2315 proto_tree_add_item (attentionNo_tree, hf_sml_attentionNo, tvb, *offset, 2, ENC_BIG_ENDIAN);
2316 *offset+=2;
2318 else {
2319 expert_add_info(pinfo, attentionNo_item, &ei_sml_attentionNo);
2320 *offset+=data;
2323 /*attention Msg*/
2324 get_length(tvb, offset, &data, &length);
2325 attentionMsg = proto_tree_add_string_format (messagebodytree_list, hf_sml_attentionMsg, tvb, *offset, length+data, NULL, "attentionMsg %s", (data == 0)? ": NOT SET" : "");
2327 if (data > 0){
2328 attentionMsg_tree = proto_item_add_subtree (attentionMsg, ett_sml_attentionMsg);
2329 proto_tree_add_uint (attentionMsg_tree, hf_sml_length, tvb, *offset, length, data);
2330 *offset+=length;
2331 proto_tree_add_item (attentionMsg_tree, hf_sml_attentionMsg, tvb, *offset, data, ENC_ASCII | ENC_BIG_ENDIAN);
2332 *offset+=data;
2334 else
2335 *offset+=1;
2337 /*attentiondetails*/
2338 attentionDetails_list = proto_tree_add_subtree(messagebodytree_list, tvb, *offset, -1, ett_sml_attentionDetails, &attentionDetails, "attentionDetails");
2339 if (tvb_get_uint8(tvb,*offset) == OPTIONAL){
2340 proto_item_append_text(attentionDetails, ": NOT SET");
2341 proto_item_set_len(attentionDetails, 1);
2342 *offset+=1;
2344 else{
2345 get_length(tvb, offset, &data, &length);
2346 proto_item_append_text(attentionDetails, " with %d %s", length+data, plurality(length+data, "element", "elements"));
2348 if ((tvb_get_uint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_uint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2349 expert_add_info_format(pinfo, attentionDetails, &ei_sml_invalid_count, "invalid count of elements in attentionDetails");
2350 return true;
2353 *offset+=length;
2355 child_tree(tvb, pinfo,attentionDetails_list, offset, &data, &length);
2356 proto_item_set_end(attentionDetails, tvb, *offset);
2359 return false;
2362 /*dissect SML-File*/
2363 static void dissect_sml_file(tvbuff_t *tvb, packet_info *pinfo, int *offset, proto_tree *sml_tree){
2364 proto_item *file = NULL;
2365 proto_item *mainlist;
2366 proto_item *sublist;
2367 proto_item *messagebody;
2368 proto_item *crc16;
2369 proto_item *messagebodytree;
2370 proto_item *msgend;
2372 proto_tree *mainlist_list = NULL;
2373 proto_tree *trans_tree = NULL;
2374 proto_tree *groupNo_tree = NULL;
2375 proto_tree *abortOnError_tree = NULL;
2376 proto_tree *sublist_list = NULL;
2377 proto_tree *messagebody_tree = NULL;
2378 proto_tree *crc16_tree = NULL;
2379 proto_tree *messagebodytree_list = NULL;
2380 proto_tree *msgend_tree = NULL;
2382 uint16_t messagebody_switch = 0;
2383 uint16_t crc_check = 0;
2384 uint16_t crc_ref = 0;
2385 unsigned check = 0;
2387 unsigned available = 0;
2388 unsigned crc_msg_len = 0;
2389 unsigned crc_file_len = 0;
2390 unsigned data = 0;
2391 unsigned length = 0;
2393 bool msg_error = false;
2394 bool close1 = false;
2395 bool close2 = false;
2396 int end_offset = 0;
2398 unsigned start_offset;
2399 start_offset = *offset;
2401 end_offset = tvb_reported_length_remaining(tvb, *offset);
2402 if (end_offset <= 0){
2403 return;
2406 if (tvb_get_ntoh40(tvb, end_offset-8) != ESC_SEQ_END && pinfo->can_desegment){
2407 if (tvb_get_uint8(tvb, end_offset-1) != 0){
2408 pinfo->desegment_offset = start_offset;
2409 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2410 return;
2412 else if (tvb_get_uint8(tvb, end_offset-4) != UNSIGNED16 && tvb_get_uint8(tvb, end_offset-3) != UNSIGNED8){
2413 pinfo->desegment_offset = start_offset;
2414 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2415 return;
2418 else if (!pinfo->can_desegment){
2419 expert_add_info(pinfo, NULL, &ei_sml_segment_needed);
2422 while(!close1 && !close2){
2423 if (sml_reassemble){
2424 file = proto_tree_add_item(sml_tree, hf_sml_file_marker, tvb, *offset, -1, ENC_NA);
2427 /*check if escape*/
2428 if (tvb_get_ntohl(tvb, *offset) == ESC_SEQ){
2429 crc_file_len = *offset;
2430 /*Escape Start*/
2431 proto_tree_add_item (sml_tree, hf_sml_esc, tvb, *offset, 4, ENC_BIG_ENDIAN);
2432 *offset+=4;
2434 /*Version*/
2435 if (tvb_get_uint8(tvb, *offset) == 0x01){
2436 proto_tree_add_item (sml_tree, hf_sml_version_1, tvb, *offset, 4, ENC_BIG_ENDIAN);
2437 *offset+=4;
2439 else{
2440 proto_tree_add_expert(sml_tree, pinfo, &ei_sml_version2_not_supported, tvb, *offset, -1);
2441 return;
2445 while (!close1){
2446 crc_msg_len = *offset;
2448 /*List*/
2449 get_length(tvb, offset, &data, &length);
2450 mainlist_list = proto_tree_add_subtree_format(sml_tree, tvb, *offset, -1, ett_sml_mainlist, &mainlist, "List with %d %s",
2451 length+data, plurality(length+data, "element", "elements"));
2453 if (tvb_get_uint8(tvb, *offset) != LIST_6_ELEMENTS) {
2454 expert_add_info_format(pinfo, mainlist, &ei_sml_invalid_count, "invalid count of elements");
2455 return;
2457 *offset+=1;
2459 /*Transaction ID*/
2460 get_length(tvb, offset, &data, &length);
2461 trans_tree = proto_tree_add_subtree_format(mainlist_list, tvb, *offset, length + data, ett_sml_trans, NULL, "Transaction ID");
2462 proto_tree_add_uint (trans_tree, hf_sml_length, tvb, *offset, length, data);
2463 *offset+=length;
2464 proto_tree_add_item (trans_tree, hf_sml_transactionId, tvb, *offset, data, ENC_NA);
2465 *offset+=data;
2467 /*Group No*/
2468 groupNo_tree = proto_tree_add_subtree(mainlist_list, tvb, *offset, 2, ett_sml_group, NULL, "Group No");
2469 proto_tree_add_item (groupNo_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
2470 *offset+=1;
2471 proto_tree_add_item (groupNo_tree, hf_sml_groupNo, tvb, *offset, 1, ENC_BIG_ENDIAN);
2472 *offset+=1;
2474 /*abort on Error*/
2475 abortOnError_tree = proto_tree_add_subtree(mainlist_list, tvb, *offset, 2, ett_sml_abort, NULL, "Abort on Error");
2476 proto_tree_add_item(abortOnError_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
2477 *offset+=1;
2478 proto_tree_add_item(abortOnError_tree, hf_sml_abortOnError, tvb, *offset, 1, ENC_BIG_ENDIAN);
2479 *offset+=1;
2481 /*Sub List*/
2482 sublist_list = proto_tree_add_subtree(mainlist_list, tvb, *offset, -1, ett_sml_sublist, &sublist, "MessageBody");
2483 *offset+=1;
2485 /*Zero Cutting Check*/
2486 get_length(tvb, offset, &data, &length);
2487 messagebody_tree = proto_tree_add_subtree(sublist_list, tvb, *offset, length + data, ett_sml_mttree, &messagebody, "Messagetype");
2488 proto_tree_add_item (messagebody_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
2489 *offset+=1;
2491 if (data == 4){
2492 *offset+=2;
2494 else if (data !=2){
2495 expert_add_info(pinfo, messagebody, &ei_sml_messagetype_unknown);
2496 return;
2499 messagebody_switch = tvb_get_ntohs(tvb, *offset);
2500 proto_tree_add_item (messagebody_tree, hf_sml_MessageBody, tvb, *offset, 2, ENC_BIG_ENDIAN);
2501 *offset+=2;
2503 /*MessageBody List*/
2504 get_length(tvb, offset, &data, &length);
2505 messagebodytree_list = proto_tree_add_subtree_format(sublist_list, tvb, *offset, -1, ett_sml_mblist, &messagebodytree,
2506 "List with %d %s", length+data, plurality(length+data, "element", "elements"));
2507 *offset+=length;
2509 switch (messagebody_switch){
2510 case OPEN_REQ:
2511 col_append_str (pinfo->cinfo, COL_INFO, "OpenReq; ");
2512 proto_item_append_text(mainlist, " [Open Request]");
2513 decode_PublicOpenReq(tvb, messagebodytree_list, offset);
2514 break;
2515 case OPEN_RES:
2516 col_append_str (pinfo->cinfo, COL_INFO, "OpenRes; ");
2517 proto_item_append_text(mainlist, " [Open Response]");
2518 decode_PublicOpenRes(tvb, pinfo, messagebodytree_list, offset);
2519 break;
2520 case CLOSE_REQ:
2521 col_append_str (pinfo->cinfo, COL_INFO, "CloseReq; ");
2522 proto_item_append_text(mainlist, " [Close Request]");
2523 field_globalSignature(tvb, messagebodytree_list, offset, &data, &length);
2524 break;
2525 case CLOSE_RES:
2526 col_append_str (pinfo->cinfo, COL_INFO, "CloseRes; ");
2527 proto_item_append_text(mainlist, " [Close Response]");
2528 field_globalSignature(tvb, messagebodytree_list, offset, &data, &length);
2529 break;
2530 case PROFILEPACK_REQ:
2531 col_append_str (pinfo->cinfo, COL_INFO, "GetProfilePackReq; ");
2532 proto_item_append_text(mainlist, " [GetProfilePack Request]");
2533 msg_error = decode_GetProfile_List_Pack_Req(tvb, pinfo,messagebodytree_list, offset);
2534 break;
2535 case PROFILEPACK_RES:
2536 col_append_str (pinfo->cinfo, COL_INFO, "GetProfilePackRes; ");
2537 proto_item_append_text(mainlist, " [GetProfilePack Response]");
2538 msg_error = decode_GetProfilePackRes(tvb, pinfo,messagebodytree_list, offset);
2539 break;
2540 case PROFILELIST_REQ:
2541 col_append_str (pinfo->cinfo, COL_INFO, "GetProfileListReq; ");
2542 proto_item_append_text(mainlist, " [GetProfileList Request]");
2543 msg_error = decode_GetProfile_List_Pack_Req(tvb, pinfo,messagebodytree_list, offset);
2544 break;
2545 case PROFILELIST_RES:
2546 col_append_str (pinfo->cinfo, COL_INFO, "GetProfileListRes; ");
2547 proto_item_append_text(mainlist, " [GetProfileList Response]");
2548 msg_error = decode_GetProfileListRes(tvb, pinfo,messagebodytree_list, offset);
2549 break;
2550 case GETPROCPARAMETER_REQ:
2551 col_append_str (pinfo->cinfo, COL_INFO, "GetProcParameterReq; ");
2552 proto_item_append_text(mainlist, " [GetProcParameter Request]");
2553 msg_error = decode_GetProcParameterReq(tvb, pinfo,messagebodytree_list, offset);
2554 break;
2555 case GETPROCPARAMETER_RES:
2556 col_append_str (pinfo->cinfo, COL_INFO, "GetProcParameterRes; ");
2557 proto_item_append_text(mainlist, " [GetProcParameter Response]");
2558 msg_error = decode_GetProcParameterRes(tvb, pinfo,messagebodytree_list, offset);
2559 break;
2560 case SETPROCPARAMETER_REQ:
2561 col_append_str (pinfo->cinfo, COL_INFO, "SetProcParameterReq; ");
2562 proto_item_append_text(mainlist, " [SetProcParameter Request]");
2563 msg_error = decode_SetProcParameterReq(tvb, pinfo,messagebodytree_list, offset);
2564 break;
2565 case GETLIST_REQ:
2566 col_append_str (pinfo->cinfo, COL_INFO, "GetListReq; ");
2567 proto_item_append_text(mainlist, " [GetList Request]");
2568 decode_GetListReq(tvb, messagebodytree_list, offset);
2569 break;
2570 case GETLIST_RES:
2571 col_append_str (pinfo->cinfo, COL_INFO, "GetListRes; ");
2572 proto_item_append_text(mainlist, " [GetList Response]");
2573 msg_error = decode_GetListRes(tvb, pinfo,messagebodytree_list, offset);
2574 break;
2575 case ATTENTION:
2576 col_append_str (pinfo->cinfo, COL_INFO, "AttentionRes; ");
2577 proto_item_append_text(mainlist, " [Attention Response]");
2578 msg_error = decode_AttentionRes(tvb, pinfo,messagebodytree_list, offset);
2579 break;
2580 default :
2581 expert_add_info(pinfo, messagebodytree, &ei_sml_messagetype_unknown);
2582 return;
2585 if (msg_error){
2586 expert_add_info(pinfo, messagebodytree, &ei_sml_MessageBody);
2587 return;
2590 proto_item_set_end(messagebodytree, tvb, *offset);
2591 proto_item_set_end(sublist, tvb, *offset);
2593 /* CRC 16*/
2594 get_length(tvb, offset, &data, &length);
2595 crc16_tree = proto_tree_add_subtree(mainlist_list, tvb, *offset, data + length, ett_sml_crc16, &crc16, "CRC");
2597 if(tvb_get_uint8(tvb, *offset) != UNSIGNED8 && tvb_get_uint8(tvb, *offset) != UNSIGNED16){
2598 expert_add_info(pinfo, crc16, &ei_sml_crc_error_length);
2599 return;
2602 proto_tree_add_item (crc16_tree, hf_sml_datatype, tvb, *offset, 1, ENC_BIG_ENDIAN);
2603 *offset+=1;
2605 if (sml_crc_enabled) {
2606 crc_msg_len = (*offset - crc_msg_len - 1);
2607 crc_check = crc16_ccitt_tvb_offset(tvb, (*offset - crc_msg_len - 1), crc_msg_len);
2609 if (data == 1){
2610 crc_ref = crc_ref & 0xFF00;
2613 proto_tree_add_checksum(crc16_tree, tvb, *offset, hf_sml_crc16, hf_sml_crc16_status, &ei_sml_crc_error, pinfo, crc_check,
2614 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
2616 else {
2617 proto_tree_add_checksum(crc16_tree, tvb, *offset, hf_sml_crc16, hf_sml_crc16_status, &ei_sml_crc_error, pinfo, 0,
2618 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
2620 *offset+=data;
2622 /*Message END*/
2623 if (tvb_get_uint8 (tvb, *offset) == 0){
2624 proto_tree_add_item (mainlist_list, hf_sml_endOfSmlMsg, tvb, *offset, 1, ENC_BIG_ENDIAN);
2625 *offset+=1;
2627 else {
2628 expert_add_info(pinfo, NULL, &ei_sml_endOfSmlMsg);
2629 return;
2632 proto_item_set_end(mainlist, tvb, *offset);
2634 if (tvb_reported_length_remaining(tvb, *offset) > 0){
2635 check = tvb_get_uint8(tvb, *offset);
2637 if (check == LIST_6_ELEMENTS){
2638 close1 = false;
2640 else if (check == 0x1b || check == 0){
2641 close1 = true;
2644 else if (sml_reassemble && pinfo->can_desegment){
2645 pinfo->desegment_offset = start_offset;
2646 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2647 return;
2649 else
2650 return;
2653 /*Padding*/
2654 if (check == 0){
2655 length = 1;
2656 *offset+=1;
2658 while (tvb_get_uint8(tvb, *offset) == 0){
2659 length++;
2660 *offset+=1;
2662 *offset-=length;
2664 proto_tree_add_item (sml_tree, hf_sml_padding, tvb, *offset, length, ENC_NA);
2665 *offset+=length;
2668 /*Escape End*/
2669 if(tvb_get_ntoh40(tvb, *offset) != ESC_SEQ_END){
2670 expert_add_info(pinfo, NULL, &ei_sml_esc_error);
2671 return;
2673 proto_tree_add_item (sml_tree, hf_sml_esc, tvb, *offset, 4, ENC_BIG_ENDIAN);
2674 *offset+=4;
2676 /*MSG END*/
2677 msgend = proto_tree_add_item (sml_tree, hf_sml_end, tvb, *offset, 4, ENC_BIG_ENDIAN);
2678 msgend_tree = proto_item_add_subtree (msgend, ett_sml_msgend);
2679 *offset+=1;
2680 proto_tree_add_item (msgend_tree, hf_sml_padding, tvb, *offset, 1, ENC_NA);
2681 *offset+=1;
2683 if (sml_crc_enabled && sml_reassemble){
2684 crc_file_len = *offset - crc_file_len;
2685 crc_check = crc16_ccitt_tvb_offset(tvb,*offset-crc_file_len, crc_file_len);
2687 proto_tree_add_checksum(msgend_tree, tvb, *offset, hf_sml_crc16, hf_sml_crc16_status, &ei_sml_crc_error, pinfo, crc_check,
2688 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
2690 else {
2691 proto_tree_add_checksum(msgend_tree, tvb, *offset, hf_sml_crc16, hf_sml_crc16_status, &ei_sml_crc_error, pinfo, crc_check,
2692 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
2694 *offset+=2;
2696 available = tvb_reported_length_remaining(tvb, *offset);
2697 if (available <= 0){
2698 close2 = true;
2700 else {
2701 if (sml_reassemble){
2702 proto_item_set_end(file, tvb, *offset);
2704 else {
2705 proto_tree_add_item(sml_tree, hf_sml_new_file_marker, tvb, *offset, 0, ENC_NA);
2707 close1 = false;
2712 /* main */
2713 static int dissect_sml (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
2714 proto_item *sml_item;
2715 proto_tree *sml_tree;
2717 unsigned offset = 0;
2719 /*Check if not SML*/
2720 if (tvb_get_ntohl(tvb, offset) != ESC_SEQ && tvb_get_uint8(tvb, offset) != LIST_6_ELEMENTS){
2721 return 0;
2724 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SML");
2725 col_clear(pinfo->cinfo,COL_INFO);
2727 /* create display subtree for the protocol */
2728 sml_item = proto_tree_add_item(tree, proto_sml, tvb, 0, -1, ENC_NA);
2729 sml_tree = proto_item_add_subtree(sml_item, ett_sml);
2730 dissect_sml_file(tvb, pinfo, &offset, sml_tree);
2731 return tvb_captured_length(tvb);
2734 static void
2735 sml_fmt_length( char *result, uint32_t length )
2737 snprintf( result, ITEM_LABEL_LENGTH, "%d %s", length, plurality(length, "octet", "octets"));
2740 void proto_register_sml (void) {
2741 module_t *sml_module;
2742 expert_module_t* expert_sml;
2744 static hf_register_info hf[] = {
2745 { &hf_sml_esc,
2746 { "Escape", "sml.esc", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2747 { &hf_sml_version_1,
2748 { "Version 1", "sml.version_1", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2749 { &hf_sml_smlVersion,
2750 { "SML Version", "sml.version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2751 { &hf_sml_crc16,
2752 { "CRC16", "sml.crc", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2753 { &hf_sml_crc16_status,
2754 { "CRC16 Status", "sml.crc.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0, NULL, HFILL }},
2755 { &hf_sml_endOfSmlMsg,
2756 { "End of SML Msg", "sml.end", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2757 { &hf_sml_transactionId,
2758 { "Transaction ID", "sml.transactionid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2759 { &hf_sml_length,
2760 { "Length", "sml.length", FT_UINT32, BASE_CUSTOM, CF_FUNC(sml_fmt_length), 0x0, NULL, HFILL }},
2761 { &hf_sml_groupNo,
2762 { "GroupNo", "sml.groupno", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2763 { &hf_sml_datatype,
2764 { "Datatype", "sml.datatype", FT_UINT8, BASE_HEX, VALS (datatype), 0x0, NULL, HFILL }},
2765 { &hf_sml_abortOnError,
2766 { "Abort On Error", "sml.abort", FT_UINT8, BASE_HEX, VALS (sml_abort), 0x0, NULL, HFILL }},
2767 { &hf_sml_MessageBody,
2768 { "Messagebody", "sml.messagebody", FT_UINT16, BASE_HEX, VALS (sml_body), 0x0, NULL, HFILL }},
2769 { &hf_sml_end,
2770 { "End of Msg", "sml.end", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2771 { &hf_sml_codepage,
2772 { "Codepage", "sml.codepage", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2773 { &hf_sml_clientId,
2774 { "Client ID", "sml.clientid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2775 { &hf_sml_reqFileId,
2776 { "reqFile ID", "sml.reqfileid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2777 { &hf_sml_serverId,
2778 { "server ID", "sml.serverid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2779 { &hf_sml_username,
2780 { "Username", "sml.username", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2781 { &hf_sml_password,
2782 { "Password", "sml.password", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2783 { &hf_sml_listName,
2784 { "List Name", "sml.listname", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2785 { &hf_sml_globalSignature,
2786 { "Global Signature", "sml.globalsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2787 { &hf_sml_timetype,
2788 { "Time type", "sml.timetype", FT_UINT8, BASE_HEX, VALS (sml_timetypes), 0x0, NULL, HFILL }},
2789 { &hf_sml_objName,
2790 { "objName", "sml.objname", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2791 { &hf_sml_status,
2792 { "Status", "sml.status", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2793 { &hf_sml_unit,
2794 { "unit", "sml.unit", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2795 { &hf_sml_scaler,
2796 { "scaler", "sml.scaler", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2797 { &hf_sml_value,
2798 { "value", "sml.value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2799 { &hf_sml_simplevalue,
2800 { "simplevalue", "sml.simplevalue", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
2801 { &hf_sml_valueSignature,
2802 { "ValueSignature", "sml.valuesignature", FT_BYTES, BASE_NONE, NULL, 0x0,NULL, HFILL }},
2803 { &hf_sml_listSignature,
2804 { "ListSignature", "sml.listsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2805 { &hf_sml_parameterTreePath,
2806 { "path_Entry", "sml.parametertreepath", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2807 { &hf_sml_attribute,
2808 { "attribute", "sml.attribute", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2809 { &hf_sml_parameterName,
2810 { "parameterName", "sml.parametername", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2811 { &hf_sml_procParValue,
2812 { "procParValue", "sml.procparvalue", FT_UINT8, BASE_HEX, VALS(procvalues), 0x0, NULL, HFILL }},
2813 { &hf_sml_padding,
2814 { "Padding", "sml.padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2815 { &hf_sml_secIndex,
2816 { "secIndex", "sml.secindex", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2817 { &hf_sml_timestamp,
2818 { "timestamp", "sml.timestamp", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2819 { &hf_sml_localOffset,
2820 { "localOffset", "sml.localOffset", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2821 { &hf_sml_seasonTimeOffset,
2822 { "seasonTimeOffset", "sml.seasonTimeOffset", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
2823 { &hf_sml_attentionNo,
2824 { "attentionNo", "sml.attentionno", FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(attentionValues), 0x0, NULL, HFILL }},
2825 { &hf_sml_attentionMsg,
2826 { "attentionMsg", "sml.attentionmsg", FT_STRING, BASE_NONE, NULL, 0x0 , NULL, HFILL }},
2827 { &hf_sml_withRawdata,
2828 { "withRawdata", "sml.withrawdata", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(bools), 0x0 , NULL, HFILL }},
2829 { &hf_sml_object_list_Entry,
2830 { "object_list_Entry", "sml.objectentry", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2831 { &hf_sml_regPeriod,
2832 { "regPeriod", "sml.regperiod", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2833 { &hf_sml_rawdata,
2834 { "rawdata", "sml.rawdata", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2835 { &hf_sml_periodSignature,
2836 { "periodSignature", "sml.periodsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2837 { &hf_sml_profileSignature,
2838 { "profileSignature", "sml.profilesignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2839 { &hf_sml_signature_mA_R2_R3,
2840 { "signature_mA_R2_R3", "sml.signaturema", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2841 { &hf_sml_signature_pA_R1_R4,
2842 { "signature_pA_R1_R4", "sml.signaturepa", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2843 { &hf_sml_unit_mA,
2844 { "unit_mA", "sml.unitmA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2845 { &hf_sml_unit_pA,
2846 { "unit_pA", "sml.unitpA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2847 { &hf_sml_unit_R1,
2848 { "unit_R1", "sml.unitR1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2849 { &hf_sml_unit_R2,
2850 { "unit_R2", "sml.unitR2", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2851 { &hf_sml_unit_R3,
2852 { "unit_R3", "sml.unitR3", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2853 { &hf_sml_unit_R4,
2854 { "unit_R4", "sml.unitR4", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2855 { &hf_sml_scaler_mA,
2856 { "scaler_mA", "sml.scalermA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2857 { &hf_sml_scaler_pA,
2858 { "scaler_pA", "sml.scalerpA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2859 { &hf_sml_scaler_R1,
2860 { "scaler_R1", "sml.scalerR1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2861 { &hf_sml_scaler_R2,
2862 { "scaler_R2", "sml.scalerR2", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2863 { &hf_sml_scaler_R3,
2864 { "scaler_R3", "sml.scalerR3", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2865 { &hf_sml_scaler_R4,
2866 { "scaler_R4", "sml.scalerR4", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2867 { &hf_sml_value_mA,
2868 { "value_mA", "sml.valuemA", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2869 { &hf_sml_value_pA,
2870 { "value_pA", "sml.valuepA", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2871 { &hf_sml_value_R1,
2872 { "value_R1", "sml.valueR1", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2873 { &hf_sml_value_R2,
2874 { "value_R2", "sml.valueR2", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2875 { &hf_sml_value_R3,
2876 { "value_R3", "sml.valueR3", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2877 { &hf_sml_value_R4,
2878 { "value_R4", "sml.valueR4", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2879 { &hf_sml_file_marker,
2880 { "---SML-File---", "sml.file_marker", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2881 { &hf_sml_new_file_marker,
2882 { "---New SML File---", "sml.new_file_marker", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2883 { &hf_sml_listtype,
2884 { "listType", "sml.listtype", FT_UINT8, BASE_HEX, VALS(listtypevalues), 0x0, NULL, HFILL }},
2885 { &hf_sml_cosemvalue,
2886 { "cosemvalue", "sml.cosemvalue", FT_UINT8, BASE_HEX, VALS(cosemvaluevalues), 0x0, NULL, HFILL } },
2889 /* Setup protocol subtree array */
2890 static int *ett[] = {
2891 &ett_sml,
2892 &ett_sml_mainlist,
2893 &ett_sml_version,
2894 &ett_sml_sublist,
2895 &ett_sml_trans,
2896 &ett_sml_group,
2897 &ett_sml_abort,
2898 &ett_sml_body,
2899 &ett_sml_mblist,
2900 &ett_sml_mttree,
2901 &ett_sml_clientId,
2902 &ett_sml_codepage,
2903 &ett_sml_reqFileId,
2904 &ett_sml_serverId,
2905 &ett_sml_username,
2906 &ett_sml_password,
2907 &ett_sml_smlVersion,
2908 &ett_sml_crc16,
2909 &ett_sml_listName,
2910 &ett_sml_globalSignature,
2911 &ett_sml_refTime,
2912 &ett_sml_actSensorTime,
2913 &ett_sml_timetype,
2914 &ett_sml_time,
2915 &ett_sml_valList,
2916 &ett_sml_objName,
2917 &ett_sml_listEntry,
2918 &ett_sml_status,
2919 &ett_sml_valTime,
2920 &ett_sml_unit,
2921 &ett_sml_scaler,
2922 &ett_sml_value,
2923 &ett_sml_simplevalue,
2924 &ett_sml_valueSignature,
2925 &ett_sml_valtree,
2926 &ett_sml_listSignature,
2927 &ett_sml_actGatewayTime,
2928 &ett_sml_treepath,
2929 &ett_sml_parameterTreePath,
2930 &ett_sml_attribute,
2931 &ett_sml_parameterTree,
2932 &ett_sml_parameterName,
2933 &ett_sml_child,
2934 &ett_sml_periodEntry,
2935 &ett_sml_procParValueTime,
2936 &ett_sml_procParValuetype,
2937 &ett_sml_procParValue,
2938 &ett_sml_msgend,
2939 &ett_sml_tuple,
2940 &ett_sml_secIndex,
2941 &ett_sml_timestamp,
2942 &ett_sml_localTimestamp,
2943 &ett_sml_localOffset,
2944 &ett_sml_seasonTimeOffset,
2945 &ett_sml_signature,
2946 &ett_sml_attentionNo,
2947 &ett_sml_attentionMsg,
2948 &ett_sml_withRawdata,
2949 &ett_sml_beginTime,
2950 &ett_sml_endTime,
2951 &ett_sml_object_list,
2952 &ett_sml_object_list_Entry,
2953 &ett_sml_actTime,
2954 &ett_sml_regPeriod,
2955 &ett_sml_rawdata,
2956 &ett_sml_periodSignature,
2957 &ett_sml_period_List_Entry,
2958 &ett_sml_periodList,
2959 &ett_sml_header_List_Entry,
2960 &ett_sml_profileSignature,
2961 &ett_sml_valuelist,
2962 &ett_sml_headerList,
2963 &ett_sml_value_List_Entry,
2964 &ett_sml_signature_mA_R2_R3,
2965 &ett_sml_signature_pA_R1_R4,
2966 &ett_sml_unit_mA,
2967 &ett_sml_scaler_mA,
2968 &ett_sml_value_mA,
2969 &ett_sml_unit_pA,
2970 &ett_sml_scaler_pA,
2971 &ett_sml_value_pA,
2972 &ett_sml_unit_R1,
2973 &ett_sml_scaler_R1,
2974 &ett_sml_value_R1,
2975 &ett_sml_unit_R2,
2976 &ett_sml_scaler_R2,
2977 &ett_sml_value_R2,
2978 &ett_sml_unit_R3,
2979 &ett_sml_scaler_R3,
2980 &ett_sml_value_R3,
2981 &ett_sml_unit_R4,
2982 &ett_sml_scaler_R4,
2983 &ett_sml_value_R4,
2984 &ett_sml_tree_Entry,
2985 &ett_sml_dasDetails,
2986 &ett_sml_attentionDetails,
2987 &ett_sml_listtypetype,
2988 &ett_sml_listtype,
2989 &ett_sml_timestampedvaluetype,
2990 &ett_sml_timestampedvalue,
2991 &ett_sml_cosemvaluetype,
2992 &ett_sml_cosemvalue,
2993 &ett_sml_scaler_unit
2996 static ei_register_info ei[] = {
2997 { &ei_sml_tuple_error, { "sml.tuple_error_", PI_PROTOCOL, PI_ERROR, "error in Tuple", EXPFILL }},
2998 { &ei_sml_procParValue_invalid, { "sml.procparvalue.invalid", PI_PROTOCOL, PI_WARN, "invalid procParValue", EXPFILL }},
2999 { &ei_sml_procParValue_errror, { "sml.procparvalue.error", PI_PROTOCOL, PI_ERROR, "error in procParValue", EXPFILL }},
3000 { &ei_sml_invalid_count, { "sml.invalid_count", PI_PROTOCOL, PI_ERROR, "invalid loop count", EXPFILL }},
3001 { &ei_sml_segment_needed, { "sml.segment_needed", PI_REASSEMBLE, PI_NOTE, "probably segment needed", EXPFILL }},
3002 { &ei_sml_messagetype_unknown, { "sml.messagetype.unknown", PI_PROTOCOL, PI_ERROR, "unknown Messagetype", EXPFILL }},
3003 { &ei_sml_MessageBody, { "sml.messagebody.error", PI_PROTOCOL, PI_ERROR, "Error in MessageBody", EXPFILL }},
3004 { &ei_sml_crc_error_length, { "sml.crc.length_error", PI_PROTOCOL, PI_ERROR, "CRC length error", EXPFILL }},
3005 { &ei_sml_crc_error, { "sml.crc.error", PI_CHECKSUM, PI_WARN, "CRC error", EXPFILL }},
3006 { &ei_sml_endOfSmlMsg, { "sml.end.not_zero", PI_PROTOCOL, PI_ERROR, "MsgEnd not 0x00", EXPFILL }},
3007 { &ei_sml_esc_error, { "sml.esc.error", PI_PROTOCOL, PI_ERROR, "escapesequence error", EXPFILL }},
3008 { &ei_sml_version2_not_supported, { "sml.version2_not_supported", PI_UNDECODED, PI_WARN, "SML Version 2 not supported", EXPFILL }},
3009 { &ei_sml_attentionNo, { "sml.attentionno.unknown", PI_PROTOCOL, PI_WARN, "unknown attentionNo", EXPFILL }},
3010 { &ei_sml_listtype_invalid, { "sml.listtype.invalid", PI_PROTOCOL, PI_WARN, "invalid listtype", EXPFILL } },
3011 { &ei_sml_cosemvalue_invalid, { "sml.cosemvalue.invalid", PI_PROTOCOL, PI_WARN, "invalid cosemvalue", EXPFILL } },
3014 proto_sml = proto_register_protocol("Smart Message Language","SML", "sml");
3015 sml_handle = register_dissector("sml", dissect_sml, proto_sml);
3017 sml_module = prefs_register_protocol(proto_sml, NULL);
3019 prefs_register_bool_preference (sml_module, "reassemble", "Enable reassemble", "Enable reassembling (default is enabled)", &sml_reassemble);
3020 prefs_register_bool_preference (sml_module, "crc", "Enable crc calculation", "Enable crc (default is disabled)", &sml_crc_enabled);
3022 proto_register_field_array(proto_sml, hf, array_length(hf));
3023 proto_register_subtree_array(ett, array_length(ett));
3024 expert_sml = expert_register_protocol(proto_sml);
3025 expert_register_field_array(expert_sml, ei, array_length(ei));
3028 void proto_reg_handoff_sml(void) {
3029 dissector_add_for_decode_as_with_preference("tcp.port", sml_handle);
3030 dissector_add_for_decode_as_with_preference("udp.port", sml_handle);
3034 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3036 * Local variables:
3037 * c-basic-offset: 8
3038 * tab-width: 8
3039 * indent-tabs-mode: t
3040 * End:
3042 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3043 * :indentSize=8:tabSize=8:noTabs=false: