Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-ansi_637.c
Line
Count
Source
1
/* packet-ansi_637.c
2
 * Routines for ANSI IS-637-A/D (SMS) dissection
3
 *
4
 * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
5
 * In association with Telos Technology Inc.
6
 * Copyright 2013, Michael Lum <michael.lum [AT] starsolutions.com>
7
 * In association with Star Solutions, Inc. (Updated for some of IS-637-D and CMAS)
8
 *
9
 * Title                3GPP2                   Other
10
 *
11
 *   Short Message Service
12
 *                      3GPP2 C.S0015-0         TIA/EIA-637-A
13
 *                      3GPP2 C.S0015-C v1.0    TIA/EIA-637-D
14
 *                      3GPP2 C.R1001-H v1.0    TSB-58-I (or J?)
15
 *
16
 * For CMAS See:
17
 *   TIA-1149.1 or
18
 *   (520-10030206__Editor_TIA-1149-0-1_CMASoverCDMA_Publication.pdf)
19
 *
20
 * Wireshark - Network traffic analyzer
21
 * By Gerald Combs <gerald@wireshark.org>
22
 * Copyright 1998 Gerald Combs
23
 *
24
 * SPDX-License-Identifier: GPL-2.0-or-later
25
 */
26
27
#include "config.h"
28
29
#include <epan/packet.h>
30
#include <epan/expert.h>
31
#include <epan/strutil.h>
32
#include <epan/tfs.h>
33
#include <wsutil/array.h>
34
35
#include "packet-gsm_sms.h"
36
#include "packet-ansi_a.h"
37
38
void proto_register_ansi_637(void);
39
void proto_reg_handoff_ansi_637(void);
40
41
/*
42
 * Masks the number of bits given by len starting at the given offset
43
 * MBoffset should be from 0 to 7 and MBlen 1 to 8
44
 * MASK_B(0, 1) = 0x80
45
 * MASK_B(0, 8) = 0xff
46
 * MASK_B(4, 3) = 0x0e
47
 * MASK_B(7, 1) = 0x01
48
 */
49
#define MASK_B(MBoffset, MBlen) \
50
    ((0xff >> (MBoffset)) & (0xff << (8 - ((MBoffset) + (MBlen)))))
51
52
static const value_string ansi_tele_msg_type_strings[] = {
53
    { 1,        "Deliver (mobile-terminated only)" },
54
    { 2,        "Submit (mobile-originated only)" },
55
    { 3,        "Cancellation (mobile-originated only)" },
56
    { 4,        "Delivery Acknowledgement (mobile-terminated only)" },
57
    { 5,        "User Acknowledgement (either direction)" },
58
    { 6,        "Read Acknowledgement (either direction)" },
59
    { 7,        "Deliver Report (mobile-originated only)" },
60
    { 8,        "Submit Report (mobile-terminated only)" },
61
    { 0, NULL }
62
};
63
64
static const value_string ansi_tele_msg_header_ind_strings[] = {
65
    { 0,        "The User Data field contains only the short message" },
66
    { 1,        "The User Data field contains a Header in addition to the short message" },
67
    { 0, NULL }
68
};
69
70
static const value_string ansi_tele_msg_status_strings[] = {
71
    { 0x00,     "Message accepted" },
72
    { 0x01,     "Message deposited to Internet" },
73
    { 0x02,     "Message delivered" },
74
    { 0x03,     "Message cancelled" },
75
    { 0x84,     "Network congestion" },
76
    { 0x85,     "Network error" },
77
    { 0x9f,     "Unknown error" },
78
    { 0xc4,     "Network congestion" },
79
    { 0xc5,     "Network error" },
80
    { 0xc6,     "Cancel failed" },
81
    { 0xc7,     "Blocked destination" },
82
    { 0xc8,     "Text too long" },
83
    { 0xc9,     "Duplicate message" },
84
    { 0xca,     "Invalid destination" },
85
    { 0xcd,     "Message expired" },
86
    { 0xdf,     "Unknown error" },
87
    { 0, NULL }
88
};
89
static value_string_ext ansi_tele_msg_status_strings_ext = VALUE_STRING_EXT_INIT(ansi_tele_msg_status_strings);
90
91
static const value_string ansi_tele_id_strings[] = {
92
    { 1,        "Reserved for maintenance" },
93
    { 4096,     "AMPS Extended Protocol Enhanced Services" },
94
    { 4097,     "CDMA Cellular Paging Teleservice" },
95
    { 4098,     "CDMA Cellular Messaging Teleservice" },
96
    { 4099,     "CDMA Voice Mail Notification" },
97
    { 4100,     "CDMA Wireless Application Protocol (WAP)" },
98
    { 4101,     "CDMA Wireless Enhanced Messaging Teleservice (WEMT)" },
99
    { 0, NULL }
100
};
101
30
#define INTERNAL_BROADCAST_TELE_ID      65535
102
103
static const value_string ansi_tele_param_strings[] = {
104
    { 0x00,     "Message Identifier" },
105
    { 0x01,     "User Data" },
106
    { 0x02,     "User Response Code" },
107
    { 0x03,     "Message Center Time Stamp" },
108
    { 0x04,     "Validity Period - Absolute" },
109
    { 0x05,     "Validity Period - Relative" },
110
    { 0x06,     "Deferred Delivery Time - Absolute" },
111
    { 0x07,     "Deferred Delivery Time - Relative" },
112
    { 0x08,     "Priority Indicator" },
113
    { 0x09,     "Privacy Indicator" },
114
    { 0x0a,     "Reply Option" },
115
    { 0x0b,     "Number of Messages" },
116
    { 0x0c,     "Alert on Message Delivery" },
117
    { 0x0d,     "Language Indicator" },
118
    { 0x0e,     "Call-Back Number" },
119
    { 0x0f,     "Message Display Mode" },
120
    { 0x10,     "Multiple Encoding User Data" },
121
    { 0x11,     "Message Deposit Index" },
122
    { 0x12,     "Service Category Program Data" },
123
    { 0x13,     "Service Category Program Results" },
124
    { 0x14,     "Message status" },
125
    { 0x15,     "TP-Failure cause" },
126
    { 0x16,     "Enhanced VMN" },
127
    { 0x17,     "Enhanced VMN Ack" },
128
    { 0, NULL }
129
};
130
static value_string_ext ansi_tele_param_strings_ext = VALUE_STRING_EXT_INIT(ansi_tele_param_strings);
131
132
0
#define ANSI_TRANS_MSG_TYPE_BROADCAST   1
133
134
static const value_string ansi_trans_msg_type_strings[] = {
135
    { 0,        "Point-to-Point" },
136
    { 1,        "Broadcast" },
137
    { 2,        "Acknowledge" },
138
    { 0, NULL }
139
};
140
141
static const value_string ansi_trans_param_strings[] = {
142
    { 0x00,     "Teleservice Identifier" },
143
    { 0x01,     "Service Category" },
144
    { 0x02,     "Originating Address" },
145
    { 0x03,     "Originating Subaddress" },
146
    { 0x04,     "Destination Address" },
147
    { 0x05,     "Destination Subaddress" },
148
    { 0x06,     "Bearer Reply Option" },
149
    { 0x07,     "Cause Codes" },
150
    { 0x08,     "Bearer Data" },
151
    { 0, NULL }
152
};
153
154
static const value_string ansi_tele_month_strings[] = {
155
    { 0,        "January" },
156
    { 1,        "February" },
157
    { 2,        "March" },
158
    { 3,        "April" },
159
    { 4,        "May" },
160
    { 5,        "June" },
161
    { 6,        "July" },
162
    { 7,        "August" },
163
    { 8,        "September" },
164
    { 9,        "October" },
165
    { 10,       "November" },
166
    { 11,       "December" },
167
    { 0, NULL }
168
};
169
170
static const value_string ansi_trans_subaddr_odd_even_ind_strings[] = {
171
    { 0x00,     "Even" },
172
    { 0x01,     "Odd" },
173
    { 0, NULL }
174
};
175
176
static const true_false_string tfs_digit_mode_8bit_4bit = {
177
    "8-bit ASCII",
178
    "4-bit DTMF"
179
};
180
181
static const true_false_string tfs_number_mode_data_ansi_t1 = {
182
    "Data Network Address",
183
    "ANSI T1.607"
184
};
185
186
/*
187
 * from Table 2.7.1.3.2.4-4. Representation of DTMF Digits
188
 * 3GPP2 C.S0005-C (IS-2000 aka cdma2000)
189
 */
190
static const unsigned char air_digits[] = {
191
  /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
192
     '?','1','2','3','4','5','6','7','8','9','0','*','#','?','?','?'
193
};
194
195
/* Initialize the protocol and registered fields */
196
static int proto_ansi_637_tele;
197
static int proto_ansi_637_trans;
198
199
static int hf_ansi_637_trans_param_id;
200
static int hf_ansi_637_trans_length;
201
static int hf_ansi_637_trans_bin_addr;
202
static int hf_ansi_637_trans_tele_id;
203
static int hf_ansi_637_trans_srvc_cat;
204
static int hf_ansi_637_trans_addr_param_digit_mode;
205
static int hf_ansi_637_trans_addr_param_number_mode;
206
static int hf_ansi_637_trans_addr_param_ton;
207
static int hf_ansi_637_trans_addr_param_plan;
208
static int hf_ansi_637_trans_addr_param_num_fields;
209
static int hf_ansi_637_trans_addr_param_number;
210
static int hf_ansi_637_trans_subaddr_type;
211
static int hf_ansi_637_trans_subaddr_odd_even_ind;
212
static int hf_ansi_637_trans_subaddr_num_fields;
213
static int hf_ansi_637_trans_bearer_reply_seq_num;
214
static int hf_ansi_637_trans_cause_codes_seq_num;
215
static int hf_ansi_637_trans_cause_codes_error_class;
216
static int hf_ansi_637_trans_cause_codes_code;
217
218
static int hf_ansi_637_tele_msg_type;
219
static int hf_ansi_637_tele_msg_id;
220
static int hf_ansi_637_tele_length;
221
static int hf_ansi_637_tele_msg_status;
222
static int hf_ansi_637_tele_msg_header_ind;
223
static int hf_ansi_637_tele_msg_rsvd;
224
static int hf_ansi_637_tele_subparam_id;
225
static int hf_ansi_637_tele_user_data_text;
226
static int hf_ansi_637_tele_user_data_encoding;
227
static int hf_ansi_637_tele_user_data_message_type;
228
static int hf_ansi_637_tele_user_data_num_fields;
229
static int hf_ansi_637_tele_response_code;
230
static int hf_ansi_637_tele_message_center_ts_year;
231
static int hf_ansi_637_tele_message_center_ts_month;
232
static int hf_ansi_637_tele_message_center_ts_day;
233
static int hf_ansi_637_tele_message_center_ts_hours;
234
static int hf_ansi_637_tele_message_center_ts_minutes;
235
static int hf_ansi_637_tele_message_center_ts_seconds;
236
static int hf_ansi_637_tele_validity_period_ts_year;
237
static int hf_ansi_637_tele_validity_period_ts_month;
238
static int hf_ansi_637_tele_validity_period_ts_day;
239
static int hf_ansi_637_tele_validity_period_ts_hours;
240
static int hf_ansi_637_tele_validity_period_ts_minutes;
241
static int hf_ansi_637_tele_validity_period_ts_seconds;
242
static int hf_ansi_637_tele_validity_period_relative_validity;
243
static int hf_ansi_637_tele_deferred_del_ts_year;
244
static int hf_ansi_637_tele_deferred_del_ts_month;
245
static int hf_ansi_637_tele_deferred_del_ts_day;
246
static int hf_ansi_637_tele_deferred_del_ts_hours;
247
static int hf_ansi_637_tele_deferred_del_ts_minutes;
248
static int hf_ansi_637_tele_deferred_del_ts_seconds;
249
static int hf_ansi_637_tele_deferred_del_relative;
250
static int hf_ansi_637_tele_priority_indicator;
251
static int hf_ansi_637_tele_privacy_indicator;
252
static int hf_ansi_637_tele_reply_option_user_ack_req;
253
static int hf_ansi_637_tele_reply_option_dak_req;
254
static int hf_ansi_637_tele_reply_option_read_ack_req;
255
static int hf_ansi_637_tele_reply_option_report_req;
256
static int hf_ansi_637_tele_num_messages;
257
static int hf_ansi_637_tele_alert_msg_delivery_priority;
258
static int hf_ansi_637_tele_language;
259
static int hf_ansi_637_tele_cb_num_digit_mode;
260
static int hf_ansi_637_tele_cb_num_ton;
261
static int hf_ansi_637_tele_cb_num_plan;
262
static int hf_ansi_637_tele_cb_num_num_fields;
263
static int hf_ansi_637_tele_cb_num_num_fields07f8;
264
static int hf_ansi_637_tele_cb_num_number;
265
static int hf_ansi_637_tele_msg_display_mode;
266
static int hf_ansi_637_tele_msg_deposit_idx;
267
static int hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat;
268
static int hf_ansi_637_tele_srvc_cat_prog_results_result;
269
static int hf_ansi_637_tele_msg_status_error_class;
270
static int hf_ansi_637_tele_msg_status_code;
271
static int hf_ansi_637_tele_tp_failure_cause_value;
272
static int hf_ansi_637_reserved_bits_8_generic;
273
static int hf_ansi_637_reserved_bits_8_03;
274
static int hf_ansi_637_reserved_bits_8_07;
275
static int hf_ansi_637_reserved_bits_8_0f;
276
static int hf_ansi_637_reserved_bits_8_3f;
277
static int hf_ansi_637_reserved_bits_8_7f;
278
static int hf_ansi_637_reserved_bits_16_generic;
279
static int hf_ansi_637_tele_cmas_encoding;
280
static int hf_ansi_637_tele_cmas_num_fields;
281
static int hf_ansi_637_tele_cmas_protocol_version;
282
static int hf_ansi_637_tele_cmas_record_type;
283
static int hf_ansi_637_tele_cmas_record_len;
284
static int hf_ansi_637_tele_cmas_char_set;
285
static int hf_ansi_637_tele_cmas_category;
286
static int hf_ansi_637_tele_cmas_response_type;
287
static int hf_ansi_637_tele_cmas_severity;
288
static int hf_ansi_637_tele_cmas_urgency;
289
static int hf_ansi_637_tele_cmas_certainty;
290
static int hf_ansi_637_tele_cmas_identifier;
291
static int hf_ansi_637_tele_cmas_alert_handling;
292
static int hf_ansi_637_tele_cmas_expires_year;
293
static int hf_ansi_637_tele_cmas_expires_month;
294
static int hf_ansi_637_tele_cmas_expires_day;
295
static int hf_ansi_637_tele_cmas_expires_hours;
296
static int hf_ansi_637_tele_cmas_expires_minutes;
297
static int hf_ansi_637_tele_cmas_expires_seconds;
298
static int hf_ansi_637_tele_cmas_language;
299
static int hf_ansi_637_tele_cmas_text;
300
static int hf_ansi_637_tele_mult_enc_user_data_encoding;
301
static int hf_ansi_637_tele_mult_enc_user_data_num_fields;
302
static int hf_ansi_637_tele_mult_enc_user_data_text;
303
static int hf_ansi_637_tele_srvc_cat_prog_data_encoding;
304
static int hf_ansi_637_tele_srvc_cat_prog_data_operation_code;
305
static int hf_ansi_637_tele_srvc_cat_prog_data_category;
306
static int hf_ansi_637_tele_srvc_cat_prog_data_language;
307
static int hf_ansi_637_tele_srvc_cat_prog_data_max_messages;
308
static int hf_ansi_637_tele_srvc_cat_prog_data_alert_option;
309
static int hf_ansi_637_tele_srvc_cat_prog_data_num_fields;
310
static int hf_ansi_637_tele_srvc_cat_prog_data_text;
311
312
/* Initialize the subtree pointers */
313
static int ett_ansi_637_tele;
314
static int ett_ansi_637_trans;
315
static int ett_ansi_637_header_ind;
316
static int ett_params;
317
318
static expert_field ei_ansi_637_extraneous_data;
319
static expert_field ei_ansi_637_short_data;
320
static expert_field ei_ansi_637_unexpected_length;
321
static expert_field ei_ansi_637_unknown_encoding;
322
static expert_field ei_ansi_637_failed_conversion;
323
static expert_field ei_ansi_637_unknown_cmas_record_type;
324
static expert_field ei_ansi_637_unknown_trans_parameter;
325
static expert_field ei_ansi_637_no_trans_parameter_dissector;
326
static expert_field ei_ansi_637_unknown_tele_parameter;
327
static expert_field ei_ansi_637_no_tele_parameter_dissector;
328
329
static dissector_handle_t ansi_637_tele_handle;
330
static dissector_handle_t ansi_637_trans_handle;
331
static dissector_handle_t ansi_637_trans_app_handle;
332
333
static uint32_t ansi_637_trans_tele_id;
334
static char ansi_637_bigbuf[1024];
335
static dissector_table_t tele_dissector_table;
336
static proto_tree *g_tree;
337
338
/* PARAM FUNCTIONS */
339
340
#define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
341
0
    if ((edc_len) > (edc_max_len)) \
342
0
    { \
343
0
        proto_tree_add_expert(tree, pinfo, &ei_ansi_637_extraneous_data, \
344
0
            tvb, offset, (edc_len) - (edc_max_len)); \
345
0
    }
346
347
#define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
348
0
    if ((sdc_len) < (sdc_min_len)) \
349
0
    { \
350
0
        proto_tree_add_expert(tree, pinfo, &ei_ansi_637_short_data, \
351
0
            tvb, offset, (sdc_len)); \
352
0
        return; \
353
0
    }
354
355
#define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
356
0
    if ((edc_len) != (edc_eq_len)) \
357
0
    { \
358
0
        proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unexpected_length, \
359
0
            tvb, offset, (edc_len)); \
360
0
        return; \
361
0
    }
362
363
/*
364
 * text decoding helper
365
 *
366
 * there are 'unused_bits' bits remaining in the octet at 'offset'
367
 */
368
static void
369
text_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint8_t encoding,
370
             uint8_t num_fields, uint16_t num_bits, uint8_t unused_bits, uint8_t fill_bits, int hf_index)
