4 #include <Elementary.h>
10 static E_DBus_Connection *bus_conn = NULL;
11 static E_DBus_Object *bus_obj = NULL;
12 static E_DBus_Interface *bus_iface = NULL;
14 #define RC_IFACE "org.tizen.dialer.Control"
16 #define RC_SIG_CALL_ADDED "AddedCall"
17 #define RC_SIG_CALL_REMOVED "RemovedCall"
19 static const char *rc_service = NULL;
20 static OFono_Callback_List_Modem_Node *modem_changed_node = NULL;
21 static OFono_Callback_List_Call_Node *call_added = NULL;
22 static OFono_Callback_List_Call_Node *call_removed = NULL;
23 static OFono_Callback_List_Call_Node *call_changed = NULL;
24 static DBusMessage *pending_dial = NULL;
25 static OFono_Call *waiting = NULL;
27 static void _dial_number(const char *number, Eina_Bool do_auto)
29 INF("dial '%s' auto=%d!", number, do_auto);
32 gui_number_set(number, do_auto);
35 static void _modem_changed_cb(void *data __UNUSED__)
42 if (!ofono_voice_is_online() || !pending_dial)
45 dbus_error_init(&err);
46 dbus_message_get_args(pending_dial, &err, DBUS_TYPE_STRING, &number,
47 DBUS_TYPE_BOOLEAN, &do_auto, DBUS_TYPE_INVALID);
49 if (dbus_error_is_set(&err)) {
50 ERR("Could not parse message: %s: %s", err.name, err.message);
51 reply = dbus_message_new_error(pending_dial, err.name,
56 _dial_number(number, do_auto);
57 reply = dbus_message_new_method_return(pending_dial);
59 e_dbus_message_send(bus_conn, reply, NULL, -1, NULL);
60 dbus_message_unref(pending_dial);
61 dbus_message_unref(reply);
66 _rc_activate(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
68 INF("Remotely activated!");
70 return dbus_message_new_method_return(msg);
74 _rc_dial(E_DBus_Object *obj __UNUSED__, DBusMessage *msg)
80 if (!ofono_voice_is_online()) {
82 dbus_message_unref(pending_dial);
83 pending_dial = dbus_message_ref(msg);
87 dbus_error_init(&err);
88 dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &number,
89 DBUS_TYPE_BOOLEAN, &do_auto, DBUS_TYPE_INVALID);
90 if (dbus_error_is_set(&err)) {
91 ERR("Could not parse message: %s: %s", err.name, err.message);
92 return dbus_message_new_error(msg, err.name, err.message);
94 _dial_number(number, do_auto);
95 return dbus_message_new_method_return(msg);
98 static DBusMessage *_rc_hangup_call(E_DBus_Object *obj __UNUSED__,
102 return dbus_message_new_error(msg,
103 "org.tizen.dialer.error.NotAvailable",
104 "No calls available");
107 ofono_call_hangup(waiting, NULL, NULL);
109 return dbus_message_new_method_return(msg);
112 static DBusMessage *_rc_answer_call(E_DBus_Object *obj __UNUSED__,
115 OFono_Call_State state;
118 return dbus_message_new_error(msg,
119 "org.tizen.dialer.error.NotAvailable",
120 "No calls available");
123 state = ofono_call_state_get(waiting);
124 if (state == OFONO_CALL_STATE_INCOMING)
125 ofono_call_answer(waiting, NULL, NULL);
126 else if (state == OFONO_CALL_STATE_WAITING)
127 ofono_hold_and_answer(NULL, NULL);
129 return dbus_message_new_method_return(msg);
132 static void _rc_signal_reply(void *data __UNUSED__,
133 DBusMessage *msg __UNUSED__,
136 if (dbus_error_is_set(err)) {
137 CRITICAL("Failed to send a signal: %s: %s",
138 err->name, err->message);
142 DBG("Signal was sent successfully");
145 static void _new_call_sig_emit(OFono_Call *call)
148 const char *line_id, *name = "", *type = "", *img = "";
149 Contact_Info *c_info;
151 line_id = ofono_call_line_id_get(call);
152 c_info = gui_contact_search(line_id, &type);
155 name = contact_info_full_name_get(c_info);
156 img = contact_info_picture_get(c_info);
161 msg = dbus_message_new_signal(RC_PATH, RC_IFACE, RC_SIG_CALL_ADDED);
162 EINA_SAFETY_ON_NULL_RETURN(msg);
164 if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &img,
165 DBUS_TYPE_STRING, &line_id,
166 DBUS_TYPE_STRING, &name,
167 DBUS_TYPE_STRING, &type,
168 DBUS_TYPE_INVALID)) {
169 ERR("Could not append msg args.");
173 e_dbus_message_send(bus_conn, msg, _rc_signal_reply, -1, NULL);
175 dbus_message_unref(msg);
178 static DBusMessage *_rc_waiting_call_get(E_DBus_Object *obj __UNUSED__,
182 const char *line_id, *name = "", *type = "", *img = "";
183 Contact_Info *c_info;
187 return dbus_message_new_error(msg,
188 "org.tizen.dialer.error.NotAvailable",
189 "No calls available");
192 line_id = ofono_call_line_id_get(waiting);
193 c_info = gui_contact_search(line_id, &type);
196 name = contact_info_full_name_get(c_info);
197 img = contact_info_picture_get(c_info);
202 ret = dbus_message_new_method_return(msg);
203 EINA_SAFETY_ON_NULL_GOTO(ret, err_ret);
205 if (!dbus_message_append_args(ret, DBUS_TYPE_STRING, &img,
206 DBUS_TYPE_STRING, &line_id,
207 DBUS_TYPE_STRING, &name,
208 DBUS_TYPE_STRING, &type,
209 DBUS_TYPE_INVALID)) {
210 ERR("Could not append msg args.");
217 dbus_message_unref(ret);
220 return dbus_message_new_error(msg,
221 "org.tizen.dialer.error.Error",
222 "Could not create a reply");
225 static void _rc_object_register(void)
227 bus_obj = e_dbus_object_add(bus_conn, RC_PATH, NULL);
229 CRITICAL("Could not create "RC_PATH" DBus object.");
232 bus_iface = e_dbus_interface_new(RC_IFACE);
233 e_dbus_object_interface_attach(bus_obj, bus_iface);
235 #define IF_ADD(name, par, ret, cb) \
236 e_dbus_interface_method_add(bus_iface, name, par, ret, cb)
238 IF_ADD("Activate", "", "", _rc_activate);
239 IF_ADD("Dial", "sb", "", _rc_dial);
240 IF_ADD("HangupCall", "", "", _rc_hangup_call);
241 IF_ADD("AnswerCall", "", "", _rc_answer_call);
242 IF_ADD("GetAvailableCall", "", "ssss", _rc_waiting_call_get);
245 e_dbus_interface_signal_add(bus_iface, RC_SIG_CALL_ADDED,
247 e_dbus_interface_signal_add(bus_iface, RC_SIG_CALL_REMOVED,
251 static void _rc_activate_existing_reply(void *data __UNUSED__,
252 DBusMessage *msg __UNUSED__,
255 if (dbus_error_is_set(err)) {
256 CRITICAL("Failed to activate existing dialer: %s: %s",
257 err->name, err->message);
258 _app_exit_code = EXIT_FAILURE;
259 ecore_main_loop_quit();
263 INF("Activated the existing dialer!");
264 ecore_main_loop_quit();
267 static void _rc_activate_existing(void)
269 DBusMessage *msg = dbus_message_new_method_call(
270 rc_service, RC_PATH, RC_IFACE, "Activate");
271 e_dbus_message_send(bus_conn, msg, _rc_activate_existing_reply,
273 dbus_message_unref(msg);
276 static void _rc_request_name_reply(void *data __UNUSED__, DBusMessage *msg,
284 WRN("%s: %s", err->name, err->message);
287 _rc_activate_existing();
292 dbus_message_get_args(msg, &e, DBUS_TYPE_UINT32, &t, DBUS_TYPE_INVALID);
293 if (t == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
294 _rc_object_register();
297 WRN("Dialer already running! Activate it!");
298 _rc_activate_existing();
302 static void _removed_signal_send(void)
306 msg = dbus_message_new_signal(RC_PATH, RC_IFACE, RC_SIG_CALL_REMOVED);
307 EINA_SAFETY_ON_NULL_RETURN(msg);
309 e_dbus_message_send(bus_conn, msg, _rc_signal_reply, -1, NULL);
311 dbus_message_unref(msg);
314 static void _rc_call_added_cb(void *data __UNUSED__, OFono_Call *call)
316 OFono_Call_State state = ofono_call_state_get(call);
318 if (state != OFONO_CALL_STATE_INCOMING &&
319 state != OFONO_CALL_STATE_WAITING)
323 _removed_signal_send();
326 _new_call_sig_emit(call);
330 static void _rc_call_removed_cb(void *data __UNUSED__, OFono_Call *call)
334 _removed_signal_send();
338 static void _rc_call_changed_cb(void *data __UNUSED__, OFono_Call *call)
340 OFono_Call_State state;
345 state = ofono_call_state_get(call);
346 if (state == OFONO_CALL_STATE_INCOMING ||
347 state == OFONO_CALL_STATE_WAITING)
350 _removed_signal_send();
354 Eina_Bool rc_init(const char *service)
356 rc_service = service;
358 if (!elm_need_e_dbus()) {
359 CRITICAL("Elementary does not support DBus.");
364 /* NOTE: Tizen is stupid and does not have a session bus. at
365 * least not for user "app". Moreover the dialer is started by
368 INF("Running on System bus");
369 bus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
371 INF("Running on Session bus");
372 bus_conn = e_dbus_bus_get(DBUS_BUS_SESSION);
375 CRITICAL("Could not get DBus Bus");
379 e_dbus_request_name(bus_conn, rc_service, DBUS_NAME_FLAG_DO_NOT_QUEUE,
380 _rc_request_name_reply, NULL);
382 modem_changed_node = ofono_modem_changed_cb_add(_modem_changed_cb,
385 call_added = ofono_call_added_cb_add(_rc_call_added_cb, NULL);
386 call_removed = ofono_call_removed_cb_add(_rc_call_removed_cb, NULL);
387 call_changed = ofono_call_changed_cb_add(_rc_call_changed_cb, NULL);
392 void rc_shutdown(void)
395 e_dbus_object_free(bus_obj);
397 e_dbus_interface_unref(bus_iface);
399 ofono_modem_changed_cb_del(modem_changed_node);
400 ofono_call_added_cb_del(call_added);
401 ofono_call_removed_cb_del(call_removed);
402 ofono_call_changed_cb_del(call_changed);
405 dbus_message_unref(pending_dial);