sms: create SMS parts only when storing or sending
When a user creates an SMS object, we will expose all its properties in DBus properly, but we will not create the internal list of SMS parts. The list of SMS parts will be created when the SMS is stored or sent, whatever comes first. When the message is sent and it was previously stored, the list of parts is not re-created. If the message requires multiple parts, the multipart reference is computed as follows: * If the SMS was not stored and is being sent, we just use a random number. * If the SMS is being stored, we will use a multipart reference which is not being used already in another SMS to the same destination.
This commit is contained in:
@@ -31,6 +31,54 @@ static GQuark storage_context_quark;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint8
|
||||
mm_iface_modem_messaging_get_local_multipart_reference (MMIfaceModemMessaging *self,
|
||||
const gchar *number,
|
||||
GError **error)
|
||||
{
|
||||
MMSmsList *list = NULL;
|
||||
guint8 reference;
|
||||
guint8 first;
|
||||
|
||||
/* Start by looking for a random number */
|
||||
reference = g_random_int_range (1,255);
|
||||
|
||||
/* Then, look for the given reference in user-created messages */
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_MESSAGING_SMS_LIST, &list,
|
||||
NULL);
|
||||
if (!list)
|
||||
return reference;
|
||||
|
||||
first = reference;
|
||||
do {
|
||||
if (!mm_sms_list_has_local_multipart_reference (list, number, reference)) {
|
||||
g_object_unref (list);
|
||||
return reference;
|
||||
}
|
||||
|
||||
if (reference == 255)
|
||||
reference = 1;
|
||||
else
|
||||
reference++;
|
||||
}
|
||||
while (reference != first);
|
||||
|
||||
g_object_unref (list);
|
||||
|
||||
/* We were not able to find a new valid multipart reference :/
|
||||
* return an error */
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_TOO_MANY,
|
||||
"Cannot create multipart SMS: No valid multipart reference "
|
||||
"available for destination number '%s'",
|
||||
number);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
mm_iface_modem_messaging_bind_simple_status (MMIfaceModemMessaging *self,
|
||||
MMSimpleStatus *status)
|
||||
|
@@ -176,4 +176,9 @@ gboolean mm_iface_modem_messaging_is_storage_supported_for_receiving (MMIfaceMod
|
||||
/* SMS creation */
|
||||
MMSms *mm_iface_modem_messaging_create_sms (MMIfaceModemMessaging *self);
|
||||
|
||||
/* Look for a new valid multipart reference */
|
||||
guint8 mm_iface_modem_messaging_get_local_multipart_reference (MMIfaceModemMessaging *self,
|
||||
const gchar *number,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_IFACE_MODEM_MESSAGING_H */
|
||||
|
@@ -54,6 +54,35 @@ struct _MMSmsListPrivate {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
mm_sms_list_has_local_multipart_reference (MMSmsList *self,
|
||||
const gchar *number,
|
||||
guint8 reference)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
/* No one should look for multipart reference 0, which isn't valid */
|
||||
g_assert (reference != 0);
|
||||
|
||||
for (l = self->priv->list; l; l = g_list_next (l)) {
|
||||
MMSms *sms = MM_SMS (l->data);
|
||||
|
||||
if (mm_sms_is_multipart (sms) &&
|
||||
mm_gdbus_sms_get_pdu_type (MM_GDBUS_SMS (sms)) == MM_SMS_PDU_TYPE_SUBMIT &&
|
||||
mm_sms_get_storage (sms) != MM_SMS_STORAGE_UNKNOWN &&
|
||||
mm_sms_get_multipart_reference (sms) == reference &&
|
||||
g_str_equal (mm_gdbus_sms_get_number (MM_GDBUS_SMS (sms)), number)) {
|
||||
/* Yes, the SMS list has an SMS with the same destination number
|
||||
* and multipart reference */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint
|
||||
mm_sms_list_get_count (MMSmsList *self)
|
||||
{
|
||||
|
@@ -82,4 +82,8 @@ gboolean mm_sms_list_delete_sms_finish (MMSmsList *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
gboolean mm_sms_list_has_local_multipart_reference (MMSmsList *self,
|
||||
const gchar *number,
|
||||
guint8 reference);
|
||||
|
||||
#endif /* MM_SMS_LIST_H */
|
||||
|
@@ -1255,7 +1255,8 @@ mm_sms_part_util_split_text (const gchar *text,
|
||||
}
|
||||
|
||||
GByteArray **
|
||||
mm_sms_part_util_split_data (const GByteArray *data)
|
||||
mm_sms_part_util_split_data (const guint8 *data,
|
||||
gsize data_len)
|
||||
{
|
||||
GByteArray **out;
|
||||
|
||||
@@ -1267,25 +1268,25 @@ mm_sms_part_util_split_data (const GByteArray *data)
|
||||
* bytes each, as we need place for the UDH header.
|
||||
*/
|
||||
|
||||
if (data->len <= 140) {
|
||||
if (data_len <= 140) {
|
||||
out = g_new0 (GByteArray *, 2);
|
||||
out[0] = g_byte_array_append (g_byte_array_sized_new (data->len),
|
||||
data->data,
|
||||
data->len);
|
||||
out[0] = g_byte_array_append (g_byte_array_sized_new (data_len),
|
||||
data,
|
||||
data_len);
|
||||
} else {
|
||||
guint n_chunks;
|
||||
guint i;
|
||||
guint j;
|
||||
|
||||
n_chunks = data->len / 134;
|
||||
if (data->len % 134 != 0)
|
||||
n_chunks = data_len / 134;
|
||||
if (data_len % 134 != 0)
|
||||
n_chunks ++;
|
||||
|
||||
out = g_new0 (GByteArray *, n_chunks + 1);
|
||||
for (i = 0, j = 0; i < n_chunks; i++, j+= 134) {
|
||||
out[i] = g_byte_array_append (g_byte_array_sized_new (134),
|
||||
&data->data[j],
|
||||
MIN (data->len - j, 134));
|
||||
&data[j],
|
||||
MIN (data_len - j, 134));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -138,6 +138,7 @@ guint mm_sms_part_encode_address (const gchar *address,
|
||||
gchar **mm_sms_part_util_split_text (const gchar *text,
|
||||
MMSmsEncoding *encoding);
|
||||
|
||||
GByteArray **mm_sms_part_util_split_data (const GByteArray *data);
|
||||
GByteArray **mm_sms_part_util_split_data (const guint8 *data,
|
||||
gsize data_len);
|
||||
|
||||
#endif /* MM_SMS_PART_H */
|
||||
|
357
src/mm-sms.c
357
src/mm-sms.c
@@ -70,6 +70,128 @@ struct _MMSmsPrivate {
|
||||
gboolean is_assembled;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
generate_submit_pdus (MMSms *self,
|
||||
GError **error)
|
||||
{
|
||||
guint i;
|
||||
guint n_parts;
|
||||
|
||||
const gchar *text;
|
||||
GVariant *data_variant;
|
||||
const guint8 *data;
|
||||
gsize data_len = 0;
|
||||
|
||||
MMSmsEncoding encoding;
|
||||
gchar **split_text = NULL;
|
||||
GByteArray **split_data = NULL;
|
||||
|
||||
g_assert (self->priv->parts == NULL);
|
||||
|
||||
text = mm_gdbus_sms_get_text (MM_GDBUS_SMS (self));
|
||||
data_variant = mm_gdbus_sms_get_data (MM_GDBUS_SMS (self));
|
||||
data = (data_variant ?
|
||||
g_variant_get_fixed_array (data_variant,
|
||||
&data_len,
|
||||
sizeof (guchar)) :
|
||||
NULL);
|
||||
|
||||
g_assert (text != NULL || data != NULL);
|
||||
g_assert (!(text != NULL && data != NULL));
|
||||
|
||||
if (text) {
|
||||
split_text = mm_sms_part_util_split_text (text, &encoding);
|
||||
if (!split_text) {
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_INVALID_ARGS,
|
||||
"Cannot create SMS: cannot process input text");
|
||||
return FALSE;
|
||||
}
|
||||
n_parts = g_strv_length (split_text);
|
||||
} else if (data) {
|
||||
encoding = MM_SMS_ENCODING_8BIT;
|
||||
split_data = mm_sms_part_util_split_data (data, data_len);
|
||||
g_assert (split_data != NULL);
|
||||
/* noop within the for */
|
||||
for (n_parts = 0; split_data[n_parts]; n_parts++);
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
|
||||
g_assert (split_text != NULL || split_data != NULL);
|
||||
g_assert (!(split_text != NULL && split_data != NULL));
|
||||
|
||||
/* Loop text/data chunks */
|
||||
i = 0;
|
||||
while (1) {
|
||||
MMSmsPart *part;
|
||||
gchar *part_text = NULL;
|
||||
GByteArray *part_data = NULL;
|
||||
|
||||
if (split_text) {
|
||||
if (!split_text[i])
|
||||
break;
|
||||
part_text = split_text[i];
|
||||
mm_dbg (" Processing chunk '%u' of text with '%u' bytes",
|
||||
i, (guint) strlen (part_text));
|
||||
} else if (split_data) {
|
||||
if (!split_data[i])
|
||||
break;
|
||||
part_data = split_data[i];
|
||||
mm_dbg (" Processing chunk '%u' of data with '%u' bytes",
|
||||
i, part_data->len);
|
||||
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
|
||||
/* Create new part */
|
||||
part = mm_sms_part_new (SMS_PART_INVALID_INDEX, MM_SMS_PDU_TYPE_SUBMIT);
|
||||
mm_sms_part_take_text (part, part_text);
|
||||
mm_sms_part_take_data (part, part_data);
|
||||
mm_sms_part_set_encoding (part, encoding);
|
||||
mm_sms_part_set_number (part, mm_gdbus_sms_get_number (MM_GDBUS_SMS (self)));
|
||||
mm_sms_part_set_smsc (part, mm_gdbus_sms_get_smsc (MM_GDBUS_SMS (self)));
|
||||
mm_sms_part_set_validity (part, mm_gdbus_sms_get_validity (MM_GDBUS_SMS (self)));
|
||||
mm_sms_part_set_class (part, mm_gdbus_sms_get_class (MM_GDBUS_SMS (self)));
|
||||
mm_sms_part_set_delivery_report_request (part, mm_gdbus_sms_get_delivery_report_request (MM_GDBUS_SMS (self)));
|
||||
|
||||
if (n_parts > 1) {
|
||||
mm_sms_part_set_concat_reference (part, 0); /* We don't set a concat reference here */
|
||||
mm_sms_part_set_concat_sequence (part, i + 1);
|
||||
mm_sms_part_set_concat_max (part, n_parts);
|
||||
|
||||
mm_dbg ("Created SMS part '%u' for multipart SMS ('%u' parts expected)",
|
||||
i + 1, n_parts);
|
||||
} else {
|
||||
mm_dbg ("Created SMS part for singlepart SMS");
|
||||
}
|
||||
|
||||
/* Add to the list of parts */
|
||||
self->priv->parts = g_list_append (self->priv->parts, part);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Free array (not contents, which were taken for the part) */
|
||||
if (split_text)
|
||||
g_free (split_text);
|
||||
if (split_data)
|
||||
g_free (split_data);
|
||||
|
||||
/* Set additional multipart specific properties */
|
||||
if (n_parts > 1) {
|
||||
self->priv->is_multipart = TRUE;
|
||||
self->priv->max_parts = n_parts;
|
||||
}
|
||||
|
||||
/* No more parts are expected */
|
||||
self->priv->is_assembled = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Store SMS (DBus call handling) */
|
||||
|
||||
@@ -111,6 +233,40 @@ handle_store_ready (MMSms *self,
|
||||
handle_store_context_free (ctx);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
prepare_sms_to_be_stored (MMSms *self,
|
||||
GError **error)
|
||||
{
|
||||
GList *l;
|
||||
guint8 reference;
|
||||
|
||||
g_assert (self->priv->parts == NULL);
|
||||
|
||||
/* Look for a valid multipart reference to use. When storing, we need to
|
||||
* check whether we have already stored multipart SMS with the same
|
||||
* reference and destination number */
|
||||
reference = (mm_iface_modem_messaging_get_local_multipart_reference (
|
||||
MM_IFACE_MODEM_MESSAGING (self->priv->modem),
|
||||
mm_gdbus_sms_get_number (MM_GDBUS_SMS (self)),
|
||||
error));
|
||||
if (!reference ||
|
||||
!generate_submit_pdus (self, error)) {
|
||||
g_prefix_error (error, "Cannot prepare SMS to be stored: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If the message is a multipart message, we need to set a proper
|
||||
* multipart reference. When sending a message which wasn't stored
|
||||
* yet, we can just get a random multipart reference. */
|
||||
self->priv->multipart_reference = reference;
|
||||
for (l = self->priv->parts; l; l = g_list_next (l)) {
|
||||
mm_sms_part_set_concat_reference ((MMSmsPart *)l->data,
|
||||
self->priv->multipart_reference);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_store_auth_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
@@ -151,6 +307,13 @@ handle_store_auth_ready (MMBaseModem *modem,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prepare the SMS to be stored, creating the PDU list if required */
|
||||
if (!prepare_sms_to_be_stored (ctx->self, &error)) {
|
||||
g_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
handle_store_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If not stored, check if we do support doing it */
|
||||
if (!MM_SMS_GET_CLASS (ctx->self)->store ||
|
||||
!MM_SMS_GET_CLASS (ctx->self)->store_finish) {
|
||||
@@ -245,6 +408,32 @@ handle_send_ready (MMSms *self,
|
||||
handle_send_context_free (ctx);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
prepare_sms_to_be_sent (MMSms *self,
|
||||
GError **error)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
if (self->priv->parts)
|
||||
return TRUE;
|
||||
|
||||
if (!generate_submit_pdus (self, error)) {
|
||||
g_prefix_error (error, "Cannot prepare SMS to be sent: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If the message is a multipart message, we need to set a proper
|
||||
* multipart reference. When sending a message which wasn't stored
|
||||
* yet, we can just get a random multipart reference. */
|
||||
self->priv->multipart_reference = g_random_int_range (1,255);
|
||||
for (l = self->priv->parts; l; l = g_list_next (l)) {
|
||||
mm_sms_part_set_concat_reference ((MMSmsPart *)l->data,
|
||||
self->priv->multipart_reference);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_send_auth_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
@@ -281,6 +470,13 @@ handle_send_auth_ready (MMBaseModem *modem,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prepare the SMS to be sent, creating the PDU list if required */
|
||||
if (!prepare_sms_to_be_sent (ctx->self, &error)) {
|
||||
g_dbus_method_invocation_take_error (ctx->invocation, error);
|
||||
handle_send_context_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if we do support doing it */
|
||||
if (!MM_SMS_GET_CLASS (ctx->self)->send ||
|
||||
!MM_SMS_GET_CLASS (ctx->self)->send_finish) {
|
||||
@@ -1439,13 +1635,11 @@ mm_sms_new_from_properties (MMBaseModem *modem,
|
||||
MMSmsProperties *properties,
|
||||
GError **error)
|
||||
{
|
||||
MMSmsPart *part;
|
||||
guint n_parts;
|
||||
MMSms *self;
|
||||
const gchar *text;
|
||||
MMSmsEncoding encoding;
|
||||
gchar **split_text = NULL;
|
||||
GByteArray *data;
|
||||
GByteArray **split_data = NULL;
|
||||
|
||||
g_assert (MM_IS_IFACE_MODEM_MESSAGING (modem));
|
||||
|
||||
text = mm_sms_properties_get_text (properties);
|
||||
data = mm_sms_properties_peek_data_bytearray (properties);
|
||||
@@ -1471,138 +1665,31 @@ mm_sms_new_from_properties (MMBaseModem *modem,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (text) {
|
||||
split_text = mm_sms_part_util_split_text (text, &encoding);
|
||||
if (!split_text) {
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_INVALID_ARGS,
|
||||
"Cannot create SMS: cannot process input text");
|
||||
return NULL;
|
||||
}
|
||||
n_parts = g_strv_length (split_text);
|
||||
} else if (data) {
|
||||
encoding = MM_SMS_ENCODING_8BIT;
|
||||
split_data = mm_sms_part_util_split_data (data);
|
||||
g_assert (split_data != NULL);
|
||||
/* noop within the for */
|
||||
for (n_parts = 0; split_data[n_parts]; n_parts++);
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
/* Create an SMS object as defined by the interface */
|
||||
self = mm_iface_modem_messaging_create_sms (MM_IFACE_MODEM_MESSAGING (modem));
|
||||
g_object_set (self,
|
||||
"state", MM_SMS_STATE_UNKNOWN,
|
||||
"storage", MM_SMS_STORAGE_UNKNOWN,
|
||||
"number", mm_sms_properties_get_number (properties),
|
||||
"pdu-type", MM_SMS_PDU_TYPE_SUBMIT,
|
||||
"text", text,
|
||||
"data", (data ?
|
||||
g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
|
||||
data->data,
|
||||
data->len * sizeof (guint8),
|
||||
TRUE,
|
||||
(GDestroyNotify) g_byte_array_unref,
|
||||
g_byte_array_ref (data)) :
|
||||
NULL),
|
||||
"smsc", mm_sms_properties_get_smsc (properties),
|
||||
"class", mm_sms_properties_get_class (properties),
|
||||
"delivery-report-request", mm_sms_properties_get_delivery_report_request (properties),
|
||||
NULL);
|
||||
|
||||
if (n_parts > 1) {
|
||||
MMSms *sms = NULL;
|
||||
guint i = 0;
|
||||
/* wtf... is this really the way to go? */
|
||||
guint reference = g_random_int_range (1,255);
|
||||
/* Only export once properly created */
|
||||
mm_sms_export (self);
|
||||
|
||||
g_assert (split_text != NULL || split_data != NULL);
|
||||
g_assert (!(split_text != NULL && split_data != NULL));
|
||||
|
||||
/* Loop text/data chunks */
|
||||
while (1) {
|
||||
gchar *part_text = NULL;
|
||||
GByteArray *part_data = NULL;
|
||||
|
||||
if (split_text) {
|
||||
if (!split_text[i])
|
||||
break;
|
||||
part_text = split_text[i];
|
||||
split_text[i] = NULL;
|
||||
mm_dbg (" Processing chunk '%u' of text with '%u' bytes",
|
||||
i, (guint) strlen (part_text));
|
||||
} else if (split_data) {
|
||||
if (!split_data[i])
|
||||
break;
|
||||
part_data = split_data[i];
|
||||
split_data[i] = NULL;
|
||||
mm_dbg (" Processing chunk '%u' of data with '%u' bytes",
|
||||
i, part_data->len);
|
||||
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
|
||||
/* Create new part */
|
||||
part = mm_sms_part_new (SMS_PART_INVALID_INDEX,
|
||||
MM_SMS_PDU_TYPE_SUBMIT);
|
||||
mm_sms_part_take_text (part, part_text);
|
||||
mm_sms_part_take_data (part, part_data);
|
||||
mm_sms_part_set_encoding (part, encoding);
|
||||
mm_sms_part_set_number (part, mm_sms_properties_get_number (properties));
|
||||
mm_sms_part_set_smsc (part, mm_sms_properties_get_smsc (properties));
|
||||
mm_sms_part_set_validity (part, mm_sms_properties_get_validity (properties));
|
||||
mm_sms_part_set_class (part, mm_sms_properties_get_class (properties));
|
||||
mm_sms_part_set_delivery_report_request (part, mm_sms_properties_get_delivery_report_request (properties));
|
||||
mm_sms_part_set_concat_reference (part, reference);
|
||||
mm_sms_part_set_concat_sequence (part, i + 1);
|
||||
mm_sms_part_set_concat_max (part, n_parts);
|
||||
|
||||
if (!sms) {
|
||||
mm_dbg ("Building user-created multipart SMS... (%u parts expected)", n_parts);
|
||||
sms = mm_sms_multipart_new (
|
||||
modem,
|
||||
MM_SMS_STATE_UNKNOWN,
|
||||
MM_SMS_STORAGE_UNKNOWN, /* not stored anywhere yet */
|
||||
reference,
|
||||
n_parts,
|
||||
part,
|
||||
error);
|
||||
if (!sms)
|
||||
break;
|
||||
} else if (!mm_sms_multipart_take_part (sms, part, error)) {
|
||||
g_clear_object (&sms);
|
||||
break;
|
||||
}
|
||||
|
||||
mm_dbg (" Added part '%u' to multipart SMS...", i + 1);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Rewalk the arrays and remove any remaining text/data not set after an error */
|
||||
if (split_text) {
|
||||
for (i = 0; i < n_parts; i++) {
|
||||
if (split_text[i])
|
||||
g_free (split_text[i]);
|
||||
}
|
||||
|
||||
g_free (split_text);
|
||||
}
|
||||
else if (split_data) {
|
||||
for (i = 0; i < n_parts; i++) {
|
||||
if (split_data[i])
|
||||
g_byte_array_unref (split_data[i]);
|
||||
}
|
||||
g_free (split_data);
|
||||
}
|
||||
|
||||
return sms;
|
||||
}
|
||||
|
||||
/* Single part it will be */
|
||||
part = mm_sms_part_new (SMS_PART_INVALID_INDEX,
|
||||
MM_SMS_PDU_TYPE_SUBMIT);
|
||||
|
||||
if (split_text) {
|
||||
mm_sms_part_take_text (part, split_text[0]);
|
||||
g_free (split_text);
|
||||
} else if (split_data) {
|
||||
mm_sms_part_take_data (part, split_data[0]);
|
||||
g_free (split_data);
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
|
||||
mm_sms_part_set_encoding (part, encoding);
|
||||
mm_sms_part_set_number (part, mm_sms_properties_get_number (properties));
|
||||
mm_sms_part_set_smsc (part, mm_sms_properties_get_smsc (properties));
|
||||
mm_sms_part_set_validity (part, mm_sms_properties_get_validity (properties));
|
||||
mm_sms_part_set_class (part, mm_sms_properties_get_class (properties));
|
||||
mm_sms_part_set_delivery_report_request (part, mm_sms_properties_get_delivery_report_request (properties));
|
||||
|
||||
return mm_sms_singlepart_new (modem,
|
||||
MM_SMS_STATE_UNKNOWN,
|
||||
MM_SMS_STORAGE_UNKNOWN, /* not stored anywhere yet */
|
||||
part,
|
||||
error);
|
||||
return self;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
Reference in New Issue
Block a user