371
0
{
372
0
    uint8_t     bit;
373
0
    uint32_t    required_octs;
374
0
    tvbuff_t    *tvb_out = NULL;
375
376
0
    const unsigned char *ustr = NULL;
377
378
    /*
379
     * has to be big enough to hold all of the 'shifted' bits
380
     */
381
0
    required_octs = (num_bits + fill_bits + 7) / 8;
382
383
    /*
384
     * shift the bits to octet alignment in 'buf'
385
     */
386
0
    tvb_out =
387
0
        tvb_new_octet_aligned(tvb, (offset * 8) + (8 - unused_bits), (required_octs * 8));
388
0
    add_new_data_source(pinfo, tvb_out, "Characters");
389
390
0
    switch (encoding)
391
0
    {
392
0
    default:
393
0
        proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unknown_encoding, tvb, offset, required_octs);
394
0
        return;
395
396
0
    case 0x00: /* Octet, unspecified */
397
398
0
        proto_tree_add_string(tree, hf_index, tvb_out, 0, required_octs,
399
0
            tvb_bytes_to_str(pinfo->pool, tvb_out, 0, required_octs));
400
0
        break;
401
402
0
    case 0x02: /* 7-bit ASCII */
403
404
0
        offset = 0;
405
0
        bit = 0;
406
407
0
        proto_tree_add_ascii_7bits_item(tree, hf_index, tvb_out, (offset << 3) + bit, num_fields);
408
0
        break;
409
410
0
    case 0x03: /* IA5 */
411
412
0
        offset = 0;
413
0
        bit = 0;
414
415
0
        ustr = (uint8_t*)tvb_get_ascii_7bits_string(pinfo->pool, tvb_out, (offset << 3) + bit, num_fields);
416
0
        IA5_7BIT_decode((uint8_t*)ansi_637_bigbuf, ustr, num_fields);
417
418
0
        proto_tree_add_string(tree, hf_index, tvb_out, 0,
419
0
            required_octs, ansi_637_bigbuf);
420
0
        break;
421
422
0
    case 0x04: /* UNICODE */
423
424
0
        offset = 0;
425
426
0
        proto_tree_add_item(tree, hf_index, tvb_out, offset, num_fields*2, ENC_UCS_2|ENC_BIG_ENDIAN);
427
0
        break;
428
429
0
    case 0x07: /* Latin/Hebrew */
430
431
0
        offset = 0;
432
433
0
        proto_tree_add_item(tree, hf_index, tvb_out, offset, num_fields, ENC_ISO_8859_8|ENC_NA);
434
0
        break;
435
436
0
    case 0x08: /* Latin */
437
438
0
        offset = 0;
439
440
0
        proto_tree_add_item(tree, hf_index, tvb_out, offset, num_fields, ENC_ISO_8859_1|ENC_NA);
441
0
        break;
442
443
0
    case 0x09: /* GSM 7-bit default alphabet */
444
445
0
        offset = 0;
446
0
        bit = fill_bits;
447
448
0
        proto_tree_add_ts_23_038_7bits_packed_item(tree, hf_index, tvb_out, (offset << 3) + bit, num_fields);
449
0
        break;
450
451
0
    case 0x10: /* KSC5601 (Korean) */
452
453
0
        offset = 0;
454
455
0
        proto_tree_add_item_ret_string(tree, hf_index, tvb_out, offset, required_octs, ENC_EUC_KR|ENC_NA, pinfo->pool, &ustr);
456
0
        if (ustr == NULL)
457
0
            proto_tree_add_expert_format(tree, pinfo, &ei_ansi_637_failed_conversion, tvb_out, offset, required_octs,
458
0
                "Failed iconv conversion on EUC-KR (report to wireshark.org)");
459
0
        break;
460
0
    }
461
0
}
462
463
static void
464
tele_param_timestamp(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, unsigned len, uint32_t offset, int hf_year, int hf_month, int hf_day, int hf_hours, int hf_minutes, int hf_seconds)
465
0
{
466
0
    uint8_t     oct;
467
0
    uint16_t    temp;
468
0
    const char *str = NULL;
469
470
0
    EXACT_DATA_CHECK(len, 6);
471
472
0
    oct = tvb_get_uint8(tvb, offset);
473
474
0
    temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
475
0
    temp += ((temp < 96) ? 2000 : 1900);
476
477
0
    proto_tree_add_uint_format_value(tree, hf_year, tvb, offset, 1,
478
0
        oct,
479
0
        "%u (%02x)",
480
0
        temp, oct);
481
482
0
    offset += 1;
483
484
0
    oct = tvb_get_uint8(tvb, offset);
485
486
0
    temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f) - 1;
487
488
0
    str = val_to_str_const(temp, ansi_tele_month_strings, "Invalid");
489
0
    proto_tree_add_uint_format_value(tree, hf_month, tvb, offset, 1,
490
0
        oct,
491
0
        "%s (%02x)",
492
0
        str, oct);
493
494
0
    offset += 1;
495
496
0
    oct = tvb_get_uint8(tvb, offset);
497
498
0
    temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
499
500
0
    proto_tree_add_uint_format_value(tree, hf_day, tvb, offset, 1,
501
0
        oct,
502
0
        "%u",
503
0
        temp);
504
505
0
    offset += 1;
506
507
0
    oct = tvb_get_uint8(tvb, offset);
508
509
0
    temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
510
511
0
    proto_tree_add_uint_format_value(tree, hf_hours, tvb, offset, 1,
512
0
        oct,
513
0
        "%u",
514
0
        temp);
515
516
0
    offset += 1;
517
518
0
    oct = tvb_get_uint8(tvb, offset);
519
520
0
    temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
521
522
0
    proto_tree_add_uint_format_value(tree, hf_minutes, tvb, offset, 1, oct,
523
0
        "%u",
524
0
        temp);
525
526
0
    offset += 1;
527
528
0
    oct = tvb_get_uint8(tvb, offset);
529
530
0
    temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
531
532
0
    proto_tree_add_uint_format_value(tree, hf_seconds, tvb, offset, 1,
533
0
        oct,
534
0
        "%u",
535
0
        temp);
536
0
}
537
538
static void
539
tele_param_msg_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p)
540
0
{
541
0
    EXACT_DATA_CHECK(len, 3);
542
543
0
    proto_tree_add_item(tree, hf_ansi_637_tele_msg_type, tvb, offset, 3, ENC_BIG_ENDIAN);
544
545
0
    proto_tree_add_item(tree, hf_ansi_637_tele_msg_id, tvb, offset, 3, ENC_BIG_ENDIAN);
546
547
0
    proto_tree_add_item(tree, hf_ansi_637_tele_msg_header_ind, tvb, offset, 3, ENC_BIG_ENDIAN);
548
0
    if ((tvb_get_uint8(tvb, offset + 2) & 0x08) == 0x08)
549
0
    {
550
0
        *has_private_data_p = true;
551
0
    }
552
553
0
    proto_tree_add_item(tree, hf_ansi_637_tele_msg_rsvd, tvb, offset, 3, ENC_BIG_ENDIAN);
554
0
}
555
556
/*
557
 * for record types 0, 1, 2 and 3 for unknowns
558
 */
559
75
#define NUM_CMAS_PARAM 4
560
static int ett_tia_1149_cmas_param[NUM_CMAS_PARAM];
561
562
/*
563
 * Special dissection for CMAS Message as defined in TIA-1149
564
 */
565
static const value_string cmas_category_strings[] = {
566
    { 0x00,     "Geo (Geophysical including landslide)" },
567
    { 0x01,     "Met (Meteorological including flood)" },
568
    { 0x02,     "Safety (General emergency and public safety)" },
569
    { 0x03,     "Security (Law enforcement, military, homeland and local/private security)" },
570
    { 0x04,     "Rescue (Rescue and recovery)" },
571
    { 0x05,     "Fire (Fire suppression and rescue)" },
572
    { 0x06,     "Health (Medical and public health)" },
573
    { 0x07,     "Env (Pollution and other environmental)" },
574
    { 0x08,     "Transport (Public and private transportation)" },
575
    { 0x09,     "Infra (Utility, telecommunication, other nontransport infrastructure)" },
576
    { 0x0a,     "CBRNE (Chemical, Biological, Radiological, Nuclear or High-Yield Explosive threat or attack)" },
577
    { 0x0b,     "Other (Other events)" },
578
    { 0, NULL }
579
};
580
581
static const value_string cmas_response_type_strings[] = {
582
    { 0x00,     "Shelter (Take shelter in place)" },
583
    { 0x01,     "Evacuate (Relocate)" },
584
    { 0x02,     "Prepare (Make preparations)" },
585
    { 0x03,     "Execute (Execute a pre-planned activity)" },
586
    { 0x04,     "Monitor (Attend to information sources)" },
587
    { 0x05,     "Avoid (Avoid hazard)" },
588
    { 0x06,     "Assess (Evaluate the information in this message. This value SHOULD NOT be used in public warning applications.)" },
589
    { 0x07,     "None (No action recommended)" },
590
    { 0, NULL }
591
};
592
593
static const value_string cmas_severity_strings[] = {
594
    { 0x00,     "Extreme (Extraordinary threat to life or property)" },
595
    { 0x01,     "Severe (Significant threat to life or property)" },
596
    { 0, NULL }
597
};
598
599
static const value_string cmas_urgency_strings[] = {
600
    { 0x00,     "Immediate (Responsive action should be taken immediately)" },
601
    { 0x01,     "Expected (Responsive action should be taken soon - within the next hour)" },
602
    { 0, NULL }
603
};
604
605
static const value_string cmas_certainty_strings[] = {
606
    { 0x00,     "Observed (Determined to have occurred or to be ongoing)" },
607
    { 0x01,     "Likely (Likely. Probability > ~50%)" },
608
    { 0, NULL }
609
};
610
611
static void
612
tele_param_user_data_cmas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
613
0
{
614
0
    proto_tree  *subtree;
615
0
    uint8_t     oct, oct2;
616
0
    uint8_t     encoding;
617
0
    uint8_t     num_fields;
618
0
    uint8_t     reserved_bits;
619
0
    uint8_t     unused_bits;
620
0
    uint8_t     record_type;
621
0
    uint8_t     record_len;
622
0
    uint8_t     subtree_idx;
623
0
    uint16_t    num_bits;
624
0
    uint32_t    value;
625
0
    uint32_t    temp_offset;
626
0
    uint32_t    required_octs;
627
0
    tvbuff_t    *tvb_out = NULL;
628
0
    const char *str = NULL;
629
630
0
    SHORT_DATA_CHECK(len, 2);
631
632
0
    value = tvb_get_ntohs(tvb, offset);
633
634
    /*
635
     * must be encoded as 'Octet, unspecified'
636
     */
637
0
    if ((value & 0xf800) != 0)
638
0
    {
639
0
        proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unknown_encoding, tvb, offset, len);
640
0
        return;
641
0
    }
642
643
0
    proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_cmas_encoding, tvb, offset, 2,
644
0
        value,
645
0
        "%s (%u)",
646
0
        val_to_str_const((value & 0xf800) >> 11, ansi_tsb58_encoding_vals, "Error"),
647
0
        (value & 0xf800) >> 11);
648
649
0
    proto_tree_add_item(tree, hf_ansi_637_tele_cmas_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
650
651
0
    num_fields = (value & 0x07f8) >> 3;
652
653
0
    offset += 2;
654
655
    /* NOTE: there are now 3 bits remaining in 'value' */
656
657
0
    unused_bits = 3;
658
659
0
    required_octs = num_fields;
660
661
0
    tvb_out =
662
0
        tvb_new_octet_aligned(tvb, ((offset - 1) * 8) + (8 - unused_bits), (required_octs * 8));
663
0
    add_new_data_source(pinfo, tvb_out, "CMAS Message");
664
665
0
    temp_offset = offset;
666
0
    offset = 0;
667
668
0
    proto_tree_add_item(tree, hf_ansi_637_tele_cmas_protocol_version, tvb_out, offset, 1, ENC_BIG_ENDIAN);
669
670
0
    offset += 1;
671
672
0
    while ((required_octs - offset) > 2)
673
0
    {
674
0
        record_type = tvb_get_uint8(tvb_out, offset);
675
0
        subtree_idx = record_type;
676
677
0
        switch (record_type)
678
0
        {
679
0
        default: str = "Reserved"; subtree_idx = 3; break;
680
0
        case 0x00: str = "Type 0 Elements (Alert Text)"; break;
681
0
        case 0x01: str = "Type 1 Elements"; break;
682
0
        case 0x02: str = "Type 2 Elements"; break;
683
0
        }
684
685
0
        record_len = tvb_get_uint8(tvb_out, offset + 1);
686
687
0
        subtree =
688
0
            proto_tree_add_subtree(tree, tvb_out, offset, record_len + 2,
689
0
                ett_tia_1149_cmas_param[subtree_idx], NULL,  str);
690
691
0
        proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_record_type, tvb_out, offset, 1,
692
0
            record_type,
693
0
            "%s",
694
0
            str);
695
696
0
        offset += 1;
697
698
0
        proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_record_len, tvb_out, offset, 1,
699
0
            record_len,
700
0
            "%u",
701
0
            record_len);
702
703
0
        offset += 1;
704
705
0
        switch (record_type)
706
0
        {
707
0
        default:
708
0
            proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_unknown_cmas_record_type, tvb_out, offset, record_len);
709
710
0
            offset += record_len;
711
0
            break;
712
713
0
        case 0x00:
714
0
            encoding = (tvb_get_uint8(tvb_out, offset) & 0xf8) >> 3;
715
716
0
            str = val_to_str_const(encoding, ansi_tsb58_encoding_vals, "Reserved");
717
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_char_set, tvb_out, offset, 1,
718
0
                encoding,
719
0
                "%s (%u)",
720
0
                str, encoding);
721
722
0
            num_bits = (record_len * 8) - 5;
723
724
0
            switch (encoding)
725
0
            {
726
0
            case 0x04: /* UNICODE */
727
                /* 16-bit encodings */
728
0
                num_fields = num_bits / 16;
729
0
                reserved_bits = 3;
730
0
                break;
731
732
0
            case 0x00: /* Octet, unspecified */
733
0
            case 0x10: /* KSC5601 (Korean) */
734
0
            case 0x07: /* Latin/Hebrew */
735
0
            case 0x08: /* Latin */
736
                /* 8-bit encodings */
737
0
                num_fields = num_bits / 8;
738
0
                reserved_bits = 3;
739
0
                break;
740
741
0
            default:
742
                /* 7-bit encodings */
743
0
                num_fields = num_bits / 7;
744
745
0
                if ((num_bits % 7) == 0)
746
0
                {
747
0
                    oct2 = tvb_get_uint8(tvb_out, offset + record_len - 1);
748
0
                    if ((oct2 & 0x7f) == 0)
749
0
                    {
750
                        /*
751
                         * the entire last 7 bits are reserved
752
                         */
753
0
                        num_fields--;
754
0
                    }
755
0
                }
756
757
0
                reserved_bits = num_bits - (num_fields * 7);
758
0
                break;
759
0
            }
760
761
0
            temp_offset = offset;
762
0
            if (num_fields) {
763
0
                text_decoder(tvb_out, pinfo, subtree, temp_offset, encoding, num_fields, num_bits,
764
0
                    3 /* (5 bits used from 'temp_offset' octet for encoding */, 0, hf_ansi_637_tele_cmas_text);
765
0
            }
766
767
0
            offset += (record_len - 1);
768
769
0
            if (reserved_bits > 0)
770
0
                proto_tree_add_bits_item(subtree, hf_ansi_637_reserved_bits_8_generic, tvb_out, (offset*8)+(8-reserved_bits), reserved_bits, ENC_NA);
771
772
0
            offset += 1;
773
0
            break;
774
775
0
        case 0x01:
776
0
            oct = tvb_get_uint8(tvb_out, offset);
777
778
0
            str = val_to_str_const(oct, cmas_category_strings, "Reserved");
779
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_category, tvb_out, offset, 1,
780
0
                oct,
781
0
                "%s (%u)",
782
0
                str, oct);
783
784
0
            offset += 1;
785
786
0
            oct = tvb_get_uint8(tvb_out, offset);
787
788
0
            str = val_to_str_const(oct, cmas_response_type_strings, "Reserved");
789
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_response_type, tvb_out, offset, 1,
790
0
                oct,
791
0
                "%s (%u)",
792
0
                str, oct);
793
794
0
            offset += 1;
795
796
0
            oct = tvb_get_uint8(tvb_out, offset);
797
798
0
            str = val_to_str_const((oct & 0xf0) >> 4, cmas_severity_strings, "Reserved");
799
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_severity, tvb_out, offset, 1,
800
0
                oct,
801
0
                "%s (%u)",
802
0
                str, (oct & 0xf0) >> 4);
803
804
0
            str = val_to_str_const(oct & 0x0f, cmas_urgency_strings, "Reserved");
805
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_urgency, tvb_out, offset, 1,
806
0
                oct,
807
0
                "%s (%u)",
808
0
                str, oct & 0x0f);
809
810
0
            offset += 1;
811
812
0
            oct = tvb_get_uint8(tvb_out, offset);
813
814
0
            str = val_to_str_const((oct & 0xf0) >> 4, cmas_certainty_strings, "Reserved");
815
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_certainty, tvb_out, offset, 1,
816
0
                oct,
817
0
                "%s (%u)",
818
0
                str, (oct & 0xf0) >> 4);
819
820
0
            proto_tree_add_item(subtree, hf_ansi_637_reserved_bits_8_0f, tvb_out, offset, 1, ENC_BIG_ENDIAN);
821
822
0
            offset += 1;
823
0
            break;
824
825
0
        case 0x02:
826
0
            proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_identifier, tvb_out, offset, 2, ENC_BIG_ENDIAN);
827
828
0
            offset += 2;
829
830
0
            proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_alert_handling, tvb_out, offset, 1, ENC_BIG_ENDIAN);
831
832
0
            offset += 1;
833
834
0
            oct = tvb_get_uint8(tvb_out, offset);
835
836
            /*
837
             * TIA-1149 does not say whether this should be encoded in the same way as IS-637
838
             * I.e. year = oct + ((oct < 96) ? 2000 : 1900);
839
             */
840
0
            value = oct + ((oct < 96) ? 2000 : 1900);
841
842
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_expires_year, tvb_out, offset, 1,
843
0
                oct,
844
0
                "%u (%02x)",
845
0
                value, oct);
846
847
0
            offset += 1;
848
849
0
            oct = tvb_get_uint8(tvb_out, offset);
850
851
0
            str = val_to_str_const(oct - 1, ansi_tele_month_strings, "Invalid");
852
853
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_expires_month, tvb_out, offset, 1,
854
0
                oct,
855
0
                "%s (%02x)",
856
0
                str, oct);
857
858
0
            offset += 1;
859
860
0
            proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_day, tvb_out, offset, 1, ENC_BIG_ENDIAN);
861
862
0
            offset += 1;
863
864
0
            proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_hours, tvb_out, offset, 1, ENC_BIG_ENDIAN);
865
866
0
            offset += 1;
867
868
0
            proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_minutes, tvb_out, offset, 1, ENC_BIG_ENDIAN);
869
870
0
            offset += 1;
871
872
0
            proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_seconds, tvb_out, offset, 1, ENC_BIG_ENDIAN);
873
874
0
            offset += 1;
875
876
0
            oct = tvb_get_uint8(tvb_out, offset);
877
878
0
            str = val_to_str_ext_const(oct, &ansi_tsb58_language_ind_vals_ext, "Reserved");
879
0
            proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_language, tvb_out, offset, 1,
880
0
                oct,
881
0
                "%s (%u)",
882
0
                str, oct);
883
884
0
            offset += 1;
885
0
            break;
886
0
        }
887
0
    }
888
889
0
    EXTRANEOUS_DATA_CHECK(required_octs, offset);
