diff options
author | Guy Harris <guy@alum.mit.edu> | 2013-12-24 00:20:09 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2013-12-24 00:20:09 +0000 |
commit | 0d7a48a8bfb2b9f954d0f6b37172bb28e0239a92 (patch) | |
tree | 1ed37fc09109411f1581cc5ae34a32b28a5d80cc | |
parent | 57c6542aaf3e0c60a46dd60f9d0c6a814928bc8d (diff) |
Add a ENC_3GPP_TS_23_038 encoding, for the standard SMS alphabet in a
bit-packed string, and use it in some places.
svn path=/trunk/; revision=54428
-rw-r--r-- | asn1/gsm_map/gsm_map.cnf | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-etsi_card_app_toolkit.c | 10 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_map.c | 46 | ||||
-rw-r--r-- | epan/dissectors/packet-mbim.c | 26 | ||||
-rw-r--r-- | epan/proto.h | 19 | ||||
-rw-r--r-- | epan/tvbuff.c | 175 |
6 files changed, 214 insertions, 70 deletions
diff --git a/asn1/gsm_map/gsm_map.cnf b/asn1/gsm_map/gsm_map.cnf index e74dac9b61..6a49fb7320 100644 --- a/asn1/gsm_map/gsm_map.cnf +++ b/asn1/gsm_map/gsm_map.cnf @@ -508,13 +508,7 @@ actx->pinfo->p2p_dir = P2P_DIR_RECV; switch(sms_encoding){ case SMS_ENCODING_7BIT: case SMS_ENCODING_7BIT_LANG: - out_len = gsm_sms_char_7bit_unpack(0, length, sizeof(msgbuf), - tvb_get_ptr(parameter_tvb, 0, length), - msgbuf); - - msgbuf[out_len] = '\0'; - utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len); - proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %%s", utf8_text); + proto_tree_add_text(tree, parameter_tvb , 0, length, "USSD String: %%s", tvb_get_string_enc(wmem_packet_scope(), parameter_tvb, 0, length, ENC_3GPP_TS_23_038|ENC_NA)); break; case SMS_ENCODING_8BIT: /* XXX - ASCII, or some extended ASCII? */ diff --git a/epan/dissectors/packet-etsi_card_app_toolkit.c b/epan/dissectors/packet-etsi_card_app_toolkit.c index a4ba641ef5..2270d6e1bc 100644 --- a/epan/dissectors/packet-etsi_card_app_toolkit.c +++ b/epan/dissectors/packet-etsi_card_app_toolkit.c @@ -1065,15 +1065,7 @@ dissect_cat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) } switch (g8) { case 0x00: /* 7bit */ - { - int out_len; - unsigned char msgbuf[300]; - - out_len = gsm_sms_char_7bit_unpack(0, len-1, sizeof(msgbuf), tvb_get_ptr(tvb, pos+1, len-1), msgbuf); - msgbuf[out_len] = '\0'; - proto_tree_add_string(elem_tree, hf_ctlv_text_string, tvb, pos+1, - len-1, gsm_sms_chars_to_utf8(msgbuf, out_len)); - } + proto_tree_add_item(elem_tree, hf_ctlv_text_string, tvb, pos+1, len-1, ENC_3GPP_TS_23_038|ENC_NA); break; case 0x04: /* 8bit */ /* XXX - ASCII, or some extended ASCII? */ diff --git a/epan/dissectors/packet-gsm_map.c b/epan/dissectors/packet-gsm_map.c index bf44cae516..cb39c895be 100644 --- a/epan/dissectors/packet-gsm_map.c +++ b/epan/dissectors/packet-gsm_map.c @@ -3546,7 +3546,7 @@ static const ber_sequence_t gsm_map_ExternalSignalInfo_sequence[] = { int dissect_gsm_map_ExternalSignalInfo(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 764 "../../asn1/gsm_map/gsm_map.cnf" +#line 758 "../../asn1/gsm_map/gsm_map.cnf" /* -- Information about the internal structure is given in -- clause 7.6.9. @@ -3762,7 +3762,7 @@ dissect_gsm_map_AlertingPattern(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, in int dissect_gsm_map_GSN_Address(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 589 "../../asn1/gsm_map/gsm_map.cnf" +#line 583 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; guint8 octet; @@ -3913,7 +3913,7 @@ dissect_gsm_map_HLR_List(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offse int dissect_gsm_map_GlobalCellId(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 844 "../../asn1/gsm_map/gsm_map.cnf" +#line 838 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; proto_tree *subtree; @@ -4190,7 +4190,7 @@ dissect_gsm_map_TA_Id(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _ int dissect_gsm_map_RAIdentity(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 613 "../../asn1/gsm_map/gsm_map.cnf" +#line 607 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; proto_tree *subtree; @@ -4238,7 +4238,7 @@ dissect_gsm_map_CellGlobalIdOrServiceAreaIdFixedLength(gboolean implicit_tag _U_ int dissect_gsm_map_LAIFixedLength(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 625 "../../asn1/gsm_map/gsm_map.cnf" +#line 619 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; proto_tree *subtree; @@ -4531,7 +4531,7 @@ dissect_gsm_map_ss_ForwardingOptions(gboolean implicit_tag _U_, tvbuff_t *tvb _U offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, NULL); -#line 532 "../../asn1/gsm_map/gsm_map.cnf" +#line 526 "../../asn1/gsm_map/gsm_map.cnf" proto_tree_add_item(tree, hf_gsm_map_notification_to_forwarding_party, tvb, 0,1,ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_gsm_map_redirecting_presentation, tvb, 0,1,ENC_BIG_ENDIAN); @@ -4897,13 +4897,7 @@ dissect_gsm_map_ss_USSD_String(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int switch(sms_encoding){ case SMS_ENCODING_7BIT: case SMS_ENCODING_7BIT_LANG: - out_len = gsm_sms_char_7bit_unpack(0, length, sizeof(msgbuf), - tvb_get_ptr(parameter_tvb, 0, length), - msgbuf); - - msgbuf[out_len] = '\0'; - utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len); - proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %s", utf8_text); + proto_tree_add_text(tree, parameter_tvb , 0, length, "USSD String: %s", tvb_get_string_enc(wmem_packet_scope(), parameter_tvb, 0, length, ENC_3GPP_TS_23_038|ENC_NA)); break; case SMS_ENCODING_8BIT: /* XXX - ASCII, or some extended ASCII? */ @@ -8479,7 +8473,7 @@ dissect_gsm_map_ms_SGSN_Capability(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, static int dissect_gsm_map_ms_APN(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 878 "../../asn1/gsm_map/gsm_map.cnf" +#line 872 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; proto_tree *subtree; int length, name_len, tmp; @@ -8726,7 +8720,7 @@ dissect_gsm_map_ms_UpdateGprsLocationRes(gboolean implicit_tag _U_, tvbuff_t *tv static int dissect_gsm_map_ms_IntegrityProtectionInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 661 "../../asn1/gsm_map/gsm_map.cnf" +#line 655 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; asn1_ctx_t asn1_ctx; @@ -8749,7 +8743,7 @@ dissect_gsm_map_ms_IntegrityProtectionInformation(gboolean implicit_tag _U_, tvb static int dissect_gsm_map_ms_EncryptionInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 673 "../../asn1/gsm_map/gsm_map.cnf" +#line 667 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; asn1_ctx_t asn1_ctx; @@ -8834,7 +8828,7 @@ dissect_gsm_map_ms_AllowedUMTS_Algorithms(gboolean implicit_tag _U_, tvbuff_t *t static int dissect_gsm_map_ms_RadioResourceInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 637 "../../asn1/gsm_map/gsm_map.cnf" +#line 631 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; proto_tree *subtree; @@ -8905,7 +8899,7 @@ dissect_gsm_map_ms_BSSMAP_ServiceHandover(gboolean implicit_tag _U_, tvbuff_t *t static int dissect_gsm_map_ms_RANAP_ServiceHandover(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 649 "../../asn1/gsm_map/gsm_map.cnf" +#line 643 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; asn1_ctx_t asn1_ctx; @@ -9851,7 +9845,7 @@ static int dissect_gsm_map_ms_T_forwardingOptions(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { offset = dissect_gsm_map_ms_Ext_ForwOptions(implicit_tag, tvb, offset, actx, tree, hf_index); -#line 538 "../../asn1/gsm_map/gsm_map.cnf" +#line 532 "../../asn1/gsm_map/gsm_map.cnf" proto_tree_add_item(tree, hf_gsm_map_notification_to_forwarding_party, tvb, 0,1,ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_gsm_map_redirecting_presentation, tvb, 0,1,ENC_BIG_ENDIAN); @@ -11014,7 +11008,7 @@ dissect_gsm_map_ms_VlrCamelSubscriptionInfo(gboolean implicit_tag _U_, tvbuff_t static int dissect_gsm_map_ms_PDP_Type(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 546 "../../asn1/gsm_map/gsm_map.cnf" +#line 540 "../../asn1/gsm_map/gsm_map.cnf" guint8 pdp_type_org; tvbuff_t *parameter_tvb; @@ -11047,7 +11041,7 @@ dissect_gsm_map_ms_PDP_Type(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int of int dissect_gsm_map_ms_QoS_Subscribed(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 568 "../../asn1/gsm_map/gsm_map.cnf" +#line 562 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; @@ -11069,7 +11063,7 @@ dissect_gsm_map_ms_QoS_Subscribed(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int dissect_gsm_map_ms_Ext_QoS_Subscribed(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 579 "../../asn1/gsm_map/gsm_map.cnf" +#line 573 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; @@ -12572,7 +12566,7 @@ dissect_gsm_map_ms_GeographicalInformation(gboolean implicit_tag _U_, tvbuff_t * static int dissect_gsm_map_ms_LocationNumber(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 905 "../../asn1/gsm_map/gsm_map.cnf" +#line 899 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; proto_tree *subtree; const char *digit_str; @@ -15423,7 +15417,7 @@ dissect_gsm_map_lcs_ProvideSubscriberLocation_Arg(gboolean implicit_tag _U_, tvb int dissect_gsm_map_lcs_Ext_GeographicalInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 856 "../../asn1/gsm_map/gsm_map.cnf" +#line 850 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; proto_tree *subtree; @@ -16849,7 +16843,7 @@ static const ber_sequence_t gsm_old_Bss_APDU_sequence[] = { static int dissect_gsm_old_Bss_APDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 686 "../../asn1/gsm_map/gsm_map.cnf" +#line 680 "../../asn1/gsm_map/gsm_map.cnf" guint8 octet; guint8 length; tvbuff_t *next_tvb; @@ -18396,7 +18390,7 @@ dissect_gsm_ss_LCS_PeriodicLocationCancellationArg(gboolean implicit_tag _U_, tv static int dissect_gsm_map_ericsson_T_locationInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { -#line 934 "../../asn1/gsm_map/gsm_map.cnf" +#line 928 "../../asn1/gsm_map/gsm_map.cnf" tvbuff_t *parameter_tvb; proto_tree *subtree; guint8 rat; diff --git a/epan/dissectors/packet-mbim.c b/epan/dissectors/packet-mbim.c index 2addee5300..b1a6ec1963 100644 --- a/epan/dissectors/packet-mbim.c +++ b/epan/dissectors/packet-mbim.c @@ -3069,10 +3069,8 @@ mbim_dissect_set_ussd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint proto_tree *subtree; gint base_offset; guint32 ussd_payload_offset, ussd_payload_length; - guint8 encoding, *ussd; + guint8 encoding; tvbuff_t *ussd_tvb; - int out_len; - gchar *utf8_text; base_offset = offset; proto_tree_add_item(tree, hf_mbim_set_ussd_ussd_action, tvb, offset, 4, ENC_LITTLE_ENDIAN); @@ -3095,13 +3093,8 @@ mbim_dissect_set_ussd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint switch (encoding) { case SMS_ENCODING_7BIT: case SMS_ENCODING_7BIT_LANG: - ussd = (guint8*)wmem_alloc(wmem_packet_scope(), ussd_payload_length+1); - out_len = gsm_sms_char_7bit_unpack(0, ussd_payload_length, ussd_payload_length, - tvb_get_ptr(ussd_tvb, 0, ussd_payload_length), ussd); - ussd[out_len] = '\0'; - utf8_text = gsm_sms_chars_to_utf8(ussd, out_len); - proto_tree_add_string(subtree, hf_mbim_set_ussd_ussd_payload_text, - ussd_tvb, 0, ussd_payload_length, utf8_text); + proto_tree_add_item(subtree, hf_mbim_set_ussd_ussd_payload_text, + ussd_tvb, 0, ussd_payload_length, ENC_3GPP_TS_23_038|ENC_NA); break; case SMS_ENCODING_8BIT: /* XXX - ASCII, or some extended ASCII? */ @@ -3126,10 +3119,8 @@ mbim_dissect_ussd_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint proto_tree *subtree; gint base_offset; guint32 ussd_payload_offset, ussd_payload_length; - guint8 encoding, *ussd; + guint8 encoding; tvbuff_t *ussd_tvb; - int out_len; - gchar *utf8_text; base_offset = offset; proto_tree_add_item(tree, hf_mbim_ussd_info_ussd_response, tvb, offset, 4, ENC_LITTLE_ENDIAN); @@ -3154,13 +3145,8 @@ mbim_dissect_ussd_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint switch (encoding) { case SMS_ENCODING_7BIT: case SMS_ENCODING_7BIT_LANG: - ussd = (guint8*)wmem_alloc(wmem_packet_scope(), ussd_payload_length+1); - out_len = gsm_sms_char_7bit_unpack(0, ussd_payload_length, ussd_payload_length, - tvb_get_ptr(ussd_tvb, 0, ussd_payload_length), ussd); - ussd[out_len] = '\0'; - utf8_text = gsm_sms_chars_to_utf8(ussd, out_len); - proto_tree_add_string(subtree, hf_mbim_ussd_info_ussd_payload_text, - ussd_tvb, 0, ussd_payload_length, utf8_text); + proto_tree_add_item(subtree, hf_mbim_ussd_info_ussd_payload_text, + ussd_tvb, 0, ussd_payload_length, ENC_3GPP_TS_23_038|ENC_NA); break; case SMS_ENCODING_8BIT: /* XXX - ASCII, or some extended ASCII? */ diff --git a/epan/proto.h b/epan/proto.h index 2c29514a73..67ffb790de 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -297,21 +297,24 @@ WS_DLL_PUBLIC WS_MSVC_NORETURN void proto_report_dissector_bug(const char *messa #define ENC_ISO_8859_15 0x00000026 #define ENC_ISO_8859_16 0x00000028 #define ENC_WINDOWS_1250 0x0000002A -#define ENC_EBCDIC 0x0000002C +#define ENC_3GPP_TS_23_038 0x0000002C +#define ENC_EBCDIC 0x0000002E /* * TODO: * * These could probably be used by existing code: * - * - "IBM MS DBCS" - * - JIS C 6226 - * 7-bit encodings such as ETSI 03.38 (GSM SMS character set - * (see packet-ansi_337.c, packet-gsm_a_dtap.c, packet-gsm_map.c, - * packet-gsm_sms.c)? + * "IBM MS DBCS" + * JIS C 6226 + * 7-bit encodings such as ETSI 03.38 (GSM SMS character set - + * used in some files, but packet-ansi_637.c, + * packet-cell_broadcast.c, packet-gmr1_rr.c, + * packet-gsm_a_dtap.c, and packet-gsm_sms.c need some + * work to use it) * - * As those are added, change code such as fCharacterString() in - * packet-bacapp.c to use them. + * As those are added, change code such as the code in packet-bacapp.c + * to use them. */ /* diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 28e22895c1..199f290d62 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -2149,6 +2149,173 @@ tvb_get_ucs_4_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, } /* + * FROM GNOKII + * gsm-encoding.c + * gsm-sms.c + */ +#define GN_BYTE_MASK ((1 << bits) - 1) + +#define GN_CHAR_ALPHABET_SIZE 128 + +#define GN_CHAR_ESCAPE 0x1b + +static const 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 gboolean +handle_ts_23_038_char(wmem_strbuf_t *strbuf, guint8 code_point, + gboolean saw_escape) +{ + gunichar uchar; + + if (char_is_escape(code_point)) { + /* + * XXX - if saw_escape is TRUE here, then this is + * the case where we escape to "another extension table", + * but TS 128 038 V11.0 doesn't specify such an extension + * table. + */ + saw_escape = TRUE; + } else { + /* + * Have we seen an escape? + */ + if (saw_escape) { + saw_escape = FALSE; + uchar = char_def_alphabet_ext_decode(code_point); + } else + uchar = char_def_alphabet_decode(code_point); + } + wmem_strbuf_append_unichar(strbuf, uchar); + return saw_escape; +} + +static gchar * +tvb_get_ts_23_038_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length) +{ + wmem_strbuf_t *strbuf; + gint i; /* Byte counter for tvbuff */ + gint in_offset = offset; /* Current pointer to the input buffer */ + guint8 in_byte, out_byte, rest = 0x00; + gboolean saw_escape = FALSE; + int bits; + + bits = 7; + + tvb_ensure_bytes_exist(tvb, offset, length); + strbuf = wmem_strbuf_new(scope, NULL); + for(i = 0; i < length; i++) { + /* Get the next byte from the string. */ + in_byte = tvb_get_guint8(tvb, in_offset); + in_offset++; + + /* + * Combine the bits we've accumulated with bits from + * that byte to make a 7-bit code point. + */ + out_byte = ((in_byte & GN_BYTE_MASK) << (7 - bits)) | rest; + + /* + * Leftover bits used in that code point. + */ + rest = in_byte >> bits; + + /* + * If we don't start from 0th bit, we shouldn't go to the + * next char. Under *out_num we have now 0 and under Rest - + * _first_ part of the char. + */ + if ((in_offset != offset) || (bits == 7)) + saw_escape = handle_ts_23_038_char(strbuf, out_byte, + saw_escape); + + /* + * After reading 7 octets we have read 7 full characters + * but we have 7 bits as well. This is the next character. + */ + if (bits == 1) { + saw_escape = handle_ts_23_038_char(strbuf, rest, + saw_escape); + bits = 7; + rest = 0x00; + } else + bits--; + } + + if (saw_escape) { + /* + * Escape not followed by anything. + * + * XXX - for now, show the escape as a "?". + */ + wmem_strbuf_append_unichar(strbuf, '?'); + } + + return (gchar*)wmem_strbuf_get_str(strbuf); +} + +/* * Given a tvbuff, an offset, a length, and an encoding, allocate a * buffer big enough to hold a non-null-terminated string of that length * at that offset, plus a trailing '\0', copy into the buffer the @@ -2284,6 +2451,10 @@ tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1250); break; + case ENC_3GPP_TS_23_038: + strbuf = tvb_get_ts_23_038_string(scope, tvb, offset, length); + break; + case ENC_EBCDIC: /* * XXX - do the copy and conversion in one pass. @@ -2576,6 +2747,10 @@ tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, g strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1250); break; + case ENC_3GPP_TS_23_038: + REPORT_DISSECTOR_BUG("TS 23.038 has no null character and doesn't support null-terminated strings"); + break; + case ENC_EBCDIC: /* * XXX - do the copy and conversion in one pass. |