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
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
71 #define UNSIGNED8 0x62
72 #define UNSIGNED16 0x63
74 #define LIST_6_ELEMENTS 0x76
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 */
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
[]={
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"},
180 static const value_string sml_abort
[]={
182 {0x01, "Continue at next group"},
183 {0x02, "Continue than abort"},
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"},
206 static const value_string sml_timetypes
[]={
209 {0x03, "localTimestamp" },
213 static const value_string procvalues
[]={
214 {PROC_VALUE
, "Value"},
215 {PROC_PERIOD
, "PeriodEntry"},
216 {PROC_TUPLE
, "TupleEntry"},
218 {PROC_LISTENTRY
, "ListEntry"},
222 static const value_string listtypevalues
[] = {
223 { LISTTYPE_TIME
, "smlTime" },
224 { LISTTYPE_TIMESTAMPEDVALUE
, "smlTimestampedValue" },
225 { LISTTYPE_COSEMVALUE
, "smlCosemValue" },
229 static const value_string cosemvaluevalues
[] = {
230 { COSEMVALUE_SCALER_UNIT
, "scaler_unit" },
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"},
263 static const range_string bools
[]={
264 {0x00, 0x00, "false"},
265 {0x01, 0xFF, "true"},
269 /* Initialize the subtree pointers */
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
;
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
){
397 unsigned temp_offset
= 0;
399 temp_offset
= *offset
;
403 check
= tvb_get_uint8(tvb
, temp_offset
);
404 if (check
== OPTIONAL
){
407 else if ((check
& 0x80) == MSB
){
408 while ((check
& 0x80) == MSB
){
409 check
= check
& 0x0F;
411 *data
= *data
+ check
;
416 check
= tvb_get_uint8(tvb
, temp_offset
);
418 check
= check
& 0x0F;
420 *data
= *data
+ check
;
422 *data
= *data
- *length
;
425 check
= check
& 0x0F;
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
);
451 proto_tree_add_item(value_tree
, hf_sml_datatype
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
454 proto_tree_add_item(value_tree
, hf_sml_simplevalue
, tvb
, *offset
, *data
, ENC_NA
);
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
;
468 SML_timestampedvalue_type_tree
= proto_tree_add_subtree(timestampedvalue_tree
, tvb
, *offset
, -1, ett_sml_timestampedvaluetype
, NULL
, "SML_TimestampedValue Type");
471 SML_time_tree
= proto_tree_add_subtree(SML_timestampedvalue_type_tree
, tvb
, *offset
, -1, ett_sml_time
, &SML_time
, "smlTime");
473 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
474 proto_item_set_end(SML_time
, tvb
, *offset
);
477 field_status(tvb
, SML_timestampedvalue_type_tree
, offset
, &data
, &length
);
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
;
487 get_length(tvb
, offset
, &data
, &length
);
488 field_scaler(tvb
, cosem_scaler_unit_tree
, offset
, &data
, &length
);
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
){
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
);
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
);
511 case COSEMVALUE_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");
515 sml_cosem_scaler_unit_type(tvb
, SML_cosem_scaler_unit_tree
, offset
);
519 expert_add_info(pinfo
, SML_cosemvalue_type_tree
, &ei_sml_cosemvalue_invalid
);
524 static void sml_listtype_type(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*listtype_tree
, unsigned *offset
){
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
);
538 proto_tree_add_item(SML_listtype_type_tree
, hf_sml_listtype
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
541 check
= tvb_get_uint8(tvb
, *offset
);
547 SML_time_tree
= proto_tree_add_subtree(SML_listtype_type_tree
, tvb
, *offset
, -1, ett_sml_time
, &SML_time
, "Time");
549 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
550 proto_item_set_end(SML_time
, tvb
, *offset
);
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");
557 sml_timestampedvalue_type(tvb
, pinfo
, SML_timestampedvalue_tree
, offset
);
558 proto_item_set_end(SML_timestampedvalue
, tvb
, *offset
);
561 case LISTTYPE_COSEMVALUE
:
563 SML_cosemvalue_tree
= proto_tree_add_subtree(SML_listtype_type_tree
, tvb
, *offset
, -1, ett_sml_cosemvalue
, &SML_cosemvalue
, "CosemValue");
565 sml_cosemvalue_type(tvb
, pinfo
, SML_cosemvalue_tree
, offset
);
569 expert_add_info(pinfo
, SML_listtype_type_tree
, &ei_sml_listtype_invalid
);
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
);
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
);
593 proto_tree_add_item (value_tree
, hf_sml_datatype
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
596 proto_tree_add_item (value_tree
, hf_sml_value
, tvb
, *offset
, *data
, ENC_NA
);
604 static void sml_time_type(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*SML_time_tree
, unsigned *offset
){
606 proto_tree
*timetype_tree
;
607 proto_tree
*timevalue_tree
;
608 proto_tree
*localtimestamptype_tree
;
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
);
616 proto_tree_add_item (timetype_tree
, hf_sml_timetype
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
619 check
= tvb_get_uint8(tvb
, *offset
);
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
);
629 proto_tree_add_item(timevalue_tree
, hf_sml_secIndex
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
639 proto_tree_add_item(timevalue_tree
, hf_sml_timestamp
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
644 case TIME_LOCALTIMESTAMP
:
646 localtimestamptype_tree
= proto_tree_add_subtree(SML_time_tree
, tvb
, *offset
, length
+ data
, ett_sml_localTimestamp
, NULL
, "localTimestamp");
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
);
653 proto_tree_add_item(timevalue_tree
, hf_sml_timestamp
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
660 proto_tree_add_item(timevalue_tree
, hf_sml_localOffset
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
667 proto_tree_add_item(timevalue_tree
, hf_sml_seasonTimeOffset
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
673 expert_add_info(pinfo
, timetype_tree
, &ei_sml_listtype_invalid
);
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" : "");
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
);
690 proto_tree_add_item (codepage_tree
, hf_sml_codepage
, tvb
, *offset
, *data
, ENC_NA
);
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" : "");
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
);
708 proto_tree_add_item (clientId_tree
, hf_sml_clientId
, tvb
, *offset
, *data
, ENC_NA
);
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
);
723 proto_tree_add_item (reqFileId_tree
, hf_sml_reqFileId
, tvb
, *offset
, *data
, ENC_NA
);
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" : "");
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
);
739 proto_tree_add_item (serverId_tree
, hf_sml_serverId
, tvb
, *offset
, *data
, ENC_NA
);
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" : "");
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
);
758 proto_tree_add_item (username_tree
, hf_sml_username
, tvb
, *offset
, *data
, ENC_ASCII
| ENC_BIG_ENDIAN
);
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" : "");
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
);
777 proto_tree_add_item (password_tree
, hf_sml_password
, tvb
, *offset
, *data
, ENC_ASCII
| ENC_BIG_ENDIAN
);
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" : "");
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
);
797 proto_tree_add_item (smlVersion_tree
, hf_sml_smlVersion
, tvb
, *offset
, 1,ENC_BIG_ENDIAN
);
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" : "");
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
);
817 proto_tree_add_item (globalSignature_tree
, hf_sml_globalSignature
, tvb
, *offset
, *data
, ENC_NA
);
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" : "");
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
);
836 proto_tree_add_item (listName_tree
, hf_sml_listName
, tvb
, *offset
, *data
, ENC_NA
);
843 static void field_objName(tvbuff_t
*tvb
, proto_tree
*insert_tree
, unsigned *offset
, unsigned *data
, unsigned *length
){
844 proto_tree
*objName_tree
;
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
);
852 proto_tree_add_item (objName_tree
, hf_sml_objName
, tvb
, *offset
, *data
, ENC_NA
);
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" : "");
864 proto_tree_add_item (status_tree
, hf_sml_datatype
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
866 proto_tree_add_item (status_tree
, hf_sml_status
, tvb
, *offset
, *data
, ENC_BIG_ENDIAN
);
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
;
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" : "");
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
);
884 proto_tree_add_item(unit_tree
, hf_sml_unit
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
;
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" : "");
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
);
903 proto_tree_add_item(scaler_tree
, hf_sml_scaler
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
;
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" : "");
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
);
922 proto_tree_add_item (valueSignature_tree
, hf_sml_valueSignature
, tvb
, *offset
, *data
, ENC_NA
);
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
);
940 proto_tree_add_item (parameterTreePath_tree
, hf_sml_parameterTreePath
, tvb
, *offset
, *data
, ENC_NA
);
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
);
952 proto_tree_add_item (object_list_Entry_tree
, hf_sml_object_list_Entry
, tvb
, *offset
, *data
, ENC_NA
);
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
);
964 proto_tree_add_item (regPeriod_tree
, hf_sml_regPeriod
, tvb
, *offset
, *data
, ENC_BIG_ENDIAN
);
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
;
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" : "");
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
);
980 proto_tree_add_item (rawdata_tree
, hf_sml_rawdata
, tvb
, *offset
, *data
, ENC_NA
);
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
;
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" : "");
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
);
999 proto_tree_add_item (periodSignature_tree
, hf_sml_periodSignature
, tvb
, *offset
, *data
, ENC_NA
);
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);
1013 proto_tree_add_item(actTime_tree, hf_sml_actTime, tvb, *offset, *data, ENC_BIG_ENDIAN);
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);
1024 proto_tree_add_item(valTime_tree, hf_sml_valTime, tvb, *offset, *data, ENC_BIG_ENDIAN);
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
;
1057 unsigned length
= 0;
1060 TupleEntry_list
= proto_tree_add_subtree(procParValue_tree
, tvb
, *offset
, -1, ett_sml_tuple
, &TupleEntry
, "TupleEntry");
1061 get_length(tvb
, offset
, &data
, &length
);
1065 field_serverId(tvb
, TupleEntry_list
, offset
, &data
, &length
);
1068 SML_time_tree
= proto_tree_add_subtree(procParValue_tree
, tvb
, *offset
, -1, ett_sml_time
, &SML_time
, "secIndex");
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
);
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
);
1080 proto_tree_add_item (unit_pA_tree
, hf_sml_unit_pA
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1087 proto_tree_add_item (scaler_pA_tree
, hf_sml_scaler_pA
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1095 proto_tree_add_item (value_pA_tree
, hf_sml_value_pA
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
1102 proto_tree_add_item (unit_R1_tree
, hf_sml_unit_R1
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1109 proto_tree_add_item (scaler_R1_tree
, hf_sml_scaler_R1
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1117 proto_tree_add_item (value_R1_tree
, hf_sml_value_R1
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
1124 proto_tree_add_item (unit_R4_tree
, hf_sml_unit_R4
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1131 proto_tree_add_item (scaler_R4_tree
, hf_sml_scaler_R4
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1139 proto_tree_add_item (value_R4_tree
, hf_sml_value_R4
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
1147 proto_tree_add_item (signature_pA_R1_R4_tree
, hf_sml_signature_pA_R1_R4
, tvb
, *offset
, data
, ENC_NA
);
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
);
1154 proto_tree_add_item (unit_mA_tree
, hf_sml_unit_mA
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1161 proto_tree_add_item (scaler_mA_tree
, hf_sml_scaler_mA
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1169 proto_tree_add_item (value_mA_tree
, hf_sml_value_mA
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
1176 proto_tree_add_item (unit_R2_tree
, hf_sml_unit_R2
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1183 proto_tree_add_item (scaler_R2_tree
, hf_sml_scaler_R2
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1191 proto_tree_add_item (value_R2_tree
, hf_sml_value_R2
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
1198 proto_tree_add_item (unit_R3_tree
, hf_sml_unit_R3
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1205 proto_tree_add_item (scaler_R3_tree
, hf_sml_scaler_R3
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
1213 proto_tree_add_item (value_R3_tree
, hf_sml_value_R3
, tvb
, *offset
, data
, ENC_BIG_ENDIAN
);
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
);
1221 proto_tree_add_item (signature_mA_R2_R3_tree
, hf_sml_signature_mA_R2_R3
, tvb
, *offset
, data
, ENC_NA
);
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
;
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
;
1248 unsigned repeat
= 0;
1252 get_length(tvb
, offset
, data
, length
);
1253 parameterName_tree
= proto_tree_add_subtree(insert_tree
, tvb
, *offset
, *length
+ *data
, ett_sml_parameterName
, ¶meterName
, "parameterName");
1254 proto_tree_add_uint (parameterName_tree
, hf_sml_length
, tvb
, *offset
, *length
, *data
);
1256 proto_tree_add_item (parameterName_tree
, hf_sml_parameterName
, tvb
, *offset
, *data
, ENC_NA
);
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");
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");
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
);
1276 check
= tvb_get_uint8(tvb
, *offset
);
1277 proto_tree_add_item (procParValuetype_tree
, hf_sml_procParValue
, tvb
, *offset
, 1 ,ENC_BIG_ENDIAN
);
1283 sml_value(tvb
, pinfo
, procParValue_tree
, offset
, data
, length
);
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"));
1294 field_objName(tvb
, periodEntry_tree
, offset
, data
, length
);
1297 field_unit(tvb
, periodEntry_tree
, offset
, data
, length
);
1300 field_scaler(tvb
, periodEntry_tree
, offset
, data
, length
);
1303 sml_value(tvb
, pinfo
, periodEntry_tree
, offset
, data
, length
);
1306 field_valueSignature(tvb
, periodEntry_tree
, offset
, data
, length
);
1308 proto_item_set_end(periodEntry
, tvb
, *offset
);
1313 if (tvb_get_uint8(tvb
, *offset
) == 0xF1 && tvb_get_uint8(tvb
, *offset
+1) == 0x07){
1314 TupleEntryTree(tvb
, pinfo
, procParValue_tree
, offset
);
1317 expert_add_info(pinfo
, NULL
, &ei_sml_tuple_error
);
1323 SML_time_tree
= proto_tree_add_subtree(procParValue_tree
, tvb
, *offset
, -1, ett_sml_time
, &SML_time
, "Time");
1325 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
1326 proto_item_set_end(SML_time
, tvb
, *offset
);
1329 case PROC_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"));
1337 field_objName(tvb
, listEntry_tree
, offset
, data
, length
);
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");
1345 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
1346 proto_item_set_end(SML_time
, tvb
, *offset
);
1349 field_unit(tvb
, listEntry_tree
, offset
, data
, length
);
1352 field_scaler(tvb
, listEntry_tree
, offset
, data
, length
);
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
);
1364 expert_add_info(pinfo
, procParValue
, &ei_sml_procParValue_invalid
);
1367 proto_item_set_end(procParValue
, tvb
, *offset
);
1370 expert_add_info(pinfo
, NULL
, &ei_sml_procParValue_errror
);
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);
1383 else if ((check
& 0x0F) != 0){
1385 get_length(tvb
, offset
, data
, length
);
1386 proto_item_append_text(child
, "with %d %s", *length
+ *data
, plurality(*length
+ *data
, "element", "elements"));
1389 tree_Entry_list
= proto_tree_add_subtree(child_list
, tvb
, *offset
, -1, ett_sml_tree_Entry
, &tree_Entry
, "tree_Entry");
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"));
1404 expert_add_info_format(pinfo
, child
, &ei_sml_invalid_count
, "invalid loop count");
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");
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
);
1427 expert_add_info_format(pinfo
, child
, &ei_sml_invalid_count
, "invalid count of elements in child List");
1432 static void decode_PublicOpenReq (tvbuff_t
*tvb
, proto_tree
*messagebodytree_list
, unsigned *offset
){
1434 unsigned length
= 0;
1436 /*Codepage OPTIONAL*/
1437 field_codepage (tvb
, messagebodytree_list
, offset
, &data
, &length
);
1440 field_clientId (tvb
, messagebodytree_list
, offset
, &data
, &length
);
1443 field_reqFileId (tvb
, messagebodytree_list
, offset
, &data
, &length
);
1446 field_serverId(tvb
,messagebodytree_list
, offset
, &data
, &length
);
1449 field_username(tvb
,messagebodytree_list
, offset
, &data
, &length
);
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
;
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
);
1474 field_reqFileId (tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
1484 proto_item_append_text(SML_time
, ": NOT SET");
1485 proto_item_set_len(SML_time
, length
+ data
);
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
;
1514 unsigned repeat
= 0;
1517 unsigned length
= 0;
1520 field_serverId(tvb
,messagebodytree_list
, offset
, &data
, &length
);
1523 field_username(tvb
,messagebodytree_list
, offset
, &data
, &length
);
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" : "");
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
);
1536 proto_tree_add_item (withRawdata_tree
, hf_sml_withRawdata
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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");
1547 proto_item_append_text(SML_time
, ": NOT SET");
1548 proto_item_set_len(SML_time
, length
+ data
);
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");
1563 proto_item_append_text(SML_time
, ": NOT SET");
1564 proto_item_set_len(SML_time
, length
+ data
);
1570 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
1571 proto_item_set_end(SML_time
,tvb
,*offset
);
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");
1584 else if (repeat
<= 0){
1585 expert_add_info_format(pinfo
, treepath
, &ei_sml_invalid_count
, "invalid loop count");
1590 for (i
=0; i
< repeat
; i
++) {
1591 field_parameterTreePath(tvb
, treepath_list
, offset
, &data
, &length
);
1593 proto_item_set_end(treepath
, tvb
, *offset
);
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);
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");
1611 else if (repeat
<= 0){
1612 expert_add_info_format(pinfo
, treepath
, &ei_sml_invalid_count
, "invalid loop count");
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
);
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);
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"));
1638 child_tree(tvb
, pinfo
, dasDetails_list
, offset
, &data
, &length
);
1639 proto_item_set_end(dasDetails
, tvb
, *offset
);
1642 expert_add_info_format(pinfo
, dasDetails
, &ei_sml_invalid_count
, "invalid count of elements in dasDetails");
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
;
1671 unsigned repeat
= 0;
1672 unsigned repeat2
= 0;
1674 unsigned length
= 0;
1677 field_serverId(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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"));
1684 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
1685 proto_item_set_end(SML_time
,tvb
,*offset
);
1688 field_regPeriod(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
1700 else if (repeat
<= 0){
1701 expert_add_info_format(pinfo
, treepath
, &ei_sml_invalid_count
, "invalid loop count");
1707 for (i
=0; i
< repeat
; i
++) {
1708 field_parameterTreePath(tvb
, treepath_list
, offset
, &data
, &length
);
1710 proto_item_set_end(treepath
, tvb
, *offset
);
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");
1722 else if (repeat
<= 0){
1723 expert_add_info_format(pinfo
, headerList
, &ei_sml_invalid_count
, "invalid loop count");
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"));
1736 field_objName(tvb
, header_List_Entry_list
, offset
, &data
, &length
);
1739 field_unit(tvb
, header_List_Entry_list
, offset
, &data
, &length
);
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
);
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");
1758 else if (repeat
<= 0){
1759 expert_add_info_format(pinfo
, periodList
, &ei_sml_invalid_count
, "invalid loop count");
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"));
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");
1775 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
1776 proto_item_set_end(SML_time
,tvb
, *offset
);
1779 field_status(tvb
, period_List_Entry_list
, offset
, &data
, &length
);
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");
1791 else if (repeat2
<= 0){
1792 expert_add_info_format(pinfo
, valuelist
, &ei_sml_invalid_count
, "invalid loop count");
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"));
1805 sml_value(tvb
, pinfo
, value_List_Entry_list
, offset
, &data
, &length
);
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
);
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" : "");
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
);
1832 proto_tree_add_item (profileSignature_tree
, hf_sml_profileSignature
, tvb
, *offset
, data
, ENC_NA
);
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
;
1853 unsigned repeat
= 0;
1855 unsigned length
= 0;
1858 field_serverId(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
1864 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
1865 proto_item_set_end(SML_time
,tvb
, *offset
);
1868 field_regPeriod(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
1880 else if (repeat
<= 0){
1881 expert_add_info_format(pinfo
, treepath
, &ei_sml_invalid_count
, "invalid loop count");
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");
1897 proto_item_append_text(SML_time
, ": NOT SET");
1898 proto_item_set_len(SML_time
, length
+ data
);
1904 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
1905 proto_item_set_end(SML_time
,tvb
,*offset
);
1909 field_status(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
1921 else if (repeat
<= 0){
1922 expert_add_info_format(pinfo
, periodList
, &ei_sml_invalid_count
, "invalid loop count");
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");
1934 field_objName(tvb
, periodList_Entry_list
, offset
, &data
, &length
);
1937 field_unit(tvb
, periodList_Entry_list
, offset
, &data
, &length
);
1940 field_scaler(tvb
, periodList_Entry_list
, offset
, &data
, &length
);
1943 sml_value(tvb
, pinfo
, periodList_Entry_list
, offset
, &data
, &length
);
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
);
1953 field_rawdata(tvb
, messagebodytree_list
, offset
, &data
, &length
);
1955 /*period Signature*/
1956 field_periodSignature(tvb
, messagebodytree_list
, offset
, &data
, &length
);
1961 static void decode_GetListReq (tvbuff_t
*tvb
, proto_tree
*messagebodytree_list
, unsigned *offset
){
1963 unsigned length
= 0;
1966 field_clientId (tvb
, messagebodytree_list
, offset
, &data
, &length
);
1969 field_serverId(tvb
,messagebodytree_list
,offset
, &data
, &length
);
1972 field_username(tvb
,messagebodytree_list
,offset
, &data
, &length
);
1975 field_password(tvb
,messagebodytree_list
,offset
, &data
, &length
);
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;
1997 unsigned length
= 0;
1999 /*clientID OPTIONAL*/
2000 field_clientId (tvb
, messagebodytree_list
, offset
, &data
, &length
);
2003 field_serverId(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
2013 proto_item_append_text(SML_time
, ": NOT SET");
2014 proto_item_set_len(SML_time
, length
+ data
);
2020 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
2021 proto_item_set_end(SML_time
,tvb
,*offset
);
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");
2034 else if (repeat
<= 0){
2035 expert_add_info_format(pinfo
, valtree
, &ei_sml_invalid_count
, "invalid loop count");
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");
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");
2057 proto_item_append_text(SML_time
, ": NOT SET");
2058 proto_item_set_len(SML_time
, length
+ data
);
2064 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
2065 proto_item_set_end(SML_time
, tvb
, *offset
);
2069 field_unit(tvb
, valList_list
, offset
, &data
, &length
);
2072 field_scaler(tvb
, valList_list
, offset
, &data
, &length
);
2075 sml_value(tvb
, pinfo
, valList_list
, offset
, &data
, &length
);
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" : "");
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
);
2092 proto_tree_add_item (listSignature_tree
, hf_sml_listSignature
, tvb
, *offset
, data
, ENC_NA
);
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");
2103 proto_item_append_text(SML_time
, ": NOT SET");
2104 proto_item_set_len(SML_time
, length
+ data
);
2110 sml_time_type(tvb
, pinfo
, SML_time_tree
, offset
);
2111 proto_item_set_end(SML_time
,tvb
,*offset
);
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
;
2124 unsigned repeat
= 0;
2126 unsigned length
= 0;
2129 field_serverId(tvb
, messagebodytree_list
, offset
, &data
, &length
);
2132 field_username(tvb
, messagebodytree_list
, offset
, &data
, &length
);
2135 field_password(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
2147 else if (repeat
<= 0){
2148 expert_add_info_format(pinfo
, treepath
, &ei_sml_invalid_count
, "invalid loop count");
2154 for (i
=0; i
< repeat
; i
++) {
2155 field_parameterTreePath(tvb
, treepath_list
, offset
, &data
, &length
);
2157 proto_item_set_end(treepath
, tvb
, *offset
);
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" : "");
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
);
2167 proto_tree_add_item (attribute_tree
, hf_sml_attribute
, tvb
, *offset
, data
, ENC_NA
);
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
;
2184 unsigned repeat
= 0;
2186 unsigned length
= 0;
2189 field_serverId(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
2201 else if (repeat
<= 0){
2202 expert_add_info_format(pinfo
, treepath
, &ei_sml_invalid_count
, "invalid loop count");
2208 for (i
=0; i
< repeat
; i
++) {
2209 field_parameterTreePath(tvb
, treepath_list
, offset
, &data
, &length
);
2211 proto_item_set_end(treepath
, tvb
, *offset
);
2214 get_length(tvb
, offset
, &data
, &length
);
2215 parameterTree_list
= proto_tree_add_subtree_format(messagebodytree_list
, tvb
, *offset
, -1, ett_sml_parameterTree
, ¶meterTree
,
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");
2225 child_tree(tvb
, pinfo
,parameterTree_list
, offset
, &data
, &length
);
2226 proto_item_set_end(parameterTree
, tvb
, *offset
);
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
;
2239 unsigned repeat
= 0;
2241 unsigned length
= 0;
2244 field_serverId(tvb
, messagebodytree_list
, offset
, &data
, &length
);
2247 field_username(tvb
, messagebodytree_list
, offset
, &data
, &length
);
2250 field_password(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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");
2262 else if (repeat
<= 0){
2263 expert_add_info_format(pinfo
, treepath
, &ei_sml_invalid_count
, "invalid loop count");
2269 for (i
=0; i
< repeat
; i
++) {
2270 field_parameterTreePath(tvb
, treepath_list
, offset
, &data
, &length
);
2272 proto_item_set_end(treepath
, tvb
, *offset
);
2275 get_length(tvb
, offset
, &data
, &length
);
2276 parameterTree_list
= proto_tree_add_subtree_format(messagebodytree_list
, tvb
, *offset
, -1, ett_sml_parameterTree
, ¶meterTree
,
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");
2286 child_tree(tvb
, pinfo
,parameterTree_list
, offset
, &data
, &length
);
2287 proto_item_set_end(parameterTree
, tvb
, *offset
);
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
;
2302 unsigned length
= 0;
2305 field_serverId(tvb
, messagebodytree_list
, offset
, &data
, &length
);
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
);
2315 proto_tree_add_item (attentionNo_tree
, hf_sml_attentionNo
, tvb
, *offset
, 2, ENC_BIG_ENDIAN
);
2319 expert_add_info(pinfo
, attentionNo_item
, &ei_sml_attentionNo
);
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" : "");
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
);
2331 proto_tree_add_item (attentionMsg_tree
, hf_sml_attentionMsg
, tvb
, *offset
, data
, ENC_ASCII
| ENC_BIG_ENDIAN
);
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);
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");
2355 child_tree(tvb
, pinfo
,attentionDetails_list
, offset
, &data
, &length
);
2356 proto_item_set_end(attentionDetails
, tvb
, *offset
);
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
;
2369 proto_item
*messagebodytree
;
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;
2387 unsigned available
= 0;
2388 unsigned crc_msg_len
= 0;
2389 unsigned crc_file_len
= 0;
2391 unsigned length
= 0;
2393 bool msg_error
= false;
2394 bool close1
= false;
2395 bool close2
= false;
2398 unsigned start_offset
;
2399 start_offset
= *offset
;
2401 end_offset
= tvb_reported_length_remaining(tvb
, *offset
);
2402 if (end_offset
<= 0){
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
;
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
;
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
);
2428 if (tvb_get_ntohl(tvb
, *offset
) == ESC_SEQ
){
2429 crc_file_len
= *offset
;
2431 proto_tree_add_item (sml_tree
, hf_sml_esc
, tvb
, *offset
, 4, ENC_BIG_ENDIAN
);
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
);
2440 proto_tree_add_expert(sml_tree
, pinfo
, &ei_sml_version2_not_supported
, tvb
, *offset
, -1);
2446 crc_msg_len
= *offset
;
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");
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
);
2464 proto_tree_add_item (trans_tree
, hf_sml_transactionId
, tvb
, *offset
, data
, ENC_NA
);
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
);
2471 proto_tree_add_item (groupNo_tree
, hf_sml_groupNo
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
2478 proto_tree_add_item(abortOnError_tree
, hf_sml_abortOnError
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
2482 sublist_list
= proto_tree_add_subtree(mainlist_list
, tvb
, *offset
, -1, ett_sml_sublist
, &sublist
, "MessageBody");
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
);
2495 expert_add_info(pinfo
, messagebody
, &ei_sml_messagetype_unknown
);
2499 messagebody_switch
= tvb_get_ntohs(tvb
, *offset
);
2500 proto_tree_add_item (messagebody_tree
, hf_sml_MessageBody
, tvb
, *offset
, 2, ENC_BIG_ENDIAN
);
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"));
2509 switch (messagebody_switch
){
2511 col_append_str (pinfo
->cinfo
, COL_INFO
, "OpenReq; ");
2512 proto_item_append_text(mainlist
, " [Open Request]");
2513 decode_PublicOpenReq(tvb
, messagebodytree_list
, offset
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
2566 col_append_str (pinfo
->cinfo
, COL_INFO
, "GetListReq; ");
2567 proto_item_append_text(mainlist
, " [GetList Request]");
2568 decode_GetListReq(tvb
, messagebodytree_list
, offset
);
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
);
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
);
2581 expert_add_info(pinfo
, messagebodytree
, &ei_sml_messagetype_unknown
);
2586 expert_add_info(pinfo
, messagebodytree
, &ei_sml_MessageBody
);
2590 proto_item_set_end(messagebodytree
, tvb
, *offset
);
2591 proto_item_set_end(sublist
, tvb
, *offset
);
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
);
2602 proto_tree_add_item (crc16_tree
, hf_sml_datatype
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
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
);
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
);
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
);
2623 if (tvb_get_uint8 (tvb
, *offset
) == 0){
2624 proto_tree_add_item (mainlist_list
, hf_sml_endOfSmlMsg
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
2628 expert_add_info(pinfo
, NULL
, &ei_sml_endOfSmlMsg
);
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
){
2640 else if (check
== 0x1b || check
== 0){
2644 else if (sml_reassemble
&& pinfo
->can_desegment
){
2645 pinfo
->desegment_offset
= start_offset
;
2646 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
2658 while (tvb_get_uint8(tvb
, *offset
) == 0){
2664 proto_tree_add_item (sml_tree
, hf_sml_padding
, tvb
, *offset
, length
, ENC_NA
);
2669 if(tvb_get_ntoh40(tvb
, *offset
) != ESC_SEQ_END
){
2670 expert_add_info(pinfo
, NULL
, &ei_sml_esc_error
);
2673 proto_tree_add_item (sml_tree
, hf_sml_esc
, tvb
, *offset
, 4, ENC_BIG_ENDIAN
);
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
);
2680 proto_tree_add_item (msgend_tree
, hf_sml_padding
, tvb
, *offset
, 1, ENC_NA
);
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
);
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
);
2696 available
= tvb_reported_length_remaining(tvb
, *offset
);
2697 if (available
<= 0){
2701 if (sml_reassemble
){
2702 proto_item_set_end(file
, tvb
, *offset
);
2705 proto_tree_add_item(sml_tree
, hf_sml_new_file_marker
, tvb
, *offset
, 0, ENC_NA
);
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
){
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
);
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
[] = {
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
}},
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
}},
2760 { "Length", "sml.length", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(sml_fmt_length
), 0x0, NULL
, HFILL
}},
2762 { "GroupNo", "sml.groupno", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
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
}},
2770 { "End of Msg", "sml.end", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2772 { "Codepage", "sml.codepage", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
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
}},
2778 { "server ID", "sml.serverid", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2780 { "Username", "sml.username", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2782 { "Password", "sml.password", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
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
}},
2788 { "Time type", "sml.timetype", FT_UINT8
, BASE_HEX
, VALS (sml_timetypes
), 0x0, NULL
, HFILL
}},
2790 { "objName", "sml.objname", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
2792 { "Status", "sml.status", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2794 { "unit", "sml.unit", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2796 { "scaler", "sml.scaler", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
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
}},
2814 { "Padding", "sml.padding", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
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
}},
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
}},
2844 { "unit_mA", "sml.unitmA", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2846 { "unit_pA", "sml.unitpA", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2848 { "unit_R1", "sml.unitR1", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2850 { "unit_R2", "sml.unitR2", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2852 { "unit_R3", "sml.unitR3", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
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
}},
2868 { "value_mA", "sml.valuemA", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2870 { "value_pA", "sml.valuepA", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2872 { "value_R1", "sml.valueR1", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2874 { "value_R2", "sml.valueR2", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
2876 { "value_R3", "sml.valueR3", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
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
}},
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
[] = {
2907 &ett_sml_smlVersion
,
2910 &ett_sml_globalSignature
,
2912 &ett_sml_actSensorTime
,
2923 &ett_sml_simplevalue
,
2924 &ett_sml_valueSignature
,
2926 &ett_sml_listSignature
,
2927 &ett_sml_actGatewayTime
,
2929 &ett_sml_parameterTreePath
,
2931 &ett_sml_parameterTree
,
2932 &ett_sml_parameterName
,
2934 &ett_sml_periodEntry
,
2935 &ett_sml_procParValueTime
,
2936 &ett_sml_procParValuetype
,
2937 &ett_sml_procParValue
,
2942 &ett_sml_localTimestamp
,
2943 &ett_sml_localOffset
,
2944 &ett_sml_seasonTimeOffset
,
2946 &ett_sml_attentionNo
,
2947 &ett_sml_attentionMsg
,
2948 &ett_sml_withRawdata
,
2951 &ett_sml_object_list
,
2952 &ett_sml_object_list_Entry
,
2956 &ett_sml_periodSignature
,
2957 &ett_sml_period_List_Entry
,
2958 &ett_sml_periodList
,
2959 &ett_sml_header_List_Entry
,
2960 &ett_sml_profileSignature
,
2962 &ett_sml_headerList
,
2963 &ett_sml_value_List_Entry
,
2964 &ett_sml_signature_mA_R2_R3
,
2965 &ett_sml_signature_pA_R1_R4
,
2984 &ett_sml_tree_Entry
,
2985 &ett_sml_dasDetails
,
2986 &ett_sml_attentionDetails
,
2987 &ett_sml_listtypetype
,
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
3039 * indent-tabs-mode: t
3042 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3043 * :indentSize=8:tabSize=8:noTabs=false: