summaryrefslogtreecommitdiffstats
path: root/epan/dvb_chartbl.c
blob: 334fd3733a49f261e7d8994afcc3b6557704c107 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/* dvb_chartbl.c
 * Routines for handling DVB-SI character tables (as defined in EN 300 468)
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "config.h"

#include <glib.h>

#include <epan/proto.h>
#include <epan/tvbuff.h>
#include <epan/value_string.h>

#include "dvb_chartbl.h"


static const value_string dvb_string_encoding_vals[] = {
   { DVB_ENCODING_INVALID,  "Incorrect length for encoding" },
   { DVB_ENCODING_RESERVED, "Reserved for future use" },
   { DVB_ENCODING_UNKNOWN,  "Unknown/undefined encoding" },

   { DVB_ENCODING_LATIN,    "Latin (default table)" },

   { DVB_ENCODING_ISO_8859_1,         "ISO/IEC 8859-1 (West European)" },
   { DVB_ENCODING_ISO_8859_2,         "ISO/IEC 8859-2 (East European)" },
   { DVB_ENCODING_ISO_8859_3,         "ISO/IEC 8859-3 (South European)" },
   { DVB_ENCODING_ISO_8859_4,         "ISO/IEC 8859-4 (North and North-East European)" },
   { DVB_ENCODING_ISO_8859_5,         "ISO/IEC 8859-5 (Latin/Cyrillic)" },
   { DVB_ENCODING_ISO_8859_6,         "ISO/IEC 8859-6 (Latin/Arabic)" },
   { DVB_ENCODING_ISO_8859_7,         "ISO/IEC 8859-7 (Latin/Greek)" },
   { DVB_ENCODING_ISO_8859_8,         "ISO/IEC 8859-8 (Latin/Hebrew)" },
   { DVB_ENCODING_ISO_8859_9,         "ISO/IEC 8859-9 (West European & Turkish)" },
   { DVB_ENCODING_ISO_8859_10,        "ISO/IEC 8859-10 (North European)" },
   { DVB_ENCODING_ISO_8859_11,        "ISO/IEC 8859-11 (Thai)" },
   { DVB_ENCODING_ISO_8859_13,        "ISO/IEC 8859-13 (Baltic)" },
   { DVB_ENCODING_ISO_8859_14,        "ISO/IEC 8859-14 (Celtic)" },
   { DVB_ENCODING_ISO_8859_15,        "ISO/IEC 8859-15 (West European)" },
   { DVB_ENCODING_ISO_10646_BMP,      "ISO/IEC 10646 Basic Multilingual Plane" },
   { DVB_ENCODING_KSX_1001,           "KSX 1001-2004 (Korean character set)" },
   { DVB_ENCODING_GB_2312,            "GB-2312-1980 (Simplified Chinese)" },
   { DVB_ENCODING_ISO_10646_BIG5,     "ISO/IEC 10646 BIG5 subset" },
   { DVB_ENCODING_ISO_10646_UTF8_BMP,
       "ISO/IEC 10646 Basic Multilingual Plane, UTF-8 encoded" },

   { 0, NULL }
};


static dvb_encoding_e
dvb_analyze_string_charset0(guint8 byte0)
{
    switch (byte0) {
        case 0x01:
            return DVB_ENCODING_ISO_8859_5;
        case 0x02:
            return DVB_ENCODING_ISO_8859_6;
        case 0x03:
            return DVB_ENCODING_ISO_8859_7;
        case 0x04:
            return DVB_ENCODING_ISO_8859_8;
        case 0x05:
            return DVB_ENCODING_ISO_8859_9;
        case 0x06:
            return DVB_ENCODING_ISO_8859_10;
        case 0x07:
            return DVB_ENCODING_ISO_8859_11;
        case 0x08:
            return DVB_ENCODING_RESERVED; /* was reserved for ISO-8859-12 */
        case 0x09:
            return DVB_ENCODING_ISO_8859_13;
        case 0x0A:
            return DVB_ENCODING_ISO_8859_14;
        case 0x0B:
            return DVB_ENCODING_ISO_8859_15;
        case 0x11:
            return DVB_ENCODING_ISO_10646_BMP;
        case 0x12:
            return DVB_ENCODING_KSX_1001;
        case 0x13:
            return DVB_ENCODING_GB_2312;
        case 0x14:
            return DVB_ENCODING_ISO_10646_BIG5;
        case 0x15:
            return DVB_ENCODING_ISO_10646_UTF8_BMP;

        default:
            return DVB_ENCODING_UNKNOWN;
    }
}


static dvb_encoding_e
dvb_analyze_string_charset0_10(guint16 byte12)
{
    switch (byte12) {
        case 0x0000:
             return DVB_ENCODING_RESERVED;
        case 0x0001:
         return DVB_ENCODING_ISO_8859_1;
        case 0x0002:
         return DVB_ENCODING_ISO_8859_2;
        case 0x0003:
         return DVB_ENCODING_ISO_8859_3;
        case 0x0004:
         return DVB_ENCODING_ISO_8859_4;
        case 0x0005:
         return DVB_ENCODING_ISO_8859_5;
        case 0x0006:
         return DVB_ENCODING_ISO_8859_6;
        case 0x0007:
         return DVB_ENCODING_ISO_8859_7;
        case 0x0008:
         return DVB_ENCODING_ISO_8859_8;
        case 0x0009:
         return DVB_ENCODING_ISO_8859_9;
        case 0x000A:
         return DVB_ENCODING_ISO_8859_10;
        case 0x000B:
         return DVB_ENCODING_ISO_8859_11;
        case 0x000C:
         return DVB_ENCODING_RESERVED;
        case 0x000D:
         return DVB_ENCODING_ISO_8859_13;
        case 0x000E:
         return DVB_ENCODING_ISO_8859_14;
        case 0x000F:
         return DVB_ENCODING_ISO_8859_15;

        default: /* 0x10 XX XX */
            return DVB_ENCODING_UNKNOWN;
    }
}


static dvb_encoding_e
dvb_analyze_string_charset0_1F(guint8 byte1)
{
   /* http://www.dvbservices.com/identifiers/encoding_type_id */

    switch (byte1) {
       case 0x00: /* 0x1F 0x00 */
          return DVB_ENCODING_RESERVED;
       case 0x01:
       case 0x02:
       case 0x03:
       case 0x04:
          /* XXX: BBC */
          return DVB_ENCODING_RESERVED;
       case 0x05:
       case 0x06:
          /* XXX: Malaysian Technical Standards Forum Bhd */
          return DVB_ENCODING_RESERVED;

       default: /* 0x1F XX */
          return DVB_ENCODING_RESERVED;
    }
}


guint
dvb_analyze_string_charset(tvbuff_t *tvb, int offset, int length, dvb_encoding_e *encoding)
{
   if (length >= 1) {
      guint8 byte0 = tvb_get_guint8(tvb, offset + 0);

      if (byte0 >= 0x20) {
         /* the first byte is a normal character, not the number of a character table */
         *encoding = DVB_ENCODING_LATIN;
         return 0;

      } else if (byte0 == 0x1F) {
         if (length >= 2) {
            *encoding = dvb_analyze_string_charset0_1F(tvb_get_guint8(tvb, offset + 1));
            return 2;
         }
         *encoding = DVB_ENCODING_INVALID;
         return 1;

      } else if (byte0 >= 0x16) { /* 16 ... 1E */
         *encoding = DVB_ENCODING_RESERVED;
         return 1;

      } else if (byte0 == 0x10) {
         if (length >= 3) {
            *encoding = dvb_analyze_string_charset0_10(tvb_get_ntohs(tvb, offset + 1));
            return 3;
         }
         *encoding = DVB_ENCODING_INVALID;
         return 1;

      } else if ((byte0 >= 0x0C && byte0 <= 0x0F)) {
         *encoding = DVB_ENCODING_RESERVED;
         return 1;
      } else {
         *encoding = dvb_analyze_string_charset0(byte0);
         return 1;
      }
   } else
      *encoding = DVB_ENCODING_LATIN;

   return 0;
}


guint
dvb_enc_to_item_enc(dvb_encoding_e encoding)
{
   /* XXX: take ISO control codes into account,
      e.g. 0x86 - turn emphasis on ; 0x87 - turn emphasis off */

   switch (encoding) {
      case DVB_ENCODING_ISO_8859_1:
         return ENC_ISO_8859_1 | ENC_NA;

      case DVB_ENCODING_ISO_8859_2:
         return ENC_ISO_8859_2 | ENC_NA;

      case DVB_ENCODING_ISO_8859_3:
         return ENC_ISO_8859_3 | ENC_NA;

      case DVB_ENCODING_ISO_8859_4:
         return ENC_ISO_8859_4 | ENC_NA;

      case DVB_ENCODING_ISO_8859_5:
         return ENC_ISO_8859_5 | ENC_NA;

      case DVB_ENCODING_ISO_8859_6:
         return ENC_ISO_8859_6 | ENC_NA;

      case DVB_ENCODING_ISO_8859_7:
         return ENC_ISO_8859_7 | ENC_NA;

      case DVB_ENCODING_ISO_8859_8:
         return ENC_ISO_8859_8 | ENC_NA;

      case DVB_ENCODING_ISO_8859_9:
         return ENC_ISO_8859_9 | ENC_NA;

      case DVB_ENCODING_ISO_8859_10:
         return ENC_ISO_8859_10 | ENC_NA;

      case DVB_ENCODING_ISO_8859_11:
         return ENC_ISO_8859_11 | ENC_NA;

      case DVB_ENCODING_ISO_8859_13:
         return ENC_ISO_8859_13 | ENC_NA;

      case DVB_ENCODING_ISO_8859_14:
         return ENC_ISO_8859_14 | ENC_NA;

      case DVB_ENCODING_ISO_8859_15:
         return ENC_ISO_8859_15 | ENC_NA;

      case DVB_ENCODING_ISO_10646_UTF8_BMP:
         return ENC_UTF_8 | ENC_NA;

      default: /* not supported */
         return ENC_ASCII | ENC_NA;
   }
}


void
dvb_add_chartbl(proto_tree *tree, int hf,
        tvbuff_t *tvb, gint offset, gint length, dvb_encoding_e encoding)
{
    if (tree == NULL)
        return;

    if (length==0) {
        proto_item *pi;

        pi = proto_tree_add_bytes_format(tree, hf, tvb, 0, 0, NULL,
                "Default character table (Latin)");
        proto_item_set_generated(pi);
    }
    else {
        proto_tree_add_bytes_format_value(tree, hf,
            tvb, offset, length, NULL, "%s (%s)",
            val_to_str_const(encoding, dvb_string_encoding_vals, "Unknown"),
            tvb_bytes_to_str_punct(PNODE_POOL(tree), tvb, offset, length, ' '));
    }
}

/*
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 4
 * tab-width: 8
 * indent-tabs-mode: nil
 * End:
 *
 * vi: set shiftwidth=4 tabstop=8 expandtab:
 * :indentSize=4:tabSize=8:noTabs=true:
 */