~ubuntu-branches/ubuntu/precise/rygel/precise

« back to all changes in this revision

Viewing changes to src/rygel/rygel-dbus-service.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Henriksson
  • Date: 2009-09-26 14:04:05 UTC
  • Revision ID: james.westby@ubuntu.com-20090926140405-d5x3j13k10psa1gu
Tags: upstream-0.4.1
ImportĀ upstreamĀ versionĀ 0.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2008 Nokia Corporation.
 
3
 * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>.
 
4
 *
 
5
 * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
 
6
 *
 
7
 * This file is part of Rygel.
 
8
 *
 
9
 * Rygel is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU Lesser General Public License as published by
 
11
 * the Free Software Foundation; either version 2 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * Rygel is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU Lesser General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU Lesser General Public License
 
20
 * along with this program; if not, write to the Free Software Foundation,
 
21
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
22
 */
 
23
 
 
24
#include <glib.h>
 
25
#include <glib-object.h>
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
#include <dbus/dbus-glib-lowlevel.h>
 
29
#include <dbus/dbus-glib.h>
 
30
#include <dbus/dbus.h>
 
31
 
 
32
 
 
33
#define RYGEL_TYPE_DBUS_SERVICE (rygel_dbus_service_get_type ())
 
34
#define RYGEL_DBUS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_DBUS_SERVICE, RygelDBusService))
 
35
#define RYGEL_DBUS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_DBUS_SERVICE, RygelDBusServiceClass))
 
36
#define RYGEL_IS_DBUS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_DBUS_SERVICE))
 
37
#define RYGEL_IS_DBUS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_DBUS_SERVICE))
 
38
#define RYGEL_DBUS_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_DBUS_SERVICE, RygelDBusServiceClass))
 
39
 
 
40
typedef struct _RygelDBusService RygelDBusService;
 
41
typedef struct _RygelDBusServiceClass RygelDBusServiceClass;
 
42
typedef struct _RygelDBusServicePrivate RygelDBusServicePrivate;
 
43
 
 
44
#define RYGEL_TYPE_MAIN (rygel_main_get_type ())
 
45
#define RYGEL_MAIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_MAIN, RygelMain))
 
46
#define RYGEL_MAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_MAIN, RygelMainClass))
 
47
#define RYGEL_IS_MAIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_MAIN))
 
48
#define RYGEL_IS_MAIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_MAIN))
 
49
#define RYGEL_MAIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_MAIN, RygelMainClass))
 
50
 
 
51
typedef struct _RygelMain RygelMain;
 
52
typedef struct _RygelMainClass RygelMainClass;
 
53
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
 
54
#define _dbus_g_connection_unref0(var) ((var == NULL) ? NULL : (var = (dbus_g_connection_unref (var), NULL)))
 
55
typedef struct _DBusObjectVTable _DBusObjectVTable;
 
56
 
 
57
struct _RygelDBusService {
 
58
        GObject parent_instance;
 
59
        RygelDBusServicePrivate * priv;
 
60
};
 
61
 
 
62
struct _RygelDBusServiceClass {
 
63
        GObjectClass parent_class;
 
64
};
 
65
 
 
66
struct _RygelDBusServicePrivate {
 
67
        RygelMain* main;
 
68
};
 
69
 
 
70
struct _DBusObjectVTable {
 
71
        void (*register_object) (DBusConnection*, const char*, void*);
 
72
};
 
73
 
 
74
 
 
75
static char* rygel_dbus_service_RYGEL_SERVICE;
 
76
static char* rygel_dbus_service_RYGEL_SERVICE = NULL;
 
77
static char* rygel_dbus_service_RYGEL_PATH;
 
78
static char* rygel_dbus_service_RYGEL_PATH = NULL;
 
79
static gpointer rygel_dbus_service_parent_class = NULL;
 
80
 
 
81
GType rygel_dbus_service_get_type (void);
 
82
GType rygel_main_get_type (void);
 
83
#define RYGEL_DBUS_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_TYPE_DBUS_SERVICE, RygelDBusServicePrivate))
 
84
enum  {
 
85
        RYGEL_DBUS_SERVICE_DUMMY_PROPERTY
 
86
};
 
87
guint _dynamic_request_name2 (DBusGProxy* self, const char* param1, guint param2, GError** error);
 
88
RygelDBusService* rygel_dbus_service_new (RygelMain* main, GError** error);
 
89
RygelDBusService* rygel_dbus_service_construct (GType object_type, RygelMain* main, GError** error);
 
90
void rygel_main_exit (RygelMain* self, gint exit_code);
 
91
void rygel_dbus_service_Shutdown (RygelDBusService* self);
 
92
void rygel_dbus_service_dbus_register_object (DBusConnection* connection, const char* path, void* object);
 
