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>
This commit is contained in:
Dan Williams
2025-05-08 20:24:38 -05:00
parent c6af442053
commit 97c189910b
5 changed files with 116 additions and 89 deletions
+48 -18
View File
@@ -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;
const gchar *number;
/* 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: ");
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);
}
+10
View File
@@ -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);
-48
View File
@@ -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)
-5
View File
@@ -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 */
+58 -18
View File
@@ -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,
/*****************************************************************************/
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),
received);
}
void
mm_sms_list_add_sms (MMSmsList *self,
MMBaseSms *sms)
{
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),
FALSE);
_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);
}