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:
+48
-18
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user