blob: 04489f6cdbbeeeb097c65aebae8dbd01ded82558 [file] [log] [blame]
David Sodmanbbcb0522014-09-19 10:34:07 -07001/*
2 * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7#include <stdlib.h>
8#include "dbus.h"
9#include "util.h"
10
11struct _dbus_t {
12 DBusConnection *conn;
13 int terminate;
14 struct {
15 DBusObjectPathVTable vtable;
16 const char* interface;
17 const char* signal;
18 const char* rule;
19 void* user_data;
20 dbus_message_handler_t signal_handler;
21 } signal;
22};
23
24dbus_t* dbus_init()
25{
26 dbus_t* new_dbus;
27 DBusError err;
28
29 dbus_error_init(&err);
30
31 new_dbus = (dbus_t*)calloc(1, sizeof(*new_dbus));
32
33 new_dbus->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
34 if (dbus_error_is_set(&err)) {
35 LOG(ERROR, "Cannot get dbus connection");
36 free(new_dbus);
37 return NULL;
38 }
39
40 dbus_connection_set_exit_on_disconnect(new_dbus->conn, FALSE);
41
42 return new_dbus;
43}
44
45
David Sodman003faed2014-11-03 09:02:10 -080046bool dbus_method_call0(dbus_t* dbus, const char* service_name,
47 const char* service_path, const char* service_interface,
48 const char* method)
49{
50 DBusMessage *msg = NULL;
51
52 msg = dbus_message_new_method_call(service_name,
53 service_path, service_interface, method);
54
55 if (!msg)
56 return false;
57
58 if (!dbus_connection_send_with_reply_and_block(dbus->conn,
59 msg, -1, NULL)) {
60 dbus_message_unref(msg);
61 return false;
62 }
63
64 dbus_connection_flush(dbus->conn);
65 dbus_message_unref(msg);
66
67 return true;
68}
69
70bool dbus_method_call1(dbus_t* dbus, const char* service_name,
David Sodmanbbcb0522014-09-19 10:34:07 -070071 const char* service_path, const char* service_interface,
72 const char* method, int* param)
73{
74 DBusMessage *msg = NULL;
75
76 msg = dbus_message_new_method_call(service_name,
77 service_path, service_interface, method);
78
79 if (!msg)
80 return false;
81
82 if (!dbus_message_append_args(msg,
83 DBUS_TYPE_INT32, param, DBUS_TYPE_INVALID)) {
84 dbus_message_unref(msg);
85 return false;
86 }
87
88 if (!dbus_connection_send_with_reply_and_block(dbus->conn,
89 msg, -1, NULL)) {
90 dbus_message_unref(msg);
91 return false;
92 }
93
94 dbus_connection_flush(dbus->conn);
95 dbus_message_unref(msg);
96
97 return true;
98}
99
100static void
101dbus_path_unregister_function(DBusConnection *connection, void *user_data)
102{
103}
104
105static DBusHandlerResult
106dbus_message_function(DBusConnection *connection,
107 DBusMessage *message, void* user_data)
108{
109 dbus_t* dbus = (dbus_t*)user_data;
110
111 if (dbus_message_is_signal(message, dbus->signal.interface,
112 dbus->signal.signal)) {
113 dbus->signal.signal_handler(dbus, dbus->signal.user_data);
114 }
115 return DBUS_HANDLER_RESULT_HANDLED;
116}
117
118bool dbus_signal_match_handler(
119 dbus_t* dbus,
120 const char* signal,
121 const char* path,
122 const char* interface,
123 const char* rule,
124 dbus_message_handler_t handler,
125 void *user_data)
126{
127 DBusError err;
128 dbus->signal.vtable.unregister_function = dbus_path_unregister_function;
129 dbus->signal.vtable.message_function = dbus_message_function;
130 dbus->signal.signal_handler = handler;
131 dbus->signal.signal = signal;
132 dbus->signal.user_data = user_data;
133 dbus->signal.interface = interface;
134
135 if (!dbus_connection_register_object_path(dbus->conn, path,
136 &dbus->signal.vtable, dbus)) {
137 LOG(ERROR, "register_object_path failed");
138 return false;
139 }
140
141 dbus_error_init(&err);
142 dbus_bus_add_match(dbus->conn, rule, &err);
143 if (dbus_error_is_set(&err)) {
144 LOG(ERROR, "add_match failed: %s", err.message);
145 return false;
146 }
147
148 return true;
149}
150
151
152void dbus_wait_for_messages(dbus_t *dbus)
153{
154 while (dbus_connection_read_write_dispatch(dbus->conn, -1)) {
155 if (dbus->terminate)
156 break;
157 }
158}
159
160
161void dbus_stop_wait(dbus_t* dbus)
162{
163 dbus->terminate = true;
164}
165
166
167void dbus_destroy(dbus_t* dbus)
168{
169 /* FIXME - not sure what the right counterpart to
170 dbus_bus_get() is, unref documentation is rather
171 unclear. Not a big issue but it would be nice to
172 clean up properly here */
173 /* dbus_connection_unref(dbus->conn); */
174 free(dbus);
175}