890
891
0
    offset += temp_offset;      /* move 'offset' back to the correct spot in 'tvb' */
892
893
0
    proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_07, tvb, offset, 1, ENC_BIG_ENDIAN);
894
0
}
895
896
static void
897
tele_param_user_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p)
898
0
{
899
0
    uint8_t             encoding;
900
0
    uint8_t             encoding_bit_len;
901
0
    uint8_t             num_fields;
902
0
    uint8_t             unused_bits;
903
0
    uint8_t             fill_bits;
904
0
    uint16_t            reserved_bits;
905
0
    uint32_t            value;
906
0
    uint32_t            orig_offset;
907
0
    uint32_t            saved_offset;
908
0
    uint32_t            required_octs;
909
0
    const char          *str;
910
0
    tvbuff_t            *tvb_out;
911
0
    enum character_set  cset;
912
913
0
    SHORT_DATA_CHECK(len, 2);
914
915
0
    orig_offset = offset;
916
0
    reserved_bits = len * 8;
917
918
0
    value = tvb_get_ntohs(tvb, offset);
919
920
0
    encoding = (uint8_t) ((value & 0xf800) >> 11);
921
0
    str = val_to_str_const(encoding, ansi_tsb58_encoding_vals, "Reserved");
922
0
    switch (encoding)
923
0
    {
924
0
    case 0x00:
925
0
    case 0x05:
926
0
    case 0x06:
927
0
    case 0x07:
928
0
    case 0x08:
929
0
    case 0x10:
930
0
        encoding_bit_len = 8;
931
0
        cset = OTHER;
932
0
        break;
933
934
0
    case 0x01:
935
0
    case 0x02:
936
0
    case 0x03:
937
0
    default:
938
0
        encoding_bit_len = 7;
939
0
        cset = ASCII_7BITS;
940
0
        break;
941
942
0
    case 0x04:
943
0
        encoding_bit_len = 16;
944
0
        cset = UCS2;
945
0
        break;
946
947
0
    case 0x09:
948
0
        encoding_bit_len = 7;
949
0
        cset = GSM_7BITS;
950
0
        break;
951
0
    }
952
953
0
    proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_user_data_encoding, tvb, offset, 2,
954
0
        value,
955
0
        "%s (%u)",
956
0
        str,
957
0
        encoding);
958
959
0
    reserved_bits -= 5;
960
961
0
    if (encoding == 0x01)
962
0
    {
963
0
        proto_tree_add_item(tree, hf_ansi_637_tele_user_data_message_type, tvb, offset, 2, ENC_BIG_ENDIAN);
964
965
0
        offset += 1;
966
0
        value = tvb_get_ntohs(tvb, offset);
967
968
0
        reserved_bits -= 8;
969
0
    }
970
971
0
    proto_tree_add_item(tree, hf_ansi_637_tele_user_data_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
972
973
0
    offset += 1;
974
975
0
    num_fields = (value & 0x07f8) >> 3;
976
977
0
    reserved_bits -= 8 + (num_fields * encoding_bit_len);
978
979
    /* NOTE: there are now 3 bits remaining in 'value' */
980
981
0
    unused_bits = 3;
982
0
    fill_bits = 0;
983
984
    /*
985
     * ALL of this is for header support !
986
     */
987
0
    if (*has_private_data_p == true)
988
0
    {
989
0
        gsm_sms_udh_fields_t    udh_fields;
990
0
        int32_t                 num_udh_bits;
991
992
0
        memset(&udh_fields, 0, sizeof(udh_fields));
993
994
0
        value = tvb_get_ntohs(tvb, offset);
995
996
        /*
997
         * 'length' split across two octets +1 for the length octet itself
998
         * (dis_field_udh() will start at the length offset)
999
         */
1000
0
        required_octs = ((value & 0x07f8) >> 3) + 1;
1001
1002
        /*
1003
         * need fill bits
1004
         */
1005
0
        if (encoding_bit_len == 7)
1006
0
        {
1007
            /*
1008
             * not the same formula as dis_field_udh() because we are including
1009
             * the length octet in the calculation but the result is the same
1010
             */
1011
0
            fill_bits = 7 - ((required_octs * 8) % 7);
1012
0
        }
1013
1014
0
        num_udh_bits = (required_octs * 8) + fill_bits;
1015
1016
0
        tvb_out =
1017
0
            tvb_new_octet_aligned(tvb, (offset * 8) + (8 - unused_bits), num_udh_bits);
1018
0
        add_new_data_source(pinfo, tvb_out, "Header");
1019
1020
0
        saved_offset = offset + required_octs;
1021
1022
0
        offset = 0;
1023
0
        fill_bits = 0;
1024
0
        if (encoding_bit_len == 16) {
1025
            /* the NUM_FIELD value represents the number of characters in Unicode encoding.
1026
               Let's translate it into bytes */
1027
0
            num_fields <<= 1;
1028
0
        }
1029
0
        dis_field_udh(tvb_out, pinfo, tree, &offset, &required_octs, &num_fields, cset, &fill_bits, &udh_fields);
1030
1031
0
        offset = saved_offset;
1032
1033
0
        if (encoding_bit_len == 7)
1034
0
        {
1035
0
            switch (cset)
1036
0
            {
1037
0
            case ASCII_7BITS:
1038
0
                if (fill_bits > unused_bits)
1039
0
                {
1040
                    /* this branch was NOT tested */
1041
1042
0
                    offset += 1;
1043
0
                    unused_bits = 8 - (fill_bits - unused_bits);
1044
0
                }
1045
0
                else if (fill_bits > 0)
1046
0
                {
1047
                    /* this branch was tested */
1048
0
                    unused_bits = unused_bits - fill_bits;
1049
0
                }
1050
1051
0
                if (unused_bits == 0)
1052
0
                {
1053
                    /* this branch was NOT tested */
1054
1055
0
                    offset += 1;
1056
0
                    unused_bits = 8;
1057
0
                }
1058
0
                break;
1059
1060
0
            default:
1061
0
                break;
1062
0
            }
1063
0
        } else if (encoding_bit_len == 16) {
1064
            /* compute the number of Unicode characters now that UDH is taken into account */
1065
0
            num_fields >>= 1;
1066
0
        }
1067
1068
0
        if (udh_fields.frags > 0)
1069
0
        {
1070
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " (Short Message fragment %u of %u)", udh_fields.frag, udh_fields.frags);
1071
0
        }
1072
0
    }
1073
1074
0
    if (num_fields) {
1075
0
        text_decoder(tvb, pinfo, tree, offset, encoding, num_fields,
1076
0
            num_fields * encoding_bit_len, unused_bits, fill_bits, hf_ansi_637_tele_user_data_text);
1077
0
    }
1078
1079
0
    if (reserved_bits > 0)
1080
0
    {
1081
        /*
1082
         * unlike for CMAS, the bits that can be reserved will always be
1083
         * at the end of an octet so we don't have to worry about them
1084
         * spanning two octets
1085
         */
1086
1087
0
        switch (cset)
1088
0
        {
1089
0
        case GSM_7BITS:
1090
0
            {
1091
0
                crumb_spec_t crumbs[3];
1092
0
                uint8_t i = 0;
1093
0
                unsigned bits_offset;
1094
1095
0
                if (reserved_bits > 3) {
1096
0
                    bits_offset = ((orig_offset + len - 2)*8)+5;
1097
0
                    crumbs[i].crumb_bit_offset = 0;
1098
0
                    crumbs[i++].crumb_bit_length = reserved_bits - 3;
1099
0
                    crumbs[i].crumb_bit_offset = 8;
1100
0
                } else {
1101
0
                    bits_offset = ((orig_offset + len - 1)*8)+5;
1102
0
                    crumbs[i].crumb_bit_offset = 0;
1103
0
                }
1104
0
                crumbs[i++].crumb_bit_length = 3;
1105
0
                crumbs[i].crumb_bit_offset = 0;
1106
0
                crumbs[i].crumb_bit_length = 0;
1107
0
                proto_tree_add_split_bits_item_ret_val(tree, hf_ansi_637_reserved_bits_16_generic, tvb, bits_offset, crumbs, NULL);
1108
0
            }
1109
0
            break;
1110
1111
0
        default:
1112
0
            proto_tree_add_bits_item(tree, hf_ansi_637_reserved_bits_8_generic, tvb, ((orig_offset + len - 1)*8)+(8-reserved_bits), reserved_bits, ENC_NA); /* LSBs */
1113
0
            break;
1114
0
        }
1115
0
    }
1116
0
}
1117
1118
static void
1119
tele_param_rsp_code(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1120
0
{
1121
0
    EXACT_DATA_CHECK(len, 1);
1122
1123
0
    proto_tree_add_item(tree, hf_ansi_637_tele_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
1124
0
}
1125
1126
static void
1127
tele_param_message_center_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1128
0
{
1129
0
    EXACT_DATA_CHECK(len, 6);
1130
1131
0
    tele_param_timestamp(tvb, pinfo, tree, len, offset,
1132
0
        hf_ansi_637_tele_message_center_ts_year,
1133
0
        hf_ansi_637_tele_message_center_ts_month,
1134
0
        hf_ansi_637_tele_message_center_ts_day,
1135
0
        hf_ansi_637_tele_message_center_ts_hours,
1136
0
        hf_ansi_637_tele_message_center_ts_minutes,
1137
0
        hf_ansi_637_tele_message_center_ts_seconds);
1138
0
}
1139
1140
static void
1141
tele_param_validity_period_abs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1142
0
{
1143
0
    EXACT_DATA_CHECK(len, 6);
1144
1145
0
    tele_param_timestamp(tvb, pinfo, tree, len, offset,
1146
0
        hf_ansi_637_tele_validity_period_ts_year,
1147
0
        hf_ansi_637_tele_validity_period_ts_month,
1148
0
        hf_ansi_637_tele_validity_period_ts_day,
1149
0
        hf_ansi_637_tele_validity_period_ts_hours,
1150
0
        hf_ansi_637_tele_validity_period_ts_minutes,
1151
0
        hf_ansi_637_tele_validity_period_ts_seconds);
1152
0
}
1153
1154
static void
1155
tele_param_timestamp_rel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned len _U_, uint32_t offset, int hf)
1156
0
{
1157
0
    uint8_t     oct;
1158
0
    uint32_t    value = 0;
1159
0
    const char *str = NULL;
1160
0
    const char *str2 = NULL;
1161
1162
0
    oct = tvb_get_uint8(tvb, offset);
1163
1164
0
    switch (oct)
1165
0
    {
1166
0
    case 245: str = "Indefinite"; break;
1167
0
    case 246: str = "Immediate"; break;
1168
0
    case 247: str = "Valid until mobile becomes inactive/Deliver when mobile next becomes active"; break;
1169
0
    case 248: str = "Valid until registration area changes, discard if not registered" ; break;
1170
0
    default:
1171
0
        if (oct <= 143) { value = (oct + 1) * 5; str2 = "Minutes"; break; }
1172
0
        else if ((oct >= 144) && (oct <= 167)) { value = (oct - 143) * 30; str2 = "Minutes + 12 Hours"; break; }
1173
0
        else if ((oct >= 168) && (oct <= 196)) { value = oct - 166; str2 = "Days"; break; }
1174
0
        else if ((oct >= 197) && (oct <= 244)) { value = oct - 192; str2 = "Weeks"; break; }
1175
0
        else { str = "Reserved"; break; }
1176
0
    }
1177
1178
0
    if (str != NULL)
1179
0
    {
1180
0
        proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
1181
0
            oct,
1182
0
            "%s",
1183
0
            str);
1184
0
    }
1185
0
    else
1186
0
    {
1187
0
        proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
1188
0
            oct,
1189
0
            "%u %s",
1190
0
            value, str2);
1191
0
    }
