summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-ansi_637.c
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2012-12-21 21:03:31 +0000
committerPascal Quantin <pascal.quantin@gmail.com>2012-12-21 21:03:31 +0000
commitd66d8c44d265aa575c5d97e76de5b5fcea8f5269 (patch)
treefb1f878bf21f2f989e1d67867198230d9d24d534 /epan/dissectors/packet-ansi_637.c
parentaae3c27307ae9b67d2a26da304a96e68e7a66324 (diff)
downloadwireshark-d66d8c44d265aa575c5d97e76de5b5fcea8f5269.tar.gz
Fix GSM 7-bit default alphabet decoding in ANSI IS-637-A
svn path=/trunk/; revision=46687
Diffstat (limited to 'epan/dissectors/packet-ansi_637.c')
-rw-r--r--epan/dissectors/packet-ansi_637.c138
1 files changed, 27 insertions, 111 deletions
diff --git a/epan/dissectors/packet-ansi_637.c b/epan/dissectors/packet-ansi_637.c
index 8a1eff4956..aaf817149f 100644
--- a/epan/dissectors/packet-ansi_637.c
+++ b/epan/dissectors/packet-ansi_637.c
@@ -36,6 +36,7 @@
#include <epan/emem.h>
#include <epan/strutil.h>
+#include "packet-gsm_sms.h"
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";
@@ -183,6 +184,7 @@ static int hf_ansi_637_tele_msg_id = -1;
static int hf_ansi_637_tele_msg_status = -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;
@@ -201,101 +203,6 @@ static packet_info *g_pinfo;
static proto_tree *g_tree;
/* FUNCTIONS */
-#define GN_CHAR_ALPHABET_SIZE 128
-
-#define GN_CHAR_ESCAPE 0x1b
-
-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,
- 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
- 0x394, '_', 0x3a6,0x393,0x39b,0x3a9,0x3a0,0x3a8,
- 0x3a3,0x398,0x39e, 0xa0, 0xc6, 0xe6, 0xdf, 0xc9,
- ' ', '!', '\"', '#', 0xa4, '%', '&', '\'',
- '(', ')', '*', '+', ',', '-', '.', '/',
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', ':', ';', '<', '=', '>', '?',
- 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
- 'X', 'Y', 'Z', 0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
- 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0
-};
-
-
-
-static gboolean
-char_is_escape(unsigned char value)
-{
- return (value == GN_CHAR_ESCAPE);
-}
-
-static gunichar
-char_def_alphabet_ext_decode(unsigned char value)
-{
- switch (value)
- {
- 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 gunichar
-char_def_alphabet_decode(unsigned char value)
-{
- if (value < GN_CHAR_ALPHABET_SIZE)
- {
- return gsm_default_alphabet[value];
- }
- else
- {
- return '?';
- }
-}
-
-static void
-gsm_sms_char_7bit_ascii_decode(unsigned char * dest, const unsigned char* src, int len)
-{
- int i, j;
- gunichar buf;
-
-
- for (i = 0, j = 0; j < len; j++)
- {
- if (char_is_escape(src[j])) {
- buf = char_def_alphabet_ext_decode(src[++j]);
- i += g_unichar_to_utf8(buf,&(dest[i]));
- }
- else {
- buf = char_def_alphabet_decode(src[j]);
- i += g_unichar_to_utf8(buf,&(dest[i]));
- }
- }
- dest[i]=0;
- return;
-}
-
-
-
-
static int
decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oct, guint8 *last_bit, gchar *buf)
@@ -661,9 +568,8 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
- proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
- "Encoded user data: %s",
- ansi_637_bigbuf);
+ proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, saved_offset,
+ offset - saved_offset, ansi_637_bigbuf);
switch (bit)
{
@@ -703,9 +609,9 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
out_len = decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
IA5_7BIT_decode(ia5_637_bigbuf, ansi_637_bigbuf, out_len);
- proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
- "Encoded user data: %s",
- ia5_637_bigbuf);
+ proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, saved_offset,
+ offset - saved_offset, ia5_637_bigbuf);
+
}
/*TODO UCS else if (encoding == 0x04)
{
@@ -726,7 +632,8 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb, offset, num_fields), num_fields , cd , NULL , NULL , &l_conv_error);
if(!l_conv_error)
{
- proto_tree_add_text(tree, tvb, offset, num_fields, "Encoded user data: %s", utf8_text);
+ proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, offset,
+ num_fields, utf8_text);
}
else
{
@@ -753,7 +660,8 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
utf8_text = g_convert_with_iconv(ansi_637_bigbuf , num_fields , cd , NULL , NULL , &l_conv_error);
if(!l_conv_error)
{
- proto_tree_add_text(tree, tvb, offset, num_fields, "Encoded user data: %s", utf8_text);
+ proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, offset,
+ num_fields, utf8_text);
}
else
{
@@ -778,16 +686,20 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset)
return;
}
- bit = 3;
- saved_offset = offset;
- out_len = decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf);
- gsm_sms_char_7bit_ascii_decode(gsm_637_bigbuf, ansi_637_bigbuf, out_len);
-
- proto_tree_add_text(tree, tvb, saved_offset, offset - saved_offset,
- "Encoded user data: %s",
- gsm_637_bigbuf);
+ saved_offset = offset - 1;
+ for (i=0; i < required_octs; i++)
+ {
+ oct = tvb_get_guint8(tvb, saved_offset);
+ oct2 = tvb_get_guint8(tvb, saved_offset + 1);
+ ansi_637_bigbuf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3);
+ saved_offset++;
+ }
+ out_len = gsm_sms_char_7bit_unpack(0, required_octs+1, num_fields, ansi_637_bigbuf, gsm_637_bigbuf);
+ gsm_637_bigbuf[out_len] = '\0';
+ proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, offset,
+ required_octs, gsm_sms_chars_to_utf8(gsm_637_bigbuf, num_fields));
}
else
{
@@ -2256,6 +2168,10 @@ proto_register_ansi_637(void)
{ "Teleservice Subparam ID", "ansi_637_tele.subparam_id",
FT_UINT8, BASE_DEC, VALS(ansi_tele_param_strings), 0,
NULL, HFILL }},
+ { &hf_ansi_637_tele_user_data_text,
+ { "Encoded user data", "ansi_637_tele.user_data.text",
+ FT_STRING, BASE_NONE, NULL, 0,
+ NULL, HFILL }},
};
/* Setup protocol subtree array */