Default to hfp modem when no args are passed
[profile/ivi/lemolo.git] / dialer / ussd.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 #include <Elementary.h>
5
6 #include "log.h"
7 #include "gui.h"
8 #include "ofono.h"
9 #include "simple-popup.h"
10
11 typedef struct _USSD
12 {
13         Evas_Object *popup;
14         OFono_Pending *pending;
15         OFono_USSD_State state;
16         const char *message;
17         OFono_Callback_List_Modem_Node *cb_changed;
18 } USSD;
19
20 static void _ussd_respond_reply(void *data, OFono_Error err, const char *str)
21 {
22         USSD *ctx = data;
23
24         DBG("ctx=%p, e=%d, str=%s, popup=%p", ctx, err, str, ctx->popup);
25
26         ctx->pending = NULL;
27
28         /* no popup? then it was canceled */
29         if (!ctx->popup)
30                 return;
31
32         if (err == OFONO_ERROR_NONE) {
33                 eina_stringshare_replace(&(ctx->message), str);
34                 simple_popup_message_set(ctx->popup, ctx->message);
35         } else if (err == OFONO_ERROR_OFFLINE) {
36                 simple_popup_title_set(ctx->popup, "Offline");
37                 simple_popup_message_set(ctx->popup, "System is Offline");
38                 simple_popup_button_dismiss_set(ctx->popup);
39         } else {
40                 char buf[256];
41
42                 if (ctx->state == OFONO_USSD_STATE_USER_RESPONSE)
43                         snprintf(buf, sizeof(buf),
44                                         "Could not complete.<br>Error: %s.<br>"
45                                         "Try again:<br><br>%s",
46                                         ofono_error_message_get(err),
47                                         ctx->message);
48                 else
49                         snprintf(buf, sizeof(buf),
50                                         "Could not complete.<br>Error: %s.",
51                                         ofono_error_message_get(err));
52
53                 simple_popup_title_set(ctx->popup, "Error");
54                 simple_popup_message_set(ctx->popup, buf);
55         }
56 }
57
58 static void _ussd_respond(void *data, Evas_Object *o __UNUSED__,
59                                 void *event_info __UNUSED__)
60 {
61         USSD *ctx = data;
62         const char *markup = simple_popup_entry_get(ctx->popup);
63         char *utf8;
64
65         DBG("ctx=%p, markup=%s, pending=%p, popup=%p",
66                 ctx, markup, ctx->pending, ctx->popup);
67
68         if (!markup)
69                 return;
70
71         /* do not respond if there is a pending ss call */
72         EINA_SAFETY_ON_TRUE_RETURN(ctx->pending != NULL);
73
74         utf8 = elm_entry_markup_to_utf8(markup);
75         EINA_SAFETY_ON_NULL_RETURN(utf8);
76
77         ctx->pending = ofono_ussd_respond(utf8, _ussd_respond_reply, ctx);
78         free(utf8);
79
80         simple_popup_message_set(ctx->popup, NULL);
81         simple_popup_entry_disable(ctx->popup);
82 }
83
84 static void _ussd_cancel_reply(void *data, OFono_Error e)
85 {
86         USSD *ctx = data;
87
88         DBG("ctx=%p, e=%d, pending=%p, popup=%p",
89                 ctx, e, ctx->pending, ctx->popup);
90
91         if (ctx->popup)
92                 evas_object_del(ctx->popup);
93 }
94
95 static void _ussd_cancel(void *data, Evas_Object *o __UNUSED__,
96                                 void *event_info __UNUSED__)
97 {
98         USSD *ctx = data;
99         ofono_ussd_cancel(_ussd_cancel_reply, ctx);
100 }
101
102 static void _ofono_changed(void *data)
103 {
104         USSD *ctx = data;
105         OFono_USSD_State state = ofono_ussd_state_get();
106
107         DBG("ctx=%p, state=%d (was: %d), pending=%p",
108                 ctx, state, ctx->state, ctx->pending);
109
110         if (ctx->state == state)
111                 return;
112
113         if (state != OFONO_USSD_STATE_USER_RESPONSE) {
114                 simple_popup_entry_disable(ctx->popup);
115                 simple_popup_button_dismiss_set(ctx->popup);
116         } else {
117                 simple_popup_entry_enable(ctx->popup);
118                 simple_popup_buttons_set(ctx->popup,
119                                                 "Respond",
120                                                 "dialer",
121                                                 _ussd_respond,
122                                                 "Cancel",
123                                                 "dialer-caution",
124                                                 _ussd_cancel,
125                                                 ctx);
126         }
127
128         ctx->state = state;
129 }
130
131 static void _on_del(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__,
132                         void *event_info __UNUSED__)
133 {
134         USSD *ctx = data;
135
136         DBG("ctx=%p, pending=%p, cb_changed=%p",
137                 ctx, ctx->pending, ctx->cb_changed);
138
139         ctx->popup = NULL;
140
141         if (ctx->pending) {
142                 ofono_ussd_cancel(NULL, NULL);
143                 ofono_pending_cancel(ctx->pending);
144         }
145
146         eina_stringshare_del(ctx->message);
147         ofono_modem_changed_cb_del(ctx->cb_changed);
148 }
149
150 void ussd_start(const char *message)
151 {
152         USSD *ctx;
153
154         EINA_SAFETY_ON_NULL_RETURN(message);
155         ctx = calloc(1, sizeof(USSD));
156         EINA_SAFETY_ON_NULL_RETURN(ctx);
157
158         ctx->message = eina_stringshare_add(message);
159         ctx->state = -1;
160         ctx->cb_changed = ofono_modem_changed_cb_add(_ofono_changed, ctx);
161
162         ctx->popup = gui_simple_popup("Supplementary Services", ctx->message);
163         evas_object_event_callback_add(ctx->popup, EVAS_CALLBACK_DEL,
164                                         _on_del, ctx);
165         _ofono_changed(ctx);
166 }