1192
0
}
1193
1194
static void
1195
tele_param_validity_period_rel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1196
0
{
1197
0
    EXACT_DATA_CHECK(len, 1);
1198
1199
0
    tele_param_timestamp_rel(tvb, pinfo, tree, len, offset, hf_ansi_637_tele_validity_period_relative_validity);
1200
0
}
1201
1202
static void
1203
tele_param_deferred_del_abs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1204
0
{
1205
0
    EXACT_DATA_CHECK(len, 6);
1206
1207
0
    tele_param_timestamp(tvb, pinfo, tree, len, offset,
1208
0
        hf_ansi_637_tele_deferred_del_ts_year,
1209
0
        hf_ansi_637_tele_deferred_del_ts_month,
1210
0
        hf_ansi_637_tele_deferred_del_ts_day,
1211
0
        hf_ansi_637_tele_deferred_del_ts_hours,
1212
0
        hf_ansi_637_tele_deferred_del_ts_minutes,
1213
0
        hf_ansi_637_tele_deferred_del_ts_seconds);
1214
0
}
1215
1216
static void
1217
tele_param_deferred_del_rel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1218
0
{
1219
0
    EXACT_DATA_CHECK(len, 1);
1220
1221
0
    tele_param_timestamp_rel(tvb, pinfo, tree, len, offset, hf_ansi_637_tele_deferred_del_relative);
1222
0
}
1223
1224
static const value_string tele_param_priority_ind_strings[] = {
1225
    { 0,        "Normal" },
1226
    { 1,        "Interactive" },
1227
    { 2,        "Urgent" },
1228
    { 3,        "Emergency" },
1229
    { 0, NULL }
1230
};
1231
1232
static void
1233
tele_param_pri_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1234
0
{
1235
0
    EXACT_DATA_CHECK(len, 1);
1236
1237
0
    proto_tree_add_item(tree, hf_ansi_637_tele_priority_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
1238
0
    proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
1239
0
}
1240
1241
static const value_string tele_param_privacy_ind_strings[] = {
1242
    { 0,        "Not restricted (privacy level 0)" },
1243
    { 1,        "Restricted (privacy level 1)" },
1244
    { 2,        "Confidential (privacy level 2)" },
1245
    { 3,        "Secret (privacy level 3)" },
1246
    { 0, NULL }
1247
};
1248
1249
static void
1250
tele_param_priv_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1251
0
{
1252
0
    EXACT_DATA_CHECK(len, 1);
1253
1254
0
    proto_tree_add_item(tree, hf_ansi_637_tele_privacy_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
1255
0
    proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
1256
0
}
1257
1258
static void
1259
tele_param_reply_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1260
0
{
1261
0
    EXACT_DATA_CHECK(len, 1);
1262
1263
0
    proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_user_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1264
0
    proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_dak_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1265
0
    proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_read_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1266
0
    proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_report_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1267
0
    proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, offset, 1, ENC_BIG_ENDIAN);
1268
0
}
1269
1270
static void
1271
tele_param_num_messages(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1272
0
{
1273
0
    uint8_t     oct;
1274
1275
0
    EXACT_DATA_CHECK(len, 1);
1276
1277
0
    oct = tvb_get_uint8(tvb, offset);
1278
1279
0
    proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_num_messages, tvb, offset, 1,
1280
0
        ((oct & 0xf0) >> 4) * 10 + (oct & 0x0f),
1281
0
        "%u%u",
1282
0
        (oct & 0xf0) >> 4, oct & 0x0f);
1283
0
}
1284
1285
static const value_string tele_param_alert_priority_strings[] = {
1286
    { 0,        "Use Mobile default alert" },
1287
    { 1,        "Use Low-priority alert" },
1288
    { 2,        "Use Medium-priority alert" },
1289
    { 3,        "Use High-priority alert" },
1290
    { 0, NULL }
1291
};
1292
1293
static void
1294
tele_param_alert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1295
0
{
1296
0
    EXACT_DATA_CHECK(len, 1);
1297
1298
0
    proto_tree_add_item(tree, hf_ansi_637_tele_alert_msg_delivery_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
1299
0
    proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
1300
0
}
1301
1302
static void
1303
tele_param_lang_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1304
0
{
1305
0
    uint8_t     oct;
1306
0
    const char *str = NULL;
1307
1308
0
    EXACT_DATA_CHECK(len, 1);
1309
1310
0
    oct = tvb_get_uint8(tvb, offset);
1311
1312
0
    str = val_to_str_ext_const(oct, &ansi_tsb58_language_ind_vals_ext, "Reserved");
1313
0
    proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_language, tvb, offset, 1,
1314
0
        oct,
1315
0
        "%s (%u)",
1316
0
        str, oct);
1317
0
}
1318
1319
static void
1320
tele_param_cb_num(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1321
0
{
1322
0
    uint8_t     oct, oct2, num_fields, odd;
1323
0
    uint8_t     *poctets;
1324
0
    uint32_t    saved_offset;
1325
0
    uint32_t    required_octs;
1326
0
    uint32_t    i;
1327
1328
0
    SHORT_DATA_CHECK(len, 2);
1329
1330
0
    proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_digit_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
1331
1332
0
    oct = tvb_get_uint8(tvb, offset);
1333
1334
0
    if (oct & 0x80)
1335
0
    {
1336
0
        proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_ton, tvb, offset, 1, ENC_BIG_ENDIAN);
1337
0
        proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_plan, tvb, offset, 1, ENC_BIG_ENDIAN);
1338
1339
0
        offset += 1;
1340
1341
0
        proto_tree_add_item_ret_uint8(tree, hf_ansi_637_tele_cb_num_num_fields, tvb, offset, 1, ENC_BIG_ENDIAN, &num_fields);
1342
1343
0
        if (num_fields == 0) return;
1344
1345
0
        SHORT_DATA_CHECK(len - 2, num_fields);
1346
1347
0
        offset += 1;
1348
1349
0
        poctets = tvb_get_string_enc(pinfo->pool, tvb, offset, num_fields, ENC_ASCII|ENC_NA);
1350
1351
0
        proto_tree_add_string_format(tree, hf_ansi_637_tele_cb_num_number, tvb, offset, num_fields,
1352
0
            (char *) poctets,
1353
0
            "Number: %s",
1354
0
            (char *) format_text(pinfo->pool, (char*)poctets, num_fields));
1355
0
    }
1356
0
    else
1357
0
    {
1358
0
        offset += 1;
1359
1360
0
        oct2 = tvb_get_uint8(tvb, offset);
1361
0
        num_fields = ((oct & 0x7f) << 1) | ((oct2 & 0x80) >> 7);
1362
1363
0
        proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_num_fields07f8, tvb, offset, 2, ENC_BIG_ENDIAN);
1364
1365
0
        oct = oct2;
1366
0
        odd = false;
1367
1368
0
        if (num_fields > 0)
1369
0
        {
1370
0
            i = (num_fields - 1) * 4;
1371
0
            required_octs = (i / 8) + ((i % 8) ? 1 : 0);
1372
1373
0
            SHORT_DATA_CHECK(len - 2, required_octs);
1374
1375
0
            odd = num_fields & 0x01;
1376
0
            memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
1377
0
            saved_offset = offset;
1378
0
            offset += 1;
1379
1380
0
            i = 0;
1381
0
            while (i < num_fields)
1382
0
            {
1383
0
                ansi_637_bigbuf[i] = air_digits[(oct & 0x78) >> 3];
1384
1385
0
                i += 1;
1386
0
                if (i >= num_fields) break;
1387
1388
0
                oct2 = tvb_get_uint8(tvb, offset);
1389
0
                offset += 1;
1390
1391
0
                ansi_637_bigbuf[i] = air_digits[((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7)];
1392
1393
0
                oct = oct2;
1394
0
                i += 1;
1395
0
            }
1396
1397
0
            proto_tree_add_string_format(tree, hf_ansi_637_tele_cb_num_number, tvb, saved_offset, offset - saved_offset,
1398
0
                ansi_637_bigbuf,
1399
0
                "Number: %s",
1400
0
                ansi_637_bigbuf);
1401
0
        }
1402
1403
0
        proto_tree_add_item(tree,
1404
0
            odd ? hf_ansi_637_reserved_bits_8_07 : hf_ansi_637_reserved_bits_8_7f,
1405
0
            tvb, offset - 1, 1, ENC_BIG_ENDIAN);
1406
0
    }
1407
0
}
1408
1409
static const value_string tele_param_msg_display_mode_strings[] = {
1410
    { 0,        "Immediate Display: The mobile station is to display the received message as soon as possible." },
1411
    { 1,        "Mobile default setting: The mobile station is to display the received message based on a pre-defined mode in the mobile station." },
1412
    { 2,        "User Invoke: The mobile station is to display the received message based on the mode selected by the user." },
1413
    { 3,        "Reserved" },
1414
    { 0, NULL }
1415
};
1416
1417
static void
1418
tele_param_disp_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1419
0
{
1420
0
    EXACT_DATA_CHECK(len, 1);
1421
1422
0
    proto_tree_add_item(tree, hf_ansi_637_tele_msg_display_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
1423
0
    proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
1424
0
}
1425
1426
static void
1427
tele_param_mult_enc_user_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1428
0
{
1429
0
    uint64_t            encoding;
1430
0
    uint8_t             encoding_bit_len;
1431
0
    uint64_t            num_fields;
1432
0
    uint8_t             unused_bits;
1433
0
    uint8_t             fill_bits;
1434
0
    uint16_t            reserved_bits;
1435
0
    uint32_t            orig_offset;
1436
0
    enum character_set  cset = OTHER;
1437
1438
0
    SHORT_DATA_CHECK(len, 2);
1439
1440
0
    orig_offset = offset;
1441
0
    offset <<= 3;
1442
0
    reserved_bits = len * 8;
1443
1444
0
    while (reserved_bits > 7) {
1445
0
        proto_tree_add_bits_ret_val(tree, hf_ansi_637_tele_mult_enc_user_data_encoding,
1446
0
                                    tvb, offset, 5, &encoding, ENC_BIG_ENDIAN);
1447
0
        switch (encoding) {
1448
0
        case 0x00:
1449
0
        case 0x05:
1450
0
        case 0x06:
1451
0
        case 0x07:
1452
0
        case 0x08:
1453
0
        case 0x10:
1454
0
            encoding_bit_len = 8;
1455
0
            cset = OTHER;
1456
0
            break;
1457
1458
0
        case 0x01:
1459
0
        case 0x02:
1460
0
        case 0x03:
1461
0
        default:
1462
0
            encoding_bit_len = 7;
1463
0
            cset = ASCII_7BITS;
1464
0
            break;
1465
1466
0
        case 0x04:
1467
0
            encoding_bit_len = 16;
1468
0
            cset = UCS2;
1469
0
            break;
1470
1471
0
        case 0x09:
1472
0
            encoding_bit_len = 7;
1473
0
            cset = GSM_7BITS;
1474
0
            break;
1475
0
        }
1476
1477
0
        offset += 5;
1478
0
        reserved_bits -= 5;
1479
1480
0
        proto_tree_add_bits_ret_val(tree, hf_ansi_637_tele_mult_enc_user_data_num_fields,
1481
0
                                    tvb, offset, 8, &num_fields, ENC_BIG_ENDIAN);
1482
1483
0
        offset += 8;
1484
0
        reserved_bits -= 8;
1485
1486
0
        unused_bits = (offset & 0x07) ? 8 - (offset & 0x07) : 0;
1487
0
        fill_bits = 0;
1488
1489
0
        if (num_fields) {
1490
0
            text_decoder(tvb, pinfo, tree, offset>>3, (uint8_t)encoding, (uint8_t)num_fields, (uint8_t)num_fields * encoding_bit_len,
1491
0
                unused_bits, fill_bits, hf_ansi_637_tele_mult_enc_user_data_text);
1492
0
            offset +=  (uint8_t)num_fields * encoding_bit_len;
1493
0
            reserved_bits -= (uint8_t)num_fields * encoding_bit_len;
1494
0
        }
1495
0
    }
1496
1497
0
    if (reserved_bits > 0)
1498
0
    {
1499
        /*
1500
         * unlike for CMAS, the bits that can be reserved will always be
1501
         * at the end of an octet so we don't have to worry about them
1502
         * spanning two octets
1503
         */
1504
1505
0
        switch (cset)
1506
0
        {
1507
0
        case GSM_7BITS:
1508
0
            {
1509
0
                crumb_spec_t crumbs[3];
1510
0
                uint8_t i = 0;
1511
0
                unsigned bits_offset;
1512
1513
0
                if (reserved_bits > 3) {
1514
0
                    bits_offset = ((orig_offset + len - 2)*8)+5;
1515
0
                    crumbs[i].crumb_bit_offset = 0;
1516
0
                    crumbs[i++].crumb_bit_length = reserved_bits - 3;
1517
0
                    crumbs[i].crumb_bit_offset = 8;
1518
0
                } else {
1519
0
                    bits_offset = ((orig_offset + len - 1)*8)+5;
1520
0
                    crumbs[i].crumb_bit_offset = 0;
1521
0
                }
1522
0
                crumbs[i++].crumb_bit_length = 3;
1523
0
                crumbs[i].crumb_bit_offset = 0;
1524
0
                crumbs[i].crumb_bit_length = 0;
1525
0
                proto_tree_add_split_bits_item_ret_val(tree, hf_ansi_637_reserved_bits_16_generic, tvb, bits_offset, crumbs, NULL);
1526
0
            }
1527
0
            break;
1528
1529
0
        default:
1530
0
            proto_tree_add_bits_item(tree, hf_ansi_637_reserved_bits_8_generic, tvb, ((orig_offset + len - 1)*8)+(8-reserved_bits), reserved_bits, ENC_NA); /* LSBs */
1531
0
            break;
1532
0
        }
1533
0
    }
1534
0
}
1535
1536
static void
1537
tele_param_msg_deposit_idx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1538
0
{
1539
0
    EXACT_DATA_CHECK(len, 2);
1540
1541
0
    proto_tree_add_item(tree, hf_ansi_637_tele_msg_deposit_idx, tvb, offset, 2, ENC_BIG_ENDIAN);
1542
0
}
1543
1544
static const value_string tele_param_srvc_cat_prog_data_op_code_vals[] = {
1545
    { 0x00, "Delete the Service Category" },
1546
    { 0x01, "Add the Service Category" },
1547
    { 0x02, "Clear all Service Categories" },
1548
    { 0x00, NULL}
1549
};
1550
1551
static const value_string tele_param_srvc_cat_prog_data_alert_option_vals[] = {
1552
    { 0x00, "No alert" },
1553
    { 0x01, "Mobile Station default alert" },
1554
    { 0x02, "Vibrate alert once" },
1555
    { 0x03, "Vibrate alert - repeat" },
1556
    { 0x04, "Visual alert once" },
1557
    { 0x05, "Visual alert - repeat" },
1558
    { 0x06, "Low-priority alert once" },
1559
    { 0x07, "Low-priority alert - repeat" },
1560
    { 0x08, "Medium-priority alert once" },
1561
    { 0x09, "Medium-priority alert - repeat" },
1562
    { 0x0a, "High-priority alert once" },
1563
    { 0x0b, "High-priority alert - repeat" },
1564
    { 0x00, NULL}
1565
};
1566
1567
static void
1568
tele_param_srvc_cat_prog_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1569
0
{
1570
0
    uint64_t            encoding;
1571
0
    uint8_t             encoding_bit_len;
1572
0
    uint64_t            num_fields;
1573
0
    uint8_t             unused_bits;
1574
0
    uint8_t             fill_bits;
1575
0
    uint16_t            reserved_bits;
1576
0
    uint32_t            orig_offset;
1577
0
    enum character_set  cset = OTHER;
1578
1579
0
    SHORT_DATA_CHECK(len, 2);
1580
1581
0
    orig_offset = offset;
1582
0
    offset <<= 3;
1583
0
    reserved_bits = len * 8;
1584
1585
0
    proto_tree_add_bits_ret_val(tree, hf_ansi_637_tele_srvc_cat_prog_data_encoding,
1586
0
                                tvb, offset, 5, &encoding, ENC_BIG_ENDIAN);
1587
0
    switch (encoding) {
1588
0
    case 0x00:
1589
0
    case 0x05:
1590
0
    case 0x06:
1591
0
    case 0x07:
1592
0
    case 0x08:
1593
0
    case 0x10:
1594
0
        encoding_bit_len = 8;
1595
0
        cset = OTHER;
1596
0
        break;
1597
1598
0
    case 0x01:
1599
0
    case 0x02:
1600
0
    case 0x03:
1601
0
    default:
1602
0
        encoding_bit_len = 7;
1603
0
        cset = ASCII_7BITS;
1604
0
        break;
1605
1606
0
    case 0x04:
1607
0
        encoding_bit_len = 16;
1608
0
        cset = OTHER;
1609
0
        break;
1610
1611
0
    case 0x09:
1612
0
        encoding_bit_len = 7;
1613
0
        cset = GSM_7BITS;
1614
0
        break;
1615
0
    }
1616
1617
0
    offset += 5;
1618
0
    reserved_bits -= 5;
1619
1620
0
    while (reserved_bits > 7) {
1621
0
        proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_operation_code,
1622
0
                                 tvb, offset, 4, ENC_BIG_ENDIAN);
1623
0
        offset += 4;
1624
0
        reserved_bits -= 4;
1625
1626
0
        proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_category,
1627
0
                                 tvb, offset, 16, ENC_BIG_ENDIAN);
1628
0
        offset += 16;
1629
0
        reserved_bits -= 16;
1630
1631
0
        proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_language,
1632
0
                                 tvb, offset, 8, ENC_BIG_ENDIAN);
1633
0
        offset += 8;
1634
0
        reserved_bits -= 8;
1635
1636
0
        proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_max_messages,
1637
0
                                 tvb, offset, 8, ENC_BIG_ENDIAN);
1638
0
        offset += 8;
1639
0
        reserved_bits -= 8;
1640
1641
0
        proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_alert_option,
1642
0
                                 tvb, offset, 4, ENC_BIG_ENDIAN);
1643
0
        offset += 4;
1644
0
        reserved_bits -= 4;
1645
1646
0
        proto_tree_add_bits_ret_val(tree, hf_ansi_637_tele_srvc_cat_prog_data_num_fields,
1647
0
                                    tvb, offset, 8, &num_fields, ENC_BIG_ENDIAN);
1648
1649
0
        offset += 8;
1650
0
        reserved_bits -= 8;
1651
1652
0
        unused_bits = (offset & 0x07) ? 8 - (offset & 0x07) : 0;
1653
0
        fill_bits = 0;
1654
1655
0
        if (num_fields) {
1656
0
            text_decoder(tvb, pinfo, tree, offset>>3, (uint8_t)encoding, (uint8_t)num_fields, (uint8_t)num_fields * encoding_bit_len,
1657
0
                unused_bits, fill_bits, hf_ansi_637_tele_srvc_cat_prog_data_text);
1658
0
            offset +=  (uint8_t)num_fields * encoding_bit_len;
1659
0
            reserved_bits -= (uint8_t)num_fields * encoding_bit_len;
1660
0
        }
1661
0
    }
1662
1663
0
    if (reserved_bits > 0)
1664
0
    {
1665
        /*
1666
         * unlike for CMAS, the bits that can be reserved will always be
1667
         * at the end of an octet so we don't have to worry about them
1668
         * spanning two octets
1669
         */
1670
1671
0
        switch (cset)
1672
0
        {
1673
0
        case GSM_7BITS:
1674
0
            {
1675
0
                crumb_spec_t crumbs[3];
1676
0
                uint8_t i = 0;
1677
0
                unsigned bits_offset;
1678
1679
0
                if (reserved_bits > 3) {
1680
0
                    bits_offset = ((orig_offset + len - 2)*8)+5;
1681
0
                    crumbs[i].crumb_bit_offset = 0;
1682
0
                    crumbs[i++].crumb_bit_length = reserved_bits - 3;
1683
0
                    crumbs[i].crumb_bit_offset = 8;
1684
0
                } else {
1685
0
                    bits_offset = ((orig_offset + len - 1)*8)+5;
1686
0
                    crumbs[i].crumb_bit_offset = 0;
1687
0
                }
1688
0
                crumbs[i++].crumb_bit_length = 3;
1689
0
                crumbs[i].crumb_bit_offset = 0;
1690
0
                crumbs[i].crumb_bit_length = 0;
1691
0
                proto_tree_add_split_bits_item_ret_val(tree, hf_ansi_637_reserved_bits_16_generic, tvb, bits_offset, crumbs, NULL);
1692
0
            }
1693
0
            break;
1694
1695
0
        default:
1696
0
            proto_tree_add_bits_item(tree, hf_ansi_637_reserved_bits_8_generic, tvb, ((orig_offset + len - 1)*8)+(8-reserved_bits), reserved_bits, ENC_NA); /* LSBs */
1697
0
            break;
1698
0
        }
1699
0
    }
