* [PATCH 1/6] Add STK agent utilities and logic.
@ 2010-07-26 13:14 Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 2/6] stk: Add STK agent registration api Andrzej Zaborowski
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-26 13:14 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 9722 bytes --]
---
Makefile.am | 2 +-
src/stkagent.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/stkagent.h | 60 +++++++++++++
3 files changed, 321 insertions(+), 1 deletions(-)
create mode 100644 src/stkagent.c
create mode 100644 src/stkagent.h
diff --git a/Makefile.am b/Makefile.am
index e256841..0e9086b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -270,7 +270,7 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) \
src/storage.c src/cbs.c src/watch.c src/call-volume.c \
src/gprs.c src/idmap.h src/idmap.c \
src/radio-settings.c src/stkutil.h src/stkutil.c \
- src/nettime.c
+ src/nettime.c src/stkagent.c src/stkagent.h
src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@ -ldl
diff --git a/src/stkagent.c b/src/stkagent.c
new file mode 100644
index 0000000..1abd84d
--- /dev/null
+++ b/src/stkagent.c
@@ -0,0 +1,260 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+
+#include <glib.h>
+#include <gdbus.h>
+
+#include "ofono.h"
+
+#include "stkagent.h"
+
+#define OFONO_NAVIGATION_PREFIX OFONO_SERVICE ".Error"
+#define OFONO_NAVIGATION_GOBACK OFONO_NAVIGATION_PREFIX ".GoBack"
+#define OFONO_NAVIGATION_TERMINATED OFONO_NAVIGATION_PREFIX ".EndSession"
+
+static void app_agent_request_send_cancel(struct stk_app_agent *agent)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+ DBusMessage *message;
+
+ message = dbus_message_new_method_call(agent->bus, agent->path,
+ OFONO_SIM_APP_INTERFACE,
+ "Cancel");
+ if (message == NULL)
+ return;
+
+ dbus_message_set_no_reply(message, TRUE);
+
+ g_dbus_send_message(conn, message);
+}
+
+static void app_agent_request_end(struct stk_app_agent *agent)
+{
+ agent->cmd_send = NULL;
+ agent->cmd_cb = NULL;
+
+ if (agent->msg) {
+ dbus_message_unref(agent->msg);
+ agent->msg = NULL;
+ }
+
+ if (agent->call) {
+ dbus_pending_call_cancel(agent->call);
+ dbus_pending_call_unref(agent->call);
+ agent->call = NULL;
+ }
+}
+
+static gboolean app_agent_busy(struct stk_app_agent *agent)
+{
+ return agent->cmd_send != NULL;
+}
+
+void app_agent_request_cancel(struct stk_app_agent *agent)
+{
+ if (!app_agent_busy(agent))
+ return;
+
+ agent->cmd_cb(STK_AGENT_RESULT_CANCEL, NULL, agent->data);
+
+ app_agent_request_end(agent);
+
+ app_agent_request_send_cancel(agent);
+}
+
+static void app_agent_request_terminate(struct stk_app_agent *agent)
+{
+ agent->cmd_cb(STK_AGENT_RESULT_TERMINATE, NULL, agent->data);
+
+ app_agent_request_end(agent);
+}
+
+void app_agent_remove(struct stk_app_agent *agent)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+
+ if (agent->disconnect_watch) {
+ DBusMessage *message;
+
+ if (app_agent_busy(agent)) {
+ app_agent_request_terminate(agent);
+
+ app_agent_request_send_cancel(agent);
+ }
+
+ message = dbus_message_new_method_call(agent->bus, agent->path,
+ OFONO_SIM_APP_INTERFACE,
+ "Release");
+ if (message) {
+ dbus_message_set_no_reply(message, TRUE);
+
+ g_dbus_send_message(conn, message);
+ }
+
+ g_dbus_remove_watch(conn, agent->disconnect_watch);
+ agent->disconnect_watch = 0;
+ } else {
+ if (app_agent_busy(agent))
+ app_agent_request_terminate(agent);
+ }
+
+ if (agent->notify)
+ agent->notify(agent->data);
+
+ g_free(agent->path);
+ g_free(agent->bus);
+ g_free(agent);
+}
+
+static void app_agent_request_reply_handle(DBusPendingCall *call, void *data)
+{
+ struct stk_app_agent *agent = data;
+ DBusError err;
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ enum stk_agent_result result = STK_AGENT_RESULT_OK;
+
+ dbus_error_init(&err);
+ if (dbus_set_error_from_message(&err, reply)) {
+ ofono_error("SimAppAgent %s replied with error %s, %s",
+ agent->path, err.name, err.message);
+
+ if (g_str_equal(err.name, DBUS_ERROR_NO_REPLY))
+ result = STK_AGENT_RESULT_TIMEOUT;
+ if (g_str_equal(err.name, OFONO_NAVIGATION_GOBACK))
+ result = STK_AGENT_RESULT_BACK;
+ else
+ result = STK_AGENT_RESULT_TERMINATE;
+
+ dbus_error_free(&err);
+ }
+
+ agent->cmd_cb(result, reply, agent->data);
+
+ app_agent_request_end(agent);
+
+ dbus_message_unref(reply);
+
+ if (result != STK_AGENT_RESULT_TERMINATE)
+ return;
+
+ if (agent->is_default)
+ return;
+
+ app_agent_remove(agent);
+}
+
+static gboolean app_agent_request_send(struct stk_app_agent *agent, int timeout)
+{
+ DBusConnection *conn = ofono_dbus_get_connection();
+
+ /*
+ * The cmd_send callback needs to set the method name to
+ * something different than "Cancel".
+ */
+ agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
+ OFONO_SIM_APP_INTERFACE,
+ "Cancel");
+ if (agent->msg == NULL) {
+ ofono_error("Couldn't make a DBusMessage");
+ return FALSE;
+ }
+
+ agent->cmd_send(agent->msg, agent->data);
+
+ if (dbus_connection_send_with_reply(conn,
+ agent->msg, &agent->call, timeout) == FALSE ||
+ agent->call == NULL) {
+ dbus_message_unref(agent->msg);
+ agent->msg = NULL;
+
+ ofono_error("Couldn't send a method call");
+ return FALSE;
+ }
+
+ dbus_pending_call_set_notify(agent->call,
+ app_agent_request_reply_handle,
+ agent, NULL);
+
+ return TRUE;
+}
+
+void app_agent_request_start(struct stk_app_agent *agent,
+ stk_agent_request_send send,
+ stk_agent_request_return cb, int timeout)
+{
+ if (agent == NULL) {
+ cb(STK_AGENT_RESULT_TERMINATE, NULL, agent->data);
+
+ return;
+ }
+
+ if (app_agent_busy(agent))
+ app_agent_request_cancel(agent);
+
+ agent->cmd_send = send;
+ agent->cmd_cb = cb;
+
+ if (!app_agent_request_send(agent, timeout)) {
+ app_agent_request_terminate(agent);
+
+ return;
+ }
+}
+
+static void app_agent_disconnect_cb(DBusConnection *conn, void *user_data)
+{
+ struct stk_app_agent *agent = user_data;
+
+ ofono_debug("Agent exited without calling Unregister");
+
+ agent->disconnect_watch = 0;
+
+ app_agent_remove(user_data);
+}
+
+struct stk_app_agent *app_agent_create(const char *path, const char *sender,
+ ofono_bool_t is_default,
+ void *user_data, GDestroyNotify notify)
+{
+ struct stk_app_agent *agent = g_try_new0(struct stk_app_agent, 1);
+ DBusConnection *conn = ofono_dbus_get_connection();
+
+ if (!agent)
+ return NULL;
+
+ agent->path = g_strdup(path);
+ agent->bus = g_strdup(sender);
+ agent->data = user_data;
+ agent->notify = notify;
+ agent->is_default = is_default;
+
+ agent->disconnect_watch = g_dbus_add_disconnect_watch(conn, sender,
+ app_agent_disconnect_cb,
+ agent, NULL);
+
+ return agent;
+}
diff --git a/src/stkagent.h b/src/stkagent.h
new file mode 100644
index 0000000..1b64fa7
--- /dev/null
+++ b/src/stkagent.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+enum stk_agent_result {
+ STK_AGENT_RESULT_OK,
+ STK_AGENT_RESULT_BACK,
+ STK_AGENT_RESULT_TERMINATE,
+ STK_AGENT_RESULT_HELP,
+ STK_AGENT_RESULT_TIMEOUT,
+ STK_AGENT_RESULT_CANCEL,
+};
+
+typedef void (*stk_agent_request_send)(DBusMessage *call, void *user_data);
+
+typedef void (*stk_agent_request_return)(enum stk_agent_result result,
+ DBusMessage *reply,
+ void *user_data);
+
+struct stk_app_agent {
+ char *path;
+ char *bus;
+ DBusMessage *msg;
+ DBusPendingCall *call;
+ guint disconnect_watch;
+ stk_agent_request_send cmd_send;
+ stk_agent_request_return cmd_cb;
+ void *data;
+ ofono_bool_t is_default;
+ GDestroyNotify notify;
+};
+
+struct stk_app_agent *app_agent_create(const char *path, const char *sender,
+ ofono_bool_t is_default,
+ void *user_data, GDestroyNotify notify);
+
+void app_agent_remove(struct stk_app_agent *agent);
+
+void app_agent_request_start(struct stk_app_agent *agent,
+ stk_agent_request_send cmd_send,
+ stk_agent_request_return cmd_cb, int timeout);
+
+void app_agent_request_cancel(struct stk_app_agent *agent);
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/6] stk: Add STK agent registration api.
2010-07-26 13:14 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
@ 2010-07-26 13:14 ` Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 3/6] stk: Utilities to deal with menus Andrzej Zaborowski
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-26 13:14 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 5927 bytes --]
This implements the agent registration and lifecycle and the command
implementations will use the functions added here and in the previous
patch.
---
src/stk.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 159 insertions(+), 0 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index 556dc68..a4a091c 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -38,6 +38,7 @@
#include "common.h"
#include "smsutil.h"
#include "stkutil.h"
+#include "stkagent.h"
static GSList *g_drivers = NULL;
@@ -57,6 +58,11 @@ struct ofono_stk {
struct stk_timer timers[8];
guint timers_source;
+ int timeout;
+ int short_timeout;
+ guint remove_agent_source;
+ struct stk_app_agent *session_agent;
+ struct stk_app_agent *default_agent;
struct sms_submit_req *sms_submit_req;
char *idle_mode_text;
};
@@ -255,8 +261,148 @@ static DBusMessage *stk_get_properties(DBusConnection *conn,
return reply;
}
+static void stk_agent_request_start(struct ofono_stk *stk,
+ stk_agent_request_send cmd_send,
+ stk_agent_request_return cmd_cb,
+ int timeout)
+{
+ struct stk_app_agent *agent = stk->default_agent;
+
+ if (stk->session_agent)
+ agent = stk->session_agent;
+
+ /* Use the timeout value specified in the command or the default. */
+ if (timeout == 0)
+ timeout = stk->timeout * 1000;
+ else if (timeout < 0)
+ timeout = INT_MAX;
+
+ return app_agent_request_start(agent, cmd_send, cmd_cb, timeout);
+}
+
+static void stk_agent_request_cancel(struct ofono_stk *stk)
+{
+ if (stk->session_agent)
+ app_agent_request_cancel(stk->session_agent);
+
+ if (stk->default_agent)
+ app_agent_request_cancel(stk->default_agent);
+}
+
+static void default_agent_notify(gpointer user_data)
+{
+ struct ofono_stk *stk = user_data;
+
+ stk->default_agent = NULL;
+}
+
+static void session_agent_notify(gpointer user_data)
+{
+ struct ofono_stk *stk = user_data;
+
+ stk->session_agent = NULL;
+
+ if (stk->remove_agent_source) {
+ g_source_remove(stk->remove_agent_source);
+ stk->remove_agent_source = 0;
+ }
+}
+
+static gboolean session_agent_remove_cb(gpointer user_data)
+{
+ struct ofono_stk *stk = user_data;
+
+ stk->remove_agent_source = 0;
+
+ app_agent_remove(stk->session_agent);
+
+ return FALSE;
+}
+
+/* Safely remove the agent even inside a callback */
+static void session_agent_remove(struct ofono_stk *stk)
+{
+ if (!stk->remove_agent_source)
+ stk->remove_agent_source =
+ g_timeout_add(0, session_agent_remove_cb, stk);
+}
+
+static DBusMessage *stk_register_agent(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_stk *stk = data;
+ const char *agent_path;
+
+ if (stk->default_agent)
+ return __ofono_error_busy(msg);
+
+ if (dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_OBJECT_PATH, &agent_path,
+ DBUS_TYPE_INVALID) == FALSE)
+ return __ofono_error_invalid_args(msg);
+
+ stk->default_agent = app_agent_create(agent_path,
+ dbus_message_get_sender(msg),
+ TRUE, stk,
+ default_agent_notify);
+ if (!stk->default_agent)
+ return __ofono_error_failed(msg);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *stk_unregister_agent(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_stk *stk = data;
+ const char *agent_path;
+ const char *agent_bus = dbus_message_get_sender(msg);
+
+ if (dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_OBJECT_PATH, &agent_path,
+ DBUS_TYPE_INVALID) == FALSE)
+ return __ofono_error_invalid_args(msg);
+
+ if (!stk->default_agent)
+ return __ofono_error_failed(msg);
+
+ if (strcmp(stk->default_agent->path, agent_path))
+ return __ofono_error_failed(msg);
+ if (strcmp(stk->default_agent->bus, agent_bus))
+ return __ofono_error_failed(msg);
+
+ app_agent_remove(stk->default_agent);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *stk_select_item(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_stk *stk = data;
+ const char *agent_path;
+ unsigned char selection;
+
+ if (stk->session_agent)
+ return __ofono_error_busy(msg);
+
+ if (dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_BYTE, &selection,
+ DBUS_TYPE_OBJECT_PATH, &agent_path,
+ DBUS_TYPE_INVALID) == FALSE)
+ return __ofono_error_invalid_args(msg);
+
+ /* TODO */
+
+ return __ofono_error_not_implemented(msg);
+}
+
static GDBusMethodTable stk_methods[] = {
{ "GetProperties", "", "a{sv}",stk_get_properties },
+ { "SelectItem", "yo", "", stk_select_item,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "RegisterAgent", "o", "", stk_register_agent },
+ { "UnregisterAgent", "o", "", stk_unregister_agent },
{ }
};
@@ -576,6 +722,11 @@ static void stk_proactive_command_cancel(struct ofono_stk *stk)
void ofono_stk_proactive_session_end_notify(struct ofono_stk *stk)
{
stk_proactive_command_cancel(stk);
+
+ if (stk->session_agent) {
+ app_agent_remove(stk->session_agent);
+ stk->session_agent = NULL;
+ }
}
void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
@@ -687,6 +838,12 @@ static void stk_unregister(struct ofono_atom *atom)
struct ofono_modem *modem = __ofono_atom_get_modem(atom);
const char *path = __ofono_atom_get_path(atom);
+ if (stk->session_agent)
+ app_agent_remove(stk->session_agent);
+
+ if (stk->default_agent)
+ app_agent_remove(stk->default_agent);
+
if (stk->pending_cmd) {
stk_command_free(stk->pending_cmd);
stk->pending_cmd = NULL;
@@ -778,6 +935,8 @@ void ofono_stk_register(struct ofono_stk *stk)
__ofono_atom_register(stk->atom, stk_unregister);
+ stk->timeout = 600; /* 10 minutes */
+ stk->short_timeout = 20; /* 20 seconds */
stk->envelope_q = g_queue_new();
}
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/6] stk: Utilities to deal with menus.
2010-07-26 13:14 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 2/6] stk: Add STK agent registration api Andrzej Zaborowski
@ 2010-07-26 13:14 ` Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 4/6] stk: Handle the main menu Andrzej Zaborowski
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-26 13:14 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 4528 bytes --]
---
src/stk.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 132 insertions(+), 0 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index a4a091c..29174d7 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -47,6 +47,17 @@ struct stk_timer {
time_t start;
};
+struct stk_menu {
+ char *title;
+ GSList *items;
+ struct stk_items_next_action_indicator next_action;
+ int default_item;
+ struct stk_text_attribute title_attr;
+ struct stk_item_text_attribute_list item_attrs;
+ gboolean soft_key;
+ gboolean has_help;
+};
+
struct ofono_stk {
const struct ofono_stk_driver *driver;
void *driver_data;
@@ -223,6 +234,127 @@ static void stk_command_cb(const struct ofono_error *error, void *data)
DBG("TERMINAL RESPONSE to a command reported no errors");
}
+static struct stk_menu *stk_menu_create(const char *title,
+ const struct stk_text_attribute *title_attr, GSList *items,
+ const struct stk_item_text_attribute_list *item_attrs,
+ const struct stk_items_next_action_indicator *next_action,
+ int default_id, gboolean soft_key, gboolean has_help)
+{
+ struct stk_menu *ret = g_new(struct stk_menu, 1);
+ GSList *l;
+ int i;
+
+ ret->title = g_strdup(title ?: "");
+ ret->items = g_slist_copy((GSList *) items);
+ ret->default_item = -1;
+ memcpy(&ret->next_action, next_action, sizeof(ret->next_action));
+ memcpy(&ret->title_attr, title_attr, sizeof(ret->title_attr));
+ memcpy(&ret->item_attrs, item_attrs, sizeof(ret->item_attrs));
+ ret->soft_key = soft_key;
+ ret->has_help = has_help;
+
+ for (l = ret->items, i = 0; l; l = l->next, i++) {
+ struct stk_item *j = g_memdup(l->data, sizeof(*j));
+
+ j->text = g_strdup(j->text);
+ l->data = j;
+
+ if (j->id == default_id)
+ ret->default_item = i;
+ }
+
+ return ret;
+}
+
+static struct stk_menu *stk_menu_create_from_set_up_menu(
+ const struct stk_command *cmd)
+{
+ gboolean soft_key = (cmd->qualifier & (1 << 0)) != 0;
+ gboolean has_help = (cmd->qualifier & (1 << 7)) != 0;
+
+ return stk_menu_create(cmd->setup_menu.alpha_id,
+ &cmd->setup_menu.text_attr,
+ cmd->setup_menu.items,
+ &cmd->setup_menu.item_text_attr_list,
+ &cmd->setup_menu.next_act,
+ 0, soft_key, has_help);
+}
+
+static struct stk_menu *stk_menu_create_from_select_item(
+ const struct stk_command *cmd)
+{
+ gboolean soft_key = (cmd->qualifier & (1 << 2)) != 0;
+ gboolean has_help = (cmd->qualifier & (1 << 7)) != 0;
+
+ return stk_menu_create(cmd->select_item.alpha_id,
+ &cmd->select_item.text_attr,
+ cmd->select_item.items,
+ &cmd->select_item.item_text_attr_list,
+ &cmd->select_item.next_act,
+ cmd->select_item.item_id, soft_key, has_help);
+}
+
+static void stk_menu_free(struct stk_menu *menu)
+{
+ GSList *l;
+
+ for (l = menu->items; l; l = l->next) {
+ struct stk_item *i = l->data;
+
+ g_free(i->text);
+ g_free(i);
+ }
+
+ g_slist_free(menu->items);
+ g_free(menu->title);
+ g_free(menu);
+}
+
+static void append_menu_items(DBusMessageIter *iter, struct stk_menu *menu)
+{
+ DBusMessageIter variant, array, entry;
+ GSList *l;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+ "a(sy)", &variant);
+
+ dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
+ "(sy)", &array);
+
+ for (l = menu->items; l; l = l->next) {
+ struct stk_item *item = l->data;
+ unsigned char icon_id = 0;
+
+ dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
+ &item->text);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_BYTE,
+ &icon_id);
+
+ dbus_message_iter_close_container(&array, &entry);
+ }
+
+ dbus_message_iter_close_container(&variant, &array);
+
+ dbus_message_iter_close_container(iter, &variant);
+}
+
+static void append_menu(DBusMessage *msg, struct stk_menu *menu)
+{
+ dbus_int16_t default_item = menu->default_item;
+ unsigned char icon_id = 0;
+ DBusMessageIter iter;
+
+ dbus_message_iter_init_append(msg, &iter);
+
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &menu->title);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE, &icon_id);
+ append_menu_items(&iter, menu);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT16, &default_item);
+}
+
static void stk_alpha_id_set(struct ofono_stk *stk, const char *text)
{
/* TODO */
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/6] stk: Handle the main menu.
2010-07-26 13:14 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 2/6] stk: Add STK agent registration api Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 3/6] stk: Utilities to deal with menus Andrzej Zaborowski
@ 2010-07-26 13:14 ` Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 5/6] stk: Handle the Select Item proactive command Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 6/6] stk: Handle the Display Text " Andrzej Zaborowski
4 siblings, 0 replies; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-26 13:14 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 7377 bytes --]
---
src/stk.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 179 insertions(+), 5 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index 29174d7..f212e9a 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -65,6 +65,7 @@ struct ofono_stk {
struct stk_command *pending_cmd;
void (*cancel_cmd)(struct ofono_stk *stk);
GQueue *envelope_q;
+ DBusMessage *pending;
struct stk_timer timers[8];
guint timers_source;
@@ -74,6 +75,8 @@ struct ofono_stk {
guint remove_agent_source;
struct stk_app_agent *session_agent;
struct stk_app_agent *default_agent;
+ struct stk_menu *main_menu;
+ gboolean in_session;
struct sms_submit_req *sms_submit_req;
char *idle_mode_text;
};
@@ -355,6 +358,65 @@ static void append_menu(DBusMessage *msg, struct stk_menu *menu)
dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT16, &default_item);
}
+static void emit_menu_changed(struct ofono_stk *stk)
+{
+ static struct stk_menu no_menu = {
+ .title = "",
+ .items = NULL,
+ .has_help = FALSE,
+ .default_item = -1,
+ };
+ static char *name = "MainMenu";
+ DBusConnection *conn = ofono_dbus_get_connection();
+ const char *path = __ofono_atom_get_path(stk->atom);
+ struct stk_menu *menu = &no_menu;
+ DBusMessage *signal;
+ DBusMessageIter iter;
+
+ if (stk->main_menu && !stk->in_session)
+ menu = stk->main_menu;
+
+ ofono_dbus_signal_property_changed(conn, path,
+ OFONO_STK_INTERFACE,
+ "MainMenuTitle",
+ DBUS_TYPE_STRING, &menu->title);
+
+ signal = dbus_message_new_signal(path, OFONO_STK_INTERFACE,
+ "PropertyChanged");
+ if (!signal) {
+ ofono_error("Unable to allocate new %s.PropertyChanged signal",
+ OFONO_SIM_APP_INTERFACE);
+
+ return;
+ }
+
+ dbus_message_iter_init_append(signal, &iter);
+
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
+
+ append_menu_items(&iter, menu);
+
+ g_dbus_send_message(conn, signal);
+}
+
+static void dict_append_menu(DBusMessageIter *dict, struct stk_menu *menu)
+{
+ DBusMessageIter entry;
+ const char *key = "MainMenu";
+
+ ofono_dbus_dict_append(dict, "MainMenuTitle",
+ DBUS_TYPE_STRING, &menu->title);
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ append_menu_items(&entry, menu);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
static void stk_alpha_id_set(struct ofono_stk *stk, const char *text)
{
/* TODO */
@@ -388,6 +450,9 @@ static DBusMessage *stk_get_properties(DBusConnection *conn,
ofono_dbus_dict_append(&dict, "IdleModeText",
DBUS_TYPE_STRING, &idle_mode_text);
+ if (stk->main_menu && !stk->in_session)
+ dict_append_menu(&dict, stk->main_menu);
+
dbus_message_iter_close_container(&iter, &dict);
return reply;
@@ -508,14 +573,70 @@ static DBusMessage *stk_unregister_agent(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}
+static void menu_selection_envelope_cb(struct ofono_stk *stk, gboolean ok,
+ const unsigned char *data, int len)
+{
+ unsigned char selection;
+ const char *agent_path;
+ DBusMessage *reply;
+
+ if (!ok) {
+ ofono_error("Sending Menu Selection to UICC failed");
+
+ reply = __ofono_error_failed(stk->pending);
+
+ goto out;
+ }
+
+ if (len)
+ ofono_error("Menu Selection returned %i bytes of unwanted data",
+ len);
+
+ DBG("Menu Selection envelope submission gave no error");
+
+ if (dbus_message_get_args(stk->pending, NULL,
+ DBUS_TYPE_BYTE, &selection,
+ DBUS_TYPE_OBJECT_PATH, &agent_path,
+ DBUS_TYPE_INVALID) == FALSE) {
+ reply = __ofono_error_failed(stk->pending);
+
+ goto out;
+ }
+
+ stk->session_agent = app_agent_create(agent_path,
+ dbus_message_get_sender(stk->pending),
+ FALSE, stk, session_agent_notify);
+ if (!stk->session_agent) {
+ reply = __ofono_error_failed(stk->pending);
+
+ goto out;
+ }
+
+ reply = dbus_message_new_method_return(stk->pending);
+
+ if (!stk->in_session) {
+ stk->in_session = TRUE;
+ emit_menu_changed(stk);
+ }
+
+out:
+ __ofono_dbus_pending_reply(&stk->pending, reply);
+}
+
static DBusMessage *stk_select_item(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct ofono_stk *stk = data;
const char *agent_path;
unsigned char selection;
+ struct stk_envelope e;
+ struct stk_menu *menu = stk->main_menu;
+ struct stk_item *item = NULL;
- if (stk->session_agent)
+ if (stk->pending)
+ return __ofono_error_busy(msg);
+
+ if (stk->session_agent || !menu)
return __ofono_error_busy(msg);
if (dbus_message_get_args(msg, NULL,
@@ -524,9 +645,22 @@ static DBusMessage *stk_select_item(DBusConnection *conn,
DBUS_TYPE_INVALID) == FALSE)
return __ofono_error_invalid_args(msg);
- /* TODO */
+ item = g_slist_nth_data(menu->items, selection);
+ if (!item)
+ return __ofono_error_invalid_format(msg);
+
+ memset(&e, 0, sizeof(e));
+ e.type = STK_ENVELOPE_TYPE_MENU_SELECTION;
+ e.src = STK_DEVICE_IDENTITY_TYPE_KEYPAD,
+ e.menu_selection.item_id = item->id;
+ e.menu_selection.help_request = FALSE;
+
+ if (stk_send_envelope(stk, &e, menu_selection_envelope_cb, 0))
+ return __ofono_error_failed(msg);
- return __ofono_error_not_implemented(msg);
+ stk->pending = dbus_message_ref(msg);
+
+ return NULL;
}
static GDBusMethodTable stk_methods[] = {
@@ -838,6 +972,34 @@ static gboolean handle_command_poll_interval(const struct stk_command *cmd,
return TRUE;
}
+static gboolean handle_command_set_up_menu(const struct stk_command *cmd,
+ struct stk_response *rsp,
+ struct ofono_stk *stk)
+{
+ gboolean modified = FALSE;
+
+ if (stk->main_menu) {
+ stk_menu_free(stk->main_menu);
+ stk->main_menu = NULL;
+
+ modified = TRUE;
+ }
+
+ if (cmd->setup_menu.items) {
+ stk->main_menu = stk_menu_create_from_set_up_menu(cmd);
+
+ if (stk->main_menu)
+ modified = TRUE;
+ else
+ rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+ }
+
+ if (modified && !stk->in_session)
+ emit_menu_changed(stk);
+
+ return TRUE;
+}
+
static void stk_proactive_command_cancel(struct ofono_stk *stk)
{
if (!stk->pending_cmd)
@@ -855,9 +1017,12 @@ void ofono_stk_proactive_session_end_notify(struct ofono_stk *stk)
{
stk_proactive_command_cancel(stk);
- if (stk->session_agent) {
+ if (stk->session_agent)
app_agent_remove(stk->session_agent);
- stk->session_agent = NULL;
+
+ if (stk->in_session) {
+ stk->in_session = FALSE;
+ emit_menu_changed(stk);
}
}
@@ -919,6 +1084,10 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
respond = handle_command_poll_interval(stk->pending_cmd,
&rsp, stk);
break;
+ case STK_COMMAND_TYPE_SETUP_MENU:
+ respond = handle_command_set_up_menu(stk->pending_cmd,
+ &rsp, stk);
+ break;
}
if (respond)
@@ -991,6 +1160,11 @@ static void stk_unregister(struct ofono_atom *atom)
stk->timers_source = 0;
}
+ if (stk->main_menu) {
+ stk_menu_free(stk->main_menu);
+ stk->main_menu = NULL;
+ }
+
g_queue_foreach(stk->envelope_q, (GFunc) g_free, NULL);
g_queue_free(stk->envelope_q);
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/6] stk: Handle the Select Item proactive command.
2010-07-26 13:14 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
` (2 preceding siblings ...)
2010-07-26 13:14 ` [PATCH 4/6] stk: Handle the main menu Andrzej Zaborowski
@ 2010-07-26 13:14 ` Andrzej Zaborowski
2010-07-27 0:27 ` Marcel Holtmann
2010-07-26 13:14 ` [PATCH 6/6] stk: Handle the Display Text " Andrzej Zaborowski
4 siblings, 1 reply; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-26 13:14 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3534 bytes --]
---
src/stk.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 105 insertions(+), 1 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index f212e9a..0aaf83d 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -75,7 +75,7 @@ struct ofono_stk {
guint remove_agent_source;
struct stk_app_agent *session_agent;
struct stk_app_agent *default_agent;
- struct stk_menu *main_menu;
+ struct stk_menu *main_menu, *select_item_menu;
gboolean in_session;
struct sms_submit_req *sms_submit_req;
char *idle_mode_text;
@@ -1000,6 +1000,106 @@ static gboolean handle_command_set_up_menu(const struct stk_command *cmd,
return TRUE;
}
+static void request_menu_send(DBusMessage *call, void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ struct stk_menu *menu = stk->select_item_menu;
+
+ dbus_message_set_member(call, "RequestSelection");
+
+ append_menu(call, menu);
+}
+
+static void request_menu_cb(enum stk_agent_result result, DBusMessage *reply,
+ void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ struct stk_menu *menu = stk->select_item_menu;
+ struct stk_item *item = NULL;
+ enum stk_result_type type;
+ unsigned char selection;
+ struct stk_response rsp;
+ static struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+
+ switch (result) {
+ case STK_AGENT_RESULT_OK:
+ type = STK_RESULT_TYPE_SUCCESS;
+ break;
+
+ case STK_AGENT_RESULT_BACK:
+ type = STK_RESULT_TYPE_GO_BACK;
+ goto send;
+
+ case STK_AGENT_RESULT_TIMEOUT:
+ type = STK_RESULT_TYPE_NO_RESPONSE;
+ goto send;
+
+ case STK_AGENT_RESULT_TERMINATE:
+ default:
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+ goto send;
+
+ case STK_AGENT_RESULT_CANCEL:
+ goto out;
+ }
+
+ if (dbus_message_get_args(reply, NULL,
+ DBUS_TYPE_BYTE, &selection,
+ DBUS_TYPE_INVALID) == FALSE) {
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+
+ ofono_error("Can't parse the reply to SelectItem()");
+ goto send;
+ }
+
+ item = g_slist_nth_data(menu->items, selection);
+ if (!item) {
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+ ofono_error("Invalid item selected");
+ }
+
+send:
+ memset(&rsp, 0, sizeof(rsp));
+ rsp.result.type = type;
+
+ if (item)
+ rsp.select_item.item_id = item->id;
+
+ if (stk_respond(stk, &rsp, stk_command_cb))
+ stk_command_cb(&error, stk);
+
+out:
+ stk_menu_free(menu);
+ stk->select_item_menu = NULL;
+}
+
+static gboolean handle_command_select_item(const struct stk_command *cmd,
+ struct stk_response *rsp,
+ struct ofono_stk *stk)
+{
+ stk->select_item_menu = stk_menu_create_from_select_item(cmd);
+
+ if (!stk->select_item_menu) {
+ rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+
+ return TRUE;
+ }
+
+ if (!stk->in_session) {
+ stk->in_session = TRUE;
+
+ if (stk->main_menu)
+ emit_menu_changed(stk);
+ }
+
+ stk->cancel_cmd = stk_agent_request_cancel;
+
+ stk_agent_request_start(stk,
+ request_menu_send, request_menu_cb, 0);
+
+ return FALSE;
+}
+
static void stk_proactive_command_cancel(struct ofono_stk *stk)
{
if (!stk->pending_cmd)
@@ -1088,6 +1188,10 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
respond = handle_command_set_up_menu(stk->pending_cmd,
&rsp, stk);
break;
+ case STK_COMMAND_TYPE_SELECT_ITEM:
+ respond = handle_command_select_item(stk->pending_cmd,
+ &rsp, stk);
+ break;
}
if (respond)
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/6] stk: Handle the Display Text proactive command.
2010-07-26 13:14 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
` (3 preceding siblings ...)
2010-07-26 13:14 ` [PATCH 5/6] stk: Handle the Select Item proactive command Andrzej Zaborowski
@ 2010-07-26 13:14 ` Andrzej Zaborowski
4 siblings, 0 replies; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-26 13:14 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 5697 bytes --]
---
src/stk.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 157 insertions(+), 3 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index 0aaf83d..9e3c14f 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -79,6 +79,7 @@ struct ofono_stk {
gboolean in_session;
struct sms_submit_req *sms_submit_req;
char *idle_mode_text;
+ gboolean session_ended;
};
struct envelope_op {
@@ -1100,6 +1101,125 @@ static gboolean handle_command_select_item(const struct stk_command *cmd,
return FALSE;
}
+static void request_text_send(DBusMessage *call, void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ struct stk_command_display_text *dt = &stk->pending_cmd->display_text;
+ uint8_t qualifier = stk->pending_cmd->qualifier;
+ dbus_bool_t confirm = (qualifier & (1 << 7)) != 0;
+ dbus_bool_t priority = (qualifier & (1 << 0)) != 0;
+ unsigned char icon_id = 0;
+
+ dbus_message_set_member(call, "DisplayText");
+
+ dbus_message_append_args(call,
+ DBUS_TYPE_STRING, &dt->text,
+ DBUS_TYPE_BYTE, &icon_id,
+ DBUS_TYPE_BOOLEAN, &priority,
+ DBUS_TYPE_BOOLEAN, &confirm,
+ DBUS_TYPE_INVALID);
+}
+
+static void request_text_cb(enum stk_agent_result result, DBusMessage *reply,
+ void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ enum stk_result_type type = STK_RESULT_TYPE_SUCCESS;
+ gboolean confirm;
+ struct stk_response rsp;
+ static struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+
+ /*
+ * Check if we have already responded to the proactive command
+ * because immediate response was requested.
+ */
+ if (!stk->pending_cmd || stk->pending_cmd->type !=
+ STK_COMMAND_TYPE_DISPLAY_TEXT ||
+ stk->pending_cmd->display_text.immediate_response) {
+ /*
+ * If session has ended in the meantime now is the time
+ * to go back to main menu or close the application
+ * window.
+ */
+ if (stk->session_ended && stk->session_agent)
+ session_agent_remove(stk);
+
+ return;
+ }
+
+ switch (result) {
+ case STK_AGENT_RESULT_OK:
+ break;
+
+ case STK_AGENT_RESULT_BACK:
+ type = STK_RESULT_TYPE_GO_BACK;
+ goto send;
+
+ case STK_AGENT_RESULT_TIMEOUT:
+ confirm = (stk->pending_cmd->qualifier & (1 << 7)) != 0;
+ if (confirm)
+ type = STK_RESULT_TYPE_NO_RESPONSE;
+
+ goto send;
+
+ case STK_AGENT_RESULT_TERMINATE:
+ default:
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+ goto send;
+
+ case STK_AGENT_RESULT_CANCEL:
+ return;
+ }
+
+ if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+
+ ofono_error("Reply not understood");
+ }
+
+send:
+ memset(&rsp, 0, sizeof(rsp));
+ rsp.result.type = type;
+
+ if (stk_respond(stk, &rsp, stk_command_cb))
+ stk_command_cb(&error, stk);
+}
+
+static gboolean handle_command_display_text(const struct stk_command *cmd,
+ struct stk_response *rsp,
+ struct ofono_stk *stk)
+{
+ int timeout = stk->short_timeout * 1000;
+
+ if (cmd->display_text.duration.interval) {
+ timeout = cmd->display_text.duration.interval;
+ switch (cmd->display_text.duration.unit) {
+ case STK_DURATION_TYPE_MINUTES:
+ timeout *= 60;
+ case STK_DURATION_TYPE_SECONDS:
+ timeout *= 10;
+ case STK_DURATION_TYPE_SECOND_TENTHS:
+ timeout *= 100;
+ }
+ }
+
+ if (!stk->in_session) {
+ stk->in_session = TRUE;
+
+ if (stk->main_menu)
+ emit_menu_changed(stk);
+ } else
+ stk_agent_request_cancel(stk);
+
+ stk->cancel_cmd = stk_agent_request_cancel;
+ stk->session_ended = FALSE;
+
+ stk_agent_request_start(stk,
+ request_text_send, request_text_cb, timeout);
+
+ return cmd->display_text.immediate_response;
+}
+
static void stk_proactive_command_cancel(struct ofono_stk *stk)
{
if (!stk->pending_cmd)
@@ -1117,12 +1237,42 @@ void ofono_stk_proactive_session_end_notify(struct ofono_stk *stk)
{
stk_proactive_command_cancel(stk);
- if (stk->session_agent)
- app_agent_remove(stk->session_agent);
+ if (!stk->session_agent)
+ goto out;
+
+ /*
+ * Go back to main menu, except when a DisplayText command has
+ * been issued with the Immediate Response flag set (TS 102.223
+ * Section 6.9):
+ * "If the text is to be sustained, the terminal shall display
+ * the text of applicable DISPLAY TEXT commands beyond the sending
+ * of the TERMINAL RESPONSE and possibly beyond the end of the
+ * proactive session.
+ *
+ * If a variable display timeout was indicated for a DISPLAY TEXT
+ * command, then the session releases the display back into terminal
+ * control no later then the period stated by the duration. If the
+ * text is to be sustained beyond an immediate response, the
+ * terminal shall display the text for a period that does not
+ * exceed the duration."
+ *
+ * For this case we set a flag and when the text stops being
+ * displayed we will make sure to go to main menu then.
+ */
+ if (!stk->pending_cmd && stk->session_agent->cmd_cb) {
+ stk->session_ended = TRUE;
+
+ return;
+ }
+
+ app_agent_remove(stk->session_agent);
+out:
if (stk->in_session) {
stk->in_session = FALSE;
- emit_menu_changed(stk);
+
+ if (stk->main_menu)
+ emit_menu_changed(stk);
}
}
@@ -1192,6 +1342,10 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
respond = handle_command_select_item(stk->pending_cmd,
&rsp, stk);
break;
+ case STK_COMMAND_TYPE_DISPLAY_TEXT:
+ respond = handle_command_display_text(stk->pending_cmd,
+ &rsp, stk);
+ break;
}
if (respond)
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 5/6] stk: Handle the Select Item proactive command.
2010-07-26 13:14 ` [PATCH 5/6] stk: Handle the Select Item proactive command Andrzej Zaborowski
@ 2010-07-27 0:27 ` Marcel Holtmann
2010-07-27 0:53 ` Andrzej Zaborowski
0 siblings, 1 reply; 10+ messages in thread
From: Marcel Holtmann @ 2010-07-27 0:27 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 924 bytes --]
Hi Andew,
> + switch (result) {
> + case STK_AGENT_RESULT_OK:
> + type = STK_RESULT_TYPE_SUCCESS;
> + break;
> +
> + case STK_AGENT_RESULT_BACK:
> + type = STK_RESULT_TYPE_GO_BACK;
> + goto send;
> +
> + case STK_AGENT_RESULT_TIMEOUT:
> + type = STK_RESULT_TYPE_NO_RESPONSE;
> + goto send;
> +
> + case STK_AGENT_RESULT_TERMINATE:
> + default:
> + type = STK_RESULT_TYPE_USER_TERMINATED;
> + goto send;
> +
> + case STK_AGENT_RESULT_CANCEL:
> + goto out;
> + }
have you tested this? The STK_AGENT_RESULT_CANCEL will never be reached
since we hit default label first.
As a general rule, default label should always be the last one. And in
case this is an enum, you can just skip default label and let the
compiler warn you about unhandled enum entries.
So just duplicate the code or re-arrange the order and work with a
proper /* fall trough */ comment.
Regards
Marcel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 5/6] stk: Handle the Select Item proactive command.
2010-07-27 0:27 ` Marcel Holtmann
@ 2010-07-27 0:53 ` Andrzej Zaborowski
0 siblings, 0 replies; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-27 0:53 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1352 bytes --]
Hi,
On 27 July 2010 02:27, Marcel Holtmann <marcel@holtmann.org> wrote:
>> + switch (result) {
>> + case STK_AGENT_RESULT_OK:
>> + type = STK_RESULT_TYPE_SUCCESS;
>> + break;
>> +
>> + case STK_AGENT_RESULT_BACK:
>> + type = STK_RESULT_TYPE_GO_BACK;
>> + goto send;
>> +
>> + case STK_AGENT_RESULT_TIMEOUT:
>> + type = STK_RESULT_TYPE_NO_RESPONSE;
>> + goto send;
>> +
>> + case STK_AGENT_RESULT_TERMINATE:
>> + default:
>> + type = STK_RESULT_TYPE_USER_TERMINATED;
>> + goto send;
>> +
>> + case STK_AGENT_RESULT_CANCEL:
>> + goto out;
>> + }
>
> have you tested this? The STK_AGENT_RESULT_CANCEL will never be reached
> since we hit default label first.
This would really be a matter of incompliant compiler if it didn't
work because of the order of the labels. I also just checked checked
a similar code in gcc and it works.
So possibly let's add this rule to the coding-style file.
I'm attaching the same patch with just the labels reordered. I left
the default label in because this function should just treat any other
response as ..USER_TERMINATED, even if a new one is added.
Best regards
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0005-stk-Handle-the-Select-Item-proactive-command.patch --]
[-- Type: text/x-patch, Size: 3629 bytes --]
From a8f5c870723d17b5909697de7d10249e737cac78 Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <andrew.zaborowski@intel.com>
Date: Mon, 26 Jul 2010 14:39:28 +0200
Subject: [PATCH 5/6] stk: Handle the Select Item proactive command.
---
src/stk.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 105 insertions(+), 1 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index f212e9a..0aaf83d 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -75,7 +75,7 @@ struct ofono_stk {
guint remove_agent_source;
struct stk_app_agent *session_agent;
struct stk_app_agent *default_agent;
- struct stk_menu *main_menu;
+ struct stk_menu *main_menu, *select_item_menu;
gboolean in_session;
struct sms_submit_req *sms_submit_req;
char *idle_mode_text;
@@ -1000,6 +1000,106 @@ static gboolean handle_command_set_up_menu(const struct stk_command *cmd,
return TRUE;
}
+static void request_menu_send(DBusMessage *call, void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ struct stk_menu *menu = stk->select_item_menu;
+
+ dbus_message_set_member(call, "RequestSelection");
+
+ append_menu(call, menu);
+}
+
+static void request_menu_cb(enum stk_agent_result result, DBusMessage *reply,
+ void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ struct stk_menu *menu = stk->select_item_menu;
+ struct stk_item *item = NULL;
+ enum stk_result_type type;
+ unsigned char selection;
+ struct stk_response rsp;
+ static struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+
+ switch (result) {
+ case STK_AGENT_RESULT_OK:
+ type = STK_RESULT_TYPE_SUCCESS;
+ break;
+
+ case STK_AGENT_RESULT_BACK:
+ type = STK_RESULT_TYPE_GO_BACK;
+ goto send;
+
+ case STK_AGENT_RESULT_TIMEOUT:
+ type = STK_RESULT_TYPE_NO_RESPONSE;
+ goto send;
+
+ case STK_AGENT_RESULT_CANCEL:
+ goto out;
+
+ case STK_AGENT_RESULT_TERMINATE:
+ default:
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+ goto send;
+ }
+
+ if (dbus_message_get_args(reply, NULL,
+ DBUS_TYPE_BYTE, &selection,
+ DBUS_TYPE_INVALID) == FALSE) {
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+
+ ofono_error("Can't parse the reply to SelectItem()");
+ goto send;
+ }
+
+ item = g_slist_nth_data(menu->items, selection);
+ if (!item) {
+ type = STK_RESULT_TYPE_USER_TERMINATED;
+ ofono_error("Invalid item selected");
+ }
+
+send:
+ memset(&rsp, 0, sizeof(rsp));
+ rsp.result.type = type;
+
+ if (item)
+ rsp.select_item.item_id = item->id;
+
+ if (stk_respond(stk, &rsp, stk_command_cb))
+ stk_command_cb(&error, stk);
+
+out:
+ stk_menu_free(menu);
+ stk->select_item_menu = NULL;
+}
+
+static gboolean handle_command_select_item(const struct stk_command *cmd,
+ struct stk_response *rsp,
+ struct ofono_stk *stk)
+{
+ stk->select_item_menu = stk_menu_create_from_select_item(cmd);
+
+ if (!stk->select_item_menu) {
+ rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+
+ return TRUE;
+ }
+
+ if (!stk->in_session) {
+ stk->in_session = TRUE;
+
+ if (stk->main_menu)
+ emit_menu_changed(stk);
+ }
+
+ stk->cancel_cmd = stk_agent_request_cancel;
+
+ stk_agent_request_start(stk,
+ request_menu_send, request_menu_cb, 0);
+
+ return FALSE;
+}
+
static void stk_proactive_command_cancel(struct ofono_stk *stk)
{
if (!stk->pending_cmd)
@@ -1088,6 +1188,10 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
respond = handle_command_set_up_menu(stk->pending_cmd,
&rsp, stk);
break;
+ case STK_COMMAND_TYPE_SELECT_ITEM:
+ respond = handle_command_select_item(stk->pending_cmd,
+ &rsp, stk);
+ break;
}
if (respond)
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/6] stk: Handle the Select Item proactive command.
2010-07-28 6:09 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
@ 2010-07-28 6:09 ` Andrzej Zaborowski
0 siblings, 0 replies; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-28 6:09 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 5925 bytes --]
---
src/stk.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/stkagent.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
src/stkagent.h | 7 +++++
3 files changed, 140 insertions(+), 1 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index fcd5eab..9322de9 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -65,7 +65,7 @@ struct ofono_stk {
struct stk_app_agent *session_agent;
struct stk_app_agent *default_agent;
struct stk_app_agent *current_agent; /* Always one of the above two */
- struct stk_menu *main_menu;
+ struct stk_menu *main_menu, *select_item_menu;
gboolean in_session;
struct sms_submit_req *sms_submit_req;
char *idle_mode_text;
@@ -924,6 +924,73 @@ static gboolean handle_command_set_up_menu(const struct stk_command *cmd,
return TRUE;
}
+static void request_menu_cb(enum stk_agent_result result, uint8_t id,
+ void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ static struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+ struct stk_response rsp;
+
+ memset(&rsp, 0, sizeof(rsp));
+
+ switch (result) {
+ case STK_AGENT_RESULT_OK:
+ rsp.result.type = STK_RESULT_TYPE_SUCCESS;
+ rsp.select_item.item_id = id;
+ break;
+
+ case STK_AGENT_RESULT_BACK:
+ rsp.result.type = STK_RESULT_TYPE_GO_BACK;
+ break;
+
+ case STK_AGENT_RESULT_TIMEOUT:
+ rsp.result.type = STK_RESULT_TYPE_NO_RESPONSE;
+ break;
+
+ case STK_AGENT_RESULT_CANCEL:
+ goto out;
+
+ case STK_AGENT_RESULT_TERMINATE:
+ default:
+ rsp.result.type = STK_RESULT_TYPE_USER_TERMINATED;
+ break;
+ }
+
+ if (stk_respond(stk, &rsp, stk_command_cb))
+ stk_command_cb(&error, stk);
+
+out:
+ stk_menu_free(stk->select_item_menu);
+ stk->select_item_menu = NULL;
+}
+
+static gboolean handle_command_select_item(const struct stk_command *cmd,
+ struct stk_response *rsp,
+ struct ofono_stk *stk)
+{
+ stk->select_item_menu = stk_menu_create_from_select_item(cmd);
+
+ if (!stk->select_item_menu) {
+ rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+
+ return TRUE;
+ }
+
+ if (!stk->in_session) {
+ stk->in_session = TRUE;
+
+ if (stk->main_menu)
+ emit_menu_changed(stk);
+ }
+
+ stk->cancel_cmd = stk_agent_request_cancel;
+
+ app_agent_request_selection(stk->current_agent, stk->select_item_menu,
+ request_menu_cb, stk->timeout * 1000);
+
+ return FALSE;
+}
+
static void stk_proactive_command_cancel(struct ofono_stk *stk)
{
if (!stk->pending_cmd)
@@ -1012,6 +1079,10 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
respond = handle_command_set_up_menu(stk->pending_cmd,
&rsp, stk);
break;
+ case STK_COMMAND_TYPE_SELECT_ITEM:
+ respond = handle_command_select_item(stk->pending_cmd,
+ &rsp, stk);
+ break;
}
if (respond)
diff --git a/src/stkagent.c b/src/stkagent.c
index 0daf7d0..19da43a 100644
--- a/src/stkagent.c
+++ b/src/stkagent.c
@@ -51,6 +51,8 @@ struct stk_app_agent {
void *data;
ofono_bool_t is_default;
GDestroyNotify notify;
+
+ const struct stk_menu *request_selection_menu;
};
#define OFONO_NAVIGATION_PREFIX OFONO_SERVICE ".Error"
@@ -329,3 +331,62 @@ void append_menu_items_variant(DBusMessageIter *iter,
dbus_message_iter_close_container(iter, &variant);
}
+
+static void request_selection_cb(struct stk_app_agent *agent,
+ enum stk_agent_result result,
+ DBusMessage *reply)
+{
+ const struct stk_menu *menu = agent->request_selection_menu;
+ app_agent_selection_cb cb = (app_agent_selection_cb) agent->user_cb;
+ unsigned char selection, i;
+
+ if (result != STK_AGENT_RESULT_OK) {
+ cb(result, 0, agent->data);
+
+ return;
+ }
+
+ if (dbus_message_get_args(reply, NULL,
+ DBUS_TYPE_BYTE, &selection,
+ DBUS_TYPE_INVALID) == FALSE) {
+ ofono_error("Can't parse the reply to RequestSelection()");
+
+ cb(STK_AGENT_RESULT_TERMINATE, 0, agent->data);
+
+ return;
+ }
+
+ for (i = 0; i < selection && menu->items[i].text; i++);
+
+ if (i != selection) {
+ ofono_error("Invalid item selected");
+
+ cb(STK_AGENT_RESULT_TERMINATE, 0, agent->data);
+
+ return;
+ }
+
+ cb(result, menu->items[selection].item_id, agent->data);
+}
+
+void app_agent_request_selection(struct stk_app_agent *agent,
+ const struct stk_menu *menu,
+ app_agent_selection_cb cb, int timeout)
+{
+ dbus_int16_t default_item = menu->default_item;
+ DBusMessageIter iter;
+
+ if (!app_agent_request_start(agent, "RequestSelection",
+ request_selection_cb,
+ (app_agent_generic_cb) cb, timeout))
+ return;
+
+ dbus_message_iter_init_append(agent->msg, &iter);
+
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &menu->title);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE, &menu->icon_id);
+ append_menu_items(&iter, menu);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT16, &default_item);
+
+ agent->request_selection_menu = menu;
+}
diff --git a/src/stkagent.h b/src/stkagent.h
index d1f3ffb..eab2055 100644
--- a/src/stkagent.h
+++ b/src/stkagent.h
@@ -46,6 +46,9 @@ enum stk_agent_result {
typedef void (*app_agent_generic_cb)(enum stk_agent_result result,
void *user_data);
+typedef void (*app_agent_selection_cb)(enum stk_agent_result result,
+ uint8_t id, void *user_data);
+
struct stk_app_agent;
struct stk_app_agent *app_agent_create(const char *path, const char *sender,
@@ -60,5 +63,9 @@ ofono_bool_t app_agent_matches(struct stk_app_agent *agent,
void app_agent_request_cancel(struct stk_app_agent *agent);
+void app_agent_request_selection(struct stk_app_agent *agent,
+ const struct stk_menu *menu,
+ app_agent_selection_cb cb, int timeout);
+
void append_menu_items_variant(DBusMessageIter *iter,
const struct stk_menu *menu);
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/6] stk: Handle the Select Item proactive command.
2010-07-28 10:26 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
@ 2010-07-28 10:26 ` Andrzej Zaborowski
0 siblings, 0 replies; 10+ messages in thread
From: Andrzej Zaborowski @ 2010-07-28 10:26 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 5897 bytes --]
---
src/stk.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/stkagent.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/stkagent.h | 8 ++++++
3 files changed, 137 insertions(+), 1 deletions(-)
diff --git a/src/stk.c b/src/stk.c
index bd7679c..c804fc6 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -65,7 +65,7 @@ struct ofono_stk {
struct stk_agent *session_agent;
struct stk_agent *default_agent;
struct stk_agent *current_agent; /* Always equals one of the above */
- struct stk_menu *main_menu;
+ struct stk_menu *main_menu, *select_item_menu;
struct sms_submit_req *sms_submit_req;
char *idle_mode_text;
};
@@ -923,6 +923,67 @@ static gboolean handle_command_set_up_menu(const struct stk_command *cmd,
return TRUE;
}
+static void request_menu_cb(enum stk_agent_result result, uint8_t id,
+ void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ static struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+ struct stk_response rsp;
+
+ memset(&rsp, 0, sizeof(rsp));
+
+ switch (result) {
+ case STK_AGENT_RESULT_OK:
+ rsp.result.type = STK_RESULT_TYPE_SUCCESS;
+ rsp.select_item.item_id = id;
+ break;
+
+ case STK_AGENT_RESULT_BACK:
+ rsp.result.type = STK_RESULT_TYPE_GO_BACK;
+ break;
+
+ case STK_AGENT_RESULT_TIMEOUT:
+ rsp.result.type = STK_RESULT_TYPE_NO_RESPONSE;
+ break;
+
+ case STK_AGENT_RESULT_CANCEL:
+ goto out;
+
+ case STK_AGENT_RESULT_TERMINATE:
+ default:
+ rsp.result.type = STK_RESULT_TYPE_USER_TERMINATED;
+ break;
+ }
+
+ if (stk_respond(stk, &rsp, stk_command_cb))
+ stk_command_cb(&error, stk);
+
+out:
+ stk_menu_free(stk->select_item_menu);
+ stk->select_item_menu = NULL;
+}
+
+static gboolean handle_command_select_item(const struct stk_command *cmd,
+ struct stk_response *rsp,
+ struct ofono_stk *stk)
+{
+ stk->select_item_menu = stk_menu_create_from_select_item(cmd);
+
+ if (!stk->select_item_menu) {
+ rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+
+ return TRUE;
+ }
+
+ stk->cancel_cmd = stk_request_cancel;
+
+ stk_agent_request_selection(stk->current_agent, stk->select_item_menu,
+ request_menu_cb, stk,
+ stk->timeout * 1000);
+
+ return FALSE;
+}
+
static void stk_proactive_command_cancel(struct ofono_stk *stk)
{
if (!stk->pending_cmd)
@@ -1006,6 +1067,10 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
respond = handle_command_set_up_menu(stk->pending_cmd,
&rsp, stk);
break;
+ case STK_COMMAND_TYPE_SELECT_ITEM:
+ respond = handle_command_select_item(stk->pending_cmd,
+ &rsp, stk);
+ break;
}
if (respond)
diff --git a/src/stkagent.c b/src/stkagent.c
index 3f80ba1..ce7ad18 100644
--- a/src/stkagent.c
+++ b/src/stkagent.c
@@ -52,6 +52,8 @@ struct stk_agent {
ofono_bool_t is_default;
GDestroyNotify destroy_notify;
void *destroy_data;
+
+ const struct stk_menu *request_selection_menu;
};
#define OFONO_NAVIGATION_PREFIX OFONO_SERVICE ".Error"
@@ -333,3 +335,64 @@ void append_menu_items_variant(DBusMessageIter *iter,
dbus_message_iter_close_container(iter, &variant);
}
+
+static void request_selection_cb(struct stk_agent *agent,
+ enum stk_agent_result result,
+ DBusMessage *reply)
+{
+ const struct stk_menu *menu = agent->request_selection_menu;
+ stk_agent_selection_cb cb = (stk_agent_selection_cb) agent->user_cb;
+ unsigned char selection, i;
+
+ if (result != STK_AGENT_RESULT_OK) {
+ cb(result, 0, agent->user_data);
+
+ return;
+ }
+
+ if (dbus_message_get_args(reply, NULL,
+ DBUS_TYPE_BYTE, &selection,
+ DBUS_TYPE_INVALID) == FALSE) {
+ ofono_error("Can't parse the reply to RequestSelection()");
+
+ cb(STK_AGENT_RESULT_TERMINATE, 0, agent->user_data);
+
+ return;
+ }
+
+ for (i = 0; i < selection && menu->items[i].text; i++);
+
+ if (i != selection) {
+ ofono_error("Invalid item selected");
+
+ cb(STK_AGENT_RESULT_TERMINATE, 0, agent->user_data);
+
+ return;
+ }
+
+ cb(result, menu->items[selection].item_id, agent->user_data);
+}
+
+void stk_agent_request_selection(struct stk_agent *agent,
+ const struct stk_menu *menu,
+ stk_agent_selection_cb cb,
+ void *user_data, int timeout)
+{
+ dbus_int16_t default_item = menu->default_item;
+ DBusMessageIter iter;
+
+ if (!stk_agent_request_start(agent, "RequestSelection",
+ request_selection_cb,
+ (stk_agent_generic_cb) cb,
+ user_data, timeout))
+ return;
+
+ dbus_message_iter_init_append(agent->msg, &iter);
+
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &menu->title);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE, &menu->icon_id);
+ append_menu_items(&iter, menu->items);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT16, &default_item);
+
+ agent->request_selection_menu = menu;
+}
diff --git a/src/stkagent.h b/src/stkagent.h
index 5561fa4..a19df92 100644
--- a/src/stkagent.h
+++ b/src/stkagent.h
@@ -46,6 +46,9 @@ enum stk_agent_result {
typedef void (*stk_agent_generic_cb)(enum stk_agent_result result,
void *user_data);
+typedef void (*stk_agent_selection_cb)(enum stk_agent_result result,
+ uint8_t id, void *user_data);
+
struct stk_agent;
struct stk_agent *stk_agent_new(const char *path, const char *sender,
@@ -61,5 +64,10 @@ void stk_agent_set_destroy_watch(struct stk_agent *agent, GDestroyNotify notify,
void stk_agent_request_cancel(struct stk_agent *agent);
+void stk_agent_request_selection(struct stk_agent *agent,
+ const struct stk_menu *menu,
+ stk_agent_selection_cb cb,
+ void *user_data, int timeout);
+
void append_menu_items_variant(DBusMessageIter *iter,
const struct stk_menu_item *items);
--
1.7.1.86.g0e460.dirty
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2010-07-28 10:26 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-26 13:14 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 2/6] stk: Add STK agent registration api Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 3/6] stk: Utilities to deal with menus Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 4/6] stk: Handle the main menu Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 5/6] stk: Handle the Select Item proactive command Andrzej Zaborowski
2010-07-27 0:27 ` Marcel Holtmann
2010-07-27 0:53 ` Andrzej Zaborowski
2010-07-26 13:14 ` [PATCH 6/6] stk: Handle the Display Text " Andrzej Zaborowski
-- strict thread matches above, loose matches on Subject: below --
2010-07-28 6:09 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
2010-07-28 6:09 ` [PATCH 5/6] stk: Handle the Select Item proactive command Andrzej Zaborowski
2010-07-28 10:26 [PATCH 1/6] Add STK agent utilities and logic Andrzej Zaborowski
2010-07-28 10:26 ` [PATCH 5/6] stk: Handle the Select Item proactive command Andrzej Zaborowski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox