aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-01-24 13:10:37 +0100
committerAleksander Morgado <aleksander@lanedo.com>2012-03-15 14:14:57 +0100
commit2bf40184e058fed71fe4d5815964a433271895ca (patch)
treede3dd9ad7d6e092cf00efb91b8450af4d652e003
parent7210e6caf1cc54b43aff9b7d4e62489ab8188799 (diff)
iface-modem-3gpp-ussd: allow error reporting in encode/decode
-rw-r--r--src/mm-broadband-modem.c186
-rw-r--r--src/mm-iface-modem-3gpp-ussd.c10
-rw-r--r--src/mm-iface-modem-3gpp-ussd.h12
3 files changed, 128 insertions, 80 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 24a7ef91..683fd761 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -2819,7 +2819,8 @@ modem_3gpp_setup_ps_registration (MMIfaceModem3gpp *self,
static gchar *
modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
const gchar *command,
- guint *scheme)
+ guint *scheme,
+ GError **error)
{
MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self);
GByteArray *ussd_command;
@@ -2844,7 +2845,8 @@ modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
static gchar *
modem_3gpp_ussd_decode (MMIfaceModem3gppUssd *self,
- const gchar *reply)
+ const gchar *reply,
+ GError **error)
{
MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self);
@@ -2865,7 +2867,8 @@ modem_3gpp_ussd_setup_cleanup_unsolicited_result_codes_finish (MMIfaceModem3gppU
static gchar *
decode_ussd_response (MMBroadbandModem *self,
- const gchar *reply)
+ const gchar *reply,
+ GError **error)
{
gchar **items, **iter, *p;
gchar *str = NULL;
@@ -2874,8 +2877,14 @@ decode_ussd_response (MMBroadbandModem *self,
/* Look for the first ',' */
p = strchr (reply, ',');
- if (!p)
+ if (!p) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Cannot decode USSD response (%s): missing field separator",
+ reply);
return NULL;
+ }
items = g_strsplit_set (p + 1, " ,", -1);
for (iter = items; iter && *iter; iter++) {
@@ -2890,8 +2899,14 @@ decode_ussd_response (MMBroadbandModem *self,
}
}
- if (!str)
+ if (!str) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Cannot decode USSD response (%s): not enough fields",
+ reply);
return NULL;
+ }
/* Strip quotes */
if (str[0] == '"')
@@ -2900,7 +2915,7 @@ decode_ussd_response (MMBroadbandModem *self,
if (p)
*p = '\0';
- decoded = mm_iface_modem_3gpp_ussd_decode (MM_IFACE_MODEM_3GPP_USSD (self), str);
+ decoded = mm_iface_modem_3gpp_ussd_decode (MM_IFACE_MODEM_3GPP_USSD (self), str, error);
g_strfreev (items);
return decoded;
}
@@ -2910,82 +2925,109 @@ cusd_received (MMAtSerialPort *port,
GMatchInfo *info,
MMBroadbandModem *self)
{
- gint status;
gchar *str;
MMModem3gppUssdSessionState ussd_state = MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE;
str = g_match_info_fetch (info, 1);
if (!str || !isdigit (*str)) {
- mm_warn ("Received invalid USSD response: '%s'", str ? str : "(none)");
- g_free (str);
- return;
- }
-
- status = g_ascii_digit_value (*str);
- switch (status) {
- case 0: /* no further action required */ {
- gchar *converted;
-
- converted = decode_ussd_response (self, str);
- if (self->priv->pending_ussd_action) {
- /* Response to the user's request */
- g_simple_async_result_set_op_res_gpointer (self->priv->pending_ussd_action,
- converted,
- g_free);
- } else {
- /* Network-initiated USSD-Notify */
- mm_iface_modem_3gpp_ussd_update_network_notification (
- MM_IFACE_MODEM_3GPP_USSD (self),
- converted);
- g_free (converted);
- }
- break;
- }
-
- case 1: /* further action required */ {
- gchar *converted;
-
- ussd_state = MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE;
- converted = decode_ussd_response (self, str);
- if (self->priv->pending_ussd_action) {
- g_simple_async_result_set_op_res_gpointer (self->priv->pending_ussd_action,
- converted,
- g_free);
- } else {
- /* Network-initiated USSD-Request */
- mm_iface_modem_3gpp_ussd_update_network_request (
- MM_IFACE_MODEM_3GPP_USSD (self),
- converted);
- g_free (converted);
- }
- break;
- }
-
- case 2:
if (self->priv->pending_ussd_action)
g_simple_async_result_set_error (self->priv->pending_ussd_action,
MM_CORE_ERROR,
- MM_CORE_ERROR_CANCELLED,
- "USSD terminated by network.");
- break;
+ MM_CORE_ERROR_FAILED,
+ "Invalid USSD response received: '%s'",
+ str ? str : "(none)");
+ else
+ mm_warn ("Received invalid USSD network-initiated request: '%s'",
+ str ? str : "(none)");
+ } else {
+ gint status;
+
+ status = g_ascii_digit_value (*str);
+ switch (status) {
+ case 0: /* no further action required */ {
+ gchar *converted;
+ GError *error = NULL;
+
+ converted = decode_ussd_response (self, str, &error);
+ if (self->priv->pending_ussd_action) {
+ /* Response to the user's request */
+ if (error)
+ g_simple_async_result_take_error (self->priv->pending_ussd_action, error);
+ else
+ g_simple_async_result_set_op_res_gpointer (self->priv->pending_ussd_action,
+ converted,
+ g_free);
+ } else {
+ if (error) {
+ mm_warn ("Invalid network initiated USSD notification: %s",
+ error->message);
+ g_error_free (error);
+ } else {
+ /* Network-initiated USSD-Notify */
+ mm_iface_modem_3gpp_ussd_update_network_notification (
+ MM_IFACE_MODEM_3GPP_USSD (self),
+ converted);
+ g_free (converted);
+ }
+ }
+ break;
+ }
- case 4:
- if (self->priv->pending_ussd_action)
- g_simple_async_result_set_error (self->priv->pending_ussd_action,
- MM_CORE_ERROR,
- MM_CORE_ERROR_UNSUPPORTED,
- "Operation not supported.");
- break;
+ case 1: /* further action required */ {
+ gchar *converted;
+ GError *error = NULL;
- default:
- if (self->priv->pending_ussd_action)
- g_simple_async_result_set_error (self->priv->pending_ussd_action,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Unhandled USSD reply: %s (%d)",
- str,
- status);
- break;
+ ussd_state = MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE;
+ converted = decode_ussd_response (self, str, &error);
+ if (self->priv->pending_ussd_action) {
+ if (error)
+ g_simple_async_result_take_error (self->priv->pending_ussd_action, error);
+ else
+ g_simple_async_result_set_op_res_gpointer (self->priv->pending_ussd_action,
+ converted,
+ g_free);
+ } else {
+ if (error) {
+ mm_warn ("Invalid network initiated USSD request: %s",
+ error->message);
+ g_error_free (error);
+ } else {
+ /* Network-initiated USSD-Request */
+ mm_iface_modem_3gpp_ussd_update_network_request (
+ MM_IFACE_MODEM_3GPP_USSD (self),
+ converted);
+ g_free (converted);
+ }
+ }
+ break;
+ }
+
+ case 2:
+ if (self->priv->pending_ussd_action)
+ g_simple_async_result_set_error (self->priv->pending_ussd_action,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_CANCELLED,
+ "USSD terminated by network.");
+ break;
+
+ case 4:
+ if (self->priv->pending_ussd_action)
+ g_simple_async_result_set_error (self->priv->pending_ussd_action,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_UNSUPPORTED,
+ "Operation not supported.");
+ break;
+
+ default:
+ if (self->priv->pending_ussd_action)
+ g_simple_async_result_set_error (self->priv->pending_ussd_action,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Unhandled USSD reply: %s (%d)",
+ str,
+ status);
+ break;
+ }
}
mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (self),
diff --git a/src/mm-iface-modem-3gpp-ussd.c b/src/mm-iface-modem-3gpp-ussd.c
index 75907369..9cdc2da9 100644
--- a/src/mm-iface-modem-3gpp-ussd.c
+++ b/src/mm-iface-modem-3gpp-ussd.c
@@ -236,16 +236,18 @@ handle_initiate (MmGdbusModem3gppUssd *skeleton,
gchar *
mm_iface_modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
const gchar *command,
- guint *scheme)
+ guint *scheme,
+ GError **error)
{
- return MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->encode (self, command, scheme);
+ return MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->encode (self, command, scheme, error);
}
gchar *
mm_iface_modem_3gpp_ussd_decode (MMIfaceModem3gppUssd *self,
- const gchar *reply)
+ const gchar *reply,
+ GError **error)
{
- return MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->decode (self, reply);
+ return MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->decode (self, reply, error);
}
/*****************************************************************************/
diff --git a/src/mm-iface-modem-3gpp-ussd.h b/src/mm-iface-modem-3gpp-ussd.h
index ce419088..6ba789d6 100644
--- a/src/mm-iface-modem-3gpp-ussd.h
+++ b/src/mm-iface-modem-3gpp-ussd.h
@@ -82,9 +82,11 @@ struct _MMIfaceModem3gppUssd {
/* Encode/Decode */
gchar * (*encode) (MMIfaceModem3gppUssd *self,
const gchar *command,
- guint *scheme);
+ guint *scheme,
+ GError **error);
gchar * (*decode) (MMIfaceModem3gppUssd *self,
- const gchar *reply);
+ const gchar *reply,
+ GError **error);
/* Send command */
void (* send) (MMIfaceModem3gppUssd *self,
@@ -142,9 +144,11 @@ void mm_iface_modem_3gpp_ussd_update_network_request (MMIfaceModem3gppUssd
/* Encode/Decode USSD */
gchar *mm_iface_modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
const gchar *command,
- guint *scheme);
+ guint *scheme,
+ GError **error);
gchar *mm_iface_modem_3gpp_ussd_decode (MMIfaceModem3gppUssd *self,
- const gchar *reply);
+ const gchar *reply,
+ GError **error);
/* Shutdown USSD interface */
void mm_iface_modem_3gpp_ussd_shutdown (MMIfaceModem3gppUssd *self);