93
void _rygel_dbus_service_dbus_unregister (DBusConnection* connection, void* _user_data_);
 
94
DBusHandlerResult rygel_dbus_service_dbus_message (DBusConnection* connection, DBusMessage* message, void* object);
 
95
static DBusHandlerResult _dbus_rygel_dbus_service_introspect (RygelDBusService* self, DBusConnection* connection, DBusMessage* message);
 
96
static DBusHandlerResult _dbus_rygel_dbus_service_property_get_all (RygelDBusService* self, DBusConnection* connection, DBusMessage* message);
 
97
static DBusHandlerResult _dbus_rygel_dbus_service_Shutdown (RygelDBusService* self, DBusConnection* connection, DBusMessage* message);
 
98
static void rygel_dbus_service_finalize (GObject* obj);
 
99
static void _vala_dbus_register_object (DBusConnection* connection, const char* path, void* object);
 
100
static void _vala_dbus_unregister_object (gpointer connection, GObject* object);
 
101
 
 
102
static const DBusObjectPathVTable _rygel_dbus_service_dbus_path_vtable = {_rygel_dbus_service_dbus_unregister, rygel_dbus_service_dbus_message};
 
103
static const _DBusObjectVTable _rygel_dbus_service_dbus_vtable = {rygel_dbus_service_dbus_register_object};
 
104
 
 
105
 
 
106
static gpointer _g_object_ref0 (gpointer self) {
 
107
        return self ? g_object_ref (self) : NULL;
 
108
}
 
109
 
 
110
 
 
111
guint _dynamic_request_name2 (DBusGProxy* self, const char* param1, guint param2, GError** error) {
 
112
        guint result;
 
113
        dbus_g_proxy_call (self, "RequestName", error, G_TYPE_STRING, param1, G_TYPE_UINT, param2, G_TYPE_INVALID, G_TYPE_UINT, &result, G_TYPE_INVALID);
 
114
        if (*error) {
 
115
                return 0U;
 
116
        }
 
117
        return result;
 
118
}
 
119
 
 
120
 
 
121
RygelDBusService* rygel_dbus_service_construct (GType object_type, RygelMain* main, GError** error) {
 
122
        GError * _inner_error_;
 
123
        RygelDBusService * self;
 
124
        RygelMain* _tmp0_;
 
125
        DBusGConnection* conn;
 
126
        DBusGProxy* bus;
 
127
        guint request_name_result;
 
128
        g_return_val_if_fail (main != NULL, NULL);
 
129
        _inner_error_ = NULL;
 
130
        self = (RygelDBusService*) g_object_new (object_type, NULL);
 
131
        self->priv->main = (_tmp0_ = _g_object_ref0 (main), _g_object_unref0 (self->priv->main), _tmp0_);
 
132
        conn = dbus_g_bus_get (DBUS_BUS_SESSION, &_inner_error_);
 
133
        if (_inner_error_ != NULL) {
 
134
                g_propagate_error (error, _inner_error_);
 
135
                return;
 
136
        }
 
137
        bus = dbus_g_proxy_new_for_name (conn, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus");
 
138
        request_name_result = _dynamic_request_name2 (bus, rygel_dbus_service_RYGEL_SERVICE, (guint) 0, &_inner_error_);
 
139
        if (_inner_error_ != NULL) {
 
140
                g_propagate_error (error, _inner_error_);
 
141
                _dbus_g_connection_unref0 (conn);
 
142
                _g_object_unref0 (bus);
 
143
                return;
 
144
        }
 
145
        if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
 
146
                g_warning ("rygel-dbus-service.vala:45: Failed to start D-Bus service, name '%s' already taken", rygel_dbus_service_RYGEL_SERVICE);
 
147
        }
 
148
        _vala_dbus_register_object (dbus_g_connection_get_connection (conn), rygel_dbus_service_RYGEL_PATH, (GObject*) self);
 
149
        _dbus_g_connection_unref0 (conn);
 
150
        _g_object_unref0 (bus);
 
151
        return self;
 
152
}
 
153
 
 
154
 
 
155
RygelDBusService* rygel_dbus_service_new (RygelMain* main, GError** error) {
 
156
        return rygel_dbus_service_construct (RYGEL_TYPE_DBUS_SERVICE, main, error);
 
157
}
 
158
 
 
159
 
 
160
void rygel_dbus_service_Shutdown (RygelDBusService* self) {
 
161
        g_return_if_fail (self != NULL);
 
162
        rygel_main_exit (self->priv->main, 0);
 
163
}
 
164
 
 
165
 
 
166
void _rygel_dbus_service_dbus_unregister (DBusConnection* connection, void* _user_data_) {
 
167
}
 
168
 
 
169
 
 
170
static DBusHandlerResult _dbus_rygel_dbus_service_introspect (RygelDBusService* self, DBusConnection* connection, DBusMessage* message) {
 
171
        DBusMessage* reply;
 
172
        DBusMessageIter iter;
 
173
        GString* xml_data;
 
174
        char** children;
 
175
        int i;
 
176
        reply = dbus_message_new_method_return (message);
 
177
        dbus_message_iter_init_append (reply, &iter);
 
178
        xml_data = g_string_new ("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n");
 
179
        g_string_append (xml_data, "<node>\n<interface name=\"org.freedesktop.DBus.Introspectable\">\n  <method name=\"Introspect\">\n    <arg name=\"data\" direction=\"out\" type=\"s\"/>\n  </method>\n</interface>\n<interface name=\"org.freedesktop.DBus.Properties\">\n  <method name=\"Get\">\n    <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n    <arg name=\"propname\" direction=\"in\" type=\"s\"/>\n    <arg name=\"value\" direction=\"out\" type=\"v\"/>\n  </method>\n  <method name=\"Set\">\n    <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n    <arg name=\"propname\" direction=\"in\" type=\"s\"/>\n    <arg name=\"value\" direction=\"in\" type=\"v\"/>\n  </method>\n  <method name=\"GetAll\">\n    <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n    <arg name=\"props\" direction=\"out\" type=\"a{sv}\"/>\n  </method>\n</interface>\n<interface name=\"org.gnome.Rygel1\">\n  <method name=\"Shutdown\">\n  </method>\n</interface>\n");
 
180
        dbus_connection_list_registered (connection, g_object_get_data ((GObject *) self, "dbus_object_path"), &children);
 
181
        for (i = 0; children[i]; i++) {
 
182
                g_string_append_printf (xml_data, "<node name=\"%s\"/>\n", children[i]);
 
183
        }
 
184
        dbus_free_string_array (children);
 
185
        g_string_append (xml_data, "</node>\n");
 
186
        dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &xml_data->str);
 
187
        g_string_free (xml_data, TRUE);
 
188
        if (reply) {
 
189
                dbus_connection_send (connection, reply, NULL);
 
190
                dbus_message_unref (reply);
 
191
                return DBUS_HANDLER_RESULT_HANDLED;
 
192
        } else {
 
193
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
194
        }
 
195
}
 
196
 
 
197
 
 
198
static DBusHandlerResult _dbus_rygel_dbus_service_property_get_all (RygelDBusService* self, DBusConnection* connection, DBusMessage* message) {
 
199
        DBusMessage* reply;
 
200
        DBusMessageIter iter, reply_iter, subiter;
 
201
        char* interface_name;
 
202
        const char* _tmp0_;
 
203
        if (strcmp (dbus_message_get_signature (message), "s")) {
 
204
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
205
        }
 
206
        dbus_message_iter_init (message, &iter);
 
207
        reply = dbus_message_new_method_return (message);
 
208
        dbus_message_iter_init_append (reply, &reply_iter);
 
209
        dbus_message_iter_get_basic (&iter, &_tmp0_);
 
210
        dbus_message_iter_next (&iter);
 
211
        interface_name = g_strdup (_tmp0_);
 
212
        if (strcmp (interface_name, "org.gnome.Rygel1") == 0) {
 
213
                dbus_message_iter_open_container (&reply_iter, DBUS_TYPE_ARRAY, "{sv}", &subiter);
 
214
                dbus_message_iter_close_container (&reply_iter, &subiter);
 
215
        } else {
 
216
                dbus_message_unref (reply);
 
217
                reply = NULL;
 
218
        }
 
219
        g_free (interface_name);
 
220
        if (reply) {
 
221
                dbus_connection_send (connection, reply, NULL);
 
222
                dbus_message_unref (reply);
 
223
                return DBUS_HANDLER_RESULT_HANDLED;
 
224
        } else {
 
225
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
226
        }
 
227
}
 
228
 
 
229
 
 
230
static DBusHandlerResult _dbus_rygel_dbus_service_Shutdown (RygelDBusService* self, DBusConnection* connection, DBusMessage* message) {
 
231
        DBusMessageIter iter;
 
232
        GError* error;
 
233
        DBusMessage* reply;
 
234
        error = NULL;
 
235
        if (strcmp (dbus_message_get_signature (message), "")) {
 
236
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
237
        }
 
238
        dbus_message_iter_init (message, &iter);
 
239
        rygel_dbus_service_Shutdown (self);
 
240
        reply = dbus_message_new_method_return (message);
 
241
        dbus_message_iter_init_append (reply, &iter);
 
242
        if (reply) {
 
243
                dbus_connection_send (connection, reply, NULL);
 
244
                dbus_message_unref (reply);
 
245
                return DBUS_HANDLER_RESULT_HANDLED;
 
246
        } else {
 
247
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
248
        }
 
249
}
 
