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 int stk_agent_request_quick_digit(struct stk_agent *agent, const char *text,
588 const struct stk_icon_id *icon,
589 stk_agent_string_cb cb, void *user_data,
590 ofono_destroy_func destroy, int timeout)
592 DBusConnection *conn = ofono_dbus_get_connection();
594 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
595 OFONO_SIM_APP_INTERFACE,
596 "RequestQuickDigit");
597 if (agent->msg == NULL)
600 dbus_message_append_args(agent->msg,
601 DBUS_TYPE_STRING, &text,
602 DBUS_TYPE_BYTE, &icon->id,
605 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
611 agent->user_data = user_data;
612 agent->user_destroy = destroy;
614 dbus_pending_call_set_notify(agent->call, get_digit_cb, agent, NULL);
619 static void get_key_cb(DBusPendingCall *call, void *data)
621 struct stk_agent *agent = data;
622 stk_agent_string_cb cb = agent->user_cb;
623 DBusMessage *reply = dbus_pending_call_steal_reply(call);
624 enum stk_agent_result result;
625 gboolean remove_agent;
628 if (check_error(agent, reply,
629 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
630 &result) == -EINVAL) {
635 if (result != STK_AGENT_RESULT_OK) {
636 cb(result, NULL, agent->user_data);
640 if (dbus_message_get_args(reply, NULL,
641 DBUS_TYPE_STRING, &key,
642 DBUS_TYPE_INVALID) == FALSE ||
643 g_utf8_strlen(key, 10) != 1) {
644 ofono_error("Can't parse the reply to GetKey()");
649 cb(result, key, agent->user_data);
654 int stk_agent_request_key(struct stk_agent *agent, const char *text,
655 const struct stk_icon_id *icon,
656 ofono_bool_t unicode_charset,
657 stk_agent_string_cb cb, void *user_data,
658 ofono_destroy_func destroy, int timeout)
660 DBusConnection *conn = ofono_dbus_get_connection();
662 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
663 OFONO_SIM_APP_INTERFACE,
665 if (agent->msg == NULL)
668 dbus_message_append_args(agent->msg,
669 DBUS_TYPE_STRING, &text,
670 DBUS_TYPE_BYTE, &icon->id,
673 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
679 agent->user_data = user_data;
680 agent->user_destroy = destroy;
682 dbus_pending_call_set_notify(agent->call, get_key_cb, agent, NULL);
687 static void get_digits_cb(DBusPendingCall *call, void *data)
689 struct stk_agent *agent = data;
690 stk_agent_string_cb cb = agent->user_cb;
691 DBusMessage *reply = dbus_pending_call_steal_reply(call);
692 enum stk_agent_result result;
693 gboolean remove_agent;
696 if (check_error(agent, reply,
697 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
698 &result) == -EINVAL) {
703 if (result != STK_AGENT_RESULT_OK) {
704 cb(result, NULL, agent->user_data);
708 if (dbus_message_get_args(reply, NULL,
709 DBUS_TYPE_STRING, &string,
710 DBUS_TYPE_INVALID) == FALSE) {
711 ofono_error("Can't parse the reply to GetDigits()");
716 cb(result, string, agent->user_data);
721 int stk_agent_request_digits(struct stk_agent *agent, const char *text,
722 const struct stk_icon_id *icon,
723 const char *default_text,
724 int min, int max, ofono_bool_t hidden,
725 stk_agent_string_cb cb, void *user_data,
726 ofono_destroy_func destroy, int timeout)
728 DBusConnection *conn = ofono_dbus_get_connection();
729 uint8_t min_val = min;
730 uint8_t max_val = max;
731 dbus_bool_t hidden_val = hidden;
733 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
734 OFONO_SIM_APP_INTERFACE,
736 if (agent->msg == NULL)
739 if (default_text == NULL)
742 dbus_message_append_args(agent->msg,
743 DBUS_TYPE_STRING, &text,
744 DBUS_TYPE_BYTE, &icon->id,
745 DBUS_TYPE_STRING, &default_text,
746 DBUS_TYPE_BYTE, &min_val,
747 DBUS_TYPE_BYTE, &max_val,
748 DBUS_TYPE_BOOLEAN, &hidden_val,
751 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
757 agent->user_data = user_data;
758 agent->user_destroy = destroy;
760 dbus_pending_call_set_notify(agent->call, get_digits_cb, agent, NULL);
765 static void get_input_cb(DBusPendingCall *call, void *data)
767 struct stk_agent *agent = data;
768 stk_agent_string_cb cb = agent->user_cb;
769 DBusMessage *reply = dbus_pending_call_steal_reply(call);
770 enum stk_agent_result result;
771 gboolean remove_agent;
774 if (check_error(agent, reply,
775 ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
776 &result) == -EINVAL) {
781 if (result != STK_AGENT_RESULT_OK) {
782 cb(result, NULL, agent->user_data);
786 if (dbus_message_get_args(reply, NULL,
787 DBUS_TYPE_STRING, &string,
788 DBUS_TYPE_INVALID) == FALSE) {
789 ofono_error("Can't parse the reply to GetInput()");
794 cb(result, string, agent->user_data);
799 int stk_agent_request_input(struct stk_agent *agent, const char *text,
800 const struct stk_icon_id *icon,
801 const char *default_text,
802 ofono_bool_t unicode_charset, int min, int max,
803 ofono_bool_t hidden, stk_agent_string_cb cb,
804 void *user_data, ofono_destroy_func destroy,
807 DBusConnection *conn = ofono_dbus_get_connection();
808 uint8_t min_val = min;
809 uint8_t max_val = max;
810 dbus_bool_t hidden_val = hidden;
812 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
813 OFONO_SIM_APP_INTERFACE,
815 if (agent->msg == NULL)
818 if (default_text == NULL)
821 dbus_message_append_args(agent->msg,
822 DBUS_TYPE_STRING, &text,
823 DBUS_TYPE_BYTE, &icon->id,
824 DBUS_TYPE_STRING, &default_text,
825 DBUS_TYPE_BYTE, &min_val,
826 DBUS_TYPE_BYTE, &max_val,
827 DBUS_TYPE_BOOLEAN, &hidden_val,
830 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
836 agent->user_data = user_data;
837 agent->user_destroy = destroy;
839 dbus_pending_call_set_notify(agent->call, get_input_cb, agent, NULL);
844 static void confirm_call_cb(DBusPendingCall *call, void *data)
846 struct stk_agent *agent = data;
847 stk_agent_confirmation_cb cb = agent->user_cb;
848 DBusMessage *reply = dbus_pending_call_steal_reply(call);
849 enum stk_agent_result result;
850 gboolean remove_agent;
853 if (check_error(agent, reply,
854 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
859 if (result != STK_AGENT_RESULT_OK) {
860 cb(result, FALSE, agent->user_data);
864 if (dbus_message_get_args(reply, NULL,
865 DBUS_TYPE_BOOLEAN, &confirm,
866 DBUS_TYPE_INVALID) == FALSE) {
867 ofono_error("Can't parse the reply to ConfirmCallSetup()");
872 cb(result, confirm, agent->user_data);
877 int stk_agent_confirm_call(struct stk_agent *agent, const char *text,
878 const struct stk_icon_id *icon,
879 stk_agent_confirmation_cb cb,
880 void *user_data, ofono_destroy_func destroy,
883 DBusConnection *conn = ofono_dbus_get_connection();
885 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
886 OFONO_SIM_APP_INTERFACE,
888 if (agent->msg == NULL)
891 dbus_message_append_args(agent->msg,
892 DBUS_TYPE_STRING, &text,
893 DBUS_TYPE_BYTE, &icon->id,
896 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
902 agent->user_data = user_data;
903 agent->user_destroy = destroy;
905 dbus_pending_call_set_notify(agent->call, confirm_call_cb, agent, NULL);
910 static void play_tone_cb(DBusPendingCall *call, void *data)
912 struct stk_agent *agent = data;
913 stk_agent_tone_cb cb = agent->user_cb;
914 DBusMessage *reply = dbus_pending_call_steal_reply(call);
915 enum stk_agent_result result;
916 gboolean remove_agent;
918 if (check_error(agent, reply,
919 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
924 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
925 ofono_error("Can't parse the reply to PlayTone()");
930 cb(result, agent->user_data);
936 int stk_agent_play_tone(struct stk_agent *agent, const char *text,
937 const struct stk_icon_id *icon, ofono_bool_t vibrate,
938 const char *tone, stk_agent_tone_cb cb, void *user_data,
939 ofono_destroy_func destroy, int timeout)
941 DBusConnection *conn = ofono_dbus_get_connection();
943 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
944 OFONO_SIM_APP_INTERFACE,
946 if (agent->msg == NULL)
949 dbus_message_append_args(agent->msg,
950 DBUS_TYPE_STRING, &tone,
951 DBUS_TYPE_STRING, &text,
952 DBUS_TYPE_BYTE, &icon->id,
955 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
961 agent->user_data = user_data;
962 agent->user_destroy = destroy;
964 dbus_pending_call_set_notify(agent->call, play_tone_cb,
970 int stk_agent_loop_tone(struct stk_agent *agent, const char *text,
971 const struct stk_icon_id *icon, ofono_bool_t vibrate,
972 const char *tone, stk_agent_tone_cb cb, void *user_data,
973 ofono_destroy_func destroy, int timeout)
975 DBusConnection *conn = ofono_dbus_get_connection();
977 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
978 OFONO_SIM_APP_INTERFACE,
980 if (agent->msg == NULL)
983 dbus_message_append_args(agent->msg,
984 DBUS_TYPE_STRING, &tone,
985 DBUS_TYPE_STRING, &text,
986 DBUS_TYPE_BYTE, &icon->id,
989 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
995 agent->user_data = user_data;
996 agent->user_destroy = destroy;
998 dbus_pending_call_set_notify(agent->call, play_tone_cb,
1004 static void action_info_cb(DBusPendingCall *call, void *data)
1006 struct stk_agent *agent = data;
1007 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1008 enum stk_agent_result result;
1009 gboolean remove_agent;
1011 if (check_error(agent, reply, 0, &result) == -EINVAL) {
1012 remove_agent = TRUE;
1016 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
1017 ofono_error("Can't parse the reply to DisplayActionInfo()");
1018 remove_agent = TRUE;
1027 int stk_agent_display_action_info(struct stk_agent *agent, const char *text,
1028 const struct stk_icon_id *icon)
1030 DBusConnection *conn = ofono_dbus_get_connection();
1032 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1033 OFONO_SIM_APP_INTERFACE,
1034 "DisplayActionInformation");
1035 if (agent->msg == NULL)
1038 dbus_message_append_args(agent->msg,
1039 DBUS_TYPE_STRING, &text,
1040 DBUS_TYPE_BYTE, &icon->id,
1043 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1044 DBUS_TIMEOUT_INFINITE) == FALSE ||
1045 agent->call == NULL)
1048 dbus_pending_call_set_notify(agent->call, action_info_cb, agent, NULL);
1053 static void confirm_launch_browser_cb(DBusPendingCall *call, void *data)
1055 struct stk_agent *agent = data;
1056 stk_agent_confirmation_cb cb = agent->user_cb;
1057 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1058 enum stk_agent_result result;
1059 gboolean remove_agent;
1060 dbus_bool_t confirm;
1062 if (check_error(agent, reply, 0, &result) == -EINVAL) {
1063 remove_agent = TRUE;
1064 cb(STK_AGENT_RESULT_TERMINATE, FALSE, agent->user_data);
1068 if (result != STK_AGENT_RESULT_OK) {
1069 cb(result, FALSE, agent->user_data);
1073 if (dbus_message_get_args(reply, NULL,
1074 DBUS_TYPE_BOOLEAN, &confirm,
1075 DBUS_TYPE_INVALID) == FALSE) {
1076 ofono_error("Can't parse the reply to ConfirmLaunchBrowser()");
1077 remove_agent = TRUE;
1081 cb(result, confirm, agent->user_data);
1086 int stk_agent_confirm_launch_browser(struct stk_agent *agent, const char *text,
1087 unsigned char icon_id, const char *url,
1088 stk_agent_confirmation_cb cb,
1090 ofono_destroy_func destroy, int timeout)
1092 DBusConnection *conn = ofono_dbus_get_connection();
1094 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1095 OFONO_SIM_APP_INTERFACE,
1096 "ConfirmLaunchBrowser");
1097 if (agent->msg == NULL)
1103 dbus_message_append_args(agent->msg,
1104 DBUS_TYPE_STRING, &text,
1105 DBUS_TYPE_BYTE, &icon_id,
1106 DBUS_TYPE_STRING, &url,
1109 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1110 timeout) == FALSE ||
1111 agent->call == NULL)
1114 agent->user_cb = cb;
1115 agent->user_data = user_data;
1116 agent->user_destroy = destroy;
1118 dbus_pending_call_set_notify(agent->call, confirm_launch_browser_cb,
1124 static void display_action_cb(DBusPendingCall *call, void *data)
1126 struct stk_agent *agent = data;
1127 stk_agent_display_action_cb cb = agent->user_cb;
1128 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1129 enum stk_agent_result result;
1130 gboolean remove_agent;
1132 if (check_error(agent, reply,
1133 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
1134 remove_agent = TRUE;
1138 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
1139 ofono_error("Can't parse the reply to DisplayAction()");
1140 remove_agent = TRUE;
1144 cb(result, agent->user_data);
1150 int stk_agent_display_action(struct stk_agent *agent,
1152 const struct stk_icon_id *icon,
1153 stk_agent_display_action_cb cb,
1155 ofono_destroy_func destroy)
1157 DBusConnection *conn = ofono_dbus_get_connection();
1159 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1160 OFONO_SIM_APP_INTERFACE,
1162 if (agent->msg == NULL)
1165 dbus_message_append_args(agent->msg,
1166 DBUS_TYPE_STRING, &text,
1167 DBUS_TYPE_BYTE, &icon->id,
1170 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1171 DBUS_TIMEOUT_INFINITE) == FALSE ||
1172 agent->call == NULL)
1175 agent->user_cb = cb;
1176 agent->user_data = user_data;
1177 agent->user_destroy = destroy;
1179 dbus_pending_call_set_notify(agent->call, display_action_cb,
1185 static void confirm_open_channel_cb(DBusPendingCall *call, void *data)
1187 struct stk_agent *agent = data;
1188 stk_agent_confirmation_cb cb = agent->user_cb;
1189 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1190 enum stk_agent_result result;
1191 gboolean remove_agent;
1192 dbus_bool_t confirm;
1194 if (check_error(agent, reply,
1195 ALLOWED_ERROR_TERMINATE, &result) == -EINVAL) {
1196 remove_agent = TRUE;
1200 if (result != STK_AGENT_RESULT_OK) {
1201 cb(result, FALSE, agent->user_data);
1205 if (dbus_message_get_args(reply, NULL,
1206 DBUS_TYPE_BOOLEAN, &confirm,
1207 DBUS_TYPE_INVALID) == FALSE) {
1208 ofono_error("Can't parse the reply to ConfirmOpenChannel()");
1209 remove_agent = TRUE;
1213 cb(result, confirm, agent->user_data);
1218 int stk_agent_confirm_open_channel(struct stk_agent *agent, const char *text,
1219 const struct stk_icon_id *icon,
1220 stk_agent_confirmation_cb cb,
1222 ofono_destroy_func destroy, int timeout)
1224 DBusConnection *conn = ofono_dbus_get_connection();
1226 agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
1227 OFONO_SIM_APP_INTERFACE,
1228 "ConfirmOpenChannel");
1229 if (agent->msg == NULL)
1232 dbus_message_append_args(agent->msg,
1233 DBUS_TYPE_STRING, &text,
1234 DBUS_TYPE_BYTE, &icon->id,
1237 if (dbus_connection_send_with_reply(conn, agent->msg, &agent->call,
1238 timeout) == FALSE ||
1239 agent->call == NULL)
1242 agent->user_cb = cb;
1243 agent->user_data = user_data;
1244 agent->user_destroy = destroy;
1246 dbus_pending_call_set_notify(agent->call, confirm_open_channel_cb,