From d66d8c44d265aa575c5d97e76de5b5fcea8f5269 Mon Sep 17 00:00:00 2001 From: Pascal Quantin Date: Fri, 21 Dec 2012 21:03:31 +0000 Subject: Fix GSM 7-bit default alphabet decoding in ANSI IS-637-A svn path=/trunk/; revision=46687 --- epan/dissectors/packet-ansi_637.c | 138 ++++++++------------------------------ 1 file changed, 27 insertions(+), 111 deletions(-) (limited to 'epan/dissectors/packet-ansi_637.c') 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 #include +#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 */ -- cgit v1.2.1