summaryrefslogtreecommitdiff
path: root/src/mm-base-sms.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-base-sms.c')
-rw-r--r--src/mm-base-sms.c533
1 files changed, 306 insertions, 227 deletions
diff --git a/src/mm-base-sms.c b/src/mm-base-sms.c
index bc38a1c5..1c291daf 100644
--- a/src/mm-base-sms.c
+++ b/src/mm-base-sms.c
@@ -33,10 +33,13 @@
#include "mm-sms-part-3gpp.h"
#include "mm-base-modem-at.h"
#include "mm-base-modem.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
#include "mm-modem-helpers.h"
-G_DEFINE_TYPE (MMBaseSms, mm_base_sms, MM_GDBUS_TYPE_SMS_SKELETON)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMBaseSms, mm_base_sms, MM_GDBUS_TYPE_SMS_SKELETON, 0,
+ G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
enum {
PROP_0,
@@ -54,6 +57,8 @@ static GParamSpec *properties[PROP_LAST];
struct _MMBaseSmsPrivate {
/* The connection to the system bus */
GDBusConnection *connection;
+ guint dbus_id;
+
/* The modem which owns this SMS */
MMBaseModem *modem;
/* The path where the SMS object is exported */
@@ -124,7 +129,7 @@ generate_3gpp_submit_pdus (MMBaseSms *self,
g_assert (!(text != NULL && data != NULL));
if (text) {
- split_text = mm_sms_part_3gpp_util_split_text (text, &encoding);
+ split_text = mm_sms_part_3gpp_util_split_text (text, &encoding, self);
if (!split_text) {
g_set_error (error,
MM_CORE_ERROR,
@@ -149,8 +154,7 @@ generate_3gpp_submit_pdus (MMBaseSms *self,
if (split_text)
g_strfreev (split_text);
else if (split_data) {
- guint i = 0;
-
+ i = 0;
while (split_data[i])
g_byte_array_unref (split_data[i++]);
g_free (split_data);
@@ -174,14 +178,14 @@ generate_3gpp_submit_pdus (MMBaseSms *self,
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));
+ mm_obj_dbg (self, " 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);
+ mm_obj_dbg (self, " processing chunk '%u' of data with '%u' bytes",
+ i, part_data->len);
} else
g_assert_not_reached ();
@@ -201,11 +205,9 @@ generate_3gpp_submit_pdus (MMBaseSms *self,
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);
+ mm_obj_dbg (self, "created SMS part '%u' for multipart SMS ('%u' parts expected)", i + 1, n_parts);
} else {
- mm_dbg ("Created SMS part for singlepart SMS");
+ mm_obj_dbg (self, "created SMS part for singlepart SMS");
}
/* Add to the list of parts */
@@ -215,10 +217,8 @@ generate_3gpp_submit_pdus (MMBaseSms *self,
}
/* Free array (not contents, which were taken for the part) */
- if (split_text)
- g_free (split_text);
- if (split_data)
- g_free (split_data);
+ g_free (split_text);
+ g_free (split_data);
/* Set additional multipart specific properties */
if (n_parts > 1) {
@@ -273,14 +273,14 @@ generate_cdma_submit_pdus (MMBaseSms *self,
/* If creating a CDMA SMS part but we don't have a Teleservice ID, we default to WMT */
if (mm_gdbus_sms_get_teleservice_id (MM_GDBUS_SMS (self)) == MM_SMS_CDMA_TELESERVICE_ID_UNKNOWN) {
- mm_dbg ("Defaulting to WMT teleservice ID when creating SMS part");
+ mm_obj_dbg (self, "defaulting to WMT teleservice ID when creating SMS part");
mm_sms_part_set_cdma_teleservice_id (part, MM_SMS_CDMA_TELESERVICE_ID_WMT);
} else
mm_sms_part_set_cdma_teleservice_id (part, mm_gdbus_sms_get_teleservice_id (MM_GDBUS_SMS (self)));
mm_sms_part_set_cdma_service_category (part, mm_gdbus_sms_get_service_category (MM_GDBUS_SMS (self)));
- mm_dbg ("Created SMS part for CDMA SMS");
+ mm_obj_dbg (self, "created SMS part for CDMA SMS");
/* Add to the list of parts */
self->priv->parts = g_list_append (self->priv->parts, part);
@@ -653,10 +653,9 @@ handle_send (MMBaseSms *self,
void
mm_base_sms_export (MMBaseSms *self)
{
- static guint id = 0;
gchar *path;
- path = g_strdup_printf (MM_DBUS_SMS_PREFIX "/%d", id++);
+ path = g_strdup_printf (MM_DBUS_SMS_PREFIX "/%d", self->priv->dbus_id);
g_object_set (self,
MM_BASE_SMS_PATH, path,
NULL);
@@ -692,9 +691,7 @@ sms_dbus_export (MMBaseSms *self)
self->priv->connection,
self->priv->path,
&error)) {
- mm_warn ("couldn't export SMS at '%s': '%s'",
- self->priv->path,
- error->message);
+ mm_obj_warn (self, "couldn't export SMS: %s", error->message);
g_error_free (error);
}
}
@@ -774,12 +771,13 @@ mm_base_sms_get_parts (MMBaseSms *self)
/*****************************************************************************/
static gboolean
-sms_get_store_or_send_command (MMSmsPart *part,
- gboolean text_or_pdu, /* TRUE for PDU */
- gboolean store_or_send, /* TRUE for send */
- gchar **out_cmd,
- gchar **out_msg_data,
- GError **error)
+sms_get_store_or_send_command (MMBaseSms *self,
+ MMSmsPart *part,
+ gboolean text_or_pdu, /* TRUE for PDU */
+ gboolean store_or_send, /* TRUE for send */
+ gchar **out_cmd,
+ gchar **out_msg_data,
+ GError **error)
{
g_assert (out_cmd != NULL);
g_assert (out_msg_data != NULL);
@@ -798,7 +796,7 @@ sms_get_store_or_send_command (MMSmsPart *part,
/* AT+CMGW=<length>[, <stat>]<CR> PDU can be entered. <CTRL-Z>/<ESC> */
- pdu = mm_sms_part_3gpp_get_submit_pdu (part, &pdulen, &msgstart, error);
+ pdu = mm_sms_part_3gpp_get_submit_pdu (part, &pdulen, &msgstart, self, error);
if (!pdu)
/* 'error' should already be set */
return FALSE;
@@ -830,9 +828,7 @@ sms_get_store_or_send_command (MMSmsPart *part,
/* Store the SMS */
typedef struct {
- MMBaseSms *self;
MMBaseModem *modem;
- GSimpleAsyncResult *result;
MMSmsStorage storage;
gboolean need_unlock;
gboolean use_pdu_mode;
@@ -841,15 +837,12 @@ typedef struct {
} SmsStoreContext;
static void
-sms_store_context_complete_and_free (SmsStoreContext *ctx)
+sms_store_context_free (SmsStoreContext *ctx)
{
- g_simple_async_result_complete (ctx->result);
- g_object_unref (ctx->result);
/* Unlock mem2 storage if we had the lock */
if (ctx->need_unlock)
mm_broadband_modem_unlock_sms_storages (MM_BROADBAND_MODEM (ctx->modem), FALSE, TRUE);
g_object_unref (ctx->modem);
- g_object_unref (ctx->self);
g_free (ctx->msg_data);
g_free (ctx);
}
@@ -859,16 +852,17 @@ sms_store_finish (MMBaseSms *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
-static void sms_store_next_part (SmsStoreContext *ctx);
+static void sms_store_next_part (GTask *task);
static void
store_msg_data_ready (MMBaseModem *modem,
GAsyncResult *res,
- SmsStoreContext *ctx)
+ GTask *task)
{
+ SmsStoreContext *ctx;
const gchar *response;
GError *error = NULL;
gint rv;
@@ -876,81 +870,92 @@ store_msg_data_ready (MMBaseModem *modem,
response = mm_base_modem_at_command_finish (modem, res, &error);
if (error) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_store_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
/* Read the new part index from the reply */
rv = sscanf (response, "+CMGW: %d", &idx);
if (rv != 1 || idx < 0) {
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Couldn't read index of already stored part: "
- "%d fields parsed",
- rv);
- sms_store_context_complete_and_free (ctx);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't read index of already stored part: "
+ "%d fields parsed",
+ rv);
+ g_object_unref (task);
return;
}
+ ctx = g_task_get_task_data (task);
+
/* Set the index in the part we hold */
mm_sms_part_set_index ((MMSmsPart *)ctx->current->data, (guint)idx);
ctx->current = g_list_next (ctx->current);
- sms_store_next_part (ctx);
+ sms_store_next_part (task);
}
static void
store_ready (MMBaseModem *modem,
GAsyncResult *res,
- SmsStoreContext *ctx)
+ GTask *task)
{
- const gchar *response;
+ SmsStoreContext *ctx;
GError *error = NULL;
- response = mm_base_modem_at_command_finish (modem, res, &error);
+ mm_base_modem_at_command_finish (modem, res, &error);
if (error) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_store_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
- /* Send the actual message data */
+ ctx = g_task_get_task_data (task);
+
+ /* Send the actual message data.
+ * We send the data as 'raw' data because we do NOT want it to
+ * be treated as an AT command (i.e. we don't want it prefixed
+ * with AT+ and suffixed with <CR><LF>), plus, we want it to be
+ * sent right away (not queued after other AT commands). */
mm_base_modem_at_command_raw (ctx->modem,
ctx->msg_data,
10,
FALSE,
(GAsyncReadyCallback)store_msg_data_ready,
- ctx);
+ task);
}
static void
-sms_store_next_part (SmsStoreContext *ctx)
+sms_store_next_part (GTask *task)
{
+ MMBaseSms *self;
+ SmsStoreContext *ctx;
gchar *cmd;
GError *error = NULL;
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
if (!ctx->current) {
/* Done we are */
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- sms_store_context_complete_and_free (ctx);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
- if (ctx->msg_data) {
- g_free (ctx->msg_data);
- ctx->msg_data = NULL;
- }
+ g_clear_pointer (&ctx->msg_data, g_free);
- if (!sms_get_store_or_send_command ((MMSmsPart *)ctx->current->data,
+ if (!sms_get_store_or_send_command (self,
+ (MMSmsPart *)ctx->current->data,
ctx->use_pdu_mode,
FALSE,
&cmd,
&ctx->msg_data,
&error)) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_store_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
@@ -962,30 +967,35 @@ sms_store_next_part (SmsStoreContext *ctx)
10,
FALSE,
(GAsyncReadyCallback)store_ready,
- ctx);
+ task);
g_free (cmd);
}
static void
store_lock_sms_storages_ready (MMBroadbandModem *modem,
GAsyncResult *res,
- SmsStoreContext *ctx)
+ GTask *task)
{
+ MMBaseSms *self;
+ SmsStoreContext *ctx;
GError *error = NULL;
if (!mm_broadband_modem_lock_sms_storages_finish (modem, res, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_store_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
/* We are now locked. Whatever result we have here, we need to make sure
* we unlock the storages before finishing. */
ctx->need_unlock = TRUE;
/* Go on to store the parts */
- ctx->current = ctx->self->priv->parts;
- sms_store_next_part (ctx);
+ ctx->current = self->priv->parts;
+ sms_store_next_part (task);
}
static void
@@ -995,14 +1005,10 @@ sms_store (MMBaseSms *self,
gpointer user_data)
{
SmsStoreContext *ctx;
+ GTask *task;
/* Setup the context */
ctx = g_new0 (SmsStoreContext, 1);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- sms_store);
- ctx->self = g_object_ref (self);
ctx->modem = g_object_ref (self->priv->modem);
ctx->storage = storage;
@@ -1011,6 +1017,9 @@ sms_store (MMBaseSms *self,
MM_IFACE_MODEM_MESSAGING_SMS_PDU_MODE, &ctx->use_pdu_mode,
NULL);
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)sms_store_context_free);
+
/* First, lock storage to use */
g_assert (MM_IS_BROADBAND_MODEM (self->priv->modem));
mm_broadband_modem_lock_sms_storages (
@@ -1018,16 +1027,14 @@ sms_store (MMBaseSms *self,
MM_SMS_STORAGE_UNKNOWN, /* none required for mem1 */
ctx->storage,
(GAsyncReadyCallback)store_lock_sms_storages_ready,
- ctx);
+ task);
}
/*****************************************************************************/
/* Send the SMS */
typedef struct {
- MMBaseSms *self;
MMBaseModem *modem;
- GSimpleAsyncResult *result;
gboolean need_unlock;
gboolean from_storage;
gboolean use_pdu_mode;
@@ -1036,15 +1043,12 @@ typedef struct {
} SmsSendContext;
static void
-sms_send_context_complete_and_free (SmsSendContext *ctx)
+sms_send_context_free (SmsSendContext *ctx)
{
- g_simple_async_result_complete_in_idle (ctx->result);
- g_object_unref (ctx->result);
/* Unlock mem2 storage if we had the lock */
if (ctx->need_unlock)
mm_broadband_modem_unlock_sms_storages (MM_BROADBAND_MODEM (ctx->modem), FALSE, TRUE);
g_object_unref (ctx->modem);
- g_object_unref (ctx->self);
g_free (ctx->msg_data);
g_free (ctx);
}
@@ -1054,10 +1058,10 @@ sms_send_finish (MMBaseSms *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
-static void sms_send_next_part (SmsSendContext *ctx);
+static void sms_send_next_part (GTask *task);
static gint
read_message_reference_from_reply (const gchar *response,
@@ -1087,86 +1091,100 @@ read_message_reference_from_reply (const gchar *response,
static void
send_generic_msg_data_ready (MMBaseModem *modem,
GAsyncResult *res,
- SmsSendContext *ctx)
+ GTask *task)
{
+ SmsSendContext *ctx;
GError *error = NULL;
const gchar *response;
gint message_reference;
response = mm_base_modem_at_command_finish (modem, res, &error);
if (error) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_send_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
message_reference = read_message_reference_from_reply (response, &error);
if (error) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_send_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
+ ctx = g_task_get_task_data (task);
+
mm_sms_part_set_message_reference ((MMSmsPart *)ctx->current->data,
(guint)message_reference);
ctx->current = g_list_next (ctx->current);
- sms_send_next_part (ctx);
+ sms_send_next_part (task);
}
static void
send_generic_ready (MMBaseModem *modem,
GAsyncResult *res,
- SmsSendContext *ctx)
+ GTask *task)
{
+ SmsSendContext *ctx;
GError *error = NULL;
mm_base_modem_at_command_finish (modem, res, &error);
if (error) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_send_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
- /* Send the actual message data */
+ ctx = g_task_get_task_data (task);
+
+ /* Send the actual message data.
+ * We send the data as 'raw' data because we do NOT want it to
+ * be treated as an AT command (i.e. we don't want it prefixed
+ * with AT+ and suffixed with <CR><LF>), plus, we want it to be
+ * sent right away (not queued after other AT commands). */
mm_base_modem_at_command_raw (ctx->modem,
ctx->msg_data,
- 10,
+ MM_BASE_SMS_DEFAULT_SEND_TIMEOUT,
FALSE,
(GAsyncReadyCallback)send_generic_msg_data_ready,
- ctx);
+ task);
}
static void
send_from_storage_ready (MMBaseModem *modem,
GAsyncResult *res,
- SmsSendContext *ctx)
+ GTask *task)
{
+ MMBaseSms *self;
+ SmsSendContext *ctx;
GError *error = NULL;
const gchar *response;
gint message_reference;
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
response = mm_base_modem_at_command_finish (modem, res, &error);
if (error) {
if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_send_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
- mm_dbg ("Couldn't send SMS from storage: '%s'; trying generic send...",
- error->message);
+ mm_obj_dbg (self, "couldn't send SMS from storage: %s; trying generic send...", error->message);
g_error_free (error);
ctx->from_storage = FALSE;
- sms_send_next_part (ctx);
+ sms_send_next_part (task);
return;
}
message_reference = read_message_reference_from_reply (response, &error);
if (error) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_send_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
@@ -1174,19 +1192,24 @@ send_from_storage_ready (MMBaseModem *modem,
(guint)message_reference);
ctx->current = g_list_next (ctx->current);
- sms_send_next_part (ctx);
+ sms_send_next_part (task);
}
static void
-sms_send_next_part (SmsSendContext *ctx)
+sms_send_next_part (GTask *task)
{
+ MMBaseSms *self;
+ SmsSendContext *ctx;
GError *error = NULL;
gchar *cmd;
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
if (!ctx->current) {
/* Done we are */
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- sms_send_context_complete_and_free (ctx);
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
@@ -1196,63 +1219,68 @@ sms_send_next_part (SmsSendContext *ctx)
mm_sms_part_get_index ((MMSmsPart *)ctx->current->data));
mm_base_modem_at_command (ctx->modem,
cmd,
- 30,
+ MM_BASE_SMS_DEFAULT_SEND_TIMEOUT,
FALSE,
(GAsyncReadyCallback)send_from_storage_ready,
- ctx);
+ task);
g_free (cmd);
return;
}
/* Generic send */
- if (ctx->msg_data) {
- g_free (ctx->msg_data);
- ctx->msg_data = NULL;
- }
+ g_clear_pointer (&ctx->msg_data, g_free);
- if (!sms_get_store_or_send_command ((MMSmsPart *)ctx->current->data,
+ if (!sms_get_store_or_send_command (self,
+ (MMSmsPart *)ctx->current->data,
ctx->use_pdu_mode,
TRUE,
&cmd,
&ctx->msg_data,
&error)) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_send_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
g_assert (cmd != NULL);
g_assert (ctx->msg_data != NULL);
+
+ /* no network involved in this initial AT command, so lower timeout */
mm_base_modem_at_command (ctx->modem,
cmd,
- 30,
+ 10,
FALSE,
(GAsyncReadyCallback)send_generic_ready,
- ctx);
+ task);
g_free (cmd);
}
static void
send_lock_sms_storages_ready (MMBroadbandModem *modem,
GAsyncResult *res,
- SmsSendContext *ctx)
+ GTask *task)
{
+ MMBaseSms *self;
+ SmsSendContext *ctx;
GError *error = NULL;
if (!mm_broadband_modem_lock_sms_storages_finish (modem, res, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_send_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
/* We are now locked. Whatever result we have here, we need to make sure
* we unlock the storages before finishing. */
ctx->need_unlock = TRUE;
/* Go on to send the parts */
- ctx->current = ctx->self->priv->parts;
- sms_send_next_part (ctx);
+ ctx->current = self->priv->parts;
+ sms_send_next_part (task);
}
static void
@@ -1261,16 +1289,15 @@ sms_send (MMBaseSms *self,
gpointer user_data)
{
SmsSendContext *ctx;
+ GTask *task;
/* Setup the context */
ctx = g_new0 (SmsSendContext, 1);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- sms_send);
- ctx->self = g_object_ref (self);
ctx->modem = g_object_ref (self->priv->modem);
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)sms_send_context_free);
+
/* If the SMS is STORED, try to send from storage */
ctx->from_storage = (mm_base_sms_get_storage (self) != MM_SMS_STORAGE_UNKNOWN);
if (ctx->from_storage) {
@@ -1281,7 +1308,7 @@ sms_send (MMBaseSms *self,
MM_SMS_STORAGE_UNKNOWN, /* none required for mem1 */
mm_base_sms_get_storage (self),
(GAsyncReadyCallback)send_lock_sms_storages_ready,
- ctx);
+ task);
return;
}
@@ -1290,30 +1317,25 @@ sms_send (MMBaseSms *self,
MM_IFACE_MODEM_MESSAGING_SMS_PDU_MODE, &ctx->use_pdu_mode,
NULL);
ctx->current = self->priv->parts;
- sms_send_next_part (ctx);
+ sms_send_next_part (task);
}
/*****************************************************************************/
typedef struct {
- MMBaseSms *self;
MMBaseModem *modem;
- GSimpleAsyncResult *result;
gboolean need_unlock;
GList *current;
guint n_failed;
} SmsDeletePartsContext;
static void
-sms_delete_parts_context_complete_and_free (SmsDeletePartsContext *ctx)
+sms_delete_parts_context_free (SmsDeletePartsContext *ctx)
{
- g_simple_async_result_complete_in_idle (ctx->result);
- g_object_unref (ctx->result);
/* Unlock mem1 storage if we had the lock */
if (ctx->need_unlock)
mm_broadband_modem_unlock_sms_storages (MM_BROADBAND_MODEM (ctx->modem), TRUE, FALSE);
g_object_unref (ctx->modem);
- g_object_unref (ctx->self);
g_free (ctx);
}
@@ -1322,24 +1344,29 @@ sms_delete_finish (MMBaseSms *self,
GAsyncResult *res,
GError **error)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
-static void delete_next_part (SmsDeletePartsContext *ctx);
+static void delete_next_part (GTask *task);
static void
delete_part_ready (MMBaseModem *modem,
GAsyncResult *res,
- SmsDeletePartsContext *ctx)
+ GTask *task)
{
+ MMBaseSms *self;
+ SmsDeletePartsContext *ctx;
GError *error = NULL;
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
mm_base_modem_at_command_finish (modem, res, &error);
if (error) {
ctx->n_failed++;
- mm_dbg ("Couldn't delete SMS part with index %u: '%s'",
- mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
- error->message);
+ mm_obj_dbg (self, "couldn't delete SMS part with index %u: %s",
+ mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
+ error->message);
g_error_free (error);
}
@@ -1347,14 +1374,17 @@ delete_part_ready (MMBaseModem *modem,
mm_sms_part_set_index ((MMSmsPart *)ctx->current->data, SMS_PART_INVALID_INDEX);
ctx->current = g_list_next (ctx->current);
- delete_next_part (ctx);
+ delete_next_part (task);
}
static void
-delete_next_part (SmsDeletePartsContext *ctx)
+delete_next_part (GTask *task)
{
+ SmsDeletePartsContext *ctx;
gchar *cmd;
+ ctx = g_task_get_task_data (task);
+
/* Skip non-stored parts */
while (ctx->current &&
mm_sms_part_get_index ((MMSmsPart *)ctx->current->data) == SMS_PART_INVALID_INDEX)
@@ -1363,15 +1393,15 @@ delete_next_part (SmsDeletePartsContext *ctx)
/* If all removed, we're done */
if (!ctx->current) {
if (ctx->n_failed > 0)
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Couldn't delete %u parts from this SMS",
- ctx->n_failed);
+ g_task_return_new_error (task,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Couldn't delete %u parts from this SMS",
+ ctx->n_failed);
else
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ g_task_return_boolean (task, TRUE);
- sms_delete_parts_context_complete_and_free (ctx);
+ g_object_unref (task);
return;
}
@@ -1382,30 +1412,35 @@ delete_next_part (SmsDeletePartsContext *ctx)
10,
FALSE,
(GAsyncReadyCallback)delete_part_ready,
- ctx);
+ task);
g_free (cmd);
}
static void
delete_lock_sms_storages_ready (MMBroadbandModem *modem,
GAsyncResult *res,
- SmsDeletePartsContext *ctx)
+ GTask *task)
{
+ MMBaseSms *self;
+ SmsDeletePartsContext *ctx;
GError *error = NULL;
if (!mm_broadband_modem_lock_sms_storages_finish (modem, res, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- sms_delete_parts_context_complete_and_free (ctx);
+ g_task_return_error (task, error);
+ g_object_unref (task);
return;
}
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
/* We are now locked. Whatever result we have here, we need to make sure
* we unlock the storages before finishing. */
ctx->need_unlock = TRUE;
/* Go on deleting parts */
- ctx->current = ctx->self->priv->parts;
- delete_next_part (ctx);
+ ctx->current = self->priv->parts;
+ delete_next_part (task);
}
static void
@@ -1414,19 +1449,18 @@ sms_delete (MMBaseSms *self,
gpointer user_data)
{
SmsDeletePartsContext *ctx;
+ GTask *task;
ctx = g_new0 (SmsDeletePartsContext, 1);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- sms_delete);
- ctx->self = g_object_ref (self);
ctx->modem = g_object_ref (self->priv->modem);
+ task = g_task_new (self, NULL, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify)sms_delete_parts_context_free);
+
if (mm_base_sms_get_storage (self) == MM_SMS_STORAGE_UNKNOWN) {
- mm_dbg ("Not removing parts from non-stored SMS");
- g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
- sms_delete_parts_context_complete_and_free (ctx);
+ mm_obj_dbg (self, "not removing parts from non-stored SMS");
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
return;
}
@@ -1436,7 +1470,7 @@ sms_delete (MMBaseSms *self,
mm_base_sms_get_storage (self),
MM_SMS_STORAGE_UNKNOWN, /* none required for mem2 */
(GAsyncReadyCallback)delete_lock_sms_storages_ready,
- ctx);
+ task);
}
/*****************************************************************************/
@@ -1458,13 +1492,13 @@ mm_base_sms_delete_finish (MMBaseSms *self,
return deleted;
}
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ return g_task_propagate_boolean (G_TASK (res), error);
}
void
mm_base_sms_delete (MMBaseSms *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
if (MM_BASE_SMS_GET_CLASS (self)->delete &&
MM_BASE_SMS_GET_CLASS (self)->delete_finish) {
@@ -1472,26 +1506,56 @@ mm_base_sms_delete (MMBaseSms *self,
return;
}
- g_simple_async_report_error_in_idle (G_OBJECT (self),
- callback,
- user_data,
- MM_CORE_ERROR,
- MM_CORE_ERROR_UNSUPPORTED,
- "Deleting SMS is not supported by this modem");
+ g_task_report_new_error (self,
+ callback,
+ user_data,
+ mm_base_sms_delete,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Deleting SMS is not supported by this modem");
}
/*****************************************************************************/
+static void
+initialize_sms (MMBaseSms *self)
+{
+ MMSmsPart *part;
+ guint validity_relative;
+
+ /* Some of the fields of the SMS object may be initialized as soon as we have
+ * one part already available, even if it's not exactly the first one */
+ g_assert (self->priv->parts);
+ part = (MMSmsPart *)(self->priv->parts->data);
+
+ /* Prepare for validity tuple */
+ validity_relative = mm_sms_part_get_validity_relative (part);
+
+ g_object_set (self,
+ "pdu-type", mm_sms_part_get_pdu_type (part),
+ "smsc", mm_sms_part_get_smsc (part),
+ "class", mm_sms_part_get_class (part),
+ "teleservice-id", mm_sms_part_get_cdma_teleservice_id (part),
+ "service-category", mm_sms_part_get_cdma_service_category (part),
+ "number", mm_sms_part_get_number (part),
+ "validity", (validity_relative ?
+ g_variant_new ("(uv)", MM_SMS_VALIDITY_TYPE_RELATIVE, g_variant_new_uint32 (validity_relative)) :
+ g_variant_new ("(uv)", MM_SMS_VALIDITY_TYPE_UNKNOWN, g_variant_new_boolean (FALSE))),
+ "timestamp", mm_sms_part_get_timestamp (part),
+ "discharge-timestamp", mm_sms_part_get_discharge_timestamp (part),
+ "delivery-state", mm_sms_part_get_delivery_state (part),
+ NULL);
+}
+
static gboolean
-assemble_sms (MMBaseSms *self,
- GError **error)
+assemble_sms (MMBaseSms *self,
+ GError **error)
{
- GList *l;
- guint idx;
+ GList *l;
+ guint idx;
MMSmsPart **sorted_parts;
- GString *fulltext;
+ GString *fulltext;
GByteArray *fulldata;
- guint validity_relative;
sorted_parts = g_new0 (MMSmsPart *, self->priv->max_parts);
@@ -1516,12 +1580,12 @@ assemble_sms (MMBaseSms *self,
idx = mm_sms_part_get_concat_sequence ((MMSmsPart *)l->data);
if (idx < 1 || idx > self->priv->max_parts) {
- mm_warn ("Invalid part index (%u) found, ignoring", idx);
+ mm_obj_warn (self, "invalid part index (%u) found, ignoring", idx);
continue;
}
if (sorted_parts[idx - 1]) {
- mm_warn ("Duplicate part index (%u) found, ignoring", idx);
+ mm_obj_warn (self, "duplicate part index (%u) found, ignoring", idx);
continue;
}
@@ -1579,30 +1643,15 @@ assemble_sms (MMBaseSms *self,
/* If we got all parts, we also have the first one always */
g_assert (sorted_parts[0] != NULL);
- /* Prepare for validity tuple */
- validity_relative = mm_sms_part_get_validity_relative (sorted_parts[0]);
-
/* If we got everything, assemble the text! */
g_object_set (self,
- "pdu-type", mm_sms_part_get_pdu_type (sorted_parts[0]),
- "text", fulltext->str,
- "data", g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
- fulldata->data,
- fulldata->len * sizeof (guint8),
- TRUE,
- (GDestroyNotify) g_byte_array_unref,
- g_byte_array_ref (fulldata)),
- "smsc", mm_sms_part_get_smsc (sorted_parts[0]),
- "class", mm_sms_part_get_class (sorted_parts[0]),
- "teleservice-id", mm_sms_part_get_cdma_teleservice_id (sorted_parts[0]),
- "service-category", mm_sms_part_get_cdma_service_category (sorted_parts[0]),
- "number", mm_sms_part_get_number (sorted_parts[0]),
- "validity", (validity_relative ?
- g_variant_new ("(uv)", MM_SMS_VALIDITY_TYPE_RELATIVE, g_variant_new_uint32 (validity_relative)) :
- g_variant_new ("(uv)", MM_SMS_VALIDITY_TYPE_UNKNOWN, g_variant_new_boolean (FALSE))),
- "timestamp", mm_sms_part_get_timestamp (sorted_parts[0]),
- "discharge-timestamp", mm_sms_part_get_discharge_timestamp (sorted_parts[0]),
- "delivery-state", mm_sms_part_get_delivery_state (sorted_parts[0]),
+ "text", fulltext->str,
+ "data", g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
+ fulldata->data,
+ fulldata->len * sizeof (guint8),
+ TRUE,
+ (GDestroyNotify) g_byte_array_unref,
+ g_byte_array_ref (fulldata)),
/* delivery report request and message reference taken always from the last part */
"message-reference", mm_sms_part_get_message_reference (sorted_parts[self->priv->max_parts - 1]),
"delivery-report-request", mm_sms_part_get_delivery_report_request (sorted_parts[self->priv->max_parts - 1]),
@@ -1674,6 +1723,10 @@ mm_base_sms_multipart_take_part (MMBaseSms *self,
part,
(GCompareFunc)cmp_sms_part_sequence);
+ /* If this is the first part we take, initialize common SMS fields */
+ if (g_list_length (self->priv->parts) == 1)
+ initialize_sms (self);
+
/* We only populate contents when the multipart SMS is complete */
if (mm_base_sms_multipart_is_complete (self)) {
GError *inner_error = NULL;
@@ -1681,8 +1734,7 @@ mm_base_sms_multipart_take_part (MMBaseSms *self,
if (!assemble_sms (self, &inner_error)) {
/* We DO NOT propagate the error. The part was properly taken
* so ownership passed to the MMBaseSms object. */
- mm_warn ("Couldn't assemble SMS: '%s'",
- inner_error->message);
+ mm_obj_warn (self, "couldn't assemble SMS: %s", inner_error->message);
g_error_free (inner_error);
} else {
/* Completed AND assembled
@@ -1724,6 +1776,9 @@ mm_base_sms_singlepart_new (MMBaseModem *modem,
/* Keep the single part in the list */
self->priv->parts = g_list_prepend (self->priv->parts, part);
+ /* Initialize common SMS fields */
+ initialize_sms (self);
+
if (!assemble_sms (self, error)) {
/* Note: we need to remove the part from the list, as we really didn't
* take it, and therefore the caller is responsible for freeing it. */
@@ -1782,9 +1837,9 @@ mm_base_sms_multipart_new (MMBaseModem *modem,
}
MMBaseSms *
-mm_base_sms_new_from_properties (MMBaseModem *modem,
- MMSmsProperties *properties,
- GError **error)
+mm_base_sms_new_from_properties (MMBaseModem *modem,
+ MMSmsProperties *props,
+ GError **error)
{
MMBaseSms *self;
const gchar *text;
@@ -1792,17 +1847,17 @@ mm_base_sms_new_from_properties (MMBaseModem *modem,
g_assert (MM_IS_IFACE_MODEM_MESSAGING (modem));
- text = mm_sms_properties_get_text (properties);
- data = mm_sms_properties_peek_data_bytearray (properties);
+ text = mm_sms_properties_get_text (props);
+ data = mm_sms_properties_peek_data_bytearray (props);
/* Don't create SMS from properties if either (text|data) or number is missing */
- if (!mm_sms_properties_get_number (properties) ||
+ if (!mm_sms_properties_get_number (props) ||
(!text && !data)) {
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_INVALID_ARGS,
"Cannot create SMS: mandatory parameter '%s' is missing",
- (!mm_sms_properties_get_number (properties)?
+ (!mm_sms_properties_get_number (props)?
"number" : "text' or 'data"));
return NULL;
}
@@ -1821,8 +1876,8 @@ mm_base_sms_new_from_properties (MMBaseModem *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_properties_get_teleservice_id (properties) == MM_SMS_CDMA_TELESERVICE_ID_UNKNOWN ?
+ "number", mm_sms_properties_get_number (props),
+ "pdu-type", (mm_sms_properties_get_teleservice_id (props) == MM_SMS_CDMA_TELESERVICE_ID_UNKNOWN ?
MM_SMS_PDU_TYPE_SUBMIT :
MM_SMS_PDU_TYPE_CDMA_SUBMIT),
"text", text,
@@ -1834,14 +1889,14 @@ mm_base_sms_new_from_properties (MMBaseModem *modem,
(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),
- "teleservice-id", mm_sms_properties_get_teleservice_id (properties),
- "service-category", mm_sms_properties_get_service_category (properties),
- "delivery-report-request", mm_sms_properties_get_delivery_report_request (properties),
+ "smsc", mm_sms_properties_get_smsc (props),
+ "class", mm_sms_properties_get_class (props),
+ "teleservice-id", mm_sms_properties_get_teleservice_id (props),
+ "service-category", mm_sms_properties_get_service_category (props),
+ "delivery-report-request", mm_sms_properties_get_delivery_report_request (props),
"delivery-state", MM_SMS_DELIVERY_STATE_UNKNOWN,
- "validity", (mm_sms_properties_get_validity_type (properties) == MM_SMS_VALIDITY_TYPE_RELATIVE ?
- g_variant_new ("(uv)", MM_SMS_VALIDITY_TYPE_RELATIVE, g_variant_new_uint32 (mm_sms_properties_get_validity_relative (properties))) :
+ "validity", (mm_sms_properties_get_validity_type (props) == MM_SMS_VALIDITY_TYPE_RELATIVE ?
+ g_variant_new ("(uv)", MM_SMS_VALIDITY_TYPE_RELATIVE, g_variant_new_uint32 (mm_sms_properties_get_validity_relative (props))) :
g_variant_new ("(uv)", MM_SMS_VALIDITY_TYPE_UNKNOWN, g_variant_new_boolean (FALSE))),
NULL);
@@ -1853,6 +1908,17 @@ mm_base_sms_new_from_properties (MMBaseModem *modem,
/*****************************************************************************/
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+ MMBaseSms *self;
+
+ self = MM_BASE_SMS (_self);
+ return g_strdup_printf ("sms%u", self->priv->dbus_id);
+}
+
+/*****************************************************************************/
+
static void
set_property (GObject *object,
guint prop_id,
@@ -1886,6 +1952,8 @@ set_property (GObject *object,
g_clear_object (&self->priv->modem);
self->priv->modem = g_value_dup_object (value);
if (self->priv->modem) {
+ /* Set owner ID */
+ mm_log_object_set_owner_id (MM_LOG_OBJECT (self), mm_log_object_get_id (MM_LOG_OBJECT (self->priv->modem)));
/* Bind the modem's connection (which is set when it is exported,
* and unset when unexported) to the SMS's connection */
g_object_bind_property (self->priv->modem, MM_BASE_MODEM_CONNECTION,
@@ -1944,10 +2012,15 @@ get_property (GObject *object,
static void
mm_base_sms_init (MMBaseSms *self)
{
+ static guint id = 0;
+
/* Initialize private data */
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BASE_SMS, MMBaseSmsPrivate);
/* Defaults */
self->priv->max_parts = 1;
+
+ /* Each SMS is given a unique id to build its own DBus path */
+ self->priv->dbus_id = id++;
}
static void
@@ -1979,6 +2052,12 @@ dispose (GObject *object)
}
static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+ iface->build_id = log_object_build_id;
+}
+
+static void
mm_base_sms_class_init (MMBaseSmsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);