diff --git a/src/common.c b/src/common.c index bcd42f63..91892bb1 100644 --- a/src/common.c +++ b/src/common.c @@ -393,7 +393,7 @@ void string_to_phone_number(const char *str, struct ofono_phone_number *ph) } } -int valid_ussd_string(const char *str) +gboolean valid_ussd_string(const char *str, gboolean call_in_progress) { int len = strlen(str); @@ -401,37 +401,31 @@ int valid_ussd_string(const char *str) return FALSE; /* - * It is hard to understand exactly what constitutes a valid USSD string - * According to 22.090: - * Case a - 1, 2 or 3 digits from the set (*, #) followed by 1X(Y), - * where X=any number 0‑4, Y=any number 0‑9, then, optionally "* - * followed by any number of any characters", and concluding with #SEND + * Return true if an MMI input string is to be sent as USSD. * - * Case b - 1, 2 or 3 digits from the set (*, #) followed by 1X(Y), - * where X=any number 5‑9, Y=any number 0‑9, then, optionally "* - * followed by any number of any characters", and concluding with #SEND + * According to 3GPP TS 22.030, after checking the well-known + * supplementary service control, SIM control and manufacturer + * defined control codes, the terminal should check if the input + * should be sent as USSD according to the following rules: * - * Case c - 7(Y) SEND, where Y=any number 0‑9 + * 1) Terminated by '#' + * 2) A short string of 1 or 2 digits * - * Case d - All other formats - * - * According to 22.030 Figure 3.5.3.2 USSD strings can be: - * - * Supplementary service control - * SIM control - * Manufacturer defined - * Terminated by '#' - * Short String - This can be any 2 digit short string. If the string - * starts with a '1' and no calls are in progress then - * this string is treated as a call setup request - * - * Everything else is not a valid USSD string + * As an exception, if a 2 digit string starts with a '1' and + * there are no calls in progress then this string is treated as + * a call setup request instead. */ - if (len != 2 && str[len-1] != '#') + if (str[len-1] == '#') + return TRUE; + + if (!call_in_progress && len == 2 && str[0] != '1') return FALSE; - return TRUE; + if (len <= 2) + return TRUE; + + return FALSE; } const char *ss_control_type_to_string(enum ss_control_type type) diff --git a/src/common.h b/src/common.h index c43e46d7..8b5798a0 100644 --- a/src/common.h +++ b/src/common.h @@ -130,7 +130,7 @@ void string_to_phone_number(const char *str, struct ofono_phone_number *ph); int mmi_service_code_to_bearer_class(int code); -gboolean valid_ussd_string(const char *str); +gboolean valid_ussd_string(const char *str, gboolean call_in_progress); gboolean parse_ss_control_string(char *str, int *ss_type, char **sc, char **sia, diff --git a/src/ussd.c b/src/ussd.c index c80d2473..42e547a0 100644 --- a/src/ussd.c +++ b/src/ussd.c @@ -565,7 +565,7 @@ static DBusMessage *ussd_initiate(DBusConnection *conn, DBusMessage *msg, return NULL; DBG("No.., checking if this is a USSD string"); - if (!valid_ussd_string(str)) + if (!valid_ussd_string(str, FALSE)) return __ofono_error_invalid_format(msg); if (!ussd_encode(str, &num_packed, buf))