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 * Ethereal - Network traffic analyzer
15 * By Gerald Combs <gerald@ethereal.com>
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.
38 /* #include <stdlib.h> */
41 #ifdef HAVE_SYS_TYPES_H
42 # include <sys/types.h>
45 #ifdef HAVE_NETINET_IN_H
46 # include <netinet/in.h>
51 #include "epan/packet.h"
54 static char *ansi_proto_name_tele = "ANSI IS-637-A (SMS) Teleservice Layer";
55 static char *ansi_proto_name_trans = "ANSI IS-637-A (SMS) Transport Layer";
56 static char *ansi_proto_name_short = "IS-637-A";
58 static const value_string ansi_srvc_cat_strings[] = {
59 { 0x0000, "Unknown or unspecified" },
60 { 0x0001, "Emergency Broadcasts" },
61 { 0x0002, "Administrative" },
62 { 0x0003, "Maintenance" },
63 { 0x0004, "General News - Local" },
64 { 0x0005, "General News - Regional" },
65 { 0x0006, "General News - National" },
66 { 0x0007, "General News - International" },
67 { 0x0008, "Business/Financial News - Local" },
68 { 0x0009, "Business/Financial News - Regional" },
69 { 0x000A, "Business/Financial News - National" },
70 { 0x000B, "Business/Financial News - International" },
71 { 0x000C, "Sports News - Local" },
72 { 0x000D, "Sports News - Regional" },
73 { 0x000E, "Sports News - National" },
74 { 0x000F, "Sports News - International" },
75 { 0x0010, "Entertainment News - Local" },
76 { 0x0011, "Entertainment News - Regional" },
77 { 0x0012, "Entertainment News - National" },
78 { 0x0013, "Entertainment News - International" },
79 { 0x0014, "Local Weather" },
80 { 0x0015, "Area Traffic Reports" },
81 { 0x0016, "Local Airport Flight Schedules" },
82 { 0x0017, "Restaurants" },
83 { 0x0018, "Lodgings" },
84 { 0x0019, "Retail Directory" },
85 { 0x001A, "Advertisements" },
86 { 0x001B, "Stock Quotes" },
87 { 0x001C, "Employment Opportunities" },
88 { 0x001D, "Medical/Health/Hospitals" },
89 { 0x001E, "Technology News" },
90 { 0x001F, "Multi-category" },
94 static const value_string ansi_tele_msg_type_strings[] = {
95 { 1, "Deliver (mobile-terminated only)" },
96 { 2, "Submit (mobile-originated only)" },
97 { 3, "Cancellation (mobile-originated only)" },
98 { 4, "Delivery Acknowledgement (mobile-terminated only)" },
99 { 5, "User Acknowledgement (either direction)" },
103 static const value_string ansi_tele_id_strings[] = {
104 { 1, "Reserved for maintenance" },
105 { 4096, "AMPS Extended Protocol Enhanced Services" },
106 { 4097, "CDMA Cellular Paging Teleservice" },
107 { 4098, "CDMA Cellular Messaging Teleservice" },
108 { 4099, "CDMA Voice Mail Notification" },
109 { 32513, "TDMA Cellular Messaging Teleservice" },
110 { 32520, "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)" },
111 { 32584, "TDMA Segmented System Assisted Mobile Positioning Service" },
115 static const value_string ansi_tele_param_strings[] = {
116 { 0x00, "Message Identifier" },
117 { 0x01, "User Data" },
118 { 0x02, "User Response Code" },
119 { 0x03, "Message Center Time Stamp" },
120 { 0x04, "Validity Period - Absolute" },
121 { 0x05, "Validity Period - Relative" },
122 { 0x06, "Deferred Delivery Time - Absolute" },
123 { 0x07, "Deferred Delivery Time - Relative" },
124 { 0x08, "Priority Indicator" },
125 { 0x09, "Privacy Indicator" },
126 { 0x0a, "Reply Option" },
127 { 0x0b, "Number of Messages" },
128 { 0x0c, "Alert on Message Delivery" },
129 { 0x0d, "Language Indicator" },
130 { 0x0e, "Call-Back Number" },
131 { 0x0f, "Message Display Mode" },
132 { 0x10, "Multiple Encoding User Data" },
136 static const value_string ansi_trans_msg_type_strings[] = {
137 { 0, "Point-to-Point" },
139 { 2, "Acknowledge" },
143 static const value_string ansi_trans_param_strings[] = {
144 { 0x00, "Teleservice Identifier" },
145 { 0x01, "Service Category" },
146 { 0x02, "Originating Address" },
147 { 0x03, "Originating Subaddress" },
148 { 0x04, "Destination Address" },
149 { 0x05, "Destination Subaddress" },
150 { 0x06, "Bearer Reply Option" },
151 { 0x07, "Cause Codes" },
152 { 0x08, "Bearer Data" },
157 * from Table 2.7.1.3.2.4-4. Representation of DTMF Digits
158 * 3GPP2 C.S0005-C (IS-2000 aka cdma2000)
160 static unsigned char air_digits[] = {
161 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
162 '?','1','2','3','4','5','6','7','8','9','0','*','#','?','?'
165 /* Initialize the protocol and registered fields */
166 static int proto_ansi_637_tele = -1;
167 static int proto_ansi_637_trans = -1;
168 static int hf_ansi_637_none = -1;
169 static int hf_ansi_637_length = -1;
170 static int hf_ansi_637_bin_addr = -1;
171 static int hf_ansi_637_tele_msg_type = -1;
172 static int hf_ansi_637_tele_msg_id = -1;
173 static int hf_ansi_637_tele_msg_rsvd = -1;
174 static int hf_ansi_637_tele_subparam_id = -1;
175 static int hf_ansi_637_trans_msg_type = -1;
176 static int hf_ansi_637_trans_param_id = -1;
178 /* Initialize the subtree pointers */
179 static gint ett_ansi_637_tele = -1;
180 static gint ett_ansi_637_trans = -1;
181 static gint ett_params = -1;
183 static guint32 ansi_637_trans_tele_id;
184 static char ansi_637_bigbuf[1024];
185 static gchar ansi_637_add_string[1024];
186 /* static dissector_handle_t data_handle; */
187 static dissector_table_t tele_dissector_table;
188 static packet_info *g_pinfo;
189 static proto_tree *g_tree;
194 decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oct, guint8 *last_bit, gchar *buf)
196 guint8 oct, oct2, bit;
197 /* guint32 saved_offset; */
206 /* saved_offset = *offset; */
207 oct = oct2 = *last_oct;
212 oct2 = tvb_get_guint8(tvb, *offset);
216 for (i=0; i < num_fields; i++)
223 * cannot grab an octet if we are getting
224 * the last field and bit is 7 or 8
225 * because there may not be another octet
227 if (((i + 1) != num_fields) ||
228 ((bit != 7) && (bit != 8)))
230 oct2 = tvb_get_guint8(tvb, *offset);
238 buf[i] = ((oct & 0x01) << 6) | ((oct2 & 0xfc) >> 2);
242 buf[i] = ((oct & 0x03) << 5) | ((oct2 & 0xf8) >> 3);
246 buf[i] = ((oct & 0x07) << 4) | ((oct2 & 0xf0) >> 4);
250 buf[i] = ((oct & 0x0f) << 3) | ((oct2 & 0xe0) >> 5);
254 buf[i] = ((oct & 0x1f) << 2) | ((oct2 & 0xc0) >> 6);
258 buf[i] = ((oct & 0x3f) << 1) | ((oct2 & 0x80) >> 7);
266 buf[i] = (oct & 0xfe) >> 1;
275 *last_oct = (bit == 1) ? oct : oct2;
278 /* PARAM FUNCTIONS */
280 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
281 if ((edc_len) > (edc_max_len)) \
283 proto_tree_add_text(tree, tvb, offset, \
284 (edc_len) - (edc_max_len), "Extraneous Data"); \
287 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
288 if ((sdc_len) < (sdc_min_len)) \
290 proto_tree_add_text(tree, tvb, offset, \
291 (sdc_len), "Short Data (?)"); \
295 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
296 if ((edc_len) != (edc_eq_len)) \
298 proto_tree_add_text(tree, tvb, offset, \
299 (edc_len), "Unexpected Data Length"); \
304 tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
312 guint32 required_octs;
313 guint32 saved_offset;
317 SHORT_DATA_CHECK(len, 2);
322 oct = tvb_get_guint8(tvb, offset);
327 encoding = ((oct & 0xf8) >> 3);
330 case 0x00: str = "Octet, unspecified"; break;
331 case 0x01: str = "Extended Protocol Message";
332 oct2 = tvb_get_guint8(tvb, offset+1);
333 msg_type = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
335 case 0x02: str = "7-bit ASCII"; break;
336 case 0x03: str = "IA5"; break;
337 case 0x04: str = "UNICODE"; break;
338 case 0x05: str = "Shift-JIS"; break;
339 case 0x06: str = "Korean"; break;
340 case 0x07: str = "Latin/Hebrew"; break;
341 case 0x08: str = "Latin"; break;
342 case 0x09: str = "GSM 7-bit default alphabet"; break;
343 default: str = "Reserved"; break;
346 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
347 proto_tree_add_text(tree, tvb, offset, 1,
352 if (encoding == 0x01)
354 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
355 proto_tree_add_text(tree, tvb, offset, 1,
356 "%s : Message type: see TIA/EIA/IS-91 (%d)",
360 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
361 proto_tree_add_text(tree, tvb, offset+1, 1,
376 oct2 = tvb_get_guint8(tvb, offset);
377 num_fields = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
379 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
380 proto_tree_add_text(tree, tvb, offset-1, 1,
381 "%s : Number of fields (MSB): %d",
385 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
386 proto_tree_add_text(tree, tvb, offset, 1,
387 "%s : Number of fields (LSB)",
390 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
391 proto_tree_add_text(tree, tvb, offset, 1,
392 "%s : Most significant bits of first field",
399 /* NOTE: there are now 3 bits remaining in 'oct' */
401 if (len <= used) return;
404 * decode rest if 7-bit ASCII
406 if (encoding == 0x02)
410 * 3 bits remaining from last octet
414 i = (num_fields * 7) - 3;
415 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
417 if (required_octs + used > len)
419 proto_tree_add_text(tree, tvb, offset, 1,
420 "Missing %d octet(s) for number of fields",
421 (required_octs + used) - len);
427 saved_offset = offset;
429 decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
431 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
432 "Encoded user data: %s",
437 case 1: oct2 = 0x01; break;
438 case 2: oct2 = 0x03; break;
439 case 3: oct2 = 0x07; break;
440 case 4: oct2 = 0x0f; break;
441 case 5: oct2 = 0x1f; break;
442 case 6: oct2 = 0x3f; break;
443 case 7: oct2 = 0x7f; break;
448 other_decode_bitfield_value(ansi_637_bigbuf, oct, oct2, 8);
449 proto_tree_add_text(tree, tvb, offset - 1, 1,
456 proto_tree_add_text(tree, tvb, offset, len - used,
457 "Encoded user data");
462 tele_param_rsp_code(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
466 EXACT_DATA_CHECK(len, 1);
471 oct = tvb_get_guint8(tvb, offset);
473 proto_tree_add_text(tree, tvb, offset, 1,
479 tele_param_timestamp(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
481 guint8 oct, oct2, oct3;
483 EXACT_DATA_CHECK(len, 6);
485 oct = tvb_get_guint8(tvb, offset);
486 oct2 = tvb_get_guint8(tvb, offset+1);
487 oct3 = tvb_get_guint8(tvb, offset+2);
489 proto_tree_add_text(tree, tvb, offset, 3,
490 "Year %d%d, Month %d%d, Day %d%d",
500 oct = tvb_get_guint8(tvb, offset);
501 oct2 = tvb_get_guint8(tvb, offset+1);
502 oct3 = tvb_get_guint8(tvb, offset+2);
504 proto_tree_add_text(tree, tvb, offset, 3,
505 "Hour %d%d, Minutes %d%d, Seconds %d%d",
515 tele_param_rel_timestamp(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
522 EXACT_DATA_CHECK(len, 1);
524 oct = tvb_get_guint8(tvb, offset);
528 case 245: str = "Indefinite"; break;
529 case 246: str = "Immediate"; break;
530 case 247: str = "Valid until mobile becomes inactive/Deliver when mobile next becomes active"; break;
531 case 248: str = "Valid until registration area changes, discard if not registered" ; break;
533 if (oct <= 143) { value = (oct + 1) * 5; str2 = "Minutes"; break; }
534 else if ((oct >= 144) && (oct <= 167)) { value = (oct - 143) * 30; str2 = "Minutes + 12 Hours"; break; }
535 else if ((oct >= 168) && (oct <= 196)) { value = oct - 166; str2 = "Days"; break; }
536 else if ((oct >= 197) && (oct <= 244)) { value = oct - 192; str2 = "Weeks"; break; }
537 else { str = "Reserved"; break; }
542 proto_tree_add_text(tree, tvb, offset, 1,
547 proto_tree_add_text(tree, tvb, offset, 1,
554 tele_param_pri_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
559 EXACT_DATA_CHECK(len, 1);
561 oct = tvb_get_guint8(tvb, offset);
563 switch ((oct & 0xc0) >> 6)
565 case 0: str = "Normal"; break;
566 case 1: str = "Interactive"; break;
567 case 2: str = "Urgent"; break;
568 case 3: str = "Emergency"; break;
571 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
572 proto_tree_add_text(tree, tvb, offset, 1,
577 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
578 proto_tree_add_text(tree, tvb, offset, 1,
584 tele_param_priv_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
589 EXACT_DATA_CHECK(len, 1);
591 oct = tvb_get_guint8(tvb, offset);
593 switch ((oct & 0xc0) >> 6)
595 case 0: str = "Not restricted (privacy level 0)"; break;
596 case 1: str = "Restricted (privacy level 1)"; break;
597 case 2: str = "Confidential (privacy level 2)"; break;
598 case 3: str = "Secret (privacy level 3)"; break;
601 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
602 proto_tree_add_text(tree, tvb, offset, 1,
607 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
608 proto_tree_add_text(tree, tvb, offset, 1,
614 tele_param_reply_opt(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
618 EXACT_DATA_CHECK(len, 1);
620 oct = tvb_get_guint8(tvb, offset);
622 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
623 proto_tree_add_text(tree, tvb, offset, 1,
624 "%s : %s (manual) acknowledgment is requested",
626 (oct & 0x80) ? "User" : "No user");
628 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
629 proto_tree_add_text(tree, tvb, offset, 1,
630 "%s : %s acknowledgment requested",
632 (oct & 0x40) ? "Delivery" : "No delivery");
634 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
635 proto_tree_add_text(tree, tvb, offset, 1,
641 tele_param_num_messages(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
645 EXACT_DATA_CHECK(len, 1);
647 oct = tvb_get_guint8(tvb, offset);
649 proto_tree_add_text(tree, tvb, offset, 1,
650 "Number of voice mail messages: %d%d",
656 tele_param_alert(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
661 EXACT_DATA_CHECK(len, 1);
663 oct = tvb_get_guint8(tvb, offset);
665 switch ((oct & 0xc0) >> 6)
667 case 0: str = "Use Mobile default alert"; break;
668 case 1: str = "Use Low-priority alert"; break;
669 case 2: str = "Use Medium-priority alert"; break;
670 case 3: str = "Use High-priority alert"; break;
673 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
674 proto_tree_add_text(tree, tvb, offset, 1,
679 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
680 proto_tree_add_text(tree, tvb, offset, 1,
686 tele_param_lang_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
691 EXACT_DATA_CHECK(len, 1);
693 oct = tvb_get_guint8(tvb, offset);
697 case 0x00: str = "Unknown or unspecified"; break;
698 case 0x01: str = "English"; break;
699 case 0x02: str = "French"; break;
700 case 0x03: str = "Spanish"; break;
701 case 0x04: str = "Japanese"; break;
702 case 0x05: str = "Korean"; break;
703 case 0x06: str = "Chinese"; break;
704 case 0x07: str = "Hebrew"; break;
705 default: str = "Reserved"; break;
708 proto_tree_add_text(tree, tvb, offset, 1,
713 tele_param_cb_num(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
715 guint8 oct, oct2, num_fields, odd;
716 guint32 saved_offset;
717 guint32 required_octs;
720 SHORT_DATA_CHECK(len, 2);
722 oct = tvb_get_guint8(tvb, offset);
724 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
725 proto_tree_add_text(tree, tvb, offset, 1,
726 "%s : Digit mode: %s",
728 (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
732 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x70, 8);
733 proto_tree_add_text(tree, tvb, offset, 1,
734 "%s : Type of number: (%d)",
738 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
739 proto_tree_add_text(tree, tvb, offset, 1,
740 "%s : Numbering plan: (%d)",
745 num_fields = tvb_get_guint8(tvb, offset);
747 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xff, 8);
748 proto_tree_add_text(tree, tvb, offset, 1,
749 "%s : Number of fields: (%d)",
753 if (num_fields == 0) return;
755 if (num_fields > (len - 2))
757 proto_tree_add_text(tree, tvb, offset, 1,
758 "Missing %d octet(s) for number of fields",
759 (num_fields + 2) - len);
767 while (i < num_fields)
769 ansi_637_bigbuf[i] = tvb_get_guint8(tvb, offset+i) & 0x7f;
772 ansi_637_bigbuf[i] = '\0';
774 proto_tree_add_text(tree, tvb, offset, num_fields,
781 num_fields = (oct & 0x7f) << 1;
782 oct2 = tvb_get_guint8(tvb, offset);
783 num_fields |= ((oct2 & 0x80) >> 7);
785 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
786 proto_tree_add_text(tree, tvb, offset-1, 1,
787 "%s : Number of fields (MBS): (%d)",
791 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
792 proto_tree_add_text(tree, tvb, offset, 1,
793 "%s : Number of fields (LSB)",
801 i = (num_fields - 1) * 4;
802 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
804 if (required_octs + 2 > len)
806 proto_tree_add_text(tree, tvb, offset, 1,
807 "Missing %d octet(s) for number of fields",
808 (required_octs + 2) - len);
813 odd = num_fields & 0x01;
814 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
815 saved_offset = offset;
819 while (i < num_fields)
822 air_digits[(oct & 0x78) >> 3];
825 if (i >= num_fields) break;
827 oct2 = tvb_get_guint8(tvb, offset);
831 air_digits[((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7)];
838 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
843 other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x07: 0x7f, 8);
844 proto_tree_add_text(tree, tvb, offset, 1,
851 tele_param_disp_mode(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
856 EXACT_DATA_CHECK(len, 1);
858 oct = tvb_get_guint8(tvb, offset);
860 switch ((oct & 0xc0) >> 6)
862 case 0: str = "Immediate Display: The mobile station is to display the received message as soon as possible."; break;
863 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;
864 case 2: str = "User Invoke: The mobile station is to display the received message based on the mode selected by the user."; break;
865 case 3: str = "Reserved"; break;
868 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
869 proto_tree_add_text(tree, tvb, offset, 1,
874 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
875 proto_tree_add_text(tree, tvb, offset, 1,
880 #define NUM_TELE_PARAM (sizeof(ansi_tele_param_strings)/sizeof(value_string))
881 static gint ett_ansi_637_tele_param[NUM_TELE_PARAM];
882 static void (*ansi_637_tele_param_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = {
883 NULL, /* Message Identifier */
884 tele_param_user_data, /* User Data */
885 tele_param_rsp_code, /* User Response Code */
886 tele_param_timestamp, /* Message Center Time Stamp */
887 tele_param_timestamp, /* Validity Period Absolute */
888 tele_param_rel_timestamp, /* Validity Period Relative */
889 tele_param_timestamp, /* Deferred Delivery Time - Absolute */
890 tele_param_rel_timestamp, /* Deferred Delivery Time - Relative */
891 tele_param_pri_ind, /* Priority Indicator */
892 tele_param_priv_ind, /* Privacy Indicator */
893 tele_param_reply_opt, /* Reply Option */
894 tele_param_num_messages, /* Number of Messages */
895 tele_param_alert, /* Alert on Message Delivery */
896 tele_param_lang_ind, /* Language Indicator */
897 tele_param_cb_num, /* Call-Back Number */
898 tele_param_disp_mode, /* Message Display Mode */
899 NULL, /* Multiple Encoding User Data */
904 trans_param_tele_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string)
907 const gchar *str = NULL;
909 EXACT_DATA_CHECK(len, 2);
911 value = tvb_get_ntohs(tvb, offset);
913 ansi_637_trans_tele_id = value;
915 str = match_strval(value, ansi_tele_id_strings);
917 if (NULL == str) str = "Unrecognized Teleservice ID";
919 proto_tree_add_text(tree, tvb, offset, 2,
924 sprintf(add_string, " - %s (%d)", str, value);
928 trans_param_srvc_cat(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string)
931 const gchar *str = NULL;
933 EXACT_DATA_CHECK(len, 2);
935 value = tvb_get_ntohs(tvb, offset);
937 str = match_strval(value, ansi_srvc_cat_strings);
939 if (NULL == str) str = "Reserved";
941 proto_tree_add_text(tree, tvb, offset, 2,
944 sprintf(add_string, " - %s (%d)", str, value);
948 trans_param_address(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string)
950 guint8 oct, oct2, num_fields, odd;
952 guint32 saved_offset;
953 guint32 required_octs;
957 SHORT_DATA_CHECK(len, 2);
959 add_string = add_string;
962 oct = tvb_get_guint8(tvb, offset);
964 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
965 proto_tree_add_text(tree, tvb, offset, 1,
966 "%s : Digit mode: %s",
968 (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
970 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
971 proto_tree_add_text(tree, tvb, offset, 1,
972 "%s : Number mode: %s",
974 (oct & 0x40) ? "Data Network Address" : "ANSI T1.607");
980 switch ((oct & 0x38) >> 3)
982 case 0: str = "Unknown"; break;
983 case 1: str = "Internet Protocol (RFC 791)"; break;
984 case 2: str = "Internet Email Address (RFC 822)"; email_addr = TRUE; break;
990 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
991 proto_tree_add_text(tree, tvb, offset, 1,
992 "%s : Type of number: %s (%d)",
998 num_fields = (oct & 0x07) << 5;
999 oct2 = tvb_get_guint8(tvb, offset);
1000 num_fields |= ((oct2 & 0xf8) >> 3);
1002 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1003 proto_tree_add_text(tree, tvb, offset-1, 1,
1004 "%s : Number of fields (MSB): (%d)",
1008 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
1009 proto_tree_add_text(tree, tvb, offset, 1,
1010 "%s : Number of fields (LSB)",
1013 if (num_fields == 0) return;
1015 if (num_fields > (len - 2))
1017 proto_tree_add_text(tree, tvb, offset, 1,
1018 "Missing %d octet(s) for number of fields",
1019 (num_fields + 2) - len);
1024 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
1025 proto_tree_add_text(tree, tvb, offset, 1,
1026 "%s : Most significant bits of first field",
1033 while (i < num_fields)
1035 ansi_637_bigbuf[i] = (oct & 0x07) << 5;
1036 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf8) >> 3;
1039 ansi_637_bigbuf[i] = '\0';
1043 proto_tree_add_text(tree, tvb, offset, num_fields - 1,
1049 proto_tree_add_bytes(tree, hf_ansi_637_bin_addr, tvb, offset, num_fields - 1,
1053 offset += (num_fields - 1);
1055 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
1056 proto_tree_add_text(tree, tvb, offset, 1,
1057 "%s : Least significant bits of last field",
1060 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1061 proto_tree_add_text(tree, tvb, offset, 1,
1067 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
1068 proto_tree_add_text(tree, tvb, offset, 1,
1069 "%s : Type of number: (%d)",
1073 oct2 = tvb_get_guint8(tvb, offset + 1);
1075 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1076 proto_tree_add_text(tree, tvb, offset, 1,
1077 "%s : Numbering plan (MSB): (%d)",
1079 ((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7));
1084 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1085 proto_tree_add_text(tree, tvb, offset, 1,
1086 "%s : Numbering plan (LSB)",
1090 num_fields = (oct & 0x7f) << 1;
1091 oct2 = tvb_get_guint8(tvb, offset);
1092 num_fields |= ((oct2 & 0x80) >> 7);
1094 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1095 proto_tree_add_text(tree, tvb, offset-1, 1,
1096 "%s : Number of fields (MSB): (%d)",
1100 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
1101 proto_tree_add_text(tree, tvb, offset, 1,
1102 "%s : Number of fields (LSB)",
1105 if (num_fields == 0) return;
1107 if (num_fields > (len - 3))
1109 proto_tree_add_text(tree, tvb, offset, 1,
1110 "Missing %d octet(s) for number of fields",
1111 (num_fields + 3) - len);
1116 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x7f, 8);
1117 proto_tree_add_text(tree, tvb, offset, 1,
1118 "%s : Most significant bits of first field",
1125 while (i < num_fields)
1127 ansi_637_bigbuf[i] = (oct & 0x7f) << 1;
1128 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0x80) >> 7;
1131 ansi_637_bigbuf[i] = '\0';
1133 proto_tree_add_text(tree, tvb, offset, num_fields - 1,
1137 offset += (num_fields - 1);
1139 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1140 proto_tree_add_text(tree, tvb, offset, 1,
1141 "%s : Least significant bit of last field",
1144 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1145 proto_tree_add_text(tree, tvb, offset, 1,
1153 num_fields = (oct & 0x3f) << 2;
1154 oct2 = tvb_get_guint8(tvb, offset);
1155 num_fields |= ((oct2 & 0xc0) >> 6);
1157 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1158 proto_tree_add_text(tree, tvb, offset-1, 1,
1159 "%s : Number of fields (MSB): (%d)",
1163 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xc0, 8);
1164 proto_tree_add_text(tree, tvb, offset, 1,
1165 "%s : Number of fields (LSB)",
1173 i = (num_fields - 1) * 4;
1174 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
1176 if (required_octs + 2 > len)
1178 proto_tree_add_text(tree, tvb, offset, 1,
1179 "Missing %d octet(s) for number of fields",
1180 (required_octs + 2) - len);
1185 odd = num_fields & 0x01;
1186 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
1187 saved_offset = offset;
1191 while (i < num_fields)
1193 ansi_637_bigbuf[i] =
1194 air_digits[(oct & 0x3c) >> 2];
1197 if (i >= num_fields) break;
1199 oct2 = tvb_get_guint8(tvb, offset);
1202 ansi_637_bigbuf[i] =
1203 air_digits[((oct & 0x03) << 2) | ((oct2 & 0xc0) >> 6)];
1210 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
1215 other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x03: 0x3f, 8);
1216 proto_tree_add_text(tree, tvb, offset, 1,
1223 trans_param_subaddress(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string)
1225 guint8 oct, oct2, num_fields;
1229 SHORT_DATA_CHECK(len, 2);
1231 add_string = add_string;
1233 oct = tvb_get_guint8(tvb, offset);
1235 switch ((oct & 0xe0) >> 5)
1237 case 0: str = "NSAP (CCITT Recommendation X.213 or ISO 8348 AD2)"; break;
1238 case 1: str = "User-specified"; break;
1244 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xe0, 8);
1245 proto_tree_add_text(tree, tvb, offset, 1,
1250 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x10, 8);
1251 proto_tree_add_text(tree, tvb, offset, 1,
1256 num_fields = (oct & 0x0f) << 4;
1257 oct2 = tvb_get_guint8(tvb, offset);
1258 num_fields |= ((oct2 & 0xf0) >> 4);
1260 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1261 proto_tree_add_text(tree, tvb, offset-1, 1,
1262 "%s : Number of fields (MSB): (%d)",
1266 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf0, 8);
1267 proto_tree_add_text(tree, tvb, offset, 1,
1268 "%s : Number of fields (LSB)",
1271 if (num_fields == 0) return;
1273 if (num_fields > (len - 2))
1275 proto_tree_add_text(tree, tvb, offset, 1,
1276 "Missing %d octet(s) for number of fields",
1277 (num_fields + 2) - len);
1282 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x0f, 8);
1283 proto_tree_add_text(tree, tvb, offset, 1,
1284 "%s : Most significant bits of first field",
1291 while (i < num_fields)
1293 ansi_637_bigbuf[i] = (oct & 0x0f) << 4;
1294 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf0) >> 4;
1297 ansi_637_bigbuf[i] = '\0';
1299 proto_tree_add_bytes(tree, hf_ansi_637_bin_addr, tvb, offset, num_fields - 1,
1302 offset += (num_fields - 1);
1304 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf0, 8);
1305 proto_tree_add_text(tree, tvb, offset, 1,
1306 "%s : Least significant bits of last field",
1309 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1310 proto_tree_add_text(tree, tvb, offset, 1,
1316 trans_param_bearer_reply_opt(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string)
1321 oct = tvb_get_guint8(tvb, offset);
1323 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
1324 proto_tree_add_text(tree, tvb, offset, 1,
1325 "%s : Reply Sequence Number: %d",
1329 sprintf(add_string, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
1331 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
1332 proto_tree_add_text(tree, tvb, offset, 1,
1338 trans_param_cause_codes(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string)
1343 oct = tvb_get_guint8(tvb, offset);
1345 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
1346 proto_tree_add_text(tree, tvb, offset, 1,
1347 "%s : Reply Sequence Number: %d",
1353 case 0x00: str = "No error"; break;
1354 case 0x02: str = "Temporary Condition"; break;
1355 case 0x03: str = "Permanent Condition"; break;
1361 sprintf(add_string, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
1363 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
1364 proto_tree_add_text(tree, tvb, offset, 1,
1365 "%s : Error Class: %s",
1371 if (!(oct & 0x03)) return;
1373 if (len == 1) return;
1375 oct = tvb_get_guint8(tvb, offset);
1379 case 0: str = "Address vacant"; break;
1380 case 1: str = "Address translation failure"; break;
1381 case 2: str = "Network resource shortage"; break;
1382 case 3: str = "Network failure"; break;
1383 case 4: str = "Invalid Teleservice ID"; break;
1384 case 5: str = "Other network problem"; break;
1385 case 6: str = "Unsupported network interface"; break;
1386 case 32: str = "No page response"; break;
1387 case 33: str = "Destination busy"; break;
1388 case 34: str = "No acknowledgement"; break;
1389 case 35: str = "Destination resource shortage"; break;
1390 case 36: str = "SMS delivery postponed"; break;
1391 case 37: str = "Destination out of service"; break;
1392 case 38: str = "Destination no longer at this address"; break;
1393 case 39: str = "Other terminal problem"; break;
1394 case 64: str = "Radio interface resource shortage"; break;
1395 case 65: str = "Radio interface incompatibility"; break;
1396 case 66: str = "Other radio interface problem"; break;
1397 case 67: str = "Unsupported Base Station Capability"; break;
1398 case 96: str = "Encoding problem"; break;
1399 case 97: str = "Service origination denied"; break;
1400 case 98: str = "Service termination denied"; break;
1401 case 99: str = "Supplementary service not supported"; break;
1402 case 100: str = "Service not supported"; break;
1403 case 101: str = "Reserved"; break;
1404 case 102: str = "Missing expected parameter"; break;
1405 case 103: str = "Missing mandatory parameter"; break;
1406 case 104: str = "Unrecognized parameter value"; break;
1407 case 105: str = "Unexpected parameter value"; break;
1408 case 106: str = "User Data size error"; break;
1409 case 107: str = "Other general problems"; break;
1410 case 108: str = "Session not active"; break;
1412 if ((oct >= 7) && (oct <= 31)) { str = "Reserved, treat as Other network problem"; }
1413 else if ((oct >= 40) && (oct <= 47)) { str = "Reserved, treat as Other terminal problem"; }
1414 else if ((oct >= 48) && (oct <= 63)) { str = "Reserved, treat as SMS delivery postponed"; }
1415 else if ((oct >= 68) && (oct <= 95)) { str = "Reserved, treat as Other radio interface problem"; }
1416 else if ((oct >= 109) && (oct <= 223)) { str = "Reserved, treat as Other general problems"; }
1417 else { str = "Reserved for protocol extension, treat as Other general problems"; }
1421 proto_tree_add_text(tree, tvb, offset, 1,
1426 trans_param_bearer_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string)
1430 add_string = add_string;
1432 proto_tree_add_text(tree, tvb, offset, len,
1436 * dissect the embedded teleservice data
1438 tele_tvb = tvb_new_subset(tvb, offset, len, len);
1440 dissector_try_port(tele_dissector_table, ansi_637_trans_tele_id,
1441 tele_tvb, g_pinfo, g_tree);
1444 #define NUM_TRANS_PARAM (sizeof(ansi_trans_param_strings)/sizeof(value_string))
1445 static gint ett_ansi_637_trans_param[NUM_TRANS_PARAM];
1446 static void (*ansi_637_trans_param_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string) = {
1447 trans_param_tele_id, /* Teleservice Identifier */
1448 trans_param_srvc_cat, /* Service Category */
1449 trans_param_address, /* Originating Address */
1450 trans_param_subaddress, /* Originating Subaddress */
1451 trans_param_address, /* Destination Address */
1452 trans_param_subaddress, /* Destination Subaddress */
1453 trans_param_bearer_reply_opt, /* Bearer Reply Option */
1454 trans_param_cause_codes, /* Cause Codes */
1455 trans_param_bearer_data, /* Bearer Data */
1459 #define NUM_TRANS_MSG_TYPE (sizeof(ansi_trans_msg_type_strings)/sizeof(value_string))
1460 static gint ett_ansi_637_trans_msg[NUM_TRANS_MSG_TYPE];
1462 /* GENERIC IS-637 DISSECTOR FUNCTIONS */
1465 dissect_ansi_637_tele_param(tvbuff_t *tvb, proto_tree *tree, guint32 *offset)
1467 void (*param_fcn)(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = NULL;
1470 guint32 curr_offset;
1471 gint ett_param_idx, idx;
1472 proto_tree *subtree;
1474 const gchar *str = NULL;
1477 curr_offset = *offset;
1479 oct = tvb_get_guint8(tvb, curr_offset);
1480 str = match_strval_idx((guint32) oct, ansi_tele_param_strings, &idx);
1487 ett_param_idx = ett_ansi_637_tele_param[idx];
1488 param_fcn = ansi_637_tele_param_fcn[idx];
1491 proto_tree_add_text(tree, tvb, curr_offset, -1, str);
1493 subtree = proto_item_add_subtree(item, ett_param_idx);
1495 proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id,
1496 tvb, curr_offset, 1, oct);
1500 len = tvb_get_guint8(tvb, curr_offset);
1502 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
1504 proto_tree_add_uint(subtree, hf_ansi_637_length,
1505 tvb, curr_offset, 1, len);
1511 if (param_fcn == NULL)
1513 proto_tree_add_text(subtree, tvb, curr_offset,
1514 len, "Parameter Data");
1518 (*param_fcn)(tvb, subtree, len, curr_offset);
1524 *offset = curr_offset;
1530 dissect_ansi_637_tele_message(tvbuff_t *tvb, proto_tree *ansi_637_tree)
1535 guint32 curr_offset;
1536 /* guint32 msg_id; */
1538 const gchar *str = NULL;
1540 proto_tree *subtree;
1543 oct = tvb_get_guint8(tvb, 0);
1549 len = tvb_get_guint8(tvb, 1);
1555 octs = tvb_get_ntoh24(tvb, 2);
1556 msg_type = (octs >> 20) & 0x0f;
1557 /* msg_id = (octs >> 4) & 0xffff; */
1559 str = match_strval(msg_type, ansi_tele_msg_type_strings);
1562 * do not append to COL_INFO
1566 proto_tree_add_none_format(ansi_637_tree, hf_ansi_637_none,
1569 subtree = proto_item_add_subtree(item, ett_params);
1571 proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id,
1574 proto_tree_add_uint(subtree, hf_ansi_637_length,
1577 proto_tree_add_uint(subtree, hf_ansi_637_tele_msg_type,
1580 proto_tree_add_uint(subtree, hf_ansi_637_tele_msg_id,
1583 proto_tree_add_uint(subtree, hf_ansi_637_tele_msg_rsvd,
1586 proto_item_set_len(item, 2 + len);
1588 curr_offset = 2 + len;
1589 len = tvb_length(tvb);
1591 while ((len - curr_offset) > 0)
1593 if (!dissect_ansi_637_tele_param(tvb, ansi_637_tree, &curr_offset))
1595 proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
1596 "Unknown Parameter Data");
1603 dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1605 proto_item *ansi_637_item;
1606 proto_tree *ansi_637_tree = NULL;
1607 const gchar *str = NULL;
1609 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1611 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
1614 /* In the interest of speed, if "tree" is NULL, don't do any work not
1615 * necessary to generate protocol tree items.
1620 * create the ansi_637 protocol tree
1622 str = match_strval(pinfo->match_port, ansi_tele_id_strings);
1624 if (NULL == str) str = "Unrecognized Teleservice ID";
1627 proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
1629 ansi_proto_name_tele,
1634 proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele);
1636 dissect_ansi_637_tele_message(tvb, ansi_637_tree);
1641 dissect_ansi_637_trans_param(tvbuff_t *tvb, proto_tree *tree, guint32 *offset)
1643 void (*param_fcn)(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string) = NULL;
1646 guint32 curr_offset;
1647 gint ett_param_idx, idx;
1648 proto_tree *subtree;
1650 const gchar *str = NULL;
1652 curr_offset = *offset;
1654 oct = tvb_get_guint8(tvb, curr_offset);
1655 str = match_strval_idx((guint32) oct, ansi_trans_param_strings, &idx);
1662 ett_param_idx = ett_ansi_637_trans_param[idx];
1663 param_fcn = ansi_637_trans_param_fcn[idx];
1666 proto_tree_add_text(tree, tvb, curr_offset, -1, str);
1668 subtree = proto_item_add_subtree(item, ett_param_idx);
1670 proto_tree_add_uint(subtree, hf_ansi_637_trans_param_id,
1671 tvb, curr_offset, 1, oct);
1675 len = tvb_get_guint8(tvb, curr_offset);
1677 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
1679 proto_tree_add_uint(subtree, hf_ansi_637_length,
1680 tvb, curr_offset, 1, len);
1686 if (param_fcn == NULL)
1688 proto_tree_add_text(subtree, tvb, curr_offset,
1689 len, "Parameter Data");
1693 ansi_637_add_string[0] = '\0';
1694 (*param_fcn)(tvb, subtree, len, curr_offset, ansi_637_add_string);
1696 if (ansi_637_add_string[0] != '\0')
1698 proto_item_append_text(item, "%s", ansi_637_add_string);
1705 *offset = curr_offset;
1711 dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1713 proto_item *ansi_637_item;
1714 proto_tree *ansi_637_tree = NULL;
1715 guint32 curr_offset;
1717 const gchar *str = NULL;
1721 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1723 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
1726 /* In the interest of speed, if "tree" is NULL, don't do any work not
1727 * necessary to generate protocol tree items.
1735 * create the ansi_637 protocol tree
1737 oct = tvb_get_guint8(tvb, 0);
1739 str = match_strval_idx(oct, ansi_trans_msg_type_strings, &idx);
1744 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
1745 "%s - Unrecognized Transport Layer Message Type (%d)",
1746 ansi_proto_name_trans,
1750 proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans);
1755 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
1757 ansi_proto_name_trans,
1761 proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans_msg[idx]);
1766 len = tvb_length(tvb);
1768 while ((len - curr_offset) > 0)
1770 if (!dissect_ansi_637_trans_param(tvb, ansi_637_tree, &curr_offset))
1772 proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
1773 "Unknown Parameter Data");
1780 /* Register the protocol with Ethereal */
1782 proto_register_ansi_637(void)
1786 /* Setup list of header fields */
1787 static hf_register_info hf[] =
1789 { &hf_ansi_637_trans_msg_type,
1791 "ansi_637.trans_msg_type",
1792 FT_UINT24, BASE_DEC, VALS(ansi_trans_msg_type_strings), 0xf00000,
1794 { &hf_ansi_637_tele_msg_type,
1796 "ansi_637.tele_msg_type",
1797 FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_type_strings), 0xf00000,
1799 { &hf_ansi_637_tele_msg_id,
1801 "ansi_637.tele_msg_id",
1802 FT_UINT24, BASE_DEC, NULL, 0x0ffff0,
1804 { &hf_ansi_637_tele_msg_rsvd,
1806 "ansi_637.tele_msg_rsvd",
1807 FT_UINT24, BASE_DEC, NULL, 0x00000f,
1809 { &hf_ansi_637_length,
1810 { "Length", "ansi_637.len",
1811 FT_UINT8, BASE_DEC, NULL, 0,
1814 { &hf_ansi_637_none,
1815 { "Sub tree", "ansi_637.none",
1819 { &hf_ansi_637_tele_subparam_id,
1820 { "Teleservice Subparam ID", "ansi_637.tele_subparam_id",
1821 FT_UINT8, BASE_DEC, VALS(ansi_tele_param_strings), 0,
1824 { &hf_ansi_637_trans_param_id,
1825 { "Transport Param ID", "ansi_637.trans_param_id",
1826 FT_UINT8, BASE_DEC, VALS(ansi_trans_param_strings), 0,
1829 { &hf_ansi_637_bin_addr,
1830 { "Binary Address", "ansi_637.bin_addr",
1831 FT_BYTES, BASE_HEX, 0, 0,
1836 /* Setup protocol subtree array */
1837 #define NUM_INDIVIDUAL_PARAMS 3
1838 static gint *ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM];
1840 memset((void *) ett, 0, sizeof(ett));
1842 ett[0] = &ett_ansi_637_tele;
1843 ett[1] = &ett_ansi_637_trans;
1844 ett[2] = &ett_params;
1846 for (i=0; i < NUM_TELE_PARAM; i++)
1848 ett_ansi_637_tele_param[i] = -1;
1849 ett[NUM_INDIVIDUAL_PARAMS+i] = &ett_ansi_637_tele_param[i];
1852 for (i=0; i < NUM_TRANS_MSG_TYPE; i++)
1854 ett_ansi_637_trans_msg[i] = -1;
1855 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+i] = &ett_ansi_637_trans_msg[i];
1858 for (i=0; i < NUM_TRANS_PARAM; i++)
1860 ett_ansi_637_trans_param[i] = -1;
1861 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+i] = &ett_ansi_637_trans_param[i];
1864 /* Register the protocol name and description */
1865 proto_ansi_637_tele =
1866 proto_register_protocol(ansi_proto_name_tele, "ANSI IS-637-A Teleservice", "ansi_637_tele");
1868 proto_ansi_637_trans =
1869 proto_register_protocol(ansi_proto_name_trans, "ANSI IS-637-A Transport", "ansi_637_trans");
1871 /* Required function calls to register the header fields and subtrees used */
1872 proto_register_field_array(proto_ansi_637_tele, hf, array_length(hf));
1873 proto_register_subtree_array(ett, array_length(ett));
1875 tele_dissector_table =
1876 register_dissector_table("ansi_637.tele_id",
1877 "ANSI IS-637-A Teleservice ID", FT_UINT8, BASE_DEC);
1882 proto_reg_handoff_ansi_637(void)
1884 dissector_handle_t ansi_637_tele_handle;
1885 dissector_handle_t ansi_637_trans_handle;
1888 ansi_637_tele_handle = create_dissector_handle(dissect_ansi_637_tele, proto_ansi_637_tele);
1889 ansi_637_trans_handle = create_dissector_handle(dissect_ansi_637_trans, proto_ansi_637_trans);
1892 * register for all known teleservices
1893 * '-1' is to stop before trailing '0' entry
1895 * to add teleservices, modify 'ansi_tele_id_strings'
1897 for (i=0; i < ((sizeof(ansi_tele_id_strings)/sizeof(value_string))-1); i++)
1900 * ANSI MAP dissector will push out teleservice ids
1902 dissector_add("ansi_map.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
1905 * we will push out teleservice ids after Transport layer decode
1907 dissector_add("ansi_637.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
1911 * ANSI A-interface will push out transport layer data
1913 dissector_add("ansi_a.sms", 0, ansi_637_trans_handle);
1915 /* data_handle = find_dissector("data"); */