guint8 out_len;
/* XXX - The maximum item label length is 240. Does this really need to be 1024?
* use ep_alloc ?
- * We need a input and an output buffer to gsm_sms_char_ascii_decode()
*/
static unsigned char msgbuf[1024];
- static unsigned char outbuf[1024];
gchar *utf8_text = NULL;
GIConv cd;
GError *l_conv_error = NULL;
msgbuf);
msgbuf[out_len] = '\0';
- gsm_sms_char_ascii_decode(outbuf, msgbuf, out_len);
- msgbuf[1023] = '\0';
- proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %%s", outbuf);
+ utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len);
+ proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %%s", utf8_text);
break;
case SMS_ENCODING_8BIT:
proto_tree_add_text(tree, parameter_tvb , 0, length, "USSD String: %%s", tvb_get_ptr(parameter_tvb, 0, length));
if (num_spare_bits == 7)
num_chars--;
a_bigbuf[num_chars] = '\0';
- /*
- * The documentation for g_unichar_to_utf8() says that
- * the output buffer "must have at least 6 bytes of space".
- * I think that maximum is for some Korean characters, so
- * perhaps that's overkill here, but there are at least
- * some SMS characters whose UTF-8 encoding takes 3
- * bytes. We'll be safe and allocate 6 bytes.
- *
- * XXX - we could have a routine that takes a string of
- * SMS characters and returns an ep_allocated UTF-8
- * string. g_unichar_to_utf8(), if passed a null
- * buffer pointer, just returns the number of bytes
- * required, so we could get the right buffer size
- * by making two passes over the SMS string.
- */
- net_name = ep_alloc(6 * num_chars);
- gsm_sms_char_ascii_decode(net_name, a_bigbuf, num_chars);
+ net_name = gsm_sms_chars_to_utf8(a_bigbuf, num_chars);
proto_tree_add_text(tree, tvb , curr_offset, len - 1, "Text String: %s", net_name);
break;
case 1:
static 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 704 "gsm_map.cnf"
+#line 701 "gsm_map.cnf"
/*
-- Information about the internal structure is given in
-- clause 7.6.9.
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 785 "gsm_map.cnf"
+#line 782 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
proto_tree *subtree;
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 564 "gsm_map.cnf"
+#line 561 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
proto_tree *subtree;
offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
NULL);
-#line 471 "gsm_map.cnf"
+#line 468 "gsm_map.cnf"
proto_tree_add_item(tree, hf_gsm_map_notification_to_forwarding_party, tvb, 0,1,FALSE);
proto_tree_add_item(tree, hf_gsm_map_redirecting_presentation, tvb, 0,1,FALSE);
guint8 out_len;
/* XXX - The maximum item label length is 240. Does this really need to be 1024?
* use ep_alloc ?
- * We need a input and an output buffer to gsm_sms_char_ascii_decode()
*/
static unsigned char msgbuf[1024];
- static unsigned char outbuf[1024];
gchar *utf8_text = NULL;
GIConv cd;
GError *l_conv_error = NULL;
msgbuf);
msgbuf[out_len] = '\0';
- gsm_sms_char_ascii_decode(outbuf, msgbuf, out_len);
- msgbuf[1023] = '\0';
- proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %s", outbuf);
+ utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len);
+ proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %s", utf8_text);
break;
case SMS_ENCODING_8BIT:
proto_tree_add_text(tree, parameter_tvb , 0, length, "USSD String: %s", tvb_get_ptr(parameter_tvb, 0, length));
int
dissect_gsm_map_ms_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 528 "gsm_map.cnf"
+#line 525 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
guint8 octet;
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 600 "gsm_map.cnf"
+#line 597 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
asn1_ctx_t asn1_ctx;
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 612 "gsm_map.cnf"
+#line 609 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
asn1_ctx_t asn1_ctx;
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 576 "gsm_map.cnf"
+#line 573 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
proto_tree *subtree;
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 588 "gsm_map.cnf"
+#line 585 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
asn1_ctx_t asn1_ctx;
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 477 "gsm_map.cnf"
+#line 474 "gsm_map.cnf"
proto_tree_add_item(tree, hf_gsm_map_notification_to_forwarding_party, tvb, 0,1,FALSE);
proto_tree_add_item(tree, hf_gsm_map_redirecting_presentation, tvb, 0,1,FALSE);
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 485 "gsm_map.cnf"
+#line 482 "gsm_map.cnf"
guint8 pdp_type_org;
tvbuff_t *parameter_tvb;
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 507 "gsm_map.cnf"
+#line 504 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
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 518 "gsm_map.cnf"
+#line 515 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
int
dissect_gsm_map_ms_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 552 "gsm_map.cnf"
+#line 549 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
proto_tree *subtree;
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 797 "gsm_map.cnf"
+#line 794 "gsm_map.cnf"
tvbuff_t *parameter_tvb;
proto_tree *subtree;
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 625 "gsm_map.cnf"
+#line 622 "gsm_map.cnf"
guint8 octet;
guint8 length;
tvbuff_t *next_tvb;
guint32 length;
guint32 i, j;
char addrbuf[MAX_ADDR_SIZE+1];
+ gchar *addrstr;
offset = *offset_p;
case 0x05: /* "Alphanumeric (coded according to 3GPP TS 23.038 GSM 7-bit default alphabet)" */
i = gsm_sms_char_7bit_unpack(0, numdigocts, MAX_ADDR_SIZE, tvb_get_ptr(tvb, offset, numdigocts), addrbuf);
addrbuf[i] = '\0';
- gsm_sms_char_ascii_decode(bigbuf, addrbuf, i);
+ 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;
}
if (g_ascii_strncasecmp(title, "TP-O", 4) == 0) {
proto_tree_add_string(subtree, hf_gsm_sms_tp_oa, tvb,
- offset, numdigocts, bigbuf);
+ 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, bigbuf);
+ 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, bigbuf);
+ 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;
}
}
}
-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;
- gunichar buf;
+ 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);
+ }
+ /* 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])) {
- 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]));
+ 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]);
+ i += g_unichar_to_utf8(c,&(outbuf[i]));
}
- dest[i]=0;
- return;
+ outbuf[i] = '\0';
+ return outbuf;
}
/*
gsm_sms_char_7bit_unpack(fill_bits, length , SMS_MAX_MESSAGE_SIZE,
tvb_get_ptr(tvb , offset , length) , messagebuf);
messagebuf[out_len] = '\0';
- gsm_sms_char_ascii_decode(bigbuf, messagebuf, out_len);
- proto_tree_add_text(subtree, tvb , offset , length , "%s", bigbuf);
+ proto_tree_add_text(subtree, tvb , offset , length , "%s",
+ gsm_sms_chars_to_utf8(messagebuf, out_len));
}
else
{
tvb_get_ptr(sm_tvb , i * MAX_SMS_FRAG_LEN , len_sms) , messagebuf);
messagebuf[out_len] = '\0';
- gsm_sms_char_ascii_decode(bigbuf, messagebuf, out_len);
- proto_tree_add_text(subtree, sm_tvb , i * MAX_SMS_FRAG_LEN , len_sms , "%s", bigbuf);
+ proto_tree_add_text(subtree, sm_tvb , i * MAX_SMS_FRAG_LEN , len_sms , "%s",
+ gsm_sms_chars_to_utf8(messagebuf, out_len));
}
}
}
extern int gsm_sms_char_7bit_unpack(unsigned int offset, unsigned int in_length, unsigned int out_length,
const guint8 *input, unsigned char *output);
-extern void gsm_sms_char_ascii_decode(unsigned char* dest, const unsigned char* src, int len);
+
+/* Convert an unpacked SMS string to UTF-8.
+ *
+ * @param src The string to convert.
+ * @param len Length of the string to convert, in bytes.
+ * @return An ep_allocated UTF-8 string.
+ */
+
+extern gchar *gsm_sms_chars_to_utf8(const unsigned char* src, int len);