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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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" },
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)" },
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"},
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" },
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" },
149 #define ANSI_TRANS_MSG_TYPE_BROADCAST 1
151 static const value_string ansi_trans_msg_type_strings
[] = {
152 { 0, "Point-to-Point" },
154 { 2, "Acknowledge" },
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" },
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
;
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; */
226 /* saved_offset = *offset; */
227 oct
= oct2
= *last_oct
;
232 oct2
= tvb_get_guint8(tvb
, *offset
);
236 for (i
=0; i
< num_fields
; i
++)
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
);
258 buf
[i
] = ((oct
& 0x01) << 6) | ((oct2
& 0xfc) >> 2);
262 buf
[i
] = ((oct
& 0x03) << 5) | ((oct2
& 0xf8) >> 3);
266 buf
[i
] = ((oct
& 0x07) << 4) | ((oct2
& 0xf0) >> 4);
270 buf
[i
] = ((oct
& 0x0f) << 3) | ((oct2
& 0xe0) >> 5);
274 buf
[i
] = ((oct
& 0x1f) << 2) | ((oct2
& 0xc0) >> 6);
278 buf
[i
] = ((oct
& 0x3f) << 1) | ((oct2
& 0x80) >> 7);
286 buf
[i
] = (oct
& 0xfe) >> 1;
295 *last_oct
= (bit
== 1) ? oct
: oct2
;
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 (?)"); \
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"); \
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 */
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 */
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 */
367 error_class
= ((oct
& 0xc0) >> 6);
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",
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",
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",
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",
442 tele_param_user_data(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data
)
450 guint32 required_octs
;
451 guint32 saved_offset
;
453 const gchar
*str
= NULL
;
455 tvbuff_t
*tvb_out
= NULL
;
457 gchar
*utf8_text
= NULL
;
459 GError
*l_conv_error
= NULL
;
461 SHORT_DATA_CHECK(len
, 2);
466 oct
= tvb_get_guint8(tvb
, offset
);
471 encoding
= ((oct
& 0xf8) >> 3);
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);
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,
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)",
505 other_decode_bitfield_value(ansi_637_bigbuf
, oct2
, 0xf8, 8);
506 proto_tree_add_text(tree
, tvb
, offset
+1, 1,
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",
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)",
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",
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)
555 * 3 bits remaining from last 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
);
571 saved_offset
= offset
- 1;
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);
582 tvb_out
= tvb_new_child_real_data(tvb
, buf
, required_octs
, required_octs
);
583 add_new_data_source(pinfo
, tvb_out
, "Characters");
586 if (*has_private_data
== TRUE
) {
587 dis_field_udh(tvb_out
, tree
, &offset
, &required_octs
, &num_fields
, TRUE
, &bit
);
590 saved_offset
= offset
;
592 oct
= tvb_get_guint8(tvb_out
, offset
);
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
);
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;
613 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, oct2
, 8);
614 proto_tree_add_text(tree
, tvb
, offset
- 1, 1,
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
);
633 saved_offset
= offset
- 1;
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);
644 tvb_out
= tvb_new_child_real_data(tvb
, buf
, required_octs
, required_octs
);
645 add_new_data_source(pinfo
, tvb_out
, "Characters");
648 if (*has_private_data
== TRUE
) {
649 dis_field_udh(tvb_out
, tree
, &offset
, &required_octs
, &num_fields
, TRUE
, &bit
);
651 saved_offset
= offset
;
653 oct
= tvb_get_guint8(tvb_out
, offset
);
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);
674 tvb_out
= tvb_new_child_real_data(tvb
, buf
, required_octs
, required_octs
);
675 add_new_data_source(pinfo
, tvb_out
, "Characters");
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
);
686 proto_tree_add_unicode_string(tree
, hf_ansi_637_tele_user_data_text
, tvb_out
, offset
,
687 required_octs
, utf8_text
);
691 proto_tree_add_text(tree
, tvb_out
, offset
, required_octs
, "%s", "Failed on UCS-2BE contact Wireshark developers");
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);
709 tvb_out
= tvb_new_child_real_data(tvb
, buf
, num_fields
, num_fields
);
710 add_new_data_source(pinfo
, tvb_out
, "Characters");
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
);
722 proto_tree_add_unicode_string(tree
, hf_ansi_637_tele_user_data_text
, tvb_out
, offset
,
723 num_fields
, utf8_text
);
727 proto_tree_add_text(tree
, tvb_out
, offset
, num_fields
, "%s", "Failed on iso-8859-8 contact Wireshark developers");
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);
745 tvb_out
= tvb_new_child_real_data(tvb
, buf
, num_fields
, num_fields
);
746 add_new_data_source(pinfo
, tvb_out
, "Characters");
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
);
758 proto_tree_add_unicode_string(tree
, hf_ansi_637_tele_user_data_text
, tvb_out
, offset
,
759 num_fields
, utf8_text
);
763 proto_tree_add_text(tree
, tvb_out
, offset
, num_fields
, "%s", "Failed on iso-8859-1 contact Wireshark developers");
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
);
784 saved_offset
= offset
- 1;
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);
795 tvb_out
= tvb_new_child_real_data(tvb
, buf
, required_octs
, required_octs
);
796 add_new_data_source(pinfo
, tvb_out
, "Characters");
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);
821 tvb_out
= tvb_new_child_real_data(tvb
, buf
, num_fields
, num_fields
);
822 add_new_data_source(pinfo
, tvb_out
, "Characters");
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
);
834 proto_tree_add_unicode_string(tree
, hf_ansi_637_tele_user_data_text
, tvb_out
, offset
,
835 num_fields
, utf8_text
);
839 proto_tree_add_text(tree
, tvb_out
, offset
, num_fields
, "%s", "Failed on EUC-KR contact Wireshark developers");
848 proto_tree_add_text(tree
, tvb
, offset
, len
- used
,
849 "Encoded user data");
854 tele_param_rsp_code(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
858 EXACT_DATA_CHECK(len
, 1);
863 oct
= tvb_get_guint8(tvb
, offset
);
865 proto_tree_add_text(tree
, tvb
, offset
, 1,
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",
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",
907 tele_param_rel_timestamp(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
911 const gchar
*str
= NULL
;
912 const gchar
*str2
= NULL
;
914 EXACT_DATA_CHECK(len
, 1);
916 oct
= tvb_get_guint8(tvb
, offset
);
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;
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; }
934 proto_tree_add_text(tree
, tvb
, offset
, 1,
939 proto_tree_add_text(tree
, tvb
, offset
, 1,
945 static const value_string tele_param_pri_ind_strings
[] = {
947 { 1, "Interactive" },
954 tele_param_pri_ind(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
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,
971 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0x3f, 8);
972 proto_tree_add_text(tree
, tvb
, offset
, 1,
978 tele_param_priv_ind(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
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,
1001 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0x3f, 8);
1002 proto_tree_add_text(tree
, tvb
, offset
, 1,
1008 tele_param_reply_opt(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
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",
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",
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,
1035 tele_param_num_messages(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
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",
1050 tele_param_alert(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
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,
1073 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0x3f, 8);
1074 proto_tree_add_text(tree
, tvb
, offset
, 1,
1080 tele_param_lang_ind(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
1083 const gchar
*str
= NULL
;
1085 EXACT_DATA_CHECK(len
, 1);
1087 oct
= tvb_get_guint8(tvb
, offset
);
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,
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
;
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",
1122 (oct
& 0x80) ? "8-bit ASCII" : "4-bit DTMF");
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)",
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)",
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)",
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
);
1161 while (i
< num_fields
)
1163 ansi_637_bigbuf
[i
] = tvb_get_guint8(tvb
, offset
+i
) & 0x7f;
1166 ansi_637_bigbuf
[i
] = '\0';
1168 proto_tree_add_text(tree
, tvb
, offset
, num_fields
,
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)",
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)",
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
);
1207 odd
= num_fields
& 0x01;
1208 memset((void *) ansi_637_bigbuf
, 0, sizeof(ansi_637_bigbuf
));
1209 saved_offset
= offset
;
1213 while (i
< num_fields
)
1215 ansi_637_bigbuf
[i
] =
1216 air_digits
[(oct
& 0x78) >> 3];
1219 if (i
>= num_fields
) break;
1221 oct2
= tvb_get_guint8(tvb
, offset
);
1224 ansi_637_bigbuf
[i
] =
1225 air_digits
[((oct
& 0x07) << 1) | ((oct2
& 0x80) >> 7)];
1232 proto_tree_add_text(tree
, tvb
, saved_offset
, offset
- saved_offset
,
1237 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, odd
? 0x07: 0x7f, 8);
1238 proto_tree_add_text(tree
, tvb
, offset
, 1,
1245 tele_param_disp_mode(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, guint len
, guint32 offset
, gboolean
* has_private_data _U_
)
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,
1268 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0x3f, 8);
1269 proto_tree_add_text(tree
, tvb
, offset
, 1,
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 */
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
)
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
);
1316 str
= "Reserved for maintenance";
1319 str
= "CDMA Service Category Programming Teleservice (SCPT)";
1322 str
= "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
1325 str
= "TDMA Cellular Messaging Teleservice";
1328 str
= "TDMA Cellular Paging Teleservice (CPT-136)";
1331 str
= "TDMA Over-the-Air Activation Teleservice (OATS)";
1334 str
= "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
1337 str
= "TDMA Segmented System Assisted Mobile Positioning Service";
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";
1362 str
= "Unrecognized Teleservice ID";
1368 proto_tree_add_text(tree
, tvb
, offset
, 2,
1373 g_snprintf(add_string
, string_len
, " - %s (%d)", str
, value
);
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
)
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,
1391 g_snprintf(add_string
, string_len
, " - %s (%d)", str
, value
);
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
;
1404 SHORT_DATA_CHECK(len
, 2);
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",
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",
1420 (oct
& 0x40) ? "Data Network Address" : "ANSI T1.607");
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;
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)",
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)",
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)",
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
);
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",
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;
1485 ansi_637_bigbuf
[i
] = '\0';
1489 proto_tree_add_text(tree
, tvb
, offset
, num_fields
- 1,
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",
1506 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0x07, 8);
1507 proto_tree_add_text(tree
, tvb
, offset
, 1,
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)",
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)",
1525 ((oct
& 0x07) << 1) | ((oct2
& 0x80) >> 7));
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)",
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)",
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)",
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
);
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",
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;
1577 ansi_637_bigbuf
[i
] = '\0';
1579 proto_tree_add_text(tree
, tvb
, offset
, num_fields
- 1,
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",
1590 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0x7f, 8);
1591 proto_tree_add_text(tree
, tvb
, 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)",
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)",
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
);
1631 odd
= num_fields
& 0x01;
1632 memset((void *) ansi_637_bigbuf
, 0, sizeof(ansi_637_bigbuf
));
1633 saved_offset
= offset
;
1637 while (i
< num_fields
)
1639 ansi_637_bigbuf
[i
] =
1640 air_digits
[(oct
& 0x3c) >> 2];
1643 if (i
>= num_fields
) break;
1645 oct2
= tvb_get_guint8(tvb
, offset
);
1648 ansi_637_bigbuf
[i
] =
1649 air_digits
[((oct
& 0x03) << 2) | ((oct2
& 0xc0) >> 6)];
1656 proto_tree_add_text(tree
, tvb
, saved_offset
, offset
- saved_offset
,
1661 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, odd
? 0x03: 0x3f, 8);
1662 proto_tree_add_text(tree
, tvb
, offset
, 1,
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
;
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;
1688 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0xe0, 8);
1689 proto_tree_add_text(tree
, tvb
, offset
, 1,
1694 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0x10, 8);
1695 proto_tree_add_text(tree
, tvb
, 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)",
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)",
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
);
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",
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;
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",
1753 other_decode_bitfield_value(ansi_637_bigbuf
, oct
, 0x0f, 8);
1754 proto_tree_add_text(tree
, tvb
, offset
, 1,
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
)
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",
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,
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
)
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",
1796 case 0x00: str
= "No error"; break;
1797 case 0x02: str
= "Temporary Condition"; break;
1798 case 0x03: str
= "Permanent Condition"; 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",
1814 if (!(oct
& 0x03)) return;
1816 if (len
== 1) return;
1818 oct
= tvb_get_guint8(tvb
, offset
);
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;
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"; }
1864 proto_tree_add_text(tree
, tvb
, offset
, 1,
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_
)
1873 proto_tree_add_text(tree
, tvb
, offset
, len
,
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 */
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 */
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
;
1911 guint32 curr_offset
;
1912 gint ett_param_idx
, idx
;
1913 proto_tree
*subtree
;
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
);
1928 ett_param_idx
= ett_ansi_637_tele_param
[idx
];
1929 param_fcn
= ansi_637_tele_param_fcn
[idx
];
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
);
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
);
1952 if (param_fcn
== NULL
)
1954 proto_tree_add_text(subtree
, tvb
, curr_offset
,
1955 len
, "Parameter Data");
1959 (*param_fcn
)(tvb
, pinfo
, subtree
, len
, curr_offset
, has_private_data
);
1965 *offset
= curr_offset
;
1971 dissect_ansi_637_tele_message(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*ansi_637_tree
, gboolean
* has_private_data
)
1974 guint32 curr_offset
;
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");
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
;
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.
2008 value
= pinfo
->match_uint
;
2011 * create the ansi_637 protocol tree
2013 str
= try_val_to_str(value
, ansi_tele_id_strings
);
2020 str
= "Reserved for maintenance";
2023 str
= "CDMA Service Category Programming Teleservice (SCPT)";
2026 str
= "CDMA Card Application Toolkit Protocol Teleservice (CATPT)";
2029 str
= "TDMA Cellular Messaging Teleservice";
2032 str
= "TDMA Cellular Paging Teleservice (CPT-136)";
2035 str
= "TDMA Over-the-Air Activation Teleservice (OATS)";
2038 str
= "TDMA System Assisted Mobile Positioning through Satellite (SAMPS)";
2041 str
= "TDMA Segmented System Assisted Mobile Positioning Service";
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";
2075 str
= "Unrecognized Teleservice ID";
2082 proto_tree_add_protocol_format(tree
, proto_ansi_637_tele
, tvb
, 0, -1,
2084 ansi_proto_name_tele
,
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
);
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
;
2101 guint32 curr_offset
;
2102 gint ett_param_idx
, idx
;
2103 proto_tree
*subtree
;
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
);
2117 ett_param_idx
= ett_ansi_637_trans_param
[idx
];
2118 param_fcn
= ansi_637_trans_param_fcn
[idx
];
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
);
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
);
2141 if (param_fcn
== NULL
)
2143 proto_tree_add_text(subtree
, tvb
, curr_offset
,
2144 len
, "Parameter Data");
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
);
2163 *offset
= curr_offset
;
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
;
2176 const gchar
*str
= NULL
;
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.
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
);
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
,
2210 proto_item_add_subtree(ansi_637_item
, ett_ansi_637_trans
);
2215 proto_tree_add_protocol_format(tree
, proto_ansi_637_trans
, tvb
, 0, -1,
2217 ansi_proto_name_trans
,
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;
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");
2250 /* Dissect SMS embedded in SIP */
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 */
2260 proto_register_ansi_637(void)
2264 /* Setup list of header fields */
2265 static hf_register_info hf_trans
[] =
2268 { &hf_ansi_637_trans_msg_type
,
2270 "ansi_637_trans.msg_type",
2271 FT_UINT24
, BASE_DEC
, VALS(ansi_trans_msg_type_strings
), 0xf00000,
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,
2278 { &hf_ansi_637_trans_length
,
2279 { "Length", "ansi_637_trans.len",
2280 FT_UINT8
, BASE_DEC
, NULL
, 0,
2282 { &hf_ansi_637_trans_bin_addr
,
2283 { "Binary Address", "ansi_637_trans.bin_addr",
2284 FT_BYTES
, BASE_NONE
, 0, 0,
2287 static hf_register_info hf_tele
[] =
2289 { &hf_ansi_637_tele_msg_type
,
2291 "ansi_637_tele.msg_type",
2292 FT_UINT24
, BASE_DEC
, VALS(ansi_tele_msg_type_strings
), 0xf00000,
2294 { &hf_ansi_637_tele_msg_id
,
2296 "ansi_637_tele.msg_id",
2297 FT_UINT24
, BASE_DEC
, NULL
, 0x0ffff0,
2299 { &hf_ansi_637_tele_msg_status
,
2301 "ansi_637_tele.msg_status",
2302 FT_UINT8
, BASE_DEC
, VALS(ansi_tele_msg_status_strings
), 0,
2304 { &hf_ansi_637_tele_msg_ind
,
2305 { "Header Indicator",
2306 "ansi_637_tele.msg_ind",
2307 FT_UINT24
, BASE_DEC
, NULL
, 0x000008,
2309 { &hf_ansi_637_tele_msg_rsvd
,
2311 "ansi_637_tele.msg_rsvd",
2312 FT_UINT24
, BASE_DEC
, NULL
, 0x000007,
2314 { &hf_ansi_637_tele_length
,
2315 { "Length", "ansi_637_tele.len",
2316 FT_UINT8
, BASE_DEC
, NULL
, 0,
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,
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,
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
);
2378 proto_reg_handoff_ansi_637(void)
2380 dissector_handle_t ansi_637_trans_app_handle
;
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
);