iface-modem-3gpp-ussd: allow error reporting in encode/decode
This commit is contained in:
+115
-73
@@ -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;
|
||||
|
||||
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;
|
||||
"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 1: /* further action required */ {
|
||||
gchar *converted;
|
||||
GError *error = NULL;
|
||||
|
||||
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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user