250
 
 
251
 
 
252
DBusHandlerResult rygel_dbus_service_dbus_message (DBusConnection* connection, DBusMessage* message, void* object) {
 
253
        DBusHandlerResult result;
 
254
        result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
255
        if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
 
256
                result = _dbus_rygel_dbus_service_introspect (object, connection, message);
 
257
        } else if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Properties", "GetAll")) {
 
258
                result = _dbus_rygel_dbus_service_property_get_all (object, connection, message);
 
259
        } else if (dbus_message_is_method_call (message, "org.gnome.Rygel1", "Shutdown")) {
 
260
                result = _dbus_rygel_dbus_service_Shutdown (object, connection, message);
 
261
        }
 
262
        if (result == DBUS_HANDLER_RESULT_HANDLED) {
 
263
                return result;
 
264
        } else {
 
265
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
266
        }
 
267
}
 
268
 
 
269
 
 
270
void rygel_dbus_service_dbus_register_object (DBusConnection* connection, const char* path, void* object) {
 
271
        if (!g_object_get_data (object, "dbus_object_path")) {
 
272
                g_object_set_data (object, "dbus_object_path", g_strdup (path));
 
273
                dbus_connection_register_object_path (connection, path, &_rygel_dbus_service_dbus_path_vtable, object);
 
274
                g_object_weak_ref (object, _vala_dbus_unregister_object, connection);
 
275
        }
 
276
}
 
277
 
 
278
 
 
279
static void rygel_dbus_service_class_init (RygelDBusServiceClass * klass) {
 
280
        rygel_dbus_service_parent_class = g_type_class_peek_parent (klass);
 
281
        g_type_class_add_private (klass, sizeof (RygelDBusServicePrivate));
 
282
        G_OBJECT_CLASS (klass)->finalize = rygel_dbus_service_finalize;
 
283
        g_type_set_qdata (RYGEL_TYPE_DBUS_SERVICE, g_quark_from_static_string ("DBusObjectVTable"), (void*) (&_rygel_dbus_service_dbus_vtable));
 
284
        rygel_dbus_service_RYGEL_SERVICE = g_strdup ("org.gnome.Rygel1");
 
285
        rygel_dbus_service_RYGEL_PATH = g_strdup ("/org/gnome/Rygel1");
 
286
}
 
287
 
 
288
 
 
289
static void rygel_dbus_service_instance_init (RygelDBusService * self) {
 
290
        self->priv = RYGEL_DBUS_SERVICE_GET_PRIVATE (self);
 
291
}
 
292
 
 
293
 
 
294
static void rygel_dbus_service_finalize (GObject* obj) {
 
295
        RygelDBusService * self;
 
296
        self = RYGEL_DBUS_SERVICE (obj);
 
297
        _g_object_unref0 (self->priv->main);
 
298
        G_OBJECT_CLASS (rygel_dbus_service_parent_class)->finalize (obj);
 
299
}
 
300
 
 
301
 
 
302
GType rygel_dbus_service_get_type (void) {
 
303
        static GType rygel_dbus_service_type_id = 0;
 
304
        if (rygel_dbus_service_type_id == 0) {
 
305
                static const GTypeInfo g_define_type_info = { sizeof (RygelDBusServiceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_dbus_service_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelDBusService), 0, (GInstanceInitFunc) rygel_dbus_service_instance_init, NULL };
 
306
                rygel_dbus_service_type_id = g_type_register_static (G_TYPE_OBJECT, "RygelDBusService", &g_define_type_info, 0);
 
307
        }
 
308
        return rygel_dbus_service_type_id;
 
309
}
 
310
 
 
311
 
 
312
static void _vala_dbus_register_object (DBusConnection* connection, const char* path, void* object) {
 
313
        const _DBusObjectVTable * vtable;
 
314
        vtable = g_type_get_qdata (G_TYPE_FROM_INSTANCE (object), g_quark_from_static_string ("DBusObjectVTable"));
 
315
        if (vtable) {
 
316
                vtable->register_object (connection, path, object);
 
317
        } else {
 
318
                g_warning ("Object does not implement any D-Bus interface");
 
319
        }
 
320
}
 
321
 
 
322
 
 
323
static void _vala_dbus_unregister_object (gpointer connection, GObject* object) {
 
324
        char* path;
 
325
        path = g_object_steal_data ((GObject*) object, "dbus_object_path");
 
326
        dbus_connection_unregister_object_path (connection, path);
 
327
        g_free (path);
 
328
}
 
329
 
 
330
 
 
331
 
 
332