sms: punt handling of 8-bit encoded SMSs to clients

There's no encoding information about 8-bit SMS messages,
and they are often binary things like ringtones or voicemail
indicator commands.  Since there's no point to our parsing
them just let clients deal with it.
This commit is contained in:
Dan Williams
2012-01-09 17:23:48 -06:00
parent 96210d1c55
commit 86e3ab1540
3 changed files with 74 additions and 25 deletions
@@ -31,7 +31,9 @@
A dictionary containing SMS properties of the SMS specified by the given index. This dictionary may contain the following key/value pairs:
number : string - Phone number (mandatory)
text : string - SMS text (mandatory)
text : string - SMS text (mandatory, empty if data cannot be decoded)
data : byte array - SMS user data (TP-UD) (mandatory)
data-coding-scheme: uint (0..255) - SMS user data coding scheme (TP-DCS) (mandatory)
smsc : string - SMS service center number (optional)
validity : uint (0..255) - Specifies when the SMS expires in SMSC (optional)
class : uint (0..3) - Message importance and location (optional)
+39 -22
View File
@@ -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] &
+32 -2
View File
@@ -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);