* Technical realization of Short Message Service (SMS)
* (3GPP TS 23.040 version 5.4.0 Release 5)
*
+ * Header field support for TPDU Parameters added by
+ * Abhik Sarkar.
+ *
* $Id$
*
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
#include <string.h>
-#include "epan/packet.h"
+#include <epan/packet.h>
#include <epan/prefs.h>
+#include <epan/reassemble.h>
+#include <glib.h>
#include "packet-gsm_sms.h"
+#define MAX_SMS_FRAG_LEN 134
/* PROTOTYPES/FORWARDS */
static gint ett_ud = -1;
static gint ett_udh = -1;
+static gint ett_udh_tfm = -1;
+static gint ett_udh_tfc = -1;
+
/* Initialize the protocol and registered fields */
static int proto_gsm_sms = -1;
+static gint hf_gsm_sms_coding_group_bits2 = -1;
+static gint hf_gsm_sms_coding_group_bits4 = -1;
+static gint hf_gsm_sms_ud_multiple_messages_msg_id = -1;
+static gint hf_gsm_sms_ud_multiple_messages_msg_parts = -1;
+static gint hf_gsm_sms_ud_multiple_messages_msg_part = -1;
+
+/* TPDU Parameters */
+static gint hf_gsm_sms_tp_mti_up = -1;
+static gint hf_gsm_sms_tp_mti_down = -1;
+static gint hf_gsm_sms_tp_mms = -1;
+static gint hf_gsm_sms_tp_vpf = -1;
+static gint hf_gsm_sms_tp_sri = -1;
+static gint hf_gsm_sms_tp_srr = -1;
+static gint hf_gsm_sms_tp_mr = -1;
+static gint hf_gsm_sms_tp_oa = -1;
+static gint hf_gsm_sms_tp_da = -1;
+static gint hf_gsm_sms_tp_pid = -1;
+static gint hf_gsm_sms_tp_dcs = -1;
+static gint hf_gsm_sms_tp_ra = -1;
+static gint hf_gsm_sms_tp_rp = -1;
+static gint hf_gsm_sms_tp_udhi = -1;
+static gint hf_gsm_sms_tp_rd = -1;
+static gint hf_gsm_sms_tp_srq = -1;
+#if 0
+static gint hf_gsm_sms_tp_scts = -1;
+static gint hf_gsm_sms_tp_vp = -1;
+static gint hf_gsm_sms_tp_dt = -1;
+static gint hf_gsm_sms_tp_st = -1;
+static gint hf_gsm_sms_tp_udl = -1;
+static gint hf_gsm_sms_tp_mn = -1;
+static gint hf_gsm_sms_tp_ct = -1;
+static gint hf_gsm_sms_tp_cdl = -1;
+static gint hf_gsm_sms_tp_cd = -1;
+static gint hf_gsm_sms_tp_ud = -1;
+#endif
+
+static gboolean msg_udh_frag = FALSE;
static char bigbuf[1024];
-static dissector_handle_t data_handle;
static packet_info *g_pinfo;
static proto_tree *g_tree;
+/* 3GPP TS 23.038 version 7.0.0 Release 7
+ * The TP-Data-Coding-Scheme field, defined in 3GPP TS 23.040 [4],
+ * indicates the data coding scheme of the TP-UD field, and may indicate a message class.
+ * Any reserved codings shall be assumed to be the GSM 7 bit default alphabet
+ * (the same as codepoint 00000000) by a receiving entity.
+ * The octet is used according to a coding group which is indicated in bits 7..4.
+ */
+
+/* Coding Group Bits */
+static const value_string gsm_sms_coding_group_bits_vals[] = {
+ { 0, "General Data Coding indication" }, /* 00xx */
+ { 1, "General Data Coding indication" }, /* 00xx */
+ { 2, "General Data Coding indication" }, /* 00xx */
+ { 3, "General Data Coding indication" }, /* 00xx */
+ { 4, "Message Marked for Automatic Deletion Group" }, /* 01xx */
+ { 5, "Message Marked for Automatic Deletion Group" }, /* 01xx */
+ { 6, "Message Marked for Automatic Deletion Group" }, /* 01xx */
+ { 7, "Message Marked for Automatic Deletion Group" }, /* 01xx */
+ { 8, "Reserved coding groups" }, /* 1000..1011 */
+ { 9, "Reserved coding groups" }, /* 1000..1011 */
+ { 10, "Reserved coding groups" }, /* 1000..1011 */
+ { 11, "Reserved coding groups" }, /* 1000..1011 */
+ { 12, "Message Waiting Indication Group: Discard Message" },/* 1100 */
+ { 13, "Message Waiting Indication Group: Store Message" }, /* 1101 */
+ { 14, "Message Waiting Indication Group: Store Message" }, /* 1110 */
+ { 15, "Data coding/message class" }, /* 1111 */
+ { 0, NULL },
+};
+
+guint16 g_sm_id;
+guint16 g_frags;
+guint16 g_frag;
+
+guint16 g_port_src;
+guint16 g_port_dst;
+static gboolean g_is_wsp;
+
+static dissector_table_t gsm_sms_dissector_tbl;
+/* Short Message reassembly */
+static GHashTable *g_sm_fragment_table = NULL;
+static GHashTable *g_sm_reassembled_table = NULL;
+static gint ett_gsm_sms_ud_fragment = -1;
+static gint ett_gsm_sms_ud_fragments = -1;
+ /*
+ * Short Message fragment handling
+ */
+static int hf_gsm_sms_ud_fragments = -1;
+static int hf_gsm_sms_ud_fragment = -1;
+static int hf_gsm_sms_ud_fragment_overlap = -1;
+static int hf_gsm_sms_ud_fragment_overlap_conflicts = -1;
+static int hf_gsm_sms_ud_fragment_multiple_tails = -1;
+static int hf_gsm_sms_ud_fragment_too_long_fragment = -1;
+static int hf_gsm_sms_ud_fragment_error = -1;
+static int hf_gsm_sms_ud_reassembled_in = -1;
+
+static const fragment_items sm_frag_items = {
+ /* Fragment subtrees */
+ &ett_gsm_sms_ud_fragment,
+ &ett_gsm_sms_ud_fragments,
+ /* Fragment fields */
+ &hf_gsm_sms_ud_fragments,
+ &hf_gsm_sms_ud_fragment,
+ &hf_gsm_sms_ud_fragment_overlap,
+ &hf_gsm_sms_ud_fragment_overlap_conflicts,
+ &hf_gsm_sms_ud_fragment_multiple_tails,
+ &hf_gsm_sms_ud_fragment_too_long_fragment,
+ &hf_gsm_sms_ud_fragment_error,
+ /* Reassembled in field */
+ &hf_gsm_sms_ud_reassembled_in,
+ /* Tag */
+ "Short Message fragments"
+};
+
+
+static void
+gsm_sms_defragment_init (void)
+{
+ fragment_table_init (&g_sm_fragment_table);
+ reassembled_table_init(&g_sm_reassembled_table);
+}
+
/*
* this is the GSM 03.40 definition with the bit 2
* set to 1 for uplink messages
{ 0, NULL },
};
-#define NUM_UDH_IEIS 256
-static gint ett_udh_ieis[NUM_UDH_IEIS];
+static const value_string msg_type_strings_sc_to_ms[] = {
+ { 0, "SMS-DELIVER" },
+ { 1, "SMS-SUBMIT REPORT" },
+ { 2, "SMS-STATUS REPORT" },
+ { 3, "Reserved" },
+ { 0, NULL },
+};
-/* FUNCTIONS */
+static const value_string msg_type_strings_ms_to_sc[] = {
+ { 0, "SMS-DELIVER REPORT" },
+ { 1, "SMS-SUBMIT" },
+ { 2, "SMS-COMMAND" },
+ { 3, "Reserved" },
+ { 0, NULL },
+};
-/* 9.2.3.1 */
-#define DIS_FIELD_MTI(m_tree, m_bitmask, m_offset) \
-{ \
- other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
- proto_tree_add_text(m_tree, tvb, \
- m_offset, 1, \
- "%s : TP-Message-Type-Indicator", \
- bigbuf); \
-}
+static const value_string vp_type_strings[] = {
+ { 0, "TP VP field not present"},
+ { 1, "TP VP field present - relative format"},
+ { 2, "TP-VP field present - enhanced format"},
+ { 3, "TP VP field present - absolute format"},
+ { 0, NULL },
+};
-/* 9.2.3.2 */
-#define DIS_FIELD_MMS(m_tree, m_bitmask, m_offset) \
-{ \
- other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
- proto_tree_add_text(m_tree, tvb, \
- m_offset, 1, \
- "%s : TP-More-Messages-to-Send: %s messages are waiting for the MS in this SC", \
- bigbuf, \
- (oct & m_bitmask) ? "No more" : "More"); \
-}
+static const true_false_string mms_bool_strings = {
+ "No more messages are waiting for the MS in this SC",
+ "More messages are waiting for the MS in this SC"
+};
-/* 9.2.3.3 */
-#define DIS_FIELD_VPF(m_tree, m_bitmask, m_offset, m_form) \
-{ \
- SMS_SHIFTMASK(oct & m_bitmask, m_bitmask, *m_form); \
- switch (*m_form) \
- { \
- case 0: str = "TP-VP field not present"; break; \
- case 1: str = "TP-VP field present - enhanced format"; break; \
- case 2: str = "TP-VP field present - relative format"; break; \
- case 3: str = "TP-VP field present - absolute format"; break; \
- } \
- other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
- proto_tree_add_text(m_tree, tvb, \
- m_offset, 1, \
- "%s : TP-Validity-Period-Format: %s", \
- bigbuf, \
- str); \
-}
+static const true_false_string sri_bool_strings = {
+ "A status report shall be returned to the SME",
+ "A status report shall not be returned to the SME"
+};
-/* 9.2.3.4 */
-#define DIS_FIELD_SRI(m_tree, m_bitmask, m_offset) \
-{ \
- other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
- proto_tree_add_text(m_tree, tvb, \
- m_offset, 1, \
- "%s : TP-Status-Report-Indication: A status report shall %sbe returned to the SME", \
- bigbuf, \
- (oct & m_bitmask) ? "" : "not "); \
-}
+static const true_false_string srr_bool_strings = {
+ "A status report is requested",
+ "A status report is not requested"
+};
-/* 9.2.3.5 */
-#define DIS_FIELD_SRR(m_tree, m_bitmask, m_offset) \
-{ \
- other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
- proto_tree_add_text(m_tree, tvb, \
- m_offset, 1, \
- "%s : TP-Status-Report-Request: A status report is %srequested", \
- bigbuf, \
- (oct & m_bitmask) ? "" : "not "); \
-}
+static const true_false_string udhi_bool_strings = {
+ "The beginning of the TP UD field contains a Header in addition to the short message",
+ "The TP UD field contains only the short message"
+};
-/* 9.2.3.6 */
-#define DIS_FIELD_MR(m_tree, m_offset) \
-{ \
- proto_tree_add_text(m_tree, tvb, \
- m_offset, 1, \
- "TP-Message-Reference %d", \
- oct); \
-}
+static const true_false_string rp_bool_strings = {
+ "TP Reply Path parameter is set in this SMS SUBMIT/DELIVER",
+ "TP Reply Path parameter is not set in this SMS SUBMIT/DELIVER"
+};
+
+static const true_false_string rd_bool_strings = {
+ "Instruct SC to reject duplicates",
+ "Instruct SC to accept duplicates"
+};
+
+static const true_false_string srq_bool_strings = {
+ "The SMS STATUS REPORT is the result of an SMS COMMAND e.g. an Enquiry.",
+ "SMS STATUS REPORT is the result of a SMS SUBMIT."
+};
+
+#define NUM_UDH_IEIS 256
+static gint ett_udh_ieis[NUM_UDH_IEIS];
+#define MAX_ADDR_SIZE 20
static void
dis_field_addr(tvbuff_t *tvb, proto_tree *tree, guint32 *offset_p, const gchar *title)
{
guint32 numdigocts;
guint32 length;
guint32 i, j;
+ char addrbuf[MAX_ADDR_SIZE+1];
+ gchar *addrstr;
offset = *offset_p;
return;
}
- item =
- proto_tree_add_text(tree, tvb,
- offset, numdigocts + 2,
+ item = proto_tree_add_text(tree, tvb,
+ offset, numdigocts + 2, "%s",
title);
subtree = proto_item_add_subtree(item, ett_addr);
switch ((oct & 0x70) >> 4)
{
case 0x05: /* "Alphanumeric (coded according to 3GPP TS 23.038 GSM 7-bit default alphabet)" */
- i = gsm_sms_char_7bit_unpack(0, numdigocts, sizeof(bigbuf), tvb_get_ptr(tvb, offset, numdigocts), bigbuf);
- bigbuf[i] = '\0';
- gsm_sms_char_ascii_decode(bigbuf, bigbuf, i);
+ i = gsm_sms_char_7bit_unpack(0, numdigocts, MAX_ADDR_SIZE, tvb_get_ptr(tvb, offset, numdigocts), addrbuf);
+ addrbuf[i] = '\0';
+ addrstr = gsm_sms_chars_to_utf8(addrbuf, i);
break;
default:
+ addrstr = ep_alloc(numdigocts*2 + 1);
for (i = 0; i < numdigocts; i++)
{
oct = tvb_get_guint8(tvb, offset + i);
- bigbuf[j++] = digit_table[oct & 0x0f];
- bigbuf[j++] = digit_table[(oct & 0xf0) >> 4];
+ addrstr[j++] = digit_table[oct & 0x0f];
+ addrstr[j++] = digit_table[(oct & 0xf0) >> 4];
}
- bigbuf[j++] = '\0';
+ addrstr[j++] = '\0';
break;
}
- proto_tree_add_text(subtree,
+ if (g_ascii_strncasecmp(title, "TP-O", 4) == 0) {
+ proto_tree_add_string(subtree, hf_gsm_sms_tp_oa, tvb,
+ offset, numdigocts, addrstr);
+ } else if (g_ascii_strncasecmp(title, "TP-D", 4) == 0) {
+ proto_tree_add_string(subtree, hf_gsm_sms_tp_da, tvb,
+ offset, numdigocts, addrstr);
+ } else if (g_ascii_strncasecmp(title, "TP-R", 4) == 0) {
+ proto_tree_add_string(subtree, hf_gsm_sms_tp_ra, tvb,
+ offset, numdigocts, addrstr);
+ } else {
+ proto_tree_add_text(subtree,
tvb, offset, numdigocts,
"Digits: %s",
- bigbuf);
+ addrstr);
+ }
- proto_item_append_text(item, " - (%s)", bigbuf);
+ proto_item_append_text(item, " - (%s)", addrstr);
*offset_p = offset + numdigocts;
}
item =
- proto_tree_add_text(tree, tvb,
- offset, 1,
- "TP-Protocol-Identifier");
+ proto_tree_add_item(tree, hf_gsm_sms_tp_pid, tvb,
+ offset, 1, FALSE);
subtree = proto_item_add_subtree(item, ett_pid);
*compressed = FALSE;
item =
- proto_tree_add_text(tree, tvb,
- offset, 1,
- "TP-Data-Coding-Scheme (%d)",
- oct);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_dcs, tvb,
+ offset, 1, FALSE);
subtree = proto_item_add_subtree(item, ett_dcs);
+ if(oct&0x80){
+ proto_tree_add_item(subtree, hf_gsm_sms_coding_group_bits4, tvb, offset, 1, FALSE);
+ }else{
+ proto_tree_add_item(subtree, hf_gsm_sms_coding_group_bits2, tvb, offset, 1, FALSE);
+ }
if (oct == 0x00)
{
case 0x00: str = "GSM 7 bit default alphabet";
*seven_bit = TRUE;
break;
- case 0x01: str = "8 bit data"; break;
+ case 0x01: str = "8 bit data";
+ *eight_bit = TRUE;
+ break;
case 0x02: str = "UCS2 (16 bit)";
*ucs2 = TRUE;
break;
}
proto_tree_add_text(subtree, tvb,
- offset, 1,
+ offset, 1, "%s",
str);
}
}
}
- return out_num - output;
+ return (int)(out_num - output);
}
#define GN_CHAR_ALPHABET_SIZE 128
#define GN_CHAR_ESCAPE 0x1b
-static unsigned char gsm_default_alphabet[GN_CHAR_ALPHABET_SIZE] = {
+static gunichar gsm_default_alphabet[GN_CHAR_ALPHABET_SIZE] = {
/* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
+ /* Fixed to use unicode */
/* Characters in hex position 10, [12 to 1a] and 24 are not present on
latin1 charset, so we cannot reproduce on the screen, however they are
greek symbol not present even on my Nokia */
- '@', 0xa3, '$', 0xa5, 0xe8, 0xe9, 0xf9, 0xec,
+ '@', 0xa3, '$' , 0xa5, 0xe8, 0xe9, 0xf9, 0xec,
0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
- '?', '_', '?', '?', '?', '?', '?', '?',
- '?', '?', '?', '?', 0xc6, 0xe6, 0xdf, 0xc9,
+ 0x394, '_', 0x3a6,0x393,0x39b,0x3a9,0x3a0,0x3a8,
+ 0x3a3,0x398,0x39e, 0xa0, 0xc6, 0xe6, 0xdf, 0xc9,
' ', '!', '\"', '#', 0xa4, '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
return (value == GN_CHAR_ESCAPE);
}
-static unsigned char
+static gunichar
char_def_alphabet_ext_decode(unsigned char value)
{
switch (value)
{
- case 0x0a: return 0x0c; break; /* form feed */
- case 0x14: return '^'; break;
- case 0x28: return '{'; break;
- case 0x29: return '}'; break;
- case 0x2f: return '\\'; break;
- case 0x3c: return '['; break;
- case 0x3d: return '~'; break;
- case 0x3e: return ']'; break;
- case 0x40: return '|'; break;
- case 0x65: return 0xa4; break; /* euro */
- default: return '?'; break; /* invalid character */
+ case 0x0a: return 0x0c; /* form feed */
+ case 0x14: return '^';
+ case 0x28: return '{';
+ case 0x29: return '}';
+ case 0x2f: return '\\';
+ case 0x3c: return '[';
+ case 0x3d: return '~';
+ case 0x3e: return ']';
+ case 0x40: return '|';
+ case 0x65: return 0x20ac; /* euro */
+ default: return '?'; /* invalid character */
}
}
-static unsigned char
+static gunichar
char_def_alphabet_decode(unsigned char value)
{
if (value < GN_CHAR_ALPHABET_SIZE)
}
}
-void
-gsm_sms_char_ascii_decode(unsigned char* dest, const unsigned char* src, int len)
+gchar *
+gsm_sms_chars_to_utf8(const unsigned char* src, int len)
{
- int i, j;
+ gint outlen, i, j;
+ gunichar c;
+ gchar *outbuf;
+
+ /* Scan the input string to see how long the output string will be */
+ for (outlen = 0, j = 0; j < len; j++)
+ {
+ if (char_is_escape(src[j])) {
+ j++;
+ if (j == len)
+ c = '?'; /* escape with nothing following it - error */
+ else
+ c = char_def_alphabet_ext_decode(src[j]);
+ }
+ else
+ c = char_def_alphabet_decode(src[j]);
+ outlen += g_unichar_to_utf8(c,NULL);
+ }
- for (i = 0, j = 0; j < len; i++, j++)
+ /* Now allocate a buffer for the output string and fill it in */
+ outbuf = ep_alloc(outlen + 1);
+ for (i = 0, j = 0; j < len; j++)
{
- if (char_is_escape(src[j]))
- dest[i] = char_def_alphabet_ext_decode(src[++j]);
+ if (char_is_escape(src[j])) {
+ j++;
+ if (j == len)
+ c = '?'; /* escape with nothing following it - error */
+ else
+ c = char_def_alphabet_ext_decode(src[j]);
+ }
else
- dest[i] = char_def_alphabet_decode(src[j]);
+ c = char_def_alphabet_decode(src[j]);
+ i += g_unichar_to_utf8(c,&(outbuf[i]));
}
- dest[i] = 0;
- return;
+ outbuf[i] = '\0';
+ return outbuf;
}
/*
* END FROM GNOKII
*/
+/* 9.2.3.24.1 */
+static void
+dis_iei_csm8(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ EXACT_DATA_CHECK(length, 3);
+ oct = tvb_get_guint8(tvb, offset);
+ g_sm_id = oct;
+ proto_tree_add_uint (tree,
+ hf_gsm_sms_ud_multiple_messages_msg_id,
+ tvb, offset, 1, g_sm_id);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+ g_frags = oct;
+ proto_tree_add_uint (tree,
+ hf_gsm_sms_ud_multiple_messages_msg_parts,
+ tvb , offset , 1, g_frags);
+ offset++;
+ oct = tvb_get_guint8(tvb, offset);
+ g_frag = oct;
+ proto_tree_add_uint (tree,
+ hf_gsm_sms_ud_multiple_messages_msg_part,
+ tvb, offset, 1, g_frag);
+
+}
+
+/* TODO 9.2.3.24.2 Special SMS Message Indication */
+
+/* 9.2.3.24.3 */
static void
dis_iei_apa_8bit(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
{
EXACT_DATA_CHECK(length, 2);
oct = tvb_get_guint8(tvb, offset);
-
+ g_port_dst = oct;
if (oct < 240)
{
str = "Reserved";
offset++;
oct = tvb_get_guint8(tvb, offset);
-
+ g_port_src = oct;
if (oct < 240)
{
str = "Reserved";
str);
}
+/* 9.2.3.24.4 */
static void
dis_iei_apa_16bit(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
{
EXACT_DATA_CHECK(length, 4);
value = tvb_get_ntohs(tvb, offset);
-
+ g_port_dst = value;
if (value < 16000)
{
str = "As allocated by IANA (http://www.IANA.com/)";
offset += 2;
value = tvb_get_ntohs(tvb, offset);
-
+ g_port_src = value;
if (value < 16000)
{
str = "As allocated by IANA (http://www.IANA.com/)";
"Originator port: %d, %s",
value,
str);
+
+ g_is_wsp = 1;
}
+/* 9.2.3.24.5 */
static void
-dis_field_ud_iei(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+dis_iei_scp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
{
- void (*iei_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length);
guint8 oct;
- proto_item *item;
- proto_tree *subtree = NULL;
- const gchar *str = NULL;
- guint8 iei_len;
-
- while (length > 2)
- {
- iei_fcn = NULL;
+ EXACT_DATA_CHECK(length, 1);
oct = tvb_get_guint8(tvb, offset);
- switch (oct)
+ if (oct & 0x01)
{
- case 0x00: str = "Concatenated short messages, 8-bit reference number (SMS Control)"; break;
- case 0x01: str = "Special SMS Message Indication (SMS Control)"; break;
- case 0x02: str = "Reserved N/A"; break;
- case 0x03: str = "Value not used to avoid misinterpretation as <LF> character N/A"; break;
- case 0x04: str = "Application port addressing scheme, 8 bit address (SMS Control)"; iei_fcn = dis_iei_apa_8bit; break;
- case 0x05: str = "Application port addressing scheme, 16 bit address (SMS Control)"; iei_fcn = dis_iei_apa_16bit; break;
- case 0x06: str = "SMSC Control Parameters (SMS Control)"; break;
- case 0x07: str = "UDH Source Indicator (SMS Control)"; break;
- case 0x08: str = "Concatenated short message, 16-bit reference number (SMS Control)"; break;
- case 0x09: str = "Wireless Control Message Protocol (SMS Control)"; break;
- case 0x0A: str = "Text Formatting (EMS Control)"; break;
- case 0x0B: str = "Predefined Sound (EMS Content)"; break;
- case 0x0C: str = "User Defined Sound (iMelody max 128 bytes) (EMS Content)"; break;
- case 0x0D: str = "Predefined Animation (EMS Content)"; break;
- case 0x0E: str = "Large Animation (16*16 times 4 = 32*4 =128 bytes) (EMS Content)"; break;
- case 0x0F: str = "Small Animation (8*8 times 4 = 8*4 =32 bytes) (EMS Content)"; break;
- case 0x10: str = "Large Picture (32*32 = 128 bytes) (EMS Content)"; break;
- case 0x11: str = "Small Picture (16*16 = 32 bytes) (EMS Content)"; break;
- case 0x12: str = "Variable Picture (EMS Content)"; break;
- case 0x13: str = "User prompt indicator (EMS Control)"; break;
- case 0x14: str = "Extended Object (EMS Content)"; break;
- case 0x15: str = "Reused Extended Object (EMS Control)"; break;
- case 0x16: str = "Compression Control (EMS Control)"; break;
- case 0x17: str = "Object Distribution Indicator (EMS Control)"; break;
- case 0x18: str = "Standard WVG object (EMS Content)"; break;
- case 0x19: str = "Character Size WVG object (EMS Content)"; break;
- case 0x1A: str = "Extended Object Data Request Command (EMS Control)"; break;
- case 0x20: str = "RFC 822 E-Mail Header (SMS Control)"; break;
- case 0x21: str = "Hyperlink format element (SMS Control)"; break;
- case 0x22: str = "Reply Address Element (SMS Control)"; break;
- default:
- if ((oct >= 0x1b) &&
- (oct <= 0x1f))
- {
- str = "Reserved for future EMS features (see subclause 3.10) N/A"; break;
- }
- else if ((oct >= 0x23) &&
- (oct <= 0x6f))
- {
- str = "Reserved for future use N/A"; break;
- }
- else if ((oct >= 0x70) &&
- (oct <= 0x7f))
- {
- str = "(U)SIM Toolkit Security Headers (SMS Control)"; break;
- }
- else if ((oct >= 0x80) &&
- (oct <= 0x9f))
- {
- str = "SME to SME specific use (SMS Control)"; break;
- }
- else if ((oct >= 0xa0) &&
- (oct <= 0xbf))
- {
- str = "Reserved for future use N/A"; break;
- }
- else if ((oct >= 0xc0) &&
- (oct <= 0xdf))
- {
- str = "SC specific use (SMS Control)"; break;
- }
- else
- {
- str = "Reserved for future use N/A"; break;
- }
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Status Report for short message transaction completed");
+ }
+ else
+ {
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "No Status Report for short message transaction completed");
}
- iei_len = tvb_get_guint8(tvb, offset + 1);
+ if (oct & 0x02)
+ {
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Status Report for permanent error when SC is not making any more transfer attempts");
+ }
+ else
+ {
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "No Status Report for permanent error when SC is not making any more transfer attempts");
+ }
- item =
- proto_tree_add_text(tree,
- tvb, offset, iei_len + 2,
- "IE: %s",
- str);
+ if (oct & 0x04)
+ {
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Status Report for temporary error when SC is not making any more transfer attempts");
+ }
+ else
+ {
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "No Status Report for temporary error when SC is not making any more transfer attempts");
+ }
- subtree = proto_item_add_subtree(item, ett_udh_ieis[oct]);
+ if (oct & 0x08)
+ {
- proto_tree_add_text(subtree,
- tvb, offset, 1,
- "Information Element Identifier: %d",
- oct);
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Status Report for temporary error when SC is still trying to transfer SM");
+ }
+ else
+ {
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "No Status Report for temporary error when SC is still trying to transfer SM");
+ }
- offset++;
+ if (oct & 0x40)
+ {
- proto_tree_add_text(subtree,
- tvb, offset, 1,
- "Length: %d",
- iei_len);
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "A Status Report generated by this Short Message, due to a permanent error or last temporary error, cancels the SRR of the rest of the Short Messages in a concatenated message");
+ }
+ else
+ {
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "No activation");
+ }
- offset++;
+ if (oct & 0x80)
+ {
- if (iei_len > 0)
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Include original UDH into the Status Report");
+ }
+ else
{
- if (iei_fcn == NULL)
- {
- proto_tree_add_text(subtree,
- tvb, offset, iei_len,
- "IE Data");
- }
- else
- {
- iei_fcn(tvb, subtree, offset, iei_len);
- }
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Do not include original UDH into the Status Report");
}
- length -= 2 + iei_len;
- offset += iei_len;
- }
}
-/* 9.2.3.24 */
-#define NUM_FILL_BITS_MASKS 6
+/* 9.2.3.24.6 */
static void
-dis_field_ud(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 length, gboolean udhi, guint8 udl,
- gboolean seven_bit, gboolean eight_bit, gboolean ucs2, gboolean compressed)
+dis_iei_udh_si(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ EXACT_DATA_CHECK(length, 1);
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ switch (oct)
+ {
+ case 1:
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "The following part of the UDH is created by the original sender (valid in case of Status Report)");
+ break;
+ case 2:
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "The following part of the UDH is created by the original receiver (valid in case of Status Report)");
+ break;
+ case 3:
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "The following part of the UDH is created by the SMSC (can occur in any message or report)");
+ break;
+ default:
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "The following part of the UDH is created by %d" , oct);
+ break;
+ }
+}
+/* 9.2.3.24.8 */
+static void
+dis_iei_csm16(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+ guint16 oct_ref;
+
+ EXACT_DATA_CHECK(length, 4);
+ oct_ref = tvb_get_ntohs(tvb, offset);
+ g_sm_id = oct_ref;
+ proto_tree_add_uint (tree,
+ hf_gsm_sms_ud_multiple_messages_msg_id,
+ tvb, offset, 2, g_sm_id);
+ offset+=2;
+ oct = tvb_get_guint8(tvb, offset);
+ g_frags = oct;
+ proto_tree_add_uint (tree,
+ hf_gsm_sms_ud_multiple_messages_msg_parts,
+ tvb , offset , 1, g_frags);
+
+ offset++;
+ oct = tvb_get_guint8(tvb, offset);
+ g_frag = oct;
+ proto_tree_add_uint (tree,
+ hf_gsm_sms_ud_multiple_messages_msg_part,
+ tvb, offset, 1, g_frag);
+}
+
+/* 9.2.3.24.10.1.1 */
+static void
+dis_iei_tf(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ const gchar *str = NULL;
+ guint8 oct;
+ proto_item *item;
+ proto_item *item_colour;
+ proto_tree *subtree = NULL;
+ proto_tree *subtree_colour = NULL;
+
+
+ EXACT_DATA_CHECK(length, 4);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Start position of the text formatting: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Text formatting length: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ item =
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "formatting mode");
+
+ subtree = proto_item_add_subtree(item, ett_udh_tfm);
+ switch(oct & 0x03)
+ {
+ case 0x00:
+ str = "Left";
+ break;
+ case 0x01:
+ str = "Center";
+ break;
+ case 0x02:
+ str = "Right";
+ break;
+ case 0x03:
+ str = "Language dependent";
+ break;
+ }
+
+ proto_tree_add_text(subtree,
+ tvb, offset, 1,
+ "Alignment : %d %s",
+ oct & 0x03 , str);
+
+ switch((oct >> 2) & 0x03)
+ {
+ case 0x00:
+ str = "Normal";
+ break;
+ case 0x01:
+ str = "Large";
+ break;
+ case 0x02:
+ str = "Small";
+ break;
+ case 0x03:
+ str = "reserved";
+ break;
+ }
+
+ proto_tree_add_text(subtree,
+ tvb, offset, 1,
+ "Font Size : %d %s",
+ (oct >> 2) & 0x03 , str);
+
+ if(oct & 0x10)
+ str = "on";
+ else
+ str = "off";
+ proto_tree_add_text(subtree,
+ tvb, offset, 1,
+ "Style bold : %d %s",
+ oct & 0x10 , str);
+
+ if(oct & 0x20)
+ str = "on";
+ else
+ str = "off";
+ proto_tree_add_text(subtree,
+ tvb, offset, 1,
+ "Style Italic : %d %s",
+ oct & 0x20 , str);
+
+ if(oct & 0x40)
+ str = "on";
+ else
+ str = "off";
+ proto_tree_add_text(subtree,
+ tvb, offset, 1,
+ "Style Underlined : %d %s",
+ oct & 0x40 , str);
+
+ if(oct & 0x80)
+ str = "on";
+ else
+ str = "off";
+ proto_tree_add_text(subtree,
+ tvb, offset, 1,
+ "Style Strikethrough : %d %s",
+ oct & 0x80 , str);
+
+ offset++;
+ oct = tvb_get_guint8(tvb, offset);
+ item_colour =
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Text Colour");
+
+ subtree_colour = proto_item_add_subtree(item_colour, ett_udh_tfc);
+ switch(oct & 0x0f)
+ {
+ case 0x00:
+ str = "Dark Grey";
+ break;
+ case 0x01:
+ str = "Dark Red";
+ break;
+ str = "Dark Yellow";
+ break;
+ str = "Dark Green";
+ break;
+ str = "Dark Cyan";
+ break;
+ str = "Dark Blue";
+ break;
+ str = "Dark Magenta";
+ break;
+ str = "Grey";
+ break;
+ str = "White";
+ break;
+ str = "Bright Red";
+ break;
+ str = "Bright Yellow";
+ break;
+ str = "Bright Green";
+ break;
+ str = "Bright Cyan";
+ break;
+ str = "Bright Blue";
+ break;
+ str = "Bright Magenta";
+ break;
+ }
+
+ proto_tree_add_text(subtree_colour,
+ tvb, offset, 1,
+ "Foreground Colour : %d %s",
+ oct & 0x0f , str);
+
+ switch((oct >> 4) & 0x0f)
+ {
+ case 0x00:
+ str = "Dark Grey";
+ break;
+ case 0x01:
+ str = "Dark Red";
+ break;
+ str = "Dark Yellow";
+ break;
+ str = "Dark Green";
+ break;
+ str = "Dark Cyan";
+ break;
+ str = "Dark Blue";
+ break;
+ str = "Dark Magenta";
+ break;
+ str = "Grey";
+ break;
+ str = "White";
+ break;
+ str = "Bright Red";
+ break;
+ str = "Bright Yellow";
+ break;
+ str = "Bright Green";
+ break;
+ str = "Bright Cyan";
+ break;
+ str = "Bright Blue";
+ break;
+ str = "Bright Magenta";
+ break;
+ }
+
+ proto_tree_add_text(subtree_colour,
+ tvb, offset, 1,
+ "Background Colour : %d %s",
+ (oct >> 4) & 0x0f , str);
+
+}
+
+
+/* 9.2.3.24.10.1.2 */
+static void
+dis_iei_ps(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ EXACT_DATA_CHECK(length, 2);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "position: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "sound number: %d",
+ oct);
+}
+
+/* 9.2.3.24.10.1.3 */
+static void
+dis_iei_uds(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ SHORT_DATA_CHECK(length, 2);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "position: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, length - 1,
+ "User Defined Sound ");
+}
+
+
+/* 9.2.3.24.10.1.4 */
+static void
+dis_iei_pa(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ EXACT_DATA_CHECK(length, 2);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "position: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "animation number: %d",
+ oct);
+}
+
+
+/* 9.2.3.24.10.1.5 */
+static void
+dis_iei_la(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ SHORT_DATA_CHECK(length, 2);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "position: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, length - 1,
+ "Large Animation ");
+}
+
+/* 9.2.3.24.10.1.6 */
+static void
+dis_iei_sa(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ SHORT_DATA_CHECK(length, 2);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "position: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, length - 1,
+ "Small Animation ");
+}
+
+
+/* 9.2.3.24.10.1.7 */
+static void
+dis_iei_lp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ SHORT_DATA_CHECK(length, 2);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "position: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, length - 1,
+ "Large Picture ");
+}
+
+/* 9.2.3.24.10.1.8 */
+static void
+dis_iei_sp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ SHORT_DATA_CHECK(length, 2);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "position: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, length - 1,
+ "Small Picture ");
+}
+
+
+/* 9.2.3.24.10.1.9 */
+static void
+dis_iei_vp(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ SHORT_DATA_CHECK(length, 4);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "position: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Horizontal dimension: %d",
+ oct);
+ offset++;
+
+ oct = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Vertical dimension: %d",
+ oct);
+ offset++;
+
+
+ oct = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(tree,
+ tvb, offset, length - 3,
+ "Variable Picture ");
+}
+
+/* 9.2.3.24.10.1.10 */
+static void
+dis_iei_upi(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ guint8 oct;
+
+ EXACT_DATA_CHECK(length, 1);
+ oct = tvb_get_guint8(tvb, offset);
+
+ proto_tree_add_text(tree,
+ tvb, offset, 1,
+ "Number of corresponding objects: %d",
+ oct);
+ offset++;
+}
+
+
+/* */
+
+
+static void
+dis_field_ud_iei(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length)
+{
+ void (*iei_fcn)(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint8 length);
+ guint8 oct;
+ proto_item *item;
+ proto_tree *subtree = NULL;
+ const gchar *str = NULL;
+ guint8 iei_len;
+
+
+ while (length >= 2)
+ {
+ iei_fcn = NULL;
+
+ oct = tvb_get_guint8(tvb, offset);
+
+ switch (oct)
+ {
+ case 0x00: str = "Concatenated short messages, 8-bit reference number (SMS Control)"; iei_fcn = dis_iei_csm8; break;
+ case 0x01: str = "Special SMS Message Indication (SMS Control)"; break;
+ case 0x02: str = "Reserved N/A"; break;
+ case 0x03: str = "Value not used to avoid misinterpretation as <LF> character N/A"; break;
+ case 0x04: str = "Application port addressing scheme, 8 bit address (SMS Control)"; iei_fcn = dis_iei_apa_8bit; break;
+ case 0x05: str = "Application port addressing scheme, 16 bit address (SMS Control)"; iei_fcn = dis_iei_apa_16bit; break;
+ case 0x06: str = "SMSC Control Parameters (SMS Control)"; iei_fcn = dis_iei_scp; break;
+ case 0x07: str = "UDH Source Indicator (SMS Control)"; iei_fcn = dis_iei_udh_si; break;
+ case 0x08: str = "Concatenated short message, 16-bit reference number (SMS Control)"; iei_fcn = dis_iei_csm16; break;
+ case 0x09: str = "Wireless Control Message Protocol (SMS Control)"; break;
+ case 0x0A: str = "Text Formatting (EMS Control)"; iei_fcn = dis_iei_tf;
+ case 0x0B: str = "Predefined Sound (EMS Content)"; iei_fcn = dis_iei_ps;break;
+ case 0x0C: str = "User Defined Sound (iMelody max 128 bytes) (EMS Content)"; iei_fcn = dis_iei_uds;break;
+ case 0x0D: str = "Predefined Animation (EMS Content)"; iei_fcn = dis_iei_pa;break;
+ case 0x0E: str = "Large Animation (16*16 times 4 = 32*4 =128 bytes) (EMS Content)"; iei_fcn = dis_iei_la;break;
+ case 0x0F: str = "Small Animation (8*8 times 4 = 8*4 =32 bytes) (EMS Content)"; iei_fcn = dis_iei_sa;break;
+ case 0x10: str = "Large Picture (32*32 = 128 bytes) (EMS Content)"; iei_fcn = dis_iei_lp;break;
+ case 0x11: str = "Small Picture (16*16 = 32 bytes) (EMS Content)"; iei_fcn = dis_iei_sp;break;
+ case 0x12: str = "Variable Picture (EMS Content)"; iei_fcn = dis_iei_vp;break;
+ case 0x13: str = "User prompt indicator (EMS Control)"; iei_fcn = dis_iei_upi;break;
+ case 0x14: str = "Extended Object (EMS Content)"; break;
+ case 0x15: str = "Reused Extended Object (EMS Control)"; break;
+ case 0x16: str = "Compression Control (EMS Control)"; break;
+ case 0x17: str = "Object Distribution Indicator (EMS Control)"; break;
+ case 0x18: str = "Standard WVG object (EMS Content)"; break;
+ case 0x19: str = "Character Size WVG object (EMS Content)"; break;
+ case 0x1A: str = "Extended Object Data Request Command (EMS Control)"; break;
+ case 0x20: str = "RFC 822 E-Mail Header (SMS Control)"; break;
+ case 0x21: str = "Hyperlink format element (SMS Control)"; break;
+ case 0x22: str = "Reply Address Element (SMS Control)"; break;
+ default:
+ if ((oct >= 0x1b) &&
+ (oct <= 0x1f))
+ {
+ str = "Reserved for future EMS features (see subclause 3.10) N/A"; break;
+ }
+ else if ((oct >= 0x23) &&
+ (oct <= 0x6f))
+ {
+ str = "Reserved for future use N/A"; break;
+ }
+ else if ((oct >= 0x70) &&
+ (oct <= 0x7f))
+ {
+ str = "(U)SIM Toolkit Security Headers (SMS Control)"; break;
+ }
+ else if ((oct >= 0x80) &&
+ (oct <= 0x9f))
+ {
+ str = "SME to SME specific use (SMS Control)"; break;
+ }
+ else if ((oct >= 0xa0) &&
+ (oct <= 0xbf))
+ {
+ str = "Reserved for future use N/A"; break;
+ }
+ else if ((oct >= 0xc0) &&
+ (oct <= 0xdf))
+ {
+ str = "SC specific use (SMS Control)"; break;
+ }
+ else
+ {
+ str = "Reserved for future use N/A"; break;
+ }
+ }
+
+ iei_len = tvb_get_guint8(tvb, offset + 1);
+
+ item =
+ proto_tree_add_text(tree,
+ tvb, offset, iei_len + 2,
+ "IE: %s",
+ str);
+
+ subtree = proto_item_add_subtree(item, ett_udh_ieis[oct]);
+
+ proto_tree_add_text(subtree,
+ tvb, offset, 1,
+ "Information Element Identifier: %d",
+ oct);
+
+ offset++;
+
+ proto_tree_add_text(subtree,
+ tvb, offset, 1,
+ "Length: %d",
+ iei_len);
+
+ offset++;
+
+ if (iei_len > 0)
+ {
+ if (iei_fcn == NULL)
+ {
+ proto_tree_add_text(subtree,
+ tvb, offset, iei_len,
+ "IE Data");
+ }
+ else
+ {
+ iei_fcn(tvb, subtree, offset, iei_len);
+ }
+ }
+
+ length -= 2 + iei_len;
+ offset += iei_len;
+ }
+}
+
+/* 9.2.3.24 */
+#define NUM_FILL_BITS_MASKS 6
+#define SMS_MAX_MESSAGE_SIZE 160
+char messagebuf[SMS_MAX_MESSAGE_SIZE+1];
+static void
+dis_field_ud(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 length, gboolean udhi, guint8 udl,
+ gboolean seven_bit, gboolean eight_bit, gboolean ucs2, gboolean compressed)
{
static guint8 fill_bits_mask[NUM_FILL_BITS_MASKS] =
{ 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc };
proto_item *udh_item;
proto_tree *subtree = NULL;
proto_tree *udh_subtree = NULL;
+ tvbuff_t *sm_tvb = NULL;
+ fragment_data *fd_sm = NULL;
guint8 oct;
guint fill_bits;
- guint32 out_len;
+ guint32 out_len , total_sms_len , len_sms , length_ucs2 , i;
char *ustr;
-
+ proto_item *ucs2_item;
+ gchar *utf8_text = NULL;
+ gchar save_byte = 0 , save_byte2 = 0;
+ GIConv cd;
+ GError *l_conv_error = NULL;
+
+ gboolean reassembled = FALSE;
+ guint32 reassembled_in = 0;
+ gboolean is_fragmented = FALSE;
+ gboolean save_fragmented = FALSE, try_gsm_sms_ud_reassemble = FALSE;
+ guint32 num_labels , save_offset;
fill_bits = 0;
item =
proto_tree_add_text(tree, tvb,
offset, length,
"TP-User-Data");
-
+ save_offset = offset;
subtree = proto_item_add_subtree(item, ett_ud);
oct = tvb_get_guint8(tvb, offset);
}
}
+ if (g_frags > 1)
+ is_fragmented = TRUE;
+
+ if ( is_fragmented )
+ {
+ try_gsm_sms_ud_reassemble = TRUE;
+ save_fragmented = g_pinfo->fragmented;
+ g_pinfo->fragmented = TRUE;
+ fd_sm = fragment_add_seq_check (tvb, offset, g_pinfo,
+ g_sm_id, /* guint32 ID for fragments belonging together */
+ g_sm_fragment_table, /* list of message fragments */
+ g_sm_reassembled_table, /* list of reassembled messages */
+ g_frag-1, /* guint32 fragment sequence number */
+ length, /* guint32 fragment length */
+ (g_frag != g_frags)); /* More fragments? */
+ if (fd_sm)
+ {
+ reassembled = TRUE;
+ reassembled_in = fd_sm->reassembled_in;
+ }
+
+ sm_tvb = process_reassembled_data(tvb, offset, g_pinfo,
+ "Reassembled Short Message", fd_sm, &sm_frag_items,
+ NULL, tree);
+ if (reassembled)
+ {
+ /* Reassembled */
+ col_append_str (g_pinfo->cinfo, COL_INFO,
+ " (Short Message Reassembled)");
+ }
+ else
+ {
+ /* Not last packet of reassembled Short Message */
+ if (check_col (g_pinfo->cinfo, COL_INFO))
+ col_append_fstr (g_pinfo->cinfo, COL_INFO,
+ " (Short Message fragment %u of %u)", g_frag, g_frags);
+ }
+ } /* Else: not fragmented */
+ if (! sm_tvb) /* One single Short Message, or not reassembled */
+ sm_tvb = tvb_new_subset_remaining (tvb, offset);
+
if (compressed)
{
proto_tree_add_text(subtree, tvb,
}
else
{
- if (seven_bit)
+ if ((reassembled && g_pinfo->fd->num == reassembled_in) || g_frag==0 || ((g_frag != 0 && msg_udh_frag)))
{
- out_len =
- gsm_sms_char_7bit_unpack(fill_bits, length, sizeof(bigbuf),
- tvb_get_ptr(tvb, offset, length), bigbuf);
- bigbuf[out_len] = '\0';
- gsm_sms_char_ascii_decode(bigbuf, bigbuf, out_len);
- bigbuf[udl] = '\0';
-
- proto_tree_add_text(subtree, tvb, offset, length, "%s", bigbuf);
- }
- else if (eight_bit)
+ if (seven_bit)
{
- proto_tree_add_text(subtree, tvb, offset, length, "%s",
- tvb_format_text(tvb, offset, length));
- }
- else if (ucs2)
+ if(msg_udh_frag || g_frag == 0 )
+ {
+ out_len =
+ gsm_sms_char_7bit_unpack(fill_bits, length , SMS_MAX_MESSAGE_SIZE,
+ tvb_get_ptr(tvb , offset , length) , messagebuf);
+ messagebuf[out_len] = '\0';
+ proto_tree_add_text(subtree, tvb , offset , length , "%s",
+ gsm_sms_chars_to_utf8(messagebuf, out_len));
+ }
+ else
+ {
+ out_len = 0;
+
+ total_sms_len = sm_tvb->length;
+ for(i = 0 ; i<g_frags; i++)
+ {
+ /* maximum len msg in 7 bit with csm8 header*/
+ if(total_sms_len > MAX_SMS_FRAG_LEN)
+ {
+ total_sms_len -= MAX_SMS_FRAG_LEN;
+ len_sms = MAX_SMS_FRAG_LEN;
+ }
+ else
+ len_sms = total_sms_len;
+ out_len =
+ gsm_sms_char_7bit_unpack(fill_bits, len_sms , SMS_MAX_MESSAGE_SIZE,
+ tvb_get_ptr(sm_tvb , i * MAX_SMS_FRAG_LEN , len_sms) , messagebuf);
+
+ messagebuf[out_len] = '\0';
+ proto_tree_add_text(subtree, sm_tvb , i * MAX_SMS_FRAG_LEN , len_sms , "%s",
+ gsm_sms_chars_to_utf8(messagebuf, out_len));
+ }
+ }
+ }
+ else if (eight_bit)
+ {
+ /*proto_tree_add_text(subtree, tvb , offset , length, "%s",
+ tvb_format_text(tvb, offset, length)); */
+ if (! dissector_try_port(gsm_sms_dissector_tbl, g_port_src, sm_tvb, g_pinfo, subtree))
+ {
+ if (! dissector_try_port(gsm_sms_dissector_tbl, g_port_dst,sm_tvb, g_pinfo, subtree))
+ {
+ if (subtree)
+ { /* Only display if needed */
+ proto_tree_add_text (subtree, sm_tvb, 0, -1,
+ "Short Message body");
+ }
+ }
+ }
+ }
+ else if (ucs2)
{
- /* tvb_get_ephemeral_faked_unicode takes the lengt in number of guint16's */
- ustr = tvb_get_ephemeral_faked_unicode(tvb, offset, (length>>1), FALSE);
- proto_tree_add_text(subtree, tvb, offset, length, "%s", ustr);
+ if ((cd = g_iconv_open("UTF-8","UCS-2BE")) != (GIConv)-1)
+ {
+ if(msg_udh_frag || g_frag == 0 )
+ {
+ utf8_text = g_convert_with_iconv(sm_tvb->real_data, sm_tvb->reported_length , cd , NULL , NULL , &l_conv_error);
+ if(!l_conv_error){
+ ucs2_item = proto_tree_add_text(subtree, tvb, offset, length, "%s", utf8_text);
+ }else{
+ ucs2_item = proto_tree_add_text(subtree, tvb, offset, length, "%s", "Failed on UCS2 contact wireshark developers");
+ }
+ PROTO_ITEM_SET_GENERATED(ucs2_item);
+ }
+ else
+ {
+ utf8_text = g_convert_with_iconv(sm_tvb->real_data, sm_tvb->reported_length , cd , NULL , NULL , &l_conv_error);
+ if(!l_conv_error)
+ {
+ len_sms = (int)strlen(utf8_text);
+ num_labels = len_sms / MAX_SMS_FRAG_LEN;
+ num_labels += len_sms % MAX_SMS_FRAG_LEN ? 1 : 0;
+ for(i = 0; i < num_labels;i++)
+ {
+ if(i * MAX_SMS_FRAG_LEN < len_sms)
+ {
+ /* set '\0' to byte number 134 text_node MAX size*/
+ save_byte = utf8_text[i * MAX_SMS_FRAG_LEN];
+ save_byte2 = utf8_text[i * MAX_SMS_FRAG_LEN + 1];
+ if(i > 0)
+ {
+ utf8_text[i * MAX_SMS_FRAG_LEN] = '\0';
+ utf8_text[i * MAX_SMS_FRAG_LEN + 1] = '\0';
+ }
+
+ length_ucs2 = MAX_SMS_FRAG_LEN;
+ }
+ else
+ length_ucs2 = len_sms % MAX_SMS_FRAG_LEN;
+
+ ucs2_item = proto_tree_add_text(subtree, sm_tvb , i * MAX_SMS_FRAG_LEN , length_ucs2 , "%s", &utf8_text[i * MAX_SMS_FRAG_LEN]);
+ /* return the save byte to utf8 buffer*/
+ if(i * MAX_SMS_FRAG_LEN < len_sms)
+ {
+ utf8_text[i * MAX_SMS_FRAG_LEN] = save_byte;
+ utf8_text[i * MAX_SMS_FRAG_LEN + 1] = save_byte2;
+ }
+ }
+ }else{
+ ucs2_item = proto_tree_add_text(subtree, tvb, offset, length, "%s", "Failed on UCS2 contact wireshark developers");
+ }
+ }
+
+ g_free(utf8_text);
+ g_iconv_close(cd);
+ }
+ else
+ {
+ /* tvb_get_ephemeral_faked_unicode takes the lengt in number of guint16's */
+ ustr = tvb_get_ephemeral_faked_unicode(tvb, offset, (length>>1), FALSE);
+ proto_tree_add_text(subtree, tvb, offset, length, "%s", ustr);
+ }
+ }
}
}
-}
-/* 9.2.3.25 */
-#define DIS_FIELD_RD(m_tree, m_bitmask, m_offset) \
-{ \
- other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
- proto_tree_add_text(m_tree, tvb, \
- m_offset, 1, \
- "%s : TP-Reject-Duplicates: Instruct SC to %s duplicates", \
- bigbuf, \
- (oct & m_bitmask) ? \
- "reject" : \
- "accept"); \
-}
-
-/* 9.2.3.26 */
-#define DIS_FIELD_SRQ(m_tree, m_bitmask, m_offset) \
-{ \
- other_decode_bitfield_value(bigbuf, oct, m_bitmask, 8); \
- proto_tree_add_text(m_tree, tvb, \
- m_offset, 1, \
- "%s : TP-Status-Report-Qualifier: The SMS-STATUS-REPORT is the result of %s", \
- bigbuf, \
- (oct & m_bitmask) ? \
- "an SMS-COMMAND e.g. an Enquiry" : \
- "a SMS-SUBMIT"); \
+ if (try_gsm_sms_ud_reassemble) /* Clean up defragmentation */
+ g_pinfo->fragmented = save_fragmented;
}
/* 9.2.3.27 */
length = tvb_length_remaining(tvb, offset);
oct = tvb_get_guint8(tvb, offset);
+ udhi = oct & 0x40;
- DIS_FIELD_RP(tree, 0x80, offset);
-
- DIS_FIELD_UDHI(tree, 0x40, offset, udhi);
-
- DIS_FIELD_SRI(tree, 0x20, offset);
-
- DIS_FIELD_MMS(tree, 0x04, offset);
-
- DIS_FIELD_MTI(tree, 0x03, offset);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_rp, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_udhi, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_sri, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mms, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mti_down, tvb, offset, 1, FALSE);
offset++;
guint8 oct;
guint8 pi;
guint8 udl;
- gboolean seven_bit;
- gboolean eight_bit;
- gboolean ucs2;
- gboolean compressed;
+ gboolean seven_bit = FALSE;
+ gboolean eight_bit = FALSE;
+ gboolean ucs2 = FALSE;
+ gboolean compressed = FALSE;
gboolean udhi;
length = tvb_length_remaining(tvb, offset);
oct = tvb_get_guint8(tvb, offset);
+ udhi = oct & 0x40;
- DIS_FIELD_UDHI(tree, 0x40, offset, udhi);
-
- DIS_FIELD_MMS(tree, 0x04, offset); /* Bit 2 */
- DIS_FIELD_MTI(tree, 0x03, offset); /* Bit 0 and 1 */
+ proto_tree_add_item(tree, hf_gsm_sms_tp_udhi, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mms, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mti_up, tvb, offset, 1, FALSE);
if (length < 2)
{
guint8 oct;
guint8 vp_form;
guint8 udl;
- const gchar *str = NULL;
gboolean seven_bit;
gboolean eight_bit;
gboolean ucs2;
length = tvb_length_remaining(tvb, offset);
oct = tvb_get_guint8(tvb, offset);
+ udhi = oct & 0x40;
+ vp_form = ((oct & 0x18) >> 3);
- DIS_FIELD_RP(tree, 0x80, offset);
-
- DIS_FIELD_UDHI(tree, 0x40, offset, udhi);
-
- DIS_FIELD_SRR(tree, 0x20, offset);
-
- DIS_FIELD_VPF(tree, 0x18, offset, &vp_form);
-
- DIS_FIELD_RD(tree, 0x04, offset);
-
- DIS_FIELD_MTI(tree, 0x03, offset);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_rp, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_udhi, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_srr, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_vpf, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_rd, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mti_up, tvb, offset, 1, FALSE);
offset++;
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_MR(tree, offset);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mr, tvb, offset, 1, FALSE);
offset++;
guint8 oct;
guint8 pi;
guint8 udl;
- gboolean seven_bit;
- gboolean eight_bit;
- gboolean ucs2;
- gboolean compressed;
+ gboolean seven_bit = FALSE;
+ gboolean eight_bit = FALSE;
+ gboolean ucs2 = FALSE;
+ gboolean compressed = FALSE;
gboolean udhi;
length = tvb_length_remaining(tvb, offset);
oct = tvb_get_guint8(tvb, offset);
-
- DIS_FIELD_UDHI(tree, 0x40, offset, udhi);
-
- DIS_FIELD_MTI(tree, 0x03, offset);
+ udhi = oct & 0x40;
+
+ proto_tree_add_item(tree, hf_gsm_sms_tp_udhi, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mti_down, tvb, offset, 1, FALSE);
/*
* there does not seem to be a way to determine that this
guint8 oct;
guint8 pi;
guint8 udl;
- gboolean seven_bit;
- gboolean eight_bit;
- gboolean ucs2;
- gboolean compressed;
- gboolean udhi;
+ gboolean seven_bit = FALSE;
+ gboolean eight_bit = FALSE;
+ gboolean ucs2 = FALSE;
+ gboolean compressed = FALSE;
+ gboolean udhi;
udl = 0;
length = tvb_length_remaining(tvb, offset);
oct = tvb_get_guint8(tvb, offset);
+ udhi = oct & 0x40;
- DIS_FIELD_UDHI(tree, 0x40, offset, udhi);
-
- DIS_FIELD_SRQ(tree, 0x20, offset);
-
- DIS_FIELD_MMS(tree, 0x04, offset);
-
- DIS_FIELD_MTI(tree, 0x03, offset);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_udhi, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_srq, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mms, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mti_down, tvb, offset, 1, FALSE);
offset++;
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_MR(tree, offset);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mr, tvb, offset, 1, FALSE);
offset++;
length = tvb_length_remaining(tvb, offset);
oct = tvb_get_guint8(tvb, offset);
+ udhi = oct & 0x40;
- DIS_FIELD_UDHI(tree, 0x40, offset, udhi);
-
- DIS_FIELD_SRR(tree, 0x20, offset);
-
- DIS_FIELD_MTI(tree, 0x03, offset);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_udhi, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_srr, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mti_up, tvb, offset, 1, FALSE);
offset++;
oct = tvb_get_guint8(tvb, offset);
- DIS_FIELD_MR(tree, offset);
+ proto_tree_add_item(tree, hf_gsm_sms_tp_mr, tvb, offset, 1, FALSE);
offset++;
oct = tvb_get_guint8(tvb, offset);
gint idx;
const gchar *str = NULL;
gint ett_msg_idx;
-
+
g_pinfo = pinfo;
+ g_is_wsp = 0;
+ g_sm_id = 0;
+ g_frags = 0;
+ g_frag = 0;
+ g_port_src = 0;
+ g_port_dst = 0;
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- {
- col_set_str(pinfo->cinfo, COL_PROTOCOL, gsm_sms_proto_name_short);
- }
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, gsm_sms_proto_name_short);
/* In the interest of speed, if "tree" is NULL, don't do any work not
* necessary to generate protocol tree items.
}
-/* Register the protocol with Ethereal */
+/* Register the protocol with Wireshark */
void
proto_register_gsm_sms(void)
{
guint i;
guint last_offset;
+ module_t *gsm_sms_module; /* Preferences for GSM SMS UD */
-#if 0
/* Setup list of header fields */
static hf_register_info hf[] =
{
+ { &hf_gsm_sms_coding_group_bits2,
+ { "Coding Group Bits", "gsm_sms.coding_group_bits2",
+ FT_UINT8, BASE_DEC, VALS(gsm_sms_coding_group_bits_vals), 0xc0,
+ NULL, HFILL }
+ },
+ { &hf_gsm_sms_coding_group_bits4,
+ { "Coding Group Bits", "gsm_sms.coding_group_bits4",
+ FT_UINT8, BASE_DEC, VALS(gsm_sms_coding_group_bits_vals), 0xf0,
+ NULL, HFILL }
+ },
+
+ /*
+ * Short Message fragment reassembly
+ */
+ { &hf_gsm_sms_ud_fragments,
+ { "Short Message fragments", "gsm-sms-ud.fragments",
+ FT_NONE, BASE_NONE, NULL, 0x00,
+ "GSM Short Message fragments",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_fragment,
+ { "Short Message fragment", "gsm-sms-ud.fragment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00,
+ "GSM Short Message fragment",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_fragment_overlap,
+ { "Short Message fragment overlap", "gsm-sms-ud.fragment.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "GSM Short Message fragment overlaps with other fragment(s)",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_fragment_overlap_conflicts,
+ { "Short Message fragment overlapping with conflicting data",
+ "gsm-sms-ud.fragment.overlap.conflicts",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "GSM Short Message fragment overlaps with conflicting data",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_fragment_multiple_tails,
+ { "Short Message has multiple tail fragments",
+ "gsm-sms-ud.fragment.multiple_tails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "GSM Short Message fragment has multiple tail fragments",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_fragment_too_long_fragment,
+ { "Short Message fragment too long",
+ "gsm-sms-ud.fragment.too_long_fragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "GSM Short Message fragment data goes beyond the packet end",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_fragment_error,
+ { "Short Message defragmentation error", "gsm-sms-ud.fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00,
+ "GSM Short Message defragmentation error due to illegal fragments",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_reassembled_in,
+ { "Reassembled in",
+ "gsm-sms-ud.reassembled.in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00,
+ "GSM Short Message has been reassembled in this packet.", HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_multiple_messages_msg_id,
+ { "Message identifier", "gsm-sms.udh.mm.msg_id",
+ FT_UINT16, BASE_DEC, NULL, 0x00,
+ "Identification of the message",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_multiple_messages_msg_parts,
+ { "Message parts", "gsm-sms.udh.mm.msg_parts",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Total number of message parts (fragments)",
+ HFILL
+ }
+ },
+ { &hf_gsm_sms_ud_multiple_messages_msg_part,
+ { "Message part number", "gsm-sms.udh.mm.msg_part",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "Message part (fragment) sequence number",
+ HFILL
+ }
+ },
+ /* TPDU parameters */
+ { &hf_gsm_sms_tp_mti_up,
+ { "TP-MTI", "gsm_sms.tp-mti",
+ FT_UINT8, BASE_DEC, VALS(msg_type_strings_ms_to_sc), 0x03,
+ "TP-Message-Type-Indicator (in the direction MS to SC)", HFILL }
+ },
+ { &hf_gsm_sms_tp_mti_down,
+ { "TP-MTI", "gsm_sms.tp-mti",
+ FT_UINT8, BASE_DEC, VALS(msg_type_strings_sc_to_ms), 0x03,
+ "TP-Message-Type-Indicator (in the direction SC to MS)", HFILL }
+ },
+ { &hf_gsm_sms_tp_oa,
+ { "TP-OA Digits", "gsm_sms.tp-oa",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "TP-Originating-Address Digits", HFILL }
+ },
+ { &hf_gsm_sms_tp_da,
+ { "TP-DA Digits", "gsm_sms.tp-da",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "TP-Destination-Address Digits", HFILL }
+ },
+ { &hf_gsm_sms_tp_ra,
+ { "TP-RA Digits", "gsm_sms.tp-ra",
+ FT_STRING, BASE_NONE, NULL, 0x00,
+ "TP-Recipient-Address Digits", HFILL }
+ },
+ { &hf_gsm_sms_tp_pid,
+ { "TP-PID", "gsm_sms.tp-pid",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "TP-Protocol-Identifier", HFILL }
+ },
+ { &hf_gsm_sms_tp_dcs,
+ { "TP-DCS", "gsm_sms.tp-dcs",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "TP-Data-Coding-Scheme", HFILL }
+ },
+ { &hf_gsm_sms_tp_mr,
+ { "TP-MR", "gsm_sms.tp-mr",
+ FT_UINT8, BASE_DEC, NULL, 0x00,
+ "TP-Message-Reference", HFILL }
+ },
+ { &hf_gsm_sms_tp_mms,
+ { "TP-MMS", "gsm_sms.tp-mms",
+ FT_BOOLEAN, 8, TFS(&mms_bool_strings), 0x04,
+ "TP-More-Messages-to-Send", HFILL }
+ },
+ { &hf_gsm_sms_tp_sri,
+ { "TP-SRI", "gsm_sms.tp-sri",
+ FT_BOOLEAN, 8, TFS(&sri_bool_strings), 0x20,
+ "TP-Status-Report-Indication", HFILL }
+ },
+ { &hf_gsm_sms_tp_srr,
+ { "TP-SRR", "gsm_sms.tp-srr",
+ FT_BOOLEAN, 8, TFS(&srr_bool_strings), 0x20,
+ "TP-Status-Report-Request", HFILL }
+ },
+ { &hf_gsm_sms_tp_udhi,
+ { "TP-UDHI", "gsm_sms.tp-udhi",
+ FT_BOOLEAN, 8, TFS(&udhi_bool_strings), 0x40,
+ "TP-User-Data-Header-Indicator", HFILL }
+ },
+ { &hf_gsm_sms_tp_rp,
+ { "TP-RP", "gsm_sms.tp-rp",
+ FT_BOOLEAN, 8, TFS(&rp_bool_strings), 0x80,
+ "TP-Reply-Path", HFILL }
+ },
+ { &hf_gsm_sms_tp_vpf,
+ { "TP-VPF", "gsm_sms.tp-vpf",
+ FT_UINT8, BASE_DEC, VALS(vp_type_strings), 0x18,
+ "TP-Validity-Period-Format", HFILL }
+ },
+ { &hf_gsm_sms_tp_rd,
+ { "TP-RD", "gsm_sms.tp-rd",
+ FT_BOOLEAN, 8, TFS(&rd_bool_strings), 0x04,
+ "TP-Reject-Duplicates", HFILL }
+ },
+ { &hf_gsm_sms_tp_srq,
+ { "TP-SRQ", "gsm_sms.tp-srq",
+ FT_BOOLEAN, 8, TFS(&srq_bool_strings), 0x20,
+ "TP-Status-Report-Qualifier", HFILL }
+ },
};
-#endif
/* Setup protocol subtree array */
#define NUM_INDIVIDUAL_PARMS 12
- static gint *ett[NUM_INDIVIDUAL_PARMS+NUM_MSGS+NUM_UDH_IEIS];
+ gint *ett[NUM_INDIVIDUAL_PARMS+NUM_MSGS+NUM_UDH_IEIS+2];
ett[0] = &ett_gsm_sms;
ett[1] = &ett_pid;
ett[last_offset] = &ett_udh_ieis[i];
}
+ ett[last_offset++] = &ett_gsm_sms_ud_fragment;
+ ett[last_offset] = &ett_gsm_sms_ud_fragments;
+
/* Register the protocol name and description */
proto_gsm_sms =
proto_register_protocol(gsm_sms_proto_name, gsm_sms_proto_name_short, "gsm_sms");
-#if 0
+
proto_register_field_array(proto_gsm_sms, hf, array_length(hf));
-#endif
proto_register_subtree_array(ett, array_length(ett));
+
+ gsm_sms_dissector_tbl = register_dissector_table("gsm-sms.udh.port",
+ "GSM SMS port IE in UDH", FT_UINT16, BASE_DEC);
+
+ gsm_sms_module = prefs_register_protocol (proto_gsm_sms, NULL);
+ prefs_register_bool_preference (gsm_sms_module,
+ "try_dissect_message_fragment",
+ "Always try subdissection of the fragment of a fragmented",
+ "Always try subdissection of 7bit, UCS2 Short Message fragment."
+ "If checked, every msg decode will shown in its fragment",
+ &msg_udh_frag);
+
+ /* register_dissector("gsm-sms", dissect_gsm_sms, proto_gsm_sms); */
+
+ /* GSM SMS UD dissector initialization routines */
+ register_init_routine (gsm_sms_defragment_init);
}
dissector_add("gsm_a.sms_tpdu", 0, gsm_sms_handle);
dissector_add("gsm_map.sms_tpdu", 0, gsm_sms_handle);
-
- data_handle = find_dissector("data");
}