diff options
author | Dan Williams <dan@ioncontrol.co> | 2025-04-19 19:13:53 -0500 |
---|---|---|
committer | Dan Williams <dan@ioncontrol.co> | 2025-05-08 20:24:38 -0500 |
commit | 97c189910bfb6cf4974a04d34a2e53a8bd1cfdf1 (patch) | |
tree | 28d7325e63911c03a838480212565cbf84b76b9b | |
parent | c6af442053d9959107c73e564731c3cb85e28981 (diff) |
base-sms,sms-list: use signals to set multipart reference
Instead of going through the messaging interface, which just asks
the MMSmsList anyway, just go straight to the list.
Signed-off-by: Dan Williams <dan@ioncontrol.co>
-rw-r--r-- | src/mm-base-sms.c | 68 | ||||
-rw-r--r-- | src/mm-base-sms.h | 10 | ||||
-rw-r--r-- | src/mm-iface-modem-messaging.c | 48 | ||||
-rw-r--r-- | src/mm-iface-modem-messaging.h | 5 | ||||
-rw-r--r-- | src/mm-sms-list.c | 76 |
5 files changed, 117 insertions, 90 deletions
diff --git a/src/mm-base-sms.c b/src/mm-base-sms.c index ecfee882..410ccc74 100644 --- a/src/mm-base-sms.c +++ b/src/mm-base-sms.c @@ -62,6 +62,13 @@ enum { static GParamSpec *properties[PROP_LAST]; +enum { + SIGNAL_SET_LOCAL_MULTIPART_REFERENCE, + SIGNAL_LAST +}; + +static guint signals[SIGNAL_LAST] = { 0 }; + struct _MMBaseSmsPrivate { gboolean initialized; @@ -383,26 +390,22 @@ prepare_sms_to_be_stored (MMBaseSms *self, * when storing locally, as we could collide with the references used * in other existing messages. */ if (self->priv->is_multipart) { - GList *l; - guint8 reference; - - /* 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) { - g_prefix_error (error, "Cannot get local multipart reference: "); + const gchar *number; + + number = mm_gdbus_sms_get_number (MM_GDBUS_SMS (self)); + g_signal_emit (self, + signals[SIGNAL_SET_LOCAL_MULTIPART_REFERENCE], + 0, + number); + if (self->priv->multipart_reference == 0) { + 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 FALSE; } - - 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; @@ -587,7 +590,7 @@ prepare_sms_to_be_sent (MMBaseSms *self, * multipart reference. When sending a message which wasn't stored * yet, we can just get a random multipart reference. */ if (self->priv->is_multipart) { - self->priv->multipart_reference = g_random_int_range (1,255); + 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); @@ -762,6 +765,23 @@ mm_base_sms_get_multipart_reference (MMBaseSms *self) return self->priv->multipart_reference; } +void +mm_base_sms_set_multipart_reference (MMBaseSms *self, guint reference) +{ + GList *l; + + g_return_if_fail (self->priv->is_multipart); + g_return_if_fail (reference > 0); + g_return_if_fail (reference <= 255); + g_return_if_fail (self->priv->multipart_reference == 0); + + 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); + } +} + gboolean mm_base_sms_multipart_is_complete (MMBaseSms *self) { @@ -1504,4 +1524,14 @@ mm_base_sms_class_init (MMBaseSmsClass *klass) G_TYPE_ARRAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_SUPPORTED_STORAGES, properties[PROP_SUPPORTED_STORAGES]); + + /* Signals */ + signals[SIGNAL_SET_LOCAL_MULTIPART_REFERENCE] = + g_signal_new (MM_BASE_SMS_SET_LOCAL_MULTIPART_REFERENCE, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (MMBaseSmsClass, set_local_multipart_reference), + NULL, NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, 0); } diff --git a/src/mm-base-sms.h b/src/mm-base-sms.h index dd1c10bb..f87a6640 100644 --- a/src/mm-base-sms.h +++ b/src/mm-base-sms.h @@ -46,6 +46,7 @@ typedef struct _MMBaseSms MMBaseSms; typedef struct _MMBaseSmsClass MMBaseSmsClass; typedef struct _MMBaseSmsPrivate MMBaseSmsPrivate; +/* Properties */ #define MM_BASE_SMS_PATH "sms-path" #define MM_BASE_SMS_CONNECTION "sms-connection" #define MM_BASE_SMS_MODEM "sms-modem" @@ -56,6 +57,9 @@ typedef struct _MMBaseSmsPrivate MMBaseSmsPrivate; #define MM_BASE_SMS_DEFAULT_STORAGE "sms-default-storage" #define MM_BASE_SMS_SUPPORTED_STORAGES "sms-supported-storages" +/* Signals */ +#define MM_BASE_SMS_SET_LOCAL_MULTIPART_REFERENCE "sms-set-local-multipart-reference" + struct _MMBaseSms { MmGdbusSmsSkeleton parent; MMBaseSmsPrivate *priv; @@ -88,6 +92,10 @@ struct _MMBaseSmsClass { gboolean (* delete_finish) (MMBaseSms *self, GAsyncResult *res, GError **error); + + /* Signal */ + void (*set_local_multipart_reference) (MMBaseSms *self, + const gchar *number); }; GType mm_base_sms_get_type (void); @@ -128,6 +136,8 @@ GList *mm_base_sms_get_parts (MMBaseSms *self); gboolean mm_base_sms_is_multipart (MMBaseSms *self); guint mm_base_sms_get_max_parts (MMBaseSms *self); guint mm_base_sms_get_multipart_reference (MMBaseSms *self); +void mm_base_sms_set_multipart_reference (MMBaseSms *self, + guint reference); gboolean mm_base_sms_multipart_is_complete (MMBaseSms *self); gboolean mm_base_sms_multipart_is_assembled (MMBaseSms *self); diff --git a/src/mm-iface-modem-messaging.c b/src/mm-iface-modem-messaging.c index 941e58e0..b6b63e49 100644 --- a/src/mm-iface-modem-messaging.c +++ b/src/mm-iface-modem-messaging.c @@ -36,54 +36,6 @@ G_DEFINE_INTERFACE (MMIfaceModemMessaging, mm_iface_modem_messaging, MM_TYPE_IFA /*****************************************************************************/ -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) diff --git a/src/mm-iface-modem-messaging.h b/src/mm-iface-modem-messaging.h index d7f29b6d..6cf7a0f6 100644 --- a/src/mm-iface-modem-messaging.h +++ b/src/mm-iface-modem-messaging.h @@ -211,9 +211,4 @@ void mm_iface_modem_messaging_unlock_storages (MMIfaceModemMessaging *s gboolean mem1, gboolean mem2); -/* 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 */ diff --git a/src/mm-sms-list.c b/src/mm-sms-list.c index 69c62153..99f35da1 100644 --- a/src/mm-sms-list.c +++ b/src/mm-sms-list.c @@ -61,6 +61,8 @@ struct _MMSmsListPrivate { GList *list; }; +static void _release_sms_internal (MMBaseSms *sms, MMSmsList *self); + /*****************************************************************************/ gboolean @@ -161,7 +163,7 @@ delete_ready (MMBaseSms *sms, path, (GCompareFunc)cmp_sms_by_path); if (l) { - g_object_unref (MM_BASE_SMS (l->data)); + _release_sms_internal (MM_BASE_SMS (l->data), self); self->priv->list = g_list_delete_link (self->priv->list, l); } @@ -213,14 +215,61 @@ mm_sms_list_delete_sms (MMSmsList *self, /*****************************************************************************/ -void -mm_sms_list_add_sms (MMSmsList *self, - MMBaseSms *sms) +static void +set_local_multipart_reference (MMBaseSms *sms, + const gchar *number, + MMSmsList *self) +{ + 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 */ + first = reference; + do { + if (!mm_sms_list_has_local_multipart_reference (self, number, reference)) { + mm_base_sms_set_multipart_reference (sms, reference); + return; + } + + if (reference == 255) + reference = 1; + else + reference++; + } while (reference != first); +} + +static void +_release_sms_internal (MMBaseSms *sms, MMSmsList *self) +{ + g_signal_handlers_disconnect_by_func (sms, set_local_multipart_reference, self); + g_object_unref (sms); +} + +static void +_add_sms_internal (MMSmsList *self, + MMBaseSms *sms, + gboolean received) { self->priv->list = g_list_prepend (self->priv->list, g_object_ref (sms)); + g_signal_connect (sms, + MM_BASE_SMS_SET_LOCAL_MULTIPART_REFERENCE, + (GCallback)set_local_multipart_reference, + self); + g_signal_emit (self, signals[SIGNAL_ADDED], 0, mm_base_sms_get_path (sms), - FALSE); + received); +} + + +void +mm_sms_list_add_sms (MMSmsList *self, + MMBaseSms *sms) +{ + _add_sms_internal (self, sms, FALSE); } /*****************************************************************************/ @@ -274,11 +323,7 @@ take_singlepart (MMSmsList *self, return FALSE; mm_obj_dbg (sms, "creating new singlepart SMS object"); - - self->priv->list = g_list_prepend (self->priv->list, g_object_ref (sms)); - g_signal_emit (self, signals[SIGNAL_ADDED], 0, - mm_base_sms_get_path (sms), - state == MM_SMS_STATE_RECEIVED); + _add_sms_internal (self, sms, state == MM_SMS_STATE_RECEIVED); return TRUE; } @@ -316,12 +361,7 @@ take_multipart (MMSmsList *self, mm_obj_dbg (sms, "creating new multipart SMS object: need to receive %u parts with reference '%u'", mm_sms_part_get_concat_max (part), concat_reference); - self->priv->list = g_list_prepend (self->priv->list, g_object_ref (sms)); - g_signal_emit (self, signals[SIGNAL_ADDED], 0, - mm_base_sms_get_path (sms), - (state == MM_SMS_STATE_RECEIVED || - state == MM_SMS_STATE_RECEIVING)); - + _add_sms_internal (self, sms, (state == MM_SMS_STATE_RECEIVED || state == MM_SMS_STATE_RECEIVING)); return TRUE; } @@ -488,8 +528,8 @@ dispose (GObject *object) g_clear_object (&self->priv->modem); g_clear_object (&self->priv->bind_to); - g_list_free_full (self->priv->list, g_object_unref); - self->priv->list = NULL; + g_list_foreach (self->priv->list, (GFunc)_release_sms_internal, self); + g_clear_pointer (&self->priv->list, (GDestroyNotify)g_list_free); G_OBJECT_CLASS (mm_sms_list_parent_class)->dispose (object); } |