HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-ansi_637.c
blob98e8a0733a594f9a9a93260a8f1330d5cb8474c4
1 /* packet-ansi_637.c
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.
7 * Title 3GPP2 Other
9 * Short Message Service
10 * 3GPP2 C.S0015-0 TIA/EIA-637-A
12 * $Id$
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include "config.h"
35 #include <epan/packet.h>
36 #include <epan/wmem/wmem.h>
37 #include <epan/strutil.h>
38 #include <epan/to_str.h>
40 #include "packet-gsm_sms.h"
42 void proto_register_ansi_637(void);
43 void proto_reg_handoff_ansi_637(void);
45 static const char *ansi_proto_name_tele = "ANSI IS-637-A (SMS) Teleservice Layer";
46 static const char *ansi_proto_name_trans = "ANSI IS-637-A (SMS) Transport Layer";
47 static const char *ansi_proto_name_short = "IS-637-A";
49 static const value_string ansi_srvc_cat_strings[] = {
50 { 0x0000, "Unknown or unspecified" },
51 { 0x0001, "Emergency Broadcasts" },
52 { 0x0002, "Administrative" },
53 { 0x0003, "Maintenance" },
54 { 0x0004, "General News - Local" },
55 { 0x0005, "General News - Regional" },
56 { 0x0006, "General News - National" },
57 { 0x0007, "General News - International" },
58 { 0x0008, "Business/Financial News - Local" },
59 { 0x0009, "Business/Financial News - Regional" },
60 { 0x000A, "Business/Financial News - National" },
61 { 0x000B, "Business/Financial News - International" },
62 { 0x000C, "Sports News - Local" },
63 { 0x000D, "Sports News - Regional" },
64 { 0x000E, "Sports News - National" },
65 { 0x000F, "Sports News - International" },
66 { 0x0010, "Entertainment News - Local" },
67 { 0x0011, "Entertainment News - Regional" },
68 { 0x0012, "Entertainment News - National" },
69 { 0x0013, "Entertainment News - International" },
70 { 0x0014, "Local Weather" },
71 { 0x0015, "Area Traffic Reports" },
72 { 0x0016, "Local Airport Flight Schedules" },
73 { 0x0017, "Restaurants" },
74 { 0x0018, "Lodgings" },
75 { 0x0019, "Retail Directory" },
76 { 0x001A, "Advertisements" },
77 { 0x001B, "Stock Quotes" },
78 { 0x001C, "Employment Opportunities" },
79 { 0x001D, "Medical/Health/Hospitals" },
80 { 0x001E, "Technology News" },
81 { 0x001F, "Multi-category" },
82 { 0, NULL },
85 static const value_string ansi_tele_msg_type_strings[] = {
86 { 1, "Deliver (mobile-terminated only)" },
87 { 2, "Submit (mobile-originated only)" },
88 { 3, "Cancellation (mobile-originated only)" },
89 { 4, "Delivery Acknowledgement (mobile-terminated only)" },
90 { 5, "User Acknowledgement (either direction)" },
91 { 0, NULL },
94 static const value_string ansi_tele_msg_status_strings[] = {
95 {0x00, "Message accepted"},
96 {0x01, "Message deposited to Internet"},
97 {0x02, "Message delivered"},
98 {0x03, "Message cancelled"},
99 {0x84, "Network congestion"},
100 {0x85, "Network error"},
101 {0x9f, "Unknown error"},
102 {0xc4, "Network congestion"},
103 {0xc5, "Network error"},
104 {0xc6, "Cancel failed"},
105 {0xc7, "Blocked destination"},
106 {0xc8, "Text too long"},
107 {0xc9, "Duplicate message"},
108 {0xca, "Invalid destination"},
109 {0xcd, "Message expired"},
110 {0xdf, "Unknown error"},
111 { 0, NULL }
114 static const value_string ansi_tele_id_strings[] = {
115 { 1, "Reserved for maintenance" },
116 { 4096, "AMPS Extended Protocol Enhanced Services" },
117 { 4097, "CDMA Cellular Paging Teleservice" },
118 { 4098, "CDMA Cellular Messaging Teleservice" },
119 { 4099, "CDMA Voice Mail Notification" },
120 { 4100, "CDMA Wireless Application Protocol (WAP)" },
121 { 4101, "CDMA Wireless Enhanced Messaging Teleservice (WEMT)" },
122 { 65535, "(Reserved) Being used for Broadcast" },
123 { 0, NULL },
127 static const value_string ansi_tele_param_strings[] = {
128 { 0x00, "Message Identifier" },
129 { 0x01, "User Data" },
130 { 0x02, "User Response Code" },
131 { 0x03, "Message Center Time Stamp" },
132 { 0x04, "Validity Period - Absolute" },
133 { 0x05, "Validity Period - Relative" },
134 { 0x06, "Deferred Delivery Time - Absolute" },
135 { 0x07, "Deferred Delivery Time - Relative" },
136 { 0x08, "Priority Indicator" },
137 { 0x09, "Privacy Indicator" },
138 { 0x0a, "Reply Option" },
139 { 0x0b, "Number of Messages" },
140 { 0x0c, "Alert on Message Delivery" },
141 { 0x0d, "Language Indicator" },
142 { 0x0e, "Call-Back Number" },
143 { 0x0f, "Message Display Mode" },
144 { 0x10, "Multiple Encoding User Data" },
145 { 0x14, "Message Status" },
146 { 0, NULL },
149 #define ANSI_TRANS_MSG_TYPE_BROADCAST 1
151 static const value_string ansi_trans_msg_type_strings[] = {
152 { 0, "Point-to-Point" },
153 { 1, "Broadcast" },
154 { 2, "Acknowledge" },
155 { 0, NULL },
158 static const value_string ansi_trans_param_strings[] = {
159 { 0x00, "Teleservice Identifier" },
160 { 0x01, "Service Category" },
161 { 0x02, "Originating Address" },
162 { 0x03, "Originating Subaddress" },
163 { 0x04, "Destination Address" },
164 { 0x05, "Destination Subaddress" },
165 { 0x06, "Bearer Reply Option" },
166 { 0x07, "Cause Codes" },
167 { 0x08, "Bearer Data" },
168 { 0, NULL },
172 * from Table 2.7.1.3.2.4-4. Representation of DTMF Digits
173 * 3GPP2 C.S0005-C (IS-2000 aka cdma2000)
175 static unsigned char air_digits[] = {
176 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
177 '?','1','2','3','4','5','6','7','8','9','0','*','#','?','?'
180 /* Initialize the protocol and registered fields */
181 static int proto_ansi_637_tele = -1;
182 static int proto_ansi_637_trans = -1;
183 static int hf_ansi_637_tele_length = -1;
184 static int hf_ansi_637_trans_length = -1;
185 static int hf_ansi_637_trans_bin_addr = -1;
186 static int hf_ansi_637_tele_msg_type = -1;
187 static int hf_ansi_637_tele_msg_id = -1;
188 static int hf_ansi_637_tele_msg_status = -1;
189 static int hf_ansi_637_tele_msg_ind = -1;
190 static int hf_ansi_637_tele_msg_rsvd = -1;
191 static int hf_ansi_637_tele_subparam_id = -1;
192 static int hf_ansi_637_tele_user_data_text = -1;
193 /* static int hf_ansi_637_trans_msg_type = -1; */
194 static int hf_ansi_637_trans_param_id = -1;
196 /* Initialize the subtree pointers */
197 static gint ett_ansi_637_tele = -1;
198 static gint ett_ansi_637_trans = -1;
199 static gint ett_params = -1;
201 static dissector_handle_t ansi_637_tele_handle;
202 static dissector_handle_t ansi_637_trans_handle;
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_table_t tele_dissector_table;
209 static proto_tree *g_tree;
211 /* FUNCTIONS */
213 static int
214 decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oct, guint8 *last_bit, gchar *buf)
216 guint8 oct, oct2, bit;
217 /* guint32 saved_offset; */
218 guint32 i;
221 if (num_fields == 0)
223 return 0;
226 /* saved_offset = *offset; */
227 oct = oct2 = *last_oct;
228 bit = *last_bit;
230 if (bit == 1)
232 oct2 = tvb_get_guint8(tvb, *offset);
233 (*offset) += 1;
236 for (i=0; i < num_fields; i++)
238 if (bit != 1)
240 oct = oct2;
243 * cannot grab an octet if we are getting
244 * the last field and bit is 7 or 8
245 * because there may not be another octet
247 if (((i + 1) != num_fields) ||
248 ((bit != 7) && (bit != 8)))
250 oct2 = tvb_get_guint8(tvb, *offset);
251 (*offset) += 1;
255 switch (bit)
257 case 1:
258 buf[i] = ((oct & 0x01) << 6) | ((oct2 & 0xfc) >> 2);
259 break;
261 case 2:
262 buf[i] = ((oct & 0x03) << 5) | ((oct2 & 0xf8) >> 3);
263 break;
265 case 3:
266 buf[i] = ((oct & 0x07) << 4) | ((oct2 & 0xf0) >> 4);
267 break;
269 case 4:
270 buf[i] = ((oct & 0x0f) << 3) | ((oct2 & 0xe0) >> 5);
271 break;
273 case 5:
274 buf[i] = ((oct & 0x1f) << 2) | ((oct2 & 0xc0) >> 6);
275 break;
277 case 6:
278 buf[i] = ((oct & 0x3f) << 1) | ((oct2 & 0x80) >> 7);
279 break;
281 case 7:
282 buf[i] = oct & 0x7f;
283 break;
285 case 8:
286 buf[i] = (oct & 0xfe) >> 1;
287 break;
290 bit = (bit % 8) + 1;
293 buf[i] = '\0';
294 *last_bit = bit;
295 *last_oct = (bit == 1) ? oct : oct2;
296 return i;
299 /* PARAM FUNCTIONS */
301 #define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
302 if ((edc_len) > (edc_max_len)) \
304 proto_tree_add_text(tree, tvb, offset, \
305 (edc_len) - (edc_max_len), "Extraneous Data"); \
308 #define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
309 if ((sdc_len) < (sdc_min_len)) \
311 proto_tree_add_text(tree, tvb, offset, \
312 (sdc_len), "Short Data (?)"); \
313 return; \
316 #define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
317 if ((edc_len) != (edc_eq_len)) \
319 proto_tree_add_text(tree, tvb, offset, \
320 (edc_len), "Unexpected Data Length"); \
321 return; \
324 static void
325 tele_param_msg_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data)
327 EXACT_DATA_CHECK(len, 3);
329 proto_tree_add_item(tree, hf_ansi_637_tele_msg_type, tvb, offset, 3, ENC_BIG_ENDIAN);
331 proto_tree_add_item(tree, hf_ansi_637_tele_msg_id, tvb, offset, 3, ENC_BIG_ENDIAN);
333 proto_tree_add_item(tree, hf_ansi_637_tele_msg_ind, tvb, offset, 3, ENC_BIG_ENDIAN);
334 if ((tvb_get_guint8(tvb, offset+2) & 0x08) == 0x08) {
335 *has_private_data = TRUE;
338 proto_tree_add_item(tree, hf_ansi_637_tele_msg_rsvd, tvb, offset, 3, ENC_BIG_ENDIAN);
341 /* Adamek Jan - IS637C Message status decoding procedure */
342 static void
343 tele_param_msg_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
345 /* Declare some variables */
346 guint8 oct;
347 guint8 error_class;
348 guint8 msg_status_code;
349 const gchar *str = NULL;
351 /* Chceck if the exact length */
352 EXACT_DATA_CHECK(len, 1);
354 /* get the status octet? */
356 oct = tvb_get_guint8(tvb, offset);
359 /* error class filter */
360 proto_tree_add_item(tree, hf_ansi_637_tele_msg_status,tvb, offset, 1, ENC_BIG_ENDIAN);
362 /*error class filter end */
365 /*error class */
367 error_class = ((oct & 0xc0) >> 6);
368 switch (error_class)
370 case 0x00: str = "No Error";break;
371 case 0x01: str = "Reserved";break;
372 case 0x02: str = "Temporary Condition";break;
373 case 0x03: str = "Permanent Condition";break;
374 default: str = "Reserved";break;
376 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
377 proto_tree_add_text(tree, tvb, offset, 1,
378 "%s : Erorr Class: %s",
379 ansi_637_bigbuf,
380 str);
384 msg_status_code = (oct & 0x3f);
386 if (error_class == 0x00){
387 switch (msg_status_code)
389 case 0x00: str = "Message accepted";break;
390 case 0x01: str = "Message deposited to internet";break;
391 case 0x02: str = "Message delivered";break;
392 case 0x03: str = "Message cancelled";break;
393 default: str = "Reserved";break;
395 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
396 proto_tree_add_text(tree, tvb, offset, 1,
397 "%s : Message status code: %s",
398 ansi_637_bigbuf,
399 str);
402 /*error message status */
403 if (error_class == 0x02){
404 switch (msg_status_code)
406 case 0x04: str = "Network congestion";break;
407 case 0x05: str = "Network error";break;
408 case 0x1f: str = "Unknown error";break;
409 default: str = "Reserved";break;
411 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
412 proto_tree_add_text(tree, tvb, offset, 1,
413 "%s : Message status code: %s",
414 ansi_637_bigbuf,
415 str);
418 if (error_class == 0x03){
419 switch (msg_status_code)
421 case 0x04: str = "Network congestion";break;
422 case 0x05: str = "Network error";break;
423 case 0x06: str = "Cancel failed";break;
424 case 0x07: str = "Blocked destination";break;
425 case 0x08: str = "Text too long";break;
426 case 0x09: str = "Duplicate message";break;
427 case 0x0a: str = "Invalid destination";break;
428 case 0x0d: str = "Message expired";break;
429 case 0x1f: str = "Unknown error";break;
430 default: str = "Reserved";break;
432 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
433 proto_tree_add_text(tree, tvb, offset, 1,
434 "%s : Message status code: %s",
435 ansi_637_bigbuf,
436 str);
441 static void
442 tele_param_user_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data)
444 guint8 oct, oct2;
445 guint8 encoding;
446 guint8 msg_type;
447 guint8 num_fields;
448 guint8 used;
449 guint8 bit;
450 guint32 required_octs;
451 guint32 saved_offset;
452 guint32 i , out_len;
453 const gchar *str = NULL;
454 gchar *buf;
455 tvbuff_t *tvb_out = NULL;
457 gchar *utf8_text = NULL;
458 GIConv cd;
459 GError *l_conv_error = NULL;
461 SHORT_DATA_CHECK(len, 2);
464 * message encoding
466 oct = tvb_get_guint8(tvb, offset);
467 oct2 = 0;
468 msg_type = 0;
469 used = 0;
471 encoding = ((oct & 0xf8) >> 3);
472 switch (encoding)
474 case 0x00: str = "Octet, unspecified"; break;
475 case 0x01: str = "Extended Protocol Message";
476 oct2 = tvb_get_guint8(tvb, offset+1);
477 msg_type = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
478 break;
479 case 0x02: str = "7-bit ASCII"; break;
480 case 0x03: str = "IA5"; break;
481 case 0x04: str = "UCS-2"; break;
482 case 0x05: str = "Shift-JIS"; break;
483 case 0x06: str = "Korean"; break;
484 case 0x07: str = "Latin/Hebrew"; break;
485 case 0x08: str = "ISO 8859-1"; break;
486 case 0x09: str = "GSM 7-bit default alphabet"; break;
487 case 0x10: str = "KSC5601 (Korean)"; break;
488 default: str = "Reserved"; break;
491 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
492 proto_tree_add_text(tree, tvb, offset, 1,
493 "%s : Encoding: %s",
494 ansi_637_bigbuf,
495 str);
497 if (encoding == 0x01)
499 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
500 proto_tree_add_text(tree, tvb, offset, 1,
501 "%s : Message type: see TIA/EIA/IS-91 (%d)",
502 ansi_637_bigbuf,
503 msg_type);
505 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
506 proto_tree_add_text(tree, tvb, offset+1, 1,
507 "%s : Message type",
508 ansi_637_bigbuf);
510 oct = oct2;
511 offset += 1;
512 used += 1;
515 offset += 1;
516 used += 1;
519 * number of fields
521 oct2 = tvb_get_guint8(tvb, offset);
522 num_fields = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
524 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
525 proto_tree_add_text(tree, tvb, offset-1, 1,
526 "%s : Number of fields (MSB): %d",
527 ansi_637_bigbuf,
528 num_fields);
530 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
531 proto_tree_add_text(tree, tvb, offset, 1,
532 "%s : Number of fields (LSB)",
533 ansi_637_bigbuf);
535 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
536 proto_tree_add_text(tree, tvb, offset, 1,
537 "%s : Most significant bits of first field",
538 ansi_637_bigbuf);
540 offset += 1;
541 used += 1;
542 oct = oct2;
544 /* NOTE: there are now 3 bits remaining in 'oct' */
546 if (len <= used) return;
549 * decode rest if 7-bit ASCII
551 if (encoding == 0x02)
554 * magic numbers:
555 * 3 bits remaining from last octet
556 * 7 bit encoding
557 * 8 bits per octet
559 i = (num_fields * 7) - 3;
560 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
562 if (required_octs + used > len)
564 proto_tree_add_text(tree, tvb, offset, 1,
565 "Missing %d octet(s) for number of fields",
566 (required_octs + used) - len);
568 return;
571 saved_offset = offset - 1;
572 i = num_fields * 7;
573 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
574 buf = (gchar*)wmem_alloc(pinfo->pool, required_octs);
575 for (i=0; i < required_octs; i++)
577 oct = tvb_get_guint8(tvb, saved_offset);
578 oct2 = tvb_get_guint8(tvb, saved_offset + 1);
579 buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
580 saved_offset += 1;
582 tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs);
583 add_new_data_source(pinfo, tvb_out, "Characters");
584 offset = 0;
585 bit = 0;
586 if (*has_private_data == TRUE) {
587 dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, TRUE, &bit);
590 saved_offset = offset;
591 bit = bit ? bit : 8;
592 oct = tvb_get_guint8(tvb_out, offset);
593 offset += 1;
595 decode_7_bits(tvb_out, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
597 proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, saved_offset,
598 offset - saved_offset, ansi_637_bigbuf);
600 switch (bit)
602 case 1: oct2 = 0x01; break;
603 case 2: oct2 = 0x03; break;
604 case 3: oct2 = 0x07; break;
605 case 4: oct2 = 0x0f; break;
606 case 5: oct2 = 0x1f; break;
607 case 6: oct2 = 0x3f; break;
608 case 7: oct2 = 0x7f; break;
611 if (bit != 8)
613 other_decode_bitfield_value(ansi_637_bigbuf, oct, oct2, 8);
614 proto_tree_add_text(tree, tvb, offset - 1, 1,
615 "%s : Reserved",
616 ansi_637_bigbuf);
619 else if (encoding == 0x03)/* IA5 */
621 i = (num_fields * 7) - 3;
622 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
624 if (required_octs + used > len)
626 proto_tree_add_text(tree, tvb, offset, 1,
627 "Missing %d octet(s) for number of fields",
628 (required_octs + used) - len);
630 return;
633 saved_offset = offset - 1;
634 i = num_fields * 7;
635 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
636 buf = (gchar*)wmem_alloc(pinfo->pool, required_octs);
637 for (i=0; i < required_octs; i++)
639 oct = tvb_get_guint8(tvb, saved_offset);
640 oct2 = tvb_get_guint8(tvb, saved_offset + 1);
641 buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
642 saved_offset += 1;
644 tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs);
645 add_new_data_source(pinfo, tvb_out, "Characters");
646 offset = 0;
647 bit = 0;
648 if (*has_private_data == TRUE) {
649 dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, TRUE, &bit);
651 saved_offset = offset;
652 bit = bit ? bit : 8;
653 oct = tvb_get_guint8(tvb_out, offset);
654 offset += 1;
655 out_len = decode_7_bits(tvb_out, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
656 IA5_7BIT_decode(ia5_637_bigbuf, ansi_637_bigbuf, out_len);
658 proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, saved_offset,
659 offset - saved_offset, ia5_637_bigbuf);
662 else if (encoding == 0x04)/* UCS-2 (not UTF-16?) */
664 saved_offset = offset - 1;
665 required_octs = 2*num_fields;
666 buf = (gchar*)wmem_alloc(pinfo->pool, required_octs);
667 for (i=0; i < required_octs; i++)
669 oct = tvb_get_guint8(tvb, saved_offset);
670 oct2 = tvb_get_guint8(tvb, saved_offset + 1);
671 buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
672 saved_offset += 1;
674 tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs);
675 add_new_data_source(pinfo, tvb_out, "Characters");
676 offset = 0;
677 if (*has_private_data == TRUE) {
678 dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, FALSE, &bit);
681 if ((cd = g_iconv_open("UTF-8","UCS-2BE")) != (GIConv)-1)
683 utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb_out, offset, required_octs), required_octs , cd , NULL , NULL , &l_conv_error);
684 if (!l_conv_error)
686 proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset,
687 required_octs, utf8_text);
689 else
691 proto_tree_add_text(tree, tvb_out, offset, required_octs, "%s", "Failed on UCS-2BE contact Wireshark developers");
693 if (utf8_text)
694 g_free(utf8_text);
695 g_iconv_close(cd);
698 else if (encoding == 0x07)/* Latin/Hebrew */
700 saved_offset = offset - 1;
701 buf = (gchar*)wmem_alloc(pinfo->pool, num_fields);
702 for (i=0; i < num_fields; i++)
704 oct = tvb_get_guint8(tvb, saved_offset);
705 oct2 = tvb_get_guint8(tvb, saved_offset + 1);
706 buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
707 saved_offset += 1;
709 tvb_out = tvb_new_child_real_data(tvb, buf, num_fields, num_fields);
710 add_new_data_source(pinfo, tvb_out, "Characters");
711 offset = 0;
712 required_octs = len - used;
713 if (*has_private_data == TRUE) {
714 dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, FALSE, &bit);
717 if ((cd = g_iconv_open("UTF-8","iso-8859-8")) != (GIConv)-1)
719 utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb_out, offset, num_fields), num_fields , cd , NULL , NULL , &l_conv_error);
720 if (!l_conv_error)
722 proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset,
723 num_fields, utf8_text);
725 else
727 proto_tree_add_text(tree, tvb_out, offset, num_fields, "%s", "Failed on iso-8859-8 contact Wireshark developers");
729 if (utf8_text)
730 g_free(utf8_text);
731 g_iconv_close(cd);
734 else if (encoding == 0x08) /* ISO 8859-1 (a/k/a ISO Latin 1) */
736 saved_offset = offset - 1;
737 buf = (gchar*)wmem_alloc(pinfo->pool, num_fields);
738 for (i=0; i < num_fields; i++)
740 oct = tvb_get_guint8(tvb, saved_offset);
741 oct2 = tvb_get_guint8(tvb, saved_offset + 1);
742 buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
743 saved_offset += 1;
745 tvb_out = tvb_new_child_real_data(tvb, buf, num_fields, num_fields);
746 add_new_data_source(pinfo, tvb_out, "Characters");
747 offset = 0;
748 required_octs = len - used;
749 if (*has_private_data == TRUE) {
750 dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, FALSE, &bit);
753 if ((cd = g_iconv_open("UTF-8","iso-8859-1")) != (GIConv)-1)
755 utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb_out, offset, num_fields) , num_fields , cd , NULL , NULL , &l_conv_error);
756 if (!l_conv_error)
758 proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset,
759 num_fields, utf8_text);
761 else
763 proto_tree_add_text(tree, tvb_out, offset, num_fields, "%s", "Failed on iso-8859-1 contact Wireshark developers");
765 if (utf8_text)
766 g_free(utf8_text);
767 g_iconv_close(cd);
770 else if (encoding == 0x09) /* GSM 7-bit default alphabet */
772 i = (num_fields * 7) - 3;
773 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
775 if (required_octs + used > len)
777 proto_tree_add_text(tree, tvb, offset, 1,
778 "Missing %d octet(s) for number of fields",
779 (required_octs + used) - len);
781 return;
784 saved_offset = offset - 1;
785 i = num_fields * 7;
786 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
787 buf = (gchar*)wmem_alloc(pinfo->pool, required_octs);
788 for (i=0; i < required_octs; i++)
790 oct = tvb_get_guint8(tvb, saved_offset);
791 oct2 = tvb_get_guint8(tvb, saved_offset + 1);
792 buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
793 saved_offset += 1;
795 tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs);
796 add_new_data_source(pinfo, tvb_out, "Characters");
797 offset = 0;
798 bit = 0;
799 if (*has_private_data == TRUE) {
800 dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, TRUE, &bit);
803 out_len = gsm_sms_char_7bit_unpack(bit, required_octs, num_fields,
804 tvb_get_ptr(tvb_out, offset, required_octs), gsm_637_bigbuf);
805 gsm_637_bigbuf[out_len] = '\0';
807 proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset,
808 required_octs, gsm_sms_chars_to_utf8(gsm_637_bigbuf, num_fields));
810 else if (encoding == 0x10)/* KSC5601 (Korean) */
812 saved_offset = offset - 1;
813 buf = (gchar*)wmem_alloc(pinfo->pool, num_fields);
814 for (i=0; i < num_fields; i++)
816 oct = tvb_get_guint8(tvb, saved_offset);
817 oct2 = tvb_get_guint8(tvb, saved_offset + 1);
818 buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
819 saved_offset += 1;
821 tvb_out = tvb_new_child_real_data(tvb, buf, num_fields, num_fields);
822 add_new_data_source(pinfo, tvb_out, "Characters");
823 offset = 0;
824 required_octs = len - used;
825 if (*has_private_data == TRUE) {
826 dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, FALSE, &bit);
829 if ((cd = g_iconv_open("UTF-8","EUC-KR")) != (GIConv)-1)
831 utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb_out, offset, num_fields), num_fields , cd , NULL , NULL , &l_conv_error);
832 if (!l_conv_error)
834 proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset,
835 num_fields, utf8_text);
837 else
839 proto_tree_add_text(tree, tvb_out, offset, num_fields, "%s", "Failed on EUC-KR contact Wireshark developers");
841 if (utf8_text)
842 g_free(utf8_text);
843 g_iconv_close(cd);
846 else
848 proto_tree_add_text(tree, tvb, offset, len - used,
849 "Encoded user data");
853 static void
854 tele_param_rsp_code(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
856 guint8 oct;
858 EXACT_DATA_CHECK(len, 1);
861 * response code
863 oct = tvb_get_guint8(tvb, offset);
865 proto_tree_add_text(tree, tvb, offset, 1,
866 "Response code: %d",
867 oct);
870 static void
871 tele_param_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
873 guint8 oct, oct2, oct3;
875 EXACT_DATA_CHECK(len, 6);
877 oct = tvb_get_guint8(tvb, offset);
878 oct2 = tvb_get_guint8(tvb, offset+1);
879 oct3 = tvb_get_guint8(tvb, offset+2);
881 proto_tree_add_text(tree, tvb, offset, 3,
882 "Year %d%d, Month %d%d, Day %d%d",
883 (oct & 0xf0) >> 4,
884 oct & 0x0f,
885 (oct2 & 0xf0) >> 4,
886 oct2 & 0x0f,
887 (oct3 & 0xf0) >> 4,
888 oct3 & 0x0f);
890 offset += 3;
892 oct = tvb_get_guint8(tvb, offset);
893 oct2 = tvb_get_guint8(tvb, offset+1);
894 oct3 = tvb_get_guint8(tvb, offset+2);
896 proto_tree_add_text(tree, tvb, offset, 3,
897 "Hour %d%d, Minutes %d%d, Seconds %d%d",
898 (oct & 0xf0) >> 4,
899 oct & 0x0f,
900 (oct2 & 0xf0) >> 4,
901 oct2 & 0x0f,
902 (oct3 & 0xf0) >> 4,
903 oct3 & 0x0f);
906 static void
907 tele_param_rel_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
909 guint8 oct;
910 guint32 value = 0;
911 const gchar *str = NULL;
912 const gchar *str2 = NULL;
914 EXACT_DATA_CHECK(len, 1);
916 oct = tvb_get_guint8(tvb, offset);
918 switch (oct)
920 case 245: str = "Indefinite"; break;
921 case 246: str = "Immediate"; break;
922 case 247: str = "Valid until mobile becomes inactive/Deliver when mobile next becomes active"; break;
923 case 248: str = "Valid until registration area changes, discard if not registered" ; break;
924 default:
925 if (oct <= 143) { value = (oct + 1) * 5; str2 = "Minutes"; break; }
926 else if ((oct >= 144) && (oct <= 167)) { value = (oct - 143) * 30; str2 = "Minutes + 12 Hours"; break; }
927 else if ((oct >= 168) && (oct <= 196)) { value = oct - 166; str2 = "Days"; break; }
928 else if ((oct >= 197) && (oct <= 244)) { value = oct - 192; str2 = "Weeks"; break; }
929 else { str = "Reserved"; break; }
932 if (str == NULL)
934 proto_tree_add_text(tree, tvb, offset, 1,
935 "%s", str2);
937 else
939 proto_tree_add_text(tree, tvb, offset, 1,
940 "%d %s",
941 value, str2);
945 static const value_string tele_param_pri_ind_strings[] = {
946 { 0, "Normal" },
947 { 1, "Interactive" },
948 { 2, "Urgent" },
949 { 3, "Emergency" },
950 { 0, NULL }
953 static void
954 tele_param_pri_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
956 guint8 oct;
957 const gchar *str = NULL;
959 EXACT_DATA_CHECK(len, 1);
961 oct = tvb_get_guint8(tvb, offset);
963 str=val_to_str_const((oct&0xc0)>>6, tele_param_pri_ind_strings, "Unknown");
965 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
966 proto_tree_add_text(tree, tvb, offset, 1,
967 "%s : %s",
968 ansi_637_bigbuf,
969 str);
971 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
972 proto_tree_add_text(tree, tvb, offset, 1,
973 "%s : Reserved",
974 ansi_637_bigbuf);
977 static void
978 tele_param_priv_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
980 guint8 oct;
981 const gchar *str = NULL;
983 EXACT_DATA_CHECK(len, 1);
985 oct = tvb_get_guint8(tvb, offset);
987 switch ((oct & 0xc0) >> 6)
989 case 0: str = "Not restricted (privacy level 0)"; break;
990 case 1: str = "Restricted (privacy level 1)"; break;
991 case 2: str = "Confidential (privacy level 2)"; break;
992 case 3: str = "Secret (privacy level 3)"; break;
995 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
996 proto_tree_add_text(tree, tvb, offset, 1,
997 "%s : %s",
998 ansi_637_bigbuf,
999 str);
1001 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1002 proto_tree_add_text(tree, tvb, offset, 1,
1003 "%s : Reserved",
1004 ansi_637_bigbuf);
1007 static void
1008 tele_param_reply_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
1010 guint8 oct;
1012 EXACT_DATA_CHECK(len, 1);
1014 oct = tvb_get_guint8(tvb, offset);
1016 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1017 proto_tree_add_text(tree, tvb, offset, 1,
1018 "%s : %s (manual) acknowledgment is requested",
1019 ansi_637_bigbuf,
1020 (oct & 0x80) ? "User" : "No user");
1022 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
1023 proto_tree_add_text(tree, tvb, offset, 1,
1024 "%s : %s acknowledgment requested",
1025 ansi_637_bigbuf,
1026 (oct & 0x40) ? "Delivery" : "No delivery");
1028 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1029 proto_tree_add_text(tree, tvb, offset, 1,
1030 "%s : Reserved",
1031 ansi_637_bigbuf);
1034 static void
1035 tele_param_num_messages(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
1037 guint8 oct;
1039 EXACT_DATA_CHECK(len, 1);
1041 oct = tvb_get_guint8(tvb, offset);
1043 proto_tree_add_text(tree, tvb, offset, 1,
1044 "Number of voice mail messages: %d%d",
1045 (oct & 0xf0) >> 4,
1046 oct & 0x0f);
1049 static void
1050 tele_param_alert(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
1052 guint8 oct;
1053 const gchar *str = NULL;
1055 EXACT_DATA_CHECK(len, 1);
1057 oct = tvb_get_guint8(tvb, offset);
1059 switch ((oct & 0xc0) >> 6)
1061 case 0: str = "Use Mobile default alert"; break;
1062 case 1: str = "Use Low-priority alert"; break;
1063 case 2: str = "Use Medium-priority alert"; break;
1064 case 3: str = "Use High-priority alert"; break;
1067 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
1068 proto_tree_add_text(tree, tvb, offset, 1,
1069 "%s : %s",
1070 ansi_637_bigbuf,
1071 str);
1073 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1074 proto_tree_add_text(tree, tvb, offset, 1,
1075 "%s : Reserved",
1076 ansi_637_bigbuf);
1079 static void
1080 tele_param_lang_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
1082 guint8 oct;
1083 const gchar *str = NULL;
1085 EXACT_DATA_CHECK(len, 1);
1087 oct = tvb_get_guint8(tvb, offset);
1089 switch (oct)
1091 case 0x00: str = "Unknown or unspecified"; break;
1092 case 0x01: str = "English"; break;
1093 case 0x02: str = "French"; break;
1094 case 0x03: str = "Spanish"; break;
1095 case 0x04: str = "Japanese"; break;
1096 case 0x05: str = "Korean"; break;
1097 case 0x06: str = "Chinese"; break;
1098 case 0x07: str = "Hebrew"; break;
1099 default: str = "Reserved"; break;
1102 proto_tree_add_text(tree, tvb, offset, 1,
1103 "%s", str);
1106 static void
1107 tele_param_cb_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
1109 guint8 oct, oct2, num_fields, odd;
1110 guint32 saved_offset;
1111 guint32 required_octs;
1112 guint32 i;
1114 SHORT_DATA_CHECK(len, 2);
1116 oct = tvb_get_guint8(tvb, offset);
1118 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1119 proto_tree_add_text(tree, tvb, offset, 1,
1120 "%s : Digit mode: %s",
1121 ansi_637_bigbuf,
1122 (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
1124 if (oct & 0x80)
1126 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x70, 8);
1127 proto_tree_add_text(tree, tvb, offset, 1,
1128 "%s : Type of number: (%d)",
1129 ansi_637_bigbuf,
1130 (oct & 0x70) >> 4);
1132 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1133 proto_tree_add_text(tree, tvb, offset, 1,
1134 "%s : Numbering plan: (%d)",
1135 ansi_637_bigbuf,
1136 oct & 0x0f);
1138 offset += 1;
1139 num_fields = tvb_get_guint8(tvb, offset);
1141 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xff, 8);
1142 proto_tree_add_text(tree, tvb, offset, 1,
1143 "%s : Number of fields: (%d)",
1144 ansi_637_bigbuf,
1145 num_fields);
1147 if (num_fields == 0) return;
1149 if (num_fields > (len - 2))
1151 proto_tree_add_text(tree, tvb, offset, 1,
1152 "Missing %d octet(s) for number of fields",
1153 (num_fields + 2) - len);
1155 return;
1158 offset += 1;
1160 i = 0;
1161 while (i < num_fields)
1163 ansi_637_bigbuf[i] = tvb_get_guint8(tvb, offset+i) & 0x7f;
1164 i += 1;
1166 ansi_637_bigbuf[i] = '\0';
1168 proto_tree_add_text(tree, tvb, offset, num_fields,
1169 "Number: %s",
1170 ansi_637_bigbuf);
1172 else
1174 offset += 1;
1175 num_fields = (oct & 0x7f) << 1;
1176 oct2 = tvb_get_guint8(tvb, offset);
1177 num_fields |= ((oct2 & 0x80) >> 7);
1179 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1180 proto_tree_add_text(tree, tvb, offset-1, 1,
1181 "%s : Number of fields (MSB): (%d)",
1182 ansi_637_bigbuf,
1183 num_fields);
1185 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
1186 proto_tree_add_text(tree, tvb, offset, 1,
1187 "%s : Number of fields (LSB)",
1188 ansi_637_bigbuf);
1190 oct = oct2;
1191 odd = FALSE;
1193 if (num_fields > 0)
1195 i = (num_fields - 1) * 4;
1196 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
1198 if (required_octs + 2 > len)
1200 proto_tree_add_text(tree, tvb, offset, 1,
1201 "Missing %d octet(s) for number of fields",
1202 (required_octs + 2) - len);
1204 return;
1207 odd = num_fields & 0x01;
1208 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
1209 saved_offset = offset;
1210 offset += 1;
1212 i = 0;
1213 while (i < num_fields)
1215 ansi_637_bigbuf[i] =
1216 air_digits[(oct & 0x78) >> 3];
1218 i += 1;
1219 if (i >= num_fields) break;
1221 oct2 = tvb_get_guint8(tvb, offset);
1222 offset += 1;
1224 ansi_637_bigbuf[i] =
1225 air_digits[((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7)];
1227 oct = oct2;
1229 i += 1;
1232 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
1233 "Number: %s",
1234 ansi_637_bigbuf);
1237 other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x07: 0x7f, 8);
1238 proto_tree_add_text(tree, tvb, offset, 1,
1239 "%s : Reserved",
1240 ansi_637_bigbuf);
1244 static void
1245 tele_param_disp_mode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
1247 guint8 oct;
1248 const gchar *str = NULL;
1250 EXACT_DATA_CHECK(len, 1);
1252 oct = tvb_get_guint8(tvb, offset);
1254 switch ((oct & 0xc0) >> 6)
1256 case 0: str = "Immediate Display: The mobile station is to display the received message as soon as possible."; break;
1257 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;
1258 case 2: str = "User Invoke: The mobile station is to display the received message based on the mode selected by the user."; break;
1259 case 3: str = "Reserved"; break;
1262 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
1263 proto_tree_add_text(tree, tvb, offset, 1,
1264 "%s : %s",
1265 ansi_637_bigbuf,
1266 str);
1268 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1269 proto_tree_add_text(tree, tvb, offset, 1,
1270 "%s : Reserved",
1271 ansi_637_bigbuf);
1274 #define NUM_TELE_PARAM (sizeof(ansi_tele_param_strings)/sizeof(value_string))
1275 static gint ett_ansi_637_tele_param[NUM_TELE_PARAM];
1276 static void (*ansi_637_tele_param_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data) = {
1277 tele_param_msg_id, /* Message Identifier */
1278 tele_param_user_data, /* User Data */
1279 tele_param_rsp_code, /* User Response Code */
1280 tele_param_timestamp, /* Message Center Time Stamp */
1281 tele_param_timestamp, /* Validity Period Absolute */
1282 tele_param_rel_timestamp, /* Validity Period Relative */
1283 tele_param_timestamp, /* Deferred Delivery Time - Absolute */
1284 tele_param_rel_timestamp, /* Deferred Delivery Time - Relative */
1285 tele_param_pri_ind, /* Priority Indicator */
1286 tele_param_priv_ind, /* Privacy Indicator */
1287 tele_param_reply_opt, /* Reply Option */
1288 tele_param_num_messages, /* Number of Messages */
1289 tele_param_alert, /* Alert on Message Delivery */
1290 tele_param_lang_ind, /* Language Indicator */
1291 tele_param_cb_num, /* Call-Back Number */
1292 tele_param_disp_mode, /* Message Display Mode */
1293 NULL, /* Multiple Encoding User Data */
1294 tele_param_msg_status /* Message status */
1297 static void
1298 trans_param_tele_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1300 guint32 value;
1301 const gchar *str = NULL;
1303 EXACT_DATA_CHECK(len, 2);
1305 value = tvb_get_ntohs(tvb, offset);
1307 ansi_637_trans_tele_id = value;
1309 str = try_val_to_str(value, ansi_tele_id_strings);
1311 if (NULL == str)
1313 switch (value)
1315 case 1:
1316 str = "Reserved for maintenance";
1317 break;
1318 case 4102:
1319 str = "CDMA Service Category Programming Teleservice (SCPT)";
1320 break;
1321 case 4103:
1322 str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
1323 break;
1324 case 32513:
1325 str = "TDMA Cellular Messaging Teleservice";
1326 break;
1327 case 32514:
1328 str = "TDMA Cellular Paging Teleservice (CPT-136)";
1329 break;
1330 case 32515:
1331 str = "TDMA Over-the-Air Activation Teleservice (OATS)";
1332 break;
1333 case 32520:
1334 str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
1335 break;
1336 case 32584:
1337 str = "TDMA Segmented System Assisted Mobile Positioning Service";
1338 break;
1339 default:
1340 if ((value >= 2) && (value <= 4095))
1342 str = "Reserved for assignment by TIA-41";
1344 else if ((value >= 4104) && (value <= 4113))
1346 str = "Reserved for GSM1x Teleservice (CDMA)";
1348 else if ((value >= 4114) && (value <= 32512))
1350 str = "Reserved for assignment by TIA-41";
1352 else if ((value >= 32521) && (value <= 32575))
1354 str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
1356 else if ((value >= 49152) && (value <= 65535))
1358 str = "Reserved for carrier specific teleservices";
1360 else
1362 str = "Unrecognized Teleservice ID";
1364 break;
1368 proto_tree_add_text(tree, tvb, offset, 2,
1369 "%s (%d)",
1370 str,
1371 value);
1373 g_snprintf(add_string, string_len, " - %s (%d)", str, value);
1376 static void
1377 trans_param_srvc_cat(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1379 guint32 value;
1380 const gchar *str = NULL;
1382 EXACT_DATA_CHECK(len, 2);
1384 value = tvb_get_ntohs(tvb, offset);
1386 str = val_to_str_const(value, ansi_srvc_cat_strings, "Reserved");
1388 proto_tree_add_text(tree, tvb, offset, 2,
1389 "%s", str);
1391 g_snprintf(add_string, string_len, " - %s (%d)", str, value);
1394 static void
1395 trans_param_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1397 guint8 oct, oct2, num_fields, odd;
1398 gboolean email_addr;
1399 guint32 saved_offset;
1400 guint32 required_octs;
1401 guint32 i;
1402 const gchar *str;
1404 SHORT_DATA_CHECK(len, 2);
1406 email_addr = FALSE;
1408 oct = tvb_get_guint8(tvb, offset);
1410 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1411 proto_tree_add_text(tree, tvb, offset, 1,
1412 "%s : Digit mode: %s",
1413 ansi_637_bigbuf,
1414 (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
1416 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
1417 proto_tree_add_text(tree, tvb, offset, 1,
1418 "%s : Number mode: %s",
1419 ansi_637_bigbuf,
1420 (oct & 0x40) ? "Data Network Address" : "ANSI T1.607");
1422 if (oct & 0x80)
1424 if (oct & 0x40)
1426 switch ((oct & 0x38) >> 3)
1428 case 0: str = "Unknown"; break;
1429 case 1: str = "Internet Protocol (RFC 791)"; break;
1430 case 2: str = "Internet Email Address (RFC 822)"; email_addr = TRUE; break;
1431 default:
1432 str = "Reserved";
1433 break;
1436 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
1437 proto_tree_add_text(tree, tvb, offset, 1,
1438 "%s : Type of number: %s (%d)",
1439 ansi_637_bigbuf,
1440 str,
1441 (oct & 0x38) >> 3);
1443 offset += 1;
1444 num_fields = (oct & 0x07) << 5;
1445 oct2 = tvb_get_guint8(tvb, offset);
1446 num_fields |= ((oct2 & 0xf8) >> 3);
1448 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1449 proto_tree_add_text(tree, tvb, offset-1, 1,
1450 "%s : Number of fields (MSB): (%d)",
1451 ansi_637_bigbuf,
1452 num_fields);
1454 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
1455 proto_tree_add_text(tree, tvb, offset, 1,
1456 "%s : Number of fields (LSB)",
1457 ansi_637_bigbuf);
1459 if (num_fields == 0) return;
1461 if (num_fields > (len - 2))
1463 proto_tree_add_text(tree, tvb, offset, 1,
1464 "Missing %d octet(s) for number of fields",
1465 (num_fields + 2) - len);
1467 return;
1470 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
1471 proto_tree_add_text(tree, tvb, offset, 1,
1472 "%s : Most significant bits of first field",
1473 ansi_637_bigbuf);
1475 offset += 1;
1476 oct = oct2;
1478 i = 0;
1479 while (i < num_fields)
1481 ansi_637_bigbuf[i] = (oct & 0x07) << 5;
1482 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf8) >> 3;
1483 i += 1;
1485 ansi_637_bigbuf[i] = '\0';
1487 if (email_addr)
1489 proto_tree_add_text(tree, tvb, offset, num_fields - 1,
1490 "Number: %s",
1491 ansi_637_bigbuf);
1493 else
1495 proto_tree_add_bytes(tree, hf_ansi_637_trans_bin_addr, tvb, offset, num_fields - 1,
1496 (guint8*)ansi_637_bigbuf);
1499 offset += (num_fields - 1);
1501 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
1502 proto_tree_add_text(tree, tvb, offset, 1,
1503 "%s : Least significant bits of last field",
1504 ansi_637_bigbuf);
1506 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1507 proto_tree_add_text(tree, tvb, offset, 1,
1508 "%s : Reserved",
1509 ansi_637_bigbuf);
1511 else
1513 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
1514 proto_tree_add_text(tree, tvb, offset, 1,
1515 "%s : Type of number: (%d)",
1516 ansi_637_bigbuf,
1517 (oct & 0x38) >> 3);
1519 oct2 = tvb_get_guint8(tvb, offset + 1);
1521 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
1522 proto_tree_add_text(tree, tvb, offset, 1,
1523 "%s : Numbering plan (MSB): (%d)",
1524 ansi_637_bigbuf,
1525 ((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7));
1527 offset += 1;
1528 oct = oct2;
1530 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1531 proto_tree_add_text(tree, tvb, offset, 1,
1532 "%s : Numbering plan (LSB)",
1533 ansi_637_bigbuf);
1535 offset += 1;
1536 num_fields = (oct & 0x7f) << 1;
1537 oct2 = tvb_get_guint8(tvb, offset);
1538 num_fields |= ((oct2 & 0x80) >> 7);
1540 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1541 proto_tree_add_text(tree, tvb, offset-1, 1,
1542 "%s : Number of fields (MSB): (%d)",
1543 ansi_637_bigbuf,
1544 num_fields);
1546 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
1547 proto_tree_add_text(tree, tvb, offset, 1,
1548 "%s : Number of fields (LSB)",
1549 ansi_637_bigbuf);
1551 if (num_fields == 0) return;
1553 if (num_fields > (len - 3))
1555 proto_tree_add_text(tree, tvb, offset, 1,
1556 "Missing %d octet(s) for number of fields",
1557 (num_fields + 3) - len);
1559 return;
1562 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x7f, 8);
1563 proto_tree_add_text(tree, tvb, offset, 1,
1564 "%s : Most significant bits of first field",
1565 ansi_637_bigbuf);
1567 offset += 1;
1568 oct = oct2;
1570 i = 0;
1571 while (i < num_fields)
1573 ansi_637_bigbuf[i] = (oct & 0x7f) << 1;
1574 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0x80) >> 7;
1575 i += 1;
1577 ansi_637_bigbuf[i] = '\0';
1579 proto_tree_add_text(tree, tvb, offset, num_fields - 1,
1580 "Number: %s",
1581 ansi_637_bigbuf);
1583 offset += (num_fields - 1);
1585 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
1586 proto_tree_add_text(tree, tvb, offset, 1,
1587 "%s : Least significant bit of last field",
1588 ansi_637_bigbuf);
1590 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
1591 proto_tree_add_text(tree, tvb, offset, 1,
1592 "%s : Reserved",
1593 ansi_637_bigbuf);
1596 else
1598 offset += 1;
1599 num_fields = (oct & 0x3f) << 2;
1600 oct2 = tvb_get_guint8(tvb, offset);
1601 num_fields |= ((oct2 & 0xc0) >> 6);
1603 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
1604 proto_tree_add_text(tree, tvb, offset-1, 1,
1605 "%s : Number of fields (MSB): (%d)",
1606 ansi_637_bigbuf,
1607 num_fields);
1609 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xc0, 8);
1610 proto_tree_add_text(tree, tvb, offset, 1,
1611 "%s : Number of fields (LSB)",
1612 ansi_637_bigbuf);
1614 oct = oct2;
1615 odd = FALSE;
1617 if (num_fields > 0)
1619 i = (num_fields - 1) * 4;
1620 required_octs = (i / 8) + ((i % 8) ? 1 : 0);
1622 if (required_octs + 2 > len)
1624 proto_tree_add_text(tree, tvb, offset, 1,
1625 "Missing %d octet(s) for number of fields",
1626 (required_octs + 2) - len);
1628 return;
1631 odd = num_fields & 0x01;
1632 memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
1633 saved_offset = offset;
1634 offset += 1;
1636 i = 0;
1637 while (i < num_fields)
1639 ansi_637_bigbuf[i] =
1640 air_digits[(oct & 0x3c) >> 2];
1642 i += 1;
1643 if (i >= num_fields) break;
1645 oct2 = tvb_get_guint8(tvb, offset);
1646 offset += 1;
1648 ansi_637_bigbuf[i] =
1649 air_digits[((oct & 0x03) << 2) | ((oct2 & 0xc0) >> 6)];
1651 oct = oct2;
1653 i += 1;
1656 proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
1657 "Number: %s",
1658 ansi_637_bigbuf);
1661 other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x03: 0x3f, 8);
1662 proto_tree_add_text(tree, tvb, offset, 1,
1663 "%s : Reserved",
1664 ansi_637_bigbuf);
1668 static void
1669 trans_param_subaddress(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1671 guint8 oct, oct2, num_fields;
1672 guint32 i;
1673 const gchar *str;
1675 SHORT_DATA_CHECK(len, 2);
1677 oct = tvb_get_guint8(tvb, offset);
1679 switch ((oct & 0xe0) >> 5)
1681 case 0: str = "NSAP (CCITT Recommendation X.213 or ISO 8348 AD2)"; break;
1682 case 1: str = "User-specified"; break;
1683 default:
1684 str = "Reserved";
1685 break;
1688 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xe0, 8);
1689 proto_tree_add_text(tree, tvb, offset, 1,
1690 "%s : Type: %s",
1691 ansi_637_bigbuf,
1692 str);
1694 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x10, 8);
1695 proto_tree_add_text(tree, tvb, offset, 1,
1696 "%s : Odd",
1697 ansi_637_bigbuf);
1699 offset += 1;
1700 num_fields = (oct & 0x0f) << 4;
1701 oct2 = tvb_get_guint8(tvb, offset);
1702 num_fields |= ((oct2 & 0xf0) >> 4);
1704 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1705 proto_tree_add_text(tree, tvb, offset-1, 1,
1706 "%s : Number of fields (MSB): (%d)",
1707 ansi_637_bigbuf,
1708 num_fields);
1710 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf0, 8);
1711 proto_tree_add_text(tree, tvb, offset, 1,
1712 "%s : Number of fields (LSB)",
1713 ansi_637_bigbuf);
1715 if (num_fields == 0) return;
1717 if (num_fields > (len - 2))
1719 proto_tree_add_text(tree, tvb, offset, 1,
1720 "Missing %d octet(s) for number of fields",
1721 (num_fields + 2) - len);
1723 return;
1726 other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x0f, 8);
1727 proto_tree_add_text(tree, tvb, offset, 1,
1728 "%s : Most significant bits of first field",
1729 ansi_637_bigbuf);
1731 offset += 1;
1732 oct = oct2;
1734 i = 0;
1735 while (i < num_fields)
1737 ansi_637_bigbuf[i] = (oct & 0x0f) << 4;
1738 ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf0) >> 4;
1739 i += 1;
1741 ansi_637_bigbuf[i] = '\0';
1743 proto_tree_add_bytes(tree, hf_ansi_637_trans_bin_addr, tvb, offset, num_fields - 1,
1744 (guint8*)ansi_637_bigbuf);
1746 offset += (num_fields - 1);
1748 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf0, 8);
1749 proto_tree_add_text(tree, tvb, offset, 1,
1750 "%s : Least significant bits of last field",
1751 ansi_637_bigbuf);
1753 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
1754 proto_tree_add_text(tree, tvb, offset, 1,
1755 "%s : Reserved",
1756 ansi_637_bigbuf);
1759 static void
1760 trans_param_bearer_reply_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len _U_, guint32 offset, gchar *add_string, int string_len)
1762 guint8 oct;
1764 oct = tvb_get_guint8(tvb, offset);
1766 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
1767 proto_tree_add_text(tree, tvb, offset, 1,
1768 "%s : Reply Sequence Number: %d",
1769 ansi_637_bigbuf,
1770 (oct & 0xfc) >> 2);
1772 g_snprintf(add_string, string_len, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
1774 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
1775 proto_tree_add_text(tree, tvb, offset, 1,
1776 "%s : Reserved",
1777 ansi_637_bigbuf);
1780 static void
1781 trans_param_cause_codes(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
1783 guint8 oct;
1784 const gchar *str = NULL;
1786 oct = tvb_get_guint8(tvb, offset);
1788 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
1789 proto_tree_add_text(tree, tvb, offset, 1,
1790 "%s : Reply Sequence Number: %d",
1791 ansi_637_bigbuf,
1792 (oct & 0xfc) >> 2);
1794 switch (oct & 0x03)
1796 case 0x00: str = "No error"; break;
1797 case 0x02: str = "Temporary Condition"; break;
1798 case 0x03: str = "Permanent Condition"; break;
1799 default:
1800 str = "Reserved";
1801 break;
1804 g_snprintf(add_string, string_len, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
1806 other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
1807 proto_tree_add_text(tree, tvb, offset, 1,
1808 "%s : Error Class: %s",
1809 ansi_637_bigbuf,
1810 str);
1812 offset += 1;
1814 if (!(oct & 0x03)) return;
1816 if (len == 1) return;
1818 oct = tvb_get_guint8(tvb, offset);
1820 switch (oct)
1822 case 0: str = "Address vacant"; break;
1823 case 1: str = "Address translation failure"; break;
1824 case 2: str = "Network resource shortage"; break;
1825 case 3: str = "Network failure"; break;
1826 case 4: str = "Invalid Teleservice ID"; break;
1827 case 5: str = "Other network problem"; break;
1828 case 6: str = "Unsupported network interface"; break;
1829 case 32: str = "No page response"; break;
1830 case 33: str = "Destination busy"; break;
1831 case 34: str = "No acknowledgement"; break;
1832 case 35: str = "Destination resource shortage"; break;
1833 case 36: str = "SMS delivery postponed"; break;
1834 case 37: str = "Destination out of service"; break;
1835 case 38: str = "Destination no longer at this address"; break;
1836 case 39: str = "Other terminal problem"; break;
1837 case 64: str = "Radio interface resource shortage"; break;
1838 case 65: str = "Radio interface incompatibility"; break;
1839 case 66: str = "Other radio interface problem"; break;
1840 case 67: str = "Unsupported Base Station Capability"; break;
1841 case 96: str = "Encoding problem"; break;
1842 case 97: str = "Service origination denied"; break;
1843 case 98: str = "Service termination denied"; break;
1844 case 99: str = "Supplementary service not supported"; break;
1845 case 100: str = "Service not supported"; break;
1846 case 101: str = "Reserved"; break;
1847 case 102: str = "Missing expected parameter"; break;
1848 case 103: str = "Missing mandatory parameter"; break;
1849 case 104: str = "Unrecognized parameter value"; break;
1850 case 105: str = "Unexpected parameter value"; break;
1851 case 106: str = "User Data size error"; break;
1852 case 107: str = "Other general problems"; break;
1853 case 108: str = "Session not active"; break;
1854 default:
1855 if ((oct >= 7) && (oct <= 31)) { str = "Reserved, treat as Other network problem"; }
1856 else if ((oct >= 40) && (oct <= 47)) { str = "Reserved, treat as Other terminal problem"; }
1857 else if ((oct >= 48) && (oct <= 63)) { str = "Reserved, treat as SMS delivery postponed"; }
1858 else if ((oct >= 68) && (oct <= 95)) { str = "Reserved, treat as Other radio interface problem"; }
1859 else if ((oct >= 109) && (oct <= 223)) { str = "Reserved, treat as Other general problems"; }
1860 else { str = "Reserved for protocol extension, treat as Other general problems"; }
1861 break;
1864 proto_tree_add_text(tree, tvb, offset, 1,
1865 "%s", str);
1868 static void
1869 trans_param_bearer_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
1871 tvbuff_t *tele_tvb;
1873 proto_tree_add_text(tree, tvb, offset, len,
1874 "Bearer Data");
1877 * dissect the embedded teleservice data
1879 tele_tvb = tvb_new_subset(tvb, offset, len, len);
1881 dissector_try_uint(tele_dissector_table, ansi_637_trans_tele_id,
1882 tele_tvb, pinfo, g_tree);
1885 #define NUM_TRANS_PARAM (sizeof(ansi_trans_param_strings)/sizeof(value_string))
1886 static gint ett_ansi_637_trans_param[NUM_TRANS_PARAM];
1887 static void (*ansi_637_trans_param_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len) = {
1888 trans_param_tele_id, /* Teleservice Identifier */
1889 trans_param_srvc_cat, /* Service Category */
1890 trans_param_address, /* Originating Address */
1891 trans_param_subaddress, /* Originating Subaddress */
1892 trans_param_address, /* Destination Address */
1893 trans_param_subaddress, /* Destination Subaddress */
1894 trans_param_bearer_reply_opt, /* Bearer Reply Option */
1895 trans_param_cause_codes, /* Cause Codes */
1896 trans_param_bearer_data, /* Bearer Data */
1897 NULL, /* NONE */
1900 #define NUM_TRANS_MSG_TYPE (sizeof(ansi_trans_msg_type_strings)/sizeof(value_string))
1901 static gint ett_ansi_637_trans_msg[NUM_TRANS_MSG_TYPE];
1903 /* GENERIC IS-637 DISSECTOR FUNCTIONS */
1905 static gboolean
1906 dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 *offset, gboolean* has_private_data)
1908 void (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, guint, guint32, gboolean*) = NULL;
1909 guint8 oct;
1910 guint8 len;
1911 guint32 curr_offset;
1912 gint ett_param_idx, idx;
1913 proto_tree *subtree;
1914 proto_item *item;
1915 const gchar *str = NULL;
1918 curr_offset = *offset;
1920 oct = tvb_get_guint8(tvb, curr_offset);
1921 str = try_val_to_str_idx((guint32) oct, ansi_tele_param_strings, &idx);
1923 if (NULL == str)
1925 return(FALSE);
1928 ett_param_idx = ett_ansi_637_tele_param[idx];
1929 param_fcn = ansi_637_tele_param_fcn[idx];
1931 item =
1932 proto_tree_add_text(tree, tvb, curr_offset, -1, "%s", str);
1934 subtree = proto_item_add_subtree(item, ett_param_idx);
1936 proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id,
1937 tvb, curr_offset, 1, oct);
1939 curr_offset += 1;
1941 len = tvb_get_guint8(tvb, curr_offset);
1943 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
1945 proto_tree_add_uint(subtree, hf_ansi_637_tele_length,
1946 tvb, curr_offset, 1, len);
1948 curr_offset += 1;
1950 if (len > 0)
1952 if (param_fcn == NULL)
1954 proto_tree_add_text(subtree, tvb, curr_offset,
1955 len, "Parameter Data");
1957 else
1959 (*param_fcn)(tvb, pinfo, subtree, len, curr_offset, has_private_data);
1962 curr_offset += len;
1965 *offset = curr_offset;
1967 return(TRUE);
1970 static void
1971 dissect_ansi_637_tele_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ansi_637_tree, gboolean* has_private_data)
1973 guint8 len;
1974 guint32 curr_offset;
1976 curr_offset = 0;
1977 len = tvb_length(tvb);
1979 while ((len - curr_offset) > 0)
1981 if (!dissect_ansi_637_tele_param(tvb, pinfo, ansi_637_tree, &curr_offset, has_private_data))
1983 proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
1984 "Unknown Parameter Data");
1985 break;
1990 static void
1991 dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1993 proto_item *ansi_637_item;
1994 proto_tree *ansi_637_tree = NULL;
1995 const gchar *str = NULL;
1996 guint32 value;
1997 gboolean has_private_data = FALSE;
1999 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
2001 /* In the interest of speed, if "tree" is NULL, don't do any work not
2002 * necessary to generate protocol tree items.
2004 if (tree)
2006 g_tree = tree;
2008 value = pinfo->match_uint;
2011 * create the ansi_637 protocol tree
2013 str = try_val_to_str(value, ansi_tele_id_strings);
2015 if (NULL == str)
2017 switch (value)
2019 case 1:
2020 str = "Reserved for maintenance";
2021 break;
2022 case 4102:
2023 str = "CDMA Service Category Programming Teleservice (SCPT)";
2024 break;
2025 case 4103:
2026 str = "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
2027 break;
2028 case 32513:
2029 str = "TDMA Cellular Messaging Teleservice";
2030 break;
2031 case 32514:
2032 str = "TDMA Cellular Paging Teleservice (CPT-136)";
2033 break;
2034 case 32515:
2035 str = "TDMA Over-the-Air Activation Teleservice (OATS)";
2036 break;
2037 case 32520:
2038 str = "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
2039 break;
2040 case 32584:
2041 str = "TDMA Segmented System Assisted Mobile Positioning Service";
2042 break;
2043 default:
2044 if ((value >= 2) && (value <= 4095))
2046 str = "Reserved for assignment by TIA-41";
2048 else if ((value >= 4104) && (value <= 4113))
2050 str = "Reserved for GSM1x Teleservice (CDMA)";
2052 else if ((value >= 4114) && (value <= 32512))
2054 str = "Reserved for assignment by TIA-41";
2056 else if ((value >= 32521) && (value <= 32575))
2058 str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
2060 else if ((value >= 49152) && (value < 65535))
2062 str = "Reserved for carrier specific teleservices";
2064 else if (value == 65535)
2067 * supposed to be "Reserved for carrier specific teleservices"
2068 * but we are using it to key SMS Broadcast dissection where
2069 * there is no teleservice ID
2071 str = "(Reserved) Being used for Broadcast";
2073 else
2075 str = "Unrecognized Teleservice ID";
2077 break;
2081 ansi_637_item =
2082 proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
2083 "%s - %s (%d)",
2084 ansi_proto_name_tele,
2085 str,
2086 pinfo->match_uint);
2088 ansi_637_tree =
2089 proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele);
2091 dissect_ansi_637_tele_message(tvb, pinfo, ansi_637_tree, &has_private_data);
2095 static gboolean
2096 dissect_ansi_637_trans_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 *offset)
2098 void (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, guint, guint32, gchar *, int) = NULL;
2099 guint8 oct;
2100 guint8 len;
2101 guint32 curr_offset;
2102 gint ett_param_idx, idx;
2103 proto_tree *subtree;
2104 proto_item *item;
2105 const gchar *str = NULL;
2107 curr_offset = *offset;
2109 oct = tvb_get_guint8(tvb, curr_offset);
2110 str = try_val_to_str_idx((guint32) oct, ansi_trans_param_strings, &idx);
2112 if (NULL == str)
2114 return(FALSE);
2117 ett_param_idx = ett_ansi_637_trans_param[idx];
2118 param_fcn = ansi_637_trans_param_fcn[idx];
2120 item =
2121 proto_tree_add_text(tree, tvb, curr_offset, -1, "%s", str);
2123 subtree = proto_item_add_subtree(item, ett_param_idx);
2125 proto_tree_add_uint(subtree, hf_ansi_637_trans_param_id,
2126 tvb, curr_offset, 1, oct);
2128 curr_offset += 1;
2130 len = tvb_get_guint8(tvb, curr_offset);
2132 proto_item_set_len(item, (curr_offset - *offset) + len + 1);
2134 proto_tree_add_uint(subtree, hf_ansi_637_trans_length,
2135 tvb, curr_offset, 1, len);
2137 curr_offset += 1;
2139 if (len > 0)
2141 if (param_fcn == NULL)
2143 proto_tree_add_text(subtree, tvb, curr_offset,
2144 len, "Parameter Data");
2146 else
2148 gchar *ansi_637_add_string;
2150 ansi_637_add_string = (gchar *)wmem_alloc(wmem_packet_scope(), 1024);
2151 ansi_637_add_string[0] = '\0';
2152 (*param_fcn)(tvb, pinfo, subtree, len, curr_offset, ansi_637_add_string, 1024);
2154 if (ansi_637_add_string[0] != '\0')
2156 proto_item_append_text(item, "%s", ansi_637_add_string);
2160 curr_offset += len;
2163 *offset = curr_offset;
2165 return(TRUE);
2169 static void
2170 dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2172 proto_item *ansi_637_item;
2173 proto_tree *ansi_637_tree = NULL;
2174 guint32 curr_offset;
2175 gint idx;
2176 const gchar *str = NULL;
2177 guint8 oct;
2178 guint8 len;
2180 col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
2182 /* In the interest of speed, if "tree" is NULL, don't do any work not
2183 * necessary to generate protocol tree items.
2185 if (tree)
2187 g_tree = tree;
2190 * reset the teleservice ID for each dissection
2192 ansi_637_trans_tele_id = 0;
2195 * create the ansi_637 protocol tree
2197 oct = tvb_get_guint8(tvb, 0);
2199 str = try_val_to_str_idx(oct, ansi_trans_msg_type_strings, &idx);
2201 if (NULL == str)
2203 ansi_637_item =
2204 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
2205 "%s - Unrecognized Transport Layer Message Type (%d)",
2206 ansi_proto_name_trans,
2207 oct);
2209 ansi_637_tree =
2210 proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans);
2212 else
2214 ansi_637_item =
2215 proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
2216 "%s - %s",
2217 ansi_proto_name_trans,
2218 str);
2220 ansi_637_tree =
2221 proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans_msg[idx]);
2223 if (oct == ANSI_TRANS_MSG_TYPE_BROADCAST)
2226 * there is no teleservice ID for Broadcast but we want the
2227 * bearer data to be dissected
2229 * using a reserved value to key dissector port
2231 ansi_637_trans_tele_id = 65535;
2235 curr_offset = 1;
2237 len = tvb_length(tvb);
2239 while ((len - curr_offset) > 0)
2241 if (!dissect_ansi_637_trans_param(tvb, pinfo, ansi_637_tree, &curr_offset))
2243 proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
2244 "Unknown Parameter Data");
2245 break;
2250 /* Dissect SMS embedded in SIP */
2251 static void
2252 dissect_ansi_637_trans_app(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2254 col_set_str(pinfo->cinfo, COL_PROTOCOL,"/");
2255 col_set_fence(pinfo->cinfo, COL_INFO);
2256 dissect_ansi_637_trans(tvb, pinfo, tree);
2258 /* Register the protocol with Wireshark */
2259 void
2260 proto_register_ansi_637(void)
2262 guint i;
2264 /* Setup list of header fields */
2265 static hf_register_info hf_trans[] =
2267 #if 0
2268 { &hf_ansi_637_trans_msg_type,
2269 { "Message Type",
2270 "ansi_637_trans.msg_type",
2271 FT_UINT24, BASE_DEC, VALS(ansi_trans_msg_type_strings), 0xf00000,
2272 NULL, HFILL }},
2273 #endif
2274 { &hf_ansi_637_trans_param_id,
2275 { "Transport Param ID", "ansi_637_trans.param_id",
2276 FT_UINT8, BASE_DEC, VALS(ansi_trans_param_strings), 0,
2277 NULL, HFILL }},
2278 { &hf_ansi_637_trans_length,
2279 { "Length", "ansi_637_trans.len",
2280 FT_UINT8, BASE_DEC, NULL, 0,
2281 NULL, HFILL }},
2282 { &hf_ansi_637_trans_bin_addr,
2283 { "Binary Address", "ansi_637_trans.bin_addr",
2284 FT_BYTES, BASE_NONE, 0, 0,
2285 NULL, HFILL }},
2287 static hf_register_info hf_tele[] =
2289 { &hf_ansi_637_tele_msg_type,
2290 { "Message Type",
2291 "ansi_637_tele.msg_type",
2292 FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_type_strings), 0xf00000,
2293 NULL, HFILL }},
2294 { &hf_ansi_637_tele_msg_id,
2295 { "Message ID",
2296 "ansi_637_tele.msg_id",
2297 FT_UINT24, BASE_DEC, NULL, 0x0ffff0,
2298 NULL, HFILL }},
2299 { &hf_ansi_637_tele_msg_status,
2300 { "Message Status",
2301 "ansi_637_tele.msg_status",
2302 FT_UINT8, BASE_DEC, VALS(ansi_tele_msg_status_strings), 0,
2303 NULL, HFILL }},
2304 { &hf_ansi_637_tele_msg_ind,
2305 { "Header Indicator",
2306 "ansi_637_tele.msg_ind",
2307 FT_UINT24, BASE_DEC, NULL, 0x000008,
2308 NULL, HFILL }},
2309 { &hf_ansi_637_tele_msg_rsvd,
2310 { "Reserved",
2311 "ansi_637_tele.msg_rsvd",
2312 FT_UINT24, BASE_DEC, NULL, 0x000007,
2313 NULL, HFILL }},
2314 { &hf_ansi_637_tele_length,
2315 { "Length", "ansi_637_tele.len",
2316 FT_UINT8, BASE_DEC, NULL, 0,
2317 NULL, HFILL }},
2318 { &hf_ansi_637_tele_subparam_id,
2319 { "Teleservice Subparam ID", "ansi_637_tele.subparam_id",
2320 FT_UINT8, BASE_DEC, VALS(ansi_tele_param_strings), 0,
2321 NULL, HFILL }},
2322 { &hf_ansi_637_tele_user_data_text,
2323 { "Encoded user data", "ansi_637_tele.user_data.text",
2324 FT_STRING, BASE_NONE, NULL, 0,
2325 NULL, HFILL }},
2328 /* Setup protocol subtree array */
2329 #define NUM_INDIVIDUAL_PARAMS 3
2330 gint *ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM];
2332 memset((void *) ett, 0, sizeof(ett));
2334 ett[0] = &ett_ansi_637_tele;
2335 ett[1] = &ett_ansi_637_trans;
2336 ett[2] = &ett_params;
2338 for (i=0; i < NUM_TELE_PARAM; i++)
2340 ett_ansi_637_tele_param[i] = -1;
2341 ett[NUM_INDIVIDUAL_PARAMS+i] = &ett_ansi_637_tele_param[i];
2344 for (i=0; i < NUM_TRANS_MSG_TYPE; i++)
2346 ett_ansi_637_trans_msg[i] = -1;
2347 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+i] = &ett_ansi_637_trans_msg[i];
2350 for (i=0; i < NUM_TRANS_PARAM; i++)
2352 ett_ansi_637_trans_param[i] = -1;
2353 ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+i] = &ett_ansi_637_trans_param[i];
2356 /* Register the protocol name and description */
2357 proto_ansi_637_tele =
2358 proto_register_protocol(ansi_proto_name_tele, "ANSI IS-637-A Teleservice", "ansi_637_tele");
2360 proto_ansi_637_trans =
2361 proto_register_protocol(ansi_proto_name_trans, "ANSI IS-637-A Transport", "ansi_637_trans");
2363 ansi_637_tele_handle = register_dissector("ansi_637_tele", dissect_ansi_637_tele, proto_ansi_637_tele);
2364 ansi_637_trans_handle = register_dissector("ansi_637_trans", dissect_ansi_637_trans, proto_ansi_637_trans);
2366 /* Required function calls to register the header fields and subtrees used */
2367 proto_register_field_array(proto_ansi_637_tele, hf_tele, array_length(hf_tele));
2368 proto_register_field_array(proto_ansi_637_trans, hf_trans, array_length(hf_trans));
2369 proto_register_subtree_array(ett, array_length(ett));
2371 tele_dissector_table =
2372 register_dissector_table("ansi_637.tele_id",
2373 "ANSI IS-637-A Teleservice ID", FT_UINT8, BASE_DEC);
2377 void
2378 proto_reg_handoff_ansi_637(void)
2380 dissector_handle_t ansi_637_trans_app_handle;
2381 guint i;
2383 ansi_637_trans_app_handle = create_dissector_handle(dissect_ansi_637_trans_app, proto_ansi_637_trans);
2385 /* Dissect messages embedded in SIP */
2386 dissector_add_string("media_type","application/vnd.3gpp2.sms", ansi_637_trans_app_handle);
2388 * register for all known teleservices
2389 * '-1' is to stop before trailing '0' entry
2391 * to add teleservices, modify 'ansi_tele_id_strings'
2393 for (i=0; i < ((sizeof(ansi_tele_id_strings)/sizeof(value_string))-1); i++)
2396 * ANSI MAP dissector will push out teleservice ids
2398 dissector_add_uint("ansi_map.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
2401 * we will push out teleservice ids after Transport layer decode
2403 dissector_add_uint("ansi_637.tele_id", ansi_tele_id_strings[i].value, ansi_637_tele_handle);
2407 * ANSI A-interface will push out transport layer data
2409 dissector_add_uint("ansi_a.sms", 0, ansi_637_trans_handle);