aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2012-01-18 18:08:20 -0600
committerDan Williams <dcbw@redhat.com>2012-01-18 18:08:20 -0600
commitf9a32a47edd7b882b3522cb4e39a071c667ac73b (patch)
treef23ff4db4d90acdf4d21cbefd55e3ee2c8b2c6e4
parentfc3fd7b983c564bc6d6523ad1232959734e04025 (diff)
gsm: fix return value of SMS send method
The introspection data specified the Send() method to return an array of unsigned integers, presumably the indexes of the messages just sent. But the code wasn't doing that, leading to a crash when dbus-glib tried to interpret garbage on the return. The problem is that sms_send_auth_cb() gave async_call_done() as the callback for sending the SMS, but that method just calls dbus_g_method_return() with no return arguments. dbus-glib interprets the arguments of dbus_g_method_return() according to the XML introspection data, and thus it was attempting to read the non-existent argument as an 'au' and getting garbage. Fix that by actually returning an array of message indexes from the SMS send code, and propagate that back to the SMS dbus code so it can return something sensible.
-rw-r--r--src/mm-generic-gsm.c49
-rw-r--r--src/mm-modem-gsm-sms.c41
-rw-r--r--src/mm-modem-gsm-sms.h9
3 files changed, 89 insertions, 10 deletions
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
index 3a95a6b0..06f29d3d 100644
--- a/src/mm-generic-gsm.c
+++ b/src/mm-generic-gsm.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
#include "mm-generic-gsm.h"
#include "mm-modem-gsm-card.h"
@@ -4726,12 +4727,33 @@ mm_generic_gsm_get_charset (MMGenericGsm *self)
/* MMModemGsmSms interface */
static void
+sms_send_invoke (MMCallbackInfo *info)
+{
+ MMModemGsmSmsSendFn callback = (MMModemGsmSmsSendFn) info->callback;
+
+ callback (MM_MODEM_GSM_SMS (info->modem),
+ mm_callback_info_get_data (info, "indexes"),
+ info->error,
+ info->user_data);
+}
+
+static void
+free_indexes (gpointer data)
+{
+ g_array_free ((GArray *) data, TRUE);
+}
+
+static void
sms_send_done (MMAtSerialPort *port,
GString *response,
GError *error,
gpointer user_data)
{
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
+ const char *p;
+ unsigned long num;
+ GArray *indexes = NULL;
+ guint32 idx = 0;
/* If the modem has already been removed, return without
* scheduling callback */
@@ -4740,7 +4762,25 @@ sms_send_done (MMAtSerialPort *port,
if (error)
info->error = g_error_copy (error);
-
+ else {
+ /* If the response happens to have a ">" in it from the interactive
+ * handling of the CMGS command, skip it.
+ */
+ p = strchr (response->str, '+');
+ if (p && *p) {
+ /* Check for the message index */
+ p = mm_strip_tag (p, "+CMGS:");
+ if (p && *p) {
+ errno = 0;
+ num = strtoul (p, NULL, 10);
+ if ((num < G_MAXUINT32) && (errno == 0))
+ idx = (guint32) num;
+ }
+ }
+ indexes = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 1);
+ g_array_append_val (indexes, idx);
+ mm_callback_info_set_data (info, "indexes", indexes, free_indexes);
+ }
mm_callback_info_schedule (info);
}
@@ -4751,7 +4791,7 @@ sms_send (MMModemGsmSms *modem,
const char *smsc,
guint validity,
guint class,
- MMModemFn callback,
+ MMModemGsmSmsSendFn callback,
gpointer user_data)
{
MMCallbackInfo *info;
@@ -4760,7 +4800,10 @@ sms_send (MMModemGsmSms *modem,
char *command;
MMAtSerialPort *port;
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
+ info = mm_callback_info_new_full (MM_MODEM (modem),
+ sms_send_invoke,
+ G_CALLBACK (callback),
+ user_data);
port = mm_generic_gsm_get_best_at_port (self, &info->error);
if (!port) {
diff --git a/src/mm-modem-gsm-sms.c b/src/mm-modem-gsm-sms.c
index e82cace3..22c42d00 100644
--- a/src/mm-modem-gsm-sms.c
+++ b/src/mm-modem-gsm-sms.c
@@ -133,6 +133,14 @@ sms_list_done (MMModemGsmSms *self,
/*****************************************************************************/
+static void
+sms_send_invoke (MMCallbackInfo *info)
+{
+ MMModemGsmSmsSendFn callback = (MMModemGsmSmsSendFn) info->callback;
+
+ callback (MM_MODEM_GSM_SMS (info->modem), NULL, info->error, info->user_data);
+}
+
void
mm_modem_gsm_sms_send (MMModemGsmSms *self,
const char *number,
@@ -140,7 +148,7 @@ mm_modem_gsm_sms_send (MMModemGsmSms *self,
const char *smsc,
guint validity,
guint class,
- MMModemFn callback,
+ MMModemGsmSmsSendFn callback,
gpointer user_data)
{
g_return_if_fail (MM_IS_MODEM_GSM_SMS (self));
@@ -150,9 +158,18 @@ mm_modem_gsm_sms_send (MMModemGsmSms *self,
if (MM_MODEM_GSM_SMS_GET_INTERFACE (self)->send)
MM_MODEM_GSM_SMS_GET_INTERFACE (self)->send (self, number, text, smsc, validity, class, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
+ else {
+ MMCallbackInfo *info;
+
+ info = mm_callback_info_new_full (MM_MODEM (self),
+ sms_send_invoke,
+ G_CALLBACK (callback),
+ user_data);
+ info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
+ "Operation not supported");
+ mm_callback_info_schedule (info);
+ }
}
static void
@@ -576,6 +593,20 @@ impl_gsm_modem_sms_save (MMModemGsmSms *modem,
/*****************************************************************************/
static void
+send_sms_call_done (MMModemGsmSms *modem,
+ GArray *indexes,
+ GError *error,
+ gpointer user_data)
+{
+ DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context, indexes);
+}
+
+static void
sms_send_auth_cb (MMAuthRequest *req,
GObject *owner,
DBusGMethodInvocation *context,
@@ -625,10 +656,10 @@ sms_send_auth_cb (MMAuthRequest *req,
done:
if (error) {
- async_call_done (MM_MODEM (self), error, context);
+ send_sms_call_done (self, NULL, error, context);
g_error_free (error);
} else
- mm_modem_gsm_sms_send (self, number, text, smsc, validity, class, async_call_done, context);
+ mm_modem_gsm_sms_send (self, number, text, smsc, validity, class, send_sms_call_done, context);
}
static void
diff --git a/src/mm-modem-gsm-sms.h b/src/mm-modem-gsm-sms.h
index 41684d72..11a1024b 100644
--- a/src/mm-modem-gsm-sms.h
+++ b/src/mm-modem-gsm-sms.h
@@ -35,6 +35,11 @@ typedef void (*MMModemGsmSmsListFn) (MMModemGsmSms *modem,
GError *error,
gpointer user_data);
+typedef void (*MMModemGsmSmsSendFn) (MMModemGsmSms *modem,
+ GArray *indexes,
+ GError *error,
+ gpointer user_data);
+
struct _MMModemGsmSms {
GTypeInterface g_iface;
@@ -45,7 +50,7 @@ struct _MMModemGsmSms {
const char *smsc,
guint validity,
guint class,
- MMModemFn callback,
+ MMModemGsmSmsSendFn callback,
gpointer user_data);
void (*get) (MMModemGsmSms *modem,
@@ -80,7 +85,7 @@ void mm_modem_gsm_sms_send (MMModemGsmSms *self,
const char *smsc,
guint validity,
guint class,
- MMModemFn callback,
+ MMModemGsmSmsSendFn callback,
gpointer user_data);
void mm_modem_gsm_sms_get (MMModemGsmSms *self,