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 *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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue