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