2 * Routines for ANSI IS-637-A (SMS) dissection
4 * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
5 * In association with Telos Technology Inc.
9 * Short Message Service
10 * 3GPP2 C.S0015-0 TIA/EIA-637-A
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
16 * Copyright 1998 Gerald Combs
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 #ifdef HAVE_SYS_TYPES_H
38 # include <sys/types.h>
41 #ifdef HAVE_NETINET_IN_H
42 # include <netinet/in.h>
45 #include <epan/packet.h>
46 #include <epan/emem.h>
47 #include <epan/strutil.h>
50 static const char *ansi_proto_name_tele = "ANSI IS-637-A (SMS) Teleservice Layer";
51 static const char *ansi_proto_name_trans = "ANSI IS-637-A (SMS) Transport Layer";
52 static const char *ansi_proto_name_short = "IS-637-A";
54 static const value_string ansi_srvc_cat_strings[] = {
55 { 0x0000, "Unknown or unspecified" },
56 { 0x0001, "Emergency Broadcasts" },
57 { 0x0002, "Administrative" },
58 { 0x0003, "Maintenance" },
59 { 0x0004, "General News - Local" },
60 { 0x0005, "General News - Regional" },
61 { 0x0006, "General News - National" },
62 { 0x0007, "General News - International" },
63 { 0x0008, "Business/Financial News - Local" },
64 { 0x0009, "Business/Financial News - Regional" },
65 { 0x000A, "Business/Financial News - National" },
66 { 0x000B, "Business/Financial News - International" },
67 { 0x000C, "Sports News - Local" },
68 { 0x000D, "Sports News - Regional" },
69 { 0x000E, "Sports News - National" },
70 { 0x000F, "Sports News - International" },
71 { 0x0010, "Entertainment News - Local" },
72 { 0x0011, "Entertainment News - Regional" },
73 { 0x0012, "Entertainment News - National" },
74 { 0x0013, "Entertainment News - International" },
75 { 0x0014, "Local Weather" },
76 { 0x0015, "Area Traffic Reports" },
77 { 0x0016, "Local Airport Flight Schedules" },
78 { 0x0017, "Restaurants" },
79 { 0x0018, "Lodgings" },
80 { 0x0019, "Retail Directory" },
81 { 0x001A, "Advertisements" },
82 { 0x001B, "Stock Quotes" },
83 { 0x001C, "Employment Opportunities" },
84 { 0x001D, "Medical/Health/Hospitals" },
85 { 0x001E, "Technology News" },
86 { 0x001F, "Multi-category" },
90 static const value_string ansi_tele_msg_type_strings[] = {
91 { 1, "Deliver (mobile-terminated only)" },
92 { 2, "Submit (mobile-originated only)" },
93 { 3, "Cancellation (mobile-originated only)" },
94 { 4, "Delivery Acknowledgement (mobile-terminated only)" },
95 { 5, "User Acknowledgement (either direction)" },
99 static const value_string ansi_tele_msg_status_strings[] = {
100 {0x00,"Message accepted"},
101 {0x01,"Message deposited to Internet"},
102 {0x02,"Message delivered"},
103 {0x03,"Message cancelled"},
104 {0x84,"Network congestion"},
105 {0x85,"Network error"},
106 {0x9f,"Unknown error"},
107 {0xc4,"Network congestion"},
108 {0xc5,"Network error"},
109 {0xc6,"Cancel failed"},
110 {0xc7,"Blocked destination"},
111 {0xc8,"Text too long"},
112 {0xc9,"Duplicate message"},
113 {0xca,"Invalid destination"},
114 {0xcd,"Message expired"},
115 {0xdf,"Unknown error"},
119 static const value_string ansi_tele_id_strings[] = {
120 { 1, "Reserved for maintenance" },
121 { 4096, "AMPS Extended Protocol Enhanced Services" },
122 { 4097, "CDMA Cellular Paging Teleservice" },
123 { 4098, "CDMA Cellular Messaging Teleservice" },
124 { 4099, "CDMA Voice Mail Notification" },
125 { 4100, "CDMA Wireless Application Protocol (WAP)" },
126 { 4101, "CDMA Wireless Enhanced Messaging Teleservice (WEMT)" },
127 { 65535, "(Reserved) Being used for Broadcast" },
132 static const value_string ansi_tele_param_strings[] = {
133 { 0x00, "Message Identifier" },
134 { 0x01, "User Data" },
135 { 0x02, "User Response Code" },
136 { 0x03, "Message Center Time Stamp" },
137 { 0x04, "Validity Period - Absolute" },
138 { 0x05, "Validity Period - Relative" },
139 { 0x06, "Deferred Delivery Time - Absolute" },
140 { 0x07, "Deferred Delivery Time - Relative" },
141 { 0x08, "Priority Indicator" },
142 { 0x09, "Privacy Indicator" },
143 { 0x0a, "Reply Option" },
144 { 0x0b, "Number of Messages" },
145 { 0x0c, "Alert on Message Delivery" },
146 { 0x0d, "Language Indicator" },
147 { 0x0e, "Call-Back Number" },
148 { 0x0f, "Message Display Mode" },
149 { 0x10, "Multiple Encoding User Data" },
150 { 0x14, "Message Status" },
154 #define ANSI_TRANS_MSG_TYPE_BROADCAST 1
156 static const value_string ansi_trans_msg_type_strings[] = {
157 { 0, "Point-to-Point" },
159 { 2, "Acknowledge" },
163 static const value_string ansi_trans_param_strings[] = {
164 { 0x00, "Teleservice Identifier" },
165 { 0x01, "Service Category" },
166 { 0x02, "Originating Address" },
167 { 0x03, "Originating Subaddress" },
168 { 0x04, "Destination Address" },
169 { 0x05, "Destination Subaddress" },
170 { 0x06, "Bearer Reply Option" },
171 { 0x07, "Cause Codes" },
172 { 0x08, "Bearer Data" },
177 * from Table 2.7.1.3.2.4-4. Representation of DTMF Digits
178 * 3GPP2 C.S0005-C (IS-2000 aka cdma2000)
180 static unsigned char air_digits[] = {
181 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
182 '?','1','2','3','4','5','6','7','8','9','0','*','#','?','?'
185 /* Initialize the protocol and registered fields */
186 static int proto_ansi_637_tele = -1;
187 static int proto_ansi_637_trans = -1;
188 static int hf_ansi_637_tele_length = -1;
189 static int hf_ansi_637_trans_length = -1;
190 static int hf_ansi_637_trans_bin_addr = -1;
191 static int hf_ansi_637_tele_msg_type = -1;
192 static int hf_ansi_637_tele_msg_id = -1;
193 static int hf_ansi_637_tele_msg_status = -1;
194 static int hf_ansi_637_tele_msg_rsvd = -1;
195 static int hf_ansi_637_tele_subparam_id = -1;
196 static int hf_ansi_637_trans_msg_type = -1;
197 static int hf_ansi_637_trans_param_id = -1;
199 /* Initialize the subtree pointers */
200 static gint ett_ansi_637_tele = -1;
201 static gint ett_ansi_637_trans = -1;
202 static gint ett_params = -1;
204 static guint32 ansi_637_trans_tele_id;
205 static char ansi_637_bigbuf[1024];
206 static char gsm_637_bigbuf[1024];
207 static char ia5_637_bigbuf[1024];
208 /* static dissector_handle_t data_handle; */
209 static dissector_table_t tele_dissector_table;
210 static packet_info *g_pinfo;
211 static proto_tree *g_tree;
214 #define GN_CHAR_ALPHABET_SIZE 128
216 #define GN_CHAR_ESCAPE 0x1b
218 static gunichar gsm_default_alphabet[GN_CHAR_ALPHABET_SIZE] = {
220 /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
221 /* Fixed to use unicode */
222 /* Characters in hex position 10, [12 to 1a] and 24 are not present on
223 latin1 charset, so we cannot reproduce on the screen, however they are
224 greek symbol not present even on my Nokia */
226 '@', 0xa3, '$' , 0xa5, 0xe8, 0xe9, 0xf9, 0xec,
227 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
228 0x394, '_', 0x3a6,0x393,0x39b,0x3a9,0x3a0,0x3a8,
229 0x3a3,0x398,0x39e, 0xa0, 0xc6, 0xe6, 0xdf, 0xc9,
230 ' ', '!', '\"', '#', 0xa4, '%', '&', '\'',
231 '(', ')', '*', '+', ',', '-', '.', '/',
232 '0', '1', '2', '3', '4', '5', '6', '7',
233 '8', '9', ':', ';', '<', '=', '>', '?',
234 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
235 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
236 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
237 'X', 'Y', 'Z', 0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
238 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
239 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
240 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
241 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0
247 char_is_escape(unsigned char value)
249 return (value == GN_CHAR_ESCAPE);
253 char_def_alphabet_ext_decode(unsigned char value)
257 case 0x0a: return 0x0c; /* form feed */
258 case 0x14: return '^';
259 case 0x28: return '{';
260 case 0x29: return '}';
261 case 0x2f: return '\\';
262 case 0x3c: return '[';
263 case 0x3d: return '~';
264 case 0x3e: return ']';
265 case 0x40: return '|';
266 case 0x65: return 0x20ac; /* euro */
267 default: return '?'; /* invalid character */
272 char_def_alphabet_decode(unsigned char value)
274 if (value < GN_CHAR_ALPHABET_SIZE)
276 return gsm_default_alphabet[value];
285 gsm_sms_char_7bit_ascii_decode(unsigned char * dest, const unsigned char* src, int len)
291 for (i = 0, j = 0; j < len; j++)
293 if (char_is_escape(src[j])) {
294 buf = char_def_alphabet_ext_decode(src[++j]);
295 i += g_unichar_to_utf8(buf,&(dest[i]));
298 buf = char_def_alphabet_decode(src[j]);
299 i += g_unichar_to_utf8(buf,&(dest[i]));
311 decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oct, guint8 *last_bit, gchar *buf)
313 guint8 oct, oct2, bit;
314 /* guint32 saved_offset; */
323 /* saved_offset = *offset; */
324 oct = oct2 = *last_oct;
329 oct2 = tvb_get_guint8(tvb, *offset);
333 for (i=0; i < num_fields; i++)
340 * cannot grab an octet if we are getting
341 * the last field and bit is 7 or 8
342 * because there may not be another octet
344 if (((i + 1) != num_fields) ||
345 ((bit != 7) && (bit != 8)))
347 oct2 = tvb_get_guint8(tvb, *offset);
355 buf[i] = ((oct & 0x01) << 6) | ((oct2 & 0xfc) >> 2);
359 buf[i] = ((oct & 0x03) << 5) | ((oct2 & 0xf8) >> 3);
363 buf[i] = ((oct & 0x07) << 4) | ((oct2 & 0xf0) >> 4);
367 buf[i] = ((oct & 0x0f) << 3) | ((oct2 & 0xe0) >> 5);
371 buf[i] = ((oct & 0x1f) << 2) | ((oct2 & 0xc0) >> 6);
375 buf[i] = ((oct & 0x3f) << 1) | ((oct2 & 0x80) >> 7);
383 buf[i] = (oct & 0xfe) >> 1;
392 *last_oct = (bit == 1) ? oct : oct2;
396 /* PARAM FUNCTIONS */
398 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
399 if ((edc_len) > (edc_max_len)) \
401 proto_tree_add_text(tree, tvb, offset, \
402 (edc_len) - (edc_max_len), "Extraneous Data"); \
405 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
406 if ((sdc_len) < (sdc_min_len)) \
408 proto_tree_add_text(tree, tvb, offset, \
409 (sdc_len), "Short Data (?)"); \
413 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
414 if ((edc_len) != (edc_eq_len)) \
416 proto_tree_add_text(tree, tvb, offset, \
417 (edc_len), "Unexpected Data Length"); \
422 tele_param_msg_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
426 EXACT_DATA_CHECK(len, 3);
428 octs = tvb_get_ntoh24(tvb, offset);
430 proto_tree_add_uint(tree, hf_ansi_637_tele_msg_type,
431 tvb, offset, 3, octs);
433 proto_tree_add_uint(tree, hf_ansi_637_tele_msg_id,
434 tvb, offset, 3, octs);
436 proto_tree_add_uint(tree, hf_ansi_637_tele_msg_rsvd,
437 tvb, offset, 3, octs);
440 /* Adamek Jan - IS637C Message status decoding procedure */
442 tele_param_msg_status(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
444 /* Declare some variables */
448 guint8 msg_status_code;
449 const gchar *str = NULL;
451 /* Chceck if the exact length */
452 EXACT_DATA_CHECK(len, 1);
454 /* get the status octet? */
456 oct = tvb_get_guint8(tvb, offset);
459 /* error class filter */
460 proto_tree_add_item(tree, hf_ansi_637_tele_msg_status,tvb, offset, 1, FALSE);
462 /*error class filter end */
467 error_class = ((oct & 0xc0) >> 6);
470 case 0x00: str = "No Error";break;
471 case 0x01: str = "Reserved";break;
472 case 0x02: str = "Temporary Condition";break;
473 case 0x03: str = "Permanent Condition";break;
474 default: str = "Reserved";break;
476 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
477 proto_tree_add_text(tree, tvb, offset, 1,
478 "%s : Erorr Class: %s",
484 msg_status_code = (oct & 0x3f);
486 if (error_class == 0x00){
487 switch (msg_status_code)
489 case 0x00: str = "Message accepted";break;
490 case 0x01: str = "Message deposited to internet";break;
491 case 0x02: str = "Message delivered";break;
492 case 0x03: str = "Message cancelled";break;
493 default: str = "Reserved";break;
495 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
496 proto_tree_add_text(tree, tvb, offset, 1,
497 "%s : Message status code: %s",
502 /*error message status */
503 if (error_class == 0x02){
504 switch (msg_status_code)
506 case 0x04: str = "Network congestion";break;
507 case 0x05: str = "Network error";break;
508 case 0x1f: str = "Unknown error";break;
509 default: str = "Reserved";break;
511 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
512 proto_tree_add_text(tree, tvb, offset, 1,
513 "%s : Message status code: %s",
518 if (error_class == 0x03){
519 switch (msg_status_code)
521 case 0x04: str = "Network congestion";break;
522 case 0x05: str = "Network error";break;
523 case 0x06: str = "Cancel failed";break;
524 case 0x07: str = "Blocked destination";break;
525 case 0x08: str = "Text too long";break;
526 case 0x09: str = "Duplicate message";break;
527 case 0x0a: str = "Invalid destination";break;
528 case 0x0d: str = "Message expired";break;
529 case 0x1f: str = "Unknown error";break;
530 default: str = "Reserved";break;
532 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
533 proto_tree_add_text(tree, tvb, offset, 1,
534 "%s : Message status code: %s",
542 tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
550 guint32 required_octs;
551 guint32 saved_offset;
553 const gchar *str = NULL;
555 /*add more translation UCS , IA5 , latin , latin \ hebrew ,gsm 7BIT*/
556 gchar *utf8_text = NULL;
558 GError *l_conv_error = NULL;
560 SHORT_DATA_CHECK(len, 2);
565 oct = tvb_get_guint8(tvb, offset);
570 encoding = ((oct & 0xf8) >> 3);
573 case 0x00: str = "Octet, unspecified"; break;
574 case 0x01: str = "Extended Protocol Message";
575 oct2 = tvb_get_guint8(tvb, offset+1);
576 msg_type = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
578 case 0x02: str = "7-bit ASCII"; break;
579 case 0x03: str = "IA5"; break;
580 case 0x04: str = "UNICODE"; break;
581 case 0x05: str = "Shift-JIS"; break;
582 case 0x06: str = "Korean"; break;
583 case 0x07: str = "Latin/Hebrew"; break;
584 case 0x08: str = "Latin"; break;
585 case 0x09: str = "GSM 7-bit default alphabet"; break;
586 default: str = "Reserved"; break;
589 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
590 proto_tree_add_text(tree, tvb, offset, 1,
595 if (encoding == 0x01)
597 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
598 proto_tree_add_text(tree, tvb, offset, 1,
599 "%s : Message type: see TIA/EIA/IS-91 (%d)",
603 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
604 proto_tree_add_text(tree, tvb, offset+1, 1,
619 oct2 = tvb_get_guint8(tvb, offset);
620 num_fields = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
622 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
623 proto_tree_add_text(tree, tvb, offset-1, 1,
624 "%s : Number of fields (MSB): %d",
628 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
629 proto_tree_add_text(tree, tvb, offset, 1,
630 "%s : Number of fields (LSB)",
633 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
634 proto_tree_add_text(tree, tvb, offset, 1,
635 "%s : Most significant bits of first field",
642 /* NOTE: there are now 3 bits remaining in 'oct' */
644 if (len <= used) return;
647 * decode rest if 7-bit ASCII
649 if (encoding == 0x02)
653 * 3 bits remaining from last octet
657 i = (num_fields * 7) - 3;
658 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
660 if (required_octs + used > len)
662 proto_tree_add_text(tree, tvb, offset, 1,
663 "Missing %d octet(s) for number of fields",
664 (required_octs + used) - len);
670 saved_offset = offset;
672 decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
674 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
675 "Encoded user data: %s",
680 case 1: oct2 = 0x01; break;
681 case 2: oct2 = 0x03; break;
682 case 3: oct2 = 0x07; break;
683 case 4: oct2 = 0x0f; break;
684 case 5: oct2 = 0x1f; break;
685 case 6: oct2 = 0x3f; break;
686 case 7: oct2 = 0x7f; break;
691 other_decode_bitfield_value(ansi_637_bigbuf, oct, oct2, 8);
692 proto_tree_add_text(tree, tvb, offset - 1, 1,
697 else if (encoding == 0x03)/* IA5 */
699 i = (num_fields * 7) - 3;
700 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
702 if (required_octs + used > len)
704 proto_tree_add_text(tree, tvb, offset, 1,
705 "Missing %d octet(s) for number of fields",
706 (required_octs + used) - len);
712 saved_offset = offset;
713 out_len = decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
714 IA5_7BIT_decode(ia5_637_bigbuf, ansi_637_bigbuf, out_len);
716 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
717 "Encoded user data: %s",
720 /*TODO UCS else if (encoding == 0x04)
723 else if (encoding == 0x07)/* Latin/Hebrew */
725 saved_offset = offset - 1;
726 for (i=0; i < num_fields; i++)
728 oct = tvb_get_guint8(tvb, saved_offset);
729 oct2 = tvb_get_guint8(tvb, saved_offset + 1);;
730 ansi_637_bigbuf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
734 if ((cd = g_iconv_open("UTF-8","iso-8859-8")) != (GIConv)-1)
736 utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb, offset, num_fields), num_fields , cd , NULL , NULL , &l_conv_error);
739 proto_tree_add_text(tree, tvb, offset, num_fields, "Encoded user data: %s", utf8_text);
743 proto_tree_add_text(tree, tvb, offset, num_fields, "%s", "Failed on iso-8859-8 contact Wireshark developers");
750 else if (encoding == 0x08) /* Latin */
752 saved_offset = offset - 1;
753 for (i=0; i < num_fields; i++)
755 oct = tvb_get_guint8(tvb, saved_offset);
756 oct2 = tvb_get_guint8(tvb, saved_offset + 1);;
757 ansi_637_bigbuf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
761 if ((cd = g_iconv_open("UTF-8","iso-8859-1")) != (GIConv)-1)
763 utf8_text = g_convert_with_iconv(ansi_637_bigbuf , num_fields , cd , NULL , NULL , &l_conv_error);
766 proto_tree_add_text(tree, tvb, offset, num_fields, "Encoded user data: %s", utf8_text);
770 proto_tree_add_text(tree, tvb, offset, num_fields, "%s", "Failed on iso-8859-1 contact Wireshark developers");
777 else if (encoding == 0x09) /* GSM 7-bit default alphabet */
779 i = (num_fields * 7) - 3;
780 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
782 if (required_octs + used > len)
784 proto_tree_add_text(tree, tvb, offset, 1,
785 "Missing %d octet(s) for number of fields",
786 (required_octs + used) - len);
792 saved_offset = offset;
793 out_len = decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
794 gsm_sms_char_7bit_ascii_decode(gsm_637_bigbuf, ansi_637_bigbuf, out_len);
796 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
797 "Encoded user data: %s",
804 proto_tree_add_text(tree, tvb, offset, len - used,
805 "Encoded user data");
810 tele_param_rsp_code(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
814 EXACT_DATA_CHECK(len, 1);
819 oct = tvb_get_guint8(tvb, offset);
821 proto_tree_add_text(tree, tvb, offset, 1,
827 tele_param_timestamp(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
829 guint8 oct, oct2, oct3;
831 EXACT_DATA_CHECK(len, 6);
833 oct = tvb_get_guint8(tvb, offset);
834 oct2 = tvb_get_guint8(tvb, offset+1);
835 oct3 = tvb_get_guint8(tvb, offset+2);
837 proto_tree_add_text(tree, tvb, offset, 3,
838 "Year %d%d, Month %d%d, Day %d%d",
848 oct = tvb_get_guint8(tvb, offset);
849 oct2 = tvb_get_guint8(tvb, offset+1);
850 oct3 = tvb_get_guint8(tvb, offset+2);
852 proto_tree_add_text(tree, tvb, offset, 3,
853 "Hour %d%d, Minutes %d%d, Seconds %d%d",
863 tele_param_rel_timestamp(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
867 const gchar *str = NULL;
868 const gchar *str2 = NULL;
870 EXACT_DATA_CHECK(len, 1);
872 oct = tvb_get_guint8(tvb, offset);
876 case 245: str = "Indefinite"; break;
877 case 246: str = "Immediate"; break;
878 case 247: str = "Valid until mobile becomes inactive/Deliver when mobile next becomes active"; break;
879 case 248: str = "Valid until registration area changes, discard if not registered" ; break;
881 if (oct <= 143) { value = (oct + 1) * 5; str2 = "Minutes"; break; }
882 else if ((oct >= 144) && (oct <= 167)) { value = (oct - 143) * 30; str2 = "Minutes + 12 Hours"; break; }
883 else if ((oct >= 168) && (oct <= 196)) { value = oct - 166; str2 = "Days"; break; }
884 else if ((oct >= 197) && (oct <= 244)) { value = oct - 192; str2 = "Weeks"; break; }
885 else { str = "Reserved"; break; }
890 proto_tree_add_text(tree, tvb, offset, 1,
895 proto_tree_add_text(tree, tvb, offset, 1,
901 static const value_string tele_param_pri_ind_strings[] = {
903 { 1, "Interactive" },
910 tele_param_pri_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
913 const gchar *str = NULL;
915 EXACT_DATA_CHECK(len, 1);
917 oct = tvb_get_guint8(tvb, offset);
919 str=val_to_str((oct&0xc0)>>6, tele_param_pri_ind_strings, "Unknown");
921 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
922 proto_tree_add_text(tree, tvb, offset, 1,
927 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
928 proto_tree_add_text(tree, tvb, offset, 1,
934 tele_param_priv_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
937 const gchar *str = NULL;
939 EXACT_DATA_CHECK(len, 1);
941 oct = tvb_get_guint8(tvb, offset);
943 switch ((oct & 0xc0) >> 6)
945 case 0: str = "Not restricted (privacy level 0)"; break;
946 case 1: str = "Restricted (privacy level 1)"; break;
947 case 2: str = "Confidential (privacy level 2)"; break;
948 case 3: str = "Secret (privacy level 3)"; break;
951 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
952 proto_tree_add_text(tree, tvb, offset, 1,
957 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
958 proto_tree_add_text(tree, tvb, offset, 1,
964 tele_param_reply_opt(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
968 EXACT_DATA_CHECK(len, 1);
970 oct = tvb_get_guint8(tvb, offset);
972 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
973 proto_tree_add_text(tree, tvb, offset, 1,
974 "%s : %s (manual) acknowledgment is requested",
976 (oct & 0x80) ? "User" : "No user");
978 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
979 proto_tree_add_text(tree, tvb, offset, 1,
980 "%s : %s acknowledgment requested",
982 (oct & 0x40) ? "Delivery" : "No delivery");
984 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
985 proto_tree_add_text(tree, tvb, offset, 1,
991 tele_param_num_messages(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
995 EXACT_DATA_CHECK(len, 1);
997 oct = tvb_get_guint8(tvb, offset);
999 proto_tree_add_text(tree, tvb, offset, 1,
1000 "Number of voice mail messages: %d%d",
1006 tele_param_alert(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
1009 const gchar *str = NULL;
1011 EXACT_DATA_CHECK(len, 1);
1013 oct = tvb_get_guint8(tvb, offset);
1015 switch ((oct & 0xc0) >> 6)
1017 case 0: str = "Use Mobile default alert"; break;
1018 case 1: str = "Use Low-priority alert"; break;
1019 case 2: str = "Use Medium-priority alert"; break;
1020 case 3: str = "Use High-priority alert"; break;
1023 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
1024 proto_tree_add_text(tree, tvb, offset, 1,
1029 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1030 proto_tree_add_text(tree, tvb, offset, 1,
1036 tele_param_lang_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
1039 const gchar *str = NULL;
1041 EXACT_DATA_CHECK(len, 1);
1043 oct = tvb_get_guint8(tvb, offset);
1047 case 0x00: str = "Unknown or unspecified"; break;
1048 case 0x01: str = "English"; break;
1049 case 0x02: str = "French"; break;
1050 case 0x03: str = "Spanish"; break;
1051 case 0x04: str = "Japanese"; break;
1052 case 0x05: str = "Korean"; break;
1053 case 0x06: str = "Chinese"; break;
1054 case 0x07: str = "Hebrew"; break;
1055 default: str = "Reserved"; break;
1058 proto_tree_add_text(tree, tvb, offset, 1,
1063 tele_param_cb_num(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
1065 guint8 oct, oct2, num_fields, odd;
1066 guint32 saved_offset;
1067 guint32 required_octs;
1070 SHORT_DATA_CHECK(len, 2);
1072 oct = tvb_get_guint8(tvb, offset);
1074 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1075 proto_tree_add_text(tree, tvb, offset, 1,
1076 "%s : Digit mode: %s",
1078 (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
1082 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x70, 8);
1083 proto_tree_add_text(tree, tvb, offset, 1,
1084 "%s : Type of number: (%d)",
1088 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1089 proto_tree_add_text(tree, tvb, offset, 1,
1090 "%s : Numbering plan: (%d)",
1095 num_fields = tvb_get_guint8(tvb, offset);
1097 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xff, 8);
1098 proto_tree_add_text(tree, tvb, offset, 1,
1099 "%s : Number of fields: (%d)",
1103 if (num_fields == 0) return;
1105 if (num_fields > (len - 2))
1107 proto_tree_add_text(tree, tvb, offset, 1,
1108 "Missing %d octet(s) for number of fields",
1109 (num_fields + 2) - len);
1117 while (i < num_fields)
1119 ansi_637_bigbuf[i] = tvb_get_guint8(tvb, offset+i) & 0x7f;
1122 ansi_637_bigbuf[i] = '\0';
1124 proto_tree_add_text(tree, tvb, offset, num_fields,
1131 num_fields = (oct & 0x7f) << 1;
1132 oct2 = tvb_get_guint8(tvb, offset);
1133 num_fields |= ((oct2 & 0x80) >> 7);
1135 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1136 proto_tree_add_text(tree, tvb, offset-1, 1,
1137 "%s : Number of fields (MBS): (%d)",
1141 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
1142 proto_tree_add_text(tree, tvb, offset, 1,
1143 "%s : Number of fields (LSB)",
1151 i = (num_fields - 1) * 4;
1152 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
1154 if (required_octs + 2 > len)
1156 proto_tree_add_text(tree, tvb, offset, 1,
1157 "Missing %d octet(s) for number of fields",
1158 (required_octs + 2) - len);
1163 odd = num_fields & 0x01;
1164 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
1165 saved_offset = offset;
1169 while (i < num_fields)
1171 ansi_637_bigbuf[i] =
1172 air_digits[(oct & 0x78) >> 3];
1175 if (i >= num_fields) break;
1177 oct2 = tvb_get_guint8(tvb, offset);
1180 ansi_637_bigbuf[i] =
1181 air_digits[((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7)];
1188 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
1193 other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x07: 0x7f, 8);
1194 proto_tree_add_text(tree, tvb, offset, 1,
1201 tele_param_disp_mode(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
1204 const gchar *str = NULL;
1206 EXACT_DATA_CHECK(len, 1);
1208 oct = tvb_get_guint8(tvb, offset);
1210 switch ((oct & 0xc0) >> 6)
1212 case 0: str = "Immediate Display: The mobile station is to display the received message as soon as possible."; break;
1213 case 1: str = "Mobile default setting: The mobile station is to display the received message based on a pre-defined mode in the mobile station."; break;
1214 case 2: str = "User Invoke: The mobile station is to display the received message based on the mode selected by the user."; break;
1215 case 3: str = "Reserved"; break;
1218 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
1219 proto_tree_add_text(tree, tvb, offset, 1,
1224 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1225 proto_tree_add_text(tree, tvb, offset, 1,
1230 #define NUM_TELE_PARAM (sizeof(ansi_tele_param_strings)/sizeof(value_string))
1231 static gint ett_ansi_637_tele_param[NUM_TELE_PARAM];
1232 static void (*ansi_637_tele_param_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = {
1233 tele_param_msg_id, /* Message Identifier */
1234 tele_param_user_data, /* User Data */
1235 tele_param_rsp_code, /* User Response Code */
1236 tele_param_timestamp, /* Message Center Time Stamp */
1237 tele_param_timestamp, /* Validity Period Absolute */
1238 tele_param_rel_timestamp, /* Validity Period Relative */
1239 tele_param_timestamp, /* Deferred Delivery Time - Absolute */
1240 tele_param_rel_timestamp, /* Deferred Delivery Time - Relative */
1241 tele_param_pri_ind, /* Priority Indicator */
1242 tele_param_priv_ind, /* Privacy Indicator */
1243 tele_param_reply_opt, /* Reply Option */
1244 tele_param_num_messages, /* Number of Messages */
1245 tele_param_alert, /* Alert on Message Delivery */
1246 tele_param_lang_ind, /* Language Indicator */
1247 tele_param_cb_num, /* Call-Back Number */
1248 tele_param_disp_mode, /* Message Display Mode */
1249 NULL, /* Multiple Encoding User Data */
1250 tele_param_msg_status /* Message status */
1254 trans_param_tele_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1257 const gchar *str = NULL;
1259 EXACT_DATA_CHECK(len, 2);
1261 value = tvb_get_ntohs(tvb, offset);
1263 ansi_637_trans_tele_id = value;
1265 str = match_strval(value, ansi_tele_id_strings);
1272 str = "Reserved for maintenance";
1275 str = "CDMA Service Category Programming Teleservice (SCPT)";
1278 str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
1281 str = "TDMA Cellular Messaging Teleservice";
1284 str = "TDMA Cellular Paging Teleservice (CPT-136)";
1287 str = "TDMA Over-the-Air Activation Teleservice (OATS)";
1290 str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
1293 str = "TDMA Segmented System Assisted Mobile Positioning Service";
1296 if ((value >= 2) && (value <= 4095))
1298 str = "Reserved for assignment by TIA-41";
1300 else if ((value >= 4104) && (value <= 4113))
1302 str = "Reserved for GSM1x Teleservice (CDMA)";
1304 else if ((value >= 4114) && (value <= 32512))
1306 str = "Reserved for assignment by TIA-41";
1308 else if ((value >= 32521) && (value <= 32575))
1310 str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
1312 else if ((value >= 49152) && (value <= 65535))
1314 str = "Reserved for carrier specific teleservices";
1318 str = "Unrecognized Teleservice ID";
1324 proto_tree_add_text(tree, tvb, offset, 2,
1329 g_snprintf(add_string, string_len, " - %s (%d)", str, value);
1333 trans_param_srvc_cat(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1336 const gchar *str = NULL;
1338 EXACT_DATA_CHECK(len, 2);
1340 value = tvb_get_ntohs(tvb, offset);
1342 str = val_to_str_const(value, ansi_srvc_cat_strings, "Reserved");
1344 proto_tree_add_text(tree, tvb, offset, 2,
1347 g_snprintf(add_string, string_len, " - %s (%d)", str, value);
1351 trans_param_address(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1353 guint8 oct, oct2, num_fields, odd;
1354 gboolean email_addr;
1355 guint32 saved_offset;
1356 guint32 required_octs;
1360 SHORT_DATA_CHECK(len, 2);
1364 oct = tvb_get_guint8(tvb, offset);
1366 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1367 proto_tree_add_text(tree, tvb, offset, 1,
1368 "%s : Digit mode: %s",
1370 (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
1372 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
1373 proto_tree_add_text(tree, tvb, offset, 1,
1374 "%s : Number mode: %s",
1376 (oct & 0x40) ? "Data Network Address" : "ANSI T1.607");
1382 switch ((oct & 0x38) >> 3)
1384 case 0: str = "Unknown"; break;
1385 case 1: str = "Internet Protocol (RFC 791)"; break;
1386 case 2: str = "Internet Email Address (RFC 822)"; email_addr = TRUE; break;
1392 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
1393 proto_tree_add_text(tree, tvb, offset, 1,
1394 "%s : Type of number: %s (%d)",
1400 num_fields = (oct & 0x07) << 5;
1401 oct2 = tvb_get_guint8(tvb, offset);
1402 num_fields |= ((oct2 & 0xf8) >> 3);
1404 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1405 proto_tree_add_text(tree, tvb, offset-1, 1,
1406 "%s : Number of fields (MSB): (%d)",
1410 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
1411 proto_tree_add_text(tree, tvb, offset, 1,
1412 "%s : Number of fields (LSB)",
1415 if (num_fields == 0) return;
1417 if (num_fields > (len - 2))
1419 proto_tree_add_text(tree, tvb, offset, 1,
1420 "Missing %d octet(s) for number of fields",
1421 (num_fields + 2) - len);
1426 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
1427 proto_tree_add_text(tree, tvb, offset, 1,
1428 "%s : Most significant bits of first field",
1435 while (i < num_fields)
1437 ansi_637_bigbuf[i] = (oct & 0x07) << 5;
1438 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf8) >> 3;
1441 ansi_637_bigbuf[i] = '\0';
1445 proto_tree_add_text(tree, tvb, offset, num_fields - 1,
1451 proto_tree_add_bytes(tree, hf_ansi_637_trans_bin_addr, tvb, offset, num_fields - 1,
1452 (guint8*)ansi_637_bigbuf);
1455 offset += (num_fields - 1);
1457 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
1458 proto_tree_add_text(tree, tvb, offset, 1,
1459 "%s : Least significant bits of last field",
1462 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1463 proto_tree_add_text(tree, tvb, offset, 1,
1469 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
1470 proto_tree_add_text(tree, tvb, offset, 1,
1471 "%s : Type of number: (%d)",
1475 oct2 = tvb_get_guint8(tvb, offset + 1);
1477 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1478 proto_tree_add_text(tree, tvb, offset, 1,
1479 "%s : Numbering plan (MSB): (%d)",
1481 ((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7));
1486 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1487 proto_tree_add_text(tree, tvb, offset, 1,
1488 "%s : Numbering plan (LSB)",
1492 num_fields = (oct & 0x7f) << 1;
1493 oct2 = tvb_get_guint8(tvb, offset);
1494 num_fields |= ((oct2 & 0x80) >> 7);
1496 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1497 proto_tree_add_text(tree, tvb, offset-1, 1,
1498 "%s : Number of fields (MSB): (%d)",
1502 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
1503 proto_tree_add_text(tree, tvb, offset, 1,
1504 "%s : Number of fields (LSB)",
1507 if (num_fields == 0) return;
1509 if (num_fields > (len - 3))
1511 proto_tree_add_text(tree, tvb, offset, 1,
1512 "Missing %d octet(s) for number of fields",
1513 (num_fields + 3) - len);
1518 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x7f, 8);
1519 proto_tree_add_text(tree, tvb, offset, 1,
1520 "%s : Most significant bits of first field",
1527 while (i < num_fields)
1529 ansi_637_bigbuf[i] = (oct & 0x7f) << 1;
1530 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0x80) >> 7;
1533 ansi_637_bigbuf[i] = '\0';
1535 proto_tree_add_text(tree, tvb, offset, num_fields - 1,
1539 offset += (num_fields - 1);
1541 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1542 proto_tree_add_text(tree, tvb, offset, 1,
1543 "%s : Least significant bit of last field",
1546 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1547 proto_tree_add_text(tree, tvb, offset, 1,
1555 num_fields = (oct & 0x3f) << 2;
1556 oct2 = tvb_get_guint8(tvb, offset);
1557 num_fields |= ((oct2 & 0xc0) >> 6);
1559 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1560 proto_tree_add_text(tree, tvb, offset-1, 1,
1561 "%s : Number of fields (MSB): (%d)",
1565 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xc0, 8);
1566 proto_tree_add_text(tree, tvb, offset, 1,
1567 "%s : Number of fields (LSB)",
1575 i = (num_fields - 1) * 4;
1576 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
1578 if (required_octs + 2 > len)
1580 proto_tree_add_text(tree, tvb, offset, 1,
1581 "Missing %d octet(s) for number of fields",
1582 (required_octs + 2) - len);
1587 odd = num_fields & 0x01;
1588 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
1589 saved_offset = offset;
1593 while (i < num_fields)
1595 ansi_637_bigbuf[i] =
1596 air_digits[(oct & 0x3c) >> 2];
1599 if (i >= num_fields) break;
1601 oct2 = tvb_get_guint8(tvb, offset);
1604 ansi_637_bigbuf[i] =
1605 air_digits[((oct & 0x03) << 2) | ((oct2 & 0xc0) >> 6)];
1612 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
1617 other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x03: 0x3f, 8);
1618 proto_tree_add_text(tree, tvb, offset, 1,
1625 trans_param_subaddress(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1627 guint8 oct, oct2, num_fields;
1631 SHORT_DATA_CHECK(len, 2);
1633 oct = tvb_get_guint8(tvb, offset);
1635 switch ((oct & 0xe0) >> 5)
1637 case 0: str = "NSAP (CCITT Recommendation X.213 or ISO 8348 AD2)"; break;
1638 case 1: str = "User-specified"; break;
1644 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xe0, 8);
1645 proto_tree_add_text(tree, tvb, offset, 1,
1650 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x10, 8);
1651 proto_tree_add_text(tree, tvb, offset, 1,
1656 num_fields = (oct & 0x0f) << 4;
1657 oct2 = tvb_get_guint8(tvb, offset);
1658 num_fields |= ((oct2 & 0xf0) >> 4);
1660 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1661 proto_tree_add_text(tree, tvb, offset-1, 1,
1662 "%s : Number of fields (MSB): (%d)",
1666 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf0, 8);
1667 proto_tree_add_text(tree, tvb, offset, 1,
1668 "%s : Number of fields (LSB)",
1671 if (num_fields == 0) return;
1673 if (num_fields > (len - 2))
1675 proto_tree_add_text(tree, tvb, offset, 1,
1676 "Missing %d octet(s) for number of fields",
1677 (num_fields + 2) - len);
1682 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x0f, 8);
1683 proto_tree_add_text(tree, tvb, offset, 1,
1684 "%s : Most significant bits of first field",
1691 while (i < num_fields)
1693 ansi_637_bigbuf[i] = (oct & 0x0f) << 4;
1694 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf0) >> 4;
1697 ansi_637_bigbuf[i] = '\0';
1699 proto_tree_add_bytes(tree, hf_ansi_637_trans_bin_addr, tvb, offset, num_fields - 1,
1700 (guint8*)ansi_637_bigbuf);
1702 offset += (num_fields - 1);
1704 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf0, 8);
1705 proto_tree_add_text(tree, tvb, offset, 1,
1706 "%s : Least significant bits of last field",
1709 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1710 proto_tree_add_text(tree, tvb, offset, 1,
1716 trans_param_bearer_reply_opt(tvbuff_t *tvb, proto_tree *tree, guint len _U_, guint32 offset, gchar *add_string, int string_len)
1720 oct = tvb_get_guint8(tvb, offset);
1722 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
1723 proto_tree_add_text(tree, tvb, offset, 1,
1724 "%s : Reply Sequence Number: %d",
1728 g_snprintf(add_string, string_len, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
1730 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
1731 proto_tree_add_text(tree, tvb, offset, 1,
1737 trans_param_cause_codes(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1740 const gchar *str = NULL;
1742 oct = tvb_get_guint8(tvb, offset);
1744 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
1745 proto_tree_add_text(tree, tvb, offset, 1,
1746 "%s : Reply Sequence Number: %d",
1752 case 0x00: str = "No error"; break;
1753 case 0x02: str = "Temporary Condition"; break;
1754 case 0x03: str = "Permanent Condition"; break;
1760 g_snprintf(add_string, string_len, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
1762 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
1763 proto_tree_add_text(tree, tvb, offset, 1,
1764 "%s : Error Class: %s",
1770 if (!(oct & 0x03)) return;
1772 if (len == 1) return;
1774 oct = tvb_get_guint8(tvb, offset);
1778 case 0: str = "Address vacant"; break;
1779 case 1: str = "Address translation failure"; break;
1780 case 2: str = "Network resource shortage"; break;
1781 case 3: str = "Network failure"; break;
1782 case 4: str = "Invalid Teleservice ID"; break;
1783 case 5: str = "Other network problem"; break;
1784 case 6: str = "Unsupported network interface"; break;
1785 case 32: str = "No page response"; break;
1786 case 33: str = "Destination busy"; break;
1787 case 34: str = "No acknowledgement"; break;
1788 case 35: str = "Destination resource shortage"; break;
1789 case 36: str = "SMS delivery postponed"; break;
1790 case 37: str = "Destination out of service"; break;
1791 case 38: str = "Destination no longer at this address"; break;
1792 case 39: str = "Other terminal problem"; break;
1793 case 64: str = "Radio interface resource shortage"; break;
1794 case 65: str = "Radio interface incompatibility"; break;
1795 case 66: str = "Other radio interface problem"; break;
1796 case 67: str = "Unsupported Base Station Capability"; break;
1797 case 96: str = "Encoding problem"; break;
1798 case 97: str = "Service origination denied"; break;
1799 case 98: str = "Service termination denied"; break;
1800 case 99: str = "Supplementary service not supported"; break;
1801 case 100: str = "Service not supported"; break;
1802 case 101: str = "Reserved"; break;
1803 case 102: str = "Missing expected parameter"; break;
1804 case 103: str = "Missing mandatory parameter"; break;
1805 case 104: str = "Unrecognized parameter value"; break;
1806 case 105: str = "Unexpected parameter value"; break;
1807 case 106: str = "User Data size error"; break;
1808 case 107: str = "Other general problems"; break;
1809 case 108: str = "Session not active"; break;
1811 if ((oct >= 7) && (oct <= 31)) { str = "Reserved, treat as Other network problem"; }
1812 else if ((oct >= 40) && (oct <= 47)) { str = "Reserved, treat as Other terminal problem"; }
1813 else if ((oct >= 48) && (oct <= 63)) { str = "Reserved, treat as SMS delivery postponed"; }
1814 else if ((oct >= 68) && (oct <= 95)) { str = "Reserved, treat as Other radio interface problem"; }
1815 else if ((oct >= 109) && (oct <= 223)) { str = "Reserved, treat as Other general problems"; }
1816 else { str = "Reserved for protocol extension, treat as Other general problems"; }
1820 proto_tree_add_text(tree, tvb, offset, 1,
1825 trans_param_bearer_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1829 proto_tree_add_text(tree, tvb, offset, len,
1833 * dissect the embedded teleservice data
1835 tele_tvb = tvb_new_subset(tvb, offset, len, len);
1837 dissector_try_uint(tele_dissector_table, ansi_637_trans_tele_id,
1838 tele_tvb, g_pinfo, g_tree);
1841 #define NUM_TRANS_PARAM (sizeof(ansi_trans_param_strings)/sizeof(value_string))
1842 static gint ett_ansi_637_trans_param[NUM_TRANS_PARAM];
1843 static void (*ansi_637_trans_param_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len) = {
1844 trans_param_tele_id, /* Teleservice Identifier */
1845 trans_param_srvc_cat, /* Service Category */
1846 trans_param_address, /* Originating Address */
1847 trans_param_subaddress, /* Originating Subaddress */
1848 trans_param_address, /* Destination Address */
1849 trans_param_subaddress, /* Destination Subaddress */
1850 trans_param_bearer_reply_opt, /* Bearer Reply Option */
1851 trans_param_cause_codes, /* Cause Codes */
1852 trans_param_bearer_data, /* Bearer Data */
1856 #define NUM_TRANS_MSG_TYPE (sizeof(ansi_trans_msg_type_strings)/sizeof(value_string))
1857 static gint ett_ansi_637_trans_msg[NUM_TRANS_MSG_TYPE];
1859 /* GENERIC IS-637 DISSECTOR FUNCTIONS */
1862 dissect_ansi_637_tele_param(tvbuff_t *tvb, proto_tree *tree, guint32 *offset)
1864 void (*param_fcn)(tvbuff_t *, proto_tree *, guint, guint32) = NULL;
1867 guint32 curr_offset;
1868 gint ett_param_idx, idx;
1869 proto_tree *subtree;
1871 const gchar *str = NULL;
1874 curr_offset = *offset;
1876 oct = tvb_get_guint8(tvb, curr_offset);
1877 str = match_strval_idx((guint32) oct, ansi_tele_param_strings, &idx);
1884 ett_param_idx = ett_ansi_637_tele_param[idx];
1885 param_fcn = ansi_637_tele_param_fcn[idx];
1888 proto_tree_add_text(tree, tvb, curr_offset, -1, "%s", str);
1890 subtree = proto_item_add_subtree(item, ett_param_idx);
1892 proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id,
1893 tvb, curr_offset, 1, oct);
1897 len = tvb_get_guint8(tvb, curr_offset);
1899 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
1901 proto_tree_add_uint(subtree, hf_ansi_637_tele_length,
1902 tvb, curr_offset, 1, len);
1908 if (param_fcn == NULL)
1910 proto_tree_add_text(subtree, tvb, curr_offset,
1911 len, "Parameter Data");
1915 (*param_fcn)(tvb, subtree, len, curr_offset);
1921 *offset = curr_offset;
1927 dissect_ansi_637_tele_message(tvbuff_t *tvb, proto_tree *ansi_637_tree)
1930 guint32 curr_offset;
1933 len = tvb_length(tvb);
1935 while ((len - curr_offset) > 0)
1937 if (!dissect_ansi_637_tele_param(tvb, ansi_637_tree, &curr_offset))
1939 proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
1940 "Unknown Parameter Data");
1947 dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1949 proto_item *ansi_637_item;
1950 proto_tree *ansi_637_tree = NULL;
1951 const gchar *str = NULL;
1954 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
1956 /* In the interest of speed, if "tree" is NULL, don't do any work not
1957 * necessary to generate protocol tree items.
1961 value = pinfo->match_uint;
1964 * create the ansi_637 protocol tree
1966 str = match_strval(value, ansi_tele_id_strings);
1973 str = "Reserved for maintenance";
1976 str = "CDMA Service Category Programming Teleservice (SCPT)";
1979 str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
1982 str = "TDMA Cellular Messaging Teleservice";
1985 str = "TDMA Cellular Paging Teleservice (CPT-136)";
1988 str = "TDMA Over-the-Air Activation Teleservice (OATS)";
1991 str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
1994 str = "TDMA Segmented System Assisted Mobile Positioning Service";
1997 if ((value >= 2) && (value <= 4095))
1999 str = "Reserved for assignment by TIA-41";
2001 else if ((value >= 4104) && (value <= 4113))
2003 str = "Reserved for GSM1x Teleservice (CDMA)";
2005 else if ((value >= 4114) && (value <= 32512))
2007 str = "Reserved for assignment by TIA-41";
2009 else if ((value >= 32521) && (value <= 32575))
2011 str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
2013 else if ((value >= 49152) && (value < 65535))
2015 str = "Reserved for carrier specific teleservices";
2017 else if (value == 65535)
2020 * supposed to be "Reserved for carrier specific teleservices"
2021 * but we are using it to key SMS Broadcast dissection where
2022 * there is no teleservice ID
2024 str = "(Reserved) Being used for Broadcast";
2028 str = "Unrecognized Teleservice ID";
2035 proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
2037 ansi_proto_name_tele,
2042 proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele);
2044 dissect_ansi_637_tele_message(tvb, ansi_637_tree);
2049 dissect_ansi_637_trans_param(tvbuff_t *tvb, proto_tree *tree, guint32 *offset)
2051 void (*param_fcn)(tvbuff_t *, proto_tree *, guint, guint32, gchar *, int) = NULL;
2054 guint32 curr_offset;
2055 gint ett_param_idx, idx;
2056 proto_tree *subtree;
2058 const gchar *str = NULL;
2060 curr_offset = *offset;
2062 oct = tvb_get_guint8(tvb, curr_offset);
2063 str = match_strval_idx((guint32) oct, ansi_trans_param_strings, &idx);
2070 ett_param_idx = ett_ansi_637_trans_param[idx];
2071 param_fcn = ansi_637_trans_param_fcn[idx];
2074 proto_tree_add_text(tree, tvb, curr_offset, -1, "%s", str);
2076 subtree = proto_item_add_subtree(item, ett_param_idx);
2078 proto_tree_add_uint(subtree, hf_ansi_637_trans_param_id,
2079 tvb, curr_offset, 1, oct);
2083 len = tvb_get_guint8(tvb, curr_offset);
2085 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
2087 proto_tree_add_uint(subtree, hf_ansi_637_trans_length,
2088 tvb, curr_offset, 1, len);
2094 if (param_fcn == NULL)
2096 proto_tree_add_text(subtree, tvb, curr_offset,
2097 len, "Parameter Data");
2101 gchar *ansi_637_add_string;
2103 ansi_637_add_string = ep_alloc(1024);
2104 ansi_637_add_string[0] = '\0';
2105 (*param_fcn)(tvb, subtree, len, curr_offset, ansi_637_add_string, 1024);
2107 if (ansi_637_add_string[0] != '\0')
2109 proto_item_append_text(item, "%s", ansi_637_add_string);
2116 *offset = curr_offset;
2123 dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2125 proto_item *ansi_637_item;
2126 proto_tree *ansi_637_tree = NULL;
2127 guint32 curr_offset;
2129 const gchar *str = NULL;
2133 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
2135 /* In the interest of speed, if "tree" is NULL, don't do any work not
2136 * necessary to generate protocol tree items.
2144 * reset the teleservice ID for each dissection
2146 ansi_637_trans_tele_id = 0;
2149 * create the ansi_637 protocol tree
2151 oct = tvb_get_guint8(tvb, 0);
2153 str = match_strval_idx(oct, ansi_trans_msg_type_strings, &idx);
2158 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
2159 "%s - Unrecognized Transport Layer Message Type (%d)",
2160 ansi_proto_name_trans,
2164 proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans);
2169 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
2171 ansi_proto_name_trans,
2175 proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans_msg[idx]);
2177 if (oct == ANSI_TRANS_MSG_TYPE_BROADCAST)
2180 * there is no teleservice ID for Broadcast but we want the
2181 * bearer data to be dissected
2183 * using a reserved value to key dissector port
2185 ansi_637_trans_tele_id = 65535;
2191 len = tvb_length(tvb);
2193 while ((len - curr_offset) > 0)
2195 if (!dissect_ansi_637_trans_param(tvb, ansi_637_tree, &curr_offset))
2197 proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
2198 "Unknown Parameter Data");
2204 /* Dissect SMS embedded in SIP */
2206 dissect_ansi_637_trans_app(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2208 col_set_str(pinfo->cinfo, COL_PROTOCOL,"/");
2209 col_set_fence(pinfo->cinfo, COL_INFO);
2210 dissect_ansi_637_trans(tvb, pinfo, tree);
2212 /* Register the protocol with Wireshark */
2214 proto_register_ansi_637(void)
2218 /* Setup list of header fields */
2219 static hf_register_info hf_trans[] =
2221 { &hf_ansi_637_trans_msg_type,
2223 "ansi_637_trans.msg_type",
2224 FT_UINT24, BASE_DEC, VALS(ansi_trans_msg_type_strings), 0xf00000,
2226 { &hf_ansi_637_trans_param_id,
2227 { "Transport Param ID", "ansi_637_trans.param_id",
2228 FT_UINT8, BASE_DEC, VALS(ansi_trans_param_strings), 0,
2230 { &hf_ansi_637_trans_length,
2231 { "Length", "ansi_637_trans.len",
2232 FT_UINT8, BASE_DEC, NULL, 0,
2234 { &hf_ansi_637_trans_bin_addr,
2235 { "Binary Address", "ansi_637_trans.bin_addr",
2236 FT_BYTES, BASE_NONE, 0, 0,
2239 static hf_register_info hf_tele[] =
2241 { &hf_ansi_637_tele_msg_type,
2243 "ansi_637_tele.msg_type",
2244 FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_type_strings), 0xf00000,
2246 { &hf_ansi_637_tele_msg_id,
2248 "ansi_637_tele.msg_id",
2249 FT_UINT24, BASE_DEC, NULL, 0x0ffff0,
2251 { &hf_ansi_637_tele_msg_status,
2253 "ansi_637_tele.msg_status",
2254 FT_UINT8, BASE_DEC, VALS(ansi_tele_msg_status_strings), 0,
2256 { &hf_ansi_637_tele_msg_rsvd,
2258 "ansi_637_tele.msg_rsvd",
2259 FT_UINT24, BASE_DEC, NULL, 0x00000f,
2261 { &hf_ansi_637_tele_length,
2262 { "Length", "ansi_637_tele.len",
2263 FT_UINT8, BASE_DEC, NULL, 0,
2265 { &hf_ansi_637_tele_subparam_id,
2266 { "Teleservice Subparam ID", "ansi_637_tele.subparam_id",
2267 FT_UINT8, BASE_DEC, VALS(ansi_tele_param_strings), 0,
2271 /* Setup protocol subtree array */
2272 #define NUM_INDIVIDUAL_PARAMS 3
2273 gint *ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM];
2275 memset((void *) ett, 0, sizeof(ett));
2277 ett[0] = &ett_ansi_637_tele;
2278 ett[1] = &ett_ansi_637_trans;
2279 ett[2] = &ett_params;
2281 for (i=0; i < NUM_TELE_PARAM; i++)
2283 ett_ansi_637_tele_param[i] = -1;
2284 ett[NUM_INDIVIDUAL_PARAMS+i] = &ett_ansi_637_tele_param[i];
2287 for (i=0; i < NUM_TRANS_MSG_TYPE; i++)
2289 ett_ansi_637_trans_msg[i] = -1;
2290 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+i] = &ett_ansi_637_trans_msg[i];
2293 for (i=0; i < NUM_TRANS_PARAM; i++)
2295 ett_ansi_637_trans_param[i] = -1;
2296 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+i] = &ett_ansi_637_trans_param[i];
2299 /* Register the protocol name and description */
2300 proto_ansi_637_tele =
2301 proto_register_protocol(ansi_proto_name_tele, "ANSI IS-637-A Teleservice", "ansi_637_tele");
2303 proto_ansi_637_trans =
2304 proto_register_protocol(ansi_proto_name_trans, "ANSI IS-637-A Transport", "ansi_637_trans");
2306 register_dissector("ansi_637_tele", dissect_ansi_637_tele, proto_ansi_637_tele);
2307 register_dissector("ansi_637_trans", dissect_ansi_637_trans, proto_ansi_637_trans);
2309 /* Required function calls to register the header fields and subtrees used */
2310 proto_register_field_array(proto_ansi_637_tele, hf_tele, array_length(hf_tele));
2311 proto_register_field_array(proto_ansi_637_trans, hf_trans, array_length(hf_trans));
2312 proto_register_subtree_array(ett, array_length(ett));
2314 tele_dissector_table =
2315 register_dissector_table("ansi_637.tele_id",
2316 "ANSI IS-637-A Teleservice ID", FT_UINT8, BASE_DEC);
2321 proto_reg_handoff_ansi_637(void)
2323 dissector_handle_t ansi_637_tele_handle;
2324 dissector_handle_t ansi_637_trans_handle;
2325 dissector_handle_t ansi_637_trans_app_handle;
2328 ansi_637_tele_handle = create_dissector_handle(dissect_ansi_637_tele, proto_ansi_637_tele);
2329 ansi_637_trans_handle = create_dissector_handle(dissect_ansi_637_trans, proto_ansi_637_trans);
2330 ansi_637_trans_app_handle = create_dissector_handle(dissect_ansi_637_trans_app, proto_ansi_637_trans);
2332 /* Dissect messages embedded in SIP */
2333 dissector_add_string("media_type","application/vnd.3gpp2.sms", ansi_637_trans_app_handle);
2335 * register for all known teleservices
2336 * '-1' is to stop before trailing '0' entry
2338 * to add teleservices, modify 'ansi_tele_id_strings'
2340 for (i=0; i < ((sizeof(ansi_tele_id_strings)/sizeof(value_string))-1); i++)
2343 * ANSI MAP dissector will push out teleservice ids
2345 dissector_add_uint("ansi_map.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
2348 * we will push out teleservice ids after Transport layer decode
2350 dissector_add_uint("ansi_637.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
2354 * ANSI A-interface will push out transport layer data
2356 dissector_add_uint("ansi_a.sms", 0, ansi_637_trans_handle);
2358 /* data_handle = find_dissector("data"); */