mirror of git://git.sysmocom.de/ofono
stk: Handle the Select Item proactive command.
This commit is contained in:
parent
47b95122cc
commit
3714eb8acd
67
src/stk.c
67
src/stk.c
|
@ -65,7 +65,7 @@ struct ofono_stk {
|
||||||
struct stk_agent *session_agent;
|
struct stk_agent *session_agent;
|
||||||
struct stk_agent *default_agent;
|
struct stk_agent *default_agent;
|
||||||
struct stk_agent *current_agent; /* Always equals one of the above */
|
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;
|
struct sms_submit_req *sms_submit_req;
|
||||||
char *idle_mode_text;
|
char *idle_mode_text;
|
||||||
};
|
};
|
||||||
|
@ -923,6 +923,67 @@ static gboolean handle_command_set_up_menu(const struct stk_command *cmd,
|
||||||
return TRUE;
|
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)
|
static void stk_proactive_command_cancel(struct ofono_stk *stk)
|
||||||
{
|
{
|
||||||
if (!stk->pending_cmd)
|
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,
|
respond = handle_command_set_up_menu(stk->pending_cmd,
|
||||||
&rsp, stk);
|
&rsp, stk);
|
||||||
break;
|
break;
|
||||||
|
case STK_COMMAND_TYPE_SELECT_ITEM:
|
||||||
|
respond = handle_command_select_item(stk->pending_cmd,
|
||||||
|
&rsp, stk);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (respond)
|
if (respond)
|
||||||
|
|
|
@ -52,6 +52,8 @@ struct stk_agent {
|
||||||
ofono_bool_t is_default;
|
ofono_bool_t is_default;
|
||||||
GDestroyNotify destroy_notify;
|
GDestroyNotify destroy_notify;
|
||||||
void *destroy_data;
|
void *destroy_data;
|
||||||
|
|
||||||
|
const struct stk_menu *request_selection_menu;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OFONO_NAVIGATION_PREFIX OFONO_SERVICE ".Error"
|
#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);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,9 @@ enum stk_agent_result {
|
||||||
typedef void (*stk_agent_generic_cb)(enum stk_agent_result result,
|
typedef void (*stk_agent_generic_cb)(enum stk_agent_result result,
|
||||||
void *user_data);
|
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;
|
||||||
|
|
||||||
struct stk_agent *stk_agent_new(const char *path, const char *sender,
|
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_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,
|
void append_menu_items_variant(DBusMessageIter *iter,
|
||||||
const struct stk_menu_item *items);
|
const struct stk_menu_item *items);
|
||||||
|
|
Loading…
Reference in New Issue