1700
0
}
1701
1702
static const value_string tele_param_srvc_cat_prog_results_result_strings[] = {
1703
    { 0x00,     "Programming successful" },
1704
    { 0x01,     "Service Category memory limit exceeded" },
1705
    { 0x02,     "Service Category limit exceeded" },
1706
    { 0x03,     "Category already programmed" },
1707
    { 0x04,     "Category not previously programmed" },
1708
    { 0x05,     "Invalid MAX_MESSAGES" },
1709
    { 0x06,     "Invalid ALERT_OPTION" },
1710
    { 0x07,     "Invalid Service Category name" },
1711
    { 0x08,     "Unspecified programming failure" },
1712
    { 0x09,     "Reserved" },
1713
    { 0x0a,     "Reserved" },
1714
    { 0x0b,     "Reserved" },
1715
    { 0x0c,     "Reserved" },
1716
    { 0x0d,     "Reserved" },
1717
    { 0x0e,     "Reserved" },
1718
    { 0x0f,     "Reserved" },
1719
    { 0, NULL }
1720
};
1721
1722
static void
1723
tele_param_srvc_cat_prog_results(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1724
0
{
1725
0
    uint32_t    curr_offset;
1726
0
    uint32_t    value;
1727
0
    const char *str = NULL;
1728
1729
0
    curr_offset = offset;
1730
1731
0
    while ((len - (curr_offset - offset)) >= 3)
1732
0
    {
1733
0
        value = tvb_get_ntohs(tvb, curr_offset);
1734
1735
0
        str = val_to_str_const(value, ansi_tsb58_srvc_cat_vals, "Reserved");
1736
0
        proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat, tvb, curr_offset, 2,
1737
0
            value,
1738
0
            "%s (%u)",
1739
0
            str, value);
1740
1741
0
        curr_offset += 2;
1742
1743
0
        proto_tree_add_item(tree, hf_ansi_637_tele_srvc_cat_prog_results_result, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
1744
0
        proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
1745
1746
0
        curr_offset += 1;
1747
0
    }
1748
1749
0
    EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1750
0
}
1751
1752
/* Adamek Jan - IS637C Message status decoding procedure */
1753
static const value_string tele_param_msg_status_error_class_strings[] = {
1754
    { 0x00,     "No Error" },
1755
    { 0x01,     "Reserved" },
1756
    { 0x02,     "Temporary Condition" },
1757
    { 0x03,     "Permanent Condition" },
1758
    { 0, NULL }
1759
};
1760
1761
static void
1762
tele_param_msg_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1763
0
{
1764
0
    uint8_t     oct;
1765
0
    uint8_t     msg_status_code;
1766
0
    const char *str = NULL;
1767
1768
0
    EXACT_DATA_CHECK(len, 1);
1769
1770
0
    proto_tree_add_item(tree, hf_ansi_637_tele_msg_status, tvb, offset, 1, ENC_BIG_ENDIAN);
1771
0
    proto_tree_add_item(tree, hf_ansi_637_tele_msg_status_error_class, tvb, offset, 1, ENC_BIG_ENDIAN);
1772
1773
0
    oct = tvb_get_uint8(tvb, offset);
1774
1775
0
    msg_status_code = (oct & 0x3f);
1776
1777
0
    switch ((oct & 0xc0) >> 6)
1778
0
    {
1779
0
    case 0x00:
1780
0
        switch (msg_status_code)
1781
0
        {
1782
0
        case 0x00: str = "Message accepted"; break;
1783
0
        case 0x01: str = "Message deposited to Internet"; break;
1784
0
        case 0x02: str = "Message delivered"; break;
1785
0
        case 0x03: str = "Message cancelled"; break;
1786
0
        default: str = "Reserved"; break;
1787
0
        }
1788
0
        break;
1789
1790
0
    case 0x02:
1791
0
        switch (msg_status_code)
1792
0
        {
1793
0
        case 0x04: str = "Network congestion"; break;
1794
0
        case 0x05: str = "Network error"; break;
1795
0
        case 0x1f: str = "Unknown error"; break;
1796
0
        default: str = "Reserved"; break;
1797
0
        }
1798
0
        break;
1799
1800
0
    case 0x03:
1801
0
        switch (msg_status_code)
1802
0
        {
1803
0
        case 0x04: str = "Network congestion"; break;
1804
0
        case 0x05: str = "Network error"; break;
1805
0
        case 0x06: str = "Cancel failed"; break;
1806
0
        case 0x07: str = "Blocked destination"; break;
1807
0
        case 0x08: str = "Text too long"; break;
1808
0
        case 0x09: str = "Duplicate message"; break;
1809
0
        case 0x0a: str = "Invalid destination"; break;
1810
0
        case 0x0d: str = "Message expired"; break;
1811
0
        case 0x1f: str = "Unknown error"; break;
1812
0
        default: str = "Reserved"; break;
1813
0
        }
1814
0
        break;
1815
1816
0
    default:
1817
0
        str = "Reserved";
1818
0
        break;
1819
0
    }
1820
1821
0
    proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_msg_status_code, tvb, offset, 1,
1822
0
        oct,
1823
0
        "%s (%u)",
1824
0
        str, msg_status_code);
1825
0
}
1826
1827
static void
1828
tele_param_tp_failure_cause(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1829
0
{
1830
0
    EXACT_DATA_CHECK(len, 1);
1831
1832
0
    proto_tree_add_item(tree, hf_ansi_637_tele_tp_failure_cause_value, tvb, offset, 1, ENC_BIG_ENDIAN);
1833
0
}
1834
1835
660
#define NUM_TELE_PARAM array_length(ansi_tele_param_strings)
1836
static int ett_ansi_637_tele_param[NUM_TELE_PARAM];
1837
static void (* const ansi_637_tele_param_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p) = {
1838
    tele_param_msg_id,                  /* Message Identifier */
1839
    tele_param_user_data,               /* User Data */
1840
    tele_param_rsp_code,                /* User Response Code */
1841
    tele_param_message_center_timestamp,/* Message Center Time Stamp */
1842
    tele_param_validity_period_abs,     /* Validity Period - Absolute */
1843
    tele_param_validity_period_rel,     /* Validity Period - Relative */
1844
    tele_param_deferred_del_abs,        /* Deferred Delivery Time - Absolute */
1845
    tele_param_deferred_del_rel,        /* Deferred Delivery Time - Relative */
1846
    tele_param_pri_ind,                 /* Priority Indicator */
1847
    tele_param_priv_ind,                /* Privacy Indicator */
1848
    tele_param_reply_opt,               /* Reply Option */
1849
    tele_param_num_messages,            /* Number of Messages */
1850
    tele_param_alert,                   /* Alert on Message Delivery */
1851
    tele_param_lang_ind,                /* Language Indicator */
1852
    tele_param_cb_num,                  /* Call-Back Number */
1853
    tele_param_disp_mode,               /* Message Display Mode */
1854
    tele_param_mult_enc_user_data,      /* Multiple Encoding User Data */
1855
    tele_param_msg_deposit_idx,         /* Message Deposit Index */
1856
    tele_param_srvc_cat_prog_data,      /* Service Category Program Data */
1857
    tele_param_srvc_cat_prog_results,   /* Service Category Program Results */
1858
    tele_param_msg_status,              /* Message status */
1859
    tele_param_tp_failure_cause,        /* TP-Failure cause */
1860
    NULL,                               /* Enhanced VMN */
1861
    NULL                                /* Enhanced VMN Ack */
1862
};
1863
1864
static void
1865
trans_param_tele_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, char *add_string, int string_len)
1866
0
{
1867
0
    uint32_t    value;
1868
0
    const char *str = NULL;
1869
1870
0
    EXACT_DATA_CHECK(len, 2);
1871
1872
0
    value = tvb_get_ntohs(tvb, offset);
1873
1874
0
    ansi_637_trans_tele_id = value;
1875
1876
0
    str = try_val_to_str(value, ansi_tele_id_strings);
1877
1878
0
    if (NULL == str)
1879
0
    {
1880
0
        switch (value)
1881
0
        {
1882
0
        case 1:
1883
0
            str = "Reserved for maintenance";
1884
0
            break;
1885
0
        case 4102:
1886
0
            str = "CDMA Service Category Programming Teleservice (SCPT)";
1887
0
            break;
1888
0
        case 4103:
1889
0
            str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
1890
0
            break;
1891
0
        case 32513:
1892
0
            str = "TDMA Cellular Messaging Teleservice";
1893
0
            break;
1894
0
        case 32514:
1895
0
            str = "TDMA Cellular Paging Teleservice (CPT-136)";
1896
0
            break;
1897
0
        case 32515:
1898
0
            str = "TDMA Over-the-Air Activation Teleservice (OATS)";
1899
0
            break;
1900
0
        case 32520:
1901
0
            str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
1902
0
            break;
1903
0
        case 32584:
1904
0
            str = "TDMA Segmented System Assisted Mobile Positioning Service";
1905
0
            break;
1906
0
        default:
1907
0
            if ((value >= 2) && (value <= 4095))
1908
0
            {
1909
0
                str = "Reserved for assignment by TIA-41";
1910
0
            }
1911
0
            else if ((value >= 4104) && (value <= 4113))
1912
0
            {
1913
0
                str = "Reserved for GSM1x Teleservice (CDMA)";
1914
0
            }
1915
0
            else if ((value >= 4114) && (value <= 32512))
1916
0
            {
1917
0
                str = "Reserved for assignment by TIA-41";
1918
0
            }
1919
0
            else if ((value >= 32521) && (value <= 32575))
1920
0
            {
1921
0
                str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
1922
0
            }
1923
0
            else if ((value >= 49152) && (value <= 65535))
1924
0
            {
1925
0
                str = "Reserved for carrier specific teleservices";
1926
0
            }
1927
0
            else
1928
0
            {
1929
0
                str = "Unrecognized Teleservice ID";
1930
0
            }
1931
0
            break;
1932
0
        }
1933
0
    }
1934
1935
    /*
1936
     * NOT format_value because I don't need the text from the hf_
1937
     */
1938
0
    proto_tree_add_uint_format(tree, hf_ansi_637_trans_tele_id, tvb, offset, 2,
1939
0
        value,
1940
0
        "%s (%u)",
1941
0
        str, value);
1942
1943
0
    snprintf(add_string, string_len, " - %s (%u)", str, value);
1944
0
}
1945
1946
static void
1947
trans_param_srvc_cat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, char *add_string, int string_len)
1948
0
{
1949
0
    uint32_t    value;
1950
0
    const char *str;
1951
1952
0
    EXACT_DATA_CHECK(len, 2);
1953
1954
0
    value = tvb_get_ntohs(tvb, offset);
1955
1956
0
    str = val_to_str_const(value, ansi_tsb58_srvc_cat_vals, "Reserved");
1957
0
    proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_srvc_cat, tvb, offset, 2,
1958
0
        value,
1959
0
        "%s (%u)",
1960
0
        str, value);
1961
1962
0
    snprintf(add_string, string_len, " - %s (%u)", str, value);
1963
1964
0
    if ((value >= ANSI_TSB58_SRVC_CAT_CMAS_MIN) && (value <= ANSI_TSB58_SRVC_CAT_CMAS_MAX))
1965
0
    {
1966
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " - CMAS (%s)", str);
1967
0
    }
1968
0
}
1969
1970
static const value_string trans_param_addr_data_net_ton_strings[] = {
1971
    { 0x00,     "Unknown" },
1972
    { 0x01,     "Internet Protocol (RFC 791)" },
1973
    { 0x02,     "Internet Email Address (RFC 822)" },
1974
    { 0, NULL }
1975
};
1976
1977
static void
1978
trans_param_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, char *add_string _U_, int string_len _U_)
1979
0
{
1980
0
    uint8_t     oct, oct2, odd;
1981
0
    bool        email_addr;
1982
0
    uint32_t    i, saved_offset, required_octs;
1983
0
    uint64_t    num_fields;
1984
0
    tvbuff_t   *tvb_out;
1985
1986
0
    SHORT_DATA_CHECK(len, 2);
1987
1988
0
    oct = tvb_get_uint8(tvb, offset);
1989
1990
0
    proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_digit_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
1991
0
    proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_number_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
1992
1993
0
    if (oct & 0x80)
1994
0
    {
1995
0
        if (oct & 0x40)
1996
0
        {
1997
0
            email_addr = (((oct & 0x38) >> 3) == 0x02) ? true : false;
1998
1999
            /*
2000
             * do not change to ...add_item() with VALS in hf definition because this parameter is
2001
             * used below in the 'else' with a different string array
2002
             */
2003
0
            proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_addr_param_ton, tvb, offset, 1,
2004
0
                oct,
2005
0
                "%s (%u)",
2006
0
                val_to_str_const((oct & 0x38) >> 3, trans_param_addr_data_net_ton_strings, "Reserved"), (oct & 0x38) >> 3);
2007
2008
0
            proto_tree_add_bits_ret_val(tree, hf_ansi_637_trans_addr_param_num_fields, tvb, (offset*8)+5, 8, &num_fields, ENC_BIG_ENDIAN);
2009
0
            if (num_fields == 0) return;
2010
0
            offset += 1;
2011
2012
0
            SHORT_DATA_CHECK(len - 2, num_fields);
2013
2014
0
            tvb_out = tvb_new_octet_aligned(tvb, offset*8 + 5, (int)num_fields*8);
2015
0
            add_new_data_source(pinfo, tvb_out, "Address");
2016
2017
0
            if (email_addr)
2018
0
            {
2019
0
                proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_number, tvb_out, 0, (int)num_fields,
2020
0
                    ENC_ASCII);
2021
0
            }
2022
0
            else
2023
0
            {
2024
0
                proto_tree_add_item(tree, hf_ansi_637_trans_bin_addr, tvb_out, 0, (int)num_fields, ENC_NA);
2025
0
            }
2026
2027
0
            offset += ((uint32_t)num_fields);
2028
2029
0
            proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_07, tvb, offset, 1, ENC_BIG_ENDIAN);
2030
0
        }
2031
0
        else
2032
0
        {
2033
            /*
2034
             * do not change to ...add_item() with VALS in hf definition because this parameter
2035
             * is used above in the 'if' with a different string array
2036
             */
2037
0
            proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_addr_param_ton, tvb, offset, 1,
2038
0
                oct,
2039
0
                "%s (%u)",
2040
0
                val_to_str_const((oct & 0x38) >> 3, ansi_a_ms_info_rec_num_type_vals, "Reserved"), (oct & 0x38) >> 3);
2041
2042
0
            proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_plan, tvb, offset, 2, ENC_BIG_ENDIAN);
2043
0
            offset += 1;
2044
2045
0
            proto_tree_add_bits_ret_val(tree, hf_ansi_637_trans_addr_param_num_fields, tvb, (offset*8)+1, 8, &num_fields, ENC_BIG_ENDIAN);
2046
0
            offset += 1;
2047
2048
0
            if (num_fields == 0) return;
2049
2050
0
            SHORT_DATA_CHECK(len - 3, num_fields);
2051
2052
0
            tvb_out = tvb_new_octet_aligned(tvb, offset*8 + 1, (int)num_fields*8);
2053
0
            add_new_data_source(pinfo, tvb_out, "Address");
2054
2055
0
            proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_number, tvb_out, 0, (int)num_fields,
2056
0
                ENC_ASCII);
2057
2058
0
            offset += ((uint32_t)num_fields);
2059
2060
0
            proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_7f, tvb, offset, 1, ENC_BIG_ENDIAN);
2061
0
        }
2062
0
    }
2063
0
    else
2064
0
    {
2065
0
        proto_tree_add_bits_ret_val(tree, hf_ansi_637_trans_addr_param_num_fields, tvb, (offset*8)+2, 8, &num_fields, ENC_BIG_ENDIAN);
2066
0
        offset += 1;
2067
2068
0
        oct = tvb_get_uint8(tvb, offset);
2069
0
        odd = false;
2070
2071
0
        if (num_fields > 0)
2072
0
        {
2073
0
            i = ((uint32_t)num_fields - 1) * 4;
2074
0
            required_octs = (i / 8) + ((i % 8) ? 1 : 0);
2075
2076
0
            SHORT_DATA_CHECK(len - 2, required_octs);
2077
2078
0
            odd = num_fields & 0x01;
2079
0
            memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
2080
0
            saved_offset = offset;
2081
0
            offset += 1;
2082
2083
0
            i = 0;
2084
0
            while (i < num_fields)
2085
0
            {
2086
0
                ansi_637_bigbuf[i] =
2087
0
                    air_digits[(oct & 0x3c) >> 2];
2088
2089
0
                i += 1;
2090
0
                if (i >= num_fields) break;
2091
2092
0
                oct2 = tvb_get_uint8(tvb, offset);
2093
0
                offset += 1;
2094
2095
0
                ansi_637_bigbuf[i] =
2096
0
                    air_digits[((oct & 0x03) << 2) | ((oct2 & 0xc0) >> 6)];
2097
2098
0
                oct = oct2;
2099
2100
0
                i += 1;
2101
0
            }
2102
2103
0
            proto_tree_add_string_format(tree, hf_ansi_637_trans_addr_param_number, tvb, saved_offset, offset - saved_offset,
2104
0
                ansi_637_bigbuf,
2105
0
                "Number: %s",
2106
0
                ansi_637_bigbuf);
2107
0
        }
2108
2109
0
        proto_tree_add_item(tree,
2110
0
            odd ? hf_ansi_637_reserved_bits_8_03 : hf_ansi_637_reserved_bits_8_3f,
2111
0
            tvb, offset - 1, 1, ENC_BIG_ENDIAN);
2112
0
    }
2113
0
}
2114
2115
static const value_string trans_param_subaddr_type_strings[] = {
2116
    { 0x0,      "NSAP (CCITT Recommendation X.213 or ISO 8348 AD2)" },
2117
    { 0x1,      "User-specified" },
2118
    { 0, NULL }
2119
};
2120
2121
static void
2122
trans_param_subaddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, char *add_string _U_, int string_len _U_)
2123
0
{
2124
0
    uint8_t     num_fields;
2125
0
    uint32_t    value;
2126
0
    tvbuff_t   *tvb_out;
2127
2128
0
    SHORT_DATA_CHECK(len, 2);
2129
2130
0
    value = tvb_get_ntohs(tvb, offset);
2131
2132
0
    proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_subaddr_type, tvb, offset, 2,
2133
0
        value,
2134
0
        "%s (%u)",
2135
0
        val_to_str_const((value & 0xe000) >> 13, trans_param_subaddr_type_strings, "Reserved"), (value & 0xe000) >> 13);
2136
2137
0
    proto_tree_add_item(tree, hf_ansi_637_trans_subaddr_odd_even_ind, tvb, offset, 2, ENC_BIG_ENDIAN);
2138
0
    proto_tree_add_item(tree, hf_ansi_637_trans_subaddr_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
2139
2140
0
    num_fields = (value & 0x0ff0) >> 4;
2141
2142
0
    if (num_fields == 0) return;
2143
2144
0
    SHORT_DATA_CHECK(len - 2, num_fields);
2145
2146
0
    offset += 1;
2147
0
    tvb_out = tvb_new_octet_aligned(tvb, offset*8 + 4, num_fields*8);
2148
0
    add_new_data_source(pinfo, tvb_out, "Subaddress");
2149
2150
0
    proto_tree_add_item(tree, hf_ansi_637_trans_bin_addr, tvb_out, 0, num_fields, ENC_NA);
2151
2152
0
    offset += num_fields;
2153
2154
0
    proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, offset, 1, ENC_BIG_ENDIAN);
2155
0
}
2156
2157
static void
2158
trans_param_bearer_reply_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned len _U_, uint32_t offset, char *add_string, int string_len)
2159
0
{
2160
0
    proto_tree_add_item(tree, hf_ansi_637_trans_bearer_reply_seq_num, tvb, offset, 1, ENC_BIG_ENDIAN);
2161
0
    proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_03, tvb, offset, 1, ENC_BIG_ENDIAN);
2162
2163
0
    snprintf(add_string, string_len, " - Reply Sequence Number (%u)",
2164
0
        (tvb_get_uint8(tvb, offset) & 0xfc) >> 2);
2165
0
}
2166
2167
static const value_string trans_param_cause_codes_error_class_strings[] = {
2168
    { 0x00,     "No Error" },
2169
    { 0x01,     "Reserved" },
2170
    { 0x02,     "Temporary Condition" },
2171
    { 0x03,     "Permanent Condition" },
2172
    { 0, NULL }
2173
};
2174
2175
static void
2176
trans_param_cause_codes(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned len, uint32_t offset, char *add_string, int string_len)
2177
0
{
2178
0
    uint8_t     oct;
2179
0
    const char *str;
2180
2181
0
    proto_tree_add_item(tree, hf_ansi_637_trans_cause_codes_seq_num, tvb, offset, 1, ENC_BIG_ENDIAN);
2182
0
    proto_tree_add_item(tree, hf_ansi_637_trans_cause_codes_error_class, tvb, offset, 1, ENC_BIG_ENDIAN);
2183
2184
0
    oct = tvb_get_uint8(tvb, offset);
2185
2186
0
    snprintf(add_string, string_len, " - Reply Sequence Number (%u)", (oct & 0xfc) >> 2);
2187
2188
0
    if (!(oct & 0x03)) return;
2189
2190
0
    if (len == 1) return;
2191
2192
0
    offset += 1;
2193
2194
0
    oct = tvb_get_uint8(tvb, offset);
2195
2196
0
    switch (oct)
2197
0
    {
2198
0
    case   0: str = "Address vacant"; break;
2199
0
    case   1: str = "Address translation failure"; break;
2200
0
    case   2: str = "Network resource shortage"; break;
2201
0
    case   3: str = "Network failure"; break;
2202
0
    case   4: str = "Invalid Teleservice ID"; break;
2203
0
    case   5: str = "Other network problem"; break;
2204
0
    case   6: str = "Unsupported network interface"; break;
2205
0
    case  32: str = "No page response"; break;
2206
0
    case  33: str = "Destination busy"; break;
2207
0
    case  34: str = "No acknowledgement"; break;
2208
0
    case  35: str = "Destination resource shortage"; break;
2209
0
    case  36: str = "SMS delivery postponed"; break;
2210
0
    case  37: str = "Destination out of service"; break;
2211
0
    case  38: str = "Destination no longer at this address"; break;
2212
0
    case  39: str = "Other terminal problem"; break;
2213
0
    case  64: str = "Radio interface resource shortage"; break;
2214
0
    case  65: str = "Radio interface incompatibility"; break;
2215
0
    case  66: str = "Other radio interface problem"; break;
2216
0
    case  67: str = "Unsupported Base Station Capability"; break;
2217
0
    case  96: str = "Encoding problem"; break;
2218
0
    case  97: str = "Service origination denied"; break;
2219
0
    case  98: str = "Service termination denied"; break;
2220
0
    case  99: str = "Supplementary service not supported"; break;
2221
0
    case 100: str = "Service not supported"; break;
2222
0
    case 101: str = "Reserved"; break;
2223
0
    case 102: str = "Missing expected parameter"; break;
2224
0
    case 103: str = "Missing mandatory parameter"; break;
2225
0
    case 104: str = "Unrecognized parameter value"; break;
2226
0
    case 105: str = "Unexpected parameter value"; break;
2227
0
    case 106: str = "User Data size error"; break;
2228
0
    case 107: str = "Other general problems"; break;
2229
0
    case 108: str = "Session not active"; break;
2230
0
    default:
2231
0
        if ((oct >= 7) && (oct <= 31)) { str = "Reserved, treat as Other network problem"; }
2232
0
        else if ((oct >= 40) && (oct <= 47)) { str = "Reserved, treat as Other terminal problem"; }
2233
0
        else if ((oct >= 48) && (oct <= 63)) { str = "Reserved, treat as SMS delivery postponed"; }
2234
0
        else if ((oct >= 68) && (oct <= 95)) { str = "Reserved, treat as Other radio interface problem"; }
2235
0
        else if ((oct >= 109) && (oct <= 223)) { str = "Reserved, treat as Other general problems"; }
2236
0
        else { str = "Reserved for protocol extension, treat as Other general problems"; }
2237
0
        break;
2238
0
    }
2239
2240
0
    proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_cause_codes_code, tvb, offset, 1,
2241
0
        oct,
2242
0
        "%s (%u)",
2243
0
        str, oct);
