diff options
author | Dan Williams <dcbw@redhat.com> | 2012-01-18 18:08:20 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2012-01-18 18:08:20 -0600 |
commit | f9a32a47edd7b882b3522cb4e39a071c667ac73b (patch) | |
tree | f23ff4db4d90acdf4d21cbefd55e3ee2c8b2c6e4 /src/mm-generic-gsm.c | |
parent | fc3fd7b983c564bc6d6523ad1232959734e04025 (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.
Diffstat (limited to 'src/mm-generic-gsm.c')
-rw-r--r-- | src/mm-generic-gsm.c | 49 |
1 files changed, 46 insertions, 3 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) { |