3 * oFono - Open Source Telephony
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
41 #ifndef DBUS_TIMEOUT_INFINITE
42 #define DBUS_TIMEOUT_INFINITE ((int) 0x7fffffff)
46 ALLOWED_ERROR_GO_BACK = 0x1,
47 ALLOWED_ERROR_TERMINATE = 0x2,
48 ALLOWED_ERROR_BUSY = 0x4,
52 char *path; /* Agent Path */
53 char *bus; /* Agent bus */
54 guint disconnect_watch; /* DBus disconnect watch */
55 ofono_bool_t remove_on_terminate;
56 ofono_destroy_func removed_cb;
59 DBusPendingCall *call;
62 ofono_destroy_func user_destroy;
64 const struct stk_menu *request_selection_menu;
67 #define ERROR_PREFIX OFONO_SERVICE ".Error"
68 #define GOBACK_ERROR ERROR_PREFIX ".GoBack"
69 #define TERMINATE_ERROR ERROR_PREFIX ".EndSession"
70 #define BUSY_ERROR ERROR_PREFIX ".Busy"
72 static void stk_agent_send_noreply(struct stk_agent *agent, const char *method)
74 DBusConnection *conn = ofono_dbus_get_connection();
77 message = dbus_message_new_method_call(agent->bus, agent->path,
78 OFONO_SIM_APP_INTERFACE,
83 dbus_message_set_no_reply(message, TRUE);
85 g_dbus_send_message(conn, message);
88 static inline void stk_agent_send_release(struct stk_agent *agent)
90 stk_agent_send_noreply(agent, "Release");
93 static inline void stk_agent_send_cancel(struct stk_agent *agent)
95 stk_agent_send_noreply(agent, "Cancel");
98 static void stk_agent_request_end(struct stk_agent *agent)
101 dbus_message_unref(agent->msg);
106 dbus_pending_call_unref(agent->call);
110 if (agent->user_destroy)
111 agent->user_destroy(agent->user_data);
113 agent->user_destroy = NULL;
114 agent->user_data = NULL;
115 agent->user_cb = NULL;
118 ofono_bool_t stk_agent_matches(struct stk_agent *agent,
119 const char *path, const char *sender)
121 return !strcmp(agent->path, path) && !strcmp(agent->bus, sender);
124 void stk_agent_set_removed_notify(struct stk_agent *agent,
125 ofono_destroy_func destroy,
128 agent->removed_cb = destroy;
129 agent->removed_data = user_data;
132 void stk_agent_request_cancel(struct stk_agent *agent)
134 if (agent->call == NULL)
137 dbus_pending_call_cancel(agent->call);
139 if (agent->disconnect_watch)
140 stk_agent_send_cancel(agent);
142 stk_agent_request_end(agent);
145 void stk_agent_free(struct stk_agent *agent)
147 DBusConnection *conn = ofono_dbus_get_connection();
149 stk_agent_request_cancel(agent);
151 if (agent->disconnect_watch) {
152 stk_agent_send_release(agent);
154 g_dbus_remove_watch(conn, agent->disconnect_watch);
155 agent->disconnect_watch = 0;
158 if (agent->removed_cb)
159 agent->removed_cb(agent->removed_data);
166 static int check_error(struct stk_agent *agent, DBusMessage *reply,
168 enum stk_agent_result *out_result)
173 dbus_error_init(&err);
175 if (dbus_set_error_from_message(&err, reply) == FALSE) {
176 *out_result = STK_AGENT_RESULT_OK;
180 ofono_debug("SimToolkitAgent %s replied with error %s, %s",
181 agent->path, err.name, err.message);
183 /* Timeout is always valid */
184 if (g_str_equal(err.name, DBUS_ERROR_NO_REPLY)) {
185 /* Send a Cancel() to the agent since its taking too long */
186 stk_agent_send_cancel(agent);
187 *out_result = STK_AGENT_RESULT_TIMEOUT;
191 if ((allowed_errors & ALLOWED_ERROR_GO_BACK) &&
192 g_str_equal(err.name, GOBACK_ERROR)) {
193 *out_result = STK_AGENT_RESULT_BACK;
197 if ((allowed_errors & ALLOWED_ERROR_TERMINATE) &&
198 g_str_equal(err.name, TERMINATE_ERROR)) {
199 *out_result = STK_AGENT_RESULT_TERMINATE;
203 if ((allowed_errors & ALLOWED_ERROR_BUSY) &&
204 g_str_equal(err.name, BUSY_ERROR)) {
205 *out_result = STK_AGENT_RESULT_BUSY;
212 dbus_error_free(&err);
216 static void stk_agent_disconnect_cb(DBusConnection *conn, void *user_data)
218 struct stk_agent *agent = user_data;
220 ofono_debug("Agent exited without calling Unregister");
222 agent->disconnect_watch = 0;
224 stk_agent_free(agent);
227 struct stk_agent *stk_agent_new(const char *path, const char *sender,
228 ofono_bool_t remove_on_terminate)
230 struct stk_agent *agent = g_try_new0(struct stk_agent, 1);
231 DBusConnection *conn = ofono_dbus_get_connection();
236 agent->path = g_strdup(path);
237 agent->bus = g_strdup(sender);
238 agent->remove_on_terminate = remove_on_terminate;
240 agent->disconnect_watch = g_dbus_add_disconnect_watch(conn, sender,
241 stk_agent_disconnect_cb,
247 static void append_menu_items(DBusMessageIter *iter,
248 const struct stk_menu_item *item)
250 DBusMessageIter array, entry;
252 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
255 while (item && item->text) {
256 dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT,
259 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
261 dbus_message_iter_append_basic(&entry, DBUS_TYPE_BYTE,
264 dbus_message_iter_close_container(&array, &entry);
268 dbus_message_iter_close_container(iter, &array);
271 void append_menu_items_variant(DBusMessageIter *iter,
272 const struct stk_menu_item *items)
274 DBusMessageIter variant;
276 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
279 append_menu_items(&variant, items);
281 dbus_message_iter_close_container(iter, &variant);
284 #define CALLBACK_END() \
286 if (result == STK_AGENT_RESULT_TERMINATE && \
287 agent->remove_on_terminate) \
288 remove_agent = TRUE; \
290 remove_agent = FALSE; \
293 stk_agent_request_end(agent); \
294 dbus_message_unref(reply); \
297 stk_agent_free(agent) \
299 static void request_selection_cb(DBusPendingCall *call, void *data)
301 struct stk_agent *agent = data;
302 const struct stk_menu *menu = agent->request_selection_menu;
303 stk_agent_selection_cb cb = (stk_agent_selection_cb) agent->user_cb;
304 DBusMessage *reply = dbus_pending_call_steal_reply(call);
305 unsigned char selection, i;
306 enum stk_agent_result result;
307 gboolean remove_agent;
309 if (check_error(agent, reply,
310 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
311 &result) == -EINVAL) {
316 if (result != STK_AGENT_RESULT_OK) {
317 cb(result, 0, agent->user_data);
321 if (dbus_message_get_args(reply, NULL,
322 DBUS_TYPE_BYTE, &selection,
323 DBUS_TYPE_INVALID) == FALSE) {
324 ofono_error("Can't parse the reply to RequestSelection()");
329 for (i = 0; i < selection && menu->items[i].text; i++);
331 if (i != selection) {
332 ofono_error("Invalid item selected");
337 cb(result, menu->items[selection].item_id, agent->user_data);
342 int stk_agent_request_selection(struct stk_agent *agent,
343 const struct stk_menu *menu,
344 stk_agent_selection_cb cb,
345 void *user_data, ofono_destroy_func destroy,
348 DBusConnection *conn = ofono_dbus_get_connection();
349 dbus_int16_t default_item = menu->default_item;
350 DBusMessageIter iter;
352 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
353 OFONO_SIM_APP_INTERFACE,
355 if (agent->msg == NULL)
358 dbus_message_iter_init_append(agent->msg, &iter);
360 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &menu->title);
361 dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE, &menu->icon.id);
362 append_menu_items(&iter, menu->items);
363 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT16, &default_item);
365 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
371 agent->user_data = user_data;
372 agent->user_destroy = destroy;
374 agent->request_selection_menu = menu;
376 dbus_pending_call_set_notify(agent->call, request_selection_cb,
382 static void display_text_cb(DBusPendingCall *call, void *data)
384 struct stk_agent *agent = data;
385 stk_agent_display_text_cb cb = agent->user_cb;
386 DBusMessage *reply = dbus_pending_call_steal_reply(call);
387 enum stk_agent_result result;
388 gboolean remove_agent;
390 if (check_error(agent, reply,
391 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE |
392 ALLOWED_ERROR_BUSY, &result) == -EINVAL) {
397 if (result != STK_AGENT_RESULT_OK) {
398 cb(result, agent->user_data);
402 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
403 ofono_error("Can't parse the reply to DisplayText()");
408 cb(result, agent->user_data);
413 int stk_agent_display_text(struct stk_agent *agent, const char *text,
414 const struct stk_icon_id *icon,
416 stk_agent_display_text_cb cb,
417 void *user_data, ofono_destroy_func destroy,
420 DBusConnection *conn = ofono_dbus_get_connection();
421 dbus_bool_t priority = urgent;
423 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
424 OFONO_SIM_APP_INTERFACE,
426 if (agent->msg == NULL)
429 dbus_message_append_args(agent->msg,
430 DBUS_TYPE_STRING, &text,
431 DBUS_TYPE_BYTE, &icon->id,
432 DBUS_TYPE_BOOLEAN, &priority,
435 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
441 agent->user_data = user_data;
442 agent->user_destroy = destroy;
444 dbus_pending_call_set_notify(agent->call, display_text_cb,
450 static void get_confirmation_cb(DBusPendingCall *call, void *data)
452 struct stk_agent *agent = data;
453 stk_agent_confirmation_cb cb = agent->user_cb;
454 DBusMessage *reply = dbus_pending_call_steal_reply(call);
455 enum stk_agent_result result;
456 gboolean remove_agent;
459 if (check_error(agent, reply,
460 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
461 &result) == -EINVAL) {
466 if (result != STK_AGENT_RESULT_OK) {
467 cb(result, FALSE, agent->user_data);
471 if (dbus_message_get_args(reply, NULL,
472 DBUS_TYPE_BOOLEAN, &confirm,
473 DBUS_TYPE_INVALID) == FALSE) {
474 ofono_error("Can't parse the reply to GetConfirmation()");
479 cb(result, confirm, agent->user_data);
484 int stk_agent_request_confirmation(struct stk_agent *agent, const char *text,
485 const struct stk_icon_id *icon,
486 stk_agent_confirmation_cb cb,
488 ofono_destroy_func destroy,
491 DBusConnection *conn = ofono_dbus_get_connection();
493 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
494 OFONO_SIM_APP_INTERFACE,
495 "RequestConfirmation");
496 if (agent->msg == NULL)
499 dbus_message_append_args(agent->msg,
500 DBUS_TYPE_STRING, &text,
501 DBUS_TYPE_BYTE, &icon->id,
504 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
510 agent->user_data = user_data;
511 agent->user_destroy = destroy;
513 dbus_pending_call_set_notify(agent->call, get_confirmation_cb,
519 static void get_digit_cb(DBusPendingCall *call, void *data)
521 struct stk_agent *agent = data;
522 stk_agent_string_cb cb = agent->user_cb;
523 DBusMessage *reply = dbus_pending_call_steal_reply(call);
524 enum stk_agent_result result;
525 gboolean remove_agent;
528 if (check_error(agent, reply,
529 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
530 &result) == -EINVAL) {
535 if (result != STK_AGENT_RESULT_OK) {
536 cb(result, NULL, agent->user_data);
540 if (dbus_message_get_args(reply, NULL,
541 DBUS_TYPE_STRING, &digit,
542 DBUS_TYPE_INVALID) == FALSE ||
543 strlen(digit) != 1 ||
544 !valid_phone_number_format(digit)) {
545 ofono_error("Can't parse the reply to GetDigit()");
550 cb(result, digit, agent->user_data);
555 int stk_agent_request_digit(struct stk_agent *agent, const char *text,
556 const struct stk_icon_id *icon,
557 stk_agent_string_cb cb, void *user_data,
558 ofono_destroy_func destroy, int timeout)
560 DBusConnection *conn = ofono_dbus_get_connection();
562 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
563 OFONO_SIM_APP_INTERFACE,
565 if (agent->msg == NULL)
568 dbus_message_append_args(agent->msg,
569 DBUS_TYPE_STRING, &text,
570 DBUS_TYPE_BYTE, &icon->id,
573 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
579 agent->user_data = user_data;
580 agent->user_destroy = destroy;
582 dbus_pending_call_set_notify(agent->call, get_digit_cb, agent, NULL);
587 static void get_key_cb(DBusPendingCall *call, void *data)
589 struct stk_agent *agent = data;
590 stk_agent_string_cb cb = agent->user_cb;
591 DBusMessage *reply = dbus_pending_call_steal_reply(call);
592 enum stk_agent_result result;
593 gboolean remove_agent;
596 if (check_error(agent, reply,
597 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
598 &result) == -EINVAL) {
603 if (result != STK_AGENT_RESULT_OK) {
604 cb(result, NULL, agent->user_data);
608 if (dbus_message_get_args(reply, NULL,
609 DBUS_TYPE_STRING, &key,
610 DBUS_TYPE_INVALID) == FALSE ||
611 g_utf8_strlen(key, 10) != 1) {
612 ofono_error("Can't parse the reply to GetKey()");
617 cb(result, key, agent->user_data);
622 int stk_agent_request_key(struct stk_agent *agent, const char *text,
623 const struct stk_icon_id *icon,
624 ofono_bool_t unicode_charset,
625 stk_agent_string_cb cb, void *user_data,
626 ofono_destroy_func destroy, int timeout)
628 DBusConnection *conn = ofono_dbus_get_connection();
630 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
631 OFONO_SIM_APP_INTERFACE,
633 if (agent->msg == NULL)
636 dbus_message_append_args(agent->msg,
637 DBUS_TYPE_STRING, &text,
638 DBUS_TYPE_BYTE, &icon->id,
641 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
647 agent->user_data = user_data;
648 agent->user_destroy = destroy;
650 dbus_pending_call_set_notify(agent->call, get_key_cb, agent, NULL);
655 static void get_digits_cb(DBusPendingCall *call, void *data)
657 struct stk_agent *agent = data;
658 stk_agent_string_cb cb = agent->user_cb;
659 DBusMessage *reply = dbus_pending_call_steal_reply(call);
660 enum stk_agent_result result;
661 gboolean remove_agent;
664 if (check_error(agent, reply,
665 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
666 &result) == -EINVAL) {
671 if (result != STK_AGENT_RESULT_OK) {
672 cb(result, NULL, agent->user_data);
676 if (dbus_message_get_args(reply, NULL,
677 DBUS_TYPE_STRING, &string,
678 DBUS_TYPE_INVALID) == FALSE) {
679 ofono_error("Can't parse the reply to GetDigits()");
684 cb(result, string, agent->user_data);
689 int stk_agent_request_digits(struct stk_agent *agent, const char *text,
690 const struct stk_icon_id *icon,
691 const char *default_text,
692 int min, int max, ofono_bool_t hidden,
693 stk_agent_string_cb cb, void *user_data,
694 ofono_destroy_func destroy, int timeout)
696 DBusConnection *conn = ofono_dbus_get_connection();
697 uint8_t min_val = min;
698 uint8_t max_val = max;
699 dbus_bool_t hidden_val = hidden;
701 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
702 OFONO_SIM_APP_INTERFACE,
704 if (agent->msg == NULL)
707 if (default_text == NULL)
710 dbus_message_append_args(agent->msg,
711 DBUS_TYPE_STRING, &text,
712 DBUS_TYPE_BYTE, &icon->id,
713 DBUS_TYPE_STRING, &default_text,
714 DBUS_TYPE_BYTE, &min_val,
715 DBUS_TYPE_BYTE, &max_val,
716 DBUS_TYPE_BOOLEAN, &hidden_val,
719 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
725 agent->user_data = user_data;
726 agent->user_destroy = destroy;
728 dbus_pending_call_set_notify(agent->call, get_digits_cb, agent, NULL);
733 static void get_input_cb(DBusPendingCall *call, void *data)
735 struct stk_agent *agent = data;
736 stk_agent_string_cb cb = agent->user_cb;
737 DBusMessage *reply = dbus_pending_call_steal_reply(call);
738 enum stk_agent_result result;
739 gboolean remove_agent;
742 if (check_error(agent, reply,
743 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
744 &result) == -EINVAL) {
749 if (result != STK_AGENT_RESULT_OK) {
750 cb(result, NULL, agent->user_data);
754 if (dbus_message_get_args(reply, NULL,
755 DBUS_TYPE_STRING, &string,
756 DBUS_TYPE_INVALID) == FALSE) {
757 ofono_error("Can't parse the reply to GetInput()");
762 cb(result, string, agent->user_data);
767 int stk_agent_request_input(struct stk_agent *agent, const char *text,
768 const struct stk_icon_id *icon,
769 const char *default_text,
770 ofono_bool_t unicode_charset, int min, int max,
771 ofono_bool_t hidden, stk_agent_string_cb cb,
772 void *user_data, ofono_destroy_func destroy,
775 DBusConnection *conn = ofono_dbus_get_connection();
776 uint8_t min_val = min;
777 uint8_t max_val = max;
778 dbus_bool_t hidden_val = hidden;
780 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
781 OFONO_SIM_APP_INTERFACE,
783 if (agent->msg == NULL)
786 if (default_text == NULL)
789 dbus_message_append_args(agent->msg,
790 DBUS_TYPE_STRING, &text,
791 DBUS_TYPE_BYTE, &icon->id,
792 DBUS_TYPE_STRING, &default_text,
793 DBUS_TYPE_BYTE, &min_val,
794 DBUS_TYPE_BYTE, &max_val,
795 DBUS_TYPE_BOOLEAN, &hidden_val,
798 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
804 agent->user_data = user_data;
805 agent->user_destroy = destroy;
807 dbus_pending_call_set_notify(agent->call, get_input_cb, agent, NULL);
812 static void confirm_call_cb(DBusPendingCall *call, void *data)
814 struct stk_agent *agent = data;
815 stk_agent_confirmation_cb cb = agent->user_cb;
816 DBusMessage *reply = dbus_pending_call_steal_reply(call);
817 enum stk_agent_result result;
818 gboolean remove_agent;
821 if (check_error(agent, reply,
822 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
827 if (result != STK_AGENT_RESULT_OK) {
828 cb(result, FALSE, agent->user_data);
832 if (dbus_message_get_args(reply, NULL,
833 DBUS_TYPE_BOOLEAN, &confirm,
834 DBUS_TYPE_INVALID) == FALSE) {
835 ofono_error("Can't parse the reply to ConfirmCallSetup()");
840 cb(result, confirm, agent->user_data);
845 int stk_agent_confirm_call(struct stk_agent *agent, const char *text,
846 const struct stk_icon_id *icon,
847 stk_agent_confirmation_cb cb,
848 void *user_data, ofono_destroy_func destroy,
851 DBusConnection *conn = ofono_dbus_get_connection();
853 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
854 OFONO_SIM_APP_INTERFACE,
856 if (agent->msg == NULL)
859 dbus_message_append_args(agent->msg,
860 DBUS_TYPE_STRING, &text,
861 DBUS_TYPE_BYTE, &icon->id,
864 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
870 agent->user_data = user_data;
871 agent->user_destroy = destroy;
873 dbus_pending_call_set_notify(agent->call, confirm_call_cb, agent, NULL);
878 static void play_tone_cb(DBusPendingCall *call, void *data)
880 struct stk_agent *agent = data;
881 stk_agent_tone_cb cb = agent->user_cb;
882 DBusMessage *reply = dbus_pending_call_steal_reply(call);
883 enum stk_agent_result result;
884 gboolean remove_agent;
886 if (check_error(agent, reply,
887 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
892 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
893 ofono_error("Can't parse the reply to PlayTone()");
898 cb(result, agent->user_data);
904 int stk_agent_play_tone(struct stk_agent *agent, const char *text,
905 const struct stk_icon_id *icon, ofono_bool_t vibrate,
906 const char *tone, stk_agent_tone_cb cb, void *user_data,
907 ofono_destroy_func destroy, int timeout)
909 DBusConnection *conn = ofono_dbus_get_connection();
911 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
912 OFONO_SIM_APP_INTERFACE,
914 if (agent->msg == NULL)
917 dbus_message_append_args(agent->msg,
918 DBUS_TYPE_STRING, &tone,
919 DBUS_TYPE_STRING, &text,
920 DBUS_TYPE_BYTE, &icon->id,
923 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
929 agent->user_data = user_data;
930 agent->user_destroy = destroy;
932 dbus_pending_call_set_notify(agent->call, play_tone_cb,
938 int stk_agent_loop_tone(struct stk_agent *agent, const char *text,
939 const struct stk_icon_id *icon, ofono_bool_t vibrate,
940 const char *tone, stk_agent_tone_cb cb, void *user_data,
941 ofono_destroy_func destroy, int timeout)
943 DBusConnection *conn = ofono_dbus_get_connection();
945 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
946 OFONO_SIM_APP_INTERFACE,
948 if (agent->msg == NULL)
951 dbus_message_append_args(agent->msg,
952 DBUS_TYPE_STRING, &tone,
953 DBUS_TYPE_STRING, &text,
954 DBUS_TYPE_BYTE, &icon->id,
957 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
963 agent->user_data = user_data;
964 agent->user_destroy = destroy;
966 dbus_pending_call_set_notify(agent->call, play_tone_cb,
972 static void action_info_cb(DBusPendingCall *call, void *data)
974 struct stk_agent *agent = data;
975 DBusMessage *reply = dbus_pending_call_steal_reply(call);
976 enum stk_agent_result result;
977 gboolean remove_agent;
979 if (check_error(agent, reply, 0, &result) == -EINVAL) {
984 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
985 ofono_error("Can't parse the reply to DisplayActionInfo()");
995 int stk_agent_display_action_info(struct stk_agent *agent, const char *text,
996 const struct stk_icon_id *icon)
998 DBusConnection *conn = ofono_dbus_get_connection();
1000 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1001 OFONO_SIM_APP_INTERFACE,
1002 "DisplayActionInformation");
1003 if (agent->msg == NULL)
1006 dbus_message_append_args(agent->msg,
1007 DBUS_TYPE_STRING, &text,
1008 DBUS_TYPE_BYTE, &icon->id,
1011 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1012 DBUS_TIMEOUT_INFINITE) == FALSE ||
1013 agent->call == NULL)
1016 dbus_pending_call_set_notify(agent->call, action_info_cb, agent, NULL);
1021 static void confirm_launch_browser_cb(DBusPendingCall *call, void *data)
1023 struct stk_agent *agent = data;
1024 stk_agent_confirmation_cb cb = agent->user_cb;
1025 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1026 enum stk_agent_result result;
1027 gboolean remove_agent;
1028 dbus_bool_t confirm;
1030 if (check_error(agent, reply, 0, &result) == -EINVAL) {
1031 remove_agent = TRUE;
1032 cb(STK_AGENT_RESULT_TERMINATE, FALSE, agent->user_data);
1036 if (result != STK_AGENT_RESULT_OK) {
1037 cb(result, FALSE, agent->user_data);
1041 if (dbus_message_get_args(reply, NULL,
1042 DBUS_TYPE_BOOLEAN, &confirm,
1043 DBUS_TYPE_INVALID) == FALSE) {
1044 ofono_error("Can't parse the reply to ConfirmLaunchBrowser()");
1045 remove_agent = TRUE;
1049 cb(result, confirm, agent->user_data);
1054 int stk_agent_confirm_launch_browser(struct stk_agent *agent, const char *text,
1055 unsigned char icon_id, const char *url,
1056 stk_agent_confirmation_cb cb,
1058 ofono_destroy_func destroy, int timeout)
1060 DBusConnection *conn = ofono_dbus_get_connection();
1062 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1063 OFONO_SIM_APP_INTERFACE,
1064 "ConfirmLaunchBrowser");
1065 if (agent->msg == NULL)
1071 dbus_message_append_args(agent->msg,
1072 DBUS_TYPE_STRING, &text,
1073 DBUS_TYPE_BYTE, &icon_id,
1074 DBUS_TYPE_STRING, &url,
1077 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1078 timeout) == FALSE ||
1079 agent->call == NULL)
1082 agent->user_cb = cb;
1083 agent->user_data = user_data;
1084 agent->user_destroy = destroy;
1086 dbus_pending_call_set_notify(agent->call, confirm_launch_browser_cb,
1092 static void display_action_cb(DBusPendingCall *call, void *data)
1094 struct stk_agent *agent = data;
1095 stk_agent_display_action_cb cb = agent->user_cb;
1096 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1097 enum stk_agent_result result;
1098 gboolean remove_agent;
1100 if (check_error(agent, reply,
1101 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
1102 remove_agent = TRUE;
1106 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
1107 ofono_error("Can't parse the reply to DisplayAction()");
1108 remove_agent = TRUE;
1112 cb(result, agent->user_data);
1118 int stk_agent_display_action(struct stk_agent *agent,
1120 const struct stk_icon_id *icon,
1121 stk_agent_display_action_cb cb,
1123 ofono_destroy_func destroy)
1125 DBusConnection *conn = ofono_dbus_get_connection();
1127 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1128 OFONO_SIM_APP_INTERFACE,
1130 if (agent->msg == NULL)
1133 dbus_message_append_args(agent->msg,
1134 DBUS_TYPE_STRING, &text,
1135 DBUS_TYPE_BYTE, &icon->id,
1138 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1139 DBUS_TIMEOUT_INFINITE) == FALSE ||
1140 agent->call == NULL)
1143 agent->user_cb = cb;
1144 agent->user_data = user_data;
1145 agent->user_destroy = destroy;
1147 dbus_pending_call_set_notify(agent->call, display_action_cb,
1153 static void confirm_open_channel_cb(DBusPendingCall *call, void *data)
1155 struct stk_agent *agent = data;
1156 stk_agent_confirmation_cb cb = agent->user_cb;
1157 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1158 enum stk_agent_result result;
1159 gboolean remove_agent;
1160 dbus_bool_t confirm;
1162 if (check_error(agent, reply,
1163 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
1164 remove_agent = TRUE;
1168 if (result != STK_AGENT_RESULT_OK) {
1169 cb(result, FALSE, agent->user_data);
1173 if (dbus_message_get_args(reply, NULL,
1174 DBUS_TYPE_BOOLEAN, &confirm,
1175 DBUS_TYPE_INVALID) == FALSE) {
1176 ofono_error("Can't parse the reply to ConfirmOpenChannel()");
1177 remove_agent = TRUE;
1181 cb(result, confirm, agent->user_data);
1186 int stk_agent_confirm_open_channel(struct stk_agent *agent, const char *text,
1187 const struct stk_icon_id *icon,
1188 stk_agent_confirmation_cb cb,
1190 ofono_destroy_func destroy, int timeout)
1192 DBusConnection *conn = ofono_dbus_get_connection();
1194 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1195 OFONO_SIM_APP_INTERFACE,
1196 "ConfirmOpenChannel");
1197 if (agent->msg == NULL)
1200 dbus_message_append_args(agent->msg,
1201 DBUS_TYPE_STRING, &text,
1202 DBUS_TYPE_BYTE, &icon->id,
1205 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1206 timeout) == FALSE ||
1207 agent->call == NULL)
1210 agent->user_cb = cb;
1211 agent->user_data = user_data;
1212 agent->user_destroy = destroy;
1214 dbus_pending_call_set_notify(agent->call, confirm_open_channel_cb,