2244
0
}
2245
2246
static void
2247
trans_param_bearer_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, unsigned len, uint32_t offset, char *add_string _U_, int string_len _U_)
2248
0
{
2249
0
    tvbuff_t    *tele_tvb;
2250
2251
    /*
2252
     * dissect the embedded teleservice data
2253
     */
2254
0
    tele_tvb = tvb_new_subset_length(tvb, offset, len);
2255
2256
0
    dissector_try_uint(tele_dissector_table, ansi_637_trans_tele_id, tele_tvb, pinfo, g_tree);
2257
0
}
2258
2259
225
#define NUM_TRANS_PARAM array_length(ansi_trans_param_strings)
2260
static int ett_ansi_637_trans_param[NUM_TRANS_PARAM];
2261
static void (* const ansi_637_trans_param_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, char *add_string, int string_len) = {
2262
    trans_param_tele_id,                /* Teleservice Identifier */
2263
    trans_param_srvc_cat,               /* Service Category */
2264
    trans_param_address,                /* Originating Address */
2265
    trans_param_subaddress,             /* Originating Subaddress */
2266
    trans_param_address,                /* Destination Address */
2267
    trans_param_subaddress,             /* Destination Subaddress */
2268
    trans_param_bearer_reply_opt,       /* Bearer Reply Option */
2269
    trans_param_cause_codes,            /* Cause Codes */
2270
    trans_param_bearer_data,            /* Bearer Data */
2271
    NULL,                               /* NONE */
2272
};
2273
2274
285
#define NUM_TRANS_MSG_TYPE array_length(ansi_trans_msg_type_strings)
2275
static int ett_ansi_637_trans_msg[NUM_TRANS_MSG_TYPE];
2276
2277
/* GENERIC IS-637 DISSECTOR FUNCTIONS */
2278
2279
static bool
2280
dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t *offset, bool *has_private_data_p)
2281
0
{
2282
0
    void        (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, unsigned, uint32_t, bool *) = NULL;
2283
0
    uint8_t     oct;
2284
0
    uint8_t     len;
2285
0
    uint32_t    curr_offset;
2286
0
    int         ett_param_idx, idx;
2287
0
    proto_tree  *subtree;
2288
0
    proto_item  *item;
2289
0
    const char *str = NULL;
2290
2291
2292
0
    curr_offset = *offset;
2293
2294
0
    oct = tvb_get_uint8(tvb, curr_offset);
2295
0
    str = try_val_to_str_idx_ext((uint32_t) oct, &ansi_tele_param_strings_ext, &idx);
2296
2297
0
    if (NULL == str)
2298
0
    {
2299
0
        return false;
2300
0
    }
2301
2302
0
    ett_param_idx = ett_ansi_637_tele_param[idx];
2303
0
    param_fcn = ansi_637_tele_param_fcn[idx];
2304
2305
0
    subtree =
2306
0
        proto_tree_add_subtree(tree, tvb, curr_offset, -1,
2307
0
            ett_param_idx, &item, str);
2308
2309
0
    proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id, tvb, curr_offset, 1, oct);
2310
2311
0
    curr_offset += 1;
2312
2313
0
    len = tvb_get_uint8(tvb, curr_offset);
2314
2315
0
    proto_item_set_len(item, (curr_offset - *offset) + len + 1);
2316
2317
0
    proto_tree_add_uint(subtree, hf_ansi_637_tele_length, tvb, curr_offset, 1, len);
2318
2319
0
    curr_offset += 1;
2320
2321
0
    if (len > 0)
2322
0
    {
2323
0
        if (param_fcn == NULL)
2324
0
        {
2325
0
            proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_no_tele_parameter_dissector, tvb, curr_offset, len);
2326
0
        }
2327
0
        else
2328
0
        {
2329
            /*
2330
             * internal working (aka hack) for CMAS
2331
             *
2332
             * the 'User Data' subparameter is encoded in a special way for CMAS
2333
             * (as per TIA-1149)
2334
             *
2335
             * if (Broadcast SMS && 'User Data') then call CMAS dissector
2336
             */
2337
0
            if ((ansi_637_trans_tele_id == INTERNAL_BROADCAST_TELE_ID) &&
2338
0
                (oct == 0x01))
2339
0
            {
2340
0
                param_fcn = tele_param_user_data_cmas;
2341
0
            }
2342
2343
0
            (*param_fcn)(tvb, pinfo, subtree, len, curr_offset, has_private_data_p);
2344
0
        }
2345
2346
0
        curr_offset += len;
2347
0
    }
2348
2349
0
    *offset = curr_offset;
2350
2351
0
    return true;
2352
0
}
2353
2354
static void
2355
dissect_ansi_637_tele_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ansi_637_tree, bool *has_private_data_p)
2356
0
{
2357
0
    uint8_t     len;
2358
0
    uint32_t    curr_offset;
2359
2360
0
    curr_offset = 0;
2361
0
    len = tvb_reported_length(tvb);
2362
2363
0
    while ((len - curr_offset) > 0)
2364
0
    {
2365
0
        if (!dissect_ansi_637_tele_param(tvb, pinfo, ansi_637_tree, &curr_offset, has_private_data_p))
2366
0
        {
2367
0
            proto_tree_add_expert(ansi_637_tree, pinfo, &ei_ansi_637_unknown_tele_parameter, tvb, curr_offset, len - curr_offset);
2368
0
            break;
2369
0
        }
2370
0
    }
2371
0
}
2372
2373
static int
2374
dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2375
0
{
2376
0
    proto_item  *ansi_637_item;
2377
0
    proto_tree  *ansi_637_tree = NULL;
2378
0
    const char *str = NULL;
2379
0
    uint32_t    value;
2380
0
    bool        has_private_data = false;
2381
2382
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IS-637-A");
2383
2384
    /* In the interest of speed, if "tree" is NULL, don't do any work not
2385
     * necessary to generate protocol tree items.
2386
     */
2387
0
    if (tree)
2388
0
    {
2389
0
        g_tree = tree;
2390
2391
0
        value = pinfo->match_uint;
2392
2393
        /*
2394
         * create the ansi_637 protocol tree
2395
         */
2396
0
        str = try_val_to_str(value, ansi_tele_id_strings);
2397
2398
0
        if (NULL == str)
2399
0
        {
2400
0
            switch (value)
2401
0
            {
2402
0
            case 1:
2403
0
                str = "Reserved for maintenance";
2404
0
                break;
2405
0
            case 4102:
2406
0
                str = "CDMA Service Category Programming Teleservice (SCPT)";
2407
0
                break;
2408
0
            case 4103:
2409
0
                str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
2410
0
                break;
2411
0
            case 32513:
2412
0
                str = "TDMA Cellular Messaging Teleservice";
2413
0
                break;
2414
0
            case 32514:
2415
0
                str = "TDMA Cellular Paging Teleservice (CPT-136)";
2416
0
                break;
2417
0
            case 32515:
2418
0
                str = "TDMA Over-the-Air Activation Teleservice (OATS)";
2419
0
                break;
2420
0
            case 32520:
2421
0
                str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
2422
0
                break;
2423
0
            case 32584:
2424
0
                str = "TDMA Segmented System Assisted Mobile Positioning Service";
2425
0
                break;
2426
0
            default:
2427
0
                if ((value >= 2) && (value <= 4095))
2428
0
                {
2429
0
                    str = "Reserved for assignment by TIA-41";
2430
0
                }
2431
0
                else if ((value >= 4104) && (value <= 4113))
2432
0
                {
2433
0
                    str = "Reserved for GSM1x Teleservice (CDMA)";
2434
0
                }
2435
0
                else if ((value >= 4114) && (value <= 32512))
2436
0
                {
2437
0
                    str = "Reserved for assignment by TIA-41";
2438
0
                }
2439
0
                else if ((value >= 32521) && (value <= 32575))
2440
0
                {
2441
0
                    str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
2442
0
                }
2443
0
                else if ((value >= 49152) && (value <= 65535))
2444
0
                {
2445
0
                    str = "Reserved for carrier specific teleservices";
2446
0
                }
2447
0
                else
2448
0
                {
2449
0
                    str = "Unrecognized Teleservice ID";
2450
0
                }
2451
0
                break;
2452
0
            }
2453
0
        }
2454
2455
0
        if (value == INTERNAL_BROADCAST_TELE_ID)
2456
0
        {
2457
            /*
2458
             * supposed to be "Reserved for carrier specific teleservices"
2459
             * but we are using it to key SMS Broadcast dissection where
2460
             * there is no teleservice ID
2461
             */
2462
0
            ansi_637_item =
2463
0
                proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
2464
0
                    "ANSI IS-637-A (SMS) Teleservice Layer");
2465
0
        }
2466
0
        else
2467
0
        {
2468
0
            ansi_637_item =
2469
0
                proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
2470
0
                    "ANSI IS-637-A (SMS) Teleservice Layer - %s (%u)",
2471
0
                    str, pinfo->match_uint);
2472
0
        }
2473
2474
0
        ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele);
2475
2476
0
        dissect_ansi_637_tele_message(tvb, pinfo, ansi_637_tree, &has_private_data);
2477
0
    }
2478
0
    return tvb_captured_length(tvb);
2479
0
}
2480
2481
static bool
2482
dissect_ansi_637_trans_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t *offset)
2483
0
{
2484
0
    void        (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, unsigned, uint32_t, char *, int) = NULL;
2485
0
    uint8_t     oct;
2486
0
    uint8_t     len;
2487
0
    uint32_t    curr_offset;
2488
0
    int         ett_param_idx, idx;
2489
0
    proto_tree  *subtree;
2490
0
    proto_item  *item;
2491
0
    const char *str;
2492
2493
0
    curr_offset = *offset;
2494
2495
0
    oct = tvb_get_uint8(tvb, curr_offset);
2496
0
    str = try_val_to_str_idx((uint32_t) oct, ansi_trans_param_strings, &idx);
2497
2498
0
    if (NULL == str)
2499
0
    {
2500
0
        return false;
2501
0
    }
2502
2503
0
    ett_param_idx = ett_ansi_637_trans_param[idx];
2504
0
    param_fcn = ansi_637_trans_param_fcn[idx];
2505
2506
0
    subtree = proto_tree_add_subtree(tree, tvb, curr_offset, -1, ett_param_idx, &item, str);
2507
2508
0
    proto_tree_add_uint(subtree, hf_ansi_637_trans_param_id, tvb, curr_offset, 1, oct);
2509
2510
0
    curr_offset += 1;
2511
2512
0
    len = tvb_get_uint8(tvb, curr_offset);
2513
2514
0
    proto_item_set_len(item, (curr_offset - *offset) + len + 1);
2515
2516
0
    proto_tree_add_uint(subtree, hf_ansi_637_trans_length, tvb, curr_offset, 1, len);
2517
2518
0
    curr_offset += 1;
2519
2520
0
    if (len > 0)
2521
0
    {
2522
0
        if (param_fcn == NULL)
2523
0
        {
2524
0
            proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_no_trans_parameter_dissector, tvb, curr_offset, len);
2525
0
        }
2526
0
        else
2527
0
        {
2528
0
            char        *ansi_637_add_string;
2529
2530
0
            ansi_637_add_string = (char *) wmem_alloc(pinfo->pool, 1024);
2531
0
            ansi_637_add_string[0] = '\0';
2532
0
            (*param_fcn)(tvb, pinfo, subtree, len, curr_offset, ansi_637_add_string, 1024);
2533
2534
0
            if (ansi_637_add_string[0] != '\0')
2535
0
            {
2536
0
                proto_item_append_text(item, "%s", ansi_637_add_string);
2537
0
            }
2538
0
        }
2539
2540
0
        curr_offset += len;
2541
0
    }
2542
2543
0
    *offset = curr_offset;
2544
2545
0
    return true;
2546
0
}
2547
2548
2549
static int
2550
dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2551
0
{
2552
0
    proto_item  *ansi_637_item;
2553
0
    proto_tree  *ansi_637_tree = NULL;
2554
0
    uint32_t    curr_offset;
2555
0
    int         idx;
2556
0
    const char *str = NULL;
2557
0
    uint8_t     oct;
2558
0
    uint8_t     len;
2559
2560
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IS-637-A");
2561
2562
    /* In the interest of speed, if "tree" is NULL, don't do any work not
2563
     * necessary to generate protocol tree items.
2564
     */
2565
0
    if (tree)
2566
0
    {
2567
0
        g_tree = tree;
2568
2569
        /*
2570
         * reset the teleservice ID for each dissection
2571
         */
2572
0
        ansi_637_trans_tele_id = 0;
2573
2574
        /*
2575
         * create the ansi_637 protocol tree
2576
         */
2577
0
        oct = tvb_get_uint8(tvb, 0);
2578
2579
0
        str = try_val_to_str_idx(oct, ansi_trans_msg_type_strings, &idx);
2580
2581
0
        if (NULL == str)
2582
0
        {
2583
0
            ansi_637_item =
2584
0
                proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
2585
0
                    "ANSI IS-637-A (SMS) Transport Layer - Unrecognized Transport Layer Message Type (%u)", oct);
2586
2587
0
            ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans);
2588
0
        }
2589
0
        else
2590
0
        {
2591
0
            ansi_637_item =
2592
0
                proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
2593
0
                    "ANSI IS-637-A (SMS) Transport Layer - %s", str);
2594
2595
0
            ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans_msg[idx]);
2596
2597
0
            if (oct == ANSI_TRANS_MSG_TYPE_BROADCAST)
2598
0
            {
2599
                /*
2600
                 * there is no teleservice ID for Broadcast but we want the
2601
                 * bearer data to be dissected
2602
                 *
2603
                 * using a reserved value to key dissector port
2604
                 */
2605
0
                ansi_637_trans_tele_id = INTERNAL_BROADCAST_TELE_ID;
2606
2607
0
                col_append_str(pinfo->cinfo, COL_INFO, "(BROADCAST)");
2608
0
            }
2609
0
        }
2610
2611
0
        curr_offset = 1;
2612
2613
0
        len = tvb_reported_length(tvb);
2614
2615
0
        while ((len - curr_offset) > 0)
2616
0
        {
2617
0
            if (!dissect_ansi_637_trans_param(tvb, pinfo, ansi_637_tree, &curr_offset))
2618
0
            {
2619
0
                proto_tree_add_expert(ansi_637_tree, pinfo, &ei_ansi_637_unknown_trans_parameter, tvb, curr_offset, len - curr_offset);
2620
0
                break;
2621
0
            }
2622
0
        }
2623
0
    }
2624
0
    return tvb_captured_length(tvb);
2625
0
}
2626
2627
2628
/* Dissect SMS embedded in SIP */
2629
static int
2630
dissect_ansi_637_trans_app(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2631
0
{
2632
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "/");
2633
0
    col_set_fence(pinfo->cinfo, COL_INFO);
2634
0
    return dissect_ansi_637_trans(tvb, pinfo, tree, data);
2635
0
}
2636
2637
2638
/* Register the protocol with Wireshark */
2639
void
2640
proto_register_ansi_637(void)
2641
15
{
2642
15
    unsigned            i;
2643
2644
    /* Setup list of header fields */
2645
15
    static hf_register_info hf_trans[] = {
2646
15
        { &hf_ansi_637_trans_param_id,
2647
15
            { "Transport Param ID", "ansi_637_trans.param_id",
2648
15
            FT_UINT8, BASE_DEC, VALS(ansi_trans_param_strings), 0,
2649
15
            NULL, HFILL }
2650
15
        },
2651
15
        { &hf_ansi_637_trans_length,
2652
15
            { "Length", "ansi_637_trans.len",
2653
15
            FT_UINT8, BASE_DEC, NULL, 0,
2654
15
            NULL, HFILL }
2655
15
        },
2656
15
        { &hf_ansi_637_trans_bin_addr,
2657
15
            { "Binary Address", "ansi_637_trans.bin_addr",
2658
15
            FT_BYTES, BASE_NONE, NULL, 0,
2659
15
            NULL, HFILL }
2660
15
        },
2661
15
        { &hf_ansi_637_trans_tele_id,
2662
15
            { "Teleservice ID", "ansi_637_trans.tele_id",
2663
15
            FT_UINT16, BASE_DEC, NULL, 0,
2664
15
            NULL, HFILL }
2665
15
        },
2666
15
        { &hf_ansi_637_trans_srvc_cat,
2667
15
            { "Service Category", "ansi_637_trans.srvc_cat",
2668
15
            FT_UINT16, BASE_DEC, NULL, 0,
2669
15
            NULL, HFILL }
2670
15
        },
2671
15
        { &hf_ansi_637_trans_addr_param_digit_mode,
2672
15
            { "Digit Mode", "ansi_637_trans.addr_param.digit_mode",
2673
15
            FT_BOOLEAN, 8, TFS(&tfs_digit_mode_8bit_4bit), 0x80,
2674
15
            NULL, HFILL }
2675
15
        },
2676
15
        { &hf_ansi_637_trans_addr_param_number_mode,
2677
15
            { "Number Mode", "ansi_637_trans.addr_param.number_mode",
2678
15
            FT_BOOLEAN, 8, TFS(&tfs_number_mode_data_ansi_t1), 0x40,
2679
15
            NULL, HFILL }
2680
15
        },
2681
15
        { &hf_ansi_637_trans_addr_param_ton,
2682
15
            { "Type of Number", "ansi_637_trans.addr_param.ton",
2683
15
            FT_UINT8, BASE_DEC, NULL, 0x38,
2684
15
            NULL, HFILL }
2685
15
        },
2686
15
        { &hf_ansi_637_trans_addr_param_plan,
2687
15
            { "Numbering Plan", "ansi_637_trans.addr_param.plan",
2688
15
            FT_UINT16, BASE_DEC, VALS(ansi_a_ms_info_rec_num_plan_vals), 0x0780,
2689
15
            NULL, HFILL }
2690
15
        },
2691
15
        { &hf_ansi_637_trans_addr_param_num_fields,
2692
15
            { "Number of fields", "ansi_637_trans.addr_param.num_fields",
2693
15
            FT_UINT8, BASE_DEC, NULL, 0x0,
2694
15
            NULL, HFILL }
2695
15
        },
2696
15
        { &hf_ansi_637_trans_addr_param_number,
2697
15
            { "Number", "ansi_637_trans.addr_param.number",
2698
15
            FT_STRING, BASE_NONE, NULL, 0,
2699
15
            NULL, HFILL }
2700
15
        },
2701
15
        { &hf_ansi_637_trans_subaddr_type,
2702
15
            { "Type", "ansi_637_trans.subaddr.type",
2703
15
            FT_UINT16, BASE_DEC, NULL, 0xe000,
2704
15
            NULL, HFILL }
2705
15
        },
2706
15
        { &hf_ansi_637_trans_subaddr_odd_even_ind,
2707
15
            { "Odd/Even Indicator", "ansi_637_trans.subaddr.odd_even_ind",
2708
15
            FT_UINT16, BASE_DEC, VALS(ansi_trans_subaddr_odd_even_ind_strings), 0x1000,
2709
15
            NULL, HFILL }
2710
15
        },
2711
15
        { &hf_ansi_637_trans_subaddr_num_fields,
2712
15
            { "Number of fields", "ansi_637_trans.subaddr.num_fields",
2713
15
            FT_UINT16, BASE_DEC, NULL, 0x0ff0,
2714
15
            NULL, HFILL }
2715
15
        },
2716
15
        { &hf_ansi_637_trans_bearer_reply_seq_num,
2717
15
            { "Reply Sequence Number", "ansi_637_trans.bearer_reply.seq_num",
2718
15
            FT_UINT8, BASE_DEC, NULL, 0xfc,
2719
15
            NULL, HFILL }
2720
15
        },
2721
15
        { &hf_ansi_637_trans_cause_codes_seq_num,
2722
15
            { "Reply Sequence Number", "ansi_637_trans.cause_codes.seq_num",
2723
15
            FT_UINT8, BASE_DEC, NULL, 0xfc,
2724
15
            NULL, HFILL }
2725
15
        },
2726
15
        { &hf_ansi_637_trans_cause_codes_error_class,
2727
15
            { "Error Class", "ansi_637_trans.cause_codes.error_class",
2728
15
            FT_UINT8, BASE_DEC, VALS(trans_param_cause_codes_error_class_strings), 0x03,
2729
15
            NULL, HFILL }
2730
15
        },
2731
15
        { &hf_ansi_637_trans_cause_codes_code,
2732
15
            { "Cause Code", "ansi_637_trans.cause_codes.code",
2733
15
            FT_UINT8, BASE_DEC, NULL, 0,
2734
15
            NULL, HFILL }
2735
15
        }
2736
15
    };
2737
2738
15
    static hf_register_info hf_tele[] = {
2739
15
        { &hf_ansi_637_tele_msg_type,
2740
15
            { "Message Type",
2741
15
            "ansi_637_tele.msg_type",
2742
15
            FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_type_strings), 0xf00000,
2743
15
            NULL, HFILL }
2744
15
        },
2745
15
        { &hf_ansi_637_tele_msg_id,
2746
15
            { "Message ID",
2747
15
            "ansi_637_tele.msg_id",
2748
15
            FT_UINT24, BASE_DEC, NULL, 0x0ffff0,
2749
15
            NULL, HFILL }
2750
15
        },
2751
15
        { &hf_ansi_637_tele_length,
2752
15
            { "Length", "ansi_637_tele.len",
2753
15
            FT_UINT8, BASE_DEC, NULL, 0,
2754
15
            NULL, HFILL }
2755
15
        },
2756
15
        { &hf_ansi_637_tele_msg_status,
2757
15
            { "Message Status",
2758
15
            "ansi_637_tele.msg_status",
2759
15
            FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ansi_tele_msg_status_strings_ext, 0,
2760
15
            NULL, HFILL }
2761
15
        },
2762
15
        { &hf_ansi_637_tele_msg_header_ind,
2763
15
            { "Header Indicator",
2764
15
            "ansi_637_tele.msg_header_ind",
2765
15
            FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_header_ind_strings), 0x000008,
2766
15
            NULL, HFILL }
2767
15
        },
2768
15
        { &hf_ansi_637_tele_msg_rsvd,
2769
15
            { "Reserved",
2770
15
            "ansi_637_tele.msg_rsvd",
2771
15
            FT_UINT24, BASE_DEC, NULL, 0x000007,
2772
15
            NULL, HFILL }
2773
15
        },
2774
15
        { &hf_ansi_637_tele_subparam_id,
2775
15
            { "Teleservice Subparam ID", "ansi_637_tele.subparam_id",
2776
15
            FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ansi_tele_param_strings_ext, 0,
2777
15
            NULL, HFILL }
2778
15
        },
2779
15
        { &hf_ansi_637_tele_user_data_text,
2780
15
            { "Encoded user data", "ansi_637_tele.user_data.text",
2781
15
            FT_STRING, BASE_NONE, NULL, 0,
2782
15
            NULL, HFILL }
2783
15
        },
2784
15
        { &hf_ansi_637_tele_user_data_encoding,
2785
15
            { "Encoding", "ansi_637_tele.user_data.encoding",
2786
15
            FT_UINT16, BASE_DEC, NULL, 0xf800,
2787
15
            NULL, HFILL }
2788
15
        },
2789
15
        { &hf_ansi_637_tele_user_data_message_type,
2790
15
            { "Message Type (see TIA/EIA/IS-91)", "ansi_637_tele.user_data.message_type",
2791
15
            FT_UINT16, BASE_DEC, NULL, 0x07f8,
2792
15
            NULL, HFILL }
2793
15
        },
2794
15
        { &hf_ansi_637_tele_user_data_num_fields,
2795
15
            { "Number of fields", "ansi_637_tele.user_data.num_fields",
2796
15
            FT_UINT16, BASE_DEC, NULL, 0x07f8,
2797
15
            NULL, HFILL }
2798
15
        },
2799
15
        { &hf_ansi_637_tele_response_code,
2800
15
            { "Response Code", "ansi_637_tele.response_code",
2801
15
            FT_UINT8, BASE_DEC, NULL, 0,
2802
15
            NULL, HFILL }
2803
15
        },
2804
15
        { &hf_ansi_637_tele_message_center_ts_year,
2805
15
            { "Timestamp (Year)", "ansi_637_tele.message_center_ts.year",
2806
15
            FT_UINT8, BASE_DEC, NULL, 0,
2807
15
            NULL, HFILL }
2808
15
        },
2809
15
        { &hf_ansi_637_tele_message_center_ts_month,
2810
15
            { "Timestamp (Month)", "ansi_637_tele.message_center_ts.month",
2811
15
            FT_UINT8, BASE_DEC, NULL, 0,
2812
15
            NULL, HFILL }
2813
15
        },
2814
15
        { &hf_ansi_637_tele_message_center_ts_day,
2815
15
            { "Timestamp (Day)", "ansi_637_tele.message_center_ts.day",
2816
15
            FT_UINT8, BASE_DEC, NULL, 0,
2817
15
            NULL, HFILL }
2818
15
        },
2819
15
        { &hf_ansi_637_tele_message_center_ts_hours,
2820
15
            { "Timestamp (Hours)", "ansi_637_tele.message_center_ts.hours",
2821
15
            FT_UINT8, BASE_DEC, NULL, 0,
2822
15
            NULL, HFILL }
2823
15
        },
2824
15
        { &hf_ansi_637_tele_message_center_ts_minutes,
2825
15
            { "Timestamp (Minutes)", "ansi_637_tele.message_center_ts.minutes",
2826
15
            FT_UINT8, BASE_DEC, NULL, 0,
2827
15
            NULL, HFILL }
2828
15
        },
2829
15
        { &hf_ansi_637_tele_message_center_ts_seconds,
2830
15
            { "Timestamp (Seconds)", "ansi_637_tele.message_center_ts.seconds",
2831
15
            FT_UINT8, BASE_DEC, NULL, 0,
2832
15
            NULL, HFILL }
2833
15
        },
2834
15
        { &hf_ansi_637_tele_validity_period_ts_year,
2835
15
            { "Timestamp (Year)", "ansi_637_tele.validity_period_ts.year",
2836
15
            FT_UINT8, BASE_DEC, NULL, 0,
2837
15
            NULL, HFILL }
2838
15
        },
2839
15
        { &hf_ansi_637_tele_validity_period_ts_month,
2840
15
            { "Timestamp (Month)", "ansi_637_tele.validity_period_ts.month",
2841
15
            FT_UINT8, BASE_DEC, NULL, 0,
2842
15
            NULL, HFILL }
2843
15
        },
2844
15
        { &hf_ansi_637_tele_validity_period_ts_day,
2845
15
            { "Timestamp (Day)", "ansi_637_tele.validity_period_ts.day",
2846
15
            FT_UINT8, BASE_DEC, NULL, 0,
2847
15
            NULL, HFILL }
2848
15
        },
2849
15
        { &hf_ansi_637_tele_validity_period_ts_hours,
2850
15
            { "Timestamp (Hours)", "ansi_637_tele.validity_period_ts.hours",
2851
15
            FT_UINT8, BASE_DEC, NULL, 0,
2852
15
            NULL, HFILL }
2853
15
        },
2854
15
        { &hf_ansi_637_tele_validity_period_ts_minutes,
2855
15
            { "Timestamp (Minutes)", "ansi_637_tele.validity_period_ts.minutes",
2856
15
            FT_UINT8, BASE_DEC, NULL, 0,
2857
15
            NULL, HFILL }
2858
15
        },
2859
15
        { &hf_ansi_637_tele_validity_period_ts_seconds,
2860
15
            { "Timestamp (Seconds)", "ansi_637_tele.validity_period_ts.seconds",
2861
15
            FT_UINT8, BASE_DEC, NULL, 0,
2862
15
            NULL, HFILL }
2863
15
        },
2864
15
        { &hf_ansi_637_tele_validity_period_relative_validity,
2865
15
            { "Validity", "ansi_637_tele.validity_period_relative.validity",
2866
15
            FT_UINT8, BASE_DEC, NULL, 0,
2867
15
            NULL, HFILL }
2868
15
        },
2869
15
        { &hf_ansi_637_tele_deferred_del_ts_year,
2870
15
            { "Timestamp (Year)", "ansi_637_tele.deferred_del_ts.year",
2871
15
            FT_UINT8, BASE_DEC, NULL, 0,
2872
15
            NULL, HFILL }
2873
15
        },
2874
15
        { &hf_ansi_637_tele_deferred_del_ts_month,
2875
15
            { "Timestamp (Month)", "ansi_637_tele.deferred_del_ts.month",
2876
15
            FT_UINT8, BASE_DEC, NULL, 0,
2877
15
            NULL, HFILL }
2878
15
        },
2879
15
        { &hf_ansi_637_tele_deferred_del_ts_day,
2880
15
            { "Timestamp (Day)", "ansi_637_tele.deferred_del_ts.day",
2881
15
            FT_UINT8, BASE_DEC, NULL, 0,
2882
15
            NULL, HFILL }
2883
15
        },
2884
15
        { &hf_ansi_637_tele_deferred_del_ts_hours,
2885
15
            { "Timestamp (Hours)", "ansi_637_tele.deferred_del_ts.hours",
2886
15
            FT_UINT8, BASE_DEC, NULL, 0,
2887
15
            NULL, HFILL }
2888
15
        },
2889
15
        { &hf_ansi_637_tele_deferred_del_ts_minutes,
2890
15
            { "Timestamp (Minutes)", "ansi_637_tele.deferred_del_ts.minutes",
2891
15
            FT_UINT8, BASE_DEC, NULL, 0,
2892
15
            NULL, HFILL }
2893
15
        },
2894
15
        { &hf_ansi_637_tele_deferred_del_ts_seconds,
2895
15
            { "Timestamp (Seconds)", "ansi_637_tele.deferred_del_ts.seconds",
2896
15
            FT_UINT8, BASE_DEC, NULL, 0,
2897
15
            NULL, HFILL }
2898
15
        },
2899
15
        { &hf_ansi_637_tele_deferred_del_relative,
2900
15
            { "Delivery Time", "ansi_637_tele.deferred_del.relative",
2901
15
            FT_UINT8, BASE_DEC, NULL, 0,
2902
15
            NULL, HFILL }
2903
15
        },
2904
15
        { &hf_ansi_637_tele_priority_indicator,
2905
15
            { "Priority", "ansi_637_tele.priority_indicator",
2906
15
            FT_UINT8, BASE_DEC, VALS(tele_param_priority_ind_strings), 0xc0,
2907
15
            NULL, HFILL }
2908
15
        },
2909
15
        { &hf_ansi_637_tele_privacy_indicator,
2910
15
            { "Privacy", "ansi_637_tele.privacy_indicator",
2911
15
            FT_UINT8, BASE_DEC, VALS(tele_param_privacy_ind_strings), 0xc0,
2912
15
            NULL, HFILL }
2913
15
        },
2914
15
        { &hf_ansi_637_tele_reply_option_user_ack_req,
2915
15
            { "User Acknowledgement Requested", "ansi_637_tele.reply_option.user_ack_req",
2916
15
            FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
2917
15
            NULL, HFILL }
2918
15
        },
2919
15
        { &hf_ansi_637_tele_reply_option_dak_req,
2920
15
            { "Delivery Acknowledgement Requested", "ansi_637_tele.reply_option.dak_req",
2921
15
            FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
2922
15
            NULL, HFILL }
2923
15
        },
2924
15
        { &hf_ansi_637_tele_reply_option_read_ack_req,
2925
15
            { "Read Acknowledgement Requested", "ansi_637_tele.reply_option.read_ack_req",
2926
15
            FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
2927
15
            NULL, HFILL }
2928
15
        },
2929
15
        { &hf_ansi_637_tele_reply_option_report_req,
2930
15
            { "Delivery/Submit Report Requested", "ansi_637_tele.reply_option.report_req",
2931
15
            FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
2932
15
            NULL, HFILL }
2933
15
        },
2934
15
        { &hf_ansi_637_tele_num_messages,
2935
15
            { "Number of voice mail messages", "ansi_637_tele.num_messages.count",
2936
15
            FT_UINT8, BASE_DEC, NULL, 0,
2937
15
            NULL, HFILL }
2938
15
        },
2939
15
        { &hf_ansi_637_tele_alert_msg_delivery_priority,
2940
15
            { "Privacy", "ansi_637_tele.alert_msg_delivery.priority",
2941
15
            FT_UINT8, BASE_DEC, VALS(tele_param_alert_priority_strings), 0xc0,
2942
15
            NULL, HFILL }
2943
15
        },
2944
15
        { &hf_ansi_637_tele_language,
2945
15
            { "Language", "ansi_637_tele.language",
2946
15
            FT_UINT8, BASE_DEC, NULL, 0,
2947
15
            NULL, HFILL }
2948
15
        },
2949
15
        { &hf_ansi_637_tele_cb_num_digit_mode,
2950
15
            { "Digit Mode", "ansi_637_tele.cb_num.digit_mode",
2951
15
            FT_BOOLEAN, 8, TFS(&tfs_digit_mode_8bit_4bit), 0x80,
2952
15
            NULL, HFILL }
2953
15
        },
2954
15
        { &hf_ansi_637_tele_cb_num_ton,
2955
15
            { "Type of Number", "ansi_637_tele.cb_num.ton",
2956
15
            FT_UINT8, BASE_DEC, VALS(ansi_a_ms_info_rec_num_type_vals), 0x70,
2957
15
            NULL, HFILL }
2958
15
        },
2959
15
        { &hf_ansi_637_tele_cb_num_plan,
2960
15
            { "Numbering Plan", "ansi_637_tele.cb_num.plan",
2961
15
            FT_UINT8, BASE_DEC, VALS(ansi_a_ms_info_rec_num_plan_vals), 0x0f,
2962
15
            NULL, HFILL }
2963
15
        },
2964
15
        { &hf_ansi_637_tele_cb_num_num_fields,
2965
15
            { "Number of fields", "ansi_637_tele.cb_num.num_fields",
2966
15
            FT_UINT8, BASE_DEC, NULL, 0,
2967
15
            NULL, HFILL }
2968
15
        },
2969
15
        { &hf_ansi_637_tele_cb_num_num_fields07f8,
2970
15
            { "Number of fields", "ansi_637_tele.cb_num.num_fields",
2971
15
            FT_UINT16, BASE_DEC, NULL, 0x07F8,
2972
15
            NULL, HFILL }
2973
15
        },
2974
15
        { &hf_ansi_637_tele_cb_num_number,
2975
15
            { "Call-Back Number", "ansi_637_tele.cb_num.number",
2976
15
            FT_STRING, BASE_NONE, NULL, 0,
2977
15
            NULL, HFILL }
2978
15
        },
2979
15
        { &hf_ansi_637_tele_msg_display_mode,
2980
15
            { "Message Display Mode", "ansi_637_tele.msg_display_mode",
2981
15
            FT_UINT8, BASE_DEC, VALS(tele_param_msg_display_mode_strings), 0xc0,
2982
15
            NULL, HFILL }
2983
15
        },
2984
15
        { &hf_ansi_637_tele_msg_deposit_idx,
2985
15
            { "Message Deposit Index", "ansi_637_tele.msg_deposit_idx",
2986
15
            FT_UINT16, BASE_DEC, NULL, 0,
2987
15
            NULL, HFILL }
2988
15
        },
2989
15
        { &hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat,
2990
15
            { "Service Category", "ansi_637_tele.srvc_cat_prog_results.srvc_cat",
2991
15
            FT_UINT16, BASE_DEC, NULL, 0,
2992
15
            NULL, HFILL }
2993
15
        },
2994
15
        { &hf_ansi_637_tele_srvc_cat_prog_results_result,
2995
15
            { "Programming Result", "ansi_637_tele.srvc_cat_prog_results.result",
2996
15
            FT_UINT8, BASE_DEC, VALS(tele_param_srvc_cat_prog_results_result_strings), 0xf0,
2997
15
            NULL, HFILL }
2998
15
        },
2999
15
        { &hf_ansi_637_tele_msg_status_error_class,
3000
15
            { "Error Class", "ansi_637_tele.msg_status.error_class",
3001
15
            FT_UINT8, BASE_DEC, VALS(tele_param_msg_status_error_class_strings), 0xc0,
3002
15
            NULL, HFILL }
3003
15
        },
3004
15
        { &hf_ansi_637_tele_msg_status_code,
3005
15
            { "Message Status Code", "ansi_637_tele.msg_status.code",
3006
15
            FT_UINT8, BASE_DEC, NULL, 0x3f,
3007
15
            NULL, HFILL }
3008
15
        },
3009
15
        { &hf_ansi_637_tele_tp_failure_cause_value,
3010
15
            { "GSM SMS TP-Failure Cause", "ansi_637_tele.tp_failure_cause.value",
3011
15
            FT_UINT8, BASE_DEC, NULL, 0,
3012
15
            NULL, HFILL }
3013
15
        },
3014
15
        { &hf_ansi_637_reserved_bits_8_generic,
3015
15
            { "Reserved bit(s)", "ansi_637_tele.reserved",
3016
15
            FT_UINT8, BASE_DEC, NULL, 0,
3017
15
            NULL, HFILL }
3018
15
        },
3019
15
        { &hf_ansi_637_reserved_bits_8_03,
3020
15
            { "Reserved bit(s)", "ansi_637_tele.reserved",
3021
15
            FT_UINT8, BASE_DEC, NULL, 0x03,
3022
15
            NULL, HFILL }
3023
15
        },
3024
15
        { &hf_ansi_637_reserved_bits_8_07,
3025
15
            { "Reserved bit(s)", "ansi_637_tele.reserved",
3026
15
            FT_UINT8, BASE_DEC, NULL, 0x07,
3027
15
            NULL, HFILL }
3028
15
        },
3029
15
        { &hf_ansi_637_reserved_bits_8_0f,
3030
15
            { "Reserved bit(s)", "ansi_637_tele.reserved",
3031
15
            FT_UINT8, BASE_DEC, NULL, 0x0f,
3032
15
            NULL, HFILL }
3033
15
        },
