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,
|
gboolean parse_ss_control_string(char *str, int *ss_type,
|
||||||
char **sc, char **sia,
|
char **sc, char **sia,
|
||||||
char **sib, char **sic,
|
char **sib, char **sic,
|
||||||
char **dn)
|
char **sid, char **dn)
|
||||||
{
|
{
|
||||||
int len = strlen(str);
|
int len = strlen(str);
|
||||||
int cur = 0;
|
int cur = 0;
|
||||||
|
@ -533,6 +533,7 @@ gboolean parse_ss_control_string(char *str, int *ss_type,
|
||||||
NEXT_FIELD(c, *sia);
|
NEXT_FIELD(c, *sia);
|
||||||
NEXT_FIELD(c, *sib);
|
NEXT_FIELD(c, *sib);
|
||||||
NEXT_FIELD(c, *sic);
|
NEXT_FIELD(c, *sic);
|
||||||
|
NEXT_FIELD(c, *sid);
|
||||||
|
|
||||||
if (*c == '\0')
|
if (*c == '\0')
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
|
@ -192,7 +192,7 @@ gboolean valid_ussd_string(const char *str);
|
||||||
gboolean parse_ss_control_string(char *str, int *ss_type,
|
gboolean parse_ss_control_string(char *str, int *ss_type,
|
||||||
char **sc, char **sia,
|
char **sc, char **sia,
|
||||||
char **sib, char **sic,
|
char **sib, char **sic,
|
||||||
char **dn);
|
char **sid, char **dn);
|
||||||
|
|
||||||
const char *ss_control_type_to_string(enum ss_control_type type);
|
const char *ss_control_type_to_string(enum ss_control_type type);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct ofono_modem {
|
||||||
void *userdata;
|
void *userdata;
|
||||||
|
|
||||||
GSList *ss_control_list;
|
GSList *ss_control_list;
|
||||||
|
GSList *ss_passwd_list;
|
||||||
|
|
||||||
struct ofono_modem_data *modem_info;
|
struct ofono_modem_data *modem_info;
|
||||||
struct network_registration_data *network_registration;
|
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);
|
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,
|
static gboolean recognized_control_string(struct ofono_modem *modem,
|
||||||
const char *ss_str,
|
const char *ss_str,
|
||||||
DBusMessage *msg)
|
DBusMessage *msg)
|
||||||
{
|
{
|
||||||
char *str = g_strdup(ss_str);
|
char *str = g_strdup(ss_str);
|
||||||
char *sc, *sia, *sib, *sic, *dn;
|
char *sc, *sia, *sib, *sic, *sid, *dn;
|
||||||
int type;
|
int type;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
ofono_debug("parsing control string");
|
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;
|
GSList *l = modem->ss_control_list;
|
||||||
|
|
||||||
ofono_debug("Got parse result: %d, %s, %s, %s, %s, %s",
|
ofono_debug("Got parse result: %d, %s, %s, %s, %s, %s, %s",
|
||||||
type, sc, sia, sib, sic, dn);
|
type, sc, sia, sib, sic, sid, dn);
|
||||||
|
|
||||||
while ((l = g_slist_find_custom(l, sc,
|
while ((l = g_slist_find_custom(l, sc,
|
||||||
ss_control_entry_find_by_service)) != NULL) {
|
ss_control_entry_find_by_service)) != NULL) {
|
||||||
|
@ -193,6 +319,13 @@ static gboolean recognized_control_string(struct ofono_modem *modem,
|
||||||
|
|
||||||
l = l->next;
|
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 */
|
/* 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.
|
* by SEND and are not valid USSD requests.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO: Handle Password registration according to 22.030 Section 6.5.4
|
|
||||||
*/
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_free(str);
|
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,
|
const char *sic, const char *dn,
|
||||||
DBusMessage *msg);
|
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,
|
gboolean ss_control_register(struct ofono_modem *modem, const char *str,
|
||||||
ss_control_cb_t cb);
|
ss_control_cb_t cb);
|
||||||
|
|
||||||
void ss_control_unregister(struct ofono_modem *modem, const char *str,
|
void ss_control_unregister(struct ofono_modem *modem, const char *str,
|
||||||
ss_control_cb_t cb);
|
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 *sia;
|
||||||
char *sib;
|
char *sib;
|
||||||
char *sic;
|
char *sic;
|
||||||
|
char *sid;
|
||||||
char *dn;
|
char *dn;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
|
@ -71,7 +72,9 @@ static void test_invalid()
|
||||||
str = strdup(invalid_strings[i]);
|
str = strdup(invalid_strings[i]);
|
||||||
|
|
||||||
ret = parse_ss_control_string(str, &type, &sc,
|
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);
|
g_assert(ret == FALSE);
|
||||||
|
|
||||||
|
@ -105,6 +108,7 @@ static void test_valid()
|
||||||
char *sia;
|
char *sia;
|
||||||
char *sib;
|
char *sib;
|
||||||
char *sic;
|
char *sic;
|
||||||
|
char *sid;
|
||||||
char *dn;
|
char *dn;
|
||||||
int type;
|
int type;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
@ -119,7 +123,9 @@ static void test_valid()
|
||||||
str = strdup(valid_strings[i]);
|
str = strdup(valid_strings[i]);
|
||||||
|
|
||||||
ret = parse_ss_control_string(str, &type, &sc,
|
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);
|
g_assert(ret == TRUE);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue