diff options
author | Nathan Williams <njw@google.com> | 2011-07-25 00:42:08 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2011-07-25 01:18:16 -0500 |
commit | e5faa242e9c6ddcd5bcb976420483ead59f81239 (patch) | |
tree | 8216e49072c2badf10e71e3ad0ebae627cf9a7cb /src | |
parent | 0cc813312f9bf446614d6aed6a85b1ee0b006451 (diff) |
sms: split SMS parsing out into a separate file
In preparation for adding tests.
Change-Id: If1ebd0fdd6e7470c21538042ab1735357649155c
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/mm-generic-gsm.c | 266 | ||||
-rw-r--r-- | src/mm-sms-utils.c | 320 | ||||
-rw-r--r-- | src/mm-sms-utils.h | 25 |
4 files changed, 355 insertions, 260 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index e813e7e8..71008c9d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,9 @@ libmodem_helpers_la_SOURCES = \ mm-charsets.c \ mm-charsets.h \ mm-utils.c \ - mm-utils.h + mm-utils.h \ + mm-sms-utils.c \ + mm-sms-utils.h libserial_la_CPPFLAGS = \ $(MM_CFLAGS) \ diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index dc2d4ddc..8e1cc5db 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -37,6 +37,7 @@ #include "mm-properties-changed-signal.h" #include "mm-utils.h" #include "mm-modem-location.h" +#include "mm-sms-utils.h" static void modem_init (MMModem *modem_class); static void modem_gsm_card_init (MMModemGsmCard *gsm_card_class); @@ -185,7 +186,6 @@ static void cusd_received (MMAtSerialPort *port, #define GS_HASH_TAG "get-sms" static GValue *simple_string_value (const char *str); static GValue *simple_uint_value (guint32 i); -static GValue *simple_boolean_value (gboolean b); static void simple_free_gvalue (gpointer data); MMModem * @@ -4196,35 +4196,6 @@ mm_generic_gsm_get_charset (MMGenericGsm *self) /* MMModemGsmSms interface */ -#define SMS_TP_MTI_MASK 0x03 -#define SMS_TP_MTI_SMS_DELIVER 0x00 -#define SMS_TP_MTI_SMS_SUBMIT_REPORT 0x01 -#define SMS_TP_MTI_SMS_STATUS_REPORT 0x02 - -#define SMS_NUMBER_TYPE_MASK 0x70 -#define SMS_NUMBER_TYPE_UNKNOWN 0x00 -#define SMS_NUMBER_TYPE_INTL 0x10 -#define SMS_NUMBER_TYPE_ALPHA 0x50 - -#define SMS_NUMBER_PLAN_MASK 0x0f -#define SMS_NUMBER_PLAN_TELEPHONE 0x01 - -#define SMS_TP_MMS 0x04 -#define SMS_TP_SRI 0x20 -#define SMS_TP_UDHI 0x40 -#define SMS_TP_RP 0x80 - -#define SMS_DCS_CODING_MASK 0xec -#define SMS_DCS_CODING_DEFAULT 0x00 -#define SMS_DCS_CODING_8BIT 0x04 -#define SMS_DCS_CODING_UCS2 0x08 - -#define SMS_DCS_CLASS_VALID 0x10 -#define SMS_DCS_CLASS_MASK 0x03 - -#define SMS_TIMESTAMP_LEN 7 -#define SMS_MIN_PDU_LEN (7 + SMS_TIMESTAMP_LEN) -#define SMS_MAX_PDU_LEN 344 static void sms_send_done (MMAtSerialPort *port, @@ -4275,219 +4246,7 @@ sms_send (MMModemGsmSms *modem, g_free (command); } -static char sms_bcd_chars[] = "0123456789*#abc\0\0"; - -static void -sms_semi_octets_to_bcd_string (char *dest, const guint8 *octets, int num_octets) -{ - int i; - - for (i = 0 ; i < num_octets; i++) { - *dest++ = sms_bcd_chars[octets[i] & 0xf]; - *dest++ = sms_bcd_chars[(octets[i] >> 4) & 0xf]; - } - *dest++ = '\0'; -} - -/* len is in semi-octets */ -static char * -sms_decode_address (const guint8 *address, int len) -{ - guint8 addrtype, addrplan; - char *utf8; - - addrtype = address[0] & SMS_NUMBER_TYPE_MASK; - addrplan = address[0] & SMS_NUMBER_PLAN_MASK; - address++; - - if (addrtype == SMS_NUMBER_TYPE_ALPHA) { - guint8 *unpacked; - guint32 unpacked_len; - unpacked = gsm_unpack (address, (len * 4) / 7, 0, &unpacked_len); - utf8 = (char *)mm_charset_gsm_unpacked_to_utf8 (unpacked, - unpacked_len); - g_free(unpacked); - } else if (addrtype == SMS_NUMBER_TYPE_INTL && - addrplan == SMS_NUMBER_PLAN_TELEPHONE) { - /* International telphone number, format as "+1234567890" */ - utf8 = g_malloc (len + 3); /* '+' + digits + possible trailing 0xf + NUL */ - utf8[0] = '+'; - sms_semi_octets_to_bcd_string (utf8 + 1, address, (len + 1) / 2); - } else { - /* - * All non-alphanumeric types and plans are just digits, but - * don't apply any special formatting if we don't know the - * format. - */ - utf8 = g_malloc (len + 2); /* digits + possible trailing 0xf + NUL */ - sms_semi_octets_to_bcd_string (utf8, address, (len + 1) / 2); - } - - return utf8; -} - -static char * -sms_decode_timestamp (const guint8 *timestamp) -{ - /* YYMMDDHHMMSS+ZZ */ - char *timestr; - int quarters, hours; - - timestr = g_malloc0 (16); - sms_semi_octets_to_bcd_string (timestr, timestamp, 6); - quarters = ((timestamp[6] & 0x7) * 10) + ((timestamp[6] >> 4) & 0xf); - hours = quarters / 4; - if (timestamp[6] & 0x08) - timestr[12] = '-'; - else - timestr[12] = '+'; - timestr[13] = (hours / 10) + '0'; - timestr[14] = (hours % 10) + '0'; - /* TODO(njw): Change timestamp rep to something that includes quarter-hours */ - return timestr; -} - -static char * -sms_decode_text (const guint8 *text, int len, int dcs, int bit_offset) -{ - char *utf8; - guint8 coding = dcs & SMS_DCS_CODING_MASK; - guint8 *unpacked; - guint32 unpacked_len; - - if (coding == SMS_DCS_CODING_DEFAULT) { - unpacked = gsm_unpack ((const guint8 *) text, len, bit_offset, &unpacked_len); - utf8 = (char *) mm_charset_gsm_unpacked_to_utf8 (unpacked, unpacked_len); - g_free (unpacked); - } else if (coding == SMS_DCS_CODING_UCS2) - utf8 = g_convert ((char *) text, len, "UTF8", "UCS-2BE", NULL, NULL, NULL); - else if (coding == SMS_DCS_CODING_8BIT) - utf8 = g_strndup ((const char *)text, len); - else - utf8 = g_strdup (""); - - return utf8; -} - - -static GHashTable * -sms_parse_pdu (const char *hexpdu) -{ - GHashTable *properties; - gsize pdu_len; - guint8 *pdu; - int 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, user_data_dcs, bit_offset; - char *smsc_addr, *sender_addr, *sc_timestamp, *msg_text; - - /* Convert PDU from hex to binary */ - pdu = (guint8 *) utils_hexstr2bin (hexpdu, &pdu_len); - if (!pdu) { - mm_err("Couldn't parse PDU of SMS GET response from hex"); - return NULL; - } - - /* SMSC, in address format, precedes the TPDU */ - smsc_addr_num_octets = pdu[0]; - variable_length_items = smsc_addr_num_octets; - if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) { - mm_err ("PDU too short (1): %zd vs %d", pdu_len, - variable_length_items + SMS_MIN_PDU_LEN); - g_free (pdu); - return NULL; - } - - /* where in the PDU the actual SMS protocol message begins */ - msg_start_offset = 1 + smsc_addr_num_octets; - sender_addr_num_digits = pdu[msg_start_offset + 1]; - /* - * round the sender address length up to an even number of - * semi-octets, and thus an integral number of octets - */ - sender_addr_num_octets = (sender_addr_num_digits + 1) >> 1; - variable_length_items += sender_addr_num_octets; - if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) { - mm_err ("PDU too short (2): %zd vs %d", pdu_len, - variable_length_items + SMS_MIN_PDU_LEN); - g_free (pdu); - return NULL; - } - - tp_pid_offset = msg_start_offset + 3 + sender_addr_num_octets; - tp_dcs_offset = tp_pid_offset + 1; - - user_data_len_offset = tp_dcs_offset + 1 + SMS_TIMESTAMP_LEN; - user_data_offset = user_data_len_offset + 1; - user_data_len = pdu[user_data_len_offset]; - user_data_dcs = pdu[tp_dcs_offset]; - if ((user_data_dcs & SMS_DCS_CODING_MASK) == SMS_DCS_CODING_DEFAULT) - variable_length_items += (7 * (user_data_len + 1 )) / 8; - else - variable_length_items += user_data_len; - if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) { - mm_err ("PDU too short (3): %zd vs %d", pdu_len, - variable_length_items + SMS_MIN_PDU_LEN); - g_free (pdu); - return NULL; - } - - /* Only handle SMS-DELIVER */ - if ((pdu[msg_start_offset] & SMS_TP_MTI_MASK) != SMS_TP_MTI_SMS_DELIVER) { - mm_err ("Unhandled message type: 0x%02x", pdu[msg_start_offset]); - g_free (pdu); - return NULL; - } - - smsc_addr = sms_decode_address (&pdu[1], 2 * (pdu[0] - 1)); - sender_addr = sms_decode_address (&pdu[msg_start_offset + 2], - pdu[msg_start_offset + 1]); - sc_timestamp = sms_decode_timestamp (&pdu[tp_dcs_offset + 1]); - bit_offset = 0; - if (pdu[msg_start_offset] & SMS_TP_UDHI) { - /* - * Skip over the user data headers to prevent it from being - * decoded into garbage text. - */ - int udhl; - udhl = pdu[user_data_offset] + 1; - user_data_offset += udhl; - if ((user_data_dcs & SMS_DCS_CODING_MASK) == SMS_DCS_CODING_DEFAULT) { - bit_offset = 7 - (udhl * 8) % 7; - user_data_len -= (udhl * 8 + bit_offset) / 7; - } else - user_data_len -= udhl; - } - - msg_text = sms_decode_text (&pdu[user_data_offset], user_data_len, - user_data_dcs, bit_offset); - - properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, - simple_free_gvalue); - g_hash_table_insert (properties, "number", - simple_string_value (sender_addr)); - g_hash_table_insert (properties, "text", - simple_string_value (msg_text)); - g_hash_table_insert (properties, "smsc", - simple_string_value (smsc_addr)); - g_hash_table_insert (properties, "timestamp", - simple_string_value (sc_timestamp)); - if (user_data_dcs & SMS_DCS_CLASS_VALID) - g_hash_table_insert (properties, "class", - simple_uint_value (user_data_dcs & - SMS_DCS_CLASS_MASK)); - g_hash_table_insert (properties, "completed", simple_boolean_value (TRUE)); - - g_free (smsc_addr); - g_free (sender_addr); - g_free (sc_timestamp); - g_free (msg_text); - g_free (pdu); - - return properties; -} static void sms_get_done (MMAtSerialPort *port, @@ -4521,11 +4280,8 @@ sms_get_done (MMAtSerialPort *port, goto out; } - properties = sms_parse_pdu (pdu); + properties = sms_parse_pdu (pdu, &info->error); if (!properties) { - info->error = g_error_new_literal (MM_MODEM_ERROR, - MM_MODEM_ERROR_GENERAL, - "Failed to parse SMS PDU"); goto out; } @@ -4638,6 +4394,7 @@ sms_list_done (MMAtSerialPort *port, while (*rstr) { GHashTable *properties; + GError *local; int idx; char pdu[SMS_MAX_PDU_LEN + 1]; @@ -4649,11 +4406,14 @@ sms_list_done (MMAtSerialPort *port, } rstr += offset; - properties = sms_parse_pdu (pdu); + properties = sms_parse_pdu (pdu, &local); if (properties) { g_hash_table_insert (properties, "index", simple_uint_value (idx)); g_ptr_array_add (results, properties); + } else { + /* Ignore the error */ + g_clear_error(&local); } } /* @@ -5373,18 +5133,6 @@ simple_uint_value (guint32 i) } static GValue * -simple_boolean_value (gboolean b) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_BOOLEAN); - g_value_set_boolean (val, b); - - return val; -} - -static GValue * simple_string_value (const char *str) { GValue *val; diff --git a/src/mm-sms-utils.c b/src/mm-sms-utils.c new file mode 100644 index 00000000..c7de0e16 --- /dev/null +++ b/src/mm-sms-utils.c @@ -0,0 +1,320 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#include <glib.h> + +#include "mm-charsets.h" +#include "mm-errors.h" +#include "mm-utils.h" +#include "mm-sms-utils.h" + +#define SMS_TP_MTI_MASK 0x03 +#define SMS_TP_MTI_SMS_DELIVER 0x00 +#define SMS_TP_MTI_SMS_SUBMIT_REPORT 0x01 +#define SMS_TP_MTI_SMS_STATUS_REPORT 0x02 + +#define SMS_NUMBER_TYPE_MASK 0x70 +#define SMS_NUMBER_TYPE_UNKNOWN 0x00 +#define SMS_NUMBER_TYPE_INTL 0x10 +#define SMS_NUMBER_TYPE_ALPHA 0x50 + +#define SMS_NUMBER_PLAN_MASK 0x0f +#define SMS_NUMBER_PLAN_TELEPHONE 0x01 + +#define SMS_TP_MMS 0x04 +#define SMS_TP_SRI 0x20 +#define SMS_TP_UDHI 0x40 +#define SMS_TP_RP 0x80 + +#define SMS_DCS_CODING_MASK 0xec +#define SMS_DCS_CODING_DEFAULT 0x00 +#define SMS_DCS_CODING_8BIT 0x04 +#define SMS_DCS_CODING_UCS2 0x08 + +#define SMS_DCS_CLASS_VALID 0x10 +#define SMS_DCS_CLASS_MASK 0x03 + +#define SMS_TIMESTAMP_LEN 7 +#define SMS_MIN_PDU_LEN (7 + SMS_TIMESTAMP_LEN) + +static char sms_bcd_chars[] = "0123456789*#abc\0\0"; + +static void +sms_semi_octets_to_bcd_string (char *dest, const guint8 *octets, int num_octets) +{ + int i; + + for (i = 0 ; i < num_octets; i++) { + *dest++ = sms_bcd_chars[octets[i] & 0xf]; + *dest++ = sms_bcd_chars[(octets[i] >> 4) & 0xf]; + } + *dest++ = '\0'; +} + +/* len is in semi-octets */ +static char * +sms_decode_address (const guint8 *address, int len) +{ + guint8 addrtype, addrplan; + char *utf8; + + addrtype = address[0] & SMS_NUMBER_TYPE_MASK; + addrplan = address[0] & SMS_NUMBER_PLAN_MASK; + address++; + + if (addrtype == SMS_NUMBER_TYPE_ALPHA) { + guint8 *unpacked; + guint32 unpacked_len; + unpacked = gsm_unpack (address, (len * 4) / 7, 0, &unpacked_len); + utf8 = (char *)mm_charset_gsm_unpacked_to_utf8 (unpacked, + unpacked_len); + g_free(unpacked); + } else if (addrtype == SMS_NUMBER_TYPE_INTL && + addrplan == SMS_NUMBER_PLAN_TELEPHONE) { + /* International telphone number, format as "+1234567890" */ + utf8 = g_malloc (len + 3); /* '+' + digits + possible trailing 0xf + NUL */ + utf8[0] = '+'; + sms_semi_octets_to_bcd_string (utf8 + 1, address, (len + 1) / 2); + } else { + /* + * All non-alphanumeric types and plans are just digits, but + * don't apply any special formatting if we don't know the + * format. + */ + utf8 = g_malloc (len + 2); /* digits + possible trailing 0xf + NUL */ + sms_semi_octets_to_bcd_string (utf8, address, (len + 1) / 2); + } + + return utf8; +} + + +static char * +sms_decode_timestamp (const guint8 *timestamp) +{ + /* YYMMDDHHMMSS+ZZ */ + char *timestr; + int quarters, hours; + + timestr = g_malloc0 (16); + sms_semi_octets_to_bcd_string (timestr, timestamp, 6); + quarters = ((timestamp[6] & 0x7) * 10) + ((timestamp[6] >> 4) & 0xf); + hours = quarters / 4; + if (timestamp[6] & 0x08) + timestr[12] = '-'; + else + timestr[12] = '+'; + timestr[13] = (hours / 10) + '0'; + timestr[14] = (hours % 10) + '0'; + /* TODO(njw): Change timestamp rep to something that includes quarter-hours */ + return timestr; +} + +static char * +sms_decode_text (const guint8 *text, int len, int dcs, int bit_offset) +{ + char *utf8; + guint8 coding = dcs & SMS_DCS_CODING_MASK; + guint8 *unpacked; + guint32 unpacked_len; + + if (coding == SMS_DCS_CODING_DEFAULT) { + unpacked = gsm_unpack ((const guint8 *) text, len, bit_offset, &unpacked_len); + utf8 = (char *) mm_charset_gsm_unpacked_to_utf8 (unpacked, unpacked_len); + g_free (unpacked); + } else if (coding == SMS_DCS_CODING_UCS2) + utf8 = g_convert ((char *) text, len, "UTF8", "UCS-2BE", NULL, NULL, NULL); + else if (coding == SMS_DCS_CODING_8BIT) + utf8 = g_strndup ((const char *)text, len); + else + utf8 = g_strdup (""); + + return utf8; +} + +static void +simple_free_gvalue (gpointer data) +{ + g_value_unset ((GValue *) data); + g_slice_free (GValue, data); +} + + + +static GValue * +simple_uint_value (guint32 i) +{ + GValue *val; + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, i); + + return val; +} + +static GValue * +simple_boolean_value (gboolean b) +{ + GValue *val; + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_BOOLEAN); + g_value_set_boolean (val, b); + + return val; +} + +static GValue * +simple_string_value (const char *str) +{ + GValue *val; + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, str); + + 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, + sender_addr_num_digits, sender_addr_num_octets, + tp_pid_offset, tp_dcs_offset, user_data_offset, user_data_len, + user_data_len_offset, user_data_dcs, bit_offset; + char *smsc_addr, *sender_addr, *sc_timestamp, *msg_text; + + /* Convert PDU from hex to binary */ + pdu = (guint8 *) utils_hexstr2bin (hexpdu, &pdu_len); + if (!pdu) { + *error = g_error_new_literal (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "Couldn't parse PDU of SMS GET response from hex"); + return NULL; + } + + /* SMSC, in address format, precedes the TPDU */ + smsc_addr_num_octets = pdu[0]; + variable_length_items = smsc_addr_num_octets; + if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) { + *error = g_error_new (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "PDU too short (1): %zd vs %d", pdu_len, + variable_length_items + SMS_MIN_PDU_LEN); + g_free (pdu); + return NULL; + } + + /* where in the PDU the actual SMS protocol message begins */ + msg_start_offset = 1 + smsc_addr_num_octets; + sender_addr_num_digits = pdu[msg_start_offset + 1]; + /* + * round the sender address length up to an even number of + * semi-octets, and thus an integral number of octets + */ + sender_addr_num_octets = (sender_addr_num_digits + 1) >> 1; + variable_length_items += sender_addr_num_octets; + if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) { + *error = g_error_new (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "PDU too short (2): %zd vs %d", pdu_len, + variable_length_items + SMS_MIN_PDU_LEN); + g_free (pdu); + return NULL; + } + + tp_pid_offset = msg_start_offset + 3 + sender_addr_num_octets; + tp_dcs_offset = tp_pid_offset + 1; + + user_data_len_offset = tp_dcs_offset + 1 + SMS_TIMESTAMP_LEN; + user_data_offset = user_data_len_offset + 1; + user_data_len = pdu[user_data_len_offset]; + user_data_dcs = pdu[tp_dcs_offset]; + if ((user_data_dcs & SMS_DCS_CODING_MASK) == SMS_DCS_CODING_DEFAULT) + variable_length_items += (7 * (user_data_len + 1 )) / 8; + else + variable_length_items += user_data_len; + if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) { + *error = g_error_new (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "PDU too short (3): %zd vs %d", pdu_len, + variable_length_items + SMS_MIN_PDU_LEN); + g_free (pdu); + return NULL; + } + + /* Only handle SMS-DELIVER */ + if ((pdu[msg_start_offset] & SMS_TP_MTI_MASK) != SMS_TP_MTI_SMS_DELIVER) { + *error = g_error_new (MM_MODEM_ERROR, + MM_MODEM_ERROR_GENERAL, + "Unhandled message type: 0x%02x", + pdu[msg_start_offset]); + g_free (pdu); + return NULL; + } + + smsc_addr = sms_decode_address (&pdu[1], 2 * (pdu[0] - 1)); + sender_addr = sms_decode_address (&pdu[msg_start_offset + 2], + pdu[msg_start_offset + 1]); + sc_timestamp = sms_decode_timestamp (&pdu[tp_dcs_offset + 1]); + bit_offset = 0; + if (pdu[msg_start_offset] & SMS_TP_UDHI) { + /* + * Skip over the user data headers to prevent it from being + * decoded into garbage text. + */ + int udhl; + udhl = pdu[user_data_offset] + 1; + user_data_offset += udhl; + if ((user_data_dcs & SMS_DCS_CODING_MASK) == SMS_DCS_CODING_DEFAULT) { + bit_offset = 7 - (udhl * 8) % 7; + user_data_len -= (udhl * 8 + bit_offset) / 7; + } else + user_data_len -= udhl; + } + + msg_text = sms_decode_text (&pdu[user_data_offset], user_data_len, + user_data_dcs, bit_offset); + + properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, + simple_free_gvalue); + g_hash_table_insert (properties, "number", + simple_string_value (sender_addr)); + g_hash_table_insert (properties, "text", + simple_string_value (msg_text)); + g_hash_table_insert (properties, "smsc", + simple_string_value (smsc_addr)); + g_hash_table_insert (properties, "timestamp", + simple_string_value (sc_timestamp)); + if (user_data_dcs & SMS_DCS_CLASS_VALID) + g_hash_table_insert (properties, "class", + simple_uint_value (user_data_dcs & + SMS_DCS_CLASS_MASK)); + g_hash_table_insert (properties, "completed", simple_boolean_value (TRUE)); + + g_free (smsc_addr); + g_free (sender_addr); + g_free (sc_timestamp); + g_free (msg_text); + g_free (pdu); + + + return properties; +} diff --git a/src/mm-sms-utils.h b/src/mm-sms-utils.h new file mode 100644 index 00000000..26d9829b --- /dev/null +++ b/src/mm-sms-utils.h @@ -0,0 +1,25 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2010 Red Hat, Inc. + */ + +#ifndef MM_SMS_UTILS_H +#define MM_SMS_UTILS_H + +#include <glib.h> + +#define SMS_MAX_PDU_LEN 344 + +GHashTable *sms_parse_pdu (const char *hexpdu, GError **error); + +#endif /* MM_SMS_UTILS_H */ |