3034
15
        { &hf_ansi_637_reserved_bits_8_3f,
3035
15
            { "Reserved bit(s)", "ansi_637_tele.reserved",
3036
15
            FT_UINT8, BASE_DEC, NULL, 0x3f,
3037
15
            NULL, HFILL }
3038
15
        },
3039
15
        { &hf_ansi_637_reserved_bits_8_7f,
3040
15
            { "Reserved bit(s)", "ansi_637_tele.reserved",
3041
15
            FT_UINT8, BASE_DEC, NULL, 0x7f,
3042
15
            NULL, HFILL }
3043
15
        },
3044
15
        { &hf_ansi_637_reserved_bits_16_generic,
3045
15
            { "Reserved bit(s)", "ansi_637_tele.reserved",
3046
15
            FT_UINT16, BASE_DEC, NULL, 0,
3047
15
            NULL, HFILL }
3048
15
        },
3049
15
        { &hf_ansi_637_tele_cmas_encoding,
3050
15
            { "Encoding", "ansi_637_tele.cmas.encoding",
3051
15
            FT_UINT16, BASE_DEC, NULL, 0xf800,
3052
15
            NULL, HFILL }
3053
15
        },
3054
15
        { &hf_ansi_637_tele_cmas_num_fields,
3055
15
            { "Number of fields", "ansi_637_tele.cmas.num_fields",
3056
15
            FT_UINT16, BASE_DEC, NULL, 0x07f8,
3057
15
            NULL, HFILL }
3058
15
        },
3059
15
        { &hf_ansi_637_tele_cmas_protocol_version,
3060
15
            { "CMAE_protocol_version", "ansi_637_tele.cmas.protocol_version",
3061
15
            FT_UINT8, BASE_DEC, NULL, 0,
3062
15
            NULL, HFILL }
3063
15
        },
3064
15
        { &hf_ansi_637_tele_cmas_record_type,
3065
15
            { "E_RECORD_TYPE", "ansi_637_tele.cmas.record_type",
3066
15
            FT_UINT8, BASE_DEC, NULL, 0,
3067
15
            NULL, HFILL }
3068
15
        },
3069
15
        { &hf_ansi_637_tele_cmas_record_len,
3070
15
            { "E_RECORD_LENGTH", "ansi_637_tele.cmas.record_len",
3071
15
            FT_UINT8, BASE_DEC, NULL, 0,
3072
15
            NULL, HFILL }
3073
15
        },
3074
15
        { &hf_ansi_637_tele_cmas_char_set,
3075
15
            { "CMAE_char_set", "ansi_637_tele.cmas.char_set",
3076
15
            FT_UINT8, BASE_DEC, NULL, 0,
3077
15
            NULL, HFILL }
3078
15
        },
3079
15
        { &hf_ansi_637_tele_cmas_category,
3080
15
            { "CMAE_category", "ansi_637_tele.cmas.category",
3081
15
            FT_UINT8, BASE_DEC, NULL, 0,
3082
15
            NULL, HFILL }
3083
15
        },
3084
15
        { &hf_ansi_637_tele_cmas_response_type,
3085
15
            { "CMAE_response_type", "ansi_637_tele.cmas.response_type",
3086
15
            FT_UINT8, BASE_DEC, NULL, 0,
3087
15
            NULL, HFILL }
3088
15
        },
3089
15
        { &hf_ansi_637_tele_cmas_severity,
3090
15
            { "CMAE_severity", "ansi_637_tele.cmas.severity",
3091
15
            FT_UINT8, BASE_DEC, NULL, 0xf0,
3092
15
            NULL, HFILL }
3093
15
        },
3094
15
        { &hf_ansi_637_tele_cmas_urgency,
3095
15
            { "CMAE_urgency", "ansi_637_tele.cmas.urgency",
3096
15
            FT_UINT8, BASE_DEC, NULL, 0x0f,
3097
15
            NULL, HFILL }
3098
15
        },
3099
15
        { &hf_ansi_637_tele_cmas_certainty,
3100
15
            { "CMAE_certainty", "ansi_637_tele.cmas.certainty",
3101
15
            FT_UINT8, BASE_DEC, NULL, 0xf0,
3102
15
            NULL, HFILL }
3103
15
        },
3104
15
        { &hf_ansi_637_tele_cmas_identifier,
3105
15
            { "CMAE_identifier", "ansi_637_tele.cmas.identifier",
3106
15
            FT_UINT16, BASE_DEC, NULL, 0,
3107
15
            NULL, HFILL }
3108
15
        },
3109
15
        { &hf_ansi_637_tele_cmas_alert_handling,
3110
15
            { "CMAE_alert_handling", "ansi_637_tele.cmas.alert_handling",
3111
15
            FT_UINT8, BASE_DEC, NULL, 0,
3112
15
            NULL, HFILL }
3113
15
        },
3114
15
        { &hf_ansi_637_tele_cmas_expires_year,
3115
15
            { "CMAE_expires (Year)", "ansi_637_tele.cmas.expires.year",
3116
15
            FT_UINT8, BASE_DEC, NULL, 0,
3117
15
            NULL, HFILL }
3118
15
        },
3119
15
        { &hf_ansi_637_tele_cmas_expires_month,
3120
15
            { "CMAE_expires (Month)", "ansi_637_tele.cmas.expires.month",
3121
15
            FT_UINT8, BASE_DEC, NULL, 0,
3122
15
            NULL, HFILL }
3123
15
        },
3124
15
        { &hf_ansi_637_tele_cmas_expires_day,
3125
15
            { "CMAE_expires (Day)", "ansi_637_tele.cmas.expires.day",
3126
15
            FT_UINT8, BASE_DEC, NULL, 0,
3127
15
            NULL, HFILL }
3128
15
        },
3129
15
        { &hf_ansi_637_tele_cmas_expires_hours,
3130
15
            { "CMAE_expires (Hours)", "ansi_637_tele.cmas.expires.hours",
3131
15
            FT_UINT8, BASE_DEC, NULL, 0,
3132
15
            NULL, HFILL }
3133
15
        },
3134
15
        { &hf_ansi_637_tele_cmas_expires_minutes,
3135
15
            { "CMAE_expires (Minutes)", "ansi_637_tele.cmas.expires.minutes",
3136
15
            FT_UINT8, BASE_DEC, NULL, 0,
3137
15
            NULL, HFILL }
3138
15
        },
3139
15
        { &hf_ansi_637_tele_cmas_expires_seconds,
3140
15
            { "CMAE_expires (Seconds)", "ansi_637_tele.cmas.expires.seconds",
3141
15
            FT_UINT8, BASE_DEC, NULL, 0,
3142
15
            NULL, HFILL }
3143
15
        },
3144
15
        { &hf_ansi_637_tele_cmas_language,
3145
15
            { "CMAE_language", "ansi_637_tele.cmas.language",
3146
15
            FT_UINT8, BASE_DEC, NULL, 0,
3147
15
            NULL, HFILL }
3148
15
        },
3149
15
        { &hf_ansi_637_tele_cmas_text,
3150
15
            { "CMAE_alert_text", "ansi_637_tele.cmas.text",
3151
15
            FT_STRING, BASE_NONE, NULL, 0,
3152
15
            NULL, HFILL }
3153
15
        },
3154
15
        { &hf_ansi_637_tele_mult_enc_user_data_encoding,
3155
15
            { "Encoding", "ansi_637_tele.mult_enc_user_data.encoding",
3156
15
            FT_UINT8, BASE_DEC, VALS(ansi_tsb58_encoding_vals), 0,
3157
15
            NULL, HFILL }
3158
15
        },
3159
15
        { &hf_ansi_637_tele_mult_enc_user_data_num_fields,
3160
15
            { "Number of fields", "ansi_637_tele.mult_enc_user_data.num_fields",
3161
15
            FT_UINT8, BASE_DEC, NULL, 0,
3162
15
            NULL, HFILL }
3163
15
        },
3164
15
        { &hf_ansi_637_tele_mult_enc_user_data_text,
3165
15
            { "Encoded user data", "ansi_637_tele.mult_enc_user_data.text",
3166
15
            FT_STRING, BASE_NONE, NULL, 0,
3167
15
            NULL, HFILL }
3168
15
        },
3169
15
        { &hf_ansi_637_tele_srvc_cat_prog_data_encoding,
3170
15
            { "Encoding", "ansi_637_tele.srvc_cat_prog_data.encoding",
3171
15
            FT_UINT8, BASE_DEC, VALS(ansi_tsb58_encoding_vals), 0,
3172
15
            NULL, HFILL }
3173
15
        },
3174
15
        { &hf_ansi_637_tele_srvc_cat_prog_data_operation_code,
3175
15
            { "Operation code", "ansi_637_tele.srvc_cat_prog_data.operation_code",
3176
15
            FT_UINT8, BASE_DEC, VALS(tele_param_srvc_cat_prog_data_op_code_vals), 0,
3177
15
            NULL, HFILL }
3178
15
        },
3179
15
        { &hf_ansi_637_tele_srvc_cat_prog_data_category,
3180
15
            { "Operation code", "ansi_637_tele.srvc_cat_prog_data.category",
3181
15
            FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ansi_tsb58_srvc_cat_vals_ext, 0,
3182
15
            NULL, HFILL }
3183
15
        },
3184
15
        { &hf_ansi_637_tele_srvc_cat_prog_data_language,
3185
15
            { "Operation code", "ansi_637_tele.srvc_cat_prog_data.language",
3186
15
            FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ansi_tsb58_language_ind_vals_ext, 0,
3187
15
            NULL, HFILL }
3188
15
        },
3189
15
        { &hf_ansi_637_tele_srvc_cat_prog_data_max_messages,
3190
15
            { "Maximum number of messages", "ansi_637_tele.srvc_cat_prog_data.max_messages",
3191
15
            FT_UINT8, BASE_DEC, NULL, 0,
3192
15
            NULL, HFILL }
3193
15
        },
3194
15
        { &hf_ansi_637_tele_srvc_cat_prog_data_alert_option,
3195
15
            { "Alert option", "ansi_637_tele.srvc_cat_prog_data.alert_option",
3196
15
            FT_UINT8, BASE_DEC, VALS(tele_param_srvc_cat_prog_data_alert_option_vals), 0,
3197
15
            NULL, HFILL }
3198
15
        },
3199
15
        { &hf_ansi_637_tele_srvc_cat_prog_data_num_fields,
3200
15
            { "Number of fields", "ansi_637_tele.srvc_cat_prog_data.num_fields",
3201
15
            FT_UINT8, BASE_DEC, NULL, 0,
3202
15
            NULL, HFILL }
3203
15
        },
3204
15
        { &hf_ansi_637_tele_srvc_cat_prog_data_text,
3205
15
            { "Encoded program data", "ansi_637_tele.srvc_cat_prog_data.text",
3206
15
            FT_STRING, BASE_NONE, NULL, 0,
3207
15
            NULL, HFILL }
3208
15
        },
3209
15
    };
3210
3211
15
    static ei_register_info ei[] = {
3212
15
        { &ei_ansi_637_extraneous_data,
3213
15
            { "ansi_637.extraneous_data", PI_PROTOCOL, PI_NOTE,
3214
15
            "Extraneous Data - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
3215
15
            EXPFILL }
3216
15
        },
3217
15
        { &ei_ansi_637_short_data,
3218
15
            { "ansi_637.short_data", PI_PROTOCOL, PI_NOTE,
3219
15
            "Short Data (?) - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
3220
15
            EXPFILL }
3221
15
        },
3222
15
        { &ei_ansi_637_unexpected_length,
3223
15
            { "ansi_637.unexpected_length", PI_PROTOCOL, PI_WARN,
3224
15
            "Unexpected Data Length - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
3225
15
            EXPFILL }
3226
15
        },
3227
15
        { &ei_ansi_637_unknown_encoding,
3228
15
            { "ansi_637.unknown_format", PI_PROTOCOL, PI_NOTE,
3229
15
            "Encoding Unknown/Unsupported (report to wireshark.org)",
3230
15
            EXPFILL }
3231
15
        },
3232
15
        { &ei_ansi_637_failed_conversion,
3233
15
            { "ansi_637.failed_conversion", PI_PROTOCOL, PI_WARN,
3234
15
            "Failed iconv conversion (report to wireshark.org)",
3235
15
            EXPFILL }
3236
15
        },
3237
15
        { &ei_ansi_637_unknown_cmas_record_type,
3238
15
            { "ansi_637.unknown_cmas_record_type", PI_PROTOCOL, PI_WARN,
3239
15
            "Unknown CMAS record type (report to wireshark.org)",
3240
15
            EXPFILL }
3241
15
        },
3242
15
        { &ei_ansi_637_unknown_trans_parameter,
3243
15
            { "ansi_637.unknown_trans_parameter", PI_PROTOCOL, PI_WARN,
3244
15
            "Unknown transport layer parameter (report to wireshark.org)",
3245
15
            EXPFILL }
3246
15
        },
3247
15
        { &ei_ansi_637_no_trans_parameter_dissector,
3248
15
            { "ansi_637.no_trans_parameter_dissector", PI_PROTOCOL, PI_WARN,
3249
15
            "No transport layer parameter dissector (report to wireshark.org)",
3250
15
            EXPFILL }
3251
15
        },
3252
15
        { &ei_ansi_637_unknown_tele_parameter,
3253
15
            { "ansi_637.unknown_tele_parameter", PI_PROTOCOL, PI_WARN,
3254
15
            "Unknown teleservice layer parameter (report to wireshark.org)",
3255
15
            EXPFILL }
3256
15
        },
3257
15
        { &ei_ansi_637_no_tele_parameter_dissector,
3258
15
            { "ansi_637.no_tele_parameter_dissector", PI_PROTOCOL, PI_WARN,
3259
15
            "No teleservice layer parameter dissector (report to wireshark.org)",
3260
15
            EXPFILL }
3261
15
        }
3262
15
    };
3263
3264
15
    expert_module_t     *expert_ansi_637;
3265
3266
    /* Setup protocol subtree array */
3267
645
#define NUM_INDIVIDUAL_PARAMS   4
3268
15
    int *ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM+NUM_CMAS_PARAM];
3269
3270
15
    memset((void *) ett, 0, sizeof(ett));
3271
3272
15
    ett[0] = &ett_ansi_637_tele;
3273
15
    ett[1] = &ett_ansi_637_trans;
3274
15
    ett[2] = &ett_ansi_637_header_ind;
3275
15
    ett[3] = &ett_params;
3276
3277
390
    for (i=0; i < NUM_TELE_PARAM; i++)
3278
375
    {
3279
375
        ett[NUM_INDIVIDUAL_PARAMS+i] = &ett_ansi_637_tele_param[i];
3280
375
    }
3281
3282
75
    for (i=0; i < NUM_TRANS_MSG_TYPE; i++)
3283
60
    {
3284
60
        ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+i] = &ett_ansi_637_trans_msg[i];
3285
60
    }
3286
3287
165
    for (i=0; i < NUM_TRANS_PARAM; i++)
3288
150
    {
3289
150
        ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+i] = &ett_ansi_637_trans_param[i];
3290
150
    }
3291
3292
75
    for (i=0; i < NUM_CMAS_PARAM; i++)
3293
60
    {
3294
60
        ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM+i] = &ett_tia_1149_cmas_param[i];
3295
60
    }
3296
3297
    /* Register the protocol name and description */
3298
15
    proto_ansi_637_tele =
3299
15
        proto_register_protocol("ANSI IS-637-A (SMS) Teleservice Layer", "ANSI IS-637-A Teleservice", "ansi_637_tele");
3300
3301
15
    proto_ansi_637_trans =
3302
15
        proto_register_protocol("ANSI IS-637-A (SMS) Transport Layer", "ANSI IS-637-A Transport", "ansi_637_trans");
3303
3304
15
    ansi_637_tele_handle = register_dissector("ansi_637_tele", dissect_ansi_637_tele, proto_ansi_637_tele);
3305
15
    ansi_637_trans_handle = register_dissector("ansi_637_trans", dissect_ansi_637_trans, proto_ansi_637_trans);
3306
15
    ansi_637_trans_app_handle = register_dissector("ansi_637_trans_app", dissect_ansi_637_trans_app, proto_ansi_637_trans);
3307
3308
    /* Required function calls to register the header fields and subtrees used */
3309
15
    proto_register_field_array(proto_ansi_637_tele, hf_tele, array_length(hf_tele));
3310
15
    proto_register_field_array(proto_ansi_637_trans, hf_trans, array_length(hf_trans));
3311
15
    proto_register_subtree_array(ett, array_length(ett));
3312
3313
15
    expert_ansi_637 =
3314
15
        expert_register_protocol(proto_ansi_637_trans);
3315
15
    expert_register_field_array(expert_ansi_637, ei, array_length(ei));
3316
3317
15
    tele_dissector_table =
3318
15
        register_dissector_table("ansi_637.tele_id",
3319
15
            "ANSI IS-637-A Teleservice ID", proto_ansi_637_tele, FT_UINT8, BASE_DEC);
3320
15
}
3321
3322
3323
void
3324
proto_reg_handoff_ansi_637(void)
3325
15
{
3326
15
    unsigned i;
3327
3328
    /* Dissect messages embedded in SIP */
3329
15
    dissector_add_string("media_type", "application/vnd.3gpp2.sms", ansi_637_trans_app_handle);
3330
3331
    /*
3332
     * register for all known teleservices
3333
     * '-1' is to stop before trailing '0' entry
3334
     *
3335
     * to add teleservices, modify 'ansi_tele_id_strings'
3336
     */
3337
120
    for (i = 0; i < array_length(ansi_tele_id_strings) - 1; i++)
3338
105
    {
3339
        /*
3340
         * ANSI MAP dissector will push out teleservice ids
3341
         */
3342
105
        dissector_add_uint("ansi_map.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
3343
3344
        /*
3345
         * we will push out teleservice ids after Transport layer decode
3346
         */
3347
105
        dissector_add_uint("ansi_637.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
3348
105
    }
3349
3350
    /*
3351
     * internal implementation add this pseudo teleservice ID for handling broadcast SMS
3352
     * (which don't have teleservice IDs)
3353
     */
3354
15
    dissector_add_uint("ansi_map.tele_id", INTERNAL_BROADCAST_TELE_ID, ansi_637_tele_handle);
3355
15
    dissector_add_uint("ansi_637.tele_id", INTERNAL_BROADCAST_TELE_ID, ansi_637_tele_handle);
3356
3357
    /*
3358
     * ANSI A-interface will push out transport layer data
3359
     */
3360
15
    dissector_add_uint("ansi_a.sms", 0, ansi_637_trans_handle);
3361
15
}
3362
3363
/*
3364
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3365
 *
3366
 * Local variables:
3367
 * c-basic-offset: 4
3368
 * tab-width: 8
3369
 * indent-tabs-mode: nil
3370
 * End:
3371
 *
3372
 * vi: set shiftwidth=4 tabstop=8 expandtab:
3373
 * :indentSize=4:tabSize=8:noTabs=true:
3374
 */