MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-sml.c
blob7d747ae21d08c0a7ade2f1b1844bed5f365befeb
1 /* packet-SML.c
2 * Routines for SML dissection
3 * Copyright 2013, Alexander Gaertner <gaertner.alex@gmx.de>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 SML dissector is based on v1.03 (12.11.2008) specifications of "smart message language" protocol
29 Link to specifications: http://www.vde.com/de/fnn/arbeitsgebiete/messwesen/Sym2/infomaterial/seiten/sml-spezifikation.aspx
31 Short description of the SML protocol on the SML Wireshark Wiki page: http://wiki.wireshark.org/SML
34 #include "config.h"
35 #include <glib.h>
36 #include <epan/packet.h>
37 #include <epan/prefs.h>
38 #include <epan/crc16-tvb.h>
39 #include <epan/expert.h>
41 #define TCP_PORT_SML 0
42 #define UDP_PORT_SML 0
44 #define ESC_SEQ_END G_GUINT64_CONSTANT(0x1b1b1b1b1a)
45 #define ESC_SEQ 0x1b1b1b1b
47 #define OPEN_REQ 0x0100
48 #define OPEN_RES 0x0101
49 #define CLOSE_REQ 0x0200
50 #define CLOSE_RES 0x0201
51 #define PROFILEPACK_REQ 0x0300
52 #define PROFILEPACK_RES 0x0301
53 #define PROFILELIST_REQ 0x0400
54 #define PROFILELIST_RES 0x0401
55 #define GETPROCPARAMETER_REQ 0x0500
56 #define GETPROCPARAMETER_RES 0x0501
57 #define SETPROCPARAMETER_REQ 0x0600
58 #define GETLIST_REQ 0x0700
59 #define GETLIST_RES 0x0701
60 #define ATTENTION 0xFF01
62 #define PROC_VALUE 0x01
63 #define PROC_PERIOD 0x02
64 #define PROC_TUPEL 0x03
65 #define PROC_TIME 0x04
67 #define SHORT_LIST 0x70
68 #define LONG_LIST 0xF0
70 #define OPTIONAL 0x01
72 #define UNSIGNED8 0x62
73 #define UNSIGNED16 0x63
75 #define LIST_6_ELEMENTS 0x76
76 #define MSB 0x80
78 static guint tcp_port_pref = TCP_PORT_SML;
79 static guint udp_port_pref = UDP_PORT_SML;
81 /* Forward declaration we need below (if using proto_reg_handoff as a prefs callback)*/
82 void proto_reg_handoff_sml(void);
84 /* Initialize the protocol and registered fields */
85 static int proto_sml = -1;
87 static int hf_sml_esc = -1;
88 static int hf_sml_version_1 = -1;
89 static int hf_sml_groupNo = -1;
90 static int hf_sml_transactionId = -1;
91 static int hf_sml_datatype = -1;
92 static int hf_sml_abortOnError = -1;
93 static int hf_sml_MessageBody = -1;
94 static int hf_sml_crc16 = -1;
95 static int hf_sml_endOfSmlMsg = -1;
96 static int hf_sml_end = -1;
97 static int hf_sml_codepage = -1;
98 static int hf_sml_clientId = -1;
99 static int hf_sml_reqFileId = -1;
100 static int hf_sml_serverId = -1;
101 static int hf_sml_username = -1;
102 static int hf_sml_password = -1;
103 static int hf_sml_smlVersion = -1;
104 static int hf_sml_listName = -1;
105 static int hf_sml_globalSignature = -1;
106 static int hf_sml_refTime = -1;
107 static int hf_sml_actSensorTime = -1;
108 static int hf_sml_timetype = -1;
109 static int hf_sml_objName = -1;
110 static int hf_sml_status = -1;
111 static int hf_sml_valTime = -1;
112 static int hf_sml_unit = -1;
113 static int hf_sml_scaler = -1;
114 static int hf_sml_value = -1;
115 static int hf_sml_valueSignature = -1;
116 static int hf_sml_listSignature = -1;
117 static int hf_sml_actGatewayTime = -1;
118 static int hf_sml_parameterTreePath = -1;
119 static int hf_sml_attribute = -1;
120 static int hf_sml_parameterName = -1;
121 static int hf_sml_procParValue = -1;
122 static int hf_sml_procParValueTime = -1;
123 static int hf_sml_padding = -1;
124 static int hf_sml_secIndex = -1;
125 static int hf_sml_attentionNo = -1;
126 static int hf_sml_attentionMsg = -1;
127 static int hf_sml_withRawdata = -1;
128 static int hf_sml_beginTime = -1;
129 static int hf_sml_endTime = -1;
130 static int hf_sml_object_list_Entry = -1;
131 static int hf_sml_actTime = -1;
132 static int hf_sml_regPeriod = -1;
133 static int hf_sml_rawdata = -1;
134 static int hf_sml_periodSignature = -1;
135 static int hf_sml_profileSignature = -1;
136 static int hf_sml_signature_mA_R2_R3 = -1;
137 static int hf_sml_signature_pA_R1_R4 = -1;
138 static int hf_sml_unit_mA = -1;
139 static int hf_sml_scaler_mA = -1;
140 static int hf_sml_value_mA = -1;
141 static int hf_sml_unit_pA = -1;
142 static int hf_sml_scaler_pA = -1;
143 static int hf_sml_value_pA = -1;
144 static int hf_sml_unit_R1 = -1;
145 static int hf_sml_scaler_R1 = -1;
146 static int hf_sml_value_R1 = -1;
147 static int hf_sml_unit_R2 = -1;
148 static int hf_sml_scaler_R2 = -1;
149 static int hf_sml_value_R2 = -1;
150 static int hf_sml_unit_R3 = -1;
151 static int hf_sml_scaler_R3 = -1;
152 static int hf_sml_value_R3 = -1;
153 static int hf_sml_unit_R4 = -1;
154 static int hf_sml_scaler_R4 = -1;
155 static int hf_sml_value_R4 = -1;
157 static const value_string datatype []={
158 {0x52, "Integer 8"},
159 {0x53, "Integer 16"},
160 {0x54, "Integer cropped"},
161 {0x55, "Integer 32"},
162 {0x56, "Integer cropped"},
163 {0x57, "Integer cropped"},
164 {0x58, "Integer cropped"},
165 {0x59, "Integer 64"},
166 {0x62, "Unsigned 8"},
167 {0x63, "Unsigned 16"},
168 {0x64, "Unsigned cropped"},
169 {0x65, "Unsigned 32"},
170 {0x66, "Unsigned cropped"},
171 {0x67, "Unsigned cropped"},
172 {0x68, "Unsigned cropped"},
173 {0x69, "Unsigned 64"},
174 {0x42, "Boolean"},
175 {0, NULL}
178 static const value_string sml_abort[]={
179 {0x00, "Continue"},
180 {0x01, "Continue at next group"},
181 {0x02, "Continue than abort"},
182 {0xFF, "Abort"},
183 {0, NULL}
186 static const value_string sml_body[]={
187 {OPEN_REQ, "PublicOpen.Req"},
188 {OPEN_RES, "PublicOpen.Res"},
189 {CLOSE_REQ, "PublicClose.Req"},
190 {CLOSE_RES, "PublicClose.Res"},
191 {PROFILEPACK_REQ, "GetProfilePack.Req"},
192 {PROFILEPACK_RES, "GetProfilePack.Res"},
193 {PROFILELIST_REQ, "GetProfileList.Req"},
194 {PROFILELIST_RES, "GetProfileList.Res"},
195 {GETPROCPARAMETER_REQ, "GetProcParameter.Req"},
196 {GETPROCPARAMETER_RES, "GetProcParameter.Res"},
197 {SETPROCPARAMETER_REQ, "SetProcParameter.Req"},
198 {GETLIST_REQ, "GetList.Req"},
199 {GETLIST_RES, "GetList.Res"},
200 {ATTENTION, "Attention.Res"},
201 {0, NULL}
204 static const value_string sml_timetypes[]={
205 {0x01, "secIndex"},
206 {0x02, "timestamp"},
207 {0, NULL}
210 static const value_string procvalues[]={
211 {PROC_VALUE, "Value"},
212 {PROC_PERIOD, "PeriodEntry"},
213 {PROC_TUPEL, "TupelEntry"},
214 {PROC_TIME, "Time"},
215 {0, NULL}
218 static const range_string attentionValues[]={
219 {0xE000, 0xFCFF, "application specific"},
220 {0xFD00, 0xFD00, "acknowledged"},
221 {0xFD01, 0xFD01, "order will be executed later"},
222 {0xFE00, 0xFE00, "error undefined"},
223 {0xFE01, 0xFE01, "unknown SML designator"},
224 {0xFE02, 0xFE02, "User/Password wrong"},
225 {0xFE03, 0xFE03, "serverId not available"},
226 {0xFE04, 0xFE04, "reqFileId not available"},
227 {0xFE05, 0xFE05, "destination attributes cannot be written"},
228 {0xFE06, 0xFE06, "destination attributes cannot be read"},
229 {0xFE07, 0xFE07, "communication disturbed"},
230 {0xFE08, 0xFE08, "rawdata cannot be interpreted"},
231 {0xFE09, 0xFE09, "value out of range"},
232 {0xFE0A, 0xFE0A, "order not executed"},
233 {0xFE0B, 0xFE0B, "checksum failed"},
234 {0xFE0C, 0xFE0C, "broadcast not supported"},
235 {0xFE0D, 0xFE0D, "unexpected message"},
236 {0xFE0E, 0xFE0E, "unknown object in the profile"},
237 {0xFE0F, 0xFE0F, "datatype not supported"},
238 {0xFE10, 0xFE10, "optional element not supported"},
239 {0xFE11, 0xFE11, "no entry in requested profile"},
240 {0xFE12, 0xFE12, "end limit before begin limit"},
241 {0xFE13, 0xFE13, "no entry in requested area"},
242 {0xFE14, 0xFE14, "SML file without close"},
243 {0xFE15, 0xFE15, "busy, response cannot be sent"},
244 {0,0, NULL}
247 static const range_string bools[]={
248 {0x00, 0x00, "false"},
249 {0x01, 0xFF, "true"},
250 {0,0, NULL}
253 /* Initialize the subtree pointers */
254 static gint ett_sml = -1;
255 static gint ett_sml_mainlist = -1;
256 static gint ett_sml_version = -1;
257 static gint ett_sml_sublist = -1;
258 static gint ett_sml_trans = -1;
259 static gint ett_sml_group = -1;
260 static gint ett_sml_abort = -1;
261 static gint ett_sml_body = -1;
262 static gint ett_sml_mblist = -1;
263 static gint ett_sml_mttree = -1;
264 static gint ett_sml_crc16 = -1;
265 static gint ett_sml_clientId = -1;
266 static gint ett_sml_codepage = -1;
267 static gint ett_sml_reqFileId= -1;
268 static gint ett_sml_serverId = -1;
269 static gint ett_sml_username = -1;
270 static gint ett_sml_password = -1;
271 static gint ett_sml_smlVersion = -1;
272 static gint ett_sml_listName = -1;
273 static gint ett_sml_globalSignature = -1;
274 static gint ett_sml_refTime = -1;
275 static gint ett_sml_actSensorTime = -1;
276 static gint ett_sml_timetype = -1;
277 static gint ett_sml_time = -1;
278 static gint ett_sml_valList = -1;
279 static gint ett_sml_listEntry = -1;
280 static gint ett_sml_objName = -1;
281 static gint ett_sml_status = -1;
282 static gint ett_sml_valTime = -1;
283 static gint ett_sml_unit = -1;
284 static gint ett_sml_scaler = -1;
285 static gint ett_sml_value = -1;
286 static gint ett_sml_valueSignature = -1;
287 static gint ett_sml_listSignature = -1;
288 static gint ett_sml_valtree = -1;
289 static gint ett_sml_actGatewayTime = -1;
290 static gint ett_sml_treepath = -1;
291 static gint ett_sml_parameterTreePath = -1;
292 static gint ett_sml_attribute = -1;
293 static gint ett_sml_parameterTree = -1;
294 static gint ett_sml_parameterName = -1;
295 static gint ett_sml_child = -1;
296 static gint ett_sml_periodEntry = -1;
297 static gint ett_sml_procParValue = -1;
298 static gint ett_sml_procParValueTime = -1;
299 static gint ett_sml_procParValuetype = -1;
300 static gint ett_sml_msgend = -1;
301 static gint ett_sml_tupel = -1;
302 static gint ett_sml_secIndex = -1;
303 static gint ett_sml_signature = -1;
304 static gint ett_sml_attentionNo = -1;
305 static gint ett_sml_attentionMsg = -1;
306 static gint ett_sml_withRawdata = -1;
307 static gint ett_sml_beginTime = -1;
308 static gint ett_sml_endTime = -1;
309 static gint ett_sml_object_list = -1;
310 static gint ett_sml_object_list_Entry = -1;
311 static gint ett_sml_actTime = -1;
312 static gint ett_sml_regPeriod = -1;
313 static gint ett_sml_rawdata = -1;
314 static gint ett_sml_periodSignature = -1;
315 static gint ett_sml_period_List_Entry = -1;
316 static gint ett_sml_periodList = -1;
317 static gint ett_sml_headerList = -1;
318 static gint ett_sml_header_List_Entry = -1;
319 static gint ett_sml_profileSignature = -1;
320 static gint ett_sml_valuelist = -1;
321 static gint ett_sml_value_List_Entry = -1;
322 static gint ett_sml_signature_mA_R2_R3 = -1;
323 static gint ett_sml_signature_pA_R1_R4 = -1;
324 static gint ett_sml_unit_mA = -1;
325 static gint ett_sml_scaler_mA = -1;
326 static gint ett_sml_value_mA = -1;
327 static gint ett_sml_unit_pA = -1;
328 static gint ett_sml_scaler_pA = -1;
329 static gint ett_sml_value_pA = -1;
330 static gint ett_sml_unit_R1 = -1;
331 static gint ett_sml_scaler_R1 = -1;
332 static gint ett_sml_value_R1 = -1;
333 static gint ett_sml_unit_R2 = -1;
334 static gint ett_sml_scaler_R2 = -1;
335 static gint ett_sml_value_R2 = -1;
336 static gint ett_sml_unit_R3 = -1;
337 static gint ett_sml_scaler_R3 = -1;
338 static gint ett_sml_value_R3 = -1;
339 static gint ett_sml_unit_R4 = -1;
340 static gint ett_sml_scaler_R4 = -1;
341 static gint ett_sml_value_R4 = -1;
342 static gint ett_sml_tree_Entry = -1;
343 static gint ett_sml_dasDetails = -1;
344 static gint ett_sml_attentionDetails = -1;
346 static expert_field ei_sml_messagetype_unknown = EI_INIT;
347 static expert_field ei_sml_procParValue_errror = EI_INIT;
348 static expert_field ei_sml_procParValue_invalid = EI_INIT;
349 static expert_field ei_sml_segment_needed = EI_INIT;
350 static expert_field ei_sml_endOfSmlMsg = EI_INIT;
351 static expert_field ei_sml_crc_error = EI_INIT;
352 static expert_field ei_sml_tupel_error = EI_INIT;
353 static expert_field ei_sml_crc_error_length = EI_INIT;
354 static expert_field ei_sml_invalid_count = EI_INIT;
355 static expert_field ei_sml_MessageBody = EI_INIT;
356 static expert_field ei_sml_esc_error = EI_INIT;
358 /*options*/
359 static gboolean sml_reassemble = TRUE;
360 static gboolean sml_crc_enabled = FALSE;
362 /*get number of length octets and calculate how many data octets, it's like BER but not the same! */
363 static void get_length(tvbuff_t *tvb, guint *offset, guint *data, guint *length){
364 guint check = 0;
365 guint temp_offset = 0;
367 temp_offset = *offset;
368 *data = 0;
369 *length = 0;
371 check = tvb_get_guint8(tvb, temp_offset);
372 if (check == OPTIONAL){
373 *length = 1;
375 else if ((check & 0x80) == MSB){
376 while ((check & 0x80) == MSB){
377 check = check & 0x0F;
379 *data = *data + check;
380 *data <<= 4;
381 *length+=1;
383 temp_offset+=1;
384 check = tvb_get_guint8(tvb, temp_offset);
386 check = check & 0x0F;
388 *data = *data + check;
389 *length+=1;
390 *data = *data - *length;
392 else{
393 check = check & 0x0F;
394 *length+=1;
395 *data = check - *length;
399 /*often used fields*/
400 static void sml_value(tvbuff_t *tvb,proto_tree *insert_tree,guint *offset, guint *data, guint *length){
401 proto_item *value = NULL;
402 proto_tree *value_tree = NULL;
404 get_length(tvb, offset, data, length);
405 value = proto_tree_add_bytes_format (insert_tree, hf_sml_value, tvb, *offset, *length + *data, NULL,"value %s", (*data == 0)? ": NOT SET" : "");
407 if (tvb_get_guint8(tvb, *offset) != OPTIONAL){
408 value_tree = proto_item_add_subtree (value, ett_sml_value);
409 if ((tvb_get_guint8(tvb, *offset) & 0x80) == MSB || (tvb_get_guint8(tvb, *offset) & 0xF0) == 0){
410 proto_tree_add_text (value_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
411 *offset+= *length;
413 else {
414 proto_tree_add_item (value_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
415 *offset+=1;
417 proto_tree_add_item (value_tree, hf_sml_value, tvb, *offset, *data, ENC_NA);
418 *offset+= *data;
420 else
421 *offset+=1;
424 static void sml_time_type(tvbuff_t *tvb, proto_tree *SML_time_tree, guint *offset){
425 proto_item *timetype = NULL;
426 proto_tree *timetype_tree = NULL;
428 timetype = proto_tree_add_text (SML_time_tree, tvb, *offset, 2, "SML-Time Type");
429 timetype_tree = proto_item_add_subtree (timetype, ett_sml_timetype);
431 proto_tree_add_item (timetype_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
432 *offset+=1;
433 proto_tree_add_item (timetype_tree, hf_sml_timetype, tvb, *offset, 1, ENC_NA);
434 *offset+=1;
437 static void field_codepage(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
438 proto_item *codepage = NULL;
439 proto_tree *codepage_tree = NULL;
441 get_length(tvb, offset, data, length);
442 codepage = proto_tree_add_bytes_format (insert_tree, hf_sml_codepage, tvb, *offset, *length + *data, NULL,"Codepage %s", (*data == 0)? ": NOT SET" : "");
444 if (*data > 0) {
445 codepage_tree = proto_item_add_subtree (codepage , ett_sml_codepage);
446 proto_tree_add_text (codepage_tree, tvb, *offset, *length, "Length: %d %s", *data ,plurality(*data, "octet", "octets"));
447 *offset+= *length;
449 proto_tree_add_item (codepage_tree, hf_sml_codepage, tvb, *offset, *data, ENC_NA);
450 *offset+= *data;
452 else
453 *offset+=1;
456 static void field_clientId(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
457 proto_item *clientId = NULL;
458 proto_tree *clientId_tree = NULL;
460 get_length(tvb, offset, data, length);
461 clientId = proto_tree_add_bytes_format (insert_tree, hf_sml_clientId, tvb, *offset, *length + *data, NULL, "clientID %s", (*data == 0)? ": NOT SET" : "");
463 if (*data > 0) {
464 clientId_tree = proto_item_add_subtree (clientId, ett_sml_clientId);
465 proto_tree_add_text (clientId_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
466 *offset+=*length;
467 proto_tree_add_item (clientId_tree, hf_sml_clientId, tvb, *offset, *data, ENC_NA);
468 *offset+=*data;
470 else
471 *offset+=1;
474 static void field_reqFileId(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
475 proto_item *reqFileId = NULL;
476 proto_tree *reqFileId_tree = NULL;
478 get_length(tvb, offset, data, length);
479 reqFileId = proto_tree_add_text (insert_tree, tvb, *offset, *length + *data, "reqFileId");
481 reqFileId_tree = proto_item_add_subtree (reqFileId, ett_sml_reqFileId);
482 proto_tree_add_text (reqFileId_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
483 *offset+=*length;
484 proto_tree_add_item (reqFileId_tree, hf_sml_reqFileId, tvb, *offset, *data, ENC_NA);
485 *offset+=*data;
488 static void field_serverId(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
489 proto_item *serverId = NULL;
490 proto_tree *serverId_tree = NULL;
492 /*Server ID OPTIONAL*/
493 get_length(tvb, offset, data, length);
494 serverId = proto_tree_add_bytes_format (insert_tree,hf_sml_serverId, tvb, *offset, *length + *data, NULL, "Server ID %s", (*data == 0)? ": NOT SET" : "");
496 if (*data > 0){
497 serverId_tree = proto_item_add_subtree (serverId , ett_sml_serverId);
498 proto_tree_add_text (serverId_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
499 *offset+=*length;
500 proto_tree_add_item (serverId_tree, hf_sml_serverId, tvb, *offset, *data, ENC_NA);
501 *offset+=*data;
503 else
504 *offset+=1;
507 static void field_username(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
508 proto_item *username = NULL;
509 proto_tree *username_tree = NULL;
511 /*Username OPTIONAL*/
512 get_length(tvb, offset, data, length);
513 username = proto_tree_add_string_format (insert_tree,hf_sml_username, tvb, *offset, *length + *data, NULL, "Username %s", (*data == 0)? ": NOT SET" : "");
515 if (*data > 0){
516 username_tree = proto_item_add_subtree (username , ett_sml_username);
517 proto_tree_add_text (username_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
518 *offset+=*length;
519 proto_tree_add_item (username_tree, hf_sml_username, tvb, *offset, *data, ENC_ASCII | ENC_BIG_ENDIAN);
520 *offset+=*data;
522 else
523 *offset+=1;
526 static void field_password(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
527 proto_item *password = NULL;
528 proto_tree *password_tree = NULL;
530 /*Password OPTIONAL*/
531 get_length(tvb, offset, data, length);
532 password = proto_tree_add_string_format (insert_tree,hf_sml_password, tvb, *offset, *length + *data, NULL, "Password %s", (*data == 0)? ": NOT SET" : "");
534 if (*data > 0) {
535 password_tree = proto_item_add_subtree (password, ett_sml_password);
536 proto_tree_add_text (password_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
537 *offset+=*length;
538 proto_tree_add_item (password_tree, hf_sml_password, tvb, *offset, *data, ENC_ASCII | ENC_BIG_ENDIAN);
539 *offset+=*data;
541 else
542 *offset+=1;
545 static void field_smlVersion(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
546 proto_item *smlVersion = NULL;
547 proto_tree *smlVersion_tree = NULL;
549 /*sml-Version OPTIONAL*/
550 get_length(tvb, offset, data, length);
551 smlVersion = proto_tree_add_uint_format (insert_tree, hf_sml_smlVersion, tvb, *offset, *length + *data, *length + *data, "SML-Version %s", (*data == 0)? ": Version 1" : "");
553 if (*data > 0) {
554 smlVersion_tree = proto_item_add_subtree (smlVersion, ett_sml_smlVersion);
555 proto_tree_add_item (smlVersion_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
556 *offset+=1;
558 proto_tree_add_item (smlVersion_tree, hf_sml_smlVersion, tvb, *offset, 1,ENC_NA);
559 *offset+=1;
561 else
562 *offset+=1;
565 static void field_globalSignature(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
566 proto_item *globalSignature = NULL;
567 proto_tree *globalSignature_tree = NULL;
569 /*Global Signature OPTIONAL*/
570 get_length(tvb, offset, data, length);
572 globalSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_globalSignature, tvb, *offset, *length + *data, NULL, "global Signature %s", (*data == 0)? ": NOT SET" : "");
574 if (*data > 0){
575 globalSignature_tree = proto_item_add_subtree (globalSignature, ett_sml_globalSignature);
576 proto_tree_add_text (globalSignature_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
577 *offset+=*length;
578 proto_tree_add_item (globalSignature_tree, hf_sml_globalSignature, tvb, *offset, *data, ENC_NA);
579 *offset+=*data;
581 else
582 *offset+=1;
585 static void field_listName(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
586 proto_item *listName = NULL;
587 proto_tree *listName_tree = NULL;
589 /*List Name OPTIONAL*/
590 get_length(tvb, offset, data, length);
591 listName = proto_tree_add_bytes_format (insert_tree,hf_sml_listName, tvb, *offset, *length + *data, NULL, "List Name %s", (*data == 0)? ": NOT SET" : "");
593 if (*data > 0) {
594 listName_tree = proto_item_add_subtree (listName, ett_sml_listName);
595 proto_tree_add_text (listName_tree, tvb, *offset, *length, "Length: %d %s", *length ,plurality(*data, "octet", "octets"));
596 *offset+=*length;
597 proto_tree_add_item (listName_tree, hf_sml_listName, tvb, *offset, *data, ENC_NA);
598 *offset+=*data;
600 else
601 *offset+=1;
604 static void field_objName(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
605 proto_item *objName = NULL;
606 proto_tree *objName_tree = NULL;
608 /*Objectname*/
609 get_length(tvb, offset, data, length);
610 objName = proto_tree_add_text (insert_tree, tvb, *offset, *length + *data ,"Objectname");
612 objName_tree = proto_item_add_subtree (objName, ett_sml_objName);
613 proto_tree_add_text (objName_tree, tvb, *offset, *length, "Length: %d %s", *data ,plurality(*data, "octet", "octets"));
614 *offset+=*length;
615 proto_tree_add_item (objName_tree, hf_sml_objName, tvb, *offset, *data, ENC_NA);
616 *offset+=*data;
619 static void field_status(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
620 proto_item *status = NULL;
621 proto_tree *status_tree = NULL;
623 get_length(tvb, offset, data, length);
624 status = proto_tree_add_text (insert_tree, tvb, *offset, *length + *data ,"status %s", (*data == 0)? ": NOT SET" : "");
626 if (*data > 0){
627 status_tree = proto_item_add_subtree (status, ett_sml_status);
628 proto_tree_add_item (status_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
629 *offset+=1;
630 proto_tree_add_item (status_tree, hf_sml_status, tvb, *offset, *data, ENC_BIG_ENDIAN);
631 *offset+= *data;
633 else
634 *offset+=1;
637 static void field_unit(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
638 proto_item *unit = NULL;
639 proto_tree *unit_tree = NULL;
641 /*unit OPTIONAL*/
642 get_length(tvb, offset, data, length);
643 unit = proto_tree_add_uint_format (insert_tree, hf_sml_unit, tvb, *offset, *length + *data, *length + *data, "Unit %s", (*data == 0)? ": NOT SET" : "");
644 if (*data > 0) {
645 unit_tree = proto_item_add_subtree (unit, ett_sml_unit);
646 proto_tree_add_item (unit_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
647 *offset+=1;
648 proto_tree_add_item(unit_tree, hf_sml_unit, tvb, *offset, 1, ENC_NA);
649 *offset+=1;
651 else
652 *offset+=1;
655 static void field_scaler(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
656 proto_item *scaler = NULL;
657 proto_tree *scaler_tree = NULL;
659 /*Scaler OPTIONAL*/
660 get_length(tvb, offset, data, length);
661 scaler = proto_tree_add_uint_format (insert_tree, hf_sml_scaler, tvb, *offset, *length + *data, *length + *data, "Scaler %s", (*data == 0)? ": NOT SET" : "");
663 if (*data > 0){
664 scaler_tree = proto_item_add_subtree (scaler, ett_sml_scaler);
665 proto_tree_add_item (scaler_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
666 *offset+=1;
667 proto_tree_add_item(scaler_tree, hf_sml_scaler, tvb, *offset, 1, ENC_NA);
668 *offset+=1;
670 else
671 *offset+=1;
674 static void field_valueSignature(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
675 proto_item *valueSignature = NULL;
676 proto_tree *valueSignature_tree = NULL;
678 /*value Signature*/
679 get_length(tvb, offset, data, length);
680 valueSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_valueSignature, tvb, *offset, *length + *data, NULL, "ValueSignature %s", (*data == 0)? ": NOT SET" : "");
682 if (*data > 0){
683 valueSignature_tree = proto_item_add_subtree (valueSignature, ett_sml_valueSignature);
684 proto_tree_add_text (valueSignature_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
685 *offset+=*length;
686 proto_tree_add_item (valueSignature_tree, hf_sml_valueSignature, tvb, *offset, *data, ENC_NA);
687 *offset+=*data;
689 else
690 *offset+=1;
693 static void field_parameterTreePath(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
694 proto_item *parameterTreePath = NULL;
695 proto_tree *parameterTreePath_tree = NULL;
697 /*parameterTreePath*/
698 get_length(tvb, offset, data, length);
699 parameterTreePath = proto_tree_add_bytes_format (insert_tree, hf_sml_parameterTreePath, tvb, *offset, *length + *data, NULL, "path_Entry %s", (*data == 0)? ": NOT SET" : "");
701 parameterTreePath_tree = proto_item_add_subtree (parameterTreePath, ett_sml_parameterTreePath);
702 proto_tree_add_text (parameterTreePath_tree, tvb, *offset, *length, "Length: %d %s", *data ,plurality(*data, "octet", "octets"));
703 *offset+=*length;
704 proto_tree_add_item (parameterTreePath_tree, hf_sml_parameterTreePath, tvb, *offset, *data, ENC_NA);
705 *offset+=*data;
708 static void field_ObjReqEntry(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
709 proto_item *object_list_Entry = NULL;
710 proto_tree *object_list_Entry_tree = NULL;
712 /*parameterTreePath*/
713 get_length(tvb, offset, data, length);
714 object_list_Entry = proto_tree_add_text (insert_tree, tvb ,*offset, *length + *data, "object_list_Entry");
715 object_list_Entry_tree = proto_item_add_subtree (object_list_Entry, ett_sml_object_list_Entry);
716 proto_tree_add_text (object_list_Entry_tree, tvb, *offset, *length, "Length: %d %s", *data ,plurality(*data, "octet", "octets"));
717 *offset+=*length;
718 proto_tree_add_item (object_list_Entry_tree, hf_sml_object_list_Entry, tvb, *offset, *data, ENC_NA);
719 *offset+=*data;
722 static void field_regPeriod(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
723 proto_item *regPeriod = NULL;
724 proto_tree *regPeriod_tree = NULL;
726 get_length(tvb, offset, data, length);
727 regPeriod = proto_tree_add_text (insert_tree, tvb, *offset, *length + *data, "regPeriod");
729 regPeriod_tree = proto_item_add_subtree (regPeriod, ett_sml_regPeriod);
730 proto_tree_add_item (regPeriod_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
731 *offset+=1;
732 proto_tree_add_item (regPeriod_tree, hf_sml_regPeriod, tvb, *offset, *data, ENC_BIG_ENDIAN);
733 *offset+=*data;
736 static void field_rawdata(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
737 proto_item *rawdata = NULL;
738 proto_tree *rawdata_tree = NULL;
740 /*rawdata*/
741 get_length(tvb, offset, data, length);
742 rawdata = proto_tree_add_bytes_format (insert_tree, hf_sml_rawdata, tvb, *offset, *length + *data, NULL, "rawdata %s", (*data == 0)? ": NOT SET" : "");
744 if (*data > 0){
745 rawdata_tree = proto_item_add_subtree (rawdata, ett_sml_rawdata);
746 proto_tree_add_text (rawdata_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
747 *offset+=*length;
748 proto_tree_add_item (rawdata_tree, hf_sml_rawdata, tvb, *offset, *data, ENC_NA);
749 *offset+=*data;
751 else
752 *offset+=1;
755 static void field_periodSignature(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
756 proto_item *periodSignature = NULL;
757 proto_tree *periodSignature_tree = NULL;
759 /*periodSignature*/
760 get_length(tvb, offset, data, length);
761 periodSignature = proto_tree_add_bytes_format (insert_tree, hf_sml_periodSignature, tvb, *offset, *length + *data, NULL,"periodSignature %s", (*data == 0)? ": NOT SET" : "");
763 if (*data > 0){
764 periodSignature_tree = proto_item_add_subtree (periodSignature, ett_sml_periodSignature);
765 proto_tree_add_text (periodSignature_tree, tvb, *offset, *length, "Length: %d %s", *data, plurality(*data, "octet", "octets"));
766 *offset+=*length;
767 proto_tree_add_item (periodSignature_tree, hf_sml_periodSignature, tvb, *offset, *data, ENC_NA);
768 *offset+=*data;
770 else
771 *offset+=1;
774 static void field_actTime(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
775 proto_item *actTime = NULL;
776 proto_tree *actTime_tree = NULL;
778 get_length(tvb, offset, data, length);
779 actTime = proto_tree_add_text (insert_tree, tvb, *offset, *length + *data, "actTime");
780 actTime_tree = proto_item_add_subtree (actTime, ett_sml_actTime);
781 proto_tree_add_item (actTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
782 *offset+=1;
783 proto_tree_add_item(actTime_tree, hf_sml_actTime, tvb, *offset, *data, ENC_BIG_ENDIAN);
784 *offset+=*data;
787 static void field_valTime(tvbuff_t *tvb, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
788 proto_item *valTime = NULL;
789 proto_tree *valTime_tree = NULL;
791 get_length(tvb, offset, data, length);
792 valTime = proto_tree_add_text (insert_tree, tvb, *offset, *length + *data, "valTime");
793 valTime_tree = proto_item_add_subtree (valTime, ett_sml_valTime);
794 proto_tree_add_item (valTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
795 *offset+=1;
796 proto_tree_add_item(valTime_tree, hf_sml_valTime, tvb, *offset, *data, ENC_BIG_ENDIAN);
797 *offset+=*data;
800 static void TupelEntryTree(tvbuff_t *tvb, proto_tree *procParValue_tree, guint *offset){
801 proto_item *TupelEntry = NULL;
802 proto_item *SML_time = NULL;
803 proto_item *secIndex = NULL;
804 proto_item *unit_pA = NULL;
805 proto_item *scaler_pA = NULL;
806 proto_item *value_pA = NULL;
807 proto_item *unit_mA = NULL;
808 proto_item *scaler_mA = NULL;
809 proto_item *value_mA = NULL;
810 proto_item *unit_R1 = NULL;
811 proto_item *scaler_R1 = NULL;
812 proto_item *value_R1 = NULL;
813 proto_item *unit_R2 = NULL;
814 proto_item *scaler_R2 = NULL;
815 proto_item *value_R2 = NULL;
816 proto_item *unit_R3 = NULL;
817 proto_item *scaler_R3 = NULL;
818 proto_item *value_R3 = NULL;
819 proto_item *unit_R4 = NULL;
820 proto_item *scaler_R4 = NULL;
821 proto_item *value_R4 = NULL;
822 proto_item *signature_pA_R1_R4 = NULL;
823 proto_item *signature_mA_R2_R3 = NULL;
825 proto_tree *TupelEntry_list = NULL;
826 proto_tree *SML_time_tree = NULL;
827 proto_tree *secIndex_tree = NULL;
828 proto_tree *unit_pA_tree = NULL;
829 proto_tree *scaler_pA_tree = NULL;
830 proto_tree *value_pA_tree = NULL;
831 proto_tree *unit_mA_tree = NULL;
832 proto_tree *scaler_mA_tree = NULL;
833 proto_tree *value_mA_tree = NULL;
834 proto_tree *unit_R1_tree = NULL;
835 proto_tree *scaler_R1_tree = NULL;
836 proto_tree *value_R1_tree = NULL;
837 proto_tree *unit_R2_tree = NULL;
838 proto_tree *scaler_R2_tree = NULL;
839 proto_tree *value_R2_tree = NULL;
840 proto_tree *unit_R3_tree = NULL;
841 proto_tree *scaler_R3_tree = NULL;
842 proto_tree *value_R3_tree = NULL;
843 proto_tree *unit_R4_tree = NULL;
844 proto_tree *scaler_R4_tree = NULL;
845 proto_tree *value_R4_tree = NULL;
846 proto_tree *signature_pA_R1_R4_tree = NULL;
847 proto_tree *signature_mA_R2_R3_tree = NULL;
849 guint data = 0;
850 guint length = 0;
852 /*Tupel_List*/
853 TupelEntry = proto_tree_add_text (procParValue_tree, tvb, *offset, -1, "TupelEntry");
854 TupelEntry_list = proto_item_add_subtree (TupelEntry, ett_sml_tupel);
855 get_length(tvb, offset, &data, &length);
856 *offset+=length;
858 /*Server Id*/
859 field_serverId(tvb, TupelEntry_list, offset, &data, &length);
861 /*secindex*/
862 SML_time = proto_tree_add_text (procParValue_tree, tvb, *offset, -1, "secIndex");
863 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
864 *offset+=1;
865 sml_time_type(tvb, SML_time_tree, offset);
866 get_length(tvb, offset, &data, &length);
867 secIndex = proto_tree_add_text (SML_time_tree, tvb, *offset, length + data, "secIndex");
868 secIndex_tree = proto_item_add_subtree (secIndex, ett_sml_secIndex);
869 proto_tree_add_item (secIndex_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
870 *offset+=1;
871 proto_tree_add_item(secIndex_tree, hf_sml_secIndex, tvb, *offset, data, ENC_BIG_ENDIAN);
872 *offset+=data;
873 proto_item_set_end(SML_time, tvb, *offset);
875 /*Sml Status OPTIONAL*/
876 field_status(tvb, TupelEntry_list, offset, &data, &length);
878 /*unit_pA*/
879 unit_pA= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "unit_pA");
880 unit_pA_tree = proto_item_add_subtree(unit_pA, ett_sml_unit_pA);
881 proto_tree_add_item (unit_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
882 *offset+=1;
883 proto_tree_add_item (unit_pA_tree, hf_sml_unit_pA, tvb, *offset, 1, ENC_NA);
884 *offset+=1;
886 /*scaler_pA*/
887 scaler_pA= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "scaler_pA");
888 scaler_pA_tree = proto_item_add_subtree(scaler_pA, ett_sml_scaler_pA);
889 proto_tree_add_item (scaler_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
890 *offset+=1;
891 proto_tree_add_item (scaler_pA_tree, hf_sml_scaler_pA, tvb, *offset, 1, ENC_NA);
892 *offset+=1;
894 /*value_pA*/
895 get_length(tvb, offset, &data, &length);
896 value_pA= proto_tree_add_text (TupelEntry_list, tvb, *offset, length+data, "value_pA");
897 value_pA_tree = proto_item_add_subtree(value_pA, ett_sml_value_pA);
898 proto_tree_add_item (value_pA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
899 *offset+=1;
900 proto_tree_add_item (value_pA_tree, hf_sml_value_pA, tvb, *offset, data, ENC_NA);
901 *offset+=data;
903 /*unit_R1*/
904 unit_R1= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "unit_R1");
905 unit_R1_tree = proto_item_add_subtree(unit_R1, ett_sml_unit_R1);
906 proto_tree_add_item (unit_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
907 *offset+=1;
908 proto_tree_add_item (unit_R1_tree, hf_sml_unit_R1, tvb, *offset, 1, ENC_NA);
909 *offset+=1;
911 /*scaler_R1*/
912 scaler_R1= proto_tree_add_text (TupelEntry_list, tvb, *offset, 1, "scaler_R1");
913 scaler_R1_tree = proto_item_add_subtree(scaler_R1, ett_sml_scaler_R1);
914 proto_tree_add_item (scaler_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
915 *offset+=1;
916 proto_tree_add_item (scaler_R1_tree, hf_sml_scaler_R1, tvb, *offset, 1, ENC_NA);
917 *offset+=1;
919 /*value_R1*/
920 get_length(tvb, offset, &data, &length);
921 value_R1= proto_tree_add_text (TupelEntry_list, tvb, *offset, length+data, "value_R1");
922 value_R1_tree = proto_item_add_subtree(value_R1, ett_sml_value_R1);
923 proto_tree_add_item (value_R1_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
924 *offset+=1;
925 proto_tree_add_item (value_R1_tree, hf_sml_value_R1, tvb, *offset, data, ENC_NA);
926 *offset+=data;
928 /*unit_R4*/
929 unit_R4= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "unit_R4");
930 unit_R4_tree = proto_item_add_subtree(unit_R4, ett_sml_unit_R4);
931 proto_tree_add_item (unit_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
932 *offset+=1;
933 proto_tree_add_item (unit_R4_tree, hf_sml_unit_R4, tvb, *offset, 1, ENC_NA);
934 *offset+=1;
936 /*scaler_R4*/
937 scaler_R4= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "scaler_R4");
938 scaler_R4_tree = proto_item_add_subtree(scaler_R4, ett_sml_scaler_R4);
939 proto_tree_add_item (scaler_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
940 *offset+=1;
941 proto_tree_add_item (scaler_R4_tree, hf_sml_scaler_R4, tvb, *offset, 1, ENC_NA);
942 *offset+=1;
944 /*value_R4*/
945 get_length(tvb, offset, &data, &length);
946 value_R4= proto_tree_add_text (TupelEntry_list, tvb, *offset, length+data, "value_R4");
947 value_R4_tree = proto_item_add_subtree(value_R4, ett_sml_value_R4);
948 proto_tree_add_item (value_R4_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
949 *offset+=1;
950 proto_tree_add_item (value_R4_tree, hf_sml_value_R4, tvb, *offset, data, ENC_NA);
951 *offset+=data;
953 /*signature_pA_R1_R4*/
954 get_length(tvb, offset, &data, &length);
955 signature_pA_R1_R4= proto_tree_add_text (TupelEntry_list, tvb, *offset, length+data, "signature_pa_R1_R4");
956 signature_pA_R1_R4_tree = proto_item_add_subtree(signature_pA_R1_R4, ett_sml_signature_pA_R1_R4);
957 proto_tree_add_text (signature_pA_R1_R4_tree, tvb, *offset, length, "Length: %d %s", data ,plurality(data, "octet", "octets"));
958 *offset+=length;
959 proto_tree_add_item (signature_pA_R1_R4_tree, hf_sml_signature_pA_R1_R4, tvb, *offset, data, ENC_NA);
960 *offset+=data;
962 /*unit_mA*/
963 unit_mA= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "unit_mA");
964 unit_mA_tree = proto_item_add_subtree(unit_mA, ett_sml_unit_mA);
965 proto_tree_add_item (unit_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
966 *offset+=1;
967 proto_tree_add_item (unit_mA_tree, hf_sml_unit_mA, tvb, *offset, 1, ENC_NA);
968 *offset+=1;
970 /*scaler_mA*/
971 scaler_mA= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "scaler_mA");
972 scaler_mA_tree = proto_item_add_subtree(scaler_mA, ett_sml_scaler_mA);
973 proto_tree_add_item (scaler_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
974 *offset+=1;
975 proto_tree_add_item (scaler_mA_tree, hf_sml_scaler_mA, tvb, *offset, 1, ENC_NA);
976 *offset+=1;
978 /*value_mA*/
979 get_length(tvb, offset, &data, &length);
980 value_mA= proto_tree_add_text (TupelEntry_list, tvb, *offset, length+data, "value_mA");
981 value_mA_tree = proto_item_add_subtree(value_mA, ett_sml_value_mA);
982 proto_tree_add_item (value_mA_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
983 *offset+=1;
984 proto_tree_add_item (value_mA_tree, hf_sml_value_mA, tvb, *offset, data, ENC_NA);
985 *offset+=data;
987 /*unit_R2*/
988 unit_R2= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "unit_R2");
989 unit_R2_tree = proto_item_add_subtree(unit_R2, ett_sml_unit_R2);
990 proto_tree_add_item (unit_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
991 *offset+=1;
992 proto_tree_add_item (unit_R2_tree, hf_sml_unit_R2, tvb, *offset, 1, ENC_NA);
993 *offset+=1;
995 /*scaler_R2*/
996 scaler_R2= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "scaler_R2");
997 scaler_R2_tree = proto_item_add_subtree(scaler_R2, ett_sml_scaler_R2);
998 proto_tree_add_item (scaler_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
999 *offset+=1;
1000 proto_tree_add_item (scaler_R2_tree, hf_sml_scaler_R2, tvb, *offset, 1, ENC_NA);
1001 *offset+=1;
1003 /*value_R2*/
1004 get_length(tvb, offset, &data, &length);
1005 value_R2= proto_tree_add_text (TupelEntry_list, tvb, *offset, length+data, "value_R2");
1006 value_R2_tree = proto_item_add_subtree(value_R2, ett_sml_value_R2);
1007 proto_tree_add_item (value_R2_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1008 *offset+=1;
1009 proto_tree_add_item (value_R2_tree, hf_sml_value_R2, tvb, *offset, data, ENC_NA);
1010 *offset+=data;
1012 /*unit_R3*/
1013 unit_R3= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "unit_R3");
1014 unit_R3_tree = proto_item_add_subtree(unit_R3, ett_sml_unit_R3);
1015 proto_tree_add_item (unit_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1016 *offset+=1;
1017 proto_tree_add_item (unit_R3_tree, hf_sml_unit_R3, tvb, *offset, 1, ENC_NA);
1018 *offset+=1;
1020 /*scaler_R3*/
1021 scaler_R3= proto_tree_add_text (TupelEntry_list, tvb, *offset, 2, "scaler_R3");
1022 scaler_R3_tree = proto_item_add_subtree(scaler_R3, ett_sml_scaler_R3);
1023 proto_tree_add_item (scaler_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1024 *offset+=1;
1025 proto_tree_add_item (scaler_R3_tree, hf_sml_scaler_R3, tvb, *offset, 1, ENC_NA);
1026 *offset+=1;
1028 /*value_R3*/
1029 get_length(tvb, offset, &data, &length);
1030 value_R3= proto_tree_add_text (TupelEntry_list, tvb, *offset, length+data, "value_R3");
1031 value_R3_tree = proto_item_add_subtree(value_R3, ett_sml_value_R3);
1032 proto_tree_add_item (value_R3_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1033 *offset+=1;
1034 proto_tree_add_item (value_R3_tree, hf_sml_value_R3, tvb, *offset, data, ENC_NA);
1035 *offset+=data;
1037 /*signature_mA_R2_R3*/
1038 get_length(tvb, offset, &data, &length);
1039 signature_mA_R2_R3= proto_tree_add_text (TupelEntry_list, tvb, *offset, length+data, "signature_mA_R2_R3");
1040 signature_mA_R2_R3_tree = proto_item_add_subtree(signature_mA_R2_R3, ett_sml_signature_mA_R2_R3);
1041 proto_tree_add_text (signature_mA_R2_R3_tree, tvb, *offset, length, "Length: %d %s", data ,plurality(data, "octet", "octets"));
1042 *offset+=length;
1043 proto_tree_add_item (signature_mA_R2_R3_tree, hf_sml_signature_mA_R2_R3, tvb, *offset, data, ENC_NA);
1044 *offset+=data;
1046 proto_item_set_end(TupelEntry, tvb, *offset);
1049 static void child_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *insert_tree, guint *offset, guint *data, guint *length){
1050 proto_item *parameterName = NULL;
1051 proto_item *procParValue = NULL;
1052 proto_item *child = NULL;
1053 proto_item *procParValuetype = NULL;
1054 proto_item *periodEntry = NULL;
1055 proto_item *SML_time = NULL;
1056 proto_item *procParValueTime = NULL;
1057 proto_item *tree_Entry = NULL;
1059 proto_tree *parameterName_tree = NULL;
1060 proto_tree *procParValue_tree = NULL;
1061 proto_tree *procParValuetype_tree = NULL;
1062 proto_tree *periodEntry_tree = NULL;
1063 proto_tree *SML_time_tree = NULL;
1064 proto_tree *procParValueTime_tree = NULL;
1065 proto_tree *child_list = NULL;
1066 proto_tree *tree_Entry_list = NULL;
1068 guint i = 0;
1069 guint repeat = 0;
1070 guint check = 0;
1072 /*parameterName*/
1073 get_length(tvb, offset, data, length);
1074 parameterName = proto_tree_add_text (insert_tree, tvb, *offset, *length + *data ,"parameterName");
1075 parameterName_tree = proto_item_add_subtree (parameterName, ett_sml_parameterName);
1076 proto_tree_add_text (parameterName_tree, tvb, *offset, *length, "Length: %d %s", *data ,plurality(*data, "octet", "octets"));
1077 *offset+=*length;
1078 proto_tree_add_item (parameterName_tree, hf_sml_parameterName, tvb, *offset, *data, ENC_NA);
1079 *offset+=*data;
1081 /*procParValue OPTIONAL*/
1082 check = tvb_get_guint8(tvb, *offset);
1084 if (check == OPTIONAL){
1085 procParValue = proto_tree_add_item(insert_tree, hf_sml_procParValue, tvb, *offset, 1, ENC_NA);
1086 proto_item_append_text(procParValue, ": NOT SET");
1087 *offset+=1;
1089 else if (check == 0x72){
1090 get_length(tvb, offset, data, length);
1091 procParValue = proto_tree_add_text(insert_tree, tvb, *offset, -1, "ProcParValue");
1092 procParValue_tree = proto_item_add_subtree (procParValue, ett_sml_procParValue);
1093 *offset+=1;
1095 /*procParValue CHOOSE*/
1096 procParValuetype = proto_tree_add_text (procParValue_tree, tvb, *offset, 2, "ProcParValueType");
1097 procParValuetype_tree = proto_item_add_subtree (procParValuetype, ett_sml_procParValuetype);
1098 proto_tree_add_item (procParValuetype_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1099 *offset+=1;
1100 check = tvb_get_guint8(tvb, *offset);
1101 proto_tree_add_item (procParValuetype_tree, hf_sml_procParValue, tvb, *offset, 1 ,ENC_NA);
1102 *offset+=1;
1104 switch (check) {
1105 case PROC_VALUE:
1106 /*value*/
1107 sml_value(tvb, procParValue_tree, offset, data, length);
1108 break;
1110 case PROC_PERIOD:
1111 /*period*/
1112 get_length(tvb, offset, data, length);
1113 periodEntry = proto_tree_add_text(procParValue_tree, tvb, *offset, -1, "PeriodEntry List with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1114 periodEntry_tree = proto_item_add_subtree(periodEntry, ett_sml_periodEntry);
1115 *offset+=*length;
1117 /*objName*/
1118 field_objName(tvb, periodEntry_tree, offset, data, length);
1120 /*unit OPTIONAL*/
1121 field_unit(tvb, periodEntry_tree, offset, data, length);
1123 /*scaler OPTIONAL*/
1124 field_scaler(tvb, periodEntry_tree, offset, data, length);
1126 /*value*/
1127 sml_value(tvb, periodEntry_tree, offset, data, length);
1129 /*value Signature*/
1130 field_valueSignature(tvb, periodEntry_tree, offset, data, length);
1132 proto_item_set_end(periodEntry, tvb, *offset);
1133 break;
1135 case PROC_TUPEL:
1136 /*TupelEntry*/
1137 if (tvb_get_guint8(tvb, *offset) == 0xF1 && tvb_get_guint8(tvb, *offset+1) == 0x07){
1138 TupelEntryTree(tvb, procParValue_tree, offset);
1140 else {
1141 expert_add_info(pinfo, NULL, &ei_sml_tupel_error);
1142 return;
1144 break;
1146 case PROC_TIME:
1147 SML_time = proto_tree_add_text (procParValue_tree, tvb, *offset, -1, "Time");
1148 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1149 *offset+=1;
1151 sml_time_type(tvb, SML_time_tree, offset);
1153 /*Time*/
1154 get_length(tvb, offset, data, length);
1155 procParValueTime = proto_tree_add_text (SML_time_tree, tvb, *offset, *length + *data, "procParValueTime");
1156 procParValueTime_tree = proto_item_add_subtree (procParValueTime, ett_sml_procParValueTime);
1157 proto_tree_add_item (procParValueTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1158 *offset+=1;
1159 proto_tree_add_item(procParValueTime_tree, hf_sml_procParValueTime, tvb, *offset, *data, ENC_BIG_ENDIAN);
1160 *offset+=*data;
1162 proto_item_set_end(SML_time, tvb, *offset);
1163 break;
1165 default:
1166 expert_add_info(pinfo, procParValue, &ei_sml_procParValue_invalid);
1167 break;
1169 proto_item_set_end(procParValue, tvb, *offset);
1171 else {
1172 expert_add_info(pinfo, NULL, &ei_sml_procParValue_errror);
1173 return;
1176 /*child list OPTIONAL*/
1177 check = tvb_get_guint8(tvb, *offset);
1179 if (check == OPTIONAL){
1180 proto_tree_add_text (insert_tree, tvb, *offset, 1, "Child List: NOT SET");
1181 *offset+=1;
1183 else if ((check & 0x0F) != 0){
1184 if (check == 0x71){
1185 get_length(tvb, offset, data, length);
1186 child = proto_tree_add_text(insert_tree, tvb, *offset, -1, "Child List with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1187 child_list = proto_item_add_subtree(child, ett_sml_child);
1188 *offset+=1;
1190 tree_Entry = proto_tree_add_text (child_list, tvb, *offset, -1, "tree_Entry");
1191 tree_Entry_list = proto_item_add_subtree(tree_Entry, ett_sml_tree_Entry);
1192 *offset+=1;
1194 child_tree(tvb, pinfo,tree_Entry_list, offset, data, length);
1196 proto_item_set_end(tree_Entry, tvb, *offset);
1197 proto_item_set_end(child, tvb, *offset);
1199 else if ((check & 0xF0) == SHORT_LIST || (check & 0xF0) == LONG_LIST){
1200 get_length(tvb, offset, data, length);
1201 repeat = *length + *data;
1202 child = proto_tree_add_text(insert_tree, tvb, *offset, -1, "Child List with %d %s", *length + *data, plurality(*length + *data, "element", "elements"));
1203 child_list = proto_item_add_subtree(child, ett_sml_child);
1204 if (repeat <= 0){
1205 expert_add_info_format(pinfo, child, &ei_sml_invalid_count, "invalid loop count");
1206 return;
1208 *offset+=*length;
1210 for(i =0 ; i < repeat; i++){
1211 tree_Entry = proto_tree_add_text (child_list, tvb, *offset, -1, "tree_Entry");
1212 tree_Entry_list = proto_item_add_subtree(tree_Entry, ett_sml_tree_Entry);
1214 if (tvb_get_guint8(tvb, *offset) != 0x73){
1215 expert_add_info_format(pinfo, tree_Entry, &ei_sml_invalid_count, "invalid count of elements in tree_Entry");
1216 return;
1218 *offset+=1;
1220 child_tree(tvb, pinfo, tree_Entry_list, offset, data, length);
1221 proto_item_set_end(tree_Entry, tvb, *offset);
1223 proto_item_set_end(child, tvb, *offset);
1226 else {
1227 expert_add_info_format(pinfo, NULL, &ei_sml_invalid_count, "invalid count of elements in child List");
1231 /*messagetypes*/
1232 static void decode_PublicOpenReq (tvbuff_t *tvb, proto_tree *messagebodytree_list, guint *offset){
1233 guint data = 0;
1234 guint length = 0;
1236 /*Codepage OPTIONAL*/
1237 field_codepage (tvb, messagebodytree_list, offset, &data, &length);
1239 /*clientID*/
1240 field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1242 /*reqFileId*/
1243 field_reqFileId (tvb, messagebodytree_list, offset, &data, &length);
1245 /*ServerID*/
1246 field_serverId(tvb,messagebodytree_list, offset, &data, &length);
1248 /*user*/
1249 field_username(tvb,messagebodytree_list, offset, &data, &length);
1251 /*password*/
1252 field_password(tvb,messagebodytree_list, offset, &data, &length);
1254 /*sml-Version OPTIONAL*/
1255 field_smlVersion(tvb,messagebodytree_list, offset, &data, &length);
1258 static void decode_PublicOpenRes (tvbuff_t *tvb, proto_tree *messagebodytree_list, guint *offset){
1259 proto_item *refTime = NULL;
1260 proto_item *SML_time = NULL;
1262 proto_tree *refTime_tree = NULL;
1263 proto_tree *SML_time_tree = NULL;
1265 guint data = 0;
1266 guint length = 0;
1268 /*Codepage OPTIONAL*/
1269 field_codepage (tvb, messagebodytree_list, offset, &data, &length);
1271 /*clientID OPTIONAL*/
1272 field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1274 /*reqFileId*/
1275 field_reqFileId (tvb, messagebodytree_list, offset, &data, &length);
1277 /*ServerID*/
1278 field_serverId(tvb,messagebodytree_list,offset, &data, &length);
1280 /*RefTime Optional*/
1281 get_length(tvb, offset, &data, &length);
1283 if (data == 0){
1284 proto_tree_add_text (messagebodytree_list, tvb, *offset, length + data, "refTime: NOT SET");
1285 *offset+=1;
1287 else{
1288 /*SML TIME*/
1289 SML_time = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "refTime");
1290 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1291 *offset+=1;
1293 sml_time_type(tvb, SML_time_tree, offset);
1295 /*refTime*/
1296 get_length(tvb, offset, &data, &length);
1297 refTime = proto_tree_add_text (SML_time_tree, tvb, *offset, length+data, "refTime");
1298 refTime_tree = proto_item_add_subtree (refTime, ett_sml_refTime);
1299 proto_tree_add_item (refTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1300 *offset+=1;
1301 proto_tree_add_item(refTime_tree, hf_sml_refTime, tvb, *offset, data, ENC_BIG_ENDIAN);
1302 *offset+=data;
1303 proto_item_set_end(SML_time,tvb,*offset);
1305 /*sml-Version OPTIONAL*/
1306 field_smlVersion(tvb, messagebodytree_list, offset, &data, &length);
1309 static gboolean decode_GetProfile_List_Pack_Req (tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, guint *offset){
1310 proto_item *withRawdata = NULL;
1311 proto_item *SML_time = NULL;
1312 proto_item *beginTime = NULL;
1313 proto_item *treepath = NULL;
1314 proto_item *object_list = NULL;
1315 proto_item *endTime = NULL;
1316 proto_item *dasDetails = NULL;
1318 proto_tree *withRawdata_tree = NULL;
1319 proto_tree *SML_time_tree = NULL;
1320 proto_tree *beginTime_tree = NULL;
1321 proto_tree *treepath_list = NULL;
1322 proto_tree *object_list_list = NULL;
1323 proto_tree *endTime_tree = NULL;
1324 proto_tree *dasDetails_list = NULL;
1326 guint i = 0;
1327 guint repeat = 0;
1328 guint check = 0;
1329 guint data = 0;
1330 guint length = 0;
1332 /*ServerID*/
1333 field_serverId(tvb,messagebodytree_list, offset, &data, &length);
1335 /*user*/
1336 field_username(tvb,messagebodytree_list, offset, &data, &length);
1338 /*password*/
1339 field_password(tvb,messagebodytree_list, offset, &data, &length);
1341 /*withRawdata OPTIONAL*/
1342 get_length(tvb, offset, &data, &length);
1343 withRawdata = proto_tree_add_uint_format (messagebodytree_list, hf_sml_withRawdata, tvb, *offset, data+length, data+length, "withRawdata %s", (data == 0)? ": NOT SET" : "");
1345 if (data > 0) {
1346 withRawdata_tree = proto_item_add_subtree (withRawdata, ett_sml_withRawdata);
1347 proto_tree_add_item (withRawdata_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1348 *offset+=1;
1349 proto_tree_add_item (withRawdata_tree, hf_sml_withRawdata, tvb, *offset, 1, ENC_NA);
1350 *offset+=1;
1352 else
1353 *offset+=1;
1355 /*beginTime OPTIONAL*/
1356 get_length(tvb, offset, &data, &length);
1358 if (data == 0){
1359 proto_tree_add_text (messagebodytree_list, tvb, *offset, length + data, "beginTime: NOT SET");
1360 *offset+=1;
1362 else {
1363 /*SML TIME*/
1364 SML_time = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "beginTime");
1365 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1366 *offset+=1;
1368 sml_time_type(tvb, SML_time_tree, offset);
1370 /*beginTime*/
1371 get_length(tvb, offset, &data, &length);
1372 beginTime = proto_tree_add_text (SML_time_tree, tvb, *offset, length + data, "beginTime");
1373 beginTime_tree = proto_item_add_subtree (beginTime, ett_sml_beginTime);
1374 proto_tree_add_item (beginTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1375 *offset+=1;
1376 proto_tree_add_item(beginTime_tree, hf_sml_beginTime, tvb, *offset, data, ENC_BIG_ENDIAN);
1377 *offset+=data;
1378 proto_item_set_end(SML_time,tvb,*offset);
1381 /*endTime OPTIONAL*/
1382 get_length(tvb, offset, &data, &length);
1384 if (data == 0){
1385 proto_tree_add_text (messagebodytree_list, tvb, *offset, length + data, "endTime: NOT SET");
1386 *offset+=1;
1388 else {
1389 /*SML TIME*/
1390 SML_time = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "endTime");
1391 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1392 *offset+=1;
1394 sml_time_type(tvb, SML_time_tree, offset);
1396 /*endTime*/
1397 get_length(tvb, offset, &data, &length);
1398 endTime = proto_tree_add_text (SML_time_tree, tvb, *offset, length + data, "endTime");
1399 endTime_tree = proto_item_add_subtree (endTime, ett_sml_beginTime);
1400 proto_tree_add_item (endTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1401 *offset+=1;
1402 proto_tree_add_item(endTime_tree, hf_sml_endTime, tvb, *offset, data, ENC_BIG_ENDIAN);
1403 *offset+=data;
1404 proto_item_set_end(SML_time,tvb,*offset);
1407 /*Treepath List*/
1408 get_length(tvb, offset, &data, &length);
1409 repeat = (data+length);
1410 treepath = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1411 treepath_list = proto_item_add_subtree(treepath, ett_sml_treepath);
1413 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1414 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in Treepath");
1415 return TRUE;
1417 else if (repeat <= 0){
1418 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1419 return TRUE;
1421 *offset+=length;
1423 for (i=0; i< repeat; i++) {
1424 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1426 proto_item_set_end(treepath, tvb, *offset);
1428 /*object_list*/
1429 if (tvb_get_guint8(tvb,*offset) == OPTIONAL){
1430 proto_tree_add_text (messagebodytree_list, tvb, *offset, 1, "object_List: NOT SET");
1431 *offset+=1;
1433 else{
1434 get_length(tvb, offset, &data, &length);
1435 repeat = (data+length);
1436 object_list = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "object_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1437 object_list_list = proto_item_add_subtree(object_list, ett_sml_object_list);
1439 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1440 expert_add_info_format(pinfo, object_list, &ei_sml_invalid_count, "invalid count of elements in object_List");
1441 return TRUE;
1443 else if (repeat <= 0){
1444 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1445 return TRUE;
1448 *offset+=length;
1450 for (i=0; i< repeat; i++) {
1451 field_ObjReqEntry(tvb, object_list_list, offset, &data, &length);
1453 proto_item_set_end(object_list, tvb, *offset);
1456 /*dasDetails*/
1457 check = tvb_get_guint8(tvb,*offset);
1459 if (check == OPTIONAL){
1460 proto_tree_add_text (messagebodytree_list, tvb, *offset, 1, "dasDetails: NOT SET");
1461 *offset+=1;
1463 else if ((check & 0xF0) == LONG_LIST || (check & 0xF0) == SHORT_LIST){
1464 get_length(tvb, offset, &data, &length);
1465 dasDetails = proto_tree_add_text(messagebodytree_list, tvb, *offset, -1, "dasDetails with %d %s", length+data, plurality(length+data, "element", "elements"));
1466 dasDetails_list = proto_item_add_subtree(dasDetails, ett_sml_dasDetails);
1467 *offset+=length;
1469 child_tree(tvb, pinfo, dasDetails_list, offset, &data, &length);
1470 proto_item_set_end(dasDetails, tvb, *offset);
1472 else {
1473 expert_add_info_format(pinfo, NULL, &ei_sml_invalid_count, "invalid count of elements in dasDetails");
1474 return TRUE;
1476 return FALSE;
1479 static gboolean decode_GetProfilePackRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, guint *offset){
1480 proto_item *SML_time = NULL;
1481 proto_item *treepath = NULL;
1482 proto_item *periodList = NULL;
1483 proto_item *period_List_Entry = NULL;
1484 proto_item *headerList = NULL;
1485 proto_item *header_List_Entry = NULL;
1486 proto_item *profileSignature = NULL;
1487 proto_item *valuelist = NULL;
1488 proto_item *value_List_Entry = NULL;
1490 proto_tree *SML_time_tree = NULL;
1491 proto_tree *treepath_list = NULL;
1492 proto_tree *periodList_list = NULL;
1493 proto_tree *period_List_Entry_list = NULL;
1494 proto_tree *headerList_subtree = NULL;
1495 proto_tree *header_List_Entry_list = NULL;
1496 proto_tree *profileSignature_tree = NULL;
1497 proto_tree *valuelist_list = NULL;
1498 proto_tree *value_List_Entry_list = NULL;
1500 guint i = 0;
1501 guint d = 0;
1502 guint repeat = 0;
1503 guint repeat2= 0;
1504 guint data = 0;
1505 guint length = 0;
1507 /*ServerID*/
1508 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
1510 /*actTime*/
1511 get_length(tvb, offset, &data, &length);
1512 SML_time = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "actTime List with %d %s", length+data, plurality(length+data, "element", "elements"));
1513 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1514 *offset+=1;
1515 sml_time_type(tvb, SML_time_tree, offset);
1516 field_actTime(tvb, SML_time_tree, offset, &data, &length);
1517 proto_item_set_end(SML_time,tvb,*offset);
1519 /*regPeriod*/
1520 field_regPeriod(tvb, messagebodytree_list, offset, &data, &length);
1522 /*Treepath List*/
1523 get_length(tvb, offset, &data, &length);
1524 repeat = (data+length);
1525 treepath = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1526 treepath_list = proto_item_add_subtree(treepath, ett_sml_treepath);
1528 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1529 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in Treepath");
1530 return TRUE;
1532 else if (repeat <= 0){
1533 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1534 return TRUE;
1537 *offset+=length;
1539 for (i=0; i< repeat; i++) {
1540 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1542 proto_item_set_end(treepath, tvb, *offset);
1544 /*headerList*/
1545 get_length(tvb, offset, &data, &length);
1546 repeat = (data+length);
1547 headerList = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "header_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1548 headerList_subtree = proto_item_add_subtree(headerList, ett_sml_headerList);
1550 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1551 expert_add_info_format(pinfo, headerList, &ei_sml_invalid_count, "invalid count of elements in headerlist");
1552 return TRUE;
1554 else if (repeat <= 0){
1555 expert_add_info_format(pinfo, headerList, &ei_sml_invalid_count, "invalid loop count");
1556 return TRUE;
1559 *offset+=length;
1561 for (i=0; i< repeat; i++) {
1562 get_length(tvb, offset, &data, &length);
1563 header_List_Entry = proto_tree_add_text (headerList_subtree, tvb, *offset, -1, "header_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1564 header_List_Entry_list = proto_item_add_subtree(header_List_Entry, ett_sml_header_List_Entry);
1565 *offset+=1;
1567 /*objname*/
1568 field_objName(tvb, header_List_Entry_list, offset, &data, &length);
1570 /*unit*/
1571 field_unit(tvb, header_List_Entry_list, offset, &data, &length);
1573 /*scaler*/
1574 field_scaler(tvb, header_List_Entry_list, offset, &data, &length);
1576 proto_item_set_end(header_List_Entry, tvb, *offset);
1578 proto_item_set_end(headerList, tvb, *offset);
1580 /*period List*/
1581 get_length(tvb, offset, &data, &length);
1582 repeat = (data+length);
1583 periodList = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "period_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1584 periodList_list = proto_item_add_subtree(periodList, ett_sml_periodList);
1586 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1587 expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid count of elements in periodList");
1588 return TRUE;
1590 else if (repeat <= 0){
1591 expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid loop count");
1592 return TRUE;
1595 *offset+=length;
1597 for (i=0; i< repeat; i++) {
1598 get_length(tvb, offset, &data, &length);
1599 period_List_Entry = proto_tree_add_text (periodList_list, tvb, *offset, -1, "period_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1600 period_List_Entry_list = proto_item_add_subtree(period_List_Entry, ett_sml_period_List_Entry);
1601 *offset+=1;
1603 /*valTime*/
1604 get_length(tvb, offset, &data, &length);
1605 SML_time = proto_tree_add_text (period_List_Entry, tvb, *offset, -1, "valTime");
1606 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1607 *offset+=1;
1608 sml_time_type(tvb, SML_time_tree, offset);
1609 field_valTime(tvb, SML_time_tree, offset, &data, &length);
1610 proto_item_set_end(SML_time,tvb, *offset);
1612 /*status*/
1613 field_status(tvb, period_List_Entry_list, offset, &data, &length);
1615 /*value List*/
1616 get_length(tvb, offset, &data, &length);
1617 repeat2 = data + length;
1618 valuelist = proto_tree_add_text (period_List_Entry_list, tvb, *offset, -1, "period_List with %d %s", length+data, plurality(length+data, "element", "elements"));
1619 valuelist_list = proto_item_add_subtree(valuelist, ett_sml_valuelist);
1621 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1622 expert_add_info_format(pinfo, valuelist, &ei_sml_invalid_count, "invalid count of elements in valueList");
1623 return TRUE;
1625 else if (repeat2 <= 0){
1626 expert_add_info_format(pinfo, valuelist, &ei_sml_invalid_count, "invalid loop count");
1627 return TRUE;
1630 *offset+=length;
1632 for (d=0; d< repeat2; d++) {
1633 get_length(tvb, offset, &data, &length);
1634 value_List_Entry = proto_tree_add_text (valuelist_list, tvb, *offset, -1, "value_List_Entry with %d %s", length+data, plurality(length+data, "element", "elements"));
1635 value_List_Entry_list = proto_item_add_subtree(value_List_Entry, ett_sml_value_List_Entry);
1636 *offset+=1;
1638 /*value*/
1639 sml_value(tvb, value_List_Entry_list, offset, &data, &length);
1641 /*value Signature*/
1642 field_valueSignature(tvb, value_List_Entry_list, offset, &data, &length);
1644 proto_item_set_end(value_List_Entry, tvb, *offset);
1646 proto_item_set_end(valuelist, tvb, *offset);
1648 /*period Signature*/
1649 field_periodSignature(tvb, period_List_Entry_list, offset, &data, &length);
1651 proto_item_set_end(period_List_Entry, tvb, *offset);
1653 proto_item_set_end(periodList,tvb, *offset);
1655 /*rawdata*/
1656 field_rawdata(tvb, messagebodytree_list, offset, &data, &length);
1658 /*profile Signature*/
1659 get_length(tvb, offset, &data, &length);
1660 profileSignature = proto_tree_add_bytes_format (messagebodytree_list, hf_sml_profileSignature, tvb, *offset, length+data, NULL, "profileSignature %s", (data == 0)? ": NOT SET" : "");
1662 if (data > 0){
1663 profileSignature_tree = proto_item_add_subtree (profileSignature, ett_sml_profileSignature);
1664 proto_tree_add_text (profileSignature_tree, tvb, *offset, length, "Length: %d %s", data, plurality(data, "octet", "octets"));
1665 *offset+=length;
1666 proto_tree_add_item (profileSignature_tree, hf_sml_profileSignature, tvb, *offset, data, ENC_NA);
1667 *offset+=data;
1669 else
1670 *offset+=1;
1672 return FALSE;
1675 static gboolean decode_GetProfileListRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, guint *offset){
1676 proto_item *SML_time = NULL;
1677 proto_item *treepath = NULL;
1678 proto_item *periodList = NULL;
1679 proto_item *periodList_Entry = NULL;
1681 proto_tree *SML_time_tree = NULL;
1682 proto_tree *treepath_list = NULL;
1683 proto_tree *periodList_list = NULL;
1684 proto_tree *periodList_Entry_list = NULL;
1686 guint i = 0;
1687 guint repeat = 0;
1688 guint data = 0;
1689 guint length = 0;
1691 /*ServerID*/
1692 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
1694 /*actTime*/
1695 get_length(tvb, offset, &data, &length);
1696 SML_time = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "actTime");
1697 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1698 *offset+=1;
1699 sml_time_type(tvb, SML_time_tree, offset);
1700 field_actTime(tvb, SML_time_tree, offset, &data, &length);
1701 proto_item_set_end(SML_time,tvb, *offset);
1703 /*regPeriod*/
1704 field_regPeriod(tvb, messagebodytree_list, offset, &data, &length);
1706 /*Treepath List*/
1707 get_length(tvb, offset, &data, &length);
1708 repeat = (data+length);
1709 treepath = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
1710 treepath_list = proto_item_add_subtree(treepath, ett_sml_treepath);
1712 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1713 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in parameterTreePath");
1714 return TRUE;
1716 else if (repeat <= 0){
1717 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
1718 return TRUE;
1721 *offset+=length;
1723 for (i=0; i< repeat; i++) {
1724 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
1726 proto_item_set_end(treepath, tvb,*offset);
1728 /*valTime Optional*/
1729 get_length(tvb, offset, &data, &length);
1731 if (data == 0){
1732 proto_tree_add_text (messagebodytree_list, tvb, *offset, length + data, "valTime: NOT SET");
1733 *offset+=1;
1735 else {
1736 /*SML TIME*/
1737 SML_time = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "valTime");
1738 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1739 *offset+=1;
1741 sml_time_type(tvb, SML_time_tree, offset);
1742 field_valTime(tvb, SML_time_tree, offset, &data, &length);
1743 proto_item_set_end(SML_time,tvb,*offset);
1746 /*Status*/
1747 field_status(tvb, messagebodytree_list, offset, &data, &length);
1749 /*period-List*/
1750 get_length(tvb, offset, &data, &length);
1751 repeat = (data+length);
1752 periodList = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "period-List with %d %s", length+data, plurality(length+data, "element", "elements"));
1753 periodList_list = proto_item_add_subtree(periodList, ett_sml_periodList);
1755 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1756 expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid count of elements in periodList");
1757 return TRUE;
1759 else if (repeat <= 0){
1760 expert_add_info_format(pinfo, periodList, &ei_sml_invalid_count, "invalid loop count");
1761 return TRUE;
1764 *offset+=length;
1766 for (i=0; i< repeat; i++) {
1767 get_length(tvb, offset, &data, &length);
1768 periodList_Entry = proto_tree_add_text (periodList_list, tvb, *offset, -1, "PeriodEntry");
1769 periodList_Entry_list = proto_item_add_subtree(periodList_Entry, ett_sml_period_List_Entry);
1770 *offset+=1;
1772 /*ObjName*/
1773 field_objName(tvb, periodList_Entry_list, offset, &data, &length);
1775 /*Unit*/
1776 field_unit(tvb, periodList_Entry_list, offset, &data, &length);
1778 /*scaler*/
1779 field_scaler(tvb, periodList_Entry_list, offset, &data, &length);
1781 /*value*/
1782 sml_value(tvb, periodList_Entry_list, offset, &data, &length);
1784 /*value*/
1785 field_valueSignature(tvb, periodList_Entry_list, offset, &data, &length);
1787 proto_item_set_end(periodList_Entry, tvb, *offset);
1789 proto_item_set_end(periodList, tvb, *offset);
1791 /*rawdata*/
1792 field_rawdata(tvb, messagebodytree_list, offset, &data, &length);
1794 /*period Signature*/
1795 field_periodSignature(tvb, messagebodytree_list, offset, &data, &length);
1797 return FALSE;
1800 static void decode_GetListReq (tvbuff_t *tvb, proto_tree *messagebodytree_list, guint *offset){
1801 guint data = 0;
1802 guint length = 0;
1804 /*clientID*/
1805 field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1807 /*ServerID*/
1808 field_serverId(tvb,messagebodytree_list,offset, &data, &length);
1810 /*user*/
1811 field_username(tvb,messagebodytree_list,offset, &data, &length);
1813 /*password*/
1814 field_password(tvb,messagebodytree_list,offset, &data, &length);
1816 /*listName*/
1817 field_listName(tvb,messagebodytree_list,offset, &data, &length);
1820 static gboolean decode_GetListRes (tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, guint *offset){
1821 proto_item *actSensorTime = NULL;
1822 proto_item *valList = NULL;
1823 proto_item *listSignature = NULL;
1824 proto_item *valtree = NULL;
1825 proto_item *actGatewayTime = NULL;
1826 proto_item *SML_time;
1828 proto_tree *actSensorTime_tree = NULL;
1829 proto_tree *valList_list = NULL;
1830 proto_tree *listSignature_tree = NULL;
1831 proto_tree *valtree_list = NULL;
1832 proto_tree *actGatewayTime_tree = NULL;
1833 proto_tree *SML_time_tree = NULL;
1835 guint repeat = 0;
1836 guint i = 0;
1837 guint data = 0;
1838 guint length = 0;
1840 /*clientID OPTIONAL*/
1841 field_clientId (tvb, messagebodytree_list, offset, &data, &length);
1843 /*ServerID*/
1844 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
1846 /*listName*/
1847 field_listName(tvb, messagebodytree_list, offset, &data, &length);
1849 /*actSensorTime OPTIONAL*/
1850 get_length(tvb, offset, &data, &length);
1852 if (data == 0){
1853 proto_tree_add_text (messagebodytree_list, tvb, *offset, length + data, "actSensorTime: NOT SET");
1854 *offset+=1;
1856 else {
1857 /*SML TIME*/
1858 SML_time = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "actSensorTime");
1859 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1860 *offset+=1;
1862 sml_time_type(tvb, SML_time_tree, offset);
1864 /*actSensorTime*/
1865 get_length(tvb, offset, &data, &length);
1866 actSensorTime = proto_tree_add_text (SML_time_tree, tvb, *offset, length + data, "actSensorTime");
1867 actSensorTime_tree = proto_item_add_subtree (actSensorTime, ett_sml_actSensorTime);
1868 proto_tree_add_item (actSensorTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1869 *offset+=1;
1870 proto_tree_add_item(actSensorTime_tree, hf_sml_actSensorTime, tvb, *offset, data, ENC_BIG_ENDIAN);
1871 *offset+=data;
1872 proto_item_set_end(SML_time,tvb,*offset);
1875 /*valList*/
1876 get_length(tvb, offset, &data, &length);
1877 repeat = (length + data);
1878 valtree = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "valList with %d %s", length+data, plurality(length+data, "element", "elements"));
1879 valtree_list = proto_item_add_subtree (valtree, ett_sml_valtree);
1881 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
1882 expert_add_info_format(pinfo, valtree, &ei_sml_invalid_count, "invalid count of elements in valList");
1883 return TRUE;
1885 else if (repeat <= 0){
1886 expert_add_info_format(pinfo, valtree, &ei_sml_invalid_count, "invalid loop count");
1887 return TRUE;
1890 *offset+=length;
1892 for (i=0; i < repeat; i++){
1893 get_length(tvb, offset, &data, &length);
1894 valList = proto_tree_add_text (valtree_list, tvb, *offset, -1, "valListEntry");
1895 valList_list = proto_item_add_subtree (valList, ett_sml_valList);
1896 *offset+=length;
1898 /*objName*/
1899 field_objName(tvb, valList_list, offset, &data, &length);
1901 /*Sml Status OPTIONAL*/
1902 field_status(tvb, valList_list, offset, &data, &length);
1904 /*valTime OPTIONAL*/
1905 get_length(tvb, offset, &data, &length);
1907 if (data == 0){
1908 proto_tree_add_text (valList_list, tvb, *offset, length + data, "valTime: NOT SET");
1909 *offset+=1;
1911 else {
1912 /*SML TIME*/
1913 SML_time = proto_tree_add_text (valList_list, tvb, *offset, -1, "valTime");
1914 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1915 *offset+=1;
1917 sml_time_type(tvb, SML_time_tree, offset);
1918 field_valTime(tvb, SML_time_tree, offset, &data, &length);
1919 proto_item_set_end(SML_time, tvb, *offset);
1922 /*unit OPTIONAL*/
1923 field_unit(tvb, valList_list, offset, &data, &length);
1925 /*Scaler OPTIONAL*/
1926 field_scaler(tvb, valList_list, offset, &data, &length);
1928 /*value*/
1929 sml_value(tvb, valList_list, offset, &data, &length);
1931 /*value Signature*/
1932 field_valueSignature(tvb, valList_list, offset, &data, &length);
1934 proto_item_set_end(valList, tvb, *offset);
1936 proto_item_set_end(valtree, tvb, *offset);
1938 /*List Signature OPTIONAL*/
1939 get_length(tvb, offset, &data, &length);
1940 listSignature = proto_tree_add_bytes_format (messagebodytree_list, hf_sml_listSignature, tvb, *offset, length+data, NULL, "ListSignature %s", (data == 0)? ": NOT SET" : "");
1942 if (data > 0){
1943 listSignature_tree = proto_item_add_subtree (listSignature, ett_sml_listSignature);
1944 proto_tree_add_text (listSignature_tree, tvb, *offset, length, "Length: %d %s", data, plurality(data, "byte", "bytes"));
1945 *offset+=length;
1946 proto_tree_add_item (listSignature_tree, hf_sml_listSignature, tvb, *offset, data, ENC_NA);
1947 *offset+=data;
1949 else
1950 *offset+=1;
1952 /*actGatewayTime OPTIONAL*/
1953 get_length(tvb, offset, &data, &length);
1955 if (data == 0){
1956 proto_tree_add_text (messagebodytree_list, tvb, *offset, length + data, "actGatewayTime: NOT SET");
1957 *offset+=1;
1959 else{
1960 /*SML TIME*/
1961 SML_time = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "actGatewayTime");
1962 SML_time_tree = proto_item_add_subtree (SML_time, ett_sml_time);
1963 *offset+=1;
1965 sml_time_type(tvb, SML_time_tree, offset);
1967 get_length(tvb, offset, &data, &length);
1968 actGatewayTime = proto_tree_add_text (SML_time_tree, tvb, *offset, length + data, "actGatewayTime");
1969 actGatewayTime_tree = proto_item_add_subtree (actGatewayTime, ett_sml_actSensorTime);
1970 proto_tree_add_item (actGatewayTime_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
1971 *offset+=1;
1972 proto_tree_add_item(actGatewayTime_tree, hf_sml_actGatewayTime, tvb, *offset, data, ENC_BIG_ENDIAN);
1973 *offset+=data;
1974 proto_item_set_end(SML_time,tvb,*offset);
1976 return FALSE;
1979 static gboolean decode_GetProcParameterReq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, guint *offset){
1980 proto_item *treepath = NULL;
1981 proto_item *attribute = NULL;
1983 proto_tree *treepath_list = NULL;
1984 proto_tree *attribute_tree = NULL;
1986 guint i = 0;
1987 guint repeat = 0;
1988 guint data = 0;
1989 guint length = 0;
1991 /*ServerID*/
1992 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
1994 /*user*/
1995 field_username(tvb, messagebodytree_list, offset, &data, &length);
1997 /*password*/
1998 field_password(tvb, messagebodytree_list, offset, &data, &length);
2000 /*Treepath List*/
2001 get_length(tvb, offset, &data, &length);
2002 repeat = data+length;
2003 treepath = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "ParameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2004 treepath_list = proto_item_add_subtree(treepath, ett_sml_treepath);
2006 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2007 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2008 return TRUE;
2010 else if (repeat <= 0){
2011 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2012 return TRUE;
2015 *offset+=length;
2017 for (i=0; i< repeat; i++) {
2018 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2020 proto_item_set_end(treepath, tvb, *offset);
2022 /*attribute*/
2023 get_length(tvb, offset, &data, &length);
2024 attribute = proto_tree_add_bytes_format (messagebodytree_list,hf_sml_attribute, tvb, *offset, length+data, NULL, "attribute %s", (data == 0)? ": NOT SET" : "");
2026 if (data > 0) {
2027 attribute_tree = proto_item_add_subtree (attribute, ett_sml_attribute);
2028 proto_tree_add_text (attribute_tree, tvb, *offset, length, "Length: %d %s", data, plurality(data, "octet", "octets"));
2029 *offset+=length;
2030 proto_tree_add_item (attribute_tree, hf_sml_attribute, tvb, *offset, data, ENC_NA);
2031 *offset+=data;
2033 else
2034 *offset+=1;
2036 return FALSE;
2039 static gboolean decode_GetProcParameterRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, guint *offset){
2040 proto_item *treepath = NULL;
2041 proto_item *parameterTree =NULL;
2043 proto_tree *treepath_list = NULL;
2044 proto_tree *parameterTree_list = NULL;
2046 guint i = 0;
2047 guint repeat = 0;
2048 guint data = 0;
2049 guint length = 0;
2051 /*ServerID*/
2052 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2054 /*Treepath List*/
2055 get_length(tvb, offset, &data, &length);
2056 repeat = (data+length);
2057 treepath = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2058 treepath_list = proto_item_add_subtree(treepath, ett_sml_treepath);
2060 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2061 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2062 return TRUE;
2064 else if (repeat <= 0){
2065 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2066 return TRUE;
2069 *offset+=length;
2071 for (i=0; i< repeat; i++) {
2072 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2074 proto_item_set_end(treepath, tvb, *offset);
2076 /*parameterTree*/
2077 get_length(tvb, offset, &data, &length);
2078 parameterTree = proto_tree_add_text(messagebodytree_list, tvb, *offset, -1, "parameterTree with %d %s", length+data, plurality(length+data, "element", "elements"));
2079 parameterTree_list = proto_item_add_subtree(parameterTree, ett_sml_parameterTree);
2081 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2082 expert_add_info_format(pinfo, parameterTree, &ei_sml_invalid_count, "invalid count of elements in parameterTree");
2083 return TRUE;
2086 *offset+=length;
2088 child_tree(tvb, pinfo,parameterTree_list, offset, &data, &length);
2089 proto_item_set_end(parameterTree, tvb, *offset);
2091 return FALSE;
2094 static gboolean decode_SetProcParameterReq(tvbuff_t *tvb, packet_info *pinfo,proto_tree *messagebodytree_list, guint *offset){
2095 proto_item *treepath = NULL;
2096 proto_item *parameterTree = NULL;
2098 proto_tree *treepath_list = NULL;
2099 proto_tree *parameterTree_list = NULL;
2101 guint i = 0;
2102 guint repeat = 0;
2103 guint data = 0;
2104 guint length = 0;
2106 /*ServerID*/
2107 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2109 /*user*/
2110 field_username(tvb, messagebodytree_list, offset, &data, &length);
2112 /*password*/
2113 field_password(tvb, messagebodytree_list, offset, &data, &length);
2115 /*Treepath List*/
2116 get_length(tvb, offset, &data, &length);
2117 repeat = (data+length);
2118 treepath = proto_tree_add_text (messagebodytree_list, tvb, *offset, -1, "parameterTreePath with %d %s", length+data, plurality(length+data, "element", "elements"));
2119 treepath_list = proto_item_add_subtree(treepath, ett_sml_treepath);
2121 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2122 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid count of elements in ParameterTreePath");
2123 return TRUE;
2125 else if (repeat <= 0){
2126 expert_add_info_format(pinfo, treepath, &ei_sml_invalid_count, "invalid loop count");
2127 return TRUE;
2130 *offset+=length;
2132 for (i=0; i< repeat; i++) {
2133 field_parameterTreePath(tvb, treepath_list, offset, &data, &length);
2135 proto_item_set_end(treepath, tvb, *offset);
2137 /*parameterTree*/
2138 get_length(tvb, offset, &data, &length);
2139 parameterTree = proto_tree_add_text(messagebodytree_list, tvb, *offset, -1, "parameterTree with %d %s", length+data, plurality(length+data, "element", "elements"));
2140 parameterTree_list = proto_item_add_subtree(parameterTree, ett_sml_parameterTree);
2142 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2143 expert_add_info_format(pinfo, parameterTree, &ei_sml_invalid_count, "invalid count of elements in parameterTree");
2144 return TRUE;
2147 *offset+=length;
2149 child_tree(tvb, pinfo,parameterTree_list, offset, &data, &length);
2150 proto_item_set_end(parameterTree, tvb, *offset);
2152 return FALSE;
2155 static gboolean decode_AttentionRes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *messagebodytree_list, guint *offset){
2156 proto_item *attentionNo = NULL;
2157 proto_item *attentionMsg = NULL;
2158 proto_item *attentionDetails = NULL;
2160 proto_tree *attentionNo_tree = NULL;
2161 proto_tree *attentionMsg_tree = NULL;
2162 proto_tree *attentionDetails_list = NULL;
2164 guint data = 0;
2165 guint length = 0;
2167 /*ServerID*/
2168 field_serverId(tvb, messagebodytree_list, offset, &data, &length);
2170 /*attention NO*/
2171 get_length(tvb, offset, &data, &length);
2172 attentionNo = proto_tree_add_text (messagebodytree_list, tvb ,*offset, length+data, "attentionNo");
2173 attentionNo_tree = proto_item_add_subtree (attentionNo, ett_sml_attentionNo);
2174 proto_tree_add_text (attentionNo_tree, tvb, *offset, length, "Length: %d %s", data ,plurality(data, "octet", "octets"));
2175 *offset+=length;
2177 if (data == 6){
2178 *offset+=4;
2179 proto_tree_add_item (attentionNo_tree, hf_sml_attentionNo, tvb, *offset, 2, ENC_BIG_ENDIAN);
2180 *offset+=2;
2182 else {
2183 proto_tree_add_text (attentionNo_tree, tvb ,*offset, data, "unknown attentionNo");
2184 *offset+=data;
2187 /*attention Msg*/
2188 get_length(tvb, offset, &data, &length);
2189 attentionMsg = proto_tree_add_string_format (messagebodytree_list, hf_sml_attentionMsg, tvb, *offset, length+data, NULL, "attentionMsg %s", (data == 0)? ": NOT SET" : "");
2191 if (data > 0){
2192 attentionMsg_tree = proto_item_add_subtree (attentionMsg, ett_sml_attentionMsg);
2193 proto_tree_add_text (attentionMsg_tree, tvb, *offset, length, "Length: %d %s", data, plurality(data, "octet", "octets"));
2194 *offset+=length;
2195 proto_tree_add_item (attentionMsg_tree, hf_sml_attentionMsg, tvb, *offset, data, ENC_ASCII | ENC_BIG_ENDIAN);
2196 *offset+=data;
2198 else
2199 *offset+=1;
2201 /*attentiondetails*/
2202 if (tvb_get_guint8(tvb,*offset) == OPTIONAL){
2203 proto_tree_add_text (messagebodytree_list, tvb, *offset, 1, "attentionDetails: NOT SET");
2204 *offset+=1;
2206 else{
2207 get_length(tvb, offset, &data, &length);
2208 attentionDetails = proto_tree_add_text(messagebodytree_list, tvb, *offset, -1, "attentionDetails with %d %s", length+data, plurality(length+data, "element", "elements"));
2209 attentionDetails_list = proto_item_add_subtree(attentionDetails, ett_sml_attentionDetails);
2211 if ((tvb_get_guint8(tvb,*offset) & 0xF0) != LONG_LIST && (tvb_get_guint8(tvb,*offset) & 0xF0) != SHORT_LIST){
2212 expert_add_info_format(pinfo, attentionDetails, &ei_sml_invalid_count, "invalid count of elements in attentionDetails");
2213 return TRUE;
2216 *offset+=length;
2218 child_tree(tvb, pinfo,attentionDetails_list, offset, &data, &length);
2219 proto_item_set_end(attentionDetails, tvb, *offset);
2222 return FALSE;
2225 /*dissect SML-File*/
2226 static void dissect_sml_file(tvbuff_t *tvb, packet_info *pinfo, gint *offset, proto_tree *sml_tree){
2227 proto_item *file = NULL;
2228 proto_item *mainlist = NULL;
2229 proto_item *trans = NULL;
2230 proto_item *groupNo = NULL;
2231 proto_item *abortOnError = NULL;
2232 proto_item *sublist = NULL;
2233 proto_item *messagebody = NULL;
2234 proto_item *crc16 = NULL;
2235 proto_item *messagebodytree = NULL;
2236 proto_item *msgend = NULL;
2238 proto_tree *mainlist_list = NULL;
2239 proto_tree *trans_tree = NULL;
2240 proto_tree *groupNo_tree = NULL;
2241 proto_tree *abortOnError_tree = NULL;
2242 proto_tree *sublist_list = NULL;
2243 proto_tree *messagebody_tree = NULL;
2244 proto_tree *crc16_tree = NULL;
2245 proto_tree *messagebodytree_list = NULL;
2246 proto_tree *msgend_tree = NULL;
2248 guint16 messagebody_switch = 0;
2249 guint16 crc_check = 0;
2250 guint16 crc_ref = 0;
2251 guint check = 0;
2253 guint available = 0;
2254 guint crc_msg_len = 0;
2255 guint crc_file_len = 0;
2256 guint data = 0;
2257 guint length = 0;
2259 gboolean msg_error = FALSE;
2260 gboolean close1 = FALSE;
2261 gboolean close2 = FALSE;
2262 gint end_offset = 0;
2264 guint start_offset;
2265 start_offset = *offset;
2267 end_offset = tvb_reported_length_remaining(tvb, *offset);
2268 if (end_offset <= 0){
2269 return;
2272 if (tvb_get_ntoh40(tvb, end_offset-8) != ESC_SEQ_END && pinfo->can_desegment){
2273 if (tvb_get_guint8(tvb, end_offset-1) != 0){
2274 pinfo->desegment_offset = start_offset;
2275 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2276 return;
2278 else if (tvb_get_guint8(tvb, end_offset-4) != UNSIGNED16 && tvb_get_guint8(tvb, end_offset-3) != UNSIGNED8){
2279 pinfo->desegment_offset = start_offset;
2280 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2281 return;
2284 else if (!pinfo->can_desegment){
2285 expert_add_info(pinfo, NULL, &ei_sml_segment_needed);
2288 while(!close1 && !close2){
2289 if (sml_reassemble){
2290 file = proto_tree_add_text(sml_tree,tvb, *offset, -1 , "----SML-File----");
2293 /*check if escape*/
2294 if (tvb_get_ntohl(tvb, *offset) == ESC_SEQ){
2295 crc_file_len = *offset;
2296 /*Escape Start*/
2297 proto_tree_add_item (sml_tree, hf_sml_esc, tvb, *offset, 4, ENC_BIG_ENDIAN);
2298 *offset+=4;
2300 /*Version*/
2301 if (tvb_get_guint8(tvb, *offset) == 0x01){
2302 proto_tree_add_item (sml_tree, hf_sml_version_1, tvb, *offset, 4, ENC_BIG_ENDIAN);
2303 *offset+=4;
2305 else{
2306 proto_tree_add_text (sml_tree, tvb, *offset, -1, "SML Version 2 not supported");
2307 return;
2311 while (!close1){
2312 crc_msg_len = *offset;
2314 /*List*/
2315 get_length(tvb, offset, &data, &length);
2316 mainlist = proto_tree_add_text (sml_tree, tvb, *offset, -1, "List with %d %s", length+data, plurality(length+data, "element", "elements"));
2318 mainlist_list = proto_item_add_subtree (mainlist, ett_sml_mainlist);
2319 if (tvb_get_guint8(tvb, *offset) != LIST_6_ELEMENTS) {
2320 expert_add_info_format(pinfo, mainlist, &ei_sml_invalid_count, "invalid count of elements");
2321 return;
2323 *offset+=1;
2325 /*Transaction ID*/
2326 get_length(tvb, offset, &data, &length);
2327 trans = proto_tree_add_text (mainlist_list, tvb, *offset, length + data ,"Transaction ID");
2328 trans_tree = proto_item_add_subtree (trans, ett_sml_trans);
2329 proto_tree_add_text (trans_tree, tvb, *offset, length, "Length: %d %s", data, plurality(data, "octet", "octets"));
2330 *offset+=length;
2331 proto_tree_add_item (trans_tree, hf_sml_transactionId, tvb, *offset, data, ENC_NA);
2332 *offset+=data;
2334 /*Group No*/
2335 groupNo = proto_tree_add_text (mainlist_list, tvb, *offset, 2, "Group No");
2336 groupNo_tree = proto_item_add_subtree (groupNo, ett_sml_group);
2337 proto_tree_add_item (groupNo_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
2338 *offset+=1;
2339 proto_tree_add_item (groupNo_tree, hf_sml_groupNo, tvb, *offset, 1, ENC_NA);
2340 *offset+=1;
2342 /*abort on Error*/
2343 abortOnError = proto_tree_add_text (mainlist_list, tvb, *offset, 2, "Abort on Error");
2344 abortOnError_tree = proto_item_add_subtree (abortOnError ,ett_sml_abort);
2345 proto_tree_add_item(abortOnError_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
2346 *offset+=1;
2347 proto_tree_add_item(abortOnError_tree, hf_sml_abortOnError, tvb, *offset, 1, ENC_NA);
2348 *offset+=1;
2350 /*Sub List*/
2351 sublist = proto_tree_add_text (mainlist_list, tvb, *offset, -1, "MessageBody");
2352 sublist_list = proto_item_add_subtree (sublist, ett_sml_sublist);
2353 *offset+=1;
2355 /*Zero Cutting Check*/
2356 get_length(tvb, offset, &data, &length);
2357 messagebody = proto_tree_add_text (sublist_list, tvb, *offset, length + data, "Messagetype");
2358 messagebody_tree = proto_item_add_subtree (messagebody , ett_sml_mttree);
2359 proto_tree_add_item (messagebody_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
2360 *offset+=1;
2362 if (data == 4){
2363 *offset+=2;
2365 else if (data !=2){
2366 expert_add_info(pinfo, messagebody, &ei_sml_messagetype_unknown);
2367 return;
2370 messagebody_switch = tvb_get_ntohs(tvb, *offset);
2371 proto_tree_add_item (messagebody_tree, hf_sml_MessageBody, tvb, *offset, 2, ENC_BIG_ENDIAN);
2372 *offset+=2;
2374 /*MessageBody List*/
2375 get_length(tvb, offset, &data, &length);
2376 messagebodytree = proto_tree_add_text (sublist_list, tvb, *offset, -1, "List with %d %s", length+data, plurality(length+data, "element", "elements"));
2377 messagebodytree_list = proto_item_add_subtree (messagebodytree, ett_sml_mblist);
2378 *offset+=length;
2380 switch (messagebody_switch){
2381 case OPEN_REQ:
2382 col_append_str (pinfo->cinfo, COL_INFO, "OpenReq; ");
2383 proto_item_append_text(mainlist, " [Open Request]");
2384 decode_PublicOpenReq(tvb, messagebodytree_list, offset);
2385 break;
2386 case OPEN_RES:
2387 col_append_str (pinfo->cinfo, COL_INFO, "OpenRes; ");
2388 proto_item_append_text(mainlist, " [Open Response]");
2389 decode_PublicOpenRes(tvb, messagebodytree_list, offset);
2390 break;
2391 case CLOSE_REQ:
2392 col_append_str (pinfo->cinfo, COL_INFO, "CloseReq; ");
2393 proto_item_append_text(mainlist, " [Close Request]");
2394 field_globalSignature(tvb, messagebodytree_list, offset, &data, &length);
2395 break;
2396 case CLOSE_RES:
2397 col_append_str (pinfo->cinfo, COL_INFO, "CloseRes; ");
2398 proto_item_append_text(mainlist, " [Close Response]");
2399 field_globalSignature(tvb, messagebodytree_list, offset, &data, &length);
2400 break;
2401 case PROFILEPACK_REQ:
2402 col_append_str (pinfo->cinfo, COL_INFO, "GetProfilePackReq; ");
2403 proto_item_append_text(mainlist, " [GetProfilePack Request]");
2404 msg_error = decode_GetProfile_List_Pack_Req(tvb, pinfo,messagebodytree_list, offset);
2405 break;
2406 case PROFILEPACK_RES:
2407 col_append_str (pinfo->cinfo, COL_INFO, "GetProfilePackRes; ");
2408 proto_item_append_text(mainlist, " [GetProfilePack Response]");
2409 msg_error = decode_GetProfilePackRes(tvb, pinfo,messagebodytree_list, offset);
2410 break;
2411 case PROFILELIST_REQ:
2412 col_append_str (pinfo->cinfo, COL_INFO, "GetProfileListReq; ");
2413 proto_item_append_text(mainlist, " [GetProfileList Request]");
2414 msg_error = decode_GetProfile_List_Pack_Req(tvb, pinfo,messagebodytree_list, offset);
2415 break;
2416 case PROFILELIST_RES:
2417 col_append_str (pinfo->cinfo, COL_INFO, "GetProfileListRes; ");
2418 proto_item_append_text(mainlist, " [GetProfileList Response]");
2419 msg_error = decode_GetProfileListRes(tvb, pinfo,messagebodytree_list, offset);
2420 break;
2421 case GETPROCPARAMETER_REQ:
2422 col_append_str (pinfo->cinfo, COL_INFO, "GetProcParameterReq; ");
2423 proto_item_append_text(mainlist, " [GetProcParameter Request]");
2424 msg_error = decode_GetProcParameterReq(tvb, pinfo,messagebodytree_list, offset);
2425 break;
2426 case GETPROCPARAMETER_RES:
2427 col_append_str (pinfo->cinfo, COL_INFO, "GetProcParameterRes; ");
2428 proto_item_append_text(mainlist, " [GetProcParameter Response]");
2429 msg_error = decode_GetProcParameterRes(tvb, pinfo,messagebodytree_list, offset);
2430 break;
2431 case SETPROCPARAMETER_REQ:
2432 col_append_str (pinfo->cinfo, COL_INFO, "SetProcParameterReq; ");
2433 proto_item_append_text(mainlist, " [SetProcParameter Request]");
2434 msg_error = decode_SetProcParameterReq(tvb, pinfo,messagebodytree_list, offset);
2435 break;
2436 case GETLIST_REQ:
2437 col_append_str (pinfo->cinfo, COL_INFO, "GetListReq; ");
2438 proto_item_append_text(mainlist, " [GetList Request]");
2439 decode_GetListReq(tvb, messagebodytree_list, offset);
2440 break;
2441 case GETLIST_RES:
2442 col_append_str (pinfo->cinfo, COL_INFO, "GetListRes; ");
2443 proto_item_append_text(mainlist, " [GetList Response]");
2444 msg_error = decode_GetListRes(tvb, pinfo,messagebodytree_list, offset);
2445 break;
2446 case ATTENTION:
2447 col_append_str (pinfo->cinfo, COL_INFO, "AttentionRes; ");
2448 proto_item_append_text(mainlist, " [Attention Response]");
2449 msg_error = decode_AttentionRes(tvb, pinfo,messagebodytree_list, offset);
2450 break;
2451 default :
2452 expert_add_info(pinfo, messagebodytree, &ei_sml_messagetype_unknown);
2453 return;
2456 if (msg_error){
2457 expert_add_info(pinfo, messagebodytree, &ei_sml_MessageBody);
2458 return;
2461 proto_item_set_end(messagebodytree, tvb, *offset);
2462 proto_item_set_end(sublist, tvb, *offset);
2464 /* CRC 16*/
2465 get_length(tvb, offset, &data, &length);
2466 crc16 = proto_tree_add_text (mainlist_list, tvb, *offset, data + length, "CRC");
2467 crc16_tree = proto_item_add_subtree (crc16, ett_sml_crc16);
2469 if(tvb_get_guint8(tvb, *offset) != UNSIGNED8 && tvb_get_guint8(tvb, *offset) != UNSIGNED16){
2470 expert_add_info(pinfo, crc16, &ei_sml_crc_error_length);
2471 return;
2474 proto_tree_add_item (crc16_tree, hf_sml_datatype, tvb, *offset, 1, ENC_NA);
2475 *offset+=1;
2477 proto_tree_add_item (crc16_tree, hf_sml_crc16, tvb, *offset, data, ENC_BIG_ENDIAN);
2478 *offset+=data;
2480 if (sml_crc_enabled) {
2481 crc_msg_len = (*offset - crc_msg_len - data - 1);
2482 crc_check = crc16_ccitt_tvb_offset(tvb, (*offset - crc_msg_len - data - 1), crc_msg_len);
2483 crc_ref = tvb_get_letohs(tvb, *offset-2);
2485 if (data == 1){
2486 crc_ref = crc_ref & 0xFF00;
2489 if (crc_check == crc_ref) {
2490 proto_tree_add_text (crc16_tree, tvb, *offset, 0, "[CRC Okay]");
2492 else {
2493 /*(little to big endian convert) to display in correct order*/
2494 crc_check = ((crc_check >> 8) & 0xFF) + ((crc_check << 8 & 0xFF00));
2495 proto_tree_add_text (crc16_tree, tvb, *offset, 0, "[CRC Bad 0x%X]", crc_check);
2496 expert_add_info(pinfo, crc16, &ei_sml_crc_error);
2499 else {
2500 proto_tree_add_text (crc16_tree, tvb, *offset, 0, "[CRC validation disabled]");
2503 /*Message END*/
2504 if (tvb_get_guint8 (tvb, *offset) == 0){
2505 proto_tree_add_item (mainlist_list, hf_sml_endOfSmlMsg, tvb, *offset, 1, ENC_BIG_ENDIAN);
2506 *offset+=1;
2508 else {
2509 expert_add_info(pinfo, NULL, &ei_sml_endOfSmlMsg);
2510 return;
2513 proto_item_set_end(mainlist, tvb, *offset);
2515 if (tvb_reported_length_remaining(tvb, *offset) > 0){
2516 check = tvb_get_guint8(tvb, *offset);
2518 if (check == LIST_6_ELEMENTS){
2519 close1 = FALSE;
2521 else if (check == 0x1b || check == 0){
2522 close1 = TRUE;
2525 else if (sml_reassemble && pinfo->can_desegment){
2526 pinfo->desegment_offset = start_offset;
2527 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
2528 return;
2530 else
2531 return;
2534 /*Padding*/
2535 if (check == 0){
2536 length = 1;
2537 *offset+=1;
2539 while (tvb_get_guint8(tvb, *offset) == 0){
2540 length++;
2541 *offset+=1;
2543 *offset-=length;
2545 proto_tree_add_item (sml_tree, hf_sml_padding, tvb, *offset, length, ENC_NA);
2546 *offset+=length;
2549 /*Escape End*/
2550 if(tvb_get_ntoh40(tvb, *offset) != ESC_SEQ_END){
2551 expert_add_info(pinfo, NULL, &ei_sml_esc_error);
2552 return;
2554 proto_tree_add_item (sml_tree, hf_sml_esc, tvb, *offset, 4, ENC_BIG_ENDIAN);
2555 *offset+=4;
2557 /*MSG END*/
2558 msgend = proto_tree_add_item (sml_tree, hf_sml_end, tvb, *offset, 4, ENC_BIG_ENDIAN);
2559 msgend_tree = proto_item_add_subtree (msgend, ett_sml_msgend);
2560 *offset+=1;
2561 proto_tree_add_item (msgend_tree, hf_sml_padding, tvb, *offset, 1, ENC_NA);
2562 *offset+=1;
2563 proto_tree_add_item (msgend_tree, hf_sml_crc16, tvb, *offset, 2, ENC_BIG_ENDIAN);
2564 *offset+=2;
2566 if (sml_crc_enabled && sml_reassemble){
2567 crc_file_len = *offset - crc_file_len - 2;
2568 crc_check = crc16_ccitt_tvb_offset(tvb,*offset-crc_file_len-2, crc_file_len);
2569 crc_ref = tvb_get_letohs(tvb, *offset-2);
2571 if (crc_check == crc_ref){
2572 proto_tree_add_text (msgend_tree, tvb, *offset, 0, "[CRC Okay]");
2574 else{
2575 /*(little to big endian convert) to display in correct order*/
2576 crc_check = ((crc_check >> 8) & 0xFF) + ((crc_check << 8) & 0xFF00);
2577 proto_tree_add_text (msgend_tree, tvb, *offset, 0, "[CRC Bad 0x%X]", crc_check);
2578 expert_add_info_format(pinfo, msgend, &ei_sml_crc_error, "CRC error (messages not reassembled ?)");
2581 else {
2582 proto_tree_add_text (msgend_tree, tvb, *offset, 0, "[CRC validation disabled]");
2585 available = tvb_reported_length_remaining(tvb, *offset);
2586 if (available <= 0){
2587 close2 = TRUE;
2589 else {
2590 if (sml_reassemble){
2591 proto_item_set_end(file, tvb, *offset);
2593 else {
2594 proto_tree_add_text(sml_tree,tvb, *offset, 0 , "---New SML File---");
2596 close1 = FALSE;
2601 /* main */
2602 static void dissect_sml (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
2603 proto_item *sml_item = NULL;
2604 proto_tree *sml_tree = NULL;
2606 guint offset = 0;
2608 /*Check if not SML*/
2609 if (tvb_get_ntohl(tvb, offset) != ESC_SEQ && tvb_get_guint8(tvb, offset) != LIST_6_ELEMENTS){
2610 return;
2613 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SML");
2614 col_clear(pinfo->cinfo,COL_INFO);
2616 /* create display subtree for the protocol */
2617 sml_item = proto_tree_add_item(tree, proto_sml, tvb, 0, -1, ENC_NA);
2618 sml_tree = proto_item_add_subtree(sml_item, ett_sml);
2619 dissect_sml_file(tvb, pinfo, &offset, sml_tree);
2622 void proto_register_sml (void) {
2623 module_t *sml_module;
2624 expert_module_t* expert_sml;
2626 static hf_register_info hf[] = {
2627 { &hf_sml_esc,
2628 { "Escape", "sml.esc", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2629 { &hf_sml_version_1,
2630 { "Version 1", "sml.version_1", FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2631 { &hf_sml_smlVersion,
2632 { "SML Version", "sml.version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2633 { &hf_sml_crc16,
2634 { "CRC16", "sml.crc", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2635 { &hf_sml_endOfSmlMsg,
2636 { "End of SML Msg", "sml.end", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2637 { &hf_sml_transactionId,
2638 { "Transaction ID", "sml.transactionid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2639 { &hf_sml_groupNo,
2640 { "GroupNo", "sml.groupno", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2641 { &hf_sml_datatype,
2642 { "Datatype", "sml.datatype", FT_UINT8, BASE_HEX, VALS (datatype), 0x0, NULL, HFILL }},
2643 { &hf_sml_abortOnError,
2644 { "Abort On Error", "sml.abort", FT_UINT8, BASE_HEX, VALS (sml_abort), 0x0, NULL, HFILL }},
2645 { &hf_sml_MessageBody,
2646 { "Messagebody", "sml.messagebody", FT_UINT16, BASE_HEX, VALS (sml_body), 0x0, NULL, HFILL }},
2647 { &hf_sml_end,
2648 { "End of Msg", "sml.end", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2649 { &hf_sml_codepage,
2650 { "Codepage", "sml.codepage", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2651 { &hf_sml_clientId,
2652 { "Client ID", "sml.clientid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2653 { &hf_sml_reqFileId,
2654 { "reqFile ID", "sml.reqfileid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2655 { &hf_sml_serverId,
2656 { "server ID", "sml.serverid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2657 { &hf_sml_username,
2658 { "Username", "sml.username", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2659 { &hf_sml_password,
2660 { "Password", "sml.password", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2661 { &hf_sml_listName,
2662 { "List Name", "sml.listname", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2663 { &hf_sml_globalSignature,
2664 { "Global Signature", "sml.globalsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2665 { &hf_sml_refTime,
2666 { "refTime", "sml.reftime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2667 { &hf_sml_actSensorTime,
2668 { "actSensorTime", "sml.actsensortime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2669 { &hf_sml_timetype,
2670 { "Time type", "sml.timetype", FT_UINT8, BASE_HEX, VALS (sml_timetypes), 0x0, NULL, HFILL }},
2671 { &hf_sml_objName,
2672 { "objName", "sml.objname", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2673 { &hf_sml_status,
2674 { "Status", "sml.status", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2675 { &hf_sml_valTime,
2676 { "valTime", "sml.valtime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2677 { &hf_sml_unit,
2678 { "unit", "sml.unit", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2679 { &hf_sml_scaler,
2680 { "scaler", "sml.scaler", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2681 { &hf_sml_value,
2682 { "value", "sml.value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2683 { &hf_sml_valueSignature,
2684 { "ValueSignature", "sml.valuesignature", FT_BYTES, BASE_NONE, NULL, 0x0,NULL, HFILL }},
2685 { &hf_sml_listSignature,
2686 { "ListSignature", "sml.listsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2687 { &hf_sml_actGatewayTime,
2688 { "actGatewayTime", "sml.gatewaytime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2689 { &hf_sml_parameterTreePath,
2690 { "path_Entry", "sml.parametertreepath", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2691 { &hf_sml_attribute,
2692 { "attribute", "sml.attribute", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2693 { &hf_sml_parameterName,
2694 { "parameterName", "sml.parametername", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2695 { &hf_sml_procParValue,
2696 { "procParValue", "sml.procparvalue", FT_UINT8, BASE_HEX, VALS(procvalues), 0x0, NULL, HFILL }},
2697 { &hf_sml_procParValueTime,
2698 { "procParValueTime", "sml.procparvaluetime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2699 { &hf_sml_padding,
2700 { "Padding", "sml.padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2701 { &hf_sml_secIndex,
2702 { "secIndex", "sml.secindex", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2703 { &hf_sml_attentionNo,
2704 { "attentionNo", "sml.attentionno", FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(attentionValues), 0x0, NULL, HFILL }},
2705 { &hf_sml_attentionMsg,
2706 { "attentionMsg", "sml.attentionmsg", FT_STRING, BASE_NONE, NULL, 0x0 , NULL, HFILL }},
2707 { &hf_sml_withRawdata,
2708 { "withRawdata", "sml.withrawdata", FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(bools), 0x0 , NULL, HFILL }},
2709 { &hf_sml_beginTime,
2710 { "beginTime", "sml.begintime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2711 { &hf_sml_endTime,
2712 { "endTime", "sml.endtime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2713 { &hf_sml_actTime,
2714 { "endTime", "sml.acttime", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2715 { &hf_sml_object_list_Entry,
2716 { "object_list_Entry", "sml.objectentry", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2717 { &hf_sml_regPeriod,
2718 { "regPeriod", "sml.regperiod", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2719 { &hf_sml_rawdata,
2720 { "rawdata", "sml.rawdata", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2721 { &hf_sml_periodSignature,
2722 { "periodSignature", "sml.periodsignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2723 { &hf_sml_profileSignature,
2724 { "profileSignature", "sml.profilesignature", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2725 { &hf_sml_signature_mA_R2_R3,
2726 { "signature_mA_R2_R3", "sml.signaturema", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2727 { &hf_sml_signature_pA_R1_R4,
2728 { "signature_pA_R1_R4", "sml.signaturepa", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2729 { &hf_sml_unit_mA,
2730 { "unit_mA", "sml.unitmA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2731 { &hf_sml_unit_pA,
2732 { "unit_pA", "sml.unitpA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2733 { &hf_sml_unit_R1,
2734 { "unit_R1", "sml.unitR1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2735 { &hf_sml_unit_R2,
2736 { "unit_R2", "sml.unitR2", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2737 { &hf_sml_unit_R3,
2738 { "unit_R3", "sml.unitR3", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2739 { &hf_sml_unit_R4,
2740 { "unit_R4", "sml.unitR4", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2741 { &hf_sml_scaler_mA,
2742 { "scaler_mA", "sml.scalermA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2743 { &hf_sml_scaler_pA,
2744 { "scaler_pA", "sml.scalerpA", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2745 { &hf_sml_scaler_R1,
2746 { "scaler_R1", "sml.scalerR1", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2747 { &hf_sml_scaler_R2,
2748 { "scaler_R2", "sml.scalerR2", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2749 { &hf_sml_scaler_R3,
2750 { "scaler_R3", "sml.scalerR3", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2751 { &hf_sml_scaler_R4,
2752 { "scaler_R4", "sml.scalerR4", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2753 { &hf_sml_value_mA,
2754 { "value_mA", "sml.valuemA", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2755 { &hf_sml_value_pA,
2756 { "value_pA", "sml.valuepA", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2757 { &hf_sml_value_R1,
2758 { "value_R1", "sml.valueR1", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2759 { &hf_sml_value_R2,
2760 { "value_R2", "sml.valueR2", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2761 { &hf_sml_value_R3,
2762 { "value_R3", "sml.valueR3", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2763 { &hf_sml_value_R4,
2764 { "value_R4", "sml.valueR4", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }}
2767 /* Setup protocol subtree array */
2768 static gint *ett[] = {
2769 &ett_sml,
2770 &ett_sml_mainlist,
2771 &ett_sml_version,
2772 &ett_sml_sublist,
2773 &ett_sml_trans,
2774 &ett_sml_group,
2775 &ett_sml_abort,
2776 &ett_sml_body,
2777 &ett_sml_mblist,
2778 &ett_sml_mttree,
2779 &ett_sml_clientId,
2780 &ett_sml_codepage,
2781 &ett_sml_reqFileId,
2782 &ett_sml_serverId,
2783 &ett_sml_username,
2784 &ett_sml_password,
2785 &ett_sml_smlVersion,
2786 &ett_sml_crc16,
2787 &ett_sml_listName,
2788 &ett_sml_globalSignature,
2789 &ett_sml_refTime,
2790 &ett_sml_actSensorTime,
2791 &ett_sml_timetype,
2792 &ett_sml_time,
2793 &ett_sml_valList,
2794 &ett_sml_objName,
2795 &ett_sml_listEntry,
2796 &ett_sml_status,
2797 &ett_sml_valTime,
2798 &ett_sml_unit,
2799 &ett_sml_scaler,
2800 &ett_sml_value,
2801 &ett_sml_valueSignature,
2802 &ett_sml_valtree,
2803 &ett_sml_listSignature,
2804 &ett_sml_actGatewayTime,
2805 &ett_sml_treepath,
2806 &ett_sml_parameterTreePath,
2807 &ett_sml_attribute,
2808 &ett_sml_parameterTree,
2809 &ett_sml_parameterName,
2810 &ett_sml_child,
2811 &ett_sml_periodEntry,
2812 &ett_sml_procParValueTime,
2813 &ett_sml_procParValuetype,
2814 &ett_sml_procParValue,
2815 &ett_sml_msgend,
2816 &ett_sml_tupel,
2817 &ett_sml_secIndex,
2818 &ett_sml_signature,
2819 &ett_sml_attentionNo,
2820 &ett_sml_attentionMsg,
2821 &ett_sml_withRawdata,
2822 &ett_sml_beginTime,
2823 &ett_sml_endTime,
2824 &ett_sml_object_list,
2825 &ett_sml_object_list_Entry,
2826 &ett_sml_actTime,
2827 &ett_sml_regPeriod,
2828 &ett_sml_rawdata,
2829 &ett_sml_periodSignature,
2830 &ett_sml_period_List_Entry,
2831 &ett_sml_periodList,
2832 &ett_sml_header_List_Entry,
2833 &ett_sml_profileSignature,
2834 &ett_sml_valuelist,
2835 &ett_sml_headerList,
2836 &ett_sml_value_List_Entry,
2837 &ett_sml_signature_mA_R2_R3,
2838 &ett_sml_signature_pA_R1_R4,
2839 &ett_sml_unit_mA,
2840 &ett_sml_scaler_mA,
2841 &ett_sml_value_mA,
2842 &ett_sml_unit_pA,
2843 &ett_sml_scaler_pA,
2844 &ett_sml_value_pA,
2845 &ett_sml_unit_R1,
2846 &ett_sml_scaler_R1,
2847 &ett_sml_value_R1,
2848 &ett_sml_unit_R2,
2849 &ett_sml_scaler_R2,
2850 &ett_sml_value_R2,
2851 &ett_sml_unit_R3,
2852 &ett_sml_scaler_R3,
2853 &ett_sml_value_R3,
2854 &ett_sml_unit_R4,
2855 &ett_sml_scaler_R4,
2856 &ett_sml_value_R4,
2857 &ett_sml_tree_Entry,
2858 &ett_sml_dasDetails,
2859 &ett_sml_attentionDetails
2862 static ei_register_info ei[] = {
2863 { &ei_sml_tupel_error, { "sml.tupel_error_", PI_PROTOCOL, PI_ERROR, "error in Tupel", EXPFILL }},
2864 { &ei_sml_procParValue_invalid, { "sml.procparvalue.invalid", PI_PROTOCOL, PI_WARN, "invalid procParValue", EXPFILL }},
2865 { &ei_sml_procParValue_errror, { "sml.procparvalue.error", PI_PROTOCOL, PI_ERROR, "error in procParValue", EXPFILL }},
2866 { &ei_sml_invalid_count, { "sml.invalid_count", PI_PROTOCOL, PI_ERROR, "invalid loop count", EXPFILL }},
2867 { &ei_sml_segment_needed, { "sml.segment_needed", PI_REASSEMBLE, PI_NOTE, "probably segment needed", EXPFILL }},
2868 { &ei_sml_messagetype_unknown, { "sml.messagetype.unknown", PI_PROTOCOL, PI_ERROR, "unknown Messagetype", EXPFILL }},
2869 { &ei_sml_MessageBody, { "sml.messagebody.error", PI_PROTOCOL, PI_ERROR, "Error in MessageBody", EXPFILL }},
2870 { &ei_sml_crc_error_length, { "sml.crc.length_error", PI_PROTOCOL, PI_ERROR, "CRC length error", EXPFILL }},
2871 { &ei_sml_crc_error, { "sml.crc.error", PI_CHECKSUM, PI_WARN, "CRC error", EXPFILL }},
2872 { &ei_sml_endOfSmlMsg, { "sml.end.not_zero", PI_PROTOCOL, PI_ERROR, "MsgEnd not 0x00", EXPFILL }},
2873 { &ei_sml_esc_error, { "sml.esc.error", PI_PROTOCOL, PI_ERROR, "escapesequence error", EXPFILL }},
2876 proto_sml = proto_register_protocol("Smart Message Language","SML", "sml");
2877 sml_module = prefs_register_protocol(proto_sml, proto_reg_handoff_sml);
2879 prefs_register_bool_preference (sml_module, "reassemble", "Enable reassemble", "Enable reassembling (default is enabled)", &sml_reassemble);
2880 prefs_register_bool_preference (sml_module, "crc", "Enable crc calculation", "Enable crc (default is disabled)", &sml_crc_enabled);
2881 prefs_register_uint_preference(sml_module, "tcp.port", "SML TCP Port", "Set the TCP port for SML (Default is 0), recommended port is 7259", 10, &tcp_port_pref);
2882 prefs_register_uint_preference(sml_module, "udp.port", "SML UDP Port", "Set the UDP port for SML (Default is 0), recommended port is 7259", 10, &udp_port_pref);
2884 proto_register_field_array(proto_sml, hf, array_length(hf));
2885 proto_register_subtree_array(ett, array_length(ett));
2886 expert_sml = expert_register_protocol(proto_sml);
2887 expert_register_field_array(expert_sml, ei, array_length(ei));
2890 void proto_reg_handoff_sml(void) {
2891 static gboolean initialized = FALSE;
2892 static int old_tcp_port;
2893 static int old_udp_port;
2894 static dissector_handle_t sml_handle;
2896 if (!initialized) {
2897 sml_handle = create_dissector_handle(dissect_sml, proto_sml);
2898 initialized = TRUE;
2899 } else {
2900 dissector_delete_uint("tcp.port", old_tcp_port, sml_handle);
2901 dissector_delete_uint("udp.port", old_udp_port, sml_handle);
2903 old_tcp_port = tcp_port_pref;
2904 old_udp_port = udp_port_pref;
2906 dissector_add_uint("tcp.port", tcp_port_pref, sml_handle);
2907 dissector_add_uint("udp.port", udp_port_pref, sml_handle);
2911 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2913 * Local variables:
2914 * c-basic-offset: 8
2915 * tab-width: 8
2916 * indent-tabs-mode: t
2917 * End:
2919 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2920 * :indentSize=8:tabSize=8:noTabs=false: