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;
64 ofono_bool_t hidden_entry;
65 ofono_destroy_func user_destroy;
67 const struct stk_menu *request_selection_menu;
70 #define ERROR_PREFIX OFONO_SERVICE ".Error"
71 #define GOBACK_ERROR ERROR_PREFIX ".GoBack"
72 #define TERMINATE_ERROR ERROR_PREFIX ".EndSession"
73 #define BUSY_ERROR ERROR_PREFIX ".Busy"
75 static void stk_agent_send_noreply(struct stk_agent *agent, const char *method)
77 DBusConnection *conn = ofono_dbus_get_connection();
80 message = dbus_message_new_method_call(agent->bus, agent->path,
81 OFONO_SIM_APP_INTERFACE,
86 dbus_message_set_no_reply(message, TRUE);
88 g_dbus_send_message(conn, message);
91 static inline void stk_agent_send_release(struct stk_agent *agent)
93 stk_agent_send_noreply(agent, "Release");
96 static inline void stk_agent_send_cancel(struct stk_agent *agent)
98 stk_agent_send_noreply(agent, "Cancel");
101 static void stk_agent_request_end(struct stk_agent *agent)
104 dbus_message_unref(agent->msg);
109 dbus_pending_call_unref(agent->call);
113 if (agent->user_destroy)
114 agent->user_destroy(agent->user_data);
116 agent->user_destroy = NULL;
117 agent->user_data = NULL;
118 agent->user_cb = NULL;
121 ofono_bool_t stk_agent_matches(struct stk_agent *agent,
122 const char *path, const char *sender)
124 return !strcmp(agent->path, path) && !strcmp(agent->bus, sender);
127 void stk_agent_set_removed_notify(struct stk_agent *agent,
128 ofono_destroy_func destroy,
131 agent->removed_cb = destroy;
132 agent->removed_data = user_data;
135 void stk_agent_request_cancel(struct stk_agent *agent)
137 if (agent->call == NULL)
140 dbus_pending_call_cancel(agent->call);
142 if (agent->disconnect_watch)
143 stk_agent_send_cancel(agent);
145 stk_agent_request_end(agent);
148 void stk_agent_free(struct stk_agent *agent)
150 DBusConnection *conn = ofono_dbus_get_connection();
152 stk_agent_request_cancel(agent);
154 if (agent->disconnect_watch) {
155 stk_agent_send_release(agent);
157 g_dbus_remove_watch(conn, agent->disconnect_watch);
158 agent->disconnect_watch = 0;
161 if (agent->removed_cb)
162 agent->removed_cb(agent->removed_data);
169 static int check_error(struct stk_agent *agent, DBusMessage *reply,
171 enum stk_agent_result *out_result)
176 dbus_error_init(&err);
178 if (dbus_set_error_from_message(&err, reply) == FALSE) {
179 *out_result = STK_AGENT_RESULT_OK;
183 ofono_debug("SimToolkitAgent %s replied with error %s, %s",
184 agent->path, err.name, err.message);
186 /* Timeout is always valid */
187 if (g_str_equal(err.name, DBUS_ERROR_NO_REPLY)) {
188 /* Send a Cancel() to the agent since its taking too long */
189 stk_agent_send_cancel(agent);
190 *out_result = STK_AGENT_RESULT_TIMEOUT;
194 if ((allowed_errors & ALLOWED_ERROR_GO_BACK) &&
195 g_str_equal(err.name, GOBACK_ERROR)) {
196 *out_result = STK_AGENT_RESULT_BACK;
200 if ((allowed_errors & ALLOWED_ERROR_TERMINATE) &&
201 g_str_equal(err.name, TERMINATE_ERROR)) {
202 *out_result = STK_AGENT_RESULT_TERMINATE;
206 if ((allowed_errors & ALLOWED_ERROR_BUSY) &&
207 g_str_equal(err.name, BUSY_ERROR)) {
208 *out_result = STK_AGENT_RESULT_BUSY;
215 dbus_error_free(&err);
219 static void stk_agent_disconnect_cb(DBusConnection *conn, void *user_data)
221 struct stk_agent *agent = user_data;
223 ofono_debug("Agent exited without calling Unregister");
225 agent->disconnect_watch = 0;
227 stk_agent_free(agent);
230 struct stk_agent *stk_agent_new(const char *path, const char *sender,
231 ofono_bool_t remove_on_terminate)
233 struct stk_agent *agent = g_try_new0(struct stk_agent, 1);
234 DBusConnection *conn = ofono_dbus_get_connection();
239 agent->path = g_strdup(path);
240 agent->bus = g_strdup(sender);
241 agent->remove_on_terminate = remove_on_terminate;
243 agent->disconnect_watch = g_dbus_add_disconnect_watch(conn, sender,
244 stk_agent_disconnect_cb,
250 static void append_menu_items(DBusMessageIter *iter,
251 const struct stk_menu_item *item)
253 DBusMessageIter array, entry;
255 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
258 while (item && item->text) {
259 dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT,
262 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
264 dbus_message_iter_append_basic(&entry, DBUS_TYPE_BYTE,
267 dbus_message_iter_close_container(&array, &entry);
271 dbus_message_iter_close_container(iter, &array);
274 void append_menu_items_variant(DBusMessageIter *iter,
275 const struct stk_menu_item *items)
277 DBusMessageIter variant;
279 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
282 append_menu_items(&variant, items);
284 dbus_message_iter_close_container(iter, &variant);
287 #define CALLBACK_END() \
289 if (result == STK_AGENT_RESULT_TERMINATE && \
290 agent->remove_on_terminate) \
291 remove_agent = TRUE; \
293 remove_agent = FALSE; \
296 stk_agent_request_end(agent); \
297 dbus_message_unref(reply); \
300 stk_agent_free(agent) \
302 static void request_selection_cb(DBusPendingCall *call, void *data)
304 struct stk_agent *agent = data;
305 const struct stk_menu *menu = agent->request_selection_menu;
306 stk_agent_selection_cb cb = (stk_agent_selection_cb) agent->user_cb;
307 DBusMessage *reply = dbus_pending_call_steal_reply(call);
308 unsigned char selection, i;
309 enum stk_agent_result result;
310 gboolean remove_agent;
312 if (check_error(agent, reply,
313 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
314 &result) == -EINVAL) {
319 if (result != STK_AGENT_RESULT_OK) {
320 cb(result, 0, agent->user_data);
324 if (dbus_message_get_args(reply, NULL,
325 DBUS_TYPE_BYTE, &selection,
326 DBUS_TYPE_INVALID) == FALSE) {
327 ofono_error("Can't parse the reply to RequestSelection()");
332 for (i = 0; i < selection && menu->items[i].text; i++);
334 if (i != selection) {
335 ofono_error("Invalid item selected");
340 cb(result, menu->items[selection].item_id, agent->user_data);
345 int stk_agent_request_selection(struct stk_agent *agent,
346 const struct stk_menu *menu,
347 stk_agent_selection_cb cb,
348 void *user_data, ofono_destroy_func destroy,
351 DBusConnection *conn = ofono_dbus_get_connection();
352 dbus_int16_t default_item = menu->default_item;
353 DBusMessageIter iter;
355 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
356 OFONO_SIM_APP_INTERFACE,
358 if (agent->msg == NULL)
361 dbus_message_iter_init_append(agent->msg, &iter);
363 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &menu->title);
364 dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE, &menu->icon.id);
365 append_menu_items(&iter, menu->items);
366 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT16, &default_item);
368 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
374 agent->user_data = user_data;
375 agent->user_destroy = destroy;
377 agent->request_selection_menu = menu;
379 dbus_pending_call_set_notify(agent->call, request_selection_cb,
385 static void display_text_cb(DBusPendingCall *call, void *data)
387 struct stk_agent *agent = data;
388 stk_agent_display_text_cb cb = agent->user_cb;
389 DBusMessage *reply = dbus_pending_call_steal_reply(call);
390 enum stk_agent_result result;
391 gboolean remove_agent;
393 if (check_error(agent, reply,
394 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE |
395 ALLOWED_ERROR_BUSY, &result) == -EINVAL) {
400 if (result != STK_AGENT_RESULT_OK) {
401 cb(result, agent->user_data);
405 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
406 ofono_error("Can't parse the reply to DisplayText()");
411 cb(result, agent->user_data);
416 int stk_agent_display_text(struct stk_agent *agent, const char *text,
417 const struct stk_icon_id *icon,
419 stk_agent_display_text_cb cb,
420 void *user_data, ofono_destroy_func destroy,
423 DBusConnection *conn = ofono_dbus_get_connection();
424 dbus_bool_t priority = urgent;
426 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
427 OFONO_SIM_APP_INTERFACE,
429 if (agent->msg == NULL)
432 dbus_message_append_args(agent->msg,
433 DBUS_TYPE_STRING, &text,
434 DBUS_TYPE_BYTE, &icon->id,
435 DBUS_TYPE_BOOLEAN, &priority,
438 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
444 agent->user_data = user_data;
445 agent->user_destroy = destroy;
447 dbus_pending_call_set_notify(agent->call, display_text_cb,
453 static void get_confirmation_cb(DBusPendingCall *call, void *data)
455 struct stk_agent *agent = data;
456 stk_agent_confirmation_cb cb = agent->user_cb;
457 DBusMessage *reply = dbus_pending_call_steal_reply(call);
458 enum stk_agent_result result;
459 gboolean remove_agent;
462 if (check_error(agent, reply,
463 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
464 &result) == -EINVAL) {
469 if (result != STK_AGENT_RESULT_OK) {
470 cb(result, FALSE, agent->user_data);
474 if (dbus_message_get_args(reply, NULL,
475 DBUS_TYPE_BOOLEAN, &confirm,
476 DBUS_TYPE_INVALID) == FALSE) {
477 ofono_error("Can't parse the reply to GetConfirmation()");
482 cb(result, confirm, agent->user_data);
487 int stk_agent_request_confirmation(struct stk_agent *agent, const char *text,
488 const struct stk_icon_id *icon,
489 stk_agent_confirmation_cb cb,
491 ofono_destroy_func destroy,
494 DBusConnection *conn = ofono_dbus_get_connection();
496 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
497 OFONO_SIM_APP_INTERFACE,
498 "RequestConfirmation");
499 if (agent->msg == NULL)
502 dbus_message_append_args(agent->msg,
503 DBUS_TYPE_STRING, &text,
504 DBUS_TYPE_BYTE, &icon->id,
507 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
513 agent->user_data = user_data;
514 agent->user_destroy = destroy;
516 dbus_pending_call_set_notify(agent->call, get_confirmation_cb,
522 static void get_digit_cb(DBusPendingCall *call, void *data)
524 struct stk_agent *agent = data;
525 stk_agent_string_cb cb = agent->user_cb;
526 DBusMessage *reply = dbus_pending_call_steal_reply(call);
527 enum stk_agent_result result;
528 gboolean remove_agent;
531 if (check_error(agent, reply,
532 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
533 &result) == -EINVAL) {
538 if (result != STK_AGENT_RESULT_OK) {
539 cb(result, NULL, agent->user_data);
543 if (dbus_message_get_args(reply, NULL,
544 DBUS_TYPE_STRING, &digit,
545 DBUS_TYPE_INVALID) == FALSE) {
546 ofono_error("Can't parse the reply to GetDigit()");
551 if (strlen(digit) != 1 || !strspn(digit, "0123456789*#+")) {
552 ofono_error("Invalid character");
557 if (agent->hidden_entry && digit[0] == '+') {
558 ofono_error("The character + is not allowed in this mode");
563 cb(result, digit, agent->user_data);
568 int stk_agent_request_digit(struct stk_agent *agent, const char *text,
569 const struct stk_icon_id *icon,
570 stk_agent_string_cb cb, void *user_data,
571 ofono_destroy_func destroy, int timeout)
573 DBusConnection *conn = ofono_dbus_get_connection();
575 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
576 OFONO_SIM_APP_INTERFACE,
578 if (agent->msg == NULL)
581 dbus_message_append_args(agent->msg,
582 DBUS_TYPE_STRING, &text,
583 DBUS_TYPE_BYTE, &icon->id,
586 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
592 agent->user_data = user_data;
593 agent->user_destroy = destroy;
594 agent->hidden_entry = FALSE;
596 dbus_pending_call_set_notify(agent->call, get_digit_cb, agent, NULL);
601 int stk_agent_request_quick_digit(struct stk_agent *agent, const char *text,
602 const struct stk_icon_id *icon,
603 stk_agent_string_cb cb, void *user_data,
604 ofono_destroy_func destroy, int timeout)
606 DBusConnection *conn = ofono_dbus_get_connection();
608 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
609 OFONO_SIM_APP_INTERFACE,
610 "RequestQuickDigit");
611 if (agent->msg == NULL)
614 dbus_message_append_args(agent->msg,
615 DBUS_TYPE_STRING, &text,
616 DBUS_TYPE_BYTE, &icon->id,
619 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
625 agent->user_data = user_data;
626 agent->user_destroy = destroy;
627 agent->hidden_entry = TRUE;
629 dbus_pending_call_set_notify(agent->call, get_digit_cb, agent, NULL);
634 static void get_key_cb(DBusPendingCall *call, void *data)
636 struct stk_agent *agent = data;
637 stk_agent_string_cb cb = agent->user_cb;
638 DBusMessage *reply = dbus_pending_call_steal_reply(call);
639 enum stk_agent_result result;
640 gboolean remove_agent;
643 if (check_error(agent, reply,
644 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
645 &result) == -EINVAL) {
650 if (result != STK_AGENT_RESULT_OK) {
651 cb(result, NULL, agent->user_data);
655 if (dbus_message_get_args(reply, NULL,
656 DBUS_TYPE_STRING, &key,
657 DBUS_TYPE_INVALID) == FALSE ||
658 g_utf8_strlen(key, 10) != 1) {
659 ofono_error("Can't parse the reply to GetKey()");
664 cb(result, key, agent->user_data);
669 int stk_agent_request_key(struct stk_agent *agent, const char *text,
670 const struct stk_icon_id *icon,
671 ofono_bool_t unicode_charset,
672 stk_agent_string_cb cb, void *user_data,
673 ofono_destroy_func destroy, int timeout)
675 DBusConnection *conn = ofono_dbus_get_connection();
677 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
678 OFONO_SIM_APP_INTERFACE,
680 if (agent->msg == NULL)
683 dbus_message_append_args(agent->msg,
684 DBUS_TYPE_STRING, &text,
685 DBUS_TYPE_BYTE, &icon->id,
688 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
694 agent->user_data = user_data;
695 agent->user_destroy = destroy;
697 dbus_pending_call_set_notify(agent->call, get_key_cb, agent, NULL);
702 static void get_digits_cb(DBusPendingCall *call, void *data)
704 struct stk_agent *agent = data;
705 stk_agent_string_cb cb = agent->user_cb;
706 DBusMessage *reply = dbus_pending_call_steal_reply(call);
707 enum stk_agent_result result;
708 gboolean remove_agent;
712 if (check_error(agent, reply,
713 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
714 &result) == -EINVAL) {
719 if (result != STK_AGENT_RESULT_OK) {
720 cb(result, NULL, agent->user_data);
724 if (dbus_message_get_args(reply, NULL,
725 DBUS_TYPE_STRING, &string,
726 DBUS_TYPE_INVALID) == FALSE) {
727 ofono_error("Can't parse the reply to GetDigits()");
732 len = strlen(string);
734 if (len < agent->min_length || len > agent->max_length) {
735 ofono_error("Length not acceptable");
740 if (agent->hidden_entry)
741 span = strspn(string, "0123456789*#");
743 span = strspn(string, "0123456789*#+");
746 ofono_error("Invalid character found");
751 cb(result, string, agent->user_data);
756 int stk_agent_request_digits(struct stk_agent *agent, const char *text,
757 const struct stk_icon_id *icon,
758 const char *default_text,
759 int min, int max, ofono_bool_t hidden,
760 stk_agent_string_cb cb, void *user_data,
761 ofono_destroy_func destroy, int timeout)
763 DBusConnection *conn = ofono_dbus_get_connection();
764 uint8_t min_val = min;
765 uint8_t max_val = max;
766 dbus_bool_t hidden_val = hidden;
768 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
769 OFONO_SIM_APP_INTERFACE,
771 if (agent->msg == NULL)
774 if (default_text == NULL)
777 dbus_message_append_args(agent->msg,
778 DBUS_TYPE_STRING, &text,
779 DBUS_TYPE_BYTE, &icon->id,
780 DBUS_TYPE_STRING, &default_text,
781 DBUS_TYPE_BYTE, &min_val,
782 DBUS_TYPE_BYTE, &max_val,
783 DBUS_TYPE_BOOLEAN, &hidden_val,
786 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
792 agent->user_data = user_data;
793 agent->user_destroy = destroy;
794 agent->min_length = min_val;
795 agent->max_length = max_val;
796 agent->hidden_entry = hidden_val;
798 dbus_pending_call_set_notify(agent->call, get_digits_cb, agent, NULL);
803 static void get_input_cb(DBusPendingCall *call, void *data)
805 struct stk_agent *agent = data;
806 stk_agent_string_cb cb = agent->user_cb;
807 DBusMessage *reply = dbus_pending_call_steal_reply(call);
808 enum stk_agent_result result;
809 gboolean remove_agent;
813 if (check_error(agent, reply,
814 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
815 &result) == -EINVAL) {
820 if (result != STK_AGENT_RESULT_OK) {
821 cb(result, NULL, agent->user_data);
825 if (dbus_message_get_args(reply, NULL,
826 DBUS_TYPE_STRING, &string,
827 DBUS_TYPE_INVALID) == FALSE) {
828 ofono_error("Can't parse the reply to GetInput()");
833 len = g_utf8_strlen(string, -1);
835 if (len < agent->min_length || len > agent->max_length) {
836 ofono_error("Length not acceptable");
841 cb(result, string, agent->user_data);
846 int stk_agent_request_input(struct stk_agent *agent, const char *text,
847 const struct stk_icon_id *icon,
848 const char *default_text,
849 ofono_bool_t unicode_charset, int min, int max,
850 ofono_bool_t hidden, stk_agent_string_cb cb,
851 void *user_data, ofono_destroy_func destroy,
854 DBusConnection *conn = ofono_dbus_get_connection();
855 uint8_t min_val = min;
856 uint8_t max_val = max;
857 dbus_bool_t hidden_val = hidden;
859 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
860 OFONO_SIM_APP_INTERFACE,
862 if (agent->msg == NULL)
865 if (default_text == NULL)
868 dbus_message_append_args(agent->msg,
869 DBUS_TYPE_STRING, &text,
870 DBUS_TYPE_BYTE, &icon->id,
871 DBUS_TYPE_STRING, &default_text,
872 DBUS_TYPE_BYTE, &min_val,
873 DBUS_TYPE_BYTE, &max_val,
874 DBUS_TYPE_BOOLEAN, &hidden_val,
877 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
883 agent->user_data = user_data;
884 agent->user_destroy = destroy;
885 agent->min_length = min_val;
886 agent->max_length = max_val;
887 agent->hidden_entry = hidden_val;
889 dbus_pending_call_set_notify(agent->call, get_input_cb, agent, NULL);
894 static void confirm_call_cb(DBusPendingCall *call, void *data)
896 struct stk_agent *agent = data;
897 stk_agent_confirmation_cb cb = agent->user_cb;
898 DBusMessage *reply = dbus_pending_call_steal_reply(call);
899 enum stk_agent_result result;
900 gboolean remove_agent;
903 if (check_error(agent, reply,
904 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
909 if (result != STK_AGENT_RESULT_OK) {
910 cb(result, FALSE, agent->user_data);
914 if (dbus_message_get_args(reply, NULL,
915 DBUS_TYPE_BOOLEAN, &confirm,
916 DBUS_TYPE_INVALID) == FALSE) {
917 ofono_error("Can't parse the reply to ConfirmCallSetup()");
922 cb(result, confirm, agent->user_data);
927 int stk_agent_confirm_call(struct stk_agent *agent, const char *text,
928 const struct stk_icon_id *icon,
929 stk_agent_confirmation_cb cb,
930 void *user_data, ofono_destroy_func destroy,
933 DBusConnection *conn = ofono_dbus_get_connection();
935 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
936 OFONO_SIM_APP_INTERFACE,
938 if (agent->msg == NULL)
941 dbus_message_append_args(agent->msg,
942 DBUS_TYPE_STRING, &text,
943 DBUS_TYPE_BYTE, &icon->id,
946 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
952 agent->user_data = user_data;
953 agent->user_destroy = destroy;
955 dbus_pending_call_set_notify(agent->call, confirm_call_cb, agent, NULL);
960 static void play_tone_cb(DBusPendingCall *call, void *data)
962 struct stk_agent *agent = data;
963 stk_agent_tone_cb cb = agent->user_cb;
964 DBusMessage *reply = dbus_pending_call_steal_reply(call);
965 enum stk_agent_result result;
966 gboolean remove_agent;
968 if (check_error(agent, reply,
969 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
974 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
975 ofono_error("Can't parse the reply to PlayTone()");
980 cb(result, agent->user_data);
986 int stk_agent_play_tone(struct stk_agent *agent, const char *text,
987 const struct stk_icon_id *icon, ofono_bool_t vibrate,
988 const char *tone, stk_agent_tone_cb cb, void *user_data,
989 ofono_destroy_func destroy, int timeout)
991 DBusConnection *conn = ofono_dbus_get_connection();
993 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
994 OFONO_SIM_APP_INTERFACE,
996 if (agent->msg == NULL)
999 dbus_message_append_args(agent->msg,
1000 DBUS_TYPE_STRING, &tone,
1001 DBUS_TYPE_STRING, &text,
1002 DBUS_TYPE_BYTE, &icon->id,
1005 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1006 timeout) == FALSE ||
1007 agent->call == NULL)
1010 agent->user_cb = cb;
1011 agent->user_data = user_data;
1012 agent->user_destroy = destroy;
1014 dbus_pending_call_set_notify(agent->call, play_tone_cb,
1020 int stk_agent_loop_tone(struct stk_agent *agent, const char *text,
1021 const struct stk_icon_id *icon, ofono_bool_t vibrate,
1022 const char *tone, stk_agent_tone_cb cb, void *user_data,
1023 ofono_destroy_func destroy, int timeout)
1025 DBusConnection *conn = ofono_dbus_get_connection();
1027 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1028 OFONO_SIM_APP_INTERFACE,
1030 if (agent->msg == NULL)
1033 dbus_message_append_args(agent->msg,
1034 DBUS_TYPE_STRING, &tone,
1035 DBUS_TYPE_STRING, &text,
1036 DBUS_TYPE_BYTE, &icon->id,
1039 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1040 timeout) == FALSE ||
1041 agent->call == NULL)
1044 agent->user_cb = cb;
1045 agent->user_data = user_data;
1046 agent->user_destroy = destroy;
1048 dbus_pending_call_set_notify(agent->call, play_tone_cb,
1054 static void action_info_cb(DBusPendingCall *call, void *data)
1056 struct stk_agent *agent = data;
1057 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1058 enum stk_agent_result result;
1059 gboolean remove_agent;
1061 if (check_error(agent, reply, 0, &result) == -EINVAL) {
1062 remove_agent = TRUE;
1066 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
1067 ofono_error("Can't parse the reply to DisplayActionInfo()");
1068 remove_agent = TRUE;
1077 int stk_agent_display_action_info(struct stk_agent *agent, const char *text,
1078 const struct stk_icon_id *icon)
1080 DBusConnection *conn = ofono_dbus_get_connection();
1082 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1083 OFONO_SIM_APP_INTERFACE,
1084 "DisplayActionInformation");
1085 if (agent->msg == NULL)
1088 dbus_message_append_args(agent->msg,
1089 DBUS_TYPE_STRING, &text,
1090 DBUS_TYPE_BYTE, &icon->id,
1093 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1094 DBUS_TIMEOUT_INFINITE) == FALSE ||
1095 agent->call == NULL)
1098 dbus_pending_call_set_notify(agent->call, action_info_cb, agent, NULL);
1103 static void confirm_launch_browser_cb(DBusPendingCall *call, void *data)
1105 struct stk_agent *agent = data;
1106 stk_agent_confirmation_cb cb = agent->user_cb;
1107 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1108 enum stk_agent_result result;
1109 gboolean remove_agent;
1110 dbus_bool_t confirm;
1112 if (check_error(agent, reply, 0, &result) == -EINVAL) {
1113 remove_agent = TRUE;
1114 cb(STK_AGENT_RESULT_TERMINATE, FALSE, agent->user_data);
1118 if (result != STK_AGENT_RESULT_OK) {
1119 cb(result, FALSE, agent->user_data);
1123 if (dbus_message_get_args(reply, NULL,
1124 DBUS_TYPE_BOOLEAN, &confirm,
1125 DBUS_TYPE_INVALID) == FALSE) {
1126 ofono_error("Can't parse the reply to ConfirmLaunchBrowser()");
1127 remove_agent = TRUE;
1131 cb(result, confirm, agent->user_data);
1136 int stk_agent_confirm_launch_browser(struct stk_agent *agent, const char *text,
1137 unsigned char icon_id, const char *url,
1138 stk_agent_confirmation_cb cb,
1140 ofono_destroy_func destroy, int timeout)
1142 DBusConnection *conn = ofono_dbus_get_connection();
1144 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1145 OFONO_SIM_APP_INTERFACE,
1146 "ConfirmLaunchBrowser");
1147 if (agent->msg == NULL)
1153 dbus_message_append_args(agent->msg,
1154 DBUS_TYPE_STRING, &text,
1155 DBUS_TYPE_BYTE, &icon_id,
1156 DBUS_TYPE_STRING, &url,
1159 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1160 timeout) == FALSE ||
1161 agent->call == NULL)
1164 agent->user_cb = cb;
1165 agent->user_data = user_data;
1166 agent->user_destroy = destroy;
1168 dbus_pending_call_set_notify(agent->call, confirm_launch_browser_cb,
1174 static void display_action_cb(DBusPendingCall *call, void *data)
1176 struct stk_agent *agent = data;
1177 stk_agent_display_action_cb cb = agent->user_cb;
1178 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1179 enum stk_agent_result result;
1180 gboolean remove_agent;
1182 if (check_error(agent, reply,
1183 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
1184 remove_agent = TRUE;
1188 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
1189 ofono_error("Can't parse the reply to DisplayAction()");
1190 remove_agent = TRUE;
1194 cb(result, agent->user_data);
1200 int stk_agent_display_action(struct stk_agent *agent,
1202 const struct stk_icon_id *icon,
1203 stk_agent_display_action_cb cb,
1205 ofono_destroy_func destroy)
1207 DBusConnection *conn = ofono_dbus_get_connection();
1209 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1210 OFONO_SIM_APP_INTERFACE,
1212 if (agent->msg == NULL)
1215 dbus_message_append_args(agent->msg,
1216 DBUS_TYPE_STRING, &text,
1217 DBUS_TYPE_BYTE, &icon->id,
1220 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1221 DBUS_TIMEOUT_INFINITE) == FALSE ||
1222 agent->call == NULL)
1225 agent->user_cb = cb;
1226 agent->user_data = user_data;
1227 agent->user_destroy = destroy;
1229 dbus_pending_call_set_notify(agent->call, display_action_cb,
1235 static void confirm_open_channel_cb(DBusPendingCall *call, void *data)
1237 struct stk_agent *agent = data;
1238 stk_agent_confirmation_cb cb = agent->user_cb;
1239 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1240 enum stk_agent_result result;
1241 gboolean remove_agent;
1242 dbus_bool_t confirm;
1244 if (check_error(agent, reply,
1245 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
1246 remove_agent = TRUE;
1250 if (result != STK_AGENT_RESULT_OK) {
1251 cb(result, FALSE, agent->user_data);
1255 if (dbus_message_get_args(reply, NULL,
1256 DBUS_TYPE_BOOLEAN, &confirm,
1257 DBUS_TYPE_INVALID) == FALSE) {
1258 ofono_error("Can't parse the reply to ConfirmOpenChannel()");
1259 remove_agent = TRUE;
1263 cb(result, confirm, agent->user_data);
1268 int stk_agent_confirm_open_channel(struct stk_agent *agent, const char *text,
1269 const struct stk_icon_id *icon,
1270 stk_agent_confirmation_cb cb,
1272 ofono_destroy_func destroy, int timeout)
1274 DBusConnection *conn = ofono_dbus_get_connection();
1276 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1277 OFONO_SIM_APP_INTERFACE,
1278 "ConfirmOpenChannel");
1279 if (agent->msg == NULL)
1282 dbus_message_append_args(agent->msg,
1283 DBUS_TYPE_STRING, &text,
1284 DBUS_TYPE_BYTE, &icon->id,
1287 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1288 timeout) == FALSE ||
1289 agent->call == NULL)
1292 agent->user_cb = cb;
1293 agent->user_data = user_data;
1294 agent->user_destroy = destroy;
1296 dbus_pending_call_set_notify(agent->call, confirm_open_channel_cb,