Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ansi_637.c
bloba517761a669b05c8bc790b40b4dafb5229002f2f
1 /* packet-ansi_637.c
2 * Routines for ANSI IS-637-A/D (SMS) dissection
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)
9 * Title 3GPP2 Other
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?)
16 * For CMAS See:
17 * TIA-1149.1 or
18 * (520-10030206__Editor_TIA-1149-0-1_CMASoverCDMA_Publication.pdf)
20 * Wireshark - Network traffic analyzer
21 * By Gerald Combs <gerald@wireshark.org>
22 * Copyright 1998 Gerald Combs
24 * SPDX-License-Identifier: GPL-2.0-or-later
27 #include "config.h"
29 #include <epan/packet.h>
30 #include <epan/expert.h>
31 #include <epan/strutil.h>
32 #include <epan/tfs.h>
33 #include <epan/value_string.h>
34 #include <wsutil/array.h>
36 #include "packet-gsm_sms.h"
37 #include "packet-ansi_a.h"
39 void proto_register_ansi_637(void);
40 void proto_reg_handoff_ansi_637(void);
42 static const char *ansi_proto_name_tele = "ANSI IS-637-A (SMS) Teleservice Layer";
43 static const char *ansi_proto_name_trans = "ANSI IS-637-A (SMS) Transport Layer";
44 static const char *ansi_proto_name_short = "IS-637-A";
47 * Masks the number of bits given by len starting at the given offset
48 * MBoffset should be from 0 to 7 and MBlen 1 to 8
49 * MASK_B(0, 1) = 0x80
50 * MASK_B(0, 8) = 0xff
51 * MASK_B(4, 3) = 0x0e
52 * MASK_B(7, 1) = 0x01
54 #define MASK_B(MBoffset, MBlen) \
55 ((0xff >> (MBoffset)) & (0xff << (8 - ((MBoffset) + (MBlen)))))
57 static const value_string ansi_tele_msg_type_strings[] = {
58 { 1, "Deliver (mobile-terminated only)" },
59 { 2, "Submit (mobile-originated only)" },
60 { 3, "Cancellation (mobile-originated only)" },
61 { 4, "Delivery Acknowledgement (mobile-terminated only)" },
62 { 5, "User Acknowledgement (either direction)" },
63 { 6, "Read Acknowledgement (either direction)" },
64 { 7, "Deliver Report (mobile-originated only)" },
65 { 8, "Submit Report (mobile-terminated only)" },
66 { 0, NULL }
69 static const value_string ansi_tele_msg_header_ind_strings[] = {
70 { 0, "The User Data field contains only the short message" },
71 { 1, "The User Data field contains a Header in addition to the short message" },
72 { 0, NULL }
75 static const value_string ansi_tele_msg_status_strings[] = {
76 { 0x00, "Message accepted" },
77 { 0x01, "Message deposited to Internet" },
78 { 0x02, "Message delivered" },
79 { 0x03, "Message cancelled" },
80 { 0x84, "Network congestion" },
81 { 0x85, "Network error" },
82 { 0x9f, "Unknown error" },
83 { 0xc4, "Network congestion" },
84 { 0xc5, "Network error" },
85 { 0xc6, "Cancel failed" },
86 { 0xc7, "Blocked destination" },
87 { 0xc8, "Text too long" },
88 { 0xc9, "Duplicate message" },
89 { 0xca, "Invalid destination" },
90 { 0xcd, "Message expired" },
91 { 0xdf, "Unknown error" },
92 { 0, NULL }
94 static value_string_ext ansi_tele_msg_status_strings_ext = VALUE_STRING_EXT_INIT(ansi_tele_msg_status_strings);
96 static const value_string ansi_tele_id_strings[] = {
97 { 1, "Reserved for maintenance" },
98 { 4096, "AMPS Extended Protocol Enhanced Services" },
99 { 4097, "CDMA Cellular Paging Teleservice" },
100 { 4098, "CDMA Cellular Messaging Teleservice" },
101 { 4099, "CDMA Voice Mail Notification" },
102 { 4100, "CDMA Wireless Application Protocol (WAP)" },
103 { 4101, "CDMA Wireless Enhanced Messaging Teleservice (WEMT)" },
104 { 0, NULL }
106 #define INTERNAL_BROADCAST_TELE_ID 65535
108 static const value_string ansi_tele_param_strings[] = {
109 { 0x00, "Message Identifier" },
110 { 0x01, "User Data" },
111 { 0x02, "User Response Code" },
112 { 0x03, "Message Center Time Stamp" },
113 { 0x04, "Validity Period - Absolute" },
114 { 0x05, "Validity Period - Relative" },
115 { 0x06, "Deferred Delivery Time - Absolute" },
116 { 0x07, "Deferred Delivery Time - Relative" },
117 { 0x08, "Priority Indicator" },
118 { 0x09, "Privacy Indicator" },
119 { 0x0a, "Reply Option" },
120 { 0x0b, "Number of Messages" },
121 { 0x0c, "Alert on Message Delivery" },
122 { 0x0d, "Language Indicator" },
123 { 0x0e, "Call-Back Number" },
124 { 0x0f, "Message Display Mode" },
125 { 0x10, "Multiple Encoding User Data" },
126 { 0x11, "Message Deposit Index" },
127 { 0x12, "Service Category Program Data" },
128 { 0x13, "Service Category Program Results" },
129 { 0x14, "Message status" },
130 { 0x15, "TP-Failure cause" },
131 { 0x16, "Enhanced VMN" },
132 { 0x17, "Enhanced VMN Ack" },
133 { 0, NULL }
135 static value_string_ext ansi_tele_param_strings_ext = VALUE_STRING_EXT_INIT(ansi_tele_param_strings);
137 #define ANSI_TRANS_MSG_TYPE_BROADCAST 1
139 static const value_string ansi_trans_msg_type_strings[] = {
140 { 0, "Point-to-Point" },
141 { 1, "Broadcast" },
142 { 2, "Acknowledge" },
143 { 0, NULL }
146 static const value_string ansi_trans_param_strings[] = {
147 { 0x00, "Teleservice Identifier" },
148 { 0x01, "Service Category" },
149 { 0x02, "Originating Address" },
150 { 0x03, "Originating Subaddress" },
151 { 0x04, "Destination Address" },
152 { 0x05, "Destination Subaddress" },
153 { 0x06, "Bearer Reply Option" },
154 { 0x07, "Cause Codes" },
155 { 0x08, "Bearer Data" },
156 { 0, NULL }
159 static const value_string ansi_tele_month_strings[] = {
160 { 0, "January" },
161 { 1, "February" },
162 { 2, "March" },
163 { 3, "April" },
164 { 4, "May" },
165 { 5, "June" },
166 { 6, "July" },
167 { 7, "August" },
168 { 8, "September" },
169 { 9, "October" },
170 { 10, "November" },
171 { 11, "December" },
172 { 0, NULL }
175 static const value_string ansi_trans_subaddr_odd_even_ind_strings[] = {
176 { 0x00, "Even" },
177 { 0x01, "Odd" },
178 { 0, NULL }
181 static const true_false_string tfs_digit_mode_8bit_4bit = {
182 "8-bit ASCII",
183 "4-bit DTMF"
186 static const true_false_string tfs_number_mode_data_ansi_t1 = {
187 "Data Network Address",
188 "ANSI T1.607"
192 * from Table 2.7.1.3.2.4-4. Representation of DTMF Digits
193 * 3GPP2 C.S0005-C (IS-2000 aka cdma2000)
195 static const unsigned char air_digits[] = {
196 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
197 '?','1','2','3','4','5','6','7','8','9','0','*','#','?','?','?'
200 /* Initialize the protocol and registered fields */
201 static int proto_ansi_637_tele;
202 static int proto_ansi_637_trans;
204 static int hf_ansi_637_trans_param_id;
205 static int hf_ansi_637_trans_length;
206 static int hf_ansi_637_trans_bin_addr;
207 static int hf_ansi_637_trans_tele_id;
208 static int hf_ansi_637_trans_srvc_cat;
209 static int hf_ansi_637_trans_addr_param_digit_mode;
210 static int hf_ansi_637_trans_addr_param_number_mode;
211 static int hf_ansi_637_trans_addr_param_ton;
212 static int hf_ansi_637_trans_addr_param_plan;
213 static int hf_ansi_637_trans_addr_param_num_fields;
214 static int hf_ansi_637_trans_addr_param_number;
215 static int hf_ansi_637_trans_subaddr_type;
216 static int hf_ansi_637_trans_subaddr_odd_even_ind;
217 static int hf_ansi_637_trans_subaddr_num_fields;
218 static int hf_ansi_637_trans_bearer_reply_seq_num;
219 static int hf_ansi_637_trans_cause_codes_seq_num;
220 static int hf_ansi_637_trans_cause_codes_error_class;
221 static int hf_ansi_637_trans_cause_codes_code;
223 static int hf_ansi_637_tele_msg_type;
224 static int hf_ansi_637_tele_msg_id;
225 static int hf_ansi_637_tele_length;
226 static int hf_ansi_637_tele_msg_status;
227 static int hf_ansi_637_tele_msg_header_ind;
228 static int hf_ansi_637_tele_msg_rsvd;
229 static int hf_ansi_637_tele_subparam_id;
230 static int hf_ansi_637_tele_user_data_text;
231 static int hf_ansi_637_tele_user_data_encoding;
232 static int hf_ansi_637_tele_user_data_message_type;
233 static int hf_ansi_637_tele_user_data_num_fields;
234 static int hf_ansi_637_tele_response_code;
235 static int hf_ansi_637_tele_message_center_ts_year;
236 static int hf_ansi_637_tele_message_center_ts_month;
237 static int hf_ansi_637_tele_message_center_ts_day;
238 static int hf_ansi_637_tele_message_center_ts_hours;
239 static int hf_ansi_637_tele_message_center_ts_minutes;
240 static int hf_ansi_637_tele_message_center_ts_seconds;
241 static int hf_ansi_637_tele_validity_period_ts_year;
242 static int hf_ansi_637_tele_validity_period_ts_month;
243 static int hf_ansi_637_tele_validity_period_ts_day;
244 static int hf_ansi_637_tele_validity_period_ts_hours;
245 static int hf_ansi_637_tele_validity_period_ts_minutes;
246 static int hf_ansi_637_tele_validity_period_ts_seconds;
247 static int hf_ansi_637_tele_validity_period_relative_validity;
248 static int hf_ansi_637_tele_deferred_del_ts_year;
249 static int hf_ansi_637_tele_deferred_del_ts_month;
250 static int hf_ansi_637_tele_deferred_del_ts_day;
251 static int hf_ansi_637_tele_deferred_del_ts_hours;
252 static int hf_ansi_637_tele_deferred_del_ts_minutes;
253 static int hf_ansi_637_tele_deferred_del_ts_seconds;
254 static int hf_ansi_637_tele_deferred_del_relative;
255 static int hf_ansi_637_tele_priority_indicator;
256 static int hf_ansi_637_tele_privacy_indicator;
257 static int hf_ansi_637_tele_reply_option_user_ack_req;
258 static int hf_ansi_637_tele_reply_option_dak_req;
259 static int hf_ansi_637_tele_reply_option_read_ack_req;
260 static int hf_ansi_637_tele_reply_option_report_req;
261 static int hf_ansi_637_tele_num_messages;
262 static int hf_ansi_637_tele_alert_msg_delivery_priority;
263 static int hf_ansi_637_tele_language;
264 static int hf_ansi_637_tele_cb_num_digit_mode;
265 static int hf_ansi_637_tele_cb_num_ton;
266 static int hf_ansi_637_tele_cb_num_plan;
267 static int hf_ansi_637_tele_cb_num_num_fields;
268 static int hf_ansi_637_tele_cb_num_num_fields07f8;
269 static int hf_ansi_637_tele_cb_num_number;
270 static int hf_ansi_637_tele_msg_display_mode;
271 static int hf_ansi_637_tele_msg_deposit_idx;
272 static int hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat;
273 static int hf_ansi_637_tele_srvc_cat_prog_results_result;
274 static int hf_ansi_637_tele_msg_status_error_class;
275 static int hf_ansi_637_tele_msg_status_code;
276 static int hf_ansi_637_tele_tp_failure_cause_value;
277 static int hf_ansi_637_reserved_bits_8_generic;
278 static int hf_ansi_637_reserved_bits_8_03;
279 static int hf_ansi_637_reserved_bits_8_07;
280 static int hf_ansi_637_reserved_bits_8_0f;
281 static int hf_ansi_637_reserved_bits_8_3f;
282 static int hf_ansi_637_reserved_bits_8_7f;
283 static int hf_ansi_637_reserved_bits_16_generic;
284 static int hf_ansi_637_tele_cmas_encoding;
285 static int hf_ansi_637_tele_cmas_num_fields;
286 static int hf_ansi_637_tele_cmas_protocol_version;
287 static int hf_ansi_637_tele_cmas_record_type;
288 static int hf_ansi_637_tele_cmas_record_len;
289 static int hf_ansi_637_tele_cmas_char_set;
290 static int hf_ansi_637_tele_cmas_category;
291 static int hf_ansi_637_tele_cmas_response_type;
292 static int hf_ansi_637_tele_cmas_severity;
293 static int hf_ansi_637_tele_cmas_urgency;
294 static int hf_ansi_637_tele_cmas_certainty;
295 static int hf_ansi_637_tele_cmas_identifier;
296 static int hf_ansi_637_tele_cmas_alert_handling;
297 static int hf_ansi_637_tele_cmas_expires_year;
298 static int hf_ansi_637_tele_cmas_expires_month;
299 static int hf_ansi_637_tele_cmas_expires_day;
300 static int hf_ansi_637_tele_cmas_expires_hours;
301 static int hf_ansi_637_tele_cmas_expires_minutes;
302 static int hf_ansi_637_tele_cmas_expires_seconds;
303 static int hf_ansi_637_tele_cmas_language;
304 static int hf_ansi_637_tele_cmas_text;
305 static int hf_ansi_637_tele_mult_enc_user_data_encoding;
306 static int hf_ansi_637_tele_mult_enc_user_data_num_fields;
307 static int hf_ansi_637_tele_mult_enc_user_data_text;
308 static int hf_ansi_637_tele_srvc_cat_prog_data_encoding;
309 static int hf_ansi_637_tele_srvc_cat_prog_data_operation_code;
310 static int hf_ansi_637_tele_srvc_cat_prog_data_category;
311 static int hf_ansi_637_tele_srvc_cat_prog_data_language;
312 static int hf_ansi_637_tele_srvc_cat_prog_data_max_messages;
313 static int hf_ansi_637_tele_srvc_cat_prog_data_alert_option;
314 static int hf_ansi_637_tele_srvc_cat_prog_data_num_fields;
315 static int hf_ansi_637_tele_srvc_cat_prog_data_text;
317 /* Initialize the subtree pointers */
318 static int ett_ansi_637_tele;
319 static int ett_ansi_637_trans;
320 static int ett_ansi_637_header_ind;
321 static int ett_params;
323 static expert_field ei_ansi_637_extraneous_data;
324 static expert_field ei_ansi_637_short_data;
325 static expert_field ei_ansi_637_unexpected_length;
326 static expert_field ei_ansi_637_unknown_encoding;
327 static expert_field ei_ansi_637_failed_conversion;
328 static expert_field ei_ansi_637_unknown_cmas_record_type;
329 static expert_field ei_ansi_637_unknown_trans_parameter;
330 static expert_field ei_ansi_637_no_trans_parameter_dissector;
331 static expert_field ei_ansi_637_unknown_tele_parameter;
332 static expert_field ei_ansi_637_no_tele_parameter_dissector;
334 static dissector_handle_t ansi_637_tele_handle;
335 static dissector_handle_t ansi_637_trans_handle;
336 static dissector_handle_t ansi_637_trans_app_handle;
338 static uint32_t ansi_637_trans_tele_id;
339 static char ansi_637_bigbuf[1024];
340 static dissector_table_t tele_dissector_table;
341 static proto_tree *g_tree;
343 /* PARAM FUNCTIONS */
345 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
346 if ((edc_len) > (edc_max_len)) \
348 proto_tree_add_expert(tree, pinfo, &ei_ansi_637_extraneous_data, \
349 tvb, offset, (edc_len) - (edc_max_len)); \
352 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
353 if ((sdc_len) < (sdc_min_len)) \
355 proto_tree_add_expert(tree, pinfo, &ei_ansi_637_short_data, \
356 tvb, offset, (sdc_len)); \
357 return; \
360 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
361 if ((edc_len) != (edc_eq_len)) \
363 proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unexpected_length, \
364 tvb, offset, (edc_len)); \
365 return; \
369 * text decoding helper
371 * there are 'unused_bits' bits remaining in the octet at 'offset'
373 static void
374 text_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint8_t encoding,
375 uint8_t num_fields, uint16_t num_bits, uint8_t unused_bits, uint8_t fill_bits, int hf_index)
377 uint8_t bit;
378 uint32_t required_octs;
379 tvbuff_t *tvb_out = NULL;
381 const unsigned char *ustr = NULL;
384 * has to be big enough to hold all of the 'shifted' bits
386 required_octs = (num_bits + fill_bits + 7) / 8;
389 * shift the bits to octet alignment in 'buf'
391 tvb_out =
392 tvb_new_octet_aligned(tvb, (offset * 8) + (8 - unused_bits), (required_octs * 8));
393 add_new_data_source(pinfo, tvb_out, "Characters");
395 switch (encoding)
397 default:
398 proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unknown_encoding, tvb, offset, required_octs);
399 return;
401 case 0x00: /* Octet, unspecified */
403 proto_tree_add_string(tree, hf_index, tvb_out, 0, required_octs,
404 tvb_bytes_to_str(pinfo->pool, tvb_out, 0, required_octs));
405 break;
407 case 0x02: /* 7-bit ASCII */
409 offset = 0;
410 bit = 0;
412 proto_tree_add_ascii_7bits_item(tree, hf_index, tvb_out, (offset << 3) + bit, num_fields);
413 break;
415 case 0x03: /* IA5 */
417 offset = 0;
418 bit = 0;
420 ustr = tvb_get_ascii_7bits_string(pinfo->pool, tvb_out, (offset << 3) + bit, num_fields);
421 IA5_7BIT_decode(ansi_637_bigbuf, ustr, num_fields);
423 proto_tree_add_string(tree, hf_index, tvb_out, 0,
424 required_octs, ansi_637_bigbuf);
425 break;
427 case 0x04: /* UNICODE */
429 offset = 0;
431 proto_tree_add_item(tree, hf_index, tvb_out, offset, num_fields*2, ENC_UCS_2|ENC_BIG_ENDIAN);
432 break;
434 case 0x07: /* Latin/Hebrew */
436 offset = 0;
438 proto_tree_add_item(tree, hf_index, tvb_out, offset, num_fields, ENC_ISO_8859_8|ENC_NA);
439 break;
441 case 0x08: /* Latin */
443 offset = 0;
445 proto_tree_add_item(tree, hf_index, tvb_out, offset, num_fields, ENC_ISO_8859_1|ENC_NA);
446 break;
448 case 0x09: /* GSM 7-bit default alphabet */
450 offset = 0;
451 bit = fill_bits;
453 proto_tree_add_ts_23_038_7bits_packed_item(tree, hf_index, tvb_out, (offset << 3) + bit, num_fields);
454 break;
456 case 0x10: /* KSC5601 (Korean) */
458 offset = 0;
460 proto_tree_add_item_ret_string(tree, hf_index, tvb_out, offset, required_octs, ENC_EUC_KR|ENC_NA, pinfo->pool, &ustr);
461 if (ustr == NULL)
462 proto_tree_add_expert_format(tree, pinfo, &ei_ansi_637_failed_conversion, tvb_out, offset, required_octs,
463 "Failed iconv conversion on EUC-KR - (report to wireshark.org)");
464 break;
468 static void
469 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)
471 uint8_t oct;
472 uint16_t temp;
473 const char *str = NULL;
475 EXACT_DATA_CHECK(len, 6);
477 oct = tvb_get_uint8(tvb, offset);
479 temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
480 temp += ((temp < 96) ? 2000 : 1900);
482 proto_tree_add_uint_format_value(tree, hf_year, tvb, offset, 1,
483 oct,
484 "%u (%02x)",
485 temp, oct);
487 offset += 1;
489 oct = tvb_get_uint8(tvb, offset);
491 temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f) - 1;
493 str = val_to_str_const(temp, ansi_tele_month_strings, "Invalid");
494 proto_tree_add_uint_format_value(tree, hf_month, tvb, offset, 1,
495 oct,
496 "%s (%02x)",
497 str, oct);
499 offset += 1;
501 oct = tvb_get_uint8(tvb, offset);
503 temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
505 proto_tree_add_uint_format_value(tree, hf_day, tvb, offset, 1,
506 oct,
507 "%u",
508 temp);
510 offset += 1;
512 oct = tvb_get_uint8(tvb, offset);
514 temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
516 proto_tree_add_uint_format_value(tree, hf_hours, tvb, offset, 1,
517 oct,
518 "%u",
519 temp);
521 offset += 1;
523 oct = tvb_get_uint8(tvb, offset);
525 temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
527 proto_tree_add_uint_format_value(tree, hf_minutes, tvb, offset, 1, oct,
528 "%u",
529 temp);
531 offset += 1;
533 oct = tvb_get_uint8(tvb, offset);
535 temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
537 proto_tree_add_uint_format_value(tree, hf_seconds, tvb, offset, 1,
538 oct,
539 "%u",
540 temp);
543 static void
544 tele_param_msg_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p)
546 EXACT_DATA_CHECK(len, 3);
548 proto_tree_add_item(tree, hf_ansi_637_tele_msg_type, tvb, offset, 3, ENC_BIG_ENDIAN);
550 proto_tree_add_item(tree, hf_ansi_637_tele_msg_id, tvb, offset, 3, ENC_BIG_ENDIAN);
552 proto_tree_add_item(tree, hf_ansi_637_tele_msg_header_ind, tvb, offset, 3, ENC_BIG_ENDIAN);
553 if ((tvb_get_uint8(tvb, offset + 2) & 0x08) == 0x08)
555 *has_private_data_p = true;
558 proto_tree_add_item(tree, hf_ansi_637_tele_msg_rsvd, tvb, offset, 3, ENC_BIG_ENDIAN);
562 * for record types 0, 1, 2 and 3 for unknowns
564 #define NUM_CMAS_PARAM 4
565 static int ett_tia_1149_cmas_param[NUM_CMAS_PARAM];
568 * Special dissection for CMAS Message as defined in TIA-1149
570 static const value_string cmas_category_strings[] = {
571 { 0x00, "Geo (Geophysical including landslide)" },
572 { 0x01, "Met (Meteorological including flood)" },
573 { 0x02, "Safety (General emergency and public safety)" },
574 { 0x03, "Security (Law enforcement, military, homeland and local/private security)" },
575 { 0x04, "Rescue (Rescue and recovery)" },
576 { 0x05, "Fire (Fire suppression and rescue)" },
577 { 0x06, "Health (Medical and public health)" },
578 { 0x07, "Env (Pollution and other environmental)" },
579 { 0x08, "Transport (Public and private transportation)" },
580 { 0x09, "Infra (Utility, telecommunication, other nontransport infrastructure)" },
581 { 0x0a, "CBRNE (Chemical, Biological, Radiological, Nuclear or High-Yield Explosive threat or attack)" },
582 { 0x0b, "Other (Other events)" },
583 { 0, NULL }
586 static const value_string cmas_response_type_strings[] = {
587 { 0x00, "Shelter (Take shelter in place)" },
588 { 0x01, "Evacuate (Relocate)" },
589 { 0x02, "Prepare (Make preparations)" },
590 { 0x03, "Execute (Execute a pre-planned activity)" },
591 { 0x04, "Monitor (Attend to information sources)" },
592 { 0x05, "Avoid (Avoid hazard)" },
593 { 0x06, "Assess (Evaluate the information in this message. This value SHOULD NOT be used in public warning applications.)" },
594 { 0x07, "None (No action recommended)" },
595 { 0, NULL }
598 static const value_string cmas_severity_strings[] = {
599 { 0x00, "Extreme (Extraordinary threat to life or property)" },
600 { 0x01, "Severe (Significant threat to life or property)" },
601 { 0, NULL }
604 static const value_string cmas_urgency_strings[] = {
605 { 0x00, "Immediate (Responsive action should be taken immediately)" },
606 { 0x01, "Expected (Responsive action should be taken soon - within the next hour)" },
607 { 0, NULL }
610 static const value_string cmas_certainty_strings[] = {
611 { 0x00, "Observed (Determined to have occurred or to be ongoing)" },
612 { 0x01, "Likely (Likely. Probability > ~50%)" },
613 { 0, NULL }
616 static void
617 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_)
619 proto_tree *subtree;
620 uint8_t oct, oct2;
621 uint8_t encoding;
622 uint8_t num_fields;
623 uint8_t reserved_bits;
624 uint8_t unused_bits;
625 uint8_t record_type;
626 uint8_t record_len;
627 uint8_t subtree_idx;
628 uint16_t num_bits;
629 uint32_t value;
630 uint32_t temp_offset;
631 uint32_t required_octs;
632 tvbuff_t *tvb_out = NULL;
633 const char *str = NULL;
635 SHORT_DATA_CHECK(len, 2);
637 value = tvb_get_ntohs(tvb, offset);
640 * must be encoded as 'Octet, unspecified'
642 if ((value & 0xf800) != 0)
644 proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unknown_encoding, tvb, offset, len);
645 return;
648 proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_cmas_encoding, tvb, offset, 2,
649 value,
650 "%s (%u)",
651 val_to_str_const((value & 0xf800) >> 11, ansi_tsb58_encoding_vals, "Error"),
652 (value & 0xf800) >> 11);
654 proto_tree_add_item(tree, hf_ansi_637_tele_cmas_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
656 num_fields = (value & 0x07f8) >> 3;
658 offset += 2;
660 /* NOTE: there are now 3 bits remaining in 'value' */
662 unused_bits = 3;
664 required_octs = num_fields;
666 tvb_out =
667 tvb_new_octet_aligned(tvb, ((offset - 1) * 8) + (8 - unused_bits), (required_octs * 8));
668 add_new_data_source(pinfo, tvb_out, "CMAS Message");
670 temp_offset = offset;
671 offset = 0;
673 proto_tree_add_item(tree, hf_ansi_637_tele_cmas_protocol_version, tvb_out, offset, 1, ENC_BIG_ENDIAN);
675 offset += 1;
677 while ((required_octs - offset) > 2)
679 record_type = tvb_get_uint8(tvb_out, offset);
680 subtree_idx = record_type;
682 switch (record_type)
684 default: str = "Reserved"; subtree_idx = 3; break;
685 case 0x00: str = "Type 0 Elements (Alert Text)"; break;
686 case 0x01: str = "Type 1 Elements"; break;
687 case 0x02: str = "Type 2 Elements"; break;
690 record_len = tvb_get_uint8(tvb_out, offset + 1);
692 subtree =
693 proto_tree_add_subtree(tree, tvb_out, offset, record_len + 2,
694 ett_tia_1149_cmas_param[subtree_idx], NULL, str);
696 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_record_type, tvb_out, offset, 1,
697 record_type,
698 "%s",
699 str);
701 offset += 1;
703 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_record_len, tvb_out, offset, 1,
704 record_len,
705 "%u",
706 record_len);
708 offset += 1;
710 switch (record_type)
712 default:
713 proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_unknown_cmas_record_type, tvb_out, offset, record_len);
715 offset += record_len;
716 break;
718 case 0x00:
719 encoding = (tvb_get_uint8(tvb_out, offset) & 0xf8) >> 3;
721 str = val_to_str_const(encoding, ansi_tsb58_encoding_vals, "Reserved");
722 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_char_set, tvb_out, offset, 1,
723 encoding,
724 "%s (%u)",
725 str, encoding);
727 num_bits = (record_len * 8) - 5;
729 switch (encoding)
731 case 0x04: /* UNICODE */
732 /* 16-bit encodings */
733 num_fields = num_bits / 16;
734 reserved_bits = 3;
735 break;
737 case 0x00: /* Octet, unspecified */
738 case 0x10: /* KSC5601 (Korean) */
739 case 0x07: /* Latin/Hebrew */
740 case 0x08: /* Latin */
741 /* 8-bit encodings */
742 num_fields = num_bits / 8;
743 reserved_bits = 3;
744 break;
746 default:
747 /* 7-bit encodings */
748 num_fields = num_bits / 7;
750 if ((num_bits % 7) == 0)
752 oct2 = tvb_get_uint8(tvb_out, offset + record_len - 1);
753 if ((oct2 & 0x7f) == 0)
756 * the entire last 7 bits are reserved
758 num_fields--;
762 reserved_bits = num_bits - (num_fields * 7);
763 break;
766 temp_offset = offset;
767 if (num_fields) {
768 text_decoder(tvb_out, pinfo, subtree, temp_offset, encoding, num_fields, num_bits,
769 3 /* (5 bits used from 'temp_offset' octet for encoding */, 0, hf_ansi_637_tele_cmas_text);
772 offset += (record_len - 1);
774 if (reserved_bits > 0)
775 proto_tree_add_bits_item(subtree, hf_ansi_637_reserved_bits_8_generic, tvb_out, (offset*8)+(8-reserved_bits), reserved_bits, ENC_NA);
777 offset += 1;
778 break;
780 case 0x01:
781 oct = tvb_get_uint8(tvb_out, offset);
783 str = val_to_str_const(oct, cmas_category_strings, "Reserved");
784 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_category, tvb_out, offset, 1,
785 oct,
786 "%s (%u)",
787 str, oct);
789 offset += 1;
791 oct = tvb_get_uint8(tvb_out, offset);
793 str = val_to_str_const(oct, cmas_response_type_strings, "Reserved");
794 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_response_type, tvb_out, offset, 1,
795 oct,
796 "%s (%u)",
797 str, oct);
799 offset += 1;
801 oct = tvb_get_uint8(tvb_out, offset);
803 str = val_to_str_const((oct & 0xf0) >> 4, cmas_severity_strings, "Reserved");
804 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_severity, tvb_out, offset, 1,
805 oct,
806 "%s (%u)",
807 str, (oct & 0xf0) >> 4);
809 str = val_to_str_const(oct & 0x0f, cmas_urgency_strings, "Reserved");
810 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_urgency, tvb_out, offset, 1,
811 oct,
812 "%s (%u)",
813 str, oct & 0x0f);
815 offset += 1;
817 oct = tvb_get_uint8(tvb_out, offset);
819 str = val_to_str_const((oct & 0xf0) >> 4, cmas_certainty_strings, "Reserved");
820 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_certainty, tvb_out, offset, 1,
821 oct,
822 "%s (%u)",
823 str, (oct & 0xf0) >> 4);
825 proto_tree_add_item(subtree, hf_ansi_637_reserved_bits_8_0f, tvb_out, offset, 1, ENC_BIG_ENDIAN);
827 offset += 1;
828 break;
830 case 0x02:
831 proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_identifier, tvb_out, offset, 2, ENC_BIG_ENDIAN);
833 offset += 2;
835 proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_alert_handling, tvb_out, offset, 1, ENC_BIG_ENDIAN);
837 offset += 1;
839 oct = tvb_get_uint8(tvb_out, offset);
842 * TIA-1149 does not say whether this should be encoded in the same way as IS-637
843 * I.e. year = oct + ((oct < 96) ? 2000 : 1900);
845 value = oct + ((oct < 96) ? 2000 : 1900);
847 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_expires_year, tvb_out, offset, 1,
848 oct,
849 "%u (%02x)",
850 value, oct);
852 offset += 1;
854 oct = tvb_get_uint8(tvb_out, offset);
856 str = val_to_str_const(oct - 1, ansi_tele_month_strings, "Invalid");
858 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_expires_month, tvb_out, offset, 1,
859 oct,
860 "%s (%02x)",
861 str, oct);
863 offset += 1;
865 proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_day, tvb_out, offset, 1, ENC_BIG_ENDIAN);
867 offset += 1;
869 proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_hours, tvb_out, offset, 1, ENC_BIG_ENDIAN);
871 offset += 1;
873 proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_minutes, tvb_out, offset, 1, ENC_BIG_ENDIAN);
875 offset += 1;
877 proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_seconds, tvb_out, offset, 1, ENC_BIG_ENDIAN);
879 offset += 1;
881 oct = tvb_get_uint8(tvb_out, offset);
883 str = val_to_str_ext_const(oct, &ansi_tsb58_language_ind_vals_ext, "Reserved");
884 proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_language, tvb_out, offset, 1,
885 oct,
886 "%s (%u)",
887 str, oct);
889 offset += 1;
890 break;
894 EXTRANEOUS_DATA_CHECK(required_octs, offset);
896 offset += temp_offset; /* move 'offset' back to the correct spot in 'tvb' */
898 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_07, tvb, offset, 1, ENC_BIG_ENDIAN);
901 static void
902 tele_param_user_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p)
904 uint8_t encoding;
905 uint8_t encoding_bit_len;
906 uint8_t num_fields;
907 uint8_t unused_bits;
908 uint8_t fill_bits;
909 uint16_t reserved_bits;
910 uint32_t value;
911 uint32_t orig_offset;
912 uint32_t saved_offset;
913 uint32_t required_octs;
914 const char *str;
915 tvbuff_t *tvb_out;
916 enum character_set cset;
918 SHORT_DATA_CHECK(len, 2);
920 orig_offset = offset;
921 reserved_bits = len * 8;
923 value = tvb_get_ntohs(tvb, offset);
925 encoding = (uint8_t) ((value & 0xf800) >> 11);
926 str = val_to_str_const(encoding, ansi_tsb58_encoding_vals, "Reserved");
927 switch (encoding)
929 case 0x00:
930 case 0x05:
931 case 0x06:
932 case 0x07:
933 case 0x08:
934 case 0x10:
935 encoding_bit_len = 8;
936 cset = OTHER;
937 break;
939 case 0x01:
940 case 0x02:
941 case 0x03:
942 default:
943 encoding_bit_len = 7;
944 cset = ASCII_7BITS;
945 break;
947 case 0x04:
948 encoding_bit_len = 16;
949 cset = UCS2;
950 break;
952 case 0x09:
953 encoding_bit_len = 7;
954 cset = GSM_7BITS;
955 break;
958 proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_user_data_encoding, tvb, offset, 2,
959 value,
960 "%s (%u)",
961 str,
962 encoding);
964 reserved_bits -= 5;
966 if (encoding == 0x01)
968 proto_tree_add_item(tree, hf_ansi_637_tele_user_data_message_type, tvb, offset, 2, ENC_BIG_ENDIAN);
970 offset += 1;
971 value = tvb_get_ntohs(tvb, offset);
973 reserved_bits -= 8;
976 proto_tree_add_item(tree, hf_ansi_637_tele_user_data_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
978 offset += 1;
980 num_fields = (value & 0x07f8) >> 3;
982 reserved_bits -= 8 + (num_fields * encoding_bit_len);
984 /* NOTE: there are now 3 bits remaining in 'value' */
986 unused_bits = 3;
987 fill_bits = 0;
990 * ALL of this is for header support !
992 if (*has_private_data_p == true)
994 gsm_sms_udh_fields_t udh_fields;
995 int32_t num_udh_bits;
997 memset(&udh_fields, 0, sizeof(udh_fields));
999 value = tvb_get_ntohs(tvb, offset);
1002 * 'length' split across two octets +1 for the length octet itself
1003 * (dis_field_udh() will start at the length offset)
1005 required_octs = ((value & 0x07f8) >> 3) + 1;
1008 * need fill bits
1010 if (encoding_bit_len == 7)
1013 * not the same formula as dis_field_udh() because we are including
1014 * the length octet in the calculation but the result is the same
1016 fill_bits = 7 - ((required_octs * 8) % 7);
1019 num_udh_bits = (required_octs * 8) + fill_bits;
1021 tvb_out =
1022 tvb_new_octet_aligned(tvb, (offset * 8) + (8 - unused_bits), num_udh_bits);
1023 add_new_data_source(pinfo, tvb_out, "Header");
1025 saved_offset = offset + required_octs;
1027 offset = 0;
1028 fill_bits = 0;
1029 if (encoding_bit_len == 16) {
1030 /* the NUM_FIELD value represents the number of characters in Unicode encoding.
1031 Let's translate it into bytes */
1032 num_fields <<= 1;
1034 dis_field_udh(tvb_out, pinfo, tree, &offset, &required_octs, &num_fields, cset, &fill_bits, &udh_fields);
1036 offset = saved_offset;
1038 if (encoding_bit_len == 7)
1040 switch (cset)
1042 case ASCII_7BITS:
1043 if (fill_bits > unused_bits)
1045 /* this branch was NOT tested */
1047 offset += 1;
1048 unused_bits = 8 - (fill_bits - unused_bits);
1050 else if (fill_bits > 0)
1052 /* this branch was tested */
1053 unused_bits = unused_bits - fill_bits;
1056 if (unused_bits == 0)
1058 /* this branch was NOT tested */
1060 offset += 1;
1061 unused_bits = 8;
1063 break;
1065 default:
1066 break;
1068 } else if (encoding_bit_len == 16) {
1069 /* compute the number of Unicode characters now that UDH is taken into account */
1070 num_fields >>= 1;
1073 if (udh_fields.frags > 0)
1075 col_append_fstr(pinfo->cinfo, COL_INFO, " (Short Message fragment %u of %u)", udh_fields.frag, udh_fields.frags);
1079 if (num_fields) {
1080 text_decoder(tvb, pinfo, tree, offset, encoding, num_fields,
1081 num_fields * encoding_bit_len, unused_bits, fill_bits, hf_ansi_637_tele_user_data_text);
1084 if (reserved_bits > 0)
1087 * unlike for CMAS, the bits that can be reserved will always be
1088 * at the end of an octet so we don't have to worry about them
1089 * spanning two octets
1092 switch (cset)
1094 case GSM_7BITS:
1096 crumb_spec_t crumbs[3];
1097 uint8_t i = 0;
1098 unsigned bits_offset;
1100 if (reserved_bits > 3) {
1101 bits_offset = ((orig_offset + len - 2)*8)+5;
1102 crumbs[i].crumb_bit_offset = 0;
1103 crumbs[i++].crumb_bit_length = reserved_bits - 3;
1104 crumbs[i].crumb_bit_offset = 8;
1105 } else {
1106 bits_offset = ((orig_offset + len - 1)*8)+5;
1107 crumbs[i].crumb_bit_offset = 0;
1109 crumbs[i++].crumb_bit_length = 3;
1110 crumbs[i].crumb_bit_offset = 0;
1111 crumbs[i].crumb_bit_length = 0;
1112 proto_tree_add_split_bits_item_ret_val(tree, hf_ansi_637_reserved_bits_16_generic, tvb, bits_offset, crumbs, NULL);
1114 break;
1116 default:
1117 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 */
1118 break;
1123 static void
1124 tele_param_rsp_code(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1126 EXACT_DATA_CHECK(len, 1);
1128 proto_tree_add_item(tree, hf_ansi_637_tele_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
1131 static void
1132 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_)
1134 EXACT_DATA_CHECK(len, 6);
1136 tele_param_timestamp(tvb, pinfo, tree, len, offset,
1137 hf_ansi_637_tele_message_center_ts_year,
1138 hf_ansi_637_tele_message_center_ts_month,
1139 hf_ansi_637_tele_message_center_ts_day,
1140 hf_ansi_637_tele_message_center_ts_hours,
1141 hf_ansi_637_tele_message_center_ts_minutes,
1142 hf_ansi_637_tele_message_center_ts_seconds);
1145 static void
1146 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_)
1148 EXACT_DATA_CHECK(len, 6);
1150 tele_param_timestamp(tvb, pinfo, tree, len, offset,
1151 hf_ansi_637_tele_validity_period_ts_year,
1152 hf_ansi_637_tele_validity_period_ts_month,
1153 hf_ansi_637_tele_validity_period_ts_day,
1154 hf_ansi_637_tele_validity_period_ts_hours,
1155 hf_ansi_637_tele_validity_period_ts_minutes,
1156 hf_ansi_637_tele_validity_period_ts_seconds);
1159 static void
1160 tele_param_timestamp_rel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned len _U_, uint32_t offset, int hf)
1162 uint8_t oct;
1163 uint32_t value = 0;
1164 const char *str = NULL;
1165 const char *str2 = NULL;
1167 oct = tvb_get_uint8(tvb, offset);
1169 switch (oct)
1171 case 245: str = "Indefinite"; break;
1172 case 246: str = "Immediate"; break;
1173 case 247: str = "Valid until mobile becomes inactive/Deliver when mobile next becomes active"; break;
1174 case 248: str = "Valid until registration area changes, discard if not registered" ; break;
1175 default:
1176 if (oct <= 143) { value = (oct + 1) * 5; str2 = "Minutes"; break; }
1177 else if ((oct >= 144) && (oct <= 167)) { value = (oct - 143) * 30; str2 = "Minutes + 12 Hours"; break; }
1178 else if ((oct >= 168) && (oct <= 196)) { value = oct - 166; str2 = "Days"; break; }
1179 else if ((oct >= 197) && (oct <= 244)) { value = oct - 192; str2 = "Weeks"; break; }
1180 else { str = "Reserved"; break; }
1183 if (str != NULL)
1185 proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
1186 oct,
1187 "%s",
1188 str);
1190 else
1192 proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
1193 oct,
1194 "%u %s",
1195 value, str2);
1199 static void
1200 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_)
1202 EXACT_DATA_CHECK(len, 1);
1204 tele_param_timestamp_rel(tvb, pinfo, tree, len, offset, hf_ansi_637_tele_validity_period_relative_validity);
1207 static void
1208 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_)
1210 EXACT_DATA_CHECK(len, 6);
1212 tele_param_timestamp(tvb, pinfo, tree, len, offset,
1213 hf_ansi_637_tele_deferred_del_ts_year,
1214 hf_ansi_637_tele_deferred_del_ts_month,
1215 hf_ansi_637_tele_deferred_del_ts_day,
1216 hf_ansi_637_tele_deferred_del_ts_hours,
1217 hf_ansi_637_tele_deferred_del_ts_minutes,
1218 hf_ansi_637_tele_deferred_del_ts_seconds);
1221 static void
1222 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_)
1224 EXACT_DATA_CHECK(len, 1);
1226 tele_param_timestamp_rel(tvb, pinfo, tree, len, offset, hf_ansi_637_tele_deferred_del_relative);
1229 static const value_string tele_param_priority_ind_strings[] = {
1230 { 0, "Normal" },
1231 { 1, "Interactive" },
1232 { 2, "Urgent" },
1233 { 3, "Emergency" },
1234 { 0, NULL }
1237 static void
1238 tele_param_pri_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1240 EXACT_DATA_CHECK(len, 1);
1242 proto_tree_add_item(tree, hf_ansi_637_tele_priority_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
1243 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
1246 static const value_string tele_param_privacy_ind_strings[] = {
1247 { 0, "Not restricted (privacy level 0)" },
1248 { 1, "Restricted (privacy level 1)" },
1249 { 2, "Confidential (privacy level 2)" },
1250 { 3, "Secret (privacy level 3)" },
1251 { 0, NULL }
1254 static void
1255 tele_param_priv_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1257 EXACT_DATA_CHECK(len, 1);
1259 proto_tree_add_item(tree, hf_ansi_637_tele_privacy_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
1260 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
1263 static void
1264 tele_param_reply_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1266 EXACT_DATA_CHECK(len, 1);
1268 proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_user_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1269 proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_dak_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1270 proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_read_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1271 proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_report_req, tvb, offset, 1, ENC_BIG_ENDIAN);
1272 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, offset, 1, ENC_BIG_ENDIAN);
1275 static void
1276 tele_param_num_messages(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1278 uint8_t oct;
1280 EXACT_DATA_CHECK(len, 1);
1282 oct = tvb_get_uint8(tvb, offset);
1284 proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_num_messages, tvb, offset, 1,
1285 ((oct & 0xf0) >> 4) * 10 + (oct & 0x0f),
1286 "%u%u",
1287 (oct & 0xf0) >> 4, oct & 0x0f);
1290 static const value_string tele_param_alert_priority_strings[] = {
1291 { 0, "Use Mobile default alert" },
1292 { 1, "Use Low-priority alert" },
1293 { 2, "Use Medium-priority alert" },
1294 { 3, "Use High-priority alert" },
1295 { 0, NULL }
1298 static void
1299 tele_param_alert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1301 EXACT_DATA_CHECK(len, 1);
1303 proto_tree_add_item(tree, hf_ansi_637_tele_alert_msg_delivery_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
1304 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
1307 static void
1308 tele_param_lang_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1310 uint8_t oct;
1311 const char *str = NULL;
1313 EXACT_DATA_CHECK(len, 1);
1315 oct = tvb_get_uint8(tvb, offset);
1317 str = val_to_str_ext_const(oct, &ansi_tsb58_language_ind_vals_ext, "Reserved");
1318 proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_language, tvb, offset, 1,
1319 oct,
1320 "%s (%u)",
1321 str, oct);
1324 static void
1325 tele_param_cb_num(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1327 uint8_t oct, oct2, num_fields, odd;
1328 uint8_t *poctets;
1329 uint32_t saved_offset;
1330 uint32_t required_octs;
1331 uint32_t i;
1333 SHORT_DATA_CHECK(len, 2);
1335 proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_digit_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
1337 oct = tvb_get_uint8(tvb, offset);
1339 if (oct & 0x80)
1341 proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_ton, tvb, offset, 1, ENC_BIG_ENDIAN);
1342 proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_plan, tvb, offset, 1, ENC_BIG_ENDIAN);
1344 offset += 1;
1346 proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_num_fields, tvb, offset, 1, ENC_BIG_ENDIAN);
1348 num_fields = tvb_get_uint8(tvb, offset);
1350 if (num_fields == 0) return;
1352 SHORT_DATA_CHECK(len - 2, num_fields);
1354 offset += 1;
1356 poctets = tvb_get_string_enc(pinfo->pool, tvb, offset, num_fields, ENC_ASCII|ENC_NA);
1358 proto_tree_add_string_format(tree, hf_ansi_637_tele_cb_num_number, tvb, offset, num_fields,
1359 (char *) poctets,
1360 "Number: %s",
1361 (char *) format_text(pinfo->pool, poctets, num_fields));
1363 else
1365 offset += 1;
1367 oct2 = tvb_get_uint8(tvb, offset);
1368 num_fields = ((oct & 0x7f) << 1) | ((oct2 & 0x80) >> 7);
1370 proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_num_fields07f8, tvb, offset, 2, ENC_BIG_ENDIAN);
1372 oct = oct2;
1373 odd = false;
1375 if (num_fields > 0)
1377 i = (num_fields - 1) * 4;
1378 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
1380 SHORT_DATA_CHECK(len - 2, required_octs);
1382 odd = num_fields & 0x01;
1383 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
1384 saved_offset = offset;
1385 offset += 1;
1387 i = 0;
1388 while (i < num_fields)
1390 ansi_637_bigbuf[i] = air_digits[(oct & 0x78) >> 3];
1392 i += 1;
1393 if (i >= num_fields) break;
1395 oct2 = tvb_get_uint8(tvb, offset);
1396 offset += 1;
1398 ansi_637_bigbuf[i] = air_digits[((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7)];
1400 oct = oct2;
1401 i += 1;
1404 proto_tree_add_string_format(tree, hf_ansi_637_tele_cb_num_number, tvb, saved_offset, offset - saved_offset,
1405 ansi_637_bigbuf,
1406 "Number: %s",
1407 ansi_637_bigbuf);
1410 proto_tree_add_item(tree,
1411 odd ? hf_ansi_637_reserved_bits_8_07 : hf_ansi_637_reserved_bits_8_7f,
1412 tvb, offset - 1, 1, ENC_BIG_ENDIAN);
1416 static const value_string tele_param_msg_display_mode_strings[] = {
1417 { 0, "Immediate Display: The mobile station is to display the received message as soon as possible." },
1418 { 1, "Mobile default setting: The mobile station is to display the received message based on a pre-defined mode in the mobile station." },
1419 { 2, "User Invoke: The mobile station is to display the received message based on the mode selected by the user." },
1420 { 3, "Reserved" },
1421 { 0, NULL }
1424 static void
1425 tele_param_disp_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1427 EXACT_DATA_CHECK(len, 1);
1429 proto_tree_add_item(tree, hf_ansi_637_tele_msg_display_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
1430 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
1433 static void
1434 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_)
1436 uint64_t encoding;
1437 uint8_t encoding_bit_len;
1438 uint64_t num_fields;
1439 uint8_t unused_bits;
1440 uint8_t fill_bits;
1441 uint16_t reserved_bits;
1442 uint32_t orig_offset;
1443 enum character_set cset = OTHER;
1445 SHORT_DATA_CHECK(len, 2);
1447 orig_offset = offset;
1448 offset <<= 3;
1449 reserved_bits = len * 8;
1451 while (reserved_bits > 7) {
1452 proto_tree_add_bits_ret_val(tree, hf_ansi_637_tele_mult_enc_user_data_encoding,
1453 tvb, offset, 5, &encoding, ENC_BIG_ENDIAN);
1454 switch (encoding) {
1455 case 0x00:
1456 case 0x05:
1457 case 0x06:
1458 case 0x07:
1459 case 0x08:
1460 case 0x10:
1461 encoding_bit_len = 8;
1462 cset = OTHER;
1463 break;
1465 case 0x01:
1466 case 0x02:
1467 case 0x03:
1468 default:
1469 encoding_bit_len = 7;
1470 cset = ASCII_7BITS;
1471 break;
1473 case 0x04:
1474 encoding_bit_len = 16;
1475 cset = UCS2;
1476 break;
1478 case 0x09:
1479 encoding_bit_len = 7;
1480 cset = GSM_7BITS;
1481 break;
1484 offset += 5;
1485 reserved_bits -= 5;
1487 proto_tree_add_bits_ret_val(tree, hf_ansi_637_tele_mult_enc_user_data_num_fields,
1488 tvb, offset, 8, &num_fields, ENC_BIG_ENDIAN);
1490 offset += 8;
1491 reserved_bits -= 8;
1493 unused_bits = (offset & 0x07) ? 8 - (offset & 0x07) : 0;
1494 fill_bits = 0;
1496 if (num_fields) {
1497 text_decoder(tvb, pinfo, tree, offset>>3, (uint8_t)encoding, (uint8_t)num_fields, (uint8_t)num_fields * encoding_bit_len,
1498 unused_bits, fill_bits, hf_ansi_637_tele_mult_enc_user_data_text);
1499 offset += (uint8_t)num_fields * encoding_bit_len;
1500 reserved_bits -= (uint8_t)num_fields * encoding_bit_len;
1504 if (reserved_bits > 0)
1507 * unlike for CMAS, the bits that can be reserved will always be
1508 * at the end of an octet so we don't have to worry about them
1509 * spanning two octets
1512 switch (cset)
1514 case GSM_7BITS:
1516 crumb_spec_t crumbs[3];
1517 uint8_t i = 0;
1518 unsigned bits_offset;
1520 if (reserved_bits > 3) {
1521 bits_offset = ((orig_offset + len - 2)*8)+5;
1522 crumbs[i].crumb_bit_offset = 0;
1523 crumbs[i++].crumb_bit_length = reserved_bits - 3;
1524 crumbs[i].crumb_bit_offset = 8;
1525 } else {
1526 bits_offset = ((orig_offset + len - 1)*8)+5;
1527 crumbs[i].crumb_bit_offset = 0;
1529 crumbs[i++].crumb_bit_length = 3;
1530 crumbs[i].crumb_bit_offset = 0;
1531 crumbs[i].crumb_bit_length = 0;
1532 proto_tree_add_split_bits_item_ret_val(tree, hf_ansi_637_reserved_bits_16_generic, tvb, bits_offset, crumbs, NULL);
1534 break;
1536 default:
1537 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 */
1538 break;
1543 static void
1544 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_)
1546 EXACT_DATA_CHECK(len, 2);
1548 proto_tree_add_item(tree, hf_ansi_637_tele_msg_deposit_idx, tvb, offset, 2, ENC_BIG_ENDIAN);
1551 static const value_string tele_param_srvc_cat_prog_data_op_code_vals[] = {
1552 { 0x00, "Delete the Service Category" },
1553 { 0x01, "Add the Service Category" },
1554 { 0x02, "Clear all Service Categories" },
1555 { 0x00, NULL}
1558 static const value_string tele_param_srvc_cat_prog_data_alert_option_vals[] = {
1559 { 0x00, "No alert" },
1560 { 0x01, "Mobile Station default alert" },
1561 { 0x02, "Vibrate alert once" },
1562 { 0x03, "Vibrate alert - repeat" },
1563 { 0x04, "Visual alert once" },
1564 { 0x05, "Visual alert - repeat" },
1565 { 0x06, "Low-priority alert once" },
1566 { 0x07, "Low-priority alert - repeat" },
1567 { 0x08, "Medium-priority alert once" },
1568 { 0x09, "Medium-priority alert - repeat" },
1569 { 0x0a, "High-priority alert once" },
1570 { 0x0b, "High-priority alert - repeat" },
1571 { 0x00, NULL}
1574 static void
1575 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_)
1577 uint64_t encoding;
1578 uint8_t encoding_bit_len;
1579 uint64_t num_fields;
1580 uint8_t unused_bits;
1581 uint8_t fill_bits;
1582 uint16_t reserved_bits;
1583 uint32_t orig_offset;
1584 enum character_set cset = OTHER;
1586 SHORT_DATA_CHECK(len, 2);
1588 orig_offset = offset;
1589 offset <<= 3;
1590 reserved_bits = len * 8;
1592 proto_tree_add_bits_ret_val(tree, hf_ansi_637_tele_srvc_cat_prog_data_encoding,
1593 tvb, offset, 5, &encoding, ENC_BIG_ENDIAN);
1594 switch (encoding) {
1595 case 0x00:
1596 case 0x05:
1597 case 0x06:
1598 case 0x07:
1599 case 0x08:
1600 case 0x10:
1601 encoding_bit_len = 8;
1602 cset = OTHER;
1603 break;
1605 case 0x01:
1606 case 0x02:
1607 case 0x03:
1608 default:
1609 encoding_bit_len = 7;
1610 cset = ASCII_7BITS;
1611 break;
1613 case 0x04:
1614 encoding_bit_len = 16;
1615 cset = OTHER;
1616 break;
1618 case 0x09:
1619 encoding_bit_len = 7;
1620 cset = GSM_7BITS;
1621 break;
1624 offset += 5;
1625 reserved_bits -= 5;
1627 while (reserved_bits > 7) {
1628 proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_operation_code,
1629 tvb, offset, 4, ENC_BIG_ENDIAN);
1630 offset += 4;
1631 reserved_bits -= 4;
1633 proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_category,
1634 tvb, offset, 16, ENC_BIG_ENDIAN);
1635 offset += 16;
1636 reserved_bits -= 16;
1638 proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_language,
1639 tvb, offset, 8, ENC_BIG_ENDIAN);
1640 offset += 8;
1641 reserved_bits -= 8;
1643 proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_max_messages,
1644 tvb, offset, 8, ENC_BIG_ENDIAN);
1645 offset += 8;
1646 reserved_bits -= 8;
1648 proto_tree_add_bits_item(tree, hf_ansi_637_tele_srvc_cat_prog_data_alert_option,
1649 tvb, offset, 4, ENC_BIG_ENDIAN);
1650 offset += 4;
1651 reserved_bits -= 4;
1653 proto_tree_add_bits_ret_val(tree, hf_ansi_637_tele_srvc_cat_prog_data_num_fields,
1654 tvb, offset, 8, &num_fields, ENC_BIG_ENDIAN);
1656 offset += 8;
1657 reserved_bits -= 8;
1659 unused_bits = (offset & 0x07) ? 8 - (offset & 0x07) : 0;
1660 fill_bits = 0;
1662 if (num_fields) {
1663 text_decoder(tvb, pinfo, tree, offset>>3, (uint8_t)encoding, (uint8_t)num_fields, (uint8_t)num_fields * encoding_bit_len,
1664 unused_bits, fill_bits, hf_ansi_637_tele_srvc_cat_prog_data_text);
1665 offset += (uint8_t)num_fields * encoding_bit_len;
1666 reserved_bits -= (uint8_t)num_fields * encoding_bit_len;
1670 if (reserved_bits > 0)
1673 * unlike for CMAS, the bits that can be reserved will always be
1674 * at the end of an octet so we don't have to worry about them
1675 * spanning two octets
1678 switch (cset)
1680 case GSM_7BITS:
1682 crumb_spec_t crumbs[3];
1683 uint8_t i = 0;
1684 unsigned bits_offset;
1686 if (reserved_bits > 3) {
1687 bits_offset = ((orig_offset + len - 2)*8)+5;
1688 crumbs[i].crumb_bit_offset = 0;
1689 crumbs[i++].crumb_bit_length = reserved_bits - 3;
1690 crumbs[i].crumb_bit_offset = 8;
1691 } else {
1692 bits_offset = ((orig_offset + len - 1)*8)+5;
1693 crumbs[i].crumb_bit_offset = 0;
1695 crumbs[i++].crumb_bit_length = 3;
1696 crumbs[i].crumb_bit_offset = 0;
1697 crumbs[i].crumb_bit_length = 0;
1698 proto_tree_add_split_bits_item_ret_val(tree, hf_ansi_637_reserved_bits_16_generic, tvb, bits_offset, crumbs, NULL);
1700 break;
1702 default:
1703 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 */
1704 break;
1709 static const value_string tele_param_srvc_cat_prog_results_result_strings[] = {
1710 { 0x00, "Programming successful" },
1711 { 0x01, "Service Category memory limit exceeded" },
1712 { 0x02, "Service Category limit exceeded" },
1713 { 0x03, "Category already programmed" },
1714 { 0x04, "Category not previously programmed" },
1715 { 0x05, "Invalid MAX_MESSAGES" },
1716 { 0x06, "Invalid ALERT_OPTION" },
1717 { 0x07, "Invalid Service Category name" },
1718 { 0x08, "Unspecified programming failure" },
1719 { 0x09, "Reserved" },
1720 { 0x0a, "Reserved" },
1721 { 0x0b, "Reserved" },
1722 { 0x0c, "Reserved" },
1723 { 0x0d, "Reserved" },
1724 { 0x0e, "Reserved" },
1725 { 0x0f, "Reserved" },
1726 { 0, NULL }
1729 static void
1730 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_)
1732 uint32_t curr_offset;
1733 uint32_t value;
1734 const char *str = NULL;
1736 curr_offset = offset;
1738 while ((len - (curr_offset - offset)) >= 3)
1740 value = tvb_get_ntohs(tvb, curr_offset);
1742 str = val_to_str_const(value, ansi_tsb58_srvc_cat_vals, "Reserved");
1743 proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat, tvb, curr_offset, 2,
1744 value,
1745 "%s (%u)",
1746 str, value);
1748 curr_offset += 2;
1750 proto_tree_add_item(tree, hf_ansi_637_tele_srvc_cat_prog_results_result, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
1751 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
1753 curr_offset += 1;
1756 EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
1759 /* Adamek Jan - IS637C Message status decoding procedure */
1760 static const value_string tele_param_msg_status_error_class_strings[] = {
1761 { 0x00, "No Error" },
1762 { 0x01, "Reserved" },
1763 { 0x02, "Temporary Condition" },
1764 { 0x03, "Permanent Condition" },
1765 { 0, NULL }
1768 static void
1769 tele_param_msg_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p _U_)
1771 uint8_t oct;
1772 uint8_t msg_status_code;
1773 const char *str = NULL;
1775 EXACT_DATA_CHECK(len, 1);
1777 proto_tree_add_item(tree, hf_ansi_637_tele_msg_status, tvb, offset, 1, ENC_BIG_ENDIAN);
1778 proto_tree_add_item(tree, hf_ansi_637_tele_msg_status_error_class, tvb, offset, 1, ENC_BIG_ENDIAN);
1780 oct = tvb_get_uint8(tvb, offset);
1782 msg_status_code = (oct & 0x3f);
1784 switch ((oct & 0xc0) >> 6)
1786 case 0x00:
1787 switch (msg_status_code)
1789 case 0x00: str = "Message accepted"; break;
1790 case 0x01: str = "Message deposited to Internet"; break;
1791 case 0x02: str = "Message delivered"; break;
1792 case 0x03: str = "Message cancelled"; break;
1793 default: str = "Reserved"; break;
1795 break;
1797 case 0x02:
1798 switch (msg_status_code)
1800 case 0x04: str = "Network congestion"; break;
1801 case 0x05: str = "Network error"; break;
1802 case 0x1f: str = "Unknown error"; break;
1803 default: str = "Reserved"; break;
1805 break;
1807 case 0x03:
1808 switch (msg_status_code)
1810 case 0x04: str = "Network congestion"; break;
1811 case 0x05: str = "Network error"; break;
1812 case 0x06: str = "Cancel failed"; break;
1813 case 0x07: str = "Blocked destination"; break;
1814 case 0x08: str = "Text too long"; break;
1815 case 0x09: str = "Duplicate message"; break;
1816 case 0x0a: str = "Invalid destination"; break;
1817 case 0x0d: str = "Message expired"; break;
1818 case 0x1f: str = "Unknown error"; break;
1819 default: str = "Reserved"; break;
1821 break;
1823 default:
1824 str = "Reserved";
1825 break;
1828 proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_msg_status_code, tvb, offset, 1,
1829 oct,
1830 "%s (%u)",
1831 str, msg_status_code);
1834 static void
1835 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_)
1837 EXACT_DATA_CHECK(len, 1);
1839 proto_tree_add_item(tree, hf_ansi_637_tele_tp_failure_cause_value, tvb, offset, 1, ENC_BIG_ENDIAN);
1842 #define NUM_TELE_PARAM array_length(ansi_tele_param_strings)
1843 static int ett_ansi_637_tele_param[NUM_TELE_PARAM];
1844 static void (*ansi_637_tele_param_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, bool *has_private_data_p) = {
1845 tele_param_msg_id, /* Message Identifier */
1846 tele_param_user_data, /* User Data */
1847 tele_param_rsp_code, /* User Response Code */
1848 tele_param_message_center_timestamp,/* Message Center Time Stamp */
1849 tele_param_validity_period_abs, /* Validity Period - Absolute */
1850 tele_param_validity_period_rel, /* Validity Period - Relative */
1851 tele_param_deferred_del_abs, /* Deferred Delivery Time - Absolute */
1852 tele_param_deferred_del_rel, /* Deferred Delivery Time - Relative */
1853 tele_param_pri_ind, /* Priority Indicator */
1854 tele_param_priv_ind, /* Privacy Indicator */
1855 tele_param_reply_opt, /* Reply Option */
1856 tele_param_num_messages, /* Number of Messages */
1857 tele_param_alert, /* Alert on Message Delivery */
1858 tele_param_lang_ind, /* Language Indicator */
1859 tele_param_cb_num, /* Call-Back Number */
1860 tele_param_disp_mode, /* Message Display Mode */
1861 tele_param_mult_enc_user_data, /* Multiple Encoding User Data */
1862 tele_param_msg_deposit_idx, /* Message Deposit Index */
1863 tele_param_srvc_cat_prog_data, /* Service Category Program Data */
1864 tele_param_srvc_cat_prog_results, /* Service Category Program Results */
1865 tele_param_msg_status, /* Message status */
1866 tele_param_tp_failure_cause, /* TP-Failure cause */
1867 NULL, /* Enhanced VMN */
1868 NULL /* Enhanced VMN Ack */
1871 static void
1872 trans_param_tele_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, char *add_string, int string_len)
1874 uint32_t value;
1875 const char *str = NULL;
1877 EXACT_DATA_CHECK(len, 2);
1879 value = tvb_get_ntohs(tvb, offset);
1881 ansi_637_trans_tele_id = value;
1883 str = try_val_to_str(value, ansi_tele_id_strings);
1885 if (NULL == str)
1887 switch (value)
1889 case 1:
1890 str = "Reserved for maintenance";
1891 break;
1892 case 4102:
1893 str = "CDMA Service Category Programming Teleservice (SCPT)";
1894 break;
1895 case 4103:
1896 str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
1897 break;
1898 case 32513:
1899 str = "TDMA Cellular Messaging Teleservice";
1900 break;
1901 case 32514:
1902 str = "TDMA Cellular Paging Teleservice (CPT-136)";
1903 break;
1904 case 32515:
1905 str = "TDMA Over-the-Air Activation Teleservice (OATS)";
1906 break;
1907 case 32520:
1908 str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
1909 break;
1910 case 32584:
1911 str = "TDMA Segmented System Assisted Mobile Positioning Service";
1912 break;
1913 default:
1914 if ((value >= 2) && (value <= 4095))
1916 str = "Reserved for assignment by TIA-41";
1918 else if ((value >= 4104) && (value <= 4113))
1920 str = "Reserved for GSM1x Teleservice (CDMA)";
1922 else if ((value >= 4114) && (value <= 32512))
1924 str = "Reserved for assignment by TIA-41";
1926 else if ((value >= 32521) && (value <= 32575))
1928 str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
1930 else if ((value >= 49152) && (value <= 65535))
1932 str = "Reserved for carrier specific teleservices";
1934 else
1936 str = "Unrecognized Teleservice ID";
1938 break;
1943 * NOT format_value because I don't need the text from the hf_
1945 proto_tree_add_uint_format(tree, hf_ansi_637_trans_tele_id, tvb, offset, 2,
1946 value,
1947 "%s (%u)",
1948 str, value);
1950 snprintf(add_string, string_len, " - %s (%u)", str, value);
1953 static void
1954 trans_param_srvc_cat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned len, uint32_t offset, char *add_string, int string_len)
1956 uint32_t value;
1957 const char *str;
1959 EXACT_DATA_CHECK(len, 2);
1961 value = tvb_get_ntohs(tvb, offset);
1963 str = val_to_str_const(value, ansi_tsb58_srvc_cat_vals, "Reserved");
1964 proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_srvc_cat, tvb, offset, 2,
1965 value,
1966 "%s (%u)",
1967 str, value);
1969 snprintf(add_string, string_len, " - %s (%u)", str, value);
1971 if ((value >= ANSI_TSB58_SRVC_CAT_CMAS_MIN) && (value <= ANSI_TSB58_SRVC_CAT_CMAS_MAX))
1973 col_append_fstr(pinfo->cinfo, COL_INFO, " - CMAS (%s)", str);
1977 static const value_string trans_param_addr_data_net_ton_strings[] = {
1978 { 0x00, "Unknown" },
1979 { 0x01, "Internet Protocol (RFC 791)" },
1980 { 0x02, "Internet Email Address (RFC 822)" },
1981 { 0, NULL }
1984 static void
1985 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_)
1987 uint8_t oct, oct2, odd;
1988 bool email_addr;
1989 uint32_t i, saved_offset, required_octs;
1990 uint64_t num_fields;
1991 tvbuff_t *tvb_out;
1993 SHORT_DATA_CHECK(len, 2);
1995 oct = tvb_get_uint8(tvb, offset);
1997 proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_digit_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
1998 proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_number_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
2000 if (oct & 0x80)
2002 if (oct & 0x40)
2004 email_addr = (((oct & 0x38) >> 3) == 0x02) ? true : false;
2007 * do not change to ...add_item() with VALS in hf definition because this parameter is
2008 * used below in the 'else' with a different string array
2010 proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_addr_param_ton, tvb, offset, 1,
2011 oct,
2012 "%s (%u)",
2013 val_to_str_const((oct & 0x38) >> 3, trans_param_addr_data_net_ton_strings, "Reserved"), (oct & 0x38) >> 3);
2015 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);
2016 if (num_fields == 0) return;
2017 offset += 1;
2019 SHORT_DATA_CHECK(len - 2, num_fields);
2021 tvb_out = tvb_new_octet_aligned(tvb, offset*8 + 5, (int)num_fields*8);
2022 add_new_data_source(pinfo, tvb_out, "Address");
2024 if (email_addr)
2026 proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_number, tvb_out, 0, (int)num_fields,
2027 ENC_ASCII);
2029 else
2031 proto_tree_add_item(tree, hf_ansi_637_trans_bin_addr, tvb_out, 0, (int)num_fields, ENC_NA);
2034 offset += ((uint32_t)num_fields);
2036 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_07, tvb, offset, 1, ENC_BIG_ENDIAN);
2038 else
2041 * do not change to ...add_item() with VALS in hf definition because this parameter
2042 * is used above in the 'if' with a different string array
2044 proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_addr_param_ton, tvb, offset, 1,
2045 oct,
2046 "%s (%u)",
2047 val_to_str_const((oct & 0x38) >> 3, ansi_a_ms_info_rec_num_type_vals, "Reserved"), (oct & 0x38) >> 3);
2049 proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_plan, tvb, offset, 2, ENC_BIG_ENDIAN);
2050 offset += 1;
2052 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);
2053 offset += 1;
2055 if (num_fields == 0) return;
2057 SHORT_DATA_CHECK(len - 3, num_fields);
2059 tvb_out = tvb_new_octet_aligned(tvb, offset*8 + 1, (int)num_fields*8);
2060 add_new_data_source(pinfo, tvb_out, "Address");
2062 proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_number, tvb_out, 0, (int)num_fields,
2063 ENC_ASCII);
2065 offset += ((uint32_t)num_fields);
2067 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_7f, tvb, offset, 1, ENC_BIG_ENDIAN);
2070 else
2072 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);
2073 offset += 1;
2075 oct = tvb_get_uint8(tvb, offset);
2076 odd = false;
2078 if (num_fields > 0)
2080 i = ((uint32_t)num_fields - 1) * 4;
2081 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
2083 SHORT_DATA_CHECK(len - 2, required_octs);
2085 odd = num_fields & 0x01;
2086 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
2087 saved_offset = offset;
2088 offset += 1;
2090 i = 0;
2091 while (i < num_fields)
2093 ansi_637_bigbuf[i] =
2094 air_digits[(oct & 0x3c) >> 2];
2096 i += 1;
2097 if (i >= num_fields) break;
2099 oct2 = tvb_get_uint8(tvb, offset);
2100 offset += 1;
2102 ansi_637_bigbuf[i] =
2103 air_digits[((oct & 0x03) << 2) | ((oct2 & 0xc0) >> 6)];
2105 oct = oct2;
2107 i += 1;
2110 proto_tree_add_string_format(tree, hf_ansi_637_trans_addr_param_number, tvb, saved_offset, offset - saved_offset,
2111 ansi_637_bigbuf,
2112 "Number: %s",
2113 ansi_637_bigbuf);
2116 proto_tree_add_item(tree,
2117 odd ? hf_ansi_637_reserved_bits_8_03 : hf_ansi_637_reserved_bits_8_3f,
2118 tvb, offset - 1, 1, ENC_BIG_ENDIAN);
2122 static const value_string trans_param_subaddr_type_strings[] = {
2123 { 0x0, "NSAP (CCITT Recommendation X.213 or ISO 8348 AD2)" },
2124 { 0x1, "User-specified" },
2125 { 0, NULL }
2128 static void
2129 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_)
2131 uint8_t num_fields;
2132 uint32_t value;
2133 tvbuff_t *tvb_out;
2135 SHORT_DATA_CHECK(len, 2);
2137 value = tvb_get_ntohs(tvb, offset);
2139 proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_subaddr_type, tvb, offset, 2,
2140 value,
2141 "%s (%u)",
2142 val_to_str_const((value & 0xe000) >> 13, trans_param_subaddr_type_strings, "Reserved"), (value & 0xe000) >> 13);
2144 proto_tree_add_item(tree, hf_ansi_637_trans_subaddr_odd_even_ind, tvb, offset, 2, ENC_BIG_ENDIAN);
2145 proto_tree_add_item(tree, hf_ansi_637_trans_subaddr_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
2147 num_fields = (value & 0x0ff0) >> 4;
2149 if (num_fields == 0) return;
2151 SHORT_DATA_CHECK(len - 2, num_fields);
2153 offset += 1;
2154 tvb_out = tvb_new_octet_aligned(tvb, offset*8 + 4, num_fields*8);
2155 add_new_data_source(pinfo, tvb_out, "Subaddress");
2157 proto_tree_add_item(tree, hf_ansi_637_trans_bin_addr, tvb_out, 0, num_fields, ENC_NA);
2159 offset += num_fields;
2161 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, offset, 1, ENC_BIG_ENDIAN);
2164 static void
2165 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)
2167 proto_tree_add_item(tree, hf_ansi_637_trans_bearer_reply_seq_num, tvb, offset, 1, ENC_BIG_ENDIAN);
2168 proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_03, tvb, offset, 1, ENC_BIG_ENDIAN);
2170 snprintf(add_string, string_len, " - Reply Sequence Number (%u)",
2171 (tvb_get_uint8(tvb, offset) & 0xfc) >> 2);
2174 static const value_string trans_param_cause_codes_error_class_strings[] = {
2175 { 0x00, "No Error" },
2176 { 0x01, "Reserved" },
2177 { 0x02, "Temporary Condition" },
2178 { 0x03, "Permanent Condition" },
2179 { 0, NULL }
2182 static void
2183 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)
2185 uint8_t oct;
2186 const char *str;
2188 proto_tree_add_item(tree, hf_ansi_637_trans_cause_codes_seq_num, tvb, offset, 1, ENC_BIG_ENDIAN);
2189 proto_tree_add_item(tree, hf_ansi_637_trans_cause_codes_error_class, tvb, offset, 1, ENC_BIG_ENDIAN);
2191 oct = tvb_get_uint8(tvb, offset);
2193 snprintf(add_string, string_len, " - Reply Sequence Number (%u)", (oct & 0xfc) >> 2);
2195 if (!(oct & 0x03)) return;
2197 if (len == 1) return;
2199 offset += 1;
2201 oct = tvb_get_uint8(tvb, offset);
2203 switch (oct)
2205 case 0: str = "Address vacant"; break;
2206 case 1: str = "Address translation failure"; break;
2207 case 2: str = "Network resource shortage"; break;
2208 case 3: str = "Network failure"; break;
2209 case 4: str = "Invalid Teleservice ID"; break;
2210 case 5: str = "Other network problem"; break;
2211 case 6: str = "Unsupported network interface"; break;
2212 case 32: str = "No page response"; break;
2213 case 33: str = "Destination busy"; break;
2214 case 34: str = "No acknowledgement"; break;
2215 case 35: str = "Destination resource shortage"; break;
2216 case 36: str = "SMS delivery postponed"; break;
2217 case 37: str = "Destination out of service"; break;
2218 case 38: str = "Destination no longer at this address"; break;
2219 case 39: str = "Other terminal problem"; break;
2220 case 64: str = "Radio interface resource shortage"; break;
2221 case 65: str = "Radio interface incompatibility"; break;
2222 case 66: str = "Other radio interface problem"; break;
2223 case 67: str = "Unsupported Base Station Capability"; break;
2224 case 96: str = "Encoding problem"; break;
2225 case 97: str = "Service origination denied"; break;
2226 case 98: str = "Service termination denied"; break;
2227 case 99: str = "Supplementary service not supported"; break;
2228 case 100: str = "Service not supported"; break;
2229 case 101: str = "Reserved"; break;
2230 case 102: str = "Missing expected parameter"; break;
2231 case 103: str = "Missing mandatory parameter"; break;
2232 case 104: str = "Unrecognized parameter value"; break;
2233 case 105: str = "Unexpected parameter value"; break;
2234 case 106: str = "User Data size error"; break;
2235 case 107: str = "Other general problems"; break;
2236 case 108: str = "Session not active"; break;
2237 default:
2238 if ((oct >= 7) && (oct <= 31)) { str = "Reserved, treat as Other network problem"; }
2239 else if ((oct >= 40) && (oct <= 47)) { str = "Reserved, treat as Other terminal problem"; }
2240 else if ((oct >= 48) && (oct <= 63)) { str = "Reserved, treat as SMS delivery postponed"; }
2241 else if ((oct >= 68) && (oct <= 95)) { str = "Reserved, treat as Other radio interface problem"; }
2242 else if ((oct >= 109) && (oct <= 223)) { str = "Reserved, treat as Other general problems"; }
2243 else { str = "Reserved for protocol extension, treat as Other general problems"; }
2244 break;
2247 proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_cause_codes_code, tvb, offset, 1,
2248 oct,
2249 "%s (%u)",
2250 str, oct);
2253 static void
2254 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_)
2256 tvbuff_t *tele_tvb;
2259 * dissect the embedded teleservice data
2261 tele_tvb = tvb_new_subset_length(tvb, offset, len);
2263 dissector_try_uint(tele_dissector_table, ansi_637_trans_tele_id, tele_tvb, pinfo, g_tree);
2266 #define NUM_TRANS_PARAM array_length(ansi_trans_param_strings)
2267 static int ett_ansi_637_trans_param[NUM_TRANS_PARAM];
2268 static void (*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) = {
2269 trans_param_tele_id, /* Teleservice Identifier */
2270 trans_param_srvc_cat, /* Service Category */
2271 trans_param_address, /* Originating Address */
2272 trans_param_subaddress, /* Originating Subaddress */
2273 trans_param_address, /* Destination Address */
2274 trans_param_subaddress, /* Destination Subaddress */
2275 trans_param_bearer_reply_opt, /* Bearer Reply Option */
2276 trans_param_cause_codes, /* Cause Codes */
2277 trans_param_bearer_data, /* Bearer Data */
2278 NULL, /* NONE */
2281 #define NUM_TRANS_MSG_TYPE array_length(ansi_trans_msg_type_strings)
2282 static int ett_ansi_637_trans_msg[NUM_TRANS_MSG_TYPE];
2284 /* GENERIC IS-637 DISSECTOR FUNCTIONS */
2286 static bool
2287 dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t *offset, bool *has_private_data_p)
2289 void (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, unsigned, uint32_t, bool *) = NULL;
2290 uint8_t oct;
2291 uint8_t len;
2292 uint32_t curr_offset;
2293 int ett_param_idx, idx;
2294 proto_tree *subtree;
2295 proto_item *item;
2296 const char *str = NULL;
2299 curr_offset = *offset;
2301 oct = tvb_get_uint8(tvb, curr_offset);
2302 str = try_val_to_str_idx_ext((uint32_t) oct, &ansi_tele_param_strings_ext, &idx);
2304 if (NULL == str)
2306 return false;
2309 ett_param_idx = ett_ansi_637_tele_param[idx];
2310 param_fcn = ansi_637_tele_param_fcn[idx];
2312 subtree =
2313 proto_tree_add_subtree(tree, tvb, curr_offset, -1,
2314 ett_param_idx, &item, str);
2316 proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id, tvb, curr_offset, 1, oct);
2318 curr_offset += 1;
2320 len = tvb_get_uint8(tvb, curr_offset);
2322 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
2324 proto_tree_add_uint(subtree, hf_ansi_637_tele_length, tvb, curr_offset, 1, len);
2326 curr_offset += 1;
2328 if (len > 0)
2330 if (param_fcn == NULL)
2332 proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_no_tele_parameter_dissector, tvb, curr_offset, len);
2334 else
2337 * internal working (aka hack) for CMAS
2339 * the 'User Data' subparameter is encoded in a special way for CMAS
2340 * (as per TIA-1149)
2342 * if (Broadcast SMS && 'User Data') then call CMAS dissector
2344 if ((ansi_637_trans_tele_id == INTERNAL_BROADCAST_TELE_ID) &&
2345 (oct == 0x01))
2347 param_fcn = tele_param_user_data_cmas;
2350 (*param_fcn)(tvb, pinfo, subtree, len, curr_offset, has_private_data_p);
2353 curr_offset += len;
2356 *offset = curr_offset;
2358 return true;
2361 static void
2362 dissect_ansi_637_tele_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ansi_637_tree, bool *has_private_data_p)
2364 uint8_t len;
2365 uint32_t curr_offset;
2367 curr_offset = 0;
2368 len = tvb_reported_length(tvb);
2370 while ((len - curr_offset) > 0)
2372 if (!dissect_ansi_637_tele_param(tvb, pinfo, ansi_637_tree, &curr_offset, has_private_data_p))
2374 proto_tree_add_expert(ansi_637_tree, pinfo, &ei_ansi_637_unknown_tele_parameter, tvb, curr_offset, len - curr_offset);
2375 break;
2380 static int
2381 dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2383 proto_item *ansi_637_item;
2384 proto_tree *ansi_637_tree = NULL;
2385 const char *str = NULL;
2386 uint32_t value;
2387 bool has_private_data = false;
2389 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
2391 /* In the interest of speed, if "tree" is NULL, don't do any work not
2392 * necessary to generate protocol tree items.
2394 if (tree)
2396 g_tree = tree;
2398 value = pinfo->match_uint;
2401 * create the ansi_637 protocol tree
2403 str = try_val_to_str(value, ansi_tele_id_strings);
2405 if (NULL == str)
2407 switch (value)
2409 case 1:
2410 str = "Reserved for maintenance";
2411 break;
2412 case 4102:
2413 str = "CDMA Service Category Programming Teleservice (SCPT)";
2414 break;
2415 case 4103:
2416 str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
2417 break;
2418 case 32513:
2419 str = "TDMA Cellular Messaging Teleservice";
2420 break;
2421 case 32514:
2422 str = "TDMA Cellular Paging Teleservice (CPT-136)";
2423 break;
2424 case 32515:
2425 str = "TDMA Over-the-Air Activation Teleservice (OATS)";
2426 break;
2427 case 32520:
2428 str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
2429 break;
2430 case 32584:
2431 str = "TDMA Segmented System Assisted Mobile Positioning Service";
2432 break;
2433 default:
2434 if ((value >= 2) && (value <= 4095))
2436 str = "Reserved for assignment by TIA-41";
2438 else if ((value >= 4104) && (value <= 4113))
2440 str = "Reserved for GSM1x Teleservice (CDMA)";
2442 else if ((value >= 4114) && (value <= 32512))
2444 str = "Reserved for assignment by TIA-41";
2446 else if ((value >= 32521) && (value <= 32575))
2448 str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
2450 else if ((value >= 49152) && (value <= 65535))
2452 str = "Reserved for carrier specific teleservices";
2454 else
2456 str = "Unrecognized Teleservice ID";
2458 break;
2462 if (value == INTERNAL_BROADCAST_TELE_ID)
2465 * supposed to be "Reserved for carrier specific teleservices"
2466 * but we are using it to key SMS Broadcast dissection where
2467 * there is no teleservice ID
2469 ansi_637_item =
2470 proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
2471 "%s",
2472 ansi_proto_name_tele);
2474 else
2476 ansi_637_item =
2477 proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
2478 "%s - %s (%u)",
2479 ansi_proto_name_tele, str, pinfo->match_uint);
2482 ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele);
2484 dissect_ansi_637_tele_message(tvb, pinfo, ansi_637_tree, &has_private_data);
2486 return tvb_captured_length(tvb);
2489 static bool
2490 dissect_ansi_637_trans_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t *offset)
2492 void (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, unsigned, uint32_t, char *, int) = NULL;
2493 uint8_t oct;
2494 uint8_t len;
2495 uint32_t curr_offset;
2496 int ett_param_idx, idx;
2497 proto_tree *subtree;
2498 proto_item *item;
2499 const char *str;
2501 curr_offset = *offset;
2503 oct = tvb_get_uint8(tvb, curr_offset);
2504 str = try_val_to_str_idx((uint32_t) oct, ansi_trans_param_strings, &idx);
2506 if (NULL == str)
2508 return false;
2511 ett_param_idx = ett_ansi_637_trans_param[idx];
2512 param_fcn = ansi_637_trans_param_fcn[idx];
2514 subtree = proto_tree_add_subtree(tree, tvb, curr_offset, -1, ett_param_idx, &item, str);
2516 proto_tree_add_uint(subtree, hf_ansi_637_trans_param_id, tvb, curr_offset, 1, oct);
2518 curr_offset += 1;
2520 len = tvb_get_uint8(tvb, curr_offset);
2522 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
2524 proto_tree_add_uint(subtree, hf_ansi_637_trans_length, tvb, curr_offset, 1, len);
2526 curr_offset += 1;
2528 if (len > 0)
2530 if (param_fcn == NULL)
2532 proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_no_trans_parameter_dissector, tvb, curr_offset, len);
2534 else
2536 char *ansi_637_add_string;
2538 ansi_637_add_string = (char *) wmem_alloc(pinfo->pool, 1024);
2539 ansi_637_add_string[0] = '\0';
2540 (*param_fcn)(tvb, pinfo, subtree, len, curr_offset, ansi_637_add_string, 1024);
2542 if (ansi_637_add_string[0] != '\0')
2544 proto_item_append_text(item, "%s", ansi_637_add_string);
2548 curr_offset += len;
2551 *offset = curr_offset;
2553 return true;
2557 static int
2558 dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2560 proto_item *ansi_637_item;
2561 proto_tree *ansi_637_tree = NULL;
2562 uint32_t curr_offset;
2563 int idx;
2564 const char *str = NULL;
2565 uint8_t oct;
2566 uint8_t len;
2568 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
2570 /* In the interest of speed, if "tree" is NULL, don't do any work not
2571 * necessary to generate protocol tree items.
2573 if (tree)
2575 g_tree = tree;
2578 * reset the teleservice ID for each dissection
2580 ansi_637_trans_tele_id = 0;
2583 * create the ansi_637 protocol tree
2585 oct = tvb_get_uint8(tvb, 0);
2587 str = try_val_to_str_idx(oct, ansi_trans_msg_type_strings, &idx);
2589 if (NULL == str)
2591 ansi_637_item =
2592 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
2593 "%s - Unrecognized Transport Layer Message Type (%u)",
2594 ansi_proto_name_trans, oct);
2596 ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans);
2598 else
2600 ansi_637_item =
2601 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
2602 "%s - %s",
2603 ansi_proto_name_trans, str);
2605 ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans_msg[idx]);
2607 if (oct == ANSI_TRANS_MSG_TYPE_BROADCAST)
2610 * there is no teleservice ID for Broadcast but we want the
2611 * bearer data to be dissected
2613 * using a reserved value to key dissector port
2615 ansi_637_trans_tele_id = INTERNAL_BROADCAST_TELE_ID;
2617 col_append_str(pinfo->cinfo, COL_INFO, "(BROADCAST)");
2621 curr_offset = 1;
2623 len = tvb_reported_length(tvb);
2625 while ((len - curr_offset) > 0)
2627 if (!dissect_ansi_637_trans_param(tvb, pinfo, ansi_637_tree, &curr_offset))
2629 proto_tree_add_expert(ansi_637_tree, pinfo, &ei_ansi_637_unknown_trans_parameter, tvb, curr_offset, len - curr_offset);
2630 break;
2634 return tvb_captured_length(tvb);
2638 /* Dissect SMS embedded in SIP */
2639 static int
2640 dissect_ansi_637_trans_app(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2642 col_set_str(pinfo->cinfo, COL_PROTOCOL, "/");
2643 col_set_fence(pinfo->cinfo, COL_INFO);
2644 return dissect_ansi_637_trans(tvb, pinfo, tree, data);
2648 /* Register the protocol with Wireshark */
2649 void
2650 proto_register_ansi_637(void)
2652 unsigned i;
2654 /* Setup list of header fields */
2655 static hf_register_info hf_trans[] = {
2656 { &hf_ansi_637_trans_param_id,
2657 { "Transport Param ID", "ansi_637_trans.param_id",
2658 FT_UINT8, BASE_DEC, VALS(ansi_trans_param_strings), 0,
2659 NULL, HFILL }
2661 { &hf_ansi_637_trans_length,
2662 { "Length", "ansi_637_trans.len",
2663 FT_UINT8, BASE_DEC, NULL, 0,
2664 NULL, HFILL }
2666 { &hf_ansi_637_trans_bin_addr,
2667 { "Binary Address", "ansi_637_trans.bin_addr",
2668 FT_BYTES, BASE_NONE, NULL, 0,
2669 NULL, HFILL }
2671 { &hf_ansi_637_trans_tele_id,
2672 { "Teleservice ID", "ansi_637_trans.tele_id",
2673 FT_UINT16, BASE_DEC, NULL, 0,
2674 NULL, HFILL }
2676 { &hf_ansi_637_trans_srvc_cat,
2677 { "Service Category", "ansi_637_trans.srvc_cat",
2678 FT_UINT16, BASE_DEC, NULL, 0,
2679 NULL, HFILL }
2681 { &hf_ansi_637_trans_addr_param_digit_mode,
2682 { "Digit Mode", "ansi_637_trans.addr_param.digit_mode",
2683 FT_BOOLEAN, 8, TFS(&tfs_digit_mode_8bit_4bit), 0x80,
2684 NULL, HFILL }
2686 { &hf_ansi_637_trans_addr_param_number_mode,
2687 { "Number Mode", "ansi_637_trans.addr_param.number_mode",
2688 FT_BOOLEAN, 8, TFS(&tfs_number_mode_data_ansi_t1), 0x40,
2689 NULL, HFILL }
2691 { &hf_ansi_637_trans_addr_param_ton,
2692 { "Type of Number", "ansi_637_trans.addr_param.ton",
2693 FT_UINT8, BASE_DEC, NULL, 0x38,
2694 NULL, HFILL }
2696 { &hf_ansi_637_trans_addr_param_plan,
2697 { "Numbering Plan", "ansi_637_trans.addr_param.plan",
2698 FT_UINT16, BASE_DEC, VALS(ansi_a_ms_info_rec_num_plan_vals), 0x0780,
2699 NULL, HFILL }
2701 { &hf_ansi_637_trans_addr_param_num_fields,
2702 { "Number of fields", "ansi_637_trans.addr_param.num_fields",
2703 FT_UINT8, BASE_DEC, NULL, 0x0,
2704 NULL, HFILL }
2706 { &hf_ansi_637_trans_addr_param_number,
2707 { "Number", "ansi_637_trans.addr_param.number",
2708 FT_STRING, BASE_NONE, NULL, 0,
2709 NULL, HFILL }
2711 { &hf_ansi_637_trans_subaddr_type,
2712 { "Type", "ansi_637_trans.subaddr.type",
2713 FT_UINT16, BASE_DEC, NULL, 0xe000,
2714 NULL, HFILL }
2716 { &hf_ansi_637_trans_subaddr_odd_even_ind,
2717 { "Odd/Even Indicator", "ansi_637_trans.subaddr.odd_even_ind",
2718 FT_UINT16, BASE_DEC, VALS(ansi_trans_subaddr_odd_even_ind_strings), 0x1000,
2719 NULL, HFILL }
2721 { &hf_ansi_637_trans_subaddr_num_fields,
2722 { "Number of fields", "ansi_637_trans.subaddr.num_fields",
2723 FT_UINT16, BASE_DEC, NULL, 0x0ff0,
2724 NULL, HFILL }
2726 { &hf_ansi_637_trans_bearer_reply_seq_num,
2727 { "Reply Sequence Number", "ansi_637_trans.bearer_reply.seq_num",
2728 FT_UINT8, BASE_DEC, NULL, 0xfc,
2729 NULL, HFILL }
2731 { &hf_ansi_637_trans_cause_codes_seq_num,
2732 { "Reply Sequence Number", "ansi_637_trans.cause_codes.seq_num",
2733 FT_UINT8, BASE_DEC, NULL, 0xfc,
2734 NULL, HFILL }
2736 { &hf_ansi_637_trans_cause_codes_error_class,
2737 { "Error Class", "ansi_637_trans.cause_codes.error_class",
2738 FT_UINT8, BASE_DEC, VALS(trans_param_cause_codes_error_class_strings), 0x03,
2739 NULL, HFILL }
2741 { &hf_ansi_637_trans_cause_codes_code,
2742 { "Cause Code", "ansi_637_trans.cause_codes.code",
2743 FT_UINT8, BASE_DEC, NULL, 0,
2744 NULL, HFILL }
2748 static hf_register_info hf_tele[] = {
2749 { &hf_ansi_637_tele_msg_type,
2750 { "Message Type",
2751 "ansi_637_tele.msg_type",
2752 FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_type_strings), 0xf00000,
2753 NULL, HFILL }
2755 { &hf_ansi_637_tele_msg_id,
2756 { "Message ID",
2757 "ansi_637_tele.msg_id",
2758 FT_UINT24, BASE_DEC, NULL, 0x0ffff0,
2759 NULL, HFILL }
2761 { &hf_ansi_637_tele_length,
2762 { "Length", "ansi_637_tele.len",
2763 FT_UINT8, BASE_DEC, NULL, 0,
2764 NULL, HFILL }
2766 { &hf_ansi_637_tele_msg_status,
2767 { "Message Status",
2768 "ansi_637_tele.msg_status",
2769 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ansi_tele_msg_status_strings_ext, 0,
2770 NULL, HFILL }
2772 { &hf_ansi_637_tele_msg_header_ind,
2773 { "Header Indicator",
2774 "ansi_637_tele.msg_header_ind",
2775 FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_header_ind_strings), 0x000008,
2776 NULL, HFILL }
2778 { &hf_ansi_637_tele_msg_rsvd,
2779 { "Reserved",
2780 "ansi_637_tele.msg_rsvd",
2781 FT_UINT24, BASE_DEC, NULL, 0x000007,
2782 NULL, HFILL }
2784 { &hf_ansi_637_tele_subparam_id,
2785 { "Teleservice Subparam ID", "ansi_637_tele.subparam_id",
2786 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ansi_tele_param_strings_ext, 0,
2787 NULL, HFILL }
2789 { &hf_ansi_637_tele_user_data_text,
2790 { "Encoded user data", "ansi_637_tele.user_data.text",
2791 FT_STRING, BASE_NONE, NULL, 0,
2792 NULL, HFILL }
2794 { &hf_ansi_637_tele_user_data_encoding,
2795 { "Encoding", "ansi_637_tele.user_data.encoding",
2796 FT_UINT16, BASE_DEC, NULL, 0xf800,
2797 NULL, HFILL }
2799 { &hf_ansi_637_tele_user_data_message_type,
2800 { "Message Type (see TIA/EIA/IS-91)", "ansi_637_tele.user_data.message_type",
2801 FT_UINT16, BASE_DEC, NULL, 0x07f8,
2802 NULL, HFILL }
2804 { &hf_ansi_637_tele_user_data_num_fields,
2805 { "Number of fields", "ansi_637_tele.user_data.num_fields",
2806 FT_UINT16, BASE_DEC, NULL, 0x07f8,
2807 NULL, HFILL }
2809 { &hf_ansi_637_tele_response_code,
2810 { "Response Code", "ansi_637_tele.response_code",
2811 FT_UINT8, BASE_DEC, NULL, 0,
2812 NULL, HFILL }
2814 { &hf_ansi_637_tele_message_center_ts_year,
2815 { "Timestamp (Year)", "ansi_637_tele.message_center_ts.year",
2816 FT_UINT8, BASE_DEC, NULL, 0,
2817 NULL, HFILL }
2819 { &hf_ansi_637_tele_message_center_ts_month,
2820 { "Timestamp (Month)", "ansi_637_tele.message_center_ts.month",
2821 FT_UINT8, BASE_DEC, NULL, 0,
2822 NULL, HFILL }
2824 { &hf_ansi_637_tele_message_center_ts_day,
2825 { "Timestamp (Day)", "ansi_637_tele.message_center_ts.day",
2826 FT_UINT8, BASE_DEC, NULL, 0,
2827 NULL, HFILL }
2829 { &hf_ansi_637_tele_message_center_ts_hours,
2830 { "Timestamp (Hours)", "ansi_637_tele.message_center_ts.hours",
2831 FT_UINT8, BASE_DEC, NULL, 0,
2832 NULL, HFILL }
2834 { &hf_ansi_637_tele_message_center_ts_minutes,
2835 { "Timestamp (Minutes)", "ansi_637_tele.message_center_ts.minutes",
2836 FT_UINT8, BASE_DEC, NULL, 0,
2837 NULL, HFILL }
2839 { &hf_ansi_637_tele_message_center_ts_seconds,
2840 { "Timestamp (Seconds)", "ansi_637_tele.message_center_ts.seconds",
2841 FT_UINT8, BASE_DEC, NULL, 0,
2842 NULL, HFILL }
2844 { &hf_ansi_637_tele_validity_period_ts_year,
2845 { "Timestamp (Year)", "ansi_637_tele.validity_period_ts.year",
2846 FT_UINT8, BASE_DEC, NULL, 0,
2847 NULL, HFILL }
2849 { &hf_ansi_637_tele_validity_period_ts_month,
2850 { "Timestamp (Month)", "ansi_637_tele.validity_period_ts.month",
2851 FT_UINT8, BASE_DEC, NULL, 0,
2852 NULL, HFILL }
2854 { &hf_ansi_637_tele_validity_period_ts_day,
2855 { "Timestamp (Day)", "ansi_637_tele.validity_period_ts.day",
2856 FT_UINT8, BASE_DEC, NULL, 0,
2857 NULL, HFILL }
2859 { &hf_ansi_637_tele_validity_period_ts_hours,
2860 { "Timestamp (Hours)", "ansi_637_tele.validity_period_ts.hours",
2861 FT_UINT8, BASE_DEC, NULL, 0,
2862 NULL, HFILL }
2864 { &hf_ansi_637_tele_validity_period_ts_minutes,
2865 { "Timestamp (Minutes)", "ansi_637_tele.validity_period_ts.minutes",
2866 FT_UINT8, BASE_DEC, NULL, 0,
2867 NULL, HFILL }
2869 { &hf_ansi_637_tele_validity_period_ts_seconds,
2870 { "Timestamp (Seconds)", "ansi_637_tele.validity_period_ts.seconds",
2871 FT_UINT8, BASE_DEC, NULL, 0,
2872 NULL, HFILL }
2874 { &hf_ansi_637_tele_validity_period_relative_validity,
2875 { "Validity", "ansi_637_tele.validity_period_relative.validity",
2876 FT_UINT8, BASE_DEC, NULL, 0,
2877 NULL, HFILL }
2879 { &hf_ansi_637_tele_deferred_del_ts_year,
2880 { "Timestamp (Year)", "ansi_637_tele.deferred_del_ts.year",
2881 FT_UINT8, BASE_DEC, NULL, 0,
2882 NULL, HFILL }
2884 { &hf_ansi_637_tele_deferred_del_ts_month,
2885 { "Timestamp (Month)", "ansi_637_tele.deferred_del_ts.month",
2886 FT_UINT8, BASE_DEC, NULL, 0,
2887 NULL, HFILL }
2889 { &hf_ansi_637_tele_deferred_del_ts_day,
2890 { "Timestamp (Day)", "ansi_637_tele.deferred_del_ts.day",
2891 FT_UINT8, BASE_DEC, NULL, 0,
2892 NULL, HFILL }
2894 { &hf_ansi_637_tele_deferred_del_ts_hours,
2895 { "Timestamp (Hours)", "ansi_637_tele.deferred_del_ts.hours",
2896 FT_UINT8, BASE_DEC, NULL, 0,
2897 NULL, HFILL }
2899 { &hf_ansi_637_tele_deferred_del_ts_minutes,
2900 { "Timestamp (Minutes)", "ansi_637_tele.deferred_del_ts.minutes",
2901 FT_UINT8, BASE_DEC, NULL, 0,
2902 NULL, HFILL }
2904 { &hf_ansi_637_tele_deferred_del_ts_seconds,
2905 { "Timestamp (Seconds)", "ansi_637_tele.deferred_del_ts.seconds",
2906 FT_UINT8, BASE_DEC, NULL, 0,
2907 NULL, HFILL }
2909 { &hf_ansi_637_tele_deferred_del_relative,
2910 { "Delivery Time", "ansi_637_tele.deferred_del.relative",
2911 FT_UINT8, BASE_DEC, NULL, 0,
2912 NULL, HFILL }
2914 { &hf_ansi_637_tele_priority_indicator,
2915 { "Priority", "ansi_637_tele.priority_indicator",
2916 FT_UINT8, BASE_DEC, VALS(tele_param_priority_ind_strings), 0xc0,
2917 NULL, HFILL }
2919 { &hf_ansi_637_tele_privacy_indicator,
2920 { "Privacy", "ansi_637_tele.privacy_indicator",
2921 FT_UINT8, BASE_DEC, VALS(tele_param_privacy_ind_strings), 0xc0,
2922 NULL, HFILL }
2924 { &hf_ansi_637_tele_reply_option_user_ack_req,
2925 { "User Acknowledgement Requested", "ansi_637_tele.reply_option.user_ack_req",
2926 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
2927 NULL, HFILL }
2929 { &hf_ansi_637_tele_reply_option_dak_req,
2930 { "Delivery Acknowledgement Requested", "ansi_637_tele.reply_option.dak_req",
2931 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
2932 NULL, HFILL }
2934 { &hf_ansi_637_tele_reply_option_read_ack_req,
2935 { "Read Acknowledgement Requested", "ansi_637_tele.reply_option.read_ack_req",
2936 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
2937 NULL, HFILL }
2939 { &hf_ansi_637_tele_reply_option_report_req,
2940 { "Delivery/Submit Report Requested", "ansi_637_tele.reply_option.report_req",
2941 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
2942 NULL, HFILL }
2944 { &hf_ansi_637_tele_num_messages,
2945 { "Number of voice mail messages", "ansi_637_tele.num_messages.count",
2946 FT_UINT8, BASE_DEC, NULL, 0,
2947 NULL, HFILL }
2949 { &hf_ansi_637_tele_alert_msg_delivery_priority,
2950 { "Privacy", "ansi_637_tele.alert_msg_delivery.priority",
2951 FT_UINT8, BASE_DEC, VALS(tele_param_alert_priority_strings), 0xc0,
2952 NULL, HFILL }
2954 { &hf_ansi_637_tele_language,
2955 { "Language", "ansi_637_tele.language",
2956 FT_UINT8, BASE_DEC, NULL, 0,
2957 NULL, HFILL }
2959 { &hf_ansi_637_tele_cb_num_digit_mode,
2960 { "Digit Mode", "ansi_637_tele.cb_num.digit_mode",
2961 FT_BOOLEAN, 8, TFS(&tfs_digit_mode_8bit_4bit), 0x80,
2962 NULL, HFILL }
2964 { &hf_ansi_637_tele_cb_num_ton,
2965 { "Type of Number", "ansi_637_tele.cb_num.ton",
2966 FT_UINT8, BASE_DEC, VALS(ansi_a_ms_info_rec_num_type_vals), 0x70,
2967 NULL, HFILL }
2969 { &hf_ansi_637_tele_cb_num_plan,
2970 { "Numbering Plan", "ansi_637_tele.cb_num.plan",
2971 FT_UINT8, BASE_DEC, VALS(ansi_a_ms_info_rec_num_plan_vals), 0x0f,
2972 NULL, HFILL }
2974 { &hf_ansi_637_tele_cb_num_num_fields,
2975 { "Number of fields", "ansi_637_tele.cb_num.num_fields",
2976 FT_UINT8, BASE_DEC, NULL, 0,
2977 NULL, HFILL }
2979 { &hf_ansi_637_tele_cb_num_num_fields07f8,
2980 { "Number of fields", "ansi_637_tele.cb_num.num_fields",
2981 FT_UINT16, BASE_DEC, NULL, 0x07F8,
2982 NULL, HFILL }
2984 { &hf_ansi_637_tele_cb_num_number,
2985 { "Call-Back Number", "ansi_637_tele.cb_num.number",
2986 FT_STRING, BASE_NONE, NULL, 0,
2987 NULL, HFILL }
2989 { &hf_ansi_637_tele_msg_display_mode,
2990 { "Message Display Mode", "ansi_637_tele.msg_display_mode",
2991 FT_UINT8, BASE_DEC, VALS(tele_param_msg_display_mode_strings), 0xc0,
2992 NULL, HFILL }
2994 { &hf_ansi_637_tele_msg_deposit_idx,
2995 { "Message Deposit Index", "ansi_637_tele.msg_deposit_idx",
2996 FT_UINT16, BASE_DEC, NULL, 0,
2997 NULL, HFILL }
2999 { &hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat,
3000 { "Service Category", "ansi_637_tele.srvc_cat_prog_results.srvc_cat",
3001 FT_UINT16, BASE_DEC, NULL, 0,
3002 NULL, HFILL }
3004 { &hf_ansi_637_tele_srvc_cat_prog_results_result,
3005 { "Programming Result", "ansi_637_tele.srvc_cat_prog_results.result",
3006 FT_UINT8, BASE_DEC, VALS(tele_param_srvc_cat_prog_results_result_strings), 0xf0,
3007 NULL, HFILL }
3009 { &hf_ansi_637_tele_msg_status_error_class,
3010 { "Error Class", "ansi_637_tele.msg_status.error_class",
3011 FT_UINT8, BASE_DEC, VALS(tele_param_msg_status_error_class_strings), 0xc0,
3012 NULL, HFILL }
3014 { &hf_ansi_637_tele_msg_status_code,
3015 { "Message Status Code", "ansi_637_tele.msg_status.code",
3016 FT_UINT8, BASE_DEC, NULL, 0x3f,
3017 NULL, HFILL }
3019 { &hf_ansi_637_tele_tp_failure_cause_value,
3020 { "GSM SMS TP-Failure Cause", "ansi_637_tele.tp_failure_cause.value",
3021 FT_UINT8, BASE_DEC, NULL, 0,
3022 NULL, HFILL }
3024 { &hf_ansi_637_reserved_bits_8_generic,
3025 { "Reserved bit(s)", "ansi_637_tele.reserved",
3026 FT_UINT8, BASE_DEC, NULL, 0,
3027 NULL, HFILL }
3029 { &hf_ansi_637_reserved_bits_8_03,
3030 { "Reserved bit(s)", "ansi_637_tele.reserved",
3031 FT_UINT8, BASE_DEC, NULL, 0x03,
3032 NULL, HFILL }
3034 { &hf_ansi_637_reserved_bits_8_07,
3035 { "Reserved bit(s)", "ansi_637_tele.reserved",
3036 FT_UINT8, BASE_DEC, NULL, 0x07,
3037 NULL, HFILL }
3039 { &hf_ansi_637_reserved_bits_8_0f,
3040 { "Reserved bit(s)", "ansi_637_tele.reserved",
3041 FT_UINT8, BASE_DEC, NULL, 0x0f,
3042 NULL, HFILL }
3044 { &hf_ansi_637_reserved_bits_8_3f,
3045 { "Reserved bit(s)", "ansi_637_tele.reserved",
3046 FT_UINT8, BASE_DEC, NULL, 0x3f,
3047 NULL, HFILL }
3049 { &hf_ansi_637_reserved_bits_8_7f,
3050 { "Reserved bit(s)", "ansi_637_tele.reserved",
3051 FT_UINT8, BASE_DEC, NULL, 0x7f,
3052 NULL, HFILL }
3054 { &hf_ansi_637_reserved_bits_16_generic,
3055 { "Reserved bit(s)", "ansi_637_tele.reserved",
3056 FT_UINT16, BASE_DEC, NULL, 0,
3057 NULL, HFILL }
3059 { &hf_ansi_637_tele_cmas_encoding,
3060 { "Encoding", "ansi_637_tele.cmas.encoding",
3061 FT_UINT16, BASE_DEC, NULL, 0xf800,
3062 NULL, HFILL }
3064 { &hf_ansi_637_tele_cmas_num_fields,
3065 { "Number of fields", "ansi_637_tele.cmas.num_fields",
3066 FT_UINT16, BASE_DEC, NULL, 0x07f8,
3067 NULL, HFILL }
3069 { &hf_ansi_637_tele_cmas_protocol_version,
3070 { "CMAE_protocol_version", "ansi_637_tele.cmas.protocol_version",
3071 FT_UINT8, BASE_DEC, NULL, 0,
3072 NULL, HFILL }
3074 { &hf_ansi_637_tele_cmas_record_type,
3075 { "E_RECORD_TYPE", "ansi_637_tele.cmas.record_type",
3076 FT_UINT8, BASE_DEC, NULL, 0,
3077 NULL, HFILL }
3079 { &hf_ansi_637_tele_cmas_record_len,
3080 { "E_RECORD_LENGTH", "ansi_637_tele.cmas.record_len",
3081 FT_UINT8, BASE_DEC, NULL, 0,
3082 NULL, HFILL }
3084 { &hf_ansi_637_tele_cmas_char_set,
3085 { "CMAE_char_set", "ansi_637_tele.cmas.char_set",
3086 FT_UINT8, BASE_DEC, NULL, 0,
3087 NULL, HFILL }
3089 { &hf_ansi_637_tele_cmas_category,
3090 { "CMAE_category", "ansi_637_tele.cmas.category",
3091 FT_UINT8, BASE_DEC, NULL, 0,
3092 NULL, HFILL }
3094 { &hf_ansi_637_tele_cmas_response_type,
3095 { "CMAE_response_type", "ansi_637_tele.cmas.response_type",
3096 FT_UINT8, BASE_DEC, NULL, 0,
3097 NULL, HFILL }
3099 { &hf_ansi_637_tele_cmas_severity,
3100 { "CMAE_severity", "ansi_637_tele.cmas.severity",
3101 FT_UINT8, BASE_DEC, NULL, 0xf0,
3102 NULL, HFILL }
3104 { &hf_ansi_637_tele_cmas_urgency,
3105 { "CMAE_urgency", "ansi_637_tele.cmas.urgency",
3106 FT_UINT8, BASE_DEC, NULL, 0x0f,
3107 NULL, HFILL }
3109 { &hf_ansi_637_tele_cmas_certainty,
3110 { "CMAE_certainty", "ansi_637_tele.cmas.certainty",
3111 FT_UINT8, BASE_DEC, NULL, 0xf0,
3112 NULL, HFILL }
3114 { &hf_ansi_637_tele_cmas_identifier,
3115 { "CMAE_identifier", "ansi_637_tele.cmas.identifier",
3116 FT_UINT16, BASE_DEC, NULL, 0,
3117 NULL, HFILL }
3119 { &hf_ansi_637_tele_cmas_alert_handling,
3120 { "CMAE_alert_handling", "ansi_637_tele.cmas.alert_handling",
3121 FT_UINT8, BASE_DEC, NULL, 0,
3122 NULL, HFILL }
3124 { &hf_ansi_637_tele_cmas_expires_year,
3125 { "CMAE_expires (Year)", "ansi_637_tele.cmas.expires.year",
3126 FT_UINT8, BASE_DEC, NULL, 0,
3127 NULL, HFILL }
3129 { &hf_ansi_637_tele_cmas_expires_month,
3130 { "CMAE_expires (Month)", "ansi_637_tele.cmas.expires.month",
3131 FT_UINT8, BASE_DEC, NULL, 0,
3132 NULL, HFILL }
3134 { &hf_ansi_637_tele_cmas_expires_day,
3135 { "CMAE_expires (Day)", "ansi_637_tele.cmas.expires.day",
3136 FT_UINT8, BASE_DEC, NULL, 0,
3137 NULL, HFILL }
3139 { &hf_ansi_637_tele_cmas_expires_hours,
3140 { "CMAE_expires (Hours)", "ansi_637_tele.cmas.expires.hours",
3141 FT_UINT8, BASE_DEC, NULL, 0,
3142 NULL, HFILL }
3144 { &hf_ansi_637_tele_cmas_expires_minutes,
3145 { "CMAE_expires (Minutes)", "ansi_637_tele.cmas.expires.minutes",
3146 FT_UINT8, BASE_DEC, NULL, 0,
3147 NULL, HFILL }
3149 { &hf_ansi_637_tele_cmas_expires_seconds,
3150 { "CMAE_expires (Seconds)", "ansi_637_tele.cmas.expires.seconds",
3151 FT_UINT8, BASE_DEC, NULL, 0,
3152 NULL, HFILL }
3154 { &hf_ansi_637_tele_cmas_language,
3155 { "CMAE_language", "ansi_637_tele.cmas.language",
3156 FT_UINT8, BASE_DEC, NULL, 0,
3157 NULL, HFILL }
3159 { &hf_ansi_637_tele_cmas_text,
3160 { "CMAE_alert_text", "ansi_637_tele.cmas.text",
3161 FT_STRING, BASE_NONE, NULL, 0,
3162 NULL, HFILL }
3164 { &hf_ansi_637_tele_mult_enc_user_data_encoding,
3165 { "Encoding", "ansi_637_tele.mult_enc_user_data.encoding",
3166 FT_UINT8, BASE_DEC, VALS(ansi_tsb58_encoding_vals), 0,
3167 NULL, HFILL }
3169 { &hf_ansi_637_tele_mult_enc_user_data_num_fields,
3170 { "Number of fields", "ansi_637_tele.mult_enc_user_data.num_fields",
3171 FT_UINT8, BASE_DEC, NULL, 0,
3172 NULL, HFILL }
3174 { &hf_ansi_637_tele_mult_enc_user_data_text,
3175 { "Encoded user data", "ansi_637_tele.mult_enc_user_data.text",
3176 FT_STRING, BASE_NONE, NULL, 0,
3177 NULL, HFILL }
3179 { &hf_ansi_637_tele_srvc_cat_prog_data_encoding,
3180 { "Encoding", "ansi_637_tele.srvc_cat_prog_data.encoding",
3181 FT_UINT8, BASE_DEC, VALS(ansi_tsb58_encoding_vals), 0,
3182 NULL, HFILL }
3184 { &hf_ansi_637_tele_srvc_cat_prog_data_operation_code,
3185 { "Operation code", "ansi_637_tele.srvc_cat_prog_data.operation_code",
3186 FT_UINT8, BASE_DEC, VALS(tele_param_srvc_cat_prog_data_op_code_vals), 0,
3187 NULL, HFILL }
3189 { &hf_ansi_637_tele_srvc_cat_prog_data_category,
3190 { "Operation code", "ansi_637_tele.srvc_cat_prog_data.category",
3191 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ansi_tsb58_srvc_cat_vals_ext, 0,
3192 NULL, HFILL }
3194 { &hf_ansi_637_tele_srvc_cat_prog_data_language,
3195 { "Operation code", "ansi_637_tele.srvc_cat_prog_data.language",
3196 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &ansi_tsb58_language_ind_vals_ext, 0,
3197 NULL, HFILL }
3199 { &hf_ansi_637_tele_srvc_cat_prog_data_max_messages,
3200 { "Maximum number of messages", "ansi_637_tele.srvc_cat_prog_data.max_messages",
3201 FT_UINT8, BASE_DEC, NULL, 0,
3202 NULL, HFILL }
3204 { &hf_ansi_637_tele_srvc_cat_prog_data_alert_option,
3205 { "Alert option", "ansi_637_tele.srvc_cat_prog_data.alert_option",
3206 FT_UINT8, BASE_DEC, VALS(tele_param_srvc_cat_prog_data_alert_option_vals), 0,
3207 NULL, HFILL }
3209 { &hf_ansi_637_tele_srvc_cat_prog_data_num_fields,
3210 { "Number of fields", "ansi_637_tele.srvc_cat_prog_data.num_fields",
3211 FT_UINT8, BASE_DEC, NULL, 0,
3212 NULL, HFILL }
3214 { &hf_ansi_637_tele_srvc_cat_prog_data_text,
3215 { "Encoded program data", "ansi_637_tele.srvc_cat_prog_data.text",
3216 FT_STRING, BASE_NONE, NULL, 0,
3217 NULL, HFILL }
3221 static ei_register_info ei[] = {
3222 { &ei_ansi_637_extraneous_data,
3223 { "ansi_637.extraneous_data", PI_PROTOCOL, PI_NOTE,
3224 "Extraneous Data - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
3225 EXPFILL }
3227 { &ei_ansi_637_short_data,
3228 { "ansi_637.short_data", PI_PROTOCOL, PI_NOTE,
3229 "Short Data (?) - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
3230 EXPFILL }
3232 { &ei_ansi_637_unexpected_length,
3233 { "ansi_637.unexpected_length", PI_PROTOCOL, PI_WARN,
3234 "Unexpected Data Length - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
3235 EXPFILL }
3237 { &ei_ansi_637_unknown_encoding,
3238 { "ansi_637.unknown_format", PI_PROTOCOL, PI_NOTE,
3239 "Encoding Unknown/Unsupported - (report to wireshark.org)",
3240 EXPFILL }
3242 { &ei_ansi_637_failed_conversion,
3243 { "ansi_637.failed_conversion", PI_PROTOCOL, PI_WARN,
3244 "Failed iconv conversion - (report to wireshark.org)",
3245 EXPFILL }
3247 { &ei_ansi_637_unknown_cmas_record_type,
3248 { "ansi_637.unknown_cmas_record_type", PI_PROTOCOL, PI_WARN,
3249 "Unknown CMAS record type - (report to wireshark.org)",
3250 EXPFILL }
3252 { &ei_ansi_637_unknown_trans_parameter,
3253 { "ansi_637.unknown_trans_parameter", PI_PROTOCOL, PI_WARN,
3254 "Unknown transport layer parameter - (report to wireshark.org)",
3255 EXPFILL }
3257 { &ei_ansi_637_no_trans_parameter_dissector,
3258 { "ansi_637.no_trans_parameter_dissector", PI_PROTOCOL, PI_WARN,
3259 "No transport layer parameter dissector - (report to wireshark.org)",
3260 EXPFILL }
3262 { &ei_ansi_637_unknown_tele_parameter,
3263 { "ansi_637.unknown_tele_parameter", PI_PROTOCOL, PI_WARN,
3264 "Unknown teleservice layer parameter - (report to wireshark.org)",
3265 EXPFILL }
3267 { &ei_ansi_637_no_tele_parameter_dissector,
3268 { "ansi_637.no_tele_parameter_dissector", PI_PROTOCOL, PI_WARN,
3269 "No teleservice layer parameter dissector - (report to wireshark.org)",
3270 EXPFILL }
3274 expert_module_t *expert_ansi_637;
3276 /* Setup protocol subtree array */
3277 #define NUM_INDIVIDUAL_PARAMS 4
3278 int *ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM+NUM_CMAS_PARAM];
3280 memset((void *) ett, 0, sizeof(ett));
3282 ett[0] = &ett_ansi_637_tele;
3283 ett[1] = &ett_ansi_637_trans;
3284 ett[2] = &ett_ansi_637_header_ind;
3285 ett[3] = &ett_params;
3287 for (i=0; i < NUM_TELE_PARAM; i++)
3289 ett[NUM_INDIVIDUAL_PARAMS+i] = &ett_ansi_637_tele_param[i];
3292 for (i=0; i < NUM_TRANS_MSG_TYPE; i++)
3294 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+i] = &ett_ansi_637_trans_msg[i];
3297 for (i=0; i < NUM_TRANS_PARAM; i++)
3299 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+i] = &ett_ansi_637_trans_param[i];
3302 for (i=0; i < NUM_CMAS_PARAM; i++)
3304 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM+i] = &ett_tia_1149_cmas_param[i];
3307 /* Register the protocol name and description */
3308 proto_ansi_637_tele =
3309 proto_register_protocol(ansi_proto_name_tele, "ANSI IS-637-A Teleservice", "ansi_637_tele");
3311 proto_ansi_637_trans =
3312 proto_register_protocol(ansi_proto_name_trans, "ANSI IS-637-A Transport", "ansi_637_trans");
3314 ansi_637_tele_handle = register_dissector("ansi_637_tele", dissect_ansi_637_tele, proto_ansi_637_tele);
3315 ansi_637_trans_handle = register_dissector("ansi_637_trans", dissect_ansi_637_trans, proto_ansi_637_trans);
3316 ansi_637_trans_app_handle = register_dissector("ansi_637_trans_app", dissect_ansi_637_trans_app, proto_ansi_637_trans);
3318 /* Required function calls to register the header fields and subtrees used */
3319 proto_register_field_array(proto_ansi_637_tele, hf_tele, array_length(hf_tele));
3320 proto_register_field_array(proto_ansi_637_trans, hf_trans, array_length(hf_trans));
3321 proto_register_subtree_array(ett, array_length(ett));
3323 expert_ansi_637 =
3324 expert_register_protocol(proto_ansi_637_trans);
3325 expert_register_field_array(expert_ansi_637, ei, array_length(ei));
3327 tele_dissector_table =
3328 register_dissector_table("ansi_637.tele_id",
3329 "ANSI IS-637-A Teleservice ID", proto_ansi_637_tele, FT_UINT8, BASE_DEC);
3333 void
3334 proto_reg_handoff_ansi_637(void)
3336 unsigned i;
3338 /* Dissect messages embedded in SIP */
3339 dissector_add_string("media_type", "application/vnd.3gpp2.sms", ansi_637_trans_app_handle);
3342 * register for all known teleservices
3343 * '-1' is to stop before trailing '0' entry
3345 * to add teleservices, modify 'ansi_tele_id_strings'
3347 for (i = 0; i < array_length(ansi_tele_id_strings) - 1; i++)
3350 * ANSI MAP dissector will push out teleservice ids
3352 dissector_add_uint("ansi_map.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
3355 * we will push out teleservice ids after Transport layer decode
3357 dissector_add_uint("ansi_637.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
3361 * internal implementation add this pseudo teleservice ID for handling broadcast SMS
3362 * (which don't have teleservice IDs)
3364 dissector_add_uint("ansi_map.tele_id", INTERNAL_BROADCAST_TELE_ID, ansi_637_tele_handle);
3365 dissector_add_uint("ansi_637.tele_id", INTERNAL_BROADCAST_TELE_ID, ansi_637_tele_handle);
3368 * ANSI A-interface will push out transport layer data
3370 dissector_add_uint("ansi_a.sms", 0, ansi_637_trans_handle);
3374 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3376 * Local variables:
3377 * c-basic-offset: 4
3378 * tab-width: 8
3379 * indent-tabs-mode: nil
3380 * End:
3382 * vi: set shiftwidth=4 tabstop=8 expandtab:
3383 * :indentSize=4:tabSize=8:noTabs=true: