mirror of git://git.sysmocom.de/ofono
Teach USSD to recognise password change strings.
This is slightly hacky, part of ussd.c responsible for registering services is duplicated and parse_ss_control_string is modified to accept a fourth SI fragment in the input string.
This commit is contained in:
parent
9156607bc9
commit
f93376229a
|
@ -465,7 +465,7 @@ const char *ss_control_type_to_string(enum ss_control_type type)
|
|||
gboolean parse_ss_control_string(char *str, int *ss_type,
|
||||
char **sc, char **sia,
|
||||
char **sib, char **sic,
|
||||
char **dn)
|
||||
char **sid, char **dn)
|
||||
{
|
||||
int len = strlen(str);
|
||||
int cur = 0;
|
||||
|
@ -533,6 +533,7 @@ gboolean parse_ss_control_string(char *str, int *ss_type,
|
|||
NEXT_FIELD(c, *sia);
|
||||
NEXT_FIELD(c, *sib);
|
||||
NEXT_FIELD(c, *sic);
|
||||
NEXT_FIELD(c, *sid);
|
||||
|
||||
if (*c == '\0')
|
||||
ret = TRUE;
|
||||
|
|
|
@ -192,7 +192,7 @@ gboolean valid_ussd_string(const char *str);
|
|||
gboolean parse_ss_control_string(char *str, int *ss_type,
|
||||
char **sc, char **sia,
|
||||
char **sib, char **sic,
|
||||
char **dn);
|
||||
char **sid, char **dn);
|
||||
|
||||
const char *ss_control_type_to_string(enum ss_control_type type);
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ struct ofono_modem {
|
|||
void *userdata;
|
||||
|
||||
GSList *ss_control_list;
|
||||
GSList *ss_passwd_list;
|
||||
|
||||
struct ofono_modem_data *modem_info;
|
||||
struct network_registration_data *network_registration;
|
||||
|
|
144
src/ussd.c
144
src/ussd.c
|
@ -165,22 +165,148 @@ void ss_control_unregister(struct ofono_modem *modem, const char *str,
|
|||
l->data);
|
||||
}
|
||||
|
||||
struct ss_passwd_entry {
|
||||
char *service;
|
||||
ss_passwd_cb_t cb;
|
||||
};
|
||||
|
||||
static struct ss_passwd_entry *ss_passwd_entry_create(const char *service,
|
||||
ss_passwd_cb_t cb)
|
||||
{
|
||||
struct ss_passwd_entry *r;
|
||||
|
||||
r = g_try_new0(struct ss_passwd_entry, 1);
|
||||
|
||||
if (!r)
|
||||
return r;
|
||||
|
||||
r->service = g_strdup(service);
|
||||
r->cb = cb;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void ss_passwd_entry_destroy(struct ss_passwd_entry *ca)
|
||||
{
|
||||
g_free(ca->service);
|
||||
g_free(ca);
|
||||
}
|
||||
|
||||
static gint ss_passwd_entry_compare(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const struct ss_passwd_entry *ca = a;
|
||||
const struct ss_passwd_entry *cb = b;
|
||||
int ret;
|
||||
|
||||
ret = strcmp(ca->service, cb->service);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (ca->cb < cb->cb)
|
||||
return -1;
|
||||
|
||||
if (ca->cb > cb->cb)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint ss_passwd_entry_find_by_service(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const struct ss_passwd_entry *ca = a;
|
||||
|
||||
return strcmp(ca->service, b);
|
||||
}
|
||||
|
||||
gboolean ss_passwd_register(struct ofono_modem *modem, const char *str,
|
||||
ss_passwd_cb_t cb)
|
||||
{
|
||||
struct ss_passwd_entry *entry;
|
||||
|
||||
if (!modem)
|
||||
return FALSE;
|
||||
|
||||
entry = ss_passwd_entry_create(str, cb);
|
||||
|
||||
if (!entry)
|
||||
return FALSE;
|
||||
|
||||
modem->ss_passwd_list = g_slist_append(modem->ss_passwd_list, entry);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ss_passwd_unregister(struct ofono_modem *modem, const char *str,
|
||||
ss_passwd_cb_t cb)
|
||||
{
|
||||
const struct ss_passwd_entry entry = { (char *)str, cb };
|
||||
GSList *l;
|
||||
|
||||
if (!modem)
|
||||
return;
|
||||
|
||||
l = g_slist_find_custom(modem->ss_passwd_list, &entry,
|
||||
ss_passwd_entry_compare);
|
||||
|
||||
if (!l)
|
||||
return;
|
||||
|
||||
ss_passwd_entry_destroy(l->data);
|
||||
modem->ss_passwd_list = g_slist_remove(modem->ss_passwd_list,
|
||||
l->data);
|
||||
}
|
||||
|
||||
static gboolean recognized_passwd_change_string(struct ofono_modem *modem,
|
||||
int type, char *sc,
|
||||
char *sia, char *sib,
|
||||
char *sic, char *sid,
|
||||
char *dn, DBusMessage *msg)
|
||||
{
|
||||
GSList *l = modem->ss_passwd_list;
|
||||
|
||||
switch (type) {
|
||||
case SS_CONTROL_TYPE_ACTIVATION:
|
||||
case SS_CONTROL_TYPE_REGISTRATION:
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (strcmp(sc, "03") || strlen(dn) || strcmp(sic, sid))
|
||||
return FALSE;
|
||||
|
||||
while ((l = g_slist_find_custom(l, sia,
|
||||
ss_passwd_entry_find_by_service)) != NULL) {
|
||||
struct ss_passwd_entry *entry = l->data;
|
||||
|
||||
if (entry->cb(modem, sia, sib, sic, msg))
|
||||
return TRUE;
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean recognized_control_string(struct ofono_modem *modem,
|
||||
const char *ss_str,
|
||||
DBusMessage *msg)
|
||||
{
|
||||
char *str = g_strdup(ss_str);
|
||||
char *sc, *sia, *sib, *sic, *dn;
|
||||
char *sc, *sia, *sib, *sic, *sid, *dn;
|
||||
int type;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
ofono_debug("parsing control string");
|
||||
|
||||
if (parse_ss_control_string(str, &type, &sc, &sia, &sib, &sic, &dn)) {
|
||||
if (parse_ss_control_string(str, &type, &sc,
|
||||
&sia, &sib, &sic, &sid, &dn)) {
|
||||
GSList *l = modem->ss_control_list;
|
||||
|
||||
ofono_debug("Got parse result: %d, %s, %s, %s, %s, %s",
|
||||
type, sc, sia, sib, sic, dn);
|
||||
ofono_debug("Got parse result: %d, %s, %s, %s, %s, %s, %s",
|
||||
type, sc, sia, sib, sic, sid, dn);
|
||||
|
||||
while ((l = g_slist_find_custom(l, sc,
|
||||
ss_control_entry_find_by_service)) != NULL) {
|
||||
|
@ -193,6 +319,13 @@ static gboolean recognized_control_string(struct ofono_modem *modem,
|
|||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
/* A password change string needs to be treated separately
|
||||
* because it uses a fourth SI and is thus not a valid
|
||||
* control string. */
|
||||
if (recognized_passwd_change_string(modem, type, sc,
|
||||
sia, sib, sic, sid, dn, msg))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* TODO: Handle all strings that control voice calls */
|
||||
|
@ -205,9 +338,6 @@ static gboolean recognized_control_string(struct ofono_modem *modem,
|
|||
* by SEND and are not valid USSD requests.
|
||||
*/
|
||||
|
||||
/* TODO: Handle Password registration according to 22.030 Section 6.5.4
|
||||
*/
|
||||
|
||||
out:
|
||||
g_free(str);
|
||||
|
||||
|
|
10
src/ussd.h
10
src/ussd.h
|
@ -26,8 +26,18 @@ typedef gboolean (*ss_control_cb_t)(struct ofono_modem *modem,
|
|||
const char *sic, const char *dn,
|
||||
DBusMessage *msg);
|
||||
|
||||
typedef gboolean (*ss_passwd_cb_t)(struct ofono_modem *modem, const char *sc,
|
||||
const char *old, const char *new,
|
||||
DBusMessage *msg);
|
||||
|
||||
gboolean ss_control_register(struct ofono_modem *modem, const char *str,
|
||||
ss_control_cb_t cb);
|
||||
|
||||
void ss_control_unregister(struct ofono_modem *modem, const char *str,
|
||||
ss_control_cb_t cb);
|
||||
|
||||
gboolean ss_passwd_register(struct ofono_modem *modem, const char *str,
|
||||
ss_passwd_cb_t cb);
|
||||
|
||||
void ss_passwd_unregister(struct ofono_modem *modem, const char *str,
|
||||
ss_passwd_cb_t cb);
|
||||
|
|
|
@ -57,6 +57,7 @@ static void test_invalid()
|
|||
char *sia;
|
||||
char *sib;
|
||||
char *sic;
|
||||
char *sid;
|
||||
char *dn;
|
||||
int type;
|
||||
|
||||
|
@ -71,7 +72,9 @@ static void test_invalid()
|
|||
str = strdup(invalid_strings[i]);
|
||||
|
||||
ret = parse_ss_control_string(str, &type, &sc,
|
||||
&sia, &sib, &sic, &dn);
|
||||
&sia, &sib, &sic, &sid, &dn);
|
||||
if (strlen(sid))
|
||||
ret = FALSE;
|
||||
|
||||
g_assert(ret == FALSE);
|
||||
|
||||
|
@ -105,6 +108,7 @@ static void test_valid()
|
|||
char *sia;
|
||||
char *sib;
|
||||
char *sic;
|
||||
char *sid;
|
||||
char *dn;
|
||||
int type;
|
||||
gboolean ret;
|
||||
|
@ -119,7 +123,9 @@ static void test_valid()
|
|||
str = strdup(valid_strings[i]);
|
||||
|
||||
ret = parse_ss_control_string(str, &type, &sc,
|
||||
&sia, &sib, &sic, &dn);
|
||||
&sia, &sib, &sic, &sid, &dn);
|
||||
if (strlen(sid))
|
||||
ret = FALSE;
|
||||
|
||||
g_assert(ret == TRUE);
|
||||
|
||||
|
|
Loading…
Reference in New Issue