summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Zaborowski <andrew.zaborowski@intel.com>2009-06-18 06:04:23 +0200
committerDenis Kenzior <denkenz@gmail.com>2009-06-18 16:57:58 -0500
commitf93376229a83d9f3f58e0e7f39fcd55ef97fbccb (patch)
tree645e645553e74fb47a01a2e87a509f8281bb814c
parent9156607bc9a84711419fe70e64f199316e50e71b (diff)
downloadofono-f93376229a83d9f3f58e0e7f39fcd55ef97fbccb.tar.bz2
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.
-rw-r--r--src/common.c3
-rw-r--r--src/common.h2
-rw-r--r--src/modem.h1
-rw-r--r--src/ussd.c144
-rw-r--r--src/ussd.h10
-rw-r--r--unit/test-common.c10
6 files changed, 159 insertions, 11 deletions
diff --git a/src/common.c b/src/common.c
index 86534320..a9166bf9 100644
--- a/src/common.c
+++ b/src/common.c
@@ -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;
diff --git a/src/common.h b/src/common.h
index 1c0a7763..0f7684e1 100644
--- a/src/common.h
+++ b/src/common.h
@@ -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);
diff --git a/src/modem.h b/src/modem.h
index 6ed4a2a3..d322df8d 100644
--- a/src/modem.h
+++ b/src/modem.h
@@ -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;
diff --git a/src/ussd.c b/src/ussd.c
index 72253982..d2251c83 100644
--- a/src/ussd.c
+++ b/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);
diff --git a/src/ussd.h b/src/ussd.h
index 5b956e55..5f40f618 100644
--- a/src/ussd.h
+++ b/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);
diff --git a/unit/test-common.c b/unit/test-common.c
index 5c753d3b..96509bd1 100644
--- a/unit/test-common.c
+++ b/unit/test-common.c
@@ -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);