Convert 'encoding' parameter of certain proto_tree_add_item() calls in asn1 dissectors:
[obnox/wireshark/wip.git] / epan / dissectors / packet-sv.c
1 /* Do not modify this file.                                                   */
2 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
3 /* packet-sv.c                                                                */
4 /* ../../tools/asn2wrs.py -b -p sv -c ./sv.cnf -s ./packet-sv-template -D . sv.asn */
5
6 /* Input file: packet-sv-template.c */
7
8 #line 1 "../../asn1/sv/packet-sv-template.c"
9 /* packet-sv.c
10  * Routines for IEC 61850 Sampled Vales packet dissection
11  * Michael Bernhard 2008
12  *
13  * $Id$
14  *
15  * Wireshark - Network traffic analyzer
16  * By Gerald Combs <gerald@wireshark.org>
17  * Copyright 1998 Gerald Combs
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License
21  * as published by the Free Software Foundation; either version 2
22  * of the License, or (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <glib.h>
39 #include <epan/packet.h>
40 #include <epan/asn1.h>
41 #include <epan/etypes.h>
42
43 #include <stdio.h>
44 #include <string.h>
45
46 #include "packet-ber.h"
47 #include "packet-acse.h"
48
49 #include "tap.h"
50
51 #include "packet-sv.h"
52
53 #define PNAME  "IEC61850 Sampled Values"
54 #define PSNAME "SV"
55 #define PFNAME "sv"
56
57 /* see IEC61850-8-1 8.2 */
58 #define Q_VALIDITY_GOOD                 (0x0 << 0)
59 #define Q_VALIDITY_INVALID              (0x1 << 0)
60 #define Q_VALIDITY_QUESTIONABLE (0x3 << 0)
61 #define Q_VALIDITY_MASK                 (0x3 << 0)
62
63 #define Q_OVERFLOW                              (1 << 2)
64 #define Q_OUTOFRANGE                    (1 << 3)
65 #define Q_BADREFERENCE                  (1 << 4)
66 #define Q_OSCILLATORY                   (1 << 5)
67 #define Q_FAILURE                               (1 << 6)
68 #define Q_OLDDATA                               (1 << 7)
69 #define Q_INCONSISTENT                  (1 << 8)
70 #define Q_INACCURATE                    (1 << 9)
71
72 #define Q_SOURCE_PROCESS                (0 << 10)
73 #define Q_SOURCE_SUBSTITUTED    (1 << 10)
74 #define Q_SOURCE_MASK                   (1 << 10)
75
76 #define Q_TEST                                  (1 << 11)
77 #define Q_OPERATORBLOCKED               (1 << 12)
78
79 /* see UCA Implementation Guideline for IEC 61850-9-2 */
80 #define Q_DERIVED                               (1 << 13)
81
82
83 /* Data for SV tap */
84 static int sv_tap = -1;
85 static sv_frame_data sv_data;
86
87 /* Initialize the protocol and registered fields */
88 static int proto_sv = -1;
89 static int hf_sv_appid = -1;
90 static int hf_sv_length = -1;
91 static int hf_sv_reserve1 = -1;
92 static int hf_sv_reserve2 = -1;
93 static int hf_sv_phmeas_instmag_i = -1;
94 static int hf_sv_phsmeas_q = -1;
95 static int hf_sv_phsmeas_q_validity = -1;
96 static int hf_sv_phsmeas_q_overflow = -1;
97 static int hf_sv_phsmeas_q_outofrange = -1;
98 static int hf_sv_phsmeas_q_badreference = -1;
99 static int hf_sv_phsmeas_q_oscillatory = -1;
100 static int hf_sv_phsmeas_q_failure = -1;
101 static int hf_sv_phsmeas_q_olddata = -1;
102 static int hf_sv_phsmeas_q_inconsistent = -1;
103 static int hf_sv_phsmeas_q_inaccurate = -1;
104 static int hf_sv_phsmeas_q_source = -1;
105 static int hf_sv_phsmeas_q_test = -1;
106 static int hf_sv_phsmeas_q_operatorblocked = -1;
107 static int hf_sv_phsmeas_q_derived = -1;
108
109
110 /*--- Included file: packet-sv-hf.c ---*/
111 #line 1 "../../asn1/sv/packet-sv-hf.c"
112 static int hf_sv_savPdu = -1;                     /* SavPdu */
113 static int hf_sv_noASDU = -1;                     /* INTEGER_0_65535 */
114 static int hf_sv_seqASDU = -1;                    /* SEQUENCE_OF_ASDU */
115 static int hf_sv_seqASDU_item = -1;               /* ASDU */
116 static int hf_sv_svID = -1;                       /* VisibleString */
117 static int hf_sv_smpCnt = -1;                     /* T_smpCnt */
118 static int hf_sv_confRef = -1;                    /* INTEGER_0_4294967295 */
119 static int hf_sv_smpSynch = -1;                   /* T_smpSynch */
120 static int hf_sv_seqData = -1;                    /* Data */
121
122 /*--- End of included file: packet-sv-hf.c ---*/
123 #line 102 "../../asn1/sv/packet-sv-template.c"
124
125 /* Initialize the subtree pointers */
126 static int ett_sv = -1;
127 static int ett_phsmeas = -1;
128 static int ett_phsmeas_q = -1;
129
130
131 /*--- Included file: packet-sv-ett.c ---*/
132 #line 1 "../../asn1/sv/packet-sv-ett.c"
133 static gint ett_sv_SampledValues = -1;
134 static gint ett_sv_SavPdu = -1;
135 static gint ett_sv_SEQUENCE_OF_ASDU = -1;
136 static gint ett_sv_ASDU = -1;
137
138 /*--- End of included file: packet-sv-ett.c ---*/
139 #line 109 "../../asn1/sv/packet-sv-template.c"
140
141 static const value_string sv_q_validity_vals[] = {
142   {   0, "good" },
143   {   1, "invalid" },
144   {   3, "questionable" },
145   { 0, NULL }
146 };
147
148 static const value_string sv_q_source_vals[] = {
149   {   0, "process" },
150   {   1, "substituted" },
151   { 0, NULL }
152 };
153
154 static int
155 dissect_PhsMeas1(gboolean implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, int hf_id _U_)
156 {
157         gint8 class;
158         gboolean pc;
159         gint32 tag;
160         guint32 len;
161         proto_item *it;
162         proto_tree *subtree = NULL;
163         gint32 value;
164         guint32 qual;
165         guint32 i;
166
167         static const int *q_flags[] = {
168                 &hf_sv_phsmeas_q_validity,
169                 &hf_sv_phsmeas_q_overflow,
170                 &hf_sv_phsmeas_q_outofrange,
171                 &hf_sv_phsmeas_q_badreference,
172                 &hf_sv_phsmeas_q_oscillatory,
173                 &hf_sv_phsmeas_q_failure,
174                 &hf_sv_phsmeas_q_olddata,
175                 &hf_sv_phsmeas_q_inconsistent,
176                 &hf_sv_phsmeas_q_inaccurate,
177                 &hf_sv_phsmeas_q_source,
178                 &hf_sv_phsmeas_q_test,
179                 &hf_sv_phsmeas_q_operatorblocked,
180                 &hf_sv_phsmeas_q_derived,
181                 NULL
182                 };
183
184         if (!implicit_tag) {
185                 offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
186                 offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL);
187         } else {
188                 len=tvb_length_remaining(tvb, offset);
189         }
190
191         if (tree) {
192                 it = proto_tree_add_text(tree, tvb, offset, len, "PhsMeas1");
193                 subtree = proto_item_add_subtree(it, ett_phsmeas);
194         }
195
196         sv_data.num_phsMeas = 0;
197         for (i = 0; i < len/8; i++) {
198                 if (tree && subtree) {
199                         value = tvb_get_ntohl(tvb, offset);
200                         qual = tvb_get_ntohl(tvb, offset + 4);
201
202                         proto_tree_add_item(subtree, hf_sv_phmeas_instmag_i, tvb, offset, 4, ENC_BIG_ENDIAN);
203                         proto_tree_add_bitmask(subtree, tvb, offset + 4, hf_sv_phsmeas_q, ett_phsmeas_q, q_flags, FALSE);
204
205                         if (i < IEC61850_SV_MAX_PHSMEAS_ENTRIES) {
206                                 sv_data.phsMeas[i].value = value;
207                                 sv_data.phsMeas[i].qual = qual;
208                                 sv_data.num_phsMeas++;
209                         }
210                 }
211
212                 offset += 8;
213         }
214
215         return offset;
216 }
217
218
219 /*--- Included file: packet-sv-fn.c ---*/
220 #line 1 "../../asn1/sv/packet-sv-fn.c"
221
222
223 static int
224 dissect_sv_INTEGER_0_65535(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
225   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
226                                                 NULL);
227
228   return offset;
229 }
230
231
232
233 static int
234 dissect_sv_VisibleString(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
235   offset = dissect_ber_restricted_string(implicit_tag, BER_UNI_TAG_VisibleString,
236                                             actx, tree, tvb, offset, hf_index,
237                                             NULL);
238
239   return offset;
240 }
241
242
243
244 static int
245 dissect_sv_T_smpCnt(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
246 #line 19 "../../asn1/sv/sv.cnf"
247         guint32 value;
248         offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, &value);
249         sv_data.smpCnt = value;
250
251
252   return offset;
253 }
254
255
256
257 static int
258 dissect_sv_INTEGER_0_4294967295(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
259   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
260                                                 NULL);
261
262   return offset;
263 }
264
265
266 static const value_string sv_T_smpSynch_vals[] = {
267   {   0, "none" },
268   {   1, "local" },
269   {   2, "global" },
270   { 0, NULL }
271 };
272
273
274 static int
275 dissect_sv_T_smpSynch(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
276 #line 25 "../../asn1/sv/sv.cnf"
277         guint32 value;
278         offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, &value);
279         sv_data.smpSynch = value;
280
281
282   return offset;
283 }
284
285
286
287 static int
288 dissect_sv_Data(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
289 #line 31 "../../asn1/sv/sv.cnf"
290         offset = dissect_PhsMeas1(implicit_tag, actx->pinfo, tree, tvb, offset, hf_index);
291
292
293   return offset;
294 }
295
296
297 static const ber_sequence_t ASDU_sequence[] = {
298   { &hf_sv_svID             , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_sv_VisibleString },
299   { &hf_sv_smpCnt           , BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_sv_T_smpCnt },
300   { &hf_sv_confRef          , BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_sv_INTEGER_0_4294967295 },
301   { &hf_sv_smpSynch         , BER_CLASS_CON, 5, BER_FLAGS_IMPLTAG, dissect_sv_T_smpSynch },
302   { &hf_sv_seqData          , BER_CLASS_CON, 7, BER_FLAGS_IMPLTAG, dissect_sv_Data },
303   { NULL, 0, 0, 0, NULL }
304 };
305
306 static int
307 dissect_sv_ASDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
308   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
309                                    ASDU_sequence, hf_index, ett_sv_ASDU);
310
311   return offset;
312 }
313
314
315 static const ber_sequence_t SEQUENCE_OF_ASDU_sequence_of[1] = {
316   { &hf_sv_seqASDU_item     , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_sv_ASDU },
317 };
318
319 static int
320 dissect_sv_SEQUENCE_OF_ASDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
321   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
322                                       SEQUENCE_OF_ASDU_sequence_of, hf_index, ett_sv_SEQUENCE_OF_ASDU);
323
324   return offset;
325 }
326
327
328 static const ber_sequence_t SavPdu_sequence[] = {
329   { &hf_sv_noASDU           , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_sv_INTEGER_0_65535 },
330   { &hf_sv_seqASDU          , BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_sv_SEQUENCE_OF_ASDU },
331   { NULL, 0, 0, 0, NULL }
332 };
333
334 static int
335 dissect_sv_SavPdu(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
336   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
337                                    SavPdu_sequence, hf_index, ett_sv_SavPdu);
338
339   return offset;
340 }
341
342
343 static const value_string sv_SampledValues_vals[] = {
344   {   0, "savPdu" },
345   { 0, NULL }
346 };
347
348 static const ber_choice_t SampledValues_choice[] = {
349   {   0, &hf_sv_savPdu           , BER_CLASS_APP, 0, BER_FLAGS_IMPLTAG, dissect_sv_SavPdu },
350   { 0, NULL, 0, 0, 0, NULL }
351 };
352
353 static int
354 dissect_sv_SampledValues(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
355   offset = dissect_ber_choice(actx, tree, tvb, offset,
356                                  SampledValues_choice, hf_index, ett_sv_SampledValues,
357                                  NULL);
358
359   return offset;
360 }
361
362
363 /*--- End of included file: packet-sv-fn.c ---*/
364 #line 188 "../../asn1/sv/packet-sv-template.c"
365
366 /*
367 * Dissect SV PDUs inside a PPDU.
368 */
369 static void
370 dissect_sv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
371 {
372         int offset = 0;
373         int old_offset;
374         proto_item *item = NULL;
375         proto_tree *tree = NULL;
376         asn1_ctx_t asn1_ctx;
377
378         asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
379
380         if (parent_tree){
381                 item = proto_tree_add_item(parent_tree, proto_sv, tvb, 0, -1, FALSE);
382                 tree = proto_item_add_subtree(item, ett_sv);
383         }
384         col_set_str(pinfo->cinfo, COL_PROTOCOL, PNAME);
385         col_clear(pinfo->cinfo, COL_INFO);
386
387         /* APPID */
388         if (tree && tvb_reported_length_remaining(tvb, offset) >= 2)
389                 proto_tree_add_item(tree, hf_sv_appid, tvb, offset, 2, ENC_BIG_ENDIAN);
390
391         /* Length */
392         if (tree && tvb_reported_length_remaining(tvb, offset) >= 4)
393                 proto_tree_add_item(tree, hf_sv_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
394
395         /* Reserved 1 */
396         if (tree && tvb_reported_length_remaining(tvb, offset) >= 6)
397                 proto_tree_add_item(tree, hf_sv_reserve1, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
398
399         /* Reserved 2 */
400         if (tree && tvb_reported_length_remaining(tvb, offset) >= 8)
401                 proto_tree_add_item(tree, hf_sv_reserve2, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
402
403         offset = 8;
404         while (tree && tvb_reported_length_remaining(tvb, offset) > 0){
405                 old_offset = offset;
406                 offset = dissect_sv_SampledValues(FALSE, tvb, offset, &asn1_ctx , tree, -1);
407                 if (offset == old_offset) {
408                         proto_tree_add_text(tree, tvb, offset, -1, "Internal error, zero-byte SV PDU");
409                         offset = tvb_length(tvb);
410                         break;
411                 }
412         }
413
414         if(tree)
415                 tap_queue_packet(sv_tap, pinfo, &sv_data);
416 }
417
418
419 /*--- proto_register_sv -------------------------------------------*/
420 void proto_register_sv(void) {
421
422         /* List of fields */
423         static hf_register_info hf[] = {
424                 { &hf_sv_appid,
425                 { "APPID",      "sv.appid", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
426
427                 { &hf_sv_length,
428                 { "Length",     "sv.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
429
430                 { &hf_sv_reserve1,
431                 { "Reserved 1", "sv.reserve1", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
432
433                 { &hf_sv_reserve2,
434                 { "Reserved 2", "sv.reserve2", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
435
436                 { &hf_sv_phmeas_instmag_i,
437                 { "value", "sv.meas_value", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
438
439                 { &hf_sv_phsmeas_q,
440                 { "quality", "sv.meas_quality", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
441
442                 { &hf_sv_phsmeas_q_validity,
443                 { "validity", "sv.meas_quality.validity", FT_UINT32, BASE_HEX, VALS(sv_q_validity_vals), Q_VALIDITY_MASK, NULL, HFILL}},
444
445                 { &hf_sv_phsmeas_q_overflow,
446                 { "overflow", "sv.meas_quality.overflow", FT_BOOLEAN, 32, NULL, Q_OVERFLOW, NULL, HFILL}},
447
448                 { &hf_sv_phsmeas_q_outofrange,
449                 { "out of range", "sv.meas_quality.outofrange", FT_BOOLEAN, 32, NULL, Q_OUTOFRANGE, NULL, HFILL}},
450
451                 { &hf_sv_phsmeas_q_badreference,
452                 { "bad reference", "sv.meas_quality.badreference", FT_BOOLEAN, 32, NULL, Q_BADREFERENCE, NULL, HFILL}},
453
454                 { &hf_sv_phsmeas_q_oscillatory,
455                 { "oscillatory", "sv.meas_quality.oscillatory", FT_BOOLEAN, 32, NULL, Q_OSCILLATORY, NULL, HFILL}},
456
457                 { &hf_sv_phsmeas_q_failure,
458                 { "failure", "sv.meas_quality.failure", FT_BOOLEAN, 32, NULL, Q_FAILURE, NULL, HFILL}},
459
460                 { &hf_sv_phsmeas_q_olddata,
461                 { "old data", "sv.meas_quality.olddata", FT_BOOLEAN, 32, NULL, Q_OLDDATA, NULL, HFILL}},
462
463                 { &hf_sv_phsmeas_q_inconsistent,
464                 { "inconsistent", "sv.meas_quality.inconsistent", FT_BOOLEAN, 32, NULL, Q_INCONSISTENT, NULL, HFILL}},
465
466                 { &hf_sv_phsmeas_q_inaccurate,
467                 { "inaccurate", "sv.meas_quality.inaccurate", FT_BOOLEAN, 32, NULL, Q_INACCURATE, NULL, HFILL}},
468
469                 { &hf_sv_phsmeas_q_source,
470                 { "source", "sv.meas_quality.source", FT_UINT32, BASE_HEX, VALS(sv_q_source_vals), Q_SOURCE_MASK, NULL, HFILL}},
471
472                 { &hf_sv_phsmeas_q_test,
473                 { "test", "sv.meas_quality.teset", FT_BOOLEAN, 32, NULL, Q_TEST, NULL, HFILL}},
474
475                 { &hf_sv_phsmeas_q_operatorblocked,
476                 { "operator blocked", "sv.meas_quality.operatorblocked", FT_BOOLEAN, 32, NULL, Q_OPERATORBLOCKED, NULL, HFILL}},
477
478                 { &hf_sv_phsmeas_q_derived,
479                 { "derived", "sv.meas_quality.derived", FT_BOOLEAN, 32, NULL, Q_DERIVED, NULL, HFILL}},
480
481
482
483 /*--- Included file: packet-sv-hfarr.c ---*/
484 #line 1 "../../asn1/sv/packet-sv-hfarr.c"
485     { &hf_sv_savPdu,
486       { "savPdu", "sv.savPdu",
487         FT_NONE, BASE_NONE, NULL, 0,
488         NULL, HFILL }},
489     { &hf_sv_noASDU,
490       { "noASDU", "sv.noASDU",
491         FT_UINT32, BASE_DEC, NULL, 0,
492         "INTEGER_0_65535", HFILL }},
493     { &hf_sv_seqASDU,
494       { "seqASDU", "sv.seqASDU",
495         FT_UINT32, BASE_DEC, NULL, 0,
496         "SEQUENCE_OF_ASDU", HFILL }},
497     { &hf_sv_seqASDU_item,
498       { "ASDU", "sv.ASDU",
499         FT_NONE, BASE_NONE, NULL, 0,
500         NULL, HFILL }},
501     { &hf_sv_svID,
502       { "svID", "sv.svID",
503         FT_STRING, BASE_NONE, NULL, 0,
504         "VisibleString", HFILL }},
505     { &hf_sv_smpCnt,
506       { "smpCnt", "sv.smpCnt",
507         FT_UINT32, BASE_DEC, NULL, 0,
508         NULL, HFILL }},
509     { &hf_sv_confRef,
510       { "confRef", "sv.confRef",
511         FT_UINT32, BASE_DEC, NULL, 0,
512         "INTEGER_0_4294967295", HFILL }},
513     { &hf_sv_smpSynch,
514       { "smpSynch", "sv.smpSynch",
515         FT_INT32, BASE_DEC, VALS(sv_T_smpSynch_vals), 0,
516         NULL, HFILL }},
517     { &hf_sv_seqData,
518       { "seqData", "sv.seqData",
519         FT_BYTES, BASE_NONE, NULL, 0,
520         "Data", HFILL }},
521
522 /*--- End of included file: packet-sv-hfarr.c ---*/
523 #line 306 "../../asn1/sv/packet-sv-template.c"
524         };
525
526         /* List of subtrees */
527         static gint *ett[] = {
528                 &ett_sv,
529                 &ett_phsmeas,
530                 &ett_phsmeas_q,
531
532 /*--- Included file: packet-sv-ettarr.c ---*/
533 #line 1 "../../asn1/sv/packet-sv-ettarr.c"
534     &ett_sv_SampledValues,
535     &ett_sv_SavPdu,
536     &ett_sv_SEQUENCE_OF_ASDU,
537     &ett_sv_ASDU,
538
539 /*--- End of included file: packet-sv-ettarr.c ---*/
540 #line 314 "../../asn1/sv/packet-sv-template.c"
541         };
542
543         /* Register protocol */
544         proto_sv = proto_register_protocol(PNAME, PSNAME, PFNAME);
545         register_dissector("sv", dissect_sv, proto_sv);
546
547         /* Register fields and subtrees */
548         proto_register_field_array(proto_sv, hf, array_length(hf));
549         proto_register_subtree_array(ett, array_length(ett));
550
551         /* Register tap */
552         sv_tap = register_tap("sv");
553 }
554
555 /*--- proto_reg_handoff_sv --- */
556 void proto_reg_handoff_sv(void) {
557
558         dissector_handle_t sv_handle;
559         sv_handle = find_dissector("sv");
560
561         dissector_add_uint("ethertype", ETHERTYPE_IEC61850_SV, sv_handle);
562 }