aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ansi_637.c
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2014-01-09 21:58:09 +0000
committerPascal Quantin <pascal.quantin@gmail.com>2014-01-09 21:58:09 +0000
commit70dc6197ec35d99cca2af594fd75c09f12b15bcd (patch)
treed28fa90922aa7d943920f89cff252f89db236ff0 /epan/dissectors/packet-ansi_637.c
parentf42fa7abf12b4f6a374901ec117081005e2ec0cd (diff)
From Michael Lum via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9472 :
ANSI IS-637 SMS enhancements for CMAS (TIA-1149) and header dissection svn path=/trunk/; revision=54684
Diffstat (limited to 'epan/dissectors/packet-ansi_637.c')
-rw-r--r--epan/dissectors/packet-ansi_637.c3097
1 files changed, 2026 insertions, 1071 deletions
diff --git a/epan/dissectors/packet-ansi_637.c b/epan/dissectors/packet-ansi_637.c
index a4ed247c61..8edfaf3698 100644
--- a/epan/dissectors/packet-ansi_637.c
+++ b/epan/dissectors/packet-ansi_637.c
@@ -1,13 +1,21 @@
/* packet-ansi_637.c
- * Routines for ANSI IS-637-A (SMS) dissection
+ * Routines for ANSI IS-637-A/D (SMS) dissection
*
* Copyright 2003, Michael Lum <mlum [AT] telostech.com>
* In association with Telos Technology Inc.
+ * Copyright 2013, Michael Lum <michael.lum [AT] starsolutions.com>
+ * In association with Star Solutions, Inc. (Updated for some of IS-637-D and CMAS)
*
* Title 3GPP2 Other
*
* Short Message Service
* 3GPP2 C.S0015-0 TIA/EIA-637-A
+ * 3GPP2 C.S0015-C v1.0 TIA/EIA-637-D
+ * 3GPP2 C.R1001-H v1.0 TSB-58-I (or J?)
+ *
+ * For CMAS See:
+ * TIA-1149.1 or
+ * (520-10030206__Editor_TIA-1149-0-1_CMASoverCDMA_Publication.pdf)
*
* $Id$
*
@@ -34,54 +42,31 @@
#include <epan/packet.h>
#include <epan/wmem/wmem.h>
+#include <epan/expert.h>
#include <epan/strutil.h>
#include <epan/to_str.h>
+#include <epan/tfs.h>
#include "packet-gsm_sms.h"
+#include "packet-ansi_a.h"
void proto_register_ansi_637(void);
void proto_reg_handoff_ansi_637(void);
-static const char *ansi_proto_name_tele = "ANSI IS-637-A (SMS) Teleservice Layer";
+static const char *ansi_proto_name_tele = "ANSI IS-637-A (SMS) Teleservice Layer";
static const char *ansi_proto_name_trans = "ANSI IS-637-A (SMS) Transport Layer";
static const char *ansi_proto_name_short = "IS-637-A";
-static const value_string ansi_srvc_cat_strings[] = {
- { 0x0000, "Unknown or unspecified" },
- { 0x0001, "Emergency Broadcasts" },
- { 0x0002, "Administrative" },
- { 0x0003, "Maintenance" },
- { 0x0004, "General News - Local" },
- { 0x0005, "General News - Regional" },
- { 0x0006, "General News - National" },
- { 0x0007, "General News - International" },
- { 0x0008, "Business/Financial News - Local" },
- { 0x0009, "Business/Financial News - Regional" },
- { 0x000A, "Business/Financial News - National" },
- { 0x000B, "Business/Financial News - International" },
- { 0x000C, "Sports News - Local" },
- { 0x000D, "Sports News - Regional" },
- { 0x000E, "Sports News - National" },
- { 0x000F, "Sports News - International" },
- { 0x0010, "Entertainment News - Local" },
- { 0x0011, "Entertainment News - Regional" },
- { 0x0012, "Entertainment News - National" },
- { 0x0013, "Entertainment News - International" },
- { 0x0014, "Local Weather" },
- { 0x0015, "Area Traffic Reports" },
- { 0x0016, "Local Airport Flight Schedules" },
- { 0x0017, "Restaurants" },
- { 0x0018, "Lodgings" },
- { 0x0019, "Retail Directory" },
- { 0x001A, "Advertisements" },
- { 0x001B, "Stock Quotes" },
- { 0x001C, "Employment Opportunities" },
- { 0x001D, "Medical/Health/Hospitals" },
- { 0x001E, "Technology News" },
- { 0x001F, "Multi-category" },
- { 0, NULL },
-};
-static value_string_ext ansi_srvc_cat_strings_ext = VALUE_STRING_EXT_INIT(ansi_srvc_cat_strings);
+/*
+ * Masks the number of bits given by len starting at the given offset
+ * MBoffset should be from 0 to 7 and MBlen 1 to 8
+ * MASK_B(0, 1) = 0x80
+ * MASK_B(0, 8) = 0xff
+ * MASK_B(4, 3) = 0x0e
+ * MASK_B(7, 1) = 0x01
+ */
+#define MASK_B(MBoffset, MBlen) \
+ ((0xff >> (MBoffset)) & (0xff << (8 - ((MBoffset) + (MBlen)))))
static const value_string ansi_tele_msg_type_strings[] = {
{ 1, "Deliver (mobile-terminated only)" },
@@ -89,26 +74,35 @@ static const value_string ansi_tele_msg_type_strings[] = {
{ 3, "Cancellation (mobile-originated only)" },
{ 4, "Delivery Acknowledgement (mobile-terminated only)" },
{ 5, "User Acknowledgement (either direction)" },
- { 0, NULL },
- };
+ { 6, "Read Acknowledgement (either direction)" },
+ { 7, "Deliver Report (mobile-originated only)" },
+ { 8, "Submit Report (mobile-terminated only)" },
+ { 0, NULL }
+};
+
+static const value_string ansi_tele_msg_header_ind_strings[] = {
+ { 0, "The User Data field contains only the short message" },
+ { 1, "The User Data field contains a Header in addition to the short message" },
+ { 0, NULL }
+};
static const value_string ansi_tele_msg_status_strings[] = {
- {0x00, "Message accepted"},
- {0x01, "Message deposited to Internet"},
- {0x02, "Message delivered"},
- {0x03, "Message cancelled"},
- {0x84, "Network congestion"},
- {0x85, "Network error"},
- {0x9f, "Unknown error"},
- {0xc4, "Network congestion"},
- {0xc5, "Network error"},
- {0xc6, "Cancel failed"},
- {0xc7, "Blocked destination"},
- {0xc8, "Text too long"},
- {0xc9, "Duplicate message"},
- {0xca, "Invalid destination"},
- {0xcd, "Message expired"},
- {0xdf, "Unknown error"},
+ { 0x00, "Message accepted" },
+ { 0x01, "Message deposited to Internet" },
+ { 0x02, "Message delivered" },
+ { 0x03, "Message cancelled" },
+ { 0x84, "Network congestion" },
+ { 0x85, "Network error" },
+ { 0x9f, "Unknown error" },
+ { 0xc4, "Network congestion" },
+ { 0xc5, "Network error" },
+ { 0xc6, "Cancel failed" },
+ { 0xc7, "Blocked destination" },
+ { 0xc8, "Text too long" },
+ { 0xc9, "Duplicate message" },
+ { 0xca, "Invalid destination" },
+ { 0xcd, "Message expired" },
+ { 0xdf, "Unknown error" },
{ 0, NULL }
};
static value_string_ext ansi_tele_msg_status_strings_ext = VALUE_STRING_EXT_INIT(ansi_tele_msg_status_strings);
@@ -121,10 +115,9 @@ static const value_string ansi_tele_id_strings[] = {
{ 4099, "CDMA Voice Mail Notification" },
{ 4100, "CDMA Wireless Application Protocol (WAP)" },
{ 4101, "CDMA Wireless Enhanced Messaging Teleservice (WEMT)" },
- { 65535, "(Reserved) Being used for Broadcast" },
- { 0, NULL },
-
+ { 0, NULL }
};
+#define INTERNAL_BROADCAST_TELE_ID 65535
static const value_string ansi_tele_param_strings[] = {
{ 0x00, "Message Identifier" },
@@ -144,8 +137,14 @@ static const value_string ansi_tele_param_strings[] = {
{ 0x0e, "Call-Back Number" },
{ 0x0f, "Message Display Mode" },
{ 0x10, "Multiple Encoding User Data" },
- { 0x14, "Message Status" },
- { 0, NULL },
+ { 0x11, "Message Deposit Index" },
+ { 0x12, "Service Category Program Data" },
+ { 0x13, "Service Category Program Results" },
+ { 0x14, "Message status" },
+ { 0x15, "TP-Failure cause" },
+ { 0x16, "Enhanced VMN" },
+ { 0x17, "Enhanced VMN Ack" },
+ { 0, NULL }
};
static value_string_ext ansi_tele_param_strings_ext = VALUE_STRING_EXT_INIT(ansi_tele_param_strings);
@@ -155,7 +154,7 @@ static const value_string ansi_trans_msg_type_strings[] = {
{ 0, "Point-to-Point" },
{ 1, "Broadcast" },
{ 2, "Acknowledge" },
- { 0, NULL },
+ { 0, NULL }
};
static const value_string ansi_trans_param_strings[] = {
@@ -168,7 +167,39 @@ static const value_string ansi_trans_param_strings[] = {
{ 0x06, "Bearer Reply Option" },
{ 0x07, "Cause Codes" },
{ 0x08, "Bearer Data" },
- { 0, NULL },
+ { 0, NULL }
+};
+
+static const value_string ansi_tele_month_strings[] = {
+ { 0, "January" },
+ { 1, "February" },
+ { 2, "March" },
+ { 3, "April" },
+ { 4, "May" },
+ { 5, "June" },
+ { 6, "July" },
+ { 7, "August" },
+ { 8, "September" },
+ { 9, "October" },
+ { 10, "November" },
+ { 11, "December" },
+ { 0, NULL }
+};
+
+static const value_string ansi_trans_subaddr_odd_even_ind_strings[] = {
+ { 0x00, "Even" },
+ { 0x01, "Odd" },
+ { 0, NULL }
+};
+
+static const true_false_string tfs_digit_mode_8bit_4bit = {
+ "8-bit ASCII",
+ "4-bit DTMF"
+};
+
+static const true_false_string tfs_number_mode_data_ansi_t1 = {
+ "Data Network Address",
+ "ANSI T1.607"
};
/*
@@ -183,24 +214,123 @@ static const unsigned char air_digits[] = {
/* Initialize the protocol and registered fields */
static int proto_ansi_637_tele = -1;
static int proto_ansi_637_trans = -1;
-static int hf_ansi_637_tele_length = -1;
+
+static int hf_ansi_637_trans_param_id = -1;
static int hf_ansi_637_trans_length = -1;
static int hf_ansi_637_trans_bin_addr = -1;
+static int hf_ansi_637_trans_tele_id = -1;
+static int hf_ansi_637_trans_srvc_cat = -1;
+static int hf_ansi_637_trans_addr_param_digit_mode = -1;
+static int hf_ansi_637_trans_addr_param_number_mode = -1;
+static int hf_ansi_637_trans_addr_param_ton = -1;
+static int hf_ansi_637_trans_addr_param_plan = -1;
+static int hf_ansi_637_trans_addr_param_num_fields = -1;
+static int hf_ansi_637_trans_addr_param_number = -1;
+static int hf_ansi_637_trans_subaddr_type = -1;
+static int hf_ansi_637_trans_subaddr_odd_even_ind = -1;
+static int hf_ansi_637_trans_subaddr_num_fields = -1;
+static int hf_ansi_637_trans_bearer_reply_seq_num = -1;
+static int hf_ansi_637_trans_cause_codes_seq_num = -1;
+static int hf_ansi_637_trans_cause_codes_error_class = -1;
+static int hf_ansi_637_trans_cause_codes_code = -1;
+
static int hf_ansi_637_tele_msg_type = -1;
static int hf_ansi_637_tele_msg_id = -1;
+static int hf_ansi_637_tele_length = -1;
static int hf_ansi_637_tele_msg_status = -1;
-static int hf_ansi_637_tele_msg_ind = -1;
+static int hf_ansi_637_tele_msg_header_ind = -1;
static int hf_ansi_637_tele_msg_rsvd = -1;
static int hf_ansi_637_tele_subparam_id = -1;
static int hf_ansi_637_tele_user_data_text = -1;
-/* static int hf_ansi_637_trans_msg_type = -1; */
-static int hf_ansi_637_trans_param_id = -1;
+static int hf_ansi_637_tele_user_data_encoding = -1;
+static int hf_ansi_637_tele_user_data_message_type = -1;
+static int hf_ansi_637_tele_user_data_num_fields = -1;
+static int hf_ansi_637_tele_response_code = -1;
+static int hf_ansi_637_tele_message_center_ts_year = -1;
+static int hf_ansi_637_tele_message_center_ts_month = -1;
+static int hf_ansi_637_tele_message_center_ts_day = -1;
+static int hf_ansi_637_tele_message_center_ts_hours = -1;
+static int hf_ansi_637_tele_message_center_ts_minutes = -1;
+static int hf_ansi_637_tele_message_center_ts_seconds = -1;
+static int hf_ansi_637_tele_validity_period_ts_year = -1;
+static int hf_ansi_637_tele_validity_period_ts_month = -1;
+static int hf_ansi_637_tele_validity_period_ts_day = -1;
+static int hf_ansi_637_tele_validity_period_ts_hours = -1;
+static int hf_ansi_637_tele_validity_period_ts_minutes = -1;
+static int hf_ansi_637_tele_validity_period_ts_seconds = -1;
+static int hf_ansi_637_tele_validity_period_relative_validity = -1;
+static int hf_ansi_637_tele_deferred_del_ts_year = -1;
+static int hf_ansi_637_tele_deferred_del_ts_month = -1;
+static int hf_ansi_637_tele_deferred_del_ts_day = -1;
+static int hf_ansi_637_tele_deferred_del_ts_hours = -1;
+static int hf_ansi_637_tele_deferred_del_ts_minutes = -1;
+static int hf_ansi_637_tele_deferred_del_ts_seconds = -1;
+static int hf_ansi_637_tele_deferred_del_relative = -1;
+static int hf_ansi_637_tele_priority_indicator = -1;
+static int hf_ansi_637_tele_privacy_indicator = -1;
+static int hf_ansi_637_tele_reply_option_user_ack_req = -1;
+static int hf_ansi_637_tele_reply_option_dak_req = -1;
+static int hf_ansi_637_tele_reply_option_read_ack_req = -1;
+static int hf_ansi_637_tele_reply_option_report_req = -1;
+static int hf_ansi_637_tele_num_messages = -1;
+static int hf_ansi_637_tele_alert_msg_delivery_priority = -1;
+static int hf_ansi_637_tele_language = -1;
+static int hf_ansi_637_tele_cb_num_digit_mode = -1;
+static int hf_ansi_637_tele_cb_num_ton = -1;
+static int hf_ansi_637_tele_cb_num_plan = -1;
+static int hf_ansi_637_tele_cb_num_num_fields = -1;
+static int hf_ansi_637_tele_cb_num_number = -1;
+static int hf_ansi_637_tele_msg_display_mode = -1;
+static int hf_ansi_637_tele_msg_deposit_idx = -1;
+static int hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat = -1;
+static int hf_ansi_637_tele_srvc_cat_prog_results_result = -1;
+static int hf_ansi_637_tele_msg_status_error_class = -1;
+static int hf_ansi_637_tele_msg_status_code = -1;
+static int hf_ansi_637_tele_tp_failure_cause_value = -1;
+static int hf_ansi_637_reserved_bits_8_generic = -1;
+static int hf_ansi_637_reserved_bits_8_03 = -1;
+static int hf_ansi_637_reserved_bits_8_07 = -1;
+static int hf_ansi_637_reserved_bits_8_0f = -1;
+static int hf_ansi_637_reserved_bits_8_3f = -1;
+static int hf_ansi_637_reserved_bits_8_7f = -1;
+static int hf_ansi_637_tele_cmas_encoding = -1;
+static int hf_ansi_637_tele_cmas_num_fields = -1;
+static int hf_ansi_637_tele_cmas_protocol_version = -1;
+static int hf_ansi_637_tele_cmas_record_type = -1;
+static int hf_ansi_637_tele_cmas_record_len = -1;
+static int hf_ansi_637_tele_cmas_char_set = -1;
+static int hf_ansi_637_tele_cmas_category = -1;
+static int hf_ansi_637_tele_cmas_response_type = -1;
+static int hf_ansi_637_tele_cmas_severity = -1;
+static int hf_ansi_637_tele_cmas_urgency = -1;
+static int hf_ansi_637_tele_cmas_certainty = -1;
+static int hf_ansi_637_tele_cmas_identifier = -1;
+static int hf_ansi_637_tele_cmas_alert_handling = -1;
+static int hf_ansi_637_tele_cmas_expires_year = -1;
+static int hf_ansi_637_tele_cmas_expires_month = -1;
+static int hf_ansi_637_tele_cmas_expires_day = -1;
+static int hf_ansi_637_tele_cmas_expires_hours = -1;
+static int hf_ansi_637_tele_cmas_expires_minutes = -1;
+static int hf_ansi_637_tele_cmas_expires_seconds = -1;
+static int hf_ansi_637_tele_cmas_language = -1;
/* Initialize the subtree pointers */
static gint ett_ansi_637_tele = -1;
static gint ett_ansi_637_trans = -1;
+static gint ett_ansi_637_header_ind = -1;
static gint ett_params = -1;
+static expert_field ei_ansi_637_extraneous_data = EI_INIT;
+static expert_field ei_ansi_637_short_data = EI_INIT;
+static expert_field ei_ansi_637_unexpected_length = EI_INIT;
+static expert_field ei_ansi_637_unknown_encoding = EI_INIT;
+static expert_field ei_ansi_637_failed_conversion = EI_INIT;
+static expert_field ei_ansi_637_unknown_cmas_record_type = EI_INIT;
+static expert_field ei_ansi_637_unknown_trans_parameter = EI_INIT;
+static expert_field ei_ansi_637_no_trans_parameter_dissector = EI_INIT;
+static expert_field ei_ansi_637_unknown_tele_parameter = EI_INIT;
+static expert_field ei_ansi_637_no_tele_parameter_dissector = EI_INIT;
+
static dissector_handle_t ansi_637_tele_handle;
static dissector_handle_t ansi_637_trans_handle;
@@ -212,20 +342,22 @@ static proto_tree *g_tree;
/* FUNCTIONS */
+/*
+ * last_bit must be from 1 to 8
+ * '1' means there is one bit remaining in 'last_oct' (i.e. 0x01)
+ * '3' means there are 3 bits remaining in 'last_oct' (i.e. 0x07)
+ */
static int
decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oct, guint8 *last_bit, gchar *buf)
{
- guint8 oct, oct2, bit;
- /* guint32 saved_offset; */
- guint32 i;
-
+ guint8 oct, oct2, bit;
+ guint32 i;
if (num_fields == 0)
{
return 0;
}
- /* saved_offset = *offset; */
oct = oct2 = *last_oct;
bit = *last_bit;
@@ -295,6 +427,7 @@ decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oc
buf[i] = '\0';
*last_bit = bit;
*last_oct = (bit == 1) ? oct : oct2;
+
return i;
}
@@ -303,573 +436,875 @@ decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oc
#define EXTRANEOUS_DATA_CHECK(edc_len, edc_max_len) \
if ((edc_len) > (edc_max_len)) \
{ \
- proto_tree_add_text(tree, tvb, offset, \
- (edc_len) - (edc_max_len), "Extraneous Data"); \
+ proto_tree_add_expert(tree, pinfo, &ei_ansi_637_extraneous_data, \
+ tvb, offset, (edc_len) - (edc_max_len)); \
}
#define SHORT_DATA_CHECK(sdc_len, sdc_min_len) \
if ((sdc_len) < (sdc_min_len)) \
{ \
- proto_tree_add_text(tree, tvb, offset, \
- (sdc_len), "Short Data (?)"); \
+ proto_tree_add_expert(tree, pinfo, &ei_ansi_637_short_data, \
+ tvb, offset, (sdc_len)); \
return; \
}
#define EXACT_DATA_CHECK(edc_len, edc_eq_len) \
if ((edc_len) != (edc_eq_len)) \
{ \
- proto_tree_add_text(tree, tvb, offset, \
- (edc_len), "Unexpected Data Length"); \
+ proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unexpected_length, \
+ tvb, offset, (edc_len)); \
return; \
}
+/*
+ * text decoding helper
+ *
+ * there are 'unused_bits' bits remaining in the octet at 'offset'
+ */
static void
-tele_param_msg_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data)
+text_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint8 encoding, guint8 num_fields, guint16 num_bits, guint8 unused_bits, guint8 fill_bits)
{
- EXACT_DATA_CHECK(len, 3);
+ guint8 oct;
+ guint8 bit;
+ guint32 required_octs;
+ guint32 out_len;
+ const gchar *str = NULL;
+ tvbuff_t *tvb_out = NULL;
- proto_tree_add_item(tree, hf_ansi_637_tele_msg_type, tvb, offset, 3, ENC_BIG_ENDIAN);
+ GIConv cd;
+ GError *l_conv_error = NULL;
+ gchar *ustr = NULL;
- proto_tree_add_item(tree, hf_ansi_637_tele_msg_id, tvb, offset, 3, ENC_BIG_ENDIAN);
+ /*
+ * has to be big enough to hold all of the 'shifted' bits
+ */
+ required_octs = (num_bits + fill_bits + 7) / 8;
- proto_tree_add_item(tree, hf_ansi_637_tele_msg_ind, tvb, offset, 3, ENC_BIG_ENDIAN);
- if ((tvb_get_guint8(tvb, offset+2) & 0x08) == 0x08) {
- *has_private_data = TRUE;
- }
+ /*
+ * shift the bits to octet alignment in 'buf'
+ */
+ tvb_out =
+ tvb_new_octet_aligned(tvb, (offset * 8) + (8 - unused_bits), (required_octs * 8));
+ add_new_data_source(pinfo, tvb_out, "Characters");
- proto_tree_add_item(tree, hf_ansi_637_tele_msg_rsvd, tvb, offset, 3, ENC_BIG_ENDIAN);
+ switch (encoding)
+ {
+ default:
+ proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unknown_encoding, tvb, offset, required_octs);
+ return;
+
+ case 0x02: /* 7-bit ASCII */
+
+ offset = 0;
+ oct = tvb_get_guint8(tvb_out, offset);
+ offset += 1;
+ bit = 8;
+
+ (void) decode_7_bits(tvb_out, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
+
+ proto_tree_add_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, 0,
+ offset, ansi_637_bigbuf);
+ break;
+
+ case 0x03: /* IA5 */
+
+ offset = 0;
+ oct = tvb_get_guint8(tvb_out, offset);
+ offset += 1;
+ bit = 8;
+
+ out_len =
+ decode_7_bits(tvb_out, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
+
+ IA5_7BIT_decode(ia5_637_bigbuf, ansi_637_bigbuf, out_len);
+
+ proto_tree_add_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, 0,
+ offset, ia5_637_bigbuf);
+ break;
+
+ case 0x09: /* GSM 7-bit default alphabet */
+
+ offset = 0;
+ bit = fill_bits;
+
+ proto_tree_add_ts_23_038_7bits_item(tree, hf_ansi_637_tele_user_data_text, tvb_out, (offset << 3) + bit, num_fields);
+ break;
+
+ case 0x04: /* UNICODE */
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset, num_fields*2, ENC_UCS_2|ENC_BIG_ENDIAN);
+ break;
+
+ case 0x10: /* KSC5601 (Korean) */
+
+ if (str == NULL) str = "EUC-KR";
+
+ /* FALLTHROUGH */
+
+ case 0x07: /* Latin/Hebrew */
+
+ if (str == NULL) str = "iso-8859-8";
+
+ /* FALLTHROUGH */
+
+ case 0x08: /* Latin */
+
+ if (str == NULL) str = "iso-8859-1";
+
+ offset = 0;
+
+ if ((cd = g_iconv_open("UTF-8", str)) != (GIConv) -1)
+ {
+ ustr = g_convert_with_iconv(tvb_get_ptr(tvb_out, offset, required_octs), required_octs , cd , NULL , NULL , &l_conv_error);
+ if (!l_conv_error)
+ {
+ proto_tree_add_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset,
+ required_octs, ustr);
+ }
+ else
+ {
+ proto_tree_add_expert_format(tree, pinfo, &ei_ansi_637_failed_conversion, tvb_out, offset, required_octs,
+ "Failed iconv conversion on %s - (report to wireshark.org)",
+ str);
+ }
+ if (ustr)
+ {
+ g_free(ustr);
+ }
+ g_iconv_close(cd);
+ }
+ break;
+ }
}
-/* Adamek Jan - IS637C Message status decoding procedure */
static void
-tele_param_msg_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, int hf_year, int hf_month, int hf_day, int hf_hours, int hf_minutes, int hf_seconds)
{
- /* Declare some variables */
- guint8 oct;
- guint8 error_class;
- guint8 msg_status_code;
+ guint8 oct;
+ guint16 temp;
const gchar *str = NULL;
- /* Chceck if the exact length */
- EXACT_DATA_CHECK(len, 1);
+ EXACT_DATA_CHECK(len, 6);
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
+ temp += ((temp < 96) ? 2000 : 1900);
+
+ proto_tree_add_uint_format_value(tree, hf_year, tvb, offset, 1,
+ oct,
+ "%u (%02x)",
+ temp, oct);
- /* get the status octet? */
+ offset += 1;
oct = tvb_get_guint8(tvb, offset);
+ temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f) - 1;
- /* error class filter */
- proto_tree_add_item(tree, hf_ansi_637_tele_msg_status,tvb, offset, 1, ENC_BIG_ENDIAN);
+ str = val_to_str_const(temp, ansi_tele_month_strings, "Invalid");
+ proto_tree_add_uint_format_value(tree, hf_month, tvb, offset, 1,
+ oct,
+ "%s (%02x)",
+ str, oct);
- /*error class filter end */
+ offset += 1;
+ oct = tvb_get_guint8(tvb, offset);
-/*error class */
+ temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
- error_class = ((oct & 0xc0) >> 6);
- switch (error_class)
- {
- case 0x00: str = "No Error";break;
- case 0x01: str = "Reserved";break;
- case 0x02: str = "Temporary Condition";break;
- case 0x03: str = "Permanent Condition";break;
- default: str = "Reserved";break;
- }
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Erorr Class: %s",
- ansi_637_bigbuf,
- str);
+ proto_tree_add_uint_format_value(tree, hf_day, tvb, offset, 1,
+ oct,
+ "%u",
+ temp);
+ offset += 1;
+ oct = tvb_get_guint8(tvb, offset);
- msg_status_code = (oct & 0x3f);
+ temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
- if (error_class == 0x00){
- switch (msg_status_code)
- {
- case 0x00: str = "Message accepted";break;
- case 0x01: str = "Message deposited to internet";break;
- case 0x02: str = "Message delivered";break;
- case 0x03: str = "Message cancelled";break;
- default: str = "Reserved";break;
- }
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Message status code: %s",
- ansi_637_bigbuf,
- str);
- }
+ proto_tree_add_uint_format_value(tree, hf_hours, tvb, offset, 1,
+ oct,
+ "%u",
+ temp);
-/*error message status */
- if (error_class == 0x02){
- switch (msg_status_code)
- {
- case 0x04: str = "Network congestion";break;
- case 0x05: str = "Network error";break;
- case 0x1f: str = "Unknown error";break;
- default: str = "Reserved";break;
- }
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Message status code: %s",
- ansi_637_bigbuf,
- str);
- }
+ offset += 1;
- if (error_class == 0x03){
- switch (msg_status_code)
- {
- case 0x04: str = "Network congestion";break;
- case 0x05: str = "Network error";break;
- case 0x06: str = "Cancel failed";break;
- case 0x07: str = "Blocked destination";break;
- case 0x08: str = "Text too long";break;
- case 0x09: str = "Duplicate message";break;
- case 0x0a: str = "Invalid destination";break;
- case 0x0d: str = "Message expired";break;
- case 0x1f: str = "Unknown error";break;
- default: str = "Reserved";break;
- }
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Message status code: %s",
- ansi_637_bigbuf,
- str);
+ oct = tvb_get_guint8(tvb, offset);
+
+ temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
+
+ proto_tree_add_uint_format_value(tree, hf_minutes, tvb, offset, 1, oct,
+ "%u",
+ temp);
+
+ offset += 1;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ temp = (((oct & 0xf0) >> 4) * 10) + (oct & 0x0f);
+
+ proto_tree_add_uint_format_value(tree, hf_seconds, tvb, offset, 1,
+ oct,
+ "%u",
+ temp);
+}
+
+static void
+tele_param_msg_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p)
+{
+ EXACT_DATA_CHECK(len, 3);
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_msg_type, tvb, offset, 3, ENC_BIG_ENDIAN);
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_msg_id, tvb, offset, 3, ENC_BIG_ENDIAN);
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_msg_header_ind, tvb, offset, 3, ENC_BIG_ENDIAN);
+ if ((tvb_get_guint8(tvb, offset + 2) & 0x08) == 0x08)
+ {
+ *has_private_data_p = TRUE;
}
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_msg_rsvd, tvb, offset, 3, ENC_BIG_ENDIAN);
}
+/*
+ * for record types 0, 1, 2 and 3 for unknowns
+ */
+#define NUM_CMAS_PARAM 4
+static gint ett_tia_1149_cmas_param[NUM_CMAS_PARAM];
+
+/*
+ * Special dissection for CMAS Message as defined in TIA-1149
+ */
+static const value_string cmas_category_strings[] = {
+ { 0x00, "Geo (Geophysical including landslide)" },
+ { 0x01, "Met (Meteorological including flood)" },
+ { 0x02, "Safety (General emergency and public safety)" },
+ { 0x03, "Security (Law enforcement, military, homeland and local/private security)" },
+ { 0x04, "Rescue (Rescue and recovery)" },
+ { 0x05, "Fire (Fire suppression and rescue)" },
+ { 0x06, "Health (Medical and public health)" },
+ { 0x07, "Env (Pollution and other environmental)" },
+ { 0x08, "Transport (Public and private transportation)" },
+ { 0x09, "Infra (Utility, telecommunication, other nontransport infrastructure)" },
+ { 0x0a, "CBRNE (Chemical, Biological, Radiological, Nuclear or High-Yield Explosive threat or attack)" },
+ { 0x0b, "Other (Other events)" },
+ { 0, NULL }
+};
+
+static const value_string cmas_response_type_strings[] = {
+ { 0x00, "Shelter (Take shelter in place)" },
+ { 0x01, "Evacuate (Relocate)" },
+ { 0x02, "Prepare (Make preparations)" },
+ { 0x03, "Execute (Execute a pre-planned activity)" },
+ { 0x04, "Monitor (Attend to information sources)" },
+ { 0x05, "Avoid (Avoid hazard)" },
+ { 0x06, "Assess (Evaluate the information in this message. This value SHOULD NOT be used in public warning applications.)" },
+ { 0x07, "None (No action recommended)" },
+ { 0, NULL }
+};
+
+static const value_string cmas_severity_strings[] = {
+ { 0x00, "Extreme (Extraordinary threat to life or property)" },
+ { 0x01, "Severe (Significant threat to life or property)" },
+ { 0, NULL }
+};
+
+static const value_string cmas_urgency_strings[] = {
+ { 0x00, "Immediate (Responsive action should be taken immediately)" },
+ { 0x01, "Expected (Responsive action should be taken soon - within the next hour)" },
+ { 0, NULL }
+};
+
+static const value_string cmas_certainty_strings[] = {
+ { 0x00, "Observed (Determined to have occurred or to be ongoing)" },
+ { 0x01, "Likely (Likely. Probability > ~50%)" },
+ { 0, NULL }
+};
static void
-tele_param_user_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data)
+tele_param_user_data_cmas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct, oct2;
- guint8 encoding;
- guint8 msg_type;
- guint8 num_fields;
- guint8 used;
- guint8 bit;
- guint32 required_octs;
- guint32 saved_offset;
- guint32 i , out_len;
- const gchar *str = NULL;
- gchar *buf;
+ proto_tree *subtree;
+ proto_item *item;
+ guint8 bit_mask_8;
+ guint8 oct, oct2;
+ guint8 encoding;
+ guint8 num_fields;
+ guint8 reserved_bits;
+ guint8 unused_bits;
+ guint8 record_type;
+ guint8 record_len;
+ guint8 subtree_idx;
+ guint16 num_bits;
+ guint32 value;
+ guint32 temp_offset;
+ guint32 required_octs;
tvbuff_t *tvb_out = NULL;
- gsm_sms_udh_fields_t udh_fields;
-
- gchar *utf8_text = NULL;
- GIConv cd;
- GError *l_conv_error = NULL;
+ const gchar *str = NULL;
SHORT_DATA_CHECK(len, 2);
- memset(&udh_fields, 0, sizeof(udh_fields));
+ value = tvb_get_ntohs(tvb, offset);
/*
- * message encoding
+ * must be encoded as 'Octet, unspecified'
*/
- oct = tvb_get_guint8(tvb, offset);
- oct2 = 0;
- msg_type = 0;
- used = 0;
-
- encoding = ((oct & 0xf8) >> 3);
- switch (encoding)
+ if ((value & 0xf800) != 0)
{
- case 0x00: str = "Octet, unspecified"; break;
- case 0x01: str = "Extended Protocol Message";
- oct2 = tvb_get_guint8(tvb, offset+1);
- msg_type = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
- break;
- case 0x02: str = "7-bit ASCII"; break;
- case 0x03: str = "IA5"; break;
- case 0x04: str = "UCS-2"; break;
- case 0x05: str = "Shift-JIS"; break;
- case 0x06: str = "Korean"; break;
- case 0x07: str = "Latin/Hebrew"; break;
- case 0x08: str = "ISO 8859-1"; break;
- case 0x09: str = "GSM 7-bit default alphabet"; break;
- case 0x10: str = "KSC5601 (Korean)"; break;
- default: str = "Reserved"; break;
+ proto_tree_add_expert(tree, pinfo, &ei_ansi_637_unknown_encoding, tvb, offset, len);
+ return;
}
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Encoding: %s",
- ansi_637_bigbuf,
- str);
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_cmas_encoding, tvb, offset, 2,
+ value,
+ "%s (%u)",
+ val_to_str_const((value & 0xf800) >> 11, ansi_tsb58_encoding_vals, "Error"),
+ (value & 0xf800) >> 11);
- if (encoding == 0x01)
- {
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Message type: see TIA/EIA/IS-91 (%d)",
- ansi_637_bigbuf,
- msg_type);
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
- proto_tree_add_text(tree, tvb, offset+1, 1,
- "%s : Message type",
- ansi_637_bigbuf);
+ proto_tree_add_item(tree, hf_ansi_637_tele_cmas_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
- oct = oct2;
- offset += 1;
- used += 1;
- }
+ num_fields = (value & 0x07f8) >> 3;
- offset += 1;
- used += 1;
+ offset += 2;
- /*
- * number of fields
- */
- oct2 = tvb_get_guint8(tvb, offset);
- num_fields = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
+ /* NOTE: there are now 3 bits remaining in 'value' */
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
- proto_tree_add_text(tree, tvb, offset-1, 1,
- "%s : Number of fields (MSB): %d",
- ansi_637_bigbuf,
- num_fields);
+ unused_bits = 3;
- other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Number of fields (LSB)",
- ansi_637_bigbuf);
+ required_octs = num_fields;
- other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Most significant bits of first field",
- ansi_637_bigbuf);
+ tvb_out =
+ tvb_new_octet_aligned(tvb, ((offset - 1) * 8) + (8 - unused_bits), (required_octs * 8));
+ add_new_data_source(pinfo, tvb_out, "CMAS Message");
- offset += 1;
- used += 1;
- oct = oct2;
+ temp_offset = offset;
+ offset = 0;
- /* NOTE: there are now 3 bits remaining in 'oct' */
+ proto_tree_add_item(tree, hf_ansi_637_tele_cmas_protocol_version, tvb_out, offset, 1, ENC_BIG_ENDIAN);
- if (len <= used) return;
+ offset += 1;
- /*
- * decode rest if 7-bit ASCII
- */
- if (encoding == 0x02)
+ while ((required_octs - offset) > 2)
{
- /*
- * magic numbers:
- * 3 bits remaining from last octet
- * 7 bit encoding
- * 8 bits per octet
- */
- i = (num_fields * 7) - 3;
- required_octs = (i / 8) + ((i % 8) ? 1 : 0);
+ record_type = tvb_get_guint8(tvb_out, offset);
+ subtree_idx = record_type;
- if (required_octs + used > len)
+ switch (record_type)
{
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (required_octs + used) - len);
-
- return;
+ default: str = "Reserved"; subtree_idx = 3; break;
+ case 0x00: str = "Type 0 Elements (Alert Text)"; break;
+ case 0x01: str = "Type 1 Elements"; break;
+ case 0x02: str = "Type 2 Elements"; break;
}
- saved_offset = offset - 1;
- i = num_fields * 7;
- required_octs = (i / 8) + ((i % 8) ? 1 : 0);
- buf = (gchar*)wmem_alloc(pinfo->pool, required_octs);
- for (i=0; i < required_octs; i++)
- {
- oct = tvb_get_guint8(tvb, saved_offset);
- oct2 = tvb_get_guint8(tvb, saved_offset + 1);
- buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
- saved_offset += 1;
- }
- tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs);
- add_new_data_source(pinfo, tvb_out, "Characters");
- offset = 0;
- bit = 0;
- if (*has_private_data == TRUE) {
- dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, ASCII_7BITS, &bit, &udh_fields);
- }
+ record_len = tvb_get_guint8(tvb_out, offset + 1);
+
+ item =
+ proto_tree_add_text(tree, tvb_out, offset, record_len + 2,
+ "%s",
+ str);
+
+ subtree = proto_item_add_subtree(item, ett_tia_1149_cmas_param[subtree_idx]);
+
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_record_type, tvb_out, offset, 1,
+ record_type,
+ "%s",
+ str);
- saved_offset = offset;
- bit = bit ? bit : 8;
- oct = tvb_get_guint8(tvb_out, offset);
offset += 1;
- decode_7_bits(tvb_out, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_record_len, tvb_out, offset, 1,
+ record_len,
+ "%u",
+ record_len);
- proto_tree_add_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, saved_offset,
- offset - saved_offset, ansi_637_bigbuf);
+ offset += 1;
- switch (bit)
+ switch (record_type)
{
- case 1: oct2 = 0x01; break;
- case 2: oct2 = 0x03; break;
- case 3: oct2 = 0x07; break;
- case 4: oct2 = 0x0f; break;
- case 5: oct2 = 0x1f; break;
- case 6: oct2 = 0x3f; break;
- case 7: oct2 = 0x7f; break;
- }
+ default:
+ proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_unknown_cmas_record_type, tvb_out, offset, record_len);
- if (bit != 8)
- {
- other_decode_bitfield_value(ansi_637_bigbuf, oct, oct2, 8);
- proto_tree_add_text(tree, tvb, offset - 1, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ offset += record_len;
+ break;
+
+ case 0x00:
+ encoding = (tvb_get_guint8(tvb_out, offset) & 0xf8) >> 3;
+
+ str = val_to_str_const(encoding, ansi_tsb58_encoding_vals, "Reserved");
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_char_set, tvb_out, offset, 1,
+ encoding,
+ "%s (%u)",
+ str, encoding);
+
+ num_bits = (record_len * 8) - 5;
+
+ switch (encoding)
+ {
+ case 0x04: /* UNICODE */
+ /* 16-bit encodings */
+ num_fields = num_bits / 16;
+ reserved_bits = 3;
+ break;
+
+ case 0x00: /* Octet, unspecified */
+ case 0x10: /* KSC5601 (Korean) */
+ case 0x07: /* Latin/Hebrew */
+ case 0x08: /* Latin */
+ /* 8-bit encodings */
+ num_fields = num_bits / 8;
+ reserved_bits = 3;
+ break;
+
+ default:
+ /* 7-bit encodings */
+ num_fields = num_bits / 7;
+
+ if ((num_bits % 7) == 0)
+ {
+ oct2 = tvb_get_guint8(tvb_out, offset + record_len - 1);
+ if ((oct2 & 0x7f) == 0)
+ {
+ /*
+ * the entire last 7 bits are reserved
+ */
+ num_fields--;
+ }
+ }
+
+ reserved_bits = num_bits - (num_fields * 7);
+ break;
+ }
+
+ temp_offset = offset;
+ text_decoder(tvb_out, pinfo, subtree, temp_offset, encoding, num_fields,
+ num_bits, 3 /* (5 bits used from 'temp_offset' octet for encoding */, 0);
+
+ offset += (record_len - 1);
+
+ if (reserved_bits > 0)
+ {
+ oct = tvb_get_guint8(tvb_out, offset);
+
+ bit_mask_8 = MASK_B(8 - reserved_bits, reserved_bits);
+
+ other_decode_bitfield_value(ansi_637_bigbuf, oct, bit_mask_8, 8);
+ proto_tree_add_uint_format(subtree, hf_ansi_637_reserved_bits_8_generic, tvb_out, offset, 1,
+ oct & bit_mask_8,
+ "%s = Reserved bit(s)",
+ ansi_637_bigbuf);
+ }
+
+ offset += 1;
+ break;
+
+ case 0x01:
+ oct = tvb_get_guint8(tvb_out, offset);
+
+ str = val_to_str_const(oct, cmas_category_strings, "Reserved");
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_category, tvb_out, offset, 1,
+ oct,
+ "%s (%u)",
+ str, oct);
+
+ offset += 1;
+
+ oct = tvb_get_guint8(tvb_out, offset);
+
+ str = val_to_str_const(oct, cmas_response_type_strings, "Reserved");
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_response_type, tvb_out, offset, 1,
+ oct,
+ "%s (%u)",
+ str, oct);
+
+ offset += 1;
+
+ oct = tvb_get_guint8(tvb_out, offset);
+
+ str = val_to_str_const((oct & 0xf0) >> 4, cmas_severity_strings, "Reserved");
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_severity, tvb_out, offset, 1,
+ oct,
+ "%s (%u)",
+ str, (oct & 0xf0) >> 4);
+
+ str = val_to_str_const(oct & 0x0f, cmas_urgency_strings, "Reserved");
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_urgency, tvb_out, offset, 1,
+ oct,
+ "%s (%u)",
+ str, oct & 0x0f);
+
+ offset += 1;
+
+ oct = tvb_get_guint8(tvb_out, offset);
+
+ str = val_to_str_const((oct & 0xf0) >> 4, cmas_certainty_strings, "Reserved");
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_certainty, tvb_out, offset, 1,
+ oct,
+ "%s (%u)",
+ str, (oct & 0xf0) >> 4);
+
+ proto_tree_add_item(subtree, hf_ansi_637_reserved_bits_8_0f, tvb_out, offset, 1, ENC_BIG_ENDIAN);
+
+ offset += 1;
+ break;
+
+ case 0x02:
+ proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_identifier, tvb_out, offset, 2, ENC_BIG_ENDIAN);
+
+ offset += 2;
+
+ proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_alert_handling, tvb_out, offset, 1, ENC_BIG_ENDIAN);
+
+ offset += 1;
+
+ oct = tvb_get_guint8(tvb_out, offset);
+
+ /*
+ * TIA-1149 does not say whether this should be encoded in the same way as IS-637
+ * I.e. year = oct + ((oct < 96) ? 2000 : 1900);
+ */
+ value = oct + ((oct < 96) ? 2000 : 1900);
+
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_expires_year, tvb_out, offset, 1,
+ oct,
+ "%u (%02x)",
+ value, oct);
+
+ offset += 1;
+
+ oct = tvb_get_guint8(tvb_out, offset);
+
+ str = val_to_str_const(oct - 1, ansi_tele_month_strings, "Invalid");
+
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_expires_month, tvb_out, offset, 1,
+ oct,
+ "%s (%02x)",
+ str, oct);
+
+ offset += 1;
+
+ proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_day, tvb_out, offset, 1, ENC_BIG_ENDIAN);
+
+ offset += 1;
+
+ proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_hours, tvb_out, offset, 1, ENC_BIG_ENDIAN);
+
+ offset += 1;
+
+ proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_minutes, tvb_out, offset, 1, ENC_BIG_ENDIAN);
+
+ offset += 1;
+
+ proto_tree_add_item(subtree, hf_ansi_637_tele_cmas_expires_seconds, tvb_out, offset, 1, ENC_BIG_ENDIAN);
+
+ offset += 1;
+
+ oct = tvb_get_guint8(tvb_out, offset);
+
+ str = val_to_str_ext_const(oct, &ansi_tsb58_language_ind_vals_ext, "Reserved");
+ proto_tree_add_uint_format_value(subtree, hf_ansi_637_tele_cmas_language, tvb_out, offset, 1,
+ oct,
+ "%s (%u)",
+ str, oct);
+
+ offset += 1;
+ break;
}
}
- else if (encoding == 0x03)/* IA5 */
- {
- i = (num_fields * 7) - 3;
- required_octs = (i / 8) + ((i % 8) ? 1 : 0);
- if (required_octs + used > len)
- {
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (required_octs + used) - len);
+ EXTRANEOUS_DATA_CHECK(required_octs, offset);
- return;
- }
+ offset += temp_offset; /* move 'offset' back to the correct spot in 'tvb' */
- saved_offset = offset - 1;
- i = num_fields * 7;
- required_octs = (i / 8) + ((i % 8) ? 1 : 0);
- buf = (gchar*)wmem_alloc(pinfo->pool, required_octs);
- for (i=0; i < required_octs; i++)
- {
- oct = tvb_get_guint8(tvb, saved_offset);
- oct2 = tvb_get_guint8(tvb, saved_offset + 1);
- buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
- saved_offset += 1;
- }
- tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs);
- add_new_data_source(pinfo, tvb_out, "Characters");
- offset = 0;
- bit = 0;
- if (*has_private_data == TRUE) {
- dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, ASCII_7BITS, &bit, &udh_fields);
- }
- saved_offset = offset;
- bit = bit ? bit : 8;
- oct = tvb_get_guint8(tvb_out, offset);
- offset += 1;
- out_len = decode_7_bits(tvb_out, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
- IA5_7BIT_decode(ia5_637_bigbuf, ansi_637_bigbuf, out_len);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_07, tvb, offset, 1, ENC_BIG_ENDIAN);
+}
- proto_tree_add_string(tree, hf_ansi_637_tele_user_data_text, tvb_out,
- saved_offset, offset - saved_offset, ia5_637_bigbuf);
+static void
+tele_param_user_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p)
+{
+ guint8 oct;
+ guint8 bit_mask_8;
+ guint8 encoding;
+ guint8 encoding_bit_len;
+ guint8 num_fields;
+ guint8 unused_bits;
+ guint8 fill_bits;
+ guint16 reserved_bits;
+ guint32 value;
+ guint32 orig_offset;
+ guint32 saved_offset;
+ guint32 required_octs;
+ const gchar *str = NULL;
+ tvbuff_t *tvb_out = NULL;
+ enum character_set cset;
- }
- else if (encoding == 0x04)/* UCS-2 (not UTF-16?) */
+ SHORT_DATA_CHECK(len, 2);
+
+ orig_offset = offset;
+ reserved_bits = len * 8;
+
+ value = tvb_get_ntohs(tvb, offset);
+
+ encoding_bit_len = 7;
+ cset = ASCII_7BITS;
+
+ encoding = (guint8) ((value & 0xf800) >> 11);
+ switch (encoding)
{
- saved_offset = offset - 1;
- required_octs = 2*num_fields;
- buf = (gchar*)wmem_alloc(pinfo->pool, required_octs);
- for (i=0; i < required_octs; i++)
- {
- oct = tvb_get_guint8(tvb, saved_offset);
- oct2 = tvb_get_guint8(tvb, saved_offset + 1);
- buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
- saved_offset += 1;
- }
- tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs);
- add_new_data_source(pinfo, tvb_out, "Characters");
- offset = 0;
- if (*has_private_data == TRUE) {
- dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, OTHER, &bit, &udh_fields);
- }
+ case 0x00:
+ str = "Octet, unspecified";
+ encoding_bit_len = 8;
+ cset = OTHER;
+ break;
- proto_tree_add_item(tree, hf_ansi_637_tele_user_data_text,
- tvb_out, offset, num_fields*2, ENC_UCS_2|ENC_BIG_ENDIAN);
+ case 0x01:
+ str = "Extended Protocol Message";
+ break;
+
+ case 0x02:
+ str = "7-bit ASCII";
+ break;
+
+ case 0x03:
+ str = "IA5";
+ break;
+
+ case 0x04:
+ str = "UNICODE";
+ encoding_bit_len = 16;
+ cset = OTHER;
+ break;
+
+ case 0x05:
+ str = "Shift-JIS";
+ break;
+
+ case 0x06:
+ str = "Korean";
+ cset = OTHER;
+ break;
+
+ case 0x07:
+ str = "Latin/Hebrew";
+ encoding_bit_len = 8;
+ cset = OTHER;
+ break;
+
+ case 0x08:
+ str = "Latin";
+ encoding_bit_len = 8;
+ cset = OTHER;
+ break;
+
+ case 0x09:
+ str = "GSM 7-bit default alphabet";
+ cset = GSM_7BITS;
+ break;
+
+ case 0x10:
+ str = "KSC5601 (Korean)";
+ encoding_bit_len = 8;
+ cset = OTHER;
+ break;
+
+ default:
+ str = "Reserved";
+ break;
}
- else if (encoding == 0x07)/* Latin/Hebrew */
+
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_user_data_encoding, tvb, offset, 2,
+ value,
+ "%s (%u)",
+ str,
+ encoding);
+
+ reserved_bits -= 5;
+
+ if (encoding == 0x01)
{
- saved_offset = offset - 1;
- buf = (gchar*)wmem_alloc(pinfo->pool, num_fields);
- for (i=0; i < num_fields; i++)
- {
- oct = tvb_get_guint8(tvb, saved_offset);
- oct2 = tvb_get_guint8(tvb, saved_offset + 1);
- buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
- saved_offset += 1;
- }
- tvb_out = tvb_new_child_real_data(tvb, buf, num_fields, num_fields);
- add_new_data_source(pinfo, tvb_out, "Characters");
- offset = 0;
- required_octs = len - used;
- if (*has_private_data == TRUE) {
- dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, OTHER, &bit, &udh_fields);
- }
+ proto_tree_add_item(tree, hf_ansi_637_tele_user_data_message_type, tvb, offset, 2, ENC_BIG_ENDIAN);
- proto_tree_add_item(tree, hf_ansi_637_tele_user_data_text,
- tvb_out, offset, num_fields, ENC_ISO_8859_8|ENC_NA);
+ offset += 1;
+ value = tvb_get_ntohs(tvb, offset);
+
+ reserved_bits -= 8;
}
- else if (encoding == 0x08) /* ISO 8859-1 (a/k/a ISO Latin 1) */
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_user_data_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
+
+ offset += 1;
+
+ num_fields = (value & 0x07f8) >> 3;
+
+ reserved_bits -= 8 + (num_fields * encoding_bit_len);
+
+ /* NOTE: there are now 3 bits remaining in 'value' */
+
+ unused_bits = 3;
+ fill_bits = 0;
+
+ /*
+ * ALL of this is for header support !
+ */
+ if (*has_private_data_p == TRUE)
{
- saved_offset = offset - 1;
- buf = (gchar*)wmem_alloc(pinfo->pool, num_fields);
- for (i=0; i < num_fields; i++)
+ gsm_sms_udh_fields_t udh_fields;
+ gint32 num_udh_bits;
+
+ memset(&udh_fields, 0, sizeof(udh_fields));
+
+ value = tvb_get_ntohs(tvb, offset);
+
+ /*
+ * 'length' split across two octets +1 for the length octet itself
+ * (dis_field_udh() will start at the length offset)
+ */
+ required_octs = ((value & 0x07f8) >> 3) + 1;
+
+ /*
+ * need fill bits
+ */
+ if (encoding_bit_len == 7)
{
- oct = tvb_get_guint8(tvb, saved_offset);
- oct2 = tvb_get_guint8(tvb, saved_offset + 1);
- buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
- saved_offset += 1;
+ /*
+ * not the same formula as dis_field_udh() because we are including
+ * the length octet in the calculation but the result is the same
+ */
+ fill_bits = 7 - ((required_octs * 8) % 7);
}
- tvb_out = tvb_new_child_real_data(tvb, buf, num_fields, num_fields);
- add_new_data_source(pinfo, tvb_out, "Characters");
+
+ num_udh_bits = (required_octs * 8) + fill_bits;
+
+ tvb_out =
+ tvb_new_octet_aligned(tvb, (offset * 8) + (8 - unused_bits), num_udh_bits);
+ add_new_data_source(pinfo, tvb_out, "Header");
+
+ saved_offset = offset + required_octs;
+
offset = 0;
- required_octs = len - used;
- if (*has_private_data == TRUE) {
- dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, OTHER, &bit, &udh_fields);
- }
+ fill_bits = 0;
+ dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, cset, &fill_bits, &udh_fields);
- proto_tree_add_item(tree, hf_ansi_637_tele_user_data_text,
- tvb_out, offset, num_fields, ENC_ISO_8859_1|ENC_NA);
- }
- else if (encoding == 0x09) /* GSM 7-bit default alphabet */
- {
- i = (num_fields * 7) - 3;
- required_octs = (i / 8) + ((i % 8) ? 1 : 0);
+ offset = saved_offset;
- if (required_octs + used > len)
+ if (encoding_bit_len == 7)
{
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (required_octs + used) - len);
+ switch (cset)
+ {
+ case GSM_7BITS:
+ case OTHER:
+ break;
+
+ case ASCII_7BITS:
+ if (fill_bits > unused_bits)
+ {
+ /* this branch was NOT tested */
- return;
+ offset += 1;
+ unused_bits = 8 - (fill_bits - unused_bits);
+ }
+ else if (fill_bits > 0)
+ {
+ /* this branch was tested */
+ unused_bits = unused_bits - fill_bits;
+ }
+
+ if (unused_bits == 0)
+ {
+ /* this branch was NOT tested */
+
+ offset += 1;
+ unused_bits = 8;
+ }
+ break;
+ }
}
- saved_offset = offset - 1;
- i = num_fields * 7;
- required_octs = (i / 8) + ((i % 8) ? 1 : 0);
- buf = (gchar*)wmem_alloc(pinfo->pool, required_octs);
- for (i=0; i < required_octs; i++)
+ if (udh_fields.frags > 0)
{
- oct = tvb_get_guint8(tvb, saved_offset);
- oct2 = tvb_get_guint8(tvb, saved_offset + 1);
- buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
- saved_offset += 1;
+ col_append_fstr(pinfo->cinfo, COL_INFO, " (Short Message fragment %u of %u)", udh_fields.frag, udh_fields.frags);
}
- tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs);
- add_new_data_source(pinfo, tvb_out, "Characters");
- offset = 0;
- bit = 0;
- if (*has_private_data == TRUE) {
- dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, GSM_7BITS, &bit, &udh_fields);
- }
-
- proto_tree_add_ts_23_038_7bits_item(tree, hf_ansi_637_tele_user_data_text, tvb_out, (offset<<3)+bit, num_fields);
}
- else if (encoding == 0x10)/* KSC5601 (Korean) */
+
+ text_decoder(tvb, pinfo, tree, offset, encoding, num_fields,
+ num_fields * encoding_bit_len, unused_bits, fill_bits);
+
+ if (reserved_bits > 0)
{
- saved_offset = offset - 1;
- buf = (gchar*)wmem_alloc(pinfo->pool, num_fields);
- for (i=0; i < num_fields; i++)
- {
- oct = tvb_get_guint8(tvb, saved_offset);
- oct2 = tvb_get_guint8(tvb, saved_offset + 1);
- buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
- saved_offset += 1;
- }
- tvb_out = tvb_new_child_real_data(tvb, buf, num_fields, num_fields);
- add_new_data_source(pinfo, tvb_out, "Characters");
- offset = 0;
- required_octs = len - used;
- if (*has_private_data == TRUE) {
- dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, OTHER, &bit, &udh_fields);
- }
+ /*
+ * unlike for CMAS, the bits that can be reserved will always be
+ * at the end of an octet so we don't have to worry about them
+ * spanning two octets
+ */
- if ((cd = g_iconv_open("UTF-8","EUC-KR")) != (GIConv)-1)
+ switch (cset)
{
- utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb_out, offset, num_fields), num_fields , cd , NULL , NULL , &l_conv_error);
- if (!l_conv_error)
- {
- proto_tree_add_string(tree, hf_ansi_637_tele_user_data_text,
- tvb_out, offset, num_fields, utf8_text);
- }
- else
- {
- proto_tree_add_text(tree, tvb_out, offset, num_fields, "%s", "Failed on EUC-KR contact Wireshark developers");
- }
- if (utf8_text)
- g_free(utf8_text);
- g_iconv_close(cd);
+ case GSM_7BITS:
+ bit_mask_8 = MASK_B(0, reserved_bits); /* MSBs */
+ break;
+
+ default:
+ bit_mask_8 = MASK_B(8 - reserved_bits, reserved_bits); /* LSBs */
+ break;
}
- }
- else
- {
- proto_tree_add_text(tree, tvb, offset, len - used,
- "Encoded user data");
+
+ oct = tvb_get_guint8(tvb, orig_offset + len - 1);
+
+ other_decode_bitfield_value(ansi_637_bigbuf, oct, bit_mask_8, 8);
+ proto_tree_add_uint_format(tree, hf_ansi_637_reserved_bits_8_generic, tvb, orig_offset + len - 1, 1,
+ oct & bit_mask_8,
+ "%s = Reserved bit(s)",
+ ansi_637_bigbuf);
}
}
static void
-tele_param_rsp_code(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_rsp_code(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct;
-
EXACT_DATA_CHECK(len, 1);
- /*
- * response code
- */
- oct = tvb_get_guint8(tvb, offset);
-
- proto_tree_add_text(tree, tvb, offset, 1,
- "Response code: %d",
- oct);
+ proto_tree_add_item(tree, hf_ansi_637_tele_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
}
static void
-tele_param_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_message_center_timestamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct, oct2, oct3;
-
EXACT_DATA_CHECK(len, 6);
- oct = tvb_get_guint8(tvb, offset);
- oct2 = tvb_get_guint8(tvb, offset+1);
- oct3 = tvb_get_guint8(tvb, offset+2);
-
- proto_tree_add_text(tree, tvb, offset, 3,
- "Year %d%d, Month %d%d, Day %d%d",
- (oct & 0xf0) >> 4,
- oct & 0x0f,
- (oct2 & 0xf0) >> 4,
- oct2 & 0x0f,
- (oct3 & 0xf0) >> 4,
- oct3 & 0x0f);
+ tele_param_timestamp(tvb, pinfo, tree, len, offset,
+ hf_ansi_637_tele_message_center_ts_year,
+ hf_ansi_637_tele_message_center_ts_month,
+ hf_ansi_637_tele_message_center_ts_day,
+ hf_ansi_637_tele_message_center_ts_hours,
+ hf_ansi_637_tele_message_center_ts_minutes,
+ hf_ansi_637_tele_message_center_ts_seconds);
+}
- offset += 3;
+static void
+tele_param_validity_period_abs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
+{
+ EXACT_DATA_CHECK(len, 6);
- oct = tvb_get_guint8(tvb, offset);
- oct2 = tvb_get_guint8(tvb, offset+1);
- oct3 = tvb_get_guint8(tvb, offset+2);
-
- proto_tree_add_text(tree, tvb, offset, 3,
- "Hour %d%d, Minutes %d%d, Seconds %d%d",
- (oct & 0xf0) >> 4,
- oct & 0x0f,
- (oct2 & 0xf0) >> 4,
- oct2 & 0x0f,
- (oct3 & 0xf0) >> 4,
- oct3 & 0x0f);
+ tele_param_timestamp(tvb, pinfo, tree, len, offset,
+ hf_ansi_637_tele_validity_period_ts_year,
+ hf_ansi_637_tele_validity_period_ts_month,
+ hf_ansi_637_tele_validity_period_ts_day,
+ hf_ansi_637_tele_validity_period_ts_hours,
+ hf_ansi_637_tele_validity_period_ts_minutes,
+ hf_ansi_637_tele_validity_period_ts_seconds);
}
static void
-tele_param_rel_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_timestamp_rel(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len _U_, guint32 offset, int hf)
{
- guint8 oct;
- guint32 value = 0;
- const gchar *str = NULL;
- const gchar *str2 = NULL;
-
- EXACT_DATA_CHECK(len, 1);
+ guint8 oct;
+ guint32 value = 0;
+ const gchar *str = NULL;
+ const gchar *str2 = NULL;
oct = tvb_get_guint8(tvb, offset);
@@ -887,262 +1322,207 @@ tele_param_rel_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
else { str = "Reserved"; break; }
}
- if (str == NULL)
+ if (str != NULL)
{
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s", str2);
+ proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
+ oct,
+ "%s",
+ str);
}
else
{
- proto_tree_add_text(tree, tvb, offset, 1,
- "%d %s",
+ proto_tree_add_uint_format_value(tree, hf, tvb, offset, 1,
+ oct,
+ "%u %s",
value, str2);
}
}
-static const value_string tele_param_pri_ind_strings[] = {
- { 0, "Normal" },
- { 1, "Interactive" },
- { 2, "Urgent" },
- { 3, "Emergency" },
- { 0, NULL }
-};
-
static void
-tele_param_pri_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_validity_period_rel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct;
- const gchar *str = NULL;
-
EXACT_DATA_CHECK(len, 1);
- oct = tvb_get_guint8(tvb, offset);
-
- str=val_to_str_const((oct&0xc0)>>6, tele_param_pri_ind_strings, "Unknown");
+ tele_param_timestamp_rel(tvb, pinfo, tree, len, offset, hf_ansi_637_tele_validity_period_relative_validity);
+}
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : %s",
- ansi_637_bigbuf,
- str);
+static void
+tele_param_deferred_del_abs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
+{
+ EXACT_DATA_CHECK(len, 6);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ tele_param_timestamp(tvb, pinfo, tree, len, offset,
+ hf_ansi_637_tele_deferred_del_ts_year,
+ hf_ansi_637_tele_deferred_del_ts_month,
+ hf_ansi_637_tele_deferred_del_ts_day,
+ hf_ansi_637_tele_deferred_del_ts_hours,
+ hf_ansi_637_tele_deferred_del_ts_minutes,
+ hf_ansi_637_tele_deferred_del_ts_seconds);
}
static void
-tele_param_priv_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_deferred_del_rel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct;
- const gchar *str = NULL;
-
EXACT_DATA_CHECK(len, 1);
- oct = tvb_get_guint8(tvb, offset);
-
- switch ((oct & 0xc0) >> 6)
- {
- case 0: str = "Not restricted (privacy level 0)"; break;
- case 1: str = "Restricted (privacy level 1)"; break;
- case 2: str = "Confidential (privacy level 2)"; break;
- case 3: str = "Secret (privacy level 3)"; break;
- }
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : %s",
- ansi_637_bigbuf,
- str);
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ tele_param_timestamp_rel(tvb, pinfo, tree, len, offset, hf_ansi_637_tele_deferred_del_relative);
}
+static const value_string tele_param_priority_ind_strings[] = {
+ { 0, "Normal" },
+ { 1, "Interactive" },
+ { 2, "Urgent" },
+ { 3, "Emergency" },
+ { 0, NULL }
+};
+
static void
-tele_param_reply_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_pri_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct;
-
EXACT_DATA_CHECK(len, 1);
- oct = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_ansi_637_tele_priority_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
+}
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : %s (manual) acknowledgment is requested",
- ansi_637_bigbuf,
- (oct & 0x80) ? "User" : "No user");
+static const value_string tele_param_privacy_ind_strings[] = {
+ { 0, "Not restricted (privacy level 0)" },
+ { 1, "Restricted (privacy level 1)" },
+ { 2, "Confidential (privacy level 2)" },
+ { 3, "Secret (privacy level 3)" },
+ { 0, NULL }
+};
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : %s acknowledgment requested",
- ansi_637_bigbuf,
- (oct & 0x40) ? "Delivery" : "No delivery");
+static void
+tele_param_priv_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
+{
+ EXACT_DATA_CHECK(len, 1);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ proto_tree_add_item(tree, hf_ansi_637_tele_privacy_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
}
static void
-tele_param_num_messages(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_reply_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct;
-
EXACT_DATA_CHECK(len, 1);
- oct = tvb_get_guint8(tvb, offset);
-
- proto_tree_add_text(tree, tvb, offset, 1,
- "Number of voice mail messages: %d%d",
- (oct & 0xf0) >> 4,
- oct & 0x0f);
+ proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_user_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_dak_req, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_read_ack_req, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_tele_reply_option_report_req, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, offset, 1, ENC_BIG_ENDIAN);
}
static void
-tele_param_alert(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_num_messages(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct;
- const gchar *str = NULL;
+ guint8 oct;
EXACT_DATA_CHECK(len, 1);
oct = tvb_get_guint8(tvb, offset);
- switch ((oct & 0xc0) >> 6)
- {
- case 0: str = "Use Mobile default alert"; break;
- case 1: str = "Use Low-priority alert"; break;
- case 2: str = "Use Medium-priority alert"; break;
- case 3: str = "Use High-priority alert"; break;
- }
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_num_messages, tvb, offset, 1,
+ ((oct & 0xf0) >> 4) * 10 + (oct & 0x0f),
+ "%u%u",
+ (oct & 0xf0) >> 4, oct & 0x0f);
+}
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : %s",
- ansi_637_bigbuf,
- str);
+static const value_string tele_param_alert_priority_strings[] = {
+ { 0, "Use Mobile default alert" },
+ { 1, "Use Low-priority alert" },
+ { 2, "Use Medium-priority alert" },
+ { 3, "Use High-priority alert" },
+ { 0, NULL }
+};
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+static void
+tele_param_alert(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
+{
+ EXACT_DATA_CHECK(len, 1);
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_alert_msg_delivery_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
}
static void
-tele_param_lang_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_lang_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct;
+ guint8 oct;
const gchar *str = NULL;
EXACT_DATA_CHECK(len, 1);
oct = tvb_get_guint8(tvb, offset);
- switch (oct)
- {
- case 0x00: str = "Unknown or unspecified"; break;
- case 0x01: str = "English"; break;
- case 0x02: str = "French"; break;
- case 0x03: str = "Spanish"; break;
- case 0x04: str = "Japanese"; break;
- case 0x05: str = "Korean"; break;
- case 0x06: str = "Chinese"; break;
- case 0x07: str = "Hebrew"; break;
- default: str = "Reserved"; break;
- }
-
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s", str);
+ str = val_to_str_ext_const(oct, &ansi_tsb58_language_ind_vals_ext, "Reserved");
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_language, tvb, offset, 1,
+ oct,
+ "%s (%u)",
+ str, oct);
}
static void
-tele_param_cb_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_cb_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct, oct2, num_fields, odd;
- guint32 saved_offset;
- guint32 required_octs;
- guint32 i;
+ guint8 oct, oct2, num_fields, odd;
+ guint8 *poctets;
+ guint32 saved_offset;
+ guint32 required_octs;
+ guint32 i;
SHORT_DATA_CHECK(len, 2);
- oct = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_digit_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Digit mode: %s",
- ansi_637_bigbuf,
- (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
+ oct = tvb_get_guint8(tvb, offset);
if (oct & 0x80)
{
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x70, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Type of number: (%d)",
- ansi_637_bigbuf,
- (oct & 0x70) >> 4);
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Numbering plan: (%d)",
- ansi_637_bigbuf,
- oct & 0x0f);
+ proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_ton, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_plan, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
- num_fields = tvb_get_guint8(tvb, offset);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xff, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Number of fields: (%d)",
- ansi_637_bigbuf,
- num_fields);
+ proto_tree_add_item(tree, hf_ansi_637_tele_cb_num_num_fields, tvb, offset, 1, ENC_BIG_ENDIAN);
- if (num_fields == 0) return;
+ num_fields = tvb_get_guint8(tvb, offset);
- if (num_fields > (len - 2))
- {
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (num_fields + 2) - len);
+ if (num_fields == 0) return;
- return;
- }
+ SHORT_DATA_CHECK(len - 2, num_fields);
offset += 1;
- i = 0;
- while (i < num_fields)
- {
- ansi_637_bigbuf[i] = tvb_get_guint8(tvb, offset+i) & 0x7f;
- i += 1;
- }
- ansi_637_bigbuf[i] = '\0';
+ poctets = tvb_get_string(wmem_packet_scope(), tvb, offset, num_fields);
- proto_tree_add_text(tree, tvb, offset, num_fields,
+ proto_tree_add_string_format(tree, hf_ansi_637_tele_cb_num_number, tvb, offset, num_fields,
+ (gchar *) poctets,
"Number: %s",
- ansi_637_bigbuf);
+ (gchar *) format_text(poctets, num_fields));
}
else
{
offset += 1;
- num_fields = (oct & 0x7f) << 1;
+
oct2 = tvb_get_guint8(tvb, offset);
- num_fields |= ((oct2 & 0x80) >> 7);
+ num_fields = ((oct & 0x7f) << 1) | ((oct2 & 0x80) >> 7);
+ /*
+ * not combined into a 16-bit field because hf_ansi_637_tele_cb_num_num_fields is used above
+ * and uses a different bitmask
+ */
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
- proto_tree_add_text(tree, tvb, offset-1, 1,
- "%s : Number of fields (MSB): (%d)",
+ proto_tree_add_uint_format(tree, hf_ansi_637_tele_cb_num_num_fields, tvb, offset, 1,
+ num_fields,
+ "%s = Number of fields (MSB): %u",
ansi_637_bigbuf,
num_fields);
other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Number of fields (LSB)",
+ "%s = Number of fields (LSB)",
ansi_637_bigbuf);
oct = oct2;
@@ -1153,14 +1533,7 @@ tele_param_cb_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint
i = (num_fields - 1) * 4;
required_octs = (i / 8) + ((i % 8) ? 1 : 0);
- if (required_octs + 2 > len)
- {
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (required_octs + 2) - len);
-
- return;
- }
+ SHORT_DATA_CHECK(len - 2, required_octs);
odd = num_fields & 0x01;
memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
@@ -1170,8 +1543,7 @@ tele_param_cb_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint
i = 0;
while (i < num_fields)
{
- ansi_637_bigbuf[i] =
- air_digits[(oct & 0x78) >> 3];
+ ansi_637_bigbuf[i] = air_digits[(oct & 0x78) >> 3];
i += 1;
if (i >= num_fields) break;
@@ -1179,83 +1551,215 @@ tele_param_cb_num(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint
oct2 = tvb_get_guint8(tvb, offset);
offset += 1;
- ansi_637_bigbuf[i] =
- air_digits[((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7)];
+ ansi_637_bigbuf[i] = air_digits[((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7)];
oct = oct2;
-
i += 1;
}
- proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
+ proto_tree_add_string_format(tree, hf_ansi_637_tele_cb_num_number, tvb, saved_offset, offset - saved_offset,
+ ansi_637_bigbuf,
"Number: %s",
ansi_637_bigbuf);
}
- other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x07: 0x7f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ proto_tree_add_item(tree,
+ odd ? hf_ansi_637_reserved_bits_8_07 : hf_ansi_637_reserved_bits_8_7f,
+ tvb, offset - 1, 1, ENC_BIG_ENDIAN);
+ }
+}
+
+static const value_string tele_param_msg_display_mode_strings[] = {
+ { 0, "Immediate Display: The mobile station is to display the received message as soon as possible." },
+ { 1, "Mobile default setting: The mobile station is to display the received message based on a pre-defined mode in the mobile station." },
+ { 2, "User Invoke: The mobile station is to display the received message based on the mode selected by the user." },
+ { 3, "Reserved" },
+ { 0, NULL }
+};
+
+static void
+tele_param_disp_mode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
+{
+ EXACT_DATA_CHECK(len, 1);
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_msg_display_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_3f, tvb, offset, 1, ENC_BIG_ENDIAN);
+}
+
+static void
+tele_param_msg_deposit_idx(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
+{
+ EXACT_DATA_CHECK(len, 2);
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_msg_deposit_idx, tvb, offset, 2, ENC_BIG_ENDIAN);
+}
+
+static const value_string tele_param_srvc_cat_prog_results_result_strings[] = {
+ { 0x00, "Programming successful" },
+ { 0x01, "Service Category memory limit exceeded" },
+ { 0x02, "Service Category limit exceeded" },
+ { 0x03, "Category already programmed" },
+ { 0x04, "Category not previously programmed" },
+ { 0x05, "Invalid MAX_MESSAGES" },
+ { 0x06, "Invalid ALERT_OPTION" },
+ { 0x07, "Invalid Service Category name" },
+ { 0x08, "Unspecified programming failure" },
+ { 0x09, "Reserved" },
+ { 0x0a, "Reserved" },
+ { 0x0b, "Reserved" },
+ { 0x0c, "Reserved" },
+ { 0x0d, "Reserved" },
+ { 0x0e, "Reserved" },
+ { 0x0f, "Reserved" },
+ { 0, NULL }
+};
+
+static void
+tele_param_srvc_cat_prog_results(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
+{
+ guint32 curr_offset;
+ guint32 value;
+ const gchar *str = NULL;
+
+ curr_offset = offset;
+
+ while ((len - (curr_offset - offset)) >= 3)
+ {
+ value = tvb_get_ntohs(tvb, curr_offset);
+
+ str = val_to_str_const(value, ansi_tsb58_srvc_cat_vals, "Reserved");
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat, tvb, curr_offset, 2,
+ value,
+ "%s (%u)",
+ str, value);
+
+ curr_offset += 2;
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_srvc_cat_prog_results_result, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+
+ curr_offset += 1;
}
+
+ EXTRANEOUS_DATA_CHECK(len, curr_offset - offset);
}
+/* Adamek Jan - IS637C Message status decoding procedure */
+static const value_string tele_param_msg_status_error_class_strings[] = {
+ { 0x00, "No Error" },
+ { 0x01, "Reserved" },
+ { 0x02, "Temporary Condition" },
+ { 0x03, "Permanent Condition" },
+ { 0, NULL }
+};
+
static void
-tele_param_disp_mode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data _U_)
+tele_param_msg_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
{
- guint8 oct;
+ guint8 oct;
+ guint8 msg_status_code;
const gchar *str = NULL;
EXACT_DATA_CHECK(len, 1);
+ proto_tree_add_item(tree, hf_ansi_637_tele_msg_status, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_tele_msg_status_error_class, tvb, offset, 1, ENC_BIG_ENDIAN);
+
oct = tvb_get_guint8(tvb, offset);
+ msg_status_code = (oct & 0x3f);
+
switch ((oct & 0xc0) >> 6)
{
- case 0: str = "Immediate Display: The mobile station is to display the received message as soon as possible."; break;
- 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;
- case 2: str = "User Invoke: The mobile station is to display the received message based on the mode selected by the user."; break;
- case 3: str = "Reserved"; break;
+ case 0x00:
+ switch (msg_status_code)
+ {
+ case 0x00: str = "Message accepted"; break;
+ case 0x01: str = "Message deposited to Internet"; break;
+ case 0x02: str = "Message delivered"; break;
+ case 0x03: str = "Message cancelled"; break;
+ default: str = "Reserved"; break;
+ }
+ break;
+
+ case 0x02:
+ switch (msg_status_code)
+ {
+ case 0x04: str = "Network congestion"; break;
+ case 0x05: str = "Network error"; break;
+ case 0x1f: str = "Unknown error"; break;
+ default: str = "Reserved"; break;
+ }
+ break;
+
+ case 0x03:
+ switch (msg_status_code)
+ {
+ case 0x04: str = "Network congestion"; break;
+ case 0x05: str = "Network error"; break;
+ case 0x06: str = "Cancel failed"; break;
+ case 0x07: str = "Blocked destination"; break;
+ case 0x08: str = "Text too long"; break;
+ case 0x09: str = "Duplicate message"; break;
+ case 0x0a: str = "Invalid destination"; break;
+ case 0x0d: str = "Message expired"; break;
+ case 0x1f: str = "Unknown error"; break;
+ default: str = "Reserved"; break;
+ }
+ break;
+
+ default:
+ str = "Reserved";
+ break;
}
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xc0, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : %s",
- ansi_637_bigbuf,
- str);
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_tele_msg_status_code, tvb, offset, 1,
+ oct,
+ "%s (%u)",
+ str, msg_status_code);
+}
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+static void
+tele_param_tp_failure_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p _U_)
+{
+ EXACT_DATA_CHECK(len, 1);
+
+ proto_tree_add_item(tree, hf_ansi_637_tele_tp_failure_cause_value, tvb, offset, 1, ENC_BIG_ENDIAN);
}
#define NUM_TELE_PARAM (sizeof(ansi_tele_param_strings)/sizeof(value_string))
static gint ett_ansi_637_tele_param[NUM_TELE_PARAM];
-static void (*ansi_637_tele_param_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean* has_private_data) = {
- tele_param_msg_id, /* Message Identifier */
- tele_param_user_data, /* User Data */
- tele_param_rsp_code, /* User Response Code */
- tele_param_timestamp, /* Message Center Time Stamp */
- tele_param_timestamp, /* Validity Period Absolute */
- tele_param_rel_timestamp, /* Validity Period Relative */
- tele_param_timestamp, /* Deferred Delivery Time - Absolute */
- tele_param_rel_timestamp, /* Deferred Delivery Time - Relative */
- tele_param_pri_ind, /* Priority Indicator */
- tele_param_priv_ind, /* Privacy Indicator */
- tele_param_reply_opt, /* Reply Option */
- tele_param_num_messages, /* Number of Messages */
- tele_param_alert, /* Alert on Message Delivery */
- tele_param_lang_ind, /* Language Indicator */
- tele_param_cb_num, /* Call-Back Number */
- tele_param_disp_mode, /* Message Display Mode */
- NULL, /* Multiple Encoding User Data */
- tele_param_msg_status /* Message status */
+static void (*ansi_637_tele_param_fcn[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint len, guint32 offset, gboolean *has_private_data_p) = {
+ tele_param_msg_id, /* Message Identifier */
+ tele_param_user_data, /* User Data */
+ tele_param_rsp_code, /* User Response Code */
+ tele_param_message_center_timestamp,/* Message Center Time Stamp */
+ tele_param_validity_period_abs, /* Validity Period - Absolute */
+ tele_param_validity_period_rel, /* Validity Period - Relative */
+ tele_param_deferred_del_abs, /* Deferred Delivery Time - Absolute */
+ tele_param_deferred_del_rel, /* Deferred Delivery Time - Relative */
+ tele_param_pri_ind, /* Priority Indicator */
+ tele_param_priv_ind, /* Privacy Indicator */
+ tele_param_reply_opt, /* Reply Option */
+ tele_param_num_messages, /* Number of Messages */
+ tele_param_alert, /* Alert on Message Delivery */
+ tele_param_lang_ind, /* Language Indicator */
+ tele_param_cb_num, /* Call-Back Number */
+ tele_param_disp_mode, /* Message Display Mode */
+ NULL, /* Multiple Encoding User Data */
+ tele_param_msg_deposit_idx, /* Message Deposit Index */
+ NULL, /* Service Category Program Data */
+ tele_param_srvc_cat_prog_results, /* Service Category Program Results */
+ tele_param_msg_status, /* Message status */
+ tele_param_tp_failure_cause, /* TP-Failure cause */
+ NULL, /* Enhanced VMN */
+ NULL /* Enhanced VMN Ack */
};
static void
trans_param_tele_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
{
- guint32 value;
+ guint32 value;
const gchar *str = NULL;
EXACT_DATA_CHECK(len, 2);
@@ -1323,41 +1827,56 @@ trans_param_tele_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gui
}
}
- proto_tree_add_text(tree, tvb, offset, 2,
- "%s (%d)",
- str,
- value);
+ /*
+ * NOT format_value because I don't need the text from the hf_
+ */
+ proto_tree_add_uint_format(tree, hf_ansi_637_trans_tele_id, tvb, offset, 2,
+ value,
+ "%s (%u)",
+ str, value);
- g_snprintf(add_string, string_len, " - %s (%d)", str, value);
+ g_snprintf(add_string, string_len, " - %s (%u)", str, value);
}
static void
trans_param_srvc_cat(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
{
- guint32 value;
+ guint32 value;
const gchar *str;
EXACT_DATA_CHECK(len, 2);
value = tvb_get_ntohs(tvb, offset);
- str = val_to_str_ext_const(value, &ansi_srvc_cat_strings_ext, "Reserved");
+ str = val_to_str_const(value, ansi_tsb58_srvc_cat_vals, "Reserved");
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_srvc_cat, tvb, offset, 2,
+ value,
+ "%s (%u)",
+ str, value);
- proto_tree_add_text(tree, tvb, offset, 2,
- "%s", str);
+ g_snprintf(add_string, string_len, " - %s (%u)", str, value);
- g_snprintf(add_string, string_len, " - %s (%d)", str, value);
+ if ((value >= ANSI_TSB58_SRVC_CAT_CMAS_MIN) && (value <= ANSI_TSB58_SRVC_CAT_CMAS_MAX))
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " - CMAS (%s)", str);
+ }
}
+static const value_string trans_param_addr_data_net_ton_strings[] = {
+ { 0x00, "Unknown" },
+ { 0x01, "Internet Protocol (RFC 791)" },
+ { 0x02, "Internet Email Address (RFC 822)" },
+ { 0, NULL }
+};
+
static void
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_)
{
- guint8 oct, oct2, num_fields, odd;
- gboolean email_addr;
- guint32 saved_offset;
- guint32 required_octs;
- guint32 i;
- const gchar *str;
+ guint8 oct, oct2, num_fields, odd;
+ gboolean email_addr;
+ guint32 saved_offset;
+ guint32 required_octs;
+ guint32 i;
SHORT_DATA_CHECK(len, 2);
@@ -1365,69 +1884,51 @@ trans_param_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gui
oct = tvb_get_guint8(tvb, offset);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Digit mode: %s",
- ansi_637_bigbuf,
- (oct & 0x80) ? "8-bit ASCII" : "4-bit DTMF");
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x40, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Number mode: %s",
- ansi_637_bigbuf,
- (oct & 0x40) ? "Data Network Address" : "ANSI T1.607");
+ proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_digit_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_trans_addr_param_number_mode, tvb, offset, 1, ENC_BIG_ENDIAN);
if (oct & 0x80)
{
if (oct & 0x40)
{
- switch ((oct & 0x38) >> 3)
- {
- case 0: str = "Unknown"; break;
- case 1: str = "Internet Protocol (RFC 791)"; break;
- case 2: str = "Internet Email Address (RFC 822)"; email_addr = TRUE; break;
- default:
- str = "Reserved";
- break;
- }
+ email_addr = (((oct & 0x38) >> 3) == 0x02) ? TRUE : FALSE;
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Type of number: %s (%d)",
- ansi_637_bigbuf,
- str,
- (oct & 0x38) >> 3);
+ /*
+ * do not change to ...add_item() with VALS in hf defintion because this parameter is
+ * used below in the 'else' with a different string array
+ */
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_addr_param_ton, tvb, offset, 1,
+ oct,
+ "%s (%u)",
+ val_to_str_const((oct & 0x38) >> 3, trans_param_addr_data_net_ton_strings, "Reserved"), (oct & 0x38) >> 3);
offset += 1;
- num_fields = (oct & 0x07) << 5;
+
oct2 = tvb_get_guint8(tvb, offset);
- num_fields |= ((oct2 & 0xf8) >> 3);
+ num_fields = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
+ /*
+ * not combined into a 16-bit field because hf_ansi_637_trans_addr_param_num_fields is used below
+ * and uses a different bitmask
+ */
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
- proto_tree_add_text(tree, tvb, offset-1, 1,
- "%s : Number of fields (MSB): (%d)",
- ansi_637_bigbuf,
- num_fields);
+ proto_tree_add_uint_format(tree, hf_ansi_637_trans_addr_param_num_fields, tvb, offset - 1, 1,
+ num_fields,
+ "%s = Number of fields (MSB): %u",
+ ansi_637_bigbuf, num_fields);
other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf8, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Number of fields (LSB)",
+ "%s = Number of fields (LSB)",
ansi_637_bigbuf);
if (num_fields == 0) return;
- if (num_fields > (len - 2))
- {
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (num_fields + 2) - len);
-
- return;
- }
+ SHORT_DATA_CHECK(len - 2, num_fields);
other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x07, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Most significant bits of first field",
+ "%s = Most significant bits of first field",
ansi_637_bigbuf);
offset += 1;
@@ -1437,49 +1938,52 @@ trans_param_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gui
while (i < num_fields)
{
ansi_637_bigbuf[i] = (oct & 0x07) << 5;
- ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf8) >> 3;
+ ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset + i)) & 0xf8) >> 3;
i += 1;
}
ansi_637_bigbuf[i] = '\0';
if (email_addr)
{
- proto_tree_add_text(tree, tvb, offset, num_fields - 1,
+ proto_tree_add_string_format(tree, hf_ansi_637_trans_addr_param_number, tvb, offset, num_fields - 1,
+ ansi_637_bigbuf,
"Number: %s",
ansi_637_bigbuf);
}
else
{
proto_tree_add_bytes(tree, hf_ansi_637_trans_bin_addr, tvb, offset, num_fields - 1,
- (guint8*)ansi_637_bigbuf);
+ (guint8 *) ansi_637_bigbuf);
}
offset += (num_fields - 1);
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf8, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Least significant bits of last field",
+ "%s = Least significant bits of last field",
ansi_637_bigbuf);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_07, tvb, offset, 1, ENC_BIG_ENDIAN);
}
else
{
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x38, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Type of number: (%d)",
- ansi_637_bigbuf,
- (oct & 0x38) >> 3);
+ /*
+ * do not change to ...add_item() with VALS in hf definition because this parameter
+ * is used above in the 'if' with a different string array
+ */
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_addr_param_ton, tvb, offset, 1,
+ oct,
+ "%s (%u)",
+ val_to_str_const((oct & 0x38) >> 3, ansi_a_ms_info_rec_num_type_vals, "Reserved"), (oct & 0x38) >> 3);
oct2 = tvb_get_guint8(tvb, offset + 1);
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x07, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Numbering plan (MSB): (%d)",
+ proto_tree_add_uint_format(tree, hf_ansi_637_trans_addr_param_plan, tvb, offset, 1,
+ ((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7),
+ "%s = Numbering Plan (MSB): %s (%u)",
ansi_637_bigbuf,
+ val_to_str_const(((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7), ansi_a_ms_info_rec_num_plan_vals, "Reserved"),
((oct & 0x07) << 1) | ((oct2 & 0x80) >> 7));
offset += 1;
@@ -1487,39 +1991,33 @@ trans_param_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gui
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Numbering plan (LSB)",
+ "%s = Numbering Plan (LSB)",
ansi_637_bigbuf);
offset += 1;
- num_fields = (oct & 0x7f) << 1;
+
oct2 = tvb_get_guint8(tvb, offset);
- num_fields |= ((oct2 & 0x80) >> 7);
+ num_fields = ((oct & 0x7f) << 1) | ((oct2 & 0x80) >> 7);
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
- proto_tree_add_text(tree, tvb, offset-1, 1,
- "%s : Number of fields (MSB): (%d)",
+ proto_tree_add_uint_format(tree, hf_ansi_637_trans_addr_param_num_fields, tvb, offset - 1, 1,
+ num_fields,
+ "%s = Number of fields (MSB): %u",
ansi_637_bigbuf,
num_fields);
other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x80, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Number of fields (LSB)",
+ "%s = Number of fields (LSB)",
ansi_637_bigbuf);
if (num_fields == 0) return;
- if (num_fields > (len - 3))
- {
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (num_fields + 3) - len);
-
- return;
- }
+ SHORT_DATA_CHECK(len - 3, num_fields);
other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x7f, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Most significant bits of first field",
+ "%s = Most significant bits of first field",
ansi_637_bigbuf);
offset += 1;
@@ -1529,12 +2027,13 @@ trans_param_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gui
while (i < num_fields)
{
ansi_637_bigbuf[i] = (oct & 0x7f) << 1;
- ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0x80) >> 7;
+ ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset + i)) & 0x80) >> 7;
i += 1;
}
ansi_637_bigbuf[i] = '\0';
- proto_tree_add_text(tree, tvb, offset, num_fields - 1,
+ proto_tree_add_string_format(tree, hf_ansi_637_trans_addr_param_number, tvb, offset, num_fields - 1,
+ ansi_637_bigbuf,
"Number: %s",
ansi_637_bigbuf);
@@ -1542,31 +2041,29 @@ trans_param_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gui
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x80, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Least significant bit of last field",
+ "%s = Least significant bit of last field",
ansi_637_bigbuf);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x7f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_7f, tvb, offset, 1, ENC_BIG_ENDIAN);
}
}
else
{
offset += 1;
- num_fields = (oct & 0x3f) << 2;
+
oct2 = tvb_get_guint8(tvb, offset);
- num_fields |= ((oct2 & 0xc0) >> 6);
+ num_fields = ((oct & 0x3f) << 2) | ((oct2 & 0xc0) >> 6);
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset-1, 1,
- "%s : Number of fields (MSB): (%d)",
+ proto_tree_add_uint_format(tree, hf_ansi_637_trans_addr_param_num_fields, tvb, offset - 1, 1,
+ num_fields,
+ "%s = Number of fields (MSB): %u",
ansi_637_bigbuf,
num_fields);
other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xc0, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Number of fields (LSB)",
+ "%s = Number of fields (LSB)",
ansi_637_bigbuf);
oct = oct2;
@@ -1577,14 +2074,7 @@ trans_param_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gui
i = (num_fields - 1) * 4;
required_octs = (i / 8) + ((i % 8) ? 1 : 0);
- if (required_octs + 2 > len)
- {
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (required_octs + 2) - len);
-
- return;
- }
+ SHORT_DATA_CHECK(len - 2, required_octs);
odd = num_fields & 0x01;
memset((void *) ansi_637_bigbuf, 0, sizeof(ansi_637_bigbuf));
@@ -1611,168 +2101,116 @@ trans_param_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gui
i += 1;
}
- proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
+ proto_tree_add_string_format(tree, hf_ansi_637_trans_addr_param_number, tvb, saved_offset, offset - saved_offset,
+ ansi_637_bigbuf,
"Number: %s",
ansi_637_bigbuf);
}
- other_decode_bitfield_value(ansi_637_bigbuf, oct, odd ? 0x03: 0x3f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ proto_tree_add_item(tree,
+ odd ? hf_ansi_637_reserved_bits_8_03 : hf_ansi_637_reserved_bits_8_3f,
+ tvb, offset - 1, 1, ENC_BIG_ENDIAN);
}
}
+static const value_string trans_param_subaddr_type_strings[] = {
+ { 0x0, "NSAP (CCITT Recommendation X.213 or ISO 8348 AD2)" },
+ { 0x1, "User-specified" },
+ { 0, NULL }
+};
+
static void
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_)
{
- guint8 oct, oct2, num_fields;
- guint32 i;
- const gchar *str;
+ guint8 oct, num_fields;
+ guint32 value;
+ guint32 i;
SHORT_DATA_CHECK(len, 2);
- oct = tvb_get_guint8(tvb, offset);
-
- switch ((oct & 0xe0) >> 5)
- {
- case 0: str = "NSAP (CCITT Recommendation X.213 or ISO 8348 AD2)"; break;
- case 1: str = "User-specified"; break;
- default:
- str = "Reserved";
- break;
- }
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xe0, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Type: %s",
- ansi_637_bigbuf,
- str);
+ value = tvb_get_ntohs(tvb, offset);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x10, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Odd",
- ansi_637_bigbuf);
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_subaddr_type, tvb, offset, 2,
+ value,
+ "%s (%u)",
+ val_to_str_const((value & 0xe000) >> 13, trans_param_subaddr_type_strings, "Reserved"), (value & 0xe000) >> 13);
- offset += 1;
- num_fields = (oct & 0x0f) << 4;
- oct2 = tvb_get_guint8(tvb, offset);
- num_fields |= ((oct2 & 0xf0) >> 4);
+ proto_tree_add_item(tree, hf_ansi_637_trans_subaddr_odd_even_ind, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_trans_subaddr_num_fields, tvb, offset, 2, ENC_BIG_ENDIAN);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
- proto_tree_add_text(tree, tvb, offset-1, 1,
- "%s : Number of fields (MSB): (%d)",
- ansi_637_bigbuf,
- num_fields);
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0xf0, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Number of fields (LSB)",
- ansi_637_bigbuf);
+ num_fields = (value & 0x0ff0) >> 4;
if (num_fields == 0) return;
- if (num_fields > (len - 2))
- {
- proto_tree_add_text(tree, tvb, offset, 1,
- "Missing %d octet(s) for number of fields",
- (num_fields + 2) - len);
+ SHORT_DATA_CHECK(len - 2, num_fields);
- return;
- }
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct2, 0x0f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Most significant bits of first field",
+ other_decode_bitfield_value(ansi_637_bigbuf, value, 0x000f, 16);
+ proto_tree_add_text(tree, tvb, offset, 2,
+ "%s = Most significant bits of first field",
ansi_637_bigbuf);
- offset += 1;
- oct = oct2;
+ offset += 2;
+ oct = value & 0x000f;
i = 0;
while (i < num_fields)
{
ansi_637_bigbuf[i] = (oct & 0x0f) << 4;
- ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset+i)) & 0xf0) >> 4;
+ ansi_637_bigbuf[i] |= ((oct = tvb_get_guint8(tvb, offset + i)) & 0xf0) >> 4;
i += 1;
}
ansi_637_bigbuf[i] = '\0';
proto_tree_add_bytes(tree, hf_ansi_637_trans_bin_addr, tvb, offset, num_fields - 1,
- (guint8*)ansi_637_bigbuf);
+ (guint8 *) ansi_637_bigbuf);
offset += (num_fields - 1);
other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xf0, 8);
proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Least significant bits of last field",
+ "%s = Least significant bits of last field",
ansi_637_bigbuf);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x0f, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_0f, tvb, offset, 1, ENC_BIG_ENDIAN);
}
static void
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)
{
- guint8 oct;
-
- oct = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_ansi_637_trans_bearer_reply_seq_num, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_reserved_bits_8_03, tvb, offset, 1, ENC_BIG_ENDIAN);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reply Sequence Number: %d",
- ansi_637_bigbuf,
- (oct & 0xfc) >> 2);
-
- g_snprintf(add_string, string_len, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reserved",
- ansi_637_bigbuf);
+ g_snprintf(add_string, string_len, " - Reply Sequence Number (%u)",
+ (tvb_get_guint8(tvb, offset) & 0xfc) >> 2);
}
+static const value_string trans_param_cause_codes_error_class_strings[] = {
+ { 0x00, "No Error" },
+ { 0x01, "Reserved" },
+ { 0x02, "Temporary Condition" },
+ { 0x03, "Permanent Condition" },
+ { 0, NULL }
+};
+
static void
trans_param_cause_codes(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint len, guint32 offset, gchar *add_string, int string_len)
{
- guint8 oct;
- const gchar *str = NULL;
-
- oct = tvb_get_guint8(tvb, offset);
-
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0xfc, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Reply Sequence Number: %d",
- ansi_637_bigbuf,
- (oct & 0xfc) >> 2);
-
- switch (oct & 0x03)
- {
- case 0x00: str = "No error"; break;
- case 0x02: str = "Temporary Condition"; break;
- case 0x03: str = "Permanent Condition"; break;
- default:
- str = "Reserved";
- break;
- }
+ guint8 oct;
+ const gchar *str;
- g_snprintf(add_string, string_len, " - Reply Sequence Number (%d)", (oct & 0xfc) >> 2);
+ proto_tree_add_item(tree, hf_ansi_637_trans_cause_codes_seq_num, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_ansi_637_trans_cause_codes_error_class, tvb, offset, 1, ENC_BIG_ENDIAN);
- other_decode_bitfield_value(ansi_637_bigbuf, oct, 0x03, 8);
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s : Error Class: %s",
- ansi_637_bigbuf,
- str);
+ oct = tvb_get_guint8(tvb, offset);
- offset += 1;
+ g_snprintf(add_string, string_len, " - Reply Sequence Number (%u)", (oct & 0xfc) >> 2);
if (!(oct & 0x03)) return;
if (len == 1) return;
+ offset += 1;
+
oct = tvb_get_guint8(tvb, offset);
switch (oct)
@@ -1819,40 +2257,38 @@ trans_param_cause_codes(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
break;
}
- proto_tree_add_text(tree, tvb, offset, 1,
- "%s", str);
+ proto_tree_add_uint_format_value(tree, hf_ansi_637_trans_cause_codes_code, tvb, offset, 1,
+ oct,
+ "%s (%u)",
+ str, oct);
}
static void
-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_)
+trans_param_bearer_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, guint len, guint32 offset, gchar *add_string _U_, int string_len _U_)
{
- tvbuff_t *tele_tvb;
-
- proto_tree_add_text(tree, tvb, offset, len,
- "Bearer Data");
+ tvbuff_t *tele_tvb;
/*
* dissect the embedded teleservice data
*/
tele_tvb = tvb_new_subset(tvb, offset, len, len);
- dissector_try_uint(tele_dissector_table, ansi_637_trans_tele_id,
- tele_tvb, pinfo, g_tree);
+ dissector_try_uint(tele_dissector_table, ansi_637_trans_tele_id, tele_tvb, pinfo, g_tree);
}
#define NUM_TRANS_PARAM (sizeof(ansi_trans_param_strings)/sizeof(value_string))
static gint ett_ansi_637_trans_param[NUM_TRANS_PARAM];
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) = {
- trans_param_tele_id, /* Teleservice Identifier */
- trans_param_srvc_cat, /* Service Category */
- trans_param_address, /* Originating Address */
- trans_param_subaddress, /* Originating Subaddress */
- trans_param_address, /* Destination Address */
- trans_param_subaddress, /* Destination Subaddress */
- trans_param_bearer_reply_opt, /* Bearer Reply Option */
- trans_param_cause_codes, /* Cause Codes */
- trans_param_bearer_data, /* Bearer Data */
- NULL, /* NONE */
+ trans_param_tele_id, /* Teleservice Identifier */
+ trans_param_srvc_cat, /* Service Category */
+ trans_param_address, /* Originating Address */
+ trans_param_subaddress, /* Originating Subaddress */
+ trans_param_address, /* Destination Address */
+ trans_param_subaddress, /* Destination Subaddress */
+ trans_param_bearer_reply_opt, /* Bearer Reply Option */
+ trans_param_cause_codes, /* Cause Codes */
+ trans_param_bearer_data, /* Bearer Data */
+ NULL, /* NONE */
};
#define NUM_TRANS_MSG_TYPE (sizeof(ansi_trans_msg_type_strings)/sizeof(value_string))
@@ -1861,9 +2297,9 @@ static gint ett_ansi_637_trans_msg[NUM_TRANS_MSG_TYPE];
/* GENERIC IS-637 DISSECTOR FUNCTIONS */
static gboolean
-dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 *offset, gboolean* has_private_data)
+dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 *offset, gboolean *has_private_data_p)
{
- void (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, guint, guint32, gboolean*) = NULL;
+ void (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, guint, guint32, gboolean *) = NULL;
guint8 oct;
guint8 len;
guint32 curr_offset;
@@ -1887,12 +2323,13 @@ dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
param_fcn = ansi_637_tele_param_fcn[idx];
item =
- proto_tree_add_text(tree, tvb, curr_offset, -1, "%s", str);
+ proto_tree_add_text(tree, tvb, curr_offset, -1,
+ "%s",
+ str);
subtree = proto_item_add_subtree(item, ett_param_idx);
- proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id,
- tvb, curr_offset, 1, oct);
+ proto_tree_add_uint(subtree, hf_ansi_637_tele_subparam_id, tvb, curr_offset, 1, oct);
curr_offset += 1;
@@ -1900,8 +2337,7 @@ dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_item_set_len(item, (curr_offset - *offset) + len + 1);
- proto_tree_add_uint(subtree, hf_ansi_637_tele_length,
- tvb, curr_offset, 1, len);
+ proto_tree_add_uint(subtree, hf_ansi_637_tele_length, tvb, curr_offset, 1, len);
curr_offset += 1;
@@ -1909,12 +2345,25 @@ dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
{
if (param_fcn == NULL)
{
- proto_tree_add_text(subtree, tvb, curr_offset,
- len, "Parameter Data");
+ proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_no_tele_parameter_dissector, tvb, curr_offset, len);
}
else
{
- (*param_fcn)(tvb, pinfo, subtree, len, curr_offset, has_private_data);
+ /*
+ * internal working (aka hack) for CMAS
+ *
+ * the 'User Data' subparameter is encoded in a special way for CMAS
+ * (as per TIA-1149)
+ *
+ * if (Broadcast SMS && 'User Data') then call CMAS dissector
+ */
+ if ((ansi_637_trans_tele_id == INTERNAL_BROADCAST_TELE_ID) &&
+ (oct == 0x01))
+ {
+ param_fcn = tele_param_user_data_cmas;
+ }
+
+ (*param_fcn)(tvb, pinfo, subtree, len, curr_offset, has_private_data_p);
}
curr_offset += len;
@@ -1926,20 +2375,19 @@ dissect_ansi_637_tele_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
static void
-dissect_ansi_637_tele_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ansi_637_tree, gboolean* has_private_data)
+dissect_ansi_637_tele_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ansi_637_tree, gboolean *has_private_data_p)
{
- guint8 len;
- guint32 curr_offset;
+ guint8 len;
+ guint32 curr_offset;
curr_offset = 0;
len = tvb_length(tvb);
while ((len - curr_offset) > 0)
{
- if (!dissect_ansi_637_tele_param(tvb, pinfo, ansi_637_tree, &curr_offset, has_private_data))
+ if (!dissect_ansi_637_tele_param(tvb, pinfo, ansi_637_tree, &curr_offset, has_private_data_p))
{
- proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
- "Unknown Parameter Data");
+ proto_tree_add_expert(ansi_637_tree, pinfo, &ei_ansi_637_unknown_tele_parameter, tvb, curr_offset, len - curr_offset);
break;
}
}
@@ -1950,9 +2398,9 @@ dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ansi_637_item;
proto_tree *ansi_637_tree = NULL;
- const gchar *str = NULL;
- guint32 value;
- gboolean has_private_data = FALSE;
+ const gchar *str = NULL;
+ guint32 value;
+ gboolean has_private_data = FALSE;
col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
@@ -2015,19 +2463,10 @@ dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
str = "Reserved for assignment by this Standard for TDMA MS-based SMEs";
}
- else if ((value >= 49152) && (value < 65535))
+ else if ((value >= 49152) && (value <= 65535))
{
str = "Reserved for carrier specific teleservices";
}
- else if (value == 65535)
- {
- /*
- * supposed to be "Reserved for carrier specific teleservices"
- * but we are using it to key SMS Broadcast dissection where
- * there is no teleservice ID
- */
- str = "(Reserved) Being used for Broadcast";
- }
else
{
str = "Unrecognized Teleservice ID";
@@ -2036,15 +2475,27 @@ dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
- ansi_637_item =
- proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
- "%s - %s (%d)",
- ansi_proto_name_tele,
- str,
- pinfo->match_uint);
+ if (value == INTERNAL_BROADCAST_TELE_ID)
+ {
+ /*
+ * supposed to be "Reserved for carrier specific teleservices"
+ * but we are using it to key SMS Broadcast dissection where
+ * there is no teleservice ID
+ */
+ ansi_637_item =
+ proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
+ "%s",
+ ansi_proto_name_tele);
+ }
+ else
+ {
+ ansi_637_item =
+ proto_tree_add_protocol_format(tree, proto_ansi_637_tele, tvb, 0, -1,
+ "%s - %s (%u)",
+ ansi_proto_name_tele, str, pinfo->match_uint);
+ }
- ansi_637_tree =
- proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele);
+ ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele);
dissect_ansi_637_tele_message(tvb, pinfo, ansi_637_tree, &has_private_data);
}
@@ -2053,14 +2504,14 @@ dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static gboolean
dissect_ansi_637_trans_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 *offset)
{
- void (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, guint, guint32, gchar *, int) = NULL;
- guint8 oct;
- guint8 len;
- guint32 curr_offset;
- gint ett_param_idx, idx;
+ void (*param_fcn)(tvbuff_t *, packet_info *, proto_tree *, guint, guint32, gchar *, int) = NULL;
+ guint8 oct;
+ guint8 len;
+ guint32 curr_offset;
+ gint ett_param_idx, idx;
proto_tree *subtree;
proto_item *item;
- const gchar *str = NULL;
+ const gchar *str;
curr_offset = *offset;
@@ -2075,13 +2526,11 @@ dissect_ansi_637_trans_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
ett_param_idx = ett_ansi_637_trans_param[idx];
param_fcn = ansi_637_trans_param_fcn[idx];
- item =
- proto_tree_add_text(tree, tvb, curr_offset, -1, "%s", str);
+ item = proto_tree_add_text(tree, tvb, curr_offset, -1, "%s", str);
subtree = proto_item_add_subtree(item, ett_param_idx);
- proto_tree_add_uint(subtree, hf_ansi_637_trans_param_id,
- tvb, curr_offset, 1, oct);
+ proto_tree_add_uint(subtree, hf_ansi_637_trans_param_id, tvb, curr_offset, 1, oct);
curr_offset += 1;
@@ -2089,8 +2538,7 @@ dissect_ansi_637_trans_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
proto_item_set_len(item, (curr_offset - *offset) + len + 1);
- proto_tree_add_uint(subtree, hf_ansi_637_trans_length,
- tvb, curr_offset, 1, len);
+ proto_tree_add_uint(subtree, hf_ansi_637_trans_length, tvb, curr_offset, 1, len);
curr_offset += 1;
@@ -2098,14 +2546,13 @@ dissect_ansi_637_trans_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
{
if (param_fcn == NULL)
{
- proto_tree_add_text(subtree, tvb, curr_offset,
- len, "Parameter Data");
+ proto_tree_add_expert(subtree, pinfo, &ei_ansi_637_no_trans_parameter_dissector, tvb, curr_offset, len);
}
else
{
- gchar *ansi_637_add_string;
+ gchar *ansi_637_add_string;
- ansi_637_add_string = (gchar *)wmem_alloc(wmem_packet_scope(), 1024);
+ ansi_637_add_string = (gchar *) wmem_alloc(wmem_packet_scope(), 1024);
ansi_637_add_string[0] = '\0';
(*param_fcn)(tvb, pinfo, subtree, len, curr_offset, ansi_637_add_string, 1024);
@@ -2129,11 +2576,11 @@ dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ansi_637_item;
proto_tree *ansi_637_tree = NULL;
- guint32 curr_offset;
- gint idx;
- const gchar *str = NULL;
- guint8 oct;
- guint8 len;
+ guint32 curr_offset;
+ gint idx;
+ const gchar *str = NULL;
+ guint8 oct;
+ guint8 len;
col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short);
@@ -2160,23 +2607,19 @@ dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
ansi_637_item =
proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
- "%s - Unrecognized Transport Layer Message Type (%d)",
- ansi_proto_name_trans,
- oct);
+ "%s - Unrecognized Transport Layer Message Type (%u)",
+ ansi_proto_name_trans, oct);
- ansi_637_tree =
- proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans);
+ ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans);
}
else
{
ansi_637_item =
proto_tree_add_protocol_format(tree, proto_ansi_637_trans, tvb, 0, -1,
"%s - %s",
- ansi_proto_name_trans,
- str);
+ ansi_proto_name_trans, str);
- ansi_637_tree =
- proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans_msg[idx]);
+ ansi_637_tree = proto_item_add_subtree(ansi_637_item, ett_ansi_637_trans_msg[idx]);
if (oct == ANSI_TRANS_MSG_TYPE_BROADCAST)
{
@@ -2186,7 +2629,9 @@ dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*
* using a reserved value to key dissector port
*/
- ansi_637_trans_tele_id = 65535;
+ ansi_637_trans_tele_id = INTERNAL_BROADCAST_TELE_ID;
+
+ col_append_str(pinfo->cinfo, COL_INFO, "(BROADCAST)");
}
}
@@ -2198,100 +2643,592 @@ dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
if (!dissect_ansi_637_trans_param(tvb, pinfo, ansi_637_tree, &curr_offset))
{
- proto_tree_add_text(ansi_637_tree, tvb, curr_offset, len - curr_offset,
- "Unknown Parameter Data");
+ proto_tree_add_expert(ansi_637_tree, pinfo, &ei_ansi_637_unknown_trans_parameter, tvb, curr_offset, len - curr_offset);
break;
}
}
}
}
+
+
/* Dissect SMS embedded in SIP */
static void
dissect_ansi_637_trans_app(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- col_set_str(pinfo->cinfo, COL_PROTOCOL,"/");
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "/");
col_set_fence(pinfo->cinfo, COL_INFO);
dissect_ansi_637_trans(tvb, pinfo, tree);
}
+
+
/* Register the protocol with Wireshark */
void
proto_register_ansi_637(void)
{
- guint i;
+ guint i;
/* Setup list of header fields */
- static hf_register_info hf_trans[] =
- {
-#if 0
- { &hf_ansi_637_trans_msg_type,
- { "Message Type",
- "ansi_637_trans.msg_type",
- FT_UINT24, BASE_DEC, VALS(ansi_trans_msg_type_strings), 0xf00000,
- NULL, HFILL }},
-#endif
+ static hf_register_info hf_trans[] = {
{ &hf_ansi_637_trans_param_id,
{ "Transport Param ID", "ansi_637_trans.param_id",
FT_UINT8, BASE_DEC, VALS(ansi_trans_param_strings), 0,
- NULL, HFILL }},
+ NULL, HFILL }
+ },
{ &hf_ansi_637_trans_length,
{ "Length", "ansi_637_trans.len",
FT_UINT8, BASE_DEC, NULL, 0,
- NULL, HFILL }},
+ NULL, HFILL }
+ },
{ &hf_ansi_637_trans_bin_addr,
{ "Binary Address", "ansi_637_trans.bin_addr",
- FT_BYTES, BASE_NONE, 0, 0,
- NULL, HFILL }},
- };
- static hf_register_info hf_tele[] =
- {
+ FT_BYTES, BASE_NONE, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_tele_id,
+ { "Teleservice ID", "ansi_637_trans.tele_id",
+ FT_UINT16, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_srvc_cat,
+ { "Service Category", "ansi_637_trans.srvc_cat",
+ FT_UINT16, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_addr_param_digit_mode,
+ { "Digit Mode", "ansi_637_trans.addr_param.digit_mode",
+ FT_BOOLEAN, 8, TFS(&tfs_digit_mode_8bit_4bit), 0x80,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_addr_param_number_mode,
+ { "Number Mode", "ansi_637_trans.addr_param.number_mode",
+ FT_BOOLEAN, 8, TFS(&tfs_number_mode_data_ansi_t1), 0x40,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_addr_param_ton,
+ { "Type of Number", "ansi_637_trans.addr_param.ton",
+ FT_UINT8, BASE_DEC, NULL, 0x38,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_addr_param_plan,
+ { "Numbering Plan", "ansi_637_trans.addr_param.plan",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_addr_param_num_fields,
+ { "Number of fields", "ansi_637_trans.addr_param.num_fields",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_addr_param_number,
+ { "Number", "ansi_637_trans.addr_param.number",
+ FT_STRING, BASE_NONE, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_subaddr_type,
+ { "Type", "ansi_637_trans.subaddr.type",
+ FT_UINT16, BASE_DEC, NULL, 0xe000,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_subaddr_odd_even_ind,
+ { "Odd/Even Indicator", "ansi_637_trans.subaddr.odd_even_ind",
+ FT_UINT16, BASE_DEC, VALS(ansi_trans_subaddr_odd_even_ind_strings), 0x1000,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_subaddr_num_fields,
+ { "Number of fields", "ansi_637_trans.subaddr.num_fields",
+ FT_UINT16, BASE_DEC, NULL, 0x0ff0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_bearer_reply_seq_num,
+ { "Reply Sequence Number", "ansi_637_trans.bearer_reply.seq_num",
+ FT_UINT8, BASE_DEC, NULL, 0xfc,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_cause_codes_seq_num,
+ { "Reply Sequence Number", "ansi_637_trans.cause_codes.seq_num",
+ FT_UINT8, BASE_DEC, NULL, 0xfc,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_cause_codes_error_class,
+ { "Error Class", "ansi_637_trans.cause_codes.error_class",
+ FT_UINT8, BASE_DEC, VALS(trans_param_cause_codes_error_class_strings), 0x03,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_trans_cause_codes_code,
+ { "Cause Code", "ansi_637_trans.cause_codes.code",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ }
+ };
+
+ static hf_register_info hf_tele[] = {
{ &hf_ansi_637_tele_msg_type,
- { "Message Type",
+ { "Message Type",
"ansi_637_tele.msg_type",
FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_type_strings), 0xf00000,
- NULL, HFILL }},
+ NULL, HFILL }
+ },
{ &hf_ansi_637_tele_msg_id,
- { "Message ID",
+ { "Message ID",
"ansi_637_tele.msg_id",
FT_UINT24, BASE_DEC, NULL, 0x0ffff0,
- NULL, HFILL }},
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_length,
+ { "Length", "ansi_637_tele.len",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
{ &hf_ansi_637_tele_msg_status,
- { "Message Status",
+ { "Message Status",
"ansi_637_tele.msg_status",
FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ansi_tele_msg_status_strings_ext, 0,
- NULL, HFILL }},
- { &hf_ansi_637_tele_msg_ind,
- { "Header Indicator",
- "ansi_637_tele.msg_ind",
- FT_UINT24, BASE_DEC, NULL, 0x000008,
- NULL, HFILL }},
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_msg_header_ind,
+ { "Header Indicator",
+ "ansi_637_tele.msg_header_ind",
+ FT_UINT24, BASE_DEC, VALS(ansi_tele_msg_header_ind_strings), 0x000008,
+ NULL, HFILL }
+ },
{ &hf_ansi_637_tele_msg_rsvd,
- { "Reserved",
+ { "Reserved",
"ansi_637_tele.msg_rsvd",
FT_UINT24, BASE_DEC, NULL, 0x000007,
- NULL, HFILL }},
- { &hf_ansi_637_tele_length,
- { "Length", "ansi_637_tele.len",
- FT_UINT8, BASE_DEC, NULL, 0,
- NULL, HFILL }},
+ NULL, HFILL }
+ },
{ &hf_ansi_637_tele_subparam_id,
{ "Teleservice Subparam ID", "ansi_637_tele.subparam_id",
FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ansi_tele_param_strings_ext, 0,
- NULL, HFILL }},
+ NULL, HFILL }
+ },
{ &hf_ansi_637_tele_user_data_text,
{ "Encoded user data", "ansi_637_tele.user_data.text",
FT_STRING, STR_UNICODE, NULL, 0,
- NULL, HFILL }},
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_user_data_encoding,
+ { "Encoding", "ansi_637_tele.user_data.encoding",
+ FT_UINT16, BASE_DEC, NULL, 0xf800,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_user_data_message_type,
+ { "Message Type (see TIA/EIA/IS-91)", "ansi_637_tele.user_data.message_type",
+ FT_UINT16, BASE_DEC, NULL, 0x07f8,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_user_data_num_fields,
+ { "Number of fields", "ansi_637_tele.user_data.num_fields",
+ FT_UINT16, BASE_DEC, NULL, 0x07f8,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_response_code,
+ { "Response Code", "ansi_637_tele.response_code",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_message_center_ts_year,
+ { "Timestamp (Year)", "ansi_637_tele.message_center_ts.year",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_message_center_ts_month,
+ { "Timestamp (Month)", "ansi_637_tele.message_center_ts.month",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_message_center_ts_day,
+ { "Timestamp (Day)", "ansi_637_tele.message_center_ts.day",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_message_center_ts_hours,
+ { "Timestamp (Hours)", "ansi_637_tele.message_center_ts.hours",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_message_center_ts_minutes,
+ { "Timestamp (Minutes)", "ansi_637_tele.message_center_ts.minutes",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_message_center_ts_seconds,
+ { "Timestamp (Seconds)", "ansi_637_tele.message_center_ts.seconds",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_validity_period_ts_year,
+ { "Timestamp (Year)", "ansi_637_tele.validity_period_ts.year",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_validity_period_ts_month,
+ { "Timestamp (Month)", "ansi_637_tele.validity_period_ts.month",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_validity_period_ts_day,
+ { "Timestamp (Day)", "ansi_637_tele.validity_period_ts.day",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_validity_period_ts_hours,
+ { "Timestamp (Hours)", "ansi_637_tele.validity_period_ts.hours",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_validity_period_ts_minutes,
+ { "Timestamp (Minutes)", "ansi_637_tele.validity_period_ts.minutes",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_validity_period_ts_seconds,
+ { "Timestamp (Seconds)", "ansi_637_tele.validity_period_ts.seconds",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_validity_period_relative_validity,
+ { "Validity", "ansi_637_tele.validity_period_relative.validity",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_deferred_del_ts_year,
+ { "Timestamp (Year)", "ansi_637_tele.deferred_del_ts.year",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_deferred_del_ts_month,
+ { "Timestamp (Month)", "ansi_637_tele.deferred_del_ts.month",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_deferred_del_ts_day,
+ { "Timestamp (Day)", "ansi_637_tele.deferred_del_ts.day",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_deferred_del_ts_hours,
+ { "Timestamp (Hours)", "ansi_637_tele.deferred_del_ts.hours",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_deferred_del_ts_minutes,
+ { "Timestamp (Minutes)", "ansi_637_tele.deferred_del_ts.minutes",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_deferred_del_ts_seconds,
+ { "Timestamp (Seconds)", "ansi_637_tele.deferred_del_ts.seconds",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_deferred_del_relative,
+ { "Delivery Time", "ansi_637_tele.deferred_del.relative",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_priority_indicator,
+ { "Priority", "ansi_637_tele.priority_indicator",
+ FT_UINT8, BASE_DEC, VALS(tele_param_priority_ind_strings), 0xc0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_privacy_indicator,
+ { "Privacy", "ansi_637_tele.privacy_indicator",
+ FT_UINT8, BASE_DEC, VALS(tele_param_privacy_ind_strings), 0xc0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_reply_option_user_ack_req,
+ { "User Acknowledgement Requested", "ansi_637_tele.reply_option.user_ack_req",
+ FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_reply_option_dak_req,
+ { "Delivery Acknowledgement Requested", "ansi_637_tele.reply_option.dak_req",
+ FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_reply_option_read_ack_req,
+ { "Read Acknowledgement Requested", "ansi_637_tele.reply_option.read_ack_req",
+ FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_reply_option_report_req,
+ { "Delivery/Submit Report Requested", "ansi_637_tele.reply_option.report_req",
+ FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_num_messages,
+ { "Number of voice mail messages", "ansi_637_tele.num_messages.count",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_alert_msg_delivery_priority,
+ { "Privacy", "ansi_637_tele.alert_msg_delivery.priority",
+ FT_UINT8, BASE_DEC, VALS(tele_param_alert_priority_strings), 0xc0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_language,
+ { "Language", "ansi_637_tele.language",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cb_num_digit_mode,
+ { "Digit Mode", "ansi_637_tele.cb_num.digit_mode",
+ FT_BOOLEAN, 8, TFS(&tfs_digit_mode_8bit_4bit), 0x80,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cb_num_ton,
+ { "Type of Number", "ansi_637_tele.cb_num.ton",
+ FT_UINT8, BASE_DEC, VALS(ansi_a_ms_info_rec_num_type_vals), 0x70,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cb_num_plan,
+ { "Numbering Plan", "ansi_637_tele.cb_num.plan",
+ FT_UINT8, BASE_DEC, VALS(ansi_a_ms_info_rec_num_plan_vals), 0x0f,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cb_num_num_fields,
+ { "Number of fields", "ansi_637_tele.cb_num.num_fields",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cb_num_number,
+ { "Call-Back Number", "ansi_637_tele.cb_num.number",
+ FT_STRING, BASE_NONE, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_msg_display_mode,
+ { "Message Display Mode", "ansi_637_tele.msg_display_mode",
+ FT_UINT8, BASE_DEC, VALS(tele_param_msg_display_mode_strings), 0xc0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_msg_deposit_idx,
+ { "Message Deposit Index", "ansi_637_tele.msg_deposit_idx",
+ FT_UINT16, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_srvc_cat_prog_results_srvc_cat,
+ { "Service Category", "ansi_637_tele.srvc_cat_prog_results.srvc_cat",
+ FT_UINT16, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_srvc_cat_prog_results_result,
+ { "Programming Result", "ansi_637_tele.srvc_cat_prog_results.result",
+ FT_UINT8, BASE_DEC, VALS(tele_param_srvc_cat_prog_results_result_strings), 0xf0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_msg_status_error_class,
+ { "Error Class", "ansi_637_tele.msg_status.error_class",
+ FT_UINT8, BASE_DEC, VALS(tele_param_msg_status_error_class_strings), 0xc0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_msg_status_code,
+ { "Message Status Code", "ansi_637_tele.msg_status.code",
+ FT_UINT8, BASE_DEC, NULL, 0x3f,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_tp_failure_cause_value,
+ { "GSM SMS TP-Failure Cause", "ansi_637_tele.tp_failure_cause.value",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_reserved_bits_8_generic,
+ { "Reserved bit(s)", "ansi_637_tele.reserved",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_reserved_bits_8_03,
+ { "Reserved bit(s)", "ansi_637_tele.reserved",
+ FT_UINT8, BASE_DEC, NULL, 0x03,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_reserved_bits_8_07,
+ { "Reserved bit(s)", "ansi_637_tele.reserved",
+ FT_UINT8, BASE_DEC, NULL, 0x07,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_reserved_bits_8_0f,
+ { "Reserved bit(s)", "ansi_637_tele.reserved",
+ FT_UINT8, BASE_DEC, NULL, 0x0f,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_reserved_bits_8_3f,
+ { "Reserved bit(s)", "ansi_637_tele.reserved",
+ FT_UINT8, BASE_DEC, NULL, 0x3f,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_reserved_bits_8_7f,
+ { "Reserved bit(s)", "ansi_637_tele.reserved",
+ FT_UINT8, BASE_DEC, NULL, 0x7f,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_encoding,
+ { "Encoding", "ansi_637_tele.cmas.encoding",
+ FT_UINT16, BASE_DEC, NULL, 0xf800,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_num_fields,
+ { "Number of fields", "ansi_637_tele.cmas.num_fields",
+ FT_UINT16, BASE_DEC, NULL, 0x07f8,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_protocol_version,
+ { "CMAE_protocol_version", "ansi_637_tele.cmas.protocol_version",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_record_type,
+ { "E_RECORD_TYPE", "ansi_637_tele.cmas.record_type",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_record_len,
+ { "E_RECORD_LENGTH", "ansi_637_tele.cmas.record_len",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_char_set,
+ { "CMAE_char_set", "ansi_637_tele.cmas.char_set",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_category,
+ { "CMAE_category", "ansi_637_tele.cmas.category",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_response_type,
+ { "CMAE_response_type", "ansi_637_tele.cmas.response_type",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_severity,
+ { "CMAE_severity", "ansi_637_tele.cmas.severity",
+ FT_UINT8, BASE_DEC, NULL, 0xf0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_urgency,
+ { "CMAE_urgency", "ansi_637_tele.cmas.urgency",
+ FT_UINT8, BASE_DEC, NULL, 0x0f,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_certainty,
+ { "CMAE_certainty", "ansi_637_tele.cmas.certainty",
+ FT_UINT8, BASE_DEC, NULL, 0xf0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_identifier,
+ { "CMAE_identifier", "ansi_637_tele.cmas.identifier",
+ FT_UINT16, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_alert_handling,
+ { "CMAE_alert_handling", "ansi_637_tele.cmas.alert_handling",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_expires_year,
+ { "CMAE_expires (Year)", "ansi_637_tele.cmas.expires.year",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_expires_month,
+ { "CMAE_expires (Month)", "ansi_637_tele.cmas.expires.month",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_expires_day,
+ { "CMAE_expires (Day)", "ansi_637_tele.cmas.expires.day",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_expires_hours,
+ { "CMAE_expires (Hours)", "ansi_637_tele.cmas.expires.hours",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_expires_minutes,
+ { "CMAE_expires (Minutes)", "ansi_637_tele.cmas.expires.minutes",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_expires_seconds,
+ { "CMAE_expires (Seconds)", "ansi_637_tele.cmas.expires.seconds",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_ansi_637_tele_cmas_language,
+ { "CMAE_language", "ansi_637_tele.cmas.language",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ }
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_ansi_637_extraneous_data,
+ { "ansi_637.extraneous_data", PI_PROTOCOL, PI_NOTE,
+ "Extraneous Data - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_short_data,
+ { "ansi_637.short_data", PI_PROTOCOL, PI_NOTE,
+ "Short Data (?) - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_unexpected_length,
+ { "ansi_637.unexpected_length", PI_PROTOCOL, PI_WARN,
+ "Unexpected Data Length - try checking decoder variant preference or dissector bug/later version spec (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_unknown_encoding,
+ { "ansi_637.unknown_format", PI_PROTOCOL, PI_NOTE,
+ "Encoding Unknown/Unsupported - (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_failed_conversion,
+ { "ansi_637.failed_conversion", PI_PROTOCOL, PI_WARN,
+ "Failed iconv conversion - (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_unknown_cmas_record_type,
+ { "ansi_637.unknown_cmas_record_type", PI_PROTOCOL, PI_WARN,
+ "Unknown CMAS record type - (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_unknown_trans_parameter,
+ { "ansi_637.unknown_trans_parameter", PI_PROTOCOL, PI_WARN,
+ "Unknown transport layer parameter - (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_no_trans_parameter_dissector,
+ { "ansi_637.no_trans_parameter_dissector", PI_PROTOCOL, PI_WARN,
+ "No transport layer parameter dissector - (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_unknown_tele_parameter,
+ { "ansi_637.unknown_tele_parameter", PI_PROTOCOL, PI_WARN,
+ "Unknown teleservice layer parameter - (report to wireshark.org)",
+ EXPFILL }
+ },
+ { &ei_ansi_637_no_tele_parameter_dissector,
+ { "ansi_637.no_tele_parameter_dissector", PI_PROTOCOL, PI_WARN,
+ "No teleservice layer parameter dissector - (report to wireshark.org)",
+ EXPFILL }
+ }
};
+ expert_module_t *expert_ansi_637;
+
/* Setup protocol subtree array */
-#define NUM_INDIVIDUAL_PARAMS 3
- gint *ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM];
+#define NUM_INDIVIDUAL_PARAMS 4
+ gint *ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM+NUM_CMAS_PARAM];
memset((void *) ett, 0, sizeof(ett));
ett[0] = &ett_ansi_637_tele;
ett[1] = &ett_ansi_637_trans;
- ett[2] = &ett_params;
+ ett[2] = &ett_ansi_637_header_ind;
+ ett[3] = &ett_params;
for (i=0; i < NUM_TELE_PARAM; i++)
{
@@ -2311,6 +3248,12 @@ proto_register_ansi_637(void)
ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+i] = &ett_ansi_637_trans_param[i];
}
+ for (i=0; i < NUM_CMAS_PARAM; i++)
+ {
+ ett_tia_1149_cmas_param[i] = -1;
+ ett[NUM_INDIVIDUAL_PARAMS+NUM_TELE_PARAM+NUM_TRANS_MSG_TYPE+NUM_TRANS_PARAM+i] = &ett_tia_1149_cmas_param[i];
+ }
+
/* Register the protocol name and description */
proto_ansi_637_tele =
proto_register_protocol(ansi_proto_name_tele, "ANSI IS-637-A Teleservice", "ansi_637_tele");
@@ -2326,6 +3269,10 @@ proto_register_ansi_637(void)
proto_register_field_array(proto_ansi_637_trans, hf_trans, array_length(hf_trans));
proto_register_subtree_array(ett, array_length(ett));
+ expert_ansi_637 =
+ expert_register_protocol(proto_ansi_637_trans);
+ expert_register_field_array(expert_ansi_637, ei, array_length(ei));
+
tele_dissector_table =
register_dissector_table("ansi_637.tele_id",
"ANSI IS-637-A Teleservice ID", FT_UINT8, BASE_DEC);
@@ -2341,7 +3288,8 @@ proto_reg_handoff_ansi_637(void)
ansi_637_trans_app_handle = create_dissector_handle(dissect_ansi_637_trans_app, proto_ansi_637_trans);
/* Dissect messages embedded in SIP */
- dissector_add_string("media_type","application/vnd.3gpp2.sms", ansi_637_trans_app_handle);
+ dissector_add_string("media_type", "application/vnd.3gpp2.sms", ansi_637_trans_app_handle);
+
/*
* register for all known teleservices
* '-1' is to stop before trailing '0' entry
@@ -2362,6 +3310,13 @@ proto_reg_handoff_ansi_637(void)
}
/*
+ * internal implementation add this pseudo teleservice ID for handling broadcast SMS
+ * (which don't have teleservice IDs)
+ */
+ dissector_add_uint("ansi_map.tele_id", INTERNAL_BROADCAST_TELE_ID, ansi_637_tele_handle);
+ dissector_add_uint("ansi_637.tele_id", INTERNAL_BROADCAST_TELE_ID, ansi_637_tele_handle);
+
+ /*
* ANSI A-interface will push out transport layer data
*/
dissector_add_uint("ansi_a.sms", 0, ansi_637_trans_handle);