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.
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"
52 #include "epan/emem.h"
55 static const char *ansi_proto_name_tele = "ANSI IS-637-A (SMS) Teleservice Layer";
56 static const char *ansi_proto_name_trans = "ANSI IS-637-A (SMS) Transport Layer";
57 static const char *ansi_proto_name_short = "IS-637-A";
59 static const value_string ansi_srvc_cat_strings[] = {
60 { 0x0000, "Unknown or unspecified" },
61 { 0x0001, "Emergency Broadcasts" },
62 { 0x0002, "Administrative" },
63 { 0x0003, "Maintenance" },
64 { 0x0004, "General News - Local" },
65 { 0x0005, "General News - Regional" },
66 { 0x0006, "General News - National" },
67 { 0x0007, "General News - International" },
68 { 0x0008, "Business/Financial News - Local" },
69 { 0x0009, "Business/Financial News - Regional" },
70 { 0x000A, "Business/Financial News - National" },
71 { 0x000B, "Business/Financial News - International" },
72 { 0x000C, "Sports News - Local" },
73 { 0x000D, "Sports News - Regional" },
74 { 0x000E, "Sports News - National" },
75 { 0x000F, "Sports News - International" },
76 { 0x0010, "Entertainment News - Local" },
77 { 0x0011, "Entertainment News - Regional" },
78 { 0x0012, "Entertainment News - National" },
79 { 0x0013, "Entertainment News - International" },
80 { 0x0014, "Local Weather" },
81 { 0x0015, "Area Traffic Reports" },
82 { 0x0016, "Local Airport Flight Schedules" },
83 { 0x0017, "Restaurants" },
84 { 0x0018, "Lodgings" },
85 { 0x0019, "Retail Directory" },
86 { 0x001A, "Advertisements" },
87 { 0x001B, "Stock Quotes" },
88 { 0x001C, "Employment Opportunities" },
89 { 0x001D, "Medical/Health/Hospitals" },
90 { 0x001E, "Technology News" },
91 { 0x001F, "Multi-category" },
95 static const value_string ansi_tele_msg_type_strings[] = {
96 { 1, "Deliver (mobile-terminated only)" },
97 { 2, "Submit (mobile-originated only)" },
98 { 3, "Cancellation (mobile-originated only)" },
99 { 4, "Delivery Acknowledgement (mobile-terminated only)" },
100 { 5, "User Acknowledgement (either direction)" },
104 static const value_string ansi_tele_id_strings[] = {
105 { 1, "Reserved for maintenance" },
106 { 4096, "AMPS Extended Protocol Enhanced Services" },
107 { 4097, "CDMA Cellular Paging Teleservice" },
108 { 4098, "CDMA Cellular Messaging Teleservice" },
109 { 4099, "CDMA Voice Mail Notification" },
110 { 4100, "CDMA Wireless Application Protocol (WAP)" },
111 { 4101, "CDMA Wireless Enhanced Messaging Teleservice (WEMT)" },
112 { 65535, "(Reserved) Being used for Broadcast" },
116 static const value_string ansi_tele_param_strings[] = {
117 { 0x00, "Message Identifier" },
118 { 0x01, "User Data" },
119 { 0x02, "User Response Code" },
120 { 0x03, "Message Center Time Stamp" },
121 { 0x04, "Validity Period - Absolute" },
122 { 0x05, "Validity Period - Relative" },
123 { 0x06, "Deferred Delivery Time - Absolute" },
124 { 0x07, "Deferred Delivery Time - Relative" },
125 { 0x08, "Priority Indicator" },
126 { 0x09, "Privacy Indicator" },
127 { 0x0a, "Reply Option" },
128 { 0x0b, "Number of Messages" },
129 { 0x0c, "Alert on Message Delivery" },
130 { 0x0d, "Language Indicator" },
131 { 0x0e, "Call-Back Number" },
132 { 0x0f, "Message Display Mode" },
133 { 0x10, "Multiple Encoding User Data" },
137 #define ANSI_TRANS_MSG_TYPE_BROADCAST 1
139 static const value_string ansi_trans_msg_type_strings[] = {
140 { 0, "Point-to-Point" },
142 { 2, "Acknowledge" },
146 static const value_string ansi_trans_param_strings[] = {
147 { 0x00, "Teleservice Identifier" },
148 { 0x01, "Service Category" },
149 { 0x02, "Originating Address" },
150 { 0x03, "Originating Subaddress" },
151 { 0x04, "Destination Address" },
152 { 0x05, "Destination Subaddress" },
153 { 0x06, "Bearer Reply Option" },
154 { 0x07, "Cause Codes" },
155 { 0x08, "Bearer Data" },
160 * from Table 2.7.1.3.2.4-4. Representation of DTMF Digits
161 * 3GPP2 C.S0005-C (IS-2000 aka cdma2000)
163 static unsigned char air_digits[] = {
164 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
165 '?','1','2','3','4','5','6','7','8','9','0','*','#','?','?'
168 /* Initialize the protocol and registered fields */
169 static int proto_ansi_637_tele = -1;
170 static int proto_ansi_637_trans = -1;
171 static int hf_ansi_637_tele_length = -1;
172 static int hf_ansi_637_trans_length = -1;
173 static int hf_ansi_637_trans_bin_addr = -1;
174 static int hf_ansi_637_tele_msg_type = -1;
175 static int hf_ansi_637_tele_msg_id = -1;
176 static int hf_ansi_637_tele_msg_rsvd = -1;
177 static int hf_ansi_637_tele_subparam_id = -1;
178 static int hf_ansi_637_trans_msg_type = -1;
179 static int hf_ansi_637_trans_param_id = -1;
181 /* Initialize the subtree pointers */
182 static gint ett_ansi_637_tele = -1;
183 static gint ett_ansi_637_trans = -1;
184 static gint ett_params = -1;
186 static guint32 ansi_637_trans_tele_id;
187 static char ansi_637_bigbuf[1024];
188 /* static dissector_handle_t data_handle; */
189 static dissector_table_t tele_dissector_table;
190 static packet_info *g_pinfo;
191 static proto_tree *g_tree;
196 decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oct, guint8 *last_bit, gchar *buf)
198 guint8 oct, oct2, bit;
199 /* guint32 saved_offset; */
208 /* saved_offset = *offset; */
209 oct = oct2 = *last_oct;
214 oct2 = tvb_get_guint8(tvb, *offset);
218 for (i=0; i < num_fields; i++)
225 * cannot grab an octet if we are getting
226 * the last field and bit is 7 or 8
227 * because there may not be another octet
229 if (((i + 1) != num_fields) ||
230 ((bit != 7) && (bit != 8)))
232 oct2 = tvb_get_guint8(tvb, *offset);
240 buf[i] = ((oct & 0x01) << 6) | ((oct2 & 0xfc) >> 2);
244 buf[i] = ((oct & 0x03) << 5) | ((oct2 & 0xf8) >> 3);
248 buf[i] = ((oct & 0x07) << 4) | ((oct2 & 0xf0) >> 4);
252 buf[i] = ((oct & 0x0f) << 3) | ((oct2 & 0xe0) >> 5);
256 buf[i] = ((oct & 0x1f) << 2) | ((oct2 & 0xc0) >> 6);
260 buf[i] = ((oct & 0x3f) << 1) | ((oct2 & 0x80) >> 7);
268 buf[i] = (oct & 0xfe) >> 1;
277 *last_oct = (bit == 1) ? oct : oct2;
280 /* PARAM FUNCTIONS */
282 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
283 if ((edc_len) > (edc_max_len)) \
285 proto_tree_add_text(tree, tvb, offset, \
286 (edc_len) - (edc_max_len), "Extraneous Data"); \
289 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
290 if ((sdc_len) < (sdc_min_len)) \
292 proto_tree_add_text(tree, tvb, offset, \
293 (sdc_len), "Short Data (?)"); \
297 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
298 if ((edc_len) != (edc_eq_len)) \
300 proto_tree_add_text(tree, tvb, offset, \
301 (edc_len), "Unexpected Data Length"); \
306 tele_param_msg_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
310 EXACT_DATA_CHECK(len, 3);
312 octs = tvb_get_ntoh24(tvb, offset);
314 proto_tree_add_uint(tree, hf_ansi_637_tele_msg_type,
315 tvb, offset, 3, octs);
317 proto_tree_add_uint(tree, hf_ansi_637_tele_msg_id,
318 tvb, offset, 3, octs);
320 proto_tree_add_uint(tree, hf_ansi_637_tele_msg_rsvd,
321 tvb, offset, 3, octs);
325 tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
333 guint32 required_octs;
334 guint32 saved_offset;
336 const gchar *str = NULL;
338 SHORT_DATA_CHECK(len, 2);
343 oct = tvb_get_guint8(tvb, offset);
348 encoding = ((oct & 0xf8) >> 3);
351 case 0x00: str = "Octet, unspecified"; break;
352 case 0x01: str = "Extended Protocol Message";
353 oct2 = tvb_get_guint8(tvb, offset+1);
354 msg_type = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
356 case 0x02: str = "7-bit ASCII"; break;
357 case 0x03: str = "IA5"; break;
358 case 0x04: str = "UNICODE"; break;
359 case 0x05: str = "Shift-JIS"; break;
360 case 0x06: str = "Korean"; break;
361 case 0x07: str = "Latin/Hebrew"; break;
362 case 0x08: str = "Latin"; break;
363 case 0x09: str = "GSM 7-bit default alphabet"; break;
364 default: str = "Reserved"; break;
367 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
368 proto_tree_add_text(tree, tvb, offset, 1,
373 if (encoding == 0x01)
375 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
376 proto_tree_add_text(tree, tvb, offset, 1,
377 "%s : Message type: see TIA/EIA/IS-91 (%d)",
381 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
382 proto_tree_add_text(tree, tvb, offset+1, 1,
397 oct2 = tvb_get_guint8(tvb, offset);
398 num_fields = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
400 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
401 proto_tree_add_text(tree, tvb, offset-1, 1,
402 "%s : Number of fields (MSB): %d",
406 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
407 proto_tree_add_text(tree, tvb, offset, 1,
408 "%s : Number of fields (LSB)",
411 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
412 proto_tree_add_text(tree, tvb, offset, 1,
413 "%s : Most significant bits of first field",
420 /* NOTE: there are now 3 bits remaining in 'oct' */
422 if (len <= used) return;
425 * decode rest if 7-bit ASCII
427 if (encoding == 0x02)
431 * 3 bits remaining from last octet
435 i = (num_fields * 7) - 3;
436 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
438 if (required_octs + used > len)
440 proto_tree_add_text(tree, tvb, offset, 1,
441 "Missing %d octet(s) for number of fields",
442 (required_octs + used) - len);
448 saved_offset = offset;
450 decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
452 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
453 "Encoded user data: %s",
458 case 1: oct2 = 0x01; break;
459 case 2: oct2 = 0x03; break;
460 case 3: oct2 = 0x07; break;
461 case 4: oct2 = 0x0f; break;
462 case 5: oct2 = 0x1f; break;
463 case 6: oct2 = 0x3f; break;
464 case 7: oct2 = 0x7f; break;
469 other_decode_bitfield_value(ansi_637_bigbuf, oct, oct2, 8);
470 proto_tree_add_text(tree, tvb, offset - 1, 1,
477 proto_tree_add_text(tree, tvb, offset, len - used,
478 "Encoded user data");
483 tele_param_rsp_code(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
487 EXACT_DATA_CHECK(len, 1);
492 oct = tvb_get_guint8(tvb, offset);
494 proto_tree_add_text(tree, tvb, offset, 1,
500 tele_param_timestamp(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
502 guint8 oct, oct2, oct3;
504 EXACT_DATA_CHECK(len, 6);
506 oct = tvb_get_guint8(tvb, offset);
507 oct2 = tvb_get_guint8(tvb, offset+1);
508 oct3 = tvb_get_guint8(tvb, offset+2);
510 proto_tree_add_text(tree, tvb, offset, 3,
511 "Year %d%d, Month %d%d, Day %d%d",
521 oct = tvb_get_guint8(tvb, offset);
522 oct2 = tvb_get_guint8(tvb, offset+1);
523 oct3 = tvb_get_guint8(tvb, offset+2);
525 proto_tree_add_text(tree, tvb, offset, 3,
526 "Hour %d%d, Minutes %d%d, Seconds %d%d",
536 tele_param_rel_timestamp(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
540 const gchar *str = NULL;
541 const gchar *str2 = NULL;
543 EXACT_DATA_CHECK(len, 1);
545 oct = tvb_get_guint8(tvb, offset);
549 case 245: str = "Indefinite"; break;
550 case 246: str = "Immediate"; break;
551 case 247: str = "Valid until mobile becomes inactive/Deliver when mobile next becomes active"; break;
552 case 248: str = "Valid until registration area changes, discard if not registered" ; break;
554 if (oct <= 143) { value = (oct + 1) * 5; str2 = "Minutes"; break; }
555 else if ((oct >= 144) && (oct <= 167)) { value = (oct - 143) * 30; str2 = "Minutes + 12 Hours"; break; }
556 else if ((oct >= 168) && (oct <= 196)) { value = oct - 166; str2 = "Days"; break; }
557 else if ((oct >= 197) && (oct <= 244)) { value = oct - 192; str2 = "Weeks"; break; }
558 else { str = "Reserved"; break; }
563 proto_tree_add_text(tree, tvb, offset, 1,
568 proto_tree_add_text(tree, tvb, offset, 1,
574 static const value_string tele_param_pri_ind_strings[] = {
576 { 1, "Interactive" },
583 tele_param_pri_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
586 const gchar *str = NULL;
588 EXACT_DATA_CHECK(len, 1);
590 oct = tvb_get_guint8(tvb, offset);
592 str=val_to_str((oct&0xc0)>>6, tele_param_pri_ind_strings, "Unknown");
594 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
595 proto_tree_add_text(tree, tvb, offset, 1,
600 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
601 proto_tree_add_text(tree, tvb, offset, 1,
607 tele_param_priv_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
610 const gchar *str = NULL;
612 EXACT_DATA_CHECK(len, 1);
614 oct = tvb_get_guint8(tvb, offset);
616 switch ((oct & 0xc0) >> 6)
618 case 0: str = "Not restricted (privacy level 0)"; break;
619 case 1: str = "Restricted (privacy level 1)"; break;
620 case 2: str = "Confidential (privacy level 2)"; break;
621 case 3: str = "Secret (privacy level 3)"; break;
624 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
625 proto_tree_add_text(tree, tvb, offset, 1,
630 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
631 proto_tree_add_text(tree, tvb, offset, 1,
637 tele_param_reply_opt(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
641 EXACT_DATA_CHECK(len, 1);
643 oct = tvb_get_guint8(tvb, offset);
645 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
646 proto_tree_add_text(tree, tvb, offset, 1,
647 "%s : %s (manual) acknowledgment is requested",
649 (oct & 0x80) ? "User" : "No user");
651 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
652 proto_tree_add_text(tree, tvb, offset, 1,
653 "%s : %s acknowledgment requested",
655 (oct & 0x40) ? "Delivery" : "No delivery");
657 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
658 proto_tree_add_text(tree, tvb, offset, 1,
664 tele_param_num_messages(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
668 EXACT_DATA_CHECK(len, 1);
670 oct = tvb_get_guint8(tvb, offset);
672 proto_tree_add_text(tree, tvb, offset, 1,
673 "Number of voice mail messages: %d%d",
679 tele_param_alert(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
682 const gchar *str = NULL;
684 EXACT_DATA_CHECK(len, 1);
686 oct = tvb_get_guint8(tvb, offset);
688 switch ((oct & 0xc0) >> 6)
690 case 0: str = "Use Mobile default alert"; break;
691 case 1: str = "Use Low-priority alert"; break;
692 case 2: str = "Use Medium-priority alert"; break;
693 case 3: str = "Use High-priority alert"; break;
696 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
697 proto_tree_add_text(tree, tvb, offset, 1,
702 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
703 proto_tree_add_text(tree, tvb, offset, 1,
709 tele_param_lang_ind(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
712 const gchar *str = NULL;
714 EXACT_DATA_CHECK(len, 1);
716 oct = tvb_get_guint8(tvb, offset);
720 case 0x00: str = "Unknown or unspecified"; break;
721 case 0x01: str = "English"; break;
722 case 0x02: str = "French"; break;
723 case 0x03: str = "Spanish"; break;
724 case 0x04: str = "Japanese"; break;
725 case 0x05: str = "Korean"; break;
726 case 0x06: str = "Chinese"; break;
727 case 0x07: str = "Hebrew"; break;
728 default: str = "Reserved"; break;
731 proto_tree_add_text(tree, tvb, offset, 1,
736 tele_param_cb_num(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
738 guint8 oct, oct2, num_fields, odd;
739 guint32 saved_offset;
740 guint32 required_octs;
743 SHORT_DATA_CHECK(len, 2);
745 oct = tvb_get_guint8(tvb, offset);
747 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
748 proto_tree_add_text(tree, tvb, offset, 1,
749 "%s : Digit mode: %s",
751 (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
755 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x70, 8);
756 proto_tree_add_text(tree, tvb, offset, 1,
757 "%s : Type of number: (%d)",
761 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
762 proto_tree_add_text(tree, tvb, offset, 1,
763 "%s : Numbering plan: (%d)",
768 num_fields = tvb_get_guint8(tvb, offset);
770 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xff, 8);
771 proto_tree_add_text(tree, tvb, offset, 1,
772 "%s : Number of fields: (%d)",
776 if (num_fields == 0) return;
778 if (num_fields > (len - 2))
780 proto_tree_add_text(tree, tvb, offset, 1,
781 "Missing %d octet(s) for number of fields",
782 (num_fields + 2) - len);
790 while (i < num_fields)
792 ansi_637_bigbuf[i] = tvb_get_guint8(tvb, offset+i) & 0x7f;
795 ansi_637_bigbuf[i] = '\0';
797 proto_tree_add_text(tree, tvb, offset, num_fields,
804 num_fields = (oct & 0x7f) << 1;
805 oct2 = tvb_get_guint8(tvb, offset);
806 num_fields |= ((oct2 & 0x80) >> 7);
808 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
809 proto_tree_add_text(tree, tvb, offset-1, 1,
810 "%s : Number of fields (MBS): (%d)",
814 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
815 proto_tree_add_text(tree, tvb, offset, 1,
816 "%s : Number of fields (LSB)",
824 i = (num_fields - 1) * 4;
825 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
827 if (required_octs + 2 > len)
829 proto_tree_add_text(tree, tvb, offset, 1,
830 "Missing %d octet(s) for number of fields",
831 (required_octs + 2) - len);
836 odd = num_fields & 0x01;
837 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
838 saved_offset = offset;
842 while (i < num_fields)
845 air_digits[(oct & 0x78) >> 3];
848 if (i >= num_fields) break;
850 oct2 = tvb_get_guint8(tvb, offset);
854 air_digits[((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7)];
861 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
866 other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x07: 0x7f, 8);
867 proto_tree_add_text(tree, tvb, offset, 1,
874 tele_param_disp_mode(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
877 const gchar *str = NULL;
879 EXACT_DATA_CHECK(len, 1);
881 oct = tvb_get_guint8(tvb, offset);
883 switch ((oct & 0xc0) >> 6)
885 case 0: str = "Immediate Display: The mobile station is to display the received message as soon as possible."; break;
886 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;
887 case 2: str = "User Invoke: The mobile station is to display the received message based on the mode selected by the user."; break;
888 case 3: str = "Reserved"; break;
891 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
892 proto_tree_add_text(tree, tvb, offset, 1,
897 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
898 proto_tree_add_text(tree, tvb, offset, 1,
903 #define NUM_TELE_PARAM (sizeof(ansi_tele_param_strings)/sizeof(value_string))
904 static gint ett_ansi_637_tele_param[NUM_TELE_PARAM];
905 static void (*ansi_637_tele_param_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = {
906 tele_param_msg_id, /* Message Identifier */
907 tele_param_user_data, /* User Data */
908 tele_param_rsp_code, /* User Response Code */
909 tele_param_timestamp, /* Message Center Time Stamp */
910 tele_param_timestamp, /* Validity Period Absolute */
911 tele_param_rel_timestamp, /* Validity Period Relative */
912 tele_param_timestamp, /* Deferred Delivery Time - Absolute */
913 tele_param_rel_timestamp, /* Deferred Delivery Time - Relative */
914 tele_param_pri_ind, /* Priority Indicator */
915 tele_param_priv_ind, /* Privacy Indicator */
916 tele_param_reply_opt, /* Reply Option */
917 tele_param_num_messages, /* Number of Messages */
918 tele_param_alert, /* Alert on Message Delivery */
919 tele_param_lang_ind, /* Language Indicator */
920 tele_param_cb_num, /* Call-Back Number */
921 tele_param_disp_mode, /* Message Display Mode */
922 NULL, /* Multiple Encoding User Data */
927 trans_param_tele_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
930 const gchar *str = NULL;
932 EXACT_DATA_CHECK(len, 2);
934 value = tvb_get_ntohs(tvb, offset);
936 ansi_637_trans_tele_id = value;
938 str = match_strval(value, ansi_tele_id_strings);
945 str = "Reserved for maintenance";
948 str = "CDMA Service Category Programming Teleservice (SCPT)";
951 str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
954 str = "TDMA Cellular Messaging Teleservice";
957 str = "TDMA Cellular Paging Teleservice (CPT-136)";
960 str = "TDMA Over-the-Air Activation Teleservice (OATS)";
963 str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
966 str = "TDMA Segmented System Assisted Mobile Positioning Service";
969 if ((value >= 2) && (value <= 4095))
971 str = "Reserved for assignment by TIA-41";
973 else if ((value >= 4104) && (value <= 4113))
975 str = "Reserved for GSM1x Teleservice (CDMA)";
977 else if ((value >= 4114) && (value <= 32512))
979 str = "Reserved for assignment by TIA-41";
981 else if ((value >= 32521) && (value <= 32575))
983 str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
985 else if ((value >= 49152) && (value <= 65535))
987 str = "Reserved for carrier specific teleservices";
991 str = "Unrecognized Teleservice ID";
997 proto_tree_add_text(tree, tvb, offset, 2,
1002 g_snprintf(add_string, string_len, " - %s (%d)", str, value);
1006 trans_param_srvc_cat(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1009 const gchar *str = NULL;
1011 EXACT_DATA_CHECK(len, 2);
1013 value = tvb_get_ntohs(tvb, offset);
1015 str = match_strval(value, ansi_srvc_cat_strings);
1017 if (NULL == str) str = "Reserved";
1019 proto_tree_add_text(tree, tvb, offset, 2,
1022 g_snprintf(add_string, string_len, " - %s (%d)", str, value);
1026 trans_param_address(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1028 guint8 oct, oct2, num_fields, odd;
1029 gboolean email_addr;
1030 guint32 saved_offset;
1031 guint32 required_octs;
1035 SHORT_DATA_CHECK(len, 2);
1039 oct = tvb_get_guint8(tvb, offset);
1041 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1042 proto_tree_add_text(tree, tvb, offset, 1,
1043 "%s : Digit mode: %s",
1045 (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
1047 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
1048 proto_tree_add_text(tree, tvb, offset, 1,
1049 "%s : Number mode: %s",
1051 (oct & 0x40) ? "Data Network Address" : "ANSI T1.607");
1057 switch ((oct & 0x38) >> 3)
1059 case 0: str = "Unknown"; break;
1060 case 1: str = "Internet Protocol (RFC 791)"; break;
1061 case 2: str = "Internet Email Address (RFC 822)"; email_addr = TRUE; break;
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: %s (%d)",
1075 num_fields = (oct & 0x07) << 5;
1076 oct2 = tvb_get_guint8(tvb, offset);
1077 num_fields |= ((oct2 & 0xf8) >> 3);
1079 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1080 proto_tree_add_text(tree, tvb, offset-1, 1,
1081 "%s : Number of fields (MSB): (%d)",
1085 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
1086 proto_tree_add_text(tree, tvb, offset, 1,
1087 "%s : Number of fields (LSB)",
1090 if (num_fields == 0) return;
1092 if (num_fields > (len - 2))
1094 proto_tree_add_text(tree, tvb, offset, 1,
1095 "Missing %d octet(s) for number of fields",
1096 (num_fields + 2) - len);
1101 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
1102 proto_tree_add_text(tree, tvb, offset, 1,
1103 "%s : Most significant bits of first field",
1110 while (i < num_fields)
1112 ansi_637_bigbuf[i] = (oct & 0x07) << 5;
1113 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf8) >> 3;
1116 ansi_637_bigbuf[i] = '\0';
1120 proto_tree_add_text(tree, tvb, offset, num_fields - 1,
1126 proto_tree_add_bytes(tree, hf_ansi_637_trans_bin_addr, tvb, offset, num_fields - 1,
1127 (guint8*)ansi_637_bigbuf);
1130 offset += (num_fields - 1);
1132 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
1133 proto_tree_add_text(tree, tvb, offset, 1,
1134 "%s : Least significant bits of last field",
1137 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1138 proto_tree_add_text(tree, tvb, offset, 1,
1144 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
1145 proto_tree_add_text(tree, tvb, offset, 1,
1146 "%s : Type of number: (%d)",
1150 oct2 = tvb_get_guint8(tvb, offset + 1);
1152 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1153 proto_tree_add_text(tree, tvb, offset, 1,
1154 "%s : Numbering plan (MSB): (%d)",
1156 ((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7));
1161 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1162 proto_tree_add_text(tree, tvb, offset, 1,
1163 "%s : Numbering plan (LSB)",
1167 num_fields = (oct & 0x7f) << 1;
1168 oct2 = tvb_get_guint8(tvb, offset);
1169 num_fields |= ((oct2 & 0x80) >> 7);
1171 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1172 proto_tree_add_text(tree, tvb, offset-1, 1,
1173 "%s : Number of fields (MSB): (%d)",
1177 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
1178 proto_tree_add_text(tree, tvb, offset, 1,
1179 "%s : Number of fields (LSB)",
1182 if (num_fields == 0) return;
1184 if (num_fields > (len - 3))
1186 proto_tree_add_text(tree, tvb, offset, 1,
1187 "Missing %d octet(s) for number of fields",
1188 (num_fields + 3) - len);
1193 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x7f, 8);
1194 proto_tree_add_text(tree, tvb, offset, 1,
1195 "%s : Most significant bits of first field",
1202 while (i < num_fields)
1204 ansi_637_bigbuf[i] = (oct & 0x7f) << 1;
1205 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0x80) >> 7;
1208 ansi_637_bigbuf[i] = '\0';
1210 proto_tree_add_text(tree, tvb, offset, num_fields - 1,
1214 offset += (num_fields - 1);
1216 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1217 proto_tree_add_text(tree, tvb, offset, 1,
1218 "%s : Least significant bit of last field",
1221 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1222 proto_tree_add_text(tree, tvb, offset, 1,
1230 num_fields = (oct & 0x3f) << 2;
1231 oct2 = tvb_get_guint8(tvb, offset);
1232 num_fields |= ((oct2 & 0xc0) >> 6);
1234 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1235 proto_tree_add_text(tree, tvb, offset-1, 1,
1236 "%s : Number of fields (MSB): (%d)",
1240 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xc0, 8);
1241 proto_tree_add_text(tree, tvb, offset, 1,
1242 "%s : Number of fields (LSB)",
1250 i = (num_fields - 1) * 4;
1251 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
1253 if (required_octs + 2 > len)
1255 proto_tree_add_text(tree, tvb, offset, 1,
1256 "Missing %d octet(s) for number of fields",
1257 (required_octs + 2) - len);
1262 odd = num_fields & 0x01;
1263 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
1264 saved_offset = offset;
1268 while (i < num_fields)
1270 ansi_637_bigbuf[i] =
1271 air_digits[(oct & 0x3c) >> 2];
1274 if (i >= num_fields) break;
1276 oct2 = tvb_get_guint8(tvb, offset);
1279 ansi_637_bigbuf[i] =
1280 air_digits[((oct & 0x03) << 2) | ((oct2 & 0xc0) >> 6)];
1287 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
1292 other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x03: 0x3f, 8);
1293 proto_tree_add_text(tree, tvb, offset, 1,
1300 trans_param_subaddress(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1302 guint8 oct, oct2, num_fields;
1306 SHORT_DATA_CHECK(len, 2);
1308 oct = tvb_get_guint8(tvb, offset);
1310 switch ((oct & 0xe0) >> 5)
1312 case 0: str = "NSAP (CCITT Recommendation X.213 or ISO 8348 AD2)"; break;
1313 case 1: str = "User-specified"; break;
1319 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xe0, 8);
1320 proto_tree_add_text(tree, tvb, offset, 1,
1325 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x10, 8);
1326 proto_tree_add_text(tree, tvb, offset, 1,
1331 num_fields = (oct & 0x0f) << 4;
1332 oct2 = tvb_get_guint8(tvb, offset);
1333 num_fields |= ((oct2 & 0xf0) >> 4);
1335 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1336 proto_tree_add_text(tree, tvb, offset-1, 1,
1337 "%s : Number of fields (MSB): (%d)",
1341 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf0, 8);
1342 proto_tree_add_text(tree, tvb, offset, 1,
1343 "%s : Number of fields (LSB)",
1346 if (num_fields == 0) return;
1348 if (num_fields > (len - 2))
1350 proto_tree_add_text(tree, tvb, offset, 1,
1351 "Missing %d octet(s) for number of fields",
1352 (num_fields + 2) - len);
1357 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x0f, 8);
1358 proto_tree_add_text(tree, tvb, offset, 1,
1359 "%s : Most significant bits of first field",
1366 while (i < num_fields)
1368 ansi_637_bigbuf[i] = (oct & 0x0f) << 4;
1369 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf0) >> 4;
1372 ansi_637_bigbuf[i] = '\0';
1374 proto_tree_add_bytes(tree, hf_ansi_637_trans_bin_addr, tvb, offset, num_fields - 1,
1375 (guint8*)ansi_637_bigbuf);
1377 offset += (num_fields - 1);
1379 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf0, 8);
1380 proto_tree_add_text(tree, tvb, offset, 1,
1381 "%s : Least significant bits of last field",
1384 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1385 proto_tree_add_text(tree, tvb, offset, 1,
1391 trans_param_bearer_reply_opt(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1396 oct = tvb_get_guint8(tvb, offset);
1398 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
1399 proto_tree_add_text(tree, tvb, offset, 1,
1400 "%s : Reply Sequence Number: %d",
1404 g_snprintf(add_string, string_len, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
1406 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
1407 proto_tree_add_text(tree, tvb, offset, 1,
1413 trans_param_cause_codes(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1416 const gchar *str = NULL;
1418 oct = tvb_get_guint8(tvb, offset);
1420 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
1421 proto_tree_add_text(tree, tvb, offset, 1,
1422 "%s : Reply Sequence Number: %d",
1428 case 0x00: str = "No error"; break;
1429 case 0x02: str = "Temporary Condition"; break;
1430 case 0x03: str = "Permanent Condition"; break;
1436 g_snprintf(add_string, string_len, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
1438 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
1439 proto_tree_add_text(tree, tvb, offset, 1,
1440 "%s : Error Class: %s",
1446 if (!(oct & 0x03)) return;
1448 if (len == 1) return;
1450 oct = tvb_get_guint8(tvb, offset);
1454 case 0: str = "Address vacant"; break;
1455 case 1: str = "Address translation failure"; break;
1456 case 2: str = "Network resource shortage"; break;
1457 case 3: str = "Network failure"; break;
1458 case 4: str = "Invalid Teleservice ID"; break;
1459 case 5: str = "Other network problem"; break;
1460 case 6: str = "Unsupported network interface"; break;
1461 case 32: str = "No page response"; break;
1462 case 33: str = "Destination busy"; break;
1463 case 34: str = "No acknowledgement"; break;
1464 case 35: str = "Destination resource shortage"; break;
1465 case 36: str = "SMS delivery postponed"; break;
1466 case 37: str = "Destination out of service"; break;
1467 case 38: str = "Destination no longer at this address"; break;
1468 case 39: str = "Other terminal problem"; break;
1469 case 64: str = "Radio interface resource shortage"; break;
1470 case 65: str = "Radio interface incompatibility"; break;
1471 case 66: str = "Other radio interface problem"; break;
1472 case 67: str = "Unsupported Base Station Capability"; break;
1473 case 96: str = "Encoding problem"; break;
1474 case 97: str = "Service origination denied"; break;
1475 case 98: str = "Service termination denied"; break;
1476 case 99: str = "Supplementary service not supported"; break;
1477 case 100: str = "Service not supported"; break;
1478 case 101: str = "Reserved"; break;
1479 case 102: str = "Missing expected parameter"; break;
1480 case 103: str = "Missing mandatory parameter"; break;
1481 case 104: str = "Unrecognized parameter value"; break;
1482 case 105: str = "Unexpected parameter value"; break;
1483 case 106: str = "User Data size error"; break;
1484 case 107: str = "Other general problems"; break;
1485 case 108: str = "Session not active"; break;
1487 if ((oct >= 7) && (oct <= 31)) { str = "Reserved, treat as Other network problem"; }
1488 else if ((oct >= 40) && (oct <= 47)) { str = "Reserved, treat as Other terminal problem"; }
1489 else if ((oct >= 48) && (oct <= 63)) { str = "Reserved, treat as SMS delivery postponed"; }
1490 else if ((oct >= 68) && (oct <= 95)) { str = "Reserved, treat as Other radio interface problem"; }
1491 else if ((oct >= 109) && (oct <= 223)) { str = "Reserved, treat as Other general problems"; }
1492 else { str = "Reserved for protocol extension, treat as Other general problems"; }
1496 proto_tree_add_text(tree, tvb, offset, 1,
1501 trans_param_bearer_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1505 proto_tree_add_text(tree, tvb, offset, len,
1509 * dissect the embedded teleservice data
1511 tele_tvb = tvb_new_subset(tvb, offset, len, len);
1513 dissector_try_port(tele_dissector_table, ansi_637_trans_tele_id,
1514 tele_tvb, g_pinfo, g_tree);
1517 #define NUM_TRANS_PARAM (sizeof(ansi_trans_param_strings)/sizeof(value_string))
1518 static gint ett_ansi_637_trans_param[NUM_TRANS_PARAM];
1519 static void (*ansi_637_trans_param_fcn[])(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len) = {
1520 trans_param_tele_id, /* Teleservice Identifier */
1521 trans_param_srvc_cat, /* Service Category */
1522 trans_param_address, /* Originating Address */
1523 trans_param_subaddress, /* Originating Subaddress */
1524 trans_param_address, /* Destination Address */
1525 trans_param_subaddress, /* Destination Subaddress */
1526 trans_param_bearer_reply_opt, /* Bearer Reply Option */
1527 trans_param_cause_codes, /* Cause Codes */
1528 trans_param_bearer_data, /* Bearer Data */
1532 #define NUM_TRANS_MSG_TYPE (sizeof(ansi_trans_msg_type_strings)/sizeof(value_string))
1533 static gint ett_ansi_637_trans_msg[NUM_TRANS_MSG_TYPE];
1535 /* GENERIC IS-637 DISSECTOR FUNCTIONS */
1538 dissect_ansi_637_tele_param(tvbuff_t *tvb, proto_tree *tree, guint32 *offset)
1540 void (*param_fcn)(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) = NULL;
1543 guint32 curr_offset;
1544 gint ett_param_idx, idx;
1545 proto_tree *subtree;
1547 const gchar *str = NULL;
1550 curr_offset = *offset;
1552 oct = tvb_get_guint8(tvb, curr_offset);
1553 str = match_strval_idx((guint32) oct, ansi_tele_param_strings, &idx);
1560 ett_param_idx = ett_ansi_637_tele_param[idx];
1561 param_fcn = ansi_637_tele_param_fcn[idx];
1564 proto_tree_add_text(tree, tvb, curr_offset, -1, str);
1566 subtree = proto_item_add_subtree(item, ett_param_idx);
1568 proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id,
1569 tvb, curr_offset, 1, oct);
1573 len = tvb_get_guint8(tvb, curr_offset);
1575 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
1577 proto_tree_add_uint(subtree, hf_ansi_637_tele_length,
1578 tvb, curr_offset, 1, len);
1584 if (param_fcn == NULL)
1586 proto_tree_add_text(subtree, tvb, curr_offset,
1587 len, "Parameter Data");
1591 (*param_fcn)(tvb, subtree, len, curr_offset);
1597 *offset = curr_offset;
1603 dissect_ansi_637_tele_message(tvbuff_t *tvb, proto_tree *ansi_637_tree)
1606 guint32 curr_offset;
1609 len = tvb_length(tvb);
1611 while ((len - curr_offset) > 0)
1613 if (!dissect_ansi_637_tele_param(tvb, ansi_637_tree, &curr_offset))
1615 proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
1616 "Unknown Parameter Data");
1623 dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1625 proto_item *ansi_637_item;
1626 proto_tree *ansi_637_tree = NULL;
1627 const gchar *str = NULL;
1630 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1632 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
1635 /* In the interest of speed, if "tree" is NULL, don't do any work not
1636 * necessary to generate protocol tree items.
1640 value = pinfo->match_port;
1643 * create the ansi_637 protocol tree
1645 str = match_strval(value, ansi_tele_id_strings);
1652 str = "Reserved for maintenance";
1655 str = "CDMA Service Category Programming Teleservice (SCPT)";
1658 str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
1661 str = "TDMA Cellular Messaging Teleservice";
1664 str = "TDMA Cellular Paging Teleservice (CPT-136)";
1667 str = "TDMA Over-the-Air Activation Teleservice (OATS)";
1670 str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
1673 str = "TDMA Segmented System Assisted Mobile Positioning Service";
1676 if ((value >= 2) && (value <= 4095))
1678 str = "Reserved for assignment by TIA-41";
1680 else if ((value >= 4104) && (value <= 4113))
1682 str = "Reserved for GSM1x Teleservice (CDMA)";
1684 else if ((value >= 4114) && (value <= 32512))
1686 str = "Reserved for assignment by TIA-41";
1688 else if ((value >= 32521) && (value <= 32575))
1690 str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
1692 else if ((value >= 49152) && (value < 65535))
1694 str = "Reserved for carrier specific teleservices";
1696 else if (value == 65535)
1699 * supposed to be "Reserved for carrier specific teleservices"
1700 * but we are using it to key SMS Broadcast dissection were
1701 * there is no teleservice ID
1703 str = "(Reserved) Being used for Broadcast";
1707 str = "Unrecognized Teleservice ID";
1714 proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
1716 ansi_proto_name_tele,
1721 proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele);
1723 dissect_ansi_637_tele_message(tvb, ansi_637_tree);
1728 dissect_ansi_637_trans_param(tvbuff_t *tvb, proto_tree *tree, guint32 *offset)
1730 void (*param_fcn)(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len) = NULL;
1733 guint32 curr_offset;
1734 gint ett_param_idx, idx;
1735 proto_tree *subtree;
1737 const gchar *str = NULL;
1739 curr_offset = *offset;
1741 oct = tvb_get_guint8(tvb, curr_offset);
1742 str = match_strval_idx((guint32) oct, ansi_trans_param_strings, &idx);
1749 ett_param_idx = ett_ansi_637_trans_param[idx];
1750 param_fcn = ansi_637_trans_param_fcn[idx];
1753 proto_tree_add_text(tree, tvb, curr_offset, -1, str);
1755 subtree = proto_item_add_subtree(item, ett_param_idx);
1757 proto_tree_add_uint(subtree, hf_ansi_637_trans_param_id,
1758 tvb, curr_offset, 1, oct);
1762 len = tvb_get_guint8(tvb, curr_offset);
1764 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
1766 proto_tree_add_uint(subtree, hf_ansi_637_trans_length,
1767 tvb, curr_offset, 1, len);
1773 if (param_fcn == NULL)
1775 proto_tree_add_text(subtree, tvb, curr_offset,
1776 len, "Parameter Data");
1780 gchar *ansi_637_add_string;
1782 ansi_637_add_string = ep_alloc(1024);
1783 ansi_637_add_string[0] = '\0';
1784 (*param_fcn)(tvb, subtree, len, curr_offset, ansi_637_add_string, 1024);
1786 if (ansi_637_add_string[0] != '\0')
1788 proto_item_append_text(item, "%s", ansi_637_add_string);
1795 *offset = curr_offset;
1801 dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1803 proto_item *ansi_637_item;
1804 proto_tree *ansi_637_tree = NULL;
1805 guint32 curr_offset;
1807 const gchar *str = NULL;
1811 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1813 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
1816 /* In the interest of speed, if "tree" is NULL, don't do any work not
1817 * necessary to generate protocol tree items.
1825 * reset the teleservice ID for each dissection
1827 ansi_637_trans_tele_id = 0;
1830 * create the ansi_637 protocol tree
1832 oct = tvb_get_guint8(tvb, 0);
1834 str = match_strval_idx(oct, ansi_trans_msg_type_strings, &idx);
1839 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
1840 "%s - Unrecognized Transport Layer Message Type (%d)",
1841 ansi_proto_name_trans,
1845 proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans);
1850 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
1852 ansi_proto_name_trans,
1856 proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans_msg[idx]);
1858 if (oct == ANSI_TRANS_MSG_TYPE_BROADCAST)
1861 * there is no teleservice ID for Broadcast but we want the
1862 * bearer data to be dissected
1864 * using a reserved value to key dissector port
1866 ansi_637_trans_tele_id = 65535;
1872 len = tvb_length(tvb);
1874 while ((len - curr_offset) > 0)
1876 if (!dissect_ansi_637_trans_param(tvb, ansi_637_tree, &curr_offset))
1878 proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
1879 "Unknown Parameter Data");
1886 /* Register the protocol with Wireshark */
1888 proto_register_ansi_637(void)
1892 /* Setup list of header fields */
1893 static hf_register_info hf_trans[] =
1895 { &hf_ansi_637_trans_msg_type,
1897 "ansi_637_trans.msg_type",
1898 FT_UINT24, BASE_DEC, VALS(ansi_trans_msg_type_strings), 0xf00000,
1900 { &hf_ansi_637_trans_param_id,
1901 { "Transport Param ID", "ansi_637_trans.param_id",
1902 FT_UINT8, BASE_DEC, VALS(ansi_trans_param_strings), 0,
1904 { &hf_ansi_637_trans_length,
1905 { "Length", "ansi_637_trans.len",
1906 FT_UINT8, BASE_DEC, NULL, 0,
1908 { &hf_ansi_637_trans_bin_addr,
1909 { "Binary Address", "ansi_637_trans.bin_addr",
1910 FT_BYTES, BASE_HEX, 0, 0,
1913 static hf_register_info hf_tele[] =
1915 { &hf_ansi_637_tele_msg_type,
1917 "ansi_637_tele.msg_type",
1918 FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_type_strings), 0xf00000,
1920 { &hf_ansi_637_tele_msg_id,
1922 "ansi_637_tele.msg_id",
1923 FT_UINT24, BASE_DEC, NULL, 0x0ffff0,
1925 { &hf_ansi_637_tele_msg_rsvd,
1927 "ansi_637_tele.msg_rsvd",
1928 FT_UINT24, BASE_DEC, NULL, 0x00000f,
1930 { &hf_ansi_637_tele_length,
1931 { "Length", "ansi_637_tele.len",
1932 FT_UINT8, BASE_DEC, NULL, 0,
1934 { &hf_ansi_637_tele_subparam_id,
1935 { "Teleservice Subparam ID", "ansi_637_tele.subparam_id",
1936 FT_UINT8, BASE_DEC, VALS(ansi_tele_param_strings), 0,
1940 /* Setup protocol subtree array */
1941 #define NUM_INDIVIDUAL_PARAMS 3
1942 static gint *ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM];
1944 memset((void *) ett, 0, sizeof(ett));
1946 ett[0] = &ett_ansi_637_tele;
1947 ett[1] = &ett_ansi_637_trans;
1948 ett[2] = &ett_params;
1950 for (i=0; i < NUM_TELE_PARAM; i++)
1952 ett_ansi_637_tele_param[i] = -1;
1953 ett[NUM_INDIVIDUAL_PARAMS+i] = &ett_ansi_637_tele_param[i];
1956 for (i=0; i < NUM_TRANS_MSG_TYPE; i++)
1958 ett_ansi_637_trans_msg[i] = -1;
1959 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+i] = &ett_ansi_637_trans_msg[i];
1962 for (i=0; i < NUM_TRANS_PARAM; i++)
1964 ett_ansi_637_trans_param[i] = -1;
1965 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+i] = &ett_ansi_637_trans_param[i];
1968 /* Register the protocol name and description */
1969 proto_ansi_637_tele =
1970 proto_register_protocol(ansi_proto_name_tele, "ANSI IS-637-A Teleservice", "ansi_637_tele");
1972 proto_ansi_637_trans =
1973 proto_register_protocol(ansi_proto_name_trans, "ANSI IS-637-A Transport", "ansi_637_trans");
1975 register_dissector("ansi_637_tele", dissect_ansi_637_tele, proto_ansi_637_tele);
1976 register_dissector("ansi_637_trans", dissect_ansi_637_trans, proto_ansi_637_trans);
1978 /* Required function calls to register the header fields and subtrees used */
1979 proto_register_field_array(proto_ansi_637_tele, hf_tele, array_length(hf_tele));
1980 proto_register_field_array(proto_ansi_637_trans, hf_trans, array_length(hf_trans));
1981 proto_register_subtree_array(ett, array_length(ett));
1983 tele_dissector_table =
1984 register_dissector_table("ansi_637.tele_id",
1985 "ANSI IS-637-A Teleservice ID", FT_UINT8, BASE_DEC);
1990 proto_reg_handoff_ansi_637(void)
1992 dissector_handle_t ansi_637_tele_handle;
1993 dissector_handle_t ansi_637_trans_handle;
1996 ansi_637_tele_handle = create_dissector_handle(dissect_ansi_637_tele, proto_ansi_637_tele);
1997 ansi_637_trans_handle = create_dissector_handle(dissect_ansi_637_trans, proto_ansi_637_trans);
2000 * register for all known teleservices
2001 * '-1' is to stop before trailing '0' entry
2003 * to add teleservices, modify 'ansi_tele_id_strings'
2005 for (i=0; i < ((sizeof(ansi_tele_id_strings)/sizeof(value_string))-1); i++)
2008 * ANSI MAP dissector will push out teleservice ids
2010 dissector_add("ansi_map.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
2013 * we will push out teleservice ids after Transport layer decode
2015 dissector_add("ansi_637.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
2019 * ANSI A-interface will push out transport layer data
2021 dissector_add("ansi_a.sms", 0, ansi_637_trans_handle);
2023 /* data_handle = find_dissector("data"); */