---
 src/stk.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/src/stk.c b/src/stk.c
index 3959dc7..b43f090 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -51,6 +51,8 @@ typedef gboolean (*command_handler_t)(const struct 
stk_command *cmd,
                                        struct stk_response *rsp,
                                        struct ofono_stk *stk);
 
+typedef void (*command_cancel_t)(struct ofono_stk *stk);
+
 struct stk_menu {
        char *title;
        GSList *items;
@@ -70,6 +72,8 @@ struct ofono_stk {
        struct stk_command *pending_cmd;
        DBusMessage *pending;
        gint cmd_timeout;
+       command_cancel_t cancel_cmd;
+       gboolean cancelled; /* Only valid when .pending set */
 
        struct stk_menu *default_menu;
        struct stk_menu *current_menu; /* For Select Item menus */
@@ -183,6 +187,19 @@ void ofono_stk_proactive_command_notify(struct ofono_stk 
*stk,
        char *buf;
        int i;
 
+       if (stk->pending_cmd) {
+               /*
+                * In theory this shouldn't happen, but it depends on
+                * hardware.  We received a new command before we managed
+                * to send a TERMINAL RESPONSE to the previous one.  3GPP
+                * says in the current revision only one command can be
+                * executing at any time, so assume that the previous one
+                * is cancelled and the card just expects a response to
+                * the new one.
+                */
+               stk->cancel_cmd(stk);
+       }
+
        buf = g_try_malloc(length * 2 + 1);
        if (!buf)
                return;
@@ -513,11 +530,39 @@ static DBusMessage *stk_set_property(DBusConnection *conn,
        return __ofono_error_invalid_args(msg);
 }
 
+static void select_item_cancel(struct ofono_stk *stk)
+{
+       if (stk->pending)
+               /*
+                * TODO: D-bus command is just executing.  Should we go
+                * ahead and respond to it with failure, or wait for the
+                * result from driver?
+                */
+               stk->cancelled = TRUE;
+
+       if (stk->cmd_timeout) {
+               g_source_remove(stk->cmd_timeout);
+               stk->cmd_timeout = 0;
+       }
+
+       stk_command_free(stk->pending_cmd);
+       stk->pending_cmd = NULL;
+
+       stk_menu_free(stk->current_menu);
+       stk->current_menu = NULL;
+
+       emit_menu_changed(stk);
+}
+
 static void select_item_cb(const struct ofono_error *error,
                                struct ofono_stk *stk)
 {
        DBusMessage *reply;
 
+       if (stk->cancelled == TRUE)
+               /* Command cancelled */
+               goto out;
+
        if (stk->cmd_timeout) {
                /*
                 * If the command has not timed out yet, return error and
@@ -629,6 +674,7 @@ static DBusMessage *stk_menu_select(DBusConnection *conn, 
DBusMessage *msg,
        if (!item)
                return __ofono_error_invalid_args(msg);
 
+       stk->cancelled = FALSE;
        stk->pending = dbus_message_ref(msg);
 
        if (stk->current_menu)
@@ -668,6 +714,7 @@ static DBusMessage *stk_back_or_terminate(DBusConnection 
*conn,
        if (dbus_message_iter_init(msg, &iter))
                return __ofono_error_invalid_args(msg);
 
+       stk->cancelled = FALSE;
        stk->pending = dbus_message_ref(msg);
 
        memset(&rsp, 0, sizeof(rsp));
@@ -740,6 +787,7 @@ static gboolean handle_command_select_item(const struct 
stk_command *cmd,
        stk->cmd_timeout = g_timeout_add_seconds(stk->timeout,
                                                        select_item_timeout,
                                                        stk);
+       stk->cancel_cmd = select_item_cancel;
 
        return FALSE;
 }
-- 
1.7.1.86.g0e460.dirty

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to