diff options
Diffstat (limited to 'src/mm-base-sms.c')
-rw-r--r-- | src/mm-base-sms.c | 533 |
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); |