aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dan@ioncontrol.co>2025-04-19 19:13:53 -0500
committerDan Williams <dan@ioncontrol.co>2025-05-08 20:24:38 -0500
commit97c189910bfb6cf4974a04d34a2e53a8bd1cfdf1 (patch)
tree28d7325e63911c03a838480212565cbf84b76b9b
parentc6af442053d9959107c73e564731c3cb85e28981 (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.c68
-rw-r--r--src/mm-base-sms.h10
-rw-r--r--src/mm-iface-modem-messaging.c48
-rw-r--r--src/mm-iface-modem-messaging.h5
-rw-r--r--src/mm-sms-list.c76
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);
}