diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem.c | 186 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp-ussd.c | 10 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp-ussd.h | 12 |
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); |