diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-sms-utils.c | 61 | ||||
-rw-r--r-- | src/tests/test-sms.c | 34 |
2 files changed, 71 insertions, 24 deletions
diff --git a/src/mm-sms-utils.c b/src/mm-sms-utils.c index df706ea7..f3e3b759 100644 --- a/src/mm-sms-utils.c +++ b/src/mm-sms-utils.c @@ -23,6 +23,7 @@ #include "mm-utils.h" #include "mm-sms-utils.h" #include "mm-log.h" +#include "dbus/dbus-glib.h" #define SMS_TP_MTI_MASK 0x03 #define SMS_TP_MTI_SMS_DELIVER 0x00 @@ -204,24 +205,10 @@ sms_decode_text (const guint8 *text, int len, SmsEncoding encoding, int bit_offs g_free (unpacked); } else if (encoding == MM_SMS_ENCODING_UCS2) utf8 = g_convert ((char *) text, len, "UTF8", "UCS-2BE", NULL, NULL, NULL); - else if (encoding == MM_SMS_ENCODING_8BIT) { - /* DBus requires UTF-8 strings, so we have some sanitizing to do */ - char *p; - int i; - utf8 = g_malloc0 (4*len+1); /* Worst case: Every byte becomes "\xFF" */ - p = utf8; - for (i = 0 ; i < len ; i++) { - if (isascii (text[i]) && text[i] != '\0') - *p++ = text[i]; - else { - sprintf(p, "\\x%02x", text[i]); - p += 4; - } - } - *p = '\0'; - } - else + else { + g_warn_if_reached (); utf8 = g_strdup (""); + } return utf8; } @@ -259,18 +246,31 @@ simple_string_value (const char *str) return val; } +static GValue * +byte_array_value (const GByteArray *array) +{ + GValue *val; + + val = g_slice_new0 (GValue); + g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY); + g_value_set_boxed (val, array); + + return val; +} + GHashTable * sms_parse_pdu (const char *hexpdu, GError **error) { GHashTable *properties; gsize pdu_len; guint8 *pdu; - int smsc_addr_num_octets, variable_length_items, msg_start_offset, + guint smsc_addr_num_octets, variable_length_items, msg_start_offset, sender_addr_num_digits, sender_addr_num_octets, tp_pid_offset, tp_dcs_offset, user_data_offset, user_data_len, user_data_len_offset, bit_offset; char *smsc_addr, *sender_addr, *sc_timestamp, *msg_text; SmsEncoding user_data_encoding; + GByteArray *pdu_data; /* Convert PDU from hex to binary */ pdu = (guint8 *) utils_hexstr2bin (hexpdu, &pdu_len); @@ -426,12 +426,29 @@ sms_parse_pdu (const char *hexpdu, GError **error) user_data_len -= udhl; } - msg_text = sms_decode_text (&pdu[user_data_offset], user_data_len, - user_data_encoding, bit_offset); - g_hash_table_insert (properties, "text", - simple_string_value (msg_text)); + if ( user_data_encoding == MM_SMS_ENCODING_8BIT + || user_data_encoding == MM_SMS_ENCODING_UNKNOWN) { + /* 8-bit encoding is usually binary data, and we have no idea what + * actual encoding the data is in so we can't convert it. + */ + msg_text = g_strdup (""); + } else { + /* Otherwise if it's 7-bit or UCS2 we can decode it */ + msg_text = sms_decode_text (&pdu[user_data_offset], user_data_len, + user_data_encoding, bit_offset); + g_warn_if_fail (msg_text != NULL); + } + g_hash_table_insert (properties, "text", simple_string_value (msg_text)); g_free (msg_text); + /* Add the raw PDU data */ + pdu_data = g_byte_array_sized_new (user_data_len); + g_byte_array_append (pdu_data, &pdu[user_data_offset], user_data_len); + g_hash_table_insert (properties, "data", byte_array_value (pdu_data)); + g_byte_array_free (pdu_data, TRUE); + g_hash_table_insert (properties, "data-coding-scheme", + simple_uint_value (pdu[tp_dcs_offset] & 0xFF)); + if (pdu[tp_dcs_offset] & SMS_DCS_CLASS_VALID) g_hash_table_insert (properties, "class", simple_uint_value (pdu[tp_dcs_offset] & diff --git a/src/tests/test-sms.c b/src/tests/test-sms.c index bd18c0bc..aa234e63 100644 --- a/src/tests/test-sms.c +++ b/src/tests/test-sms.c @@ -20,6 +20,7 @@ #include "mm-sms-utils.h" #include "mm-utils.h" +#include "dbus/dbus-glib.h" #define TEST_ENTRY_EQ(hash, key, expectvalue) do { \ @@ -30,6 +31,27 @@ g_assert_cmpstr(g_value_get_string(value), ==, (expectvalue)); \ } while (0) +#define TEST_UINT_ENTRY_EQ(hash, key, expectvalue) do { \ + GValue *value; \ + value = g_hash_table_lookup((hash), (key)); \ + g_assert(value); \ + g_assert(G_VALUE_HOLDS_UINT(value)); \ + g_assert_cmpint(g_value_get_uint(value), ==, (expectvalue)); \ + } while (0) + +#define TEST_ARRAY_ENTRY_EQ(hash, key, expectvalue) do { \ + GValue *value; \ + GByteArray *tmp; \ + guint32 i; \ + value = g_hash_table_lookup((hash), (key)); \ + g_assert(value); \ + g_assert(G_VALUE_HOLDS(value, DBUS_TYPE_G_UCHAR_ARRAY)); \ + tmp = g_value_get_boxed (value); \ + g_assert_cmpint (tmp->len, ==, sizeof (expectvalue)); \ + for (i = 0; i < tmp->len; i++) \ + g_assert_cmpint (tmp->data[i], ==, expectvalue[i]); \ + } while (0) + static void test_pdu1 (void *f, gpointer d) { @@ -217,6 +239,8 @@ test_pdu3_8bit (void *f, gpointer d) 0xf2, 0x00, 0x04, 0x11, 0x10, 0x10, 0x21, 0x43, 0x65, 0x00, 0x0a, 0xe8, 0x32, 0x9b, 0xfd, 0x46, 0x97, 0xd9, 0xec, 0x37, 0xde}; + static const guint8 expected_data[] = { + 0xe8, 0x32, 0x9b, 0xfd, 0x46, 0x97, 0xd9, 0xec, 0x37, 0xde }; GHashTable *sms; GError *error; char *hexpdu; @@ -228,7 +252,9 @@ test_pdu3_8bit (void *f, gpointer d) TEST_ENTRY_EQ (sms, "smsc", "+12345678901"); TEST_ENTRY_EQ (sms, "number", "+18005551212"); TEST_ENTRY_EQ (sms, "timestamp", "110101123456+00"); - TEST_ENTRY_EQ (sms, "text", "\xe8\x32\x9b\xfd\x46\x97\xd9\xec\x37\xde"); + TEST_ENTRY_EQ (sms, "text", ""); + TEST_UINT_ENTRY_EQ (sms, "data-coding-scheme", 0x04); + TEST_ARRAY_ENTRY_EQ (sms, "data", expected_data); g_free (hexpdu); g_hash_table_unref (sms); @@ -301,6 +327,8 @@ test_pdu_dcsf_8bit (void *f, gpointer d) 0xf2, 0x00, 0xf4, 0x11, 0x10, 0x10, 0x21, 0x43, 0x65, 0x00, 0x0a, 0xe8, 0x32, 0x9b, 0xfd, 0x46, 0x97, 0xd9, 0xec, 0x37, 0xde}; + static const guint8 expected_data[] = { + 0xe8, 0x32, 0x9b, 0xfd, 0x46, 0x97, 0xd9, 0xec, 0x37, 0xde }; GHashTable *sms; GError *error; char *hexpdu; @@ -312,7 +340,9 @@ test_pdu_dcsf_8bit (void *f, gpointer d) TEST_ENTRY_EQ (sms, "smsc", "+12345678901"); TEST_ENTRY_EQ (sms, "number", "+18005551212"); TEST_ENTRY_EQ (sms, "timestamp", "110101123456+00"); - TEST_ENTRY_EQ (sms, "text", "\xe8\x32\x9b\xfd\x46\x97\xd9\xec\x37\xde"); + TEST_ENTRY_EQ (sms, "text", ""); + TEST_UINT_ENTRY_EQ (sms, "data-coding-scheme", 0xF4); + TEST_ARRAY_ENTRY_EQ (sms, "data", expected_data); g_free (hexpdu); g_hash_table_unref (sms); |