1 #include <nm_core.h>
2 #include <nm_utils.h>
3 #if defined (NM_WITH_DBUS)
4 #include <dbus/dbus.h>
5 #endif
6
7 #define DBUS_NOTIFY_OBJECT "/org/freedesktop/Notifications"
8 #define DBUS_NOTIFY_INTERFACE "org.freedesktop.Notifications"
9 #define DBUS_NOTIFY_METHOD "Notify"
10
11 #if defined (NM_WITH_DBUS)
12 static DBusConnection* dbus_conn = NULL;
13 static DBusError dbus_err;
14
nm_dbus_get_error(void)15 static int nm_dbus_get_error(void)
16 {
17 if (dbus_error_is_set(&dbus_err)) {
18 nm_debug("%s: dbus error: %s\n", __func__, dbus_err.message);
19 dbus_error_free(&dbus_err);
20
21 return NM_OK;
22 }
23
24 return NM_ERR;
25 }
26
nm_dbus_connect(void)27 int nm_dbus_connect(void)
28 {
29 if (!nm_cfg_get()->dbus_enabled)
30 return NM_OK;
31
32 dbus_error_init(&dbus_err);
33 dbus_conn = dbus_bus_get(DBUS_BUS_SESSION, &dbus_err);
34
35 if (nm_dbus_get_error() == NM_OK) {
36 return NM_ERR;
37 }
38
39 if (!dbus_conn) {
40 nm_debug("%s: NULL DBusConnection\n", __func__);
41 return NM_ERR;
42 }
43
44 return NM_OK;
45 }
46
nm_dbus_disconnect(void)47 void nm_dbus_disconnect(void)
48 {
49 if (!nm_cfg_get()->dbus_enabled)
50 return;
51
52 if (dbus_conn) {
53 dbus_connection_unref(dbus_conn);
54 }
55 }
56
57 static int
nm_dbus_build_message(DBusMessage * msg,const char * head,const char * body)58 nm_dbus_build_message(DBusMessage* msg, const char *head, const char *body)
59 {
60 DBusMessageIter args[2];
61 dbus_bool_t rc = 1;
62 const char *app[] = {NM_PROGNAME};
63 uint32_t replaces_id = -1;
64 const char *app_icon[] = {""};
65 int32_t timeout = nm_cfg_get()->dbus_timeout;
66
67 /* TODO add return code checking */
68 dbus_message_iter_init_append(msg, &args[0]);
69 dbus_message_iter_append_basic(&args[0], DBUS_TYPE_STRING, &app);
70 dbus_message_iter_append_basic(&args[0], DBUS_TYPE_UINT32, &replaces_id);
71 dbus_message_iter_append_basic(&args[0], DBUS_TYPE_STRING, &app_icon);
72 dbus_message_iter_append_basic(&args[0], DBUS_TYPE_STRING, &head);
73 dbus_message_iter_append_basic(&args[0], DBUS_TYPE_STRING, &body);
74
75 dbus_message_iter_open_container(&args[0], DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING, &args[1]);
76 dbus_message_iter_close_container(&args[0], &args[1]);
77 dbus_message_iter_open_container(&args[0], DBUS_TYPE_ARRAY, "{sv}", &args[1]);
78 dbus_message_iter_close_container(&args[0], &args[1]);
79 dbus_message_iter_append_basic(&args[0], DBUS_TYPE_INT32, &timeout);
80
81 return rc;
82 }
83
nm_dbus_send_notify(const char * title,const char * body)84 void nm_dbus_send_notify(const char *title, const char *body)
85 {
86 DBusMessage *msg = NULL;
87
88 if (!nm_cfg_get()->dbus_enabled)
89 return;
90
91 if ((msg = dbus_message_new_method_call(
92 NULL,
93 DBUS_NOTIFY_OBJECT,
94 DBUS_NOTIFY_INTERFACE,
95 DBUS_NOTIFY_METHOD)) == NULL) {
96 nm_dbus_get_error();
97 goto clean;
98 }
99
100 dbus_message_set_no_reply(msg, TRUE);
101 dbus_message_set_auto_start(msg, TRUE);
102 dbus_message_set_destination(msg, DBUS_NOTIFY_INTERFACE);
103
104 if (!nm_dbus_build_message(msg, title, body)) {
105 nm_debug("%s: enomem\n", __func__);
106 goto clean;
107 }
108
109 if (!dbus_connection_send(dbus_conn, msg, NULL)) {
110 nm_dbus_get_error();
111 goto clean;
112 }
113
114 dbus_connection_flush(dbus_conn);
115
116 clean:
117 if (msg)
118 dbus_message_unref(msg);
119 }
120 #endif
121
122 /* vim:set ts=4 sw=4: */
123