epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-r09.c
blob6936d0dd14b72cad6325492e0b7342d2877f5299
1 /*
2 * R09.x public transport priority telegrams
4 * Anlagen zu VOEV 04.05 "LSA/R09.14 and R09.16"
5 * https://www.vdv.de/voev-04-05-1-erg.pdfx
7 * Copyright 2020, Tomas Kukosa
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 #include <epan/packet.h>
20 void proto_register_r09(void);
21 void proto_reg_handoff_r09(void);
23 #define PNAME "R09.x"
24 #define PSNAME "R09"
25 #define PFNAME "r09"
27 static int proto_r09;
28 static int hf_r09_modus;
29 static int hf_r09_ty;
30 static int hf_r09_tl;
31 static int hf_r09_zv;
32 static int hf_r09_zw;
33 static int hf_r09_mp8;
34 static int hf_r09_mp16;
35 static int hf_r09_pr;
36 static int hf_r09_ha;
37 static int hf_r09_ln;
38 static int hf_r09_kn;
39 static int hf_r09_zn;
40 static int hf_r09_zl;
41 static int hf_r09_fn;
42 static int hf_r09_un;
44 static int ett_r09;
46 static dissector_handle_t r09_handle;
48 static const value_string r09_zv_vals[] = {
49 { 0x00, "Verspätung" },
50 { 0x01, "Verfrühung/Vorsprung" },
51 {0, NULL}
54 static const value_string r09_ha_vals[] = {
55 { 0x00, "Ohne Bedeutung" },
56 { 0x01, "Taste 'gerade' betätigt" },
57 { 0x02, "Taste 'links' betätigt" },
58 { 0x03, "Taste 'rechts' betätigt" },
59 {0, NULL}
62 static int
63 dissect_r09(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
64 proto_item *ti= NULL;
65 proto_tree *r09_tree = NULL;
66 uint8_t ib1, ib2;
67 uint8_t ty, tl;
68 uint16_t mp;
69 const char *r09x_str;
71 ib1 = tvb_get_uint8(tvb, 0);
72 ty = ib1 & 0x0F;
74 if (ib1 != 0x91) {
75 return 0;
78 ib2 = tvb_get_uint8(tvb, 1);
79 tl = ib2 & 0x0F;
81 r09x_str = wmem_strdup_printf(pinfo->pool, "R09.%u%u", ty, tl);
82 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", r09x_str);
84 ti = proto_tree_add_protocol_format(tree, proto_r09, tvb, 0, -1, "%s", r09x_str);
85 r09_tree = proto_item_add_subtree(ti, ett_r09);
87 /* Infobyte 1 */
88 proto_tree_add_item(r09_tree, hf_r09_modus, tvb, 0, 1, ENC_BIG_ENDIAN);
89 proto_tree_add_item(r09_tree, hf_r09_ty, tvb, 0, 1, ENC_BIG_ENDIAN);
91 /* Infobyte 2 */
92 proto_tree_add_item(r09_tree, hf_r09_zv, tvb, 1, 1, ENC_BIG_ENDIAN);
93 proto_tree_add_item(r09_tree, hf_r09_zw, tvb, 1, 1, ENC_BIG_ENDIAN);
94 proto_tree_add_item(r09_tree, hf_r09_tl, tvb, 1, 1, ENC_BIG_ENDIAN);
96 if (tl == 0) {
97 /* Infobyte 3 */
98 proto_tree_add_item(r09_tree, hf_r09_mp8, tvb, 2, 1, ENC_BIG_ENDIAN);
99 mp = tvb_get_uint8(tvb, 2);
100 } else {
101 /* Infobyte 3, Zusatzbyte 1 */
102 proto_tree_add_item(r09_tree, hf_r09_mp16, tvb, 2, 2, ENC_BIG_ENDIAN);
103 mp = tvb_get_uint16(tvb, 2, ENC_BIG_ENDIAN);
105 col_append_fstr(pinfo->cinfo, COL_INFO, " MP=%u", mp);
107 if (tl >= 2) {
108 /* Zusatzbyte 2 */
109 proto_tree_add_item(r09_tree, hf_r09_pr, tvb, 4, 1, ENC_BIG_ENDIAN);
110 proto_tree_add_item(r09_tree, hf_r09_ha, tvb, 4, 1, ENC_BIG_ENDIAN);
113 if (tl >= 3) {
114 /* Zusatzbyte 2, 3 */
115 proto_tree_add_item(r09_tree, hf_r09_ln, tvb, 4, 2,
116 ENC_BCD_DIGITS_0_9 | ENC_BIG_ENDIAN | ENC_BCD_SKIP_FIRST);
119 if (tl >= 4) {
120 /* Zusatzbyte 4 */
121 proto_tree_add_item(r09_tree, hf_r09_kn, tvb, 6, 1, ENC_BCD_DIGITS_0_9 | ENC_BIG_ENDIAN);
124 if (tl >= 6) {
125 /* Zusatzbyte 5, 6 */
126 proto_tree_add_item(r09_tree, hf_r09_zn, tvb, 7, 2,
127 ENC_BCD_DIGITS_0_9 | ENC_BIG_ENDIAN | ENC_BCD_ODD_NUM_DIG);
130 if (tl == 6) {
131 /* Zusatzbyte 6 */
132 proto_tree_add_item(r09_tree, hf_r09_zl, tvb, 8, 1, ENC_BIG_ENDIAN);
135 if (tl == 8) {
136 /* Zusatzbyte 6, 7, 8 */
137 proto_tree_add_item(r09_tree, hf_r09_fn, tvb, 8, 2,
138 ENC_BCD_DIGITS_0_9 | ENC_BIG_ENDIAN | ENC_BCD_SKIP_FIRST);
139 proto_tree_add_item(r09_tree, hf_r09_un, tvb, 10, 1, ENC_BCD_DIGITS_0_9 | ENC_BIG_ENDIAN);
142 return tvb_captured_length(tvb);
145 void
146 proto_register_r09(void)
149 static hf_register_info hf[] = {
150 { &hf_r09_modus, { "Modus", "r09.modus",
151 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}
153 { &hf_r09_ty, { "TY", "r09.ty",
154 FT_UINT8, BASE_DEC, NULL, 0x0F, "Typ", HFILL}
156 { &hf_r09_zv, { "ZV", "r09.zv",
157 FT_UINT8, BASE_DEC, VALS(r09_zv_vals), 0x80, "Vorzeichen einer Fahrplanabweichung", HFILL}
159 { &hf_r09_zw, { "ZW", "r09.zw",
160 FT_UINT8, BASE_DEC, NULL, 0x70, "Betrag einer Fahrplanabweichung", HFILL}
162 { &hf_r09_tl, { "TL", "r09.tl",
163 FT_UINT8, BASE_DEC, NULL, 0x0F, "Anzahl der Zusatzbytes", HFILL}
165 { &hf_r09_mp8, { "MP", "r09.mp",
166 FT_UINT8, BASE_DEC_HEX, NULL, 0x00, "Meldepunktnummer", HFILL}
168 { &hf_r09_mp16, { "MP", "r09.mp",
169 FT_UINT16, BASE_DEC_HEX, NULL, 0x00, "Meldepunktnummer", HFILL}
171 { &hf_r09_pr, { "PR", "r09.pr",
172 FT_UINT8, BASE_DEC, NULL, 0xC0, "Priorität", HFILL}
174 { &hf_r09_ha, { "HA", "r09.ha",
175 FT_UINT8, BASE_DEC, VALS(r09_ha_vals), 0x30, "Anforderung manuell ausgelöst", HFILL}
177 { &hf_r09_ln, { "LN", "r09.ln",
178 FT_STRING, BASE_NONE, NULL, 0x00, "Liniennummer", HFILL}
180 { &hf_r09_kn, { "KN", "r09.kn",
181 FT_STRING, BASE_NONE, NULL, 0x00, "Kursnummer", HFILL}
183 { &hf_r09_zn, { "ZN", "r09.zn",
184 FT_STRING, BASE_NONE, NULL, 0x00, "Zielnummer", HFILL}
186 { &hf_r09_zl, { "ZL", "r09.zl",
187 FT_UINT8, BASE_DEC, NULL, 0x07, "Zuglänge", HFILL}
189 { &hf_r09_fn, { "FN", "r09.fn",
190 FT_STRING, BASE_NONE, NULL, 0x00, "Fahrzeugnummer", HFILL}
192 { &hf_r09_un, { "UN", "r09.un",
193 FT_STRING, BASE_NONE, NULL, 0x00, "Unternehmer", HFILL}
197 static int* ett[] = {
198 &ett_r09,
201 proto_r09 = proto_register_protocol(PNAME, PSNAME, PFNAME);
203 proto_register_subtree_array(ett, array_length(ett));
204 proto_register_field_array(proto_r09, hf,array_length(hf));
206 r09_handle = register_dissector(PFNAME, dissect_r09, proto_r09);
210 void
211 proto_reg_handoff_r09(void)
214 if (find_dissector_table("cam.ptat")) {
215 dissector_add_uint("cam.ptat", 1, r09_handle);